Module 03 · V1.0 · Posts & Content Model

内容模型与发帖

社区的血肉,五种发帖形态覆盖表达需求

P0V1.0缺失则产品不成立,必须最先交付

模块目标

要达成什么

定义结构化的内容模型,支持文本、链接、图片、投票、转发五种帖子类型,并具备草稿、编辑、删除、置顶等完整生命周期。

为什么必须存在

内容模型一旦定错,后续排序、检索、推荐全部要返工。必须在编码前把「一篇帖子到底有哪些字段」想清楚。

功能清单

共 10 个功能点,每个功能点给出实现要点,可直接作为开发任务的描述。

五种帖子类型

P0

Text(富文本正文)、Link(外链 + 自动抓取标题摘要缩略图)、Image/Video(媒体帖)、Poll(投票帖)、Crosspost(跨社区转发)。

实现要点:统一使用 posts 主表 + type 字段区分,类型特有的数据放 post_polls / post_media 附表,避免主表字段膨胀。

结构化富文本编辑器

P0

所见即所得 Markdown 编辑器:标题、粗斜体、代码块(语法高亮)、引用、列表、表格、分割线、图片、视频、@提及、#标签。

实现要点:内容以结构化 JSON(ProseMirror/TipTap 文档)存储,同时冗余一份渲染后的 HTML 与纯文本(用于搜索与摘要),避免每次渲染都解析。

草稿与自动保存

P1

本地每 5 秒自动保存草稿到浏览器,服务端草稿需手动「保存草稿」。

实现要点:支持多草稿管理,草稿列表可预览首行内容与最后编辑时间。切换设备后可继续编辑服务端草稿。

编辑与版本历史

P1

发帖后 30 分钟内可自由编辑不留痕,超过后编辑会标记「已编辑」并保留可查看的修订历史。

实现要点:每次编辑写入 post_revisions 表存快照,仅保留最近 20 个版本。版主与本人可查看差异。

帖子生命周期与状态

P0

draft → published → locked(锁定禁评)→ archived(归档只读)→ removed(删除)。删除采用软删除,保留审计。

实现要点:状态机在服务层强校验,禁止非法跃迁。用户删除自己的帖子不影响他人评论的显示,仅标记 [deleted]。

媒体上传与处理

P1

图片自动压缩与多尺寸缩略图、EXIF 清理;视频转码 HLS;上传进度与失败重试。

实现要点:前端直传对象存储(预签名 URL),避免占用应用服务器带宽;上传完成后回调服务端登记,异步转码完成才允许发布。

投票帖(Poll)

P2

支持 2–6 个选项、可配置多选、可配置截止时间、可配置是否公开投票人。

实现要点:单个用户对同一 Poll 只能投一次(多选可改但记录修改次数),计数走 Redis,投票结果实时更新。

跨社区转发(Crosspost)

P2

把已有帖子转发到另一个社区,原帖与转发帖保持关联,评论各自独立或可指向原帖。

实现要点:crosspost_of 字段指向原帖,转发帖在卡片上显示原帖来源;原帖删除时转发帖保留但显示来源已删除。

置顶与公告

P2

版主可置顶最多 2 条帖子;管理员可发布平台级公告(Banner 形式)。

实现要点:置顶帖独立排序,始终排在最前并带「置顶」角标;支持定时置顶与自动取消。

短动态(Shout)

P2

借鉴掘金「沸点」:≤ 300 字的轻量动态,支持图片与话题,进入独立的短内容流。

实现要点:复用 posts 表,type = shout,不参与长内容社区的置顶与 Flair 逻辑,但在关注流中优先展示。

交互设计

2 条关键交互的分步流程,按用户体验顺序描述,可直接作为前端开发与可用性测试脚本。

1

发帖流程

  1. 1

    在社区页或首页点击「发帖」,弹出全屏编辑器(移动端为全屏,桌面端为居中模态)。

  2. 2

    顶部选择帖子类型 Tab,切换时保留已输入内容。

  3. 3

    填写标题(必填,≤ 300 字符)与正文;插入 Link 时自动抓取 og:title / og:image 预览。

  4. 4

    选择 Flair(若社区设为必选);可添加标签。

  5. 5

    点击发布,前端做敏感词与长度预校验,提交后乐观插入列表顶部并显示「发布中」状态。

  6. 6

    发布成功替换为真实卡片;失败保留编辑器内容并提示重试。

2

删除与恢复

  1. 1

    作者点击帖子菜单 → 删除,二次确认后进入软删除状态,本人可在「已隐藏内容」中恢复。

  2. 2

    版主删除会写入 Mod Log 并通知作者,作者可申诉。

  3. 3

    管理员删除为硬性下架,列表中不再出现且不可恢复。

业务规则

5 条硬性约束。这些规则应当在服务层强校验,而非仅在前端提示。

R01

标题 1–300 字符;正文上限 40000 字符(TL1)至 40000 无上限(TL3+ 可发长文)。

R02

同一用户在同一社区 10 分钟内最多发 3 帖,跨社区累计 10 分钟 5 帖。

R03

重复链接检测:同一社区内若相同 URL 已在 24 小时内发布,提示「已有相似内容」并给出链接。

R04

草稿最多保留 20 份,超出按最后编辑时间淘汰。

R05

投票帖创建后不可修改选项文本,只可修改截止时间或提前结束。

涉及数据表

本模块涉及的 9 张表。完整字段、索引与说明见「数据表设计」页。

竞品参考

本模块的设计参照了哪些产品,具体参照了什么。

RE

Reddit

五种帖子类型 + Flair 必选机制,引导内容规范化。

掘金

掘金

所见即所得编辑器 + 文章/沸点双轨,兼顾深度与频次。

DI

Discourse

主题内阅读进度记忆,长内容体验优秀。

V2

V2EX

Markdown 代码块渲染质量是技术社区的关键体验。

验收指标

本模块交付时应当达到的量化目标。未达标即视为该模块未完成。

发帖完成率打开编辑器 → 发布成功 ≥ 55%
草稿恢复率使用草稿的用户 ≥ 15%
媒体上传成功率≥ 99%
重复内容拦截24 小时内重复 URL 识别率 ≥ 90%

避坑清单

竞品踩过的坑,以及本模块在实现时最容易犯的错误。

  • 正文同时存 JSON 与 HTML 与纯文本会带来一致性风险,需在服务层统一生成,禁止客户端提交 HTML。

  • 不做软删除会导致「评论上下文断裂」,删除帖子必须保留壳。

  • 编辑器若直接提交 HTML,XSS 风险极高,必须走白名单净化。

  • 视频转码是长耗时任务,务必异步化,否则发帖接口会超时。