# chatok-jnr/legalaid-user-auth architecture

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

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

## Overview

1. **Service role and deployment boundary**  
   This repository is a single Spring Boot 3.2 microservice for the Legal Aid platform’s user authentication and profile domain. It exposes REST endpoints under `/api/v1` and runs as a standalone Java 21 application, packaged with Maven and deployable as a JAR or Docker container.

2. **Primary request flow**  
   Incoming HTTP requests enter the controller layer, are authenticated/authorized by Spring Security and a JWT filter, then delegated to service classes. Services orchestrate validation, token logic, persistence, and external uploads before returning DTO responses. Error handling is centralized so controllers stay thin.

3. **Security and identity subsystem**  
   The core security boundary is JWT-based authentication built on Spring Security 6. Access tokens are HS256-signed JWTs handled by `JwtService` and enforced by `JwtAuthenticationFilter`. `UserDetailsServiceImpl` bridges Spring Security to the user store. `SecurityConfig` and `CorsConfig` define the filter chain, role-based access control, and cross-origin policy.

4. **Authentication and session lifecycle**  
   `AuthController` and `AuthServiceImpl` implement registration, login, refresh, and “me” endpoints. The system uses BCrypt for password hashing, opaque UUID refresh tokens persisted in the database, and refresh-token rotation with reuse detection. `RefreshToken` is a first-class entity, so session state is not purely stateless JWT.

5. **User and role data model**  
   The shared identity model centers on `User`, `Role`, and `UserRole`, with `UserAddress` and `UserAddressId` for user-owned addresses. `UserRole` and `RoleRepository` support multi-role users such as CLIENT, LAWYER, and ADMIN. The model is relational and JPA-backed rather than document-based.

6. **Role-specific profile subsystems**  
   The repository separates profile management by audience: `ClientController` / `ClientService`, `LawyerController` / `LawyerService`, and `AdminController` / `AdminService`. Each role has its own entity package, DTOs, and repositories, which keeps client, lawyer, and admin data isolated while still anchored to the shared `User` identity.

7. **Address management subsystem**  
   `AddressController` and `UserAddressServiceImpl` manage authenticated users’ addresses. The presence of `UserAddress`, `UserAddressRepository`, and a composite ID indicates addresses are uniquely keyed per user and address type. This is a user-owned subdomain layered on top of the common identity model.

8. **Cloudinary integration boundary**  
   Lawyer document uploads are the only explicit external file-storage integration. `CloudinaryServiceImpl` and `CloudinaryConfig` wrap Cloudinary credentials and upload settings, and are used for lawyer profile document storage. This is a separate external I/O boundary from the core database-backed profile logic.

9. **Persistence layer**  
   All durable state lives in PostgreSQL through Spring Data JPA/Hibernate repositories. The repository package is split by domain: shared identity, refresh tokens, user addresses, and role-specific profile repositories. Projection interfaces in the lawyer repository suggest read-optimized queries for admin or profile views without loading full entity graphs.

10. **DTO and API contract layer**  
   Request and response payloads are kept in dedicated DTO packages, grouped by domain and by direction. This indicates the API contract is intentionally decoupled from entity shapes, which is important for protecting internal persistence structure and supporting PATCH-style partial updates.

11. **Error handling and response consistency**  
   `AuthExceptions` and `GlobalExceptionHandler` define the domain error boundary. The exception handler likely maps business failures into consistent API errors rather than exposing persistence or security internals directly. This is important for diagramming because it sits cross-cutting over all controllers and services.

12. **Operational and build context**  
   The project is Maven-based, uses `application.yml` plus environment variables for runtime configuration, and includes Docker and deployment scripts, which means it is designed to run consistently across local, container, and production environments. The tests cover auth, JWT, cloudinary, controller, and lawyer service paths, showing those are the most critical integration seams.

Main entry points: [`src/main/java/com/legalaid/userauth/repository`](https://github.com/chatok-jnr/legalaid-user-auth/tree/main/src/main/java/com/legalaid/userauth/repository) (Repositories), [`src/main/java/com/legalaid/userauth/UserAuthApplication.java`](https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/UserAuthApplication.java) (UserAuth App), [`src/main/java/com/legalaid/userauth/dto`](https://github.com/chatok-jnr/legalaid-user-auth/tree/main/src/main/java/com/legalaid/userauth/dto) (DTOs), [`src/main/java/com/legalaid/userauth/exception/GlobalExceptionHandler.java`](https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/exception/GlobalExceptionHandler.java) (Error Handler)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_group_platform["Platform"]
  node_node_app(("UserAuth App<br/>spring boot app"))
end

subgraph group_group_api["API"]
  node_node_auth_controller["Auth API<br/>rest controller"]
  node_node_client_controller["Client API<br/>rest controller"]
  node_node_lawyer_controller["Lawyer API<br/>rest controller"]
  node_node_admin_controller["Admin API<br/>rest controller"]
  node_node_address_controller["Address API<br/>rest controller"]
  node_node_dto_layer["DTOs<br/>api contract"]
end

subgraph group_group_security["Security"]
  node_node_security_config["Security Config"]
  node_node_jwt_filter["JWT Filter<br/>auth filter"]
  node_node_jwt_service["JWT Service<br/>token service<br/>[JwtService.java]"]
  node_node_userdetails["User Details<br/>security bridge"]
end

subgraph group_group_domain["Domain"]
  node_node_auth_service["Auth Service<br/>session service"]
  node_node_client_service["Client Service<br/>profile service"]
  node_node_lawyer_service["Lawyer Service<br/>profile service"]
  node_node_admin_service["Admin Service<br/>profile service"]
  node_node_address_service["Address Service"]
  node_node_shared_identity[("Identity Model<br/>jpa entities")]
  node_node_role_profiles[("Role Profiles<br/>jpa entities")]
end

subgraph group_group_persistence["Persistence"]
  node_node_repositories[("Repositories")]
end

subgraph group_group_external["External"]
  node_node_cloudinary_service["Cloudinary<br/>file upload"]
end

subgraph group_group_errors["Errors"]
  node_node_exception_handler["Error Handler<br/>exception mapping"]
end

node_node_app -->|"boots with"| node_node_security_config
node_node_app -->|"exposes"| node_node_auth_controller
node_node_app -->|"exposes"| node_node_client_controller
node_node_app -->|"exposes"| node_node_lawyer_controller
node_node_app -->|"exposes"| node_node_admin_controller
node_node_app -->|"exposes"| node_node_address_controller
node_node_auth_controller -->|"delegates to"| node_node_auth_service
node_node_client_controller -->|"delegates to"| node_node_client_service
node_node_lawyer_controller -->|"delegates to"| node_node_lawyer_service
node_node_admin_controller -->|"delegates to"| node_node_admin_service
node_node_address_controller -->|"delegates to"| node_node_address_service
node_node_auth_controller -.->|"errors mapped by"| node_node_exception_handler
node_node_client_controller -.->|"errors mapped by"| node_node_exception_handler
node_node_lawyer_controller -.->|"errors mapped by"| node_node_exception_handler
node_node_admin_controller -.->|"errors mapped by"| node_node_exception_handler
node_node_address_controller -.->|"errors mapped by"| node_node_exception_handler
node_node_security_config -->|"registers"| node_node_jwt_filter
node_node_security_config -->|"uses"| node_node_userdetails
node_node_jwt_filter -->|"validates with"| node_node_jwt_service
node_node_jwt_filter -->|"loads principal"| node_node_userdetails
node_node_auth_service -->|"issues tokens"| node_node_jwt_service
node_node_auth_service -->|"persists session data"| node_node_repositories
node_node_auth_service -->|"works with"| node_node_shared_identity
node_node_client_service -->|"persists profile"| node_node_repositories
node_node_client_service -->|"anchors on"| node_node_shared_identity
node_node_lawyer_service -->|"persists profile"| node_node_repositories
node_node_lawyer_service -->|"uploads via"| node_node_cloudinary_service
node_node_lawyer_service -->|"manages"| node_node_role_profiles
node_node_admin_service -->|"persists profile"| node_node_repositories
node_node_admin_service -->|"manages"| node_node_role_profiles
node_node_address_service -->|"persists addresses"| node_node_repositories
node_node_address_service -->|"anchors on"| node_node_shared_identity
node_node_repositories -->|"stores"| node_node_shared_identity
node_node_repositories -->|"stores"| node_node_role_profiles
node_node_dto_layer -.->|"contracts for"| node_node_auth_controller
node_node_dto_layer -.->|"contracts for"| node_node_client_controller
node_node_dto_layer -.->|"contracts for"| node_node_lawyer_controller
node_node_dto_layer -.->|"contracts for"| node_node_admin_controller
node_node_dto_layer -.->|"contracts for"| node_node_address_controller
node_node_cloudinary_service -.->|"supports"| node_node_repositories

click node_node_app "https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/UserAuthApplication.java"
click node_node_auth_controller "https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/controller/AuthController.java"
click node_node_client_controller "https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/controller/ClientController.java"
click node_node_lawyer_controller "https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/controller/LawyerController.java"
click node_node_admin_controller "https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/controller/AdminController.java"
click node_node_address_controller "https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/controller/AddressController.java"
click node_node_dto_layer "https://github.com/chatok-jnr/legalaid-user-auth/tree/main/src/main/java/com/legalaid/userauth/dto"
click node_node_security_config "https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/config/SecurityConfig.java"
click node_node_jwt_filter "https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/security/JwtAuthenticationFilter.java"
click node_node_jwt_service "https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/security/JwtService.java"
click node_node_userdetails "https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/security/UserDetailsServiceImpl.java"
click node_node_auth_service "https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/service/impl/AuthServiceImpl.java"
click node_node_client_service "https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/service/client/impl/ClientServiceImpl.java"
click node_node_lawyer_service "https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/service/lawyer/impl/LawyerServiceImpl.java"
click node_node_admin_service "https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/service/admin/impl/AdminServiceImpl.java"
click node_node_address_service "https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/service/impl/UserAddressServiceImpl.java"
click node_node_shared_identity "https://github.com/chatok-jnr/legalaid-user-auth/tree/main/src/main/java/com/legalaid/userauth/entity"
click node_node_role_profiles "https://github.com/chatok-jnr/legalaid-user-auth/tree/main/src/main/java/com/legalaid/userauth/entity"
click node_node_repositories "https://github.com/chatok-jnr/legalaid-user-auth/tree/main/src/main/java/com/legalaid/userauth/repository"
click node_node_cloudinary_service "https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/service/cloudinary/impl/CloudinaryServiceImpl.java"
click node_node_exception_handler "https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/exception/GlobalExceptionHandler.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_node_app,node_node_exception_handler toneBlue
class node_node_auth_controller,node_node_client_controller,node_node_lawyer_controller,node_node_admin_controller,node_node_address_controller,node_node_dto_layer toneAmber
class node_node_security_config,node_node_jwt_filter,node_node_jwt_service,node_node_userdetails toneMint
class node_node_auth_service,node_node_client_service,node_node_lawyer_service,node_node_admin_service,node_node_address_service,node_node_shared_identity,node_node_role_profiles toneRose
class node_node_repositories toneIndigo
class node_node_cloudinary_service toneTeal
```

## Components

### Platform

Application entrypoint and runtime configuration

- [UserAuth App](https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/UserAuthApplication.java): spring boot app · Standalone Java 21 Spring Boot service entrypoint · `src/main/java/com/legalaid/userauth/UserAuthApplication.java`

### API

REST controllers and DTO contracts

- [Auth API](https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/controller/AuthController.java): rest controller · Registration, login, refresh, and me endpoints · `src/main/java/com/legalaid/userauth/controller/AuthController.java`
- [Client API](https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/controller/ClientController.java): rest controller · Client profile endpoints · `src/main/java/com/legalaid/userauth/controller/ClientController.java`
- [Lawyer API](https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/controller/LawyerController.java): rest controller · Lawyer profile and credential endpoints · `src/main/java/com/legalaid/userauth/controller/LawyerController.java`
- [Admin API](https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/controller/AdminController.java): rest controller · Admin management endpoints · `src/main/java/com/legalaid/userauth/controller/AdminController.java`
- [Address API](https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/controller/AddressController.java): rest controller · Authenticated address endpoints · `src/main/java/com/legalaid/userauth/controller/AddressController.java`
- [DTOs](https://github.com/chatok-jnr/legalaid-user-auth/tree/main/src/main/java/com/legalaid/userauth/dto): api contract · Request and response payloads separated from entities · `src/main/java/com/legalaid/userauth/dto`

### Security

JWT authentication and Spring Security boundary

- [Security Config](https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/config/SecurityConfig.java): security config · Filter chain, CORS, and authorization rules · `src/main/java/com/legalaid/userauth/config/SecurityConfig.java`
- [JWT Filter](https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/security/JwtAuthenticationFilter.java): auth filter · Extracts and validates bearer tokens on requests · `src/main/java/com/legalaid/userauth/security/JwtAuthenticationFilter.java`
- [JWT Service](https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/security/JwtService.java): token service · Creates and validates HS256 access tokens · `src/main/java/com/legalaid/userauth/security/JwtService.java`
- [User Details](https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/security/UserDetailsServiceImpl.java): security bridge · Adapts stored users to Spring Security · `src/main/java/com/legalaid/userauth/security/UserDetailsServiceImpl.java`

### Domain

Identity, profile, and session models

- [Auth Service](https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/service/impl/AuthServiceImpl.java): session service · Registration, login, refresh rotation, and current-user logic · `src/main/java/com/legalaid/userauth/service/impl/AuthServiceImpl.java`
- [Client Service](https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/service/client/impl/ClientServiceImpl.java): profile service · Client profile orchestration · `src/main/java/com/legalaid/userauth/service/client/impl/ClientServiceImpl.java`
- [Lawyer Service](https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/service/lawyer/impl/LawyerServiceImpl.java): profile service · Lawyer profile, credentials, and document flow · `src/main/java/com/legalaid/userauth/service/lawyer/impl/LawyerServiceImpl.java`
- [Admin Service](https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/service/admin/impl/AdminServiceImpl.java): profile service · Admin profile and action management · `src/main/java/com/legalaid/userauth/service/admin/impl/AdminServiceImpl.java`
- [Address Service](https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/service/impl/UserAddressServiceImpl.java): address service · User-owned address management · `src/main/java/com/legalaid/userauth/service/impl/UserAddressServiceImpl.java`
- [Identity Model](https://github.com/chatok-jnr/legalaid-user-auth/tree/main/src/main/java/com/legalaid/userauth/entity): jpa entities · User, role, user-role, refresh token, and address entities · `src/main/java/com/legalaid/userauth/entity`
- [Role Profiles](https://github.com/chatok-jnr/legalaid-user-auth/tree/main/src/main/java/com/legalaid/userauth/entity): jpa entities · Client, lawyer, and admin profile entities · `src/main/java/com/legalaid/userauth/entity`

### Persistence

JPA repositories and stored state

- [Repositories](https://github.com/chatok-jnr/legalaid-user-auth/tree/main/src/main/java/com/legalaid/userauth/repository): jpa repositories · Spring Data persistence for users, tokens, addresses, and role profiles · `src/main/java/com/legalaid/userauth/repository`

### External

Third-party integration boundary

- [Cloudinary](https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/service/cloudinary/impl/CloudinaryServiceImpl.java): file upload · External document upload integration for lawyer profiles · `src/main/java/com/legalaid/userauth/service/cloudinary/impl/CloudinaryServiceImpl.java`

### Errors

Centralized exception mapping

- [Error Handler](https://github.com/chatok-jnr/legalaid-user-auth/blob/main/src/main/java/com/legalaid/userauth/exception/GlobalExceptionHandler.java): exception mapping · Converts domain and auth failures into API errors · `src/main/java/com/legalaid/userauth/exception/GlobalExceptionHandler.java`

## Connections

- UserAuth App → Security Config: boots with · Application starts with security and web configuration
- UserAuth App → Auth API: exposes · Primary authentication REST surface
- UserAuth App → Client API: exposes · Client profile REST surface
- UserAuth App → Lawyer API: exposes · Lawyer profile REST surface
- UserAuth App → Admin API: exposes · Admin management REST surface
- UserAuth App → Address API: exposes · Address management REST surface
- Auth API → Auth Service: delegates to · Thin controller hands off auth logic
- Client API → Client Service: delegates to · Client endpoints route to service layer
- Lawyer API → Lawyer Service: delegates to · Lawyer endpoints route to service layer
- Admin API → Admin Service: delegates to · Admin endpoints route to service layer
- Address API → Address Service: delegates to · Address endpoints route to service layer
- Auth API → Error Handler: errors mapped by · Auth errors are normalized centrally
- Client API → Error Handler: errors mapped by · Client errors are normalized centrally
- Lawyer API → Error Handler: errors mapped by · Lawyer errors are normalized centrally
- Admin API → Error Handler: errors mapped by · Admin errors are normalized centrally
- Address API → Error Handler: errors mapped by · Address errors are normalized centrally
- Security Config → JWT Filter: registers · Security chain includes JWT request filtering
- Security Config → User Details: uses · Security config relies on user lookup bridge
- JWT Filter → JWT Service: validates with · Bearer token parsing and verification
- JWT Filter → User Details: loads principal · Filter resolves authenticated user details
- Auth Service → JWT Service: issues tokens · Access tokens are generated and validated here
- Auth Service → Repositories: persists session data · Uses user and refresh-token repositories
- Auth Service → Identity Model: works with · Operates on users, roles, and refresh tokens
- Client Service → Repositories: persists profile · Stores client profile state
- Client Service → Identity Model: anchors on · Client profile is attached to shared identity
- Lawyer Service → Repositories: persists profile · Stores lawyer profile and credential state
- Lawyer Service → Cloudinary: uploads via · Lawyer documents are sent to external storage
- Lawyer Service → Role Profiles: manages · Operates on lawyer-specific profile entities
- Admin Service → Repositories: persists profile · Stores admin profile and audit state
- Admin Service → Role Profiles: manages · Operates on admin-specific profile entities
- Address Service → Repositories: persists addresses · Uses composite-key address repository
- Address Service → Identity Model: anchors on · Addresses belong to the authenticated user
- Repositories → Identity Model: stores · User, role, refresh token, and address persistence
- Repositories → Role Profiles: stores · Client, lawyer, and admin profile persistence
- DTOs → Auth API: contracts for · Auth payloads define API request and response shapes
- DTOs → Client API: contracts for · Client payloads define API request and response shapes
- DTOs → Lawyer API: contracts for · Lawyer payloads define API request and response shapes
- DTOs → Admin API: contracts for · Admin payloads define API request and response shapes
- DTOs → Address API: contracts for · Address payloads define API request and response shapes
- Cloudinary → Repositories: supports · Uploads complement persisted lawyer profile data
