Baseleg Docs
Domain · Lite contexts / Billing · Baseleg Docs
v1 lite

Billing

v1 lite — currently a stub. Only what MVP needs (recording raw Usage Events) is built; charge tracking and invoicing are designed below but not implemented.

Packages: packages/domain/billing, packages/application/billing

Purpose

The Billing context will track the financial relationship between the organisation and its people. Today it does exactly one thing: records Usage Events (raw hours-flown facts) so that future charge calculation has an input to work from. Charge Items, Invoice Drafts, and the invoice lifecycle described below are a design, not a build — packages/application/billing is currently export {} and db/schema/billing.ts has only the usage_events table.

Key entities

Implemented

Usage event

The raw, unpriced usage fact recorded automatically when a Scheduling Flight completes — hours flown per meter type, computed as an end-minus-start delta from the Flight’s Checkout/Return meter readings. Written via the UsageEventRecorder port from returnBooking; Billing does not call into Scheduling, only receives this write.

Key attributes:

  • id — unique identifier
  • flightId — the Flight this usage was computed from (FlightId)
  • personId — the person who flew (PersonId)
  • aircraftId — the aircraft used (AircraftId)
  • hobbsHours / tachHours — hours flown per meter type; either may be null if that meter wasn’t recorded, but at least one must be present
  • occurredAt — when the Flight completed
  • createdAt — when the event was recorded

Persisted (usage_events table, UsageEventRecorderD1) but not yet surfaced anywhere — it’s the input a future Billing pass will use to compute a Charge Item, not a Charge Item itself. No rate, price, or amount is attached at this stage.

Planned — not yet implemented

The two entities below have no domain type, no application use case, and no schema yet. They’re recorded here as the intended design for whenever Billing moves past the usage-event stub, not as a description of current behaviour.

Charge item (aggregate root or entity)

A single billable line item against a Person. The atomic unit of billing.

Key attributes:

  • id — unique identifier
  • personId — the person being charged (PersonId)
  • bookingId — optional reference to the Booking that generated the charge (BookingId | null)
  • description — human-readable description (e.g. C172 ZK-ABC — 1.2 hrs at $150/hr)
  • quantity — amount or duration (e.g. hours flown)
  • unitPrice — price per unit in cents (avoids floating-point currency issues)
  • total — computed: quantity × unitPrice
  • invoiceId — null until added to an Invoice Draft
  • createdAt — when the charge was recorded

Invoice draft

An un-issued invoice accumulating Charge Items for a Person.

Key attributes:

  • id — unique identifier
  • personId — the invoice recipient (PersonId)
  • lineItems — list of ChargeItemId references
  • subtotal — sum of all line item totals
  • statusdraft | issued | void
  • createdAt — draft creation timestamp
  • issuedAt — null until issued

Domain rules

Implemented:

  1. A Usage Event’s hours-flown delta must not be negative (an end reading below the start reading is rejected), and at least one meter type must have a complete start/end pair.

Planned (Charge Item / Invoice Draft, not yet implemented): 2. A Charge Item must reference an active Person. 3. Charge Items cannot be modified once added to an issued Invoice. 4. An Invoice Draft may be edited freely before issuance. 5. Once issued, an Invoice transitions to issued and is immutable; corrections require a new invoice or credit note. 6. All monetary values are stored in the smallest currency unit (e.g. cents).

Key use cases

Implemented:

  • recordUsageEvent — record a raw hours-flown fact, called by returnBooking.

Planned (not yet implemented):

  • recordChargeItem — create a Charge Item against a Person (optionally linked to a Booking).
  • createInvoiceDraft — create a new draft Invoice for a Person.
  • addChargeToInvoice — attach a Charge Item to an existing Invoice Draft.
  • issueInvoice — finalise and issue an Invoice Draft.
  • voidInvoice — void a draft or issued invoice.

Cross-context relationships

ContextUsage
PeopleReferences PersonId for the charge/invoice recipient
SchedulingCharge Items may reference BookingId to link charges to bookings; receives Usage Events written via the UsageEventRecorder port (Scheduling writes, Billing does not read back)
NotificationsInvoice issuance triggers a notification to the Person