Aviation Safety & Risk Intelligence Platform
Real-time flight dispatch, ground operations, and safety management
⚠️ Project Under ConstructionAeroFlow is actively being developed. Core functionality is implemented and ready for manual testing, but some features are still being built out. Expect breaking changes. Contributions and feedback are welcome.
- Overview
- Tech Stack
- Architecture
- Prerequisites
- Getting Started
- Deployment to Vercel
- Manual Testing Guide
- Project Structure
- API Routes
- Roles & Permissions
- Running Tests
- Contributing
- License
AeroFlow is a production-oriented aviation safety and risk intelligence web application designed for managing flight dispatch operations, ground crew readiness, weather monitoring, and safety compliance. It enforces strict role-based access control, immutable audit logging, and real-time event streaming to ensure operational integrity.
- Flight Dispatch Management — Schedule, approve, and track flight dispatch operations with multi-gate safety enforcement.
- Risk Calculation Engine — Weighted risk scoring based on crew fatigue, weather severity, equipment status, and checklist compliance.
- Ground Operations Dashboard — Mobile-first interface for ground crew to complete pre-flight checklists and log shift fatigue.
- Real-Time Alerts (SSE) — Server-Sent Events powered by a Node EventEmitter for live dispatch status updates.
- Weather Ingestion — Automated weather data collection from OpenWeatherMap via Vercel Cron jobs.
- AI Safety Drafts — LLM-powered draft safety briefings (clearly marked as drafts, never authoritative).
- Immutable Audit Ledger — Every mutation is logged with user ID, action, resource, old/new state, timestamp, and IP address.
- Manual Override System — Operations Directors can force-approve blocked flights with mandatory justification tracking.
| Layer | Technology |
|---|---|
| Framework | Next.js 16 (App Router) |
| Language | TypeScript (strict mode) |
| Styling | TailwindCSS 4 (mobile-first) |
| Database | PostgreSQL |
| ORM | Prisma 6 |
| Authentication | NextAuth.js v4 (Credentials Provider) |
| Validation | Zod |
| Live Updates | Server-Sent Events (SSE) |
| Weather API | OpenWeatherMap |
| AI Drafting | OpenAI API (gpt-4o-mini) |
| Deployment | Vercel |
| Scheduled Jobs | Vercel Cron |
| Testing | Vitest |
┌──────────────────────────────────────────────────────┐
│ Next.js App Router │
│ ┌──────────┐ ┌───────────┐ ┌──────────────────┐ │
│ │ Pages │ │ Layouts │ │ API Routes │ │
│ │ (RSC) │ │ (Auth) │ │ /auth /cron /sse │ │
│ └────┬─────┘ └─────┬─────┘ └────────┬─────────┘ │
│ │ │ │ │
│ ┌────▼──────────────▼─────────────────▼──────────┐ │
│ │ Server Actions │ │
│ │ flight.ts · crew.ts · actions.ts │ │
│ └────────────────────┬───────────────────────────┘ │
│ │ │
│ ┌────────────────────▼───────────────────────────┐ │
│ │ Core Libraries │ │
│ │ risk.ts · auth.ts · ai.ts · events.ts │ │
│ │ audit/ledger.ts · db.ts · validations.ts │ │
│ └────────────────────┬───────────────────────────┘ │
│ │ │
│ ┌────────────────────▼───────────────────────────┐ │
│ │ Prisma ORM → PostgreSQL │ │
│ └────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────┘
Before you begin, ensure you have the following installed:
- Node.js ≥ 18.17 — Download
- npm ≥ 9 (ships with Node.js)
- PostgreSQL ≥ 14 — Download
- Git — Download
- A Vercel account (for deployment) — Sign up
Fork the repository on GitHub by clicking the "Fork" button at the top right of the repo page.
Then clone your fork locally:
git clone https://github.com/<your-username>/AeroFlow.git
cd AeroFlownpm installThis will install all runtime and development dependencies including Next.js, Prisma, NextAuth, Zod, and TailwindCSS.
Create a .env file in the project root. This file is git-ignored by default and must never be committed.
cp .env.example .envOr create it manually with the following variables:
# ─── Database ────────────────────────────────────────
DATABASE_URL="postgresql://<user>:<password>@localhost:5432/aeroflow?schema=public"
# ─── NextAuth ────────────────────────────────────────
NEXTAUTH_SECRET="your-random-secret-string-here"
NEXTAUTH_URL="http://localhost:3000"
# ─── External APIs ───────────────────────────────────
OPENWEATHER_API_KEY="your-openweathermap-api-key"
OPENAI_API_KEY="your-openai-api-key"
# ─── Cron Protection ────────────────────────────────
CRON_SECRET="your-cron-secret-string"| Variable | Required | Description |
|---|---|---|
DATABASE_URL |
✅ | PostgreSQL connection string |
NEXTAUTH_SECRET |
✅ | Random string for JWT signing (generate one) |
NEXTAUTH_URL |
✅ | Your app's base URL (http://localhost:3000 for local dev) |
OPENWEATHER_API_KEY |
✅ | Free API key from OpenWeatherMap |
OPENAI_API_KEY |
Required only for AI safety draft generation | |
CRON_SECRET |
✅ | Bearer token to protect the weather cron endpoint |
Create the PostgreSQL database:
createdb aeroflowGenerate the Prisma client and push the schema to your database:
npx prisma generate
npx prisma db pushNote:
prisma db pushis used for development. For production migrations, usenpx prisma migrate devto create a migration history.
Seed initial data (optional):
If a seed file exists:
npx prisma db seedIf no seed file exists yet, you can manually insert a test user via Prisma Studio:
npx prisma studioThis opens a browser UI at http://localhost:5555 where you can create users with different roles (GROUND_CREW_LEAD, FLIGHT_DISPATCHER, OPERATIONS_DIRECTOR).
npm run devOpen http://localhost:3000 in your browser.
If you haven't already, initialize git and push to your fork:
git add .
git commit -m "Initial commit"
git push origin main- Go to vercel.com/new.
- Import your GitHub repository.
- Select the Next.js framework preset (should be auto-detected).
In the Vercel project dashboard, navigate to Settings → Environment Variables and add each variable from your .env file:
| Key | Value | Environment |
|---|---|---|
DATABASE_URL |
Your hosted PostgreSQL connection string (e.g., from Neon, Supabase, or Railway) | Production, Preview |
NEXTAUTH_SECRET |
Your secret string | Production, Preview |
NEXTAUTH_URL |
https://your-app.vercel.app |
Production |
OPENWEATHER_API_KEY |
Your API key | Production, Preview |
OPENAI_API_KEY |
Your API key | Production, Preview |
CRON_SECRET |
Your cron secret | Production, Preview |
Important: You must use a hosted PostgreSQL provider for Vercel deployment. Vercel serverless functions cannot connect to
localhost.
Create or verify the vercel.json file in the project root:
{
"crons": [
{
"path": "/api/cron/weather",
"schedule": "*/15 * * * *"
}
]
}This runs the weather ingestion cron every 15 minutes. The endpoint is protected by the CRON_SECRET bearer token — Vercel automatically sends the Authorization: Bearer <CRON_SECRET> header for cron invocations.
After pushing and configuring environment variables:
git push origin mainVercel will automatically build and deploy. You can also trigger a manual deploy from the Vercel dashboard.
Post-deployment checklist:
- Run
npx prisma db pushagainst your production database (or apply migrations) - Verify the app loads at your Vercel URL
- Create initial users via Prisma Studio connected to your production DB
- Test the authentication flow
Follow these steps to verify the complete dispatch flow:
Use Prisma Studio or a database client to insert users with these roles:
| Role | |
|---|---|
crew@aeroflow.test |
GROUND_CREW_LEAD |
dispatcher@aeroflow.test |
FLIGHT_DISPATCHER |
director@aeroflow.test |
OPERATIONS_DIRECTOR |
Insert a Flights record with status SCHEDULED, linked to a RouteProfiles entry and at least one FlightChecklists with mandatory ChecklistItems.
- Log in as
crew@aeroflow.test. - Navigate to
/crew/dashboard. - Complete all mandatory checklist items by clicking the checkboxes.
- Submit a shift log with a fatigue score.
- Log in as
dispatcher@aeroflow.test. - Navigate to
/dispatcher/dashboard. - Click into a flight to view its dossier at
/dispatcher/flight/[id]. - Verify the risk score, weather status, and checklist completion are displayed.
- Click Approve Dispatch (should succeed if risk is below critical threshold).
- Create a scenario with high fatigue (index > 8) or critical weather.
- Verify the Approve Dispatch button is disabled and an error is thrown.
- Log in as
director@aeroflow.test. - Navigate to the blocked flight's dossier.
- Enter a justification and click Force Override.
- Verify the flight status changes to
READY.
- Log in as
director@aeroflow.test. - Navigate to
/director/ledger. - Verify all actions (checklist completions, shift logs, approvals, overrides) are logged with correct timestamps, user IDs, and IP addresses.
AeroFlow/
├── prisma/
│ └── schema.prisma # Database schema (20+ models)
├── src/
│ ├── app/
│ │ ├── api/
│ │ │ ├── auth/[...nextauth]/ # NextAuth API route
│ │ │ ├── cron/weather/ # Weather ingestion cron
│ │ │ └── sse/ # Server-Sent Events endpoint
│ │ ├── crew/
│ │ │ └── dashboard/ # Ground operations UI
│ │ ├── dispatcher/
│ │ │ ├── dashboard/ # Dispatch overview
│ │ │ └── flight/[id]/ # Flight dossier & approval
│ │ ├── director/
│ │ │ └── ledger/ # Immutable audit log viewer
│ │ ├── layout.tsx # Root layout
│ │ ├── page.tsx # Landing page
│ │ └── globals.css # Global styles
│ └── lib/
│ ├── actions/
│ │ ├── crew.ts # Checklist & shift log actions
│ │ └── flight.ts # Dispatch approval & override
│ ├── audit/
│ │ └── ledger.ts # Immutable audit logging
│ ├── auth.ts # NextAuth config & RBAC
│ ├── ai.ts # OpenAI draft generation
│ ├── db.ts # Prisma client singleton
│ ├── events.ts # SSE EventEmitter singleton
│ ├── risk.ts # Risk calculation engine
│ └── validations.ts # Zod schemas
├── tests/
│ └── unit/
│ └── risk.test.ts # Risk engine unit tests
├── .env # Environment variables (git-ignored)
├── .gitignore
├── package.json
├── tsconfig.json
├── next.config.ts
├── postcss.config.mjs
├── eslint.config.mjs
└── README.md
| Route | Method | Auth | Description |
|---|---|---|---|
/api/auth/[...nextauth] |
GET/POST | Public | NextAuth authentication endpoints |
/api/cron/weather |
GET | Bearer Token (CRON_SECRET) |
Ingests weather data for active flights |
/api/sse |
GET | None (event stream) | Real-time Server-Sent Events for dispatch updates |
| Role | Access |
|---|---|
GROUND_CREW_LEAD |
/crew/dashboard — Complete checklists, log shift fatigue |
FLIGHT_DISPATCHER |
/dispatcher/dashboard, /dispatcher/flight/[id] — View flights, approve dispatch |
OPERATIONS_DIRECTOR |
All dispatcher routes + /director/ledger — Override blocked dispatches, view audit logs |
Run the Vitest test suite:
npx vitest runRun tests in watch mode:
npx vitestRun a specific test file:
npx vitest run tests/unit/risk.test.ts- Fork the repository.
- Create a feature branch:
git checkout -b feature/your-feature-name - Commit your changes:
git commit -m "feat: add your feature" - Push to your branch:
git push origin feature/your-feature-name - Open a Pull Request against the
mainbranch.
- Follow TypeScript strict mode — no
anytypes except where explicitly required. - All Server Actions must include
requireRole()andlogAudit()calls. - Never expose API keys or secrets to client components.
- Write tests for any new risk calculation logic or gating rules.
- Use conventional commit messages (
feat:,fix:,docs:,test:).
This project is currently unlicensed. A license will be added as the project matures.
AeroFlow is being actively developed. Features, APIs, and database schemas may change without notice.