Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Aerostratus

Multi-tenant flight logging & aircraft maintenance — a clean foundation to build on.

This is not the full application. It is a deliberately small base with the hard parts (multi-tenancy, auth, validation, a service layer) done correctly, plus aircraft and flight logging implemented end-to-end as the reference pattern to copy when adding features.

Stack

  • Next.js 14 (App Router) + React 18 + TypeScript
  • Postgres via Prisma
  • NextAuth (credentials + JWT) for auth
  • Zod for input validation
  • Tailwind CSS

Getting started

npm install

# configure environment
cp .env.example .env
#   - set DATABASE_URL to your Postgres database
#   - set NEXTAUTH_SECRET   (openssl rand -base64 32)

# create the database schema
npx prisma migrate dev --name init

# load demo data (one org, one aircraft, one flight)
npm run db:seed

npm run dev

Then open http://localhost:3000 and sign in with the seeded account:

owner@demo.test  /  password123

Project structure

app/
  (app)/              authenticated area (shares nav + auth gate)
    dashboard/
    aircraft/         ← reference feature: list / new / [id]
    flights/          ← reference feature: list / new
  login/  register/   public auth pages
  api/auth/           NextAuth route
components/           shared UI (app-nav)
lib/
  auth.ts             NextAuth config
  auth-guard.ts       requireUser / requireRole — use in every protected page & action
  prisma.ts           Prisma client singleton
  validation.ts       Zod schemas (the only place input shapes are defined)
  services/           data access + business logic, always scoped by orgId
  format.ts           display helpers
prisma/
  schema.prisma       multi-tenant data model
  seed.ts             demo data

The patterns to follow

When you add a feature, copy how aircraft / flights are built:

  1. Validation — define the input shape as a Zod schema in lib/validation.ts.
  2. Service — put data access in lib/services/<x>-service.ts. Every query is scoped by orgId; that is the tenant boundary. Never query without it.
  3. Server action — in app/(app)/<x>/actions.ts. Call requireUser() or requireRole() first; derive orgId/userId from the session, never from form input. Validate, call the service, redirect on success.
  4. Pages — server components that call the service; client components only for forms/interactivity.

Concurrency note: flight-service.logFlight locks the aircraft row (SELECT … FOR UPDATE) before updating airframe hours — follow that approach for any operation that reads-then-writes shared counters.

What's intentionally left out

OCR meter reading, engine-monitor data, financials, GPS/KML, PDF export, and the legacy admin/pilot screens are not here. The previous implementation of all of it is preserved in _legacy/ (gitignored) for reference — copy pieces back as you rebuild them on this foundation.

See DATABASE_DESIGN.md and REMEDIATION_PLAN.md (repo root) for the schema rationale and the longer-term roadmap, including the planned Expo mobile app.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages