# chatok-jnr/legalaid-backend architecture

> Architecture diagram of the GitHub repository chatok-jnr/legalaid-backend, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-30). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/chatok-jnr/legalaid-backend
- Repository: https://github.com/chatok-jnr/legalaid-backend

## Overview

1. This repository is a backend-only Spring Boot 3.3 application written in Java 21. It is organized as a modular monolith: one deployable process, with business areas split into separate packages under `com.legalaid`.

2. The request entrypoint is the REST API layer. Each feature package has a `*Controller` that accepts HTTP requests, delegates to a `*Service`, and persists through Spring Data JPA repositories. DTOs are used at the boundary so API shapes stay separate from database entities.

3. Cross-cutting infrastructure lives in `config/` and `common/`. `SecurityConfig`, `JwtConfig`, `JwtAuthFilter`, `CorsConfig`, and `CloudinaryConfig` define authentication, CORS, token handling, and external storage wiring. `GlobalExceptionHandler` and `ApiResponse` standardize error and success responses across all endpoints.

4. Authentication is centered in `auth/`. The flow supports Google OAuth token exchange, JWT issuance, token refresh, and logout. `JwtAuthFilter` protects private routes, while `AuthService`, `GoogleOAuthService`, and `JwtService` handle identity verification and token lifecycle. This is the main security boundary before requests reach domain services.

5. User identity and roles are modeled separately in `user/`. `User`, `UserRole`, and `UserService` represent platform accounts and role-based state. This package is the base layer that other domains build on, since lawyer, client, and admin behavior all depend on the current authenticated user.

6. Lawyer management is a distinct domain in `lawyer/`. It contains the core lawyer profile plus specialized sub-entities for availability, courts, languages, locations, practice areas, and verification documents. This package supports onboarding, verification, public profile viewing, and lawyer statistics.

7. Service listings are handled in `service/`. `LegalService` and related entities such as `ServiceMedia`, `ServiceFeature`, `ServiceFaq`, and `ServiceHighlight` represent the marketplace offering a lawyer publishes. The structure suggests a rich listing model with media and metadata rather than a simple title/description record.

8. Contracting is its own bounded context in `contract/`. `Contract`, `ContractMilestone`, status enums, and repositories model the hire flow between client and lawyer. The README’s state-machine behavior is reflected here: contracts move through pending, active, completed, cancelled, and escrow-related states, and milestones are tracked separately from the contract header.

9. Case management lives in `case_/`. `LegalCase` is the core case record, with supporting entities for access control, milestones, and tags. This package is important because it defines collaborative legal work: access grants, editor/owner rules, and case-level milestone tracking.

10. Documents are isolated in `document/` and are backed by Cloudinary rather than stored locally. `DocumentService` and `CloudinaryService` handle upload and metadata persistence, while `DocumentRepository` stores references in PostgreSQL. This creates a clear split between binary storage in Cloudinary and structured metadata in the database.

11. Payments are modeled in `payment/` with both client-side payments and lawyer payouts. `Payment`, `Payout`, their status enums, and related DTOs support escrow-like transaction handling, manual verification, release, and withdrawal flows. The backend is the source of truth for payment state; external bKash interaction is represented as submitted transaction IDs plus admin verification.

12. Notifications are a separate domain in `notification/`. The package includes paginated listing, unread counts, read state updates, and deletion. Architecturally, notifications act as a platform-side side effect of other business actions such as contract updates, payments, or case changes.

13. Persistence is PostgreSQL-centric throughout. Nearly every domain has a repository package using Spring Data JPA, which means the application keeps business rules in services and uses the database as the durable system of record for users, listings, contracts, cases, payments, and documents.

14. The most important runtime flow is: HTTP request → Spring Security/JWT filter → controller → service → repository → PostgreSQL or Cloudinary → DTO response. That flow is consistent across the modules, making the repo a good candidate for an architecture diagram with a shared infrastructure layer and multiple domain boxes beneath it.

15. Testing is lightweight and focused on core service behavior. The repository includes JUnit tests for auth, JWT, and user services, plus a Spring Boot context test. Build and execution are Maven-based via the wrapper scripts, and configuration is driven from `application.yaml` and test resources.

Main entry points: [`src/main/java/com/legalaid/config/SecurityConfig.java`](https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/config/SecurityConfig.java) (Security), [`src/main/java/com/legalaid/auth/AuthService.java`](https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/auth/AuthService.java) (Auth service), [`src/main/java/com/legalaid/document/DocumentService.java`](https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/document/DocumentService.java) (Document service), [`src/main/java/com/legalaid/auth/AuthController.java`](https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/auth/AuthController.java) (Auth API)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_bootstrap["Bootstrap"]
  node_backend_app(("App<br/>Spring Boot entrypoint"))
end

subgraph group_infra["Infrastructure"]
  node_security_config["Security"]
  node_jwt_filter["JWT filter<br/>request filter<br/>[JwtAuthFilter.java]"]
  node_jwt_config["JWT config<br/>token config<br/>[JwtConfig.java]"]
  node_cors_config["CORS config<br/>web config<br/>[CorsConfig.java]"]
  node_global_errors["Errors<br/>exception handler"]
  node_api_response["Response<br/>[ApiResponse.java]"]
  node_oauth_service["Google OAuth<br/>oauth client"]
  node_jwt_service["JWT service<br/>token service<br/>[JwtService.java]"]
end

subgraph group_domains["Business domains"]
  node_auth_controller["Auth API<br/>REST controller"]
  node_auth_service["Auth service<br/>identity service<br/>[AuthService.java]"]
  node_user_controller["User API<br/>REST controller"]
  node_user_service["User service<br/>account service<br/>[UserService.java]"]
  node_lawyer_controller["Lawyer API<br/>REST controller"]
  node_lawyer_service["Lawyer service<br/>profile service<br/>[LawyerService.java]"]
  node_service_controller["Service API<br/>REST controller"]
  node_service_service["Service service<br/>listing service"]
  node_contract_controller["Contract API<br/>REST controller"]
  node_contract_service["Contract service<br/>workflow service"]
  node_case_controller["Case API<br/>REST controller"]
  node_case_service["Case service<br/>collaboration service<br/>[CaseService.java]"]
  node_document_controller["Document API<br/>REST controller"]
  node_document_service["Document service<br/>file service"]
  node_payment_controller["Payment API<br/>REST controller"]
  node_payment_service["Payment service<br/>transaction service"]
  node_notification_controller["Notify API<br/>REST controller"]
  node_notification_service["Notify service<br/>notification service"]
end

subgraph group_external["External systems"]
  node_cloudinary_service["Cloudinary<br/>storage adapter"]
  node_postgres[("PostgreSQL<br/>database")]
  node_cloudinary[("Cloudinary<br/>object storage")]
end

node_backend_app -->|"boots"| node_security_config
node_security_config -->|"uses"| node_jwt_filter
node_security_config -->|"reads"| node_jwt_config
node_security_config -->|"applies"| node_cors_config
node_auth_controller -->|"delegates"| node_auth_service
node_auth_service -->|"verifies"| node_oauth_service
node_auth_service -->|"issues"| node_jwt_service
node_jwt_filter -->|"validates"| node_jwt_service
node_auth_controller -->|"returns"| node_api_response
node_user_controller -->|"delegates"| node_user_service
node_user_service -->|"persists"| node_postgres
node_lawyer_controller -->|"delegates"| node_lawyer_service
node_lawyer_service -->|"persists"| node_postgres
node_service_controller -->|"delegates"| node_service_service
node_service_service -->|"persists"| node_postgres
node_contract_controller -->|"delegates"| node_contract_service
node_contract_service -->|"persists"| node_postgres
node_case_controller -->|"delegates"| node_case_service
node_case_service -->|"persists"| node_postgres
node_document_controller -->|"delegates"| node_document_service
node_document_service -->|"uploads"| node_cloudinary_service
node_document_service -->|"persists"| node_postgres
node_cloudinary_service -->|"stores"| node_cloudinary
node_payment_controller -->|"delegates"| node_payment_service
node_payment_service -->|"persists"| node_postgres
node_notification_controller -->|"delegates"| node_notification_service
node_notification_service -->|"persists"| node_postgres
node_global_errors -->|"standardizes"| node_api_response

click node_backend_app "https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/BackendApplication.java"
click node_security_config "https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/config/SecurityConfig.java"
click node_jwt_filter "https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/auth/JwtAuthFilter.java"
click node_jwt_config "https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/config/JwtConfig.java"
click node_cors_config "https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/config/CorsConfig.java"
click node_global_errors "https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/common/exception/GlobalExceptionHandler.java"
click node_api_response "https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/common/response/ApiResponse.java"
click node_auth_controller "https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/auth/AuthController.java"
click node_auth_service "https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/auth/AuthService.java"
click node_user_controller "https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/user/UserController.java"
click node_user_service "https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/user/UserService.java"
click node_lawyer_controller "https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/lawyer/LawyerController.java"
click node_lawyer_service "https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/lawyer/LawyerService.java"
click node_service_controller "https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/service/ServiceController.java"
click node_service_service "https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/service/ServiceService.java"
click node_contract_controller "https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/contract/ContractController.java"
click node_contract_service "https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/contract/ContractService.java"
click node_case_controller "https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/case_/CaseController.java"
click node_case_service "https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/case_/CaseService.java"
click node_document_controller "https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/document/DocumentController.java"
click node_document_service "https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/document/DocumentService.java"
click node_payment_controller "https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/payment/PaymentController.java"
click node_payment_service "https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/payment/PaymentService.java"
click node_notification_controller "https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/notification/NotificationController.java"
click node_notification_service "https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/notification/NotificationService.java"
click node_oauth_service "https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/auth/GoogleOAuthService.java"
click node_jwt_service "https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/auth/JwtService.java"
click node_cloudinary_service "https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/document/CloudinaryService.java"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_backend_app toneBlue
class node_security_config,node_jwt_filter,node_jwt_config,node_cors_config,node_global_errors,node_api_response,node_oauth_service,node_jwt_service toneAmber
class node_auth_controller,node_auth_service,node_user_controller,node_user_service,node_lawyer_controller,node_lawyer_service,node_service_controller,node_service_service,node_contract_controller,node_contract_service,node_case_controller,node_case_service,node_document_controller,node_document_service,node_payment_controller,node_payment_service,node_notification_controller,node_notification_service toneMint
class node_cloudinary_service,node_postgres,node_cloudinary toneRose
```

## Components

### Bootstrap

Application entrypoint and startup wiring

- [App](https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/BackendApplication.java): Spring Boot entrypoint · Main application bootstrap and component scan · `src/main/java/com/legalaid/BackendApplication.java`

### Infrastructure

Security, shared responses, and external integrations

- [Security](https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/config/SecurityConfig.java): Spring security config · HTTP security, auth boundaries, and filter chain setup · `src/main/java/com/legalaid/config/SecurityConfig.java`
- [JWT filter](https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/auth/JwtAuthFilter.java): request filter · Authenticates protected requests before controllers run · `src/main/java/com/legalaid/auth/JwtAuthFilter.java`
- [JWT config](https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/config/JwtConfig.java): token config · JWT token settings and signing parameters · `src/main/java/com/legalaid/config/JwtConfig.java`
- [CORS config](https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/config/CorsConfig.java): web config · Cross-origin policy for the API · `src/main/java/com/legalaid/config/CorsConfig.java`
- [Errors](https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/common/exception/GlobalExceptionHandler.java): exception handler · Centralized API exception mapping · `src/main/java/com/legalaid/common/exception/GlobalExceptionHandler.java`
- [Response](https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/common/response/ApiResponse.java): response wrapper · Shared success and error payload shape · `src/main/java/com/legalaid/common/response/ApiResponse.java`
- [Google OAuth](https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/auth/GoogleOAuthService.java): oauth client · Verifies Google token exchange for sign-in · `src/main/java/com/legalaid/auth/GoogleOAuthService.java`
- [JWT service](https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/auth/JwtService.java): token service · Issues and validates JWTs · `src/main/java/com/legalaid/auth/JwtService.java`

### Business domains

Feature packages exposed through REST controllers and services

- [Auth API](https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/auth/AuthController.java): REST controller · Login, token refresh, logout, and OAuth exchange endpoints · `src/main/java/com/legalaid/auth/AuthController.java`
- [Auth service](https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/auth/AuthService.java): identity service · Coordinates OAuth verification and JWT lifecycle · `src/main/java/com/legalaid/auth/AuthService.java`
- [User API](https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/user/UserController.java): REST controller · Current user and profile endpoints · `src/main/java/com/legalaid/user/UserController.java`
- [User service](https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/user/UserService.java): account service · Manages platform accounts and roles · `src/main/java/com/legalaid/user/UserService.java`
- [Lawyer API](https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/lawyer/LawyerController.java): REST controller · Lawyer onboarding, profile, and verification endpoints · `src/main/java/com/legalaid/lawyer/LawyerController.java`
- [Lawyer service](https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/lawyer/LawyerService.java): profile service · Coordinates lawyer profiles, availability, and verification · `src/main/java/com/legalaid/lawyer/LawyerService.java`
- [Service API](https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/service/ServiceController.java): REST controller · Marketplace service listing endpoints · `src/main/java/com/legalaid/service/ServiceController.java`
- [Service service](https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/service/ServiceService.java): listing service · Manages legal service listings and metadata · `src/main/java/com/legalaid/service/ServiceService.java`
- [Contract API](https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/contract/ContractController.java): REST controller · Contract creation and lifecycle endpoints · `src/main/java/com/legalaid/contract/ContractController.java`
- [Contract service](https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/contract/ContractService.java): workflow service · Handles hiring flow, contract states, and milestones · `src/main/java/com/legalaid/contract/ContractService.java`
- [Case API](https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/case_/CaseController.java): REST controller · Case management and access control endpoints · `src/main/java/com/legalaid/case_/CaseController.java`
- [Case service](https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/case_/CaseService.java): collaboration service · Manages cases, access grants, tags, and milestones · `src/main/java/com/legalaid/case_/CaseService.java`
- [Document API](https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/document/DocumentController.java): REST controller · Document upload and management endpoints · `src/main/java/com/legalaid/document/DocumentController.java`
- [Document service](https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/document/DocumentService.java): file service · Persists document metadata and coordinates Cloudinary uploads · `src/main/java/com/legalaid/document/DocumentService.java`
- [Payment API](https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/payment/PaymentController.java): REST controller · Payment recording, invoice, and payout endpoints · `src/main/java/com/legalaid/payment/PaymentController.java`
- [Payment service](https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/payment/PaymentService.java): transaction service · Tracks payment and payout state · `src/main/java/com/legalaid/payment/PaymentService.java`
- [Notify API](https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/notification/NotificationController.java): REST controller · Notification list and read-state endpoints · `src/main/java/com/legalaid/notification/NotificationController.java`
- [Notify service](https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/notification/NotificationService.java): notification service · Creates and manages user notifications · `src/main/java/com/legalaid/notification/NotificationService.java`

### External systems

Durable storage and third-party services

- [Cloudinary](https://github.com/chatok-jnr/legalaid-backend/blob/main/src/main/java/com/legalaid/document/CloudinaryService.java): storage adapter · Uploads and retrieves file assets from Cloudinary · `src/main/java/com/legalaid/document/CloudinaryService.java`
- **PostgreSQL**: database · System of record for all domain entities
- **Cloudinary**: object storage · External binary storage for documents and media

## Connections

- App → Security: boots · Application startup wires security and web infrastructure
- Security → JWT filter: uses · Security chain includes JWT authentication
- Security → JWT config: reads · Security depends on token settings
- Security → CORS config: applies · Security exposes configured cross-origin policy
- Auth API → Auth service: delegates · REST auth endpoints delegate to identity workflows
- Auth service → Google OAuth: verifies · Google OAuth token exchange and identity verification
- Auth service → JWT service: issues · Creates and refreshes JWTs
- JWT filter → JWT service: validates · Filter checks bearer tokens before routing
- Auth API → Response: returns · Auth endpoints use shared response shapes
- User API → User service: delegates · User endpoints delegate to account logic
- User service → PostgreSQL: persists · User accounts and roles are stored in the database
- Lawyer API → Lawyer service: delegates · Lawyer endpoints coordinate onboarding and profile reads
- Lawyer service → PostgreSQL: persists · Lawyer profile and verification data are stored in the database
- Service API → Service service: delegates · Service listing endpoints delegate to marketplace logic
- Service service → PostgreSQL: persists · Listing data and metadata are stored in the database
- Contract API → Contract service: delegates · Contract API routes enter the hiring workflow
- Contract service → PostgreSQL: persists · Contracts and milestones are stored in the database
- Case API → Case service: delegates · Case endpoints manage collaborative legal work
- Case service → PostgreSQL: persists · Cases, access grants, and tags are stored in the database
- Document API → Document service: delegates · Document endpoints handle upload and metadata operations
- Document service → Cloudinary: uploads · Binary files are sent to Cloudinary
- Document service → PostgreSQL: persists · Document metadata is stored in the database
- Cloudinary → Cloudinary: stores · Cloudinary is the external binary store
- Payment API → Payment service: delegates · Payment endpoints manage transactions and payouts
- Payment service → PostgreSQL: persists · Payment and payout state are stored in the database
- Notify API → Notify service: delegates · Notification endpoints handle inbox operations
- Notify service → PostgreSQL: persists · Notification state is stored in the database
- Errors → Response: standardizes · Exceptions are normalized into the shared response envelope
