173 lines
5.2 KiB
TypeScript
173 lines
5.2 KiB
TypeScript
/**
|
|
* Einzige Quelle der Wahrheit für alle SQL-Tabellen — treibt sowohl die Schema-Erstellung
|
|
* (database.ts) als auch Export/Import (queries/backup.ts) an. Eine neue Tabelle, die hier
|
|
* fehlt, fehlt dadurch gleichzeitig im Schema UND im Backup — sichtbarer Fehler statt eines
|
|
* Datenverlusts, der erst beim nächsten Restore aus dem Backup auffällt (siehe CLAUDE.md:
|
|
* appSettings fehlte einmal in TABLE_NAMES).
|
|
*
|
|
* 1:1 abgeleitet aus TABLE_NAMES (src/utils/dbBackup.ts) und den Interfaces in src/db/types.ts.
|
|
*/
|
|
|
|
export type ColumnCodec = 'json' | 'bool' | 'plain'
|
|
|
|
export interface ColumnDef {
|
|
name: string
|
|
sqlType: 'INTEGER' | 'TEXT' | 'REAL'
|
|
codec: ColumnCodec
|
|
}
|
|
|
|
export interface TableDef {
|
|
name: string
|
|
columns: ColumnDef[]
|
|
}
|
|
|
|
const col = (name: string, sqlType: ColumnDef['sqlType'], codec: ColumnCodec = 'plain'): ColumnDef =>
|
|
({ name, sqlType, codec })
|
|
|
|
export const TABLE_DEFINITIONS: TableDef[] = [
|
|
{ name: 'categories', columns: [
|
|
col('name', 'TEXT'),
|
|
col('order', 'INTEGER'),
|
|
]},
|
|
{ name: 'criteria', columns: [
|
|
col('categoryId', 'INTEGER'),
|
|
col('name', 'TEXT'),
|
|
col('description', 'TEXT'),
|
|
col('weight', 'REAL'),
|
|
col('order', 'INTEGER'),
|
|
]},
|
|
{ name: 'assignmentTypes', columns: [
|
|
col('name', 'TEXT'),
|
|
col('defaultPhaseKeys', 'TEXT', 'json'),
|
|
col('criteriaIds', 'TEXT', 'json'),
|
|
]},
|
|
{ name: 'phaseTemplates', columns: [
|
|
col('assignmentTypeId', 'INTEGER'),
|
|
col('phaseKey', 'TEXT'),
|
|
col('label', 'TEXT'),
|
|
col('withWhom', 'TEXT'),
|
|
col('isRepeatable', 'INTEGER', 'bool'),
|
|
col('hasConversation', 'INTEGER', 'bool'),
|
|
col('hasAssessment', 'INTEGER', 'bool'),
|
|
col('criteriaIds', 'TEXT', 'json'),
|
|
col('order', 'INTEGER'),
|
|
]},
|
|
{ name: 'groups', columns: [
|
|
col('name', 'TEXT'),
|
|
col('cohortYear', 'INTEGER'),
|
|
]},
|
|
{ name: 'consultants', columns: [
|
|
col('groupId', 'INTEGER'),
|
|
col('firstName', 'TEXT'),
|
|
col('lastName', 'TEXT'),
|
|
]},
|
|
{ name: 'assignments', columns: [
|
|
col('title', 'TEXT'),
|
|
col('client', 'TEXT'),
|
|
col('assignmentTypeId', 'INTEGER'),
|
|
col('instituteeIds', 'TEXT', 'json'),
|
|
col('leadName', 'TEXT'),
|
|
col('status', 'TEXT'),
|
|
col('createdAt', 'TEXT'),
|
|
col('assignmentNumber', 'TEXT'),
|
|
col('description', 'TEXT'),
|
|
col('instituteeEnrollments', 'TEXT', 'json'),
|
|
]},
|
|
{ name: 'meetingInstances', columns: [
|
|
col('assignmentId', 'INTEGER'),
|
|
col('phaseTemplateId', 'INTEGER'),
|
|
col('phaseIndex', 'INTEGER'),
|
|
col('date', 'TEXT'),
|
|
col('status', 'TEXT'),
|
|
col('generalNotes', 'TEXT'),
|
|
col('deletedAt', 'TEXT'),
|
|
]},
|
|
{ name: 'conversationEntries', columns: [
|
|
col('meetingInstanceId', 'INTEGER'),
|
|
col('instituteeId', 'INTEGER'),
|
|
col('sequenceIndex', 'INTEGER'),
|
|
col('note', 'TEXT'),
|
|
col('fillerCount', 'INTEGER'),
|
|
col('updatedAt', 'TEXT'),
|
|
col('lineTags', 'TEXT', 'json'),
|
|
]},
|
|
{ name: 'conversationSkillScores', columns: [
|
|
col('conversationEntryId', 'INTEGER'),
|
|
col('criteriaId', 'INTEGER'),
|
|
col('score', 'TEXT'),
|
|
]},
|
|
{ name: 'assessments', columns: [
|
|
col('meetingInstanceId', 'INTEGER'),
|
|
col('instituteeId', 'INTEGER'),
|
|
col('criteriaId', 'INTEGER'),
|
|
col('score', 'TEXT'),
|
|
col('note', 'TEXT'),
|
|
col('updatedAt', 'TEXT'),
|
|
]},
|
|
{ name: 'feedbackDrafts', columns: [
|
|
col('assignmentId', 'INTEGER'),
|
|
col('instituteeId', 'INTEGER'),
|
|
col('content', 'TEXT'),
|
|
col('updatedAt', 'TEXT'),
|
|
]},
|
|
{ name: 'feedbackDimensions', columns: [
|
|
col('name', 'TEXT'),
|
|
col('order', 'INTEGER'),
|
|
]},
|
|
{ name: 'feedbackCategories', columns: [
|
|
col('dimensionId', 'INTEGER'),
|
|
col('name', 'TEXT'),
|
|
col('order', 'INTEGER'),
|
|
]},
|
|
{ name: 'feedbackCriterionItems', columns: [
|
|
col('categoryId', 'INTEGER'),
|
|
col('name', 'TEXT'),
|
|
col('weight', 'REAL'),
|
|
col('order', 'INTEGER'),
|
|
]},
|
|
{ name: 'assignmentFeedbacks', columns: [
|
|
col('assignmentId', 'INTEGER'),
|
|
col('instituteeId', 'INTEGER'),
|
|
col('status', 'TEXT'),
|
|
col('aiModel', 'TEXT'),
|
|
col('updatedAt', 'TEXT'),
|
|
]},
|
|
{ name: 'feedbackCategoryRatings', columns: [
|
|
col('assignmentFeedbackId', 'INTEGER'),
|
|
col('feedbackCategoryId', 'INTEGER'),
|
|
col('rating', 'TEXT'),
|
|
]},
|
|
{ name: 'feedbackDimensionTexts', columns: [
|
|
col('assignmentFeedbackId', 'INTEGER'),
|
|
col('feedbackDimensionId', 'INTEGER'),
|
|
col('achievements', 'TEXT'),
|
|
col('developmentNeeds', 'TEXT'),
|
|
col('suggestedAchievements', 'TEXT'),
|
|
col('suggestedDevelopmentNeeds', 'TEXT'),
|
|
]},
|
|
{ name: 'feedbackDimensionPrompts', columns: [
|
|
col('dimensionId', 'INTEGER'),
|
|
col('promptTemplate', 'TEXT'),
|
|
]},
|
|
{ name: 'feedbackCategoryTexts', columns: [
|
|
col('assignmentFeedbackId', 'INTEGER'),
|
|
col('feedbackCategoryId', 'INTEGER'),
|
|
col('text', 'TEXT'),
|
|
col('suggestedText', 'TEXT'),
|
|
]},
|
|
{ name: 'criterionCategoryMappings', columns: [
|
|
col('criterionId', 'INTEGER'),
|
|
col('feedbackCategoryId', 'INTEGER'),
|
|
]},
|
|
{ name: 'criterionLevelDescriptions', columns: [
|
|
col('criterionItemId', 'INTEGER'),
|
|
col('rating', 'TEXT'),
|
|
col('text', 'TEXT'),
|
|
]},
|
|
{ name: 'appSettings', columns: [
|
|
col('ratingTrendWeightStep', 'REAL'),
|
|
]},
|
|
]
|
|
|
|
export const TABLE_NAMES = TABLE_DEFINITIONS.map(t => t.name)
|