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>
66 lines
1.9 KiB
Markdown
66 lines
1.9 KiB
Markdown
---
|
|
arc42: "7 — Deployment View"
|
|
status: stub
|
|
---
|
|
|
|
## 7.1 Hetzner Deployment Diagram
|
|
|
|
```plantuml
|
|
@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.sh` runs via cron daily at 03:00 UTC
|
|
- Executes `pg_dump` into `/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 in `infra/hetzner/RESTORE.md`
|
|
|
|
## 7.4 Domain and DNS
|
|
|
|
TODO: Confirm domain name (OQ-MVP-01).
|
|
|
|
Planned DNS setup:
|
|
- `registry.apix.dev` (or `index.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.
|