GrayPane helps travelers check available flights, monitor price trends, plan upcoming trips, and create personalized alerts. The application is built with Next.js 15, React 19, Supabase authentication, a PostgreSQL database via Drizzle ORM, Apple MapKit visualizations, Tailwind CSS, and TypeScript.
- Search for flights and review route availability in real time with comprehensive filtering.
- Track fare changes and set alert thresholds for routes of interest.
- Search award flight availability via seats.aero integration with async processing.
- Plan itineraries with Supabase-backed user dashboards.
- Create, edit, and manage alert rules with validation safeguards.
- Automated alert processing with Cloudflare Workers and scheduled email notifications.
- Explore airports with Apple MapKit maps and responsive Tailwind UI components.
- Frontend: Next.js 15, React 19, Tailwind CSS, Radix UI primitives, next-themes, Sonner, tRPC.
- Backend: Next.js Server Actions, tRPC API layer, Supabase SSR client, Drizzle ORM.
- Workers: Cloudflare Workers with Workflows and Queues for alert processing, fully decoupled from the Next.js app.
- Database: PostgreSQL with prefixed ULID identifiers.
- Notifications: Resend for email delivery, custom templates.
- Monitoring: Sentry for error tracking and performance monitoring.
- Tooling: TypeScript, Bun test runner with happy-dom, Biome formatter/linter, Bun runtime.
- Install Bun for dependency management and scripts.
- Copy
.env.exampleto.env.localand populate the required variables validated by@t3-oss/env-nextjs.
- Install dependencies:
bun install - Run the development server:
bun run dev - Open
http://localhost:3000to use Flights Tracker.
bun run devβ Start the Turbopack development server.bun run buildβ Produce an optimized production bundle.bun startβ Serve the production build.
bun testβ Execute all tests with Bun's built-in test runner.bun run test:watchβ Run tests in watch mode.bun run test:fliβ Run fli integration tests with extended timeout.bun run test:workersβ Run Cloudflare Worker tests (43 tests).bun run test:workers:watchβ Run worker tests in watch mode.
bun run lintβ Check code style with Biome.bun run formatβ Format the codebase with Biome.
bun run worker:devβ Start worker with local development server.bun run worker:deployβ Deploy worker to Cloudflare.bun run worker:tailβ Stream live logs from production worker.bun run trigger:alertsβ Manually trigger alert processing (production).bun run trigger:alerts:localβ Manually trigger alert processing (local).
- Schema definition:
src/db/schema.ts - Database configuration:
drizzle.config.ts - Migrations directory:
./migrations - Commands:
bun run db:generateβ Generate migration files from schema changes.bun run db:pushβ Push schema updates directly to the development database.bun run db:migrateβ Apply pending migrations.bun run db:studioβ Open Drizzle Studio for database exploration.
tRPC Architecture: End-to-end type-safe API with:
- Server routers in
src/server/routers/for alerts, flights, airports, and seats.aero - React Query integration via
@trpc/react-queryfor client-side data fetching - Automatic error handling and validation with Zod schemas
- Real-time subscriptions support
Drizzle ORM manages PostgreSQL entities:
- Core tables:
airport,airline,alertwith JSONB filters - Workers tables:
seats_aero_search_request,seats_aero_availability_trip - Notification table for email tracking and rate limiting
Supabase handles authentication with SSR support. Middleware in src/middleware.ts to validate sessions and enforce public-route access rules.
Core Services:
src/core/alerts-service.ts- High-level alert business logicsrc/core/alerts-db.ts- Database operations for alertssrc/core/seats-aero.db.ts- Seats.aero data managementsrc/core/filters.ts- Zod schemas for alert filters (versioned)src/lib/notifications/- Email templates and delivery system
Worker Adapters:
src/workers/adapters/- Thin wrappers around core servicessrc/workers/utils/- Worker-specific utilities (logger, Sentry, Supabase client wrappers)
Automated alert processing runs on Cloudflare Workers with:
- Cron Triggers: Every 6 hours (00:00, 06:00, 12:00, 18:00 UTC)
- Workflows: Durable execution with automatic retries and state persistence
- Queues: Process up to 10 users concurrently with auto-scaling
- Email Scheduling: Sends daily emails between 6-9 PM UTC, max once per 24 hours
- Monitoring: Full Sentry integration for error tracking and performance monitoring
- Testing: Comprehensive test suite with 43 passing tests
- Performance: Optimized with parallel async operations throughout
See docs/workflows.md for complete deployment and monitoring guide.
Reusable components reside in src/components/ui, while custom features like airport-search and airport-map integrate Apple MapKit and Tailwind styling. Path alias @/* maps to ./src/* for cleaner imports.
DATABASE_URLβ PostgreSQL connection string.NEXT_PUBLIC_SUPABASE_URLβ Supabase project URL.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEYβ Supabase anon key.SUPABASE_SECRET_KEYβ Supabase service role key.NEXT_PUBLIC_MAPKIT_TOKENβ Apple MapKit JS token.WORKER_URLβ Cloudflare Workers URL for seats.aero searches.WORKER_API_KEYβ Authentication key for worker endpoints.
DATABASE_URLβ PostgreSQL connection string.RESEND_API_KEYβ Resend email service API key.SUPABASE_URLβ Supabase project URL.SUPABASE_SERVICE_ROLE_KEYβ Supabase service role key.SEATS_AERO_API_KEYβ Seats.aero API key.WORKER_API_KEYβ API key for authenticating manual triggers.SENTRY_DSNβ Sentry project DSN (optional but recommended).
Tests run with Bun's built-in test runner in a happy-dom environment. Global setup, mocks, and database stubs are configured in src/test/setup.ts.
Comprehensive test suite for Cloudflare Workers with 43 passing tests covering:
- Utils (logger, user fetching, flights search, sentry)
- Adapters (alerts-db, alert-processing)
- Workflows (check-flight-alerts, process-flight-alerts)
- Handlers (scheduled, queue, fetch)
- E2E flow validation
Run with bun run test:workers - all tests execute in under 100ms without requiring Cloudflare Workers runtime.