--- arc42: "4 — Solution Strategy" status: stub --- ## 4.1 Technology Decisions | Decision | Choice | Rationale | |---|---|---| | Language + framework | Java 21 + Quarkus 3.x | Compile-time safety; purpose-built for microservices; GraalVM native image first-class (see ADR-001) | | Production binary | GraalVM Native Image | ~50–80MB RAM per service; ~100ms startup; fits Hetzner CX22 with headroom | | Dev loop | `quarkus dev` (JVM mode) | Live reload + continuous testing; native build only for production image | | Persistence | Hibernate ORM + Panache | Standard Quarkus persistence; Panache active record reduces boilerplate | | BSM payload | PostgreSQL JSONB + `@JdbcTypeCode(SqlTypes.JSON)` | Flexible schema for optional BSM fields without a separate document store | | Migrations | Liquibase | User's existing tool; first-class Quarkus extension; rollback + context support (see ADR-008) | | Reverse proxy | Caddy | Auto-TLS with Let's Encrypt; minimal config (see ADR-003) | | Portal rendering | HTMX + Qute | No JS build pipeline; type-safe templates (build-time error on missing variables); idiomatic Quarkus (see ADR-004) | | Spider concurrency | Java 21 virtual threads (`@RunOnVirtualThread`) | Non-blocking HTTP checks without reactive programming complexity | | HTTP client (Spider) | Quarkus REST Client Reactive | Declarative; integrates with Quarkus DI and fault tolerance extensions | | Build tool | Maven 3.9 | Quarkus documentation is Maven-first; Quarkus Maven plugin handles native build | | Testing | JUnit 5 + `@QuarkusTest` + RestAssured + WireMock | `@QuarkusTest` starts real application context; RestAssured for HTTP assertions; WireMock for external API mocks | ## 4.2 Architectural Patterns | Pattern | Application | |---|---| | HATEOAS | `IndexResource` returns all navigation links; agents navigate from root without prior knowledge | | Repository pattern | DB access in `ServiceRepository` (Panache); business logic in `RegistryService`; resources are thin | | Compile-time DI | Quarkus CDI resolves all injection at build time; no runtime reflection surprises | | Scheduler-based Spider | `@Scheduled(every="15m")` on `SpiderScheduler`; stateless per run; virtual threads for concurrent checks | | Verification pipeline | Sequential O-level elevation (O-1 → sanctions → O-2 → O-3); each step is an independent CDI bean | | API key on writes | Single shared key for MVP via custom Quarkus Security identity provider; per-registrant keys post-MVP | | Fail-fast validation | BSM validated at boundary via Bean Validation (`@Valid` on JAX-RS resource); invalid BSM rejected with 400 + constraint violation details | ## 4.3 Quality Goal → Decision Mapping | Quality Goal | Architecture Decision | |---|---| | Compile-time safety | Quarkus CDI + Bean Validation + Qute type-safe templates — errors at build time, not runtime | | Queryability | HATEOAS root + capability search; JPQL + JSONB operator query in ServiceRepository | | Liveness accuracy | SpiderScheduler every 15 min; `last_checked_at` + `uptime_30d_percent` exposed in response | | Registration reliability | Idempotent `UPSERT` on endpoint URL; Liquibase migrations with rollback support | | Security hygiene | HTTPS via Caddy; API key on write endpoints; no PII in logs; non-root container user | | Solo maintainability | Docker Compose; `quarkus dev` for local loop; single JVM language across all services | ## 4.4 MVP Shortcuts (Accepted Technical Debt) | Shortcut | Exit Path | |---|---| | O-4 / O-5 assigned manually | Accredited Verifier integration post-MVP | | Single shared API key | Per-registrant key management + OAuth2 post-MVP | | No rate limiting on read endpoints | Caddy rate_limit directive when traffic warrants | | OpenAPI / MCP parsers validate presence only | Field-level spec comparison in Spider post-MVP | | Single-region deployment | Hetzner multi-region + Managed Database post-funding | | No billing | Commercial tier in Phase 2 | | No CI/CD pipeline | GitHub Actions native build pipeline post-MVP |