_refresh_ai_rows deleted only unconfirmed AI rows, then bulk-inserted freshly generated rows keyed by a deterministic uuid5 of (template_id, semantic key). A confirmed ghost keeps that id, so a re-run re-emitted it → primary-key conflict that failed the whole insert batch (reachable: auto-map is blocked only when marks exist, not when ghosts are confirmed). Fix: after the delete, read the ids that survived (confirmed-AI + manual) and skip re-inserting any freshly generated row whose id matches — preserving the teacher's curated row and making the insert PK-safe. Adds test_auto_map_rerun_after_confirm_does_not_pk_collide, which confirms a ghost at its REAL generated id (the prior test used an arbitrary id that never collided) and asserts the row survives exactly once with confirmed=True. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Description
FastAPI + Python 3.12 backend for Classroom Copilot — auth, document processing, transcription sessions, LLM integration, Supabase-backed
Languages
Python
98.9%
Shell
0.8%
Jupyter Notebook
0.3%