fix: add showProjectIcons and weekStartDay to Prisma schema + route

Both fields existed in the DB but were missing from schema.prisma,
so the Prisma client didn't know about them. The client has been
regenerated (prisma db push). Added both fields to:
- prisma/schema.prisma (with correct defaults)
- GET select, PATCH destructure, updateData, PATCH select in route.ts

This resolves the 500 errors on PATCH /api/user/profile that occurred
when saveSetting() tried to persist these fields.

v1.81.8
This commit is contained in:
mARTin 2026-04-02 10:15:49 +02:00
parent 676c5612ed
commit b7954f9367
3 changed files with 159 additions and 152 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "my-weekly-todo-list", "name": "my-weekly-todo-list",
"version": "1.81.7", "version": "1.81.8",
"description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view", "description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {

View File

@ -9,125 +9,127 @@ datasource db {
} }
model User { model User {
id String @id @default(cuid()) id String @id @default(cuid())
email String @unique email String @unique
passwordHash String? passwordHash String?
name String? name String?
image String? image String?
emailVerified DateTime? emailVerified DateTime?
verifiedAt DateTime? verifiedAt DateTime?
emailVerificationToken String? emailVerificationToken String?
emailVerificationExpires DateTime? emailVerificationExpires DateTime?
passwordResetToken String? passwordResetToken String?
passwordResetExpires DateTime? passwordResetExpires DateTime?
createdAt DateTime @default(now()) createdAt DateTime @default(now())
updatedAt DateTime @updatedAt updatedAt DateTime @updatedAt
timezone String @default("UTC") timezone String @default("UTC")
autoRolling Boolean @default(false) autoRolling Boolean @default(false)
protectEventTimes Boolean @default(false) protectEventTimes Boolean @default(false)
showCalendarProviderIcon Boolean @default(false) language String @default("de")
language String @default("de") dateFormat String @default("yyyy-MM-dd")
dateFormat String @default("yyyy-MM-dd") timeFormat String @default("24h")
timeFormat String @default("24h") startHour Int @default(8)
startHour Int @default(8) endHour Int @default(18)
endHour Int @default(18) showNextTask Boolean @default(false)
showNextTask Boolean @default(false) calendarEditMode Boolean @default(false)
calendarEditMode Boolean @default(false) focusTimerDuration Int @default(25)
focusTimerDuration Int @default(25) focusBreakDuration Int @default(5)
focusBreakDuration Int @default(5) showTimeGrid Boolean @default(true)
showTimeGrid Boolean @default(true) showSomeday Boolean @default(true)
showSomeday Boolean @default(true) showAllDayEvents Boolean @default(true)
showAllDayEvents Boolean @default(true) showSchedule Boolean @default(true)
showSchedule Boolean @default(true) cellDuration Int @default(30)
cellDuration Int @default(30) viewStyle String @default("simple")
viewStyle String @default("simple") viewDays Int @default(7)
viewDays Int @default(7) fontSize String @default("M")
fontSize String @default("M") goalFallbackType String @default("quote")
goalFallbackType String @default("quote") goalDefaultSentence String @default("goal of the week")
goalDefaultSentence String @default("goal of the week") goalFontFamily String? @default("Lato")
goalFontFamily String? @default("Lato") goalFontSize String? @default("1rem")
goalFontSize String? @default("1rem") goalFontWeight String? @default("500")
goalFontWeight String? @default("500") headlineFont String @default("Oswald")
headlineFont String @default("Oswald") headlineFontSize String? @default("1.5rem")
headlineFontSize String? @default("1.5rem") headlineFontWeight String? @default("900")
headlineFontWeight String? @default("900") dateFontFamily String? @default("Inter")
dateFontFamily String? @default("Inter") dateFontSize String? @default("0.65rem")
dateFontSize String? @default("0.65rem") dateFontWeight String? @default("400")
dateFontWeight String? @default("400") timeTaskFontFamily String? @default("Inter")
timeTaskFontFamily String? @default("Inter") timeTaskFontSize String? @default("0.75rem")
timeTaskFontSize String? @default("0.75rem") timeTaskFontWeight String? @default("500")
timeTaskFontWeight String? @default("500") bodyFont String @default("Inter")
bodyFont String @default("Inter") taskFontFamily String? @default("Inter")
taskFontFamily String? @default("Inter") taskFontSize String? @default("0.9rem")
taskFontSize String? @default("0.9rem") taskFontWeight String? @default("400")
taskFontWeight String? @default("400") eventFontFamily String? @default("Inter")
eventFontFamily String? @default("Inter") eventFontSize String? @default("0.85rem")
eventFontSize String? @default("0.85rem") eventFontWeight String? @default("400")
eventFontWeight String? @default("400") lightTheme Json?
lightTheme Json? darkTheme Json?
darkTheme Json? fontWeight String @default("400")
fontWeight String @default("400") weekdayColor String? @default("#0ea5e9")
weekdayColor String? @default("#0ea5e9") dateColor String? @default("#888888")
dateColor String? @default("#888888") taskColor String? @default("#333333")
taskColor String? @default("#333333") todayHighlightColor String? @default("#f0fafa")
todayHighlightColor String? @default("#f0fafa") weekendColorSat String? @default("#ffc107")
weekendColorSat String? @default("#ffc107") weekendColorSun String? @default("#dc2626")
weekendColorSun String? @default("#dc2626") pastDayColor String? @default("#a6a6a7")
pastDayColor String? @default("#a6a6a7") goalScope String @default("week")
goalScope String @default("week") dateLayout String @default("right")
dateLayout String @default("right") mobileDateLayout String @default("below")
mobileDateLayout String @default("below") dateAlignment String @default("center")
dateAlignment String @default("center") dateVerticalAlign String? @default("middle")
dateVerticalAlign String? @default("middle") headerDisplay String? @default("kw")
headerDisplay String? @default("kw") headerCustomFormat String? @default("KW WW | YYYY")
headerCustomFormat String? @default("KW WW | YYYY") hourLabelFormat String @default("short")
headerCurrentDayFormat String? @default("DDD, DD. MMMM YYYY") showSubHourSlots Boolean @default(true)
mobilePortraitHeaderDisplay String? @default("current_day") allDayPosition String @default("above")
mobileLandscapeHeaderDisplay String? @default("kw") cwColor String? @default("#333333")
hourLabelFormat String @default("short") cwFontFamily String? @default("Oswald")
showSubHourSlots Boolean @default(true) cwFontSize String? @default("1.5rem")
allDayPosition String @default("above") cwFontWeight String? @default("700")
cwColor String? @default("#333333") yearColor String? @default("#333333")
cwFontFamily String? @default("Oswald") yearFontFamily String? @default("Oswald")
cwFontSize String? @default("1.5rem") yearFontSize String? @default("1.5rem")
cwFontWeight String? @default("700") yearFontWeight String? @default("700")
yearColor String? @default("#333333") showTaskCheckboxes Boolean @default(false)
yearFontFamily String? @default("Oswald") showProjectIcons Boolean @default(false)
yearFontSize String? @default("1.5rem") weekStartDay Int @default(1)
yearFontWeight String? @default("700") emailVerificationCode String?
showTaskCheckboxes Boolean @default(false) dayHeaderGap String? @default("0.75em")
emailVerificationCode String? accountNumber Int @unique @default(autoincrement())
dayHeaderGap String? @default("0.75em") showCompletedTasks Boolean @default(true)
accountNumber Int @unique @default(autoincrement()) showLines Boolean @default(true)
showCompletedTasks Boolean @default(true) weekdayFormat String? @default("long")
showLines Boolean @default(true) weekdayCase String? @default("capitalize")
weekdayFormat String? @default("long") customWeekdayNames String? @default("")
weekdayCase String? @default("capitalize") mobileFontScale Float @default(1.0)
customWeekdayNames String? @default("") startDayOffset Int @default(-1)
mobileFontScale Float @default(1.0) quoteSourceUrls String[] @default([])
startDayOffset Int @default(-1) quoteLanguages String[] @default(["en", "de"])
quoteSourceUrls String[] @default([]) kanbanStages String?
quoteLanguages String[] @default(["en", "de"]) notificationsEnabled Boolean @default(false)
kanbanStages String? weatherEnabled Boolean @default(false)
viewSettings Json? weatherLat Float?
accounts Account[] weatherLocation String?
cachedCalendarEvents CachedCalendarEvent[] weatherLon Float?
calendarConnections CalendarConnection[] viewSettings Json?
calendarSyncRules CalendarSyncRule[] weatherRecentCities Json?
projects Project[] hasCompletedOnboarding Boolean @default(true)
sessions Session[] showCalendarProviderIcon Boolean @default(false)
weatherEnabled Boolean @default(false) headerCurrentDayFormat String? @default("DDD, DD. MMMM YYYY")
weatherLat Float? mobileLandscapeHeaderDisplay String? @default("kw")
weatherLon Float? mobilePortraitHeaderDisplay String? @default("current_day")
weatherLocation String? accounts Account[]
weatherRecentCities Json? cachedCalendarEvents CachedCalendarEvent[]
hasCompletedOnboarding Boolean @default(true) calendarConnections CalendarConnection[]
notificationsEnabled Boolean @default(false) calendarSyncRules CalendarSyncRule[]
somedayLists SomedayList[] projects Project[]
tasks Task[] pushSubscriptions PushSubscription[]
weeklyGoals WeeklyGoal[] sentNotifications SentNotification[]
pushSubscriptions PushSubscription[] sessions Session[]
sentNotifications SentNotification[] somedayLists SomedayList[]
tasks Task[]
weeklyGoals WeeklyGoal[]
} }
model Account { model Account {
@ -266,11 +268,10 @@ model CachedCalendarEvent {
url String? url String?
recurringEventId String? recurringEventId String?
isRecurring Boolean @default(false) isRecurring Boolean @default(false)
reminders Json?
connection CalendarConnection @relation(fields: [connectionId], references: [id], onDelete: Cascade) connection CalendarConnection @relation(fields: [connectionId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade) user User @relation(fields: [userId], references: [id], onDelete: Cascade)
reminders Json?
@@unique([userId, externalId, provider]) @@unique([userId, externalId, provider])
@@index([userId, startDateTime]) @@index([userId, startDateTime])
@@index([userId, startDate]) @@index([userId, startDate])
@ -321,40 +322,40 @@ model PushSubscription {
} }
model CalendarSyncRule { model CalendarSyncRule {
id String @id @default(cuid()) id String @id @default(cuid())
userId String userId String
name String @default("") name String @default("")
enabled Boolean @default(true) enabled Boolean @default(true)
direction String @default("one-way") // "one-way" (source→target) direction String @default("one-way")
sourceConnectionId String sourceConnectionId String
sourceCalendarId String sourceCalendarId String
targetConnectionId String targetConnectionId String
targetCalendarId String targetCalendarId String
syncDescription Boolean @default(true) syncDescription Boolean @default(true)
syncLocation Boolean @default(true) syncLocation Boolean @default(true)
syncRecurring Boolean @default(false) syncRecurring Boolean @default(false)
titlePrefix String @default("") titlePrefix String @default("")
createdAt DateTime @default(now()) createdAt DateTime @default(now())
updatedAt DateTime @updatedAt updatedAt DateTime @updatedAt
lastSyncedAt DateTime? lastSyncedAt DateTime?
mappings CalendarSyncMapping[] mappings CalendarSyncMapping[]
user User @relation(fields: [userId], references: [id], onDelete: Cascade) user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([userId]) @@index([userId])
} }
model CalendarSyncMapping { model CalendarSyncMapping {
id String @id @default(cuid()) id String @id @default(cuid())
ruleId String ruleId String
userId String userId String
sourceEventId String sourceEventId String
sourceProvider String sourceProvider String
targetEventId String targetEventId String
targetProvider String targetProvider String
targetCalendarId String targetCalendarId String
sourceFingerprint String sourceFingerprint String
lastSyncedAt DateTime @default(now()) lastSyncedAt DateTime @default(now())
rule CalendarSyncRule @relation(fields: [ruleId], references: [id], onDelete: Cascade) rule CalendarSyncRule @relation(fields: [ruleId], references: [id], onDelete: Cascade)
@@unique([ruleId, sourceEventId]) @@unique([ruleId, sourceEventId])
@@index([userId, targetEventId, targetProvider]) @@index([userId, targetEventId, targetProvider])
@ -362,12 +363,12 @@ model CalendarSyncMapping {
} }
model SentNotification { model SentNotification {
id String @id @default(cuid()) id String @id @default(cuid())
userId String userId String
eventId String eventId String
minutes Int minutes Int
sentAt DateTime @default(now()) sentAt DateTime @default(now())
user User @relation(fields: [userId], references: [id], onDelete: Cascade) user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([userId, eventId, minutes]) @@unique([userId, eventId, minutes])
@@index([sentAt]) @@index([sentAt])

View File

@ -33,6 +33,7 @@ export async function GET(request: NextRequest) {
showAllDayEvents: true, showAllDayEvents: true,
showSchedule: true, showSchedule: true,
showTaskCheckboxes: true, showTaskCheckboxes: true,
showProjectIcons: true,
cellDuration: true, cellDuration: true,
viewStyle: true, viewStyle: true,
viewDays: true, viewDays: true,
@ -93,6 +94,7 @@ export async function GET(request: NextRequest) {
weekdayFormat: true, weekdayFormat: true,
weekdayCase: true, weekdayCase: true,
customWeekdayNames: true, customWeekdayNames: true,
weekStartDay: true,
quoteSourceUrls: true, quoteSourceUrls: true,
quoteLanguages: true, quoteLanguages: true,
kanbanStages: true, kanbanStages: true,
@ -148,8 +150,8 @@ export async function PATCH(request: NextRequest) {
hourLabelFormat, showSubHourSlots, allDayPosition, hourLabelFormat, showSubHourSlots, allDayPosition,
cwFontFamily, cwFontSize, cwFontWeight, cwColor, cwFontFamily, cwFontSize, cwFontWeight, cwColor,
yearFontFamily, yearFontSize, yearFontWeight, yearColor, yearFontFamily, yearFontSize, yearFontWeight, yearColor,
showTaskCheckboxes, dayHeaderGap, showTaskCheckboxes, showProjectIcons, dayHeaderGap,
showCompletedTasks, showLines, startDayOffset, weekdayFormat, weekdayCase, customWeekdayNames, quoteSourceUrls, quoteLanguages, showCompletedTasks, showLines, startDayOffset, weekdayFormat, weekdayCase, customWeekdayNames, weekStartDay, quoteSourceUrls, quoteLanguages,
kanbanStages, lightTheme, darkTheme, notificationsEnabled, mobileFontScale, kanbanStages, lightTheme, darkTheme, notificationsEnabled, mobileFontScale,
weatherEnabled, weatherLat, weatherLon, weatherLocation, weatherRecentCities, viewSettings, weatherEnabled, weatherLat, weatherLon, weatherLocation, weatherRecentCities, viewSettings,
hasCompletedOnboarding hasCompletedOnboarding
@ -175,6 +177,7 @@ export async function PATCH(request: NextRequest) {
...(showAllDayEvents !== undefined && { showAllDayEvents }), ...(showAllDayEvents !== undefined && { showAllDayEvents }),
...(showSchedule !== undefined && { showSchedule }), ...(showSchedule !== undefined && { showSchedule }),
...(showTaskCheckboxes !== undefined && { showTaskCheckboxes }), ...(showTaskCheckboxes !== undefined && { showTaskCheckboxes }),
...(showProjectIcons !== undefined && { showProjectIcons }),
...(cellDuration !== undefined && !isNaN(cellDuration) && { cellDuration }), ...(cellDuration !== undefined && !isNaN(cellDuration) && { cellDuration }),
...(viewStyle !== undefined && { viewStyle }), ...(viewStyle !== undefined && { viewStyle }),
...(viewDays !== undefined && !isNaN(viewDays) && { viewDays }), ...(viewDays !== undefined && !isNaN(viewDays) && { viewDays }),
@ -235,6 +238,7 @@ export async function PATCH(request: NextRequest) {
...(weekdayFormat !== undefined && { weekdayFormat }), ...(weekdayFormat !== undefined && { weekdayFormat }),
...(weekdayCase !== undefined && { weekdayCase }), ...(weekdayCase !== undefined && { weekdayCase }),
...(customWeekdayNames !== undefined && { customWeekdayNames }), ...(customWeekdayNames !== undefined && { customWeekdayNames }),
...(weekStartDay !== undefined && { weekStartDay }),
...(quoteSourceUrls !== undefined && { quoteSourceUrls }), ...(quoteSourceUrls !== undefined && { quoteSourceUrls }),
...(quoteLanguages !== undefined && { quoteLanguages }), ...(quoteLanguages !== undefined && { quoteLanguages }),
...(kanbanStages !== undefined && { kanbanStages }), ...(kanbanStages !== undefined && { kanbanStages }),
@ -278,6 +282,7 @@ export async function PATCH(request: NextRequest) {
showAllDayEvents: true, showAllDayEvents: true,
showSchedule: true, showSchedule: true,
showTaskCheckboxes: true, showTaskCheckboxes: true,
showProjectIcons: true,
cellDuration: true, cellDuration: true,
viewStyle: true, viewStyle: true,
viewDays: true, viewDays: true,
@ -338,6 +343,7 @@ export async function PATCH(request: NextRequest) {
weekdayFormat: true, weekdayFormat: true,
weekdayCase: true, weekdayCase: true,
customWeekdayNames: true, customWeekdayNames: true,
weekStartDay: true,
quoteSourceUrls: true, quoteSourceUrls: true,
quoteLanguages: true, quoteLanguages: true,
kanbanStages: true, kanbanStages: true,