Skip to content

Structured error types, multi-strategy auth, payment provider bootstrap, typed API client - #778

Merged
Smartdevs17 merged 1 commit into
Smartdevs17:mainfrom
codeX-james:fix/waves-719-721-726-729
Aug 28, 2026
Merged

Structured error types, multi-strategy auth, payment provider bootstrap, typed API client#778
Smartdevs17 merged 1 commit into
Smartdevs17:mainfrom
codeX-james:fix/waves-719-721-726-729

Conversation

@codeX-james

Copy link
Copy Markdown

Summary

Four independent, self-contained fixes — one per assigned wave issue.

#719 — Structured error types with error codes
PaymentError/AuthError/ProjectError/DisputeError/NotFoundError/ValidationError (backend/src/types/errors.ts) all extended Error directly, so errorHandler.ts's err instanceof AppError check — the thing that decides whether a thrown error's statusCode/code/details are trusted or discarded in favor of a generic 500 — never recognized any of them. They now all extend AppError. types/errors.ts is the single source of truth for AppError; errorHandler.ts re-exports it so none of its ~130 existing import { AppError } from '../middleware/errorHandler.js' call sites need to change.

#721 — Auth middleware supporting multiple strategies
routes/push.ts does import { authMiddleware } from '../middleware/auth.js' — a module that didn't exist. Added it as a composable multi-strategy authenticator (session / HMAC / bearer-token / API-key), reusing the existing single-purpose validators (token-auth.ts, hmac-auth.ts) instead of re-implementing their crypto/replay-protection, and populating req.user in the {id, tenantId, role} shape BaseController.getUser() already expects (also added the missing Express.Request.user type augmentation, referenced but never declared).

#726 — Payment processing strategy pattern for multi-chain
The strategy pattern itself (provider-registry.ts, payment-router.ts, four chain/rail providers, unified-payment-tracker.ts, payment-strategies routes) was already fully built and tested. The gap: provider registration only happened inside di/container.ts's initialize(), which nothing in the running app ever calls — so providerRegistry was empty and every /payment-strategies/pay request would fail with PROVIDER_UNAVAILABLE. Extracted the registration into services/payments/bootstrap.ts and call it — plus mount the payment-strategies router — from index.ts at startup.

#729 — Frontend API layer: typed client with automatic retry
The retry piece was already solid (lib/api/client.ts has exponential backoff, jitter, and offline queueing). Most of lib/api.ts's endpoint wrappers returned any though, including one (checkout) whose type didn't even match the real { data: ... } response envelope its backend route returns. Replaced the anys with real interfaces, cross-checking the ones with live consumers against their backend route/service (e.g. GeneratedInvoice against InvoiceRecord).

Incidental fix used to get an accurate test signal: two pre-existing, stale compiled .js files sitting next to their .ts source (middleware/errorHandler.js, types/errors.js) were shadowing the .ts under vitest's module resolution, so err instanceof AppError didn't actually hold in tests even after the #719 fix. Regenerated both from current source. Two other such stale siblings (services/stellar.js, config/env.js) had drifted too far to safely regenerate (missing transitive requires) — removed instead. Nothing in the real app runs from these src/**/*.js files (the build emits to dist/), so this is test-resolution-only and doesn't touch prod behavior.

Verification

  • Backend: full vitest run before vs. after this branch — diffed the failing-test-file lists directly (not just totals). Zero new failures; four pre-existing failures fixed as a side effect of the stale-.js cleanup (errorHandler.test.ts, relayer/health.test.ts, stellar.test.ts, stellar.validation.test.ts).
  • Scoped tsc --noEmit on every touched/new backend file: no errors in any of them; the few surrounding errors that show up when pulling in index.ts's full transitive closure are pre-existing and unrelated (confirmed via the same baseline diff).
  • Frontend: full vitest run — 4/5 files pass (including the 2 new ones); the 1 failure is a pre-existing, unrelated UI test. tsc --noEmit clean on lib/api.ts and its one real consumer.

Test plan

  • npx vitest run — full backend suite, diffed against a pre-change baseline
  • npx vitest run — full frontend suite
  • npx vitest runpackages/sdk (untouched, confirmed still green)
  • Scoped tsc --noEmit on all touched backend files
  • tsc --noEmit on frontend/lib/api.ts + its real consumer page

Closes #719
Closes #721
Closes #726
Closes #729

…ap, typed API client

Four independent fixes, each closing one assigned wave issue:

- Smartdevs17#719: PaymentError/AuthError/ProjectError/DisputeError/NotFoundError/
  ValidationError extended `Error` directly, so errorHandler.ts's
  `err instanceof AppError` check never recognized them — throwing any of
  them anywhere would have been silently downgraded to an opaque 500,
  discarding their real statusCode/code/message. They now all extend
  AppError. types/errors.ts is the single source of truth for AppError;
  errorHandler.ts re-exports it for the ~130 existing import sites.
- Smartdevs17#721: `routes/push.ts` imports `authMiddleware` from
  `middleware/auth.ts` — a module that didn't exist. Added it as a
  composable multi-strategy authenticator (session/HMAC/token/API-key),
  reusing the existing single-purpose validators (token-auth.ts,
  hmac-auth.ts) rather than re-implementing their crypto, and populating
  `req.user` in the shape BaseController.getUser() already expects.
- Smartdevs17#726: The PaymentProvider strategy pattern for multi-chain payments
  (provider-registry.ts, payment-router.ts, the four chain/rail providers,
  unified-payment-tracker.ts, payment-strategies routes) was already fully
  built and tested, but provider registration only happened inside
  `di/container.ts`'s `initialize()`, which nothing in the running app
  ever called — so `providerRegistry` was empty and every payment would
  have failed with PROVIDER_UNAVAILABLE. Extracted the registration into
  `services/payments/bootstrap.ts` and call it (plus mount the
  payment-strategies router) from index.ts at startup.
- Smartdevs17#729: frontend/lib/api.ts's automatic retry was already solid
  (lib/api/client.ts has exponential backoff, jitter, and offline
  queueing) but most of its endpoint wrappers returned `any`, including
  one (checkout) whose type didn't even match the real `{ data: ... }`
  response envelope. Replaced the `any`s with real interfaces (some
  cross-checked against their backend route/service, e.g.
  GeneratedInvoice against InvoiceRecord).

Also: two stale, pre-existing compiled `.js` files (middleware/errorHandler.js,
types/errors.js) sitting alongside their `.ts` source were shadowing the
`.ts` files under vitest's module resolution — regenerated both from current
source so `err instanceof AppError` actually holds under test. Two other
such stale siblings (services/stellar.js, config/env.js) had drifted too far
from their `.ts` source to safely regenerate (missing transitive requires),
so those two are just removed; nothing runs the app from these `src/**/*.js`
files (the real build emits to dist/), so this is test-resolution-only and
does not touch prod behavior.

Closes Smartdevs17#719
Closes Smartdevs17#721
Closes Smartdevs17#726
Closes Smartdevs17#729
@vercel

vercel Bot commented Aug 28, 2026

Copy link
Copy Markdown

@JamesVictor-O is attempting to deploy a commit to the smartdevs17's projects Team on Vercel.

A member of the Team first needs to authorize it.

@drips-wave

drips-wave Bot commented Aug 28, 2026

Copy link
Copy Markdown

@codeX-james Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Smartdevs17
Smartdevs17 merged commit fd0d8d4 into Smartdevs17:main Aug 28, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants