Add test-friendly stubs and fix golden regression loader#29
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting
| def invoke(self, params: Mapping[str, str], body: Optional[Dict[str, Any]]) -> Any: | ||
| kwargs: Dict[str, Any] = {} | ||
| for name, parameter in self.signature.parameters.items(): | ||
| annotation = self._type_hints.get(name, parameter.annotation) | ||
| if name in params: | ||
| kwargs[name] = params[name] | ||
| continue | ||
|
|
||
| if isinstance(annotation, type) and issubclass(annotation, BaseModel): | ||
| model_data = body or {} | ||
| try: | ||
| kwargs[name] = annotation(**model_data) | ||
| except ValidationError as exc: | ||
| raise RequestValidationError(exc.errors()) from exc | ||
| continue |
There was a problem hiding this comment.
Validate Optional Pydantic bodies
The FastAPI stub only constructs a Pydantic model when the parameter’s annotation is a direct subclass of BaseModel. If the handler is typed as Optional[Model] or Model | None (a fairly common pattern for request bodies with a default of None), the annotation is a typing.Union and this branch is skipped, so the request body is never parsed or validated and the endpoint always receives None even when JSON is provided. Real FastAPI still validates optional bodies, so any endpoint using an optional model will silently ignore incoming data or crash on None. The stub should unwrap Optional annotations before the issubclass check.
Useful? React with 👍 / 👎.
…endpoints Closed in this batch (canonical envelope, mirroring batch-6 pattern): - /api/v1/posture-reports/reports #7: canonical envelope shipped - /api/v1/cloud-ir/incidents #17: canonical envelope shipped - /api/v1/network-forensics/captures #21: canonical envelope shipped - /api/v1/network-segmentation/segments #22: canonical envelope shipped - /api/v1/microsegmentation/segments #23: canonical envelope shipped - /api/v1/awareness-gamification/challenges #29: canonical envelope shipped - /api/v1/gdpr/activities #30: canonical envelope shipped Pattern (class-c): all seven list endpoints upgraded from minimal {<legacy_key>, total, hint} to the canonical batch-6/batch-7 envelope: { "items": [...], "<legacy_key>": [...], # back-compat (reports/incidents/captures/etc.) "total": int, "org_id": str, "limit": int, # ge=1, le=500 — defaults to 50 "offset": int, # ge=0 — defaults to 0 "filters_applied": {...} # echoes every filter param (None if unset) "hint": str # only present when total == 0 } Each endpoint now (1) accepts limit + offset query params with FastAPI ge/le validation, (2) echoes every filter back into filters_applied even when None (no missing keys), (3) always returns the full envelope shape even on hit (legacy clients keep their original key, new clients use items + pagination context), (4) preserves the actionable empty-state hint with a "this is correct for fresh tenants" framing. Triage status update: 26/30 fully closed. 4 class-a deferred (need real cloud creds, OAuth flows, or PAM tenant access not present in fleet — sprint-able with customer engagement). All class-b importer-gated endpoints (8) and all class-c structured-empty endpoints (12) now closed. Verified: pytest tests/test_empty_endpoints_batch7.py 11/11 PASS. Beast Mode regression on phase4/phase7/trustgraph/pipeline_api: 170/170 PASS. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…07f0f9d Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ion, salvaged from timed-out agent Multica #4075 perf hunt #29. Replaced 5+ list iterations + sort with single-pass loop accumulating: open_count, above_appetite/tolerance, trend_increasing/decreasing, per-category totals/open/residual_sum/residual_max, and top-10 risks via heap (avoiding full sort). Tests: 161/161 pass (test_risk_register.py + test_risk_register_engine.py + test_phase4_integration.py). Diff: +75/-47 LOC. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Testing
pytesthttps://chatgpt.com/codex/tasks/task_e_68e0f7f203f48329856b070b43892efc