296d454d30
CI / docs-build (push) Successful in 41s
- backend-modules.md:速览图补 patbond-creation(:8085) 与独立的 patbond-ai 仓;新增两节职责说明(含 V6 两处偏离目标模型的原因、队列不引入 broker 的依据、服务身份 JWT 用独立密钥对的事实依据、以及骨架阶段刻意未实现项); 关键纪律第 2 条补「谁拥有 schema」与「迁移文件放哪」是分开的(pet/ community/creation 代码各在自己模块,迁移全在 patbond-user),第 3 条补 两套内部鉴权并存的原因。并注明 patbond-creation 尚未入 compose 及其原因。 - 新建本仓 README(此前四仓中唯一没有的):权威文档索引、本地构建与门禁、 以及三条写作纪律——常设文档不写死本机路径、迭代报告是时点存档不回改 (结论失效时追加带日期注记)、不要引用别的报告的转述结论(附本项目 已因此把规模预估高估一整档的实例)。 验证:secret-scan exit 0;mkdocs build --strict exit 0。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
8.3 KiB
8.3 KiB
后端模块结构与职责
本页是后端结构的唯一权威速览:模块怎么划分、各自负责什么、端口与依赖关系。 结构性变更(新增/拆分模块)须经 ADR 决策并同步更新本页。 最后更新:2026-09-08(M3 第一波收口:六容器 + media 闭环)。
一图速览
patbond-api(Maven 多模块,Spring Boot 3.5 + JDK 17)
├── patbond-common 公共库(无端口,被其余模块依赖)
├── patbond-auth 认证服务 :8081
├── patbond-user 用户服务 + 埋点 :8082 ← Flyway 迁移链唯一持有者
├── patbond-pet 宠物健康档案服务 :8083 ← M2 新增(ADR-009)
├── patbond-community 社区服务 :8084 ← M3 新增(ADR-017)
└── patbond-creation AI 生成编排服务 :8085 ← M4 新增(ADR-023)
patbond-ai(独立仓库,Python) ← M4 新增(ADR-023),只调 AI 服务商 API
部署形态:docker compose 六容器(postgres:18 + MinIO 对象存储(ADR-016,自托管、私有桶)+ auth + user + pet + community),应用容器无状态(ADR-007)。patbond-creation 尚未入 compose——其 Worker 依赖 patbond-ai 与对象存储方案,两者均未落地。
模块职责
patbond-common(公共库)
- 统一错误信封与业务错误码体系(
code/message/data结构,稳定错误码契约) - 共享异常类型与基础组件
- 不含业务逻辑、不起服务;其余四个服务模块都依赖它
patbond-auth(认证域,:8081)
- 注册 / 登录 / 退出:
/api/v1/auth/** - JWT RS256 签发;access 15 分钟 / refresh 30 天轮换 / 多设备并行(ADR-003)
- 登录失败锁定(5 次错误 → 423 临时锁定)
- 首版仅账号 + 密码(ADR-004),凭证模型预留扩展
- 会话真值在数据库(auth_sessions,token_family 轮换检测)
patbond-user(用户域 + 平台能力,:8082)
- 用户资料:
/api/v1/me - 埋点接收:
/api/v1/events(批量 ≤50、202 逐条结果、唯一允许匿名的写端点、eventId 幂等),落platform.product_events - media 上传流程(ADR-017):
POST /api/v1/media/uploads两步上传(预签名 PUT 直传 MinIO → confirm ready)+ 预签名 GET 读取,存储经 ObjectStorage 适配层隔离供应商 - Flyway 迁移链唯一持有者:全部数据库迁移(V1 身份/媒体基线、V2 埋点表、V3 宠物健康域、V4 字典种子……)集中在本模块
src/main/resources/db/migration/统一执行,其他模块不得携带 Flyway——避免多模块并发迁移竞争,pet 域建表也在这里
patbond-pet(宠物健康档案域,:8083,M2 新增)
- 宠物 CRUD 与品种目录:
/api/v1/pets、breeds - 成员权限模型:pet_owners 三角色(owner / caregiver 可写,viewer 只读;ADR-015),创建宠物者自动成为 primary owner
- 健康记录:体重(weights)、疫苗(vaccinations + vaccine catalog,状态机)、健康事件(health-events,六类)、照护提醒(care-reminders,四类,仅数据接口不做推送)
- 档案聚合摘要:summary(最新体重 / 疫苗进度 / 下次接种 / 当月花费,事实表实时聚合不持久化展示值)
- 照片/附件 M2 未做(ADR-010);media 基础能力 M3 已落地(ADR-016/017),宠物头像/疫苗证书接线另排
- 当前状态:M2 已收官全量交付(18 操作 + 契约 v1.2.0 冻结)
patbond-community(社区域,:8084,M3 新增)
- 社区 Feed / 帖子 / 单层评论 / 点赞收藏 / 关注(ADR-018 的 M3 MVP 范围;话题表已建但功能首版剪出)
- 只读写
communityschema(数据表由 V5 建);作者公开资料按 D3-9 方案 B 经 patbond-user 的 /internal 批量接口取数(后续波次落地) /api/v1/**自骨架起即接 RS256 资源侧校验(与 user/pet 同一公钥约定);/health探活在 /api/v1 之外- media 上传流程不在本模块(ADR-017:实现在 patbond-user,社区侧只做 asset 只读校验)
- 当前状态:第一波骨架(T3-02)已落地;业务端点随 M3 后续波次按契约实现
patbond-creation(AI 生成编排域,:8085,M4 新增)
- 编排生成任务,不调用 AI 服务商:上游调用在独立的
patbond-ai(Python)仓库,经 REST 到达(ADR-023 §2) - 只读写
creationschema(数据表由 V6 建,含两处刻意偏离目标模型:input_asset_id改可空以支持文生图、新增first_attempt_at使排队时长与执行耗时可分离) /api/v1/creation/**客户端端点 + 数据库租约队列 Worker(FOR UPDATE SKIP LOCKED+ 租约列,不引入 Redis/MQ,ADR-023 §3)- 不直连对象存储:产物上传凭证来自 patbond-user 的内部媒体接口(预签名 PUT),由生成方直传——ADR-017 的边界不动,且
patbond-ai也因此零对象存储凭证 - 调用 patbond-ai 用服务身份 JWT,独立密钥对(不转发用户 token)。选独立密钥对的依据:现有
JwtVerifier只验签名、不校验aud/iss,而用户 token 无audclaim,复用密钥对会让四个模块把服务票当合法用户 token 接受(ADR-023 §5) - 当前状态:骨架已落地(端点、队列仓储、Worker 三通道、租约回收器、provider 适配层接口)。刻意未实现且会响亮失败:provider 两个实现位(待服务商文档确认五项)、预签名上传目标获取与产物入
media.assets(取决于挂起中的对象存储决策,ADR-023 §7)
patbond-ai(AI 生成服务,独立仓库,Python,M4 新增)
- 不属于
patbond-api多模块,是第四个仓库,已纳入发布语义(ADR-023 §12) - 只负责调用 AI 服务商 API(视频 Seedance / 图片 gpt-image-2);不访问数据库,任务状态的唯一事实来源是 Java 侧的
creation.generation_jobs - 对上游同步或异步一律对外呈现为异步:
submit立即返回任务 id,同步型服务商在其内部以后台任务承载长连接。这样 Java 侧无长连接占线程,且provider_request_id立即可得——超时不再产生「是否已扣费」的歧义 - 内部契约为该仓内独立的
openapi-internal.yaml,不进四模块快照锁,也不写入对外openapi.yaml - 是四仓中唯一持有 AI 服务商凭证的仓库,故
check-secrets.sh已补sk-ant-/sk-/api_key等形态
关键纪律
- 契约先行:所有对外端点以
patbond-doc/docs/api/openapi.yaml为唯一事实源,新接口先冻结契约再实现(M2 起)。 - 单迁移链:数据库迁移只进 patbond-user,新表按域用 schema 前缀区分(identity / platform / pet_health / community / creation)。注意「谁拥有 schema」与「迁移文件放哪」是分开的——pet/community/creation 的业务代码各在自己模块,迁移文件全在 patbond-user,
flyway_schema_history只有一份。 - 服务间调用:MVP 阶段 Feign 静态 URL 直连、无注册中心(ADR-002,Nacos 已移除);微服务化阶段再引入。Java↔Java 用
InternalAuthFilter的共享 token,Java↔Python 用服务身份 JWT——两套并存是有意选择,见 ADR-023 §5。 - 配置:敏感配置走
.env/application.yml(gitignore)+.sample模式,环境变量注入(PATBOND_DB_URL等)。 - 测试:集成测试一律 Testcontainers(postgres:18,ADR-006/008),每模块交付
./mvnw clean test必绿。
演进方向
- 微服务化(ADR-002 预留):模块边界即服务边界,pet 域可整模块独立部署;届时引入配套版本 Spring Cloud Alibaba。
- M5 marketplace 域:V3 已裁剪的 4 条跨 schema 外键(vaccinations/health_events → providers/bookings)由 M5 迁移补回。
- media 域扩展:基础上传链路已随 M3 落地(自托管 MinIO,ADR-016);带宽/预算触发时迁云对象存储(适配层保证仅换配置);宠物头像、疫苗证书、健康事件附件接线另排。
相关文档
- 技术决策记录:decisions.md(ADR-001 起持续编号)
- API 契约:
docs/api/openapi.yaml - 各迭代过程报告:开发文档 → 第一/第二迭代