Add Aeromexico (AM) load integration
AM exposes a public Sabre GetPassengerListRQ proxy via AWS API Gateway —
no auth, no API key — used by the consumer app's flight-status widget.
The endpoint returns per-cabin authorized/available plus full standby +
upgrade passenger lists with isStaff flag, numeric priority, fare class,
position movement, and PII (matching what we get from AA but with
better cabin capacity data).
Implementation:
- AirlineLoadService.fetchAeromexicoLoad: parallel GETs against
/rb/passengerliststandby and /rb/passengerlistupgrade, merging
cabin info + per-list passengers into a single FlightLoad. Headers
channel=web / flow=CHECKIN extracted from the AM APK Constant.smali.
Cabin codes Y/C/P/F mapped to readable names (Economy / Clase Premier /
Premier One / First).
- 4-digit zero-padding of the operating flight code (server validates
^[0-9]{4}$).
- "NONE LISTED" warning treated as nil (snapshot outside T-1d/T+2d
window or no pax yet); explicit log so future failures are
diagnosable.
Test infrastructure:
- Added test_AM_aeromexico using MEX/GDL/MTY/CUN hubs.
- Cascading fallback in runAirlineLoadTest: try the route-explorer
discovered flight first; if it returns nil (typical for AM Connect
regionals that aren't in Sabre), fall back to the known-daily flight
(AM0058 MEX-MTY). Pattern useful for any future carrier whose
regional ops don't show up in the load system.
- knownDailyFlights extended with AM0058 MEX-MTY.
Docs:
- AIRLINE_INTEGRATION_GUIDE: AM status row + full section 5b with
endpoint params, response shape, snapshot window timing, failure
modes, cabin code mapping, regional carrier caveat.
Test run 2026-05-26:
✅ AA, AM (cabins=1 upgrade=1), AS, B6, EK, KE, UA ⏭️ XE
7 passing, 1 skipped, 0 failures, 12s total.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,7 @@ Drop-in reference for integrating flight load / seat availability data from 11 a
|
||||
| B6 | ✅ Status-only | Confirms flight exists; no load data without check-in session |
|
||||
| EK | ✅ Status-only | Confirms flight exists; load data requires PNR |
|
||||
| KE | ✅ Working | Returns seat count only (no capacity) |
|
||||
| AM | ✅ Working | Public AWS gateway Sabre proxy. Returns per-cabin `authorized`+`available` + full standby/upgrade passenger lists with `isStaff` flag and priority. Snapshot window: T-1d to T+2d. |
|
||||
| ~~NK~~ | Removed | Spirit Airlines ceased operations (merged into Frontier). Removed from `AirlineLoadService` and tests. |
|
||||
| XE | Manual only | WKWebView path; unit tests can't exercise it |
|
||||
|
||||
@@ -214,6 +215,71 @@ Spirit ceased operations and merged into Frontier. Removed from the codebase ent
|
||||
|
||||
---
|
||||
|
||||
## 5b. Aeromexico — WORKING (richer than AA in some ways)
|
||||
|
||||
**What you get:** per-cabin `authorized` (capacity) + `available` (open seats), full standby + upgrade passenger lists with `isStaff` flag, numeric priority, fare class, booking class, ascendsToClass, original/new position, check-in / board status, PII (firstName, lastName, reservationCode/PNR).
|
||||
|
||||
**Auth:** None. Public AWS API Gateway. Headers required: `channel: web`, `flow: CHECKIN`, `x-transaction-id: <uuid>`. Values extracted from `com.aeromexico.aeromexico.amwidgets.utils.Constant` in the APK.
|
||||
|
||||
**Flow:**
|
||||
```
|
||||
GET https://lw18yj0mhb.execute-api.us-east-1.amazonaws.com/rb/passengerliststandby
|
||||
?departureAirport=<IATA>
|
||||
&code=<4-digit, zero-padded>
|
||||
&departureDate=<YYYY-MM-DD>
|
||||
&operatingCarrier=AM
|
||||
&operatingFlightCode=<4-digit, zero-padded>
|
||||
|
||||
GET https://lw18yj0mhb.execute-api.us-east-1.amazonaws.com/rb/passengerlistupgrade
|
||||
?<same params>
|
||||
```
|
||||
|
||||
`operatingFlightCode` is validated against `^[0-9]{4}$` — zero-pad short flight numbers.
|
||||
|
||||
**Response shape:**
|
||||
```json
|
||||
{
|
||||
"itineraryInfo": {"airline":"AM","flight":"0058","origin":"MEX","destination":"MTY","aircraftType":"789"},
|
||||
"cabinInfoList": [{"cabin":"Y","authorized":238,"available":0}],
|
||||
"totalListed": 1,
|
||||
"passengers": [{
|
||||
"isStaff": true,
|
||||
"rawPriorityCode": "SAE",
|
||||
"priorityCode": {"id":"SAE","priority":21},
|
||||
"status": "STB",
|
||||
"bookingClass": "H",
|
||||
"ascendsToClass": "Y",
|
||||
"firstName": "RAMSITO",
|
||||
"lastName": "UNO",
|
||||
"reservationCode": "OBLWDT",
|
||||
"passengerId": "0A6612610001",
|
||||
"seat": null,
|
||||
"originalPosition": 2,
|
||||
"newPosition": 1,
|
||||
"checkInStatus": false,
|
||||
"boardStatus": false,
|
||||
"boardingPassFlag": false
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
**Snapshot window** (empirical, AM0058 MEX-MTY):
|
||||
- T-3 days and earlier → `NONE LISTED` (data purged)
|
||||
- **T-1 day → T+0** → snapshot live, `passengers[]` populates when listed
|
||||
- T+1, T+2 → `NONE LISTED` (flight known but no snapshot)
|
||||
- T+3 and beyond → `FLIGHT NOT INITIALIZED`
|
||||
|
||||
**Failure modes** to watch for in the response body:
|
||||
- `NONE LISTED` → params valid, no passengers / no snapshot yet
|
||||
- `FLIGHT NOT INITIALIZED - INVALID DATE OR CITY` → flight number doesn't match a real AM operation on that date+airport, OR snapshot window not open
|
||||
- The `code` query param is ignored — only `operatingCarrier` + `operatingFlightCode` + `departureAirport` + `departureDate` are discriminating
|
||||
|
||||
**Cabin codes:** `Y` = Economy, `C` = Clase Premier (business), `P` = Premier One (long-haul biz/first), `F` = First. Mapped in `aeromexicoCabinName(code:)`.
|
||||
|
||||
**AM Connect / regional flights** (e.g. AM1460 MEX-QRO) often return `FLIGHT NOT INITIALIZED` — they're not in AM's Sabre system. The integration falls back to a known-daily mainline flight (AM0058 MEX-MTY) when route-explorer surfaces a regional that the load endpoint doesn't recognise.
|
||||
|
||||
---
|
||||
|
||||
## 6. JetBlue — PARTIAL (status yes, loads need PNR)
|
||||
|
||||
**What you get without PNR:** Flight status, full route database (12MB of origin/dest pairs, Mint/seasonal flags).
|
||||
|
||||
Reference in New Issue
Block a user