Files
parking_solution/komodo/resources.toml
T
julian 84f00db48b
Build desktop / desktop (push) Successful in 4m17s
Build & push images / images (push) Failing after 39s
CI / check (push) Successful in 39s
feat(backup): admin-tunable retention + BACKUP_KEY as a Komodo secret
Retention (keep-last / keep-daily-days) is operational policy the on-site admin
should tune, not a server env var requiring a redeploy -- same reasoning that moved
the target directory to the UI.

- Migration 0017: site_config.backup_keep_last + backup_keep_daily_days (nullable;
  null = code default 7 / 30 per field).
- BackupService reads retention fresh each run; status() exposes keepLast +
  keepDailyDays. DEFAULT_BACKUP_RETENTION is now a pure code default (env reads gone).
- PUT /api/backup/config accepts keepLast / keepDailyDays (non-negative int, or null
  to reset to default; 400 on negative).
- UI: two retention fields on the Backup config card; one Save covers target +
  retention. i18n sq + en.

BACKUP_KEY wired into Komodo:
- komodo/resources.toml: BACKUP_KEY=[[park_buzi_backup_key]] (per-booth secret,
  alongside JWT / signing keys).
- komodo/.env.komodo.example: documents it as the ONLY backup env var -- escrow it
  offsite alongside EVENT_SIGNING_KEY (recovery needs both); target + retention are
  admin-chosen in the UI / DB, not env. Server .env.example trimmed to just BACKUP_KEY.

Also carries the small in-progress setup-intro i18n copy trim.

Tests: 218 server tests green, incl. retention persist / reset-to-default / reject-
negative and the updated status shape. Migration applies cleanly (needed a
statement-breakpoint between the two ALTERs). Wiki backup-recovery updated.

Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V
2026-06-29 12:52:18 +02:00

54 lines
2.3 KiB
TOML

# Komodo resources — parking appliance fleet (control plane as code)
#
# Synced into Komodo Core via a ResourceSync pointing at this file. Drives the SAME
# compose files the booth runs locally (docker-compose.yml + docker-compose.prod.yml);
# Komodo Periphery on each booth executes them. See:
# wiki/decisions/fleet-deployment-komodo.md (rationale + threat model)
# wiki/decisions/container-deployment.md (image build/tag/registry — unchanged)
#
# This file mirrors the WORKING park-buzi Stack (built by hand in the Core UI, then
# exported to TOML). Field names match the running Komodo version (v2.2).
#
# NO [[server]] block: servers are created by the AGENT onboarding outbound (a one-time
# onboarding key → Periphery self-registers with auto-rotating key pairs). The sync owns
# only the Stack; it references the server by the name it onboarded as (`connect_as`).
#
# Secrets ([[park_buzi_jwt_secret]] etc.) are REFERENCES to Komodo Core's secret store —
# per-booth + unique, never inlined here (this file is in git). JWT_SECRET gates login;
# EVENT_SIGNING_KEY signs the append-only anti-fraud ledger; BACKUP_KEY encrypts on-site DB
# backups (separate from the signing key; escrow it offsite — recovery needs both).
#
# Deploys are MANUAL + PINNED in spirit: bump TAG to an immutable dev-<sha> before a
# production booth goes live (TAG=dev here is the moving tag, fine while staging). NO
# deploy webhook is attached to a booth Stack.
##############################################################################
# Stack — the deployable unit for booth "park-buzi". One Stack per booth; add a
# new [[stack]] block per site (unique name, its own per-booth secret refs).
##############################################################################
[[stack]]
name = "park-buzi"
[stack.config]
server = "park-buzi"
git_provider = "git.infra.msai.al"
git_account = "komodo"
repo = "mca/parking_solution"
branch = "dev"
file_paths = [
"docker-compose.yml",
"docker-compose.prod.yml"
]
registry_provider = "git.infra.msai.al"
registry_account = "komodo"
environment = """
REGISTRY=git.infra.msai.al/mca/parking_solution
TAG=dev
COOKIE_SECURE=0
VISION_ENABLED=1
WS_ALLOWED_ORIGINS=
JWT_SECRET=[[park_buzi_jwt_secret]]
EVENT_SIGNING_KEY=[[park_buzi_event_signing_key]]
BACKUP_KEY=[[park_buzi_backup_key]]
"""