Structured error types, multi-strategy auth, payment provider bootstrap, typed API client - #778
Merged
Smartdevs17 merged 1 commit intoAug 28, 2026
Conversation
…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
|
@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. |
|
@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! 🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 extendedErrordirectly, soerrorHandler.ts'serr instanceof AppErrorcheck — 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 extendAppError.types/errors.tsis the single source of truth forAppError;errorHandler.tsre-exports it so none of its ~130 existingimport { AppError } from '../middleware/errorHandler.js'call sites need to change.#721 — Auth middleware supporting multiple strategies
routes/push.tsdoesimport { 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 populatingreq.userin the{id, tenantId, role}shapeBaseController.getUser()already expects (also added the missingExpress.Request.usertype 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-strategiesroutes) was already fully built and tested. The gap: provider registration only happened insidedi/container.ts'sinitialize(), which nothing in the running app ever calls — soproviderRegistrywas empty and every/payment-strategies/payrequest would fail withPROVIDER_UNAVAILABLE. Extracted the registration intoservices/payments/bootstrap.tsand call it — plus mount the payment-strategies router — fromindex.tsat startup.#729 — Frontend API layer: typed client with automatic retry
The retry piece was already solid (
lib/api/client.tshas exponential backoff, jitter, and offline queueing). Most oflib/api.ts's endpoint wrappers returnedanythough, including one (checkout) whose type didn't even match the real{ data: ... }response envelope its backend route returns. Replaced theanys with real interfaces, cross-checking the ones with live consumers against their backend route/service (e.g.GeneratedInvoiceagainstInvoiceRecord).Incidental fix used to get an accurate test signal: two pre-existing, stale compiled
.jsfiles sitting next to their.tssource (middleware/errorHandler.js,types/errors.js) were shadowing the.tsunder vitest's module resolution, soerr instanceof AppErrordidn'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 thesesrc/**/*.jsfiles (the build emits todist/), so this is test-resolution-only and doesn't touch prod behavior.Verification
vitest runbefore 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-.jscleanup (errorHandler.test.ts,relayer/health.test.ts,stellar.test.ts,stellar.validation.test.ts).tsc --noEmiton every touched/new backend file: no errors in any of them; the few surrounding errors that show up when pulling inindex.ts's full transitive closure are pre-existing and unrelated (confirmed via the same baseline diff).vitest run— 4/5 files pass (including the 2 new ones); the 1 failure is a pre-existing, unrelated UI test.tsc --noEmitclean onlib/api.tsand its one real consumer.Test plan
npx vitest run— full backend suite, diffed against a pre-change baselinenpx vitest run— full frontend suitenpx vitest run—packages/sdk(untouched, confirmed still green)tsc --noEmiton all touched backend filestsc --noEmitonfrontend/lib/api.ts+ its real consumer pageCloses #719
Closes #721
Closes #726
Closes #729