Files
codex-bot 8b650fdf78
PROMPT CI and deployment / verify-and-deploy (push) Successful in 8m18s
Build PROMPT media library with masonry UI and persistent PostgreSQL S3 storage
2026-10-22 22:18:11 +08:00

3.1 KiB

数据模型与网址约定

唯一具有树形结构的是 tags。素材、素材包和对象存储路径都不组成目录树。

erDiagram
  posts ||--o{ post_assets : references
  assets ||--o{ post_assets : reused_by
  posts ||--o{ post_tags : classified_by
  tags ||--o{ post_tags : groups
  assets ||--o{ asset_tags : classified_by
  tags ||--o{ asset_tags : groups
  tags o|--o{ tags : single_parent
  assets ||--o{ asset_variants : owns
  assets ||--o| media_jobs : processed_by
  • assets:每个图片、视频、独立音频或文字片段有稳定 UUID。二进制引用 S3 key;文字保存在 body。宽高、时长、原件是否有声音、处理状态记录在素材上。SHA256 用于识别内容,但不会把不同导入擅自合并。同一素材可以被任意多个素材包引用。
  • asset_variants:视频衍生物,以 (asset_id, role) 唯一。无声画面、原视频音轨和封面始终挂在原视频下。没有 audio 类型的新资产,因此音轨不会混入独立音频素材。
  • posts:展示单位,稳定 slug、类型、创建时间、标题等元数据。cover_asset_id 是图片指针;page_key 只引用代码注册的图文或动态组件,不保存可执行代码。正文和描述不是 post 上的重复字段。
  • post_assets:记录素材 ID、展示顺序及 content/caption 角色。删除素材包只移除关联,不删除素材;有引用的素材不能直接删除。
  • tags:相邻表结构,每个节点仅一个 parent;数据库约束拒绝自引用和环,同层 slug 唯一,包括根节点。新增、移动时用事务锁串行化树修改。
  • asset_tags、post_tags:两套多对多关联。导入时可同时给素材和素材包分类,之后互相独立。修改素材分类不会悄悄改动所有引用它的素材包。
  • media_jobs:数据库任务队列,支持并发安全领取、崩溃租约恢复、三次重试。状态变化不会创建新的素材包。
  • contribution_events:以细分事件作为事实记录,展示时按日聚合。subject ID 不强制外键,历史事件不因对象删除而消失。唯一幂等键用于将来防止重复计数。当前不配置任何自动触发器。

分类网址是“内容类型入口 + 从根到叶的 slug 链”。例如标签树 style → white-line 可以同时用于 /images/style/white-line 和 /videos/style/white-line。同一个标签跨不同内容类型共享其身份,内容类型入口只负责过滤素材包类型。父标签筛选包含后代标签;结果按 post 去重。

素材包详情始终使用 /p/<slug>,更换分类不改变它的网址。同一份二进制在多个素材包中仍只有一个 asset ID 和对象引用。

媒体包必须有对应类型的非空文件引用才进入瀑布流;图文和动态作品必须有已注册的组件。只有标题、空关联或未知组件的对象都被过滤。不存在的分类网址返回 404,不退回全部内容。

迁移保存在 db/ 并在 schema_migrations 记录;迁移过程加会话锁。不能通过应用回退删除数据库或对象卷。