init: 项目初始提交 - NeoZQYY Monorepo 完整代码
This commit is contained in:
553
.kiro/specs/monorepo-migration/design.md
Normal file
553
.kiro/specs/monorepo-migration/design.md
Normal file
@@ -0,0 +1,553 @@
|
||||
# 设计文档:Monorepo 迁移
|
||||
|
||||
## 概述
|
||||
|
||||
本设计将现有单一 ETL 仓库(`FQ-ETL`)迁移为 Monorepo 单体仓库(`NeoZQYY`),采用一次性搬迁策略。核心设计原则:
|
||||
|
||||
1. **最小破坏性**:ETL 整体平移,保持内部结构不变,仅调整外部引用
|
||||
2. **分层隔离**:通过 uv workspace 实现 Python 包依赖隔离,通过 `.env` 分层实现配置隔离
|
||||
3. **数据库重组**:从现有 4 个 schema(billiards_ods/billiards_dwd/billiards_dws/etl_admin)重组为 6 层 schema(meta/ods/dwd/core/dws/app)
|
||||
4. **渐进式扩展**:第一阶段只建必要骨架,未来扩展点记录在 Roadmap 中
|
||||
|
||||
## 架构
|
||||
|
||||
### 整体架构
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "NeoZQYY Monorepo"
|
||||
subgraph "apps/"
|
||||
ETL["apps/etl/pipelines/feiqiu/"]
|
||||
Backend["apps/backend/ (FastAPI)"]
|
||||
Mini["apps/miniprogram/ (Donut+TDesign)"]
|
||||
Admin["apps/admin-web/ (未来)"]
|
||||
end
|
||||
|
||||
subgraph "packages/"
|
||||
Shared["packages/shared/"]
|
||||
end
|
||||
|
||||
subgraph "gui/"
|
||||
GUI["gui/ (PySide6,过渡期)"]
|
||||
end
|
||||
|
||||
subgraph "db/"
|
||||
ETLDB["db/etl_feiqiu/"]
|
||||
AppDB["db/zqyy_app/"]
|
||||
FDW["db/fdw/"]
|
||||
end
|
||||
end
|
||||
|
||||
ETL --> Shared
|
||||
Backend --> Shared
|
||||
GUI --> Shared
|
||||
Backend --> AppDB
|
||||
ETL --> ETLDB
|
||||
AppDB -.->|postgres_fdw 只读| ETLDB
|
||||
```
|
||||
|
||||
### 数据流架构
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
API["上游 SaaS API"] --> ODS["ods (原始数据)"]
|
||||
ODS --> DWD["dwd (main+EX 明细)"]
|
||||
DWD --> Core["core (统一最小字段集)"]
|
||||
DWD --> DWS["dws (汇总/工资)"]
|
||||
Core --> DWS
|
||||
DWS --> App["app (视图+RLS)"]
|
||||
App -.->|FDW 只读映射| ZqyyApp["zqyy_app DB"]
|
||||
ZqyyApp --> FastAPI["FastAPI 后端"]
|
||||
FastAPI --> MiniApp["微信小程序"]
|
||||
|
||||
subgraph "etl_feiqiu DB"
|
||||
Meta["meta (调度/游标)"]
|
||||
ODS
|
||||
DWD
|
||||
Core
|
||||
DWS
|
||||
App
|
||||
end
|
||||
```
|
||||
|
||||
## 组件与接口
|
||||
|
||||
### 1. 目录结构生成器(Scaffold)
|
||||
|
||||
负责创建 Monorepo 完整目录结构和基础配置文件。
|
||||
|
||||
**输入**:目标路径 `C:\NeoZQYY\`
|
||||
**输出**:完整目录树 + README.md + 配置文件
|
||||
|
||||
**关键行为**:
|
||||
- 创建所有一级和二级目录
|
||||
- 为每个一级目录生成 README.md(作用 + 结构 + Roadmap)
|
||||
- 生成 `.gitignore`、`.kiroignore`、`.env.template`
|
||||
- 初始化 Git 仓库
|
||||
|
||||
### 2. uv Workspace 配置
|
||||
|
||||
**根 `pyproject.toml`**:
|
||||
```toml
|
||||
[project]
|
||||
name = "neozqyy"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.10"
|
||||
|
||||
[tool.uv.workspace]
|
||||
members = [
|
||||
"apps/etl/pipelines/feiqiu",
|
||||
"apps/backend",
|
||||
"packages/shared",
|
||||
"gui",
|
||||
]
|
||||
```
|
||||
|
||||
**子项目 `pyproject.toml` 模式**(以 ETL 为例):
|
||||
```toml
|
||||
[project]
|
||||
name = "etl-feiqiu"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.10"
|
||||
dependencies = [
|
||||
"psycopg2-binary>=2.9.0",
|
||||
"requests>=2.28.0",
|
||||
"python-dateutil>=2.8.0",
|
||||
"tzdata>=2023.0",
|
||||
"python-dotenv",
|
||||
"openpyxl>=3.1.0",
|
||||
"neozqyy-shared",
|
||||
]
|
||||
|
||||
[tool.uv.sources]
|
||||
neozqyy-shared = { workspace = true }
|
||||
```
|
||||
|
||||
### 3. 配置隔离机制
|
||||
|
||||
**分层加载顺序**:
|
||||
```
|
||||
根 .env(公共配置)→ 应用 .env.local(私有覆盖)→ 环境变量 → CLI 参数
|
||||
```
|
||||
|
||||
**实现方式**:
|
||||
- 现有 `AppConfig` 的 `DEFAULTS < ENV < CLI` 模式保持不变
|
||||
- 新增:在 `load_env_overrides()` 中先加载根 `.env`,再加载应用级 `.env.local`
|
||||
- 冲突策略:应用级优先(后加载覆盖先加载)
|
||||
- 缺失检测:在 `_validate()` 中检查必需项,报告缺失项名称
|
||||
|
||||
### 4. ETL 平移策略
|
||||
|
||||
**平移范围**:
|
||||
| 源路径 | 目标路径 | 说明 |
|
||||
|--------|----------|------|
|
||||
| `api/` | `apps/etl/pipelines/feiqiu/api/` | API 客户端 |
|
||||
| `cli/` | `apps/etl/pipelines/feiqiu/cli/` | CLI 入口 |
|
||||
| `config/` | `apps/etl/pipelines/feiqiu/config/` | 配置 |
|
||||
| `loaders/` | `apps/etl/pipelines/feiqiu/loaders/` | 加载器 |
|
||||
| `models/` | `apps/etl/pipelines/feiqiu/models/` | 模型 |
|
||||
| `orchestration/` | `apps/etl/pipelines/feiqiu/orchestration/` | 调度 |
|
||||
| `scd/` | `apps/etl/pipelines/feiqiu/scd/` | SCD2 |
|
||||
| `tasks/` | `apps/etl/pipelines/feiqiu/tasks/` | 任务 |
|
||||
| `utils/` | `apps/etl/pipelines/feiqiu/utils/` | 工具 |
|
||||
| `quality/` | `apps/etl/pipelines/feiqiu/quality/` | 质量检查 |
|
||||
| `tests/` | `apps/etl/pipelines/feiqiu/tests/` | 测试 |
|
||||
| `database/*.sql` | `db/etl_feiqiu/schemas/` | DDL |
|
||||
| `database/migrations/` | `db/etl_feiqiu/migrations/` | 迁移脚本 |
|
||||
| `database/seed_*.sql` | `db/etl_feiqiu/seeds/` | 种子数据 |
|
||||
| `gui/` | `gui/` | GUI(顶层) |
|
||||
|
||||
**import 路径策略**:
|
||||
- ETL 内部使用相对 import(`from .config.settings import AppConfig`)或保持现有绝对 import
|
||||
- `pyproject.toml` 中设置 `pythonpath`,使 `apps/etl/pipelines/feiqiu/` 为 Python 路径根
|
||||
- `pytest.ini` 同步更新 `pythonpath = .`
|
||||
- 目标:ETL 内部代码零修改或最小修改
|
||||
|
||||
### 5. 小程序平移策略
|
||||
|
||||
**平移范围**:
|
||||
| 源路径 | 目标路径 |
|
||||
|--------|----------|
|
||||
| `C:\ZQYY\XCX\`(除 Prototype) | `apps/miniprogram/` |
|
||||
| `C:\ZQYY\XCX\Prototype\` | `docs/h5_ui/` |
|
||||
|
||||
小程序为独立前端项目(Donut + TDesign),不涉及 Python 依赖管理,直接复制即可。
|
||||
|
||||
|
||||
### 6. 数据库 Schema 重组(etl_feiqiu)
|
||||
|
||||
**现有 → 新 schema 映射**:
|
||||
|
||||
| 现有 Schema | 新 Schema | 说明 |
|
||||
|-------------|-----------|------|
|
||||
| `etl_admin` | `meta` | 调度、游标、运行记录 |
|
||||
| `billiards_ods` | `ods` | ODS 原始数据,结构不变 |
|
||||
| `billiards_dwd` | `dwd` | DWD 明细,保留 main+EX 拆分 |
|
||||
| (新增) | `core` | 统一维度/事实最小字段集 |
|
||||
| `billiards_dws` | `dws` | DWS 汇总,结构不变 |
|
||||
| (新增) | `app` | 面向外部的视图/函数 + RLS |
|
||||
|
||||
**core schema 设计原则**:
|
||||
- 仅包含跨系统共享的最小字段集(如会员 ID、姓名、手机号、状态)
|
||||
- 维度表从 DWD 维度表提取核心字段
|
||||
- 事实表从 DWD 事实表提取核心度量
|
||||
- 第一版保持精简,后续按需扩展
|
||||
|
||||
**app schema 设计原则**:
|
||||
- 以视图(VIEW)封装 DWS/Core 层数据
|
||||
- 所有视图启用 RLS,以 `site_id` 过滤
|
||||
- 提供函数接口供 FDW 映射使用
|
||||
- 不存储实际数据,仅做访问层
|
||||
|
||||
**RLS 实现方案**:
|
||||
```sql
|
||||
-- 创建应用角色
|
||||
CREATE ROLE app_reader;
|
||||
|
||||
-- 在 app schema 的视图上启用 RLS
|
||||
ALTER TABLE app.v_member_summary ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- 创建策略:根据会话变量 app.current_site_id 过滤
|
||||
CREATE POLICY site_isolation ON app.v_member_summary
|
||||
FOR SELECT TO app_reader
|
||||
USING (site_id = current_setting('app.current_site_id')::bigint);
|
||||
```
|
||||
|
||||
### 7. 业务数据库设计(zqyy_app)
|
||||
|
||||
**核心表**:
|
||||
- `users`:用户账户(微信 OpenID、手机号、角色)
|
||||
- `roles` / `permissions`:RBAC 权限模型
|
||||
- `user_roles`:用户-角色关联
|
||||
- `tasks`:任务管理(审批流)
|
||||
- `approvals`:审批记录
|
||||
|
||||
**FDW 映射**:
|
||||
```sql
|
||||
-- 在 zqyy_app 中创建外部服务器
|
||||
CREATE SERVER etl_feiqiu_server
|
||||
FOREIGN DATA WRAPPER postgres_fdw
|
||||
OPTIONS (host 'localhost', dbname 'etl_feiqiu', port '5432');
|
||||
|
||||
-- 创建用户映射
|
||||
CREATE USER MAPPING FOR app_user
|
||||
SERVER etl_feiqiu_server
|
||||
OPTIONS (user 'app_reader', password '***');
|
||||
|
||||
-- 导入 app schema 的外部表
|
||||
IMPORT FOREIGN SCHEMA app
|
||||
FROM SERVER etl_feiqiu_server
|
||||
INTO fdw_etl;
|
||||
```
|
||||
|
||||
**约束**:FDW 映射为只读,`zqyy_app` 不存储 ETL 数据副本。
|
||||
|
||||
### 8. FastAPI 后端骨架
|
||||
|
||||
**项目结构**:
|
||||
```
|
||||
apps/backend/
|
||||
├── app/
|
||||
│ ├── __init__.py
|
||||
│ ├── main.py # FastAPI 入口
|
||||
│ ├── config.py # 配置加载
|
||||
│ ├── database.py # 数据库连接
|
||||
│ ├── routers/ # 路由模块
|
||||
│ │ └── __init__.py
|
||||
│ ├── middleware/ # 中间件
|
||||
│ │ └── __init__.py
|
||||
│ └── schemas/ # Pydantic 模型
|
||||
│ └── __init__.py
|
||||
├── tests/
|
||||
│ └── __init__.py
|
||||
├── pyproject.toml
|
||||
└── README.md
|
||||
```
|
||||
|
||||
**关键配置**:
|
||||
- 连接 `zqyy_app` 数据库(通过 FDW 访问 ETL 数据)
|
||||
- OpenAPI 文档自动生成(FastAPI 内置)
|
||||
- 依赖 `packages/shared` 获取通用工具
|
||||
|
||||
### 9. 共享包(packages/shared)
|
||||
|
||||
**模块划分**:
|
||||
```
|
||||
packages/shared/
|
||||
├── src/
|
||||
│ └── neozqyy_shared/
|
||||
│ ├── __init__.py
|
||||
│ ├── enums.py # 字段枚举定义
|
||||
│ ├── money.py # 金额精度工具(CNY, numeric(2))
|
||||
│ └── datetime_utils.py # 时间处理工具
|
||||
├── tests/
|
||||
│ └── __init__.py
|
||||
├── pyproject.toml
|
||||
└── README.md
|
||||
```
|
||||
|
||||
**提取来源**:
|
||||
- `enums.py`:从 ETL 的 `models/` 中提取通用枚举
|
||||
- `money.py`:金额四舍五入、格式化(`Decimal` + `ROUND_HALF_UP`,scale=2)
|
||||
- `datetime_utils.py`:时区转换、日期范围计算(从 `utils/` 提取)
|
||||
|
||||
### 10. .kiro 迁移
|
||||
|
||||
**迁移内容**:
|
||||
- 复制 `.kiro/steering/` 到 Monorepo
|
||||
- 更新 `product.md`:从单一 ETL 视角扩展为 Monorepo 全局视角
|
||||
- 更新 `tech.md`:新增 FastAPI、uv workspace、Donut+TDesign 等技术栈
|
||||
- 更新 `structure-lite.md`:反映 Monorepo 目录结构和模块边界
|
||||
- 更新路径引用:所有 steering 文件中的路径适配新结构
|
||||
|
||||
## 数据模型
|
||||
|
||||
### etl_feiqiu 数据库(六层 Schema)
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
META {
|
||||
bigint run_id PK
|
||||
text task_code
|
||||
timestamptz started_at
|
||||
timestamptz ended_at
|
||||
text status
|
||||
jsonb result_summary
|
||||
}
|
||||
|
||||
META ||--o{ ODS : "调度触发"
|
||||
|
||||
ODS {
|
||||
bigint id PK
|
||||
text content_hash PK
|
||||
jsonb payload
|
||||
text source_endpoint
|
||||
timestamptz fetched_at
|
||||
}
|
||||
|
||||
ODS ||--o{ DWD : "清洗装载"
|
||||
|
||||
DWD {
|
||||
bigint id PK
|
||||
timestamptz scd2_start_time
|
||||
timestamptz scd2_end_time
|
||||
int scd2_is_current
|
||||
int scd2_version
|
||||
}
|
||||
|
||||
DWD ||--o{ CORE : "提取最小字段集"
|
||||
|
||||
CORE {
|
||||
bigint id PK
|
||||
text name
|
||||
bigint site_id
|
||||
}
|
||||
|
||||
DWD ||--o{ DWS : "汇总聚合"
|
||||
CORE ||--o{ DWS : "汇总聚合"
|
||||
|
||||
DWS {
|
||||
bigint id PK
|
||||
date stat_date
|
||||
numeric amount
|
||||
bigint site_id
|
||||
}
|
||||
|
||||
DWS ||--o{ APP : "视图封装"
|
||||
|
||||
APP {
|
||||
text view_name
|
||||
text rls_policy
|
||||
}
|
||||
```
|
||||
|
||||
### zqyy_app 数据库
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
USERS {
|
||||
bigint id PK
|
||||
text wx_openid UK
|
||||
text mobile
|
||||
text nickname
|
||||
int status
|
||||
timestamptz created_at
|
||||
}
|
||||
|
||||
ROLES {
|
||||
int id PK
|
||||
text name UK
|
||||
text description
|
||||
}
|
||||
|
||||
USER_ROLES {
|
||||
bigint user_id FK
|
||||
int role_id FK
|
||||
}
|
||||
|
||||
PERMISSIONS {
|
||||
int id PK
|
||||
text resource
|
||||
text action
|
||||
}
|
||||
|
||||
ROLE_PERMISSIONS {
|
||||
int role_id FK
|
||||
int permission_id FK
|
||||
}
|
||||
|
||||
USERS ||--o{ USER_ROLES : "拥有"
|
||||
ROLES ||--o{ USER_ROLES : "分配给"
|
||||
ROLES ||--o{ ROLE_PERMISSIONS : "包含"
|
||||
PERMISSIONS ||--o{ ROLE_PERMISSIONS : "授予"
|
||||
|
||||
FDW_ETL_VIEWS {
|
||||
text foreign_table_name
|
||||
text source_schema
|
||||
text mapping_type
|
||||
}
|
||||
```
|
||||
|
||||
### 配置分层模型
|
||||
|
||||
```
|
||||
优先级(低 → 高):
|
||||
┌─────────────────────────────┐
|
||||
│ 根 .env(公共配置模板) │ DB_HOST, DB_PORT, TIMEZONE
|
||||
├─────────────────────────────┤
|
||||
│ 应用 .env.local(私有覆盖) │ DB_NAME, DB_PASSWORD, API_TOKEN
|
||||
├─────────────────────────────┤
|
||||
│ 环境变量 │ 运行时覆盖
|
||||
├─────────────────────────────┤
|
||||
│ CLI 参数 │ 最高优先级
|
||||
└─────────────────────────────┘
|
||||
```
|
||||
|
||||
|
||||
## 正确性属性
|
||||
|
||||
*属性是系统在所有有效执行中都应保持为真的特征或行为——本质上是关于系统应该做什么的形式化陈述。属性是人类可读规格与机器可验证正确性保证之间的桥梁。*
|
||||
|
||||
### Property 1: README.md 结构完整性
|
||||
|
||||
*对于任意* Monorepo 一级目录,其 README.md 文件应存在且包含"作用说明"、"结构描述"和"Roadmap"三个段落。
|
||||
|
||||
**Validates: Requirements 1.5**
|
||||
|
||||
### Property 2: Python 子项目配置完整性
|
||||
|
||||
*对于任意* uv workspace 声明的 Python 子项目成员,该子项目目录下应存在独立的 `pyproject.toml` 文件,且文件中包含 `[project]` 段落。
|
||||
|
||||
**Validates: Requirements 3.2**
|
||||
|
||||
### Property 3: 配置优先级 - .env.local 覆盖
|
||||
|
||||
*对于任意*配置项名称和两个不同的值,当根 `.env` 和应用 `.env.local` 都定义了该配置项时,配置加载器返回的值应等于 `.env.local` 中的值。
|
||||
|
||||
**Validates: Requirements 4.3**
|
||||
|
||||
### Property 4: 必需配置缺失检测
|
||||
|
||||
*对于任意*必需配置项,当所有配置层级(.env、.env.local、环境变量、CLI)均未提供该项时,配置加载器应抛出错误,且错误信息中包含该缺失配置项的名称。
|
||||
|
||||
**Validates: Requirements 4.4**
|
||||
|
||||
### Property 5: 文件迁移完整性
|
||||
|
||||
*对于任意*源-目标目录映射关系(ETL 业务代码、database 文件、tests 目录),源目录中的每个文件在目标目录的对应位置都应存在且内容一致。
|
||||
|
||||
**Validates: Requirements 5.1, 5.2, 5.3**
|
||||
|
||||
### Property 6: Schema 表定义迁移完整性
|
||||
|
||||
*对于任意*现有数据库 schema(billiards_ods、billiards_dws)中的表,新 schema(ods、dws)的 DDL 文件中应包含该表的 CREATE TABLE 定义。
|
||||
|
||||
**Validates: Requirements 7.3, 7.6**
|
||||
|
||||
### Property 7: Core schema 最小字段集
|
||||
|
||||
*对于任意* core schema 中的表,其字段数量应严格少于对应 dwd schema 中同名(或对应)表的字段数量。
|
||||
|
||||
**Validates: Requirements 7.5**
|
||||
|
||||
### Property 8: 测试数据库结构一致性
|
||||
|
||||
*对于任意*生产数据库(etl_feiqiu、zqyy_app)中的 schema 和表定义,对应的测试数据库(test_etl_feiqiu、test_zqyy_app)中应存在相同的 schema 和表结构。
|
||||
|
||||
**Validates: Requirements 9.1, 9.2**
|
||||
|
||||
### Property 9: Steering 文件路径更新
|
||||
|
||||
*对于任意* `.kiro/steering/` 目录下的文件,文件内容中不应包含旧仓库路径引用(如 `FQ-ETL`、`C:\ZQYY\FQ-ETL`)。
|
||||
|
||||
**Validates: Requirements 10.2**
|
||||
|
||||
### Property 10: 业务表 site_id 字段存在性
|
||||
|
||||
*对于任意* app schema 中的业务视图和 dws/core schema 中的业务表,其定义中应包含 `site_id` 字段。
|
||||
|
||||
**Validates: Requirements 13.1**
|
||||
|
||||
### Property 11: RLS 按 site_id 隔离
|
||||
|
||||
*对于任意* app schema 中启用了 RLS 的视图,当会话变量 `app.current_site_id` 设置为某个门店 ID 时,查询结果应仅包含该 `site_id` 的数据行。
|
||||
|
||||
**Validates: Requirements 13.2**
|
||||
|
||||
## 错误处理
|
||||
|
||||
### 配置错误
|
||||
- **缺失必需配置**:启动时立即报错,列出所有缺失项名称,不启动服务
|
||||
- **配置值格式错误**:报告具体的配置项路径和期望格式
|
||||
- **.env 文件不存在**:使用默认值继续,不报错(.env.template 仅为模板)
|
||||
|
||||
### 迁移错误
|
||||
- **源文件不存在**:记录警告日志,继续迁移其他文件,最终汇总报告缺失文件列表
|
||||
- **目标目录已存在**:提示用户确认是否覆盖,默认不覆盖
|
||||
- **import 路径修复失败**:记录错误日志,标记需要手动修复的文件
|
||||
|
||||
### 数据库错误
|
||||
- **Schema 创建失败**:回滚当前 schema 的所有 DDL,报告失败原因
|
||||
- **FDW 连接失败**:记录错误日志,不影响本地表的正常使用
|
||||
- **RLS 策略创建失败**:回滚策略创建,报告受影响的表
|
||||
|
||||
### 测试数据库错误
|
||||
- **结构不一致**:提供 diff 工具比较生产与测试库结构差异
|
||||
- **数据迁移失败**:回滚到迁移前状态,报告失败的表和原因
|
||||
|
||||
## 测试策略
|
||||
|
||||
### 测试框架
|
||||
- **单元测试**:`pytest`(Python 子项目)
|
||||
- **属性测试**:`hypothesis`(Python 属性测试库)
|
||||
- 每个属性测试配置最少 100 次迭代
|
||||
|
||||
### 单元测试覆盖
|
||||
|
||||
1. **Scaffold 测试**:验证目录创建、文件生成的具体示例
|
||||
2. **配置加载器测试**:验证分层加载、冲突处理、缺失检测的边界情况
|
||||
3. **迁移脚本测试**:验证文件复制、路径映射的具体场景
|
||||
4. **DDL 语法测试**:验证生成的 SQL 语法正确性
|
||||
|
||||
### 属性测试覆盖
|
||||
|
||||
每个属性测试必须引用设计文档中的属性编号:
|
||||
|
||||
- **Feature: monorepo-migration, Property 1: README.md 结构完整性** — 验证所有一级目录 README 包含必需段落
|
||||
- **Feature: monorepo-migration, Property 2: Python 子项目配置完整性** — 验证所有 workspace 成员有 pyproject.toml
|
||||
- **Feature: monorepo-migration, Property 3: 配置优先级** — 生成随机配置项,验证 .env.local 覆盖行为
|
||||
- **Feature: monorepo-migration, Property 4: 必需配置缺失检测** — 生成随机必需项组合,验证缺失报错
|
||||
- **Feature: monorepo-migration, Property 5: 文件迁移完整性** — 验证源-目标文件映射的完整性
|
||||
- **Feature: monorepo-migration, Property 6: Schema 表定义迁移完整性** — 验证现有表在新 DDL 中存在
|
||||
- **Feature: monorepo-migration, Property 7: Core schema 最小字段集** — 验证 core 表字段数少于 dwd
|
||||
- **Feature: monorepo-migration, Property 8: 测试数据库结构一致性** — 验证测试库与生产库结构相同
|
||||
- **Feature: monorepo-migration, Property 9: Steering 文件路径更新** — 验证无旧路径残留
|
||||
- **Feature: monorepo-migration, Property 10: 业务表 site_id 存在性** — 验证业务表包含 site_id
|
||||
- **Feature: monorepo-migration, Property 11: RLS 隔离** — 验证 RLS 按 site_id 过滤(集成测试)
|
||||
|
||||
### 集成测试
|
||||
|
||||
- **ETL 运行验证**:在新目录结构下运行 `pytest tests/unit`,确保所有现有测试通过
|
||||
- **数据库 Schema 验证**:在测试数据库上执行 DDL,验证 schema 创建成功
|
||||
- **FDW 连接验证**:验证 zqyy_app 通过 FDW 可读取 etl_feiqiu 的 app schema 数据
|
||||
- **uv workspace 验证**:运行 `uv sync`,验证所有子项目依赖正确解析
|
||||
Reference in New Issue
Block a user