Multi-language i18n, 10 locales pre-wired
VN, EN, ES, FR, JA, KO, ZH, AR (with RTL), ID and TH ship as working locales. Type-safe translation keys, browser-locale and timezone auto-detect, hreflang alternates, a multi-locale sitemap and a language switcher. `bun run i18n:check` validates parity in CI, and `bun run i18n:sync` writes `[EN]`-prefixed placeholders for missing keys.
46+ themed UI primitives and a live Theme Studio
Every shadcn and Base UI primitive a SaaS needs: DataTable on TanStack v8, recharts, a cmdk command palette, a vaul drawer, resizable panels, combobox, sortable, hover-card, context-menu, tabs, dialog, a TipTap editor. `/settings/theme` carries a live Theme Studio with 12 WCAG-AA presets, light, dark and system modes, three contrast levels, a font slider and RTL or LTR, all persisted through CSS variables with no rebuild.
Stripe billing with multi-currency and a freemium gate
Free, Pro and Family tiers with webhook-verified upgrades, a customer portal, dunning and grace-period handling, an idempotent `stripe_events` table, and a `profiles_update_self_safe_columns` RLS policy that blocks user-side billing tampering. Multi-currency across USD, EUR, GBP, VND, IDR and THB with a USD fallback. Server-side freemium middleware blocks Pro routes for Free users.
Claude insight engine with four prompt types
A weekly digest on sonnet, an anomaly alert on haiku at roughly a twentieth of the cost, a goal review and a forecast write-up on sonnet. Generation runs in an Edge Function (`supabase/functions/generate-insight/`) so the Anthropic key stays server-side and out of the Next.js bundle. Per-user 7-day cache, with token and model usage surfaced in admin. Six mandatory prompt rules: JSON only, specific amounts, no hallucination, 120 words or fewer, and the right model per task.
OCR receipts and 5-bank CSV import
Three ways to get a transaction in: manual entry through React Hook Form and Zod, a client-side OCR receipt scan through Tesseract.js with no server upload, and CSV import with five pre-wired bank parsers (Vietcombank, Techcombank, TPBank, VIB and a generic one) behind a diff-and-confirm screen so duplicates never land in the ledger.
Full finance suite with tax calculators
Dashboard, transactions, goals with SMART templates and AI nudges, budgets with caps, rollover and alerts, recurring subscription and income detection, a debt planner running snowball and avalanche, invoices and clients for freelancer mode, an accountant share-link at `/accountant/[token]` with scope and expiry, a 30, 60 and 90-day forecast, net worth and portfolio, a calendar, and family and team accounts across owner, co-pilot and view-only roles. Tax calculators cover Vietnamese TNCN across seven brackets, Indonesian PPh 21 with PTKP 54M, and Thai PIT across eight brackets.
Full admin panel, audit log and investor PDF
Nine admin routes. A dashboard with DAU, MRR, paying and churn KPIs, 30-day signups, plan mix and a 15-second cache. Users with list, detail and five lifecycle actions: reset password, magic link, ban, unban and cancel subscription. Messages as an inbox with replies through Resend. A paginated, filterable audit log. Feature flags as runtime kill-switches with a rollout percentage. Analytics with a cohort LTV heatmap, an onboarding funnel and an investor PDF export through jsPDF. Every admin write is recorded.
Public API v1 and v2, per-user keys and an SDK
`/api/v1/me`, `/api/v2/transactions/batch` at 100 per call, and `/api/v2/usage` are bearer-token endpoints. The `ApiKey` table stores a prefix and sha256 of the plaintext, shown once at creation. `/finance/settings#api-keys` handles create and revoke. A typed `FinanceAIClient` SDK lives in `public/sdk/` with automatic 429 retry, and webhook delivery auto-disables after ten consecutive failures.
Gamification: XP, levels, badges and streaks
Streaks with a streak freeze, XP across ten level thresholds, ten badge types, weekly challenges and an achievements wall, all driven by a fire-and-forget award pipeline. In our cohort it woke dormant users roughly 40% more often than the control with no gamification.
PWA, offline and Web Push
A service worker through `vite-plugin-pwa` gives an install prompt, an offline shell, transaction-queue replay on reconnect and an `/offline` fallback route. Web Push through the `web-push` library is wired for the daily nudge, the anomaly alert and the weekly recap.
Demo mode and a seeded admin user
`NEXT_PUBLIC_DEMO_MODE=true` flips the deployment to read-only, where every write API returns `403 DEMO_MODE_READONLY` behind a sticky banner. `bun run seed:demo` provisions an admin user with 90 days of sample transactions, goals and insights, so a reviewer can browse every screen without polluting the data set.
RLS-first Postgres with a verifier script
Over 60 SQL migrations under `supabase/migrations/` with a paired `CREATE POLICY` block for every table. An `on_auth_user_created` trigger materialises a Profile row on signup, and `enforce_role_immutability` blocks role escalation through the user-facing PATCH. `bun run verify:rls` asserts every table has RLS on with the expected policy block, and drift fails CI.