Skip to content

feat(glider): first-class launches + EASA sailplane (SPL) logbook export - #71

Open
fjaeckel wants to merge 8 commits into
mainfrom
feat/glider-spl-operations
Open

feat(glider): first-class launches + EASA sailplane (SPL) logbook export#71
fjaeckel wants to merge 8 commits into
mainfrom
feat/glider-spl-operations

Conversation

@fjaeckel

@fjaeckel fjaeckel commented Jun 9, 2026

Copy link
Copy Markdown
Owner

Summary

Phase G1 of the glider-operations-and-spl spec, plus the separate-logbook output for sailplane pilots. Branched off feat/currency-rule-registry-engine, so this PR targets that branch.

A glider flight is launched (not "taken off"), and EASA SPL recency (FCL.140.S) is counted in launches, not landings. Until now the codebase used the landings count as a proxy. This PR makes launches a first-class fact and gives sailplane pilots a logbook artefact they can hand an examiner.

Changes

Data model

  • Migration 000041: launches (INTEGER NOT NULL DEFAULT 0), release_altitude_m, release_altitude_ref with CHECK constraints (ref ∈ {AGL, AMSL}; release altitude requires a launch method). Backfill makes existing glider flights inherit their landings count as launches, so SPL currency totals are unchanged.
  • Launch methods expanded: winch / aerotow / self-launch + bungee + auto-tow.

Currency

  • SPL recency now counts real launches via a new mLaunches metric / Progress.Launches instead of using landings as a proxy. Per-method launch currency extended to the new methods. TMG continues to use landings (it's a powered flight).

Export

  • New PDF format=glider: EASA sailplane logbook with launch (W/A/S/B/T), # launches, and release-altitude columns. Respects logbookLicenseId, so a pilot's sailplane logbook prints separately from their aeroplane logbook.

Handlers

  • Launch data kept consistent with the DB constraint (no launch method → no launches/release altitude; default 1 launch when a method is present).

Tests

  • Unit: launchAbbrev, fmtReleaseAltitude, renderGlider (PDF), updated SPL recency tests.
  • e2e: glider launch round-trip incl. launches/release altitude across all 5 methods; glider PDF format.
  • go test ./internal/... ./pkg/... and targeted e2e (TestFlightGliderLaunch|TestExportPDFFormats|TestCurrency) green against a freshly migrated stack.

Out of scope (later phases)

LAPL(S)/FAA_GLIDER license types, sites table for ICAO-less fields, .igc/.cup import, lifetime passenger threshold.

Note: API-first — OpenAPI updated and server types regenerated before implementation.

fjaeckel added 3 commits June 9, 2026 22:29
…ngine

Replace the hand-coded per-authority/per-class switch bodies with a generic,
Go-native rule engine. Regulatory data (lookback windows, experience
thresholds, requirement names/units/messages, rule descriptions, display keys)
now lives in declarative ratingRule values; the per-rule status/message prose
stays in each rule's finalize closure.

- Add engine.go: metric vocabulary, reqSpec/buildReqs, windowSpec
  (rollingNow | precedingExpiry), progressScope (byClass | byClassOverride |
  all), ratingRule + ratingRuntime, and the evalRatingRule driver.
- Convert EASA/FAA/GermanUL/Other evaluators to thin adapters that select a
  rule and run it through the engine; delete the legacy switch bodies.

The FlightDataProvider interface is unchanged — rules declare what to
aggregate (scope + window); the provider owns how to query it. The public
surface and all wire types are preserved, so main.go wiring and the existing
currency test suite compile and assert unchanged.

Behaviour is preserved bit-for-bit (parity-tested by the existing unit suite
and the TestCurrency e2e suite against the real Postgres-backed provider).
No OpenAPI/wire changes.
Phase G1 of the glider/SPL operations spec, plus the separate-logbook
output for sailplane pilots.

Data model
- Migration 000041: launches (INTEGER), release_altitude_m,
  release_altitude_ref with CHECKs (ref in AGL/AMSL; release altitude
  requires a launch method). Backfill makes existing glider flights
  inherit their landings count as launches so SPL currency is unchanged.
- Expanded launch methods: winch/aerotow/self-launch + bungee + auto-tow.

Currency
- SPL recency (FCL.140.S) now counts real launches via a new mLaunches
  metric / Progress.Launches instead of using landings as a proxy.
  Per-method launch currency extended to the new methods. TMG still
  uses landings (powered).

Export
- New PDF format=glider: EASA sailplane logbook with launch (W/A/S/B/T),
  # launches, and release-altitude columns. Respects logbookLicenseId so
  a pilot's sailplane logbook prints separately from their aeroplane one.

Handlers keep launch data consistent with the DB constraint (no launch
method -> no launches/release altitude; default 1 launch otherwise).

Tests: unit (launchAbbrev, fmtReleaseAltitude, renderGlider) + e2e
(glider launch round-trip incl. launches/release altitude, glider PDF
format). go test ./internal/... ./pkg/... and targeted e2e all green.
@fjaeckel
fjaeckel changed the base branch from feat/currency-rule-registry-engine to main June 10, 2026 08:12
fjaeckel added 5 commits June 10, 2026 10:28
…tions

# Conflicts:
#	internal/api/generated/server.go
#	internal/api/generated/spec.go
#	internal/api/generated/types.go
#	internal/service/currency/easa.go
#	internal/service/currency/engine.go
…tions

# Conflicts:
#	internal/api/generated/spec.go
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant