From cd6d9c02af7a83d8bf8ec7bfb0fc33ddddcb68ac Mon Sep 17 00:00:00 2001 From: borja Date: Wed, 15 Oct 2025 10:55:46 +0200 Subject: [PATCH] fix: inicializar esquema en desarrollo si no existe la tabla tasks Co-authored-by: aider (openrouter/openai/gpt-5) --- apps/web/src/lib/server/db.ts | 105 +++++++++++++++++++++------------- 1 file changed, 66 insertions(+), 39 deletions(-) diff --git a/apps/web/src/lib/server/db.ts b/apps/web/src/lib/server/db.ts index 4196721..819f5eb 100644 --- a/apps/web/src/lib/server/db.ts +++ b/apps/web/src/lib/server/db.ts @@ -60,54 +60,81 @@ async function openDb(filename: string = 'tasks.db'): Promise { const instance = new DatabaseCtor(absolutePath); applyDefaultPragmas(instance); - // Auto-inicialización y seed sólo en desarrollo y primer arranque - if (firstCreate && isDev() && DEV_AUTOSEED_DB) { - // Detectar entorno Bun vs Node (Vite dev) - const isBun = typeof (globalThis as any).Bun !== 'undefined'; + // Auto-inicialización de esquema en desarrollo si falta y seed opcional + if (isDev()) { + // ¿Existe la tabla principal? + let hasTasksTable = false; + try { + instance.prepare(`SELECT 1 FROM tasks LIMIT 1`).get(); + hasTasksTable = true; + } catch {} - if (isBun) { - // En Bun podemos reutilizar initializeDatabase del repo principal - try { - const dbModule = await import('../../../../../src/db'); - if (typeof (dbModule as any).initializeDatabase === 'function') { - (dbModule as any).initializeDatabase(instance); + // Si no existe el esquema, aplicar inicialización/migraciones + if (!hasTasksTable) { + const isBun = typeof (globalThis as any).Bun !== 'undefined'; + + if (isBun) { + // En Bun podemos reutilizar initializeDatabase del repo principal + try { + const dbModule = await import('../../../../../src/db'); + if (typeof (dbModule as any).initializeDatabase === 'function') { + (dbModule as any).initializeDatabase(instance); + hasTasksTable = true; + } + } catch (e) { + console.warn('[web/db] No se pudo ejecutar initializeDatabase en dev (Bun):', e); + } + } else { + // En SSR Node: aplicar migraciones directamente con compat para .query + try { + const mod = await import('../../../../../src/db/migrations/index.ts'); + const list = (mod as any).migrations as any[]; + const compat: any = instance; + if (typeof compat.query !== 'function') { + compat.query = (sql: string) => ({ + all: () => compat.prepare(sql).all(), + get: () => compat.prepare(sql).get() + }); + } + try { compat.exec?.(`PRAGMA foreign_keys = ON;`); } catch {} + for (const m of list) { + try { + await (m.up as any)(compat); + } catch (e) { + console.warn('[web/db] Error aplicando migración en dev (Node):', (m as any)?.name ?? '(sin nombre)', e); + } + } + // Verificar de nuevo + try { + compat.prepare(`SELECT 1 FROM tasks LIMIT 1`).get(); + hasTasksTable = true; + } catch {} + } catch (e) { + console.warn('[web/db] No se pudieron aplicar migraciones en dev (Node):', e); } - } catch (e) { - console.warn('[web/db] No se pudo ejecutar initializeDatabase en dev (Bun):', e); } - } else { - // En SSR Node: aplicar migraciones directamente con compat para .query + } + + // Seed de datos de demo si está habilitado y la tabla está vacía + if (DEV_AUTOSEED_DB) { try { - const mod = await import('../../../../../src/db/migrations/index.ts'); - const list = (mod as any).migrations as any[]; - const compat: any = instance; - if (typeof compat.query !== 'function') { - compat.query = (sql: string) => ({ - all: () => compat.prepare(sql).all(), - get: () => compat.prepare(sql).get() - }); + let count = 0; + try { + const row = instance.prepare(`SELECT COUNT(1) AS c FROM tasks`).get() as any; + count = Number(row?.c ?? 0); + } catch { + // Si aún no existe la tabla, no seedear + count = 0; } - try { compat.exec?.(`PRAGMA foreign_keys = ON;`); } catch {} - for (const m of list) { - try { - await (m.up as any)(compat); - } catch (e) { - console.warn('[web/db] Error aplicando migración en dev (Node):', (m as any)?.name ?? '(sin nombre)', e); + if (count === 0) { + const seed = await import('./dev-seed'); + if (typeof (seed as any).seedDev === 'function') { + await (seed as any).seedDev(instance, DEV_DEFAULT_USER); } } } catch (e) { - console.warn('[web/db] No se pudieron aplicar migraciones en dev (Node):', e); - } - } - - // Seed de datos de demo - try { - const seed = await import('./dev-seed'); - if (typeof (seed as any).seedDev === 'function') { - await (seed as any).seedDev(instance, DEV_DEFAULT_USER); + console.warn('[web/db] No se pudo realizar el seed de datos de demo:', e); } - } catch (e) { - console.warn('[web/db] No se pudo realizar el seed de datos de demo:', e); } }