# GORM + Redis 缓存调用规范

本文档约定了项目内 GORM 与 Redis 缓存的推荐调用方式，目标是避免“有的地方自动清缓存，有的地方手动清缓存”的分散写法。

## 统一入口

项目缓存统一由 `pkg/cache/CachedConn` 提供，常用方法：

- `QueryCtx`：读缓存，未命中回源 DB 并写缓存
- `ExecCtx`：写 DB，成功后删除指定缓存 key
- `QueryNoCacheCtx`：只查 DB，不读写缓存
- `ExecNoCacheCtx`：只写 DB，不自动清缓存
- `TransactCtx`：事务执行

## 推荐使用规则

### 1) 主键/唯一键查询（有稳定 key）

优先使用 `QueryCtx`，必须显式构建缓存 key。

### 2) 列表/复杂筛选查询

仅当 key 规则稳定时用 `QueryCtx`；否则用 `QueryNoCacheCtx`。

### 3) 写操作（新增/更新/删除）

优先使用“统一 helper”封装为一条路径：

1. 执行 DB 写入
2. 按模型计算 key
3. 清理关联缓存

避免在业务逻辑层分散调用 `DelCache`。

## user_subscribe 规范落地

`internal/model/user/subscribe.go` 已提供统一 helper：

- `execSubscribeMutation(...)`

`InsertSubscribe / UpdateSubscribe / DeleteSubscribe / DeleteSubscribeById` 统一通过该 helper 执行，避免每个方法重复写“ExecNoCacheCtx + defer 清缓存”。

## key 生成约定

模型缓存 key 统一在模型侧定义，不在 handler/logic 手写：

- `internal/model/user/cache.go`
  - `(*Subscribe).GetCacheKeys()`
  - `ClearSubscribeCacheByModels(...)`

> 说明：`user_subscribe` 当前会同时清理普通列表 key 与 `:all` 列表 key，避免删改后列表残留旧缓存。

## 新增模型时的最小模板

1. 在 model 中定义 `getCacheKeys(...)` 或 `GetCacheKeys()`
2. 查询方法优先 `QueryCtx`
3. 写方法统一走 helper（DB 写 + 缓存失效）
4. 避免在 handler/logic 直接操作缓存 key
