Files
bank-flow/docs/api-routes.md
2026-07-22 15:02:14 +03:30

15 KiB
Raw Blame History

BankFlow API Reference

This document describes the HTTP API contract for BankFlow. It is based on the requirements in bank-flow.md.

Overview

All loan routes are versioned under /api/v1. The health-check route is not versioned.

Routes

Method Route Description Success status
POST /api/v1/loans Create a loan application 201 Created
POST /api/v1/loans/{loanId}/process Process a loan application 200 OK
GET /api/v1/loans/{loanId} Get a loan application 200 OK
GET /api/v1/loans/{loanId}/history Get processing history 200 OK
GET /health Check service health 200 OK

General conventions

Content type

Requests with a body must use JSON. Every response must include:

Content-Type: application/json

Timestamps

All timestamps use ISO 8601 format in UTC:

2026-07-15T10:00:00Z

Loan types

Value Description
PERSONAL Personal loan
BUSINESS Business loan

Loan statuses

Status Description Terminal for automatic processing
SUBMITTED The application has been created but not processed No
IN_PROGRESS The application is being processed No
MANUAL_REVIEW The application requires a manual decision Yes
APPROVED The application has been approved Yes
REJECTED The application has been rejected Yes

Loan stages

Stage Description
VALIDATION Validate the submitted application data
FRAUD_CHECK Perform the mocked fraud check
GUARANTOR_CHECK Check for a guarantor on business loans
CREDIT_CHECK Evaluate the applicant's credit score
MANAGER_APPROVAL Apply the mocked manager-approval rule

Stage result type

Result Effect
PASS Continue to the next applicable stage
FAIL Stop processing and set the loan status to REJECTED
MANUAL_REVIEW Stop processing and set the loan status to MANUAL_REVIEW

Create a loan application

Creates and stores a new loan application. Creating an application does not execute its workflow.

POST /api/v1/loans

Request body

Field Type Required Rules
customerId string Yes Must not be empty
amount integer Yes Must be greater than 0
phone string Yes Must contain exactly 11 digits and start with 09
loanType string Yes Must be PERSONAL or BUSINESS
monthlyIncome integer Yes Must be greater than or equal to 0
creditScore integer Yes Must be between 0 and 1000, inclusive
hasGuarantor boolean Yes Indicates whether the applicant has a guarantor
{
  "customerId": "C-1001",
  "amount": 400000000,
  "phone": "09121234567",
  "loanType": "PERSONAL",
  "monthlyIncome": 50000000,
  "creditScore": 720,
  "hasGuarantor": false
}

Processing rules

  • The service generates a unique loanId.
  • The initial status is SUBMITTED.
  • The initial workflow stage is VALIDATION.
  • Business validation is deferred until the workflow is processed.
  • An invalid field value does not produce an HTTP 400 response during creation. It causes the VALIDATION stage to fail when the application is processed.
  • A malformed JSON document produces an HTTP 400 response.

Success response

HTTP/1.1 201 Created
Content-Type: application/json
{
  "loanId": "L-10001",
  "status": "SUBMITTED",
  "currentStage": "VALIDATION"
}

Response fields

Field Type Description
loanId string Unique identifier generated by the service
status string Current loan status; initially SUBMITTED
currentStage string Current workflow stage; initially VALIDATION

Malformed JSON response

HTTP/1.1 400 Bad Request
Content-Type: application/json
{
  "error": "INVALID_REQUEST"
}

Process a loan application

Processes an application from its current workflow stage until it reaches a terminal automatic-processing status.

POST /api/v1/loans/{loanId}/process

Path parameters

Parameter Type Required Description
loanId string Yes Unique loan application identifier

This route does not accept a request body.

Workflow rules

All applications begin with the following stages:

VALIDATION → FRAUD_CHECK

The remaining route depends on the loan type:

PERSONAL:
VALIDATION → FRAUD_CHECK → CREDIT_CHECK → [MANAGER_APPROVAL] → APPROVED

BUSINESS:
VALIDATION → FRAUD_CHECK → GUARANTOR_CHECK → CREDIT_CHECK
           → [MANAGER_APPROVAL] → APPROVED

MANAGER_APPROVAL runs only when amount is greater than the configured managerApprovalThreshold.

Processing stops immediately when a stage returns FAIL or MANUAL_REVIEW.

Idempotency rules

This operation must be idempotent.

If the application is already APPROVED, REJECTED, or MANUAL_REVIEW:

  • no workflow stage is executed again;
  • no duplicate history record is created;
  • the existing status is not changed;
  • the current application state is returned with 200 OK.

Approved response

HTTP/1.1 200 OK
Content-Type: application/json
{
  "loanId": "L-10001",
  "status": "APPROVED",
  "currentStage": null
}

Rejected response

HTTP/1.1 200 OK
Content-Type: application/json
{
  "loanId": "L-10001",
  "status": "REJECTED",
  "currentStage": null
}

Manual-review response

HTTP/1.1 200 OK
Content-Type: application/json
{
  "loanId": "L-10001",
  "status": "MANUAL_REVIEW",
  "currentStage": null
}

Loan-not-found response

HTTP/1.1 404 Not Found
Content-Type: application/json
{
  "error": "LOAN_NOT_FOUND"
}

Get a loan application

Returns the submitted data and current processing state of a loan application.

GET /api/v1/loans/{loanId}

Path parameters

Parameter Type Required Description
loanId string Yes Unique loan application identifier

Success response

HTTP/1.1 200 OK
Content-Type: application/json
{
  "loanId": "L-10001",
  "customerId": "C-1001",
  "amount": 400000000,
  "phone": "09121234567",
  "loanType": "PERSONAL",
  "monthlyIncome": 50000000,
  "creditScore": 720,
  "hasGuarantor": false,
  "status": "APPROVED",
  "currentStage": null,
  "createdAt": "2026-07-15T10:00:00Z",
  "updatedAt": "2026-07-15T10:00:03Z"
}

Response fields

Field Type Nullable Description
loanId string No Unique loan application identifier
customerId string No Customer identifier
amount integer No Requested loan amount
phone string No Applicant's mobile number
loanType string No Loan type
monthlyIncome integer No Applicant's monthly income
creditScore integer No Applicant's credit score
hasGuarantor boolean No Whether the applicant has a guarantor
status string No Current loan status
currentStage string Yes Current workflow stage; null after processing stops
createdAt string No Creation timestamp in ISO 8601 UTC format
updatedAt string No Last-update timestamp in ISO 8601 UTC format

Loan-not-found response

HTTP/1.1 404 Not Found
Content-Type: application/json
{
  "error": "LOAN_NOT_FOUND"
}

Get processing history

Returns workflow stage executions in chronological order.

GET /api/v1/loans/{loanId}/history

Path parameters

Parameter Type Required Description
loanId string Yes Unique loan application identifier

History rules

  • Records are ordered by timestamp from oldest to newest.
  • A workflow stage is recorded at most once for an application.
  • Reprocessing a terminal application does not add history records.
  • reason contains SUCCESS for a successful stage or the applicable business error code for a failed validation.

Success response

HTTP/1.1 200 OK
Content-Type: application/json
[
  {
    "stage": "VALIDATION",
    "result": "PASS",
    "timestamp": "2026-07-15T10:00:00Z",
    "reason": "SUCCESS"
  },
  {
    "stage": "FRAUD_CHECK",
    "result": "PASS",
    "timestamp": "2026-07-15T10:00:01Z",
    "reason": "SUCCESS"
  },
  {
    "stage": "CREDIT_CHECK",
    "result": "PASS",
    "timestamp": "2026-07-15T10:00:02Z",
    "reason": "SUCCESS"
  }
]

History record fields

Field Type Description
stage string Name of the executed workflow stage
result string PASS, FAIL, or MANUAL_REVIEW
timestamp string Execution time in ISO 8601 UTC format
reason string Reason or business error code associated with the result

Loan-not-found response

HTTP/1.1 404 Not Found
Content-Type: application/json
{
  "error": "LOAN_NOT_FOUND"
}

Health check

Reports whether the service is available.

GET /health

Success response

HTTP/1.1 200 OK
Content-Type: application/json
{
  "status": "UP"
}

Business rules

Validation

The VALIDATION stage applies the following rules:

Field Rule Failure reason
customerId Required and not empty INVALID_CUSTOMER_ID
amount Greater than 0 INVALID_AMOUNT
phone Exactly 11 digits, starts with 09, and contains digits only INVALID_PHONE
loanType PERSONAL or BUSINESS INVALID_LOAN_TYPE
monthlyIncome Greater than or equal to 0 INVALID_MONTHLY_INCOME
creditScore Between 0 and 1000, inclusive INVALID_CREDIT_SCORE

Any validation failure produces a FAIL stage result and changes the application status to REJECTED.

Fraud check

The FRAUD_CHECK stage is mocked using customerId:

Rule Result
Starts with FRAUD FAIL
Starts with REVIEW MANUAL_REVIEW
Any other value PASS

Guarantor check

The GUARANTOR_CHECK stage runs only for BUSINESS loans:

Rule Result
hasGuarantor is false FAIL
hasGuarantor is true PASS

Credit check

The default credit-score rules are:

Rule Result
creditScore < 500 FAIL
500 <= creditScore < 650 MANUAL_REVIEW
creditScore >= 650 PASS

The score boundaries must be loaded from configuration and must not be hard-coded.

Manager approval

MANAGER_APPROVAL runs when the requested amount is greater than the configured managerApprovalThreshold.

Rule Result
amount > monthlyIncome × incomeMultiplier FAIL
Otherwise PASS

Both managerApprovalThreshold and incomeMultiplier must be loaded from configuration.

Error codes

HTTP errors

HTTP status Error code Description
400 Bad Request INVALID_REQUEST The request body is not valid JSON
404 Not Found LOAN_NOT_FOUND No loan application exists for the supplied loanId

HTTP error responses use this shape:

{
  "error": "LOAN_NOT_FOUND"
}

Business validation errors

Business validation errors do not produce HTTP 400 responses during loan creation. They are recorded as the reason of the failed VALIDATION history entry.

Error code Description
INVALID_AMOUNT The requested amount is invalid
INVALID_PHONE The mobile number is invalid
INVALID_CUSTOMER_ID The customer identifier is invalid
INVALID_LOAN_TYPE The loan type is invalid
INVALID_CREDIT_SCORE The credit score is invalid
INVALID_MONTHLY_INCOME The monthly income is invalid