Operations
Backups
Section titled “Backups”Do not forget the three secrets from
Configuration. A database and bucket restored
without QNOP_AUTH_ENCRYPTION_KEY and QNOP_AUTH_ENCRYPTION_SALT will come up,
but everything encrypted at rest — stored OIDC client secrets among them — is
unreadable.
Upgrades
Section titled “Upgrades”- Read the release notes for the version you are moving to.
- Take a backup of both stores.
- Pin the new image version and restart.
Liquibase runs the schema migration on startup. The first boot on a new version therefore takes longer than usual; the health check’s start period accounts for this.
Migrations are forward-only. There is no downgrade path — going back to an older image after a migration means restoring from the backup you took in step two. This is the reason step two is not optional.
Monitoring
Section titled “Monitoring”GET /actuator/health is anonymous; point your load balancer or orchestrator at
it, or at the liveness and readiness groups underneath it.
Everything else on /actuator/** — health details, metrics, the Prometheus
endpoint — requires an authenticated ADMIN. Scraping metrics means giving the
scraper admin credentials, which is a deliberate default: the operational
surface is not public.
Beyond the actuator, Administration → Scheduler shows the maintenance jobs and their last runs, and Administration → Storage consistency reports mismatches between the database and the bucket.
What runs on its own
Section titled “What runs on its own”qnop schedules several maintenance jobs. In a multi-instance deployment they are coordinated so exactly one instance runs each sweep.
| Job | Default schedule | What it does |
|---|---|---|
| Staged-object reaper | 0 30 3 * * * | removes uploads that were staged but never referenced, after a grace period |
| Orphan reaper | 0 15 4 * * * | removes bucket objects nothing points at any more |
| Review archive | 0 50 3 * * * | archives reviews older than the configured window |
| Review purge | 0 55 3 * * * | purges archived reviews after their retention window |
The archive and purge windows are set in Administration → Settings, not in the environment. Both archiving and purging are recorded in the audit trail.
Long-running work triggered by users — text extraction, re-anchoring annotations onto a new version — runs through a durable job queue held in PostgreSQL rather than in memory. A crash or restart mid-extraction resumes rather than losing the work.
The audit trail
Section titled “The audit trail”Every relevant action is appended to the audit trail: annotation lifecycle (created, classified, resolved, reopened, dismissed, auto-closed), placement changes, workflow transitions, review archive/unarchive/purge, due-date changes, extraction outcomes, orphan deletions and scheduler runs.
It is exposed at GET /api/v1/audit/events, filterable, and readable by the
AUDITOR role or an ADMIN — that is the only surface the auditor role
unlocks. Actor identity is deliberately resolved there even where the UI
pseudonymises it elsewhere, because the point of the trail is accountability.