// server/lib/businessDefaults.ts // // Valores por defecto de un negocio recién creado. Existen porque el backfill de // `slug` y `working_hours` vivía SOLO dentro de las migraciones (migrateV2ToV3 y // migrateV3ToV4), y las migraciones corren al importar db.ts, es decir **antes** de // que `ensureSeed()` inserte ningún negocio. Resultado en una instalación nueva: // // • `working_hours = NULL` → `getWorkingHoursForDate` devuelve null para todos los // días → el endpoint de slots responde `[]` en cualquier fecha y no se puede // reservar nada. // • `slug = NULL` → `publicBusiness()` nunca encuentra el negocio → /b/:slug da 404. // // Un backfill de migración no puede cubrir filas que aún no existen: el default tiene // que aplicarse en el INSERT. Este módulo es la única definición, compartida por el // seed, el alta desde /api/admin y las propias migraciones. import type { DatabaseSync } from "node:sqlite"; /** Lun-Vie 09:00-20:00, fin de semana cerrado. */ export const DEFAULT_WORKING_HOURS = JSON.stringify({ 1: { start: "09:00", end: "20:00" }, 2: { start: "09:00", end: "20:00" }, 3: { start: "09:00", end: "20:00" }, 4: { start: "09:00", end: "20:00" }, 5: { start: "09:00", end: "20:00" }, 6: null, 7: null, }); /** "Lumière Estética & Spa" → "lumiere-estetica-spa". Puro. */ export function slugify(s: string): string { return (s || "negocio") .toLowerCase() .normalize("NFD") .replace(/[\u0300-\u036f]/g, "") .replace(/[^a-z0-9]+/g, "-") .replace(/^-+|-+$/g, "") .slice(0, 60) || "negocio"; } /** Slug único para `name`, añadiendo sufijo numérico si ya está tomado. */ export function uniqueSlug(db: DatabaseSync, name: string, excludeId: number | null = null): string { const base = slugify(name); let slug = base; let n = 2; const taken = db.prepare(`SELECT id FROM businesses WHERE slug = ? AND id IS NOT ?`); while (taken.get(slug, excludeId)) slug = `${base}-${n++}`; return slug; }