| content |
{"Commits":[{"Sha1":"36fd05364 {"Commits":[{"Sha1":"36fd0536408149355981d06096633ca3249a035e","Message":"feat: 合并成员姓名、应用、登录客户端与资源类型名称\n\n用户测试时发现成员只有成员代码、应用登记只有应用代码,登录客户端和资源类型也只有代码。本次把四项名称的后端实现与前端接入一起合入 main。\n\n实现内容:\n- 后端(feat/display-names):两类邀请必填 displayName,新账号使用邀请姓名、已有账号不覆盖;本人与平台管理员可改姓名(带账号版本,不影响会话与授权),历史默认姓名标记 display_name_set=false;成员列表可按姓名搜索;应用登记必填名称并可改名,管理角色返回 application_name;登录客户端与资源类型新增可选名称及改名接口(资源类型使用独立 name_version);V33 迁移\n- 前端:两类邀请表单加姓名;个人中心确认/修改姓名,所有账号可更正姓名;应用登记填写名称、概况页改名,角色标签与切换器显示应用名称;客户端与资源规则可设置、修改、清除名称,企业侧数据范围显示资源类型名称\n\n验证:\n- 后端:Codex 在功能分支上执行定向 verify,237 项单元测试与 142 项集成测试通过,同步 main 0200f78 后复验 1 项单元测试与 19 项集成测试通过(见交接文档 docs/console/display-names-handoff.md)\n- 前端:npm run check 通过,测试 293 项\n- 合并前核对 main 新增的 P12 提交 f8a1e54、b892d79 与本次合并内容没有共同修改的文件,也没有新增迁移;合并后未重新运行后端测试\n- 未做浏览器检查,未与真实后端联调\n\nBREAKING CHANGE: 企业邀请、平台管理员邀请与应用登记必须提供 displayName,前后端需同时发布;部署前先执行 V33 迁移。\n","AuthorEmail":"gamebyteyu@gmail.com","AuthorName":"starry","CommitterEmail":"gamebyteyu@gmail.com","CommitterName":"starry","Timestamp":"2026-10-15T20:00:56-07:00"},{"Sha1":"b892d7971af67f4f48c971d89b1a96f4c27d9249","Message":"test(capacity): 驱动支持恢复合同统计、专用报告与受控拥塞诊断\n\n容量驱动原来把任何刷新 503 都记为会话不可用,本地也没有办法制造真实的入口名额占满。本提交合入隔离实验中的驱动恢复选项、专用报告与拥塞辅助;正式容量命令默认路径不变。\n\n实现内容:\n- CapacityDriver 新增默认关闭的恢复选项:仅原 token 端点的完整响应可判定未执行,响应头、长度或 chunk 合同不明确时不授予重试资格;每次刷新最多两次串行尝试、25ms 退避、250ms 预算;原始 503、额外尝试、额外 HTTP 与台账父子耗时分别计入样本与汇总;私有轮换台账按 pending/completed/not_started 配对并 force 落盘,未知 pending 永不被后续记录洗白\n- 新增 CapacityRefreshRecovery(台账状态机与合同判定)、CapacityRecoveryEvidence、CapacityRecoveryExperimentDriver(只通过显式构造器开启恢复的计划入口)以及 CapacityRefreshRecoveryTest 15、CapacityRecoveryStatisticsTest 3;RefreshRecoveryContractIT 用真实双实例与数据库屏障验证 503→200 且旧令牌只消费一次,撤权/到期/已消费/回滚仍按原规则\n- scripts/capacity:recovery_report.py 严格复算恢复样本(业务成功、原始拒绝、额外 HTTP 分别计账,样本/汇总/存量三方对账);http_report.py 对恢复合同样本按设计拒绝;environment.py 与 round.py 新增 --driver-main 白名单;prepare.py 编译清单加入新驱动类;round.py --congestion 与 congestion.py 按日程持有部署独占屏障制造真实入口拥塞(持有 50–1000ms、最多 60 窗口、失败即停);README 补充说明\n- 工具测试:test_recovery_report 28、test_congestion 9、test_tools 新增 2\n\n验证:\n- PYTHONDONTWRITEBYTECODE=1 python3 -I -m unittest discover -s scripts/capacity -p 'test_*.py':66 项通过\n- 单元 283 项与集成回归同上一提交,在同一工作树上执行:12 个类 134 项通过,0 失败(ProtocolIT 14、AttackProtectionIT 12、MachineBudgetIT 6、AuthIngressLifecycleIT 6、AuthIngressConservativeIT 1、AuthIngressTimeContractIT 1、RefreshRecoveryContractIT 5、SdkRefreshRecoveryIT 8、DualApplicationsIT 23、RefreshExpiryLifecycleIT 23、ScopedLifecycleIT 9、SessionLifecycleIT 26),335 秒\n- 本地对照证据见未入库的 release/p12-recovery-contrast-local-20261015-b80658e8(低负载零 503)与 release/p12-congestion-recovery-local-20261015-b9411306(真实 503 下恢复率 21.9%、会话零丢失)\n- 未运行云端容量验收\n","AuthorEmail":"gamebyteyu@gmail.com","AuthorName":"starry","CommitterEmail":"gamebyteyu@gmail.com","CommitterName":"starry","Timestamp":"2026-10-15T19:59:08-07:00"},{"Sha1":"f8a1e548ef6adf50a225636d7005b3f13cb259da","Message":"feat(protocol): 入口名额拒绝返回未执行标记并由 SDK 有界重试一次\n\n每实例 8 个协议入口名额占满时 POST /oauth2/token 立即 503,客户端无法区分“业务未开始”与“结果未知”,只能丢弃会话重新登录;E2d 云测 30 次此类拒绝使原始可用会话 19970/20000,正式测量未开始。本提交把隔离候选的恢复合同合入主区:服务端只在该分支标记未执行,SDK 据此最多再试一次,其余失败语义不变。\n\n实现内容:\n- AttackProtectionConfiguration:仅 POST /oauth2/token 的 tryAcquire 失败分支,在调用过滤链之前加响应头 IAM-Request-Outcome: not-started-v1;状态 503、Cache-Control: no-store 与正文 {\"error\":\"server_error\"} 不变,/internal/protocol/* 与其他 503 不带标记,名额数与释放逻辑不变\n- iam-java-sdk 新增 RefreshRecovery:只有状态、唯一头、no-store 与固定正文(多读一字节)全部匹配才判定未执行;同一会话串行,最多额外一次,退避 25ms,第二次须在首次发起后 250ms 内发出,每次发起前重查撤销/绝对/闲置期限;BffSessions 第二次仍未执行时保留原代与 lastUse 并返回 503 TOKEN_REQUEST_NOT_STARTED,未知结果、invalid_grant、验签失败仍结束会话\n- 测试:RefreshRecoveryTest 15 项(真实 Spring 协议解析加模拟 HTTP)、IngressOutcomeContractTest(八名额占满时只有拒绝分支带标记且名额全部归还)、SdkRefreshRecoveryIT(真实 Java SDK、浏览器、双 IAM 与数据库屏障:单次/两次拒绝后恢复、撤销/到期/已消费拒绝、提交后丢响应不重放、本地闲置不发第二次)及支撑类 SdkRecoveryTestBridge、SdkLoginDiagnostics、SdkTestClock;测试签名密钥改为 3072 位与生产一致\n- 文档:attack-protection.md 新增“P12 入口拒绝的明确未执行标记”,sdk.md 新增“P12 明确未执行的刷新恢复”并修正刷新尝试次数描述\n\n验证(在同时含后续 test(capacity) 提交内容的同一工作树上执行):\n- ./mvnw -o -B -ntp -pl iam-key-security,iam-java-sdk,iam-server -am test:6 个模块 283 项单元测试通过\n- ./mvnw -o -B -ntp -pl iam-server -am verify -Dit.test=SdkRefreshRecoveryIT,RefreshRecoveryContractIT,AuthIngressLifecycleIT,AuthIngressConservativeIT,AuthIngressTimeContractIT,AttackProtectionIT,MachineBudgetIT,RefreshExpiryLifecycleIT,ScopedLifecycleIT,SessionLifecycleIT,DualApplicationsIT,ProtocolIT(含 spotless:check):12 个类 134 项通过,0 失败(ProtocolIT 14、AttackProtectionIT 12、MachineBudgetIT 6、AuthIngressLifecycleIT 6、AuthIngressConservativeIT 1、AuthIngressTimeContractIT 1、RefreshRecoveryContractIT 5、SdkRefreshRecoveryIT 8、DualApplicationsIT 23、RefreshExpiryLifecycleIT 23、ScopedLifecycleIT 9、SessionLifecycleIT 26),335 秒\n- 本提交单独检出到临时工作树执行 ./mvnw -o -B -ntp -pl iam-server,iam-java-sdk -am test-compile:通过\n- 本地证据见未入库的 release/p12-id-clock-sdk-recovery-local-20261015-87b969eb 与 release/p12-congestion-recovery-local-20261015-b9411306(受控拥塞下开启组 228 次拒绝全部确认未执行、恢复 50 次、会话零丢失)\n- 未运行云端容量验收,P12 正式门槛未变\n","AuthorEmail":"gamebyteyu@gmail.com","AuthorName":"starry","CommitterEmail":"gamebyteyu@gmail.com","CommitterName":"starry","Timestamp":"2026-10-15T19:58:41-07:00"},{"Sha1":"bcd9b9cd1cc5de30b234888c49738613500d7511","Message":"feat(console): 支持应用、登录客户端与资源类型名称\n\n应用登记原先只能填写代码,登录客户端和资源类型也只有代码,角色标签显示的是「应用管理员 · sales」这类代码。后端已补齐三类名称的写入与读取,控制台同步接入。\n\n实现内容:\n- 应用:登记时名称与代码都必填,提交 displayName;概况页「基本信息」增加设置/修改名称(读取应用版本,归档应用不提供入口);应用列表可按名称或代码搜索\n- 角色标签、工作台、企业切换器与平台入口提示改用 application_name,旧后端未返回时回退为应用代码;权限与路由仍以 application_id 为准\n- 登录客户端:创建时可选填名称(留空不提交该字段);列表以名称为主、代码为辅;详情可就地设置、修改或清除名称(清除提交 null,使用客户端版本)\n- 资源类型:添加资源规则时可选填名称;规则标题以名称为主,可就地改名,改名使用资源类型自己的 name_version,旧后端没有 name_version 时不提供改名;企业侧数据范围与选项显示「名称(代码)」\n- 新增 InlineNameEditor(就地展开的改名表单)与 codeWithName 展示工具\n\n验证:\n- npm run check:格式、lint、类型检查通过,33 个测试文件 293 项测试通过,构建成功\n- 新增 display-names.test.tsx 共 8 项:角色标签回退、可选名称校验、应用登记与改名请求体、客户端创建可选名称与清除名称、资源规则名称提交与按 name_version 改名\n- 未与真实后端联调,未做浏览器检查\n\nBREAKING CHANGE: 登记应用请求新增必填 displayName,须与 V33 及对应后端同时发布\n","AuthorEmail":"gamebyteyu@gmail.com","AuthorName":"starry","CommitterEmail":"gamebyteyu@gmail.com","CommitterName":"starry","Timestamp":"2026-10-15T19:57:20-07:00"},{"Sha1":"873358da99c3ab27ed78c5f4c87edba00229b960","Message":"feat(console): 邀请时填写姓名并支持本人与平台修改姓名\n\n新账号的姓名原先固定为「成员」,成员列表、所有账号等处只能靠成员代码区分。后端已支持邀请时填写姓名、本人改名和平台代改,控制台同步接入。\n\n实现内容:\n- 企业邀请成员、邀请平台管理员均增加必填「姓名」,提交 displayName;待接受的平台邀请以姓名为主、邮箱为辅显示,旧邀请没有姓名时只显示邮箱\n- 个人中心增加「修改姓名」,读取 /api/v1/me 的 version 提交;display_name_set=false 时提示确认姓名,输入框不预填默认名称,成功后用回执更新会话身份\n- 「所有账号」详情增加「更正姓名」,展开时重新读取账号版本,已归档账号不提供入口;企业侧不提供代改\n- 成员列表与设置所有者的搜索改为可按姓名或成员代码搜索;姓名未确认的成员和账号在列表与详情中标出\n- 企业改名弹窗抽成通用 NameEditor(必填/可选、提交 { displayName, version },409 保留草稿),名称校验抽成 nameError,规则仍为 1—160 个 Unicode 字符、拒绝控制字符与行/段落分隔符\n\n验证:\n- npm run check:格式、lint、类型检查通过,32 个测试文件 285 项测试通过,构建成功\n- 新增用例覆盖两类邀请的姓名必填与请求体、按姓名搜索与未确认标记、本人确认姓名、平台更正姓名及版本来源、归档账号无入口\n- 未与真实后端联调,未做浏览器检查\n\nBREAKING CHANGE: 两类邀请请求新增必填 displayName,须与 V33 及对应后端同时发布\n","AuthorEmail":"gamebyteyu@gmail.com","AuthorName":"starry","CommitterEmail":"gamebyteyu@gmail.com","CommitterName":"starry","Timestamp":"2026-10-15T19:52:20-07:00"}],"HeadCommit":{"Sha1":"36fd0536408149355981d06096633ca3249a035e","Message":"feat: 合并成员姓名、应用、登录客户端与资源类型名称\n\n用户测试时发现成员只有成员代码、应用登记只有应用代码,登录客户端和资源类型也只有代码。本次把四项名称的后端实现与前端接入一起合入 main。\n\n实现内容:\n- 后端(feat/display-names):两类邀请必填 displayName,新账号使用邀请姓名、已有账号不覆盖;本人与平台管理员可改姓名(带账号版本,不影响会话与授权),历史默认姓名标记 display_name_set=false;成员列表可按姓名搜索;应用登记必填名称并可改名,管理角色返回 application_name;登录客户端与资源类型新增可选名称及改名接口(资源类型使用独立 name_version);V33 迁移\n- 前端:两类邀请表单加姓名;个人中心确认/修改姓名,所有账号可更正姓名;应用登记填写名称、概况页改名,角色标签与切换器显示应用名称;客户端与资源规则可设置、修改、清除名称,企业侧数据范围显示资源类型名称\n\n验证:\n- 后端:Codex 在功能分支上执行定向 verify,237 项单元测试与 142 项集成测试通过,同步 main 0200f78 后复验 1 项单元测试与 19 项集成测试通过(见交接文档 docs/console/display-names-handoff.md)\n- 前端:npm run check 通过,测试 293 项\n- 合并前核对 main 新增的 P12 提交 f8a1e54、b892d79 与本次合并内容没有共同修改的文件,也没有新增迁移;合并后未重新运行后端测试\n- 未做浏览器检查,未与真实后端联调\n\nBREAKING CHANGE: 企业邀请、平台管理员邀请与应用登记必须提供 displayName,前后端需同时发布;部署前先执行 V33 迁移。\n","AuthorEmail":"gamebyteyu@gmail.com","AuthorName":"starry","CommitterEmail":"gamebyteyu@gmail.com","CommitterName":"starry","Timestamp":"2026-10-15T20:00:56-07:00"},"CompareURL":"pengzhiyu/IAM/compare/d2ff1f1d1423e14426de9db677c5239376cec6a8...36fd0536408149355981d06096633ca3249a035e","Len":9}... |