docs: refine moderation and signup policy
This commit is contained in:
+4
-2
@@ -61,7 +61,7 @@
|
||||
|
||||
| ID | 任务 | 依赖 | 验收要点 | 状态 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| T-501 | 注册 / 登录(allauth) | T-201 | 自助注册(邮箱验证)、登录、登出;注册后钱包点数为 0(不送点数);session + CSRF | DONE |
|
||||
| T-501 | 注册 / 登录(allauth) | T-201 | 自助注册(**免邮箱验证、注册即可用;邮箱仍必填且唯一**)、登录、登出;注册后钱包点数为 0(不送点数);session + CSRF。**策略变更见 T-605 与 2026-07-06 决策** | DONE |
|
||||
| T-502 | API Key 自助管理页 | T-501, T-301 | 登录用户生成/删除 Key;明文只显示一次、库内只存哈希;列表只显示 prefix;删除即吊销,吊销后该 Key 调用 403(无效/不存在 Key 仍为 401) | DONE |
|
||||
| T-503 | 个人中心 / 记录页 | T-501, T-203 | 剩余点数、充值总额、充值记录、消费(调用)记录;数据与流水一致;仅见本人 | DONE |
|
||||
| T-504 | 充值页(扫码 + 轮询到账) | T-501, T-305 | 发起充值→展示二维码→轮询订单状态→到账后余额刷新;到账以回调为权威 | DONE |
|
||||
@@ -81,7 +81,9 @@
|
||||
| --- | --- | --- | --- | --- |
|
||||
| T-601 | 可用别名发现(portal 别名页 + `GET /api/v1/models`) | T-202, T-301, T-503 | 让调用方能自助发现「能填哪些 `model` 能力别名」。① 新增 `GET /api/v1/models`(**API Key 鉴权,继承 `ExternalApiView`,只复用认证失败限流;不要占用生成接口的 `GenerateRateThrottle` 额度**),仅返回 `ModelAlias.is_active=True` 且 `ai_model.is_active=True` 的可调用别名;② 响应每项只含对外安全字段:`alias`、`operation_type`、`capabilities`、`requires_image`(按 `api_type`/provider 规则推导,如 `images_edits=true`)、`pricing_status`、`prices[{resolution, points_cost}]`,缺 `PricingRule` 时标「暂未定价」而非报错;③ **实现时不得调用 `AiModel.to_resolved_model()` 或任何会解密 provider key 的路径**,列表接口不依赖 `AI_KEY_ENCRYPTION_KEY`,也不读取/输出 `api_key_encrypted`;④ **不暴露具体 SKU/模型名/url/key/provider 原始配置**,测试必须断言响应不含 `ai_model.model`、`ai_model.url`、`api_key`、`api_key_encrypted`、`extra_body` 等内部字段;⑤ portal 加只读「可用模型」页(session 鉴权),同字段、人类可读、单价以点数展示,并在导航中加入入口;⑥ 含测试:API Key 成功返回结构、缺/无效 Key 拒绝、Web session 不能调用外部 API、portal 未登录跳转、页面不泄露 SKU/URL/Key、缺定价别名显示暂未定价。**标注**:未来接 `account_alias_permission`(见 Backlog)后,本清单改为「只列该用户被授权的别名」,接口与页面均按 `user` 过滤 | DONE |
|
||||
| T-602 | django-admin 中文化(第 1-3 层) | - | 让运营后台表名/分组/框架文字显示中文,**仅显示层、不改业务逻辑与 DB 结构**。**第 1 层**:`config/settings.py` 设 `LANGUAGE_CODE='zh-hans'` + `USE_I18N=True`,使 Django 自带 admin 界面与内置 `auth`(用户/组/权限)中文化(无迁移)。**第 2 层**:各 app `AppConfig.verbose_name` 设中文分组名(`users`/`billing`/`ai`/`api`/`portal`),无迁移。**第 3 层**:各模型 `Meta.verbose_name`/`verbose_name_plural` 设中文表名(`User`/`UserWallet`/`ApiKey`/`PointsLedger`/`CallRecord`/`PricingRule`/`ExchangeRate`/`RechargeOrder`/`AiModel`/`ModelAlias`/`AiConfigAuditLog`)。**不含第 4 层字段级 `verbose_name`(字段列名保持英文,见 T-603)**。第 3 层会产出 `AlterModelOptions` 等**无 DB 变更**迁移;验收:`makemigrations`(仅 options 变更)→ `migrate` → `check` 0 issues → `test` 全绿 → `/admin/` 目视中文化,并在 `../progress.md` 留证据 | DONE |
|
||||
| T-603 | django-admin 中文化(第 4 层·字段级) | T-602 | 给各模型**字段**加中文 `verbose_name`,使 admin 列表/编辑页的字段标签显示中文,在 T-602(1-3 层)之上做。范围覆盖 `users`/`billing`/`ai`(及 portal 相关)模型的业务字段,例如 `points_balance`→点数余额、`key_prefix`→Key 前缀、`points_delta`→点数变动、`balance_after`→变动后余额、`amount_money`→金额、`exchange_rate`→汇率、`points_granted`→到账点数、`api_type`/`capabilities`/`is_active`/`created_at` 等;`admin.py` 里自定义显示方法(`@admin.display(description=...)`)同步中文。**仅显示层**:`verbose_name` 只改展示,**不改字段名、不改代码引用、英文字段名保持不变**;产出的是 `AlterField`(metadata-only,**无 DB schema 变更**)迁移。验收:`makemigrations`(仅 AlterField,无 schema 变更)→ `migrate` → `check` 0 issues → `test` 全绿 → `/admin/` 字段标签目视中文,并在 `../progress.md` 留证据。**当前阻塞**:代码与迁移已完成,完整测试被工作区既有 `config/settings.py` 中 `ACCOUNT_EMAIL_VERIFICATION="none"` 改动阻断,需恢复 `mandatory` 后重跑测试再标 `DONE` | BLOCKED |
|
||||
| T-603 | django-admin 中文化(第 4 层·字段级) | T-602 | 给各模型**字段**加中文 `verbose_name`,使 admin 列表/编辑页的字段标签显示中文,在 T-602(1-3 层)之上做。范围覆盖 `users`/`billing`/`ai`(及 portal 相关)模型的业务字段,例如 `points_balance`→点数余额、`key_prefix`→Key 前缀、`points_delta`→点数变动、`balance_after`→变动后余额、`amount_money`→金额、`exchange_rate`→汇率、`points_granted`→到账点数、`api_type`/`capabilities`/`is_active`/`created_at` 等;`admin.py` 里自定义显示方法(`@admin.display(description=...)`)同步中文。**仅显示层**:`verbose_name` 只改展示,**不改字段名、不改代码引用、英文字段名保持不变**;产出的是 `AlterField`(metadata-only,**无 DB schema 变更**)迁移。验收:`makemigrations`(仅 AlterField,无 schema 变更)→ `migrate` → `check` 0 issues → `test` 全绿 → `/admin/` 字段标签目视中文,并在 `../progress.md` 留证据。**当前阻塞**:代码与迁移已完成;`ACCOUNT_EMAIL_VERIFICATION="none"`(免邮箱验证)已定为**既定策略**(见 2026-07-06 决策),原假设 `mandatory` 的 2 条 portal 测试需**按新策略更新**(不再恢复 `mandatory`),由 **T-605** 处理;T-605 完成后本任务解封、重跑测试标 `DONE` | BLOCKED |
|
||||
| T-605 | 落实「免邮箱验证」策略 | T-501 | 把 `ACCOUNT_EMAIL_VERIFICATION="none"`(注册即可用、不发验证邮件、邮箱仍必填且唯一)作为**既定策略**清理落地:① `config/settings.py` 把 `ACCOUNT_EMAIL_VERIFICATION = "none"#"mandatory"` 改为干净的 `"none"`(去行内注释),评估 `ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION` 是否仍需要;② 更新 `apps/portal/tests.py` 里假设 mandatory 的 2 条测试(signup 不再依赖验证邮件、未验证也可直接登录),改为断言「注册后可直接登录」;③ 同步全项目文档口径(`02-requirements`/`05-coding-rules`/`api`/`04-architecture`/`03-tech-stack`/`routes`/`env`/`deployment`/`00-ai-start-here` 中「邮箱验证」→「免邮箱验证,邮箱仍唯一」);④(可选)注册防刷改用图形验证码/限流补位。验收:`check`/`test` 全绿(含更新后的注册测试)并在 `../progress.md` 留证据;**完成后解封 T-603** | TODO |
|
||||
| T-604 | 中文敏感词本地过滤(本地 keyword provider) | T-302, T-401 | 按 [`moderation.md`](moderation.md) 实施。**范围收紧**:T-604 只做输入 prompt 的本地敏感词快筛,不做云内容安全、不做输出审核、不做图片审核。**关键时序**:serializer 后先审 prompt,命中即 `400 content_blocked`;不得先下载 `image_url`,不得预扣点,不写 `CallRecord` / `PointsLedger`,不调上游。**核心实现**:新增 `apps.moderation`、`SensitiveWord` 模型/admin/迁移、keyword provider、归一化管线、Aho-Corasick matcher;`ahocorapy` 作为候选依赖,编码前必须验证 PyPI 可用性和 API 形状。**缓存**:matcher 进程内缓存,词库变更用共享 cache 版本号失效,不能只靠 `post_save` signal;生产依赖共享 cache。**配置**:`MODERATION_ENABLED=false` 默认 no-op;启用时 `MODERATION_PROVIDER=keyword`;MVP `SensitiveWord.action` 只支持 `block`。**验收**:`check`/`test` 全绿,覆盖 no-op、命中拦截且不扣点/不建记录/不调上游/不下载图片、归一化防绕过、词库变更后 matcher 重建;真实词库数据不进仓库,`__pycache__` 不进 Git | TODO |
|
||||
|
||||
## 里程碑
|
||||
|
||||
|
||||
Reference in New Issue
Block a user