pmc 5d8f81a4a9 docs(qy-lty-admin): 初始化 PROJECT.md + STATE.md
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 仓库管理的关键说明。
2026-05-07 14:32:53 +08:00

164 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 洛天依应用管理后台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 优化都无法弥补这种安全风险。
## 需求清单
### 已交付
<!-- 已交付且在生产链路上跑通的能力,从 .planning/codebase/ 推断 -->
**鉴权与会话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 + runnerrunner 镜像 < 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 通过 phase 推动这一段移到 Validated 才算完成 -->
(暂无 — 本次 `/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 存于 localStorageXSS 暴露面)+ 7 天有效期不轮换 — CONCERNS.md 标 HIGH
## 约束
- **技术栈**Next.js 15.2.4App Router+ React 19 + TypeScript 5 — 已锁定,迁移成本高
- **技术栈**Tailwind CSS 3.4 + Radix UI + shadcn 风格组件 — 不替换为其他设计系统
- **运行时**Node.js 22.10.0 AlpineDocker 镜像锁定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 同时存 localStorageAPI 客户端读取)与 cookiemiddleware 读取)— 双存储必须保持同步
- **角色命名**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 | 镜像体积约 100MBvs 标准 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-07brownfield 文档化初始化完成(已映射现有系统,尚无进行中 milestone — 使用 /gsd-new-milestone 启动下一周期)*