lixi
|
8089c06a73
|
feat: 事件字典 v3 白名单扩充——community 域 19 事件 + experiment_exposed 字典先行(T3-20 后端,ADR-020)
CI / backend-test (push) Successful in 5m26s
- EventDictionary 增补 20 个事件(iteration-3 报告 06 §1.5 白名单原样落地):
post 域 8(发布漏斗 started/draft_saved/publish_succeeded/failed、post_deleted、
媒体上传三段逐文件漏斗);feed 域 2(feed_viewed 浏览段聚合曝光 + feed_load_failed);
互动 8(like/unlike、favorite/unfavorite、comment 成败对、follow/unfollow);
platform 域 experiment_exposed(A/B 前置 #5,M4 启用字典先行)
- 字典 javadoc 同步 v3:社区隐私红线增量(§1.3 无正文/无内容 ID/无话题名/无媒体线索)
与 pageName v3 页面族(§6.1 收编 4 + 新增 9,键级校验不变、后端零代码)
- EventDictionaryTest:每个新事件键集边界锁定 + §1.2/§1.4/§1.6 故意不设事件
(post_impression/post_viewed/comment_create_started/单点互动 _failed/topic_follow)
- AnalyticsIntegrationTest:feed_viewed 聚合事件入库、post_liked 白名单外
postId 剥离(红线 2)、post_impression 拒绝(§1.2 裁定 ingest 侧锁死)
- 测试 325 → 334(+9),openapi.yaml 无需变更(events 契约对事件名开放)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
v0.3.0
|
2026-09-09 11:51:16 +08:00 |
|
lixi
|
0569585434
|
test: 契约冻结 v1.3.0 api 侧收尾——四模块字节级快照同步 + community/media 契约矩阵入场
CI / backend-test (push) Successful in 5m4s
- 正典 v1.3.0(doc main@f848476)字节级复制为 pet/auth/community/user 四份
openapi-v1.3.0.yaml 快照(md5 与正典一致),删除旧 v1.2.0(守卫只认一份,
历史由 git 承载);pet/auth 守卫期望升版 1.3.0/31 路径/43 操作/72 schemas
- CommunityContractConformanceTest:community 域 17 操作 64 单元格全响应矩阵
(Feed/帖子/评论/互动/关注,401/403/404/409/422 各格实证,零豁免)
- MediaContractConformanceTest(user 模块):media 两步上传 2 操作 8 单元格
全矩阵(真实 MinIO 直传,零豁免)
- ContractValidator 四副本加单分支 allOf 展平合并,修复 v1.3.0
nullable+allOf 模式(coverImage/replyToUser)被静默跳过的校验盲区,
定向 mutation 自证生效
- 实现与冻结契约零漂移;310 → 325 测试全绿;check-secrets --all 通过
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-09-09 11:31:45 +08:00 |
|
lixi
|
7f1dd33097
|
feat: 单层评论——幂等创建/游标列表/作者软删与 comment_count 同事务维护(T3-07,ADR-019)
CI / backend-test (push) Successful in 7m33s
- POST /api/v1/posts/{postId}/comments:Idempotency-Key 必带,落
client_request_id + 规范化 request_hash(uq author×key,键按作者隔离);
同键同 payload 返回首条(201,不重复计数),异 payload 409/40905,
重试撞已删首评 404/40404(沿 T3-04 §2.4 先例);replyToUserId 可选
@ 回复,目标须为存活用户(404/40406);content trim 后 1~2000
- GET 评论列表:(created_at DESC, id DESC) 走 ix_comments_post_created
keyset 游标,仅 status=visible,作者与 @ 目标批量走 AuthorProfileGateway
(降级 id-only 同构复用)
- DELETE /api/v1/comments/{commentId} 顶层短路径:仅评论作者可删
(D3-7 拍板,帖主删他人评论不做);可见评论他人删 403/40301,
不存在/已删/所属帖不可见合并 404/40404;FOR UPDATE 锁定状态迁移,
comment_count 同事务 -1 恰一次
- 评论域同用互动门禁:帖子公开面之外(含作者本人草稿)一律 404/40403
逐字节一致
- ErrorCode 新增 40404 COMMENT_NOT_FOUND
- CommentIntegrationTest 14 例:六类路径、幂等矩阵专项、分页不丢不重、
计数对账专项(删评后列值 = visible 行数 = 列表长度)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-09-09 10:50:28 +08:00 |
|
lixi
|
19e8cba59f
|
feat: 点赞/收藏/关注幂等互动与同事务计数——PUT/DELETE 权威终态、我的收藏游标列表、follow-stats(T3-06/T3-08,ADR-018/019)
- PUT/DELETE like|bookmark:复合主键即幂等键(ON CONFLICT DO NOTHING /
条件 DELETE),计数列按关系写实际变更行数同事务增减,响应回
{liked,likeCount}/{bookmarked,bookmarkCount} 权威终态;并发重复施加
恰计 1、PUT+DELETE 竞态终态列值与关系表恒一致(真并发测试锚定)
- 互动门禁定型:只认帖子公开面(published 且未删)——作者本人草稿、
hidden/archived、软删、不存在合并逐字节一致 404/40403
- GET /api/v1/me/bookmarks:按 (bookmarks.created_at DESC, post_id DESC)
keyset 游标,卡片复用 FeedCard 装配;失效帖在页查询内静默剔除,
游标键在关系行上、分页正确性不受剔除影响
- PUT/DELETE /api/v1/users/{userId}/follow + GET follow-stats:
自关注 422/42204(ck_user_follows_self 库层兜底);目标不存在/注销
合并 404/40406,存在性走同库只读 identity.users(ADR-017 例外,
写门禁不适用 Feign 降级语义);计数实时 COUNT 双向索引
- ErrorCode 新增 40406 TARGET_USER_NOT_FOUND、42204 FOLLOW_RULE_VIOLATION
- 集成测试 14 例(LikeBookmark 9 + Follow 5):六类路径、并发幂等专项、
计数对账专项、收藏列表静默剔除与分页
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-09-09 10:50:06 +08:00 |
|
lixi
|
99a3c1f8ab
|
feat: 公共 Feed 游标分页 + 作者公开资料链路(T3-05 / D3-9 方案 B,ADR-002/017)
CI / backend-test (push) Successful in 8m0s
- GET /api/v1/feed:仅 published+public+未删,(published_at DESC, id DESC) keyset
游标恰合 ix_posts_feed,{items,nextCursor,hasMore},禁 OFFSET
- FeedCard 定型:author/category/title/contentPreview(200 码点截断)/coverImage
(唯一 is_cover 行)/mediaCount/三计数(posts 冗余列)/likedByMe/bookmarkedByMe/publishedAt
- AuthorSummary 定型并回填 Post 详情(T3-04 偏差① authorId 占位闭环):
userId+nickname+avatarUrl;Feign 批量调 user /internal/users/profiles,
60s 进程内 TTL 缓存,avatarAssetId 经 media.assets 只读解析后本地签名
- 降级语义:user 服务不可达/出错时 Feed/详情照常 200,作者摘要退为仅 userId,
失败不入缓存;Feign 1s/2s 超时兜底
- compose 为 community 注入 PATBOND_USER_SERVICE_URL/PATBOND_INTERNAL_TOKEN
- 新增分页专项 8 例、卡片定型 5 例、作者链路 7 例、Feign 线路 3 例
(community 32→55;全仓 251→282 全绿,check-secrets --all 通过)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-09-09 10:26:16 +08:00 |
|
lixi
|
40bac85543
|
feat: user 域 /internal 批量公开资料接口——昵称回退/头像指针/静默缺席(D3-9 方案 B,T3-05)
- GET /internal/users/profiles?ids=…:一次最多 50 个,超限/空/非法 UUID 均 400/40000
- 仅暴露 userId/nickname/avatarAssetId;nickname→username 回退在归属侧 SQL 完成
- 不存在与已注销用户静默缺席(墓碑形态 = 消费侧 authorId 保底,不泄露成因)
- InternalAuthFilter 既有 /internal/** 共享密钥保护直接覆盖,无新安全面
- 新增 InternalProfileEndpointTest 8 例(user 模块 88→96)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-09-09 10:26:01 +08:00 |
|
lixi
|
101ac0fbbc
|
feat: 帖子生命周期——草稿/编辑/发布/软删/详情/我的列表(ADR-019,T3-04)
CI / backend-test (push) Successful in 6m33s
- patbond-community 帖子域五端点:POST/GET/PATCH/DELETE /api/v1/posts(/{postId}) + GET /api/v1/me/posts
- 创建型幂等按 ADR-019:Idempotency-Key 必带(1~128)落 uq_posts_author_idempotency,
规范化 request_hash 比对——同键同 hash 返回首帖、异 hash 40905、键按作者隔离
- 权限/错误语义定型(T3-10 冻结输入):403/40301 仅发给可见者,一切不可见合并
404/40403 防枚举(hidden/archived 对作者同样 404);version 乐观锁 40902
- 发布 = PATCH 状态迁移 draft→published(publishedAt 恰写一次,重复发布幂等 no-op)
- 软删 deleted_at 为唯一判定基准,published 行归档为 archived 满足 ck_posts_publish_state
- post_media:仅本人 ready asset(同库只读 media.assets,ADR-017 先例;40405/42203),
position 全给或全不给、isCover 至多一、封面缺省落 position 0;PATCH media 整组替换
- 读取侧图片 URL 由 community 本地预签名 GET(与 user 共用 PATBOND_MINIO_* 配置,
compose 已注入;未配置降级 url=null)
- ErrorCode 增 40301/40403/40905/42203;异常处理补 MissingRequestHeaderException→40000
- 集成测试 +25(六类路径/幂等专项/草稿可见性矩阵/并发 PATCH 真竞争),全套 251 全绿
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-09-09 09:59:46 +08:00 |
|
lixi
|
263cd88451
|
test: auth 域 6 操作契约一致性测试全响应矩阵(D3-8,T3-19)
CI / backend-test (push) Failing after 8s
- 复制 pet 模块契约框架(OpenApiContract/ContractValidator + v1.2.0
字节级快照)入 patbond-auth,沿每模块复制纪律;快照守卫防漏同步
- AuthContractConformanceTest:沿 AuthE2eIntegrationTest 编排同 JVM 真实
拉起 user 服务,register/login/refresh/logout 打 auth、me/trackEvents
打 user;6 操作 19 个 (操作,状态码) 单元格全矩阵零豁免(含 409 双业务
码、423 锁定、40102 重放、me 404 幽灵用户、events 匿名 202/无效 token 401)
- 修契约测试首轮抓到的真实漂移:EventResult.reason 在 accepted/duplicate
条目序列化出 null,契约声明仅 rejected 时出现——reason 加
@JsonInclude(NON_NULL),既有埋点测试零回归
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-09-08 17:11:58 +08:00 |
|
lixi
|
10a43f876c
|
feat: media 域最小闭环——存储适配层 + MinIO 预签名两步上传(ADR-016/017,T3-03)
- ObjectStorage 适配层(供应商唯一缝)+ S3ObjectStorage(AWS SDK v2,
path-style,内网/公网双端点分离签发);endpoint 未配置时服务可启动、
media 端点 500(沿 JWT 公钥先例)
- POST /api/v1/media/uploads:白名单校验(purpose/mime/byteSize 全配置项)
→ uploading 行(objectKey 服务端生成不含用户输入)→ 预签名 PUT 凭据
(requiredHeaders 定型仅 Content-Type,TTL 10m)
- complete:HEAD 校验存在性/大小/类型 → uploading→ready(guarded UPDATE
并发幂等);对象缺失保持 uploading 可重试,内容不符置 failed 终态;
防枚举 40405;新错误码 40405/42205
- 读取侧预签名 GET(TTL 1h),桶保持私有
- compose 纳入 minio 第六容器(镜像与 Testcontainer 同 tag,桶初始化走
应用启动 ensureBucket,三环境零分叉);init-secrets.sh 幂等追加 MinIO
根凭证到 .env(凭证零入库,ADR-021)
- MediaUploadIntegrationTest 12 例:MinIO Testcontainer 全链路直传取回 +
六类失败路径 + 库层约束一致性;uploading 超时清理只记方案(报告 13 §6)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-09-08 17:11:44 +08:00 |
|
lixi
|
8330885b06
|
chore: 凭证防泄漏检查落地——check-secrets 脚本入库 + CI 兜底 step(ADR-021)
CI / backend-test (push) Successful in 6m47s
- 新增 scripts/check-secrets.sh:8 条内容规则 + 文件名黑名单 + 占位/注入允许清单,纯 shell 零外部依赖
- 新增 scripts/hooks/pre-commit:git config core.hooksPath scripts/hooks 启用,扫暂存区
- ci.yml 在 checkout 后新增 Secret scan step(同一脚本 --all),既有 step 未动
- 验收:全仓 194 个已跟踪文件扫描零误报;构造假 AK/SK/私钥/.env 自测 9 类命中全拦截
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-09-08 16:28:04 +08:00 |
|
lixi
|
3c671fcaf5
|
feat: 新建 patbond-community 模块骨架(ADR-017,T3-02)
CI / backend-test (push) Successful in 7m15s
社区服务 :8084 挂入父 pom 与 compose(第五容器,依赖 postgres 健康 + user
先起保证 V5 已执行);/api/v1/** 自骨架起接 RS256 资源侧校验(无 token/畸形/
错签/过期均 401+40101,user/pet 同款复制,P9 下沉待拍板);GET /health 探活
在 /api/v1 之外;.sample 配置模式;生产 classpath 无 Flyway,测试经 user jar
跑全链 V1..V5(pet 先例)。模块只读写 community schema。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-09-08 16:16:26 +08:00 |
|
lixi
|
a97814ac1c
|
feat: Flyway V5 community schema 基线 + 迁移验证集成测试(T3-01)
从目标模型 718~875 行提取 community 全部 8 表(含 topics,ADR-018 表建功能剪、
无种子进生产链);启用 pg_trgm(02 号发现 V1 漏建,trgm 索引照建);剥离 2 条
跨 schema FK:posts.generation_job_id→creation(M4 补回)、posts.region_id→
platform.regions(M5 地区体系补回),裸可空 uuid 列与索引保留,照 V3 剪
marketplace FK 先例。CommunityMigrationIntegrationTest 8 例验证结构与裁剪。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-09-08 16:16:16 +08:00 |
|
lixi
|
64c9b72fd1
|
feat: 事件字典 v2 白名单扩充 pet/health_record 域 10 事件(T2-17 后端)
CI / backend-test (push) Successful in 5m18s
- EventDictionary 增补 pet 域 3 事件(pet_create_started/succeeded/failed)
与 health_record 域 7 事件(create_started/succeeded/failed、viewed、
edit_succeeded/failed、deleted),props 键集按 06 号报告 §1.5 直抄
- page_viewed 转正为 v2 正稿:props 键集 pageName/referrer 与正稿一致,
pageName 枚举(含 pet_form)在客户端编译期约束 + §6.4 值级巡检兜底
- 字典边界测试 5 例:三域 props 键集全矩阵、page_viewed 正稿键集、
刻意不设事件(pet_viewed/edit_started/delete_failed)保持 unknown
- 接收端集成测试 4 例:v2 事件端到端接受、v2 白名单外 props 剥离、
枚举外 recordType 值过 ingest 交巡检、废弃 health_record_action 仍拒绝
- 测试 182 → 191 全绿
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-09-08 11:30:44 +08:00 |
|
lixi
|
d026f2f63d
|
test: 契约一致性测试对冻结契约 v1.2.0 全矩阵校验(T2-09)
CI / backend-test (push) Successful in 5m14s
- 新增 ContractConformanceTest:pets 域 18 操作真实起服务(Testcontainers +
MockMvc)逐一发请求,对照冻结快照 src/test/resources/contract/
openapi-v1.2.0.yaml 严格校验响应结构(未声明字段即漂移、必填/nullable、
类型/枚举/格式/边界、错误码值);覆盖门禁断言契约声明的每个
(操作, 状态码) 单元格都被真实触发(唯一豁免:提醒 PATCH 409 并发守卫)。
- OpenApiContract/ContractValidator:snakeyaml 解析快照 + 自写严格断言,
零新增依赖;快照守卫锁 info.version=1.2.0 与 18 路径/24 操作/45 schema,
正典(doc 仓 docs/api/openapi.yaml)升版而快照未同步时 CI 立即变红。
- 修复漂移:CreatePetRequest.sex 按冻结契约改为必填(原实现缺省补
unknown,契约 required 含 sex);既有测试载荷补 sex 字段。
全套 ./mvnw clean test 182 项全绿(171 → 182,+11 契约测试)。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-09-08 10:36:12 +08:00 |
|
lixi
|
00f7dbdb69
|
feat: 档案聚合摘要接口与四项聚合口径定型(T2-08)
CI / backend-test (push) Successful in 3m36s
- GET /api/v1/pets/{petId}/summary,READ 档(viewer 可读),四项聚合全部实时计算、零持久化(4.3 红线)
- 最新体重:measured_at DESC, id DESC 首行,与体重列表口径一致;无记录为 null
- 疫苗进度:completed 剂次 / 非 cancelled 总剂次;无非 cancelled 记录为 null
- 下次接种:scheduled planned_on 与 completed next_due_on(同系列更高剂次未登记时)取全候选最早日期,含逾期;source 区分 planned/nextDue
- 当月花费:health_events.amount_cents 按 tz 参数(IANA 时区,缺省 UTC)自然月半开区间求和,NULL 金额不计入;恒非 null,无支出为 0
- 集成测试 12 例:空数据语义、跨月边界(含时区口径)、cancelled 不计入、被接续加强针剔除、多宠隔离、防枚举 404、零写入断言
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-09-08 09:45:50 +08:00 |
|
lixi
|
3b27f9fcbe
|
feat: 照护提醒接口与 pending 状态流转(T2-07)
CI / backend-test (push) Successful in 5m8s
- GET/POST /api/v1/pets/{petId}/care-reminders + PATCH /api/v1/care-reminders/{reminderId}
- 四类提醒白名单;创建恒为 pending;列表按 due_at ASC,
?status=pending 待办视图走 ix_care_reminders_due 部分索引
- 状态机 pending→completed/dismissed,终态不可迁移、同状态重放幂等;
completed 必带 completedAt、其余状态禁带(镜像 ck_care_reminder_completed),
违反 → 新错误码 42202 REMINDER_RULE_VIOLATION
- 表无 version 列:流转用当前状态条件更新守卫竞态(落空 → 40902);
顶层记录路径 40402 记录级防枚举;Idempotency-Key 派生主键幂等
- 仅 app 内数据接口,不做推送(D2-5,通知系统属 M6)
- Testcontainers 集成测试 10 例(六类路径 + 状态-completedAt 一致性)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-09-07 17:59:34 +08:00 |
|
lixi
|
d8303bf446
|
feat: 健康事件时间线接口与 occurred_at 游标分页(T2-06)
- GET/POST /api/v1/pets/{petId}/health-events + PATCH /api/v1/health-events/{eventId}
- 六类事件白名单、amount_cents 整数分非负(禁用 Jackson float→int 截断)、
created_by_user_id 记操作者
- occurred_at DESC, id DESC 游标分页对齐 ix_health_events_pet_time;
Idempotency-Key 派生主键幂等;version 乐观锁 40902;
顶层记录路径 40402 记录级防枚举
- health_event_media / provider / booking 不实现不外露(ADR-010)
- Testcontainers 集成测试 11 例(六类路径 + 分页专项)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-09-07 17:59:17 +08:00 |
|
lixi
|
4c2653c643
|
feat: 疫苗目录与疫苗记录接口、状态机与剂次唯一(T2-05)
CI / backend-test (push) Successful in 5m18s
- GET /api/v1/vaccine-catalog(只读字典,species 过滤,仅 enabled)
- GET/POST /api/v1/pets/{petId}/vaccinations、PATCH /api/v1/vaccinations/{id}
(顶层短路径,记录级防枚举:不可见记录一律 404/40402)
- 状态机 scheduled→completed/cancelled,completed/cancelled 终态;
日期规则镜像 ck_vaccination_dates/ck_vaccination_next_due,违反返回
422/42201(新码 VACCINATION_RULE_VIOLATION)
- 剂次唯一冲突 409/40904(新码 VACCINATION_DOSE_EXISTS,草案提议的
40903 已被 MICROCHIP_EXISTS 占用故改号);cancelled 释放唯一占位
- version 乐观锁 409/40902;Idempotency-Key 幂等与 T2-04 同机制
- 疫苗须存在/启用且物种与宠物匹配(40000)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-09-07 17:44:23 +08:00 |
|
lixi
|
825dde3928
|
feat: 体重记录接口与 cursor 分页、Idempotency-Key 幂等(T2-04)
- GET/POST /api/v1/pets/{petId}/weights,复用 PetAccessService 闸口
(READ 读 / WRITE 写,含 caregiver 写成功正向用例)
- cursor 分页按 (measured_at DESC, id DESC) 与 ix_pet_weight_pet_measured
对齐,limit+1 探测 hasMore,同刻记录跨页不丢不重
- Idempotency-Key 可选头:键派生确定性主键 + ON CONFLICT (id) DO NOTHING,
重试返回原记录,零新增迁移
- weight_kg 校验镜像 ck_pet_weight(>0 且 ≤500,两位小数)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-09-07 17:43:59 +08:00 |
|
lixi
|
8fbf44472d
|
feat: 宠物 CRUD 与 pet_owners 三角色权限框架(T2-03)
CI / backend-test (push) Successful in 7m22s
- GET/POST /api/v1/pets、GET/PATCH /api/v1/pets/{petId}、GET /api/v1/breeds
(species 过滤);创建者自动写入 pet_owners primary owner(同事务)
- PetAccessService 统一权限闸口(READ/WRITE/MANAGE 三档 × owner/caregiver/
viewer 三角色,ADR-015):无关系一律 404/40401 防枚举,可见越权 403/40300;
每请求实时查库无缓存,撤销关系即时生效;T2-04~07 复用同一入口
- PATCH version 乐观锁(40902);部分更新语义;status 白名单排除 deleted,
软删除不可经 PATCH 绕过 ck_pets_deleted
- ck_pets_breed 互斥 + 字典品种存在/物种匹配应用层先行校验(40000);
芯片号唯一冲突新错误码 40903 MICROCHIP_EXISTS
- pet 模块接入 RS256 bearer 鉴权(与 user 同一公钥约定),compose 挂载公钥
- 测试基建:test classpath 引入 patbond-user + Flyway,Testcontainers 上跑
完整 V1..V4 迁移链;三角色以测试数据直写 pet_owners 构造(T2-10)
- 集成测试覆盖六类路径 23 例;全套 118 测试全绿(基线 95)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-09-07 17:27:44 +08:00 |
|
lixi
|
58576f8ebc
|
refactor: 移除 EventDictionary 的 health_record_action(ADR-013)
CI / backend-test (push) Successful in 7m19s
- health_record_action 从白名单直接移除(客户端零引用,废弃零成本)
- M2 事件按字典 v2(具体事件名,iteration-2/06)随第二波接口纵切落地;
不复活通用 actionType 设计(多套指标共享分母污染)
- v1 auth 漏斗事件 + page_viewed(遗留 §2)为当前完整白名单
- 新增 EventDictionaryTest:锁定移除后白名单边界,回归防护
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-09-07 14:35:31 +08:00 |
|
lixi
|
0eae1c9bec
|
feat: 新建 patbond-pet 模块骨架(ADR-009,T2-02 前置)
- 新 Maven 模块挂入父 pom,依赖/插件管理对齐既有 user/auth 模式
(common 依赖、starter-web/validation/jdbc、exec classifier repackage)
- 骨架内容:PetApplication、/health 探活端点(含 DB 连通检查)、
GlobalExceptionHandler(同一 {code,message,data} 信封契约)
- 与 user 共库只读写 pet_health schema;不携带 Flyway——单一迁移链
(V1..V4)仍由 patbond-user 启动时统一执行,flyway_schema_history 不拆
- 配置走 .sample 模式(默认端口 8083,敏感信息经环境变量注入不入库)
- compose 编排纳入 pet 服务(依赖 postgres 健康 + user 先起保证迁移就绪);
Dockerfile 与既有服务同模式;Readme 模块清单同步
- 测试:Testcontainers postgres:18 上下文启动冒烟 + /health 探活断言
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-09-07 14:34:52 +08:00 |
|
lixi
|
49299fb4eb
|
feat: Flyway V3 pet_health 结构基线 + V4 字典种子 + pet 域错误码(T2-01)
- V3:pet_health schema 8 张表(breeds/pets/pet_owners/pet_weight_records/
vaccine_catalog/pet_vaccinations/health_events/care_reminders),列、CHECK、
部分唯一索引、updated_at 触发器与目标模型一致
- 强制裁剪:剥离 bootstrap SQL 1156~1166 行 4 条指向 marketplace 的跨 schema
外键(provider_id/booking_id 保留为裸可空 uuid,M5 迁移 marketplace 时补回)
- ADR-010:health_event_media 不建(media 剪出 M2,纯增量表后续补零成本)
- V4:breeds(28 条)与 vaccine_catalog(10 条)字典种子,生产参考数据走正式
迁移链不放 db/dev;正典目录内容由产品侧供稿(D2-6)
- ErrorCode 预置 pets 域四码:40300 PET_ACCESS_DENIED、40401 PET_NOT_FOUND、
40402 RECORD_NOT_FOUND、40902 VERSION_CONFLICT(第二波接口直接消费)
- 新增 PetHealthMigrationIntegrationTest:干净 postgres:18 上全量迁移验证
表数、结构抽查、4 条 FK 确不存在、触发器与种子数据
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-09-07 14:34:19 +08:00 |
|
lixi
|
0d81c38fc6
|
fix: CI 移除全部外部 action 依赖,checkout 改为手动克隆本 Gitea 实例
CI / backend-test (push) Successful in 3m18s
- Gitea 1.20+ 的 DEFAULT_ACTIONS_URL 仅接受 github/self,自定义 gitea.com 不生效,
actions/checkout 回落 github.com 克隆(服务器不可达,实测 unexpected EOF)
- checkout 改为 git init + 从 ${{ github.server_url }} 认证克隆(github.token),
与 apt 装 JDK 一起实现全链路零 GitHub 依赖
|
2026-09-04 18:13:34 +08:00 |
|
lixi
|
b38b0d83bb
|
fix: CI 改用 apt 安装 JDK17 并加 concurrency 取消旧 run
CI / backend-test (push) Failing after 1m31s
- setup-java 从 github.com 下载 JDK 二进制在服务器网络不可达(实测 ETIMEDOUT),
改为 apt 安装 openjdk-17-jdk-headless,apt 源优先切腾讯云镜像
- 同分支连推提交时自动取消旧的排队/进行中 run
|
2026-09-04 18:02:23 +08:00 |
|
lixi
|
6d47c5a2b6
|
feat: 埋点接收端落地——V2 迁移 + POST /api/v1/events 批量上报(报告 13)
CI / backend-test (push) Failing after 1m31s
- Flyway V2:platform.product_events(客户端 UUIDv7 主键即幂等键,user_id 不设外键,client_ts 合理性约束,三索引),DDL 照报告 13 §2.2
- POST /api/v1/events(报告 13 §1 OpenAPI):批量 1-50 条、202 逐条结果(accepted/duplicate/rejected)、eventId ON CONFLICT 去重、字典 v1 白名单(11 个 auth_* + 工单增补 page_viewed/health_record_action)、字典外 props 剥离计数、隐私红线字段整条拒绝(forbidden_field)、认证请求 userId 与 token subject 不一致拒绝(identity_mismatch)
- BearerAuthFilter 对 /api/v1/events 改为可选鉴权(规范:唯一允许匿名的写端点;带 token 仍严格验签 401/40101)
- 日志红线:props 内容不落日志(仅计数与字段名告警)
- 门禁:./mvnw clean test → BUILD SUCCESS,82 测试 0 失败(新增 AnalyticsIntegrationTest 7 例:V2 生效/匿名落库/未知事件拒绝/去重/剥离/红线拒绝/参数 40000)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-09-04 17:09:00 +08:00 |
|
lixi
|
b22eaede28
|
update
CI / backend-test (push) Successful in 9m51s
|
2026-09-04 16:53:43 +08:00 |
|
lixi
|
6528a06c28
|
feat: auth_sessions 死亡行定时清理任务(报告 16 遗留 §9.3)
CI / backend-test (push) Failing after 8m10s
- SessionCleanupJob(@Scheduled,间隔/初始延迟/保留期均配置项,默认 6h/10m/30d)删除撤销或过期超过保留期的会话行;保留期即重用检测窗口(已撤销行是重用比对对象),注释与 sample 已说明
- 多实例并发安全(幂等 DELETE);轮换链 FK 由 ON DELETE SET NULL 释放
- 门禁:./mvnw clean test → BUILD SUCCESS,75 测试 0 失败(新增 SessionCleanupIntegrationTest:仅删超期死亡行,存活与近期撤销行保留)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-09-04 15:45:38 +08:00 |
|
lixi
|
3f6e8187cf
|
chore: 新增 Gitea Actions CI 门禁工作流(审计 M3)
CI / backend-test (push) Failing after 16m6s
- .gitea/workflows/ci.yml:push(dev)/PR 触发 ./mvnw -B clean test,与本地门禁同一命令
- 服务器侧启用前提(开启 Actions、注册带 Docker 的 act_runner)已写入文件头注释;未启用时本文件无副作用
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-09-04 14:52:55 +08:00 |
|
lixi
|
ab0265c17b
|
feat: Docker Compose 最小编排——postgres:18 + 双无状态服务容器(ADR-007)
- 新增 docker-compose.yml、两服务 Dockerfile(eclipse-temurin:17-jre、非 root、仅装 exec jar)与 deploy/init-secrets.sh(幂等生成 RS256 密钥对与 .env 随机机密,产物入 .gitignore)
- 容器配置复用 application.yml.sample(SPRING_CONFIG_LOCATION 挂载)+ PATBOND_* 环境变量,与本机运行同一套约定;DB 端口不对宿主机发布
- spring-boot-maven-plugin 显式绑定 repackage(本工程无 starter-parent,此前 package 产物不可执行),exec classifier 保留普通 jar 供 auth 模块 E2E 依赖
- 验收:docker compose up -d --build 后完整冒烟通过(register→me→refresh→旧 token 重用 40102→/internal 无凭证 401→logout),down -v 无残留;./mvnw clean test 全绿 74 测试
- README 新增 Docker Compose 一节
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-09-04 14:51:34 +08:00 |
|
lixi
|
8a799719ff
|
fix: 响应信封不再泄露派生字段 success,严格等于 {code, message, data}
- ApiResponse.isSuccess() 加 @JsonIgnore(common 引入 jackson-annotations,仅注解不含 databind);三波以来所有响应都多带了一个契约外的 success 字段,前端解析器忽略未知字段,无破坏
- 测试补断言 $.success doesNotExist;门禁:./mvnw clean test → BUILD SUCCESS,74 测试 0 失败
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-09-04 14:51:34 +08:00 |
|
lixi
|
8bdaf53222
|
feat: 会话记录接入客户端 X-Device-Id(auth_sessions.device_id)
- Flutter 端每次请求已携带 X-Device-Id;auth 读取该头(截断 128)经 CreateSessionRequest 透传,user 落 auth_sessions.device_id,为多设备会话列表备数据
- 门禁:./mvnw clean test → BUILD SUCCESS,74 测试 0 失败(新增 registerForwardsDeviceIdHeaderToTheSessionRecord + 会话落库断言)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-09-04 14:43:44 +08:00 |
|
lixi
|
4dc3dcdfa3
|
feat: JWT RS256 + refresh 会话轮换与 /api/v1 契约落地(ADR-003)
- 会话逻辑下沉 patbond-user(新 /internal/sessions;auth_sessions 只存 SHA-256 摘要,刷新即轮换并链 token_family,重用撤销整个 family,退出仅撤当前会话,多设备并行)
- patbond-auth 作薄入口签发 RS256 JWT(access 15m / refresh 30d 均为配置项;密钥经环境变量注入,仓库零密钥材料,测试密钥运行时生成);公开端点迁至 /api/v1,冻结契约字段零偏差,expiresAt 无时区遗留修复
- /internal/** 加 X-Internal-Token 服务间鉴权(无凭证 401);/api/v1/me 由 user 以公钥本地验签(40101/40102 新错误码)
- 登录失败限制:按用户名 15 分钟窗口 5 次锁 15 分钟(423/42300,DB 原子计数,可配置)
- 修复两处存量缺陷:ErrorDecoder 未注册进 Feign 子上下文、JDK HttpURLConnection 对流式 POST 的 401 读不到错误体(引入 feign-hc5)——真实调用中下游错误码此前一律折叠为 503
- 门禁:JAVA_HOME=/usr/lib/jvm/java-17-openjdk ./mvnw clean test → BUILD SUCCESS,73 测试 0 失败(37→73),含同 JVM 双服务真实 HTTP E2E:注册→me→刷新→旧 refresh 重用被拒且 family 撤销→退出后 refresh 失效;Testcontainers postgres:18,无遗留容器
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-09-04 12:15:40 +08:00 |
|
lixi
|
43ab6c5827
|
test: Testcontainers 数据库镜像升级为 postgres:18(ADR-008)
- 验收:JAVA_HOME=jdk17 ./mvnw clean test 全量 37 测试 0 失败,Flyway V1 于 PostgreSQL 18.6 执行无兼容问题
|
2026-09-04 11:34:08 +08:00 |
|
lixi
|
bd20adc700
|
feat: 用户 UUID 持久化与统一异常契约(Flyway baseline / UUIDv7 / 错误码透传)
- Flyway V1 baseline:identity 全部 5 表 + media.assets + platform 最小硬依赖(set_updated_at/regions),无 fixture 凭据;dev 种子独立为 afterMigrate 回调且默认不执行
- patbond-user 迁移到 PostgreSQL:UUIDv7 主键、JdbcClient 仓储、bcrypt 密码、唯一性依赖 DB 约束翻译为 409、E.164 手机号校验对齐 ck_users_phone
- 统一异常契约:common 新增 ErrorCode/BusinessException,两服务 GlobalExceptionHandler;auth 经 ApiErrorDecoder 原码透传下游错误,修复状态码折叠(审计 M1)
- 门禁:JAVA_HOME=jdk17 ./mvnw clean test,37 个测试 0 失败(含 Testcontainers postgres:16 集成测试),BUILD SUCCESS
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-09-04 10:34:48 +08:00 |
|
lixi
|
c7ddaecb76
|
重构底层框架
|
2026-09-03 17:59:56 +08:00 |
|
nmbh1122@126.com
|
5a52b44d46
|
chore: move local configs to sample files
|
2026-07-20 16:22:54 +08:00 |
|
nmbh1122@126.com
|
8cfc574247
|
feat(update):更新nacos配置文件
|
2026-07-20 14:56:05 +08:00 |
|
nmbh1122@126.com
|
c743b7a753
|
Add project README
|
2026-07-13 09:48:26 +08:00 |
|
nmbh1122@126.com
|
c43f30175d
|
Ignore build outputs
|
2026-07-13 09:41:33 +08:00 |
|
nmbh1122@126.com
|
b1252b991d
|
Initialize patbond microservice modules
|
2026-07-13 09:41:15 +08:00 |
|