Skip to content

feat: i18n, PWA offline mode, high-contrast theme & coverage CI gate (#1329, #1330, #1332, #1333) - #1595

Open
Hollujay wants to merge 11 commits into
LabsCrypt:mainfrom
Hollujay:feature/i18n-pwa-theme-coverage-1329-1330-1332-1333
Open

Hollujay wants to merge 11 commits into
LabsCrypt:mainfrom
Hollujay:feature/i18n-pwa-theme-coverage-1329-1330-1332-1333

Conversation

@Hollujay

Copy link
Copy Markdown
Contributor

Summary

Implements four frontend / CI issues in one PR.

Closes #1329
Closes #1330
Closes #1332
Closes #1333

#1329 – Multi-language i18n

  • Lightweight dictionaries (no new dependency) in frontend/src/locales/ for en (default), es, fr, pt, zh, ja, covering Navbar, Dashboard, Stream Wizard, Settings, theme and offline strings.
  • I18nProvider / useI18n() (context/i18n-provider.tsx): stored preference (flowfi-locale) → navigator.languages detection → English. It sets <html lang> and exposes t() with {var} interpolation plus locale-aware formatNumber, formatCurrency and formatDate built on Intl.
  • LanguageSelector added to the Navbar (desktop and mobile menu) and Settings. The choice persists in localStorage.
  • Navbar and Settings are wired to t(). The Dashboard and Stream Wizard keys exist in every dictionary, but those screens' own copy is not migrated in this PR.

#1330 – PWA & offline read-only mode

  • public/manifest.webmanifest (standalone, theme colours, 192/512 and maskable icons), plus icons, and manifest, viewport and Apple metadata in layout.tsx.
  • public/sw.js: stale-while-revalidate for static assets, fonts and API GETs; navigation falls back to cached pages when offline. SSE and auth requests are never cached. It is registered in production builds only.
  • useNetworkStatus and OfflineBanner: a non-intrusive banner reading "Offline (Last synced X mins ago)". The sync time comes from successful service-worker API responses and reconnects.

#1332 – Theme architecture & high-contrast

  • globals.css now has semantic tokens (--color-bg-canvas, --color-bg-surface, --color-border-subtle, --color-text-{primary,secondary,muted}, --color-brand-{primary,accent}). The legacy variables now read from them.
  • New data-theme="high-contrast": black canvas, white text and borders, yellow (#ffff00) focus ring. Every text/background/border token pair is at least 15:1 on the black canvas (WCAG AAA needs 7:1). Hard-coded slate/zinc/white-alpha utility classes are remapped onto the tokens in this theme.
  • No flash on reload: next-themes' pre-paint script now sets both class and data-theme. ModeToggle is a System / Light / Dark / High-contrast radio group, and Settings offers the same four options.

#1333 – Coverage enforcement & CI gate

  • Frontend and backend Vitest configs emit lcov, json and json-summary. The frontend previously did not write lcov.info, which CI uploads.
  • CI posts a per-file coverage table on PRs (vitest-coverage-report-action, changed files only). It is non-blocking so fork PRs with read-only tokens don't fail.
  • codecov.yml: threshold: 1% on the backend, frontend and contracts project statuses, so a PR fails if coverage drops by more than 1%. It also adds flag carryforward and a per-file comment layout.
  • Threshold note: the issue asks for 80/75/80/80. Measured frontend coverage today is 51% statements, 80% branches, 67% functions and 51% lines, so an 80% floor would fail every PR. The gate is set to a ratchet at the current baseline (50/75/65/50) with the 80/75/80/80 target documented in the config. Raise it as coverage improves. Backend thresholds are unchanged at 60%; I couldn't run the DB-backed backend suite locally to re-measure them.

Testing

  • New tests: i18n.test.tsx (dictionary key and placeholder parity across locales, detection, persistence, formatting), theme.test.tsx, offline.test.tsx. All pass.
  • tsc and ESLint report nothing in the files added or changed here.
  • Full frontend suite: 27 failures, the same set as on unmodified main in my environment (stream-details-content, Navbar.test, TransactionTracker, and others). They are missing QueryClientProvider and jest globals, and were not caused by this change. next build also stops at type errors in files this PR doesn't touch (dashboard-view.tsx, StreamCreationWizard.tsx, soroban.ts).
  • Not verified: Lighthouse PWA audit and installability on real devices, and the CI workflow changes. Both need a real deployment or a CI run.

Hollujay and others added 11 commits September 30, 2026 04:54
…the test suite

- health.routes.ts: complete the failure-spike/lag degradation logic; add
  missing rpcPoolHealthy() import and fix the truncated checks object so
  the endpoint reports eventsProcessed/eventsFailed/lastErrorAt plus the
  granular database/indexer/redis/sorobanRpc breakdown
- rpc-pool.ts: add synchronous rpcPoolHealthy() derived from circuit
  state so liveness probes never spend an RPC round-trip
- indexerService.ts: absorb indexer.service.ts (admin control-plane
  helpers, previewReset/previewReplay, request-scoped replays via
  runExclusive) and replace inline dead-letter retries with the
  quarantineEvent flow; delete the now-duplicate indexer.service.ts
- sorobanService.ts/event-worker: finish the Stellar SDK 17 migration
  (ScVal discriminated unions, TransactionEnvelope property arms,
  InvokeContractArgs) and migrate affected tests
- rate limiter: wrap the req.ip fallback in ipKeyGenerator so IPv6
  clients are subnet-bucketed, clearing ERR_ERL_KEY_GEN_IPV6
- admin-dead-letter.test.ts: sign test JWTs with the iss/aud claims
  verifyJwt requires, matching admin-metrics.test.ts (fixes 16 x 401)
- schema.prisma formatting pass + idempotent dead-letter migration;
  lockfile reflects the intentional stellar-sdk 17 / vitest 3 upgrade

Full suite: 57 files, 556 passed, 0 failed; tsc --noEmit clean.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
…e-coverage-1329-1330-1332-1333

# Conflicts:
#	.github/workflows/ci.yml
#	backend/docs/SSE_ARCHITECTURE.md
#	backend/prisma/schema.prisma
#	backend/src/lib/prisma.ts
#	backend/src/middleware/admin-rate-limiter.middleware.ts
#	backend/src/routes/health.routes.ts
#	backend/src/services/indexerService.ts
#	backend/src/services/sorobanService.ts
#	backend/src/workers/soroban-event-worker.ts
#	backend/swagger/flowfi.openapi.json
#	backend/tests/indexer-service.test.ts
#	backend/tests/integration/admin-dead-letter.test.ts
#	backend/tests/stream-simulation.test.ts
#	contracts/stream_contract/src/errors.rs
#	contracts/stream_contract/src/lib.rs
#	contracts/stream_contract/src/storage.rs
#	contracts/stream_contract/src/test.rs
#	frontend/src/__tests__/create-stream-recipient-prefill.test.tsx
#	frontend/src/app/layout.tsx
#	frontend/src/app/settings/webhooks/page.tsx
#	frontend/src/app/streams/[id]/__tests__/stream-details-content.test.tsx
#	frontend/src/components/TransactionTracker.test.tsx
#	frontend/src/components/dashboard/dashboard-view.tsx
#	frontend/src/components/stream-creation/ScheduleStep.tsx
#	frontend/src/components/stream-creation/__tests__/CancelConfirmModal.test.tsx
#	frontend/src/components/stream-creation/__tests__/TopUpModal.test.tsx
#	frontend/src/components/ui/__tests__/StellarExplorerLink.test.tsx
#	frontend/src/context/NetworkContext.tsx
#	frontend/src/lib/api-types.generated.ts
#	frontend/src/lib/soroban.ts
#	frontend/src/lib/stream-validation.ts
#	package-lock.json
#	package.json
…eme-coverage-1329-1330-1332-1333

# Conflicts:
#	backend/prisma/schema.prisma

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant