feat(i18n): consume published Customer Master screen copy - #932
feat(i18n): consume published Customer Master screen copy#932seonghobae wants to merge 32 commits into
Conversation
Load the complete authenticated Customer Master translation resource before customer data and expose an explicit retry state when copy is unavailable. Signed-off-by: Codex <codex@localhost>
Signed-off-by: Codex <codex@localhost>
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: trueThanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
seonghobae
left a comment
There was a problem hiding this comment.
Valid finding on the Customer Master translation cutover: copy readiness is bound to locale, but not to the access-token identity that authorized the screen resource. On an accessToken A→B rerender, the translation effect schedules copyState="loading", but the following data-load effect still observes the previous render's copyState === "ready"; loadMaster has already been recreated around token B, so /api/v1/customer-master can start before token B's published screen projection is admitted. The render guard has the same stale-ready window because copyLocale may still match. Please make the ready state auth-bound (or equivalently make the sequencing contract explicit and fail-closed) and add a regression that changes the access token while copy is ready and proves Customer Master data is not requested until the replacement translation resource succeeds. Keep this PR Draft until the repaired exact head has fresh UI/runtime evidence.
seonghobae
left a comment
There was a problem hiding this comment.
Current-head finding: the translation-gate retry copy currently diagnoses every projection failure as “not published in the selected language yet”. fetchTranslationScreen() throws BackendError for transport failure, 401/403, 404, and 5xx, while the Customer Master effect collapses all of them into copyState="retry". The rendered message therefore turns permission/service failures into a publication claim and tells the operator to ask an administrator to publish copy even when publication may be healthy. That violates the explicit unavailable/failed/permission evidence boundary. Keep the retry state fail-closed, but make its copy cause-neutral until the caller carries a typed failure reason; do not imply unpublished copy from an unclassified exception. Add a focused regression before the product change.
seonghobae
left a comment
There was a problem hiding this comment.
Current-head i18n review found a buyer-visible bootstrap gap outside the published screen resource: the Customer Master gate rendered raw English loading/retry copy while the selected product locale could be ko/ja/zh/vi/es/de/fr. Because this gate is shown before the versioned screen resource can be admitted, the database-backed resource cannot safely translate its own loading/failure shell. RED 51c766614d8303da96918e6d405481cd6b8a5569 requires the bootstrap shell and retry action to stay in all eight governed locales. 422064e7da5804c0d985c197c9cd52687acc57fe adds an optional already-localized label/description boundary to shared StatusNotice without changing ordinary callers; 078f47d51aa120c1f901b15cd3d8e63567581a47 supplies the bounded eight-locale bootstrap copy and keeps failure wording cause-neutral. Do not treat the static bootstrap strings as reviewed material Customer Master copy or as replacement for the PostgreSQL translation ledger. Exact-head hosted Tests are Draft-skipped, so product GREEN is not claimed.
seonghobae
left a comment
There was a problem hiding this comment.
Valid auth-transition finding on this exact head: translation readiness is bound to (locale, accessToken), but the Customer Master data projection itself is not invalidated until the post-render data effect runs. When accessToken changes from A→B, the render gate correctly stays closed while B copy loads; once B copy becomes ready, React can render one frame with copyAccessToken === B while master still contains A-authorized data, because setMaster(null) is only executed later inside the second effect immediately before B's fetch. An A request that resolves late can also repopulate master because loadMaster() has no stale-token completion guard. This is a purpose-bound data/auth boundary defect, not a translation-copy issue. Add RED coverage that a token transition invalidates the customer data projection before B copy can unlock rendering and that stale A completions cannot publish into B state; then minimally bind master response admission to the current token/generation. Keep this Draft behind #929 and do not weaken the existing translation gate.
seonghobae
left a comment
There was a problem hiding this comment.
Fresh parent check: #929 advanced non-force from f07a755… to 2a8ed5d… with a test-only review-quality delta in three translation foundation test files. Those files are disjoint from #932’s Customer Master consumer delta. I adopted the parent changes non-force by rebuilding the child tree with the exact parent blobs and joining the new parent at a0ebd1fb60890f31e5408fc196e2af633d03fd41; compare now reports #929 as the exact merge base with behind_by=0. The existing stale-auth Customer Master RED remains intentionally unresolved, so this is ancestry convergence only, not GREEN or Ready evidence.
Signed-off-by: Codex <codex@localhost>
Signed-off-by: Codex <codex@localhost>
seonghobae
left a comment
There was a problem hiding this comment.
Current-head review found a second purpose-bound authorization leak beyond the repaired master response. relatedByEntity survives an access-token change and toggleEntity() can publish a late response from the old token after the transition; selectedPostGraph and canResolveHints also retain the old authorization projection until their replacement effects complete. Once the new translation gate becomes ready, those secondary projections can reappear under the new token (especially when entity/post identities overlap). The fix must invalidate all Customer Master-owned secondary projections on auth transition and reject late async completions by the current auth identity; do not rely only on the translation gate or the masterRequestGeneration counter.
|
@codex address that feedback Work only on current exact head |
|
To use Codex here, create an environment for this repo. |
|
@codex address that feedback Repair only the verified current-head Customer Master auth/data RED from review 5120072275 on exact head fe01453. Keep this presentation/read-model local. On access-token identity transition, invalidate Customer Master secondary authorization-derived state ( |
|
You have reached your Codex usage limits. You can see your limits in the Codex usage dashboard. |
seonghobae
left a comment
There was a problem hiding this comment.
Parent movement finding is current: #932 includes #929 only through 0f4fd26a5f0fcf26932d0945188aefb2143d6605, while canonical parent #929 is now 603a7e1498a21f61bf4482746834bcca0bcfe1f2. The parent suffix is docs-only but modifies the same docs/product-technical-gap-baseline.md that #932 previously resolved while preserving child authorization/browser/full-suite evidence. Therefore a blind tree adoption would drop parent queue/coverage evidence, and a blind parent tree adoption would drop child evidence. Keep Draft/conflicting and reconstruct the baseline losslessly with ordinary ancestry; preserve all child runtime/test trees and both evidence sets. This is not a Close or force/rebase case.
seonghobae
left a comment
There was a problem hiding this comment.
Lossless descendant reconstruction completed after #929 moved to fabdacd4c487be7feb8db02c32b79d4e7d89f581. Fresh parent history proves 0f4fd26a...→fabdacd4... changes only the active docs/product-technical-gap-baseline.md, so the prior child tree can retain every non-baseline Customer Master delta without regressing parent runtime/API/DB source. New exact #932 f5392955e80c4c94492a07d3d2e893451c98ba81 is an ordinary two-parent commit: prior child 8c662a055... first, exact current #929 second; branch update was force=false. The active baseline blob is inherited exactly from current #929 (16b689e6...), while the prior child baseline blob (816fe8fc...) is preserved losslessly as dated historical evidence at docs/product-technical-gap-baseline-history-2026-09-07-pr932.md instead of being allowed to overwrite current authority. Fresh parent→child compare is ahead-only / behind 0 with merge base exactly fabdacd4...; the active baseline is no longer a child delta. Net child paths are the prior Customer Master/translation consumer source, tests, ADR, Storybook/screenshots plus the historical evidence archive. Keep Draft and require fresh exact-head validation; historical focused passes do not transfer.
…ledger' into feat/i18n-ledger-frontend-consumer
Ordinary non-force descendant convergence: inherit current translation-ledger owner repairs while preserving the Customer Master consumer/evidence delta.
Product delta
Customer Master waits for a complete authenticated screen translation before requesting customer records. Locale or authorization changes retire previous screen/customer projections. The eight-locale loading/retry shell remains available, and the authorization fence prevents deferred A → B → A related-record or hint completions from restoring stale data or errors.
Current exact authority
feat/i18n-versioned-translation-ledger@d997a282f3393b9c2ecbef6998cdc080b7576beddba4224a0953a3eff251cc500677a4cb9286bbb5d997a282...Parent movement and convergence
The parent advanced non-force through exact HTTP/wire evidence, canonical identity/replay-safe rollback, bounded authoritative cache decoding, and octet-miss convergence. These are parent-owned translation-ledger repairs and must not be copied into the consumer as a competing implementation.
This run converged #932 by normal merge PR #987 into the feature branch. Fresh compare from exact parent
d997a282...is ahead-only / behind 0 and preserves the same 21 child-owned paths: Customer Master translation gate, frontend/i18n/API tests and components, ADR evidence, browser screenshots, and dated history. No force push, destructive rebase, or Customer Master delta loss occurred.Validation boundary
Parent #929 exact
d997a282...has terminal GREEN Tests (frontend lint/test/build/Storybook and PostgreSQL full suite), PROV-O, Ontology Pages, and SAST. Security and CodeQL remain fail-closed at canonical owner boundaries, and predecessor Noema approval is not transferred to this parent head.Because #932 remains Draft, repository-local lifecycle skips on the newly converged child are expected and are not acceptance. Parent #929 must reach protected truth first; then this exact child must be revalidated against the released parent rather than inheriting stacked receipts.
Product behavior retained
The child consumes authenticated versioned screen copy before requesting Customer Master records, retires prior copy/customer projections on locale or authorization changes, and maintains loading/retry behavior across
ko/en/ja/zh/vi/es/de/fr. The A → B → A generation fence prevents an earlier authorization generation's deferred related-record/hint completions from mutating the current projection.The child does not become a translation-ledger owner: PostgreSQL publication/cache/version invariants remain in #929, identity/auth remain canonical owner concerns, and ontology/concept labels remain outside the presentation translation ledger.
Remaining buyer acceptance
After parent delivery, this child still needs its own complete Tests/Security/SAST/CodeQL/current review evidence plus one reviewed complete eight-locale published resource, authenticated PostgreSQL/API/browser evidence, normal/loading/empty/error/permission/responsive states, keyboard/focus/screen-reader behavior, CJK/text expansion/font fallback, representative all-page performance evidence where applicable, and code-current PRD/TRD/ARCHITECTURE/UX/OPERABILITY/TEST_STRATEGY/CHANGELOG/baseline documentation.
No self-approval, bypass, force-push, destructive rebase, stale-head evidence transfer, or release claim.