Charter Quoting Platform
A charter quotation platform that turns multi-leg jet itineraries into branded PDF proposals in seconds.

Charter sales is a proposal business. Every enquiry, two passengers, Geneva to Nice on Friday, three aircraft options, has to come back to the customer as a presentable, priced document, and it has to come back fast, because charter customers shop between brokers. Producing those documents by hand means copying aircraft photos and specs into a layout tool, working out arrival times across timezones, numbering proposals, and keeping branding consistent across every agent.
The tool centralizes the fleet catalog, the airport database, pricing, and brand presentation into one console, so an agent can go from enquiry to a finished multi-page PDF proposal in a single screen. We designed and built the entire system: the NestJS API, the PostgreSQL data model, the PDF rendering engine, and the Next.js admin console.
The platform ships two document formats matched to how charter sales actually works, a condensed quick quotation for the fast first response, and a full proposal with cover page, personalized introduction letter, journey itinerary, and one presentation page per aircraft for the polished follow-up.
Proposals were the bottleneck of the sales process
Charter customers compare brokers, so the speed and polish of the first priced document often decides the deal. Assembling that document manually is slow and error-prone: agents copy aircraft imagery and specifications into layout tools, compute arrival times across origin and destination timezones by hand, track proposal numbers themselves, and inevitably drift from the brand's presentation standards.
The business needed one system that owned all the inputs, fleet data, airports, pricing, brand templates, and produced the output that actually matters: a consistent, branded, customer-ready PDF, generated fast enough to win the enquiry.

Treat the PDF as the product
The proposal document is what the customer actually sees, so the rendering pipeline got the most engineering attention. We built it on Handlebars page templates rendered through headless Chromium at exact A4 geometry, with brand fonts embedded and every aircraft image downloaded, recompressed, and inlined as data URIs, so the document renders identically wherever it is opened and never ships with broken images.
We designed for two speeds of selling: agents get both a full proposal (cover, introduction letter, itinerary, per-aircraft pages, closing page) and a quick quotation without the cover, matching the rhythm of fast first response followed by polished follow-up.
We also made data entry cheap. A fleet of aircraft with three photos each is tedious to key in, so the catalog supports bulk import from a single ZIP containing a spreadsheet and an images folder, with images matched to rows by filename, uploaded to cloud storage automatically, and per-row validation errors reported back to the agent.

From enquiry to finished proposal in one screen
An agent enters the customer's name, builds the itinerary leg by leg, searching a seeded database of over 26,000 airports through paginated, debounced dropdowns, and sets date, departure time, duration, and passenger count per leg. The system computes arrival times across origin and destination timezones automatically. The agent picks aircraft from the fleet with search-as-you-type, overriding price, year, currency, and remarks per aircraft, and attaching cabin features on the fly.
One click assembles the document server-side: cover, introduction letter, journey page, one presentation page per aircraft with exterior, interior, and floorplan imagery, and a closing page with contact details and legal disclaimer. Every proposal carries a sequential number. Because generation involves image downloads and browser rendering, the API streams live progress over Server-Sent Events, so the agent watches a real progress bar rather than a spinner.
Around the core workflow sits full management tooling: fleet CRUD with Excel export and ZIP bulk import, an airport directory, a reusable aircraft-features system, admin-managed user accounts with SMTP welcome emails, and a template screen where marketing edits the cover letter, cover image, and footer without a code release. A nightly job purges generated PDFs older than 30 days from storage and history, keeping document storage bounded by design.
Branded PDF proposal generation
Two document formats, a full multi-page proposal and a condensed quick quotation, rendered server-side at exact A4 geometry with embedded fonts and inlined imagery, streamed to the agent with live progress updates.
Multi-leg itinerary builder
Leg-by-leg flight construction with passenger counts, searchable airport lookups, and arrival times computed automatically across origin and destination timezones.
Fleet catalog with bulk import
Full aircraft CRUD with three image slots per aircraft, Excel export, and one-step ZIP import that matches spreadsheet rows to image files by filename and reports validation failures per row.
Airport directory
A database of 26,318 airports with IATA/ICAO codes, coordinates, and timezones, seeded from a bundled dataset and searchable from the console.
Self-service template branding
The proposal cover letter heading and body, cover image, and footer text are editable in the console, so the pitch changes without developer involvement.
Quotation history with automatic cleanup
Every generated proposal is recorded with customer, agent, proposal number, and file link; PDFs can be re-downloaded on demand, and a nightly job purges documents older than 30 days.






- 01
HTML-to-PDF through a real browser engine
Handlebars templates with shared partials are rendered by Puppeteer and headless Chromium at a fixed A4 viewport. Proposal pages are designed as normal HTML/CSS, so layout changes are a designer-level task and the output matches the preview pixel for pixel.
- 02
Asset inlining before render
Aircraft imagery is downloaded, recompressed with sharp, and embedded as base64 data URIs, with the brand font inlined the same way, generation never depends on external hosts being reachable mid-render.
- 03
Server-Sent Events for generation progress
PDF generation takes real time between image downloads and browser rendering, so the API streams percentage updates to the console instead of leaving agents staring at a frozen button.
- 04
Versioned NestJS API with migration-driven schema
A NestJS 10 REST API with Swagger documentation and global validation, over PostgreSQL via TypeORM with 18 incremental migrations, soft deletes throughout, and case-insensitive unique login backed by a generated column.
- 05
Database-backed session auth and S3 storage
Email/password login with bcrypt and database-backed bearer sessions with expiry and invalidation; generated PDFs and catalog images upload server-side to AWS S3, with presigned URLs for direct browser uploads of template imagery.
- A single console takes a charter agent from enquiry to a finished, consistently branded multi-page PDF proposal, with live progress feedback.
- Two proposal formats cover both fast first responses and polished follow-ups.
- Marketing controls the proposal's cover letter, cover image, and footer without a code release.
- Fleet onboarding drops from many manual forms to one ZIP upload with per-row error reporting.
- A complete, numbered proposal history is maintained with automatic 30-day document cleanup, keeping storage bounded without anyone thinking about it.