feat: add stock calculation mode to user settings with automatic and manual options

This commit is contained in:
Daniel Volz
2025-12-28 15:03:24 +01:00
parent 78ee668c8b
commit 0e52a03f7a
8 changed files with 165 additions and 10 deletions
@@ -0,0 +1,4 @@
-- Add stock calculation mode setting
-- "automatic" = stock decreases based on schedule from start date
-- "manual" = stock only decreases when doses are marked as taken
ALTER TABLE user_settings ADD COLUMN stock_calculation_mode TEXT NOT NULL DEFAULT 'automatic';
+2 -1
View File
@@ -13,6 +13,7 @@
{ "idx": 10, "version": 1, "when": 1735600000, "tag": "0010_add_user_settings", "breakpoint": false },
{ "idx": 11, "version": 1, "when": 1735700000, "tag": "0011_add_dose_tracking", "breakpoint": false },
{ "idx": 12, "version": 1, "when": 1735800000, "tag": "0012_add_user_avatar", "breakpoint": false },
{ "idx": 13, "version": 1, "when": 1735900000, "tag": "0013_add_oidc_subject", "breakpoint": false }
{ "idx": 13, "version": 1, "when": 1735900000, "tag": "0013_add_oidc_subject", "breakpoint": false },
{ "idx": 14, "version": 1, "when": 1735400000, "tag": "0014_add_stock_calculation_mode", "breakpoint": false }
]
}
+2
View File
@@ -69,6 +69,8 @@ export const userSettings = sqliteTable("user_settings", {
highStockDays: integer("high_stock_days").notNull().default(180),
// UI preferences
language: text("language", { length: 10 }).notNull().default("en"),
// Stock calculation mode: "automatic" (schedule-based) or "manual" (only marked doses)
stockCalculationMode: text("stock_calculation_mode", { length: 20 }).notNull().default("automatic"),
// Last notification tracking
lastAutoEmailSent: text("last_auto_email_sent"),
lastNotificationType: text("last_notification_type"),
+7
View File
@@ -25,6 +25,7 @@ export type UserSettings = {
normalStockDays: number;
highStockDays: number;
language: Language;
stockCalculationMode: "automatic" | "manual";
lastAutoEmailSent: string | null;
lastNotificationType: string | null;
lastNotificationChannel: string | null;
@@ -45,6 +46,7 @@ type SettingsBody = {
shoutrrrStockReminders: boolean;
shoutrrrIntakeReminders: boolean;
language: string;
stockCalculationMode: "automatic" | "manual";
};
type TestEmailBody = {
@@ -71,6 +73,7 @@ const defaultSettings = {
normalStockDays: 90,
highStockDays: 180,
language: "en",
stockCalculationMode: "automatic" as const,
lastAutoEmailSent: null,
lastNotificationType: null,
lastNotificationChannel: null,
@@ -110,6 +113,7 @@ export async function loadUserSettings(userId: number): Promise<UserSettings> {
normalStockDays: settings.normalStockDays,
highStockDays: settings.highStockDays,
language: settings.language as Language,
stockCalculationMode: (settings.stockCalculationMode as "automatic" | "manual") ?? "automatic",
lastAutoEmailSent: settings.lastAutoEmailSent,
lastNotificationType: settings.lastNotificationType,
lastNotificationChannel: settings.lastNotificationChannel,
@@ -135,6 +139,7 @@ export async function getAllUserSettings(): Promise<UserSettings[]> {
normalStockDays: settings.normalStockDays,
highStockDays: settings.highStockDays,
language: settings.language as Language,
stockCalculationMode: (settings.stockCalculationMode as "automatic" | "manual") ?? "automatic",
lastAutoEmailSent: settings.lastAutoEmailSent,
lastNotificationType: settings.lastNotificationType,
lastNotificationChannel: settings.lastNotificationChannel,
@@ -183,6 +188,7 @@ export async function settingsRoutes(app: FastifyInstance) {
shoutrrrStockReminders: settings.shoutrrrStockReminders,
shoutrrrIntakeReminders: settings.shoutrrrIntakeReminders,
language: settings.language,
stockCalculationMode: settings.stockCalculationMode ?? "automatic",
// SMTP settings (from .env - shared/server-configured)
smtpHost: process.env.SMTP_HOST ?? "",
smtpPort: parseInt(process.env.SMTP_PORT ?? "587"),
@@ -231,6 +237,7 @@ export async function settingsRoutes(app: FastifyInstance) {
normalStockDays: body.normalStockDays ?? 90,
highStockDays: body.highStockDays ?? 180,
language: body.language ?? "en",
stockCalculationMode: body.stockCalculationMode ?? "automatic",
updatedAt: new Date(),
};