| content |
{"Commits":[{"Sha1":"d2ff1f1d1 {"Commits":[{"Sha1":"d2ff1f1d1423e14426de9db677c5239376cec6a8","Message":"feat: 合并企业名称、邀请弹窗修复与平台管理员邀请\n\n用户测试时发现三个问题:开通企业没有名称输入项;未配置邮件服务时邀请弹窗关不掉;平台侧无法增加第二位平台管理员。本次把后端实现与前端接入一起合入 main。\n\n实现内容:\n- 后端(feat/tenant-name-platform-invite):开通企业时必填 displayName,平台管理员与企业所有者可以改名,企业搜索同时匹配名称;/api/v1/me 返回 mail_delivery_available,并明确 MAIL_UNAVAILABLE 一定回滚;新增平台级邮箱邀请、待接受列表与撤销(V31、V32)\n- 前端:开通弹窗加名称,平台详情页与企业概览可以改名;确定失败的邮件错误码不再锁定弹窗,结果不确定时提供「关闭,稍后核对」,邮件不可用时提前置灰邀请;平台管理员页新增邮箱邀请与待接受邀请列表,激活页文案改为「接受邀请」\n\n验证:\n- 后端:Codex 在功能分支上执行定向 verify,10 个集成测试类共 93 项及服务器单元测试 157 项通过(见交接文档 docs/console/tenant-name-platform-invite-handoff.md)\n- 前端:npm run check 通过,测试 279 项\n- 浏览器只用页面内模拟接口验证,未与真实后端联调,未验证真实邮件投递;合并后未重新运行后端测试\n\nBREAKING CHANGE: POST /api/v1/platform/tenants 必须提供 displayName,前后端需同时发布;部署前先执行 V31、V32 迁移。\n","AuthorEmail":"gamebyteyu@gmail.com","AuthorName":"starry","CommitterEmail":"gamebyteyu@gmail.com","CommitterName":"starry","Timestamp":"2026-10-15T18:54:10-07:00"},{"Sha1":"1079b27dfca2ad1535dbab213431ca3895478780","Message":"feat(console): 支持按邮箱邀请平台管理员\n\n平台管理员原先只能从已有账号中添加,而新账号只能通过企业邀请产生,导致想增加平台管理员必须先把对方拉进某家企业,没有邮件服务时则根本加不了。后端已提供平台级邀请,前端随之接入。\n\n实现内容:\n- 平台管理员页新增「邀请管理员」(主要入口),原「添加管理员」在平台侧改名为「添加已有账号」并说明适用场景\n- 邀请表单:邮箱、管理职责(不预选,平台管理员或应用管理员)、应用管理员的负责应用、生效与截止时间、确认勾选;邮件不可用时说明原因并禁用表单\n- 后端错误码分别说明:SELF_INVITATION、INVALID_INPUT、INVITATION_PENDING、INVITATION_NOT_APPLICABLE、LIMIT_EXCEEDED;冲突后「重新填写」并刷新待接受列表\n- 新增「待接受的邀请」列表:邮箱、管理职责与应用名称、邀请有效期,管理职责已过截止时间的标注提示;可按读到的版本撤销,409 时关闭并刷新列表\n- WriteError 新增 conflictAction,允许新建类表单改写冲突按钮文字\n- 激活页与登录页文案改为通用的「接受邀请」,成功提示说明含管理职责时需要按提示开通两步验证\n\n验证:\n- npm run check(格式、lint、类型检查、测试、构建):通过,测试 279 项,含新增 platform-invitations.test.tsx 5 项\n- 浏览器(Vite + 页面内模拟接口):发送邀请后列表新增记录;邮件不可用时表单禁用并显示说明\n- 未与真实后端联调,未验证真实邮件投递与收件人接受邀请流程\n","AuthorEmail":"gamebyteyu@gmail.com","AuthorName":"starry","CommitterEmail":"gamebyteyu@gmail.com","CommitterName":"starry","Timestamp":"2026-10-15T17:43:58-07:00"},{"Sha1":"18ddef4d5ee7662de116717dc7970482b123e033","Message":"feat(console): 开通企业时填写名称并支持修改企业名称\n\n开通企业原先只能填企业代码,之后各处只能靠代码辨认企业。后端已支持开通时必填 displayName、平台管理员与企业所有者改名,前端随之接入。\n\n实现内容:\n- 开通企业弹窗新增必填「企业名称」,按后端同样的规则预检(去首尾空白后 1—160 个 Unicode 字符,拒绝控制字符与行、段落分隔符),提交时去掉首尾空白;成功卡片显示企业名称\n- 平台企业详情「基本信息」提供「设置名称 / 修改名称」,已归档企业不提供入口\n- 企业概览页头仅对本企业所有者显示改名入口;企业版本取自 GET /api/v1/me/tenants/{tenant} 的 tenant_version,缺失时不提交\n- 两处共用 TenantNameEditor:每次打开重新读取企业版本;409 冲突后重新读取但保留已输入的名称;未命名企业不把代码预填为名称\n- 企业侧改名成功后,就地更新上下文里的企业名称,页头与切换器立即显示新名称,不重新校验整个上下文\n- 企业列表搜索文案改为「搜索企业名称或代码」,操作记录新增 tenant.renamed 的「修改企业名称」标签\n\n验证:\n- 本提交暂存快照 npx tsc -b --noEmit、npx eslint .、npx prettier --check src:通过\n- 本提交暂存快照 npx vitest run:274 项通过,含新增 tenant-name.test.tsx 4 项;tenant-overview.test.tsx 改为包裹 ToastProvider\n- 浏览器(Vite + 页面内模拟接口):开通企业提交 code 与 displayName;未命名企业设置名称后标题更新;所有者改名遇到 409 时保留输入,带新版本重提成功\n- 未与真实后端联调\n","AuthorEmail":"gamebyteyu@gmail.com","AuthorName":"starry","CommitterEmail":"gamebyteyu@gmail.com","CommitterName":"starry","Timestamp":"2026-10-15T17:43:27-07:00"},{"Sha1":"327cad554ad55a68f628c06f3b486bf54a76184b","Message":"fix(console): 邀请邮件未配置时不再锁死弹窗\n\n未配置邮件服务时,邀请接口返回 503 MAIL_UNAVAILABLE,此时邀请已经整体回滚;但前端把所有 503 都当作结果不确定,锁定表单并禁止关闭,只剩原样重试,邀请弹窗因此关不掉。\n\n实现内容:\n- useMutation 对后端合同保证已回滚的错误码(MAIL_UNAVAILABLE、MAIL_TEST_RECIPIENT_REQUIRED)按确定失败处理:不锁定输入,可以取消和关闭;其余 503、5xx 和网络错误仍按结果不确定处理\n- 业务弹层通过 ForceDismiss 向错误提示提供「关闭,稍后核对」,结果不确定时用户可以显式离开,原样重试仍然保留\n- 两个邮件错误码给出具体说明:邀请没有发出也没有保存,或只能邀请 .test 邮箱\n- /api/v1/me 的 mail_delivery_available 为 false 时,成员页置灰「邀请成员」并在列表上方说明原因;字段缺失时按可用处理\n\n验证:\n- 本提交暂存快照 npx tsc -b --noEmit、npx eslint .、npx prettier --check src:通过\n- 本提交暂存快照 npx vitest run:270 项通过,含新增 write-dismiss.test.tsx 4 项\n- 浏览器(Vite + 页面内模拟接口):成员邀请遇到通用 503 时可用「关闭,稍后核对」关闭;MAIL_UNAVAILABLE 时输入不锁定、可以取消;邮件不可用时邀请按钮置灰并显示说明\n- 未与真实后端联调\n","AuthorEmail":"gamebyteyu@gmail.com","AuthorName":"starry","CommitterEmail":"gamebyteyu@gmail.com","CommitterName":"starry","Timestamp":"2026-10-15T17:42:56-07:00"},{"Sha1":"e2c4a59663c315cfdfc12159c26306a8f32859ae","Message":"merge: 合入企业名称、邀请邮件能力与平台管理员邀请后端\n","AuthorEmail":"gamebyteyu@gmail.com","AuthorName":"starry","CommitterEmail":"gamebyteyu@gmail.com","CommitterName":"starry","Timestamp":"2026-10-15T17:24:35-07:00"}],"HeadCommit":{"Sha1":"d2ff1f1d1423e14426de9db677c5239376cec6a8","Message":"feat: 合并企业名称、邀请弹窗修复与平台管理员邀请\n\n用户测试时发现三个问题:开通企业没有名称输入项;未配置邮件服务时邀请弹窗关不掉;平台侧无法增加第二位平台管理员。本次把后端实现与前端接入一起合入 main。\n\n实现内容:\n- 后端(feat/tenant-name-platform-invite):开通企业时必填 displayName,平台管理员与企业所有者可以改名,企业搜索同时匹配名称;/api/v1/me 返回 mail_delivery_available,并明确 MAIL_UNAVAILABLE 一定回滚;新增平台级邮箱邀请、待接受列表与撤销(V31、V32)\n- 前端:开通弹窗加名称,平台详情页与企业概览可以改名;确定失败的邮件错误码不再锁定弹窗,结果不确定时提供「关闭,稍后核对」,邮件不可用时提前置灰邀请;平台管理员页新增邮箱邀请与待接受邀请列表,激活页文案改为「接受邀请」\n\n验证:\n- 后端:Codex 在功能分支上执行定向 verify,10 个集成测试类共 93 项及服务器单元测试 157 项通过(见交接文档 docs/console/tenant-name-platform-invite-handoff.md)\n- 前端:npm run check 通过,测试 279 项\n- 浏览器只用页面内模拟接口验证,未与真实后端联调,未验证真实邮件投递;合并后未重新运行后端测试\n\nBREAKING CHANGE: POST /api/v1/platform/tenants 必须提供 displayName,前后端需同时发布;部署前先执行 V31、V32 迁移。\n","AuthorEmail":"gamebyteyu@gmail.com","AuthorName":"starry","CommitterEmail":"gamebyteyu@gmail.com","CommitterName":"starry","Timestamp":"2026-10-15T18:54:10-07:00"},"CompareURL":"pengzhiyu/IAM/compare/972164fbd3e90b74e1c6f61434ddc8b0db52fc65...d2ff1f1d1423e14426de9db677c5239376cec6a8","Len":10}... |