Skip to content

Admin panel reference

The admin panel is at Settings → Admin in the top nav (visible only to users with isAdmin: true). It groups instance-wide configuration into seven panes.

This page is the reference that maps every field to its effect.

The basics. Most of these were set during the first-run wizard and rarely change afterwards.

FieldWhat it does
Instance nameBrowser title bar text, email subject prefix
Public URLUsed in email links (invitations, password reset). Crucial — if this is wrong, password-reset links go to the wrong host
Maximum usersCap on the user count. New registrations / invitations fail when reached. Set to 0 = unlimited
Registration modepublic — anyone can sign up · invite — only invited users · closed — admin-created users only
Default UI languageNew users default to this. They can change it in their personal settings

Encrypted at rest with the auto-generated encryption key under /app/data/secrets/encryption.key.

FieldWhat it unlocksRequired?
AirLabs API keyLive flight enrichment (today’s flights primarily)No
Aviationstack API keyHistorical + future flight enrichmentNo
OpenSky Client ID + SecretReal-time tracking position fallbackNo
OpenAI API keyOpenAI Vision for boarding-pass scanningNo
Anthropic API keyClaude Vision for boarding-pass scanningNo
Ollama URLLocal LLM endpoint (default http://ollama:11434)No (defaults to bundled container)
Ollama text modelModel used for email parsing fallback (default gemma3:12b)No
Ollama vision modelModel used for boarding-pass scanning when Ollama is the cascade defaultNo

Each row has a Test connection button that hits the provider’s healthcheck endpoint. Use it after pasting a key.

The pages Flight data APIs, Ollama, and Vision parsers walk through getting each key set up.

Same fields as the SMTP page — host, port, encryption, username, password, from-address, plus a Send test button. Empty fields here mean SMTP is disabled — invitations and password-resets fall back to the “ask the admin” message.

FieldDefault
Enabledtrue
Schedule (cron)0 2 * * *
Retention14 (keep last 14 backup files)
Compressiongzip
WebDAV URL(empty — disabled)
WebDAV user / password(empty)

Plus a Run backup now button. Full deep-dive on the Backups & Restore page.

A table of all user accounts with admin actions:

  • Create user — manual user creation (no email sent)
  • Send invitation — generates a single-use invite link, sends it via SMTP if configured
  • Promote to admin / Demote — toggle the isAdmin flag
  • Force password change — sets mustChangePassword; user must change at next login
  • Send reset email — generates a password-reset link, mails it via SMTP
  • Delete user — cascades to their flights, achievements, tokens. Confirms with a typed-in-username challenge before destruction

The table shows username, email (if any), admin flag, registration date, last login, total flights logged.

Read-only tabular view of every mutation:

ColumnContains
TimestampUTC, ISO 8601
UserWho triggered the action (cookie or PAT-bearing user)
TokenWhich PAT, if PAT-authenticated. Empty for cookie sessions
IPClient IP (anonymised after 7 days per server-log policy)
Method + pathThe HTTP request that was logged
ResourceWhat changed (e.g. Flight#abc-123-def)
ActionCREATE / UPDATE / DELETE
DiffPer-field before-and-after values

Filter by user, action, date range, resource. Export filtered results as CSV.

The audit log is the canonical “what happened on this instance” — useful for debugging “why did this flight change”, forensics if you suspect a token leak, and compliance review.

FieldDefaultDescription
Log levelinfoOne of error / warn / info / debug / trace. Persisted across restarts
Log retention (days)14Older log files are pruned by the daily cleanup job
Pino destination/app/data/logs/Files: app.log (everything), error.log (errors only), http.log (request/response), parser*.log (parser pipeline traces)

Raise to debug for one-off troubleshooting, drop back to info afterwards. debug adds a lot of volume to app.log — ~10× growth per day.

Log files are also tail-able from the host:

Terminal window
docker exec travstats-app tail -f /app/data/logs/app.log | jq .

Read-only “about” pane — informational only:

  • TravStats version — bottom of every page in the UI, also here
  • Build date — when the running image was built
  • Node version inside the container
  • Postgres version the database is running
  • Database size — total Postgres data + indexes
  • Backup count — how many backup files in /app/data/backups/
  • Pending updates — link to the Pending Updates dashboard
  • Health status — same as the /health endpoint, refreshed live

In the top-right corner of every page TravStats displays a yellow Update available badge when a newer stable release exists on GitHub. The check works as follows:

  • The backend hits https://api.github.com/repos/Abrechen2/TravStats/releases/latest on the first version-endpoint call after start
  • The result (latest version + release URL + release notes) is cached in process memory for 6 hours; subsequent UI loads reuse the cached value
  • Only stable releases trigger the banner — RC / draft / pre-release tags are filtered out
  • Pre-release suffixes on your current version are stripped before comparison, so running 1.3.0-rc.4 doesn’t pop the banner when 1.3.0 ships (you’re effectively running the release)
  • Air-gapped instances: GitHub is unreachable → the check fails silently and the badge stays hidden. No retries flood the network

If you’d rather hide the banner entirely (e.g. on a corporate deployment where you control the upgrade cadence), there’s no runtime toggle; suppress it at the reverse-proxy by stripping /api/v1/version’s response, or fork the frontend to comment out the badge.

The Diagnostic export button builds an anonymised diagnostic bundle for filing GitHub issues. Details on what’s redacted and when to send it: Troubleshooting → Diagnostic export.

Some settings deliberately live in .env (deploy-time) rather than the admin UI (runtime):

  • DATABASE_URL — changing the database in flight is not a thing
  • JWT_SECRET — auto-generated, persisted to file, never editable in UI (rotation = delete file + restart, signs out everyone)
  • COOKIE_SECURE, CORS_ORIGIN — proxy-related; almost always auto-detected correctly. Only set in .env for unusual proxy setups
  • TZ — the container’s clock. Always UTC. The UI renders in user-local time

If you need to change any of these, edit .env and restart the stack. Everything else lives in the admin UI.