## P1 数据库基础 - zqyy_app: 创建 auth/biz schema、FDW 连接 etl_feiqiu - etl_feiqiu: 创建 app schema RLS 视图、商品库存预警表 - 清理 assistant_abolish 残留数据 ## P2 ETL/DWS 扩展 - 新增 DWS 助教订单贡献度表 (dws.assistant_order_contribution) - 新增 assistant_order_contribution_task 任务及 RLS 视图 - member_consumption 增加充值字段、assistant_daily 增加处罚字段 - 更新 ODS/DWD/DWS 任务文档及业务规则文档 - 更新 consistency_checker、flow_runner、task_registry 等核心模块 ## P3 小程序鉴权系统 - 新增 xcx_auth 路由/schema(微信登录 + JWT) - 新增 wechat/role/matching/application 服务层 - zqyy_app 鉴权表迁移 + 角色权限种子数据 - auth/dependencies.py 支持小程序 JWT 鉴权 ## 文档与审计 - 新增 DOCUMENTATION-MAP 文档导航 - 新增 7 份 BD_Manual 数据库变更文档 - 更新 DDL 基线快照(etl_feiqiu 6 schema + zqyy_app auth) - 新增全栈集成审计记录、部署检查清单更新 - 新增 BACKLOG 路线图、FDW→Core 迁移计划 ## Kiro 工程化 - 新增 5 个 Spec(P1/P2/P3/全栈集成/核心业务) - 新增审计自动化脚本(agent_on_stop/build_audit_context/compliance_prescan) - 新增 6 个 Hook(合规检查/会话日志/提交审计等) - 新增 doc-map steering 文件 ## 运维与测试 - 新增 ops 脚本:迁移验证/API 健康检查/ETL 监控/集成报告 - 新增属性测试:test_dws_contribution / test_auth_system - 清理过期 export 报告文件 - 更新 .gitignore 排除规则
17 KiB
需求文档:小程序用户认证系统(miniapp-auth-system)
简介
本 SPEC 实现小程序用户认证系统,涵盖微信登录、用户申请审核、人员匹配、多店铺权限管理等完整认证链路。系统基于 P1(miniapp-db-foundation)已建立的 auth Schema 和 FDW 映射,在 test_zqyy_app.auth 中创建用户、申请、角色、绑定等业务表,并在 FastAPI 后端实现对应的 API 端点和权限中间件。
术语表
- Auth_System:小程序用户认证系统,负责微信登录、用户管理、申请审核、权限控制的完整后端服务
- WeChat_Auth_Service:微信认证服务模块,负责调用微信
code2Session接口换取openid和session_key - Application_Service:用户申请服务模块,负责处理用户提交的入驻申请、状态流转和审核操作
- Matching_Service:人员匹配服务模块,负责根据球房ID和手机号/编号在助教表和员工表中查找候选匹配
- Permission_Middleware:权限中间件,基于用户的
site_id+role拦截无权请求 - JWT_Service:JWT 令牌服务,负责签发和刷新 access_token / refresh_token(已有实现,本 SPEC 扩展)
- site_code:球房ID,格式为 2 字母 + 3 数字(如
AB123),与site_id一一映射 - site_id:门店标识符,类型为
BIGINT,用于多门店数据隔离 - user_status:用户状态枚举,取值为
pending(审核中)/approved(已通过)/rejected(已拒绝)/disabled(已禁用) - binding_type:绑定类型枚举,取值为
assistant(助教)/staff(员工)/manager(管理员) - FDW:
postgres_fdw外部数据包装器,通过fdw_etlSchema 读取 ETL 库数据 - Migration_Script:存放在
db/zqyy_app/migrations/中的纯 SQL 迁移脚本,以日期前缀命名 - BD_Manual:数据库手册文档,存放在
docs/database/中,记录表结构变更、兼容性影响、回滚策略和验证 SQL - DDL_Baseline:DDL 基线文件,存放在
docs/database/ddl/中,由gen_consolidated_ddl.py自动生成 - Miniprogram_Auth_Pages:小程序认证相关前端页面,包括登录页、申请表单页、审核等待页、无权限页
- Dev_Login:开发模式下的 mock 登录端点,绕过微信 code2Session 调用,用于联调测试
需求
需求 1:认证数据表创建
用户故事: 作为后端开发者,我需要在 auth Schema 中创建用户认证相关的数据表,以便支撑完整的认证和权限管理功能。
验收标准
- WHEN Migration_Script 执行完成, THE Auth_System SHALL 在
authSchema 中创建users表,包含id(SERIAL PK)、wx_openid(UNIQUE)、wx_union_id、wx_avatar_url、nickname、phone、status(默认pending)、created_at、updated_at字段 - WHEN Migration_Script 执行完成, THE Auth_System SHALL 在
authSchema 中创建user_applications表,包含id(SERIAL PK)、user_id(FK → users)、site_code、applied_role_text、employee_number(可选)、phone、status(默认pending)、reviewer_id、review_note、created_at、reviewed_at字段 - WHEN Migration_Script 执行完成, THE Auth_System SHALL 在
authSchema 中创建site_code_mapping表,包含id(SERIAL PK)、site_code(UNIQUE,格式 2 字母 + 3 数字)、site_id(BIGINT UNIQUE)、site_name、tenant_id、created_at字段 - WHEN Migration_Script 执行完成, THE Auth_System SHALL 在
authSchema 中创建user_site_roles表,包含id(SERIAL PK)、user_id(FK → users)、site_id(BIGINT)、role_id(FK → roles)、created_at字段,并对(user_id, site_id, role_id)建立唯一约束 - WHEN Migration_Script 执行完成, THE Auth_System SHALL 在
authSchema 中创建user_assistant_binding表,包含id(SERIAL PK)、user_id(FK → users)、site_id(BIGINT)、assistant_id(BIGINT,可选)、staff_id(BIGINT,可选)、binding_type、created_at字段 - WHEN Migration_Script 执行完成, THE Auth_System SHALL 在
authSchema 中创建roles表,包含id(SERIAL PK)、code(UNIQUE)、name、description、created_at字段 - WHEN Migration_Script 执行完成, THE Auth_System SHALL 在
authSchema 中创建permissions表,包含id(SERIAL PK)、code(UNIQUE)、name、description、created_at字段 - WHEN Migration_Script 执行完成, THE Auth_System SHALL 在
authSchema 中创建role_permissions表,包含role_id(FK → roles)、permission_id(FK → permissions)字段,并以(role_id, permission_id)为联合主键 - THE Migration_Script SHALL 使用
IF NOT EXISTS/OR REPLACE等幂等语法,确保重复执行不会报错 - THE Migration_Script SHALL 在脚本中包含回滚语句(以注释形式)
需求 2:种子数据预置
用户故事: 作为系统管理员,我需要系统预置固定的权限列表和默认角色,以便审核时可直接分配。
验收标准
- WHEN 种子数据脚本执行完成, THE Auth_System SHALL 在
auth.permissions表中插入 5 条固定权限记录:view_tasks、view_board、view_board_finance、view_board_customer、view_board_coach - WHEN 种子数据脚本执行完成, THE Auth_System SHALL 在
auth.roles表中插入默认角色(至少包含coach(助教)、staff(员工)、site_admin(店铺管理员)、tenant_admin(租户管理员)) - WHEN 种子数据脚本执行完成, THE Auth_System SHALL 在
auth.role_permissions表中为每个默认角色分配对应的权限组合 - THE 种子数据脚本 SHALL 使用
ON CONFLICT DO NOTHING语法,确保重复执行不会产生重复数据
需求 3:微信登录
用户故事: 作为球房工作人员,我需要通过微信登录小程序,以便快速进入系统。
验收标准
- WHEN 小程序端发送微信临时登录凭证(
code), THE WeChat_Auth_Service SHALL 调用微信code2Session接口换取openid和session_key - WHEN
code2Session返回有效openid且该openid已存在于auth.users表中, THE Auth_System SHALL 返回该用户的 JWT 令牌对(access_token + refresh_token)和用户状态信息 - WHEN
code2Session返回有效openid且该openid不存在于auth.users表中, THE Auth_System SHALL 创建新用户记录(status 为pending),返回 JWT 令牌对和pending状态标识 - IF
code2Session接口调用失败或返回错误码, THEN THE WeChat_Auth_Service SHALL 返回 HTTP 401 错误,包含具体的错误描述 - WHEN 用户状态为
disabled, THE Auth_System SHALL 返回 HTTP 403 错误,拒绝登录
需求 4:用户申请提交
用户故事: 作为球房工作人员,我需要在首次登录后填写申请表单(球房ID、申请身份、手机号、编号、昵称),以便管理员审核我的身份。
验收标准
- WHEN 用户提交申请表单(包含
site_code、applied_role_text、phone,可选employee_number), THE Application_Service SHALL 在auth.user_applications表中创建一条 status 为pending的申请记录 - WHEN 用户提交的
site_code在auth.site_code_mapping中存在映射, THE Application_Service SHALL 将申请记录关联到对应的site_id - WHEN 用户提交的
site_code在auth.site_code_mapping中不存在映射, THE Application_Service SHALL 仍然接受申请,申请记录中保留site_code文本,管理端显示"未找到关联信息" - WHEN 用户提交申请时提供了
nickname, THE Auth_System SHALL 更新auth.users表中该用户的nickname字段 - IF 用户提交的
phone为空或格式无效(非 11 位数字), THEN THE Application_Service SHALL 返回 HTTP 422 错误,包含具体的校验失败信息 - WHEN 用户已有一条
pending状态的申请, THE Application_Service SHALL 拒绝重复提交,返回 HTTP 409 错误
需求 5:人员匹配
用户故事: 作为系统,我需要根据球房ID和手机号自动建议用户与助教/员工的对应关系,以便管理员快速审核。
验收标准
- WHEN 管理员查看某条申请详情时, THE Matching_Service SHALL 根据申请中的
site_id和phone在fdw_etl.v_dim_assistant中按site_id+mobile匹配助教记录 - WHEN 管理员查看某条申请详情时, THE Matching_Service SHALL 根据申请中的
site_id和phone在fdw_etl.v_dim_staff和fdw_etl.v_dim_staff_ex中按site_id+mobile匹配员工记录 - WHEN 申请中包含
employee_number, THE Matching_Service SHALL 额外按job_num字段匹配员工记录 - THE Matching_Service SHALL 将助教匹配结果和员工匹配结果合并为统一的候选列表返回,每条候选包含来源类型(
assistant/staff)、姓名、手机号、编号 - WHEN 助教表和员工表均无匹配结果, THE Matching_Service SHALL 返回空候选列表,管理端显示"未找到关联信息"
- WHEN 申请的
site_code无法映射到site_id, THE Matching_Service SHALL 跳过匹配,返回空候选列表
需求 6:申请审核
用户故事: 作为租户管理员,我需要审核用户申请,将用户关联到对应的助教/员工,并分配身份权限。
验收标准
- WHEN 管理员批准申请并选择了候选匹配对象, THE Application_Service SHALL 将申请状态更新为
approved,在auth.user_assistant_binding中创建绑定记录,在auth.user_site_roles中分配角色 - WHEN 管理员批准申请但无候选匹配(手动审核), THE Application_Service SHALL 将申请状态更新为
approved,仅在auth.user_site_roles中分配角色,不创建绑定记录 - WHEN 管理员拒绝申请, THE Application_Service SHALL 将申请状态更新为
rejected,记录review_note(拒绝原因) - WHEN 申请审核通过后, THE Auth_System SHALL 将
auth.users表中该用户的status更新为approved - WHEN 审核操作完成, THE Application_Service SHALL 记录
reviewer_id和reviewed_at时间戳 - IF 审核目标申请的状态不是
pending, THEN THE Application_Service SHALL 返回 HTTP 409 错误,拒绝重复审核
需求 7:用户状态查询
用户故事: 作为用户,我需要看到自己的申请状态(审核中/通过/拒绝),以便了解审核进度。
验收标准
- WHEN 用户查询自身状态, THE Auth_System SHALL 返回用户的
status、所有申请记录列表(含每条申请的site_code、applied_role_text、status、review_note) - WHEN 用户状态为
approved, THE Auth_System SHALL 同时返回用户已关联的店铺列表和对应角色
需求 8:多店铺支持与店铺切换
用户故事: 作为用户,我可以同时属于多个店铺(连锁场景),切换店铺后数据正确隔离。
验收标准
- THE Auth_System SHALL 允许一个用户通过多次申请关联到多个不同的
site_id,每个site_id独立分配角色 - WHEN 用户切换当前店铺, THE JWT_Service SHALL 签发包含新
site_id的 JWT 令牌对 - WHEN 用户携带某
site_id的 JWT 访问 API, THE Permission_Middleware SHALL 仅允许访问该site_id下用户拥有权限的资源
需求 9:权限中间件
用户故事: 作为系统,我需要权限中间件正确拦截无权请求,确保数据安全。
验收标准
- WHEN 用户携带有效 JWT 访问受保护端点, THE Permission_Middleware SHALL 从 JWT 中提取
user_id和site_id,查询auth.user_site_roles和auth.role_permissions获取用户在该店铺下的权限列表 - WHEN 用户的权限列表不包含端点所需的权限 code, THE Permission_Middleware SHALL 返回 HTTP 403 错误
- WHEN 用户的
status不是approved, THE Permission_Middleware SHALL 返回 HTTP 403 错误,拒绝访问受保护端点 - WHEN JWT 令牌过期或无效, THE Permission_Middleware SHALL 返回 HTTP 401 错误
需求 10:JWT 令牌扩展
用户故事: 作为后端开发者,我需要扩展现有 JWT 服务以支持微信登录场景和多店铺切换。
验收标准
- THE JWT_Service SHALL 在 JWT payload 中包含
user_id(sub)、site_id、roles(角色 code 列表)、type(access/refresh)、exp字段 - WHEN 用户通过微信登录且状态为
approved, THE JWT_Service SHALL 使用用户默认店铺(第一个关联的 site_id)签发令牌 - WHEN 用户通过微信登录且状态为
pending, THE JWT_Service SHALL 签发不含site_id和roles的受限令牌,仅允许访问申请提交和状态查询端点 - WHEN 用户请求切换店铺, THE JWT_Service SHALL 验证用户在目标
site_id下有角色绑定后签发新令牌
需求 11:迁移脚本管理
用户故事: 作为后端开发者,我需要所有数据库变更都有对应的迁移脚本,以便变更可追溯、可重放。
验收标准
- THE Migration_Script SHALL 将所有认证相关表的 DDL 存放在
db/zqyy_app/migrations/目录中 - THE Migration_Script SHALL 使用日期前缀命名(格式:
YYYY-MM-DD__<描述>.sql) - THE Migration_Script SHALL 使用 UTF-8 编码,纯 SQL(非 ORM)
- THE Migration_Script SHALL 在每个脚本中包含回滚语句(以注释形式)
- THE Migration_Script SHALL 使用幂等语法(
IF NOT EXISTS、ON CONFLICT DO NOTHING),确保重复执行不会报错
需求 12:DDL 测试库落库与文档同步
用户故事: 作为后端开发者,我需要所有 DDL 变更在测试库(test_zqyy_app)中实际执行验证,并同步更新数据库手册和 DDL 基线,确保文档与实际 Schema 一致。
验收标准
- WHEN 迁移脚本编写完成, THE Auth_System SHALL 在
test_zqyy_app测试库中执行迁移脚本,验证无错误 - WHEN 迁移脚本执行成功, THE Auth_System SHALL 创建或更新
docs/database/BD_Manual_auth_tables.md数据库手册,包含变更说明、兼容性影响、回滚策略、验证 SQL(至少 3 条) - WHEN 迁移脚本执行成功, THE Auth_System SHALL 运行
python scripts/ops/gen_consolidated_ddl.py重新生成 DDL 基线文件docs/database/ddl/zqyy_app__auth.sql - WHEN 种子数据脚本执行成功, THE Auth_System SHALL 在数据库手册中记录种子数据内容(角色、权限、角色-权限映射)
需求 13:小程序认证前端页面
用户故事: 作为球房工作人员,我需要在小程序中看到登录页、申请表单页、审核状态页,以便完成从微信登录到正式使用的完整流程。
验收标准
- WHEN 用户首次打开小程序, THE Auth_System SHALL 展示登录页面,调用
wx.login()获取 code 并发送到后端/api/xcx/login - WHEN 后端返回
user_status=pending且用户无 pending 申请, THE Auth_System SHALL 跳转到申请表单页面,包含球房ID(site_code)、申请身份、手机号、编号(选填)、昵称输入框 - WHEN 用户提交申请表单, THE Auth_System SHALL 调用
/api/xcx/apply提交申请,成功后跳转到审核等待页面 - WHEN 用户状态为
pending且已有 pending 申请, THE Auth_System SHALL 展示审核等待页面,显示"审核中"状态和申请信息摘要 - WHEN 用户状态为
rejected, THE Auth_System SHALL 在审核等待页面显示拒绝原因,并提供"重新申请"按钮 - WHEN 用户状态为
approved, THE Auth_System SHALL 跳转到小程序主页(任务列表) - WHEN 用户状态为
disabled, THE Auth_System SHALL 展示无权限页面,提示账号已被禁用 - THE Auth_System SHALL 在小程序
app.ts的onLaunch中实现自动登录逻辑,根据用户状态路由到对应页面 - WHEN 用户拥有多个店铺, THE Auth_System SHALL 在主页提供店铺切换入口
需求 14:前后端联调验证
用户故事: 作为开发者,我需要在微信开发者工具中验证完整的认证流程(登录→申请→审核→进入主页),确保前后端接口对接正确。
验收标准
- THE Auth_System SHALL 提供联调验证脚本或文档,说明如何在微信开发者工具中测试完整认证流程
- THE Auth_System SHALL 在后端提供开发模式下的 mock 登录端点(
POST /api/xcx/dev-login),接受任意 openid 直接返回 JWT,绕过微信 code2Session 调用 - WHEN 开发模式启用时, THE Auth_System SHALL 允许通过环境变量
WX_DEV_MODE=true切换到 mock 模式 - THE Auth_System SHALL 在
apps/miniprogram/doc/中提供联调指南文档,包含微信开发者工具配置、后端启动步骤、测试账号说明