Files
patbond-api/docker-compose.yml
lixi 15c2e66519 feat: 宠物头像读写——PATCH 支持 avatarAssetId、详情与列表补 avatarUrl(T3.5-05,ADR-022)
- PATCH /api/v1/pets/{petId} 支持 avatarAssetId 三态:缺省不改、显式 null
  清空、给值设置。这是 pets 域唯一的三态字段——M2 惯例「null 与缺省同义」
  无法表达「删掉头像」,而 name/species/sex 本就不允许为空,故差异刻意限定
  在本字段
- 权限按「本次请求碰了哪些字段」定档:仅改头像为 WRITE(owner+caregiver,
  ADR-022:头像属日常照护信息,与体重/疫苗同档),碰到任一资料字段仍是
  MANAGE(仅 owner),混合请求按更严的一半判;viewer 一律 403/40300
- 头像与资料共用同一把乐观锁:仅改头像也吃 version,旧版本必答 409/40902
- asset 校验复用 T3-03 引用侧协议 + purpose='pet_avatar':不存在/非本人/
  已删/用途不符答 404/40405,本人未就绪答 422/42203(user_avatar 资源也不能
  当宠物头像)
- 详情与列表响应补 avatarUrl(本地 SigV4 现签预签名 GET,沿用 community 读侧
  先例):仅当 asset 为 ready 才签,指针在而资源退出 ready 时降级为 null,
  不签一个下载必 404 的地址,也不隐式清理指针
- PetRepository 读改为返回 PetRow(含头像存储坐标),签名上移到 PetService,
  与 community 的 PostRow → PostResponse 装配同构——过期 URL 不下沉到仓储层
- pet 模块加入 aws-sdk s3(仅本地签名,不直连对象存储)与读侧 patbond.media
  配置;compose 补同一组 PATBOND_MINIO_* 环境变量
- 测试 +11(成功/清空/缺省保留/降级/caregiver 与 viewer 权限/防枚举 404/
  asset 五态/畸形入参/乐观锁与重放),pet 模块 89 → 100

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

156 lines
7.7 KiB
YAML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Patbond MVP 编排(ADR-007):应用容器无状态,PostgreSQL 数据落 volume。
# 使用步骤见 Readme.md「Docker Compose」一节:
# 1) ./deploy/init-secrets.sh 生成 RS256 密钥对与 .env(均不入库)
# 2) JAVA_HOME=... ./mvnw -DskipTests package
# 3) docker compose up -d --build
#
# 配置来源:容器内挂载各服务的 application.yml.sample 作为配置文件,
# 其中的 ${PATBOND_*} 占位由下方 environment 注入 —— 与本机运行同一套约定。
name: patbond
services:
postgres:
image: postgres:18
environment:
POSTGRES_DB: ${PATBOND_DB_NAME:-patbond}
POSTGRES_USER: ${PATBOND_DB_USER:-patbond}
POSTGRES_PASSWORD: ${PATBOND_DB_PASSWORD:?先运行 deploy/init-secrets.sh 生成 .env}
volumes:
# postgres:18 官方镜像的挂载点是 /var/lib/postgresql(含版本子目录)
- pgdata:/var/lib/postgresql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${PATBOND_DB_USER:-patbond} -d ${PATBOND_DB_NAME:-patbond}"]
interval: 2s
timeout: 3s
retries: 30
# 数据库不对宿主机发布端口;调试需要时可临时加 ports: ["15432:5432"]
# M3ADR-016):自托管 MinIO 对象存储。镜像 tag 与集成测试的 MinIO
# Testcontainer 钉同一版本(三环境零分叉);对象数据落 volume(ADR-007
# 应用容器保持无状态)。桶初始化由 user 服务启动时执行(ensureBucket
# 本地/compose/CI 同一条路径),无需 mc 初始化容器。9000 端口必须对客户端
# 可达:预签名直传/读取 URL 都直接指向 MinIO,不经应用服务器。
minio:
image: minio/minio:RELEASE.2025-04-22T22-12-26Z
command: server /data
environment:
MINIO_ROOT_USER: ${PATBOND_MINIO_ROOT_USER:?先运行 deploy/init-secrets.sh 生成 .env}
MINIO_ROOT_PASSWORD: ${PATBOND_MINIO_ROOT_PASSWORD:?先运行 deploy/init-secrets.sh 生成 .env}
volumes:
- minio-data:/data
healthcheck:
test: ["CMD-SHELL", "curl -sf http://127.0.0.1:9000/minio/health/live"]
interval: 2s
timeout: 3s
retries: 30
ports:
- "${PATBOND_MINIO_PORT:-9000}:9000"
user:
build: ./patbond-user
environment:
SPRING_CONFIG_LOCATION: file:/config/application.yml
PATBOND_DB_URL: jdbc:postgresql://postgres:5432/${PATBOND_DB_NAME:-patbond}
PATBOND_DB_USER: ${PATBOND_DB_USER:-patbond}
PATBOND_DB_PASSWORD: ${PATBOND_DB_PASSWORD:?先运行 deploy/init-secrets.sh 生成 .env}
PATBOND_INTERNAL_TOKEN: ${PATBOND_INTERNAL_TOKEN:?先运行 deploy/init-secrets.sh 生成 .env}
PATBOND_JWT_PUBLIC_KEY: /run/patbond/keys/jwt-public.pem
# ADR-016/017media 上传流程在 user 服务。服务自身走内网端点;
# 预签名 URL 按 PATBOND_MINIO_PUBLIC_ENDPOINT 签发(默认本机回环,
# 真机联调/生产改为客户端可达地址)。
PATBOND_MINIO_ENDPOINT: http://minio:9000
PATBOND_MINIO_PUBLIC_ENDPOINT: ${PATBOND_MINIO_PUBLIC_ENDPOINT:-http://127.0.0.1:9000}
PATBOND_MINIO_ACCESS_KEY: ${PATBOND_MINIO_ROOT_USER:?先运行 deploy/init-secrets.sh 生成 .env}
PATBOND_MINIO_SECRET_KEY: ${PATBOND_MINIO_ROOT_PASSWORD:?先运行 deploy/init-secrets.sh 生成 .env}
PATBOND_MINIO_BUCKET: ${PATBOND_MINIO_BUCKET:-patbond-media}
volumes:
- ./patbond-user/src/main/resources/application.yml.sample:/config/application.yml:ro
- ./deploy/keys:/run/patbond/keys:ro
# MVP 直连暴露 8082 供客户端访问 /api/v1/me/internal/** 已有服务间鉴权,
# 规模化阶段应由网关统一入口并停止直接暴露本端口。
ports:
- "${PATBOND_USER_PORT:-8082}:8082"
depends_on:
postgres:
condition: service_healthy
minio:
condition: service_healthy
auth:
build: ./patbond-auth
environment:
SPRING_CONFIG_LOCATION: file:/config/application.yml
PATBOND_USER_SERVICE_URL: http://user:8082
PATBOND_INTERNAL_TOKEN: ${PATBOND_INTERNAL_TOKEN:?先运行 deploy/init-secrets.sh 生成 .env}
PATBOND_JWT_PRIVATE_KEY: /run/patbond/keys/jwt-private.pem
volumes:
- ./patbond-auth/src/main/resources/application.yml.sample:/config/application.yml:ro
- ./deploy/keys:/run/patbond/keys:ro
ports:
- "${PATBOND_AUTH_PORT:-8081}:8081"
depends_on:
- user
# M2(ADR-009):宠物健康档案服务。第二波起提供 /api/v1/pets、/api/v1/breeds
# 业务端点(RS256 校验,与 user 同一公钥)。与 user 共库;Flyway 迁移链由
# user 服务统一执行,故依赖 user 先起,保证 pet_health schema 已就绪。
pet:
build: ./patbond-pet
environment:
SPRING_CONFIG_LOCATION: file:/config/application.yml
PATBOND_DB_URL: jdbc:postgresql://postgres:5432/${PATBOND_DB_NAME:-patbond}
PATBOND_DB_USER: ${PATBOND_DB_USER:-patbond}
PATBOND_DB_PASSWORD: ${PATBOND_DB_PASSWORD:?先运行 deploy/init-secrets.sh 生成 .env}
PATBOND_JWT_PUBLIC_KEY: /run/patbond/keys/jwt-public.pem
# 媒体读取侧(M3.5 T3.5-05):宠物头像的预签名 GET 与 user 服务同一凭证/
# 同一客户端可达地址(本地 SigV4 计算,不直连 MinIO,无需 depends_on minio)。
PATBOND_MINIO_PUBLIC_ENDPOINT: ${PATBOND_MINIO_PUBLIC_ENDPOINT:-http://127.0.0.1:9000}
PATBOND_MINIO_ACCESS_KEY: ${PATBOND_MINIO_ROOT_USER:?先运行 deploy/init-secrets.sh 生成 .env}
PATBOND_MINIO_SECRET_KEY: ${PATBOND_MINIO_ROOT_PASSWORD:?先运行 deploy/init-secrets.sh 生成 .env}
volumes:
- ./patbond-pet/src/main/resources/application.yml.sample:/config/application.yml:ro
- ./deploy/keys:/run/patbond/keys:ro
ports:
- "${PATBOND_PET_PORT:-8083}:8083"
depends_on:
postgres:
condition: service_healthy
user:
condition: service_started
# M3ADR-017):社区服务(Feed/帖子/评论/互动)。骨架起 /api/v1/** 即接
# RS256 校验(与 user/pet 同一公钥);只读写 community schema。与 user 共库;
# Flyway 迁移链(V1..V5,含 community 基线)由 user 服务统一执行,故依赖
# user 先起,保证 community schema 已就绪。
community:
build: ./patbond-community
environment:
SPRING_CONFIG_LOCATION: file:/config/application.yml
PATBOND_DB_URL: jdbc:postgresql://postgres:5432/${PATBOND_DB_NAME:-patbond}
PATBOND_DB_USER: ${PATBOND_DB_USER:-patbond}
PATBOND_DB_PASSWORD: ${PATBOND_DB_PASSWORD:?先运行 deploy/init-secrets.sh 生成 .env}
PATBOND_JWT_PUBLIC_KEY: /run/patbond/keys/jwt-public.pem
# 作者公开资料(D3-9 方案 B):走 user 服务 /internal 批量接口,
# 服务间共享密钥与 auth/user 同一值。
PATBOND_USER_SERVICE_URL: http://user:8082
PATBOND_INTERNAL_TOKEN: ${PATBOND_INTERNAL_TOKEN:?先运行 deploy/init-secrets.sh 生成 .env}
# 媒体读取侧:帖子响应中图片 URL 的预签名 GET 与 user 服务同一凭证/同一
# 客户端可达地址(本地 SigV4 计算,不直连 MinIO,无需 depends_on minio)。
PATBOND_MINIO_PUBLIC_ENDPOINT: ${PATBOND_MINIO_PUBLIC_ENDPOINT:-http://127.0.0.1:9000}
PATBOND_MINIO_ACCESS_KEY: ${PATBOND_MINIO_ROOT_USER:?先运行 deploy/init-secrets.sh 生成 .env}
PATBOND_MINIO_SECRET_KEY: ${PATBOND_MINIO_ROOT_PASSWORD:?先运行 deploy/init-secrets.sh 生成 .env}
volumes:
- ./patbond-community/src/main/resources/application.yml.sample:/config/application.yml:ro
- ./deploy/keys:/run/patbond/keys:ro
ports:
- "${PATBOND_COMMUNITY_PORT:-8084}:8084"
depends_on:
postgres:
condition: service_healthy
user:
condition: service_started
volumes:
pgdata:
minio-data: