refactor: split buspro ApiClient into domain clients
This commit is contained in:
1 parent
0a55544ca8
commit
b755a6f43e
52 files changed
+805
-695
No files matched your search
@@ -25,7 +25,7 @@ Every request is `<anfrage>` with `<user>`, `<key>` and `<satz typ="…"/>`.
|
||||
key = md5( user + password + date("YYYYMMDD") + satz-typ )
|
||||
```
|
||||
|
||||
Per satz type and per day. `ApiClient::createKey()` implements it, and `sendRawXml()` regenerates
|
||||
Per satz type and per day. `XmlChannel::createKey()` implements it, and `XmlChannel::replay()` regenerates
|
||||
the key before sending, so a hand-built payload can carry a placeholder.
|
||||
|
||||
## Satz types
|
||||
@@ -39,7 +39,7 @@ the key before sending, so a hand-built payload can carry a placeholder.
|
||||
`VERFUEGBARKEITHOTEL`, `ZAHLUNG`, `ZAHLUNG2`, `ZAHLUNGSARTEN`, `ZAHLUNGSARTEN2`.
|
||||
`SITZPLATZAUSWAHL` and `ZAHLUNG4` are named in prose without their own section.
|
||||
|
||||
**Used here but undocumented:** `VERFUEGBARKEIT2` (`ApiClient::TYPE_AVAILABILITY_EXTENDED`) — the
|
||||
**Used here but undocumented:** `VERFUEGBARKEIT2` (`MessageType::AvailabilityExtended`) — the
|
||||
extended availability call returning `buchungstatusmoeglich` and per-service `pflicht`/`frei`.
|
||||
Its contract is observed, not specified.
|
||||
|
||||
@@ -201,11 +201,11 @@ the same way. Ask `MOEGLICHEAENDERUNGEN` first (`<idreise>`), which answers:
|
||||
## How this app maps onto the contract
|
||||
|
||||
`BookingPayloadBuilder::buildCreatePayload()` builds create; `buildBasePayload()` + the
|
||||
`addTo…Payload()` helpers build edit; `ApiClient::createBooking()`/`updateBooking()` wrap them.
|
||||
`addTo…Payload()` helpers build edit; `BookingClient::createBooking()`/`updateBooking()` wrap them.
|
||||
|
||||
| Documented element | Sent on create | Sent on edit | Notes |
|
||||
|---|---|---|---|
|
||||
| `buchungsart` | yes | yes | Edit **hardcodes `Buchung`** (`ApiClient.php:233`) |
|
||||
| `buchungsart` | yes | yes | Edit **hardcodes `Buchung`** (`BookingClient::updateBooking()`) |
|
||||
| `status` | yes | yes | Edit replays the value read back from BusPro — see the caveat below |
|
||||
| `idreise`, `idpartner`, `idagentur` | yes | yes | `idpartner` sent unconditionally, even with no room |
|
||||
| `anmelder` | yes | yes | Create builds it from participant[0]; edit uses `PersonalData::toPayload()`. BusPro accepts an Anmelder who is not a participant |
|
||||
@@ -253,7 +253,7 @@ booking before relying on it.
|
||||
### Gap: edit never dry-runs
|
||||
|
||||
Create is two-phase — `Anfrage` to validate and price, then `Buchung`. Edit sends
|
||||
`buchungsart=Buchung` directly (`ApiClient.php:233`), even though `BUCHUNGAENDERUNG` supports
|
||||
`buchungsart=Buchung` directly (`BookingClient::updateBooking()`), even though `BUCHUNGAENDERUNG` supports
|
||||
`Anfrage` identically. An enquiry pass would surface `913`/`924`/`962` and return the recalculated
|
||||
price *before* mutating a live booking.
|
||||
|
||||
@@ -315,8 +315,8 @@ answers `<reise id status>` plus per-service `status` ("buchbar"), `frei`, `prei
|
||||
## Selling vouchers (Kaufgutschein)
|
||||
|
||||
Used by the `/gutschein` flow, which replaces the BusProNet-hosted shop
|
||||
(`maske_gutschein.php`). `ApiClient::TYPE_VOUCHER_*`; not to be confused with
|
||||
`TYPE_PURCHASE_VOUCHER` (`GUTSCHEINPRUEFUNGEINLOESUNG`), which redeems a voucher in a booking.
|
||||
(`maske_gutschein.php`). `VoucherClient`, `MessageType::Voucher*`; not to be confused with
|
||||
`MessageType::PurchaseVoucher` (`GUTSCHEINPRUEFUNGEINLOESUNG`), which redeems a voucher in a booking.
|
||||
|
||||
| Satz | Request | Response |
|
||||
|---|---|---|
|
||||
|
||||
@@ -9,7 +9,7 @@ Companion to `travel-queries.md` (static catalog) and `live-api-queries.md` (liv
|
||||
socket endpoints). This one covers the `KUNDENKONTO` / `art=SelektionCRM` response —
|
||||
the document that drives the portal's entire authorization model.
|
||||
|
||||
Request side: `ApiClient::getCrmAttributes()` (`src/BusProNet/ApiClient.php`) sends
|
||||
Request side: `AccountClient::getCrmAttributes()` (`src/BusProNet/Client/AccountClient.php`) sends
|
||||
`satz typ="KUNDENKONTO"` + `art=SelektionCRM` + the customer's email/password.
|
||||
Response side: `CrmAttributesResponseParser`
|
||||
(`src/BusProNet/XmlParser/CrmAttributesResponseParser.php`) turns selection ids into
|
||||
@@ -229,7 +229,7 @@ Three conclusions:
|
||||
`dbo.AgenturSelektionenKunde` is a bare two-column link table,
|
||||
`(IDAdresse_FS, IDSelektionsstamm_FS)` — literally *"agency's customer selections"*. The
|
||||
portal authenticates against BusPro as an **agency** account (`bpn_username` in
|
||||
`ApiClient`), so a per-agency whitelist of which customer selections that agency may see
|
||||
`XmlChannel`), so a per-agency whitelist of which customer selections that agency may see
|
||||
and/or edit is exactly the right shape. It is the only candidate found so far that could
|
||||
explain the `1478` omission **and** `aenderbar` through one mechanism.
|
||||
|
||||
@@ -461,7 +461,7 @@ and they are long shots. Prefer the escalation path below.
|
||||
Escalation path, cheapest first:
|
||||
|
||||
1. **Re-fetch and confirm staleness.** Our side does not cache this call — the
|
||||
`xml-sync` cache tag covers the XML *export* sync, and `ApiClient::getCrmAttributes()`
|
||||
`xml-sync` cache tag covers the XML *export* sync, and `AccountClient::getCrmAttributes()`
|
||||
has no cache layer — so a fresh login hits BusPro directly. If `1478` is still absent
|
||||
from a response captured after the insert, the staleness is on the BusProNet host and
|
||||
an application-pool/service restart there is the test.
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
> per-endpoint migration verdicts and the `frei` discovery SQL.
|
||||
|
||||
This complements `travel-queries.md`. That doc replaced the **XML export** (static
|
||||
catalog). This one covers the **live socket API** methods on
|
||||
`src/BusProNet/ApiClient.php` and classifies how replicable each is by direct MSSQL
|
||||
catalog). This one covers the **live socket API** methods of the clients in
|
||||
`src/BusProNet/Client/` and classifies how replicable each is by direct MSSQL
|
||||
query in the Go proxy.
|
||||
|
||||
**Verdict in one line:** the *structural* parts replicate cleanly; the *live "free"
|
||||
|
||||
Reference in new issue
Block a user