Skip to content

quellen-sol/VATMissions

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

VATMissions

VATMissions is a flight mission and reward system for the VATSIM online flight simulation network. ARTCC administrators create missions (point-to-point flights between real-world airports), and registered pilots earn rewards by completing them on the live network. The system automatically tracks pilot progress in real time by polling the VATSIM data feed.

Overall Design

The project is a multi-service monorepo with three main components and a shared library:

vatmissions/
├── control/     # Background worker – polls VATSIM, tracks pilots, awards rewards
├── gateway/     # HTTP API server – authentication, mission CRUD, reward queries
├── shared/      # Go packages shared by control and gateway
├── app/         # Next.js frontend (React, TailwindCSS, shadcn/ui)
├── db/          # SQL schema and seed data
└── compose.yml  # Docker Compose orchestration

Data Flow

VATSIM Data Feed (JSON)
        │
        ▼
    ┌────────┐     ┌───────┐     ┌──────────┐
    │ control│────▶│ Redis │◀────│ gateway  │
    └────────┘     └───────┘     └──────────┘
        │                             │
        ▼                             ▼
    ┌──────────┐                ┌──────────┐
    │ Postgres │                │   app    │
    └──────────┘                └──────────┘
  1. control polls the VATSIM v3 data feed every 30 seconds.
  2. It matches online pilots to active missions by comparing departure/arrival ICAO pairs.
  3. Pilot tracking state is stored in Redis as a JSON-encoded state machine.
  4. When a pilot lands at the destination, control writes reward rows to Postgres.
  5. gateway serves the REST API that the app frontend consumes.
  6. gateway uses Redis for response caching and shares the same Postgres database.

Component Design

Control Service (control/)

The control service is a headless background worker with no HTTP endpoints. It runs two goroutines:

  • DataFeedConsumerRoutine – Polls https://data.vatsim.net/v3/vatsim-data.json every 30 seconds and pushes parsed snapshots into a buffered Go channel.
  • DataFeedParser – Reads snapshots from the channel and executes the tracking pipeline:

Tracking Pipeline (per feed cycle)

  1. Load missions – Queries all non-expired missions and their airport coordinates from Postgres.
  2. Match pilots – Filters the feed to pilots whose departure:arrival ICAO pair matches a mission route.
  3. Exclude known – Removes pilots already tracked in Redis and known non-members (cached with 24h TTL).
  4. Membership check – Queries remaining candidates against the users table. Non-members are cached.
  5. Begin tracking – New members on the ground at the departure airport enter the state machine.
  6. Update tracked – Every tracked pilot's state is recomputed. Only forward progression is allowed:
State Description
0 – OnGroundAtDep Parked at departure (<5 nm, <100 ft AGL)
1 – OffGroundNearDep Airborne, first 25% of route
2 – OffGroundAtCruise Airborne, 25%–75% of route
3 – OffGroundNearDest Airborne, last 25% of route
4 – OnGroundAtDest Landed at destination (<5 nm, <100 ft AGL)
  1. Award rewards – When state reaches 4, all mission_rewards rows for that mission are inserted into user_rewards, and the tracking key is removed.
  2. Evict stale – Pilots not seen in the feed for >10 minutes are removed from tracking.

Distance calculations use the Haversine formula in nautical miles. "Percentage traveled" is derived from distFromDep / (distFromDep + distFromArr).

Gateway Service (gateway/)

The gateway is a standard library net/http server listening on port 3100. It provides:

Middleware

  • Permissioned – Extracts and validates a JWT Bearer token, checks the caller's permission bitmask, and injects VMClaims into the request context.
  • Cached – Redis-backed response caching with configurable TTL. Clients can bypass with Cache-Control: no-cache.

Endpoints

Method Path Permission Description
POST /register-user Public Register a new user by VATSIM CID
POST /authenticate Public Exchange VATSIM CID for a JWT (1h expiry)
GET /missions User List all missions with rewards (cached 1h)
GET /user-rewards User List rewards earned by the authenticated user
GET /artccs User List all ARTCC names (cached 1h)
GET /airports User List all airports; ?artcc= to filter (cached 1h)
POST /add-artcc Superuser Create a new ARTCC
POST /make-artcc-admin Superuser Promote/demote a user to ARTCC admin
POST /set-user-flags Superuser Enable/disable permission bitmask flags
POST /add-airport ARTCC Admin Add an airport to an ARTCC
POST /add-mission ARTCC Admin Create a new mission
POST /add-mission-reward ARTCC Admin Attach a reward to a mission

Note: There is currently no real authentication for demonstration purposes. The /authenticate endpoint issues a JWT for any CID without verifying identity against VATSIM.

Permission Bitmask

Permissions are stored as a 64-bit integer with bitwise composition:

Bit Value Role
0b001 1 Superuser
0b010 2 ARTCC Admin
0b100 4 User

A superuser has all bits set (0b111 = 7).

Shared Library (shared/)

Shared Go packages used by both services:

  • cache_utils – Redis key conventions (tracked_pilots:<CID>, non_members:<CID>).
  • db_types – Database row structs (Mission, MissionReward).
  • gateway_types – Request/response structs with validation (Validatable interface).
  • http_utils – Generic JSON body reader, response writer, and error writer.
  • jwt_utils – JWT creation, parsing, claims context injection, and Permissions type.

Frontend (app/)

A Next.js application with:

  • TailwindCSS + shadcn/ui for styling and components
  • Dark/light mode via next-themes
  • Login page (authenticates by VATSIM CID)
  • Dashboard with missions grouped by ARTCC
  • Mission detail page with rewards
  • User rewards page

The frontend proxies API requests to the gateway via Next.js rewrites.

Database (db/)

PostgreSQL schema with the following tables:

  • artccs – ARTCC identifiers (e.g. "ZDV")
  • airports – ICAO code, elevation, lat/lon, linked to an ARTCC
  • missions – Origin/destination airports, flight rules, constraints, expiration
  • mission_rewards – Rewards attached to missions (title, description, image)
  • users – VATSIM CID, permission bitmask, optional ARTCC admin assignment
  • user_rewards – Join table linking users to earned rewards

Running

Prerequisites

Start

./run.sh

This will:

  1. Create the Docker network (if it doesn't already exist)
  2. Build and start all services via docker compose up -d
  3. Apply the database schema (db/tables.sql) and seed data to Postgres

Once running, the services are available at:

  • gatewayhttp://localhost:3100
  • controlhttp://localhost:3101 (no HTTP endpoints; background worker only)
  • Postgreslocalhost:5432
  • Redislocalhost:6379

You can pass any extra Docker Compose flags directly:

./run.sh --force-recreate --build

About

A mission add-on for VATSIM. Fly predetermined routes and earn rewards.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors