# 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)