# jeslor/airline_app architecture

> Architecture diagram of the GitHub repository jeslor/airline_app, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-08-11). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/jeslor/airline_app
- Repository: https://github.com/jeslor/airline_app

## Overview

#### Purpose and entry points
Quencer Airlines is a full-stack flight-search and booking platform. The React client starts at `client/src/main.tsx` and composes the booking UI in `client/src/App.tsx`. The Express API starts at `server/server.js`, mounting flight, booking, and Stripe-webhook routes.

#### Client booking orchestration
A React Context owns cross-step flight/booking state in `client/src/components/providers/FlightProvider.tsx`. Search, selection, passenger details, payment, and completion are represented by `client/src/components/forms/SearchFlights.tsx`, `client/src/components/BookingFlights/availableFlights.tsx`, and `client/src/components/booking/FinalizeBooking.tsx`. Client API calls and Stripe browser setup are isolated in `client/src/lib/api.ts` and `client/src/lib/stripe.ts`.

#### Search and signed-offer boundary
The client submits validated route/date inputs, then renders server-returned offers. Server routing and request validation are split across `server/routes/flights.routes.js`, `server/controllers/flights.controller.js`, and `server/schemas/flightSearch.schema.js`. Google Generative AI produces dynamic flight data through `server/configs/GoogleAIService.js`; each offer is HMAC-signed by `server/utils/offerSigning.js`. Signed offer fields form the trust boundary: the client may display/select offers but cannot authoritatively set prices.

#### Booking and payment lifecycle
Booking submission enters through `server/routes/bookings.routes.js` and `server/controllers/bookings.controller.js`, with payload validation in `server/schemas/booking.schema.js`. The server verifies signed offers, computes the authoritative total, persists a pending booking through `server/utils/prismaClient.js`, and creates a Stripe PaymentIntent via `server/utils/stripeClient.js`. The client confirms that intent with Stripe Elements, then polls booking status by reference.

#### Webhook-driven fulfillment
Stripe—not the browser—is the payment source of truth. `server/routes/webhooks.routes.js` delegates payment events to `server/controllers/webhooks.controller.js`. Success handling must be idempotent: it confirms the stored booking, generates booking/ticket identifiers and seats through `server/utils/ticketAndBookingGenerator.js`, then triggers ticket delivery. This separates asynchronous payment settlement from synchronous booking initiation.

#### Ticket generation and delivery
Confirmed bookings are rendered into branded multi-segment PDF e-tickets using Puppeteer. Ticket HTML and branding reside in `server/constants/ticketTemplate.js` and `server/constants/branding.js`; PDF rendering is in `server/utils/pdfHelper.js`. `server/utils/ticketDelivery.js` sends the generated attachment through the Resend client in `server/utils/resendClient.js`. Puppeteer requires Chromium plus Render system dependencies declared in `server/apt.txt`.

#### Persistence, visualization, and deployment
MongoDB is accessed through Prisma, with the booking data model in `server/prisma/schema.prisma`. The client also provides a non-transactional discovery/visualization surface: interactive Three.js globe components at `client/src/components/Globe/GlobeWrapper.tsx` and `client/src/components/Globe/Globe.tsx`, backed by airport/map assets. Deployment is split: Vite/React on Vercel and Node/Express on Render; backend external dependencies are MongoDB, Google Generative AI, Stripe webhooks, Resend, and Puppeteer Chromium.

Main entry points: [`server/server.js`](https://github.com/jeslor/airline_app/blob/main/server/server.js) (API entry), [`server/routes/bookings.routes.js`](https://github.com/jeslor/airline_app/blob/main/server/routes/bookings.routes.js) (Booking initiation API), [`server/routes/webhooks.routes.js`](https://github.com/jeslor/airline_app/blob/main/server/routes/webhooks.routes.js) (Stripe webhook handler), [`client/src/App.tsx`](https://github.com/jeslor/airline_app/blob/main/client/src/App.tsx) (Booking UI)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_client["React client"]
  node_client_entry["Client entry<br/>Vite bootstrap<br/>[main.tsx]"]
  node_booking_ui["Booking UI<br/>React screens<br/>[App.tsx]"]
  node_flight_state["Flight state<br/>React context<br/>[FlightProvider.tsx]"]
  node_booking_steps["Search &amp; booking steps<br/>React forms<br/>[SearchFlights.tsx]"]
  node_finalize_booking["Payment completion<br/>React checkout"]
  node_client_api["API client<br/>HTTP client<br/>[api.ts]"]
  node_stripe_browser["Stripe Elements<br/>browser payment SDK<br/>[stripe.ts]"]
  node_globe["Airport globe<br/>Three.js visualization<br/>[GlobeWrapper.tsx]"]
end

subgraph group_api["Express API"]
  node_server_entry["API entry<br/>Express server<br/>[server.js]"]
  node_flight_api["Flight search API<br/>route/controller/validation<br/>[flights.routes.js]"]
  node_ai_offers["Dynamic flight offers<br/>Google AI integration<br/>[GoogleAIService.js]"]
  node_offer_signing["Signed offers<br/>HMAC trust boundary<br/>[offerSigning.js]"]
  node_booking_api["Booking initiation API<br/>route/controller/validation<br/>[bookings.routes.js]"]
  node_bookings_db[("Bookings<br/>Prisma/MongoDB model<br/>[schema.prisma]")]
  node_stripe_intents["PaymentIntent creation<br/>Stripe server client<br/>[stripeClient.js]"]
end

subgraph group_fulfillment["Payment &amp; fulfillment"]
  node_webhook_api["Stripe webhook handler<br/>route/controller<br/>[webhooks.routes.js]"]
  node_ticket_generator["Ticket &amp; seat generation<br/>booking fulfillment"]
  node_pdf_ticket["PDF e-ticket rendering<br/>Puppeteer renderer<br/>[pdfHelper.js]"]
  node_ticket_delivery["Ticket delivery<br/>email delivery<br/>[ticketDelivery.js]"]
end

subgraph group_external["External services"]
  node_google_ai{{"Google Generative AI<br/>offer data provider"}}
  node_stripe{{"Stripe<br/>payment authority"}}
  node_mongodb[("MongoDB<br/>database")]
  node_resend{{"Resend<br/>email provider"}}
  node_chromium["Puppeteer Chromium<br/>PDF runtime<br/>[apt.txt]"]
end

node_client_entry -->|"mounts"| node_booking_ui
node_booking_ui -->|"uses"| node_flight_state
node_flight_state -->|"drives"| node_booking_steps
node_booking_steps -->|"searches and books"| node_client_api
node_finalize_booking -->|"confirms intent"| node_stripe_browser
node_client_api -->|"HTTP"| node_server_entry
node_booking_ui -.->|"discovery view"| node_globe
node_server_entry -->|"mounts"| node_flight_api
node_server_entry -->|"mounts"| node_booking_api
node_server_entry -->|"mounts"| node_webhook_api
node_flight_api -->|"generates offers"| node_ai_offers
node_ai_offers -->|"requests data"| node_google_ai
node_flight_api -->|"signs offers"| node_offer_signing
node_booking_api -->|"verifies offer"| node_offer_signing
node_booking_api -->|"creates pending booking"| node_bookings_db
node_bookings_db -->|"persists via Prisma"| node_mongodb
node_booking_api -->|"creates intent"| node_stripe_intents
node_stripe_intents -->|"PaymentIntent"| node_stripe
node_stripe_browser -->|"payment confirmation"| node_stripe
node_stripe -->|"settlement event"| node_webhook_api
node_webhook_api -->|"confirms idempotently"| node_bookings_db
node_webhook_api -->|"fulfills booking"| node_ticket_generator
node_ticket_generator -->|"renders ticket"| node_pdf_ticket
node_pdf_ticket -->|"runs on"| node_chromium
node_pdf_ticket -->|"PDF attachment"| node_ticket_delivery
node_ticket_delivery -->|"sends email"| node_resend

click node_client_entry "https://github.com/jeslor/airline_app/blob/main/client/src/main.tsx"
click node_booking_ui "https://github.com/jeslor/airline_app/blob/main/client/src/App.tsx"
click node_flight_state "https://github.com/jeslor/airline_app/blob/main/client/src/components/providers/FlightProvider.tsx"
click node_booking_steps "https://github.com/jeslor/airline_app/blob/main/client/src/components/forms/SearchFlights.tsx"
click node_finalize_booking "https://github.com/jeslor/airline_app/blob/main/client/src/components/booking/FinalizeBooking.tsx"
click node_client_api "https://github.com/jeslor/airline_app/blob/main/client/src/lib/api.ts"
click node_stripe_browser "https://github.com/jeslor/airline_app/blob/main/client/src/lib/stripe.ts"
click node_globe "https://github.com/jeslor/airline_app/blob/main/client/src/components/Globe/GlobeWrapper.tsx"
click node_server_entry "https://github.com/jeslor/airline_app/blob/main/server/server.js"
click node_flight_api "https://github.com/jeslor/airline_app/blob/main/server/routes/flights.routes.js"
click node_ai_offers "https://github.com/jeslor/airline_app/blob/main/server/configs/GoogleAIService.js"
click node_offer_signing "https://github.com/jeslor/airline_app/blob/main/server/utils/offerSigning.js"
click node_booking_api "https://github.com/jeslor/airline_app/blob/main/server/routes/bookings.routes.js"
click node_bookings_db "https://github.com/jeslor/airline_app/blob/main/server/prisma/schema.prisma"
click node_stripe_intents "https://github.com/jeslor/airline_app/blob/main/server/utils/stripeClient.js"
click node_webhook_api "https://github.com/jeslor/airline_app/blob/main/server/routes/webhooks.routes.js"
click node_ticket_generator "https://github.com/jeslor/airline_app/blob/main/server/utils/ticketAndBookingGenerator.js"
click node_pdf_ticket "https://github.com/jeslor/airline_app/blob/main/server/utils/pdfHelper.js"
click node_ticket_delivery "https://github.com/jeslor/airline_app/blob/main/server/utils/ticketDelivery.js"
click node_chromium "https://github.com/jeslor/airline_app/blob/main/server/apt.txt"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_client_entry,node_booking_ui,node_flight_state,node_booking_steps,node_finalize_booking,node_client_api,node_stripe_browser,node_globe toneBlue
class node_server_entry,node_flight_api,node_ai_offers,node_offer_signing,node_booking_api,node_bookings_db,node_stripe_intents toneAmber
class node_webhook_api,node_ticket_generator,node_pdf_ticket,node_ticket_delivery toneMint
class node_google_ai,node_stripe,node_mongodb,node_resend,node_chromium toneRose
```

## Components

### React client

- [Client entry](https://github.com/jeslor/airline_app/blob/main/client/src/main.tsx): Vite bootstrap · `client/src/main.tsx`
- [Booking UI](https://github.com/jeslor/airline_app/blob/main/client/src/App.tsx): React screens · `client/src/App.tsx`
- [Flight state](https://github.com/jeslor/airline_app/blob/main/client/src/components/providers/FlightProvider.tsx): React context · Owns search and cross-step booking state. · `client/src/components/providers/FlightProvider.tsx`
- [Search & booking steps](https://github.com/jeslor/airline_app/blob/main/client/src/components/forms/SearchFlights.tsx): React forms · `client/src/components/forms/SearchFlights.tsx`
- [Payment completion](https://github.com/jeslor/airline_app/blob/main/client/src/components/booking/FinalizeBooking.tsx): React checkout · `client/src/components/booking/FinalizeBooking.tsx`
- [API client](https://github.com/jeslor/airline_app/blob/main/client/src/lib/api.ts): HTTP client · `client/src/lib/api.ts`
- [Stripe Elements](https://github.com/jeslor/airline_app/blob/main/client/src/lib/stripe.ts): browser payment SDK · `client/src/lib/stripe.ts`
- [Airport globe](https://github.com/jeslor/airline_app/blob/main/client/src/components/Globe/GlobeWrapper.tsx): Three.js visualization · Non-transactional discovery surface. · `client/src/components/Globe/GlobeWrapper.tsx`

### Express API

- [API entry](https://github.com/jeslor/airline_app/blob/main/server/server.js): Express server · `server/server.js`
- [Flight search API](https://github.com/jeslor/airline_app/blob/main/server/routes/flights.routes.js): route/controller/validation · `server/routes/flights.routes.js`
- [Dynamic flight offers](https://github.com/jeslor/airline_app/blob/main/server/configs/GoogleAIService.js): Google AI integration · `server/configs/GoogleAIService.js`
- [Signed offers](https://github.com/jeslor/airline_app/blob/main/server/utils/offerSigning.js): HMAC trust boundary · Server-authorized offer prices and fields. · `server/utils/offerSigning.js`
- [Booking initiation API](https://github.com/jeslor/airline_app/blob/main/server/routes/bookings.routes.js): route/controller/validation · `server/routes/bookings.routes.js`
- [Bookings](https://github.com/jeslor/airline_app/blob/main/server/prisma/schema.prisma): Prisma/MongoDB model · Stores pending and confirmed bookings. · `server/prisma/schema.prisma`
- [PaymentIntent creation](https://github.com/jeslor/airline_app/blob/main/server/utils/stripeClient.js): Stripe server client · `server/utils/stripeClient.js`

### Payment & fulfillment

- [Stripe webhook handler](https://github.com/jeslor/airline_app/blob/main/server/routes/webhooks.routes.js): route/controller · Idempotently settles payment events. · `server/routes/webhooks.routes.js`
- [Ticket & seat generation](https://github.com/jeslor/airline_app/blob/main/server/utils/ticketAndBookingGenerator.js): booking fulfillment · `server/utils/ticketAndBookingGenerator.js`
- [PDF e-ticket rendering](https://github.com/jeslor/airline_app/blob/main/server/utils/pdfHelper.js): Puppeteer renderer · Renders branded multi-segment tickets. · `server/utils/pdfHelper.js`
- [Ticket delivery](https://github.com/jeslor/airline_app/blob/main/server/utils/ticketDelivery.js): email delivery · `server/utils/ticketDelivery.js`

### External services

- **Google Generative AI**: offer data provider
- **Stripe**: payment authority · Sends authoritative settlement webhooks.
- **MongoDB**: database
- **Resend**: email provider
- [Puppeteer Chromium](https://github.com/jeslor/airline_app/blob/main/server/apt.txt): PDF runtime · Render dependencies are declared in server/apt.txt. · `server/apt.txt`

## Connections

- Client entry → Booking UI: mounts
- Booking UI → Flight state: uses
- Flight state → Search & booking steps: drives
- Search & booking steps → API client: searches and books
- Payment completion → Stripe Elements: confirms intent
- API client → API entry: HTTP
- Booking UI → Airport globe: discovery view
- API entry → Flight search API: mounts
- API entry → Booking initiation API: mounts
- API entry → Stripe webhook handler: mounts
- Flight search API → Dynamic flight offers: generates offers
- Dynamic flight offers → Google Generative AI: requests data
- Flight search API → Signed offers: signs offers
- Booking initiation API → Signed offers: verifies offer
- Booking initiation API → Bookings: creates pending booking
- Bookings → MongoDB: persists via Prisma
- Booking initiation API → PaymentIntent creation: creates intent
- PaymentIntent creation → Stripe: PaymentIntent
- Stripe Elements → Stripe: payment confirmation
- Stripe → Stripe webhook handler: settlement event
- Stripe webhook handler → Bookings: confirms idempotently
- Stripe webhook handler → Ticket & seat generation: fulfills booking
- Ticket & seat generation → PDF e-ticket rendering: renders ticket
- PDF e-ticket rendering → Puppeteer Chromium: runs on
- PDF e-ticket rendering → Ticket delivery: PDF attachment
- Ticket delivery → Resend: sends email
