Release digest
Fixed
- PROD-AI-REPORT-08 (LLM Receives Empty Data) — Root cause:
ai_report_generator.pycreated a plainpsycopg2cursor (tuples) but accessed rows as dicts, silently falling intoexceptwith empty stats/reviews. Three related bugs fixed:- Added
cursor_factory=psycopg2.extras.RealDictCursorfor dict-based row access (backend/ai_report_generator.py). - Removed broken
dict(zip(columns, stats_row))conversion that produced{"col_name": "col_name"}once cursor returned dicts. - Added NULL/NaN-safe
str(x or "").strip()for review text fields that previously crashed onNone.strip().
- Added
- PROD-AI-REPORT-09 (Analysis Bypasses Quality Gate) —
POST /api/analyzenow routes throughReportOrchestrationService.resolve_sections()withforce_regenerate=Trueinstead of saving raw LLM output directly to DB (backend/routers/analytics.py). - PROD-AI-REPORT-10 (No Force-Regenerate) — Added
force_regenerateparameter toresolve_sections()so "Run AI Analysis" always generates fresh content, skipping cached hallucinations (backend/services/report_orchestration_service.py).
Internal
- Added
tests/test_ai_report_data_integrity.py(9 tests):- Stats serialization correctness (numeric values, not column names)
- NULL/NaN-safe review text assembly (None, NaN, all-NULL)
- Quality gate hallucination blocking (Trust Score N/A, no employee reviews)
- Orchestration force-regenerate contract
- Full targeted regression: 9 passed.
- Added
docs/reports/2026-03-07_PROD_REPAIR_SEARCH_SENTIMENT_AI_REPORT.md(updated with PROD-AI-REPORT-08/09/10 closure).