import { type CommonReservedFields, type NoReservedFields, defaultGqlPermission, defaultPermission, } from "@tailor-platform/erp-kit/core"; import { db, type TailorAnyDBField } from "@tailor-platform/sdk"; import { shiftScheduleLifecycle } from "./shiftSchedule.lifecycle.generated"; // Lifecycle: DRAFT -> CONFIRMED. Confirming commits the whole period's shifts to workers in one // act, which is the unit planners actually work in ("publish next month's shiftSchedule"). CONFIRMED is // terminal: a confirmed period is corrected by cancelling/adding individual slots, not by // un-confirming the table underneath the people already looking at it. // // The states come from the generated lifecycle, whose source is the State Transitions table in // docs/model/ShiftSchedule.md — so the column and the commands cannot disagree on the state set. const builtins = () => { return { // The period is the shiftSchedule's identity — it is exactly the from/to a planner enters when // generating shifts, so a generation run produces one ShiftSchedule plus its Shifts. startDate: db.date().description("First business date covered by this shiftSchedule period"), endDate: db .date() .description( "Last business date covered by this shiftSchedule period; on or after startDate", ), // Lifecycle status. Shift carries no status of its own; a shift's committed-ness is its // shiftSchedule's status (the "publish" axis), while staffing is ShiftPlacement (the "who" axis). status: db .enum(shiftScheduleLifecycle.states) .description("Lifecycle status: DRAFT (freely editable) / CONFIRMED (committed to workers)"), // Audit trail: when the period was committed confirmedAt: db .datetime({ optional: true }) .description("Timestamp this shiftSchedule was confirmed; null while DRAFT"), }; }; type ReservedFields = keyof ReturnType | CommonReservedFields; export interface CreateShiftScheduleTypeParams> { fields?: NoReservedFields; } export function createShiftScheduleType< const F extends Record = Record, >(params: CreateShiftScheduleTypeParams) { return db .table("ShiftSchedule", { ...builtins(), // Custom fields spread + timestamps ...((params.fields ?? {}) as F), ...db.fields.timestamps(), }) .permission(defaultPermission) .gqlPermission(defaultGqlPermission); } // Codegen instance with no cross-module types export const shiftSchedule = createShiftScheduleType({});