Files
Neo-ZQYY/docs/database/BD_Manual_auth_tables.md
Neo b25308c3f4 feat: P1-P3 全栈集成 — 数据库基础 + DWS 扩展 + 小程序鉴权 + 工程化体系
## 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 排除规则
2026-02-26 08:03:53 +08:00

170 lines
8.1 KiB
Markdown
Raw Permalink 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.
# BD_Manualauth Schema 认证业务表
> 目标库:`test_zqyy_app`(通过 `APP_DB_DSN` 连接)
> 迁移脚本:
> - `db/zqyy_app/migrations/2026-02-25__p3_create_auth_tables.sql`(建表)
> - `db/zqyy_app/migrations/2026-02-25__p3_seed_roles_permissions.sql`(种子数据)
> 关联 SPEC`miniapp-auth-system`P3 小程序用户认证系统)
---
## 1. 变更说明
### 新增表8 张)
| # | 表名 | 用途 | 主要字段 |
|---|------|------|---------|
| 1 | `auth.users` | 微信用户主表 | `id`(PK), `wx_openid`(UK), `wx_union_id`, `wx_avatar_url`, `nickname`, `phone`, `status`(默认 `pending`), `created_at`, `updated_at` |
| 2 | `auth.user_applications` | 用户入驻申请表 | `id`(PK), `user_id`(FK→users), `site_code`, `site_id`, `applied_role_text`, `employee_number`, `phone`, `status`(默认 `pending`), `reviewer_id`, `review_note`, `created_at`, `reviewed_at` |
| 3 | `auth.site_code_mapping` | 球房ID与门店映射表 | `id`(PK), `site_code`(UK), `site_id`(UK), `site_name`, `tenant_id`, `created_at` |
| 4 | `auth.roles` | 角色定义表 | `id`(PK), `code`(UK), `name`, `description`, `created_at` |
| 5 | `auth.permissions` | 权限定义表 | `id`(PK), `code`(UK), `name`, `description`, `created_at` |
| 6 | `auth.role_permissions` | 角色-权限关联表 | `role_id`(FK→roles), `permission_id`(FK→permissions),联合主键 |
| 7 | `auth.user_site_roles` | 用户-门店-角色关联表 | `id`(PK), `user_id`(FK→users), `site_id`, `role_id`(FK→roles), `created_at``(user_id, site_id, role_id)` 唯一约束 |
| 8 | `auth.user_assistant_binding` | 用户-人员绑定表 | `id`(PK), `user_id`(FK→users), `site_id`, `assistant_id`(可空), `staff_id`(可空), `binding_type`, `created_at` |
### 约束与索引
| 表 | 约束/索引名 | 类型 | 说明 |
|----|-----------|------|------|
| `users` | `uq_users_wx_openid` | UNIQUE | 微信 openid 唯一 |
| `users` | `ix_users_wx_openid` | INDEX | openid 查询加速 |
| `site_code_mapping` | `uq_site_code_mapping_site_code` | UNIQUE | 球房ID 唯一 |
| `site_code_mapping` | `uq_site_code_mapping_site_id` | UNIQUE | site_id 唯一映射 |
| `site_code_mapping` | `ix_site_code_mapping_site_code` | INDEX | site_code 查询加速 |
| `roles` | `uq_roles_code` | UNIQUE | 角色 code 唯一 |
| `permissions` | `uq_permissions_code` | UNIQUE | 权限 code 唯一 |
| `role_permissions` | PK `(role_id, permission_id)` | PRIMARY KEY | 联合主键 |
| `role_permissions` | `fk_role_permissions_role_id` | FK | → `auth.roles(id)` CASCADE |
| `role_permissions` | `fk_role_permissions_permission_id` | FK | → `auth.permissions(id)` CASCADE |
| `user_applications` | `fk_user_applications_user_id` | FK | → `auth.users(id)` CASCADE |
| `user_applications` | `ix_user_applications_user_id` | INDEX | user_id 查询加速 |
| `user_applications` | `ix_user_applications_status` | INDEX | status 过滤加速 |
| `user_site_roles` | `uq_user_site_roles_user_site_role` | UNIQUE | 防止重复分配 |
| `user_site_roles` | `fk_user_site_roles_user_id` | FK | → `auth.users(id)` CASCADE |
| `user_site_roles` | `fk_user_site_roles_role_id` | FK | → `auth.roles(id)` CASCADE |
| `user_site_roles` | `ix_user_site_roles_user_site` | INDEX | (user_id, site_id) 查询加速 |
| `user_assistant_binding` | `fk_user_assistant_binding_user_id` | FK | → `auth.users(id)` CASCADE |
### 种子数据
#### 权限5 条)
| code | name | description |
|------|------|-------------|
| `view_tasks` | 查看任务 | 允许查看任务列表和任务详情 |
| `view_board` | 查看看板 | 允许查看数据看板概览 |
| `view_board_finance` | 查看财务看板 | 允许查看财务相关的数据看板 |
| `view_board_customer` | 查看客户看板 | 允许查看客户相关的数据看板 |
| `view_board_coach` | 查看助教看板 | 允许查看助教相关的数据看板 |
#### 角色4 条)
| code | name | description |
|------|------|-------------|
| `coach` | 助教 | 球房助教,可查看任务和助教看板 |
| `staff` | 员工 | 球房员工,可查看任务和数据看板 |
| `site_admin` | 店铺管理员 | 单店管理员,可查看所有看板 |
| `tenant_admin` | 租户管理员 | 租户级管理员,拥有全部权限 |
#### 角色-权限映射14 条)
| 角色 | 权限列表 | 权限数 |
|------|---------|--------|
| `coach` | `view_tasks`, `view_board_coach` | 2 |
| `staff` | `view_tasks`, `view_board` | 2 |
| `site_admin` | `view_tasks`, `view_board`, `view_board_finance`, `view_board_customer`, `view_board_coach` | 5 |
| `tenant_admin` | `view_tasks`, `view_board`, `view_board_finance`, `view_board_customer`, `view_board_coach` | 5 |
---
## 2. 兼容性影响
| 组件 | 影响 |
|------|------|
| ETL 任务 | 无影响。本次变更仅操作业务库 `auth` Schema不涉及 ETL 库 |
| 后端 API | 直接依赖。FastAPI 后端将基于这些表实现微信登录、用户申请、审核、权限中间件等认证功能 |
| 小程序 | 间接依赖。小程序通过后端 API 间接使用这些表(登录、申请、状态查询) |
| 管理后台 | 间接依赖。管理端通过后端 API 进行申请审核操作 |
| FDW 配置 | 无影响。`fdw_etl` Schema 独立于 `auth`,但人员匹配服务会通过 FDW 查询 ETL 库的助教/员工表 |
| `public` Schema | 无影响。脚本不包含任何对 `public` 的操作 |
| 现有 `auth` Schema | 兼容。`auth` Schema 已由 P1 迁移脚本创建,本次仅在其中新增表,不修改已有对象 |
---
## 3. 回滚策略
按逆序 `DROP TABLE IF EXISTS CASCADE`(迁移脚本末尾已包含注释形式的回滚语句):
```sql
-- 先删除种子数据(如需保留表结构)
DELETE FROM auth.role_permissions
WHERE role_id IN (SELECT id FROM auth.roles WHERE code IN ('coach', 'staff', 'site_admin', 'tenant_admin'))
AND permission_id IN (SELECT id FROM auth.permissions WHERE code IN ('view_tasks', 'view_board', 'view_board_finance', 'view_board_customer', 'view_board_coach'));
DELETE FROM auth.roles WHERE code IN ('coach', 'staff', 'site_admin', 'tenant_admin');
DELETE FROM auth.permissions WHERE code IN ('view_tasks', 'view_board', 'view_board_finance', 'view_board_customer', 'view_board_coach');
-- 删除表按逆序CASCADE 处理外键依赖)
DROP TABLE IF EXISTS auth.user_assistant_binding CASCADE;
DROP TABLE IF EXISTS auth.user_site_roles CASCADE;
DROP TABLE IF EXISTS auth.user_applications CASCADE;
DROP TABLE IF EXISTS auth.role_permissions CASCADE;
DROP TABLE IF EXISTS auth.permissions CASCADE;
DROP TABLE IF EXISTS auth.roles CASCADE;
DROP TABLE IF EXISTS auth.site_code_mapping CASCADE;
DROP TABLE IF EXISTS auth.users CASCADE;
```
注意:`CASCADE` 会级联删除依赖对象。如果表中已有业务数据,需先备份再执行回滚。
---
## 4. 验证 SQL
```sql
-- 1. 验证 auth Schema 下 8 张认证表全部存在
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'auth'
AND table_name IN (
'users', 'user_applications', 'site_code_mapping',
'roles', 'permissions', 'role_permissions',
'user_site_roles', 'user_assistant_binding'
)
ORDER BY table_name;
-- 预期:返回 8 行
-- 2. 验证种子数据5 条权限
SELECT COUNT(*) AS perm_count
FROM auth.permissions
WHERE code IN ('view_tasks', 'view_board', 'view_board_finance', 'view_board_customer', 'view_board_coach');
-- 预期5
-- 3. 验证种子数据4 条角色
SELECT COUNT(*) AS role_count
FROM auth.roles
WHERE code IN ('coach', 'staff', 'site_admin', 'tenant_admin');
-- 预期4
-- 4. 验证角色-权限映射数量
SELECT r.code AS role_code, COUNT(rp.permission_id) AS perm_count
FROM auth.roles r
JOIN auth.role_permissions rp ON r.id = rp.role_id
GROUP BY r.code
ORDER BY r.code;
-- 预期coach=2, site_admin=5, staff=2, tenant_admin=5共 14 条映射)
-- 5. 验证关键约束存在
SELECT conname, contype
FROM pg_constraint
WHERE conrelid IN (
'auth.users'::regclass,
'auth.site_code_mapping'::regclass,
'auth.user_site_roles'::regclass
)
ORDER BY conrelid::regclass::text, conname;
-- 预期:包含 uq_users_wx_openid、uq_site_code_mapping_site_code、uq_site_code_mapping_site_id、uq_user_site_roles_user_site_role 等
```