"""Supplements CRUD.""" from db.connection import query, execute, execute_returning def insert(contract_id, document_id, supp_type="additional"): return execute_returning( """INSERT INTO supplements (contract_id, document_id, type) VALUES (%s, %s, %s) RETURNING *""", (contract_id, document_id, supp_type), ) def list_by_contract(contract_id): """Supplements with parsed documents, ordered by created_at.""" return query( """SELECT s.id, s.type, s.document_id, d.filename FROM supplements s JOIN documents d ON s.document_id = d.id WHERE s.contract_id = %s AND d.elements_json IS NOT NULL ORDER BY s.created_at""", (contract_id,), ) def get(supp_id): rows = query("SELECT * FROM supplements WHERE id = %s", (supp_id,)) return rows[0] if rows else None def delete_by_document(contract_id, filename): """Delete ALL supplements+documents by contract+filename (cascade: spec_events first). Handles duplicates from previously failed uploads.""" rows = query( """SELECT s.id as sid, s.document_id FROM supplements s JOIN documents d ON d.id = s.document_id WHERE s.contract_id = %s AND d.filename = %s""", (contract_id, filename), ) if not rows: return False for r in rows: # 1. Delete spec_current rows referencing this supplement's events execute( """DELETE FROM spec_current WHERE contract_id = %s AND last_event_id IN (SELECT id FROM spec_events WHERE supplement_id = %s)""", (contract_id, r["sid"]), ) # 2. Delete spec_events referencing this supplement execute("DELETE FROM spec_events WHERE supplement_id = %s", (r["sid"],)) # 3. Delete supplement execute("DELETE FROM supplements WHERE id = %s", (r["sid"],)) # 4. Delete document execute("DELETE FROM documents WHERE id = %s", (r["document_id"],)) return True def delete(supp_id): return execute("DELETE FROM supplements WHERE id = %s", (supp_id,))