Files
marco 4ee6de2548 feat(cps): 活动支持编辑(PATCH /activities/{id})
- CpsActivityUpdate schema + repo update_activity(部分更新,非 None 覆盖)
- router 按「合并后最终值」校验平台必填项(同新建口径),写审计 cps.activity.update
- 可改名/平台/对应字段/落地页图/备注/状态

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 22:13:35 +08:00

32 lines
3.0 KiB
Markdown

# app_config — 运营可配置项(覆盖 rewards 常量)
> 模型 `app/models/app_config.py` · 仓库 `app/repositories/app_config.py` · 注册表 `app/core/config_schema.py` · 接口 admin [admin-stats-overview](../api/admin-stats-overview.md) 同组的配置页(`app/admin/routers/config.py`) · [← 索引](./README.md) · [总览](./OVERVIEW.md)
把原本硬编码在 `core/rewards.py` 的**产品规则常量**(签到档位、任务奖励、提现额度、看广告金币/上限/冷却等)挪到 DB,运营后台可改、跨进程即时生效。`key` 主键,`value` 用 JSON 存任意值(int / list / dict)。
> **核心约定**:表里**没有**的 key,业务读配置时 fallback 到 `config_schema.CONFIG_DEFS` 的默认值(= 原 rewards 常量)。所以**空表 = 现有行为完全不变**;admin 改某项 = 写一行 → 业务下次 `get_value` 读到新值。
## 用在哪 / 增删改查
- **C / U(upsert)**:admin 配置页改某项 `set_value(key, value, admin_id)`:无该 key 行→插,有→更新 `value`+`updated_by_admin_id`(同事务写 `admin_audit_log`,`action='config.set'`)。未知 key(不在 CONFIG_DEFS)抛 KeyError。
- **D**:无(要恢复默认 = 删行即可回退到 CONFIG_DEFS,但当前无删除接口;改回默认值亦可)。
- **R**:**业务侧**——`rewards.get_*(db)` 一族(`get_signin_rewards` / `get_withdraw_min_cents` / `get_ad_reward_coin` …)经 `get_value` 读,签到/任务/提现/看广告发奖处用;**admin 侧**——`list_all` 列出所有可配项(default + 当前值 + 元信息)给配置页渲染。
## 字段
| 列 | 类型 | 约束 / 默认 | 说明(取值 / join) |
|---|---|---|---|
| `key` | String(64) | **PK** | 配置标识,取值见 `config_schema.CONFIG_DEFS`:`signin_rewards` / `min_exchange_coin` / `withdraw_min_cents` / `withdraw_max_cents` / `task_rewards` / `record_milestones` / `ad_reward_coin` / `ad_daily_limit` / `ad_max_coin` / `ad_round_count` / `ad_cooldown_sec` / `signin_boost_coin` / `withdraw_auto_reconcile_enabled` / `comparing_ad_enabled` |
| `value` | JSON(PG: JSONB) | NOT NULL | 配置值,类型随 key(`int` / `int_list` 如签到 14 档 / `dict_str_int` 如 task_rewards / `bool` 如 withdraw_auto_reconcile_enabled / comparing_ad_enabled) |
| `updated_by_admin_id` | Integer | nullable | 最后修改的管理员 id(= `admin_user.id`,软引用,无 FK) |
| `updated_at` | DateTime(tz) | server_default now(), onupdate now() | 最后修改时间 |
## 关系 / Join Key
- 无外键。`updated_by_admin_id` 软指向 `admin_user.id`(仅记录谁改的)。
- 逻辑上"覆盖"`core/rewards.py` 的常量:每个 key 的默认值/类型/分组/说明在 `config_schema.CONFIG_DEFS` 定义(配置项的 single source of truth)。
## 索引与约束
- PK `key`(无自增 id)。
## 注意
- 不缓存:配置读频率低(每次福利操作读一次,主键查极快),admin 改了立即生效、跨进程一致(多 worker 也对)。
- 新增可配项 = 在 `CONFIG_DEFS` 加一条 + 业务处改用 `app_config.get_value(db, key)` 读;不需要建迁移(行是动态插的,表结构不变)。