diff --git a/.claude/agents/architecture-reviewer.md b/.claude/agents/architecture-reviewer.md index e9648ab9..236d9779 100644 --- a/.claude/agents/architecture-reviewer.md +++ b/.claude/agents/architecture-reviewer.md @@ -60,9 +60,10 @@ Specific bug-classes that have bitten this repo before. When the target file mat - **IDOR check (CRITICAL).** Every GET-by-id, GET-by-scope, PATCH, PUT, DELETE on a buyer/seller-scoped entity must: - Read `ClaimTypes.NameIdentifier` from JWT at the endpoint - Pass `RequestingBuyerId` (or `RequestingSellerId`) into the query/command - - Handler returns `null` on entity-owner mismatch - - Endpoint translates `null` → 404 (NOT 403) - - Reference: `OrderEndpoints.cs:GET /orders/{id}`, `ShippingEndpoints.cs:GET /shipments/order/{orderId}`. Any deviation is a Must-fix IDOR. + - **Read handlers**: push the ownership predicate INTO the EF `Where` clause (`Where(o => o.Id == OrderId && o.BuyerId == RequestingBuyerId)`) so non-owner rows never leave the database. Tighter than a post-materialization C# check — a buggy refactor can't weaken a SQL predicate. + - **Write handlers** (need tracked load to mutate): in-memory ownership check on the loaded entity, return `false`/`null` on mismatch. + - Endpoint translates `null`/`false` → 404 (NOT 403) + - Reference: `OrderEndpoints.cs:GET /orders/{id}` + `Features/GetOrderById.cs` (read, predicate in SQL), `ShippingEndpoints.cs:GET /shipments/order/{orderId}` + `Features/GetShipmentByOrder.cs` (read, predicate in SQL), `CatalogEndpoints.cs:PUT /products/{id}` + `Features/UpdateProduct.cs` (write, in-memory check after tracked load). Any deviation is a Must-fix IDOR. A read handler with the predicate ONLY in C# (i.e. fetch by id, then `if (entity.BuyerId != requestingId) return null`) is a Should-consider — it satisfies the external contract but is structurally weaker; recommend tightening to the SQL-predicate shape. - **Mass assignment.** Any `[FromBody]` or minimal-API body parameter binding a record/class that contains a server-controlled field (`BuyerId`, `SellerId`, `Status`, `Price`, `IsDeleted`). The endpoint must verify the field matches the JWT claim or strip it from the bound type. - **`MapV1ApiGroup` used** (not hand-rolled `NewVersionedApi().MapGroup().HasApiVersion()` chains). - **`.RequireAuthorization()` at group level** unless explicitly public. diff --git a/.claude/skills/excalidraw-diagram/references/render_excalidraw.py b/.claude/skills/excalidraw-diagram/references/render_excalidraw.py index 9c0a4443..b6fb8d3c 100644 --- a/.claude/skills/excalidraw-diagram/references/render_excalidraw.py +++ b/.claude/skills/excalidraw-diagram/references/render_excalidraw.py @@ -143,11 +143,23 @@ def render( device_scale_factor=scale, ) + # Capture console and network failures — when the esm.sh bundle fails + # to load, the surfaced error is a generic Timeout. The actual cause + # (CORS, 404, syntax error, etc.) shows up in the page console; route + # it to stderr so the script's output explains what went wrong. + page.on("console", lambda msg: print(f" [page console.{msg.type}] {msg.text}", file=sys.stderr)) + page.on("pageerror", lambda exc: print(f" [page error] {exc}", file=sys.stderr)) + page.on("requestfailed", lambda req: print(f" [request failed] {req.url} — {req.failure}", file=sys.stderr)) + # Load the template page.goto(template_url) - # Wait for the ES module to load (imports from esm.sh) - page.wait_for_function("window.__moduleReady === true", timeout=30000) + # Wait for the ES module to load (imports from esm.sh). The + # `@excalidraw/excalidraw?bundle` URL serves a small entry shim but + # the browser pulls in many transitive modules afterwards; 30s was + # too tight on slower networks. 90s is a comfortable ceiling — if we + # ever hit that, the CDN is genuinely down rather than slow. + page.wait_for_function("window.__moduleReady === true", timeout=90000) # Inject the diagram data and render json_str = json.dumps(data) diff --git a/.claude/skills/excalidraw-diagram/references/render_template.html b/.claude/skills/excalidraw-diagram/references/render_template.html index 78133b94..c5764150 100644 --- a/.claude/skills/excalidraw-diagram/references/render_template.html +++ b/.claude/skills/excalidraw-diagram/references/render_template.html @@ -13,7 +13,11 @@