From 5d8f81a4a9e56c06feae0a298e4e659857eb1b9a Mon Sep 17 00:00:00 2001 From: pmc <740076875@qq.com> Date: Thu, 7 May 2026 14:32:53 +0800 Subject: [PATCH] =?UTF-8?q?docs(qy-lty-admin):=20=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96=20PROJECT.md=20+=20STATE.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Brownfield 文档化模式 —— 从 .planning/codebase/ 推断 47 项已交付能力(AUTH/PERM/DASH/AI/CONT/SYS/UPL/UI/DEP), Active 段留空待 /gsd-new-milestone 启动下一周期。 PROJECT.md 沿用 qy_lty 的章节结构(核心价值 / 已交付 / 进行中 / 范围外 / 背景 / 约束 / 关键决策 / 演进规则)。 STATE.md 记录锚定路径与 git 由父 Lila-Server 仓库管理的关键说明。 --- qy-lty-admin/.planning/PROJECT.md | 163 ++++++++++++++++++++++++++++++ qy-lty-admin/.planning/STATE.md | 69 +++++++++++++ 2 files changed, 232 insertions(+) create mode 100644 qy-lty-admin/.planning/PROJECT.md create mode 100644 qy-lty-admin/.planning/STATE.md diff --git a/qy-lty-admin/.planning/PROJECT.md b/qy-lty-admin/.planning/PROJECT.md new file mode 100644 index 0000000..c209e38 --- /dev/null +++ b/qy-lty-admin/.planning/PROJECT.md @@ -0,0 +1,163 @@ +# 洛天依应用管理后台(qy-lty-admin) + +## 项目简介 + +qy-lty-admin 是「洛天依(Luotianyi)智能陪伴产品」生态的 **Web 管理后台前端**,基于 **Next.js 15 (App Router) + React 19 + TypeScript** 构建,搭配 Tailwind CSS + Radix UI / shadcn 风格组件。它通过 `/api/v1/admin/` 命名空间消费独立后端 [qy_lty](../qy_lty/)(Django)的 REST 接口,为运营者提供 AI / 内容(服饰/道具/家居/食物/歌曲/舞蹈/成就/好感度)/ 用户与权限 / 系统设置等模块的管理能力。 + +## 核心价值 + +**运营者能基于真实角色权限,安全且无障碍地管理后端各业务模块的数据**——`lib/permissions.ts` 中的 RBAC 矩阵 + `qy_lty` 后端服务端校验必须始终配套生效。一旦权限校验链路断裂(前端伪造角色或后端漏校验),整个管理后台就从"运营工具"退化为"任意操作面板",其余所有 UI / UX 优化都无法弥补这种安全风险。 + +## 需求清单 + +### 已交付 + + + +**鉴权与会话(AUTH)** +- ✓ **AUTH-01** 邮箱 + 密码登录页(`app/login/page.tsx` + `lib/api/auth.ts:emailLogin`)— existing +- ✓ **AUTH-02** 注册 / 找回密码占位页(`app/register/`、`app/forgot-password/`)— existing +- ✓ **AUTH-03** Bearer token 拦截器自动注入(`lib/api/client.ts` 请求拦截器从 localStorage 读 `auth_token`)— existing +- ✓ **AUTH-04** 401 响应统一处理(响应拦截器清空 token + 重定向 `/login`)— existing +- ✓ **AUTH-05** Cookie 镜像 token(`js-cookie`,7 天有效期,供 `middleware.ts` 路由保护使用)— existing +- ✓ **AUTH-06** 退出登录调用后端 logout 接口并清空双存储 — existing + +**RBAC 权限体系(PERM)** +- ✓ **PERM-01** 5 角色 × 13 模块的 `PERMISSION_MATRIX`(`lib/permissions.ts`)— existing +- ✓ **PERM-02** `hasPermission(module)` / `hasPathPermission(pathname)` / `getModuleFromPath()` 工具集 — existing +- ✓ **PERM-03** `DashboardShell` 挂载时按路径校验权限并渲染访问拒绝 UI(`components/dashboard-shell.tsx`)— existing +- ✓ **PERM-04** `Sidebar` 按角色过滤可见菜单项(`components/sidebar.tsx`)— existing +- ✓ **PERM-05** `middleware.ts` 在受保护路径前校验 cookie token 并重定向未鉴权访问 — existing + +**仪表盘(DASH)** +- ✓ **DASH-01** 仪表盘首页(`app/page.tsx`)含 KPI 统计卡片、概览图表、最近活动 Feed — existing +- ✓ **DASH-02** Recharts 数据可视化集成 — existing + +**AI 管理(AI)** +- ✓ **AI-01** AI 模型 / Bot 管理(`app/ai-model/page.tsx` + `lib/api/ai-models.ts`)— existing + +**内容管理(CONT)** +- ✓ **CONT-01** 服饰模块 CRUD(列表 / 详情 / 编辑 / 创建对话框,`app/outfits/` + `lib/api/outfits.ts`)— existing +- ✓ **CONT-02** 道具模块 CRUD(`app/props/`)— existing +- ✓ **CONT-03** 家居装饰模块 CRUD(`app/home-decor/`)— existing +- ✓ **CONT-04** 食物模块 CRUD(`app/food/`)— existing +- ✓ **CONT-05** 歌曲模块 CRUD(`app/songs/` + `lib/api/songs.ts`)— existing +- ✓ **CONT-06** 舞蹈模块 CRUD(`app/dances/` + `lib/api/dances.ts`)— existing +- ✓ **CONT-07** 成就模块管理(`app/achievements/` + `lib/api/achievements.ts`)— existing +- ✓ **CONT-08** 好感度系统管理页(`app/affinity/page.tsx`,1005 行单文件,规则/等级/互动 三段)— existing +- ✓ **CONT-09** 后端响应到前端类型的适配器层(`lib/api/adapters.ts` + 各模块 `mapBackend*` 函数)— existing + +**系统管理(SYS)** +- ✓ **SYS-01** 用户管理模块(`app/users/` + `lib/api/users.ts`)— existing +- ✓ **SYS-02** 权限/角色管理模块(`app/permissions/` + `lib/api/roles.ts`)— existing +- ✓ **SYS-03** 系统设置页(`app/settings/`)— existing + +**文件上传(UPL)** +- ✓ **UPL-01** 后端代理上传接口封装(`lib/api/upload.ts`,支持 image / avatar / audio / animation 类型 + 大小限制)— existing +- ✓ **UPL-02** 上传进度回调(Axios `onUploadProgress`)— existing + +**通用 UI 基础设施(UI)** +- ✓ **UI-01** shadcn 风格原子组件库(`components/ui/`,30+ 组件,复制粘贴模式可直接修改)— existing +- ✓ **UI-02** 表单层(React Hook Form + Zod + `@hookform/resolvers`)— existing +- ✓ **UI-03** Toast 通知(Sonner + Radix Toast,封装为 `hooks/use-toast.ts`)— existing +- ✓ **UI-04** 暗黑/明亮主题切换(`next-themes` + Tailwind CSS 变量)— existing +- ✓ **UI-05** 移动端断点检测 hook(`hooks/use-mobile.tsx`)— existing +- ✓ **UI-06** 删除 / 发布二次确认对话框(`components/delete-confirmation-dialog.tsx`、`publish-confirmation-dialog.tsx`)— existing + +**部署(DEP)** +- ✓ **DEP-01** Docker 多阶段构建(builder + runner,runner 镜像 < 200MB)— existing +- ✓ **DEP-02** Next.js standalone 输出(`.next/standalone` + `public/`)— existing +- ✓ **DEP-03** Yarn + 淘宝镜像源(`registry.npmmirror.com`,仅 Dockerfile 内)— existing +- ✓ **DEP-04** 端口 3000 暴露 + `yarn start` 入口 — existing + +### 进行中 + + + +(暂无 — 本次 `/gsd-new-project` 仅做 brownfield 文档化。下次新增功能 / 子系统时使用 `/gsd-new-milestone` 启动新 milestone,把当时要交付的能力加到这一段,然后 `/gsd-plan-phase` 拆 phase。) + +### 范围外 + + + +- **后端实现** — 在独立项目 [qy_lty](../qy_lty/) 中维护(Django + DRF + Channels)。本仓库**只**作为消费方调用 `/api/v1/admin/` REST 接口,不编写任何服务端代码。 +- **Unity 客户端业务逻辑** — 在 `C:\Unity2022project\LTY_App_Project_URP`(手机 App)和 `C:\Unity2022project\LTY_Project`(设备端)独立维护。本管理后台不与 Unity 客户端直接通信。 +- **跨项目混合修改记录** — 服务端 / 管理后台改动**各自记录**到对方仓库的 `docs/修改记录.md`,跨项目联动**两端各写一条互相引用**,不混在同一条记录里(CLAUDE.md 显式规定)。 +- **国际化(i18n)** — UI 文案当前硬编码中文,未引入 i18n 库;管理后台用户群体仅运营人员,不在本周期范畴。 +- **移动端原生体验** — 仅响应式 Web;移动 App 在 `LTY_App_Project_URP` 独立维护。 +- **真正意义的测试套件** — 当前未配置 Jest/Vitest,无任何测试文件。CONCERNS.md 标为 MEDIUM 工程债,需独立 milestone 系统性补齐。 +- **客户端错误追踪服务(如 Sentry)** — 仅依赖 Sonner toast + console,未引入第三方监控;如需要再开 milestone 评估。 + +## 背景上下文 + +**生态位**:本项目是「设备—App—管理端」三角中的 **管理端** 节点,是运营者操作 qy_lty 后端业务数据的唯一图形化入口。 + +**对接服务清单**(以 CLAUDE.md 为准): + +| 服务 | 路径 | 通讯方式 | +|------|------|---------| +| qy_lty 后端 Django | `../qy_lty/`(`C:\Users\admin\Desktop\Lila-Server\qy_lty`) | HTTP REST `/api/v1/admin/`、`/card/category/*`、`/music/`、`/dances/`、`/affinity/`、`/common/upload/` 等 | + +**最近活跃工作**(git log + 修改记录推断): +- 2026-04 ~ 至今:好感度系统管理页(`affinity/page.tsx`,1005 行)建设完成,与 qy_lty 后端 P1 数据层联动 +- 2026-05-07:完成 brownfield 代码库映射(commit `a85b6a7`) +- 持续在内容模块(outfits / songs / dances 等)补充 CRUD 表单与详情视图 + +**已知工程现状**(详见 `.planning/codebase/`): +- 整体规模约 27K LOC TypeScript / TSX +- 测试覆盖**零**(无 Jest/Vitest 配置,无任何测试文件)— 是最大的工程债 +- `next.config.mjs` 配置 `eslint.ignoreDuringBuilds: true` 与 `typescript.ignoreBuildErrors: true` — 构建期不阻断错误 +- 多锁文件并存(`package-lock.json` + `pnpm-lock.yaml` + `yarn.lock`)— 本地与 Docker 容易拉到不同版本 +- `lib/api/client.ts` 含大量 `console.log/warn/error` 调试残留,会暴露 token 前缀 +- 部分依赖钉为 `"latest"`(`@hookform/resolvers`、`react-hook-form`、`recharts`、`zod`)— 升级不可控 +- `app/affinity/page.tsx`(1005 行)、`components/ui/sidebar.tsx`(763 行)等单文件偏大,需要拆分 +- 权限校验**仅在客户端**(localStorage.user_role 可篡改)— 后端必须重检每个 admin 接口才能闭环 +- Token 存于 localStorage(XSS 暴露面)+ 7 天有效期不轮换 — CONCERNS.md 标 HIGH + +## 约束 + +- **技术栈**:Next.js 15.2.4(App Router)+ React 19 + TypeScript 5 — 已锁定,迁移成本高 +- **技术栈**:Tailwind CSS 3.4 + Radix UI + shadcn 风格组件 — 不替换为其他设计系统 +- **运行时**:Node.js 22.10.0 Alpine(Docker 镜像锁定,CI/Local 应保持版本一致) +- **HTTP 客户端**:Axios(已配置请求/响应拦截器) — 不改用 fetch / SWR / React Query(避免重写大量适配器) +- **后端契约**:所有请求走 `NEXT_PUBLIC_API_BASE_URL + /api/v1/admin/...`;响应结构 `{ success, code, message, data }`(由 qy_lty 的 `StandardResponseMiddleware` 保证)— 整体壳层不可改 +- **Token 协议**:`Authorization: Bearer {token}`,token 同时存 localStorage(API 客户端读取)与 cookie(middleware 读取)— 双存储必须保持同步 +- **角色命名**:5 个角色(超级管理员 / 内容管理员 / AI模型管理员 / 卡牌管理员 / 查看者 / 管理员),中文名硬编码,与 qy_lty 后端必须一致 +- **包管理器**:项目并存三种 lockfile,**Dockerfile 用 yarn**,本地任选其一但**不要混用**(CLAUDE.md 警告) +- **文档规范**:每次代码改动**必须**追加到 `docs/修改记录.md` 顶部(CLAUDE.md 强制规则,结构性文档变更同样适用) +- **沟通语言**:与用户沟通使用中文(CLAUDE.md「沟通语言」节,只能因用户显式要求才切换) +- **项目独立**:`qy-lty-admin` 与 `qy_lty` 独立维护,**修改记录、planning 工件不混合** +- **跨仓库联动**:任何 `/api/v1/admin/` 接口契约改动**两端各写一条 `docs/修改记录.md` 并互相引用** + +## 关键决策 + +| 决策 | 理由 | 结果 | +|------|------|------| +| 权限矩阵硬编码在前端(`lib/permissions.ts`) | 5 角色固定、变更频率低,不必引入额外配置中心 | ⚠️ Revisit — 客户端权限**仅是 UI 礼貌**;后端必须独立校验。CONCERNS.md 标"信任边界违规"为极高优先级,需明文写进 CLAUDE.md | +| Token 同时写 localStorage + cookie | API 客户端需 JS 可读,middleware 需 SSR 可读 | ⚠️ Revisit — 双存储扩大了 XSS 暴露面,理想形态是后端 HttpOnly cookie;当前形态是与后端契约的妥协 | +| shadcn 风格复制粘贴组件(不是 npm 包) | 可直接修改源码而不被 npm 升级覆盖 | ✓ Good — 已稳定使用,30+ 组件 | +| Axios + 拦截器(不是 fetch / SWR / React Query) | 拦截器统一处理 token 注入与 401,迁移到 hook 形态会重写大量代码 | ✓ Good — 当前形态稳定 | +| Next.js standalone 输出(Docker) | 镜像体积约 100MB(vs 标准 500MB) | ✓ Good — Dockerfile 已正确处理 public + next.config.mjs 复制 | +| 构建期忽略 TS / ESLint 错误(`ignoreBuildErrors: true`) | 早期开发不阻断构建 | ⚠️ Revisit — 应在生产配置中关闭并修干净;属技术债 | +| API 适配器层(`mapBackend*`) | 后端字段命名与前端类型契约不一致,集中映射避免散落 | ✓ Good — 已成为约定,新模块沿用即可 | +| `.planning/` 锚定在 `qy-lty-admin\`(不是 `Lila-Server\`) | `qy_lty` 与 `qy-lty-admin` 是独立项目,CLAUDE.md 规定各自维护 | ✓ Good — 2026-05-07 通过预创建空目录强制锚定生效 | + +## 演进规则 + +本文档在 phase 切换与 milestone 边界处更新。 + +**每次 phase 切换后**(通过 `/gsd-transition`): +1. 需求被推翻?→ 移到「范围外」并说明理由 +2. 需求已交付?→ 移到「已交付」并标注 phase 引用 +3. 出现新需求?→ 加到「进行中」 +4. 有决策需要记录?→ 加到「关键决策」 +5. 「项目简介」是否仍然准确?→ 如有偏移则更新 + +**每个 milestone 完成后**(通过 `/gsd-complete-milestone`): +1. 全面回顾所有章节 +2. 复核「核心价值」—— 是否仍是当前最高优先级? +3. 审视「范围外」—— 排除理由是否仍然成立? +4. 用当前状态更新「背景上下文」 + +--- +*最后更新:2026-05-07,brownfield 文档化初始化完成(已映射现有系统,尚无进行中 milestone — 使用 /gsd-new-milestone 启动下一周期)* diff --git a/qy-lty-admin/.planning/STATE.md b/qy-lty-admin/.planning/STATE.md new file mode 100644 index 0000000..3aa9fbc --- /dev/null +++ b/qy-lty-admin/.planning/STATE.md @@ -0,0 +1,69 @@ +# Project State — 洛天依应用管理后台(qy-lty-admin) + +**最后更新**: 2026-05-07(brownfield 文档化初始化) + +## 项目引用 + +参见:`.planning/PROJECT.md`(更新于 2026-05-07) + +**核心价值**:运营者能基于真实角色权限,安全且无障碍地管理后端各业务模块——`lib/permissions.ts` 的客户端 RBAC + qy_lty 后端服务端校验必须**配套生效**才完整。 + +**当前重点**:暂无 Active milestone — 待 `/gsd-new-milestone` 启动下一周期 + +## 状态 + +| 项目 | 状态 | +|------|------| +| 代码库映射 | ✅ `.planning/codebase/` 7 文档(commit `a85b6a7`) | +| PROJECT.md | ✅ 已交付段已从 codebase 推断填充,进行中段空 | +| REQUIREMENTS.md | ✅ 已交付段已拆 REQ-ID,进行中段空,可追溯性待 phase 回填 | +| 路线图 | ⏸️ 暂未生成(无进行中需求 → 无 phase 可分) | +| 当前 phase | — | +| 当前 milestone | — | + +## 下一步 + +**当你准备开始下一个开发周期**: + +``` +/gsd-new-milestone +``` + +GSD 会: +1. 询问 milestone 目标(例如:后端权限校验闭环验证、Token 存储重构、测试基础设施……) +2. 把需求加到 `.planning/REQUIREMENTS.md` 的 Active 段 +3. 路由到 `/gsd-roadmap` 拆 phase + +**候选优先级排序见 `REQUIREMENTS.md → Active → 候选优先级` 段**。 + +## 工作流配置 + +详见 `.planning/config.json`: + +- 模式:**YOLO**(自动通过审批,直接执行) +- 粒度:**Coarse**(每个 milestone 拆 3-5 phase) +- 并行化:**已启用** +- 工作流 agent:research / plan_check / verifier 全部启用 +- 模型档位:**balanced**(Sonnet 主力) +- `.planning/` 提交到 git:**是**(提交至父级 `Lila-Server\` 仓库) + +随时可用 `/gsd-settings` 调整。 + +## 锚定路径重要说明 + +`.planning/` 必须保持在 `c:\Users\admin\Desktop\Lila-Server\qy-lty-admin\` 这一层(**不是父级 `Lila-Server\`**)。父级 `.git` 容易让 GSD CLI 误把 `Lila-Server` 当作 project_root;本目录的存在就是锚定信号,不要删。 + +`qy-lty-admin\` 自身**没有** `.git`——版本控制由父级 `Lila-Server\.git` 统一管理。任何 `.planning/` 工件的提交都通过父仓库进行;**不要**在 `qy-lty-admin\` 内执行 `git init`,否则会形成嵌套仓库与父仓库冲突。 + +## 项目规则提醒 + +CLAUDE.md 中两条强制规则,做任何 phase 时必须遵守: + +1. **沟通语言**:所有面向用户的回复使用中文(CLAUDE.md 顶部「语言」要求 + 跨项目约定) +2. **修改记录**:每次代码 / 配置 / `package.json` / Dockerfile / CI / 文档结构性改动 **必须**追加到 `docs/修改记录.md` 顶部(CLAUDE.md「项目修改记录规则」节) + +`qy-lty-admin` 与 `qy_lty` 是独立项目,修改记录互不混合,跨项目联动两端各写一条互相引用对方的条目。 + +--- + +*由 /gsd-new-project(brownfield 文档化)生成于 2026-05-07*