From c643bfcc471548d53a7c6d4f3ed2f17d6ec14bcf Mon Sep 17 00:00:00 2001 From: Daniel Volz Date: Sat, 20 Dec 2025 17:57:11 +0100 Subject: [PATCH] feat: implement database setup with direct table creation and improved error handling --- backend/Dockerfile | 4 +- backend/src/db/migrate.ts | 85 ++++++++++++++++++++++++++++++++++----- 2 files changed, 75 insertions(+), 14 deletions(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index a0df0f0..ae14362 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -13,9 +13,7 @@ WORKDIR /app ENV NODE_ENV=production COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/dist ./dist -# Copy migration SQL files (needed for runtime migrations) -COPY --from=builder /app/src/db/migrations ./dist/db/migrations COPY package.json . EXPOSE 3000 -# Run migrations before starting the server +# Run database setup before starting the server CMD ["sh", "-c", "mkdir -p /app/data && node dist/db/migrate.js && node dist/index.js"] diff --git a/backend/src/db/migrate.ts b/backend/src/db/migrate.ts index 5fb0914..4645fb1 100644 --- a/backend/src/db/migrate.ts +++ b/backend/src/db/migrate.ts @@ -1,20 +1,83 @@ -import { migrate } from "drizzle-orm/libsql/migrator"; -import { db } from "./client.js"; -import { env } from "../plugins/env.js"; -import { join } from "node:path"; -import { fileURLToPath } from "node:url"; +import { createClient } from "@libsql/client"; +import dotenv from "dotenv"; -const __filename = fileURLToPath(import.meta.url); -const __dirname = join(__filename, ".."); +dotenv.config({ path: process.env.DOTENV_PATH || ".env" }); + +const url = process.env.DATABASE_URL || "file:./data/medassist.db"; async function main() { - const migrationsFolder = join(__dirname, "migrations"); - await migrate(db, { migrationsFolder }); - console.log("Migrations applied"); + console.log("Starting database setup..."); + console.log("Database URL:", url); + + const client = createClient({ url }); + + // Create tables directly + const sql = ` + CREATE TABLE IF NOT EXISTS users ( + id integer PRIMARY KEY AUTOINCREMENT, + email text NOT NULL UNIQUE, + password_hash text NOT NULL, + role text NOT NULL DEFAULT 'user', + created_at integer NOT NULL DEFAULT (strftime('%s','now')), + updated_at integer NOT NULL DEFAULT (strftime('%s','now')) + ); + + CREATE TABLE IF NOT EXISTS medications ( + id integer PRIMARY KEY AUTOINCREMENT, + name text NOT NULL UNIQUE, + count integer NOT NULL DEFAULT 0, + strips integer NOT NULL DEFAULT 0, + pack_count integer NOT NULL DEFAULT 1, + strips_per_pack integer NOT NULL DEFAULT 1, + tabs_per_strip integer NOT NULL DEFAULT 1, + loose_tablets integer NOT NULL DEFAULT 0, + usage_json text NOT NULL DEFAULT '[]', + every_json text NOT NULL DEFAULT '[]', + start_json text NOT NULL DEFAULT '[]', + strip_size integer NOT NULL DEFAULT 1, + updated_at integer NOT NULL DEFAULT (strftime('%s','now')) + ); + + CREATE TABLE IF NOT EXISTS refresh_tokens ( + id integer PRIMARY KEY AUTOINCREMENT, + user_id integer NOT NULL, + token_id text NOT NULL UNIQUE, + expires_at integer NOT NULL, + rotated_at integer, + revoked integer NOT NULL DEFAULT 0, + created_at integer NOT NULL DEFAULT (strftime('%s','now')), + FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE + ); + + CREATE TABLE IF NOT EXISTS settings ( + id integer PRIMARY KEY AUTOINCREMENT, + smtp_host text, + smtp_port integer, + smtp_user text, + smtp_pass_encrypted text, + smtp_from text, + smtp_secure integer NOT NULL DEFAULT 0, + emails_per_day integer NOT NULL DEFAULT 3, + email_enabled integer NOT NULL DEFAULT 0, + notification_email text, + reminder_days_before integer NOT NULL DEFAULT 7, + updated_at integer NOT NULL DEFAULT (strftime('%s','now')) + ); + `; + + // Execute each statement separately + const statements = sql.split(';').filter(s => s.trim().length > 0); + + for (const stmt of statements) { + console.log("Executing:", stmt.trim().substring(0, 50) + "..."); + await client.execute(stmt); + } + + console.log("Database setup complete!"); process.exit(0); } main().catch((err) => { - console.error(err); + console.error("Migration failed:", err); process.exit(1); });