1
11import { resolveRecordId, writeRecordPropertyById } from "./record-write.js";
12import { FatalError } from "./classify.js";
13import type { ActionExecutor, ActionResult } from "./types.js";
14
15const executor: ActionExecutor = {
16 type: "CHANGE_STATUS",
17 async execute(cfg, ctx, deps): Promise<ActionResult> {
18 const recordId = resolveRecordId(cfg, ctx);
19 const propertyId = cfg.propertyId as string;
20 const value = cfg.value as string;
21
22
23
24 const prop = await deps.prisma.databaseProperty.findFirst({
25 where: { id: propertyId, deletedAt: null },
26 select: { id: true, name: true, type: true, config: true }
27 });
28 if (!prop) throw new FatalError("PROPERTY_UNKNOWN", `property ${propertyId} not found`);
29 if (prop.type !== "STATUS" && prop.type !== "SELECT") {
30 throw new FatalError("PROPERTY_TYPE_MISMATCH", `property ${propertyId} is ${prop.type}, not STATUS/SELECT`);
31 }
32 const options: { name?: string; id?: string }[] = Array.isArray((prop.config as Record<string, unknown>)?.options)
33 ? ((prop.config as Record<string, unknown>).options as { name?: string; id?: string }[])
34 : [];
35 const known = options.some((o) => o.name === value || o.id === value);
36 if (options.length > 0 && !known) {
37 throw new FatalError("PROPERTY_OPTION_UNKNOWN", `option "${value}" not found on property ${propertyId}`);
38 }
39
40 const result = await writeRecordPropertyById(deps, ctx, recordId, propertyId, value);
41 return {
42 output: { recordId: result.recordId, propertyId, value, eventEmitted: result.eventEmitted },
43 emittedEvents: result.eventEmitted ? ["record.updated"] : [],
44 audit: { action: "automation.status_changed", resourceType: "record", resourceId: result.recordId, metadata: { propertyId, value } }
45 };
46 }
47};
48
49export default executor;
50