# 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 ``` 执行导入: ```bash npm run import:json ``` 导入后执行验证: ```bash npm run import:validate ``` 根目录也可以执行: ```bash npm run pb:import:json npm run pb:import:validate ``` 导入器会先把所有 JSON 放入 `pb_raw_records`,并默认对敏感字段脱敏;然后按依赖顺序标准化导入业务表。上线前必须处理 `FAIL` 项;`WARN` 项通常表示旧数据关系缺失,例如旧题目引用了不存在的章节,需要业务确认是否可接受。