b2a16a8be7
- 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>
1.9 KiB
1.9 KiB
arc42, status
| arc42 | status |
|---|---|
| 7 — Deployment View | stub |
7.1 Hetzner Deployment Diagram
@startuml deploy
node "Hetzner CX22\n(2 vCPU, 4GB RAM, Ubuntu 24.04)" as hetzner {
component [Caddy\n:80, :443] as caddy
component [API Service\n:8000 (internal)] as api
component [Portal Service\n:8001 (internal)] as portal
component [Spider Service\n(no exposed port)] as spider
database [PostgreSQL 16\n:5432 (internal)] as db
folder "Hetzner Volume\n(20GB)" as vol
}
cloud "Internet" {
actor Agent
actor Registrant
}
cloud "Let's Encrypt" as le
Agent --> caddy : HTTPS :443
Registrant --> caddy : HTTPS :443
caddy --> api
caddy --> portal
caddy <--> le : ACME cert renewal
api --> db
spider --> db
db --> vol : data persistence
@enduml
7.2 Environment Table
| Setting | Dev | Prod (Hetzner) |
|---|---|---|
| TLS | None (HTTP only) | Auto via Caddy + Let's Encrypt |
| DB | postgres:16 local container | postgres:16 container, data on Hetzner volume |
| Spider interval | 2 min (fast feedback) | 15 min |
| API key | dev-key-insecure |
Strong random key, env var only |
| Log level | DEBUG | INFO |
| Port exposure | All ports exposed to host | Only :80, :443 via Caddy; all others internal |
7.3 Backup and Restore
backup.shruns via cron daily at 03:00 UTC- Executes
pg_dumpinto/backup/apix_$(date +%Y%m%d).sql.gz - Backup directory mounted on Hetzner volume (separate from DB data volume)
- Retain last 7 dumps; older files deleted by script
- Restore:
psql < apix_YYYYMMDD.sql.gz— documented ininfra/hetzner/RESTORE.md
7.4 Domain and DNS
TODO: Confirm domain name (OQ-MVP-01).
Planned DNS setup:
registry.apix.dev(orindex.botstandards.org) → Hetzner VPS IP (A record)- TTL: 300s initially for fast propagation during setup
Caddy will automatically obtain and renew the TLS certificate once the A record resolves to the server IP.