- Shipped
- August 7, 2026 at 2:41 AM UTC
- Author
- kamo
- Commit
- 80bc041
Opening **************** errored with "Unknown status: **************** for every member. listMyAssignments sent the whole bucket as one CSV value. A comma in a query VALUE has to travel as %2C, and APIService — the shared gateway every /api/docs/** call crosses — concatenates the already-encoded URI and query into a plain String and hands that String to RestTemplate.exchange. RestTemplate treats a String URL as a URI TEMPLATE and percent-encodes it a SECOND time: %2C became %252C. DocsService decoded once, got the literal %2C back, and parseStatuses split on a comma that was no longer there — so the entire bucket failed valueOf as one run-together token. The gateway is deliberately NOT touched. It carries /api/docs/**, /api/security/** and every other service; changing its encoding would change semantics for every caller on the platform at once, and callers that pass raw reserved characters survive only because of that re-encode. Written up for scheduling in **************** (gitignored). The reserved character comes off the wire instead: - statusCsvFor -> statusesFor, returning the string[] rather than a joined CSV. The CSV shape had exactly one caller, so both forms were not worth keeping. - listMyAssignments appends one `status` param per value. A CSV string handed in by any future caller is SPLIT here rather than passed through, so the old shape cannot silently come back. Status names are [A-Z_] only, which makes the gateway's second encode a no-op on them. - The proxy route's contract is spelled out: mergeForwardedQuery appends pair by pair, so repeats survive, and it must never collapse them back into a CSV. apiProxyQuery.test.ts now pins that — iterating keys instead of pairs would silently re-break this page. Tests assert the URL that actually leaves the browser: repeated params, no '%' anywhere in the query, a CSV split rather than forwarded, the single-status EXECUTION_INCOMPLETE probe unchanged, blank tokens dropped, and every status this app can send surviving a round-trip. DocsService accepts both shapes through one parseStatuses rule (see its matching commit), so bookmarked URLs and the HR grid's status=EXECUTED are unaffected. tsc --noEmit clean; 873 tests, 0 failures; next build succeeds.