Files
lixi d2867826d3
CI / docs-build (push) Successful in 55s
docs: M3 开工分析 8 份报告入档 + ADR-016~021 拍板决策
- iteration-3 报告 01-08(PM 拆解/后端/Flutter/RC 首个 CERTIFIED/UI/埋点/证据基线/Git)
- ADR-016 自托管 MinIO 起步预留迁云(用户确认现无云存储)、ADR-017 patbond-community
  :8084 + media 归 user + 作者信息跨 schema 只读、ADR-018 范围裁剪(话题剪出/单层评论)、
  ADR-019 幂等按域(PUT/DELETE + request_hash)、ADR-020 聚合 feed_viewed/字典 v3/
  北极星不变/队列三项升第一波、ADR-021 Git 修订(main 更正/PR 情形触发/首发布重建 main/
  防泄漏 grep 先行)
- mkdocs 挂「第三迭代」导航,build --strict 通过

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-08 16:02:53 +08:00

35 KiB
Raw Permalink Blame History

Patbond 第三迭代任务分解(M3 社区)

作者:Senior Project Manager 日期:2026-09-08 依据:docs/development/development-plan.md(第 7 节 M3、第 4/6 节规范、第 9/10 节质量门禁与 DoD)、iterations/iteration-2/29-m2-summary.mdM2 收官与遗留)、docs/architecture/backend-modules.mddocs/architecture/decisions.mdADR-001~015)、docs/database/patbond_postgresql.sqlcommunity schema 7 表 + media.assets)、docs/api/openapi.yaml v1.2.0(18 路径,冻结中) 编号约定:本迭代工单以 T3- 前缀编号,避免与 T1/T2 冲突。 范围声明:严格限定为 M3 社区。AI 创作(M4)、本地服务(M5)、通知推送(M6)不在本迭代范围;posts.generation_job_id 等 M4 挂钩字段仅作预留,不开放写入。范围外需求一律记 backlog。


1. 范围界定与依据

1.1 开发计划 M3 原文(正典依据)

开发计划第 7 节 M3 定义(引用原文):

  • 目标:"完成真实动态发布和互动闭环。"
  • "实现 Feed、帖子详情、草稿/发布、媒体、评论、点赞、收藏、关注和话题。"
  • "Feed 使用游标分页;点赞、收藏使用幂等写入。"
  • "Flutter 替换本地帖子,并实现刷新、分页、失败重试和乐观更新回滚。"
  • 验收标准:"发布后可在另一客户端看到;重复点赞不重复计数;分页不丢失、不重复;删除或隐藏内容不可继续出现在公共 Feed。"

四条验收标准与工单的映射:跨客户端可见 → T3-21(E2E);重复点赞不重复计数 → T3-06;分页不丢失不重复 → T3-05 + T3-11 专项测试;删除/隐藏不出公共 Feed → T3-04/T3-05 语义 + T3-21 取证。

1.2 开工前的关键事实(PM 逐项核实)

  1. media 域是本迭代最大前置media.assets 表结构 V1 已建,但上传流程零代码ADR-010 剪出 M2),且对象存储供应商至今未拍板(第一迭代 D4 → M2 D2-1 两度遗留)。社区帖子以图片为主要形态(demo 每帖有 mainImage),媒体不通则发帖闭环不成立。对象存储选型是本迭代头号拍板项(D3-1)。
  2. community 数据模型已定稿评审7 张表(posts、post_media、comments、post_likes、post_bookmarks、user_follows、topics + post_topics 关联)。要点:
    • posts 自带 idempotency_key + request_hash 唯一约束、version 乐观锁、like_count/comment_count/bookmark_count 计数列、statusdraft/published/hidden/archived)与 visibilitypublic/followers/private);Feed 索引 (published_at DESC, id DESC) WHERE status='published' AND visibility='public' 已就绪。
    • 评论刻意设计为单层平铺DDL 注释原文:"Comments are deliberately one flat level. reply_to_user_id supports @ replies without parent_comment_id")——"评论层级"不是开放问题,模型已裁决,仅需确认沿用(D3-5)。
    • post_likes/post_bookmarks 复合主键 (post_id, user_id) 天然支撑幂等写入。
  3. Flutter 待替换对象明确lib/features/home/home_page.dart(首页 Feed + _PostCard)、lib/features/create/create_page.dart(创作页)、lib/features/post/post_detail_page.dart(详情 + 评论),数据挂在 AppState 的本地 PostModel(含 mainImage、tags、hasLiked/hasBookmarked、平铺 comments)。demo 没有关注页与话题页——关注/话题是纯增量,不是替换项,这是裁剪空间的客观依据(D3-2/D3-3)。
  4. 隐藏依赖——作者公开资料:Feed 卡片与评论需要作者昵称/头像,但现有契约只有 GET /api/v1/me,无任何"查看他人公开资料"的途径;identity.users.avatar_asset_id 又指向 media。获取方式(跨 schema 只读 vs Feign 调 user 内部接口 vs 嵌入响应)需拍板技术方案(D3-9),头像在 M3 至少要能随 media 域上传(否则占位)。
  5. 跨 schema 外键posts.generation_job_id → creation.generation_jobsM4)与 posts.region_id → platform.regionsplatform.regions 未随 V1/V2 迁移)在 V5 迁移时须裁剪为裸 uuid 列——与 M2 T2-01 裁剪 marketplace 外键同一先例。另 topics.namecitextix_posts_content_trgmpg_trgm,两个扩展需随 V5 启用。

1.3 本迭代 MVP 范围(PM 建议口径,待 §4 拍板确认)

  • 纳入:图片媒体上传闭环(对象存储 + POST /api/v1/media/uploads + 状态机)、帖子草稿/编辑/发布/删除(幂等 + 乐观锁)、公共 Feed 游标分页、帖子详情、单层评论(含 @ 回复)、点赞/收藏幂等写入与计数、Flutter 三页替换真实数据 + 乐观更新回滚、M2 高优先遗留两项(auth 契约测试、埋点队列完善)。
  • 待拍板裁剪项(默认建议见 §4):关注(D3-2,建议最小数据接口入、关注流与 followers 可见性后置)、话题(D3-3,建议首版剪出)、视频(D3-4,建议图片先行视频后置 M4+)。
  • 默认剪出region_id/location_text_snapshot(依赖 platform.regions,属 M5 地区体系)、visibility='followers'(依赖关注体系成熟)、内容审核后台与举报流程(hidden 字段保留为运营位,见 D3-7)、评论区通知(M6)、全文搜索(trgm 索引建了但搜索端点不在 M3 原文)。

2. 工单列表

预估规模口径沿用前两迭代:S ≈ 半天内,M ≈ 1-2 天,L ≈ 3-5 天(含测试与文档)。

A 组:数据与工程基础(后端)

T3-01 Flyway V5community schema 迁移与扩展启用

  • 仓库patbond-api(迁移进 patbond-user,单迁移链纪律),patbond-doc(迁移说明)
  • 描述:从 bootstrap SQL 提取 community 全部表结构为 V5;启用 citextpg_trgm 扩展;裁剪两条跨 schema 外键posts.generation_job_idposts.region_id 保留为裸 uuid 可空列,M4/M5 迁移时补回,写入迁移说明);topics 开发种子(若 D3-3 纳入)独立为不进生产的脚本。
  • 验收标准
    • 全新 postgres:18Testcontainers)上 V1→V5 全量迁移一次成功,表结构与 bootstrap SQL 一致(裁剪项除外,差异入迁移说明)。
    • ./mvnw clean test 全绿(既有 191 测试不回归)。
  • 依赖:无(第一波首项)。
  • 规模M

T3-02 patbond-community 模块骨架与鉴权接入

  • 仓库patbond-apipatbond-docbackend-modules.md 更新随收口)
  • 描述:按 D3-6 拍板结果建立社区模块骨架(PM 建议:沿 ADR-009 先例新建 Maven 模块 patbond-community,:8084);复用 JWT 资源侧校验与当前用户解析;模块只读写 community schema(作者资料获取按 D3-9 方案);compose 编排纳入新容器。
  • 验收标准
    • 模块编译入构建链,./mvnw clean test 全绿;无 token/过期 token 返回 401 + 既有 40100 系错误码。
    • compose 起五容器(postgres + auth + user + pet + community)健康。
  • 依赖:D3-6 拍板(可先按建议方案搭骨架,骨架期变更成本最低)。
  • 规模M

T3-03 media 域最小闭环:对象存储接入与上传流程

  • 仓库patbond-api(模块归属随 D3-6),patbond-doc(上传流程说明)
  • 描述本迭代关键路径起点,依赖 D3-1 拍板。实现 POST /api/v1/media/uploads(创建 asset 记录 + 签发上传凭据,建议预签名直传)与上传完成确认端点(uploading→ready,校验 mime/尺寸/大小;失败→failed);接入拍板的对象存储(建议 MinIO 起步);读取侧签发访问 URL(或公共读桶策略,随 D3-1 定);首版仅 kind='image'(D3-4),单文件上限与允许 mime 白名单写入契约。清理策略(uploading 超时未确认的 asset)首版仅记录方案不实现定时任务。
  • 验收标准
    • 上传→确认→ready→URL 可访问全链路 compose 实测通过;非法 mime/超限被拒且错误码稳定。
    • 集成测试覆盖状态机合法/非法迁移;CI 内以 MinIO Testcontainer(或拍板方案对应容器)验证。
    • ck_media_location/ck_media_ready 等数据库约束与应用层校验一致。
  • 依赖D3-1 拍板;T3-02(或 media 独立模块骨架)。
  • 规模L

B 组:后端社区纵切

T3-04 帖子生命周期:草稿/编辑/发布/删除

  • 仓库patbond-api
  • 描述POST /api/v1/posts(创建草稿,Idempotency-Key + request_hash 落 uq_posts_author_idempotency)、PATCH /api/v1/posts/{postId}(编辑,version 乐观锁,仅作者)、发布动作(draft→published,写 published_at,校验 ck_posts_publish_state)、删除(软删 deleted_at,语义随 D3-7)、GET /api/v1/posts/{postId} 详情、我的帖子列表(含草稿,ix_posts_author_created 游标)。post_media 挂接:只接受 status='ready' 且属于当前用户的 assetposition/is_cover 语义与 uq_post_media_cover 一致;发布时至少校验内容非空(图片是否必填随 D3-4 定)。category 三值白名单(general/help/ai_creationai_creation 仅预留不开放)。
  • 验收标准
    • 草稿→编辑→发布→详情→删除全链路走真实 PostgreSQL;相同 Idempotency-Key 重试不产生重复帖子。
    • 非作者编辑/删除被拒(403/404 语义契约定死);version 冲突返回既有 40902 语义。
    • 引用非 ready/非本人 asset 被拒;六类测试路径(成功/参数错/不存在/无权限/并发冲突/幂等重试)覆盖。
  • 依赖T3-01、T3-02、T3-03media ready 校验)。
  • 规模L

T3-05 公共 Feed 游标分页与帖子卡片聚合

  • 仓库patbond-api
  • 描述GET /api/v1/feed(命名待契约定稿):status='published' AND visibility='public'ix_posts_feed,复合游标 (published_at, id) 降序,禁止 OFFSET(第 6.1 节红线);软删/hidden/archived 一律不可见(M3 验收标准四)。响应含卡片所需全部字段:作者公开摘要(昵称/头像,取数方案按 D3-9)、封面图 URL、三计数、当前用户 liked/bookmarked 状态(批量查询避免 N+1)、话题标签(若 D3-3 纳入)。
  • 验收标准
    • 分页不丢失不重复:含"翻页间隙有新发布/有删除"两个专项集成测试;游标篡改/过期返回规范错误。
    • 删除与 hidden 帖子在下一次请求即不可见,有测试。
    • 卡片字段口径逐项写入契约描述(liked 状态、封面选取规则、计数来源)。
  • 依赖T3-04。
  • 规模L

T3-06 点赞/收藏幂等写入与计数

  • 仓库patbond-api
  • 描述:点赞/收藏的施加与取消(建议 PUT/DELETE /api/v1/posts/{postId}/like.../bookmarkPUT/DELETE 天然幂等语义);依托复合主键防重,like_count/bookmark_count 与关系行同事务原子增减;重复施加/重复取消均返回成功且计数不变(M3 验收标准二);对不可见帖子(软删/hidden/他人 private)操作返回 404。我的收藏列表(ix_post_bookmarks_user_created 游标分页)。
  • 验收标准
    • 重复点赞并发压测(同用户并发 N 次)后 like_count 恰为 1,有集成测试。
    • 取消不存在的点赞不报错不减计数;计数列与关系表对账一致性有测试。
  • 依赖T3-04;与 T3-05/T3-07 可并行。
  • 规模M

T3-07 评论:单层平铺 + @ 回复

  • 仓库patbond-api
  • 描述:按 D3-5 确认的单层模型实现 GET/POST /api/v1/posts/{postId}/commentsix_comments_post_created 游标分页;创建带 client_request_id 幂等 + reply_to_user_id 可选 @ 回复)与评论删除(作者可删;帖主是否可删他人评论随 D3-7 定)。comment_count 同事务维护(删除减计数);ck_comments_deleted 状态一致性;评论长度 1~2000 与数据库约束一致。响应含评论作者公开摘要(同 D3-9 方案)。
  • 验收标准
    • 相同 client_request_id 重试不产生重复评论;对不可见帖子评论返回 404。
    • 分页正确;删除后计数与列表一致;六类测试路径覆盖。
  • 依赖T3-04。
  • 规模M

T3-08 关注最小数据接口(条件单,随 D3-2)

  • 仓库patbond-api
  • 描述:若 D3-2 拍板纳入:follow/unfollowPUT/DELETE 幂等,ck_user_follows_self 禁自关注)、我的关注/粉丝列表(游标分页)、目标用户维度的关注状态查询(嵌入 D3-9 公开资料响应)。关注 Feed tab 与 visibility='followers' 不在本单(后置,见 D3-2 影响面)。
  • 验收标准:重复 follow 幂等;自关注被拒;列表分页正确;六类测试路径覆盖。
  • 依赖D3-2 拍板;T3-02。
  • 规模M

T3-09 话题目录与帖子挂接(条件单,随 D3-3)

  • 仓库patbond-api
  • 描述:若 D3-3 拍板纳入:topics 只读目录(active 过滤)、发帖挂话题(≤N 个,上限入契约)、话题维度 Feed(ix_post_topics_topic + 可见性过滤)。话题创建首版仅种子数据,不开放用户建话题。
  • 验收标准:挂接与话题 Feed 正确过滤不可见帖;目录/上限校验有测试。
  • 依赖D3-3 拍板;T3-04。
  • 规模M

C 组:契约与测试

T3-10 OpenAPI v1.3.0 扩展与冻结

  • 仓库patbond-docdocs/api/openapi.yaml),patbond-api(字节级快照同步)
  • 描述:沿用 M2 验证过的迭代式契约冻结:第一波按 §1.1 与数据模型出草案(TODO-FREEZE 标注媒体凭据形态、Feed 卡片字段、公开资料形态三处待定型点)→ 随 T3-03/04/05 实现定型回填 → 拍板 → 冻结合入 + api 侧字节级快照同步升版(冻结纪律:升版须同步快照,缺一 CI 必红)。沿用既定规范:camelCase、UUID 字符串、统一信封、稳定错误码(community/media 域新错误码段定死)、cursor 分页形态、Idempotency-Key、version。
  • 验收标准:契约评审通过;契约测试锁定零漂移;mkdocs build --strict 通过;冻结后变更须显著上报两端同步。
  • 依赖:草案仅依赖数据模型;冻结须 T3-03 凭据形态 + T3-04 权限/错误语义 + T3-05 卡片字段定型。冻结是第三波前端联调放行闸门。
  • 规模M

T3-11 后端集成测试滚动补齐与 CI(横切单)

  • 仓库patbond-api
  • 描述:随 B 组滚动补齐 Testcontainers 集成测试与契约一致性测试(机制复用 M2 T2-20);每单交付 ./mvnw clean test 必绿。专项:Feed 分页边界矩阵(空 Feed/单页/翻页间隙增删/游标非法)、计数对账、幂等并发。MinIO 容器纳入 CI 后记录时长,超阈值评估分层。
  • 验收标准:每个业务接口覆盖六类路径;Gitea Actions 全绿(commit status API 实查,M2 惯例);CI 时长记录在案。
  • 依赖:随 T3-03~T3-09 滚动。
  • 规模M(分摊在各单内)

D 组:Flutter 客户端

T3-12 community feature 分层与 API Client

  • 仓库patbond-flutter
  • 描述:按第 4.2 节拆出 community featureController → Repository → API Client,对齐 pets feature 既有结构);依 T3-10 冻结契约实现 DTO 与 Client(帖子、Feed、评论、点赞/收藏、媒体上传,条件项随拍板);错误码解析复用既有网络层与 token 拦截。AppStatePostModel demo 数据链路在本组末位工单交付后移除。
  • 验收标准:DTO 映射有单元测试;错误映射类型化;UI 无关骨架可先行。
  • 依赖:T3-10 冻结(骨架部分可提前与后端并行)。
  • 规模M

T3-13 媒体上传客户端

  • 仓库patbond-flutter
  • 描述:选图(image_picker 或既定方案)、客户端压缩/尺寸约束(与契约上限一致)、按 T3-03 协议两步上传(取凭据→直传→确认)、上传中/失败/重试状态、多图并发上传与顺序保持(position)。
  • 验收标准:上传全链路 compose 实测;弱网失败可重试不产生孤儿引用(未确认 asset 不挂帖);单元/widget 测试覆盖状态机。
  • 依赖T3-12T3-03 联调。
  • 规模L

T3-14 首页 Feed 替换真实数据

  • 仓库patbond-flutter
  • 描述home_page.dart Feed 替换:下拉刷新、游标分页加载更多、loading/empty/error/retry 四态(第 9 节硬要求)、图片加载占位与失败态、卡片计数与 liked/bookmarked 状态取自服务端。demo 的 breedTag/tags 展示按契约实际字段调整(话题未纳入则该位裁剪)。
  • 验收标准:刷新与分页不丢不重(widget 测试模拟游标);四态齐备有测试;不再读 AppState demo 帖子。
  • 依赖T3-12。
  • 规模L

T3-15 发帖与草稿流程

  • 仓库patbond-flutter
  • 描述create_page.dart 替换:文字 + 多图(挂 T3-13)、本地暂存与服务端草稿(保存草稿/继续编辑/发布)、发布携带 Idempotency-Key(客户端生成并在重试间保持)、发布失败重试、成功后 Feed 可见引导。字段对齐契约(title 可选 120、content 1~10000、category)。
  • 验收标准:草稿→发布→Feed 出现全链路真实后端;断网发布重试不产生重复帖;四态与校验提示齐备有测试。
  • 依赖T3-12、T3-13。
  • 规模L

T3-16 帖子详情与评论接入

  • 仓库patbond-flutter
  • 描述post_detail_page.dart 替换:详情取数、评论游标分页、发评论(client_request_id 幂等 + @ 回复)乐观插入(发送即上屏置 pending 态,失败标红可重试/撤回)、删除自己的评论。已删除/隐藏帖子的详情页兜底(404 → 友好提示并从列表移除)。
  • 验收标准:评论乐观插入失败回滚有 widget 测试;分页与 @ 回复展示正确;四态齐备。
  • 依赖T3-12T3-14 后并行于 T3-15。
  • 规模M

T3-17 点赞/收藏乐观更新与回滚

  • 仓库patbond-flutter
  • 描述:统一乐观更新工具(立即翻转 UI 与本地计数 → 请求失败回滚 + toast;快速连点合并为末态请求,防抖;响应乱序以末次请求为准);Feed 卡片、详情页、收藏列表三处状态一致(同一帖子跨页面状态同源)。我的收藏列表页接入。
  • 验收标准:失败回滚、连点合并、跨页面一致各有 widget 测试;离线操作提示明确不假成功。
  • 依赖T3-12、T3-14。
  • 规模M

T3-18 关注 UI 最小版(条件单,随 D3-2)

  • 仓库patbond-flutter
  • 描述:若 D3-2 纳入:帖子作者处关注/取关按钮(乐观更新复用 T3-17 工具)、我的关注/粉丝列表页。不做关注 Feed tab。
  • 验收标准:关注状态跨页面一致;乐观回滚有测试。
  • 依赖T3-08、T3-17。
  • 规模S

E 组:遗留、埋点与收口

T3-19 M2 高优先遗留清偿(第一波插入)

  • 仓库patbond-api、patbond-flutter
  • 描述:随 D3-8 拍板,PM 建议纳入两项:① auth 域契约测试补齐(机制复用 M2 契约测试框架,S);② 埋点队列完善(30s 定时冲刷、失败退避——429 依赖后端限流未做则先覆盖网络错误退避、anonymousId 持久化;方案见 iteration-2/15 §4)。与 M3 契约零耦合,第一波并行消化。
  • 验收标准:auth 全响应矩阵入契约测试;队列三项行为各有测试;不回归既有 272 前端测试。
  • 依赖D3-8 拍板。
  • 规模M

T3-20 社区埋点:字典 v3 与挂接

  • 仓库patbond-flutter(挂接)、patbond-api(白名单扩充)、patbond-doc(字典)
  • 描述:事件定义以 Experiment Tracker 的 M3 埋点方案为准(本单不自造字典;沿用 v1「结果编码进事件名」惯例与 ADR-013 纪律),预期覆盖发帖成功/Feed 浏览/点赞/收藏/评论等关键动作;随 D 组页面落地滚动挂接;埋点不含帖子内容明文。兼顾 ADR-012:A/B 前置 8 项目标 M3 末全绿,缺口由 Experiment Tracker 盘点。
  • 验收标准:关键动作事件端到端落库;白名单与字典同步;有测试。
  • 依赖Experiment Tracker 方案;T3-14~T3-17 滚动。
  • 规模S

T3-21 E2E 烟囱与验收取证

  • 仓库patbond-flutter(用例)、patbond-apicompose 环境)、patbond-doc(证据归档)
  • 描述:沿用 M2 收官战模式,烟囱场景对齐 M3 四条验收标准:账号 A 传图发帖 → 账号 B(另一客户端会话)Feed 可见并点赞/收藏/评论 → A 重复点赞并发验证计数 → 翻页期间新发布/删除验证分页 → A 删帖后 B 侧 Feed 与详情不可见 → 幂等重试发帖不重复。HTTP transcript 脱敏、数据库证据、门禁输出入档。
  • 验收标准:全场景绿;契约偏差 0;M3 四条验收标准逐条有证据。
  • 依赖T3-05、T3-06、T3-15、T3-16、T3-17。
  • 规模M

T3-22 文档与迭代收口

  • 仓库patbond-doc
  • 描述OpenAPI v1.3.0 归档、backend-modules.md 更新(新模块与 media 归属)、feature-checklist 增补、迭代报告归档与收官总结。iteration-3 目录的 mkdocs.yml 导航由文档维护者收口提交统一添加(本拆解报告不改 mkdocs.yml)
  • 验收标准mkdocs build --strict 通过;报告索引完整。
  • 依赖:各波交付。
  • 规模S

3. 波次划分与关键路径

沿用已验证模式:波次并行 + 迭代式契约冻结 + 同仓串行跨仓并行 + 每波 compose 实测。

第一波(并行开工)

并行线 工单 说明
数据与骨架 T3-01 → T3-02 V5 + community 骨架,一人连续负责
media 闭环 T3-03 需 D3-1 开工前拍板;未拍板时可先做 asset 元数据/状态机 + 存储接口抽象,把供应商差异隔离在适配层
契约草案 T3-10(起草态) TODO-FREEZE 标注三处待定型点
前端遗留 T3-19 与 M3 契约零耦合
UI 设计 Feed/发帖/详情四态与空态设计稿 供 T3-14~16,不占关键路径

第二波(后端纵切,契约收敛)

并行线 工单 说明
后端主线 T3-04 → T3-05 / T3-06 / T3-0704 后三线并行);条件单 T3-08/T3-09 随拍板插入 T3-04 帖子生命周期是全部互动单的前置
前端骨架 T3-12 分层骨架(不依赖契约部分) Repository/状态骨架先行
测试滚动 T3-11 即测即绿即提交

波末闸门:T3-10 契约冻结(条件:T3-03 凭据形态 + T3-04 权限/错误语义 + T3-05 卡片字段定型;快照同步升版)。不冻结不放行第三波联调。

第三波(冻结契约下两端并行)

并行线 工单 说明
前端主线 T3-12(完成)→ T3-13 → T3-14 → T3-15 / T3-16 / T3-17(可两人并行);条件单 T3-18 媒体上传客户端先通,发帖流程才有意义
后端旁路 契约测试补齐、Feed 分页专项、性能核对 不占关键路径
埋点 T3-20 随页面落地滚动挂接

第四波(收官)

T3-21 E2E 烟囱 → T3-22 文档收口 → 任务板更新与验收报告。

关键路径

[D3-1 拍板] → T3-03(L) → T3-04(L) → T3-05(L) → [T3-10 冻结] → T3-12 → T3-13(L) → T3-15(L) → T3-21

五个 L 工单串在关键路径上,media 双端(T3-03/T3-13)占其二——媒体链路是周期决定因素。压缩手段:D3-1 置顶开工前拍板;T3-03 存储适配层先行;T3-10 草案与 T3-12 骨架前移;T3-06/07/16/17 走旁路。


4. 需要用户拍板的决策清单

以下决策 PM 只给建议,不替用户拍板。D3-1 是头号,阻塞关键路径起点;D3-1~D3-6 建议开工前裁决。

# 决策事项 影响 PM 建议(仅供参考)
D3-1 对象存储选型(第一迭代 D4 → M2 D2-1 三度上桌,本迭代无法再拖)。候选路径:A. 自建 MinIOS3 兼容,compose/Testcontainers 即起,后续平滑迁云 S3 兼容服务);B. 云厂商对象存储(阿里 OSS/腾讯 COS/AWS S3:免运维、自带 CDN,但引入账号/密钥/成本与 CI 外部依赖,且当前无生产部署环境承接);C. 本地磁盘/DB 临时方案(不建议:与 storage_type='object' 模型冲突、无预签名能力、迁移即返工) 阻塞 T3-03/T3-13 全部媒体链路(关键路径起点);决定上传协议(预签名直传 vs 服务端中转)、URL 签发/公共读策略、compose 与 CI 编排、M4 AI 输出存储 方案 AMinIO)起步:S3 SDK 编码,供应商差异收敛在配置层,生产化阶段(M6)再评估迁云;上传走预签名直传(服务端不过流量);读取侧首版公共读桶 + 稳定 URL,签名读后置
D3-2 关注是否首版M3 原文含"关注",但 demo 无关注 UI、四条验收标准均不涉及关注;完整关注体系 = follow 写入 + 关注 Feed + visibility='followers' 三层 全量纳入约 +1M(后端)+1M(前端)并拖长契约面;全剪则 M3 原文范围有显式缺口 中间态T3-08/T3-18 最小版纳入(follow/unfollow 幂等 + 列表 + 按钮),关注 Feed tab 与 followers 可见性后置(首版 visibility 固定 public,字段保留);若周期紧张可整体后置,在收官总结记范围缺口
D3-3 话题是否首版M3 原文含"话题"demo 帖面有 tags 展示但无话题页;topics 模型已就绪 纳入 +1M(T3-09)+ 前端话题选择/话题页;剪出则 demo tags 位需处理 首版剪出,帖子先跑通"内容+图片"主干;topics 端点 M3.5/M4 随 AI 创作分类需求一起做(ai_creation category 天然关联)。demo tags 展示位首版收起
D3-4 媒体形态:图片先行、视频后置?每帖图片上限?图片是否必填? 视频涉及转码/时长/封面帧,复杂度台阶式上升;上限影响 UI 与存储 图片先行kind='image',视频 M4+ 随 AI 视频输出统一考虑);每帖上限 9 图(对齐主流社区惯例);图片非必填(纯文字帖合法,content 本就 NOT NULL
D3-5 评论层级确认DDL 已裁决单层平铺 + reply_to_user_id @ 回复(注释言明不做 parent_comment_id/递归) 若推翻需数据模型变更提案(新列 + 树查询 + UI 缩进体系,约 +1L) 沿用单层设计,不做二级楼中楼;@ 回复已覆盖对话场景。若产品坚持多级,另立模型变更提案排 M3.5
D3-6 模块归属:① 社区域——沿 ADR-009 先例新建 patbond-community:8084vs 并入现有模块;② media 域归属——独立 patbond-media(:8085,跨域共享:用户头像/宠物照片/帖子/M4 AI 输出都写 media.assetsvs 并入 patbond-user(平台能力先例:埋点在 uservs 并入 community(本迭代唯一消费方) 决定 T3-02/T3-03 骨架、compose 容器数(5 或 6)、CI 时长 社区新建 patbond-community(ADR-009 同理:数据所有权独立、微服务化边界清晰);media 倾向独立 patbond-media 小模块(M4 起至少三个域消费,塞进任何业务模块都会造成反向依赖),但六容器对双人团队运维面偏重,若求稳可先并入 patbond-user(迁移链持有者,平台能力聚合),M4 前再拆
D3-7 删除/隐藏语义与权限:作者删帖(软删)与 hidden(运营位)的开放范围;帖主是否可删他人评论 影响 T3-04/T3-07 权限矩阵与 M3 验收标准四的取证口径 作者可删自己帖子与评论(软删);hidden/archived 字段保留但不开放任何端点(无运营后台,M6+);帖主删他人评论首版不做(涉治理策略,随举报体系一起设计)
D3-8 M2 遗留纳入范围:① auth 契约测试(S);② 埋点队列完善(M);③ T2-12 §8 三项交互(单宠直进/归档入口/sterilizedOn,本身即待产品拍板项);④ iteration-2/09 契约-实现出入 5 项(64KB 上限、429 限流等) 纳入挤占 M3 周期;不纳入债务滚动 ①② 纳入(T3-19,第一波,与 M3 零耦合);③ 待产品对三项交互本身拍板后另排,不进 M3 计划;④ 其中 429 限流若不做,T3-19 退避按网络错误实现并记录依赖;跨迭代项(token 黑名单、mTLS)继续挂技术债清单不进 M3
D3-9 作者公开资料获取方案:Feed/评论需他人昵称头像,现无公开资料端点。候选:A. community 跨 schema 只读 identity.users(破"模块只读写自己 schema"纪律,需 ADR 豁免);B. Feign 批量调 user 内部接口(ADR-002 静态直连先例,/internal/** 保护范围内);C. user 增开公开资料端点由前端二次请求(N+1 且泄露面大) 决定 T3-05/T3-07 响应组装方式与性能形态;亦影响 M4/M5 同类需求的先例 方案 Buser 模块增 /internal 批量公开资料接口(仅昵称/头像 assetId),community 侧 Feign 批量取并短 TTL 进程内缓存;跨 schema 只读若被选择须补 ADR 明确豁免边界

5. 遗留项插入位置汇总

遗留项(iteration-2/29 §4 口径) 优先级 插入位置
media 域(ADR-010 剪出项) 最高(M3 天然落点) T3-03/T3-13 主线工单;宠物头像/疫苗证书/事件附件的接入不在 M3(属 pet 域回填,media 通了之后 M3.5 顺手做,本迭代只交付能力)
auth 域契约测试 T3-19,第一波(随 D3-8
埋点队列完善(30s 冲刷/退避/anonymousId T3-19,第一波(随 D3-8
T2-12 §8 三项交互 中(待产品拍板) 不进 M3 计划,拍板后另排(D3-8③)
照护人邀请流程(ADR-015 后置项) 不进 M3(社区已满负荷),M3.5+ 候选
health_record_deleted 事件 随 pet 域删除端点设计,不进 M3
真机补验两项(iteration-2/30 挂起 真机到位即插入,不阻塞 M3(约 0.5 天)
token 黑名单、/internal mTLS 中(跨迭代) 技术债清单,加固阶段处理;D3-9 若选 Feign 方案,mTLS 需求权重上升,记入债项说明

6. 风险清单

# 风险 影响 缓解措施
R1 媒体链路全新且横跨双端:对象存储、上传协议、状态机、CI 容器、客户端选图压缩上传全部从零;T3-03 + T3-13 占关键路径两个 L 估算失准直接拖垮迭代周期 D3-1 开工前拍板;存储适配层隔离供应商差异;范围钉死"图片先行 + 预签名直传 + 公共读"最小面;MinIO Testcontainer 让 CI 无外部依赖;每波 compose 实测媒体链路
R2 D3-1 拍板拖延:三度遗留的决策,再拖则关键路径起点空转 第一波 media 线停摆 决策清单置顶;未拍板期间 T3-03 先行做元数据/状态机/接口抽象(明确止损线:适配层以上不写供应商代码)
R3 乐观更新回滚复杂度:点赞/收藏/评论三处乐观 UI,叠加快速连点、响应乱序、跨页面状态同源、离线场景 前端状态 bug 密集区,返工黑洞 T3-17 先建统一乐观更新工具再铺页面;widget 测试矩阵(失败回滚/连点合并/乱序末态)作为 DoD 硬项;服务端幂等兜底(重复请求无害)
R4 Feed 正确性与性能:翻页间隙增删导致丢帖/重帖;liked-by-me 逐帖查询 N+1;计数列与关系表漂移 直接命中 M3 验收标准二、三 复合游标 (published_at, id) 严格实现(索引已就绪);liked/bookmarked 批量 IN 查询;计数同事务更新 + 对账测试;T3-11 分页专项测试矩阵
R5 作者资料组装成为性能与架构双坑D3-9):Feed 每页 20 帖若逐个查作者即 N+1 跨服务调用 Feed 延迟高、服务间耦合失控 D3-9 开工前拍板;无论何种方案都要求批量接口 + 缓存;契约测试锁定卡片字段避免前端二次拼装
R6 UGC 无审核机制上线:帖子/评论/图片全开放,无敏感词、无举报、无运营后台 内容风险敞口(虽 MVP 阶段用户面小) 模型已留 hidden 运营位(D3-7 保留字段不开放端点);数据库侧可手工 hidden 应急;举报/审核入 backlog 并在收官总结显式声明敞口,产品知情
R7 契约面与冻结节奏:media 凭据、Feed 卡片、公开资料三处形态开工时未定型,比 M2 的 TODO-FREEZE 面更宽 冻结延迟连锁推迟第三波 三处待定型点第一波即在草案中显式标注并限期收敛(第二波中期);冻结闸门纪律不放松,偏差显著上报
R8 CI 时长与容器数增长:五~六应用容器 + MinIO + 测试数从 191/272 继续上量 门禁反馈变慢被绕过 T3-11 记录每波 CI 时长;超阈值按模块分层执行;不降低"提交前全绿"标准
R9 未提交/未推送风险(第一迭代 R3 教训惯例项) 工作量全损 每波每单交付即提交即推送(ADR-011:只推 dev);PM 每波核对三仓 git status 与远端同步
R10 demo 替换的 UI 落差home_page.dart/create_page.dart 是 demo 中视觉最重的页面,真实数据字段与 demo 卡片(breedTag、tags、精选图)不完全对齐 "替换后不如 demo 好看"的观感回退,或前端擅自造字段 第一波 UI 稿先行明确真实字段下的卡片形态(含无图帖、无头像作者的降级样式);缺失字段一律走契约提案不留本地拼凑

7. 质量要求(对全部工单生效)

  • 遵守开发计划第 10 节 DoD:不依赖 Demo 常量;权限、校验、幂等、并发已处理;文档同步更新;干净环境可复现。
  • 契约规范沿用:camelCase、UUID 字符串、ISO 8601 + timestamptz、统一信封与稳定错误码、cursor 分页(Feed 禁 OFFSET)、Idempotency-Key、version 乐观锁;契约冻结后 api 侧字节级快照同步升版
  • 不提交任何密码、token、对象存储密钥(.env/.sample 模式,ADR 纪律);埋点不含帖子内容明文与敏感信息。
  • 集成测试一律 Testcontainers postgres:18ADR-006/008),媒体测试用 MinIO 容器(随 D3-1);每单交付 ./mvnw clean testflutter analyze + flutter test 全绿。
  • 所有网络页面四态(loading/empty/error/retry)齐备;图片位另加占位/失败态。
  • 本迭代不实现 AI 创作、预约、通知推送的任何接口或页面;generation_job_id/region_id 仅预留;范围外需求记 backlog。

8. 工单统计

  • 工单总数:22(数据与工程基础 3 + 后端社区纵切 6 + 契约与测试 2 + Flutter 7 + 遗留与收口 4),其中 3 个条件单T3-08/T3-09/T3-18,随 D3-2/D3-3 拍板启停)
  • 规模分布(核心 19 单):S × 2、M × 12、L × 5;条件单另计 S × 1、M × 2
  • 关键路径:D3-1 拍板 → T3-03 → T3-04 → T3-05 → 契约冻结 → T3-12 → T3-13 → T3-15 → T3-21L × 5 在链上,media 双端占其二
  • 待拍板决策:9 项D3-1D3-9;D3-1 头号且阻塞关键路径起点,D3-1D3-6 建议开工前裁决)