Session 12: i18n (10 languages, cookie-based), Africa tier .99, locale switcher, RTL Arabic (1305 tests)

This commit is contained in:
Kev
2026-06-10 22:24:40 -04:00
parent e5c45ecc8e
commit d957dee17b
27 changed files with 1834 additions and 29 deletions
+35
View File
@@ -218,6 +218,41 @@ Container runtime (Session 9 finding):
in production and the container OOM-loops (44 restarts observed on
the live host before the fix was identified).
### Pricing tiers (Session 12 — Africa tier added)
| Var | Required | Default | Used By | Doc? |
| ---------------------------- | -------- | ------- | ---------------------------------- | ---- |
| `STRIPE_PRICE_AFRICA` | no | (none) | `web/components/Pricing`, `stripeService` (post-DB-CHECK migration) | ✓ S12 |
**Blocker**: the existing migrations (001 + 011) declare `tier IN
('free','analyst','desk')` as a CHECK constraint on `users.tier` and
`user_profiles.tier`. The `africa` tier value will VIOLATE that
constraint until the constraint is updated. The frontend Pricing page
shows the tier now (UX), but the click handler short-circuits to an
honest "coming soon" message rather than triggering checkout. Required
follow-up: manual SQL to drop + re-add the CHECK across both tables
including 'africa' (cannot be done in this session per the no-migration
rule).
### Internationalization (Session 12)
| Var / file | Required | Default | Used By | Doc? |
| ---------------------------- | -------- | ------- | ---------------------------------- | ---- |
| `NEXT_LOCALE` cookie | no | en | `web/middleware.ts`, switcher | ✓ S12 |
| `web/src/lib/locales.ts` | n/a | n/a | locale registry (10 languages) | ✓ S12 |
| `web/src/locales/{code}.json`| n/a | n/a | per-locale translation dictionaries | ✓ S12 |
Locale-detection priority (left wins): URL prefix (reserved for future
`[locale]/` segment) → `NEXT_LOCALE` cookie → `Accept-Language`
header → `'en'`. Resolved locale rides on the request via the
`x-vyndr-locale` header; server components read it through
`next/headers`, client components consume it via `LocaleContext`.
**Side effect**: every Next.js page is now `ƒ (Dynamic)` instead of
`○ (Static)` because the root layout reads request headers. If FCP
regresses meaningfully, the fix is to move locale resolution
client-side (cookie-only, no `headers()` in layout) — that re-enables
static prerendering at the cost of a brief English flash on first
paint for non-English users.
### Engine 2
| Var | Doc? |
| ---------------------------- | ---- |