feat(db): v4 migration + shared types for specialist auto-assignment
Adds auto_assign_specialist + working_hours to businesses, and specialties + working_hours + efficiency_score to employees, with idempotent migrateV3ToV4 (backfills default Lun-Vie 09:00-20:00 working hours). Updates Business/Employee types and adds WorkingHoursMap.
This commit is contained in:
@@ -222,11 +222,46 @@ function migrateV1ToV2() {
|
|||||||
setMeta("schema_version", "2");
|
setMeta("schema_version", "2");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** v4: auto-assign specialist, business & employee working hours, employee specialties/efficiency. */
|
||||||
|
function migrateV3ToV4() {
|
||||||
|
if (getMeta("schema_version") >= "4") return;
|
||||||
|
|
||||||
|
const bizCols: [string, string][] = [
|
||||||
|
["auto_assign_specialist", "INTEGER NOT NULL DEFAULT 0"],
|
||||||
|
["working_hours", "TEXT"],
|
||||||
|
];
|
||||||
|
for (const [col, def] of bizCols) {
|
||||||
|
if (!columnExists("businesses", col)) db.exec(`ALTER TABLE businesses ADD COLUMN ${col} ${def};`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const empCols: [string, string][] = [
|
||||||
|
["specialties", "TEXT"],
|
||||||
|
["working_hours", "TEXT"],
|
||||||
|
["efficiency_score", "REAL NOT NULL DEFAULT 50"],
|
||||||
|
];
|
||||||
|
for (const [col, def] of empCols) {
|
||||||
|
if (!columnExists("employees", col)) db.exec(`ALTER TABLE employees ADD COLUMN ${col} ${def};`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Backfill business working_hours: Lun-Vie 09:00-20:00 (replica del hardcodeado anterior)
|
||||||
|
const DEFAULT_WH = 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,
|
||||||
|
});
|
||||||
|
const noWh = db.prepare(`SELECT id FROM businesses WHERE working_hours IS NULL`).all() as { id: number }[];
|
||||||
|
const upd = db.prepare(`UPDATE businesses SET working_hours = ? WHERE id = ?`);
|
||||||
|
for (const b of noWh) upd.run(DEFAULT_WH, b.id);
|
||||||
|
|
||||||
|
setMeta("schema_version", "4");
|
||||||
|
}
|
||||||
|
|
||||||
export function runMigrations() {
|
export function runMigrations() {
|
||||||
// Ensure base schema exists (no-op on existing tables)
|
// Ensure base schema exists (no-op on existing tables)
|
||||||
db.exec(SCHEMA);
|
db.exec(SCHEMA);
|
||||||
migrateV1ToV2();
|
migrateV1ToV2();
|
||||||
migrateV2ToV3();
|
migrateV2ToV3();
|
||||||
|
migrateV3ToV4();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** v3: cancellation policy, commissions, cash register, notifications/reminders, booking slug. */
|
/** v3: cancellation policy, commissions, cash register, notifications/reminders, booking slug. */
|
||||||
|
|||||||
@@ -14,9 +14,20 @@ export interface Business {
|
|||||||
status?: string;
|
status?: string;
|
||||||
template?: string | null;
|
template?: string | null;
|
||||||
trial_ends_at?: string | null;
|
trial_ends_at?: string | null;
|
||||||
|
booking_enabled?: number | boolean;
|
||||||
|
cancel_window_hours?: number;
|
||||||
|
cancel_penalty_pct?: number;
|
||||||
|
require_deposit?: number | boolean;
|
||||||
|
deposit_pct?: number;
|
||||||
|
timezone?: string;
|
||||||
|
auto_assign_specialist?: number | boolean;
|
||||||
|
working_hours?: WorkingHoursMap | string | null;
|
||||||
created_at?: string;
|
created_at?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type WorkingDay = { start: string; end: string };
|
||||||
|
export type WorkingHoursMap = Record<number, WorkingDay | null>; // 1=Lun … 7=Dom
|
||||||
|
|
||||||
export interface User {
|
export interface User {
|
||||||
id: number;
|
id: number;
|
||||||
business_id: number | null;
|
business_id: number | null;
|
||||||
@@ -39,6 +50,9 @@ export interface Employee {
|
|||||||
rating: number;
|
rating: number;
|
||||||
hire_date: string | null;
|
hire_date: string | null;
|
||||||
service_ids?: number[];
|
service_ids?: number[];
|
||||||
|
specialties?: string[];
|
||||||
|
working_hours?: WorkingHoursMap | string | null;
|
||||||
|
efficiency_score?: number;
|
||||||
stats?: EmployeeStats;
|
stats?: EmployeeStats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user