Repository navigation
fix(app-shell): the exported register page says why a sign-up is refused, in the reader's language (objectui#11030) - #11052
Conversation
…sed, in the reader's language (objectui#11030) DefaultRegisterPage passed no errorMessages to RegisterForm, so every refused sign-up showed the server's raw English message. The refusal-code map now lives once in @object-ui/app-shell (signUpRefusalMessages), keyed on the pack keys auth.register.errors.userExists / .selfRegistrationClosed / .emailDomainNotAllowed; both the exported page and the console app's page pass it. AUTH_CONFIG_ERROR stays unmapped; the unknown-code fallback is unchanged. Claude-Session: https://claude.ai/code/session_011p7ikEivgXefNDaE5S5Uec Co-authored-by: Claude <noreply@anthropic.com>
|
changeset-claim-re-read
|
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
Contract reviewServed-tier: Inputs: card #11030 (body, triage ruling ① Derived judgments
② Semver level
③ Boundary flags
Findings for the FAIL: one — ② the Implemented-by: VERDICT: FAIL Generated by Claude Code |
Claude-Session: https://claude.ai/code/session_011p7ikEivgXefNDaE5S5Uec Co-authored-by: Claude <noreply@anthropic.com>
…1030) The diff adds a public export to @object-ui/app-shell (signUpRefusalMessages) and the claim declares Clause-② yes, which takes at least minor. Claude-Session: https://claude.ai/code/session_011p7ikEivgXefNDaE5S5Uec Co-authored-by: Claude <noreply@anthropic.com>
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
Contract reviewServed-tier: Second record on this PR, after the FAIL record What moved since ① Derived judgments
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS Generated by Claude Code |
Fixes #11030
Clause-②: yes
Why yes (copied from the claim): the shared map is a new export of the published
@object-ui/app-shell, which widens its public surface.What changed
DefaultRegisterPage, the register page@object-ui/app-shellpublishes (mounted at/registerbyexamples/console-starter), renderedRegisterFormwith noerrorMessages. SoRegisterForm's catch ((code && errorMessages?.[code]) || authError.message) showed the server's own English message for every refused sign-up, in every language. ForSELF_REGISTRATION_CLOSEDthat message also names the internal setting "audience posture invite_only".Triage (comment
5882764311) ruled one map, used by both pages, and no second hand-written copy. This PR does that:signUpRefusalMessages(t)inpackages/app-shell/src/console/auth/signUpRefusalMessages.ts, re-exported from the package entry besideDefaultRegisterPage. It returns the refusal code to pack text map, keyed on the pack keys PR objectui#11029 added:auth.register.errors.userExists,.selfRegistrationClosedand.emailDomainNotAllowed. The parameter is typed with the oneTranslateFnauthority from@object-ui/i18n, as that type's header asks of a message builder.useObjectTranslation()'stpasses without a cast (both type-checks below are green).DefaultRegisterPagepasseserrorMessages={signUpRefusalMessages(t)}.RegisterPagepasses the same call instead of its own inline object. It is the same code set, byte for byte:USER_ALREADY_EXISTS_USE_ANOTHER_EMAIL,USER_ALREADY_EXISTS,SELF_REGISTRATION_CLOSED,EMAIL_DOMAIN_NOT_ALLOWED, with the same keys and the same inlinedefaultValuestrings.apps/consolealready depended on@object-ui/app-shell(workspace:*), andApp.tsx/main.tsxalready import the barrel eagerly, so no dependency was added.AUTH_CONFIG_ERRORstays unmapped on purpose (operator-facing), as the docblock says..changeset/11030-register-refusal-map.md:'@object-ui/app-shell': patch,'@object-ui/console': patch(both are in the release group, and the console source changed even though what it shows did not).Why the name is
signUpRefusalMessagesand not aregister...name: in this codebase aregisterprefix names a registration function (registerAppComponent,registerBuiltInLocales).registerRefusalMessageswould read as "register some messages". The name follows the endpoint (/sign-up/email) instead. The seat can rename it before landing if it prefers.Premises checked on
origin/main(63ab76112) before any editDefaultRegisterPagerendersRegisterFormwith noerrorMessages: confirmed.apps/console/package.jsonlists"@object-ui/app-shell": "workspace:*": confirmed.Tests, all at
c209a6fc5(the only commit on this branch)packages/app-shell/src/console/auth/__tests__/registerRefusalCodes-11030.test.tsx. It renders the exported page underzhwith the real form, a realAuthProviderover a realcreateAuthClient, and a realI18nProvider; onlyfetchis stubbed. Cases: one per mapped code (the three pack keys, with both user-exists codes), plus the unknown-code fallback, plus a check that the zh pack differs from en for all three keys. Expected text is read from the packs, not copied.pnpm exec vitest run packages/app-shell/src/console/auth/ apps/console/src/pages/auth/__tests__/registerRefusalCodes-10998.test.tsxgaveTest Files 3 passed (3)/Tests 15 passed (15). The console page's objectui#10998 pin is unchanged and green. It is the control showing that the shared map keeps the console behaviour.scripts/ablation-replace.mjs, which checks the change on disk and restores to HEAD). DeletingerrorMessages={signUpRefusalMessages(t)}fromDefaultRegisterPagegaveanchor 1 -> 0, bloba03ba581ab2f -> 1cd1ced129f3, thenTests 4 failed | 2 passed (6). The four code cases went red, for exampleExpected: "本环境未开放自助注册,请联系管理员获取邀请。"/Received: "Self-registration is closed on this environment (audience posture invite_only). ...". The pack check and the fallback stayed green, which is the expected direction. After restore, the blob equals HEAD andgit diff HEADis empty.signUpRefusalMessages()made consoletsc --noEmitfail witherror TS2554: Expected 1 arguments, but got 0.After restore, the blob equals HEAD. So the console type-check reads the rebuiltpackages/app-shell/dist/index.d.ts, which carries the export (built this run; there was nodistbefore it).pnpm --filter @object-ui/app-shell type-check(tsc --noEmit && tsc -p tsconfig.test.json) exits 0.tsc -p tsconfig.test.json --listFileslists the new test file once andsignUpRefusalMessages.tsonce, so the test is inside what that project compiles.pnpm --filter @object-ui/console type-checkexits 0. The dependency closure was built first (turbo run build --filter="@object-ui/console^..." --concurrency=2: 34/34).scripts/__tests__/one-authority-per-exported-name-6273.test.ts,scripts/__tests__/vite-declared-lazy-views.test.ts,rootLandingHasOneResolver-10042,appSidebarRemoved-5817andexpressionUser.mountSites.ratchetgaveTest Files 5 passed (5)/Tests 54 passed (54).node scripts/check-changeset-presence.mjs(exit 0: "5 source file(s) of 2 released package(s) changed, and this change declares 1 changeset(s)"),node scripts/check-control-bytes.mjs(exit 0),node scripts/check-changeset-no-major.mjs(exit 0),pnpm check:i18n-keys(exit 0: "every literal inline defaultValue matches the value the pack serves"), andpnpm check:new-line-citations(exit 0:0 new citation(s))..ts/.tsxfiles. Each is in the lint population; none came back ignored. (2)--format jsongave 5 results, 0 errors and 2 warnings. Both warnings arereact-hooks/set-state-in-effecton lines of the console page this diff does not touch (thehasBootstrappedlatch and the org auto-select). (3) Invariance:eslint --print-configon the changed files shows noparserOptions.projectorprojectService, so type-aware linting is off and this diff cannot change any verdict on an untouched file.Declared narrowings (CI owns these)
pnpm testfarm and repo-widepnpm lint.check:eager-closure/ the performance budget needs a full console build. The console now imports one small module from the barrel it already loads eagerly, and drops the same amount of inline code. NOT MEASURED locally, reason: it needs a full consolevite build, which CI runs.Acceptance notes
DefaultLoginPageinpackages/app-shell/src/console/auth/LoginPage.tsxalso passes noerrorMessages. The console app'sLoginPagemapsINVALID_EMAIL_OR_PASSWORDandEMAIL_NOT_VERIFIEDtoauth.login.errors.invalidCredentials/.emailNotVerified, which exist in the packs. So on the exported login page, a refused sign-in shows the server's own message. This is read from source only and has not been reproduced at a running door, so no card is filed. It goes to the seat through the report.Default*auth pages, so there are no docs to update.Generated by Claude Code