Files
apix-mvp/docs/arc42/04-solution-strategy.md
Carsten Rehfeld b2a16a8be7 Implement apix-registry with IoT sunset/decommission lifecycle and full BDD suite
- REST API: register, patch, O-level, replacements, history, search endpoints
- IoT lifecycle validations: future sunset, lock-before-release, sunset-passed-before-decommission
- DB schema: Liquibase changesets 001–008 (services, versions, replacements, sunset-at column)
- @ColumnTransformer(write="?::jsonb") on bsm_payload fields to avoid JDBC varchar→jsonb rejection
- Jandex plugin on apix-common + quarkus.index-dependency so @NotBlank validators resolve at runtime
- quarkus-logging-json extension added; quarkus.log.console.json=false is now a recognised key
- Fix requireSunsetBeforeLockRelease: Boolean.TRUE.equals instead of !Boolean.FALSE.equals (null guard)
- BDD suite: 27 scenarios / 213 steps across 5 feature files (sunset-lock, decommission, replacement, discovery, anonymity)
- Test infrastructure: JDBC TRUNCATE in @Before for DB isolation, Arc.container() for clock control — no test endpoints in production code
- sunsetAt truncated to microseconds in BDD steps to match Postgres timestamptz precision
- Cucumber step fixes: singular/plural candidate(s), lastResponse propagation in replacementsReturnsNCandidates

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 09:13:26 +02:00

4.0 KiB
Raw Permalink Blame History

arc42, status
arc42 status
4 — Solution Strategy 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 ~5080MB 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