02-当前系统现实
02-当前系统现实
Section titled “02-当前系统现实”文档性质:当前系统唯一真相源 + 目标理想差距总账
用途:统一记录 Yomiya 当前服务端已经存在的内容对象、字段、关系、标签机制、唯一性约束,以及后续研究要补齐的目标理想与行动项
适用范围:01-当前目标与范围.md、03-新资源入库流程.md、04-内容样本池.md 之间所有涉及“当前现实 / 目标理想 / 差距动作”的讨论
规则:
- 凡涉及当前服务端已存在什么对象、字段、关系、标签、唯一性约束,以本文件为准
- 凡涉及目标理想与改造动作,也先回写本文件,再同步
03-新资源入库流程.md或04-内容样本池.md archive/specs/负责保留旧规格,不负责证明某个对象已经在服务端落库archive/research/负责保留研究样本与判断,不直接改写当前现实 最后更新:2026-04-06
1. 最小白先记住这 8 句话
Section titled “1. 最小白先记住这 8 句话”如果第一次读 Yomiya 内容系统,先只记这 8 句:
- 当前真正承载内容条目的正式主表,还是
news - 当前唯一长期归属是
news.channel_id -> channels - 当前
scene不是news主表字段,而是scenes + news_scenes关系层能力 - 当前公开 Tag 机制只正式暴露
level / scene / premium news.source当前只表达进入路径:news / imports,不表达平台来源- 当前服务端已经正式区分
collected/news与user_imported/imports两条内容进入路径 - 我们提供的官方内容会跑风控、难度、scene;用户导入内容当前不会跑风控和难度
- 当前前台公开内容读取默认只取
source = news,且服务端里还没有正式collections / collection_items / series / topic表
2. 当前真相源的证据来自哪里
Section titled “2. 当前真相源的证据来自哪里”本文件不靠概念讨论落结论,主要证据来自 yomiya-service 当前仓库。
| 证据文件 | 说明 | 本文件用它证明什么 |
|---|---|---|
internal/infrastructure/database/migration/20250519052734_news_sentences_tokens.sql | 初始 news 表结构 | news 是当前正式内容主表;visibility 早已存在 |
internal/infrastructure/database/migration/20250729092341_create_channels.sql | channels 表 migration | channels 已正式存在,且 channels.name 有唯一键 |
internal/infrastructure/database/migration/20250729210800_create_scenes.sql | scenes 表 migration | scenes 已正式存在,但只有索引,没有三元唯一键 |
internal/infrastructure/database/migration/20250813190617_create_news_scenes.sql | news_scenes 关系表 migration | scene 当前通过关系表挂在 news 上,且 (news_id, scene_id) 有唯一约束 |
internal/infrastructure/database/migration/20260109120000_create_content_import_tables.sql | user_content_imports 与 transcription_tasks migration | 用户导入链路当前已有正式支持对象,不只是文档概念 |
internal/infrastructure/database/migration/20260120000000_add_source_and_type_to_news.sql | news.source 与 news.type migration | source 当前现实是 news / imports,type 当前现实是 webpage / video / audio |
internal/application/dto/news.go | 对外 DTO | 当前公开 TagType 只有 level / scene / premium;Admin API 暴露 primary_scenes / secondary_scenes |
internal/application/news.go | DTO 组装逻辑 | scene 标签来自 news_scenes;premium 标签来自 visibility 衍生 |
internal/application/content_processing/profile_resolver.go | 内容处理 profile 解析 | 当前已经正式区分官方供给与用户导入的处理策略;官方内容会跑风控 / 难度,用户导入不会 |
internal/application/content_processing/raw_lifecycle.go | Raw 内容状态收口 | 风控结果当前会落到 raw_news.status / risk_check_status,被拦截内容会进入 REJECTED / BLOCKED |
internal/repository/news_repo_impl.go | 前台公开内容查询 | 当前公开内容读取默认只取 news.source = news,imports 不会自动进入官方分发池 |
internal/infrastructure/database/migration/20260328074037_create_youtube_channels.sql | YouTube 频道映射表 | 当前只有 YouTube 有正式外部品牌映射表,播客 / B 站还没有统一品牌层落库 |
internal/crawler/youtube_channel/youtube_channel_crawler.go | 系统级 YouTube 自动抓取 | 系统抓取会直接进入统一处理链路,但不会创建 user_content_imports 记录 |
补充判断:
- 截至 2026-04-04,
yomiya-service当前 migration 树里没有collections、collection_items、series、topics相关正式 DDL - 当前官方分发链路与用户导入链路已经在服务端分开,但“分发资格”仍未独立成正式字段或状态机
- 因此,
Collection / Series / Topic现在仍属于目标理想与执行目标,不是当前后端现实
3. 为什么要新增这份文件
Section titled “3. 为什么要新增这份文件”| 变更对象 | 动作 | 现在的问题 | 为什么这样改 | 不这样改会怎样 | 关联系统证据 | 后续动作 |
|---|---|---|---|---|---|---|
| 当前系统现实 | 新增唯一真相源 | 目标文档和研究文档都可能写“系统现在有什么”,口径容易漂移 | 把“现实 / 理想 / 差距动作”收进一份总账,后续只维护一处 | 新研究一进来就会继续复制旧误差 | news / channels / scenes / news_scenes 当前模型已经能给出真实边界 | 后续所有结构升级先回写本文件 |
yomiya-canonical-naming.md | 降级为名词冻结 | 命名文档里写了很多“目标承载”,容易被误读成当前已经存在 | 命名继续保留,但不再承担“当前现实证明”职责 | 团队会把“应该叫什么”误读成“现在已经怎么建模” | 服务端当前没有 collections / series / topic 正式表 | 名词继续保留,现实统一引用本文件 |
yomiya-implementation-spec-core.md | 聚焦执行目标 | 实施规格里既写目标页面与目标容器,又容易被当成当前后端真相 | 让它只回答“当前阶段按什么目标落地”,不再自证现实 | 研发会把目标表结构当成现网事实,研究会把现网事实当成目标已完成 | 当前 news 现实与 collections 目标并不在同一层 | 以后任何目标模型先在本文件登记 Gap + Actions |
03 / 04 | 固定为研究映射层 | 研究文档为了方便,经常把平台字段、研究字段和系统正式字段混写 | 让研究层只负责样本、判断、映射建议,不再自创系统字段真相 | 后续 YouTube / 播客研究越多,误差越会扩散 | source、type、scene 的现实含义已经和研究层旧写法不一致 | 研究稳定后,先回写本文件再改研究文档 |
4. 当前正式对象总表
Section titled “4. 当前正式对象总表”| 对象 | 当前现实 | 关键字段 / 关系 | 当前约束 | 状态 |
|---|---|---|---|---|
News | 当前正式内容主对象 | id、news_id、level、channel_id、source、type、visibility | 主键在 id;news_id 当前未见数据库唯一键 | 已完成 |
Channel | 当前正式长期归属层 | id、name、display_name、description、is_visible | channels.name 唯一 | 已完成 |
Scene | 当前正式场景标签主表 | id、category、scene、sub_scene、available | 只有索引,没有 (category, scene, sub_scene) 唯一键 | 已完成 |
NewsScene | 当前 news 与 scene 关系表 | news_id、scene_id、scene_primary | (news_id, scene_id) 唯一;scene_primary 当前只区分 primary / secondary | 已完成 |
Tag DTO | 当前对外公开标签机制 | TagTypeLevel、TagTypeScene、TagTypePremium | 公开层只暴露这 3 类 TagType | 已完成 |
RawNews | 当前统一原始内容暂存对象 | unique_id、status、data、risk_check_status、channel | status 当前可到 REJECTED;risk_check_status 当前可到 BLOCKED | 已完成 |
UserContentImport | 当前正式用户导入记录对象 | pluto_user_id、unique_id、channel_id、content_type、url、news_id | 只承接用户导入,不承接系统抓取 | 已完成 |
TranscriptionTask | 当前统一转写 / 重处理任务对象 | unique_id、status、content_type、news_id、error_code | unique_id 唯一 | 已完成 |
YouTubeChannel | 当前唯一正式外部品牌映射表 | youtube_channel_id、name、channel_id | youtube_channel_id 唯一,映射到内部 channels | 已完成 |
明确不应误读为“当前正式对象”的概念:
CollectionSeriesTopic- 跨媒介统一的
Source Brand - 跨媒介统一的
Series Unit
这些概念现在仍然属于目标理想 / 研究映射 / 后续建模动作,不是当前服务端现实。
4.1 当前正式对象关系图
Section titled “4.1 当前正式对象关系图”flowchart LR A[News] -->|channel_id| B[Channel] A -->|news_id / source / type / visibility| A1[正式内容核心字段] A --> C[NewsScene] C --> D[Scene] A --> E[公开 DTO] E --> F[level Tag] E --> G[scene Tag] E --> H[premium Tag] I[YouTubeChannel] -->|映射到内部 channel| B J[UserContentImport] -->|导入后回填 news_id| A K[TranscriptionTask] -->|作用于 news| A
这张图的重点是:news 现在仍是正式主内容对象;scene 通过关系表挂接;YouTubeChannel 只是外部品牌映射,不是新的内容主表。
5. 当前正式字段冻结表
Section titled “5. 当前正式字段冻结表”这一节只写“当前已经存在什么”,不写“理论上应该有什么”。
| 字段 / 能力 | 当前现实 | 目标理想 | 差距与动作 | 状态 |
|---|---|---|---|---|
news.id | 当前正式主键 | 继续保持主键 | 无需改动 | 已完成 |
news.news_id | 当前有字段,用于上游内容 ID,但未见数据库唯一键 | 明确它到底是“外部来源唯一 ID”还是“可重复抓取源 ID” | 需要补一条唯一性策略:要么加唯一键,要么文档明确允许重复并给出去重规则 | 待定义 |
news.channel_id | 当前正式长期归属字段,指向 channels.id,可为空 | 继续作为唯一长期归属层 | 需要补“空值何时允许、何时必须补齐”的执行规则 | 已完成 |
news.source | 当前现实只表示内容来源类型:news / imports | 如果未来要表达平台来源,不能复用这个字段 | 不允许把 source 直接拿来表示 podcast / youtube / bilibili;平台信息应留在研究层或后续独立品牌层 | 已完成 |
news.type | 当前现实值域来自服务端 migration:webpage / video / audio | 后续若要支持更复杂媒介语义,应先评估是否真要扩字段 | 03 / 04 不能把 text / mixed 写成当前系统已存在值;若研究发现需要,先回写 Gap 表 | 已完成 |
news.level | 当前正式难度字段是数值型;公开层已稳定映射 N5 / N4 / N3 / N2 / N1 / N1+ | 继续保持单一难度字段,不额外并行造第二套等级体系 | 研究层可暂时写 待定,但 待定 不等于正式系统值 | 已完成 |
news.visibility | 当前正式可见性字段,公开枚举已存在 | 继续保留内容可见性能力 | 不能把 visibility 直接等同于“能否被分发” | 已完成 |
scene | 当前不是 news 主表字段,而是 scenes + news_scenes 关系层能力 | 继续沿用关系层表达场景标签 | 所有文档都不能把 scene 写成当前正式的 news.scene 列 | 已完成 |
primary_scenes / secondary_scenes | 当前已在 Admin DTO 与更新逻辑中暴露,但它们是 API 表达,不是 news 表字段 | 继续作为后台编辑接口表达 | 文档必须明确这是“关系层编辑接口”,不是“主表新增两列” | 已完成 |
6. 当前正式处理策略冻结表
Section titled “6. 当前正式处理策略冻结表”| 处理能力 | 当前现实 | 目标理想 | 差距与动作 | 状态 |
|---|---|---|---|---|
| 内容进入路径 | 当前持久化边界仍使用 news.source = news / imports;应用层内部已映射为 collected / user_imported | 继续保持“进入路径”和“平台来源”分离 | 不能把 source 重写成平台名;平台来源仍应由 channel / source_brand 一侧解决 | 已完成 |
| 官方供给处理 | 当前 collected 内容会跑 risk_review -> difficulty -> add_scene,并走通知型发布 | 继续作为官方内容的默认处理链路 | 文档应明确这是“我们提供的内容”的现实,不要再把它遗漏成只有字段扩充 | 已完成 |
| 用户导入处理 | 当前 user_imported 内容会走统一处理流水线,但 NeedRiskReview=false、NeedDifficultyLevel=false、PublishModeSilent | 继续和官方供给分开 | 文档不能把用户导入链路误写成官方内容扩充链路 | 已完成 |
| 风控落库 | 当前风控结果会写回 raw_news.status / risk_check_status;被拦截内容会进入 REJECTED / BLOCKED | 继续作为官方供给的前置准入信息 | 后续若要讨论“分发资格”,不能直接拿 risk_check_status 代替全部分发规则 | 已完成 |
| 前台公开读取 | 当前公开内容列表默认只查询 source = news | 继续把 imports 排除在官方内容池之外 | 这说明“用户导入内容已落到 news”不等于“自动进入官方分发层” | 已完成 |
6.1 当前进入路径与处理差异图
Section titled “6.1 当前进入路径与处理差异图”flowchart LR A[官方供给 / 系统抓取] --> B[RawNews] Y[YouTube channel crawler] --> B B --> C[risk_review] C --> D[difficulty] D --> E[add_scene] E --> F[写入 news<br/>source = news] G[用户导入] --> H[UserContentImport] H --> I[统一处理流水线] I --> J[写入 news<br/>source = imports<br/>跳过 risk_review / difficulty] F --> K[前台公开查询] J --> K K -->|默认只取| L[source = news]
这张图专门解释 3 个最容易混掉的事实:
- 官方供给和用户导入最终都会落到
news - 但两条处理策略并不相同
- 前台默认只取
source = news,所以imports不会自动变成官方分发内容
7. 当前正式标签机制冻结表
Section titled “7. 当前正式标签机制冻结表”| 标签能力 | 当前现实 | 目标理想 | 差距与动作 | 状态 |
|---|---|---|---|---|
level Tag | 来自 news.level,公开 TagType 是 level | 保持当前统一难度描述能力 | 无需新造并行 difficulty_tag 体系 | 已完成 |
scene Tag | 来自 scenes + news_scenes;公开 Tag 名当前取 sub_scene | 继续作为主内容方向标签能力,但要补稳定治理规则 | 后续如果研究要扩 scene 体系,应优先补 scenes 治理与唯一性,而不是新建第二套主标签 | 已完成 |
premium Tag | 不是独立表,而是由 visibility == MEMBERSHIP_VISIBLE 衍生 | 如后续需要更多会员态,仍应先看 visibility 体系 | 不要在研究层自造“高级会员标签主模型” | 已完成 |
operator_tag | 当前只是文档概念,不是正式后端 TagType | 后续若真要长期运营标签,需要明确是否独立建模 | 目前不能把它写成当前服务端已支持能力 | 待定义 |
8. 当前唯一性约束与风险表
Section titled “8. 当前唯一性约束与风险表”这一节专门回答你提出的“冻结表还没有形成完全唯一性约束,导致很乱”的问题。
| 对象 / 约束 | 当前现实 | 风险 | 为什么重要 | 建议动作 | 状态 |
|---|---|---|---|---|---|
channels.name | 已有唯一键 UK_channels_name | 低 | 长期归属层已经有稳定唯一性 | 保持现状 | 已完成 |
scenes(category, scene, sub_scene) | 当前只有索引,没有唯一键 | 同义或重复场景可能进入系统,研究与后台会越用越乱 | scene 是当前主标签体系,缺唯一约束会直接污染样本映射与标签编辑 | 如果确认这三列就是当前最小唯一单位,应补唯一键;若不够,再先补场景治理规则 | 待迁移 |
news_scenes(news_id, scene_id) | 已有唯一键 | 同一条内容不能重复挂同一个 scene,基础关系去重已存在 | 这是当前最可靠的一条标签关系约束 | 保持现状 | 已完成 |
news_scenes(news_id, scene_primary) | 当前只有索引,不是唯一约束 | 一条内容当前可以拥有多个 primary scene | 如果团队希望“一个 Item 只有一个主 scene”,数据库现在并没有强制保证 | 先在文档规则里写清;若要硬约束,需要补更细约束或改表结构 | 待定义 |
news.news_id | 当前未见唯一键 | 同一上游内容是否可能重复入库,没有数据库层强保证 | 这会影响“唯一内容条目”的边界、去重和运营判断 | 明确 news_id 语义,再决定是否补唯一键或保留软去重 | 待定义 |
youtube_channels.youtube_channel_id | 已有唯一键 | 低 | YouTube 品牌层至少已经有正式唯一入口 | 可作为未来统一外部品牌治理的参考样板 | 已完成 |
9. 理想目标与差距动作总账
Section titled “9. 理想目标与差距动作总账”这一节不是在说“现在已经有”,而是在说“接下来要补什么”。
后续播客 / YouTube / B 站研究的新结论,应主要回写这一节。
| 概念 | 当前现实 | 目标理想 | 差距 | 为什么要补 | 建议动作 | 状态 |
|---|---|---|---|---|---|---|
Channel | 已正式存在,且是当前唯一长期归属层 | 继续保持一级长期归属层 | 目前缺的是治理规则,不是主模型缺失 | 这是当前最稳的正式层,后续扩容应尽量沿用它 | 继续以 channel_id 为长期归属,不并行发明第二套一级归属 | 已完成 |
Collection | 当前服务端未正式建模 | 成为长期发现容器,承接首页、列表页、详情页的核心发现层 | 文档目标很多,但后端真实模型还没落地 | 不补这层,首页和持续发现只能停在“单条内容分发” | 新增 collections + collection_items 主表、Admin CRUD、读接口、排序与可见性规则 | 待建模 |
Series | 当前未正式独立建模 | 成为连续更新容器,服务追更预期 | 现在只有概念,没有现实模型,也没有正式唯一边界 | 播客 / YouTube 研究越深入,这层越重要 | 先让 04-内容样本池.md 稳定 Series Unit 判断,再决定是独立表还是 Collection 特化 | 待定义 |
Topic | 当前未正式独立建模 | 成为时效性运营容器 | 现在只停留在概念层 | 不补清楚,会持续和 Collection 混用 | 先在文档里保持为目标概念;若要落地,优先评估是否复用 Collection + 时效字段 | 待定义 |
Source Brand | 当前只有 YouTube 有正式映射表,播客 / B 站没有统一品牌层 | 建立跨媒介统一的外部来源品牌治理 | 当前研究可以识别品牌,但系统无法统一承接 | 后续多平台内容进入后,没有品牌层会很难维护来源、风格和抓取策略 | 短期继续在 04-内容样本池.md 使用 source_brand;中期评估统一品牌主表或扩展现有 channel 体系 | 待迁移 |
Series Unit | 当前完全是研究层概念 | 成为 Series 候选或 Collection 组织判断依据 | 没有正式承接位置 | YouTube 播放列表、播客栏目、B 站合集很容易继续被混成一层 | 先在 04-内容样本池.md 中稳定判断标准,再回写本表决定正式承载方式 | 待定义 |
Distribution Eligibility | 当前只是文档规则,没有正式独立字段 | 与 visibility 分离,成为“能否进入分发层”的正式能力 | 现在最容易和 visibility 混掉 | 不拆开的话,“看得见”和“值得分发”会长期混用 | 先把规则写清;后续再决定是独立字段、状态表还是规则层 | 待定义 |
Scene 治理 | 当前已有正式标签表,但治理和唯一性不够硬 | 让 scene 成为稳定、可扩容的主方向标签体系 | 研究会不断带来新方向,但底层唯一性与治理规则不足 | 不补治理,研究输入越多,主标签越容易失控 | 优先补 scenes 唯一性策略、命名规则、废弃规则,再谈扩字段 | 待迁移 |
10. 03 / 04 怎么回写这份总账
Section titled “10. 03 / 04 怎么回写这份总账”| 研究里新出现的信号 | 先更新哪里 | 不应该怎么做 |
|---|---|---|
某个平台样本让 Collection / Series / Topic 边界更清楚了 | 回写本文件第 9 节的 目标理想 / 差距 / 动作 | 不要直接在样本文档里把它写成“系统已支持” |
某个新方向证明 scene 体系需要扩容或重命名 | 回写本文件第 7 节和第 8 节 | 不要直接在研究表里新增一套并行主标签体系 |
| 某类平台来源需要正式品牌层 | 回写本文件第 9 节的 Source Brand 行 | 不要把 news.source 改写成平台字段 |
| 研究发现当前字段不够表达 | 先回写本文件第 5 节、第 6 节或第 9 节 | 不要先在样本表里把临时列写成“系统已有字段” |
更新顺序固定为:
- 先在
03 / 04里形成证据、样本和判断 - 再回写本文件的
目标理想 / 差距 / 动作 - 最后根据本文件的最新口径,调整入库流程文档与样本池
11. 一句话总结
Section titled “11. 一句话总结”Yomiya 当前正式内容系统的现实仍然是 news + channels + scenes + news_scenes + Tag(level/scene/premium) + source(news/imports);官方 collected 内容已有风控 / 难度 / scene 处理链路,前台默认只分发 source = news;Collection / Series / Topic / Source Brand / Series Unit 现在都还属于目标理想与后续动作。