From ab3d728a08a9aa1cb2aef5aeb71c83fe55d40cfa Mon Sep 17 00:00:00 2001 From: pmc <740076875@qq.com> Date: Thu, 7 May 2026 16:29:10 +0800 Subject: [PATCH] =?UTF-8?q?docs(qy=5Flty):=20=E5=90=AF=E5=8A=A8=20Mileston?= =?UTF-8?q?e=20v1.0=20=E9=80=9A=E7=94=A8=E5=87=AD=E6=8D=AE=E6=A7=BD?= =?UTF-8?q?=E4=BD=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PROJECT.md 加入「本期 Milestone」段:全局单例 APP ID + Access Token 凭据存储, 管理端读写 + 客户端读取 + 日志脱敏;前端联动 milestone 在 qy-lty-admin 另起。 STATE.md 切换到 v1.0 状态:当前位置 = 需求定义中(roadmap 待生成)。 --- qy_lty/.planning/PROJECT.md | 98 +++++++++++++++++++++++-------------- qy_lty/.planning/STATE.md | 55 ++++++++++++--------- 2 files changed, 93 insertions(+), 60 deletions(-) diff --git a/qy_lty/.planning/PROJECT.md b/qy_lty/.planning/PROJECT.md index cf63de9..5263664 100644 --- a/qy_lty/.planning/PROJECT.md +++ b/qy_lty/.planning/PROJECT.md @@ -1,16 +1,33 @@ # 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)、卡片/二维码、成就、订阅等综合能力。 -## Core Value +## 核心价值 **设备端与手机端通过同一个用户身份实时互通**——`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}`,与现有所有接口对齐 + +## 需求清单 + +### 已交付 @@ -76,13 +93,20 @@ QY LTY Backend 是「洛天依(Luotianyi)智能陪伴产品」生态的统 - ✓ **DEP-03** PostgreSQL(主库)+ Redis(缓存 + Channel Layer)— existing - ✓ **DEP-04** i18n 双语(zh_HAns / en)via django-rosetta — existing -### Active +### 进行中 -(暂无 — 本次 `/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 决议。 - **真正意义的测试套件** — 当前 ≈10 个 test 文件中只有 1 个真正在测,无 mock 基础设施。这是 CONCERNS.md 标的 HIGH-severity 工程债,但需要独立 milestone 系统性修。 -## Context +## 背景上下文 **生态位**:本服务是「设备—App—管理端」三角的中心节点,对所有客户端来说**它是唯一的真理来源**。 @@ -117,24 +141,24 @@ QY LTY Backend 是「洛天依(Luotianyi)智能陪伴产品」生态的统 - `requirements.txt` 不锁版本(无 lockfile)—— 部署一致性靠 Docker 镜像保证 - Python 3.8 已 EOL(2024-10),需要规划升级 -## Constraints +## 约束 -- **Tech stack**: Django 4.2.13 + DRF + Channels + Daphne — 已锁定,迁移成本极高 -- **Tech stack**: Python 3.8(EOL)— 当前限制,但近期需升级 -- **Tech stack**: PostgreSQL(主)+ Redis(缓存 + Channel Layer)— 不可替换 -- **Tech stack**: ASGI 必须,因为 WebSocket 是核心 — WSGI 路径 (`wsgi.py`) 仅作历史保留 -- **Compatibility**: WebSocket 消息协议(11 种 message type)被 2 个 Unity 客户端依赖 — 任何新增字段必须向前兼容,删除字段需协调 3 方排期 -- **Compatibility**: REST API 响应包装格式(`StandardResponseMiddleware` 输出的 `{success, code, message, data}`)被 `qy-lty-admin` 依赖 — 整体结构不可改 -- **Compatibility**: `device_{user_id}` 分组命名 + `room_{user_id}` 房间命名是端到端的隐式契约 — 改名要同步 Unity / Volcengine RTC 配置 -- **Documentation**: 每次代码改动**必须**追加到 `docs/修改记录.md` 顶部(CLAUDE.md 强制规则,结构性文档变更同样适用) -- **Communication**: 与用户沟通使用中文(CLAUDE.md「沟通语言」章节强制) -- **Independence**: `qy_lty` 与 `qy-lty-admin` 独立维护,**修改记录、planning 工件不混合** -- **Security**: `.env` 不入库,所有 SDK secret 必须通过环境变量加载(CONCERNS.md 已标 SECRET_KEY / DEBUG / CORS 多处需收紧) +- **技术栈**:Django 4.2.13 + DRF + Channels + Daphne — 已锁定,迁移成本极高 +- **技术栈**:Python 3.8(EOL)— 当前限制,但近期需升级 +- **技术栈**:PostgreSQL(主)+ Redis(缓存 + Channel Layer)— 不可替换 +- **技术栈**:ASGI 必须,因为 WebSocket 是核心 — WSGI 路径 (`wsgi.py`) 仅作历史保留 +- **兼容性**:WebSocket 消息协议(11 种 message type)被 2 个 Unity 客户端依赖 — 任何新增字段必须向前兼容,删除字段需协调 3 方排期 +- **兼容性**:REST API 响应包装格式(`StandardResponseMiddleware` 输出的 `{success, code, message, data}`)被 `qy-lty-admin` 依赖 — 整体结构不可改 +- **兼容性**:`device_{user_id}` 分组命名 + `room_{user_id}` 房间命名是端到端的隐式契约 — 改名要同步 Unity / Volcengine RTC 配置 +- **文档规范**:每次代码改动**必须**追加到 `docs/修改记录.md` 顶部(CLAUDE.md 强制规则,结构性文档变更同样适用) +- **沟通语言**:与用户沟通使用中文(CLAUDE.md「沟通语言」章节强制) +- **项目独立**:`qy_lty` 与 `qy-lty-admin` 独立维护,**修改记录、planning 工件不混合** +- **安全**:`.env` 不入库,所有 SDK secret 必须通过环境变量加载(CONCERNS.md 已标 SECRET_KEY / DEBUG / CORS 多处需收紧) -## Key Decisions +## 关键决策 -| Decision | Rationale | Outcome | -|----------|-----------|---------| +| 决策 | 理由 | 结果 | +|------|------|------| | WebSocket 分组用 `device_{user_id}`(不是 `device_{mac}`) | 让"同一用户"的多个端点(手机 + 设备)天然共享同一通信空间;同时一个设备同一时刻只能被最新绑定的用户控制,符合"陪伴"产品语义 | ✓ Good — 已支撑生产 | | `UserDevice.Meta.ordering = ['-bound_at']` 隐式驱动控制权解析 | 实现"后绑挤先绑"语义无需显式状态机,依赖 ORM 默认排序 | ⚠️ Revisit — 语义正确但隐式,新人容易误删旧记录或绕过 ordering 直接 query;建议改写为显式 `current_owner` 字段 | | 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,上规模前必须替换为环境变量开关 | | `.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`): -1. Requirements invalidated? → Move to Out of Scope with reason -2. Requirements validated? → Move to Validated with phase reference -3. New requirements emerged? → Add to Active -4. Decisions to log? → Add to Key Decisions -5. "What This Is" still accurate? → Update if drifted +**每次 phase 切换后**(通过 `/gsd-transition`): +1. 需求被推翻?→ 移到「范围外」并说明理由 +2. 需求已交付?→ 移到「已交付」并标注 phase 引用 +3. 出现新需求?→ 加到「进行中」 +4. 有决策需要记录?→ 加到「关键决策」 +5. 「项目简介」是否仍然准确?→ 如有偏移则更新 -**After each milestone** (via `/gsd-complete-milestone`): -1. Full review of all sections -2. Core Value check — still the right priority? -3. Audit Out of Scope — reasons still valid? -4. Update Context with current state +**每个 milestone 完成后**(通过 `/gsd-complete-milestone`): +1. 全面回顾所有章节 +2. 复核「核心价值」—— 是否仍是当前最高优先级? +3. 审视「范围外」—— 排除理由是否仍然成立? +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)」* diff --git a/qy_lty/.planning/STATE.md b/qy_lty/.planning/STATE.md index b88f46c..741542a 100644 --- a/qy_lty/.planning/STATE.md +++ b/qy_lty/.planning/STATE.md @@ -1,27 +1,36 @@ # 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`) | -| PROJECT.md | ✅ Validated 已从 codebase 推断填充,Active 段空 | -| REQUIREMENTS.md | ✅ Validated 已拆 REQ-ID,Active 段空,Traceability 待 phase 回填 | -| Roadmap | ⏸️ 暂未生成(无 Active 需求 → 无 phase 可分) | -| Active phase | — | -| Active milestone | — | +| 代码库映射 | ✅ `.planning/codebase/` 7 文档(commit `64a8cb8`) | +| PROJECT.md | ✅ 已加入 Milestone v1.0 段 + Active 6 项 | +| REQUIREMENTS.md | 🟡 Active 段待回填(CRED-01~06),可追溯性待 phase 回填 | +| 路线图 | ⏸️ 待 gsd-roadmapper 生成 | +| 当前 phase | — | +| 当前 milestone | v1.0 通用凭据槽位 | -## Next Action +## 下一步 **当你准备开始下一个开发周期**: @@ -36,24 +45,24 @@ GSD 会: **候选优先级排序见 `REQUIREMENTS.md → Active → 候选优先级` 段**。 -## Workflow Config +## 工作流配置 详见 `.planning/config.json`: -- Mode: **YOLO**(自动通过审批,直接执行) -- Granularity: **Coarse**(每个 milestone 拆 3-5 phase) -- Parallelization: **enabled** -- Workflow agents: research / plan_check / verifier 全部启用 -- Model profile: **balanced**(Sonnet 主力) -- `.planning/` commits to git: **yes** +- 模式:**YOLO**(自动通过审批,直接执行) +- 粒度:**Coarse**(每个 milestone 拆 3-5 phase) +- 并行化:**已启用** +- 工作流 agent:research / plan_check / verifier 全部启用 +- 模型档位:**balanced**(Sonnet 主力) +- `.planning/` 提交到 git:**是** 随时可用 `/gsd-settings` 调整。 -## Important Anchoring Note +## 锚定路径重要说明 `.planning/` 必须保持在 `c:\Users\admin\Desktop\Lila-Server\qy_lty\` 这一层(**不是父级 `Lila-Server\`**)。父级 `.git` 容易让 GSD CLI 误把 `Lila-Server` 当作 project_root;本目录的存在就是锚定信号,不要删。 -## Project Rules Reminder +## 项目规则提醒 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*