import { getRowById, insertRowWithId, updateRow } from '../crud' import type { AppSettings, RatingColorBand } from '../../../src/db/types' import { AI_CONFIG, DEFAULT_RATING_COLOR_BANDS, normalizeRatingColorBands } from '../../../src/config/constants' /** Muss mit DEFAULT_RATING_TREND_WEIGHT_STEP in src/config/constants.ts synchron gehalten werden. */ const DEFAULT_RATING_TREND_WEIGHT_STEP = 0.5 export function getRatingTrendWeightStep(): number { const settings = getRowById('appSettings', 1) return settings?.ratingTrendWeightStep ?? DEFAULT_RATING_TREND_WEIGHT_STEP } export function getOrSeedRatingTrendWeightStep(): number { let settings = getRowById('appSettings', 1) if (!settings) { insertRowWithId('appSettings', 1, { ratingTrendWeightStep: DEFAULT_RATING_TREND_WEIGHT_STEP }) settings = getRowById('appSettings', 1) } return settings?.ratingTrendWeightStep ?? DEFAULT_RATING_TREND_WEIGHT_STEP } export function saveRatingTrendWeightStep(weightStep: number): number { const existing = getRowById('appSettings', 1) if (existing) updateRow('appSettings', 1, { ratingTrendWeightStep: weightStep }) else insertRowWithId('appSettings', 1, { ratingTrendWeightStep: weightStep }) return 1 } export function getOrSeedRatingColorBands(): RatingColorBand[] { let settings = getRowById('appSettings', 1) if (!settings) { insertRowWithId('appSettings', 1, { ratingTrendWeightStep: DEFAULT_RATING_TREND_WEIGHT_STEP, ratingColorBands: DEFAULT_RATING_COLOR_BANDS.map(b => ({ ...b })), }) return DEFAULT_RATING_COLOR_BANDS.map(b => ({ ...b })) } if (!settings.ratingColorBands?.length) { const seeded = DEFAULT_RATING_COLOR_BANDS.map(b => ({ ...b })) updateRow('appSettings', 1, { ratingColorBands: seeded }) return seeded } return normalizeRatingColorBands(settings.ratingColorBands) } export function saveRatingColorBands(bands: RatingColorBand[]): number { const normalized = normalizeRatingColorBands(bands) const existing = getRowById('appSettings', 1) if (existing) updateRow('appSettings', 1, { ratingColorBands: normalized }) else insertRowWithId('appSettings', 1, { ratingTrendWeightStep: DEFAULT_RATING_TREND_WEIGHT_STEP, ratingColorBands: normalized, }) return 1 } /** * Der Standard-Prompt für neue Dimensionen/"Zurücksetzen" lebt jetzt in der DB statt im Code * (`AI_CONFIG.defaultDimensionPromptTemplate` dient nur noch als einmaliger Erstbefüllungs-Wert * beim allerersten Zugriff auf einer Installation, siehe Config → KI-Prompts). */ export function getDefaultDimensionPromptTemplate(): string { const settings = getRowById('appSettings', 1) return settings?.defaultDimensionPromptTemplate ?? AI_CONFIG.defaultDimensionPromptTemplate } export function getOrSeedDefaultDimensionPromptTemplate(): string { const settings = getRowById('appSettings', 1) if (!settings) { insertRowWithId('appSettings', 1, { ratingTrendWeightStep: DEFAULT_RATING_TREND_WEIGHT_STEP, defaultDimensionPromptTemplate: AI_CONFIG.defaultDimensionPromptTemplate, }) return AI_CONFIG.defaultDimensionPromptTemplate } if (!settings.defaultDimensionPromptTemplate) { updateRow('appSettings', 1, { defaultDimensionPromptTemplate: AI_CONFIG.defaultDimensionPromptTemplate }) return AI_CONFIG.defaultDimensionPromptTemplate } return settings.defaultDimensionPromptTemplate } export function saveDefaultDimensionPromptTemplate(template: string): number { const existing = getRowById('appSettings', 1) if (existing) updateRow('appSettings', 1, { defaultDimensionPromptTemplate: template }) else insertRowWithId('appSettings', 1, { ratingTrendWeightStep: DEFAULT_RATING_TREND_WEIGHT_STEP, defaultDimensionPromptTemplate: template }) return 1 } /** * Prompt-Template für Protokoll-Tagging („🏷 Vorschläge analysieren", Freitext-Zeilen). * Checklisten haben seit der Trennung ein eigenes Template (`checklistTaggingPromptTemplate`). * Alte Zwischenstände mit `{{CHECKLISTEN_PUNKTE}}` im Protokoll-Prompt werden einmalig auf den * aktuellen Protokoll-Standard migriert — sonst bleibt der Platzhalter unersetzt und die KI * liefert keine brauchbaren ZEILE-Vorschläge mehr. */ export function getOrSeedCriterionTaggingPromptTemplate(): string { const fresh = AI_CONFIG.defaultCriterionTaggingPromptTemplate let settings = getRowById('appSettings', 1) if (!settings) { insertRowWithId('appSettings', 1, { ratingTrendWeightStep: DEFAULT_RATING_TREND_WEIGHT_STEP, criterionTaggingPromptTemplate: fresh, }) return fresh } const stored = settings.criterionTaggingPromptTemplate if (!stored || stored.includes('{{CHECKLISTEN_PUNKTE}}')) { updateRow('appSettings', 1, { criterionTaggingPromptTemplate: fresh }) return fresh } return stored } export function saveCriterionTaggingPromptTemplate(template: string): number { const existing = getRowById('appSettings', 1) if (existing) updateRow('appSettings', 1, { criterionTaggingPromptTemplate: template }) else insertRowWithId('appSettings', 1, { ratingTrendWeightStep: DEFAULT_RATING_TREND_WEIGHT_STEP, criterionTaggingPromptTemplate: template }) return 1 } export function getOrSeedChecklistTaggingPromptTemplate(): string { let settings = getRowById('appSettings', 1) if (!settings) { insertRowWithId('appSettings', 1, { ratingTrendWeightStep: DEFAULT_RATING_TREND_WEIGHT_STEP, checklistTaggingPromptTemplate: AI_CONFIG.defaultChecklistTaggingPromptTemplate, }) return AI_CONFIG.defaultChecklistTaggingPromptTemplate } if (!settings.checklistTaggingPromptTemplate) { updateRow('appSettings', 1, { checklistTaggingPromptTemplate: AI_CONFIG.defaultChecklistTaggingPromptTemplate }) return AI_CONFIG.defaultChecklistTaggingPromptTemplate } return settings.checklistTaggingPromptTemplate } export function saveChecklistTaggingPromptTemplate(template: string): number { const existing = getRowById('appSettings', 1) if (existing) updateRow('appSettings', 1, { checklistTaggingPromptTemplate: template }) else insertRowWithId('appSettings', 1, { ratingTrendWeightStep: DEFAULT_RATING_TREND_WEIGHT_STEP, checklistTaggingPromptTemplate: template, }) return 1 } export function getOrSeedDefaultCategoryPromptTemplate(): string { let settings = getRowById('appSettings', 1) if (!settings) { insertRowWithId('appSettings', 1, { ratingTrendWeightStep: DEFAULT_RATING_TREND_WEIGHT_STEP, defaultCategoryPromptTemplate: AI_CONFIG.defaultCategoryPromptTemplate, }) return AI_CONFIG.defaultCategoryPromptTemplate } if (!settings.defaultCategoryPromptTemplate) { updateRow('appSettings', 1, { defaultCategoryPromptTemplate: AI_CONFIG.defaultCategoryPromptTemplate }) return AI_CONFIG.defaultCategoryPromptTemplate } return settings.defaultCategoryPromptTemplate } export function saveDefaultCategoryPromptTemplate(template: string): number { const existing = getRowById('appSettings', 1) if (existing) updateRow('appSettings', 1, { defaultCategoryPromptTemplate: template }) else insertRowWithId('appSettings', 1, { ratingTrendWeightStep: DEFAULT_RATING_TREND_WEIGHT_STEP, defaultCategoryPromptTemplate: template, }) return 1 } export function getOrSeedRequirePlannedDates(): boolean { let settings = getRowById('appSettings', 1) if (!settings) { insertRowWithId('appSettings', 1, { ratingTrendWeightStep: DEFAULT_RATING_TREND_WEIGHT_STEP, requirePlannedDates: false, }) return false } if (settings.requirePlannedDates === undefined || settings.requirePlannedDates === null) { updateRow('appSettings', 1, { requirePlannedDates: false }) return false } return !!settings.requirePlannedDates } export function saveRequirePlannedDates(required: boolean): number { const existing = getRowById('appSettings', 1) if (existing) updateRow('appSettings', 1, { requirePlannedDates: required }) else insertRowWithId('appSettings', 1, { ratingTrendWeightStep: DEFAULT_RATING_TREND_WEIGHT_STEP, requirePlannedDates: required, }) return 1 }