From e3433799f113ddc27814099b6f1815c805e7c0ff Mon Sep 17 00:00:00 2001 From: lobo Date: Sat, 26 Sep 2026 07:37:44 +0200 Subject: [PATCH] docs(readme): add the architecture overview --- readme.md | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/readme.md b/readme.md index 0a61f4b..1880881 100644 --- a/readme.md +++ b/readme.md @@ -66,12 +66,40 @@ layers: | Layer | Package | Rule | |---|---|---| | API | `api` | REST controllers, request/response records, `ApiMapper`. Calls services, never repositories. | -| Domain | `model`, `service`, `exception` | Plain Java models and business logic. No dependency on API or persistence. | +| Domain | `model`, `service`, `exception` | Plain Java models and business logic. Uses repositories, never API classes, entities or `EntityMapper`. | | Persistence | `persistence` | JPA entities, Spring Data repositories, `EntityMapper`. Entities never reach the API layer. | +`profile` and `stats` only read data. They have no entities and use `JdbcTemplate` queries in a `repo` package. + ArchUnit enforces these rules in `src/test/java/auth_service/architecture/ArchitectureTest.java`, so a layer -violation fails the build. Test base classes (`AbstractUnitTest`, `AbstractWebMvcTest`, `AbstractPersistenceTest`, -`AbstractIntegrationTest`) live in `auth_service.shared.test`; all integration tests share one PostgreSQL container. +violation fails the build. It also keeps the modules independent of each other and free of cycles. Test base +classes (`AbstractUnitTest`, `AbstractWebMvcTest`, `AbstractPersistenceTest`, `AbstractIntegrationTest`) live in +`auth_service.shared.test`; all integration tests share one PostgreSQL container. + +### Login flow + +```mermaid +sequenceDiagram + participant B as Browser (Frontend) + participant A as Auth + participant C as Core + B->>A: POST /api/auth/login + A-->>B: Set-Cookie tbp_access (15 min), tbp_refresh (30 days, path /api/auth) + B->>C: API call with tbp_access + C->>A: GET /.well-known/jwks.json (new kid only) + A-->>C: Public keys (Ed25519) + C-->>B: 200, or 401 when the access token expired + B->>A: POST /api/auth/refresh with tbp_refresh + A-->>B: New tbp_access and tbp_refresh, old refresh token rotated + B->>C: Same API call again +``` + +1. `LoginService` checks the password. `LoginController` sets both HttpOnly cookies (`AuthCookies`), so no script + can read them. +2. Core verifies the access token with Auth's public keys only. `JwksController` publishes them; Core loads them + again only for an unknown `kid`. +3. On a `401` the frontend calls `POST /api/auth/refresh` once and sends the request again. + `RefreshTokenService` replaces the refresh token. A replaced token that comes back revokes the whole login. ## Run locally