import { getAllRows, getRowsWhereEquals, getRowsWhereIn, insertRow, updateRow, deleteRowById, deleteRowsWhereEquals, } from '../crud' import type { ChecklistItemDef, ChecklistResponse } from '../../../src/db/types' export const listChecklistItemDefsForPhaseTemplate = (phaseTemplateId: number): ChecklistItemDef[] => { const rows = getRowsWhereEquals('checklistItemDefs', 'phaseTemplateId', phaseTemplateId) return rows.sort((a, b) => a.order - b.order) } /** Bulk-Variante für Berichte über mehrere Phasentypen hinweg (Assignment-Report-PDF, Gesamtprotokoll). */ export const listChecklistItemDefsForPhaseTemplates = (phaseTemplateIds: number[]): ChecklistItemDef[] => getRowsWhereIn('checklistItemDefs', 'phaseTemplateId', phaseTemplateIds).sort((a, b) => a.order - b.order) export const addChecklistItemDef = (def: Omit): number => insertRow('checklistItemDefs', def) export const updateChecklistItemDef = (id: number, patch: Partial): number => updateRow('checklistItemDefs', id, patch) /** Räumt zugehörige `checklistResponses` mit auf — gleiches Verteidigungs-Prinzip wie `deleteFeedbackCriterionItem`. */ export function deleteChecklistItemDef(id: number): void { deleteRowsWhereEquals('checklistResponses', 'checklistItemId', id) deleteRowById('checklistItemDefs', id) } /** Cascade-Baustein für `deletePhaseTemplate`/`deleteAssignmentType` — löscht alle Checklisten-Punkte samt Antworten einer Phase. */ export function deleteChecklistItemDefsForPhaseTemplate(phaseTemplateId: number): void { for (const def of listChecklistItemDefsForPhaseTemplate(phaseTemplateId)) { deleteChecklistItemDef(def.id!) } } export const listChecklistResponsesForMeeting = (meetingInstanceId: number): ChecklistResponse[] => getRowsWhereEquals('checklistResponses', 'meetingInstanceId', meetingInstanceId) /** Bulk-Variante für Berichte über mehrere Meetings hinweg (Assignment-Report-PDF, Gesamtprotokoll). */ export const listChecklistResponsesForMeetings = (meetingInstanceIds: number[]): ChecklistResponse[] => getRowsWhereIn('checklistResponses', 'meetingInstanceId', meetingInstanceIds) /** * Upsert per Komposit-Schlüssel (meetingInstanceId, checklistItemId, instituteeId ?? null), gleiches * Find-or-Insert-Muster wie `setAssessmentScore`/`saveAssessmentNote` in MeetingView.tsx. `criterionItemId` * überschreibt pro Antwort individuell die Konfigurations-Vorgabe (`ChecklistItemDef.linkedCriterionItemId`) * — siehe CLAUDE.md „Individuelle Kriterium-Zuordnung pro Checklisten-Antwort". */ export function upsertChecklistResponse(input: { meetingInstanceId: number instituteeId?: number checklistItemId: number rating: ChecklistResponse['rating'] note: string criterionItemId?: number }): number { const existing = getAllRows('checklistResponses').find(r => r.meetingInstanceId === input.meetingInstanceId && r.checklistItemId === input.checklistItemId && (r.instituteeId ?? null) === (input.instituteeId ?? null), ) if (existing?.id) { updateRow('checklistResponses', existing.id, { rating: input.rating, note: input.note, criterionItemId: input.criterionItemId }) return existing.id } return insertRow('checklistResponses', input) }