feat(workflows): per-quote booking-workflow picker + quote→invoice (no gallery) built-in
A quote can now choose which flow runs on acceptance instead of every enabled quote.accepted flow firing. Migration 147 adds quotes.booking_workflow_id; the editor shows a "Booking workflow (on acceptance)" dropdown listing the quote.accepted flows (workflow-engine flag only); emitQuoteEvent passes it as the new emitWorkflowEvent targetWorkflowId so ONLY the picked flow runs (still gated on enabled + trigger match → a disabled/None selection runs nothing). Adds the booking_invoice_only built-in (quote.accepted → prepare invoice → review gate → send; no event/gallery, no wait), the variant requested for shoots billed without an online gallery. Disabled stub like the other booking flows until the prepare_*/send_document cutover. Tests: targetWorkflowId runs only the selected flow; invoice-only built-in has no wait/prepare_event.
This commit is contained in:
@@ -240,7 +240,7 @@ async function resumeRun(runId, { decisionHandle = null } = {}) {
|
||||
* workflow (idempotent via dedup_key) and starts it. Never throws — safe to
|
||||
* call after a caller's commit. Fails CLOSED if the flag system is unavailable.
|
||||
*/
|
||||
async function emitWorkflowEvent(triggerType, { entityType = null, entityId = null, payload = {} } = {}) {
|
||||
async function emitWorkflowEvent(triggerType, { entityType = null, entityId = null, payload = {}, targetWorkflowId = null } = {}) {
|
||||
try {
|
||||
const { isFeatureEnabled } = require('../../middleware/requireFeatureFlag');
|
||||
let enabled = false;
|
||||
@@ -250,7 +250,13 @@ async function emitWorkflowEvent(triggerType, { entityType = null, entityId = nu
|
||||
}
|
||||
if (!enabled) return [];
|
||||
|
||||
const workflows = await db('workflows').where({ enabled: true, trigger_type: triggerType });
|
||||
// targetWorkflowId restricts the fan-out to a SINGLE chosen flow — used when
|
||||
// the entity explicitly selected which flow to run (e.g. a quote picks its
|
||||
// booking workflow). Still gated on enabled + matching trigger_type, so a
|
||||
// disabled/mismatched selection simply runs nothing.
|
||||
const q = db('workflows').where({ enabled: true, trigger_type: triggerType });
|
||||
if (targetWorkflowId != null) q.where({ id: targetWorkflowId });
|
||||
const workflows = await q;
|
||||
const runIds = [];
|
||||
for (const wf of workflows) {
|
||||
const tcfg = parseJson(wf.trigger_config, {});
|
||||
|
||||
Reference in New Issue
Block a user