import { ok, type ReadonlyDB, type PaginationInput, buildPaginatedResult, DEFAULT_PAGE_SIZE, } from "@tailor-platform/erp-kit/core"; import type { DB } from "../generated/kysely-tailordb"; export interface ListPositionsByDepartmentInput extends PaginationInput { departmentId: string; } /** * Function: listPositionsByDepartment * Returns the paginated list of Positions belonging to a given organization * Department, including both filled and vacant/TBH Positions. Only current * (today-effective) Position generations are returned. */ export async function run(db: ReadonlyDB, input: ListPositionsByDepartmentInput) { const limit = input.limit ?? DEFAULT_PAGE_SIZE; const offset = input.offset ?? 0; const orderBy = input.orderBy ?? "id"; const orderDirection = input.orderDirection ?? "asc"; const now = new Date(); const positions = await db .selectFrom("Position") .selectAll() .where("departmentId", "=", input.departmentId) // Today-effective = the generation whose window contains now. A scheduled future change closes // the current generation (effectiveEnd set) and opens a future one (effectiveStart > now), so an // "effectiveEnd IS NULL" test would surface the future generation and drop today's (M02). .where("effectiveStart", "<=", now) .where((eb) => eb.or([eb("effectiveEnd", "is", null), eb("effectiveEnd", ">=", now)])) .orderBy(orderBy, orderDirection) .limit(limit + 1) .offset(offset) .execute(); return ok(buildPaginatedResult(positions, limit)); }