← Back to projects
Summary

Before a flight the crew has to prove the aircraft is loaded inside its certified envelope, and getting that arithmetic wrong is a safety event rather than a bug report. Every tail in Azimuth can carry a weight-and-balance profile made of its empty mass, fuel tanks, loading stations, and one or more certified centre-of-gravity envelopes. A planner takes that profile plus an actual load and computes total weight, moment, and CG, checks it against the selected envelope, and can save the result onto a reservation so it is ready at check-in.

Stack

What it's built with.

TypeScriptPure Functional CoreReact (live recompute)Server ActionsChartingPostgreSQL (jsonb)
Details

How it works.

One module, two callers

The requirement pulls in two directions. The planner has to feel immediate, recomputing as gallons and passenger weights are typed, which argues for doing the math in the browser. The stored result has to be trustworthy, which argues for doing it on the server. Implementing it twice would satisfy both and introduce the worst possible bug class, where the number the crew saw and the number the system kept are different and nothing reports an error.

Writing the calculation as a pure function with no dependencies and no side effects makes the question moot. The client imports it and runs it on every keystroke, the server imports the same function and re-runs it before writing, and there is exactly one definition of what the aircraft weighs. The profile lives as structured jsonb on the aircraft and a saved load as jsonb on the reservation, so the inputs that produced a result are stored alongside it.

Highlights

The things I'm proudest of.

  • ▹The entire computation is one pure, dependency-free module, imported unchanged by the client planner for instant recompute as the crew types and by the server actions for an authoritative recompute before persistence. The same math runs in both places by construction rather than by two implementations agreeing.
  • ▹The client's numbers are never trusted for storage. Live recompute exists for feedback; what gets written to the database is always recomputed server-side, which is the only version that matters if the two ever disagree.
  • ▹Certified envelopes are modelled as interpolated limits rather than a single box, resolving the permitted forward and aft arm at a given weight by linear interpolation so an envelope with a stepped or tapered shape is evaluated correctly instead of approximated.
  • ▹Units are fixed and stated explicitly at the module boundary (pounds, inches aft of datum, pound-inches, US gallons), since silent unit drift is the classic way this category of calculation goes wrong.
  • ▹A planned load can be attached to a specific booking and cleared again, gated on scheduling write access plus a booking-ownership rule, so the plan travels with the reservation to the dispatch desk.
  • ▹Access is capability-gated in both directions: using a profile requires fleet read, defining or editing one requires fleet write, and an aircraft with no profile shows a setup path only to someone who could actually create it.