# 生产库首页专家推荐位脏引用检查与清理

## 背景

后台删除专家时是软删除：`expert_profiles.deleted_at` 会被设置，专家状态通常会变成 `offline`。

首页专家推荐位保存在 `site_recommendation_slots`，其中 `placement_key = 'home.experts'` 的四个位置会保存专家 `source_id`。如果旧专家被删除后推荐位没有清空，就会继续引用已删除专家，后台“推荐位配置 -> 首页专家”会提示：

- 内容不存在、已删除或当前不可见
- 推荐内容不存在

本次任务只处理数据库里的无效引用，不改代码，不重启服务。

## 执行要求

- 不要删除 `expert_profiles` 数据。
- 不要删除 `site_recommendation_slots` 行。
- 只清空无效的 `home.experts` 推荐位。
- 如果当前只有一个可用专家，不要自动填满四个推荐位，因为同一个推荐区不能重复选择同一个专家。

## 1. 查询首页专家推荐位当前引用

```sql
select
  s.placement_key,
  s.slot_key,
  s.source_type,
  s.source_id,
  s.status as slot_status,
  s.sort_order,
  e.id as expert_id,
  e.name,
  e.slug,
  e.status as expert_status,
  e.deleted_at
from site_recommendation_slots s
left join expert_profiles e on e.id::text = s.source_id
where s.placement_key = 'home.experts'
order by s.sort_order, s.slot_key;
```

## 2. 查询当前可用专家

```sql
select id, name, slug, status, deleted_at, updated_at
from expert_profiles
where deleted_at is null
order by updated_at desc
limit 20;
```

## 3. 清空已删除或未发布专家引用

如果第 1 步结果里有以下任一情况，需要清空对应推荐位：

- `expert_id is null`
- `deleted_at is not null`
- `expert_status <> 'published'`

先清空已存在但不可用的专家：

```sql
update site_recommendation_slots s
set
  source_id = '',
  status = 'hidden',
  title_override = '',
  subtitle_override = '',
  image_url_override = '',
  cta_label_override = '',
  href_override = '',
  updated_at = now()
from expert_profiles e
where s.placement_key = 'home.experts'
  and s.source_type = 'expert'
  and s.source_id = e.id::text
  and (e.deleted_at is not null or e.status <> 'published');
```

再清空已经找不到专家记录的引用：

```sql
update site_recommendation_slots s
set
  source_id = '',
  status = 'hidden',
  title_override = '',
  subtitle_override = '',
  image_url_override = '',
  cta_label_override = '',
  href_override = '',
  updated_at = now()
where s.placement_key = 'home.experts'
  and s.source_type = 'expert'
  and s.source_id <> ''
  and not exists (
    select 1
    from expert_profiles e
    where e.id::text = s.source_id
  );
```

## 4. 复查

再次执行第 1 步查询，并把清理后的结果发回。

清理后，后台可以重新进入“推荐位配置 -> 首页专家”，只给可用专家配置推荐位并保存。
