← all branches

feat/soft-launch

needs attention
3709e2e · incrementalPR #263reviewed 2026-07-07 02:18 UTC0H · 3M · 3L · 3I
The branch
Purpose
Gate the platform to bills+credentials-only soft launch: keep PR-207 surfaces (Sites, Assets, Tarifas, metrics) mounted but dark until each is ready, with a single SSOT that prevents nav/route drift.
Goal
Bills + Credentials are the only live modules. All other top-level modules are either greyed ('Pronto') or hidden, and their routes redirect to /bills/contratos. Platform admins bypass the gate.
Sub-goals
  • SG-1: SSOT lib/soft-launch.ts with isGated()/navState() + sidebar grey-out/hide + admin bypass
  • SG-2: Single <SoftLaunchGuard> in (dashboard)/layout.tsx covers all gated routes centrally
  • SG-3: Login default + bare /dashboard redirect to /bills/contratos
  • Tangential (BAT-254): Fix i18n locale config self-contradiction — defaultLocale es + localePrefix always to match Supabase proxy
The changes (whole branch)
What
This incremental commit (3709e2e) folds in the BAT-254 i18n fix: routing.ts defaultLocale en→es + localePrefix as-needed→always; config.ts aligned; openapi/source.ts baseUrlFor simplified; soft-launch.ts and DocsI18nProvider.tsx comments updated. No logic changes to the soft-launch gate itself.
Why
The proxy was force-prefixing every request to /es regardless of the next-intl config. The old as-needed+en config was dead — English was never served prefix-less in practice. The fix makes the config match reality and prevents a future redirect loop if es were set as default with as-needed.
Areas
apps/platform/src/i18n+156apps/platform/src/lib/openapi+23apps/platform/src/lib/soft-launch.ts+22apps/platform/src/app/[locale]/(docs)+22.branch/scope.md+140apps/platform/CLAUDE.md+11
Blast
Config-only. 7 files changed, +36/-14 in this incremental window. The soft-launch gate SG-1/2/3 files (SoftLaunchGuard.tsx, DashboardSidebar.tsx, credentials/layout.tsx, dashboard layout.tsx, soft-launch.ts logic) are not touched — those were done in prior commits. No backend, no migrations, no CDK.
i18n-config-change locale-routing-change adm-doc-gap
typecheck· pnpm typecheck passes (per PR description)lint· pnpm lint passes (per PR description)unit-tests· Full suite green — 406 tests (per scope.md)coderabbit· No .coderabbit.yaml foundci· No CI check data available from GitHub

Findings · 9

correctness3

medium

DashboardHeader/Sidebar fallback locale 'en' is stale — now wrong default

apps/platform/src/components/DashboardSidebar.tsx:73

DashboardHeader.tsx and DashboardSidebar.tsx extract the locale via `pathname.split('/')[1] || 'en'` using raw next/navigation usePathname(). Under localePrefix: 'always' the fallback fires only if the locale segment is absent — which the proxy prevents in practice — but if it does fire, navigation lands on /en/... instead of /es/.... Not introduced by this diff but exposed by making 'en' the wrong fallback.

low

ADR-006 'English-First' header in routing.ts now contradicts config

apps/platform/src/i18n/routing.ts:4

Same issue as in config.ts — the JSDoc block at the top of routing.ts still says 'Per ADR-006: Internationalization with English-First Approach'. No behavioral impact but misleading to future readers.

info

In-memory docs source cache won't invalidate if locale config changes

apps/platform/src/lib/openapi/source.ts:88

The module-level cache Map is never invalidated. Not a regression from this diff — the new baseUrlFor is simpler and correct. But the cache means a future locale config change would serve stale baseUrls until process restart.

conventions1

medium

File-level ADR-006 header contradicts new defaultLocale in config.ts and routing.ts

apps/platform/src/i18n/config.ts:4

The file header says 'Per ADR-006: Internationalization with English-First Approach' and '- English as source language' with no qualification, but the module now exports defaultLocale: 'es'. A reader skimming the file top-down sees 'English-First' then immediately hits a Spanish default. The ADR itself may specify defaultLocale: 'en' in examples, risking a future developer reverting this as an 'ADR violation'. Should note the distinction: English as translation source language; Spanish as routing default per proxy mechanics (BAT-254).

tests4

medium

No unit test for baseUrlFor — old conditional was silently broken, no guard for regressions

apps/platform/src/lib/openapi/source.ts:84

The old baseUrlFor had a branch: `locale === routing.defaultLocale ? '/developers' : '/${locale}/developers'`. Once defaultLocale changed to 'es', it would have returned the un-prefixed '/developers' for Spanish — silently wrong. No test caught it. The simplification to `/${locale}/developers` is correct, but a two-line unit test (baseUrlFor('es') === '/es/developers', baseUrlFor('en') === '/en/developers') would lock this in.

low

docs-route-gate tests only exercise /es/developers — /en/developers path untested

apps/platform/src/lib/supabase/__tests__/docs-route-gate.test.ts:35

Both test cases pass /es/developers. With localePrefix: 'always', /en/developers is equally valid. A third case with /en/developers (anonymous → redirect to /en/login) would confirm locale-stripping logic is locale-agnostic.

low

No proxy test for locale-less /developers — 'always' prefix invariant unverified at middleware

apps/platform/src/lib/supabase/__tests__/docs-route-gate.test.ts:31

Under localePrefix: 'always', a bare /developers should be redirected to /es/developers by the proxy before auth fires. No test exercises this. A test for req('/developers') verifying redirect to /es/developers would protect against proxy reordering.

info

Three-way defaultLocale invariant (config.ts / routing.ts / proxy.ts) has no machine check

apps/platform/src/i18n/config.ts:17

Three files independently declare the default locale as 'es' with no import relationship. BAT-254 was exactly this drift. A one-line unit test importing all three and asserting equality would make the invariant machine-checked.

improvement1

info

proxy.ts duplicates locale constants instead of importing from i18n/config.ts

apps/platform/src/lib/supabase/proxy.ts:17

proxy.ts defines its own DEFAULT_LOCALE = 'es' and type SupportedLocale = 'en' | 'es' independently. routing.ts comment now explicitly warns 'This must match that proxy' — that warning exists because there's no compile-time enforcement. Importing defaultLocale and Locale from @/i18n/config would make them consistent by construction.

History · 4 commits

  1. 3709e2eneeds attentionincremental0H · 3M · 3L2026-07-07 02:18current
  2. a4d7b63needs attentionfull1H · 4M · 4L2026-07-07 01:39
  3. 682c40cneeds attentionincremental5H · 4M · 6L2026-07-07 01:21
  4. 0385797needs attentionfull7H · 15M · 10L2026-07-06 19:45