feat: implement per-person dose tracking and update migration process
- Enhanced the database migration process to ensure compatibility with existing production databases, including detailed steps for adding/modifying columns. - Updated the client-side logic to support tracking doses taken by multiple users, including changes to the data structure and UI components. - Added new styles for per-person dose tracking to improve user experience and visual clarity.
This commit is contained in:
@@ -78,6 +78,7 @@ async function runMigrations() {
|
||||
name text NOT NULL,
|
||||
generic_name text,
|
||||
taken_by text,
|
||||
taken_by_json text NOT NULL DEFAULT '[]',
|
||||
count integer NOT NULL DEFAULT 0,
|
||||
strips integer NOT NULL DEFAULT 0,
|
||||
pack_count integer NOT NULL DEFAULT 1,
|
||||
@@ -114,6 +115,7 @@ async function runMigrations() {
|
||||
high_stock_days integer NOT NULL DEFAULT 180,
|
||||
expiry_warning_days integer NOT NULL DEFAULT 90,
|
||||
language text NOT NULL DEFAULT 'en',
|
||||
stock_calculation_mode text NOT NULL DEFAULT 'automatic',
|
||||
last_auto_email_sent text,
|
||||
last_notification_type text,
|
||||
last_notification_channel text,
|
||||
@@ -137,6 +139,7 @@ async function runMigrations() {
|
||||
taken_by text NOT NULL,
|
||||
schedule_days integer NOT NULL DEFAULT 30,
|
||||
created_at integer NOT NULL DEFAULT (strftime('%s','now')),
|
||||
expires_at integer,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||
)`,
|
||||
`CREATE TABLE IF NOT EXISTS dose_tracking (
|
||||
@@ -167,10 +170,13 @@ async function runMigrations() {
|
||||
{ name: "intake_reminders_enabled", sql: "ALTER TABLE medications ADD COLUMN intake_reminders_enabled INTEGER NOT NULL DEFAULT 0" },
|
||||
{ name: "pill_weight_mg", sql: "ALTER TABLE medications ADD COLUMN pill_weight_mg REAL" },
|
||||
{ name: "taken_by", sql: "ALTER TABLE medications ADD COLUMN taken_by TEXT" },
|
||||
{ name: "taken_by_json", sql: "ALTER TABLE medications ADD COLUMN taken_by_json TEXT NOT NULL DEFAULT '[]'" },
|
||||
{ name: "users_email", sql: "ALTER TABLE users ADD COLUMN email TEXT" },
|
||||
{ name: "users_avatar_url", sql: "ALTER TABLE users ADD COLUMN avatar_url TEXT" },
|
||||
{ name: "users_oidc_subject", sql: "ALTER TABLE users ADD COLUMN oidc_subject TEXT" },
|
||||
{ name: "user_settings_expiry_warning_days", sql: "ALTER TABLE user_settings ADD COLUMN expiry_warning_days INTEGER NOT NULL DEFAULT 90" },
|
||||
{ name: "user_settings_stock_calculation_mode", sql: "ALTER TABLE user_settings ADD COLUMN stock_calculation_mode TEXT NOT NULL DEFAULT 'automatic'" },
|
||||
{ name: "share_tokens_expires_at", sql: "ALTER TABLE share_tokens ADD COLUMN expires_at INTEGER" },
|
||||
];
|
||||
|
||||
for (const migration of migrations) {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { createClient } from "@libsql/client";
|
||||
import dotenv from "dotenv";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
|
||||
dotenv.config({ path: process.env.DOTENV_PATH || ".env" });
|
||||
|
||||
@@ -117,6 +119,52 @@ async function main() {
|
||||
await client.execute(stmt);
|
||||
}
|
||||
|
||||
console.log("Base tables created. Running migrations for existing databases...");
|
||||
|
||||
// Run incremental migrations for existing databases
|
||||
// These ALTER TABLE statements are safe to run multiple times (they'll fail silently if column exists)
|
||||
const migrations = [
|
||||
// 0003: Add image_url to medications
|
||||
{ name: "0003_add_image_url", sql: "ALTER TABLE medications ADD COLUMN image_url text" },
|
||||
// 0004: Add expiry_date to medications
|
||||
{ name: "0004_add_expiry_date", sql: "ALTER TABLE medications ADD COLUMN expiry_date text" },
|
||||
// 0005: Add notes to medications
|
||||
{ name: "0005_add_notes", sql: "ALTER TABLE medications ADD COLUMN notes text" },
|
||||
// 0006: Add generic_name to medications
|
||||
{ name: "0006_add_generic_name", sql: "ALTER TABLE medications ADD COLUMN generic_name text" },
|
||||
// 0007: Add intake_reminders_enabled to medications
|
||||
{ name: "0007_add_intake_reminders", sql: "ALTER TABLE medications ADD COLUMN intake_reminders_enabled integer NOT NULL DEFAULT 0" },
|
||||
// 0008: Add pill_weight_mg to medications
|
||||
{ name: "0008_add_pill_weight", sql: "ALTER TABLE medications ADD COLUMN pill_weight_mg integer" },
|
||||
// 0009: Add taken_by to medications
|
||||
{ name: "0009_add_taken_by", sql: "ALTER TABLE medications ADD COLUMN taken_by text" },
|
||||
// 0012: Add avatar_url to users
|
||||
{ name: "0012_add_user_avatar", sql: "ALTER TABLE users ADD COLUMN avatar_url text" },
|
||||
// 0013: Add oidc_subject to users
|
||||
{ name: "0013_add_oidc_subject", sql: "ALTER TABLE users ADD COLUMN oidc_subject text" },
|
||||
// 0014: Add stock_calculation_mode to user_settings
|
||||
{ name: "0014_add_stock_calculation_mode", sql: "ALTER TABLE user_settings ADD COLUMN stock_calculation_mode text NOT NULL DEFAULT 'automatic'" },
|
||||
// 0015: Add expires_at to share_tokens
|
||||
{ name: "0015_add_share_token_expiry", sql: "ALTER TABLE share_tokens ADD COLUMN expires_at integer" },
|
||||
// 0016: Add taken_by_json to medications
|
||||
{ name: "0016_taken_by_json_array", sql: "ALTER TABLE medications ADD COLUMN taken_by_json text NOT NULL DEFAULT '[]'" },
|
||||
];
|
||||
|
||||
for (const migration of migrations) {
|
||||
try {
|
||||
await client.execute(migration.sql);
|
||||
console.log(`Migration ${migration.name}: applied`);
|
||||
} catch (err: unknown) {
|
||||
// Ignore "duplicate column" errors - means migration was already applied
|
||||
const errorMessage = err instanceof Error ? err.message : String(err);
|
||||
if (errorMessage.includes("duplicate column") || errorMessage.includes("already exists")) {
|
||||
console.log(`Migration ${migration.name}: already applied (skipped)`);
|
||||
} else {
|
||||
console.error(`Migration ${migration.name}: failed - ${errorMessage}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log("Database setup complete!");
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user