CG-Feedback-Monitor/server/db/queries/appSettings.ts

199 lines
8.1 KiB
TypeScript
Raw Normal View History

2026-07-06 19:08:24 +02:00
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'
2026-07-06 19:08:24 +02:00
/** 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>('appSettings', 1)
return settings?.ratingTrendWeightStep ?? DEFAULT_RATING_TREND_WEIGHT_STEP
}
export function getOrSeedRatingTrendWeightStep(): number {
let settings = getRowById<AppSettings>('appSettings', 1)
if (!settings) {
insertRowWithId('appSettings', 1, { ratingTrendWeightStep: DEFAULT_RATING_TREND_WEIGHT_STEP })
settings = getRowById<AppSettings>('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>('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>('appSettings', 1)
return settings?.defaultDimensionPromptTemplate ?? AI_CONFIG.defaultDimensionPromptTemplate
}
export function getOrSeedDefaultDimensionPromptTemplate(): string {
const settings = getRowById<AppSettings>('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>('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>('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>('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>('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
}