15c2e66519
- 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>
156 lines
7.7 KiB
YAML
156 lines
7.7 KiB
YAML
# 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"]
|
||
|
||
# M3(ADR-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/017:media 上传流程在 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
|
||
|
||
# M3(ADR-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:
|