Files
gongxue-base/docs/refactor/pocketbase-to-supabase-mapping.md
2026-06-29 11:06:31 +08:00

114 lines
4.4 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.

# PocketBase 到 Supabase 迁移映射
## 迁移原则
- 保留 PocketBase 旧 ID 到 `legacy_id`,新系统主键统一用 UUID。
- 所有租户内业务表都带 `tenant_id`
- 旧表原始 JSON 进入 `pb_raw_records` 前默认脱敏,保证可追溯但不泄露密钥。
- 旧集合里不符合商用规范的字段不得直接映射到正式表,必须经过清洗和拆表。
- 第一阶段标准化导入覆盖核心商用链路租户、用户、题库目录、题目、订单、支付、权益、激活码、优惠券、词库、手册、运营内容、分数线、视频解析、CRM 和推广关系。未覆盖集合先 raw import并在 `pb_import_issues` 里记录风险。
- `users.isSvip``svipExpiry``svipRegions` 最终迁移为 `entitlements`
- `users.stats.favorites``wrongBook` 最终迁移为 `favorite_questions``wrong_questions`
- `settings` 中的密钥类配置必须进入 `app_private.tenant_secrets` 或外部 Vault不进入 `public` schema。
## 核心映射
| PocketBase | PostgreSQL | 说明 |
| --- | --- | --- |
| `tenant_config` | `tenants` / `tenant_branding` / `tenant_settings` | 从单实例配置升级为平台租户配置 |
| `users` | `platform_users` / `tenant_memberships` / `student_profiles` / `user_identities` | 用户身份、租户角色、学生资料拆分 |
| `regions` | `regions` | 增加 `tenant_id` |
| `region_modules` | `region_modules` | 增加 `tenant_id` |
| `module_nodes` | `module_nodes` | 作为后续题库层级主结构 |
| `subjects` | `subjects` | 保留旧结构兼容,逐步和 `module_nodes` 对齐 |
| `categories` | `categories` | 保留旧结构兼容 |
| `questions` | `questions` / `question_versions` | 题目实体和题目内容版本拆分 |
| `orders` | `orders` / `order_items` / `payments` / `payment_events` | 订单与支付流水分离 |
| `svip_plans` | `svip_plans` | 金额改为分 |
| `codes` | `activation_codes` | 激活码表 |
| `code_batches` | `code_batches` | 批次表 |
| `coupons` | `coupons` | 优惠券 |
| `coupon_redemptions` | `coupon_redemptions` | 兑换流水 |
| `vocabulary_units` | `vocabulary_units` | 背单词单元 |
| `vocabulary` | `vocabulary_words` | 单词表 |
| `handbook_*` | `handbook_*` | 手册内容 |
| `banners` / `faqs` / `announcements` | 同名表 | 运营内容 |
| `settings` | `tenant_settings` / `tenant_payment_accounts` | 拆分公开配置、私密配置、支付配置 |
| `crm_config.secret` | `app_private.tenant_secrets` | 公共表只保留 `secret_ref` |
| `users.stats.favorites` | `favorite_questions` | 迁移为关系表 |
| `users.stats.wrongBook` | `wrong_questions` | 迁移为关系表 |
| `users.isSvip` / `svipExpiry` / `svipRegions` | `entitlements` | 迁移为租户/地区范围权益 |
| `user_word_progress` / `user_word_favorites` | 同名规范表 | 关联到 `platform_users``vocabulary_words` |
| `app_assets` / `images` | `content_assets` | 统一素材索引 |
## 导入命令
先安装导入器依赖:
```bash
cd scripts/import-pocketbase
copy .env.example .env
npm install
```
查看 schema 摘要:
```bash
npm run schema:summary
npm run schema:risk
```
把 PocketBase 导出的集合 JSON 放到 `pb_export`
```text
pb_export/
users.json
regions.json
questions.json
```
先执行不写数据库的 dry-run
```bash
npm run import:dry-run
```
根目录也可以执行:
```bash
npm run pb:import:dry-run
```
dry-run 会检查:
- 导出目录和 JSON 文件格式。
- 核心集合是否缺失。
- 旧记录 `id` 是否缺失或重复。
-`pb_schema.json` 中的 relation 是否能在导出数据里找到目标记录。
- `settings``crm_config`、用户资料等位置是否存在敏感字段。
- 哪些集合当前已有规范化 mapper哪些集合仍未映射。
存在 `blocker` 时不要执行正式导入;先修导出、补 mapper 或记录业务处理结论。
执行正式导入:
```bash
npm run import:json
```
导入后执行验证:
```bash
npm run import:validate
```
根目录也可以执行:
```bash
npm run pb:import:dry-run
npm run pb:import:json
npm run pb:import:validate
```
导入器会先把所有 JSON 放入 `pb_raw_records`,并默认对敏感字段脱敏;然后按依赖顺序标准化导入业务表。上线前必须处理 `FAIL` 项;`WARN` 项通常表示旧数据关系缺失,例如旧题目引用了不存在的章节,需要业务确认是否可接受。