Skip to content

Open official airport web forms prefilled (EGTF book-out, PPR, out-of-hours) - #16

Merged
roznet merged 1 commit into
mainfrom
feat/egtf-web-forms
Sep 11, 2026
Merged

roznet merged 1 commit into
mainfrom
feat/egtf-web-forms

Conversation

@roznet

@roznet roznet commented Sep 11, 2026

Copy link
Copy Markdown
Owner

Summary

Some airports take movements through their own web pages — EGTF (Fairoaks) now wants a book-out, a PPR, and an out-of-hours form. Rather than submitting on the pilot's behalf, the app opens the official page prefilled from the flight; the pilot checks it and taps the site's own Submit.

  • Server — web_form mapping type + POST /prefill: returns a fill plan (page URL + a value per input, keyed by the input's name). Keying by name means the same plan can drive a direct server-side submission later.
  • Mappings: redatlas_bookout / redatlas_ppr (one mapping per RedAtlas form, https://{site}.redatlas.co.uk/... — other RedAtlas airports are an icao_list entry away; per-airport extra questions via airport_fields), egtf_ooh_departure / egtf_ooh_arrival (Elementor, scoped to the right form on the shared page).
  • Return flight: book-outs get their return details from the first later flight landing back at the airport (new optional return_flight, has_return_flight flag). Separate from the connecting-flight search, which looks back for a departure.
  • Direction: forms can be pinned to departure/arrival (validated, and used for local flights).
  • Compatibility: web forms are only listed by GET /airports/{icao}?include_web=true; /airports never lists them, so older app builds are unaffected. /generate refuses web forms, /prefill refuses documents.
  • App: web forms appear in the airport's section for the side they cover, with Open PrefilledWebFormView (WKWebView, iOS + macOS). A banner reports filled fields and flags any not found on the page; Fill Again re-applies.
  • Refactor: pdf_filler's canonical values move into build_values(), shared with fill plans — generated documents are unchanged (all snapshots pass).

Testing

  • pytest: 182 passed. 2 failures are pre-existing on main and unrelated (TestPdfFillerLSGS::test_output_flattened, TestFrenchCustomsFiller::test_flattened).
  • New tests/unit/test_web_form.py + /prefill integration tests.
  • Fill script run against the live pages (headless Chromium, no submission): all fields on book-out (incl. return section, left enabled), PPR, and both out-of-hours forms take the right values and pass the pages' own validation.
  • iOS simulator and macOS builds succeed; tested end-to-end in the macOS app against the local dev server (book-out incl. return).

Notes

  • Out-of-hours times are filled in UK local time — the form doesn't say UTC or local; the rules are local, and the banner says so. Worth confirming with the tower.
  • Elementor field names (form_fields[field_…]) are generated and change if the form is rebuilt; the app flags fields it can't find.
  • Pilot = first crew member; phone/email from the responsible person.

🤖 Generated with Claude Code

https://claude.ai/code/session_01P3XXAkHdDjdoisPWZqmGaB

…-out, PPR, out-of-hours)

Some airports take movements through their own web pages rather than a
document. A new `web_form` mapping type describes such a page, and
POST /prefill answers with a fill plan: the page URL plus a value per
input, keyed by the input's name (so the same plan can drive a direct
submission later). The app opens the official page in a web view,
applies the plan with a generic script, and the pilot submits on the
airport's own site.

- RedAtlas book-out and PPR as one mapping each ({site} URL template),
  so other RedAtlas airports are an ICAO-list entry away
- Fairoaks out-of-hours departure/arrival (Elementor, local UK time)
- Book-out return details from the first later flight back to the
  airport (new optional return_flight on the request)
- Forms can be pinned to a direction; web forms are only listed for
  clients sending include_web, so older builds never see them
- pdf_filler's canonical values move into build_values(), shared with
  the fill plans (no change to generated documents)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P3XXAkHdDjdoisPWZqmGaB
@claude

claude Bot commented Sep 11, 2026

Copy link
Copy Markdown

Review

Went through the diff (Swift WebFormView/FlightEditView, the new /prefill endpoint, web_form.py, the mapping JSONs, and the design-doc updates). Overall this is well-scoped and well-tested (direction validation, return-flight dropping, transforms, checkbox ordering are all covered by unit/integration tests).

One correctness issue worth a look:

Return-flight lookup can silently skip a valid candidateFlightEditView.swift:892-903

```swift
let back: Flight? = {
if flight.destinationICAO == airport { return flight }
...
return allFlights
.filter { ... && $0.destinationICAO == airport }
.min { $0.departureDateTime < $1.departureDateTime }
}()
guard let back, hasTimes(back) else { return nil }
```

back is picked purely by earliest departureDateTime, and only then checked for having times filled in. If that chronologically-first candidate has empty departureTimeUTC/arrivalTimeUTC (e.g. a flight stub the pilot hasn't finished entering yet), the whole lookup bails to nil instead of trying the next later flight that does land back at the airport with times set. The same applies to the local-flight case (flight.destinationICAO == airport): if the very flight being booked out hasn't had its own arrival time filled in yet, hasReturnFlight-driven fields are silently dropped with no indication to the pilot that anything's missing — it just looks like the return section wasn't needed. Given the return-flight fields exist specifically to save the pilot re-entering data, consider filtering to hasTimes candidates before taking .min, or at least surfacing to the user when a return was expected but omitted.

Nothing else stood out — the direction validation (validation.py), the build_values/build_fill_plan split, the include_web gating for backwards compatibility, and the WKWebView fill script (checkbox click-before-fields ordering, flatpickr/jQuery-autocomplete handling, single-fill-after-first-load guard) all look correct.

🤖 Generated with Claude Code

@roznet
roznet merged commit 6ec78ff into main Sep 11, 2026
2 checks passed
@roznet
roznet deleted the feat/egtf-web-forms branch September 14, 2026 22:24
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