92 lines
4.8 KiB
TypeScript
92 lines
4.8 KiB
TypeScript
import {
|
|
getAllRows, getRowsWhereIn, insertRow, updateRow,
|
|
getRowsWhereEquals, deleteRowsWhereEquals, deleteRowById,
|
|
} from '../crud'
|
|
import type { FeedbackDimension, FeedbackCategory, FeedbackCriterionItem, FeedbackDimensionPrompt } from '../../../src/db/types'
|
|
import { AI_CONFIG } from '../../../src/config/constants'
|
|
|
|
export interface FeedbackStructure {
|
|
dimensions: FeedbackDimension[]
|
|
categories: FeedbackCategory[]
|
|
items: FeedbackCriterionItem[]
|
|
}
|
|
|
|
const byOrder = <T extends { order: number }>(rows: T[]) => [...rows].sort((a, b) => a.order - b.order)
|
|
|
|
/** Vollständige, nach `order` sortierte Feedback-Taxonomie. */
|
|
export function loadFeedbackStructure(): FeedbackStructure {
|
|
return {
|
|
dimensions: byOrder(getAllRows<FeedbackDimension>('feedbackDimensions')),
|
|
categories: byOrder(getAllRows<FeedbackCategory>('feedbackCategories')),
|
|
items: byOrder(getAllRows<FeedbackCriterionItem>('feedbackCriterionItems')),
|
|
}
|
|
}
|
|
|
|
export const listFeedbackCategoriesOrdered = (): FeedbackCategory[] => byOrder(getAllRows<FeedbackCategory>('feedbackCategories'))
|
|
export const listFeedbackCategoriesAll = (): FeedbackCategory[] => getAllRows<FeedbackCategory>('feedbackCategories')
|
|
export const listFeedbackCriterionItemsAll = (): FeedbackCriterionItem[] => getAllRows<FeedbackCriterionItem>('feedbackCriterionItems')
|
|
export const getFeedbackCriterionItemsByIds = (ids: number[]): FeedbackCriterionItem[] =>
|
|
getRowsWhereIn<FeedbackCriterionItem>('feedbackCriterionItems', 'id', ids)
|
|
|
|
/** Legt zusätzlich einen Default-KI-Prompt für die neue Dimension an, siehe CLAUDE.md „Mehrstufiges Prompt-System". */
|
|
export function addFeedbackDimension(d: Omit<FeedbackDimension, 'id'>): number {
|
|
const id = insertRow('feedbackDimensions', d)
|
|
insertRow('feedbackDimensionPrompts', { dimensionId: id, promptTemplate: AI_CONFIG.defaultDimensionPromptTemplate })
|
|
return id
|
|
}
|
|
export const updateFeedbackDimension = (id: number, patch: Partial<FeedbackDimension>): number =>
|
|
updateRow('feedbackDimensions', id, patch)
|
|
|
|
/** Cascade: Items der Kategorien → Kategorien → Prompt-Konfiguration → Dimension. */
|
|
export function deleteFeedbackDimension(id: number): void {
|
|
const cats = getRowsWhereEquals<FeedbackCategory>('feedbackCategories', 'dimensionId', id)
|
|
for (const cat of cats) {
|
|
deleteRowsWhereEquals('feedbackCriterionItems', 'categoryId', cat.id!)
|
|
}
|
|
deleteRowsWhereEquals('feedbackCategories', 'dimensionId', id)
|
|
deleteRowsWhereEquals('feedbackDimensionPrompts', 'dimensionId', id)
|
|
deleteRowById('feedbackDimensions', id)
|
|
}
|
|
|
|
/**
|
|
* Selbstheilend: Dimensionen, die vor Einführung des Prompt-Systems (2026-07-07) angelegt wurden,
|
|
* haben noch keine `feedbackDimensionPrompts`-Zeile — wird hier per Backfill nachgezogen, statt eine
|
|
* separate Migration zu brauchen.
|
|
*/
|
|
export function listFeedbackDimensionPrompts(): FeedbackDimensionPrompt[] {
|
|
const dims = getAllRows<FeedbackDimension>('feedbackDimensions')
|
|
const existingDimIds = new Set(getAllRows<FeedbackDimensionPrompt>('feedbackDimensionPrompts').map(p => p.dimensionId))
|
|
for (const dim of dims) {
|
|
if (!existingDimIds.has(dim.id!)) {
|
|
insertRow('feedbackDimensionPrompts', { dimensionId: dim.id!, promptTemplate: AI_CONFIG.defaultDimensionPromptTemplate })
|
|
}
|
|
}
|
|
return getAllRows<FeedbackDimensionPrompt>('feedbackDimensionPrompts')
|
|
}
|
|
|
|
/** Selbstheilend wie `listFeedbackDimensionPrompts` — legt die Zeile bei Bedarf lazy an. */
|
|
export function getFeedbackDimensionPrompt(dimensionId: number): FeedbackDimensionPrompt {
|
|
const existing = getRowsWhereEquals<FeedbackDimensionPrompt>('feedbackDimensionPrompts', 'dimensionId', dimensionId)[0]
|
|
if (existing) return existing
|
|
const id = insertRow('feedbackDimensionPrompts', { dimensionId, promptTemplate: AI_CONFIG.defaultDimensionPromptTemplate })
|
|
return { id, dimensionId, promptTemplate: AI_CONFIG.defaultDimensionPromptTemplate }
|
|
}
|
|
|
|
export const updateFeedbackDimensionPrompt = (id: number, patch: Partial<FeedbackDimensionPrompt>): number =>
|
|
updateRow('feedbackDimensionPrompts', id, patch)
|
|
|
|
export const addFeedbackCategory = (c: Omit<FeedbackCategory, 'id'>): number => insertRow('feedbackCategories', c)
|
|
export const updateFeedbackCategory = (id: number, patch: Partial<FeedbackCategory>): number =>
|
|
updateRow('feedbackCategories', id, patch)
|
|
|
|
/** Cascade: Items der Kategorie → Kategorie. */
|
|
export function deleteFeedbackCategory(id: number): void {
|
|
deleteRowsWhereEquals('feedbackCriterionItems', 'categoryId', id)
|
|
deleteRowById('feedbackCategories', id)
|
|
}
|
|
|
|
export const addFeedbackCriterionItem = (i: Omit<FeedbackCriterionItem, 'id'>): number => insertRow('feedbackCriterionItems', i)
|
|
export const updateFeedbackCriterionItem = (id: number, patch: Partial<FeedbackCriterionItem>): number =>
|
|
updateRow('feedbackCriterionItems', id, patch)
|
|
export const deleteFeedbackCriterionItem = (id: number): void => deleteRowById('feedbackCriterionItems', id)
|