Skip to content

VA Dispatch — Live Dispatch & ACARS

CI Security License: AGPL v3 or later

Multi-tenant Virtual Airline Live Dispatch & ACARS tool.

For the full product guide, architecture, API reference, operating runbooks, and current limitations, see the project Wiki.

  • One tenant = one Virtual Airline (first: vSAS)
  • API: Hono + TypeScript on Vercel Services (apps/api)
  • Web: Next.js pilot portal + dispatcher suite (apps/web)
  • ACARS: Hoppie's ACARS with tenant-scoped encrypted ground-station credentials

Monorepo

apps/api   — Hono REST API (/api/v1)
apps/web   — Next.js frontend (path tenancy at /vsas)

Prerequisites

  • Node.js 24+ (26.7 recommended locally; Vercel currently builds on 24.x)
  • pnpm 11.21+
  • Neon Postgres + Clerk (Vercel Marketplace)

Quick start

pnpm install
cp .env.example apps/api/.env
# configure apps/web/.env.local from apps/web/.env.example
# fill DATABASE_URL, CLERK_SECRET_KEY, etc.

DATABASE_URL='postgresql://...' pnpm db:push
pnpm dev              # web :3000 + API :3001

Open http://localhost:3000/vsas. Health check: GET http://localhost:3001/health. The API reference is available through Swagger UI, ReDoc, and the raw OpenAPI document.

The public legal pages are available at /impressum and /privacy. Configure all required LEGAL_* values from apps/web/.env.example before production; production requests fail closed rather than publish placeholder operator data. See docs/privacy-compliance.md for the deployment and operating checklist. Guarded retention, export, legal-hold, and verified request procedures are in docs/privacy-operations.md; the software does not by itself certify GDPR compliance.

Clerk Organizations must use optional membership, organization slugs must be enabled, end-user organization creation and Verified Domain enrollment must be disabled, and the Primary Role Set must contain org:admin, org:dispatcher, and org:pilot. Production uses Clerk Waitlist mode with email enabled; self-service new users enter through /vsas/waitlist. Clerk Dashboard approval emails open the Clerk Account Portal sign-up flow; configure its sign-up fallback redirect to /vsas/join, where VA Dispatch handles tenant-role approval. The tenant-branded /vsas/sign-up route remains available for direct invitation flows that redirect into the application. This flow does not require Clerk's Invite-only (restricted) sign-up mode or the paid allowlist. The vSAS Clerk organization slug is vsas; set VSAS_CLERK_ORG_ID to its immutable ID. Tenant admins then manage the separate pilot/dispatcher application approval, roles, removal, and tenant membership settings inside VA Dispatch. See the Wiki configuration reference for the one-time global Clerk setup.

Core flows

Role Capabilities
Pilot Request schedule, accept / decline / cancel flights
Dispatcher Fulfill requests, flight board, ACARS send/receive
Admin Tenant settings, invitations, approvals, roles/removal, ACARS config

ACARS

Production ACARS uses Hoppie exclusively. An administrator opens /:slug/settings/organization, enters the VA ground-station callsign and Hoppie logon code, and runs a connection test. The code is encrypted with TENANT_SECRETS_KEY and is never returned by the API. Until that succeeds, ACARS is explicitly unconfigured and outbound sends fail safely.

Every member, including dispatchers who also fly, saves their aircraft callsign under /:slug/settings. Their personal Hoppie logon remains in their simulator ACARS client; this application never asks for or stores it. The member and VA ground-station Hoppie accounts must use the same network affiliation.

Hoppie registration is free and self-service; no separate API approval is required: https://www.hoppie.nl/acars/system/register.html.

Local development and automated tests can use the internal DB-backed adapter with ACARS_PROVIDER=mock. Its POST /api/v1/acars/simulate fixture is never enabled in production, even if a stale production variable says mock.

Cost model (no idle cost)

Layer Choice Idle behavior
Postgres Neon Free / scale-to-zero Suspends when unused → $0 idle
Auth Clerk + B2B Authentication Production custom roles require the add-on
API Vercel Fluid Compute Active CPU pricing; no charge when not invoked
ACARS cron Every 1 min, configured tenants only Required for a live Hoppie ground station

Do not add Redis/queues for v1 — they would add idle or minimum footprint.

The production poll cron selects only tenants with an encrypted Hoppie logon. Set ACARS_PROVIDER=hoppie in production for an explicit, self-documenting configuration; the runtime enforces Hoppie there regardless. Vercel Pro is required for the one-minute schedule; slower cron schedules delay inbound messages but do not affect outbound sends.

Deploy

Vercel Services (vercel.ts): web + api, rewrites /api/* → API. If the Services private beta is unavailable, deploy apps/web and apps/api as two projects and set API_ORIGIN on the web project to the API project's public origin; the Next.js rewrite keeps browser calls on same-origin /api/*.

Normal releases are automatic: CI validates an internal pull request before a separate credentialed workflow deploys its preview; a successful main CI run deploys Production. Builds do not modify the database; /api/ready must confirm that the selected environment already has the required tenant/membership schema. See docs/maintainer-setup.md for the one-time GitHub and Vercel configuration.

Initial local provisioning remains manual:

vercel login
vercel link
# Prefer Neon Free / Launch (autosuspend). Avoid always-on compute plans.
vercel integration add neon
vercel integration add clerk
vercel env pull apps/api/.env.local --yes
# copy DATABASE_URL + CLERK_* into apps/api/.env for local
DATABASE_URL='postgresql://...' pnpm db:push

Scripts

Script Description
pnpm dev:api Run API locally
pnpm dev:web Run the Next.js app locally
pnpm dev Run API and web together
pnpm test:api API unit and isolation tests
pnpm test:web Frontend unit and component tests
pnpm test:coverage Full-source tests and coverage
pnpm security:audit High-severity dependency audit
pnpm --filter @va-dispatch/web test:e2e Deterministic browser smoke tests
pnpm test:e2e:integrated Real web/API/PostgreSQL journeys
pnpm db:push Apply the canonical schema to a fresh database
pnpm typecheck TypeScript check

This Shiftbloom project is pre-production and uses schema.ts as its canonical database definition. Recreate an empty database and run db:push; never point that command at a database containing user data. If the product later becomes long-lived production software, define a new data-evolution policy first.

The integrated browser suite requires a separately confirmed disposable PostgreSQL database. See docs/integrated-e2e.md for its guarded local command, provider isolation, and deployed-browser acceptance checklist.

Contributing

Contributions are welcome. Read CONTRIBUTING.md for setup, quality checks, and pull request expectations. Participation is governed by the Code of Conduct, and support guidance is available in SUPPORT.md. Repository administrators should also complete the maintainer setup checklist after these files land on main.

Security

Do not report vulnerabilities in public issues. Follow the private reporting process in SECURITY.md.

License

Copyright is held by the respective VA Dispatch contributors. The project is free software licensed under the GNU Affero General Public License version 3 or any later version (AGPL-3.0-or-later). Operators who make a modified version available over a network must offer its corresponding source to users as required by the license. Hosted forks must set NEXT_PUBLIC_SOURCE_URL to the corresponding source for their deployed version; the application exposes this link in its legal notice.

About

Dispatcher & ACARS Tools for Virtual Airline Staff -> Pilot Roleplay

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages