diff --git a/docs/superpowers/plans/2026-09-08-auth-and-dual-settings.md b/docs/superpowers/plans/2026-09-08-auth-and-dual-settings.md new file mode 100644 index 00000000..3243c2c0 --- /dev/null +++ b/docs/superpowers/plans/2026-09-08-auth-and-dual-settings.md @@ -0,0 +1,204 @@ +# 用户认证、双设置体系与环境隔离治理实施计划 (Auth, Dual Settings & Environment Isolation Implementation Plan) + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** 构建全栈贯通的用户认证、注册审批与首次改密体系,深度拆分用户个人设置与系统管理员设置,实现环境变量超级管理员凭证载入与测试/生产严格环境隔离。 + +**Architecture:** +- Go 后端(`internal/auth` + `internal/server`)提供用户数据存储、bcrypt 密码哈希、`.env` 超级管理员初始化、准入开关(自主注册/注册审批)策略及 RESTful API; +- 前端(React + TypeScript)提供医疗合规美观的登录/注册界面、首次登录阻断式强制改密、普通用户个人设置(`UserSettingsModal`)及管理员独占系统设置(`AdminSettingsModal`); +- 环境隔离治理机制:仅在 `dev` 环境暴露便捷测试身份切换悬浮条,`test` 与 `main` 环境彻底剔除一切无密切换后门,强制登出/登录。 + +**Tech Stack:** Go 1.22+, `golang.org/x/crypto/bcrypt`, React 18, TypeScript, Tailwind CSS, Vite. + +## Global Constraints + +- **Git 三分支与环境准则**:在 `dev` 分支开发,遵循原子性渐进式提交 (`feat(auth)`, `feat(api)`, `feat(web)`, `test(...)`, `docs(...)`)。 +- **环境隔离红线**:`test` 与 `main` 环境严禁暴露身份切换入口;切换身份必须通过正规登出与账号密码登录。 +- **职位治理准则**:职位严格绑定系统 RBAC 角色,由系统管理员统一指派与审核,自主注册仅填用户名、密码、姓名,不可自行填选职位。 +- **管理员凭据注入**:系统超级管理员用户名与密码通过环境变量 `ADMIN_USERNAME` 与 `ADMIN_PASSWORD` 动态配置。 +- **测试报告规范**:测试完成后归档于 `.doc/test-reports/2026-09-08-auth-and-dual-settings-test-report.md`。 + +--- + +### Task 1: Go 后端用户认证数据契约、配置项与存储引擎 (`internal/config`, `internal/auth`) + +**Files:** +- Modify: `internal/config/config.go` +- Create: `internal/auth/models.go` +- Create: `internal/auth/crypto.go` +- Create: `internal/auth/store.go` +- Test: `internal/auth/auth_test.go` + +**Interfaces:** +- Produces: + - `UserAccount`, `AccountStatus`, `SystemAuthConfig` + - `HashPassword(password string) (string, error)` + - `CheckPassword(hashed, password string) bool` + - `AuthStore` interface with methods: `GetUserByUsername`, `GetUserByID`, `CreateUser`, `UpdateUser`, `ListUsers`, `GetConfig`, `UpdateConfig` + +- [ ] **Step 1: 编写 Go 后端认证数据模型与密码加盐哈希的失败单元测试** +- [ ] **Step 2: 运行测试验证失败** (`go test -v ./internal/auth`) +- [ ] **Step 3: 扩展 `internal/config/config.go` 解析 `ADMIN_USERNAME`, `ADMIN_PASSWORD`, `AUTH_REGISTRATION_ENABLED`, `AUTH_REQUIRE_APPROVAL`** +- [ ] **Step 4: 实现 `internal/auth/models.go`、`internal/auth/crypto.go` 与 `internal/auth/store.go`** +- [ ] **Step 5: 运行测试验证全部通过** (`go test -v ./internal/auth`) +- [ ] **Step 6: Git 渐进式提交 (`feat(auth): add auth data models, config and store engine`)** + +--- + +### Task 2: Go 后端认证业务服务与 RESTful 路由处理 (`internal/auth`, `internal/server`) + +**Files:** +- Create: `internal/auth/service.go` +- Modify: `internal/server/server.go` +- Create: `internal/server/auth_handlers.go` +- Test: `internal/server/auth_handlers_test.go` + +**Interfaces:** +- Consumes: `internal/auth/store.go`, `internal/config/config.go` +- Produces: + - `POST /api/v1/auth/login` + - `POST /api/v1/auth/register` + - `POST /api/v1/auth/logout` + - `POST /api/v1/auth/change-password` + - `GET /api/v1/auth/me` + - `GET /api/v1/admin/users` + - `POST /api/v1/admin/users` + - `PUT /api/v1/admin/users/{id}/role` + - `PUT /api/v1/admin/users/{id}/status` + - `GET/PUT /api/v1/admin/config` + +- [ ] **Step 1: 编写 HTTP 认证与管理接口的失败测试** (`internal/server/auth_handlers_test.go`) +- [ ] **Step 2: 运行测试验证接口未就绪失败** +- [ ] **Step 3: 实现 `internal/auth/service.go` 鉴权与业务逻辑** +- [ ] **Step 4: 实现 `internal/server/auth_handlers.go` 并挂载至 `internal/server/server.go`** +- [ ] **Step 5: 运行接口测试验证全部通过** (`go test -v ./internal/server -run TestAuthHandlers`) +- [ ] **Step 6: Git 渐进式提交 (`feat(api): add auth and admin management endpoints`)** + +--- + +### Task 3: 前端数据模型契约与认证客户端封装 (`web/src/types/auth.ts`, `web/src/api/auth.ts`) + +**Files:** +- Create: `web/src/types/auth.ts` +- Create: `web/src/api/auth.ts` +- Test: `web/src/api/auth.test.ts` + +**Interfaces:** +- Consumes: 后端 RESTful API 契约 +- Produces: + - `login(username, password): Promise` + - `register(payload): Promise` + - `changePassword(oldPass, newPass): Promise` + - `getAdminUsers(): Promise` + - `createAdminUser(payload): Promise` + - `updateUserRole(id, roleId): Promise` + - `updateUserStatus(id, status, roleId): Promise` + - `getSystemAuthConfig(): Promise` + - `updateSystemAuthConfig(config): Promise` + +- [ ] **Step 1: 定义 `web/src/types/auth.ts` 数据契约** +- [ ] **Step 2: 编写 `web/src/api/auth.test.ts` 客户端接口与双模持久化测试** +- [ ] **Step 3: 实现 `web/src/api/auth.ts` 客户端网络层与兜底机制** +- [ ] **Step 4: 运行前端 API 测试验证通过** (`npm test` 或 `npx vitest run`) +- [ ] **Step 5: Git 渐进式提交 (`feat(web): add frontend auth types and api client`)** + +--- + +### Task 4: 医疗合规设计登录页、自主注册与首次强制改密组件 (`web/src/components/auth/`) + +**Files:** +- Create: `web/src/components/auth/LoginView.tsx` +- Create: `web/src/components/auth/FirstLoginPasswordModal.tsx` + +**Interfaces:** +- Produces: + - `` + - `` + +- [ ] **Step 1: 构建 `LoginView.tsx`**: + - 现代化商务医疗设计质感(Logo、品牌标语、用户名密码表单); + - 注册折叠/切换:仅需填写用户名、密码、姓名(必填),工号与部门(选填),职位锁定提示由管理员指派; + - 响应准入策略:若 `allowRegistration === false` 隐藏注册;若 `requireApproval === true` 提交后给出待审核温馨提醒; +- [ ] **Step 2: 构建 `FirstLoginPasswordModal.tsx`**: + - 全屏半透明高权重遮罩,不可点击背景关闭; + - 强制输入原密码(或初始密码)、新密码与确认新密码,完成改密后解除阻断; +- [ ] **Step 3: Git 渐进式提交 (`feat(web): add LoginView and FirstLoginPasswordModal components`)** + +--- + +### Task 5: 重构用户个人设置界面 (`UserSettingsModal.tsx`) + +**Files:** +- Create: `web/src/components/user/UserSettingsModal.tsx` +- (Deprecate old mixed `SettingsModal.tsx` for users) + +**Interfaces:** +- Produces: + - `` + +- [ ] **Step 1: 实现 `UserSettingsModal.tsx` 五大板块**: + - Tab 1: 个人资料(姓名、用户名、工号、部门,职位只读高亮徽章并提示由管理员配置); + - Tab 2: 安全设置(修改密码); + - Tab 3: 偏好设定(明暗主题、字号大小、默认导出格式); + - Tab 4: 我的权限(清晰列出当前职位对应的 7 项原子权限能力); + - 登出操作区:醒目安全登出按钮,带有确认提示,退出后清除会话; +- [ ] **Step 2: Git 渐进式提交 (`feat(web): implement dedicated UserSettingsModal`)** + +--- + +### Task 6: 构建系统管理员独占系统设置界面 (`AdminSettingsModal.tsx`) + +**Files:** +- Create: `web/src/components/admin/AdminSettingsModal.tsx` + +**Interfaces:** +- Produces: + - `` + +- [ ] **Step 1: 实现管理员独占入口保护与校验**(非管理员调用直接拦截并报警) +- [ ] **Step 2: 实现 Tab 1: 人员与职位治理**(用户全量表格、指派职位/角色、启用/停用、重置密码、新建账号弹窗且置标首次强制改密) +- [ ] **Step 3: 实现 Tab 2: 注册审批中心**(展示待审核新用户,一键批准并指定职位,或拒绝) +- [ ] **Step 4: 实现 Tab 3: 系统准入策略**(自主注册开关、注册需审批开关) +- [ ] **Step 5: 嵌入 Tab 4: 动态 RBAC 角色与权限矩阵**(继承现有 RBAC 动态增删改与 7 项权限配置) +- [ ] **Step 6: 实现 Tab 5: 系统运行与环境状态**(展示环境类型、知识库连接与 AI 参谋状态) +- [ ] **Step 7: Git 渐进式提交 (`feat(web): implement dedicated AdminSettingsModal for role-admin`)** + +--- + +### Task 7: 环境隔离与调试切换控制集成 (`App.tsx`, `LeftRail.tsx`, `AppShell.tsx`) + +**Files:** +- Modify: `web/src/App.tsx` +- Modify: `web/src/components/layout/LeftRail.tsx` +- Modify: `web/src/components/layout/AppShell.tsx` +- Create: `web/src/components/dev/DevRoleSwitcher.tsx` +- Modify: `.env.example`, `.env`, `configs/.env.dev.example` + +**Interfaces:** +- Consumes: 全局状态、环境标识 `env` +- Enforces: + - 未登录态:工作台整体隐藏,呈现 `LoginView`; + - `mustChangePassword` 态:弹出阻断式 `FirstLoginPasswordModal`; + - 顶部/侧边栏:所有用户可见“用户设置”,**仅管理员(`role-admin`)可见“系统设置”**; + - 环境隔离:若 `env === 'dev'`,渲染小巧的 `DevRoleSwitcher`;若 `env !== 'dev'`,**彻底不渲染任何切换组件**。 + +- [ ] **Step 1: 实现 `DevRoleSwitcher.tsx`(仅在开发调试态按需浮现,一键切换张工/李主管/王总监/管理员)** +- [ ] **Step 2: 在 `LeftRail.tsx` 与顶栏拆分“个人设置”与“系统设置”入口,精准根据 `role-admin` 显隐** +- [ ] **Step 3: 在 `App.tsx` 串联认证守卫、环境判定、登出流转与首次强制改密弹窗** +- [ ] **Step 4: 在 `.env.example` 与 `.env` 中补齐 `ADMIN_USERNAME`, `ADMIN_PASSWORD` 等字段** +- [ ] **Step 5: Git 渐进式提交 (`feat(web): integrate auth guards, dual settings and dev switcher`)** + +--- + +### Task 8: 全链路端到端回归验证、测试报告归档与交付 (`.doc/test-reports/`) + +**Files:** +- Create: `web/src/engine/authIntegration.test.ts` +- Create: `.doc/test-reports/2026-09-08-auth-and-dual-settings-test-report.md` + +- [ ] **Step 1: 编写全链路认证与双设置集成自动化测试** +- [ ] **Step 2: 执行全部后端与前端测试套件验证 100% 通过** +- [ ] **Step 3: 归档标准化测试报告至 `.doc/test-reports/2026-09-08-auth-and-dual-settings-test-report.md`** +- [ ] **Step 4: Git 渐进式提交 (`test(auth): archive auth and dual settings test report`)** +- [ ] **Step 5: 总结与汇报**