import { type EmptyFields } from "@tailor-platform/erp-kit/core"; import { type TailorAnyDBField } from "@tailor-platform/sdk"; import type { TailorDBInsertable } from "@tailor-platform/sdk/kysely"; import type { UserManagementModule } from "../user-management"; import { attachLabelToPipelineItem } from "./command/attachLabelToPipelineItem.generated"; import { closePipelineItem } from "./command/closePipelineItem.generated"; import { createPipeline } from "./command/createPipeline.generated"; import { createPipelineItem } from "./command/createPipelineItem.generated"; import { createPipelineItemComment } from "./command/createPipelineItemComment.generated"; import { createPipelineLabel } from "./command/createPipelineLabel.generated"; import { createPipelineStage } from "./command/createPipelineStage.generated"; import { deactivatePipeline } from "./command/deactivatePipeline.generated"; import { deletePipelineItem } from "./command/deletePipelineItem.generated"; import { deletePipelineItemComment } from "./command/deletePipelineItemComment.generated"; import { deletePipelineLabel } from "./command/deletePipelineLabel.generated"; import { deletePipelineStage } from "./command/deletePipelineStage.generated"; import { detachLabelFromPipelineItem } from "./command/detachLabelFromPipelineItem.generated"; import { movePipelineItem } from "./command/movePipelineItem.generated"; import { openPipelineItem } from "./command/openPipelineItem.generated"; import { reopenPipelineItem } from "./command/reopenPipelineItem.generated"; import { reorderPipelineItem } from "./command/reorderPipelineItem.generated"; import { reorderPipelineStage } from "./command/reorderPipelineStage.generated"; import { updatePipeline } from "./command/updatePipeline.generated"; import { updatePipelineItem } from "./command/updatePipelineItem.generated"; import { updatePipelineItemComment } from "./command/updatePipelineItemComment.generated"; import { updatePipelineLabel } from "./command/updatePipelineLabel.generated"; import { updatePipelineStage } from "./command/updatePipelineStage.generated"; import { createPipelineType, type CreatePipelineTypeParams } from "./db/pipeline"; import { createPipelineItemType, type CreatePipelineItemTypeParams } from "./db/pipelineItem"; import { createPipelineItemChangeType, type CreatePipelineItemChangeTypeParams, } from "./db/pipelineItemChange"; import { createPipelineItemCommentType, type CreatePipelineItemCommentTypeParams, } from "./db/pipelineItemComment"; import { createPipelineItemLabelType, type CreatePipelineItemLabelTypeParams, } from "./db/pipelineItemLabel"; import { createPipelineLabelType, type CreatePipelineLabelTypeParams } from "./db/pipelineLabel"; import { createPipelineStageType, type CreatePipelineStageTypeParams } from "./db/pipelineStage"; import { createPipelineStageTransitionType, type CreatePipelineStageTransitionTypeParams, } from "./db/pipelineStageTransition"; import { listPipelineItemCommentsByItem } from "./query/listPipelineItemCommentsByItem.generated"; import { listPipelineItemsByStage } from "./query/listPipelineItemsByStage.generated"; import { listPipelineLabelsByItem } from "./query/listPipelineLabelsByItem.generated"; import { listPipelineLabelsByPipeline } from "./query/listPipelineLabelsByPipeline.generated"; import { listPipelineStagesByPipeline } from "./query/listPipelineStagesByPipeline.generated"; import { listPipelineStageTransitionsByItem } from "./query/listPipelineStageTransitionsByItem.generated"; type UserManagementDB = UserManagementModule["db"]; export interface DefineModuleParams< PipelineF extends Record, PipelineStageF extends Record, PipelineItemF extends Record, PipelineItemChangeF extends Record, PipelineItemCommentF extends Record, PipelineStageTransitionF extends Record, PipelineLabelF extends Record, PipelineItemLabelF extends Record, > { /** * Allowed `pipelineType` vocabulary, declared by the consuming app * (e.g. ["TASK_BOARD", "SUPPORT_QUEUE"]). The module itself is * type-agnostic; when omitted, createPipeline accepts any non-empty string. */ pipelineTypes?: readonly string[]; // userType is Omit-ed: defineModule injects the real User type, so a consumer value would be discarded. pipeline?: Omit, "userType">; pipelineStage?: CreatePipelineStageTypeParams; pipelineItem?: Omit, "userType">; pipelineItemChange?: Omit, "userType">; pipelineItemComment?: Omit, "userType">; pipelineStageTransition?: Omit< CreatePipelineStageTransitionTypeParams, "userType" >; pipelineLabel?: CreatePipelineLabelTypeParams; pipelineItemLabel?: CreatePipelineItemLabelTypeParams; userManagement: { db: { user: UserManagementDB["user"]; }; /** * Optional user-existence check used by createPipeline (createdByUserId) and * createPipelineItem / updatePipelineItem (assigneeId). When provided, * referencing an unknown user fails with USER_NOT_FOUND. */ getUser?: (id: string) => Promise<{ id: string } | null>; }; } /* @__NO_SIDE_EFFECTS__ */ export const defineModule = < const PipelineF extends Record = EmptyFields, const PipelineStageF extends Record = EmptyFields, const PipelineItemF extends Record = EmptyFields, const PipelineItemChangeF extends Record = EmptyFields, const PipelineItemCommentF extends Record = EmptyFields, const PipelineStageTransitionF extends Record = EmptyFields, const PipelineLabelF extends Record = EmptyFields, const PipelineItemLabelF extends Record = EmptyFields, >( params: DefineModuleParams< PipelineF, PipelineStageF, PipelineItemF, PipelineItemChangeF, PipelineItemCommentF, PipelineStageTransitionF, PipelineLabelF, PipelineItemLabelF >, ) => { const userType = params.userManagement.db.user; const pipeline = createPipelineType({ ...params.pipeline, userType }); const pipelineStage = createPipelineStageType(params.pipelineStage ?? {}); const pipelineItem = createPipelineItemType({ ...params.pipelineItem, userType }); const pipelineLabel = createPipelineLabelType(params.pipelineLabel ?? {}); const pipelineItemChange = createPipelineItemChangeType({ ...params.pipelineItemChange, userType, }); const pipelineItemComment = createPipelineItemCommentType({ ...params.pipelineItemComment, userType, }); const pipelineStageTransition = createPipelineStageTransitionType({ ...params.pipelineStageTransition, userType, }); const pipelineItemLabel = createPipelineItemLabelType(params.pipelineItemLabel ?? {}); return { db: { pipeline, pipelineStage, pipelineItem, pipelineItemChange, pipelineItemComment, pipelineStageTransition, pipelineLabel, pipelineItemLabel, }, commands: { createPipeline: createPipeline>({ allowedPipelineTypes: params.pipelineTypes, getUser: params.userManagement.getUser, }), updatePipeline: updatePipeline>(), deactivatePipeline: deactivatePipeline(), createPipelineStage: createPipelineStage>(), updatePipelineStage: updatePipelineStage>(), deletePipelineStage: deletePipelineStage(), reorderPipelineStage: reorderPipelineStage(), createPipelineItem: createPipelineItem>({ getUser: params.userManagement.getUser, }), updatePipelineItem: updatePipelineItem>({ getUser: params.userManagement.getUser, }), movePipelineItem: movePipelineItem(), reorderPipelineItem: reorderPipelineItem(), deletePipelineItem: deletePipelineItem(), closePipelineItem: closePipelineItem(), openPipelineItem: openPipelineItem(), reopenPipelineItem: reopenPipelineItem(), createPipelineItemComment: createPipelineItemComment>(), updatePipelineItemComment: updatePipelineItemComment>(), deletePipelineItemComment: deletePipelineItemComment(), createPipelineLabel: createPipelineLabel>(), updatePipelineLabel: updatePipelineLabel>(), deletePipelineLabel: deletePipelineLabel(), attachLabelToPipelineItem: attachLabelToPipelineItem>(), detachLabelFromPipelineItem: detachLabelFromPipelineItem(), }, queries: { listPipelineStagesByPipeline, listPipelineItemsByStage, listPipelineStageTransitionsByItem, listPipelineItemCommentsByItem, listPipelineLabelsByPipeline, listPipelineLabelsByItem, }, }; }; /** EmptyFields-instantiated alias — use instead of `ReturnType`, which widens field generics to their constraint. */ export type PipelineManagementModule = ReturnType< typeof defineModule< EmptyFields, EmptyFields, EmptyFields, EmptyFields, EmptyFields, EmptyFields, EmptyFields, EmptyFields > >;