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>
143 lines
5.8 KiB
XML
143 lines
5.8 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
<modelVersion>4.0.0</modelVersion>
|
|
|
|
<parent>
|
|
<groupId>com.patbond.patbond</groupId>
|
|
<artifactId>patbond-api</artifactId>
|
|
<version>1.0.0-SNAPSHOT</version>
|
|
<relativePath>../pom.xml</relativePath>
|
|
</parent>
|
|
|
|
<artifactId>patbond-pet</artifactId>
|
|
<packaging>jar</packaging>
|
|
|
|
<name>patbond-pet</name>
|
|
<description>Pet profile and health record service for Patbond (ADR-009)</description>
|
|
|
|
<!-- M2 second-wave: business endpoints with RS256 bearer auth (same JWT
|
|
verification stack as patbond-user), pet_health schema CRUD. Flyway
|
|
remains absent — the migration chain is owned by patbond-user. -->
|
|
<dependencies>
|
|
<dependency>
|
|
<groupId>com.patbond.patbond</groupId>
|
|
<artifactId>patbond-common</artifactId>
|
|
<version>${project.version}</version>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-web</artifactId>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-validation</artifactId>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-jdbc</artifactId>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.postgresql</groupId>
|
|
<artifactId>postgresql</artifactId>
|
|
<scope>runtime</scope>
|
|
</dependency>
|
|
<!-- Read-side media URL signing only (presigned GET is a local SigV4
|
|
computation): this service never talks to the object store, the
|
|
media write flow stays in patbond-user (ADR-016/017). Same
|
|
precedent as patbond-community's read side. Version managed by
|
|
the root pom's awssdk bom. -->
|
|
<dependency>
|
|
<groupId>software.amazon.awssdk</groupId>
|
|
<artifactId>s3</artifactId>
|
|
</dependency>
|
|
<!-- Access token verification (RS256, public key only): jjwt is not in
|
|
the Boot BOM, version pinned in step with patbond-user/auth. -->
|
|
<dependency>
|
|
<groupId>io.jsonwebtoken</groupId>
|
|
<artifactId>jjwt-api</artifactId>
|
|
<version>0.12.6</version>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>io.jsonwebtoken</groupId>
|
|
<artifactId>jjwt-impl</artifactId>
|
|
<version>0.12.6</version>
|
|
<scope>runtime</scope>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>io.jsonwebtoken</groupId>
|
|
<artifactId>jjwt-jackson</artifactId>
|
|
<version>0.12.6</version>
|
|
<scope>runtime</scope>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-test</artifactId>
|
|
<scope>test</scope>
|
|
</dependency>
|
|
<!-- Tests need the pet_health schema. The migration chain (V1..V4) is
|
|
owned by patbond-user (single flyway_schema_history); pulling its
|
|
plain jar plus Flyway into the TEST classpath lets Boot's Flyway
|
|
auto-config apply the same chain to the disposable container.
|
|
Production wiring is unchanged: this module still ships without
|
|
Flyway and the chain runs in patbond-user's startup path. -->
|
|
<dependency>
|
|
<groupId>com.patbond.patbond</groupId>
|
|
<artifactId>patbond-user</artifactId>
|
|
<version>${project.version}</version>
|
|
<scope>test</scope>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.flywaydb</groupId>
|
|
<artifactId>flyway-core</artifactId>
|
|
<scope>test</scope>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.flywaydb</groupId>
|
|
<artifactId>flyway-database-postgresql</artifactId>
|
|
<scope>test</scope>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-testcontainers</artifactId>
|
|
<scope>test</scope>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.testcontainers</groupId>
|
|
<artifactId>postgresql</artifactId>
|
|
<scope>test</scope>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.testcontainers</groupId>
|
|
<artifactId>junit-jupiter</artifactId>
|
|
<scope>test</scope>
|
|
</dependency>
|
|
</dependencies>
|
|
|
|
<build>
|
|
<plugins>
|
|
<plugin>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
|
<!-- No spring-boot-starter-parent in this build, so the
|
|
executable-jar repackaging must be bound explicitly. -->
|
|
<executions>
|
|
<execution>
|
|
<goals>
|
|
<goal>repackage</goal>
|
|
</goals>
|
|
<configuration>
|
|
<!-- Keep the plain jar as the main artifact so other
|
|
modules can depend on this one; the runnable fat
|
|
jar gets the -exec classifier and is what the
|
|
Dockerfile ships (same pattern as user/auth). -->
|
|
<classifier>exec</classifier>
|
|
</configuration>
|
|
</execution>
|
|
</executions>
|
|
</plugin>
|
|
</plugins>
|
|
</build>
|
|
</project>
|