From 6e31373a6e537a6670e61e6d5fbf9f1d1cf2165b Mon Sep 17 00:00:00 2001 From: Andreas Dahm Date: Mon, 11 May 2026 14:40:29 +0200 Subject: [PATCH] Changed README.md --- readme.md | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 85277f7..4e4416f 100644 --- a/readme.md +++ b/readme.md @@ -34,7 +34,9 @@ The project strictly follows a Domain-Driven / Clean Architecture (Ports & Adapt * Implements the interfaces defined in the Domain layer. * **Rule:** Entities never leak into the API layer. -*Note: Future implementations will include ArchUnit tests to automatically enforce these architectural boundaries during the CI pipeline.* +Architectural boundaries are enforced via ArchUnit (`src/test/java/core_service/architecture/ArchitectureTest.java`), which runs as part of the standard `./mvnw test` quality gate. Abstract test bases live under `core_service.shared.test` (`AbstractUnitTest`, `AbstractIntegrationTest`, `AbstractPersistenceTest`, `AbstractWebMvcTest`, `AbstractArchitectureTest`). + +> **Core-specific structure note.** Unlike `auth-service`, Core keeps JPA `@Entity` classes in `..domain..` (rather than a separate `..persistence.entities..` package) and repository interfaces in `..repo..`. The ArchUnit rules are adapted to this layout. See "Roadmap / Open Topics" below for the planned tightening. ## ⚙️ Local Development @@ -79,4 +81,32 @@ Metrics and health checks are exposed out-of-the-box via Spring Boot Actuator: Health: http://localhost:8090/actuator/health -Prometheus Metrics: http://localhost:8090/actuator/prometheus \ No newline at end of file +Prometheus Metrics: http://localhost:8090/actuator/prometheus + +## 🗺️ Roadmap / Open Topics + +Tracking known work that is not yet implemented. Each item is independently actionable. + +### Architecture / ArchUnit follow-ups + +Currently active rules cover: cycles, controller→repository direction, repository naming, controller/service annotations, shared/configuration isolation, and a relaxed slice rule. The following rules are intentionally **not** yet enforced because they would fail today; addressing them is a separate refactor. + +- **Strict module independence.** `library` currently imports from `steam_adapter` (e.g. `SteamApiService`, response DTOs). The ArchUnit rule exempts that edge via `ignoreDependency(library.., steam_adapter..)`. Long-term: either move `steam_adapter` out of `modules` (into `core_service.adapters.steam` or `core_service.shared.steam`) to make its role as a shared outbound port explicit, then enable strict `notDependOnEachOther()` without exemptions. +- **"DTOs only in `..api..`" rule.** Steam adapter response records currently live in `..api.dto..` and are consumed by `library` services. Move them to `core_service.modules.steam_adapter.model` (or `.port`) so they read as domain types, not API DTOs, then re-enable the strict rule. +- **"Entities only in `..persistence..`" rule.** Skipped because Core mixes entities with the domain package. Decide whether to (a) accept that pattern and keep the rule off, or (b) split entities into `..repo.entity..` and re-enable the rule for consistency with `auth-service`. + +### Security + +- **Drop the shared `JWT_SECRET`.** Today both Auth and Core hold the same HMAC secret, which means a Core compromise lets an attacker forge tokens for Auth. Once Auth ships EdDSA signing (see Auth README roadmap), Core should hold only the **public key** (`JWT_PUBLIC_KEY`) and verify with `Jwts.parser().verifyWith(publicKey).build()`. Touches `JwtConfig` (rename `secret` → `publicKey`), `JwtService` (replace `Keys.hmacShaKeyFor` with `KeyFactory.getInstance("Ed25519")`), and the deployment env wiring. +- **Consume a JWKS endpoint** once Auth exposes one (`GET https://auth.tbp.andreas-dahm.eu/.well-known/jwks.json`). Cache keys at startup, refresh on `kid` miss. Avoids redeploying Core when keys rotate. +- **Add a `JwtServiceTest`.** No verification tests exist for Core's JWT parser today; adding one is also a natural place to add the EdDSA key fixture. + +### Testing + +- **First Steam adapter integration test.** `SteamApiServiceTest` is a unit test; an integration test with WireMock (or Spring's `MockRestServiceServer`) would lock in the contract with the external Steam API and the Resilience4j retry/rate-limit configuration. +- **Persistence-layer tests.** `library/repo/*Repository` has no `AbstractPersistenceTest`-based test today. Good first targets: `UserGameRepository`, `UserSteamSyncRepository`. +- **Controller WebMvc tests.** `LibraryController`, `PublicStatsController`, `SteamController` have no `AbstractWebMvcTest`-based tests yet. The Auth project's `*ControllerTest` classes are the pattern to follow. + +### CI + +- **Wire the ArchUnit + scaffolding into the existing Forgejo Actions quality gate.** `./mvnw verify` already runs them; confirm CI fails (not just warns) on architecture violations so drift is caught before merge. \ No newline at end of file