# System Architecture Interview KYC = know your customer — it is a regulatory requirement for companies to do due diligence on who their customer is and, depending on how much they are transacting, have differing levels of verification and due diligence. ## Context Users can have up to 4 documents: ID front ID back Proof of address Selfie If all 4 documents are verified, user is verified else user is unverified. User can resubmit for documents that have been rejected. ## Database Design Design tables to store all required informations ## API Endpoint Design Design APIs for clients to query for user statuses Design APIs for clients to submit user documents ## Architecture Design Design overall architecture of the service Notes * Assume if we use external service to verify user kyc ## Additional How if we want to sell the service to merchants, so they can use our service to do KYC? Table user_kyc_status - id (auto increment long) - user_id (long) - overall_status (boolean) Table user_kyc_doc_status - user_id (long) - doc_type (string) - user_kyc_doc_history_id (long) - doc_status (boolean) Table user_kyc_doc_history - id (auto increment long) - user_id (long) - doc_location (string) - created_at (datetime) KYC Status API GET /api/v1/user/me/kyc/status Request Header: - Authorization (jwt <token>) - content-type Response: { "user_id": 123456, "status": "unverified", "submission_status": "SUBMITTED", "doc_status": [ { "doc_type": "ID_FRONT", "doc_status": "VERIFIED" }, { "doc_type": "ID_BACK", "doc_status": "UNVERIFIED" }, ] } Response: { "user_id": 123456, "status": "unverified", "submission_status": "NOT_SUBMITTED" } Submit KYC Doc API POST /api/v1/user/me/kyc/submit Request Header: - Authorization (jwt <token>) - content-type Request Body: { "doc_type": "ID_FRONT", "doc_body": "<base-64 encoded of the image>" } Response 200: { "is_success": true, "err_code": "Err0000", "err_message": "OK" } Response 400: { "is_success": false, "err_code": "Err1234", "err_message": "File size is too big" } Response: { "user_id": 123456, "status": "unverified", "submission_status": "NOT_SUBMITTED" } Apps -> (API Gateway) -> (Service LB) -> Individual server Service KYC service -> external regulator -> Database (PostgreSQL) -> Redis cache (for storing cacheable doc statuses) <- external regulator (webhook of the status)