docs(route-authority): record v1/v2 economy URL prefix contract
Accepted prefixes /ut/game/<sku>/ and /ut/v2/game/<sku>/ for every economy route; StoreBuy accepts store/transaction and store/transaction/<txn-id>.
This commit is contained in:
@@ -12,6 +12,38 @@ entitlements (`unopenedPackIds`). `points` has **no** writer (read-only). EASFC
|
||||
Legend: **R** = Rust/Core authoritative, **P** = Python proxied (oracle).
|
||||
Evidence lines refer to `fifa17-recon/tools/{utas_server.py,fut_store.py}`.
|
||||
|
||||
|
||||
## Accepted URL prefixes (v1 + v2) — S2 fix
|
||||
|
||||
The retail FIFA 17 client issues the **Store family** under a `/ut/v2/game/<sku>/`
|
||||
prefix (live-observed `PUT /ut/v2/game/fifa17/store/transaction/0`), while other
|
||||
routes use `/ut/game/<sku>/`. `classify_economy` normalizes BOTH prefixes to the
|
||||
same tail (`ut_tail`), so economy ownership is prefix-agnostic. This closes the
|
||||
S2 live-staging defect where the v2 Store BUY escaped to Python.
|
||||
|
||||
| Route | Accepted method + path shapes (both prefixes) | Economy route |
|
||||
|---|---|---|
|
||||
| Credits | `GET (/ut/game\|/ut/v2/game)/<sku>/user/credits` | `Credits` |
|
||||
| Store catalogue | `GET …/store/purchasegroup[/…]` | `PurchaseGroup` |
|
||||
| **Store BUY** | `PUT …/store/transaction` **and** `PUT …/store/transaction/<txn-id>` (numeric, e.g. `…/store/transaction/0`) | `StoreBuy` |
|
||||
| Pack open | `POST …/purchased` | `PackOpen` |
|
||||
| Pack reveal | `GET …/purchased` | `PackReveal` |
|
||||
| Quick-sell (path) | `DELETE …/item/<digits>` | `QuickSellPath` |
|
||||
| Quick-sell (body) | `POST (/ut/delete/game\|/ut/v2/delete/game)/<sku>/item` | `QuickSellBody` |
|
||||
| Move | `PUT …/item` | `MoveItems` |
|
||||
| Match end | `POST (/ut/delete/game\|/ut/v2/delete/game)/<sku>/match` | `MatchEnd` |
|
||||
| Market list | `POST …/auctionhouse` \| `…/transfermarket` | `MarketList` |
|
||||
| Market query | `GET …/tradePile` | `MarketQuery` |
|
||||
| Market buy | `…/trade/<id>` | `MarketBuy` |
|
||||
| Market cancel | `DELETE (/ut/delete/game\|/ut/v2/delete/game)/<sku>/trade/<id>` | `MarketCancel` |
|
||||
|
||||
`store/transaction` matching is BOUNDED to a single all-digit id segment — it
|
||||
never absorbs `store/transactions`, `store/transactionfoo`, or
|
||||
`store/transaction/<id>/extra` (those proxy to Python as non-economy). Audit
|
||||
basis: Python route table `utas_server.py:1420` matches the store family
|
||||
"regardless of /ut/game vs /ut/v2/game prefix"; all other economy routes are
|
||||
`G = /ut/game/[^/]+`-prefixed (v1-only) and the retail client uses v1 for them.
|
||||
|
||||
## E1 — CUTOVER READY (barrier `93a46d4`, superproject source-ready; NOT deployed)
|
||||
|
||||
The economy authority barrier is committed: `Server::handle_with_ip` dispatches
|
||||
|
||||
Reference in New Issue
Block a user