- Admin logic (role-based access, user management, audit logging)
- Clerk v6 integration (secure authentication, metadata sync, dual-write pattern)
- Aircraft registry and management (soft delete/archive, access control)
- Flight logging with advanced filtering (URL state, shareable links)
- Server-side validation (Zod schemas, tRPC procedures)
- Weather widget (AVWX METAR integration with caching)
- Analytics dashboard (charts, statistics, 90-day recency tracking)
- Security hardening: 5-layer defense (Zod validation, rate limiting, request body limits, DB constraints, HTML sanitization)
- Test suite (97 tests): Comprehensive coverage of all 10 test suites including security and rate-limit validation
- Mobile-first responsive design: Viewport config, responsive nav with hamburger menu, touch-friendly UI (40px targets), documented standards
- UI polish and accessibility improvements
- Multi-aircraft support for users
- Bulk import/export for flight logs
- Open source documentation and contribution guidelines
- Automated deployment scripts for multiple cloud providers
Progress Scores (Jan 2026 Audit - Updated):
- Core Logic: 95% (Soft Delete/Archiving, client-side tRPC hooks, real-time reactivity)
- UI/UX: 98% (Mobile-first responsive design, no stale data flashes, touch-friendly navigation)
- Infrastructure/Perf: 95% (Optimized DB queries, strict protectedProcedure auth)
- Test Coverage: 95% (74 tests across all 8 routers with comprehensive edge case coverage)
For a detailed breakdown of completed features, WIPs, and the audit log, please see PROJECT_STATUS_REPORT.md.
All dashboard data fetching was moved to the client (via tRPC hooks) to address issues with Next.js App Router's soft-navigation and React Query hydration. This ensures:
- Real-time reactivity and instant updates after navigation or mutations.
- Consistent, up-to-date data for all dashboard widgets, regardless of navigation method.
- Simpler cache invalidation and error handling, especially for authenticated/protected data.
This is now the standard for all dashboard and user-specific data modules.
Compliance: Implemented a non-destructive soft-delete system for both Users and Aircraft, ensuring historical flight data remains intact even when accounts are deactivated (FAA/CAA friendly).
UX/Performance: Shifted to client-side tRPC data fetching with pre-defined loading skeletons, eliminating stale-data flashes during Next.js navigation and improving perceived performance (LCP) on the dashboard.
A comprehensive flight logging and pilot management application built with the T3 Stack. Pilot Handbook helps pilots track their flight hours, manage aircraft, and maintain accurate logbook records while providing administrative tools for flight schools and organizations.
- Smart Flight Logging: Automated duration calculation and aircraft tracking.
- Live Weather Widget: Real-time METAR data with airport name resolution.
- Dynamic Filtering: Filter logs by aircraft type using URL-based state (shareable links).
- Recency Tracking: 90-Day currency monitoring (Day/Night/IFR).
- Role-Based Access: Admin dashboard for user verification and management.
- Secure Auth: Clerk integration with "In-App Browser" detection for TikTok/Instagram users.
- Data Integrity: Server-side validation with Zod schemas.
Core
- Framework: Next.js 16 (App Router)
- Language: TypeScript
- Library: React 19 (Server Components & Actions)
- Styling: Tailwind CSS v4
βββ app/ # Next.js App Router (UI, pages, layouts)
β βββ admin/ # Protected admin dashboard (user/role management)
β βββ aircraft/ # Aircraft registry and details
β βββ dashboard/ # User dashboard (stats, analytics)
β βββ flights/ # Flight logbook and entry forms
β βββ settings/ # User settings (profile, preferences)
β βββ sign-in/ # Auth routes (Clerk)
β βββ ... # Other feature routes
βββ components/ # Shared React components (UI, layout, widgets)
β βββ admin/ # Admin-specific UI components
β βββ landing/ # Landing page sections
β βββ ui/ # Design system (Button, Card, etc.)
βββ lib/ # Server utilities (db, auth, helpers)
β βββ hooks/ # Custom React hooks
βββ prisma/ # Database schema and migrations
βββ public/ # Static assets (images, favicon)
βββ scripts/ # Utility scripts (admin tools, DB checks)
βββ server/ # tRPC API routers and server logic
β βββ routers/ # tRPC routers (admin, aircraft, user, etc.)
β βββ trpc.ts # tRPC server entrypoint
βββ src/ # (Legacy) Shared logic, actions, utils
βββ trpc/ # tRPC client/provider for React
βββ internal-docs/ # Internal scripts and documentation (not shipped)
βββ .env, .gitignore, ... # Config and environment files- /app: Main Next.js App Router. Each subfolder is a route (e.g.,
/adminis the admin dashboard,/flightsis the logbook UI).
## π Getting Started
### Prerequisites
- **Node.js** 20+
- **pnpm** (recommended) or npm
- **PostgreSQL** database (Supabase, Neon, or local)
### 1. Clone the Repository
```bash
git clone <your-repo-url>
cd pilothandbook
pnpm installpnpm prisma db pushCreate a .env file in the project root with the following keys:
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=your_clerk_publishable_key
CLERK_SECRET_KEY=your_clerk_secret_key
DATABASE_URL=your_postgres_connection_string
CLERK_WEBHOOK_SECRET=your_clerk_webhook_secret
Important: In your Clerk Dashboard, go to User Settings > Metadata and enable Public Metadata. This is required for the
ADMINrole and other user roles to work correctly in the app.
pnpm devOpen http://localhost:3000 to view the app.
npm run dev- Start the development servernpm run build- Build the application for productionnpm start- Start the production servernpm run lint- Run ESLint to check code qualitynpm run test- Run all tests with Vitestnpm run test:ui- Run tests with interactive UInpm run test:coverage- Generate test coverage reportnpm run typecheck- Run TypeScript type checkingnpm run make:admin <clerkUserId>- Promote a user to admin role
The application uses the following main models:
- User: User accounts with role-based permissions
- Aircraft: Aircraft registry with specifications
- Flight: Flight log entries with detailed information
- UserPreferences: User preferences including theme and settings
See prisma/schema.prisma for the complete schema definition.
The application includes a comprehensive test suite with 97 tests covering:
- Admin Router (14 tests): Role management, user verification, audit logging, Clerk sync
- Security Tests (11 tests): Input length validation, SQL injection prevention, business logic enforcement, authorization
- Rate Limiting (12 tests): Token bucket algorithm, IP extraction, concurrent requests, time-based refill
- Weather Router (11 tests): METAR cache hit/miss, AVWX API fallback, favorite airport, mock data
- Flight Router (10 tests): CRUD operations, filtering, time calculations, float precision
- Preferences Router (10 tests): Theme/units management, Clerk metadata sync, validation, defaults
- Stats Router (10 tests): Hours by type/month aggregation, summary stats, edge cases, unauthenticated handling
- User Router (9 tests): Profile management, upsert logic, authentication
- Aircraft Router (7 tests): Fleet management, validation, soft delete, access control
- Dashboard Logic (3 tests): Status card logic, fleet vs stats distinction
Test Infrastructure:
- Mock tRPC context with Clerk auth simulation
- Database model mocks (Prisma client mocking)
- Audit logger and external service mocks
- Type-safe test utilities
Run tests with:
npm run test # Run all tests (97/97 passing β)
npm run test:ui # Interactive test UI
npm run test:coverage # Coverage reportThe easiest way to deploy this application is using Vercel:
- Push your code to a Git repository (GitHub, GitLab, or Bitbucket)
- Import your repository in Vercel
- Add all environment variables from your
.envfile - Deploy!
Vercel will automatically detect Next.js and configure the build settings.
- Create a production PostgreSQL database (recommended: Supabase)
- Run migrations:
npx prisma migrate deploy - Update your production
DATABASE_URLenvironment variable
Contributions are welcome! Please feel free to submit a Pull Request.
This project is private and proprietary.
For questions or issues, please open an issue in the repository.