Banking Platform
A multi-client banking system spanning a Spring Boot core, Next.js web application, Android client, and FastAPI KYC service.
- Role
- Software engineer
- Sources
- 4 grouped repositories
Problem
Keep core banking, web, mobile, and identity-verification concerns explicit while the clients and services evolve together.
Constraints
- The core backend, web application, Android client, and KYC service have separate interfaces and responsibilities.
- Verification behavior must remain scoped to the KYC service rather than being implied by the portfolio project identity.
- The former route was synthetic and repository-derived; the portfolio slug must now resolve to one curated system record.
Architecture
Core banking backend
Own the authoritative Spring Boot banking API, authentication, authorization, customers, accounts, financial workflows, ledger, MySQL/Flyway persistence, KYC orchestration, and server-side banking rules.
Web application
Provide supported customer, staff, and administrative browser workflows through a typed bank-core API boundary.
KYC service
Own FastAPI KYC component checks and aggregate verification policy consumed by bank-core; optional ONNX/Tesseract modules are not presented as the default runtime path.
Android application
Provide native Kotlin/Android banking, account, KYC, wallet, and device-local security flows.
Evidence record
Mixed classificationsHow the system is split, synchronized, and tested
Banking Platform is documented as one cross-stack system across four independently versioned repositories: bank-core owns the authoritative Spring Boot backend, bank-web provides the Next.js browser client, bank-service owns the FastAPI KYC service, and bank-app supplies the Kotlin/Android client. This record distinguishes implemented source structure and decision policy from design documents, optional model modules, and untested operational or outcome claims.
Ownership boundaries
The system is easier to reason about when authority, policy, processing, and presentation state have explicit owners.
Spring backend API and persistence
IMPLEMENTEDbank-core / Spring backend
Own authentication, role checks, customer/account/KYC/wallet feature modules, JPA entities and repositories, and the HTTP API surface.
Next.js web client
IMPLEMENTEDbank-web / Next.js web
Own browser routing, role-gated screens, login state, bearer-token requests, account creation, and account-transaction views through the Next.js/React client.
Android client
IMPLEMENTEDbank-app / Android client
Own the Kotlin/Compose application shell, Hilt bindings, Retrofit/Moshi/OkHttp API adapters, account/KYC/wallet flows, local auth-token storage, and app-lock UI.
Identity-verification service
IMPLEMENTEDbank-service / FastAPI KYC
Own `/api/v1/kyc` component checks and aggregate policy for document classification, OCR, face matching, liveness, and the APPROVE/UNDER_REVIEW/REJECT decision boundary.
Each boundary is shown with its owner and classification. The arrows describe the evidence-oriented relationship, not a claim that every message moves in one direction.
Transport and boundary contracts
Each boundary describes how data, identity, state, or work crosses between owned parts of the system.
Next.js web or Android to Spring API
IMPLEMENTEDThe web and Android clients call the Spring API over JSON/multipart endpoints and send a Bearer token after login. Route and method guards remain server-owned rather than being treated as client authorization.
Spring core to FastAPI KYC
IMPLEMENTEDThe KYC orchestrator reads bounded uploaded files, sends an aggregate request to `/api/v1/kyc/aggregate`, accepts an `X-Request-ID`, records returned checks, and maps empty or exceptional ML responses to UNDER_REVIEW.
KYC upload to case
IMPLEMENTEDThe Spring API accepts only named document categories and selected image content types, stores an upload owned by the authenticated user, and requires four distinct, correctly typed owned upload IDs before a case is submitted.
Android unauthorized response
IMPLEMENTEDThe Android network layer attaches the stored bearer token and clears it after a 401 response; repository methods expose network/API failures as Result or typed domain exceptions rather than treating a failed request as a successful operation.
Workflow modes
The product keeps immediate responses, queued processing, and page previews as distinct contracts.
| Workflow | Mode | Entry point / owner | Processing and result | Evidence |
|---|---|---|---|---|
| Web or Android login | SynchronousIMPLEMENTED | POST `/api/v1/auth/login` from the Next.js client or bank-app Owner: Spring authentication boundary | The core loads the user, checks active status, authenticates the password through the configured provider, generates a role-bearing JWT, and creates a server-side session record. The clients retain the returned token in their respective auth stores. Result: The client receives a token, then sends it as Bearer authentication to protected routes; invalid or logged-out sessions are rejected by the server filter. | auth-controller, spring-security, jwt-auth, web-auth, android-auth |
| Account opening with an opening deposit | SynchronousIMPLEMENTED | POST `/api/v1/accounts` for a customer or `/api/v1/accounts/{id}` for a teller Owner: Spring account service | The service resolves the current or target user, customer, and branch, validates non-negative and account-type minimum deposits, creates an ACTIVE account with a generated unique account number, and writes an opening DEPOSIT transaction when the initial deposit is positive. Result: The API returns an account DTO; the web and Android clients can then request the account transaction history. | account-api, account-service, account-domain, android-accounts, web-account-flow |
| KYC submission and auto-review | SynchronousIMPLEMENTED | Authenticated KYC upload and submit flow with four upload IDs and consent Owner: Spring KYC case/orchestration boundary | The case service validates ownership, distinctness, and upload types, persists a PENDING case, then the submit controller invokes the orchestrator. A scheduled batch also claims PENDING cases in bounded pages and calls the same review path. Result: The case moves through PENDING/AUTO_REVIEW and receives APPROVED, REJECTED, UNDER_REVIEW, or a further-review state according to the returned aggregate decision and transition rules. | kyc-case, kyc-orchestrator, kyc-status, kyc-review, android-kyc |
| KYC aggregate decision | SynchronousIMPLEMENTED | POST `/api/v1/kyc/aggregate` with selfie and document inputs Owner: FastAPI KYC policy | The service computes or selects FACE_MATCH, LIVENESS, OCR_ID, and DOC_CLASS results, attaches thresholds, and evaluates the policy. All checks passing produces APPROVE; failed checks produce reasons, with a low face/liveness score below 0.40 producing REJECT and other failures producing UNDER_REVIEW. Result: The response contains a decision, reason codes, and per-check score/pass/details records. This is decision policy evidence, not a population-level accuracy result. | kyc-aggregate, kyc-policy, kyc-config, kyc-schemas |
| Android wallet payment intent | AsynchronousIMPLEMENTED | bank-app QR, reload, or bill payment flow Owner: bank-app wallet client and Spring wallet service | The Android repository sends an Idempotency-Key, the Spring service creates a PROCESSING PaymentIntent, and the Android view model polls the intent with bounded backoff until success, failure, cancellation, or timeout. Result: The UI exposes explicit creating, processing, succeeded, failed, and canceled states; the audited source does not establish a completed external-provider settlement result. | android-wallet, android-payment-flow, wallet-service |
Architecture decisions
Each decision records the boundary it protects and the alternative that was deliberately not chosen.
Group the cross-stack implementation as one portfolio project
ACCEPTED- Decision
- Represent four independently versioned repositories as one Banking Platform record.
- Why
- Repository ownership follows backend, web, AI/KYC, and Android boundaries while the product remains one multi-client banking system.
- Alternative considered
- Treating KYC, web, and Android as separate flagship projects would reproduce the old repository-equals-project problem.
Keep authorization server-owned
IMPLEMENTED- Decision
- Use Spring Security route/method guards, JWT validation, server-side session activity, and owner checks for protected resources.
- Why
- Client route guards improve navigation but cannot replace the core API's authorization boundary.
- Alternative considered
- Relying on web/Android role state alone would leave API access decisions outside the authoritative service.
Use review fallback for KYC uncertainty
IMPLEMENTED- Decision
- Represent non-approval failures and ML unavailability as UNDER_REVIEW unless the explicit low-score rejection branch applies.
- Why
- The source preserves a reviewable case state and records reason/check data instead of collapsing every missing or unavailable signal into a rejection or approval.
- Alternative considered
- A binary approve/reject-only policy was not selected in the audited code path.
Keep mobile auth storage behind an adapter
IMPLEMENTED- Decision
- Store the Android bearer token through AES/GCM and Android Keystore-backed DataStore, then attach it through the network module.
- Why
- Token persistence, request decoration, and unauthorized cleanup are kept out of feature screens and repositories.
- Alternative considered
- Keeping the token in screen state or unencrypted preferences was not the selected token path.
Do not publish KYC accuracy outcomes without labeled evidence
ACCEPTED- Decision
- Show the implemented checks, thresholds, policy, calibration tooling, and limitations, but do not publish accuracy, false-rejection, or manual-review improvements.
- Why
- The reviewed repositories contain policy code and calibration utilities but no labeled evaluation dataset or reproducible report supporting those outcomes.
- Alternative considered
- Turning threshold values or smoke tests into a quality-rate claim would confuse implementation evidence with measured outcomes.
Keep optional model paths visibly optional
DEFERRED- Decision
- Describe ONNX/Tesseract modules as available source paths while identifying the current simple FeatureFactory path as the reviewed default.
- Why
- This keeps the portfolio aligned with the actual wiring and avoids implying that model files or a selected inference deployment were verified.
- Alternative considered
- Naming ArcFace/ONNX as the active production inference path would exceed the source evidence.
Primary lifecycle
The primary sequence follows input, ownership, processing, result, and cleanup transitions without collapsing synchronous and queued work into one claim.
Authenticate
IMPLEMENTEDAuthenticate
Web or Android client
Submit credentials, receive the JWT/role response, and retain the token in the client auth boundary.
Result: Protected requests carry a Bearer token; server-side session activity and JWT validation remain required.
Open account
IMPLEMENTEDOpen account
Customer or teller through the Spring API
Resolve the customer and branch, validate account type/deposit constraints, generate an account number, persist the account, and persist the opening deposit transaction when applicable.
Result: An ACTIVE account DTO and an account-linked opening transaction are available to the client.
Collect KYC inputs
IMPLEMENTEDCollect KYC inputs
Spring KYC upload boundary and bank-app
Upload DOC_FRONT, DOC_BACK, SELFIE, and ADDRESS_PROOF images, enforce type/size/count checks, and return upload IDs.
Result: The server retains ownership metadata and the authenticated user can submit only their own correctly typed files.
Submit and claim case
IMPLEMENTEDSubmit and claim case
Spring KycCaseService and scheduled orchestrator
Require consent, validate four distinct upload IDs, save or reuse a case, transition it to AUTO_REVIEW, and use an atomic processing flag for scheduled claims.
Result: A case has an explicit status, timestamps, processing flag, reviewer fields, and a version field for optimistic persistence checks.
Run component checks
IMPLEMENTEDRun component checks
FastAPI KYC service
Run the configured factory's face, liveness, OCR, and document-classification paths, attach thresholds, and write optional calibration rows when enabled.
Result: The aggregate response has per-check scores/pass values and details; source-level thresholds are visible without being presented as calibrated outcomes.
Resolve or review
IMPLEMENTEDResolve or review
FastAPI policy and Spring case service
Map APPROVE/REJECT/other decisions to Spring statuses; on empty or exceptional ML responses, record an ERROR check and move the case to UNDER_REVIEW.
Result: The system preserves a reviewable case state instead of treating an unavailable ML response as an approval.
KYC document lifecycle
The Spring service keeps uploaded documents behind an authenticated owner/admin boundary and passes bounded base64 payloads to the KYC service for a case review.
Accept
IMPLEMENTEDAccept
KycUploadController
Validate category, content type, 10 MB request-file limit, authenticated owner, and daily upload count before storing the file.
Result: A persisted upload ID is returned or the request is rejected with a deliberate client error.
Associate
IMPLEMENTEDAssociate
KycCaseService
Require four distinct upload IDs owned by the user and matching the expected document categories.
Result: The case references a known set of document roles rather than arbitrary file IDs.
Read and review
IMPLEMENTEDRead and review
KycAutoReviewOrchestrator
Read each file, reject empty or over-6 MB inputs for the aggregate payload, encode valid bytes, and persist returned checks.
Result: The KYC service sees bounded request data and the core retains check details against the case.
Android authentication token lifecycle
bank-app wraps the token with AES/GCM using an Android Keystore key before storing it in DataStore, then supplies it through the network boundary.
Receive
IMPLEMENTEDReceive
UserRepositoryImpl
Save a successful login response token through TokenManager.
Result: The token enters the encrypted storage adapter rather than being kept as a normal UI field.
Encrypt and persist
IMPLEMENTEDEncrypt and persist
TokenManager and Android Keystore
Encrypt the token with AES/GCM and persist the IV plus ciphertext in Preferences DataStore.
Result: Subsequent reads can decrypt the token with the Keystore-backed secret key.
Attach or clear
IMPLEMENTEDAttach or clear
NetworkModule and UnauthorizedHandler
Attach `Authorization: Bearer ...` to requests and clear the token after a 401 response or explicit logout.
Result: Expired/unauthorized sessions do not remain active in the client token store.
Wallet payment intent lifecycle
The mobile wallet uses an idempotency key at creation and polls the server-owned PaymentIntent state; the audited source does not establish external settlement completion.
Create
IMPLEMENTEDCreate
bank-app WalletRepository
Send QR/reload/bill details and an Idempotency-Key to the Spring wallet API.
Result: A PaymentIntent identifier is returned or a Result failure is exposed.
Poll
IMPLEMENTEDPoll
PaymentFlowViewModel
Poll the intent with exponential backoff capped at ten seconds for up to two minutes.
Result: The UI reflects PROCESSING, SUCCESS, FAILED, CANCELED, or timeout behavior.
External completion
NOT TESTEDExternal completion
Out of audited proof
Treat provider settlement, webhook delivery, and end-to-end reconciliation as future evidence work.
Result: No portfolio claim is made about completed external payment settlement.
Processing paths
Processing choices are shown with their boundary and limits instead of being collapsed into one generic pipeline claim.
KYC component-check pipeline
IMPLEMENTEDFastAPI `/api/v1/kyc/aggregate`
The aggregate route runs the factory's face, liveness, OCR, and document-classification implementations when inputs exist, adds threshold/pass fields, and returns a check list with details.
Limits
- The default factory constructs simple face, liveness, OCR, and document-classification implementations; optional ONNX/Tesseract modules exist but are not presented as the default runtime path.
- No population-level accuracy or false-rejection result is published.
Aggregate decision policy
IMPLEMENTEDFastAPI policy module to Spring KYC status mapping
All four checks must pass for APPROVE. Any failed check contributes a reason; a face or liveness score below 0.40 produces REJECT, while other failed or missing evidence produces UNDER_REVIEW. Spring maps the result to APPROVED, REJECTED, or UNDER_REVIEW.
Limits
- The thresholds and policy are code behavior, not evidence that the policy has a measured error rate or is suitable for regulated production use.
Optional model/inference modules
DEFERREDFastAPI feature modules and environment selectors
The repository contains ONNX face/liveness/portrait modules and Tesseract OCR code, while the current FeatureFactory constructs simple implementations and does not branch on every backend setting. The portfolio therefore describes optional module source without claiming active deployment of a specific model.
Limits
- Model files, selected deployment configuration, inference reproducibility, and model-level evaluation were not established in the reviewed default branch.
Core financial workflow path
IMPLEMENTEDSpring financial workflows to the immutable ledger
The Spring financial workflow service validates deposit, withdrawal, and transfer commands, coordinates client idempotency, and delegates the authoritative balance write to the transactional double-entry posting engine. Transaction history remains queryable through the core API.
Limits
- The portfolio does not claim a completed MySQL-backed integration run, throughput result, or production deployment from source inspection alone.
Focused code excerpts
Short, source-pinned excerpts make one engineering boundary concrete without reproducing a source file.
KYC policy decision states
pythonif not reasons:
return "APPROVE", reasons
fm = checks.get("FACE_MATCH", {}).get("score")
lv = checks.get("LIVENESS", {}).get("score")
if (fm is not None and fm < 0.40) or (lv is not None and lv < 0.40):
return "REJECT", reasons
return "UNDER_REVIEW", reasonsThe policy makes the three decision states and low-score reject boundary explicit; it shows implementation policy rather than a measured accuracy or false-rejection result.
Limit: Thresholds are implementation rules. The audited repository does not establish labeled model quality, FAR/FRR, or false-rejection improvement.
View exact sourcecommit 7e4beb846c65afc99966a6e4edc9dfd3c9311250
Failure boundaries
Failure handling is attached to the boundary that owns the response, cleanup, retry, or user-visible state transition.
Authentication and session validity
IMPLEMENTED- Trigger
- Missing, invalid, expired, or logged-out JWT/session
- Behavior
- Spring rejects protected requests; bank-app clears its token on a 401 and web auth state can be revalidated through the protected token-validation route.
KYC upload and case validation
IMPLEMENTED- Trigger
- Unsupported type, over-size file, daily upload limit, duplicate ID, unowned upload, or mismatched document category
- Behavior
- The upload/case boundary returns a deliberate client error and does not submit an arbitrary file set to review.
KYC service unavailable
IMPLEMENTED- Trigger
- Empty ML response, timeout, connection failure, or exception while calling the FastAPI aggregate endpoint
- Behavior
- The orchestrator records an ERROR check, marks the case UNDER_REVIEW with an unavailable reason, clears processing, and returns the case state instead of approving it.
KYC low-score policy
IMPLEMENTED- Trigger
- A required check fails or face/liveness score falls below the source-level rejection threshold
- Behavior
- The policy returns a reasoned REJECT only for the documented low-score branch; other failed or missing checks remain UNDER_REVIEW.
Android API/network failure
IMPLEMENTED- Trigger
- Non-success HTTP response, IOException, timeout, or invalid response body
- Behavior
- Auth clears on 401; account/KYC/wallet repositories expose typed failures or Result failures, and the payment flow enters FAILED or timeout state rather than claiming success.
Account opening validation
IMPLEMENTED- Trigger
- Missing customer/branch, invalid initial deposit, or account-type minimum not met
- Behavior
- The Spring service raises explicit business/resource errors before returning an account DTO.
Evidence, measurements, and limits
Values retain their context, sample, method, and limits so an implementation detail is not mistaken for universal capacity or outcome evidence.
| Evidence | Classification | Result and context | Method / environment / sample | Limitations |
|---|---|---|---|---|
| KYC admission and decision thresholds | IMPLEMENTED | The FastAPI defaults are face 0.85, liveness 0.80, OCR 0.80, and document classification 0.80; the policy's explicit low-score branch uses 0.40 for face or liveness. Spring limits individual uploads to 10 MB and daily uploads to 20 per user. These are source/configuration guardrails and policy constants, not measured quality or capacity results. | Method: Remote default-branch source and configuration inspection. Environment: bank-core main at the recorded public commit; no deployed service configuration was used. Sample: Static defaults and branch conditions; no population sample. |
|
| KYC service timeout and bounded payload behavior | IMPLEMENTED | The Spring ML WebClient defaults to a 1,000 ms connect timeout, 180,000 ms read timeout, and 20 MB in-memory body limit; the orchestrator declines empty files and individual files above 6 MB before base64 encoding. These are integration and input guardrails. | Method: Source/configuration inspection. Environment: bank-core main at the recorded public commit; no live KYC service was started. Sample: Deterministic configured defaults; no workload run. |
|
| KYC accuracy and false-rejection outcomes | NOT TESTED | No labeled evaluation dataset, accuracy report, FAR/FRR report, or reproducible false-rejection comparison was found in the audited default-branch source. Calibration and label-merging tools exist, but no completed labeled report is included. A deliberate evidence gap for face match, liveness, OCR, document classification, and aggregate decisions. | Method: Bounded search of the KYC source/tests/tools for labeled samples, calibration CSV output, benchmark reports, and population-level quality metrics. Environment: bank-core main at `609e7f567720ec1edf186d5803fbd744e063e34b`; no external dataset or deployment was supplied. Sample: Source, test, and tooling inventory only; no labeled evaluation sample. |
|
| Account opening and transaction integrity | IMPLEMENTED | The current core source includes BigDecimal monetary validation, immutable double-entry journal posting, materialized customer balances, deposit/withdrawal/transfer workflows, idempotency coordination, transaction history, and a compensating reversal workflow. The source establishes the financial workflow and ledger boundaries; runtime acceptance and MySQL-backed execution remain separate evidence claims. | Method: Source and test inventory inspection of account, transaction, repository, controller, and Spring test paths. Environment: bank-core main at the recorded public commit; no MySQL-backed integration run was performed. Sample: Ledger, workflow, idempotency, reversal, entity/controller source, and two Spring test files; no transaction workload. Monetary amount policyDouble-entry posting and reversal engineDeposit, withdrawal, and transfer workflowsFinancial mutation idempotency coordinatorCompensating reversal workflowTransaction history query serviceAccount entityTransaction entityAccount service implementationTransaction controllerSpring application test inventory |
|
| Android payment state handling | IMPLEMENTED | The bank-app payment view model polls with an initial one-second delay, exponential backoff capped at ten seconds, and a two-minute limit, then exposes success, failure, canceled, or timeout states. This is an implemented client state machine, not a measured network or provider reliability result. | Method: Source inspection of wallet API, repository, and payment-flow view model. Environment: bank-app main at the recorded public commit; no device or provider session was run. Sample: Deterministic source constants and branches; no network sample. |
|
| Performance and scaling | NOT TESTED | No reproducible load, latency, throughput, memory, or concurrent-user report suitable for publication was found in the audited repositories. Existing timeout, upload-limit, and page structures are documented as guardrails only. The source audit intentionally separates topology and limits from operational measurements. | Method: Bounded repository search and test inventory inspection across the Spring, Next.js, FastAPI, and Android sources. Environment: Remote public default branches; no shared deployment, database, emulator, or load environment. Sample: Source/docs/tests only; no performance sample. |
|
| Repository test inventory | ACCEPTED | The audited source contains two Spring test files, fourteen Python KYC test files including aggregate/policy-path smoke coverage, and two bank-app template tests. This is an inventory of test material, not a passing cross-repository test result. Test presence is reported separately from executed validation. | Method: Remote default-branch file inventory and focused test-source inspection. Environment: bank-core, bank-web, bank-service, and bank-app public main snapshots recorded in the source links. Sample: 2 Spring files, 14 Python files, 2 Android Kotlin files. |
|
Failure and recovery stories
Each story connects a symptom to an owned boundary and keeps verification limits visible.
Keep an unavailable KYC dependency reviewable
IMPLEMENTED- Symptom
- The Spring orchestrator cannot obtain a usable aggregate response from the FastAPI service.
- Root cause
- The ML response is empty or the WebClient call raises while the KYC case is being processed.
- Correction
- Persist an ERROR check with the exception detail, mark the case UNDER_REVIEW with `ml_unavailable`, and clear the processing flag in the finally path.
- Verification
- The behavior is directly visible in KycAutoReviewOrchestratorImpl; it is not presented as a measured incident or production recovery result.
Limitations
- No deployed outage drill or retry/queue benchmark was found in the audited source.
Clear an Android session after unauthorized access
IMPLEMENTED- Symptom
- A protected Android request returns HTTP 401.
- Root cause
- The stored bearer token is no longer accepted by the Spring API or the session is no longer active.
- Correction
- NetworkModule's unauthorized handler clears the TokenManager value; feature repositories expose the request failure to the calling UI.
- Verification
- The interceptor, token store, and auth repository paths are present in the audited bank-app source; no device-level test was run here.
Limitations
- No emulator/device session or concurrent-request race test is included.
Do not turn missing KYC evidence into a false quality claim
ACCEPTED- Symptom
- The repository contains thresholds, smoke fixtures, and a calibration utility but no completed labeled evaluation report.
- Root cause
- Implementation/configuration evidence and population-level outcome evidence are different boundaries.
- Correction
- Keep the check/policy description, classify outcome quality as NOT TESTED, and defer false-rejection/accuracy language until a labeled evaluation is attached.
- Verification
- The reviewed source contains `calib_log.py`, `calibrate.py`, and KYC tests but no completed labeled report in the audited tree.
Limitations
- This is a portfolio evidence decision, not a claim about the eventual model quality.
Limitations and deferred evidence
- Evidence is based on the public pinned snapshots bank-core main at 609e7f567720ec1edf186d5803fbd744e063e34b, bank-web main at b7d62497452733894a6f42216ea83e767406b8f3, bank-service main at 7e4beb846c65afc99966a6e4edc9dfd3c9311250, and bank-app main at 770afcff097a58cfadf2be47e4c71fca301ca8ac. Neither external repository was modified.
- The source establishes four independently versioned repositories with Spring, Next.js, FastAPI, and Android boundaries; it does not establish a deployed production topology, banking-grade controls, regulatory compliance, or operational SLO.
- No labeled KYC evaluation cohort, accuracy report, FAR/FRR report, false-rejection comparison, or manual-review rate was found. Those outcome claims remain intentionally unpublished.
- The current FastAPI FeatureFactory constructs simple face, liveness, OCR, document-classification, and portrait implementations; ONNX/Tesseract source modules and backend settings are not treated as proof of an active model deployment.
- The current bank-core source establishes BigDecimal monetary handling, immutable double-entry posting, materialized balances, idempotent deposit/withdrawal/transfer workflows, transaction history, and compensating reversal code. This source evidence does not substitute for a completed MySQL-backed integration run or production acceptance.
- Android token encryption and unauthorized cleanup are implemented in source, but the manifest permits cleartext traffic, app-lock PINs are stored through ordinary SharedPreferences, and no device/security audit was performed here.
- No reproducible performance, throughput, concurrency, provider-settlement, or horizontal-scaling result is published. Timeout and size values are configuration guardrails only.
- The external repository test files were inspected as evidence inventory, not freshly executed as part of the portfolio repository validation.
Source evidence
Links point to the commits inspected for this page. The classification attached to each claim is more important than the existence of a link alone.
- Monetary amount policy
Immutable BigDecimal monetary value object with explicit customer-input and ledger-storage scales and no binary floating-point path.
commit 609e7f567720ec1edf186d5803fbd744e063e34b · 2026-09-11
- Double-entry posting and reversal engine
Transactional balance writer for normal postings and compensating reversals with journal entries and materialized customer balances.
commit 609e7f567720ec1edf186d5803fbd744e063e34b · 2026-09-11
- Deposit, withdrawal, and transfer workflows
Core financial workflows validate account authority and compose idempotency with the authoritative posting engine.
commit 609e7f567720ec1edf186d5803fbd744e063e34b · 2026-09-11
- Financial mutation idempotency coordinator
Transactional claim coordination for exactly-once deposit, withdrawal, and transfer command execution and replay handling.
commit 609e7f567720ec1edf186d5803fbd744e063e34b · 2026-09-11
- Compensating reversal workflow
Server-owned reversal command path that delegates to the posting engine and returns a reversal receipt.
commit 609e7f567720ec1edf186d5803fbd744e063e34b · 2026-09-11
- Transaction history query service
Core transaction-history query implementation for the authoritative banking API.
commit 609e7f567720ec1edf186d5803fbd744e063e34b · 2026-09-11
- Spring core build configuration
Spring Boot, Java 21, JPA, Security, WebFlux, MySQL, and test dependencies for the core service.
commit 609e7f567720ec1edf186d5803fbd744e063e34b · 2025-09-19
- Spring Security configuration
Stateless security filter chain, public auth routes, role gates, BCrypt password encoder, and method security.
commit 609e7f567720ec1edf186d5803fbd744e063e34b · 2025-09-19
- JWT filter and token utilities
Bearer extraction, active-session check, JWT validation, and role authority construction.
commit 609e7f567720ec1edf186d5803fbd744e063e34b · 2025-09-19
- Spring authentication controller
Login, registration, logout, token validation, password, and session creation endpoints.
commit 609e7f567720ec1edf186d5803fbd744e063e34b · 2025-09-19
- Account controller
Role-guarded account creation, owner/admin reads, status operations, and transaction-history route.
commit 609e7f567720ec1edf186d5803fbd744e063e34b · 2025-09-19
- Account service implementation
Customer/branch resolution, deposit validation, unique account number generation, account persistence, and opening transaction creation.
commit 609e7f567720ec1edf186d5803fbd744e063e34b · 2025-09-19
- Account entity
Account identity, unique account number, status, balance, customer/branch relationships, and timestamps.
commit 609e7f567720ec1edf186d5803fbd744e063e34b · 2025-09-19
- Transaction entity
Persisted transaction type, amount, balance-after, account association, and creation timestamp.
commit 609e7f567720ec1edf186d5803fbd744e063e34b · 2025-09-19
- Transaction controller
Current deposit, withdrawal, transfer, reversal, and transaction-history routes over the core financial workflow boundary.
commit 609e7f567720ec1edf186d5803fbd744e063e34b · 2025-09-19
- Spring application test inventory
Core Spring test source inspected alongside the KYC integration contract test.
commit 609e7f567720ec1edf186d5803fbd744e063e34b · 2025-09-19
- Next.js web package
Next.js 16, React 19, TypeScript, Tailwind CSS, and the web-client test/build dependencies.
commit b7d62497452733894a6f42216ea83e767406b8f3 · 2025-09-19
- Next.js route composition
Public and role-gated route composition for customer, admin, teller, manager, and employee surfaces.
commit b7d62497452733894a6f42216ea83e767406b8f3 · 2025-09-19
- Next.js authentication provider
Browser token initialization, validation, logout, auth headers, and role state.
commit b7d62497452733894a6f42216ea83e767406b8f3 · 2025-09-19
- typed web API client
Configured API client that adds the browser bearer token to requests.
commit b7d62497452733894a6f42216ea83e767406b8f3 · 2025-09-19
- Next.js account creation flow
Role-aware account creation form, client-side deposit hints, API submission, and transaction-history navigation.
commit b7d62497452733894a6f42216ea83e767406b8f3 · 2025-09-19
- KYC upload boundary
Allowed upload categories, image content types, 10 MB limit, daily count limit, and authenticated ownership.
commit 609e7f567720ec1edf186d5803fbd744e063e34b · 2025-09-19
- KYC file access boundary
Owner/admin authorization before reading stored KYC bytes.
commit 609e7f567720ec1edf186d5803fbd744e063e34b · 2025-09-19
- KYC case service and submit controller
Distinct owned upload validation, case creation/reuse, consent submission, and status transitions.
commit 609e7f567720ec1edf186d5803fbd744e063e34b · 2025-09-19
- KYC status transitions
Explicit pending, auto-review, under-review, more-information, approved, and rejected transitions.
commit 609e7f567720ec1edf186d5803fbd744e063e34b · 2025-09-19
- KYC case persistence model
Case status, upload references, reviewer fields, processing flag, timestamps, and optimistic version field.
commit 609e7f567720ec1edf186d5803fbd744e063e34b · 2025-09-19
- KYC case repository
Status queries, candidate paging, and atomic processing-claim update.
commit 609e7f567720ec1edf186d5803fbd744e063e34b · 2025-09-19
- KYC upload entity
Upload category, checksum/path metadata, size, owner, and timestamp fields.
commit 609e7f567720ec1edf186d5803fbd744e063e34b · 2025-09-19
- KYC check entity
Per-check type, score, pass value, details JSON, case association, and timestamp.
commit 609e7f567720ec1edf186d5803fbd744e063e34b · 2025-09-19
- KYC auto-review orchestrator
Scheduled batch, bounded case claiming, file reads, FastAPI call, check persistence, decision mapping, and failure fallback.
commit 609e7f567720ec1edf186d5803fbd744e063e34b · 2025-09-19
- Spring to FastAPI KYC client
Aggregate request/response DTOs and `/api/v1/kyc/aggregate` WebClient call.
commit 609e7f567720ec1edf186d5803fbd744e063e34b · 2025-09-19
- KYC WebClient configuration
Configurable KYC base URL, connection/read timeouts, and maximum in-memory body size.
commit 609e7f567720ec1edf186d5803fbd744e063e34b · 2025-09-19
- KYC admin review boundary
Admin-only case listing, decision transitions, and check inspection.
commit 609e7f567720ec1edf186d5803fbd744e063e34b · 2025-09-19
- FastAPI KYC aggregate route
Component check composition, portrait fallback, thresholds, request IDs, calibration logging, and aggregate response.
commit 7e4beb846c65afc99966a6e4edc9dfd3c9311250 · 2025-09-19
- FastAPI KYC aggregate policy
Reason codes and APPROVE/UNDER_REVIEW/REJECT policy branches.
commit 7e4beb846c65afc99966a6e4edc9dfd3c9311250 · 2025-09-19
- FastAPI KYC configuration
Default thresholds, backend settings, portrait mode, and calibration-log configuration.
commit 7e4beb846c65afc99966a6e4edc9dfd3c9311250 · 2025-09-19
- FastAPI feature factory
Reviewed default feature construction for face, liveness, OCR, document classification, and portrait extraction.
commit 7e4beb846c65afc99966a6e4edc9dfd3c9311250 · 2025-09-19
- FastAPI KYC schemas
Input payload and aggregate/check response structures.
commit 7e4beb846c65afc99966a6e4edc9dfd3c9311250 · 2025-09-19
- Optional ONNX face module
ONNX/OpenCV face detection and matching implementation present in source but not treated as the default factory path.
commit 7e4beb846c65afc99966a6e4edc9dfd3c9311250 · 2025-09-19
- Optional ONNX liveness module
ONNX anti-spoof implementation and threshold handling present in source.
commit 7e4beb846c65afc99966a6e4edc9dfd3c9311250 · 2025-09-19
- Optional Tesseract OCR module
Tesseract preprocessing and structured field extraction implementation present in source.
commit 7e4beb846c65afc99966a6e4edc9dfd3c9311250 · 2025-09-19
- KYC calibration tooling
CSV grouping, labeled GOOD/BAD summaries, threshold suggestions, and estimated FAR/FRR calculation tooling; no completed report was found.
commit 7e4beb846c65afc99966a6e4edc9dfd3c9311250 · 2025-09-19
- FastAPI KYC test inventory
Aggregate and component smoke tests, portrait fallback/provided paths, and backend/test fixtures; inventory only for this portfolio record.
commit 7e4beb846c65afc99966a6e4edc9dfd3c9311250 · 2025-09-19
- Spring KYC contract test inventory
Contract fixture expectations for APPROVE, UNDER_REVIEW, and REJECT when a live ML service is available.
commit 609e7f567720ec1edf186d5803fbd744e063e34b · 2025-09-19
- bank-app Android build
Kotlin/Android, Compose, Retrofit, OkHttp logging, DataStore, Biometric, Camera, and Hilt dependencies.
commit 770afcff097a58cfadf2be47e4c71fca301ca8ac · 2025-09-17
- bank-app network module
Retrofit/OkHttp construction, bearer-token interceptor, unauthorized cleanup, timeouts, and API bindings.
commit 770afcff097a58cfadf2be47e4c71fca301ca8ac · 2025-09-17
- bank-app auth API and repository
Login, token persistence, validation, logout cleanup, and network/API failure mapping.
commit 770afcff097a58cfadf2be47e4c71fca301ca8ac · 2025-09-17
- bank-app account API/repository
Account opening, current-user account list, transaction-history retrieval, and typed error mapping.
commit 770afcff097a58cfadf2be47e4c71fca301ca8ac · 2025-09-17
- bank-app KYC API/repository
Multipart upload of four KYC image types, consented case submission, status, and check retrieval.
commit 770afcff097a58cfadf2be47e4c71fca301ca8ac · 2025-09-17
- bank-app token storage
AES/GCM token encryption, DataStore persistence, decryption, and clearing.
commit 770afcff097a58cfadf2be47e4c71fca301ca8ac · 2025-09-17
- bank-app Keystore encryption
Android Keystore AES key generation and GCM parameters used by token storage.
commit 770afcff097a58cfadf2be47e4c71fca301ca8ac · 2025-09-17
- bank-app wallet API/repository
Card sessions, QR/reload/bill payment intents, idempotency keys, and result mapping.
commit 770afcff097a58cfadf2be47e4c71fca301ca8ac · 2025-09-17
- bank-app payment state flow
Payment intent polling, bounded backoff, terminal states, and timeout behavior.
commit 770afcff097a58cfadf2be47e4c71fca301ca8ac · 2025-09-17
- bank-app test inventory
The audited repository contains the default unit and instrumented test templates; no feature-level acceptance is inferred.
commit 770afcff097a58cfadf2be47e4c71fca301ca8ac · 2025-09-17
- Spring wallet service
Server-side idempotency wrapper and PaymentIntent creation for QR, reload, and bill flows.
commit 609e7f567720ec1edf186d5803fbd744e063e34b · 2025-09-19
Repository enrichment
Mutable public facts are optional; the project identity above is portfolio-owned.
bank-core
Spring Boot authoritative banking backend
- Updated
- 4 Oct 2026
- Language
- Java
- Stars
- 0
- Forks
- 0
bank-web
Next.js web frontend
- Updated
- 3 Oct 2026
- Language
- TypeScript
- Stars
- 0
- Forks
- 0
bank-service
FastAPI AI/KYC service
- Updated
- 2 Oct 2026
- Language
- Python
- Stars
- 0
- Forks
- 0
bank-app
Kotlin/Android banking client
- Updated
- 4 Oct 2026
- Language
- Kotlin
- Stars
- 0
- Forks
- 0
Related case studies
Related Engineering Decisions
See the selected constraints, alternatives, and evidence behind this project's key boundaries.
Explore Banking Platform decisionsContent notes
- The curated slug is banking-platform; bank-core, bank-web, bank-service, and bank-app remain independently versioned source repositories.
- KYC thresholds and decision branches are source-backed policy evidence, not measured accuracy or false-rejection outcomes.