MODEL.md
2.65 KB
@drama/db 表关系设计纪律
本文件兑现任务文档 §2 验收标准 6:列出每张业务表到
users表的外键可达路径,证明「user 级联可整体删除 / 可导出」的口子(架构基线 §10.1「数据可删除」)在一期就以纯纪律留好——二期实现cascadeDeleteUser(db, userId)/exportUser(db, userId)时无需穿透改表结构。
根锚:users
users 是全库唯一的级联根。本包 src/db/tables/users.cjs 提供这一张跨域共享的根表。其余业务表由各领域包(@drama/auth / @drama/account / @drama/billing / @drama/payment / @drama/email / ...)自己的 src/db/tables/* 提供。
硬约束(领域包建表时必须遵守)
每张业务表必须满足下列其一,保证到 users.id 有可遍历的外键路径:
- 直接挂:表含
user_id BIGINT外键,references users.id。适用于 user 直属数据(资料、积分账户、订阅、播放历史、收藏、创建的 drama)。 - 一层可达:表经父表的外键间接可达
users。例如episode.drama_id → drama.id,而drama.user_id → users.id;则episode经drama一层可达。 - 全局共享、无属主:不挂 user 的纯字典 / 素材池(如官方种子素材、系统枚举)显式标注「无属主」,级联删除时跳过、导出时不含。这类表必须在其领域包
MODEL.md中明示,避免被误判为「漏挂 user_id」。
级联可达路径示意(领域表二期落地后填充)
一期本包只锚定根表,下表是约定示意(实际由各领域包 table definition 落地并在各自文档登记其可达路径):
users←drama.user_id(直接)drama←episode.drama_id(一层经 drama 到 users)drama←play_record.drama_id+play_record.user_id(直接 + 冗余直挂,便于按 user 整段删)users←subscription.user_id/credit_account.user_id/favorite.user_id(直接)
软删除约定
deleted_at TIMESTAMP NULL 为软删除标记,与 helpers.notDeleted(qb)(where deleted_at is null)配套。需要软删除语义的表统一用此列名,保证 helper 复用。
二期实现留口子(本包不实现,仅此设计支撑)
cascadeDeleteUser(db, userId):从users.id出发,沿上述外键路径自顶向下删除(或软删)所有归属该 user 的行。exportUser(db, userId):同一遍历,收集而非删除,产出可导出的 user 数据快照(GDPR/CCPA 数据导出)。
只要领域包建表时遵守上述硬约束,这两个遍历器二期可纯靠外键元数据驱动实现,无需回头改表结构。