Backend (app.py / database.py / ai_agent.py):
- [Critique] Autoclose loop: add pg_try_advisory_lock so only one Gunicorn
worker runs the check per 60s cycle; add random startup jitter
- [Critique] admin_delete_idea: pass consultation_id to
_update_synthesis_background so the right synthesis is regenerated
- [Majeur] admin_login: return HMAC-signed session token instead of raw
ADMIN_SECRET; require_admin verifies the signature (TTL 8h)
- [Majeur] bulk_delete: replace str.isdigit() (Unicode-unsafe) with
try/except int() to prevent crash on Unicode digit characters
- [Majeur] create_consultation: force UTC timezone on naive datetime from
fromisoformat() to prevent TypeError when comparing with UTC-aware now()
- [Majeur] ai_agent.py: fix 'raw' in dir() -> 'raw' in locals() so the
JSON parse error log actually shows the raw response
- [Mineur] export print: use datetime.now(UTC) instead of datetime.now()
Frontend (React):
- [Majeur] consultation.tsx: show startsAt (not endsAt) for upcoming
consultations; add startsAt variable
- [Majeur] consultations-list.tsx: same fix for the list view
- [Mineur] home.tsx: guard new Date(idea.createdAt) against null
- [Mineur] admin.tsx: check HTTP status in exportCsv XHR before creating
download link; show error toast on non-200
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>