feat: KYC onboarding flow with document verification - #993
Merged
github-actions[bot] merged 4 commits intoSep 28, 2026
Merged
github-actions[bot] merged 4 commits into
github-actions[bot] merged 4 commits into
Conversation
Validate KYC documents before verification: allowed MIME types and size limits from the kyc upload category, extension and magic-byte checks, document-number patterns (with country-specific formats), identity document expiry and proof-of-address recency. Define a DocumentVerificationProvider interface with a deterministic mock provider for local development and tests. Refs Smartdevs17#921
Extend KycService with a personal info -> documents -> review flow: provider-backed document checks, duplicate document detection, status transitions (pending, under_review, approved, rejected, expired) with recorded history and reasons, automatic approval for low-risk applications and a manual review queue. Expose it under /api/v1/kyc, allow larger JSON bodies for base64 document uploads and redact document numbers, file contents and dates of birth from audit logs. Also makes the two timestamp-based KycService tests deterministic. Refs Smartdevs17#921
Add a /dashboard/kyc page with a three-step flow (personal info, document upload, review and status) that mirrors the backend document checks in the browser, shows per-document verification results and rejection reasons, and resumes from the step the API reports. Link it from the sidebar and the onboarding wizard's identity step. Refs Smartdevs17#921
|
@Itodo-S is attempting to deploy a commit to the smartdevs17's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
@Itodo-S 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
Closes #921
Adds a full KYC onboarding flow for individual users: personal info → document upload → review & status, with document verification in two layers: local format checks, then a pluggable verification provider. It builds on the existing
KycService(backend/src/services/kyc.ts), which already had profiles, risk scoring and AML/sanctions/PEP stubs but no API or flow. It reuses thekycupload category rules from the file-upload middleware.Backend
services/kyc-verification.ts(new): document checks.jpeg/png/webp/pdf), 1 KB–10 MB size, extension/MIME match and magic-byte signature (shared with the upload middleware).DocumentVerificationProviderinterface and a deterministicMockDocumentVerificationProvider: numbers ending000are rejected, numbers ending999go to manual review.services/kyc.ts(extended):savePersonalInfo,uploadDocument,getOnboardingState,submitForReview,review,reviewDocument,listForReview.pending → under_review → approved | rejected. Rejected or expired applications return topendingwhen the applicant resubmits.statusHistorywith the actor and reason, and rejections need at least one reason.HIGH_RISK_COUNTRIESlist), goes to the review queue.submitDocument/verifyDocument/updateStatusAPIs keep working.routes/kyc.ts+schemas/kyc.ts(new): mounted at/api/v1/kyc. Endpoints: requirements, state, personal-info, documents, submit, review queue, document review, application review. Service errors map to the standard error envelope, with the reasons indetails./api/v1/kycaccepts JSON bodies up to 15 MB so a base64-encoded 10 MB document fits, and is added to the request-size-limit upload paths.documentNumber,fileContentanddateOfBirthare redacted from audit-log request bodies.file-upload.ts, a file this PR already touches.Frontend
/dashboard/kycpage (components/kyc/*,lib/kyc.ts). It runs a three-step flow that repeats the backend's file, number and date checks in the browser, shows each document's status, warnings and rejection reasons, and resumes from the step the API reports.Docs
docs/KYC_ONBOARDING.mdcovers the endpoints, error codes, validation rules, status transitions, the provider interface and the mock provider's behaviour.How it was tested
New tests:
backend/src/services/__tests__/kyc-verification.test.ts: every format check (pass and fail), plus the mock provider.backend/src/services/__tests__/kyc-onboarding.test.ts: the full flow.backend/src/routes/__tests__/kyc.test.ts: the HTTP API end to end on a real Express server.frontend/lib/kyc.test.ts: client-side validation and API error handling.frontend/components/kyc/__tests__/KycOnboardingFlow.test.tsx: the UI flow, including validation, upload, server errors, submit and the rejected state.I also ran a manual end-to-end check with
tsx: Express with the KYC router, a 3 MB PDF sent as base64, a passport plus a bank statement, then submit. It wentpending → under_review → approved.Full-suite regression check: the backend suite has the same failing files before and after this change. The only difference is that
kyc.test.tsnow passes: two of its timestamp tests were flaky (same-millisecondupdatedAt) and now use fake timers.Notes for reviewers
.jsimport specifiers inbackend/src/middlewareresolve to old compiled CommonJS files that sit next toerrorHandler.tsandvalidate.ts. The route test mocks those two modules to use the TypeScript sources, which are what the build actually ships.tsxandtscare not affected.next buildfails becausenext-intlis not infrontend/package.json.@testing-library/react, which is not installed. For that reason the new component test renders withreact-domdirectly.backend/src/index.tshas existing unused-import lint errors.