# 数据库软删除 (Soft Delete) 统一标准规范

## 1. 核心目标
- **数据保留**：防止误操作导致的数据永久丢失，支持操作审计。
- **级联安全**：通过逻辑链路同步软删关联数据，避免孤儿数据。
- **透明过滤**：利用 RLS（行级安全策略）或统一过滤口径，使业务层查询默认排除已标记删除的记录。

## 2. 字段规范
所有需要支持软删除的业务表必须统一包含以下字段：

| 字段名        | 类型          | 说明                                    | 索引建议         |
| :------------ | :------------ | :-------------------------------------- | :--------------- |
| `deleted_at`  | `TIMESTAMPTZ` | 删除时间戳。非 NULL 表示已删除。        | **必须建立索引** |
| `deleted_by`  | `UUID`        | 执行删除操作的用户 ID (`ak_users.id`)。 | 建议索引         |
| `restored_at` | `TIMESTAMPTZ` | (可选) 最近一次恢复的时间戳。           | -                |
| `restored_by` | `UUID`        | (可选) 最近一次恢复的操作人。           | -                |

## 3. RLS 自动过滤口径
为了确保查询透明性，必须在 `20_rls/` 策略中统一加入过滤条件：

```sql
-- 示例策略：仅允许查询未删除的记录
CREATE POLICY select_active_records ON public.your_table
  FOR SELECT
  TO authenticated
  USING (deleted_at IS NULL);
```

## 4. RPC 重构准则
删除接口必须从 `DELETE FROM ...` 改为 `UPDATE ... SET deleted_at = now()`：

### 4.1 基础删除模板
```sql
CREATE OR REPLACE FUNCTION public.rpc_admin_soft_delete_item(p_id UUID)
RETURNS BOOLEAN SECURITY DEFINER SET search_path = public AS $$
BEGIN
    -- 1. 鉴权 (示例)
    IF NOT EXISTS (
        SELECT 1 FROM public.ak_users 
        WHERE auth_id = auth.uid() AND role = 'admin'
    ) THEN
        RAISE EXCEPTION 'Permission denied';
    END IF;
    
    -- 2. 执行软删
    UPDATE public.your_table
    SET deleted_at = now(), deleted_by = auth.uid()
    WHERE id = p_id AND deleted_at IS NULL;
    
    RETURN FOUND;
END;
$$ LANGUAGE plpgsql;
```

### 4.2 级联软删除规范
若存在级联依赖（如：软删“商品分类”时需同步软删其下的“商品”），必须在 RPC 内部通过事务或同步 UPDATE 处理：

```sql
-- 级联链路示例
UPDATE public.ml_products
SET deleted_at = now(), deleted_by = auth.uid()
WHERE category_id = p_category_id AND deleted_at IS NULL;
```

## 5. UI 交互适配
- **默认视图**：列表页面默认仅展示 `deleted_at IS NULL` 的数据。
- **回收站 (可选)**：若业务需要，可提供“回收站”视图（过滤 `deleted_at IS NOT NULL`）及“恢复”功能。
- **二次确认**：点击“删除”按钮时，必须弹出提示明确告知数据将进入逻辑删除状态。

---

## 6. 改造优先级
1. **第一梯队**：基础资产（商品、分类、文章、分销商）。
2. **第二梯队**：配置类（运费模板、通知模板、DIY 页面）。
3. **第三梯队**：日志/交互类（评论、收藏、地址）。
