3 Commits

Author SHA1 Message Date
isra el
3e4597294c refactor: turn on strict TypeScript and fix the 63 errors it found
My earlier estimate of 34 errors was wrong, and the reason is worth
recording: tsconfig carried "strictNullChecks": false as a duplicate key
AFTER the strict flag, and an explicit option beats the strict umbrella
even when --strict is passed on the CLI. So the measurement that produced
34 had silently excluded every null-safety error. The real number was 63.
Both duplicate keys are gone; strict: true now stands alone.

Most were implicit-any, but strict caught several genuine type lies:

- SendSmsPayload.deviceId and WebhookData._id were optional while both
  are interpolated into request paths, so an absent value would have hit
  /gateway/devices/undefined/send-sms or PATCH /webhooks/undefined.
- webhook-table's deviceName was typed string while buildDeviceLabel
  returns string | string[] and the Device cell already renders the
  array case. The type never described what the code produced.
- webhooks-section read `webhooks?.data?.length > 0`, comparing
  undefined against 0 while the query was still in flight.
- app-header declared a non-null Session while its own body guarded with
  session?.user throughout. Making the type honest surfaced four
  genuinely unguarded accesses.
- api-keys kept a local ApiKeyRow duplicating the shared ApiKey type, so
  the list callback annotated rows as one type while the hook returned
  the other. ApiKeyRow is now an alias and the two extra fields moved
  onto ApiKey.
- The notifications envelope typed its rows as unknown[], so the
  deliveries table's row type went entirely unchecked. Now a real
  WebhookNotification type.

The react-hook-form cluster (20 of the 63) was one root cause: zod's
.default() makes the input and output types differ, so z.infer (the
output) is not what the resolver takes. Fixed by typing the forms with
z.input and z.output separately, which changes nothing at runtime.

Also bumped target es5 to ES2017, which fixes the Set-iteration error
that made tsc --noEmit fail before any of this. Next compiles browser
output via SWC and its own browserslist, so bundle targeting is
unaffected. Added @types/papaparse and @types/react-syntax-highlighter,
and a typecheck script, since next build does not check test files.

No @ts-expect-error and no new any were used.

Verified: typecheck clean, build clean, 0 lint errors (21 warnings,
unchanged), 155 unit tests, 78 e2e.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-19 04:19:35 +03:00
isra el
8a5f12a6eb feat: redesign onboarding into a conversion-focused guided setup
The Get Started card is the activation funnel; this makes it exceptional:

- animated progress bar + "x of 6" + momentum copy that changes with
  progress; per-step time-estimate chips; benefit-led step copy
- focus model: completed steps collapse to compact checked rows (check-pop
  animation), only the active step expands with one primary CTA; staggered
  entrance; auto-advance when the poll detects a step completed
- register_device is now self-serve inline: numbered instructions beside an
  in-place generate-key + QR panel (reuses the existing key mutation and
  react-qr-code); help dialog demoted to a "Need help?" fallback
- verify_email shows the actual email and an inline resend with a 60s
  cooldown via the existing sendEmailVerificationEmail endpoint
- completion is celebrated (one-time success state with "Send a message"
  CTA) instead of the card vanishing mid-glance
- minimize control collapses the card to a slim resumable progress pill
  (localStorage), so setup never nags

Fail-closed states (bug fixes):
- previously a backend failure rendered the checklist from missing data,
  showing verified users stuck on "Verify your email"; now a status machine
  (loading/error/ready/hidden/celebrate) only renders the checklist when all
  three queries succeeded; error shows a quiet retry row
- the full-height 6-row loading skeleton is replaced by a compact ~90px
  placeholder; background poll failures keep last-good data

Tests: MSW handlers for onboarding PATCH + resend; RTL tests for the error
policy, mid-funnel progress, and all-done progress; e2e asserts the progress
bar on Home. Build, 28 unit tests, and 13 e2e green; verified at 375px.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 07:49:28 +03:00
isra el
c92740c401 test: add vitest + rtl + msw + playwright harness with mocked api
Establish the testing safety net for the web dashboard before refactoring.

- Vitest + React Testing Library + jsdom for unit/component tests
- MSW node server mocks the API; unhandled requests throw so tests can
  never reach a real backend
- Playwright e2e boots the real Next app but intercepts every /api/v1 call
  with shared fixtures, and mints a NextAuth session cookie to run authed
- Shared fixtures in test/fixtures.ts back both layers
- Seed tests: Button unit tests, MSW sanity checks, and a dashboard e2e
  happy path plus an auth-guard redirect

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 01:01:05 +03:00