feat(mileage): mileage entries, per-mile rate card rate, invoice line type #277
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/pms-315-mileage-entries"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Add a first-class mileage entry that mirrors a time entry's FK shape and billing/approval lifecycle but swaps the hours axis for a distance axis (PMS-315 Phase 1, server side).
Migration 051 creates
mileage_entries(tenant-scoped, fail-closed RLS + FORCE + updated_at trigger attached explicitly since the 024/038 loops already ran), addsrate_cards.default_per_mile_rate, and widens theinvoice_lines.line_typeCHECK to admitmileage.New
mokosh-types::mileage_trackingDTOs (CreateMileageEntryRequest / UpdateMileageEntryRequest / MileageEntryResponse / MileageEntryFilter) reuse the time-trackingApprovalStatusandtickets::BillingStatus. Newmodules::mileage_trackingexposes CRUD under/api/v1/mileage-entries, gated by the time-tracking module and tenant-scoped end to end; a billable entry inherits the tenant default rate card's per-mile rate when no explicit rate is given and pricestotal_amount = distance_miles * rate_per_mile. Mileage has no timesheet gate, so a billable entry isready_to_billon creation.The invoice builder (
create_invoice_from_time_entries) now sweeps unbilled mileage entries alongside time entries: onemileageline per entry, descriptionMileage: <start> -> <end>(or bareMileagewhen both addresses are empty), and both flip tobilledin the same transaction.InvoiceLineType::Mileageadded.Frontend ACs (Log Time Hours/Mileage toggle, list badge, Rate Cards UI) live in the separate mokosh-clients repo and are out of scope for this repo; Phase 2 address-to-address routing is an optional follow-up.
Tested: new tests/mileage_tracking.rs (CRUD, rate inheritance, combined time+mileage invoice, cross-tenant isolation); full integration suite green.
#PMS-315
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com