Gaps — spec 034 key-transport supersession & shared-gw2 follow-ups
Records from spec 034 — client-direct ArenaNet and its research. Observations/decisions already made during 034, parked here rather than acted on further — nothing below is a proposal.
1 — stack.md's key-transport claim is superseded for prices + account/materials/wallet
docs/architecture/stack.md (Authentication) documents the key travelling as Authorization: Bearer from the browser to our api, which forwards it to GW2. Spec 034 (the gw2.app-alignment epic) supersedes this for prices and account/materials/wallet only: those now go browser → ArenaNet directly, with the key as ?access_token= — the Authorization header is CORS-blocked from a browser (research 034 V1: a cross-origin fetch with an Authorization header never leaves the browser, TypeError: Failed to fetch; ?access_token= is a "simple" request and reaches the server).
Ranking and the assistant (Wave 3 / Spec 5) are untouched by 034 and still send the key to our origin — stack.md's description holds for those flows. stack.md itself is unedited by 034 (spec status is a plan.md concern, not this record's); it should be updated to note the split when a later spec next touches it.
2 — GW2 CORS / rate-limit facts worth graduating into gw2-api.md
From research 034 (V1, V2, V3, V6), not yet in docs/architecture/gw2-api.md:
- The
/v2API is CORS-open (access-control-allow-origin: *) for GETs. - A cross-origin
Authorizationheader is CORS-blocked (fails preflight);?access_token=works (no preflight — a "simple" request). - The rate limit (
gw2-api.mdalready documents 300 burst / 5-per-sec) is per IP, confirmed against the wiki. Browser-direct calls therefore spend each user's own budget, not our shared origin's — the whole justification for 034's move.gw2-api.mddocuments the limit itself but not this browser-direct consequence. - The response body is readable cross-origin despite a minimal
access-control-expose-headers:expose-headersgates response headers, not the body.cache-controlis readable (it's a CORS-safelisted response header, needs noexpose-headersentry);access-control-allow-originitself reads asnullin JS (consumed by the browser, never exposed) — thatnullis not a CORS failure signal.
3 — Stale "types-only @gw2priory/recipe-graph" comments (broader sweep deferred)
Several apps/api comments say to import only types from @gw2priory/recipe-graph, but both apps now runtime-import it: apps/web already did (mergeOwnVsNeed/aggregateNeed), apps/api's ranking.service.ts already did (mergeOwnVsNeed, needRows), and 034 added priceGraph (recipe-graph.service.ts). Spec 034 corrected the comments in the files it edited; one stale pair remains untouched — recipe-graph.schema.ts:1,7 — since 034 didn't edit that file. A broader sweep is deferred.
4 — Orphaned models-zod/*.zod.ts after orval regen
apps/web's Orval api-zod client-generator entry runs with clean: false, so regenerating the API client leaves unreferenced *.zod.ts files on disk for endpoints that no longer exist. Spec 034 dropped /account* and /commerce/*, and confirmed the pattern on both the newly-orphaned files (materialListDtoOutput.zod.ts, walletListDtoOutput.zod.ts, commercePriceListDtoOutput*.zod.ts, …) and a pre-existing case (recipeTreeDtoOutput*.zod.ts, orphaned since the recipe-tree route was replaced by recipe-graph). All are import type-only from present sibling files, unreferenced by the generated barrel, and lint-clean after pnpm format — harmless dead files, not a build or lint hazard. A later cleanup could set clean: true on the orval config or prune them by hand; out of scope here.