fix(mappings): move sku/codmat from path to query — slash in keys 404'd

Codurile ROA contin legitim '/' si '"' (ex. RCR1/4"). Rutele FastAPI
foloseau parametri de cale (/api/mappings/{sku}/{codmat}...); ASGI decodeaza
%2F -> '/' INAINTE de routing, deci o cheie cu slash devine doua segmente si
Starlette nu mai potriveste ruta -> 404 la edit/delete/restore. Cand ambii
parametri au slash, un convertor {path} nu rezolva (split ambiguu).

Solutie: sku/codmat trec din cale in query string. %2F/%22 din query se
decodeaza ca parte a valorii, fara sa atinga routing-ul de cale.

- backend: 4 rute statice + Query(...) (update/edit/delete/restore);
  semnaturile mapping_service raman neschimbate
- frontend: helper mapQS(); toate cele 8 apeluri path -> query; cache-bust ?v=19
- tests: regresie ci-layer (chei-sentinel cu slash, !=404, toate 4 rutele);
  test_integration update/delete convertite la query; e2e delete RCR1/4"
  (slash+ghilimea) prin modalul UI, skip cand Oracle lipseste

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-06-08 13:58:04 +00:00
parent b1595f45c7
commit 550d94ff16
6 changed files with 130 additions and 21 deletions

View File

@@ -112,3 +112,25 @@ def test_route(client, path, expected_codes, is_oracle_route):
f"GET {path} returned {resp.status_code}, expected one of {expected_codes}. "
f"Body: {resp.text[:300]}"
)
def test_mappings_slash_in_keys_routes_ok(client):
"""Regression: slash in BOTH sku and codmat used to 404 (path-param routes,
ASGI decoded %2F before routing). Now sku/codmat are query params, so the
route resolves regardless of slashes/quotes. Sentinel keys with a slash can
match no real row, so even if Oracle were up the UPDATE/WHERE is a no-op —
here pool is None so the handler returns 200 success:False without mutation.
Asserting != 404 proves the route resolved."""
sku, codmat = '__TEST_SKU/X"', '__TEST_CODMAT/Y'
calls = [
client.delete("/api/mappings/delete", params={"sku": sku, "codmat": codmat}),
client.put("/api/mappings/update", params={"sku": sku, "codmat": codmat},
json={"cantitate_roa": 1}),
client.put("/api/mappings/edit", params={"sku": sku, "codmat": codmat},
json={"new_sku": sku, "new_codmat": codmat, "cantitate_roa": 1}),
client.post("/api/mappings/restore", params={"sku": sku, "codmat": codmat}),
]
for resp in calls:
assert resp.status_code != 404, (
f"route did not resolve: {resp.status_code} {resp.url}"
)