- Stack: Bun, Hono, Drizzle ORM, Zod, Handlebars, Pino - Models: ticket, queue, transaction, scrip, template, custom_field, user, lifecycle - Scrip engine: prepare/commit two-phase dispatch, template rendering, mock actions - Lifecycle validator: state machine transition validation with wildcard support - Routes: health, tickets (full CRUD + preview + transactions), queues, scrips, custom-fields, lifecycles - Middleware: Pino logging, error handler - Database: Drizzle ORM schema + initial migration (10 tables) - Type-check: passes (tsc --noEmit, zero errors)
63 lines
2.2 KiB
TypeScript
63 lines
2.2 KiB
TypeScript
export interface ActionExecutor {
|
|
execute(payload: ActionPayload): { success: boolean; message: string };
|
|
}
|
|
|
|
export interface ActionPayload {
|
|
scripId: string;
|
|
scripName: string;
|
|
actionType: string;
|
|
actionConfig: Record<string, unknown>;
|
|
recipients?: string[];
|
|
subject?: string;
|
|
body?: string;
|
|
url?: string;
|
|
method?: string;
|
|
headers?: Record<string, string>;
|
|
field_id?: string;
|
|
value?: string;
|
|
}
|
|
|
|
export class SendEmail implements ActionExecutor {
|
|
execute(payload: ActionPayload): { success: boolean; message: string } {
|
|
console.log('[SendEmail] Would send email:', {
|
|
subject: payload.subject ?? payload.actionConfig['subject'],
|
|
body: payload.body ?? payload.actionConfig['body'],
|
|
recipients: payload.recipients ?? payload.actionConfig['recipients'],
|
|
});
|
|
return { success: true, message: `Email queued: "${payload.subject ?? 'No subject'}"` };
|
|
}
|
|
}
|
|
|
|
export class Webhook implements ActionExecutor {
|
|
execute(payload: ActionPayload): { success: boolean; message: string } {
|
|
console.log('[Webhook] Would fire webhook:', {
|
|
url: payload.url ?? payload.actionConfig['url'],
|
|
method: payload.method ?? payload.actionConfig['method'] ?? 'POST',
|
|
headers: payload.headers ?? payload.actionConfig['headers'],
|
|
body: payload.body ?? payload.actionConfig['body'],
|
|
});
|
|
return { success: true, message: `Webhook fired: ${payload.url ?? 'unknown URL'}` };
|
|
}
|
|
}
|
|
|
|
export class SetCustomField implements ActionExecutor {
|
|
execute(payload: ActionPayload): { success: boolean; message: string } {
|
|
const fieldId = payload.field_id ?? String(payload.actionConfig['field_id'] ?? '');
|
|
const value = payload.value ?? String(payload.actionConfig['value'] ?? '');
|
|
console.log('[SetCustomField] Would set:', { field_id: fieldId, value });
|
|
return { success: true, message: `Custom field ${fieldId} set to "${value}"` };
|
|
}
|
|
}
|
|
|
|
const actionRegistry: Record<string, ActionExecutor> = {
|
|
SendEmail: new SendEmail(),
|
|
Webhook: new Webhook(),
|
|
SetCustomField: new SetCustomField(),
|
|
};
|
|
|
|
export function getActionExecutor(type: string): ActionExecutor | null {
|
|
return actionRegistry[type] ?? null;
|
|
}
|
|
|
|
export { actionRegistry };
|