docs(qy_lty): 启动 Milestone v1.0 通用凭据槽位
PROJECT.md 加入「本期 Milestone」段:全局单例 APP ID + Access Token 凭据存储, 管理端读写 + 客户端读取 + 日志脱敏;前端联动 milestone 在 qy-lty-admin 另起。 STATE.md 切换到 v1.0 状态:当前位置 = 需求定义中(roadmap 待生成)。
This commit is contained in:
parent
3e8a212e9f
commit
ab3d728a08
@ -1,16 +1,33 @@
|
|||||||
# QY LTY Backend(洛天依统一后端服务)
|
# QY LTY Backend(洛天依统一后端服务)
|
||||||
|
|
||||||
## What This Is
|
## 项目简介
|
||||||
|
|
||||||
QY LTY Backend 是「洛天依(Luotianyi)智能陪伴产品」生态的统一 Django 后端,同时服务于 **3 个客户端**:Unity 设备端(`LTY_Project`)、Unity 移动 App(`LTY_App_Project_URP`)、Web 管理后台(`qy-lty-admin`)。提供用户认证、AI 对话(含语音)、设备实时通信(WebSocket + RTC)、卡片/二维码、成就、订阅等综合能力。
|
QY LTY Backend 是「洛天依(Luotianyi)智能陪伴产品」生态的统一 Django 后端,同时服务于 **3 个客户端**:Unity 设备端(`LTY_Project`)、Unity 移动 App(`LTY_App_Project_URP`)、Web 管理后台(`qy-lty-admin`)。提供用户认证、AI 对话(含语音)、设备实时通信(WebSocket + RTC)、卡片/二维码、成就、订阅等综合能力。
|
||||||
|
|
||||||
## Core Value
|
## 核心价值
|
||||||
|
|
||||||
**设备端与手机端通过同一个用户身份实时互通**——`device_{user_id}` 分组模型必须始终成立。一旦绑定/控制权解析、WebSocket 路由、RTC 房间号三者偏离同一 user_id,整个产品的"陪伴"价值就坍塌了。其他能力(卡片、成就、订阅)可以暂时降级,这条不行。
|
**设备端与手机端通过同一个用户身份实时互通**——`device_{user_id}` 分组模型必须始终成立。一旦绑定/控制权解析、WebSocket 路由、RTC 房间号三者偏离同一 user_id,整个产品的"陪伴"价值就坍塌了。其他能力(卡片、成就、订阅)可以暂时降级,这条不行。
|
||||||
|
|
||||||
## Requirements
|
## 本期 Milestone:v1.0 通用凭据槽位(APP ID + Access Token)
|
||||||
|
|
||||||
### Validated
|
**启动日期**:2026-05-07
|
||||||
|
**目标**:在后端提供一组全局单例的通用凭据存储槽位(APP ID + Access Token),管理后台可写入,手机端 + 设备端可读取。不绑定特定服务商,运营自由填值;前端联动 milestone 在 `qy-lty-admin` 仓库另行启动。
|
||||||
|
|
||||||
|
**目标能力**:
|
||||||
|
- 后端单例配置模型(保存 APP ID + Access Token,强制全局唯一记录)
|
||||||
|
- 管理端读写接口(admin token 鉴权,`/api/v1/admin/` 命名空间,GET 时 Access Token 脱敏)
|
||||||
|
- 客户端读取接口(user token 鉴权,复用 `RedisTokenAuthentication`,明文返回供 LTY_App_Project_URP / LTY_Project 实际调用第三方服务)
|
||||||
|
- 敏感字段脱敏(响应壳层 + 阿里云日志),避免 Access Token 落入生产日志
|
||||||
|
|
||||||
|
**关键约束**:
|
||||||
|
- 客户端实际使用 Access Token 调用第三方服务,所以**客户端 GET 接口必须返回明文**;只有管理端 GET 与日志做脱敏
|
||||||
|
- 单例语义:DB 中保证最多一条记录(建议 `pk=1` 固定主键 + `get_or_create` 模式,或单字段唯一约束)
|
||||||
|
- 与现有 `StandardResponseMiddleware` 响应壳层兼容(`{ success, code, message, data }`)
|
||||||
|
- 不引入新的鉴权体系:管理端走 `admin_token:{token}`,客户端走 `token:{token}`,与现有所有接口对齐
|
||||||
|
|
||||||
|
## 需求清单
|
||||||
|
|
||||||
|
### 已交付
|
||||||
|
|
||||||
<!-- 已交付且在生产链路上跑通的能力,从 .planning/codebase/ 推断 -->
|
<!-- 已交付且在生产链路上跑通的能力,从 .planning/codebase/ 推断 -->
|
||||||
|
|
||||||
@ -76,13 +93,20 @@ QY LTY Backend 是「洛天依(Luotianyi)智能陪伴产品」生态的统
|
|||||||
- ✓ **DEP-03** PostgreSQL(主库)+ Redis(缓存 + Channel Layer)— existing
|
- ✓ **DEP-03** PostgreSQL(主库)+ Redis(缓存 + Channel Layer)— existing
|
||||||
- ✓ **DEP-04** i18n 双语(zh_HAns / en)via django-rosetta — existing
|
- ✓ **DEP-04** i18n 双语(zh_HAns / en)via django-rosetta — existing
|
||||||
|
|
||||||
### Active
|
### 进行中
|
||||||
|
|
||||||
<!-- 当前正在建设的目标。GSD 通过 phase 推动这一段;移到 Validated 才算完成 -->
|
<!-- 当前正在建设的目标。GSD 通过 phase 推动这一段;移到 Validated 才算完成 -->
|
||||||
|
|
||||||
(暂无 — 本次 `/gsd-new-project` 仅做 brownfield 文档化。下次新增功能 / 子系统时使用 `/gsd-new-milestone` 启动新 milestone,把当时要交付的能力加到这一段,然后 `/gsd-plan-phase` 拆 phase。)
|
**Milestone v1.0 通用凭据槽位**(启动 2026-05-07):
|
||||||
|
|
||||||
### Out of Scope
|
- [ ] **CRED-01** 单例 `CredentialSlot` 模型 + 迁移(强制 DB 中最多一条)
|
||||||
|
- [ ] **CRED-02** Django Admin 注册(`Access Token` 字段写入态可见,列表/查看态脱敏)
|
||||||
|
- [ ] **CRED-03** 管理端 GET `/api/v1/admin/credential-slot/`(admin token 鉴权,Access Token 字段脱敏掩码返回)
|
||||||
|
- [ ] **CRED-04** 管理端 PUT `/api/v1/admin/credential-slot/`(admin token 鉴权,全字段覆写更新)
|
||||||
|
- [ ] **CRED-05** 客户端 GET `/api/credential-slot/`(user token 鉴权 via `RedisTokenAuthentication`,明文返回 APP ID + Access Token)
|
||||||
|
- [ ] **CRED-06** Access Token 在阿里云日志中过滤(日志格式化器 / 中间件层避免 secret 落生产日志)
|
||||||
|
|
||||||
|
### 范围外
|
||||||
|
|
||||||
<!-- 明确排除项 + 理由。防止后续被无意识地拉回来 -->
|
<!-- 明确排除项 + 理由。防止后续被无意识地拉回来 -->
|
||||||
|
|
||||||
@ -93,7 +117,7 @@ QY LTY Backend 是「洛天依(Luotianyi)智能陪伴产品」生态的统
|
|||||||
- **多 Redis 实例 / Sentinel 集群** — 当前是单 Redis,CONCERNS.md 标记为 HA 风险,但不在本次范畴内;待性能/可用性 milestone 决议。
|
- **多 Redis 实例 / Sentinel 集群** — 当前是单 Redis,CONCERNS.md 标记为 HA 风险,但不在本次范畴内;待性能/可用性 milestone 决议。
|
||||||
- **真正意义的测试套件** — 当前 ≈10 个 test 文件中只有 1 个真正在测,无 mock 基础设施。这是 CONCERNS.md 标的 HIGH-severity 工程债,但需要独立 milestone 系统性修。
|
- **真正意义的测试套件** — 当前 ≈10 个 test 文件中只有 1 个真正在测,无 mock 基础设施。这是 CONCERNS.md 标的 HIGH-severity 工程债,但需要独立 milestone 系统性修。
|
||||||
|
|
||||||
## Context
|
## 背景上下文
|
||||||
|
|
||||||
**生态位**:本服务是「设备—App—管理端」三角的中心节点,对所有客户端来说**它是唯一的真理来源**。
|
**生态位**:本服务是「设备—App—管理端」三角的中心节点,对所有客户端来说**它是唯一的真理来源**。
|
||||||
|
|
||||||
@ -117,24 +141,24 @@ QY LTY Backend 是「洛天依(Luotianyi)智能陪伴产品」生态的统
|
|||||||
- `requirements.txt` 不锁版本(无 lockfile)—— 部署一致性靠 Docker 镜像保证
|
- `requirements.txt` 不锁版本(无 lockfile)—— 部署一致性靠 Docker 镜像保证
|
||||||
- Python 3.8 已 EOL(2024-10),需要规划升级
|
- Python 3.8 已 EOL(2024-10),需要规划升级
|
||||||
|
|
||||||
## Constraints
|
## 约束
|
||||||
|
|
||||||
- **Tech stack**: Django 4.2.13 + DRF + Channels + Daphne — 已锁定,迁移成本极高
|
- **技术栈**:Django 4.2.13 + DRF + Channels + Daphne — 已锁定,迁移成本极高
|
||||||
- **Tech stack**: Python 3.8(EOL)— 当前限制,但近期需升级
|
- **技术栈**:Python 3.8(EOL)— 当前限制,但近期需升级
|
||||||
- **Tech stack**: PostgreSQL(主)+ Redis(缓存 + Channel Layer)— 不可替换
|
- **技术栈**:PostgreSQL(主)+ Redis(缓存 + Channel Layer)— 不可替换
|
||||||
- **Tech stack**: ASGI 必须,因为 WebSocket 是核心 — WSGI 路径 (`wsgi.py`) 仅作历史保留
|
- **技术栈**:ASGI 必须,因为 WebSocket 是核心 — WSGI 路径 (`wsgi.py`) 仅作历史保留
|
||||||
- **Compatibility**: WebSocket 消息协议(11 种 message type)被 2 个 Unity 客户端依赖 — 任何新增字段必须向前兼容,删除字段需协调 3 方排期
|
- **兼容性**:WebSocket 消息协议(11 种 message type)被 2 个 Unity 客户端依赖 — 任何新增字段必须向前兼容,删除字段需协调 3 方排期
|
||||||
- **Compatibility**: REST API 响应包装格式(`StandardResponseMiddleware` 输出的 `{success, code, message, data}`)被 `qy-lty-admin` 依赖 — 整体结构不可改
|
- **兼容性**:REST API 响应包装格式(`StandardResponseMiddleware` 输出的 `{success, code, message, data}`)被 `qy-lty-admin` 依赖 — 整体结构不可改
|
||||||
- **Compatibility**: `device_{user_id}` 分组命名 + `room_{user_id}` 房间命名是端到端的隐式契约 — 改名要同步 Unity / Volcengine RTC 配置
|
- **兼容性**:`device_{user_id}` 分组命名 + `room_{user_id}` 房间命名是端到端的隐式契约 — 改名要同步 Unity / Volcengine RTC 配置
|
||||||
- **Documentation**: 每次代码改动**必须**追加到 `docs/修改记录.md` 顶部(CLAUDE.md 强制规则,结构性文档变更同样适用)
|
- **文档规范**:每次代码改动**必须**追加到 `docs/修改记录.md` 顶部(CLAUDE.md 强制规则,结构性文档变更同样适用)
|
||||||
- **Communication**: 与用户沟通使用中文(CLAUDE.md「沟通语言」章节强制)
|
- **沟通语言**:与用户沟通使用中文(CLAUDE.md「沟通语言」章节强制)
|
||||||
- **Independence**: `qy_lty` 与 `qy-lty-admin` 独立维护,**修改记录、planning 工件不混合**
|
- **项目独立**:`qy_lty` 与 `qy-lty-admin` 独立维护,**修改记录、planning 工件不混合**
|
||||||
- **Security**: `.env` 不入库,所有 SDK secret 必须通过环境变量加载(CONCERNS.md 已标 SECRET_KEY / DEBUG / CORS 多处需收紧)
|
- **安全**:`.env` 不入库,所有 SDK secret 必须通过环境变量加载(CONCERNS.md 已标 SECRET_KEY / DEBUG / CORS 多处需收紧)
|
||||||
|
|
||||||
## Key Decisions
|
## 关键决策
|
||||||
|
|
||||||
| Decision | Rationale | Outcome |
|
| 决策 | 理由 | 结果 |
|
||||||
|----------|-----------|---------|
|
|------|------|------|
|
||||||
| WebSocket 分组用 `device_{user_id}`(不是 `device_{mac}`) | 让"同一用户"的多个端点(手机 + 设备)天然共享同一通信空间;同时一个设备同一时刻只能被最新绑定的用户控制,符合"陪伴"产品语义 | ✓ Good — 已支撑生产 |
|
| WebSocket 分组用 `device_{user_id}`(不是 `device_{mac}`) | 让"同一用户"的多个端点(手机 + 设备)天然共享同一通信空间;同时一个设备同一时刻只能被最新绑定的用户控制,符合"陪伴"产品语义 | ✓ Good — 已支撑生产 |
|
||||||
| `UserDevice.Meta.ordering = ['-bound_at']` 隐式驱动控制权解析 | 实现"后绑挤先绑"语义无需显式状态机,依赖 ORM 默认排序 | ⚠️ Revisit — 语义正确但隐式,新人容易误删旧记录或绕过 ordering 直接 query;建议改写为显式 `current_owner` 字段 |
|
| `UserDevice.Meta.ordering = ['-bound_at']` 隐式驱动控制权解析 | 实现"后绑挤先绑"语义无需显式状态机,依赖 ORM 默认排序 | ⚠️ Revisit — 语义正确但隐式,新人容易误删旧记录或绕过 ordering 直接 query;建议改写为显式 `current_owner` 字段 |
|
||||||
| 30 天 token TTL(Redis 后端) | 设备 + 手机端长期在线,短 TTL 体验差 | ✓ Good — 与产品形态匹配 |
|
| 30 天 token TTL(Redis 后端) | 设备 + 手机端长期在线,短 TTL 体验差 | ✓ Good — 与产品形态匹配 |
|
||||||
@ -144,22 +168,22 @@ QY LTY Backend 是「洛天依(Luotianyi)智能陪伴产品」生态的统
|
|||||||
| 测试 MAC `AA:BB:CC:DD:EE:FF` 硬编码绕过绑定校验 | 早期开发便利 | ⚠️ Revisit — CONCERNS.md 标 HIGH,上规模前必须替换为环境变量开关 |
|
| 测试 MAC `AA:BB:CC:DD:EE:FF` 硬编码绕过绑定校验 | 早期开发便利 | ⚠️ Revisit — CONCERNS.md 标 HIGH,上规模前必须替换为环境变量开关 |
|
||||||
| `.planning/` 锚定在 `qy_lty\`(不是 `Lila-Server\`) | `qy_lty` 与 `qy-lty-admin` 是独立项目,CLAUDE.md 规定各自维护 | ✓ Good — 2026-05-07 通过预创建空目录强制锚定生效 |
|
| `.planning/` 锚定在 `qy_lty\`(不是 `Lila-Server\`) | `qy_lty` 与 `qy-lty-admin` 是独立项目,CLAUDE.md 规定各自维护 | ✓ Good — 2026-05-07 通过预创建空目录强制锚定生效 |
|
||||||
|
|
||||||
## Evolution
|
## 演进规则
|
||||||
|
|
||||||
This document evolves at phase transitions and milestone boundaries.
|
本文档在 phase 切换与 milestone 边界处更新。
|
||||||
|
|
||||||
**After each phase transition** (via `/gsd-transition`):
|
**每次 phase 切换后**(通过 `/gsd-transition`):
|
||||||
1. Requirements invalidated? → Move to Out of Scope with reason
|
1. 需求被推翻?→ 移到「范围外」并说明理由
|
||||||
2. Requirements validated? → Move to Validated with phase reference
|
2. 需求已交付?→ 移到「已交付」并标注 phase 引用
|
||||||
3. New requirements emerged? → Add to Active
|
3. 出现新需求?→ 加到「进行中」
|
||||||
4. Decisions to log? → Add to Key Decisions
|
4. 有决策需要记录?→ 加到「关键决策」
|
||||||
5. "What This Is" still accurate? → Update if drifted
|
5. 「项目简介」是否仍然准确?→ 如有偏移则更新
|
||||||
|
|
||||||
**After each milestone** (via `/gsd-complete-milestone`):
|
**每个 milestone 完成后**(通过 `/gsd-complete-milestone`):
|
||||||
1. Full review of all sections
|
1. 全面回顾所有章节
|
||||||
2. Core Value check — still the right priority?
|
2. 复核「核心价值」—— 是否仍是当前最高优先级?
|
||||||
3. Audit Out of Scope — reasons still valid?
|
3. 审视「范围外」—— 排除理由是否仍然成立?
|
||||||
4. Update Context with current state
|
4. 用当前状态更新「背景上下文」
|
||||||
|
|
||||||
---
|
---
|
||||||
*Last updated: 2026-05-07 after brownfield documentation initialization (existing system mapped, no Active milestone yet — use /gsd-new-milestone to start the next cycle)*
|
*最后更新:2026-05-07,启动 Milestone v1.0「通用凭据槽位(APP ID + Access Token)」*
|
||||||
|
|||||||
@ -1,27 +1,36 @@
|
|||||||
# Project State — QY LTY Backend
|
# Project State — QY LTY Backend
|
||||||
|
|
||||||
**最后更新**: 2026-05-07(brownfield 文档化初始化)
|
**最后更新**: 2026-05-07(启动 Milestone v1.0 通用凭据槽位)
|
||||||
|
|
||||||
## Project Reference
|
## 项目引用
|
||||||
|
|
||||||
See: `.planning/PROJECT.md` (updated 2026-05-07)
|
参见:`.planning/PROJECT.md`(更新于 2026-05-07)
|
||||||
|
|
||||||
**Core value**: 设备端与手机端通过同一个 user_id 实时互通——`device_{user_id}` 分组语义必须始终成立。
|
**核心价值**:设备端与手机端通过同一个 user_id 实时互通——`device_{user_id}` 分组语义必须始终成立。
|
||||||
|
|
||||||
**Current focus**: 暂无 Active milestone — 待 `/gsd-new-milestone` 启动下一周期
|
**当前重点**:Milestone v1.0 通用凭据槽位(APP ID + Access Token)— 后端存储 + 管理端读写 + 客户端读取 + 脱敏
|
||||||
|
|
||||||
## Status
|
## 当前位置
|
||||||
|
|
||||||
|
```
|
||||||
|
Phase: 未启动(定义需求中)
|
||||||
|
Plan: —
|
||||||
|
Status: 需求定义中(roadmap 待生成)
|
||||||
|
Last activity: 2026-05-07 — 启动 Milestone v1.0
|
||||||
|
```
|
||||||
|
|
||||||
|
## 状态
|
||||||
|
|
||||||
| 项目 | 状态 |
|
| 项目 | 状态 |
|
||||||
|------|------|
|
|------|------|
|
||||||
| Codebase mapped | ✅ `.planning/codebase/` 7 文档(commit `64a8cb8`) |
|
| 代码库映射 | ✅ `.planning/codebase/` 7 文档(commit `64a8cb8`) |
|
||||||
| PROJECT.md | ✅ Validated 已从 codebase 推断填充,Active 段空 |
|
| PROJECT.md | ✅ 已加入 Milestone v1.0 段 + Active 6 项 |
|
||||||
| REQUIREMENTS.md | ✅ Validated 已拆 REQ-ID,Active 段空,Traceability 待 phase 回填 |
|
| REQUIREMENTS.md | 🟡 Active 段待回填(CRED-01~06),可追溯性待 phase 回填 |
|
||||||
| Roadmap | ⏸️ 暂未生成(无 Active 需求 → 无 phase 可分) |
|
| 路线图 | ⏸️ 待 gsd-roadmapper 生成 |
|
||||||
| Active phase | — |
|
| 当前 phase | — |
|
||||||
| Active milestone | — |
|
| 当前 milestone | v1.0 通用凭据槽位 |
|
||||||
|
|
||||||
## Next Action
|
## 下一步
|
||||||
|
|
||||||
**当你准备开始下一个开发周期**:
|
**当你准备开始下一个开发周期**:
|
||||||
|
|
||||||
@ -36,24 +45,24 @@ GSD 会:
|
|||||||
|
|
||||||
**候选优先级排序见 `REQUIREMENTS.md → Active → 候选优先级` 段**。
|
**候选优先级排序见 `REQUIREMENTS.md → Active → 候选优先级` 段**。
|
||||||
|
|
||||||
## Workflow Config
|
## 工作流配置
|
||||||
|
|
||||||
详见 `.planning/config.json`:
|
详见 `.planning/config.json`:
|
||||||
|
|
||||||
- Mode: **YOLO**(自动通过审批,直接执行)
|
- 模式:**YOLO**(自动通过审批,直接执行)
|
||||||
- Granularity: **Coarse**(每个 milestone 拆 3-5 phase)
|
- 粒度:**Coarse**(每个 milestone 拆 3-5 phase)
|
||||||
- Parallelization: **enabled**
|
- 并行化:**已启用**
|
||||||
- Workflow agents: research / plan_check / verifier 全部启用
|
- 工作流 agent:research / plan_check / verifier 全部启用
|
||||||
- Model profile: **balanced**(Sonnet 主力)
|
- 模型档位:**balanced**(Sonnet 主力)
|
||||||
- `.planning/` commits to git: **yes**
|
- `.planning/` 提交到 git:**是**
|
||||||
|
|
||||||
随时可用 `/gsd-settings` 调整。
|
随时可用 `/gsd-settings` 调整。
|
||||||
|
|
||||||
## Important Anchoring Note
|
## 锚定路径重要说明
|
||||||
|
|
||||||
`.planning/` 必须保持在 `c:\Users\admin\Desktop\Lila-Server\qy_lty\` 这一层(**不是父级 `Lila-Server\`**)。父级 `.git` 容易让 GSD CLI 误把 `Lila-Server` 当作 project_root;本目录的存在就是锚定信号,不要删。
|
`.planning/` 必须保持在 `c:\Users\admin\Desktop\Lila-Server\qy_lty\` 这一层(**不是父级 `Lila-Server\`**)。父级 `.git` 容易让 GSD CLI 误把 `Lila-Server` 当作 project_root;本目录的存在就是锚定信号,不要删。
|
||||||
|
|
||||||
## Project Rules Reminder
|
## 项目规则提醒
|
||||||
|
|
||||||
CLAUDE.md 中两条强制规则,做任何 phase 时必须遵守:
|
CLAUDE.md 中两条强制规则,做任何 phase 时必须遵守:
|
||||||
|
|
||||||
@ -64,4 +73,4 @@ CLAUDE.md 中两条强制规则,做任何 phase 时必须遵守:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*Generated by /gsd-new-project (brownfield doc pass) on 2026-05-07*
|
*由 /gsd-new-project(brownfield 文档化)生成于 2026-05-07*
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user