@fayz-ai/plugin-automations 0.13.8 β 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +6 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/data/payment-preflight.ts","../src/data/test-send.ts","../src/lib/runtime.ts","../src/data/fayz.ts","../src/views/RunLog.tsx","../src/views/whatsapp-preview-bg.ts","../src/data/provider-templates.ts","../src/views/ProviderTemplateStatus.tsx","../src/views/AutomationDetailPage.tsx","../src/lib/connector-automations.ts","../src/views/ConnectorAutomations.tsx","../src/views/AutomationsList.tsx","../src/data/templates.ts","../src/views/CadenceComposer.tsx","../src/data/flows.ts","../src/views/FlowsPage.tsx","../src/locales/en.ts","../src/locales/pt-BR.ts","../src/locales/index.ts","../src/migrations/index.ts","../src/index.ts"],"names":["React","getSupabaseClientOptional","getActiveTenantId","row","jsxs","jsx","Badge","Button","store","current","Card","Fragment","adminNavigateTo","ChevronRight","CHANNEL_ICON","Mail","WhatsAppIcon","Smartphone","MessageSquare","CHANNEL_LABEL","Zap","usePluginRuntimeOptional","useAgentSurface","toast","Switch","errorMessage","data","error","useTranslation","Clock","useState","useEffect","PageHeaderActions","PageActions","resolveFayzAgentConnection"],"mappings":"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AAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;;AAAA;AAAA;;AAAA;AAAA;;;AAAA;;AAAA;;AAAA;;AAAA;;AAAA;;AAAA;;;AAAA;;AAAA;AAAA;;;AAAA;;AAAA;;AAAA;;;AAAA;;AAAA;;AAAA;;;AAAA;;AAAA;;AAAA;;;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;;AAAA;;AAAA;;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAgV/B,IAAM,gCAAA,GAAmC,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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","file":"index.js","sourcesContent":["// \"Can this app take a Pix?\" β asked here so the editor does not offer a button\n// that would produce a charge nobody can open.\n//\n// ββ Why this is a second copy βββββββββββββββββββββββββββββββββββββββββββββββ\n// The function is `tyxter-payment-preflight`, it is OWNED by plugin-conversations\n// (which ships its source and declares it in its manifest), and that plugin\n// exports a richer reader of the same answer. This is not that reader, because\n// plugins in this repo do not depend on one another β there is no\n// @fayz-ai/plugin-conversations in this package.json and adding one would make\n// the automations screen refuse to build in an app that installs automations\n// without the inbox.\n//\n// So the shared thing is the FUNCTION, and the duplicated thing is one invoke.\n// The half that could drift β what \"ready\" means, which modes count β is the\n// function's answer, not this file's opinion.\n//\n// Absence is not failure: an app with no WhatsApp connector at all gets a null\n// readiness, and the editor shows the pay action disabled with a reason rather\n// than an error.\nimport { getActiveTenantId, getSupabaseClientOptional } from '@fayz-ai/core'\nimport * as React from 'react'\n\nconst PREFLIGHT_FUNCTION = 'tyxter-payment-preflight'\n\nexport interface PaymentReadiness {\n ready: boolean\n status: string\n /** 'abacate_pay' is production; 'sandbox_default' works end to end with money\n * that is not real; null means nothing is selected behind the channel. */\n mode: string | null\n sandbox: boolean\n reason: string | null\n}\n\ninterface MinimalClient {\n functions: {\n invoke: (name: string, options: { body: unknown }) => Promise<{ data: unknown; error: unknown }>\n }\n}\n\nasync function readReadiness(): Promise<PaymentReadiness | null> {\n const supabase = getSupabaseClientOptional() as MinimalClient | null\n const tenantId = getActiveTenantId()\n if (!supabase || !tenantId) return null\n const { data, error } = await supabase.functions.invoke(PREFLIGHT_FUNCTION, {\n body: { action: 'status', tenantId },\n })\n if (error) return null\n const payments = (data as { payments?: PaymentReadiness } | null)?.payments\n return payments ?? null\n}\n\n/** Ready AND with a rail actually selected. See PaymentReadiness.mode. */\nexport function canOfferPayment(readiness: PaymentReadiness | null): boolean {\n return Boolean(readiness?.ready) && readiness?.mode !== null && readiness?.mode !== undefined\n}\n\n/**\n * One read per screen, never thrown.\n *\n * `loading` is distinguished from \"not ready\" on purpose: a pay toggle that\n * flickers from enabled to disabled while an edge function answers is a toggle\n * somebody clicks in the gap.\n */\nexport function usePaymentReadiness(): { readiness: PaymentReadiness | null; loading: boolean } {\n const [readiness, setReadiness] = React.useState<PaymentReadiness | null>(null)\n const [loading, setLoading] = React.useState(true)\n\n React.useEffect(() => {\n let cancelled = false\n void readReadiness()\n .then((value) => { if (!cancelled) setReadiness(value) })\n .catch(() => { /* absence is not failure */ })\n .finally(() => { if (!cancelled) setLoading(false) })\n return () => { cancelled = true }\n }, [])\n\n return { readiness, loading }\n}\n","// \"Enviar teste\" β the message, sent for real, to the operator's own phone.\n//\n// Same function, same template resolution, same sender resolution as the\n// automation's send (`messaging-send`); the only differences are who is calling\n// (the operator's session instead of the platform secret) and the subject type,\n// which is forced to 'test' so a tapped Confirmar on the test message routes\n// nowhere. A preview that renders locally can lie about template approval and\n// sender state β a test that walks the real path cannot.\nimport { getActiveTenantId, getSupabaseClientOptional } from '@fayz-ai/core'\n\nconst SEND_FUNCTION = 'messaging-send'\n\ninterface MinimalClient {\n functions: {\n invoke: (name: string, options: { body: unknown }) => Promise<{ data: unknown; error: unknown }>\n }\n}\n\nexport interface TestSendResult {\n ok: boolean\n /** A code the editor can phrase: 'template_not_approved', 'no_sender', β¦ */\n error?: string\n message?: string\n}\n\nfunction readFunctionError(error: unknown, data: unknown): TestSendResult {\n const payload = (data ?? null) as { error?: string; message?: string } | null\n if (payload?.error) return { ok: false, error: payload.error, message: payload.message }\n const context = (error as { context?: { error?: string; message?: string } } | null)?.context\n if (context?.error) return { ok: false, error: context.error, message: context.message }\n return { ok: false, error: 'send_failed', message: error instanceof Error ? error.message : undefined }\n}\n\nexport async function sendTestMessage(input: {\n eventKey: string\n channel: string\n to: string\n variables: Record<string, string>\n /** Email only: send this draft instead of the saved template row. */\n template?: { subject: string; body: string }\n}): Promise<TestSendResult> {\n const supabase = getSupabaseClientOptional() as MinimalClient | null\n const tenantId = getActiveTenantId()\n if (!supabase || !tenantId) return { ok: false, error: 'not_available' }\n const { data, error } = await supabase.functions.invoke(SEND_FUNCTION, {\n body: {\n test: true,\n tenantId,\n channel: input.channel,\n eventKey: input.eventKey,\n to: input.to,\n variables: input.variables,\n subject: { type: 'test', id: crypto.randomUUID() },\n ...(input.template ? { template: input.template } : {}),\n },\n })\n if (error || (data as { error?: string } | null)?.error) return readFunctionError(error, data)\n return { ok: true }\n}\n","import { useOrganizationStore } from '@fayz-ai/admin'\n\n// Re-exports para as views nΓ£o precisarem saber de onde vem cada peΓ§a.\nexport {\n resolveMessages, resolveMessage, renderMessageTemplate,\n getEventsWithoutMessages,\n} from '@fayz-ai/core'\n\n/** Conta ativa β todo modelo Γ© escopado nela. */\nexport function useOrganizationStoreLike(): string | undefined {\n return useOrganizationStore((s) => s.currentOrg?.id)\n}\n","import { getFayzSupabaseClientOptional } from '@fayz-ai/admin'\nimport type { ResolvedFayzAgentConnection } from '@fayz-ai/admin'\nimport { getMessageDefaults } from '@fayz-ai/core'\nimport type { MessageChannel, MessageTemplate } from '@fayz-ai/core'\nimport {\n createFayzAutomationsClient,\n FayzAutomationsError,\n type FayzAutomation,\n type FayzAutomationsClient,\n} from '@fayz-ai/sdk/automations'\nimport type { MessageTemplateStore } from './templates'\n\n// ---------------------------------------------------------------------------\n// The SAME contract as `templates.ts`, served by the platform: behind a Fayz\n// project the platform is what runs the automations, so the customisation has\n// to live there β a local row the platform never reads is a fake switch.\n// ---------------------------------------------------------------------------\n\nfunction toTemplate(automation: FayzAutomation): MessageTemplate | null {\n const eventKey = automation.triggerConfig?.eventKey\n // No eventKey means it isn't a catalogue automation β standalone platform\n // flows have no row on this screen.\n if (!eventKey) return null\n const action = automation.actions?.[0]\n return {\n id: automation.id,\n tenantId: automation.tenantId ?? '',\n eventKey,\n channel: (automation.triggerConfig.sourceChannel ?? 'email') as MessageChannel,\n enabled: automation.enabled,\n // Empty and absent mean the same β \"no customisation\", the catalogue default.\n subject: action?.config?.subject || null,\n body: action?.config?.body || null,\n // The automation name belongs to the platform, not a user rename: the\n // catalogue title still owns the screen.\n name: null,\n // The platform's automation action carries a subject and a body and nothing\n // else, so there is nowhere for a customised button to live yet. NULL, not\n // [], because the catalogue default is what still applies β an empty list\n // would read as \"this tenant removed the buttons\".\n actions: null,\n updatedAt: automation.updatedAt,\n }\n}\n\nfunction catalogDefaultEnabled(eventKey: string, channel: MessageChannel): boolean {\n const def = getMessageDefaults().find((d) => d.eventKey === eventKey)\n return def?.defaultEnabled?.[channel] ?? false\n}\n\nasync function defaultSessionToken(): Promise<string | null> {\n const session = (await getFayzSupabaseClientOptional()?.auth.getSession())?.data.session\n return session?.access_token ?? null\n}\n\nexport interface FayzTemplateStoreDeps {\n client?: FayzAutomationsClient\n getSessionToken?: () => Promise<string | null>\n}\n\nexport function createFayzTemplateStore(\n connection: ResolvedFayzAgentConnection,\n deps: FayzTemplateStoreDeps = {},\n): MessageTemplateStore {\n const client = deps.client ?? createFayzAutomationsClient({\n baseUrl: connection.apiBaseUrl,\n projectId: connection.projectId,\n publishableKey: connection.publishableKey,\n })\n const getSessionToken = deps.getSessionToken ?? defaultSessionToken\n\n // (event_key, channel) β platform automation id, repopulated on every list.\n const ids = new Map<string, string>()\n const keyOf = (eventKey: string, channel: string) => `${eventKey}:${channel}`\n\n async function refresh(tenantId: string): Promise<MessageTemplate[]> {\n const automations = await client.list({ tenantId })\n ids.clear()\n const rows: MessageTemplate[] = []\n for (const automation of automations) {\n const row = toTemplate(automation)\n if (!row) continue\n ids.set(keyOf(row.eventKey, row.channel), automation.id)\n rows.push(row)\n }\n return rows\n }\n\n // One screen mounts several views of the same catalogue (list, detail, CRM β‘)\n // and StrictMode doubles effects in dev β unshared, opening it costs 8+ identical\n // GETs. One flight per tenant, short-lived; writes invalidate.\n const LIST_TTL_MS = 30_000\n let cache: { tenantId: string; at: number; promise: Promise<MessageTemplate[]> } | null = null\n\n function invalidate(): void {\n cache = null\n }\n\n function load(tenantId: string): Promise<MessageTemplate[]> {\n if (cache && cache.tenantId === tenantId && Date.now() - cache.at < LIST_TTL_MS) return cache.promise\n const promise = refresh(tenantId)\n promise.catch(() => {\n if (cache?.promise === promise) cache = null // a failure must not stay cached for 30s\n })\n cache = { tenantId, at: Date.now(), promise }\n return promise\n }\n\n async function requireToken(): Promise<string> {\n const token = await getSessionToken()\n // Writing needs the app session β same message as the rest of the admin.\n if (!token) throw new Error('SessΓ£o expirada β entre de novo.')\n return token\n }\n\n async function resolveId(eventKey: string, channel: string, tenantId: string): Promise<string | undefined> {\n const key = keyOf(eventKey, channel)\n if (!ids.has(key)) await load(tenantId)\n return ids.get(key)\n }\n\n return {\n async list(tenantId) {\n // No account yet, nothing to ask β the catalogue at its defaults is a\n // complete state, same as the local store when the read fails.\n if (!tenantId) return []\n return load(tenantId)\n },\n\n async upsert(input, tenantId) {\n if (!tenantId) throw new Error('@fayz-ai/plugin-automations: tenantId is required')\n const appSessionToken = await requireToken()\n const key = keyOf(input.eventKey, input.channel)\n let id = await resolveId(input.eventKey, input.channel, tenantId)\n\n if (!id) {\n const action: { subject?: string; body?: string } = {}\n if (input.subject != null) action.subject = input.subject\n if (input.body != null) action.body = input.body\n try {\n const created = await client.create({\n tenantId,\n appSessionToken,\n eventKey: input.eventKey,\n sourceChannel: input.channel,\n // The platform has no \"inherit from catalogue\": materialise the default.\n enabled: input.enabled ?? catalogDefaultEnabled(input.eventKey, input.channel),\n ...(Object.keys(action).length ? { action } : {}),\n })\n ids.set(key, created.id)\n invalidate()\n const row = toTemplate(created)\n if (!row) throw new Error('@fayz-ai/plugin-automations: platform did not round-trip eventKey')\n return row\n } catch (err) {\n // 409: someone created it first β turn it into an update.\n if (!(err instanceof FayzAutomationsError) || err.status !== 409) throw err\n invalidate()\n await refresh(tenantId)\n id = ids.get(key)\n if (!id) throw err\n }\n }\n\n const updated = await client.update({\n id,\n tenantId,\n appSessionToken,\n // Only what was sent: omitting has to mean \"leave it alone\", as in the local store.\n ...(typeof input.enabled === 'boolean' ? { enabled: input.enabled } : {}),\n ...(input.subject !== undefined || input.body !== undefined\n ? {\n action: {\n ...(input.subject !== undefined ? { subject: input.subject } : {}),\n ...(input.body !== undefined ? { body: input.body } : {}),\n },\n }\n : {}),\n })\n invalidate()\n const row = toTemplate(updated)\n if (!row) throw new Error('@fayz-ai/plugin-automations: platform did not round-trip eventKey')\n return row\n },\n\n async reset(eventKey, channel, tenantId) {\n if (!tenantId) return\n const id = await resolveId(eventKey, channel, tenantId)\n // Never customised: the default already applies, nothing to clear.\n if (!id) return\n const appSessionToken = await requireToken()\n // The automation stays (the on/off belongs to it); only the text goes back\n // to the catalogue β null clears the field on the server.\n await client.update({ id, tenantId, appSessionToken, action: { subject: null, body: null } })\n invalidate()\n },\n }\n}\n\nlet cachedClient: { key: string; client: FayzAutomationsClient } | null = null\n\n/** One client per connection β RunLog and the store read the same surface. */\nexport function getFayzAutomationsClient(connection: ResolvedFayzAgentConnection): FayzAutomationsClient {\n const key = `${connection.apiBaseUrl}|${connection.projectId}|${connection.publishableKey}`\n if (cachedClient?.key === key) return cachedClient.client\n const client = createFayzAutomationsClient({\n baseUrl: connection.apiBaseUrl,\n projectId: connection.projectId,\n publishableKey: connection.publishableKey,\n })\n cachedClient = { key, client }\n return client\n}\n","import React from 'react'\nimport { AlertTriangle, ChevronRight, CircleCheck, CircleSlash, History, RefreshCw } from 'lucide-react'\nimport { Badge, Button, Card } from '@fayz-ai/ui'\nimport { loadEventRuns, type EventRun, type EventRunStatus } from '@fayz-ai/core'\nimport type { ResolvedFayzAgentConnection } from '@fayz-ai/admin'\nimport type { FayzAutomationExecution } from '@fayz-ai/sdk/automations'\nimport { getFayzAutomationsClient } from '../data/fayz'\n\n// ---------------------------------------------------------------------------\n// The last runs of this trigger.\n//\n// The screen said what SHOULD happen, never what DID β so testing an automation\n// meant waiting for a customer complaint, and a complaint can't tell \"never\n// fired\" from \"fired and the send failed\", which are defects in different\n// places. The payload stays visible (collapsed) on purpose: it answers \"why did\n// it go out with the wrong name?\" without reproducing the case.\n//\n// Works for ANY trigger: the list is read by event key and every emitted event\n// goes through the same collector, so a new module shows up here untouched.\n// ---------------------------------------------------------------------------\n\nconst STATUS: Record<EventRunStatus, {\n label: string; hint: string; variant: 'success' | 'info' | 'warning' | 'destructive'\n Icon: React.ComponentType<{ className?: string }>\n}> = {\n sent: { label: 'Enviado', hint: 'A mensagem saiu.', variant: 'success', Icon: CircleCheck },\n recorded: {\n label: 'Disparou',\n // Today's honest state: the trigger works, the send doesn't exist yet.\n hint: 'O gatilho disparou e ficou registrado. O envio automΓ‘tico ainda nΓ£o estΓ‘ ligado neste ambiente.',\n variant: 'info', Icon: History,\n },\n skipped: { label: 'Ignorado', hint: 'O gatilho disparou, mas nada foi enviado β automaΓ§Γ£o desligada ou sem canal.', variant: 'warning', Icon: CircleSlash },\n failed: { label: 'Falhou', hint: 'A tentativa de envio quebrou. O erro estΓ‘ na linha.', variant: 'destructive', Icon: AlertTriangle },\n}\n\nfunction when(iso: string): string {\n const then = new Date(iso).getTime()\n const diff = Date.now() - then\n const min = Math.round(diff / 60000)\n if (min < 1) return 'agora'\n if (min < 60) return `hΓ‘ ${min} min`\n const h = Math.round(min / 60)\n if (h < 24) return `hΓ‘ ${h} h`\n return new Date(iso).toLocaleString('pt-BR', { day: '2-digit', month: '2-digit', hour: '2-digit', minute: '2-digit' })\n}\n\nfunction RunRow({ run }: { run: EventRun }) {\n const [open, setOpen] = React.useState(false)\n const cfg = STATUS[run.status] ?? STATUS.recorded\n const { Icon } = cfg\n\n return (\n <div className=\"border-b border-border last:border-b-0\">\n <button\n type=\"button\"\n onClick={() => setOpen(!open)}\n className=\"flex w-full items-center gap-3 px-4 py-2.5 text-left transition-colors hover:bg-muted/40\"\n >\n <ChevronRight className={`h-3.5 w-3.5 shrink-0 text-muted-foreground transition-transform ${open ? 'rotate-90' : ''}`} />\n <Icon className=\"h-3.5 w-3.5 shrink-0 text-muted-foreground\" />\n <Badge variant={cfg.variant}>{cfg.label}</Badge>\n <span className=\"min-w-0 flex-1 truncate text-sm text-muted-foreground\">\n {typeof run.payload.record_name === 'string' ? run.payload.record_name\n : typeof run.payload.customer_name === 'string' ? run.payload.customer_name\n : typeof run.payload.contact_name === 'string' ? run.payload.contact_name\n : run.subjectId ?? 'β'}\n </span>\n <span className=\"shrink-0 text-xs text-muted-foreground\">{when(run.occurredAt)}</span>\n </button>\n\n {open && (\n <div className=\"space-y-3 bg-muted/20 px-4 pb-4 pt-1\">\n <p className=\"text-xs text-muted-foreground\">{cfg.hint}</p>\n <div>\n <p className=\"mb-1 text-[11px] font-medium uppercase tracking-wide text-muted-foreground\">\n Dados do disparo\n </p>\n <pre className=\"overflow-x-auto rounded-md border border-border bg-card p-3 font-mono text-[11px] leading-relaxed\">\n{JSON.stringify(run.payload, null, 2)}\n </pre>\n </div>\n {run.result && (\n <div>\n <p className=\"mb-1 text-[11px] font-medium uppercase tracking-wide text-muted-foreground\">\n Resultado\n </p>\n <pre className=\"overflow-x-auto rounded-md border border-border bg-card p-3 font-mono text-[11px] leading-relaxed\">\n{JSON.stringify(run.result, null, 2)}\n </pre>\n </div>\n )}\n {run.error && (\n <p className=\"rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 font-mono text-[11px] text-destructive\">\n {run.error}\n </p>\n )}\n </div>\n )}\n </div>\n )\n}\n\nexport function RunLog({ eventKey, tenantId, enabled }: {\n eventKey: string\n tenantId?: string\n /** Current automation state β changes what the empty state means. */\n enabled: boolean\n}) {\n const [runs, setRuns] = React.useState<EventRun[] | null>(null)\n const [loading, setLoading] = React.useState(false)\n\n const load = React.useCallback(async () => {\n setLoading(true)\n setRuns(await loadEventRuns(eventKey, { tenantId, limit: 20 }))\n setLoading(false)\n }, [eventKey, tenantId])\n\n React.useEffect(() => { void load() }, [load])\n\n return (\n <Card className=\"overflow-hidden\">\n <div className=\"flex items-center justify-between gap-3 border-b border-border px-4 py-2.5\">\n <div className=\"min-w-0\">\n <span className=\"text-sm font-medium\">ExecuΓ§Γ΅es recentes</span>\n <p className=\"text-xs text-muted-foreground\">Cada vez que este gatilho disparou nesta conta.</p>\n </div>\n <Button variant=\"ghost\" size=\"sm\" onClick={() => void load()} disabled={loading}>\n <RefreshCw className={`h-3.5 w-3.5 ${loading ? 'animate-spin' : ''}`} />\n </Button>\n </div>\n\n {runs === null ? (\n <div className=\"space-y-2 p-4\">\n {[1, 2, 3].map((i) => <div key={i} className=\"h-8 animate-pulse rounded bg-muted/40\" />)}\n </div>\n ) : runs.length === 0 ? (\n <div className=\"flex flex-col items-center gap-1 px-4 py-10 text-center\">\n <History className=\"h-7 w-7 text-muted-foreground/40\" strokeWidth={1.5} />\n <p className=\"text-sm font-medium\">Nenhum disparo ainda</p>\n <p className=\"max-w-sm text-xs text-muted-foreground\">\n {enabled\n ? 'Assim que este evento acontecer, ele aparece aqui β mesmo antes de existir envio.'\n : 'A automaΓ§Γ£o estΓ‘ desligada. O gatilho continua sendo registrado aqui quando o evento acontecer.'}\n </p>\n </div>\n ) : (\n <div>{runs.map((run) => <RunRow key={run.id} run={run} />)}</div>\n )}\n </Card>\n )\n}\n\n// ---------------------------------------------------------------------------\n// The PLATFORM's runs. Behind a Fayz project the send runs there, so the real\n// history is the platform's β the local collector only knows the trigger fired,\n// not what the platform did with it.\n// ---------------------------------------------------------------------------\n\nconst EXEC_STATUS: Record<string, {\n label: string; variant: 'success' | 'info' | 'destructive'\n Icon: React.ComponentType<{ className?: string }>\n}> = {\n success: { label: 'Executada', variant: 'success', Icon: CircleCheck },\n error: { label: 'Falhou', variant: 'destructive', Icon: AlertTriangle },\n}\n\nfunction ExecutionRow({ execution }: { execution: FayzAutomationExecution }) {\n const cfg = EXEC_STATUS[execution.status]\n ?? { label: execution.status, variant: 'info' as const, Icon: History }\n const { Icon } = cfg\n return (\n <div className=\"border-b border-border px-4 py-2.5 last:border-b-0\">\n <div className=\"flex items-center gap-3\">\n <Icon className=\"h-3.5 w-3.5 shrink-0 text-muted-foreground\" />\n <Badge variant={cfg.variant}>{cfg.label}</Badge>\n <span className=\"min-w-0 flex-1 truncate text-sm text-muted-foreground\">\n {execution.automationName}\n </span>\n <span className=\"shrink-0 text-xs text-muted-foreground\">{when(execution.executedAt)}</span>\n </div>\n {execution.error && (\n <p className=\"ml-6 mt-2 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 font-mono text-[11px] text-destructive\">\n {execution.error}\n </p>\n )}\n </div>\n )\n}\n\nexport function FayzRunLog({ connection, eventKey, tenantId, enabled }: {\n connection: ResolvedFayzAgentConnection\n eventKey: string\n tenantId?: string\n /** Current automation state β changes what the empty state means. */\n enabled: boolean\n}) {\n const [executions, setExecutions] = React.useState<FayzAutomationExecution[] | null>(null)\n const [loading, setLoading] = React.useState(false)\n\n const load = React.useCallback(async () => {\n if (!tenantId) return\n setLoading(true)\n try {\n setExecutions(await getFayzAutomationsClient(connection).listExecutions({ tenantId, eventKey, limit: 20 }))\n } catch (err) {\n console.warn('[automations] could not load platform executions', err)\n setExecutions([])\n } finally {\n setLoading(false)\n }\n }, [connection, eventKey, tenantId])\n\n React.useEffect(() => { void load() }, [load])\n\n return (\n <Card className=\"overflow-hidden\">\n <div className=\"flex items-center justify-between gap-3 border-b border-border px-4 py-2.5\">\n <div className=\"min-w-0\">\n <span className=\"text-sm font-medium\">ExecuΓ§Γ΅es recentes</span>\n <p className=\"text-xs text-muted-foreground\">\n O que a plataforma Fayz executou para este gatilho nesta conta.\n </p>\n </div>\n <Button variant=\"ghost\" size=\"sm\" onClick={() => void load()} disabled={loading}>\n <RefreshCw className={`h-3.5 w-3.5 ${loading ? 'animate-spin' : ''}`} />\n </Button>\n </div>\n\n {executions === null ? (\n <div className=\"space-y-2 p-4\">\n {[1, 2, 3].map((i) => <div key={i} className=\"h-8 animate-pulse rounded bg-muted/40\" />)}\n </div>\n ) : executions.length === 0 ? (\n <div className=\"flex flex-col items-center gap-1 px-4 py-10 text-center\">\n <History className=\"h-7 w-7 text-muted-foreground/40\" strokeWidth={1.5} />\n <p className=\"text-sm font-medium\">Nenhuma execuΓ§Γ£o ainda</p>\n <p className=\"max-w-sm text-xs text-muted-foreground\">\n {enabled\n ? 'Assim que este evento acontecer, a plataforma executa a automaΓ§Γ£o e o resultado aparece aqui.'\n : 'A automaΓ§Γ£o estΓ‘ desligada β a plataforma nΓ£o executa nada para este gatilho.'}\n </p>\n </div>\n ) : (\n <div>{executions.map((e) => <ExecutionRow key={e.id} execution={e} />)}</div>\n )}\n </Card>\n )\n}\n","// The real WhatsApp doodle wallpaper, served from the product's own R2 bucket\n// (uploaded by the founder next to the connector marks). One URL beats 39KB of\n// base64 in every app bundle; the preview is an admin surface, always online.\nexport const WHATSAPP_PREVIEW_BG = 'https://assets.fayz.ai/connectors/whatsapp-background.jpg'\n","import { getSupabaseClientOptional } from '@fayz-ai/core'\nimport type { MessageChannel } from '@fayz-ai/core'\n\n// ---------------------------------------------------------------------------\n// O que a Meta respondeu sobre cada modelo.\n//\n// SΓ³ LEITURA. A tabela Γ© escrita pelo webhook e pela funΓ§Γ£o de sincronizaΓ§Γ£o,\n// com service role: quem pudesse marcar `approved` daqui faria o envio tentar um\n// modelo que a Meta nunca liberou, e a recusa chegaria como uma confirmaΓ§Γ£o de\n// horΓ‘rio que nΓ£o saiu.\n//\n// A leitura traz as linhas do tenant E as do produto (tenant_id NULL). SΓ£o as\n// duas que importam na tela: a mensagem sai pela do produto atΓ© a do tenant ser\n// aprovada, entΓ£o \"aguardando aprovaΓ§Γ£o\" sΓ³ Γ© verdade quando NENHUMA das duas\n// estΓ‘ aprovada.\n// ---------------------------------------------------------------------------\n\nexport const PROVIDER_TEMPLATES_TABLE = 'plg_automations_provider_templates'\n\nexport type ProviderTemplateStatus =\n | 'draft' | 'submitted' | 'approved' | 'rejected' | 'paused' | 'disabled'\n\nexport interface ProviderTemplateRow {\n id: string\n /** NULL = o modelo padrΓ£o do produto, que serve todos os tenants. */\n tenantId: string | null\n eventKey: string\n channel: MessageChannel\n provider: string\n templateName: string\n status: ProviderTemplateStatus\n rejectionReason: string | null\n updatedAt: string | null\n}\n\nfunction rowToProviderTemplate(row: any): ProviderTemplateRow {\n return {\n id: row.id,\n tenantId: row.tenant_id ?? null,\n eventKey: row.event_key,\n channel: (row.channel ?? 'whatsapp') as MessageChannel,\n provider: row.provider ?? 'tyxter',\n templateName: row.template_name ?? '',\n status: (row.status ?? 'draft') as ProviderTemplateStatus,\n rejectionReason: row.rejection_reason || null,\n updatedAt: row.updated_at ?? row.created_at ?? null,\n }\n}\n\n/**\n * Nunca lanΓ§a: sem cliente, sem tabela ou sem permissΓ£o a lista de automaΓ§Γ΅es\n * continua inteira, sΓ³ sem a pastilha de aprovaΓ§Γ£o. Um erro aqui nΓ£o pode\n * esconder as automaΓ§Γ΅es de e-mail, que nΓ£o dependem da Meta para nada.\n */\nexport async function loadProviderTemplates(): Promise<ProviderTemplateRow[]> {\n const client = getSupabaseClientOptional() as unknown as { from: (t: string) => any } | null\n if (!client) return []\n try {\n // Sem filtro de tenant: a RLS jΓ‘ entrega as linhas deste tenant mais as do\n // produto, e filtrar por tenant aqui esconderia justamente o modelo padrΓ£o\n // pelo qual a mensagem sai hoje.\n const { data, error } = await client.from(PROVIDER_TEMPLATES_TABLE).select('*')\n if (error) throw error\n return (data ?? []).map(rowToProviderTemplate)\n } catch (err) {\n console.warn('[automations] could not load provider template status', err)\n return []\n }\n}\n\n/**\n * A linha que decide o que a tela mostra para um (evento Γ canal).\n *\n * A do tenant ganha quando existe β Γ© a que ele estΓ‘ esperando. Se ela nΓ£o\n * existe, vale a do produto. E se a do tenant foi recusada mas a do produto estΓ‘\n * aprovada, a mensagem AINDA SAI (pela do produto): quem escolhe aqui Γ© a linha\n * do tenant, e o texto da pastilha Γ© que diz isso.\n */\nexport function providerTemplateFor(\n rows: ProviderTemplateRow[],\n eventKey: string,\n channel: MessageChannel,\n): { own: ProviderTemplateRow | null; fallback: ProviderTemplateRow | null } {\n const matching = rows.filter((r) => r.eventKey === eventKey && r.channel === channel)\n return {\n own: matching.find((r) => r.tenantId !== null) ?? null,\n fallback: matching.find((r) => r.tenantId === null) ?? null,\n }\n}\n","import React from 'react'\nimport { Badge } from '@fayz-ai/ui'\nimport type { MessageChannel } from '@fayz-ai/core'\nimport {\n loadProviderTemplates, providerTemplateFor,\n type ProviderTemplateRow,\n} from '../data/provider-templates'\n\n// ---------------------------------------------------------------------------\n// \"Ligado\" nΓ£o quer dizer \"vai sair\".\n//\n// No WhatsApp a mensagem sΓ³ existe depois que a Meta aprova o modelo, e a\n// aprovaΓ§Γ£o Γ© assΓncrona: pode levar horas e pode voltar recusada. Sem esta\n// pastilha a tela mostra um interruptor verde para uma automaΓ§Γ£o que a Meta\n// ainda nΓ£o liberou β e o negΓ³cio sΓ³ descobre quando a cliente nΓ£o recebe.\n//\n// SΓ³ o WhatsApp tem isso. E-mail nΓ£o passa por aprovaΓ§Γ£o de ninguΓ©m, entΓ£o a\n// pastilha some nos outros canais em vez de dizer \"aprovado\" sobre algo que\n// nunca precisou ser.\n// ---------------------------------------------------------------------------\n\nexport type ProviderApproval =\n | { tone: 'ok'; label: string; detail?: string }\n | { tone: 'waiting'; label: string; detail?: string }\n | { tone: 'error'; label: string; detail?: string }\n\n/**\n * O que a linha mostra para um (evento Γ canal).\n *\n * `null` = nada a dizer, e Γ© o caso comum: canal sem aprovaΓ§Γ£o, ou WhatsApp\n * ainda nΓ£o conectado (sem nenhuma linha, o assunto nΓ£o existe para este\n * negΓ³cio e uma pastilha vermelha seria um alarme sobre algo que ninguΓ©m pediu).\n *\n * A regra que decide o texto Γ© a mesma do envio: sai pelo modelo do produto atΓ©\n * o do tenant ser aprovado. Por isso um modelo do tenant recusado, com o do\n * produto aprovado, Γ© um AVISO e nΓ£o uma falha β a mensagem continua saindo.\n */\nexport function providerApprovalFor(\n rows: ProviderTemplateRow[],\n eventKey: string,\n channel: MessageChannel,\n): ProviderApproval | null {\n if (channel !== 'whatsapp') return null\n const { own, fallback } = providerTemplateFor(rows, eventKey, channel)\n const row = own ?? fallback\n if (!row) return null\n\n const fallbackApproved = fallback?.status === 'approved'\n\n switch (row.status) {\n case 'approved':\n return { tone: 'ok', label: 'Aprovado pela Meta' }\n case 'rejected':\n return {\n tone: fallbackApproved && own ? 'waiting' : 'error',\n label: fallbackApproved && own ? 'Seu texto foi recusado' : 'Recusado pela Meta',\n detail: row.rejectionReason\n ? `Motivo: ${row.rejectionReason}`\n : 'A Meta nΓ£o disse o motivo.',\n }\n case 'paused':\n return {\n tone: 'error',\n label: 'Pausado pela Meta',\n detail: row.rejectionReason ?? 'Costuma ser excesso de marcaΓ§Γ΅es de spam pelos clientes.',\n }\n case 'disabled':\n return { tone: 'error', label: 'Desativado pela Meta', detail: row.rejectionReason ?? undefined }\n case 'submitted':\n return {\n tone: 'waiting',\n label: 'Aguardando aprovaΓ§Γ£o da Meta',\n detail: fallbackApproved && own\n ? 'AtΓ© lΓ‘ a mensagem sai com o texto padrΓ£o.'\n : 'A revisΓ£o costuma levar algumas horas.',\n }\n default:\n return { tone: 'waiting', label: 'Ainda nΓ£o enviado para aprovaΓ§Γ£o' }\n }\n}\n\nconst TONE_VARIANT: Record<ProviderApproval['tone'], 'success' | 'warning' | 'destructive'> = {\n ok: 'success',\n waiting: 'warning',\n error: 'destructive',\n}\n\nexport function ProviderTemplateBadge({ approval, showDetail }: {\n approval: ProviderApproval | null\n showDetail?: boolean\n}) {\n if (!approval) return null\n // Aprovado nΓ£o ganha pastilha na lista: Γ© o estado normal, e uma linha em que\n // tudo estΓ‘ certo nΓ£o precisa de enfeite. O que precisa aparecer Γ© o que\n // impede a mensagem de sair.\n if (approval.tone === 'ok' && !showDetail) return null\n return (\n <span className=\"inline-flex flex-wrap items-center gap-1.5\">\n <Badge variant={TONE_VARIANT[approval.tone]}>{approval.label}</Badge>\n {showDetail && approval.detail && (\n <span className=\"text-xs text-muted-foreground\">{approval.detail}</span>\n )}\n </span>\n )\n}\n\n/** Uma leitura por tela. Nunca lanΓ§a: sem a tabela, a lista continua inteira. */\nexport function useProviderTemplates(): ProviderTemplateRow[] {\n const [rows, setRows] = React.useState<ProviderTemplateRow[]>([])\n React.useEffect(() => {\n let cancelled = false\n void loadProviderTemplates().then((data) => { if (!cancelled) setRows(data) })\n return () => { cancelled = true }\n }, [])\n return rows\n}\n","import React from 'react'\nimport { Check, Clock, Mail, MessageSquare, Monitor, RotateCcw, Send, Smartphone, Zap } from 'lucide-react'\nimport { Badge, Button, Card, HeaderTabs, Hint, PhoneField, SubpageHeader, Switch, toast, WhatsAppIcon } from '@fayz-ai/ui'\nimport {\n adminNavigateTo, resolveFayzAgentConnection, AskAIButton, useAgentSurface,\n type AgentSurfaceContribution,\n} from '@fayz-ai/admin'\nimport type { MessageAction, MessageActionId, MessageChannel, PluginAITool, ResolvedMessage } from '@fayz-ai/core'\nimport { usePluginRuntimeOptional } from '@fayz-ai/core'\nimport { canOfferPayment, usePaymentReadiness } from '../data/payment-preflight'\nimport { sendTestMessage } from '../data/test-send'\nimport { resolveMessage, renderMessageTemplate, useOrganizationStoreLike } from '../lib/runtime'\nimport { FayzRunLog, RunLog } from './RunLog'\nimport { WHATSAPP_PREVIEW_BG } from './whatsapp-preview-bg'\nimport {\n ProviderTemplateBadge, providerApprovalFor, useProviderTemplates,\n} from './ProviderTemplateStatus'\nimport type { MessageTemplateStore } from '../data/templates'\n\n// ---------------------------------------------------------------------------\n// Um modelo, em tela cheia. Duas visΓ΅es do MESMO texto:\n// PrΓ©via o que a pessoa recebe, com os campos jΓ‘ substituΓdos\n// CΓ³digo o texto-fonte, onde se edita\n//\n// A substituiΓ§Γ£o da prΓ©via Γ© a de @fayz-ai/core (renderMessageTemplate), nΓ£o um\n// replace local: prΓ©via e envio precisam concordar, senΓ£o aprova-se um texto e\n// entrega-se outro.\n//\n// \"Igual ao padrΓ£o\" Γ© gravado como AUSΓNCIA de personalizaΓ§Γ£o (null), nΓ£o como\n// cΓ³pia β assim melhorias no texto padrΓ£o continuam chegando a quem nunca\n// mexeu. Γ o mesmo motivo pelo qual \"Restaurar padrΓ£o\" APAGA a linha em vez de\n// escrever o texto de fΓ‘brica nela.\n// ---------------------------------------------------------------------------\n\ntype ViewTab = 'preview' | 'code' | 'runs' | 'test'\n\n// ---------------------------------------------------------------------------\n// Os botΓ΅es da mensagem.\n//\n// O catΓ‘logo do plugin define os padrΓ΅es (Confirmar/Cancelar no agendamento);\n// aqui a pessoa liga e desliga cada um. Γ uma lista fechada porque um botΓ£o nΓ£o\n// Γ© um texto: cada id tem um significado do lado de cΓ‘ β `confirm` e `cancel`\n// mexem no agendamento, `pay` abre uma cobranΓ§a β e um id inventado seria um\n// botΓ£o que o cliente toca e nada acontece.\n//\n// `pay` Γ© o ΓΊnico que depende de algo fora deste app, e por isso Γ© o ΓΊnico que\n// pode aparecer desligado por motivo alheio: sem uma conta de pagamento\n// escolhida na Tyxter, a cobranΓ§a nΓ£o abre. Mostrar o botΓ£o desabilitado com o\n// motivo Γ© melhor do que escondΓͺ-lo β escondido, a pergunta \"cadΓͺ o Pix?\" nΓ£o\n// tem onde ser respondida.\n// ---------------------------------------------------------------------------\nconst ACTION_CATALOG: Array<{ id: MessageActionId; label: string; kind: MessageAction['kind']; hint: string }> = [\n { id: 'confirm', label: 'Confirma', kind: 'reply', hint: 'O cliente confirma o horΓ‘rio no toque.' },\n { id: 'cancel', label: 'Cancela', kind: 'reply', hint: 'O cliente desmarca sem precisar ligar.' },\n { id: 'pay', label: 'Pagar', kind: 'payment', hint: 'O cliente recebe o Pix na conversa.' },\n]\n\n/**\n * A lista de botΓ΅es depois de ligar ou desligar um deles.\n *\n * A ordem Γ© a do catΓ‘logo e nΓ£o a do clique: os botΓ΅es chegam ao WhatsApp\n * numerados, e reordenΓ‘-los ao ligar o terceiro mudaria o que o segundo faz\n * numa mensagem que a Meta jΓ‘ aprovou.\n */\nexport function nextActions(\n current: MessageAction[], id: MessageActionId, on: boolean,\n): MessageAction[] {\n const kept = new Set(current.filter((a) => a.id !== id).map((a) => a.id))\n if (on) kept.add(id)\n const labels = new Map(current.map((a) => [a.id, a.label]))\n return ACTION_CATALOG\n .filter((a) => kept.has(a.id))\n // O rΓ³tulo que jΓ‘ existe ganha do padrΓ£o: se o texto foi personalizado,\n // ligar outro botΓ£o nΓ£o Γ© hora de reescrevΓͺ-lo.\n .map((a) => ({ id: a.id, label: labels.get(a.id) ?? a.label, kind: a.kind }))\n}\n\n// What each refusal of a test send means to the person reading the toast. The\n// codes are messaging-send's own; an unknown one falls back to its message.\nconst TEST_ERROR: Record<string, string> = {\n template_not_approved: 'O modelo ainda nΓ£o foi aprovado pela Meta β sincronize os modelos e tente de novo.',\n no_sender: 'Este app ainda nΓ£o tem um nΓΊmero de WhatsApp ativo. Veja Conversas β Tyxter.',\n not_connected: 'O WhatsApp ainda nΓ£o estΓ‘ conectado neste app. Veja Conversas β Tyxter.',\n contact_opted_out: 'Este contato pediu para nΓ£o receber mensagens.',\n invalid_recipient: 'Esse destino nΓ£o parece vΓ‘lido.',\n not_a_member: 'A sua sessΓ£o nΓ£o pertence a este negΓ³cio.',\n not_available: 'O envio de teste nΓ£o estΓ‘ disponΓvel neste ambiente.',\n email_not_configured: 'O envio de e-mail nΓ£o estΓ‘ configurado neste app.',\n template_not_found: 'Escreva a mensagem antes de testar.',\n email_rejected: 'O provedor de e-mail recusou a mensagem.',\n email_credential_rejected: 'A chave de e-mail do app foi recusada pelo provedor.',\n email_rate_limited: 'O provedor pediu uma pausa β tente de novo em instantes.',\n}\n\n/**\n * O teste que anda o caminho de verdade.\n *\n * A prΓ©via acima substitui variΓ‘veis localmente e nΓ£o pode mentir sobre o texto\n * β mas sΓ³ o envio real revela o resto: modelo aprovado, nΓΊmero ativo, chave da\n * plataforma. Por isso o teste chama a MESMA funΓ§Γ£o do envio da automaΓ§Γ£o, com\n * a sessΓ£o da pessoa no lugar do segredo da plataforma e um assunto 'test' que\n * nenhum botΓ£o consegue transformar em aΓ§Γ£o sobre um registro real.\n */\nfunction TestSendStrip({ eventKey, channel, placeholders, template }: {\n eventKey: string\n channel: MessageChannel\n placeholders: string[]\n /** Email only: the draft on screen goes with the test, saved or not. */\n template?: { subject: string; body: string }\n}) {\n const isEmail = channel === 'email'\n const [recipient, setRecipient] = React.useState('')\n const [sending, setSending] = React.useState(false)\n const valid = isEmail\n ? /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(recipient.trim())\n : recipient.replace(/\\D/g, '').length >= 10\n\n const send = async () => {\n setSending(true)\n try {\n const variables = Object.fromEntries(placeholders.map((p) => {\n const key = p.replace(/[{}]/g, '').trim()\n return [key, SAMPLE[key] ?? key]\n }))\n const result = await sendTestMessage({ eventKey, channel, to: recipient.trim(), variables, template })\n if (result.ok) {\n toast.success(isEmail\n ? 'Teste enviado β confira a caixa de entrada desse e-mail'\n : 'Teste enviado β confira o WhatsApp desse nΓΊmero')\n } else {\n toast.error(TEST_ERROR[result.error ?? ''] ?? result.message ?? 'NΓ£o foi possΓvel enviar o teste')\n }\n } finally {\n setSending(false)\n }\n }\n\n return (\n // Sem moldura prΓ³pria: o strip vive dentro do Card da aba Testar, e uma\n // borda aqui era o anel duplicado de sempre.\n <div className=\"mt-3 flex flex-wrap items-end gap-2\">\n <div className=\"min-w-0 flex-1\">\n <label className=\"mb-1 block text-xs font-medium text-muted-foreground\">\n {isEmail ? 'E-mail que recebe o teste' : 'NΓΊmero que recebe o teste'}\n </label>\n {isEmail ? (\n <input\n type=\"email\"\n value={recipient}\n onChange={(e) => setRecipient(e.target.value)}\n placeholder=\"voce@exemplo.com\"\n disabled={sending}\n aria-label=\"E-mail que recebe o teste\"\n className=\"w-full rounded-input border border-input bg-card px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring\"\n />\n ) : (\n <PhoneField\n value={recipient}\n onChange={setRecipient}\n placeholder=\"(21) 99999-9999\"\n disabled={sending}\n aria-label=\"NΓΊmero que recebe o teste\"\n />\n )}\n </div>\n <Button variant=\"outline\" onClick={() => void send()} disabled={!valid || sending}>\n <Send className=\"mr-2 h-3.5 w-3.5\" />\n {sending ? 'Enviandoβ¦' : 'Enviar teste'}\n </Button>\n </div>\n )\n}\n\nconst TABS: { value: ViewTab; label: string }[] = [\n { value: 'preview', label: 'PrΓ©via' },\n { value: 'code', label: 'CΓ³digo' },\n // O que jΓ‘ aconteceu. Fica ao lado do texto, e nΓ£o numa tela Γ parte, porque\n // Γ© a mesma pergunta em dois tempos: o que vai sair, e o que saiu.\n { value: 'runs', label: 'ExecuΓ§Γ΅es' },\n]\n\n// SΓ³ aparece nos canais que tΓͺm envio de teste (WhatsApp, e-mail).\nconst TEST_TAB: { value: ViewTab; label: string } = { value: 'test', label: 'Testar' }\n\nconst CHANNEL_LABEL: Record<MessageChannel, string> = {\n email: 'E-mail', whatsapp: 'WhatsApp', sms: 'SMS', push: 'Push', webchat: 'Chat',\n}\n\n// The channel is what distinguishes this screen from its siblings (the same\n// event exists per channel), so the identity slot carries the CHANNEL's face β\n// and WhatsApp's face is its mark, not a generic bubble.\nconst CHANNEL_ICON: Record<MessageChannel, React.ComponentType<{ className?: string }>> = {\n email: Mail, whatsapp: WhatsAppIcon, sms: Smartphone, push: MessageSquare, webchat: MessageSquare,\n}\n\n/** Dados de exemplo da prΓ©via. NΓ£o sΓ£o de ninguΓ©m β a tela diz isso. */\n// ---------------------------------------------------------------------------\n// A mensagem, escrita pelo assistente.\n//\n// Client-plane e `mode: 'read'` de propΓ³sito: a ferramenta NΓO grava nada β ela\n// preenche o rascunho do editor ao lado, e o Salvar continua sendo um clique de\n// uma pessoa. Declarar `persist` aqui pediria uma confirmaΓ§Γ£o para escrever num\n// campo de texto, e avisaria as listas do app de uma mudanΓ§a que nΓ£o houve.\n// ---------------------------------------------------------------------------\nconst WRITE_MESSAGE_TOOL: PluginAITool = {\n id: 'automations.writeMessage',\n name: 'writeAutomationMessage',\n description:\n 'Writes the subject and body of the automation message the user has open, into the editor (it does NOT save β the user does). '\n + 'Use ONLY the placeholders listed in the surface state, spelled exactly, including the braces: an invented one renders as literal text in a message a customer reads. '\n + 'Match the channel: e-mail takes a subject and paragraphs; WhatsApp and SMS take no subject and few lines.',\n icon: 'MessageSquare',\n mode: 'read',\n execution: { plane: 'client' },\n category: 'Automations',\n parameters: {\n type: 'object',\n properties: {\n subject: { type: 'string', description: 'Subject line. Leave empty for channels that have none.' },\n body: { type: 'string', description: 'Message body, with placeholders where they belong.' },\n },\n required: ['body'],\n },\n}\n\nconst SAMPLE: Record<string, string> = {\n store_name: 'Sua Loja', company_name: 'Sua Empresa',\n customer_name: 'Maria Silva', contact_name: 'Maria Silva', lead_name: 'Maria Silva',\n order_number: '1042', order_total: 'R$ 189,90',\n order_items: '1 Γ Camiseta ClΓ‘ssica β R$ 89,90\\n2 Γ Caneca Esmaltada β R$ 100,00',\n tracking_code: 'BR123456789BR', cart_url: 'https://sualoja.com.br/carrinho',\n deal_name: 'Proposta β Reforma da fachada', deal_value: 'R$ 12.400,00',\n stage_name: 'NegociaΓ§Γ£o', owner_name: 'JoΓ£o Pereira',\n appointment_date: '12/08/2026', appointment_time: '14:30',\n}\n\nexport interface AutomationDetailPageProps {\n eventKey?: string\n channel?: string\n store: MessageTemplateStore\n /** Para onde o \"voltar\" leva β a lista pode morar no menu ou nas\n * configuraΓ§Γ΅es, e a pessoa tem que voltar por onde entrou. */\n backTo?: string\n /**\n * Montada na coluna da direita, ao lado da lista, em vez de ser a tela.\n *\n * Some o cabeΓ§alho prΓ³prio: quem nomeia a coluna e oferece a volta Γ© o\n * cabeΓ§alho dela, e desenhar o nosso ali embaixo era o mesmo tΓtulo duas\n * vezes, com dois jeitos de sair.\n */\n embedded?: boolean\n /**\n * Como sair, quando sair NΓO Γ© navegar.\n *\n * Aberta pela coluna a partir de outra tela (o raio do CRM), a saΓda Γ© fechar\n * a coluna e continuar onde se estava β `backTo` levaria embora justamente a\n * tela que se queria manter.\n */\n onDone?: () => void\n}\n\nexport function AutomationDetailPage({ eventKey, channel, store, backTo = '/automations', embedded, onDone }: AutomationDetailPageProps) {\n const tenantId = useOrganizationStoreLike()\n const runtime = usePluginRuntimeOptional()\n const fayzConnection = React.useMemo(() => resolveFayzAgentConnection(), [])\n const [message, setMessage] = React.useState<ResolvedMessage | null | undefined>(undefined)\n const [tab, setTab] = React.useState<ViewTab>('preview')\n const [device, setDevice] = React.useState<'desktop' | 'mobile'>('desktop')\n const [draft, setDraft] = React.useState<{ subject: string; body: string } | null>(null)\n // O texto de cada botΓ£o enquanto se digita. Grava no blur, nΓ£o por tecla:\n // cada gravaΓ§Γ£o vai direto ao banco (como o interruptor ao lado), e um PATCH\n // por caractere seria uma automaΓ§Γ£o salva vinte vezes por palavra.\n const [labelDrafts, setLabelDrafts] = React.useState<Record<string, string>>({})\n const [saving, setSaving] = React.useState(false)\n const providerTemplates = useProviderTemplates()\n const { readiness, loading: readinessLoading } = usePaymentReadiness()\n\n const back = React.useCallback(\n () => (onDone ? onDone() : adminNavigateTo(backTo)),\n [onDone, backTo],\n )\n\n // --- assistant surface ---------------------------------------------------\n const surfaceRef = React.useRef({ message, draft })\n surfaceRef.current = { message, draft }\n\n const agentSurface = React.useMemo<AgentSurfaceContribution>(() => ({\n id: 'automations.message',\n pluginId: 'automations',\n instructions:\n 'The user is editing one automation message. `placeholders` in the surface state are the ONLY variables that resolve β copy them verbatim, braces included. '\n + 'Call writeAutomationMessage once with the whole text; the editor fills and the user reviews before saving.',\n describe: () => {\n const o = surfaceRef.current\n if (!o.message) return { title: 'AutomaΓ§Γ£o' }\n const current = o.draft ?? { subject: o.message.subject, body: o.message.body }\n return {\n title: `AutomaΓ§Γ£o β ${o.message.event?.title ?? o.message.event?.name ?? ''}`,\n state: {\n event: o.message.event?.name ?? null,\n channel: o.message.channel,\n hasSubject: o.message.channel === 'email',\n placeholders: Object.keys(SAMPLE).map((key) => `{{${key}}}`),\n currentSubject: current.subject,\n currentBody: current.body,\n },\n }\n },\n tools: [{\n tool: WRITE_MESSAGE_TOOL,\n execute: (args: Record<string, unknown>) => {\n const o = surfaceRef.current\n if (!o.message) return { ok: false, error: 'no_message_open' }\n const current = o.draft ?? { subject: o.message.subject, body: o.message.body }\n const body = String(args.body ?? '').trim()\n if (!body) return { ok: false, error: 'empty_body' }\n const subject = args.subject === undefined ? current.subject : String(args.subject)\n setDraft({ subject, body })\n // Leva para a aba do texto: ele acabou de mudar e a prΓ©-visualizaΓ§Γ£o\n // nΓ£o mostra onde mexer.\n setTab('code')\n return { ok: true, filled: true, saved: false, note: 'Draft filled β the user still has to press Save.' }\n },\n }],\n }), [])\n useAgentSurface(agentSurface)\n\n const reload = React.useCallback(async () => {\n if (!eventKey || !channel) { setMessage(null); return }\n let overrides: Awaited<ReturnType<MessageTemplateStore['list']>> = []\n try {\n overrides = await store.list(tenantId)\n } catch (err) {\n console.warn('[automations] could not load overrides; showing defaults', err)\n }\n const found = resolveMessage(decodeURIComponent(eventKey), channel as MessageChannel, overrides, runtime?.events ?? [])\n setMessage(found)\n if (found) setDraft({ subject: found.subject, body: found.body })\n }, [eventKey, channel, store, tenantId, runtime])\n\n React.useEffect(() => { void reload() }, [reload])\n\n const header = embedded ? null : (\n <SubpageHeader\n title={message === undefined ? '' : (message?.override?.name ?? message?.event.title ?? message?.event.name ?? 'AutomaΓ§Γ£o')}\n parentLabel=\"AutomaΓ§Γ΅es\"\n onBack={back}\n />\n )\n\n if (message === undefined) {\n return (\n <div className=\"space-y-4\">\n {header}\n <div className=\"h-8 w-64 animate-pulse rounded bg-muted\" />\n <Card className=\"h-96 animate-pulse\" />\n </div>\n )\n }\n\n if (!message) {\n return (\n <>\n {header}\n <Card className=\"flex flex-col items-center gap-2 p-12 text-center\">\n <Mail className=\"h-9 w-9 text-muted-foreground/40\" strokeWidth={1.5} />\n <p className=\"font-semibold\">AutomaΓ§Γ£o nΓ£o encontrada</p>\n <p className=\"max-w-sm text-sm text-muted-foreground\">\n O evento <code className=\"font-mono\">{eventKey}</code> nΓ£o estΓ‘ no catΓ‘logo β o mΓ³dulo\n que o registra pode nΓ£o estar instalado nesta conta.\n </p>\n <Button variant=\"outline\" className=\"mt-2\" onClick={back}>Voltar para AutomaΓ§Γ΅es</Button>\n </Card>\n </>\n )\n }\n\n const event = message.event\n // O texto de fΓ‘brica: o que \"restaurar padrΓ£o\" devolve. Vem do registro de\n // padrΓ΅es, nΓ£o do evento β o evento Γ© o fato, nΓ£o a mensagem.\n const fallback = { subject: message.override ? undefined : message.subject, body: message.body }\n const ChannelIcon = CHANNEL_ICON[message.channel] ?? Zap\n const isWhatsapp = message.channel === 'whatsapp'\n const current = draft ?? { subject: message.subject, body: message.body }\n const dirty = current.subject !== message.subject || current.body !== message.body\n const hasSubject = message.channel === 'email'\n\n const patch = async (input: Parameters<MessageTemplateStore['upsert']>[0]) => {\n setSaving(true)\n try {\n await store.upsert(input, tenantId)\n await reload()\n } catch (err) {\n console.warn('[automations] save failed', err)\n toast.error('NΓ£o foi possΓvel salvar')\n } finally {\n setSaving(false)\n }\n }\n\n const save = () => void patch({\n eventKey: event.name,\n channel: message.channel,\n // Igual ao padrΓ£o volta a ser \"sem personalizaΓ§Γ£o\", nΓ£o uma cΓ³pia.\n subject: current.subject.trim() === (fallback?.subject ?? '') ? null : current.subject.trim() || null,\n body: current.body.trim() === fallback?.body ? null : current.body.trim() || null,\n })\n\n const reset = async () => {\n setDraft({ subject: fallback?.subject ?? '', body: fallback?.body ?? '' })\n setSaving(true)\n try {\n // Apaga a linha inteira: com ela fora, o padrΓ£o volta a valer e melhorias\n // no texto de fΓ‘brica voltam a chegar aqui.\n await store.reset(event.name, message.channel, tenantId)\n await reload()\n toast.success('Texto restaurado')\n } catch (err) {\n console.warn('[automations] reset failed', err)\n toast.error('NΓ£o foi possΓvel restaurar')\n } finally {\n setSaving(false)\n }\n }\n\n const previewSubject = renderMessageTemplate(current.subject, SAMPLE)\n const previewBody = renderMessageTemplate(current.body, SAMPLE)\n\n return (\n <div className=\"space-y-5\">\n {header}\n\n {/* Identidade e controles.\n Numa pΓ‘gina larga cabem na mesma linha. Na coluna nΓ£o cabem: as\n pastilhas quebravam uma por linha, a descriΓ§Γ£o virava uma coluna de\n trΓͺs palavras e \"Restaurar padrΓ£o\" por extenso empurrava o Salvar para\n fora β por isso na coluna eles sΓ£o duas faixas empilhadas, com o\n restaurar reduzido ao seu glifo. */}\n <div className={embedded ? 'space-y-3' : 'flex flex-wrap items-start gap-3'}>\n <div className={embedded ? 'flex items-start gap-3' : 'contents'}>\n <span\n className={`flex h-9 w-9 shrink-0 items-center justify-center rounded-lg border ${\n isWhatsapp\n ? 'border-[#25D366]/30 bg-[#25D366]/10 text-[#1faf55]'\n : 'border-border text-muted-foreground'\n }`}\n >\n <ChannelIcon className=\"h-4 w-4\" />\n </span>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <Badge variant=\"outline\">{CHANNEL_LABEL[message.channel]}</Badge>\n <Badge variant=\"outline\">{message.kind === 'marketing' ? 'Marketing' : 'Transacional'}</Badge>\n {message.customized && <Badge variant=\"info\">Personalizado</Badge>}\n </div>\n <p className=\"mt-0.5 text-sm text-muted-foreground\">{event.description}</p>\n {/* Aqui a pastilha aparece MESMO quando estΓ‘ tudo certo, e traz o\n motivo junto: Γ© a tela onde se decide o que fazer com uma\n recusa, e \"recusado\" sem o motivo nΓ£o deixa ninguΓ©m agir. */}\n <div className=\"mt-1.5\">\n <ProviderTemplateBadge\n approval={providerApprovalFor(providerTemplates, event.name, message.channel)}\n showDetail\n />\n </div>\n </div>\n </div>\n\n <div className={embedded ? 'flex items-center gap-2' : 'flex shrink-0 flex-wrap items-center gap-2'}>\n {/* O mesmo interruptor da lista: liga na hora, sem passar pelo Salvar\n β que aqui Γ© sΓ³ do TEXTO. Vem primeiro na coluna porque Γ© o que se\n toca com mais frequΓͺncia, e porque ligar nΓ£o Γ© salvar. */}\n <Switch\n size=\"md\"\n checked={message.enabled}\n onCheckedChange={(next) => void patch({ eventKey: event.name, channel: message.channel, enabled: next })}\n disabled={saving}\n label={message.enabled ? 'Ativa' : 'Inativa'}\n />\n <div className={embedded ? 'ml-auto flex items-center gap-2' : 'contents'}>\n <Hint label=\"Descarta o texto personalizado e volta ao padrΓ£o do produto.\">\n <span>\n <Button\n variant={embedded ? 'ghost' : 'outline'}\n size={embedded ? 'icon' : undefined}\n onClick={() => void reset()}\n disabled={!message.customized || saving}\n aria-label={embedded ? 'Restaurar padrΓ£o' : undefined}\n >\n <RotateCcw className={embedded ? 'h-4 w-4' : 'mr-2 h-4 w-4'} />\n {!embedded && 'Restaurar padrΓ£o'}\n </Button>\n </span>\n </Hint>\n {/* Escrever a mensagem Γ o trabalho desta tela, e Γ© o trabalho que\n um modelo faz melhor que um campo vazio. A ferramenta preenche o\n RASCUNHO β quem salva continua sendo a pessoa, no botΓ£o ao lado. */}\n <AskAIButton\n variant={embedded ? 'ghost' : 'outline'}\n label={embedded ? '' : undefined}\n hint=\"Descreva o tom da mensagemβ¦\"\n intro={{\n role: 'setup',\n persona: 'Redator das automaΓ§Γ΅es',\n pitch: 'Diga como esta mensagem deve soar.',\n description:\n 'Escrevo o assunto e o corpo desta automaΓ§Γ£o usando as variΓ‘veis que ela tem Γ disposiΓ§Γ£o. O texto cai no editor ao lado para vocΓͺ revisar β nada Γ© salvo sem vocΓͺ.',\n suggestions: [\n { label: 'Mais curta e direta' },\n { label: 'Mais calorosa, com o nome do cliente' },\n { label: 'Formal, para um pΓΊblico corporativo' },\n ],\n }}\n />\n {/* Uma tela, um CTA: o Salvar sΓ³ se veste de botΓ£o primΓ‘rio quando\n hΓ‘ o que salvar. \"Salvo\" nΓ£o Γ© uma aΓ§Γ£o β desenhΓ‘-lo como um\n botΓ£o apagado deixava um CTA morto no lugar mais nobre da\n coluna; como confirmaΓ§Γ£o silenciosa, ele diz o estado e sai do\n caminho. */}\n {dirty || saving ? (\n <Button onClick={save} disabled={saving}>\n {saving ? 'Salvandoβ¦' : 'Salvar'}\n </Button>\n ) : (\n <span className=\"inline-flex h-9 items-center gap-1 px-2 text-xs font-medium text-muted-foreground\">\n <Check className=\"h-3.5 w-3.5\" />\n Salvo\n </span>\n )}\n </div>\n </div>\n </div>\n\n <HeaderTabs\n tabs={isWhatsapp || message.channel === 'email' ? [...TABS, TEST_TAB] : TABS}\n value={tab}\n onChange={setTab}\n aria-label=\"VisualizaΓ§Γ£o\"\n />\n\n <div className=\"flex flex-wrap items-center gap-x-6 gap-y-2 border-b border-border pb-4 text-xs text-muted-foreground\">\n <span className=\"inline-flex items-center gap-1.5\">\n <Zap className=\"h-3.5 w-3.5\" />\n Gatilho:\n <code className=\"rounded bg-muted px-1.5 py-0.5 font-mono text-[11px] text-foreground\">{event.name}</code>\n </span>\n <span className=\"inline-flex items-center gap-1.5\">\n <Clock className=\"h-3.5 w-3.5\" />\n {event.trigger}\n </span>\n {hasSubject && current.subject && <span className=\"min-w-0 truncate\">Assunto: {current.subject}</span>}\n </div>\n\n {tab === 'runs' ? (\n // AtrΓ‘s de um projeto Fayz o histΓ³rico verdadeiro Γ© o da plataforma β\n // Γ© ela quem executa. Fora dele, o coletor local continua valendo.\n fayzConnection ? (\n <FayzRunLog connection={fayzConnection} eventKey={event.name} tenantId={tenantId} enabled={message.enabled} />\n ) : (\n <RunLog eventKey={event.name} tenantId={tenantId} enabled={message.enabled} />\n )\n ) : tab === 'preview' ? (\n <Card className=\"overflow-hidden\">\n {/* Na coluna, a aba ativa jΓ‘ diz \"PrΓ©via\" logo acima β repetir o\n tΓtulo dentro do cartΓ£o era o mesmo nome duas vezes a um dedo de\n distΓ’ncia. A faixa sΓ³ existe na pΓ‘gina larga, onde carrega a\n comparaΓ§Γ£o computador/celular. */}\n {!embedded && (\n <div className=\"flex items-center justify-between gap-3 border-b border-border px-4 py-2.5\">\n <span className=\"text-sm font-medium\">PrΓ©via</span>\n {/* Computador/celular Γ© uma COMPARAΓΓO de larguras, e a coluna tem\n uma sΓ³: os dois botΓ΅es levavam ao mesmo desenho, e um controle\n que nΓ£o muda nada Γ© pior do que controle nenhum. */}\n <div className=\"flex items-center gap-1\">\n {(['desktop', 'mobile'] as const).map((d) => (\n <button\n key={d}\n type=\"button\"\n onClick={() => setDevice(d)}\n aria-label={d === 'desktop' ? 'Computador' : 'Celular'}\n className={`flex h-7 w-7 items-center justify-center rounded-md transition-colors ${\n device === d ? 'bg-muted text-foreground' : 'text-muted-foreground hover:bg-muted/60'\n }`}\n >\n {d === 'desktop' ? <Monitor className=\"h-4 w-4\" /> : <Smartphone className=\"h-4 w-4\" />}\n </button>\n ))}\n </div>\n </div>\n )}\n\n <div className={embedded ? 'bg-muted/30 p-4' : 'bg-muted/30 p-6'}>\n {/* WhatsApp/SMS nΓ£o tΓͺm assunto nem cabeΓ§alho de remetente β mostrar\n a moldura de e-mail neles prometeria uma forma que o canal nΓ£o\n tem. */}\n {/* Uma aresta sΓ³: a moldura interna vive de sombra e cantos\n clipados β borda aqui somava um segundo anel dentro do Card. */}\n <div\n className={`mx-auto overflow-hidden rounded-card bg-card shadow-sm transition-[max-width] ${\n device === 'mobile' ? 'max-w-[380px]' : hasSubject ? 'max-w-[600px]' : 'max-w-[420px]'\n }`}\n >\n {hasSubject ? (\n <>\n {/* Moldura de navegador (Safari): a prΓ©via de e-mail Γ© \"como\n o cliente vΓͺ no Gmail\", e a janela diz isso sem legenda.\n SemΓ‘foro decorativo β nada aqui Γ© clicΓ‘vel. */}\n <div aria-hidden className=\"flex items-center gap-1.5 border-b border-border bg-muted/40 px-4 py-2.5\">\n <span className=\"h-3 w-3 rounded-full bg-[#ff5f57]\" />\n <span className=\"h-3 w-3 rounded-full bg-[#febc2e]\" />\n <span className=\"h-3 w-3 rounded-full bg-[#28c840]\" />\n </div>\n <div className=\"px-6 pb-4 pt-5\">\n <p className=\"text-base font-semibold leading-snug\">{previewSubject}</p>\n {/* A linha do remetente, como no Gmail: avatar + nome no\n topo-esquerdo, destinatΓ‘rio embaixo, hora Γ direita. */}\n <div className=\"mt-4 flex items-center gap-3\">\n <span className=\"flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-primary/10 text-sm font-semibold text-primary\">\n {(SAMPLE.store_name ?? 'S').charAt(0)}\n </span>\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-semibold\">{SAMPLE.store_name}</p>\n <p className=\"text-xs text-muted-foreground\">para mim</p>\n </div>\n <span className=\"ml-auto shrink-0 text-xs text-muted-foreground\">09:41</span>\n </div>\n </div>\n <div className=\"whitespace-pre-wrap border-t border-border px-6 py-5 text-sm leading-relaxed\">{previewBody}</div>\n </>\n ) : (\n <div\n className=\"p-4\"\n // O papel de parede real do WhatsApp: quem escreve vΓͺ a\n // mensagem no palco em que ela vai aparecer. O balΓ£o Γ©\n // sempre o de saΓda (verde) β Γ© o negΓ³cio falando. Sem\n // raio prΓ³prio: a moldura clipa os cantos.\n style={isWhatsapp ? { backgroundImage: `url(${WHATSAPP_PREVIEW_BG})`, backgroundSize: 'cover', backgroundPosition: 'center' } : undefined}\n >\n <div className=\"whitespace-pre-wrap rounded-2xl rounded-tl-sm bg-[#dcf8c6] px-3 py-2 text-sm leading-relaxed text-[#111b21] shadow-sm\">\n {previewBody}\n </div>\n {/* Os botΓ΅es fazem parte da mensagem, entΓ£o fazem parte da\n prΓ©via: quem escreve o texto precisa ver que Confirmar e\n Cancelar jΓ‘ dizem o que a ΓΊltima linha ia dizer. */}\n {message.actions.length > 0 && (\n <div className=\"mt-1 space-y-1\">\n {message.actions.map((action) => (\n <div\n key={action.id}\n // Chips brancos, como o WhatsApp desenha reply buttons β\n // no papel de parede o verde do balΓ£o os engolia.\n className=\"rounded-lg bg-white px-3 py-1.5 text-center text-sm font-medium text-[#1e7fd6] shadow-sm\"\n >\n {action.label}\n </div>\n ))}\n </div>\n )}\n </div>\n )}\n </div>\n <p className=\"mt-4 text-center text-xs text-muted-foreground\">\n Dados de exemplo β nenhum registro real foi usado.\n </p>\n </div>\n </Card>\n ) : tab === 'test' ? (\n <Card className=\"p-4\">\n <p className=\"text-sm text-muted-foreground\">\n {isWhatsapp\n ? 'Envio real, pelo mesmo caminho da automaΓ§Γ£o β modelo aprovado, nΓΊmero ativo e entrega de verdade, com os dados de exemplo.'\n : 'Envio real, pelo mesmo caminho da automaΓ§Γ£o β vai o texto que estΓ‘ na tela, salvo ou nΓ£o, com os dados de exemplo.'}\n </p>\n <TestSendStrip\n eventKey={event.name}\n channel={message.channel}\n placeholders={message.placeholders}\n // WhatsApp must ride the Meta-approved template; email tests\n // exactly the text on screen, saved or not.\n template={message.channel === 'email'\n ? { subject: current.subject, body: current.body }\n : undefined}\n />\n </Card>\n ) : (\n <Card className=\"space-y-4 p-4\">\n {hasSubject && (\n <div>\n <label className=\"mb-1 block text-xs font-medium text-muted-foreground\">Assunto</label>\n <input\n value={current.subject}\n onChange={(e) => setDraft({ ...current, subject: e.target.value })}\n className=\"w-full rounded-input border border-input bg-card px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring\"\n />\n </div>\n )}\n <div>\n <label className=\"mb-1 block text-xs font-medium text-muted-foreground\">Mensagem</label>\n <textarea\n rows={14}\n value={current.body}\n onChange={(e) => setDraft({ ...current, body: e.target.value })}\n className=\"w-full rounded-input border border-input bg-card px-3 py-2 font-mono text-xs leading-relaxed focus:outline-none focus:ring-2 focus:ring-ring\"\n />\n </div>\n {message.channel === 'whatsapp' && (\n <div>\n <p className=\"mb-1.5 text-xs font-medium text-muted-foreground\">\n BotΓ΅es β o cliente responde no toque, sem digitar\n </p>\n <div className=\"space-y-2\">\n {ACTION_CATALOG.map((action) => {\n const active = message.actions.find((a) => a.id === action.id)\n const on = Boolean(active)\n // `pay` Γ© o ΓΊnico que pergunta a alguΓ©m de fora se pode.\n const gated = action.id === 'pay' && !canOfferPayment(readiness)\n const blocked = gated && !readinessLoading\n const labelValue = labelDrafts[action.id] ?? active?.label ?? action.label\n const commitLabel = () => {\n const next = labelValue.trim()\n setLabelDrafts((d) => { const { [action.id]: _, ...rest } = d; return rest })\n if (!active || !next || next === active.label) return\n void patch({\n eventKey: event.name,\n channel: message.channel,\n actions: message.actions.map((a) => (a.id === action.id ? { ...a, label: next } : a)),\n })\n }\n return (\n <div key={action.id} className=\"flex flex-wrap items-center gap-x-3 gap-y-1\">\n <Switch\n size=\"md\"\n checked={on}\n disabled={saving || gated}\n onCheckedChange={(next) => void patch({\n eventKey: event.name,\n channel: message.channel,\n actions: nextActions(message.actions, action.id, next),\n })}\n label={on ? '' : action.label}\n />\n {on && (\n // O texto do botΓ£o como a cliente vΓͺ. 25 caracteres Γ© o\n // teto da Meta para QUICK_REPLY; mudar o texto de um\n // modelo jΓ‘ aprovado dispara nova aprovaΓ§Γ£o β a\n // pastilha de status acima conta essa histΓ³ria.\n <input\n value={labelValue}\n maxLength={25}\n disabled={saving}\n aria-label={`Texto do botΓ£o ${action.label}`}\n onChange={(e) => setLabelDrafts((d) => ({ ...d, [action.id]: e.target.value }))}\n onBlur={commitLabel}\n onKeyDown={(e) => { if (e.key === 'Enter') (e.target as HTMLInputElement).blur() }}\n className=\"w-36 rounded-input border border-input bg-card px-2 py-1 text-sm focus:outline-none focus:ring-2 focus:ring-ring\"\n />\n )}\n <p className=\"text-xs text-muted-foreground\">\n {blocked\n ? 'Para cobrar por aqui, configure a conta de pagamento em Conversas β Tyxter.'\n : action.hint}\n </p>\n </div>\n )\n })}\n </div>\n </div>\n )}\n <div>\n <p className=\"mb-1.5 text-xs font-medium text-muted-foreground\">\n Campos deste evento β o envio substitui pelo dado real\n </p>\n <div className=\"flex flex-wrap gap-1\">\n {message.placeholders.map((p) => (\n <span key={p} className=\"rounded bg-muted px-1.5 py-0.5 font-mono text-[11px] text-muted-foreground\">\n {p}\n </span>\n ))}\n </div>\n </div>\n </Card>\n )}\n </div>\n )\n}\n","import type { UnifiedConnector } from '@fayz-ai/admin'\nimport type { ConnectorDelivery } from '@fayz-ai/core'\n\n// ---------------------------------------------------------------------------\n// As automaΓ§Γ΅es que a INTEGRAΓΓO Γ© dona.\n//\n// A tela de automaΓ§Γ΅es lia uma fonte sΓ³: mensagens. \"Quando um horΓ‘rio Γ©\n// agendado β manda um e-mail\" Γ© uma preferΓͺncia que alguΓ©m escolheu, mora numa\n// linha de `plg_automations_templates` e pode ser apagada. \"Quando um horΓ‘rio Γ©\n// agendado β cria o evento no Google Calendar\" nΓ£o Γ© preferΓͺncia nenhuma: Γ© o\n// que a integraΓ§Γ£o Γ. Por isso Γ© uma SEGUNDA fonte de linhas, e nΓ£o um texto\n// padrΓ£o fingido β um texto padrΓ£o viraria uma linha que o usuΓ‘rio pode apagar,\n// deixando a integraΓ§Γ£o conectada e meio ligada em silΓͺncio.\n//\n// Elas existem sΓ³ enquanto a conexΓ£o estΓ‘ viva. Desconectar Γ© a saΓda, e Γ© a\n// ΓΊnica β o contrato estΓ‘ em ConnectorManagedAutomation (@fayz-ai/core).\n// ---------------------------------------------------------------------------\n\nexport interface ConnectorAutomationRow {\n connectorId: string\n connectorName: string\n /** Onde a integraΓ§Γ£o Γ© configurada β para onde a linha leva. */\n hostPluginId?: string\n /** A cara da integraΓ§Γ£o, resolvida como em qualquer outra tela (ConnectorMark). */\n icon?: string\n logoUrl?: string\n eventKey: string\n label: string\n /** O locatΓ‘rio pode desligar esta e seguir conectado. */\n optional: boolean\n /** Registro a registro: o que chegou no provedor. Ausente = a integraΓ§Γ£o nΓ£o conta. */\n listDeliveries?: (options?: { eventKey?: string; limit?: number }) => Promise<ConnectorDelivery[]>\n}\n\n/** As linhas de automaΓ§Γ£o dos conectores CONECTADOS. Nada dos demais. */\nexport function connectorAutomationRows(connectors: UnifiedConnector[]): ConnectorAutomationRow[] {\n const out: ConnectorAutomationRow[] = []\n for (const connector of connectors) {\n if (connector.state !== 'connected') continue\n for (const auto of connector.definition?.managedAutomations ?? []) {\n out.push({\n connectorId: connector.id,\n connectorName: connector.name,\n hostPluginId: connector.hostPluginId,\n icon: connector.icon,\n logoUrl: connector.logoUrl,\n eventKey: auto.eventKey,\n label: auto.label,\n optional: auto.optional ?? false,\n ...(connector.definition?.listDeliveries\n ? { listDeliveries: connector.definition.listDeliveries.bind(connector.definition) }\n : {}),\n })\n }\n }\n return out\n}\n\n/** Agrupadas por conector: o dono precisa estar escrito em cima das linhas. */\nexport function groupConnectorAutomations(\n rows: ConnectorAutomationRow[],\n): {\n connectorId: string\n connectorName: string\n hostPluginId?: string\n icon?: string\n logoUrl?: string\n items: ConnectorAutomationRow[]\n}[] {\n const groups: ReturnType<typeof groupConnectorAutomations> = []\n for (const row of rows) {\n let group = groups.find((g) => g.connectorId === row.connectorId)\n if (!group) {\n group = {\n connectorId: row.connectorId,\n connectorName: row.connectorName,\n hostPluginId: row.hostPluginId,\n icon: row.icon,\n logoUrl: row.logoUrl,\n items: [],\n }\n groups.push(group)\n }\n group.items.push(row)\n }\n return groups\n}\n","import React from 'react'\nimport { ChevronRight } from 'lucide-react'\nimport { Card } from '@fayz-ai/ui'\nimport { adminNavigateTo, connectorRoute, ConnectorDeliveries, ConnectorMark } from '@fayz-ai/admin'\nimport {\n groupConnectorAutomations,\n type ConnectorAutomationRow,\n} from '../lib/connector-automations'\n\n// ---------------------------------------------------------------------------\n// As linhas que a integraΓ§Γ£o Γ© dona.\n//\n// Sem interruptor e sem lixeira, de propΓ³sito: uma linha apagada deixaria a\n// integraΓ§Γ£o conectada e meio ligada, e semanas depois isso chega como \"o\n// Google Calendar parou de funcionar\". A saΓda Γ© desconectar, e a linha diz\n// isso em texto β nΓ£o em botΓ£o cinza, que se lΓͺ como algo que o usuΓ‘rio poderia\n// consertar (mesmo padrΓ£o de ConnectorDetail β \"faz parte do app\").\n// ---------------------------------------------------------------------------\n\nexport function ConnectorAutomations({ rows }: { rows: ConnectorAutomationRow[] }) {\n if (rows.length === 0) return null\n\n return (\n <>\n {groupConnectorAutomations(rows).map((group) => {\n const href = connectorRoute({ hostPluginId: group.hostPluginId })\n return (\n <div key={group.connectorId} className=\"space-y-3\">\n <p className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n {group.connectorName}\n </p>\n {group.items.map((row) => (\n <AutomationCard\n key={`${group.connectorId}:${row.eventKey}`}\n row={row}\n group={group}\n href={href}\n />\n ))}\n </div>\n )\n })}\n </>\n )\n}\n\n/**\n * Uma linha da integraΓ§Γ£o, e β quando a integraΓ§Γ£o sabe responder β o que de\n * fato chegou lΓ‘.\n *\n * A tela dizia que o gatilho existe. NΓ£o dizia se o pedido subiu, que Γ© a\n * pergunta que alguΓ©m tem depois de cadastrar. As duas metades eram contadas por\n * sistemas diferentes e nenhum conhecia o outro.\n */\nfunction AutomationCard({\n row,\n group,\n href,\n}: {\n row: ConnectorAutomationRow\n group: { connectorId: string; connectorName: string; icon?: string; logoUrl?: string }\n href: string\n}) {\n const [open, setOpen] = React.useState(false)\n\n return (\n <Card className=\"overflow-hidden\">\n <div\n role=\"button\"\n tabIndex={0}\n onClick={() => adminNavigateTo(href)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); adminNavigateTo(href) }\n }}\n className=\"flex cursor-pointer items-start gap-4 p-4 transition-colors hover:bg-muted/30 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {/* A mesma cara que a integraΓ§Γ£o tem em qualquer outra tela: um plugue\n cinza aqui e o logo do Bling na tela de conectores Γ© a mesma coisa\n parecendo duas. */}\n <ConnectorMark\n connector={{\n id: group.connectorId,\n name: group.connectorName,\n icon: group.icon,\n logoUrl: group.logoUrl,\n }}\n size=\"sm\"\n />\n <div className=\"min-w-0 flex-1\">\n <p className=\"font-medium\">{row.label}</p>\n <p className=\"text-sm text-muted-foreground\">\n Quando <code className=\"font-mono text-xs\">{row.eventKey}</code> acontece aqui.\n </p>\n </div>\n <span className=\"shrink-0 pt-0.5 text-right text-xs text-muted-foreground\">\n {row.optional\n ? `Opcional β desligue em ${group.connectorName}`\n : `Ligada pela integraΓ§Γ£o Β· sai ao desconectar ${group.connectorName}`}\n </span>\n </div>\n\n {row.listDeliveries && (\n <>\n <button\n type=\"button\"\n onClick={() => setOpen(!open)}\n aria-expanded={open}\n className=\"flex w-full items-center gap-2 border-t border-border px-4 py-2 text-left transition-colors hover:bg-muted/40\"\n >\n <ChevronRight className={`h-3.5 w-3.5 shrink-0 text-muted-foreground transition-transform ${open ? 'rotate-90' : ''}`} />\n <span className=\"text-xs font-medium\">O que jΓ‘ foi para o {group.connectorName}</span>\n </button>\n {open && (\n <div className=\"border-t border-border p-4\">\n <ConnectorDeliveries\n load={(options) => row.listDeliveries!({ ...options, eventKey: row.eventKey })}\n providerName={group.connectorName}\n />\n </div>\n )}\n </>\n )}\n </Card>\n )\n}\n","import { errorMessage } from '@fayz-ai/core'\nimport React from 'react'\nimport * as LucideIcons from 'lucide-react'\nimport { ChevronRight, Mail, Megaphone, MessageSquare, Receipt, Smartphone, WandSparkles, Zap } from 'lucide-react'\nimport { Card, PageHeaderActions, PageTabs, Switch, toast, WhatsAppIcon } from '@fayz-ai/ui'\nimport {\n adminNavigateTo, useConnectors, askAI, PageActions, RightRailPage, SettingsTabs, useAgentSurface,\n type AgentSurfaceContribution,\n} from '@fayz-ai/admin'\nimport type { PluginAITool } from '@fayz-ai/core'\n\n// ---------------------------------------------------------------------------\n// A lista inteira, entregue ao assistente.\n//\n// Da lista dΓ‘ para fazer as duas coisas que se faz aqui β ligar/desligar e\n// escrever o texto β sem abrir uma por uma, que Γ© a diferenΓ§a entre \"revise as\n// mensagens de pedido\" e catorze cliques. Passa pelo MESMO `store.upsert` do\n// interruptor e do botΓ£o Salvar.\n//\n// `persist` de propΓ³sito, ao contrΓ‘rio da ferramenta da tela de detalhe: aqui o\n// texto vai direto para o registro, sem passar por um editor onde alguΓ©m leia\n// antes. A confirmaΓ§Γ£o obrigatΓ³ria Γ© o que pΓ΅e uma pessoa entre o modelo e uma\n// mensagem que um cliente vai receber.\n// ---------------------------------------------------------------------------\nconst CONFIGURE_TOOL: PluginAITool = {\n id: 'automations.configure',\n name: 'configureAutomation',\n description:\n 'Turns an automation on or off, and/or rewrites its message. Use the `event` and `channel` values exactly as they appear in the surface state. '\n + 'Placeholders must come from that automation\\'s own list β an invented one renders as literal text in a message a customer reads. '\n + 'To review several, call once per automation.',\n icon: 'Zap',\n mode: 'persist',\n execution: { plane: 'client' },\n category: 'Automations',\n parameters: {\n type: 'object',\n properties: {\n event: { type: 'string', description: 'Event key from the surface state.' },\n channel: { type: 'string', description: 'Channel of that automation (email | whatsapp | sms | in_app).' },\n enabled: { type: 'boolean', description: 'Turn it on or off. Omit to leave as is.' },\n subject: { type: 'string', description: 'New subject. Email only.' },\n body: { type: 'string', description: 'New message body.' },\n },\n required: ['event', 'channel'],\n },\n}\nimport { AutomationDetailPage } from './AutomationDetailPage'\nimport { resolveMessages, useOrganizationStoreLike } from '../lib/runtime'\nimport { usePluginRuntimeOptional } from '@fayz-ai/core'\nimport type { MessageChannel, MessageKind, ResolvedMessage } from '@fayz-ai/core'\nimport type { MessageTemplateStore } from '../data/templates'\nimport { connectorAutomationRows } from '../lib/connector-automations'\nimport { ConnectorAutomations } from './ConnectorAutomations'\nimport {\n ProviderTemplateBadge, providerApprovalFor, useProviderTemplates,\n} from './ProviderTemplateStatus'\n\n// ---------------------------------------------------------------------------\n// AutomaΓ§Γ΅es β quando ISTO acontece, mande AQUILO.\n//\n// Cada linha Γ© uma automaΓ§Γ£o inteira: o gatilho Γ esquerda, o canal na\n// pastilha, o interruptor Γ direita. NΓ£o existe \"modelo\" separado do \"fluxo\" β\n// um texto sem gatilho nunca sai, e um fluxo de um passo Γ© o texto com o\n// gatilho escrito na frente.\n//\n// Agrupado por MΓDULO (Loja, CRM, Agenda) e nΓ£o por canal, porque Γ© assim que a\n// pergunta chega: \"o que a gente manda quando um pedido Γ© enviado?\" β e a\n// resposta pode ser um e-mail, um WhatsApp, ou os dois. Separar por canal, como\n// fazia a tela de e-mails, obriga a visitar dois menus para responder isso.\n//\n// Cada linha Γ© um par eventoΓcanal. O evento aparece uma vez, com uma pastilha\n// por canal ofertado: Γ© o desenho que o RD Station e o Kommo usam para nΓ£o\n// esconder que \"confirmaΓ§Γ£o de pedido\" e \"confirmaΓ§Γ£o por WhatsApp\" sΓ£o o mesmo\n// gatilho com duas saΓdas.\n//\n// Duas fontes de linha, e nΓ£o uma: alΓ©m das mensagens, as automaΓ§Γ΅es que uma\n// integraΓ§Γ£o conectada Γ© dona β ../lib/connector-automations.ts diz por quΓͺ.\n// ---------------------------------------------------------------------------\n\n// A porta de IA desta tela, fora do JSX para a aΓ§Γ£o poder ser declarada.\nconst ASK_AI_ACTION = {\n label: 'Criar com IA',\n hint: 'O que revisar nas automaΓ§Γ΅esβ¦',\n intro: {\n role: 'setup' as const,\n persona: 'Redator das automaΓ§Γ΅es',\n pitch: 'Diga o que revisar nas automaΓ§Γ΅es.',\n description:\n 'Vejo todas as automaΓ§Γ΅es deste app, quais estΓ£o ligadas e o texto de cada uma. Posso ligar, desligar e reescrever β em uma ou em vΓ‘rias de uma vez. VocΓͺ confirma cada mudanΓ§a.',\n suggestions: [\n { label: 'Revise as mensagens de pedido no tom da minha marca' },\n { label: 'Ligue as automaΓ§Γ΅es de entrega' },\n { label: 'Deixe as mensagens de WhatsApp mais curtas' },\n ],\n },\n}\n\nconst CHANNEL_ICON: Record<MessageChannel, React.ComponentType<{ className?: string }>> = {\n email: Mail,\n // The brand glyph, not a generic bubble: in a list of channels, WhatsApp\n // is recognized by its mark before its label.\n whatsapp: WhatsAppIcon,\n sms: Smartphone,\n push: MessageSquare,\n webchat: MessageSquare,\n}\n\nconst CHANNEL_LABEL: Record<MessageChannel, string> = {\n email: 'E-mail', whatsapp: 'WhatsApp', sms: 'SMS', push: 'Push', webchat: 'Chat',\n}\n\nconst KIND_TABS: { value: MessageKind | 'all'; label: string; icon: React.ComponentType<{ className?: string }> }[] = [\n { value: 'all', label: 'Todos', icon: Zap },\n { value: 'transactional', label: 'Transacionais', icon: Receipt },\n { value: 'marketing', label: 'Marketing', icon: Megaphone },\n]\n\nconst KIND_HINT: Record<string, string> = {\n all: 'Tudo que o produto sabe enviar, por qualquer canal.',\n transactional: 'Disparados por uma aΓ§Γ£o da pessoa. NΓ£o precisam de opt-in.',\n marketing: 'Iniciativa da empresa. SΓ³ para quem aceitou receber.',\n}\n\nfunction iconFor(name?: string): React.ComponentType<{ className?: string }> {\n if (!name) return Zap\n const icons = LucideIcons as unknown as Record<string, React.ComponentType<{ className?: string }>>\n return icons[name] ?? Zap\n}\n\n/**\n * Qual automaΓ§Γ£o a URL estΓ‘ pedindo. `null` = nenhuma, e a coluna fica com o\n * assistente.\n *\n * A URL continua sendo a verdade mesmo com o detalhe na coluna: Γ© o que faz o\n * link direto funcionar e o botΓ£o voltar do navegador FECHAR o painel em vez de\n * sair da lista.\n */\nfunction readSelection(basePath: string): { eventKey: string; channel: string } | null {\n const hash = window.location.hash.slice(1) || '/'\n if (!hash.startsWith(basePath + '/')) return null\n const [eventKey, channel] = hash.slice(basePath.length + 1).split('/')\n if (!eventKey || !channel) return null\n return { eventKey, channel }\n}\n\nexport function AutomationsList({ store, variant = 'page', basePath = '/automations' }: {\n store: MessageTemplateStore\n /**\n * Onde esta lista mora, e portanto sob que caminho o detalhe abre.\n *\n * A lista pode estar no menu (`/automations`) ou dentro de ConfiguraΓ§Γ΅es\n * (`/settings/automations`) β e o detalhe tem que abrir SOB ela, senΓ£o clicar\n * numa linha dentro de ConfiguraΓ§Γ΅es jogava a pessoa para fora da tela em que\n * ela estava.\n */\n basePath?: string\n /**\n * Onde a lista estΓ‘ montada, e portanto que faixa de abas ela desenha.\n *\n * 'page' a tela Γ© dela: a faixa Γ© a sub-cabeΓ§a do mΓ³dulo, sangra atΓ© as\n * bordas e sua rΓ©gua encontra a barra da shell.\n * 'panel' ela Γ© o conteΓΊdo de uma aba de ConfiguraΓ§Γ΅es, onde a shell jΓ‘\n * escreveu \"β ConfiguraΓ§Γ΅es / AutomaΓ§Γ΅es\". AΓ vale a MESMA faixa dos\n * outros painΓ©is de configuraΓ§Γ£o (Agenda, CRM, FormulΓ‘rios), que\n * comeΓ§a e termina onde o conteΓΊdo comeΓ§a e termina.\n */\n variant?: 'page' | 'panel'\n}) {\n const tenantId = useOrganizationStoreLike()\n // Os eventos vΓͺm do runtime: sΓ³ os plugins ATIVOS anunciam fatos.\n const runtime = usePluginRuntimeOptional()\n const [messages, setMessages] = React.useState<ResolvedMessage[] | null>(null)\n const [kind, setKind] = React.useState<MessageKind | 'all'>('all')\n // A segunda fonte de linhas: as automaΓ§Γ΅es que a integraΓ§Γ£o Γ© dona. Mesmo\n // loader dos conectores β duas leituras seriam duas respostas para \"o Google\n // Calendar estΓ‘ ligado?\". Sem grants e sem catΓ‘logo: nada disso vira linha\n // aqui, e assim a tela nΓ£o faz rede nenhuma.\n const { connectors } = useConnectors({ includeGrants: false, includeCatalog: false })\n const owned = React.useMemo(() => connectorAutomationRows(connectors ?? []), [connectors])\n // O que a Meta respondeu sobre cada modelo de WhatsApp. Uma leitura por tela,\n // e sem ela a lista continua inteira β sΓ³ sem a pastilha.\n const providerTemplates = useProviderTemplates()\n\n // A automaΓ§Γ£o aberta na coluna da direita, lida da URL.\n const [selected, setSelected] = React.useState(() => readSelection(basePath))\n React.useEffect(() => {\n const sync = () => setSelected(readSelection(basePath))\n sync()\n window.addEventListener('hashchange', sync)\n return () => window.removeEventListener('hashchange', sync)\n }, [basePath])\n\n const reload = React.useCallback(async () => {\n // Uma leitura que falha ainda mostra o catΓ‘logo inteiro nos padrΓ΅es: os\n // eventos sΓ£o cΓ³digo, entΓ£o \"sem personalizaΓ§Γ£o\" Γ© um estado vΓ‘lido e\n // completo, nΓ£o uma tela vazia.\n let overrides: Awaited<ReturnType<MessageTemplateStore['list']>> = []\n try {\n overrides = await store.list(tenantId)\n } catch (err) {\n console.warn('[automations] could not load template overrides; showing defaults', err)\n }\n setMessages(resolveMessages(overrides, runtime?.events ?? []))\n }, [store, tenantId, runtime])\n\n React.useEffect(() => { void reload() }, [reload])\n\n // --- assistant surface ---------------------------------------------------\n const surfaceRef = React.useRef({ messages, store, tenantId, reload, basePath })\n surfaceRef.current = { messages, store, tenantId, reload, basePath }\n\n const agentSurface = React.useMemo<AgentSurfaceContribution>(() => ({\n id: 'automations.list',\n pluginId: 'automations',\n instructions:\n 'The user is on the automations list. `automations` in the surface state is the complete set β use each entry\\'s `event` and `channel` verbatim, and each entry\\'s own `placeholders` when rewriting its text. '\n + 'Call configureAutomation once per automation you change; say afterwards which ones you touched.',\n describe: () => {\n const o = surfaceRef.current\n return {\n title: 'AutomaΓ§Γ΅es',\n state: {\n automations: (o.messages ?? []).map((m) => ({\n event: m.event.name,\n title: m.event.title,\n channel: m.channel,\n enabled: m.enabled,\n customized: Boolean(m.customized),\n subject: m.subject,\n body: m.body,\n // `fields` Γ© o contrato do evento β os mesmos descritores que viram\n // as merge fields do editor. Γ de lΓ‘ que saem os placeholders.\n placeholders: (m.event.fields ?? []).map((f) => `{{${f.name}}}`),\n })),\n },\n }\n },\n tools: [{\n tool: CONFIGURE_TOOL,\n execute: async (args: Record<string, unknown>) => {\n const o = surfaceRef.current\n const found = (o.messages ?? []).find(\n (m) => m.event.name === args.event && m.channel === args.channel,\n )\n if (!found) {\n return {\n ok: false,\n error: 'unknown_automation',\n available: (o.messages ?? []).map((m) => `${m.event.name}/${m.channel}`),\n }\n }\n try {\n await o.store.upsert({\n eventKey: found.event.name,\n channel: found.channel,\n ...(args.enabled === undefined ? {} : { enabled: Boolean(args.enabled) }),\n ...(args.subject === undefined ? {} : { subject: String(args.subject) }),\n ...(args.body === undefined ? {} : { body: String(args.body) }),\n }, o.tenantId)\n await o.reload()\n // `ref.path` decorates the reply with a goto chip (RecordChip) β the\n // user lands on what the agent just changed. `path`, not archetype:\n // an automation is a settings destination, not a record.\n return {\n ok: true,\n event: found.event.name,\n channel: found.channel,\n ref: {\n id: `${found.event.name}/${found.channel}`,\n label: `${found.event.title ?? found.event.name} β ${CHANNEL_LABEL[found.channel] ?? found.channel}`,\n path: `${o.basePath}/${encodeURIComponent(found.event.name)}/${found.channel}`,\n },\n }\n } catch (e) {\n return { ok: false, error: errorMessage(e) }\n }\n },\n }],\n }), [])\n useAgentSurface(agentSurface)\n\n const toggle = async (m: ResolvedMessage, enabled: boolean) => {\n setMessages((prev) => prev?.map((x) =>\n x.event.name === m.event.name && x.channel === m.channel ? { ...x, enabled } : x) ?? null)\n try {\n await store.upsert({ eventKey: m.event.name, channel: m.channel, enabled }, tenantId)\n await reload()\n } catch (err) {\n console.warn('[automations] toggle failed', err)\n toast.error('NΓ£o foi possΓvel salvar')\n await reload()\n }\n }\n\n const visible = (messages ?? []).filter((m) => kind === 'all' || m.kind === kind)\n // As linhas do conector nΓ£o sΓ£o mensagens, entΓ£o nΓ£o tΓͺm \"kind\" β aparecem na\n // aba Todos. Contam no total porque estΓ£o rodando: omiti-las faria o contador\n // dizer menos automaΓ§Γ΅es ativas do que o negΓ³cio tem.\n const ownedVisible = kind === 'all' ? owned : []\n const activeCount = (messages ?? []).filter((m) => m.enabled).length + owned.length\n const totalCount = (messages?.length ?? 0) + owned.length\n\n // Agrupa por mΓ³dulo preservando a ordem de registro dos plugins.\n const groups: { module: string; label: string; items: ResolvedMessage[] }[] = []\n for (const m of visible) {\n let g = groups.find((x) => x.module === m.event.pluginId)\n if (!g) { g = { module: m.event.pluginId, label: m.event.pluginName, items: [] }; groups.push(g) }\n g.items.push(m)\n }\n\n const counter = messages !== null && (\n <span className=\"text-sm text-muted-foreground\">\n {activeCount} de {totalCount} automaΓ§Γ΅es ativas\n </span>\n )\n\n return (\n <div className=\"space-y-6\">\n {/* Declarado, nΓ£o desenhado: o <AskAIButton> cru ficava no cabeΓ§alho no\n celular, onde toda outra tela jΓ‘ entrega a aΓ§Γ£o ao polegar. */}\n {variant !== 'panel' ? (\n <PageHeaderActions>\n <PageActions\n actions={[{\n id: 'automations-ai',\n label: ASK_AI_ACTION.label,\n icon: WandSparkles,\n intent: 'primary',\n creates: true,\n onSelect: () => askAI({ hint: ASK_AI_ACTION.hint, intro: ASK_AI_ACTION.intro }),\n }]}\n />\n </PageHeaderActions>\n ) : null}\n\n {variant === 'panel' ? (\n <SettingsTabs\n tabs={KIND_TABS.map((t) => ({ id: t.value, label: t.label, IconComp: t.icon }))}\n value={kind}\n onChange={(id) => setKind(id as MessageKind | 'all')}\n aria-label=\"AutomaΓ§Γ΅es\"\n actions={counter}\n />\n ) : (\n /* Mesma faixa das listas e da sub-nav de mΓ³dulo. */\n <PageTabs\n className=\"mb-0\"\n tabs={KIND_TABS.map((t) => ({ value: t.value, label: t.label, icon: t.icon }))}\n value={kind}\n onChange={setKind}\n aria-label=\"AutomaΓ§Γ΅es\"\n actions={counter}\n />\n )}\n\n <p className=\"text-sm text-muted-foreground\">{KIND_HINT[kind]}</p>\n\n {messages === null ? (\n <div className=\"space-y-3\">\n {Array.from({ length: 4 }).map((_, i) => (\n <Card key={i} className=\"p-4\">\n <div className=\"h-4 w-40 animate-pulse rounded bg-muted\" />\n <div className=\"mt-2 h-3 w-64 animate-pulse rounded bg-muted\" />\n </Card>\n ))}\n </div>\n ) : groups.length === 0 && ownedVisible.length === 0 ? (\n <Card className=\"flex flex-col items-center gap-1 p-12 text-center\">\n <Zap className=\"mb-2 h-9 w-9 text-muted-foreground/40\" strokeWidth={1.5} />\n <p className=\"text-base font-semibold\">Nenhuma automaΓ§Γ£o nesta aba</p>\n <p className=\"max-w-sm text-sm text-muted-foreground\">\n Os eventos vΓͺm dos mΓ³dulos instalados β a loja traz os do pedido, o CRM os do funil.\n </p>\n </Card>\n ) : groups.map((group) => (\n <div key={group.module} className=\"space-y-3\">\n <p className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n {group.label}\n </p>\n {group.items.map((m) => {\n const Icon = iconFor(m.event.icon ?? m.event.pluginIcon)\n const ChannelIcon = CHANNEL_ICON[m.channel]\n const href = `${basePath}/${encodeURIComponent(m.event.name)}/${m.channel}`\n // A linha cujo detalhe estΓ‘ aberto na coluna ao lado. Sem a marca,\n // com o rail aberto a lista nΓ£o diz de QUEM ele fala.\n const isOpen = selected != null\n && decodeURIComponent(selected.eventKey) === m.event.name\n && selected.channel === m.channel\n return (\n <Card\n key={`${m.event.name}:${m.channel}`}\n role=\"button\"\n tabIndex={0}\n aria-current={isOpen || undefined}\n onClick={() => adminNavigateTo(href)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); adminNavigateTo(href) }\n }}\n // Outline, not border/ring: the glass surface forces the card's\n // border-color to transparent and owns its box-shadow, so both\n // utilities are silently defeated there. Outline is the one\n // edge the glass system does not touch, and inline style keeps\n // it out of Tailwind's content-scan lottery.\n style={isOpen ? { outline: '2px solid hsl(var(--primary) / 0.65)', outlineOffset: '-2px' } : undefined}\n className={`cursor-pointer overflow-hidden transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-ring ${\n isOpen ? '' : 'hover:border-primary/40'\n }`}\n >\n <div className=\"flex items-start gap-4 p-4\">\n <span className=\"flex h-9 w-9 shrink-0 items-center justify-center rounded-lg border border-border text-muted-foreground\">\n <Icon className=\"h-4 w-4\" />\n </span>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <p className=\"font-medium\">{m.override?.name ?? m.event.title ?? m.event.name}</p>\n <span className=\"inline-flex items-center gap-1 rounded-full bg-muted px-2 py-0.5 text-[11px] text-muted-foreground\">\n <ChannelIcon className=\"h-3 w-3\" />\n {CHANNEL_LABEL[m.channel]}\n </span>\n {m.customized && (\n <span className=\"rounded-full bg-primary/10 px-2 py-0.5 text-[11px] text-primary\">\n personalizado\n </span>\n )}\n {/* Ligado nΓ£o quer dizer que vai sair: no WhatsApp a Meta\n ainda precisa aprovar o modelo. */}\n <ProviderTemplateBadge\n approval={providerApprovalFor(providerTemplates, m.event.name, m.channel)}\n />\n </div>\n <p className=\"text-sm text-muted-foreground\">{m.event.description}</p>\n <div className=\"mt-2 flex flex-wrap items-center gap-x-4 gap-y-1 text-xs text-muted-foreground\">\n <span className=\"inline-flex items-center gap-1\">\n <Zap className=\"h-3 w-3\" />\n {m.event.trigger}\n </span>\n {m.subject && <span className=\"truncate\">Assunto: {m.subject}</span>}\n </div>\n </div>\n <div className=\"flex shrink-0 items-center gap-3\">\n {/* Switch e nΓ£o checkbox: isto vale na hora, nΓ£o quando\n algum Salvar for clicado. */}\n <Switch\n checked={m.enabled}\n onCheckedChange={(next) => void toggle(m, next)}\n label={m.enabled ? 'Ativo' : 'Inativo'}\n aria-label={`${m.event.title} β ${CHANNEL_LABEL[m.channel]}`}\n />\n <ChevronRight className=\"h-4 w-4 text-muted-foreground\" />\n </div>\n </div>\n </Card>\n )\n })}\n </div>\n ))}\n\n {messages !== null && <ConnectorAutomations rows={ownedVisible} />}\n\n {/* O detalhe abre AO LADO da lista, nΓ£o no lugar dela: escolher o que uma\n automaΓ§Γ£o diz Γ© olhar as outras que jΓ‘ existem, e a tela cheia tirava\n exatamente isso de vista. O nome sai da linha que jΓ‘ estΓ‘ carregada β\n a coluna se nomeia antes de o detalhe terminar de carregar. */}\n {selected && (\n <RightRailPage\n title={\n (messages ?? []).find(\n (m) => m.event.name === decodeURIComponent(selected.eventKey) && m.channel === selected.channel,\n )?.event.title ?? 'AutomaΓ§Γ£o'\n }\n open\n onClose={() => adminNavigateTo(basePath)}\n width=\"max-w-2xl\"\n >\n <div className=\"min-h-0 flex-1 overflow-y-auto p-4\">\n <AutomationDetailPage\n eventKey={selected.eventKey}\n channel={selected.channel}\n store={store}\n backTo={basePath}\n embedded\n />\n </div>\n </RightRailPage>\n )}\n </div>\n )\n}\n","import { getSupabaseClientOptional, normalizeMessageActions } from '@fayz-ai/core'\nimport type { MessageTemplate, UpsertMessageTemplateInput } from '@fayz-ai/core'\n\n// ---------------------------------------------------------------------------\n// Acesso aos modelos personalizados. SΓ³ as PERSONALIZAΓΓES: o catΓ‘logo Γ©\n// cΓ³digo, e uma leitura que falha ainda deve mostrar a lista inteira nos\n// padrΓ΅es β ver `resolveMessages`.\n// ---------------------------------------------------------------------------\n\nconst TABLE = 'plg_automations_templates'\n\nfunction rowToTemplate(row: any): MessageTemplate {\n return {\n id: row.id,\n tenantId: row.tenant_id,\n eventKey: row.event_key,\n channel: row.channel ?? 'email',\n // NULL fica NULL: quem decide o padrΓ£o Γ© o catΓ‘logo, nΓ£o este mapeamento.\n // Colapsar para `false` aqui desligaria em silΓͺncio todo modelo cuja linha\n // sΓ³ existe porque o texto foi editado.\n enabled: row.enabled ?? null,\n // String vazia e NULL significam a mesma coisa β \"sem personalizaΓ§Γ£o\" β,\n // senΓ£o um assunto apagado sairia em branco em vez de voltar ao padrΓ£o.\n subject: row.subject || null,\n body: row.body || null,\n name: row.name || null,\n // NULL fica NULL pelo mesmo motivo do `enabled`; lista vazia Γ© uma escolha\n // (\"sem botΓ΅es\"), nΓ£o a ausΓͺncia de uma.\n actions: normalizeMessageActions(row.actions),\n updatedAt: row.updated_at ?? row.created_at,\n }\n}\n\nexport interface MessageTemplateStore {\n list(tenantId?: string): Promise<MessageTemplate[]>\n upsert(input: UpsertMessageTemplateInput, tenantId?: string): Promise<MessageTemplate>\n /** Descarta a personalizaΓ§Γ£o inteira β a linha some e o padrΓ£o volta a valer. */\n reset(eventKey: string, channel: string, tenantId?: string): Promise<void>\n}\n\nexport function createSupabaseTemplateStore(): MessageTemplateStore {\n const db = () => {\n const client = getSupabaseClientOptional()\n if (!client) throw new Error('@fayz-ai/plugin-automations: Supabase client not initialized')\n return client as any\n }\n\n return {\n async list(tenantId) {\n let q = db().from(TABLE).select('*')\n if (tenantId) q = q.eq('tenant_id', tenantId)\n const { data, error } = await q\n if (error) throw error\n return (data ?? []).map(rowToTemplate)\n },\n\n async upsert(input, tenantId) {\n const payload: Record<string, unknown> = {\n tenant_id: tenantId,\n event_key: input.eventKey,\n channel: input.channel,\n }\n // SΓ³ o que veio: omitir uma chave tem de significar \"nΓ£o mexa nisso\",\n // senΓ£o salvar o texto apagaria o ligado/desligado junto.\n if (input.enabled !== undefined) payload.enabled = input.enabled\n if (input.subject !== undefined) payload.subject = input.subject\n if (input.body !== undefined) payload.body = input.body\n if (input.name !== undefined) payload.name = input.name\n if (input.actions !== undefined) payload.actions = input.actions\n\n const { data, error } = await db()\n .from(TABLE)\n .upsert(payload, { onConflict: 'tenant_id,event_key,channel' })\n .select().single()\n if (error) throw error\n return rowToTemplate(data)\n },\n\n async reset(eventKey, channel, tenantId) {\n let q = db().from(TABLE).delete().eq('event_key', eventKey).eq('channel', channel)\n if (tenantId) q = q.eq('tenant_id', tenantId)\n const { error } = await q\n if (error) throw error\n },\n }\n}\n","import React from 'react'\nimport { Workflow } from 'lucide-react'\nimport {\n Modal, ModalContent, ModalHeader, ModalTitle, ModalBody, ModalFooter,\n Button, Input,\n Select, SelectTrigger, SelectValue, SelectContent, SelectItem,\n toast,\n} from '@fayz-ai/ui'\nimport { errorMessage, useTranslation, usePluginRuntimeOptional } from '@fayz-ai/core'\n\n// ---------------------------------------------------------------------------\n// Nova cadΓͺncia.\n//\n// Era `window.prompt` duas vezes β uma para o nome e outra pedindo que se\n// DIGITASSE `crm.lead_created`. Quem nΓ£o conhece o catΓ‘logo de eventos nΓ£o tem\n// como acertar, e errar nΓ£o dΓ‘ erro: cria um fluxo que espera por um fato que\n// nunca chega, e o ecrΓ£ fica mostrando uma cadΓͺncia ativa com zero pessoas.\n//\n// As trΓͺs perguntas que definem uma cadΓͺncia, e nenhuma a mais:\n//\n// QUEM ENTRA um fato do catΓ‘logo (sΓ³ os plugins ativos anunciam fatos),\n// escolhido numa lista β nΓ£o digitado.\n// QUEM SAI o fato que faz alguΓ©m parar de receber. Γ o campo que\n// separa uma rΓ©gua de uma perseguiΓ§Γ£o: sem ele, quem jΓ‘\n// respondeu continua recebendo a mensagem do dia 5.\n// COMO SE CHAMA para o operador achar de novo.\n//\n// Os passos NΓO entram aqui. Uma cadΓͺncia nasce vazia e desligada, e os passos\n// se montam na tabela do painel, onde se vΓͺ o que cada um jΓ‘ enviou. Um\n// formulΓ‘rio que pedisse nome, gatilho, saΓda e trΓͺs mensagens de uma vez seria\n// abandonado no terceiro campo.\n// ---------------------------------------------------------------------------\n\nexport function CadenceComposer({ open, onClose, onCreate }: {\n open: boolean\n onClose: () => void\n onCreate: (input: { name: string; entryEvent: string; exitEvents: string[] }) => Promise<void>\n}) {\n const t = useTranslation()\n const runtime = usePluginRuntimeOptional()\n // SΓ³ os plugins ATIVOS anunciam fatos: oferecer um gatilho de um mΓ³dulo que\n // nΓ£o estΓ‘ montado Γ© prometer uma cadΓͺncia que nunca dispara.\n const events = runtime?.events ?? []\n\n const [name, setName] = React.useState('')\n const [entryEvent, setEntryEvent] = React.useState('')\n const [exitEvent, setExitEvent] = React.useState('')\n const [saving, setSaving] = React.useState(false)\n\n React.useEffect(() => {\n if (!open) return\n setName(''); setExitEvent('')\n setEntryEvent(events.find((e) => e.name === 'crm.lead_created')?.name ?? events[0]?.name ?? '')\n }, [open])\n\n const entry = events.find((e) => e.name === entryEvent)\n\n async function submit() {\n if (!name.trim() || !entryEvent || saving) return\n setSaving(true)\n try {\n await onCreate({\n name: name.trim(),\n entryEvent,\n exitEvents: exitEvent ? [exitEvent] : [],\n })\n onClose()\n } catch (e) {\n toast.error(errorMessage(e))\n } finally {\n setSaving(false)\n }\n }\n\n return (\n <Modal open={open} onOpenChange={(o) => { if (!o) onClose() }}>\n <ModalContent size=\"md\">\n <ModalHeader>\n <ModalTitle>{t('automations.flow.newTitle')}</ModalTitle>\n </ModalHeader>\n <ModalBody className=\"space-y-4\">\n <label className=\"block space-y-1.5\">\n <span className=\"text-sm font-medium text-foreground\">{t('automations.flow.nameLabel')}</span>\n <Input value={name} onChange={(e) => setName(e.target.value)} placeholder={t('automations.flow.namePlaceholder')} />\n </label>\n\n <label className=\"block space-y-1.5\">\n <span className=\"text-sm font-medium text-foreground\">{t('automations.flow.entryLabel')}</span>\n {events.length > 0 ? (\n <Select value={entryEvent} onValueChange={setEntryEvent}>\n <SelectTrigger><SelectValue placeholder={t('automations.flow.entryPlaceholder')} /></SelectTrigger>\n <SelectContent>\n {events.map((e) => <SelectItem key={e.name} value={e.name}>{e.title ?? e.name}</SelectItem>)}\n </SelectContent>\n </Select>\n ) : (\n <p className=\"rounded-lg border border-dashed px-3 py-2 text-xs text-muted-foreground\">\n {t('automations.flow.noEvents')}\n </p>\n )}\n {entry?.trigger && <span className=\"text-[11px] text-muted-foreground\">{entry.trigger}</span>}\n </label>\n\n <label className=\"block space-y-1.5\">\n <span className=\"text-sm font-medium text-foreground\">{t('automations.flow.exitLabel')}</span>\n <Select value={exitEvent || '__none__'} onValueChange={(v) => setExitEvent(v === '__none__' ? '' : v)}>\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n <SelectItem value=\"__none__\">{t('automations.flow.exitNone')}</SelectItem>\n {events.filter((e) => e.name !== entryEvent).map((e) => (\n <SelectItem key={e.name} value={e.name}>{e.title ?? e.name}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n <span className=\"text-[11px] text-muted-foreground\">{t('automations.flow.exitHint')}</span>\n </label>\n\n <p className=\"flex items-start gap-2 rounded-lg bg-muted/40 px-3 py-2 text-[11px] text-muted-foreground\">\n <Workflow className=\"mt-0.5 h-3.5 w-3.5 shrink-0\" />\n {t('automations.flow.bornOffHint')}\n </p>\n </ModalBody>\n <ModalFooter>\n <Button variant=\"outline\" onClick={onClose}>{t('common.cancel')}</Button>\n <Button onClick={() => { void submit() }} disabled={saving || !name.trim() || !entryEvent}>\n {t('automations.flow.create')}\n </Button>\n </ModalFooter>\n </ModalContent>\n </Modal>\n )\n}\n","import { getSupabaseClientOptional, getActiveTenantId } from '@fayz-ai/core'\n\n// ---------------------------------------------------------------------------\n// Cadence flows: the rows behind \"day 0 message, day 2 call, day 5 message\".\n//\n// Read and write only. The ENGINE is SQL β `automations_flows_run_due` on the\n// minute tick β and nothing here advances an enrolment. That split is the point:\n// a cadence that depended on a browser being open would stop at 6pm.\n//\n// Enrolments are read-only by policy too (the operator leaves a flow through\n// `automations_flow_exit`, never by editing a pointer), so this module exposes\n// no write for them.\n// ---------------------------------------------------------------------------\n\nconst FLOWS = 'plg_automations_flows'\nconst STEPS = 'plg_automations_flow_steps'\nconst ENROLLMENTS = 'plg_automations_enrollments'\nconst STEP_STATS = 'v_automations_flow_steps'\n\nexport interface CadenceFlow {\n id: string\n tenantId: string\n name: string\n description: string | null\n /** The event that puts somebody in, e.g. `crm.lead_created`. */\n entryEvent: string\n /** Events that take somebody out. Empty means \"only ends by running out\". */\n exitEvents: string[]\n isActive: boolean\n createdAt: string\n updatedAt: string\n}\n\nexport type CadenceStepKind = 'message' | 'task'\n\nexport interface CadenceStep {\n id: string\n flowId: string\n position: number\n /** Minutes to wait AFTER THE PREVIOUS STEP β not since enrolment. */\n delayMinutes: number\n kind: CadenceStepKind\n templateKey: string | null\n /** NULL lets the recipient's own preference choose. */\n channel: string | null\n taskTitle: string | null\n taskDueDays: number | null\n}\n\n/** A step plus what actually happened on it. Per step, never per flow: the\n * question a cadence is judged by is WHERE people stop. */\nexport interface CadenceStepStats extends CadenceStep {\n queued: number\n sent: number\n blocked: number\n failed: number\n cancelled: number\n}\n\nexport interface FlowCounts {\n active: number\n completed: number\n exited: number\n}\n\nexport interface CadenceFlowStore {\n listFlows(): Promise<CadenceFlow[]>\n saveFlow(input: Partial<CadenceFlow> & { name: string; entryEvent: string }): Promise<CadenceFlow>\n setFlowActive(id: string, isActive: boolean): Promise<void>\n deleteFlow(id: string): Promise<void>\n listSteps(flowId: string): Promise<CadenceStepStats[]>\n saveStep(flowId: string, input: Partial<CadenceStep>): Promise<void>\n deleteStep(id: string): Promise<void>\n countsFor(flowId: string): Promise<FlowCounts>\n}\n\nfunction rowToFlow(r: any): CadenceFlow {\n return {\n id: r.id,\n tenantId: r.tenant_id,\n name: r.name,\n description: r.description ?? null,\n entryEvent: r.entry_event,\n exitEvents: Array.isArray(r.exit_events) ? r.exit_events : [],\n isActive: r.is_active === true,\n createdAt: r.created_at,\n updatedAt: r.updated_at ?? r.created_at,\n }\n}\n\nfunction rowToStepStats(r: any): CadenceStepStats {\n return {\n id: r.step_id ?? r.id,\n flowId: r.flow_id,\n position: r.position,\n delayMinutes: r.delay_minutes ?? 0,\n kind: (r.kind === 'task' ? 'task' : 'message'),\n templateKey: r.template_key ?? null,\n channel: r.channel ?? null,\n taskTitle: r.task_title ?? null,\n taskDueDays: r.task_due_days ?? null,\n queued: Number(r.queued ?? 0),\n sent: Number(r.sent ?? 0),\n blocked: Number(r.blocked ?? 0),\n failed: Number(r.failed ?? 0),\n cancelled: Number(r.cancelled ?? 0),\n }\n}\n\n/**\n * Sparse positions (10, 20, 30β¦) so that inserting a step between two others\n * does not renumber the ones after it β an enrolment's pointer names a\n * position, and renumbering would move people to a step they already had.\n */\nexport function nextPosition(steps: Array<{ position: number }>): number {\n if (steps.length === 0) return 10\n return Math.max(...steps.map((s) => s.position)) + 10\n}\n\n/** Minutes as a salesperson says them. 2880 is \"2 days\", not \"two thousand\". */\nexport function describeDelay(minutes: number, t: (k: string, v?: Record<string, string>) => string): string {\n if (minutes <= 0) return t('automations.flow.delayNow')\n if (minutes % 1440 === 0) return t('automations.flow.delayDays', { count: String(minutes / 1440) })\n if (minutes % 60 === 0) return t('automations.flow.delayHours', { count: String(minutes / 60) })\n return t('automations.flow.delayMinutes', { count: String(minutes) })\n}\n\nexport function createSupabaseFlowStore(): CadenceFlowStore {\n function client() {\n const supabase = getSupabaseClientOptional() as any\n if (!supabase) throw new Error('Supabase not initialized')\n return supabase\n }\n\n const store: CadenceFlowStore = {\n async listFlows() {\n const { data, error } = await client().from(FLOWS).select('*').order('name')\n if (error) throw new Error(error.message)\n return (data ?? []).map(rowToFlow)\n },\n\n async saveFlow(input) {\n const row: any = {\n name: input.name,\n description: input.description ?? null,\n entry_event: input.entryEvent,\n exit_events: input.exitEvents ?? [],\n }\n if (input.id) {\n const { data, error } = await client().from(FLOWS).update(row).eq('id', input.id).select().single()\n if (error) throw new Error(error.message)\n return rowToFlow(data)\n }\n row.tenant_id = getActiveTenantId()\n // A new flow is born INACTIVE. `is_active` defaults false in the table and\n // is not set here on purpose: a cadence that starts sending the moment\n // somebody saves a draft is a cadence that sends a draft.\n const { data, error } = await client().from(FLOWS).insert(row).select().single()\n if (error) throw new Error(error.message)\n return rowToFlow(data)\n },\n\n async setFlowActive(id, isActive) {\n const { error } = await client().from(FLOWS)\n .update({ is_active: isActive, updated_at: new Date().toISOString() }).eq('id', id)\n if (error) throw new Error(error.message)\n },\n\n async deleteFlow(id) {\n const { error } = await client().from(FLOWS).delete().eq('id', id)\n if (error) throw new Error(error.message)\n },\n\n async listSteps(flowId) {\n // The stats view, not the table: the numbers are the reason to look.\n const { data, error } = await client().from(STEP_STATS)\n .select('*').eq('flow_id', flowId).order('position')\n if (error) throw new Error(error.message)\n return (data ?? []).map(rowToStepStats)\n },\n\n async saveStep(flowId, input) {\n const row: any = {\n flow_id: flowId,\n position: input.position,\n delay_minutes: input.delayMinutes ?? 0,\n kind: input.kind ?? 'message',\n template_key: input.kind === 'task' ? null : (input.templateKey ?? null),\n channel: input.kind === 'task' ? null : (input.channel ?? null),\n task_title: input.kind === 'task' ? (input.taskTitle ?? null) : null,\n task_due_days: input.kind === 'task' ? (input.taskDueDays ?? null) : null,\n }\n if (input.id) {\n const { error } = await client().from(STEPS).update(row).eq('id', input.id)\n if (error) throw new Error(error.message)\n return\n }\n row.tenant_id = getActiveTenantId()\n const { error } = await client().from(STEPS).insert(row)\n if (error) throw new Error(error.message)\n },\n\n async deleteStep(id) {\n const { error } = await client().from(STEPS).delete().eq('id', id)\n if (error) throw new Error(error.message)\n },\n\n async countsFor(flowId) {\n const { data, error } = await client().from(ENROLLMENTS).select('status').eq('flow_id', flowId)\n if (error) throw new Error(error.message)\n const rows = (data ?? []) as Array<{ status: string }>\n return {\n active: rows.filter((r) => r.status === 'active').length,\n completed: rows.filter((r) => r.status === 'completed').length,\n exited: rows.filter((r) => r.status === 'exited').length,\n }\n },\n }\n\n return store\n}\n","import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { ChevronRight, Clock, ListChecks, Loader2, MessageSquare, Plus, Trash2 } from 'lucide-react'\nimport { Card, DataTable, PageHeaderActions, Switch, toast } from '@fayz-ai/ui'\nimport { CadenceComposer } from './CadenceComposer'\nimport { PageActions } from '@fayz-ai/admin'\nimport { errorMessage, useTranslation } from '@fayz-ai/core'\nimport {\n createSupabaseFlowStore, describeDelay, nextPosition,\n type CadenceFlow, type CadenceStepStats, type FlowCounts,\n} from '../data/flows'\n\n// ---------------------------------------------------------------------------\n// Cadence flows.\n//\n// The list answers \"what is running\"; the panel answers \"where do people stop\".\n// Those are the only two questions a cadence screen has to answer, and the\n// second one is why the step table carries the numbers instead of a chart\n// somewhere else: the third message being the one nobody answers is a fact\n// about a ROW, and it belongs next to the row.\n//\n// Nothing here advances a cadence. The engine is `automations_flows_run_due` on\n// the minute tick β a cadence that needed this page open would stop at 6pm.\n// ---------------------------------------------------------------------------\n\nconst store = createSupabaseFlowStore()\n\n/** The delays a cadence is actually built from, in minutes. */\nconst DELAY_CHOICES = [0, 60, 1440, 2880, 4320, 10080]\n\nfunction useStepColumns(onDelete: (id: string) => void): ColumnDef<CadenceStepStats, any>[] {\n const t = useTranslation()\n return useMemo(() => [\n {\n accessorKey: 'position', header: '#',\n cell: ({ getValue }) => <span className=\"text-xs tabular-nums text-muted-foreground\">{getValue() as number}</span>,\n },\n {\n id: 'step', header: t('automations.flow.colStep'),\n cell: ({ row }) => {\n const s = row.original\n const isTask = s.kind === 'task'\n return (\n <span className=\"inline-flex items-center gap-1.5 text-sm\">\n {isTask ? <ListChecks className=\"h-3.5 w-3.5 text-muted-foreground\" />\n : <MessageSquare className=\"h-3.5 w-3.5 text-muted-foreground\" />}\n {isTask ? s.taskTitle : s.templateKey}\n {!isTask && s.channel && (\n <span className=\"rounded bg-muted px-1.5 py-0.5 text-[10px] text-muted-foreground\">{s.channel}</span>\n )}\n </span>\n )\n },\n },\n {\n accessorKey: 'delayMinutes', header: t('automations.flow.colWait'),\n cell: ({ getValue }) => (\n <span className=\"inline-flex items-center gap-1 text-xs text-muted-foreground\">\n <Clock className=\"h-3 w-3\" />{describeDelay(getValue() as number, t)}\n </span>\n ),\n },\n // The scoreboard. Zeroes are shown rather than hidden: a step that has never\n // sent is the finding, not an empty cell.\n {\n accessorKey: 'queued', header: t('automations.flow.colQueued'),\n cell: ({ getValue }) => <span className=\"text-xs tabular-nums\">{getValue() as number}</span>,\n },\n {\n accessorKey: 'sent', header: t('automations.flow.colSent'),\n cell: ({ getValue }) => <span className=\"text-xs tabular-nums\">{getValue() as number}</span>,\n },\n {\n accessorKey: 'blocked', header: t('automations.flow.colBlocked'),\n cell: ({ getValue }) => {\n const n = getValue() as number\n return <span className={`text-xs tabular-nums ${n > 0 ? 'text-warning' : ''}`}>{n}</span>\n },\n },\n {\n accessorKey: 'failed', header: t('automations.flow.colFailed'),\n cell: ({ getValue }) => {\n const n = getValue() as number\n return <span className={`text-xs tabular-nums ${n > 0 ? 'text-destructive' : ''}`}>{n}</span>\n },\n },\n {\n id: 'actions', header: '',\n cell: ({ row }) => (\n <div className=\"flex justify-end\">\n <button\n onClick={(e) => { e.stopPropagation(); onDelete(row.original.id) }}\n title={t('automations.flow.deleteStep')}\n className=\"inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-destructive\"\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n ),\n },\n ], [t, onDelete])\n}\n\nfunction StepComposer({ steps, onAdd }: {\n steps: CadenceStepStats[]\n onAdd: (input: { kind: 'message' | 'task'; delayMinutes: number; templateKey?: string; channel?: string; taskTitle?: string; position: number }) => void\n}) {\n const t = useTranslation()\n const [kind, setKind] = useState<'message' | 'task'>('message')\n const [delay, setDelay] = useState(1440)\n const [value, setValue] = useState('')\n\n const submit = () => {\n if (!value.trim()) {\n toast.error(t(kind === 'task' ? 'automations.flow.needTitle' : 'automations.flow.needTemplate'))\n return\n }\n onAdd({\n kind, delayMinutes: delay, position: nextPosition(steps),\n ...(kind === 'task' ? { taskTitle: value.trim() } : { templateKey: value.trim() }),\n })\n setValue('')\n }\n\n return (\n <div className=\"mt-3 flex flex-wrap items-center gap-2 rounded-lg border border-dashed p-3\">\n <select\n value={kind}\n onChange={(e) => { setKind(e.target.value as 'message' | 'task'); setValue('') }}\n className=\"rounded-md border bg-background px-2 py-1.5 text-sm\"\n >\n <option value=\"message\">{t('automations.flow.kindMessage')}</option>\n <option value=\"task\">{t('automations.flow.kindTask')}</option>\n </select>\n <select\n value={delay}\n onChange={(e) => setDelay(Number(e.target.value))}\n className=\"rounded-md border bg-background px-2 py-1.5 text-sm\"\n >\n {DELAY_CHOICES.map((m) => (\n <option key={m} value={m}>{describeDelay(m, t)}</option>\n ))}\n </select>\n <input\n value={value}\n onChange={(e) => setValue(e.target.value)}\n onKeyDown={(e) => { if (e.key === 'Enter') submit() }}\n placeholder={t(kind === 'task' ? 'automations.flow.titlePlaceholder' : 'automations.flow.templatePlaceholder')}\n className=\"min-w-[200px] flex-1 rounded-md border bg-background px-2 py-1.5 text-sm\"\n />\n <button\n onClick={submit}\n className=\"inline-flex items-center gap-1 rounded-md bg-primary px-3 py-1.5 text-sm text-primary-foreground hover:opacity-90\"\n >\n <Plus className=\"h-3.5 w-3.5\" />{t('automations.flow.addStep')}\n </button>\n </div>\n )\n}\n\nexport function FlowsPage() {\n const t = useTranslation()\n const [flows, setFlows] = useState<CadenceFlow[]>([])\n const [loading, setLoading] = useState(true)\n const [selectedId, setSelectedId] = useState<string | null>(null)\n const [steps, setSteps] = useState<CadenceStepStats[]>([])\n const [counts, setCounts] = useState<FlowCounts | null>(null)\n const [composerOpen, setComposerOpen] = useState(false)\n\n const load = useCallback(async () => {\n setLoading(true)\n try {\n setFlows(await store.listFlows())\n } catch (e) {\n toast.error(errorMessage(e))\n } finally {\n setLoading(false)\n }\n }, [])\n\n // `selectedId` lives in a ref so a late answer can be checked against the\n // selection as it is NOW, without re-creating the callback on every change.\n const selectedRef = useRef<string | null>(null)\n selectedRef.current = selectedId\n\n const loadDetail = useCallback(async (flowId: string) => {\n try {\n const [s, c] = await Promise.all([store.listSteps(flowId), store.countsFor(flowId)])\n // Two selections can resolve out of order, and the panel renders whatever\n // `steps` holds. Applying the wrong flow's rows is not cosmetic: the trash\n // icon deletes `row.original.id`, so a click in that window removes a step\n // from the flow the operator is no longer looking at.\n if (selectedRef.current !== flowId) return\n setSteps(s); setCounts(c)\n } catch (e) {\n toast.error(errorMessage(e))\n }\n }, [])\n\n const deleteStep = useCallback((id: string) => {\n void (async () => {\n try {\n await store.deleteStep(id)\n if (selectedId) await loadDetail(selectedId)\n } catch (e) { toast.error(errorMessage(e)) }\n })()\n }, [selectedId, loadDetail])\n const stepColumns = useStepColumns(deleteStep)\n\n useEffect(() => { void load() }, [load])\n useEffect(() => {\n // Clear FIRST. The panel opens as soon as `selectedId` flips, so without\n // this it shows the previous flow's steps and counts until the fetch lands\n // β and forever if it throws, since `loadDetail` only toasts.\n setSteps([]); setCounts(null)\n if (selectedId) void loadDetail(selectedId)\n }, [selectedId, loadDetail])\n\n const selected = flows.find((f) => f.id === selectedId) ?? null\n\n async function createFlow(input: { name: string; entryEvent: string; exitEvents: string[] }) {\n const flow = await store.saveFlow(input)\n await load()\n // Abre o painel dela na hora: uma cadΓͺncia sem passos nΓ£o faz nada, e o\n // prΓ³ximo ato Γ© sempre adicionar o primeiro.\n setSelectedId(flow.id)\n toast.success(t('automations.flow.created'))\n }\n\n async function toggleActive(flow: CadenceFlow) {\n // Turning a flow ON with no steps would enrol people into nothing: they\n // would sit in `active` forever, and the screen would show a cadence that\n // never sends. Cheaper to refuse than to explain.\n if (!flow.isActive) {\n // Always ask. Reading the shared `steps` when `flow.id === selectedId`\n // meant that during the window above β selection flipped, fetch not back\n // β an empty list let a flow with no steps switch itself on, which is the\n // one thing this guard exists to stop.\n const s = await store.listSteps(flow.id)\n if (s.length === 0) {\n toast.error(t('automations.flow.needStepsToActivate'))\n return\n }\n }\n try {\n await store.setFlowActive(flow.id, !flow.isActive)\n await load()\n } catch (e) {\n toast.error(errorMessage(e))\n }\n }\n\n // Esqueleto com a FORMA da lista, nΓ£o uma linha de texto centrada: a tela\n // que aparece depois tem cartΓ΅es empilhados, e um \"Carregandoβ¦\" faz o\n // conteΓΊdo saltar quando chega.\n if (loading) {\n return <div className=\"space-y-2\" aria-busy=\"true\" aria-label={t('automations.flow.loading')}>\n {[0, 1, 2].map((i) => (\n <Card key={i} className=\"p-3\">\n <div className=\"flex items-center gap-3\">\n <div className=\"h-4 w-4 shrink-0 animate-pulse rounded bg-muted/40\" />\n <div className=\"h-3.5 animate-pulse rounded bg-muted/40\" style={{ width: `${34 - i * 6}%` }} />\n <div className=\"h-4 w-28 animate-pulse rounded-full bg-muted/30\" />\n <div className=\"ml-auto h-5 w-9 animate-pulse rounded-full bg-muted/30\" />\n </div>\n </Card>\n ))}\n </div>\n }\n\n return (\n <div className=\"space-y-4\">\n <PageHeaderActions>\n <PageActions\n actions={[{\n id: 'new-flow', label: t('automations.flow.new'), icon: Plus,\n intent: 'primary' as const, creates: true, onSelect: () => setComposerOpen(true),\n }]}\n />\n </PageHeaderActions>\n\n <CadenceComposer\n open={composerOpen}\n onClose={() => setComposerOpen(false)}\n onCreate={createFlow}\n />\n\n {flows.length === 0 ? (\n <Card className=\"flex flex-col items-center gap-1 border-dashed py-12 text-center\">\n <p className=\"text-sm font-medium\">{t('automations.flow.emptyTitle')}</p>\n <p className=\"max-w-md text-xs text-muted-foreground\">{t('automations.flow.emptyHint')}</p>\n </Card>\n ) : (\n <div className=\"space-y-2\">\n {flows.map((flow) => (\n <Card key={flow.id} className=\"p-3\">\n <div className=\"flex items-center gap-3\">\n <button\n onClick={() => setSelectedId(selectedId === flow.id ? null : flow.id)}\n className=\"flex flex-1 items-center gap-2 text-left\"\n >\n <ChevronRight\n className={`h-4 w-4 text-muted-foreground transition-transform ${selectedId === flow.id ? 'rotate-90' : ''}`}\n />\n <span className=\"text-sm font-medium\">{flow.name}</span>\n <span className=\"rounded bg-muted px-1.5 py-0.5 text-[10px] text-muted-foreground\">\n {flow.entryEvent}\n </span>\n </button>\n {/* The switch says what it will do, not what it is: a flow with\n no steps cannot be turned on, and the refusal explains. */}\n <Switch\n checked={flow.isActive}\n onCheckedChange={() => { void toggleActive(flow) }}\n aria-label={t('automations.flow.toggle')}\n />\n </div>\n\n {selectedId === flow.id && (\n <div className=\"mt-3 border-t pt-3\">\n {counts && (\n <p className=\"mb-2 text-xs text-muted-foreground\">\n {t('automations.flow.counts', {\n active: String(counts.active),\n completed: String(counts.completed),\n exited: String(counts.exited),\n })}\n </p>\n )}\n <DataTable\n columns={stepColumns}\n data={steps}\n emptyMessage={\n <p className=\"py-4 text-xs text-muted-foreground\">{t('automations.flow.noSteps')}</p>\n }\n />\n\n <StepComposer\n steps={steps}\n onAdd={(input) => {\n void (async () => {\n try {\n await store.saveStep(flow.id, input)\n await loadDetail(flow.id)\n } catch (e) { toast.error(errorMessage(e)) }\n })()\n }}\n />\n </div>\n )}\n </Card>\n ))}\n </div>\n )}\n </div>\n )\n}\n","// automations.* β the cadence screen. The plugin's older views still carry\n// their pt-BR copy inline; new UI ships both locales (CONTRIBUTING).\nexport const en: Record<string, string> = {\n \"automations.flow.newTitle\": \"New cadence\",\n \"automations.flow.nameLabel\": \"Name\",\n \"automations.flow.namePlaceholder\": \"e.g. New lead sequence\",\n \"automations.flow.entryLabel\": \"Who enters\",\n \"automations.flow.entryPlaceholder\": \"Pick the fact that puts somebody in\",\n \"automations.flow.exitLabel\": \"Who leaves\",\n \"automations.flow.exitNone\": \"Only leaves when the steps run out\",\n \"automations.flow.exitHint\": \"The fact that stops the sequence. Without it, someone who already replied still gets the day-5 message.\",\n \"automations.flow.bornOffHint\": \"A cadence is born off and empty. Add the steps below and switch it on when it is ready.\",\n \"automations.flow.noEvents\": \"No active module announces facts in this app β no trigger, no cadence.\",\n \"automations.flow.create\": \"Create cadence\",\n \"automations.flow.new\": \"New flow\",\n \"automations.flow.loading\": \"Loading flowsβ¦\",\n \"automations.flow.emptyTitle\": \"No cadence flows yet\",\n \"automations.flow.emptyHint\": \"A flow touches the same lead more than once β a message today, a call in two days, another message on Friday β and stops on its own when they answer.\",\n \"automations.flow.namePrompt\": \"Name this flow\",\n \"automations.flow.entryPrompt\": \"Which event puts someone in?\",\n \"automations.flow.created\": \"Flow created. It starts switched off.\",\n \"automations.flow.toggle\": \"Active\",\n \"automations.flow.needStepsToActivate\": \"Add a step first β an empty flow enrols people into nothing.\",\n \"automations.flow.noSteps\": \"No steps yet.\",\n \"automations.flow.counts\": \"{{active}} in the flow Β· {{completed}} finished Β· {{exited}} left early\",\n \"automations.flow.colStep\": \"Step\",\n \"automations.flow.colWait\": \"Wait\",\n \"automations.flow.colQueued\": \"Queued\",\n \"automations.flow.colSent\": \"Sent\",\n \"automations.flow.colBlocked\": \"Blocked\",\n \"automations.flow.colFailed\": \"Failed\",\n \"automations.flow.addStep\": \"Add step\",\n \"automations.flow.deleteStep\": \"Remove step\",\n \"automations.flow.kindMessage\": \"Message\",\n \"automations.flow.kindTask\": \"Task\",\n \"automations.flow.templatePlaceholder\": \"Template key, e.g. lead.followup\",\n \"automations.flow.titlePlaceholder\": \"What should somebody do?\",\n \"automations.flow.needTemplate\": \"A message step needs a template.\",\n \"automations.flow.needTitle\": \"A task step needs a title.\",\n \"automations.flow.delayNow\": \"Right away\",\n \"automations.flow.delayMinutes\": \"{{count}} min later\",\n \"automations.flow.delayHours\": \"{{count}}h later\",\n \"automations.flow.delayDays\": \"{{count}} days later\",\n}\n","// automations.* β a tela de cadΓͺncia.\nexport const ptBR: Record<string, string> = {\n \"automations.flow.newTitle\": \"Nova cadΓͺncia\",\n \"automations.flow.nameLabel\": \"Nome\",\n \"automations.flow.namePlaceholder\": \"ex.: RΓ©gua do lead novo\",\n \"automations.flow.entryLabel\": \"Quem entra\",\n \"automations.flow.entryPlaceholder\": \"Escolha o fato que coloca alguΓ©m na rΓ©gua\",\n \"automations.flow.exitLabel\": \"Quem sai\",\n \"automations.flow.exitNone\": \"SΓ³ sai quando os passos acabam\",\n \"automations.flow.exitHint\": \"O fato que faz a pessoa parar de receber. Sem ele, quem jΓ‘ respondeu continua recebendo a mensagem do dia 5.\",\n \"automations.flow.bornOffHint\": \"A cadΓͺncia nasce desligada e sem passos. Monte os passos abaixo e ligue quando estiver pronta.\",\n \"automations.flow.noEvents\": \"Nenhum mΓ³dulo ativo anuncia fatos neste app β sem gatilho nΓ£o hΓ‘ cadΓͺncia.\",\n \"automations.flow.create\": \"Criar cadΓͺncia\",\n \"automations.flow.new\": \"Novo fluxo\",\n \"automations.flow.loading\": \"Carregando fluxosβ¦\",\n \"automations.flow.emptyTitle\": \"Nenhum fluxo de cadΓͺncia ainda\",\n \"automations.flow.emptyHint\": \"Um fluxo toca o mesmo lead mais de uma vez β uma mensagem hoje, uma ligaΓ§Γ£o em dois dias, outra mensagem na sexta β e para sozinho quando a pessoa responde.\",\n \"automations.flow.namePrompt\": \"Nome do fluxo\",\n \"automations.flow.entryPrompt\": \"Qual evento coloca alguΓ©m aqui?\",\n \"automations.flow.created\": \"Fluxo criado. Ele nasce desligado.\",\n \"automations.flow.toggle\": \"Ativo\",\n \"automations.flow.needStepsToActivate\": \"Adicione um passo antes β um fluxo vazio inscreve gente em nada.\",\n \"automations.flow.noSteps\": \"Nenhum passo ainda.\",\n \"automations.flow.counts\": \"{{active}} no fluxo Β· {{completed}} concluΓram Β· {{exited}} saΓram antes\",\n \"automations.flow.colStep\": \"Passo\",\n \"automations.flow.colWait\": \"Espera\",\n \"automations.flow.colQueued\": \"Na fila\",\n \"automations.flow.colSent\": \"Enviados\",\n \"automations.flow.colBlocked\": \"Bloqueados\",\n \"automations.flow.colFailed\": \"Falharam\",\n \"automations.flow.addStep\": \"Adicionar passo\",\n \"automations.flow.deleteStep\": \"Remover passo\",\n \"automations.flow.kindMessage\": \"Mensagem\",\n \"automations.flow.kindTask\": \"Tarefa\",\n \"automations.flow.templatePlaceholder\": \"Chave do modelo, ex.: lead.followup\",\n \"automations.flow.titlePlaceholder\": \"O que alguΓ©m precisa fazer?\",\n \"automations.flow.needTemplate\": \"Um passo de mensagem precisa de um modelo.\",\n \"automations.flow.needTitle\": \"Um passo de tarefa precisa de um tΓtulo.\",\n \"automations.flow.delayNow\": \"Na hora\",\n \"automations.flow.delayMinutes\": \"{{count}} min depois\",\n \"automations.flow.delayHours\": \"{{count}}h depois\",\n \"automations.flow.delayDays\": \"{{count}} dias depois\",\n}\n","import { en } from './en'\nimport { ptBR } from './pt-BR'\n\nexport const automationsLocales: Record<string, Record<string, string>> = {\n en,\n 'pt-BR': ptBR,\n}\n","// AUTO-GENERATED from 000_baseline.sql, 001_the_flow_has_steps.sql β regenerate with scripts/embed-migrations.mjs\n// SQL files are the source of truth; this inline copy lets the manifest declare\n// migrations as data. Do not edit by hand β run the embed script instead.\n\nexport const MIGRATION_000_BASELINE = `-- ============================================================================\n-- plugins/plugin-automations/migrations/000_baseline.sql β what installing this provisions, as one file.\n--\n-- GENERATED by scripts/emit-unit-baselines.mjs (#338). Do not edit by hand:\n-- change the schema, regenerate, and let scripts/check-chain-equivalence.mjs\n-- prove the result still matches.\n--\n-- This replaced 4 migration files. They are kept, unapplied, in\n-- migrations.archive/ β a year of decisions is worth reading even when it is no\n-- longer worth replaying.\n--\n-- Object order is fixed rather than dependency-sorted: schemas, types,\n-- sequences, tables, defaults, functions, constraints, views, indexes, foreign\n-- keys, triggers, row security, policies, grants. Dependencies BETWEEN units\n-- are carried by the order packages/db/chain.json declares.\n-- ============================================================================\n\n-- A LANGUAGE sql function binds its body at CREATE time, and 570 functions\n-- sorted by name are not sorted by who calls whom. This is what lets them load\n-- in any order; every body is still compiled on first call, so a genuinely\n-- broken reference surfaces then rather than never. Session-scoped.\nSET check_function_bodies = false;\n\n\n\n-- ββ default privileges: reset βββββββββββββββββββββββββββββββββββββββββββ\n-- Cleared BEFORE anything is created, so every object below gets the ACL the\n-- dump describes rather than the image's defaults on top of it. Restored at\n-- the end of this file.\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public REVOKE ALL ON SEQUENCES FROM anon, authenticated, service_role, fayz_connector$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public REVOKE ALL ON SEQUENCES FROM anon, authenticated, service_role, fayz_connector$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public REVOKE ALL ON SEQUENCES FROM anon, authenticated, service_role, fayz_connector$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public REVOKE ALL ON SEQUENCES FROM anon, authenticated, service_role, fayz_connector$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public REVOKE ALL ON FUNCTIONS FROM anon, authenticated, service_role, fayz_connector$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public REVOKE ALL ON FUNCTIONS FROM anon, authenticated, service_role, fayz_connector$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public REVOKE ALL ON FUNCTIONS FROM anon, authenticated, service_role, fayz_connector$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public REVOKE ALL ON FUNCTIONS FROM anon, authenticated, service_role, fayz_connector$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public REVOKE ALL ON TABLES FROM anon, authenticated, service_role, fayz_connector$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public REVOKE ALL ON TABLES FROM anon, authenticated, service_role, fayz_connector$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public REVOKE ALL ON TABLES FROM anon, authenticated, service_role, fayz_connector$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public REVOKE ALL ON TABLES FROM anon, authenticated, service_role, fayz_connector$stmt$;\nEND $dp$;\n\n\n-- ββ table βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nCREATE TABLE public.plg_automations_provider_templates (\n id uuid DEFAULT gen_random_uuid() NOT NULL,\n tenant_id uuid,\n event_key text NOT NULL,\n channel text DEFAULT 'whatsapp'::text NOT NULL,\n provider text DEFAULT 'tyxter'::text NOT NULL,\n provider_template_id text,\n template_name text NOT NULL,\n language text DEFAULT 'pt_BR'::text NOT NULL,\n variable_map jsonb DEFAULT '[]'::jsonb NOT NULL,\n actions_map jsonb DEFAULT '[]'::jsonb NOT NULL,\n status text DEFAULT 'draft'::text NOT NULL,\n rejection_reason text,\n body_snapshot text,\n submitted_at timestamp with time zone,\n approved_at timestamp with time zone,\n created_at timestamp with time zone DEFAULT now() NOT NULL,\n updated_at timestamp with time zone DEFAULT now() NOT NULL,\n CONSTRAINT plg_automations_provider_templates_status_check CHECK ((status = ANY (ARRAY['draft'::text, 'submitted'::text, 'approved'::text, 'rejected'::text, 'paused'::text, 'disabled'::text])))\n);\n\nCREATE TABLE public.plg_automations_templates (\n id uuid DEFAULT gen_random_uuid() NOT NULL,\n tenant_id uuid NOT NULL,\n event_key text NOT NULL,\n channel text DEFAULT 'email'::text NOT NULL,\n enabled boolean,\n subject text,\n body text,\n name text,\n created_at timestamp with time zone DEFAULT now() NOT NULL,\n updated_at timestamp with time zone DEFAULT now() NOT NULL,\n actions jsonb\n);\n\n\n-- ββ function ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nCREATE FUNCTION public.automations_set_updated_at() RETURNS trigger\n LANGUAGE plpgsql\n AS $$\nBEGIN\n NEW.updated_at = now();\n RETURN NEW;\nEND $$;\n\n\n-- ββ constraint ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nALTER TABLE ONLY public.plg_automations_provider_templates\n ADD CONSTRAINT plg_automations_provider_templates_pkey PRIMARY KEY (id);\n\nALTER TABLE ONLY public.plg_automations_templates\n ADD CONSTRAINT plg_automations_templates_pkey PRIMARY KEY (id);\n\n\n-- ββ index βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nCREATE INDEX idx_plg_automations_provider_templates_lookup ON public.plg_automations_provider_templates USING btree (event_key, channel, provider, status);\n\nCREATE INDEX plg_automations_templates_tenant_idx ON public.plg_automations_templates USING btree (tenant_id);\n\nCREATE UNIQUE INDEX plg_automations_templates_unique_idx ON public.plg_automations_templates USING btree (tenant_id, event_key, channel);\n\nCREATE UNIQUE INDEX uq_plg_automations_provider_templates_owner ON public.plg_automations_provider_templates USING btree (COALESCE(tenant_id, '00000000-0000-0000-0000-000000000000'::uuid), event_key, channel, provider);\n\nCREATE UNIQUE INDEX uq_plg_automations_provider_templates_provider_id ON public.plg_automations_provider_templates USING btree (provider, provider_template_id) WHERE (provider_template_id IS NOT NULL);\n\n\n-- ββ fk constraint βββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nALTER TABLE ONLY public.plg_automations_provider_templates\n ADD CONSTRAINT plg_automations_provider_templates_tenant_id_fkey FOREIGN KEY (tenant_id) REFERENCES public.tenants(id) ON DELETE CASCADE;\n\n\n-- ββ trigger βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nCREATE TRIGGER plg_automations_provider_templates_set_updated_at BEFORE UPDATE ON public.plg_automations_provider_templates FOR EACH ROW EXECUTE FUNCTION public.automations_set_updated_at();\n\nCREATE TRIGGER plg_automations_templates_set_updated_at BEFORE UPDATE ON public.plg_automations_templates FOR EACH ROW EXECUTE FUNCTION public.automations_set_updated_at();\n\n\n-- ββ row security ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nALTER TABLE public.plg_automations_provider_templates ENABLE ROW LEVEL SECURITY;\n\nALTER TABLE public.plg_automations_templates ENABLE ROW LEVEL SECURITY;\n\n\n-- ββ policy ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nCREATE POLICY plg_automations_provider_templates_select ON public.plg_automations_provider_templates FOR SELECT TO authenticated USING (((tenant_id IS NULL) OR (tenant_id IN ( SELECT public.user_tenant_ids() AS user_tenant_ids))));\n\nCREATE POLICY plg_automations_templates_member_all ON public.plg_automations_templates TO authenticated USING ((tenant_id IN ( SELECT public.user_tenant_ids() AS user_tenant_ids))) WITH CHECK ((tenant_id IN ( SELECT public.user_tenant_ids() AS user_tenant_ids)));\n\n\n-- ββ acl βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nGRANT ALL ON FUNCTION public.automations_set_updated_at() TO authenticated;\nGRANT ALL ON FUNCTION public.automations_set_updated_at() TO service_role;\n\nGRANT MAINTAIN ON TABLE public.plg_automations_provider_templates TO anon;\nGRANT ALL ON TABLE public.plg_automations_provider_templates TO authenticated;\nGRANT ALL ON TABLE public.plg_automations_provider_templates TO service_role;\n\nGRANT MAINTAIN ON TABLE public.plg_automations_templates TO anon;\nGRANT ALL ON TABLE public.plg_automations_templates TO authenticated;\nGRANT ALL ON TABLE public.plg_automations_templates TO service_role;\n\n\n-- ββ comment βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nCOMMENT ON COLUMN public.plg_automations_templates.actions IS 'Channel-neutral message actions: [{id: confirm|cancel|pay, label, kind: reply|payment}]. NULL = the catalog default; [] = deliberately no buttons.';\n\n\n-- ββ default privileges: restore βββββββββββββββββββββββββββββββββββββββββ\n-- Put back, so the NEXT thing installed inherits what the chain had.\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON SEQUENCES TO postgres$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON SEQUENCES TO postgres$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON SEQUENCES TO anon$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON SEQUENCES TO anon$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON SEQUENCES TO authenticated$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON SEQUENCES TO authenticated$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON SEQUENCES TO service_role$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON SEQUENCES TO service_role$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON SEQUENCES TO postgres$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON SEQUENCES TO postgres$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON SEQUENCES TO anon$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON SEQUENCES TO anon$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON SEQUENCES TO authenticated$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON SEQUENCES TO authenticated$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON SEQUENCES TO service_role$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON SEQUENCES TO service_role$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON FUNCTIONS TO postgres$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON FUNCTIONS TO postgres$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON FUNCTIONS TO authenticated$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON FUNCTIONS TO authenticated$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON FUNCTIONS TO service_role$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON FUNCTIONS TO service_role$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON FUNCTIONS TO postgres$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON FUNCTIONS TO postgres$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON FUNCTIONS TO anon$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON FUNCTIONS TO anon$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON FUNCTIONS TO authenticated$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON FUNCTIONS TO authenticated$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON FUNCTIONS TO service_role$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON FUNCTIONS TO service_role$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON TABLES TO postgres$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON TABLES TO postgres$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT MAINTAIN ON TABLES TO anon$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT MAINTAIN ON TABLES TO anon$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON TABLES TO authenticated$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON TABLES TO authenticated$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON TABLES TO service_role$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON TABLES TO service_role$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON TABLES TO postgres$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON TABLES TO postgres$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON TABLES TO anon$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON TABLES TO anon$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON TABLES TO authenticated$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON TABLES TO authenticated$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON TABLES TO service_role$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON TABLES TO service_role$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$--\n-- PostgreSQL database dump complete\n--$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$--\n-- PostgreSQL database dump complete\n--$stmt$;\nEND $dp$;\n`\n\nexport const MIGRATION_001_THE_FLOW_HAS_STEPS = `-- 001_the_flow_has_steps.sql\n--\n-- A CADENCE: the same lead touched on day 0, day 2 and day 5, by itself.\n--\n-- This plugin's README has promised \"multi-step sequences, and enrollment\n-- stats\" since M1, and \\`AutomationsList.tsx\\` says plainly what shipped instead:\n-- \"um fluxo de um passo Γ© o texto com o gatilho escrito na frente\". One row per\n-- (event, channel). Nothing waits, nothing remembers where a person got to, and\n-- nothing stops when they reply.\n--\n-- WHAT THIS DOES NOT BUILD, BECAUSE IT ALREADY EXISTS.\n--\n-- * The clock. \\`fayz_event_runner\\` is a pg_cron job that already calls\n-- \\`event_runner_tick(200)\\` every minute. This adds a fifth call to it\n-- (packages/db 046), guarded like the other four.\n-- * The delay. \\`notifications_enqueue(..., p_scheduled_for, p_dedupe_key)\\`\n-- already means \"send this at time T, and not twice\". A cadence step is a\n-- row in that queue with a computed \\`scheduled_for\\`.\n-- * Consent, channel preference and quiet-channel fallback β all inside\n-- \\`notifications_resolve_channel\\`, which plugin-notifications 002 just\n-- taught to read the opt-out correctly. A cadence that dodged the queue\n-- would dodge consent with it, which is the whole reason it does not.\n-- * The claim-and-retry shape. \\`marketing_run_due\\` / \\`marketing_campaign_run\\`\n-- already solve \"advance a set of enrolled people on a tick\" with\n-- \\`FOR UPDATE SKIP LOCKED\\`. \\`automations_flows_run_due\\` is that function\n-- with a step pointer.\n--\n-- THE THREE DECISIONS WORTH ARGUING WITH.\n--\n-- 1. THE DELAY IS AN OFFSET FROM THE PREVIOUS STEP, NOT FROM ENROLMENT.\n-- \"Two days after the call\" is how a salesperson describes a cadence, and it\n-- survives inserting a step in the middle. Absolute offsets from day 0 mean\n-- every later step silently shifts when you add one.\n--\n-- 2. THE ENROLMENT CARRIES THE STEP POINTER, AND THE DEDUPE KEY CARRIES THE\n-- POSITION. \\`flow:<enrolment>:<position>\\` means replaying a tick, or two\n-- workers taking the same row, cannot send a step twice β\n-- \\`notifications_enqueue\\` refuses a repeated \\`dedupe_key\\` before it writes\n-- anything. The SKIP LOCKED claim is the first defence; this is the one that\n-- survives a crash between the enqueue and the pointer update.\n--\n-- 3. A FLOW IS BORN INACTIVE. \\`is_active\\` defaults false. A cadence that starts\n-- sending the moment somebody saves a draft is a cadence that sends a draft.\n--\n-- WHAT IS STILL MISSING AFTER THIS, AND IS NOT PRETENDED OTHERWISE: e-mail and\n-- SMS still resolve to \\`notifications_send_to_log\\`, which records and sends\n-- nothing. A cadence on those channels will enqueue, drain, and deliver to a\n-- log row. WhatsApp reaches a provider; in-app reaches the bell.\n\nSET check_function_bodies = false;\n\n-- ββ tables ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nCREATE TABLE IF NOT EXISTS public.plg_automations_flows (\n id uuid DEFAULT gen_random_uuid() NOT NULL,\n tenant_id uuid NOT NULL,\n unit_id uuid,\n name text NOT NULL,\n description text,\n -- The fact that puts somebody in. Names an event from the aggregated plugin\n -- catalog (\\`crm.lead_created\\`, \\`crm.stage_changed\\`, β¦); it is text and not a\n -- foreign key because the catalog is assembled at runtime from whichever\n -- plugins an app mounts.\n entry_event text NOT NULL,\n -- The facts that take somebody out. Empty means the flow only ends by\n -- running out of steps.\n exit_events text[] DEFAULT '{}'::text[] NOT NULL,\n is_active boolean DEFAULT false NOT NULL,\n owner_id uuid,\n created_at timestamptz DEFAULT now() NOT NULL,\n updated_at timestamptz DEFAULT now() NOT NULL,\n CONSTRAINT plg_automations_flows_pkey PRIMARY KEY (id)\n);\n\nCREATE TABLE IF NOT EXISTS public.plg_automations_flow_steps (\n id uuid DEFAULT gen_random_uuid() NOT NULL,\n tenant_id uuid NOT NULL,\n flow_id uuid NOT NULL,\n -- Sparse on purpose (10, 20, 30β¦): inserting between two steps should not\n -- renumber the ones after it, and the enrolment's pointer names a position.\n position integer NOT NULL,\n -- Minutes to wait AFTER THE PREVIOUS STEP. The first step's delay is measured\n -- from enrolment, so 0 means \"right away\".\n delay_minutes integer DEFAULT 0 NOT NULL,\n kind text DEFAULT 'message' NOT NULL,\n -- kind='message': which template, and optionally force a channel. NULL\n -- channel lets notifications_resolve_channel pick, which is what honours the\n -- recipient's preference.\n template_key text,\n channel text,\n -- kind='task': what the human is asked to do, and by when.\n task_title text,\n task_due_days integer,\n created_at timestamptz DEFAULT now() NOT NULL,\n updated_at timestamptz DEFAULT now() NOT NULL,\n CONSTRAINT plg_automations_flow_steps_pkey PRIMARY KEY (id),\n CONSTRAINT plg_automations_flow_steps_kind_check\n CHECK (kind = ANY (ARRAY['message'::text, 'task'::text])),\n CONSTRAINT plg_automations_flow_steps_delay_check CHECK (delay_minutes >= 0),\n -- A message step with no template has nothing to send; a task step with no\n -- title gives the human nothing to read. Either is a step that would fail at\n -- 3am rather than at save time.\n CONSTRAINT plg_automations_flow_steps_payload_check CHECK (\n (kind = 'message' AND template_key IS NOT NULL)\n OR (kind = 'task' AND task_title IS NOT NULL)\n )\n);\n\nCREATE TABLE IF NOT EXISTS public.plg_automations_enrollments (\n id uuid DEFAULT gen_random_uuid() NOT NULL,\n tenant_id uuid NOT NULL,\n flow_id uuid NOT NULL,\n person_id uuid NOT NULL,\n -- What put them here, for the timeline: ('lead', <id>) or ('deal', <id>).\n subject_type text,\n subject_id uuid,\n status text DEFAULT 'active' NOT NULL,\n -- The position of the step that runs NEXT. NULL once nothing is left.\n current_position integer,\n next_run_at timestamptz DEFAULT now() NOT NULL,\n entered_at timestamptz DEFAULT now() NOT NULL,\n exited_at timestamptz,\n exit_reason text,\n created_at timestamptz DEFAULT now() NOT NULL,\n updated_at timestamptz DEFAULT now() NOT NULL,\n CONSTRAINT plg_automations_enrollments_pkey PRIMARY KEY (id),\n CONSTRAINT plg_automations_enrollments_status_check\n CHECK (status = ANY (ARRAY['active'::text, 'completed'::text, 'exited'::text]))\n);\n\n-- ββ constraint ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nALTER TABLE public.plg_automations_flows\n DROP CONSTRAINT IF EXISTS plg_automations_flows_tenant_fkey;\nALTER TABLE public.plg_automations_flows\n ADD CONSTRAINT plg_automations_flows_tenant_fkey\n FOREIGN KEY (tenant_id) REFERENCES public.tenants(id) ON DELETE CASCADE;\n\nALTER TABLE public.plg_automations_flow_steps\n DROP CONSTRAINT IF EXISTS plg_automations_flow_steps_flow_fkey;\nALTER TABLE public.plg_automations_flow_steps\n ADD CONSTRAINT plg_automations_flow_steps_flow_fkey\n FOREIGN KEY (flow_id) REFERENCES public.plg_automations_flows(id) ON DELETE CASCADE;\n\nALTER TABLE public.plg_automations_enrollments\n DROP CONSTRAINT IF EXISTS plg_automations_enrollments_flow_fkey;\nALTER TABLE public.plg_automations_enrollments\n ADD CONSTRAINT plg_automations_enrollments_flow_fkey\n FOREIGN KEY (flow_id) REFERENCES public.plg_automations_flows(id) ON DELETE CASCADE;\n\n-- ββ index βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nCREATE UNIQUE INDEX IF NOT EXISTS plg_automations_flow_steps_position_uq\n ON public.plg_automations_flow_steps (flow_id, position);\nCREATE INDEX IF NOT EXISTS plg_automations_flows_tenant_idx\n ON public.plg_automations_flows (tenant_id);\nCREATE INDEX IF NOT EXISTS plg_automations_flows_entry_idx\n ON public.plg_automations_flows (tenant_id, entry_event) WHERE is_active;\n\n-- One live enrolment per person per flow. Re-entering a cadence somebody is\n-- already in would double every remaining message.\nCREATE UNIQUE INDEX IF NOT EXISTS plg_automations_enrollments_live_uq\n ON public.plg_automations_enrollments (flow_id, person_id) WHERE status = 'active';\n-- The claim index: the runner only ever asks for due, active rows.\nCREATE INDEX IF NOT EXISTS plg_automations_enrollments_due_idx\n ON public.plg_automations_enrollments (next_run_at) WHERE status = 'active';\nCREATE INDEX IF NOT EXISTS plg_automations_enrollments_person_idx\n ON public.plg_automations_enrollments (tenant_id, person_id);\n\n-- ββ row security ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\n-- ENABLE **and** FORCE. Without FORCE the table owner β which is the role that\n-- runs migrations and every SECURITY DEFINER function here β bypasses these\n-- policies entirely, and \\`packages/db/test/pgtap/900_verification/001_posture.sql\\`\n-- (N14b) fails the whole pool for it.\nALTER TABLE public.plg_automations_flows ENABLE ROW LEVEL SECURITY;\nALTER TABLE public.plg_automations_flows FORCE ROW LEVEL SECURITY;\nALTER TABLE public.plg_automations_flow_steps ENABLE ROW LEVEL SECURITY;\nALTER TABLE public.plg_automations_flow_steps FORCE ROW LEVEL SECURITY;\nALTER TABLE public.plg_automations_enrollments ENABLE ROW LEVEL SECURITY;\nALTER TABLE public.plg_automations_enrollments FORCE ROW LEVEL SECURITY;\n\nDROP POLICY IF EXISTS plg_automations_flows_authz_select ON public.plg_automations_flows;\nCREATE POLICY plg_automations_flows_authz_select ON public.plg_automations_flows\n FOR SELECT TO authenticated USING (\n tenant_id = (SELECT app.current_tenant_id())\n AND (SELECT app.has_permission('automations.read', NULL::uuid)));\n\nDROP POLICY IF EXISTS plg_automations_flows_authz_insert ON public.plg_automations_flows;\nCREATE POLICY plg_automations_flows_authz_insert ON public.plg_automations_flows\n FOR INSERT TO authenticated WITH CHECK (\n tenant_id = (SELECT app.current_tenant_id())\n AND (SELECT app.has_permission('automations.edit', NULL::uuid)));\n\nDROP POLICY IF EXISTS plg_automations_flows_authz_update ON public.plg_automations_flows;\nCREATE POLICY plg_automations_flows_authz_update ON public.plg_automations_flows\n FOR UPDATE TO authenticated USING (\n tenant_id = (SELECT app.current_tenant_id())\n AND (SELECT app.has_permission('automations.edit', NULL::uuid)))\n WITH CHECK (\n tenant_id = (SELECT app.current_tenant_id())\n AND (SELECT app.has_permission('automations.edit', NULL::uuid)));\n\nDROP POLICY IF EXISTS plg_automations_flows_authz_delete ON public.plg_automations_flows;\nCREATE POLICY plg_automations_flows_authz_delete ON public.plg_automations_flows\n FOR DELETE TO authenticated USING (\n tenant_id = (SELECT app.current_tenant_id())\n AND (SELECT app.has_permission('automations.edit', NULL::uuid)));\n\nDROP POLICY IF EXISTS plg_automations_flow_steps_authz_select ON public.plg_automations_flow_steps;\nCREATE POLICY plg_automations_flow_steps_authz_select ON public.plg_automations_flow_steps\n FOR SELECT TO authenticated USING (\n tenant_id = (SELECT app.current_tenant_id())\n AND (SELECT app.has_permission('automations.read', NULL::uuid)));\n\nDROP POLICY IF EXISTS plg_automations_flow_steps_authz_insert ON public.plg_automations_flow_steps;\n-- The parent flow is checked, not just the stamped tenant. A tenant-only\n-- WITH CHECK lets a caller stamp their OWN tenant_id on a step and hang it off\n-- somebody else's flow β and the engine looks steps up by flow_id alone, so the\n-- injected step runs in that tenant's cadence.\nCREATE POLICY plg_automations_flow_steps_authz_insert ON public.plg_automations_flow_steps\n FOR INSERT TO authenticated WITH CHECK (\n tenant_id = (SELECT app.current_tenant_id())\n AND (SELECT app.has_permission('automations.edit', NULL::uuid))\n AND EXISTS (SELECT 1 FROM public.plg_automations_flows f\n WHERE f.id = flow_id AND f.tenant_id = (SELECT app.current_tenant_id())));\n\nDROP POLICY IF EXISTS plg_automations_flow_steps_authz_update ON public.plg_automations_flow_steps;\nCREATE POLICY plg_automations_flow_steps_authz_update ON public.plg_automations_flow_steps\n FOR UPDATE TO authenticated USING (\n tenant_id = (SELECT app.current_tenant_id())\n AND (SELECT app.has_permission('automations.edit', NULL::uuid)))\n WITH CHECK (\n tenant_id = (SELECT app.current_tenant_id())\n AND (SELECT app.has_permission('automations.edit', NULL::uuid)));\n\nDROP POLICY IF EXISTS plg_automations_flow_steps_authz_delete ON public.plg_automations_flow_steps;\nCREATE POLICY plg_automations_flow_steps_authz_delete ON public.plg_automations_flow_steps\n FOR DELETE TO authenticated USING (\n tenant_id = (SELECT app.current_tenant_id())\n AND (SELECT app.has_permission('automations.edit', NULL::uuid)));\n\n-- Enrolments are READ-ONLY to the operator. They are written by the engine, and\n-- a hand-edited step pointer is a cadence nobody can explain afterwards.\n-- Leaving a flow is \\`automations_flow_exit\\`, not an UPDATE.\nDROP POLICY IF EXISTS plg_automations_enrollments_authz_select ON public.plg_automations_enrollments;\nCREATE POLICY plg_automations_enrollments_authz_select ON public.plg_automations_enrollments\n FOR SELECT TO authenticated USING (\n tenant_id = (SELECT app.current_tenant_id())\n AND (SELECT app.has_permission('automations.read', NULL::uuid)));\n\nGRANT SELECT, INSERT, UPDATE, DELETE ON public.plg_automations_flows TO authenticated;\nGRANT ALL ON public.plg_automations_flows TO service_role;\nGRANT SELECT, INSERT, UPDATE, DELETE ON public.plg_automations_flow_steps TO authenticated;\nGRANT ALL ON public.plg_automations_flow_steps TO service_role;\nGRANT SELECT ON public.plg_automations_enrollments TO authenticated;\nGRANT ALL ON public.plg_automations_enrollments TO service_role;\n\nINSERT INTO app.scaffold_registry\n (table_schema, table_name, resource_type, plugin, owner_scoping, mode, previous_policies, audit_hook, scope, distributable)\nVALUES\n ('public', 'plg_automations_flows', 'automations.flow', 'automations', false, 'enforce', ARRAY[]::text[], false, 'unit_optional', false),\n ('public', 'plg_automations_flow_steps', 'automations.flow_step', 'automations', false, 'enforce', ARRAY[]::text[], false, 'tenant', false),\n ('public', 'plg_automations_enrollments', 'automations.enrollment', 'automations', false, 'enforce', ARRAY[]::text[], false, 'tenant', false)\nON CONFLICT DO NOTHING;\n\n-- ββ function ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\n-- Put somebody into a flow. Returns the enrolment, or NULL when the flow is\n-- inactive, has no steps, or the person is already in it.\nCREATE OR REPLACE FUNCTION public.automations_flow_enroll(\n p_tenant_id uuid, p_flow_id uuid, p_person_id uuid,\n p_subject_type text DEFAULT NULL, p_subject_id uuid DEFAULT NULL\n) RETURNS uuid\nLANGUAGE plpgsql SECURITY DEFINER\nSET search_path TO ''\nAS $$\nDECLARE v_first record; v_id uuid;\nBEGIN\n SELECT s.position, s.delay_minutes INTO v_first\n FROM public.plg_automations_flow_steps s\n JOIN public.plg_automations_flows f ON f.id = s.flow_id\n WHERE s.flow_id = p_flow_id AND f.tenant_id = p_tenant_id AND f.is_active\n ORDER BY s.position\n LIMIT 1;\n\n -- An inactive flow, or one with no steps, enrols nobody. Silently: this is\n -- called from an event handler, and raising would fail the whole delivery.\n IF v_first.position IS NULL THEN RETURN NULL; END IF;\n\n INSERT INTO public.plg_automations_enrollments\n (tenant_id, flow_id, person_id, subject_type, subject_id, current_position, next_run_at)\n VALUES\n (p_tenant_id, p_flow_id, p_person_id, p_subject_type, p_subject_id,\n v_first.position, now() + make_interval(mins => v_first.delay_minutes))\n ON CONFLICT DO NOTHING\n RETURNING id INTO v_id;\n\n RETURN v_id;\nEND $$;\n\n-- Take somebody out of every flow they are in. The reason is kept, because\n-- \"left because they replied\" and \"left because the deal was lost\" are the two\n-- halves of whether a cadence works.\nCREATE OR REPLACE FUNCTION public.automations_flow_exit(\n p_tenant_id uuid, p_person_id uuid, p_reason text, p_flow_ids uuid[] DEFAULT NULL\n) RETURNS integer\nLANGUAGE plpgsql SECURITY DEFINER\nSET search_path TO ''\nAS $$\nDECLARE v_n integer; v_gone uuid[];\nBEGIN\n -- SCOPED TO THE FLOWS THAT ASKED. \\`p_flow_ids\\` NULL still means \"every flow\",\n -- which is what a manual \"take this person out\" wants; the event handler\n -- passes the flows whose own \\`exit_events\\` name the fact.\n --\n -- Without the scope, one flow declaring \\`crm.deal_won\\` pulled the person out\n -- of EVERY flow they were in and cancelled every queued step β including a\n -- flow that declared no exits at all, whose comment says it \"only ends by\n -- running out of steps\". Flow-level exit_events were meaningless the moment a\n -- second flow existed.\n WITH gone AS (\n UPDATE public.plg_automations_enrollments\n SET status = 'exited', exited_at = now(), exit_reason = p_reason,\n current_position = NULL, updated_at = now()\n WHERE tenant_id = p_tenant_id AND person_id = p_person_id AND status = 'active'\n AND (p_flow_ids IS NULL OR flow_id = ANY (p_flow_ids))\n RETURNING id\n )\n SELECT count(*)::integer, array_agg(id) INTO v_n, v_gone FROM gone;\n\n -- A step already in the queue but not yet sent must not go out after the\n -- person left. \\`cancelled\\` was in the status CHECK from the beginning and\n -- nothing ever wrote it; this is what it was for.\n --\n -- Keyed by the ENROLMENTS that just left, not by \\`flow:%\\` β the wide pattern\n -- cancelled the pending steps of flows the person is still in.\n IF v_n > 0 AND to_regclass('public.plg_notifications_queue') IS NOT NULL THEN\n UPDATE public.plg_notifications_queue q\n SET status = 'cancelled', last_error = 'left the flow: ' || p_reason\n WHERE q.tenant_id = p_tenant_id\n AND q.person_id = p_person_id\n AND q.status = 'pending'\n AND split_part(q.dedupe_key, ':', 1) = 'flow'\n AND split_part(q.dedupe_key, ':', 2) = ANY (SELECT unnest(v_gone)::text);\n END IF;\n\n RETURN v_n;\nEND $$;\n\n-- The tick. Claims due enrolments, runs ONE step each, moves the pointer.\nCREATE OR REPLACE FUNCTION public.automations_flows_run_due(p_limit integer DEFAULT 50)\nRETURNS jsonb\nLANGUAGE plpgsql SECURITY DEFINER\nSET search_path TO ''\nAS $$\nDECLARE\n e record; v_step record; v_next record; v_error text;\n v_ran integer := 0; v_done integer := 0; v_failed integer := 0;\nBEGIN\n -- JOINED to the flow, and \\`f.is_active\\` checked here rather than only in\n -- \\`automations_flow_enroll\\`. Switching a flow off used to stop new entrants\n -- and nothing else: everybody already mid-cadence kept receiving messages\n -- from a flow the operator had just turned off, which is the opposite of what\n -- the switch promises.\n FOR e IN\n SELECT en.* FROM public.plg_automations_enrollments en\n JOIN public.plg_automations_flows f ON f.id = en.flow_id AND f.is_active\n WHERE en.status = 'active' AND en.next_run_at <= now()\n ORDER BY en.next_run_at\n LIMIT greatest(p_limit, 0)\n FOR UPDATE OF en SKIP LOCKED\n LOOP\n SELECT * INTO v_step FROM public.plg_automations_flow_steps s\n WHERE s.flow_id = e.flow_id AND s.position = e.current_position;\n\n -- The step was deleted while somebody stood on it. Move on rather than\n -- spinning on a pointer that will never resolve.\n IF v_step.id IS NULL THEN\n SELECT * INTO v_next FROM public.plg_automations_flow_steps s\n WHERE s.flow_id = e.flow_id AND s.position > coalesce(e.current_position, -1)\n ORDER BY s.position LIMIT 1;\n ELSE\n BEGIN\n IF v_step.kind = 'message' THEN\n PERFORM public.notifications_enqueue(\n e.tenant_id, v_step.template_key, e.person_id,\n jsonb_build_object('flow_id', e.flow_id, 'enrollment_id', e.id, 'step', v_step.position),\n 'flow:' || e.id::text || ':' || v_step.position::text,\n now(),\n v_step.channel\n );\n ELSIF v_step.kind = 'task' AND to_regclass('public.tasks') IS NOT NULL THEN\n -- \\`tasks_source_uniq (tenant_id, source, source_key)\\` makes this\n -- idempotent for free β the same step cannot raise two tasks.\n INSERT INTO public.tasks\n (tenant_id, title, description, status, due_date, source, source_key)\n VALUES\n (e.tenant_id, v_step.task_title,\n 'Automation flow step ' || v_step.position::text,\n 'todo',\n CASE WHEN v_step.task_due_days IS NOT NULL\n THEN (now() + make_interval(days => v_step.task_due_days))::date END,\n 'automation:flow', e.id::text || ':' || v_step.position::text)\n ON CONFLICT DO NOTHING;\n END IF;\n v_ran := v_ran + 1;\n EXCEPTION WHEN OTHERS THEN\n -- One bad step must not stop the tick for everybody else, so the\n -- enrolment still leaves this step: a template that no longer exists\n -- would otherwise wedge the person forever.\n --\n -- But it does NOT read as a finished cadence. The first cut let the\n -- loop fall through to \\`completed\\`, and because a failed step never\n -- produces a queue row, \\`v_automations_flow_steps\\` β which counts queue\n -- statuses β could not show it either. The screen built to answer\n -- \"where do people stop\" reported the person as having finished.\n v_failed := v_failed + 1;\n v_error := SQLERRM;\n RAISE NOTICE 'automations_flows_run_due: step % of enrolment % failed (%)',\n v_step.position, e.id, SQLERRM;\n END;\n\n SELECT * INTO v_next FROM public.plg_automations_flow_steps s\n WHERE s.flow_id = e.flow_id AND s.position > v_step.position\n ORDER BY s.position LIMIT 1;\n END IF;\n\n IF v_next.id IS NULL THEN\n UPDATE public.plg_automations_enrollments\n SET status = 'completed', current_position = NULL,\n exited_at = now(), updated_at = now(),\n -- A cadence that ended on a step that could not run did not\n -- finish; saying so is the difference between \"nobody answers the\n -- third message\" and \"the third message never left\".\n exit_reason = CASE WHEN v_error IS NOT NULL\n THEN 'last step failed: ' || v_error END\n WHERE id = e.id;\n v_done := v_done + 1;\n ELSE\n UPDATE public.plg_automations_enrollments\n SET current_position = v_next.position,\n next_run_at = now() + make_interval(mins => v_next.delay_minutes),\n updated_at = now()\n WHERE id = e.id;\n END IF;\n\n v_next := NULL; v_step := NULL; v_error := NULL;\n END LOOP;\n\n RETURN jsonb_build_object('steps_ran', v_ran, 'completed', v_done, 'failed', v_failed);\nEND $$;\n\nREVOKE ALL ON FUNCTION public.automations_flow_enroll(uuid, uuid, uuid, text, uuid) FROM PUBLIC;\nGRANT EXECUTE ON FUNCTION public.automations_flow_enroll(uuid, uuid, uuid, text, uuid) TO service_role;\nREVOKE ALL ON FUNCTION public.automations_flow_exit(uuid, uuid, text, uuid[]) FROM PUBLIC;\nGRANT EXECUTE ON FUNCTION public.automations_flow_exit(uuid, uuid, text, uuid[]) TO authenticated;\nGRANT EXECUTE ON FUNCTION public.automations_flow_exit(uuid, uuid, text, uuid[]) TO service_role;\nREVOKE ALL ON FUNCTION public.automations_flows_run_due(integer) FROM PUBLIC;\nGRANT EXECUTE ON FUNCTION public.automations_flows_run_due(integer) TO service_role;\n\n-- ββ the two handlers the event log calls ββββββββββββββββββββββββββββββββ\n\n-- Who the event is about.\n--\n-- \\`consume_event_log\\` calls a handler with \\`to_jsonb(v_event)\\` β the whole\n-- \\`event_log\\` ROW. So \\`tenant_id\\`, \\`event_key\\`, \\`subject_type\\` and \\`subject_id\\`\n-- are at the top level and everything the emitter chose to send is nested under\n-- \\`payload\\`. The first cut read \\`person_id\\` at the top level, where it never is:\n-- every delivery answered \"payload carries no tenant, person or event\", was\n-- marked DELIVERED, and the cadence enrolled nobody, ever, with nothing\n-- reporting it.\n--\n-- \\`subject_id\\` first, because that is the convention the shipped handlers use\n-- (\\`plg_notifications_on_fulfillment_completed\\` reads exactly that), and it is\n-- \\`text\\` on the row. The payload fallbacks are for emitters that name the person\n-- there instead.\nCREATE OR REPLACE FUNCTION public.automations_event_person(p_event jsonb)\nRETURNS uuid\nLANGUAGE sql IMMUTABLE\nSET search_path TO ''\nAS $$\n SELECT nullif(coalesce(\n CASE WHEN p_event ->> 'subject_type' IN ('lead', 'person', 'contact')\n THEN p_event ->> 'subject_id' END,\n p_event -> 'payload' ->> 'person_id',\n p_event -> 'payload' ->> 'lead_id',\n p_event -> 'payload' ->> 'contact_id',\n p_event ->> 'person_id',\n p_event ->> 'lead_id'\n ), '')::uuid\n$$;\n\nREVOKE ALL ON FUNCTION public.automations_event_person(jsonb) FROM PUBLIC;\nGRANT EXECUTE ON FUNCTION public.automations_event_person(jsonb) TO service_role;\n\n-- Enrol on the flow's entry event. The payload names the person; a fact that\n-- does not carry one cannot start a cadence.\nCREATE OR REPLACE FUNCTION public.plg_automations_on_entry_event(p_event jsonb)\nRETURNS jsonb\nLANGUAGE plpgsql SECURITY DEFINER\nSET search_path TO ''\nAS $$\nDECLARE\n v_tenant uuid := nullif(p_event ->> 'tenant_id', '')::uuid;\n v_event text := p_event ->> 'event_key';\n v_person uuid := public.automations_event_person(p_event);\n f record; v_n integer := 0;\nBEGIN\n IF v_tenant IS NULL OR v_person IS NULL OR v_event IS NULL THEN\n RETURN jsonb_build_object('enrolled', 0, 'reason', 'event carries no tenant, person or key');\n END IF;\n\n FOR f IN SELECT id FROM public.plg_automations_flows\n WHERE tenant_id = v_tenant AND entry_event = v_event AND is_active\n LOOP\n IF public.automations_flow_enroll(\n v_tenant, f.id, v_person,\n p_event ->> 'subject_type', nullif(p_event ->> 'subject_id', '')::uuid) IS NOT NULL THEN\n v_n := v_n + 1;\n END IF;\n END LOOP;\n\n RETURN jsonb_build_object('enrolled', v_n);\nEND $$;\n\n-- Leave the flows whose own \\`exit_events\\` name this fact.\nCREATE OR REPLACE FUNCTION public.plg_automations_on_exit_event(p_event jsonb)\nRETURNS jsonb\nLANGUAGE plpgsql SECURITY DEFINER\nSET search_path TO ''\nAS $$\nDECLARE\n v_tenant uuid := nullif(p_event ->> 'tenant_id', '')::uuid;\n v_event text := p_event ->> 'event_key';\n v_person uuid := public.automations_event_person(p_event);\n v_flows uuid[]; v_n integer := 0;\nBEGIN\n IF v_tenant IS NULL OR v_person IS NULL OR v_event IS NULL THEN\n RETURN jsonb_build_object('exited', 0, 'reason', 'event carries no tenant, person or key');\n END IF;\n\n SELECT array_agg(id) INTO v_flows\n FROM public.plg_automations_flows\n WHERE tenant_id = v_tenant AND is_active AND v_event = ANY (exit_events);\n\n IF v_flows IS NOT NULL THEN\n v_n := public.automations_flow_exit(v_tenant, v_person, v_event, v_flows);\n END IF;\n\n RETURN jsonb_build_object('exited', v_n);\nEND $$;\n\nREVOKE ALL ON FUNCTION public.plg_automations_on_entry_event(jsonb) FROM PUBLIC;\nGRANT EXECUTE ON FUNCTION public.plg_automations_on_entry_event(jsonb) TO service_role;\nREVOKE ALL ON FUNCTION public.plg_automations_on_exit_event(jsonb) FROM PUBLIC;\nGRANT EXECUTE ON FUNCTION public.plg_automations_on_exit_event(jsonb) TO service_role;\n\n-- ββ subscription ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\n-- The manifest DECLARES the reaction; this is what makes the event log call it.\n-- Both handlers on every CRM fact, because which fact opens a cadence and which\n-- closes it is the operator's choice: the handler looks the flow up and returns\n-- immediately when no flow in that tenant names the event.\n-- Written out one call per line rather than looped over an array. The loop was\n-- shorter and \\`check-event-contract\\` could not read it: its registration parser\n-- matches literal arguments, so a FOREACH registering fourteen subscriptions\n-- looked like zero. Same lesson as the manifest side β the gate reads source,\n-- so the source has to say it.\nSELECT public.register_event_subscription('automations', 'crm.lead_created', 'plg_automations_on_entry_event',\n 'Enrol into flows whose entry event is crm.lead_created', 5);\nSELECT public.register_event_subscription('automations', 'crm.lead_created', 'plg_automations_on_exit_event',\n 'Leave flows that exit on crm.lead_created', 5);\nSELECT public.register_event_subscription('automations', 'crm.stage_changed', 'plg_automations_on_entry_event',\n 'Enrol into flows whose entry event is crm.stage_changed', 5);\nSELECT public.register_event_subscription('automations', 'crm.stage_changed', 'plg_automations_on_exit_event',\n 'Leave flows that exit on crm.stage_changed', 5);\nSELECT public.register_event_subscription('automations', 'crm.quote_sent', 'plg_automations_on_entry_event',\n 'Enrol into flows whose entry event is crm.quote_sent', 5);\nSELECT public.register_event_subscription('automations', 'crm.quote_sent', 'plg_automations_on_exit_event',\n 'Leave flows that exit on crm.quote_sent', 5);\nSELECT public.register_event_subscription('automations', 'crm.quote_approved', 'plg_automations_on_entry_event',\n 'Enrol into flows whose entry event is crm.quote_approved', 5);\nSELECT public.register_event_subscription('automations', 'crm.quote_approved', 'plg_automations_on_exit_event',\n 'Leave flows that exit on crm.quote_approved', 5);\nSELECT public.register_event_subscription('automations', 'crm.deal_won', 'plg_automations_on_entry_event',\n 'Enrol into flows whose entry event is crm.deal_won', 5);\nSELECT public.register_event_subscription('automations', 'crm.deal_won', 'plg_automations_on_exit_event',\n 'Leave flows that exit on crm.deal_won', 5);\nSELECT public.register_event_subscription('automations', 'crm.deal_lost', 'plg_automations_on_entry_event',\n 'Enrol into flows whose entry event is crm.deal_lost', 5);\nSELECT public.register_event_subscription('automations', 'crm.deal_lost', 'plg_automations_on_exit_event',\n 'Leave flows that exit on crm.deal_lost', 5);\nSELECT public.register_event_subscription('automations', 'crm.deal_idle', 'plg_automations_on_entry_event',\n 'Enrol into flows whose entry event is crm.deal_idle', 5);\nSELECT public.register_event_subscription('automations', 'crm.deal_idle', 'plg_automations_on_exit_event',\n 'Leave flows that exit on crm.deal_idle', 5);\n\n-- ββ view ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\n-- Per-step numbers, which is the question a cadence is judged by: where do\n-- people stop. Aggregating per FLOW would hide that the third message is the\n-- one nobody answers.\nCREATE OR REPLACE VIEW public.v_automations_flow_steps WITH (security_invoker='true') AS\n SELECT\n s.tenant_id, s.flow_id, s.id AS step_id, s.position, s.kind,\n s.template_key, s.channel, s.delay_minutes, s.task_title,\n count(q.id) FILTER (WHERE q.id IS NOT NULL) AS queued,\n count(q.id) FILTER (WHERE q.status = 'sent') AS sent,\n count(q.id) FILTER (WHERE q.status = 'blocked') AS blocked,\n count(q.id) FILTER (WHERE q.status = 'failed') AS failed,\n count(q.id) FILTER (WHERE q.status = 'cancelled') AS cancelled\n FROM public.plg_automations_flow_steps s\n LEFT JOIN public.plg_automations_enrollments e ON e.flow_id = s.flow_id\n LEFT JOIN public.plg_notifications_queue q\n ON q.dedupe_key = 'flow:' || e.id::text || ':' || s.position::text\n GROUP BY s.tenant_id, s.flow_id, s.id, s.position, s.kind,\n s.template_key, s.channel, s.delay_minutes, s.task_title;\n\nGRANT SELECT ON public.v_automations_flow_steps TO authenticated;\nGRANT SELECT ON public.v_automations_flow_steps TO service_role;\n`\n\nexport const MIGRATIONS: Array<{ id: string; sql: string }> = [\n { id: \"000_baseline\", sql: MIGRATION_000_BASELINE },\n { id: \"001_the_flow_has_steps\", sql: MIGRATION_001_THE_FLOW_HAS_STEPS },\n]\n","import React from 'react'\nimport type { PluginManifest, PluginScope, VerticalId } from '@fayz-ai/core'\nimport { startEventLog } from '@fayz-ai/core'\nimport { resolveFayzAgentConnection, registerRailPage, type RailPageProps } from '@fayz-ai/admin'\nimport { AutomationsList } from './views/AutomationsList'\nimport { AutomationDetailPage } from './views/AutomationDetailPage'\nimport { createSupabaseTemplateStore, type MessageTemplateStore } from './data/templates'\nimport { createFayzTemplateStore } from './data/fayz'\nimport { FlowsPage } from './views/FlowsPage'\nimport { automationsLocales } from './locales'\nimport { MIGRATIONS } from './migrations'\n\n\n// ---------------------------------------------------------------------------\n// @fayz-ai/plugin-automations β everything the product SENDS, in one place.\n//\n// ONE automation = when THIS happens, send THAT over THIS channel.\n//\n// Events do NOT live here. Each module DECLARES them in its own manifest\n// (`events`) and the runtime aggregates the active plugins' β the store brings\n// the order's, the CRM the pipeline's. If this screen had to import store and\n// CRM, an app installing only the CRM would carry the store catalog too, and\n// every new module would mean another import in here.\n//\n// The same catalog feeds integrations (webhooks) and audit: three readers of the\n// SAME fact, which is why the message text is not part of it.\n// ---------------------------------------------------------------------------\n\nexport interface AutomationsPluginOptions {\n navPosition?: number\n navSection?: 'main' | 'secondary' | 'settings'\n navLabel?: string\n /**\n * Where the list lives.\n *\n * 'nav' its own menu item (default) β for apps where sending is daily\n * routine, like the store.\n * 'settings' a tab inside settings, no menu item. In a salon the calendar is\n * what runs all day; automations are configured once, and a fixed\n * top-level item charges attention daily for a monthly screen.\n */\n placement?: 'nav' | 'settings'\n scope?: PluginScope\n verticalId?: VerticalId\n /** Swaps data access (tests, mock mode). */\n store?: MessageTemplateStore\n}\n\nexport function createAutomationsPlugin(options?: AutomationsPluginOptions): PluginManifest {\n // Built once per manifest: the store holds no state, and rebuilding it every\n // render would remount the effects that depend on it.\n // Behind a Fayz project the platform executes the automations, so the\n // customisations live there; outside one, the local table keeps working.\n const connection = resolveFayzAgentConnection()\n const store = options?.store\n ?? (connection ? createFayzTemplateStore(connection) : createSupabaseTemplateStore())\n\n // Turns on the trigger history. Idempotent, and from here on EVERY event the\n // app emits is recorded, not only those with a message β it is the same\n // history webhooks and audit read.\n startEventLog()\n\n const inSettings = options?.placement === 'settings'\n\n const ListPage: React.ComponentType<unknown> = () =>\n React.createElement(AutomationsList, { store })\n ListPage.displayName = 'AutomationsList'\n\n // A mesma lista servida DENTRO de ConfiguraΓ§Γ΅es: a shell jΓ‘ nomeou a tela, e\n // as abas tΓͺm de ser as dos outros painΓ©is de lΓ‘, nΓ£o a faixa de um mΓ³dulo.\n // `basePath` leva o detalhe junto β dentro de ConfiguraΓ§Γ΅es ele abre sob\n // `/settings/automations`, para a pessoa nΓ£o ser jogada para fora da tela.\n const SettingsListPage: React.ComponentType<unknown> = () =>\n React.createElement(AutomationsList, { store, variant: 'panel', basePath: '/settings/automations' })\n SettingsListPage.displayName = 'AutomationsSettings'\n\n // O detalhe, oferecido para quem quiser abri-lo na coluna sem sair da tela em\n // que estΓ‘. O raio do CRM Γ© o primeiro a pedir: ele aponta para o MESMO fato\n // que a linha do tempo mostra, e mandar a pessoa para outra pΓ‘gina para ver\n // \"o que este fato dispara\" custava o funil que ela estava lendo.\n const RailDetail: React.FC<RailPageProps> = ({ params, onClose }) =>\n React.createElement(AutomationDetailPage, {\n eventKey: params.eventKey,\n channel: params.channel,\n store,\n backTo: inSettings ? '/settings/automations' : '/automations',\n embedded: true,\n onDone: onClose,\n })\n RailDetail.displayName = 'AutomationRailDetail'\n registerRailPage('automations.detail', RailDetail)\n\n const READ = { feature: 'automations', action: 'read' as const }\n\n return {\n id: 'automations',\n defaultAgentRole: 'setup',\n name: options?.navLabel ?? 'AutomaΓ§Γ΅es',\n icon: 'Zap',\n version: '2.0.0',\n scope: options?.scope ?? 'universal',\n verticalId: options?.verticalId,\n defaultEnabled: true,\n dependencies: [],\n declaredFeatures: [{ id: 'automations', label: 'Automations', group: 'Automate' }],\n navigation: inSettings ? [] : [\n {\n section: options?.navSection ?? 'main',\n position: options?.navPosition ?? 6,\n label: options?.navLabel ?? 'AutomaΓ§Γ΅es',\n route: '/automations',\n icon: 'Zap',\n permission: READ,\n indexChild: false,\n },\n // SEM linha para `/automations/flows`.\n //\n // A rΓ©gua de relacionamento tem UMA tela e ela se planeja no Marketing\n // (`cadenceSurface`), que Γ© onde \"como a casa fala com quem ainda nΓ£o\n // comprou\" Γ© decisΓ£o. A linha aqui era a segunda porta para a mesma tela,\n // pendurada como filha de AutomaΓ§Γ΅es β e AutomaΓ§Γ΅es Γ© uma tela sΓ³, que\n // abre inteira. A rota continua de pΓ© (ver `routes`), entΓ£o quem chega\n // pelo Marketing ou por link direto nΓ£o perde nada.\n ],\n // The SAME list, served inside settings β not a second screen.\n settings: inSettings ? [\n { id: 'automations', label: options?.navLabel ?? 'AutomaΓ§Γ΅es', icon: 'Zap', component: SettingsListPage, permission: READ },\n ] : [],\n routes: [\n { path: '/automations', component: ListPage, permission: READ },\n // O detalhe de uma automaΓ§Γ£o Γ© a MESMA tela com a coluna da direita\n // aberta β a lista continua atrΓ‘s dela. Por isso o curinga aponta para o\n // mesmo componente: a shell colapsa '/x' e '/x/*' na mesma chave, entΓ£o a\n // pΓ‘gina nΓ£o remonta ao abrir o painel (ver AdminShell.routeKey). Um\n // segundo componente aqui traria de volta a troca de tela.\n // Flows are their OWN route, not a tab of the list. A one-step automation\n // and a cadence answer different questions β \"does the order confirmation\n // go out\" versus \"where do people stop\" β and the wildcard above already\n // owns the right rail, so a tab here would fight it for the same URL.\n { path: '/automations/flows', component: FlowsPage, permission: READ },\n { path: '/automations/*', component: ListPage, permission: READ },\n ],\n // A flow names its own entry and exit events, but a SUBSCRIPTION is a row:\n // static, written at install time. So both handlers listen to the whole CRM\n // fact catalogue and each one decides whether any flow cares β the handler\n // is a lookup against `plg_automations_flows`, and a tenant with no flow on\n // that event does one indexed read and returns.\n //\n // Both handlers on every event on purpose: which facts open a cadence and\n // which close it is the operator's choice, not ours. A house may well start\n // a win-back flow on `crm.deal_lost`.\n //\n // Written out one by one rather than generated from CADENCE_FACTS. The\n // generated form read better and was invisible to `check-event-contract`,\n // whose regex needs a literal `subscribesTo: [ β¦ ]` with literal event and\n // handler strings β so fourteen subscriptions that nothing registered\n // passed the gate in silence. A contract a checker cannot read is not a\n // contract.\n subscribesTo: [\n { event: 'crm.lead_created', handler: 'plg_automations_on_entry_event', description: 'Enrol into flows entered by a new lead', maxAttempts: 5 },\n { event: 'crm.lead_created', handler: 'plg_automations_on_exit_event', description: 'Leave flows that exit on a new lead', maxAttempts: 5 },\n { event: 'crm.stage_changed', handler: 'plg_automations_on_entry_event', description: 'Enrol into flows entered by a stage change', maxAttempts: 5 },\n { event: 'crm.stage_changed', handler: 'plg_automations_on_exit_event', description: 'Leave flows that exit on a stage change', maxAttempts: 5 },\n { event: 'crm.quote_sent', handler: 'plg_automations_on_entry_event', description: 'Enrol into flows entered by a sent quote', maxAttempts: 5 },\n { event: 'crm.quote_sent', handler: 'plg_automations_on_exit_event', description: 'Leave flows that exit on a sent quote', maxAttempts: 5 },\n { event: 'crm.quote_approved', handler: 'plg_automations_on_entry_event', description: 'Enrol into flows entered by an approved quote', maxAttempts: 5 },\n { event: 'crm.quote_approved', handler: 'plg_automations_on_exit_event', description: 'Leave flows that exit on an approved quote', maxAttempts: 5 },\n { event: 'crm.deal_won', handler: 'plg_automations_on_entry_event', description: 'Enrol into flows entered by a won deal', maxAttempts: 5 },\n { event: 'crm.deal_won', handler: 'plg_automations_on_exit_event', description: 'Leave flows that exit on a won deal', maxAttempts: 5 },\n { event: 'crm.deal_lost', handler: 'plg_automations_on_entry_event', description: 'Enrol into flows entered by a lost deal', maxAttempts: 5 },\n { event: 'crm.deal_lost', handler: 'plg_automations_on_exit_event', description: 'Leave flows that exit on a lost deal', maxAttempts: 5 },\n { event: 'crm.deal_idle', handler: 'plg_automations_on_entry_event', description: 'Enrol into flows entered by an idle deal', maxAttempts: 5 },\n { event: 'crm.deal_idle', handler: 'plg_automations_on_exit_event', description: 'Leave flows that exit on an idle deal', maxAttempts: 5 },\n ],\n // The barrel an app installing this plugin applies. Without it the tables\n // and functions below simply do not exist there: `chain.json` provisions a\n // CLUSTER, and the manifest is what provisions an app β this plugin had\n // neither a `migrations` key nor a barrel to point it at, so fourteen\n // subscriptions and a whole screen shipped over nothing.\n migrations: MIGRATIONS.map((m) => ({\n id: `automations-${m.id}`,\n version: '1.0.0',\n sql: m.sql,\n description: m.id,\n })),\n locales: automationsLocales,\n widgets: [],\n }\n}\n\nexport { createSupabaseTemplateStore }\nexport { createFayzTemplateStore } from './data/fayz'\nexport type { MessageTemplateStore }\n// O que a Meta respondeu sobre cada modelo. Exportado porque a decisΓ£o \"esta\n// automaΓ§Γ£o de WhatsApp vai mesmo sair?\" Γ© lida fora desta lista β o painel do\n// conector e o provisionamento perguntam a mesma coisa.\nexport {\n loadProviderTemplates, providerTemplateFor, PROVIDER_TEMPLATES_TABLE,\n type ProviderTemplateRow, type ProviderTemplateStatus,\n} from './data/provider-templates'\nexport { providerApprovalFor, type ProviderApproval } from './views/ProviderTemplateStatus'\n\n// ---------------------------------------------------------------------------\n// A tela das cadΓͺncias, exportada como COMPONENTE.\n//\n// Uma cadΓͺncia Γ© o mesmo objeto visto de dois lugares: quem automatiza o funil\n// chega por /automations/flows; quem planeja a rΓ©gua de relacionamento chega\n// pelo Marketing. Exportar a superfΓcie (em vez de o Marketing reimplementΓ‘-la,\n// ou importar este pacote) Γ© o que mantΓ©m UMA tela e UM motor: o app injeta\n// isto no `cadenceSurface` do plugin-marketing e os dois caminhos mostram as\n// mesmas linhas.\n// ---------------------------------------------------------------------------\nexport { FlowsPage as CadenceFlowsSurface } from './views/FlowsPage'\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/data/payment-preflight.ts","../src/data/test-send.ts","../src/lib/runtime.ts","../src/data/fayz.ts","../src/views/RunLog.tsx","../src/views/whatsapp-preview-bg.ts","../src/data/provider-templates.ts","../src/views/ProviderTemplateStatus.tsx","../src/views/AutomationDetailPage.tsx","../src/lib/connector-automations.ts","../src/views/ConnectorAutomations.tsx","../src/views/AutomationsList.tsx","../src/data/templates.ts","../src/views/CadenceComposer.tsx","../src/data/flows.ts","../src/views/FlowsPage.tsx","../src/locales/en.ts","../src/locales/pt-BR.ts","../src/locales/index.ts","../src/migrations/index.ts","../src/index.ts"],"names":["React","getSupabaseClientOptional","getActiveTenantId","row","jsxs","jsx","Badge","Button","store","current","Card","Fragment","adminNavigateTo","ChevronRight","CHANNEL_ICON","Mail","WhatsAppIcon","Smartphone","MessageSquare","CHANNEL_LABEL","Zap","usePluginRuntimeOptional","useAgentSurface","toast","Switch","errorMessage","data","error","useTranslation","Clock","useState","useEffect","PageHeaderActions","PageActions","resolveFayzAgentConnection"],"mappings":"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AAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;;AAAA;AAAA;;AAAA;AAAA;;;AAAA;;AAAA;;AAAA;;AAAA;;AAAA;;AAAA;;;AAAA;;AAAA;AAAA;;;AAAA;;AAAA;;AAAA;;;AAAA;;AAAA;;AAAA;;;AAAA;;AAAA;;AAAA;;;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;;AAAA;;AAAA;;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAgV/B,IAAM,gCAAA,GAAmC,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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","file":"index.js","sourcesContent":["// \"Can this app take a Pix?\" β asked here so the editor does not offer a button\n// that would produce a charge nobody can open.\n//\n// ββ Why this is a second copy βββββββββββββββββββββββββββββββββββββββββββββββ\n// The function is `tyxter-payment-preflight`, it is OWNED by plugin-conversations\n// (which ships its source and declares it in its manifest), and that plugin\n// exports a richer reader of the same answer. This is not that reader, because\n// plugins in this repo do not depend on one another β there is no\n// @fayz-ai/plugin-conversations in this package.json and adding one would make\n// the automations screen refuse to build in an app that installs automations\n// without the inbox.\n//\n// So the shared thing is the FUNCTION, and the duplicated thing is one invoke.\n// The half that could drift β what \"ready\" means, which modes count β is the\n// function's answer, not this file's opinion.\n//\n// Absence is not failure: an app with no WhatsApp connector at all gets a null\n// readiness, and the editor shows the pay action disabled with a reason rather\n// than an error.\nimport { getActiveTenantId, getSupabaseClientOptional } from '@fayz-ai/core'\nimport * as React from 'react'\n\nconst PREFLIGHT_FUNCTION = 'tyxter-payment-preflight'\n\nexport interface PaymentReadiness {\n ready: boolean\n status: string\n /** 'abacate_pay' is production; 'sandbox_default' works end to end with money\n * that is not real; null means nothing is selected behind the channel. */\n mode: string | null\n sandbox: boolean\n reason: string | null\n}\n\ninterface MinimalClient {\n functions: {\n invoke: (name: string, options: { body: unknown }) => Promise<{ data: unknown; error: unknown }>\n }\n}\n\nasync function readReadiness(): Promise<PaymentReadiness | null> {\n const supabase = getSupabaseClientOptional() as MinimalClient | null\n const tenantId = getActiveTenantId()\n if (!supabase || !tenantId) return null\n const { data, error } = await supabase.functions.invoke(PREFLIGHT_FUNCTION, {\n body: { action: 'status', tenantId },\n })\n if (error) return null\n const payments = (data as { payments?: PaymentReadiness } | null)?.payments\n return payments ?? null\n}\n\n/** Ready AND with a rail actually selected. See PaymentReadiness.mode. */\nexport function canOfferPayment(readiness: PaymentReadiness | null): boolean {\n return Boolean(readiness?.ready) && readiness?.mode !== null && readiness?.mode !== undefined\n}\n\n/**\n * One read per screen, never thrown.\n *\n * `loading` is distinguished from \"not ready\" on purpose: a pay toggle that\n * flickers from enabled to disabled while an edge function answers is a toggle\n * somebody clicks in the gap.\n */\nexport function usePaymentReadiness(): { readiness: PaymentReadiness | null; loading: boolean } {\n const [readiness, setReadiness] = React.useState<PaymentReadiness | null>(null)\n const [loading, setLoading] = React.useState(true)\n\n React.useEffect(() => {\n let cancelled = false\n void readReadiness()\n .then((value) => { if (!cancelled) setReadiness(value) })\n .catch(() => { /* absence is not failure */ })\n .finally(() => { if (!cancelled) setLoading(false) })\n return () => { cancelled = true }\n }, [])\n\n return { readiness, loading }\n}\n","// \"Enviar teste\" β the message, sent for real, to the operator's own phone.\n//\n// Same function, same template resolution, same sender resolution as the\n// automation's send (`messaging-send`); the only differences are who is calling\n// (the operator's session instead of the platform secret) and the subject type,\n// which is forced to 'test' so a tapped Confirmar on the test message routes\n// nowhere. A preview that renders locally can lie about template approval and\n// sender state β a test that walks the real path cannot.\nimport { getActiveTenantId, getSupabaseClientOptional } from '@fayz-ai/core'\n\nconst SEND_FUNCTION = 'messaging-send'\n\ninterface MinimalClient {\n functions: {\n invoke: (name: string, options: { body: unknown }) => Promise<{ data: unknown; error: unknown }>\n }\n}\n\nexport interface TestSendResult {\n ok: boolean\n /** A code the editor can phrase: 'template_not_approved', 'no_sender', β¦ */\n error?: string\n message?: string\n}\n\nfunction readFunctionError(error: unknown, data: unknown): TestSendResult {\n const payload = (data ?? null) as { error?: string; message?: string } | null\n if (payload?.error) return { ok: false, error: payload.error, message: payload.message }\n const context = (error as { context?: { error?: string; message?: string } } | null)?.context\n if (context?.error) return { ok: false, error: context.error, message: context.message }\n return { ok: false, error: 'send_failed', message: error instanceof Error ? error.message : undefined }\n}\n\nexport async function sendTestMessage(input: {\n eventKey: string\n channel: string\n to: string\n variables: Record<string, string>\n /** Email only: send this draft instead of the saved template row. */\n template?: { subject: string; body: string }\n}): Promise<TestSendResult> {\n const supabase = getSupabaseClientOptional() as MinimalClient | null\n const tenantId = getActiveTenantId()\n if (!supabase || !tenantId) return { ok: false, error: 'not_available' }\n const { data, error } = await supabase.functions.invoke(SEND_FUNCTION, {\n body: {\n test: true,\n tenantId,\n channel: input.channel,\n eventKey: input.eventKey,\n to: input.to,\n variables: input.variables,\n subject: { type: 'test', id: crypto.randomUUID() },\n ...(input.template ? { template: input.template } : {}),\n },\n })\n if (error || (data as { error?: string } | null)?.error) return readFunctionError(error, data)\n return { ok: true }\n}\n","import { useOrganizationStore } from '@fayz-ai/admin'\n\n// Re-exports para as views nΓ£o precisarem saber de onde vem cada peΓ§a.\nexport {\n resolveMessages, resolveMessage, renderMessageTemplate,\n getEventsWithoutMessages,\n} from '@fayz-ai/core'\n\n/** Conta ativa β todo modelo Γ© escopado nela. */\nexport function useOrganizationStoreLike(): string | undefined {\n return useOrganizationStore((s) => s.currentOrg?.id)\n}\n","import { getFayzSupabaseClientOptional } from '@fayz-ai/admin'\nimport type { ResolvedFayzAgentConnection } from '@fayz-ai/admin'\nimport { getMessageDefaults } from '@fayz-ai/core'\nimport type { MessageChannel, MessageTemplate } from '@fayz-ai/core'\nimport {\n createFayzAutomationsClient,\n FayzAutomationsError,\n type FayzAutomation,\n type FayzAutomationsClient,\n} from '@fayz-ai/sdk/automations'\nimport type { MessageTemplateStore } from './templates'\n\n// ---------------------------------------------------------------------------\n// The SAME contract as `templates.ts`, served by the platform: behind a Fayz\n// project the platform is what runs the automations, so the customisation has\n// to live there β a local row the platform never reads is a fake switch.\n// ---------------------------------------------------------------------------\n\nfunction toTemplate(automation: FayzAutomation): MessageTemplate | null {\n const eventKey = automation.triggerConfig?.eventKey\n // No eventKey means it isn't a catalogue automation β standalone platform\n // flows have no row on this screen.\n if (!eventKey) return null\n const action = automation.actions?.[0]\n return {\n id: automation.id,\n tenantId: automation.tenantId ?? '',\n eventKey,\n channel: (automation.triggerConfig.sourceChannel ?? 'email') as MessageChannel,\n enabled: automation.enabled,\n // Empty and absent mean the same β \"no customisation\", the catalogue default.\n subject: action?.config?.subject || null,\n body: action?.config?.body || null,\n // The automation name belongs to the platform, not a user rename: the\n // catalogue title still owns the screen.\n name: null,\n // The platform's automation action carries a subject and a body and nothing\n // else, so there is nowhere for a customised button to live yet. NULL, not\n // [], because the catalogue default is what still applies β an empty list\n // would read as \"this tenant removed the buttons\".\n actions: null,\n updatedAt: automation.updatedAt,\n }\n}\n\nfunction catalogDefaultEnabled(eventKey: string, channel: MessageChannel): boolean {\n const def = getMessageDefaults().find((d) => d.eventKey === eventKey)\n return def?.defaultEnabled?.[channel] ?? false\n}\n\nasync function defaultSessionToken(): Promise<string | null> {\n const session = (await getFayzSupabaseClientOptional()?.auth.getSession())?.data.session\n return session?.access_token ?? null\n}\n\nexport interface FayzTemplateStoreDeps {\n client?: FayzAutomationsClient\n getSessionToken?: () => Promise<string | null>\n}\n\nexport function createFayzTemplateStore(\n connection: ResolvedFayzAgentConnection,\n deps: FayzTemplateStoreDeps = {},\n): MessageTemplateStore {\n const client = deps.client ?? createFayzAutomationsClient({\n baseUrl: connection.apiBaseUrl,\n projectId: connection.projectId,\n publishableKey: connection.publishableKey,\n })\n const getSessionToken = deps.getSessionToken ?? defaultSessionToken\n\n // (event_key, channel) β platform automation id, repopulated on every list.\n const ids = new Map<string, string>()\n const keyOf = (eventKey: string, channel: string) => `${eventKey}:${channel}`\n\n async function refresh(tenantId: string): Promise<MessageTemplate[]> {\n const automations = await client.list({ tenantId })\n ids.clear()\n const rows: MessageTemplate[] = []\n for (const automation of automations) {\n const row = toTemplate(automation)\n if (!row) continue\n ids.set(keyOf(row.eventKey, row.channel), automation.id)\n rows.push(row)\n }\n return rows\n }\n\n // One screen mounts several views of the same catalogue (list, detail, CRM β‘)\n // and StrictMode doubles effects in dev β unshared, opening it costs 8+ identical\n // GETs. One flight per tenant, short-lived; writes invalidate.\n const LIST_TTL_MS = 30_000\n let cache: { tenantId: string; at: number; promise: Promise<MessageTemplate[]> } | null = null\n\n function invalidate(): void {\n cache = null\n }\n\n function load(tenantId: string): Promise<MessageTemplate[]> {\n if (cache && cache.tenantId === tenantId && Date.now() - cache.at < LIST_TTL_MS) return cache.promise\n const promise = refresh(tenantId)\n promise.catch(() => {\n if (cache?.promise === promise) cache = null // a failure must not stay cached for 30s\n })\n cache = { tenantId, at: Date.now(), promise }\n return promise\n }\n\n async function requireToken(): Promise<string> {\n const token = await getSessionToken()\n // Writing needs the app session β same message as the rest of the admin.\n if (!token) throw new Error('SessΓ£o expirada β entre de novo.')\n return token\n }\n\n async function resolveId(eventKey: string, channel: string, tenantId: string): Promise<string | undefined> {\n const key = keyOf(eventKey, channel)\n if (!ids.has(key)) await load(tenantId)\n return ids.get(key)\n }\n\n return {\n async list(tenantId) {\n // No account yet, nothing to ask β the catalogue at its defaults is a\n // complete state, same as the local store when the read fails.\n if (!tenantId) return []\n return load(tenantId)\n },\n\n async upsert(input, tenantId) {\n if (!tenantId) throw new Error('@fayz-ai/plugin-automations: tenantId is required')\n const appSessionToken = await requireToken()\n const key = keyOf(input.eventKey, input.channel)\n let id = await resolveId(input.eventKey, input.channel, tenantId)\n\n if (!id) {\n const action: { subject?: string; body?: string } = {}\n if (input.subject != null) action.subject = input.subject\n if (input.body != null) action.body = input.body\n try {\n const created = await client.create({\n tenantId,\n appSessionToken,\n eventKey: input.eventKey,\n sourceChannel: input.channel,\n // The platform has no \"inherit from catalogue\": materialise the default.\n enabled: input.enabled ?? catalogDefaultEnabled(input.eventKey, input.channel),\n ...(Object.keys(action).length ? { action } : {}),\n })\n ids.set(key, created.id)\n invalidate()\n const row = toTemplate(created)\n if (!row) throw new Error('@fayz-ai/plugin-automations: platform did not round-trip eventKey')\n return row\n } catch (err) {\n // 409: someone created it first β turn it into an update.\n if (!(err instanceof FayzAutomationsError) || err.status !== 409) throw err\n invalidate()\n await refresh(tenantId)\n id = ids.get(key)\n if (!id) throw err\n }\n }\n\n const updated = await client.update({\n id,\n tenantId,\n appSessionToken,\n // Only what was sent: omitting has to mean \"leave it alone\", as in the local store.\n ...(typeof input.enabled === 'boolean' ? { enabled: input.enabled } : {}),\n ...(input.subject !== undefined || input.body !== undefined\n ? {\n action: {\n ...(input.subject !== undefined ? { subject: input.subject } : {}),\n ...(input.body !== undefined ? { body: input.body } : {}),\n },\n }\n : {}),\n })\n invalidate()\n const row = toTemplate(updated)\n if (!row) throw new Error('@fayz-ai/plugin-automations: platform did not round-trip eventKey')\n return row\n },\n\n async reset(eventKey, channel, tenantId) {\n if (!tenantId) return\n const id = await resolveId(eventKey, channel, tenantId)\n // Never customised: the default already applies, nothing to clear.\n if (!id) return\n const appSessionToken = await requireToken()\n // The automation stays (the on/off belongs to it); only the text goes back\n // to the catalogue β null clears the field on the server.\n await client.update({ id, tenantId, appSessionToken, action: { subject: null, body: null } })\n invalidate()\n },\n }\n}\n\nlet cachedClient: { key: string; client: FayzAutomationsClient } | null = null\n\n/** One client per connection β RunLog and the store read the same surface. */\nexport function getFayzAutomationsClient(connection: ResolvedFayzAgentConnection): FayzAutomationsClient {\n const key = `${connection.apiBaseUrl}|${connection.projectId}|${connection.publishableKey}`\n if (cachedClient?.key === key) return cachedClient.client\n const client = createFayzAutomationsClient({\n baseUrl: connection.apiBaseUrl,\n projectId: connection.projectId,\n publishableKey: connection.publishableKey,\n })\n cachedClient = { key, client }\n return client\n}\n","import React from 'react'\nimport { AlertTriangle, ChevronRight, CircleCheck, CircleSlash, History, RefreshCw } from 'lucide-react'\nimport { Badge, Button, Card } from '@fayz-ai/ui'\nimport { loadEventRuns, type EventRun, type EventRunStatus } from '@fayz-ai/core'\nimport type { ResolvedFayzAgentConnection } from '@fayz-ai/admin'\nimport type { FayzAutomationExecution } from '@fayz-ai/sdk/automations'\nimport { getFayzAutomationsClient } from '../data/fayz'\n\n// ---------------------------------------------------------------------------\n// The last runs of this trigger.\n//\n// The screen said what SHOULD happen, never what DID β so testing an automation\n// meant waiting for a customer complaint, and a complaint can't tell \"never\n// fired\" from \"fired and the send failed\", which are defects in different\n// places. The payload stays visible (collapsed) on purpose: it answers \"why did\n// it go out with the wrong name?\" without reproducing the case.\n//\n// Works for ANY trigger: the list is read by event key and every emitted event\n// goes through the same collector, so a new module shows up here untouched.\n// ---------------------------------------------------------------------------\n\nconst STATUS: Record<EventRunStatus, {\n label: string; hint: string; variant: 'success' | 'info' | 'warning' | 'destructive'\n Icon: React.ComponentType<{ className?: string }>\n}> = {\n sent: { label: 'Enviado', hint: 'A mensagem saiu.', variant: 'success', Icon: CircleCheck },\n recorded: {\n label: 'Disparou',\n // Today's honest state: the trigger works, the send doesn't exist yet.\n hint: 'O gatilho disparou e ficou registrado. O envio automΓ‘tico ainda nΓ£o estΓ‘ ligado neste ambiente.',\n variant: 'info', Icon: History,\n },\n skipped: { label: 'Ignorado', hint: 'O gatilho disparou, mas nada foi enviado β automaΓ§Γ£o desligada ou sem canal.', variant: 'warning', Icon: CircleSlash },\n failed: { label: 'Falhou', hint: 'A tentativa de envio quebrou. O erro estΓ‘ na linha.', variant: 'destructive', Icon: AlertTriangle },\n}\n\nfunction when(iso: string): string {\n const then = new Date(iso).getTime()\n const diff = Date.now() - then\n const min = Math.round(diff / 60000)\n if (min < 1) return 'agora'\n if (min < 60) return `hΓ‘ ${min} min`\n const h = Math.round(min / 60)\n if (h < 24) return `hΓ‘ ${h} h`\n return new Date(iso).toLocaleString('pt-BR', { day: '2-digit', month: '2-digit', hour: '2-digit', minute: '2-digit' })\n}\n\nfunction RunRow({ run }: { run: EventRun }) {\n const [open, setOpen] = React.useState(false)\n const cfg = STATUS[run.status] ?? STATUS.recorded\n const { Icon } = cfg\n\n return (\n <div className=\"border-b border-border last:border-b-0\">\n <button\n type=\"button\"\n onClick={() => setOpen(!open)}\n className=\"flex w-full items-center gap-3 px-4 py-2.5 text-left transition-colors hover:bg-muted/40\"\n >\n <ChevronRight className={`h-3.5 w-3.5 shrink-0 text-muted-foreground transition-transform ${open ? 'rotate-90' : ''}`} />\n <Icon className=\"h-3.5 w-3.5 shrink-0 text-muted-foreground\" />\n <Badge variant={cfg.variant}>{cfg.label}</Badge>\n <span className=\"min-w-0 flex-1 truncate text-sm text-muted-foreground\">\n {typeof run.payload.record_name === 'string' ? run.payload.record_name\n : typeof run.payload.customer_name === 'string' ? run.payload.customer_name\n : typeof run.payload.contact_name === 'string' ? run.payload.contact_name\n : run.subjectId ?? 'β'}\n </span>\n <span className=\"shrink-0 text-xs text-muted-foreground\">{when(run.occurredAt)}</span>\n </button>\n\n {open && (\n <div className=\"space-y-3 bg-muted/20 px-4 pb-4 pt-1\">\n <p className=\"text-xs text-muted-foreground\">{cfg.hint}</p>\n <div>\n <p className=\"mb-1 text-[11px] font-medium uppercase tracking-wide text-muted-foreground\">\n Dados do disparo\n </p>\n <pre className=\"overflow-x-auto rounded-md border border-border bg-card p-3 font-mono text-[11px] leading-relaxed\">\n{JSON.stringify(run.payload, null, 2)}\n </pre>\n </div>\n {run.result && (\n <div>\n <p className=\"mb-1 text-[11px] font-medium uppercase tracking-wide text-muted-foreground\">\n Resultado\n </p>\n <pre className=\"overflow-x-auto rounded-md border border-border bg-card p-3 font-mono text-[11px] leading-relaxed\">\n{JSON.stringify(run.result, null, 2)}\n </pre>\n </div>\n )}\n {run.error && (\n <p className=\"rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 font-mono text-[11px] text-destructive\">\n {run.error}\n </p>\n )}\n </div>\n )}\n </div>\n )\n}\n\nexport function RunLog({ eventKey, tenantId, enabled }: {\n eventKey: string\n tenantId?: string\n /** Current automation state β changes what the empty state means. */\n enabled: boolean\n}) {\n const [runs, setRuns] = React.useState<EventRun[] | null>(null)\n const [loading, setLoading] = React.useState(false)\n\n const load = React.useCallback(async () => {\n setLoading(true)\n setRuns(await loadEventRuns(eventKey, { tenantId, limit: 20 }))\n setLoading(false)\n }, [eventKey, tenantId])\n\n React.useEffect(() => { void load() }, [load])\n\n return (\n <Card className=\"overflow-hidden\">\n <div className=\"flex items-center justify-between gap-3 border-b border-border px-4 py-2.5\">\n <div className=\"min-w-0\">\n <span className=\"text-sm font-medium\">ExecuΓ§Γ΅es recentes</span>\n <p className=\"text-xs text-muted-foreground\">Cada vez que este gatilho disparou nesta conta.</p>\n </div>\n <Button variant=\"ghost\" size=\"sm\" onClick={() => void load()} disabled={loading}>\n <RefreshCw className={`h-3.5 w-3.5 ${loading ? 'animate-spin' : ''}`} />\n </Button>\n </div>\n\n {runs === null ? (\n <div className=\"space-y-2 p-4\">\n {[1, 2, 3].map((i) => <div key={i} className=\"h-8 animate-pulse rounded bg-muted/40\" />)}\n </div>\n ) : runs.length === 0 ? (\n <div className=\"flex flex-col items-center gap-1 px-4 py-10 text-center\">\n <History className=\"h-7 w-7 text-muted-foreground/40\" strokeWidth={1.5} />\n <p className=\"text-sm font-medium\">Nenhum disparo ainda</p>\n <p className=\"max-w-sm text-xs text-muted-foreground\">\n {enabled\n ? 'Assim que este evento acontecer, ele aparece aqui β mesmo antes de existir envio.'\n : 'A automaΓ§Γ£o estΓ‘ desligada. O gatilho continua sendo registrado aqui quando o evento acontecer.'}\n </p>\n </div>\n ) : (\n <div>{runs.map((run) => <RunRow key={run.id} run={run} />)}</div>\n )}\n </Card>\n )\n}\n\n// ---------------------------------------------------------------------------\n// The PLATFORM's runs. Behind a Fayz project the send runs there, so the real\n// history is the platform's β the local collector only knows the trigger fired,\n// not what the platform did with it.\n// ---------------------------------------------------------------------------\n\nconst EXEC_STATUS: Record<string, {\n label: string; variant: 'success' | 'info' | 'destructive'\n Icon: React.ComponentType<{ className?: string }>\n}> = {\n success: { label: 'Executada', variant: 'success', Icon: CircleCheck },\n error: { label: 'Falhou', variant: 'destructive', Icon: AlertTriangle },\n}\n\nfunction ExecutionRow({ execution }: { execution: FayzAutomationExecution }) {\n const cfg = EXEC_STATUS[execution.status]\n ?? { label: execution.status, variant: 'info' as const, Icon: History }\n const { Icon } = cfg\n return (\n <div className=\"border-b border-border px-4 py-2.5 last:border-b-0\">\n <div className=\"flex items-center gap-3\">\n <Icon className=\"h-3.5 w-3.5 shrink-0 text-muted-foreground\" />\n <Badge variant={cfg.variant}>{cfg.label}</Badge>\n <span className=\"min-w-0 flex-1 truncate text-sm text-muted-foreground\">\n {execution.automationName}\n </span>\n <span className=\"shrink-0 text-xs text-muted-foreground\">{when(execution.executedAt)}</span>\n </div>\n {execution.error && (\n <p className=\"ml-6 mt-2 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 font-mono text-[11px] text-destructive\">\n {execution.error}\n </p>\n )}\n </div>\n )\n}\n\nexport function FayzRunLog({ connection, eventKey, tenantId, enabled }: {\n connection: ResolvedFayzAgentConnection\n eventKey: string\n tenantId?: string\n /** Current automation state β changes what the empty state means. */\n enabled: boolean\n}) {\n const [executions, setExecutions] = React.useState<FayzAutomationExecution[] | null>(null)\n const [loading, setLoading] = React.useState(false)\n\n const load = React.useCallback(async () => {\n if (!tenantId) return\n setLoading(true)\n try {\n setExecutions(await getFayzAutomationsClient(connection).listExecutions({ tenantId, eventKey, limit: 20 }))\n } catch (err) {\n console.warn('[automations] could not load platform executions', err)\n setExecutions([])\n } finally {\n setLoading(false)\n }\n }, [connection, eventKey, tenantId])\n\n React.useEffect(() => { void load() }, [load])\n\n return (\n <Card className=\"overflow-hidden\">\n <div className=\"flex items-center justify-between gap-3 border-b border-border px-4 py-2.5\">\n <div className=\"min-w-0\">\n <span className=\"text-sm font-medium\">ExecuΓ§Γ΅es recentes</span>\n <p className=\"text-xs text-muted-foreground\">\n O que a plataforma Fayz executou para este gatilho nesta conta.\n </p>\n </div>\n <Button variant=\"ghost\" size=\"sm\" onClick={() => void load()} disabled={loading}>\n <RefreshCw className={`h-3.5 w-3.5 ${loading ? 'animate-spin' : ''}`} />\n </Button>\n </div>\n\n {executions === null ? (\n <div className=\"space-y-2 p-4\">\n {[1, 2, 3].map((i) => <div key={i} className=\"h-8 animate-pulse rounded bg-muted/40\" />)}\n </div>\n ) : executions.length === 0 ? (\n <div className=\"flex flex-col items-center gap-1 px-4 py-10 text-center\">\n <History className=\"h-7 w-7 text-muted-foreground/40\" strokeWidth={1.5} />\n <p className=\"text-sm font-medium\">Nenhuma execuΓ§Γ£o ainda</p>\n <p className=\"max-w-sm text-xs text-muted-foreground\">\n {enabled\n ? 'Assim que este evento acontecer, a plataforma executa a automaΓ§Γ£o e o resultado aparece aqui.'\n : 'A automaΓ§Γ£o estΓ‘ desligada β a plataforma nΓ£o executa nada para este gatilho.'}\n </p>\n </div>\n ) : (\n <div>{executions.map((e) => <ExecutionRow key={e.id} execution={e} />)}</div>\n )}\n </Card>\n )\n}\n","// The real WhatsApp doodle wallpaper, served from the product's own R2 bucket\n// (uploaded by the founder next to the connector marks). One URL beats 39KB of\n// base64 in every app bundle; the preview is an admin surface, always online.\nexport const WHATSAPP_PREVIEW_BG = 'https://assets.fayz.ai/connectors/whatsapp-background.jpg'\n","import { getSupabaseClientOptional } from '@fayz-ai/core'\nimport type { MessageChannel } from '@fayz-ai/core'\n\n// ---------------------------------------------------------------------------\n// O que a Meta respondeu sobre cada modelo.\n//\n// SΓ³ LEITURA. A tabela Γ© escrita pelo webhook e pela funΓ§Γ£o de sincronizaΓ§Γ£o,\n// com service role: quem pudesse marcar `approved` daqui faria o envio tentar um\n// modelo que a Meta nunca liberou, e a recusa chegaria como uma confirmaΓ§Γ£o de\n// horΓ‘rio que nΓ£o saiu.\n//\n// A leitura traz as linhas do tenant E as do produto (tenant_id NULL). SΓ£o as\n// duas que importam na tela: a mensagem sai pela do produto atΓ© a do tenant ser\n// aprovada, entΓ£o \"aguardando aprovaΓ§Γ£o\" sΓ³ Γ© verdade quando NENHUMA das duas\n// estΓ‘ aprovada.\n// ---------------------------------------------------------------------------\n\nexport const PROVIDER_TEMPLATES_TABLE = 'plg_automations_provider_templates'\n\nexport type ProviderTemplateStatus =\n | 'draft' | 'submitted' | 'approved' | 'rejected' | 'paused' | 'disabled'\n\nexport interface ProviderTemplateRow {\n id: string\n /** NULL = o modelo padrΓ£o do produto, que serve todos os tenants. */\n tenantId: string | null\n eventKey: string\n channel: MessageChannel\n provider: string\n templateName: string\n status: ProviderTemplateStatus\n rejectionReason: string | null\n updatedAt: string | null\n}\n\nfunction rowToProviderTemplate(row: any): ProviderTemplateRow {\n return {\n id: row.id,\n tenantId: row.tenant_id ?? null,\n eventKey: row.event_key,\n channel: (row.channel ?? 'whatsapp') as MessageChannel,\n provider: row.provider ?? 'tyxter',\n templateName: row.template_name ?? '',\n status: (row.status ?? 'draft') as ProviderTemplateStatus,\n rejectionReason: row.rejection_reason || null,\n updatedAt: row.updated_at ?? row.created_at ?? null,\n }\n}\n\n/**\n * Nunca lanΓ§a: sem cliente, sem tabela ou sem permissΓ£o a lista de automaΓ§Γ΅es\n * continua inteira, sΓ³ sem a pastilha de aprovaΓ§Γ£o. Um erro aqui nΓ£o pode\n * esconder as automaΓ§Γ΅es de e-mail, que nΓ£o dependem da Meta para nada.\n */\nexport async function loadProviderTemplates(): Promise<ProviderTemplateRow[]> {\n const client = getSupabaseClientOptional() as unknown as { from: (t: string) => any } | null\n if (!client) return []\n try {\n // Sem filtro de tenant: a RLS jΓ‘ entrega as linhas deste tenant mais as do\n // produto, e filtrar por tenant aqui esconderia justamente o modelo padrΓ£o\n // pelo qual a mensagem sai hoje.\n const { data, error } = await client.from(PROVIDER_TEMPLATES_TABLE).select('*')\n if (error) throw error\n return (data ?? []).map(rowToProviderTemplate)\n } catch (err) {\n console.warn('[automations] could not load provider template status', err)\n return []\n }\n}\n\n/**\n * A linha que decide o que a tela mostra para um (evento Γ canal).\n *\n * A do tenant ganha quando existe β Γ© a que ele estΓ‘ esperando. Se ela nΓ£o\n * existe, vale a do produto. E se a do tenant foi recusada mas a do produto estΓ‘\n * aprovada, a mensagem AINDA SAI (pela do produto): quem escolhe aqui Γ© a linha\n * do tenant, e o texto da pastilha Γ© que diz isso.\n */\nexport function providerTemplateFor(\n rows: ProviderTemplateRow[],\n eventKey: string,\n channel: MessageChannel,\n): { own: ProviderTemplateRow | null; fallback: ProviderTemplateRow | null } {\n const matching = rows.filter((r) => r.eventKey === eventKey && r.channel === channel)\n return {\n own: matching.find((r) => r.tenantId !== null) ?? null,\n fallback: matching.find((r) => r.tenantId === null) ?? null,\n }\n}\n","import React from 'react'\nimport { Badge } from '@fayz-ai/ui'\nimport type { MessageChannel } from '@fayz-ai/core'\nimport {\n loadProviderTemplates, providerTemplateFor,\n type ProviderTemplateRow,\n} from '../data/provider-templates'\n\n// ---------------------------------------------------------------------------\n// \"Ligado\" nΓ£o quer dizer \"vai sair\".\n//\n// No WhatsApp a mensagem sΓ³ existe depois que a Meta aprova o modelo, e a\n// aprovaΓ§Γ£o Γ© assΓncrona: pode levar horas e pode voltar recusada. Sem esta\n// pastilha a tela mostra um interruptor verde para uma automaΓ§Γ£o que a Meta\n// ainda nΓ£o liberou β e o negΓ³cio sΓ³ descobre quando a cliente nΓ£o recebe.\n//\n// SΓ³ o WhatsApp tem isso. E-mail nΓ£o passa por aprovaΓ§Γ£o de ninguΓ©m, entΓ£o a\n// pastilha some nos outros canais em vez de dizer \"aprovado\" sobre algo que\n// nunca precisou ser.\n// ---------------------------------------------------------------------------\n\nexport type ProviderApproval =\n | { tone: 'ok'; label: string; detail?: string }\n | { tone: 'waiting'; label: string; detail?: string }\n | { tone: 'error'; label: string; detail?: string }\n\n/**\n * O que a linha mostra para um (evento Γ canal).\n *\n * `null` = nada a dizer, e Γ© o caso comum: canal sem aprovaΓ§Γ£o, ou WhatsApp\n * ainda nΓ£o conectado (sem nenhuma linha, o assunto nΓ£o existe para este\n * negΓ³cio e uma pastilha vermelha seria um alarme sobre algo que ninguΓ©m pediu).\n *\n * A regra que decide o texto Γ© a mesma do envio: sai pelo modelo do produto atΓ©\n * o do tenant ser aprovado. Por isso um modelo do tenant recusado, com o do\n * produto aprovado, Γ© um AVISO e nΓ£o uma falha β a mensagem continua saindo.\n */\nexport function providerApprovalFor(\n rows: ProviderTemplateRow[],\n eventKey: string,\n channel: MessageChannel,\n): ProviderApproval | null {\n if (channel !== 'whatsapp') return null\n const { own, fallback } = providerTemplateFor(rows, eventKey, channel)\n const row = own ?? fallback\n if (!row) return null\n\n const fallbackApproved = fallback?.status === 'approved'\n\n switch (row.status) {\n case 'approved':\n return { tone: 'ok', label: 'Aprovado pela Meta' }\n case 'rejected':\n return {\n tone: fallbackApproved && own ? 'waiting' : 'error',\n label: fallbackApproved && own ? 'Seu texto foi recusado' : 'Recusado pela Meta',\n detail: row.rejectionReason\n ? `Motivo: ${row.rejectionReason}`\n : 'A Meta nΓ£o disse o motivo.',\n }\n case 'paused':\n return {\n tone: 'error',\n label: 'Pausado pela Meta',\n detail: row.rejectionReason ?? 'Costuma ser excesso de marcaΓ§Γ΅es de spam pelos clientes.',\n }\n case 'disabled':\n return { tone: 'error', label: 'Desativado pela Meta', detail: row.rejectionReason ?? undefined }\n case 'submitted':\n return {\n tone: 'waiting',\n label: 'Aguardando aprovaΓ§Γ£o da Meta',\n detail: fallbackApproved && own\n ? 'AtΓ© lΓ‘ a mensagem sai com o texto padrΓ£o.'\n : 'A revisΓ£o costuma levar algumas horas.',\n }\n default:\n return { tone: 'waiting', label: 'Ainda nΓ£o enviado para aprovaΓ§Γ£o' }\n }\n}\n\nconst TONE_VARIANT: Record<ProviderApproval['tone'], 'success' | 'warning' | 'destructive'> = {\n ok: 'success',\n waiting: 'warning',\n error: 'destructive',\n}\n\nexport function ProviderTemplateBadge({ approval, showDetail }: {\n approval: ProviderApproval | null\n showDetail?: boolean\n}) {\n if (!approval) return null\n // Aprovado nΓ£o ganha pastilha na lista: Γ© o estado normal, e uma linha em que\n // tudo estΓ‘ certo nΓ£o precisa de enfeite. O que precisa aparecer Γ© o que\n // impede a mensagem de sair.\n if (approval.tone === 'ok' && !showDetail) return null\n return (\n <span className=\"inline-flex flex-wrap items-center gap-1.5\">\n <Badge variant={TONE_VARIANT[approval.tone]}>{approval.label}</Badge>\n {showDetail && approval.detail && (\n <span className=\"text-xs text-muted-foreground\">{approval.detail}</span>\n )}\n </span>\n )\n}\n\n/** Uma leitura por tela. Nunca lanΓ§a: sem a tabela, a lista continua inteira. */\nexport function useProviderTemplates(): ProviderTemplateRow[] {\n const [rows, setRows] = React.useState<ProviderTemplateRow[]>([])\n React.useEffect(() => {\n let cancelled = false\n void loadProviderTemplates().then((data) => { if (!cancelled) setRows(data) })\n return () => { cancelled = true }\n }, [])\n return rows\n}\n","import React from 'react'\nimport { Check, Clock, Mail, MessageSquare, Monitor, RotateCcw, Send, Smartphone, Zap } from 'lucide-react'\nimport { Badge, Button, Card, HeaderTabs, Hint, PhoneField, SubpageHeader, Switch, toast, WhatsAppIcon } from '@fayz-ai/ui'\nimport {\n adminNavigateTo, resolveFayzAgentConnection, AskAIButton, useAgentSurface,\n type AgentSurfaceContribution,\n} from '@fayz-ai/admin'\nimport type { MessageAction, MessageActionId, MessageChannel, PluginAITool, ResolvedMessage } from '@fayz-ai/core'\nimport { usePluginRuntimeOptional } from '@fayz-ai/core'\nimport { canOfferPayment, usePaymentReadiness } from '../data/payment-preflight'\nimport { sendTestMessage } from '../data/test-send'\nimport { resolveMessage, renderMessageTemplate, useOrganizationStoreLike } from '../lib/runtime'\nimport { FayzRunLog, RunLog } from './RunLog'\nimport { WHATSAPP_PREVIEW_BG } from './whatsapp-preview-bg'\nimport {\n ProviderTemplateBadge, providerApprovalFor, useProviderTemplates,\n} from './ProviderTemplateStatus'\nimport type { MessageTemplateStore } from '../data/templates'\n\n// ---------------------------------------------------------------------------\n// Um modelo, em tela cheia. Duas visΓ΅es do MESMO texto:\n// PrΓ©via o que a pessoa recebe, com os campos jΓ‘ substituΓdos\n// CΓ³digo o texto-fonte, onde se edita\n//\n// A substituiΓ§Γ£o da prΓ©via Γ© a de @fayz-ai/core (renderMessageTemplate), nΓ£o um\n// replace local: prΓ©via e envio precisam concordar, senΓ£o aprova-se um texto e\n// entrega-se outro.\n//\n// \"Igual ao padrΓ£o\" Γ© gravado como AUSΓNCIA de personalizaΓ§Γ£o (null), nΓ£o como\n// cΓ³pia β assim melhorias no texto padrΓ£o continuam chegando a quem nunca\n// mexeu. Γ o mesmo motivo pelo qual \"Restaurar padrΓ£o\" APAGA a linha em vez de\n// escrever o texto de fΓ‘brica nela.\n// ---------------------------------------------------------------------------\n\ntype ViewTab = 'preview' | 'code' | 'runs' | 'test'\n\n// ---------------------------------------------------------------------------\n// Os botΓ΅es da mensagem.\n//\n// O catΓ‘logo do plugin define os padrΓ΅es (Confirmar/Cancelar no agendamento);\n// aqui a pessoa liga e desliga cada um. Γ uma lista fechada porque um botΓ£o nΓ£o\n// Γ© um texto: cada id tem um significado do lado de cΓ‘ β `confirm` e `cancel`\n// mexem no agendamento, `pay` abre uma cobranΓ§a β e um id inventado seria um\n// botΓ£o que o cliente toca e nada acontece.\n//\n// `pay` Γ© o ΓΊnico que depende de algo fora deste app, e por isso Γ© o ΓΊnico que\n// pode aparecer desligado por motivo alheio: sem uma conta de pagamento\n// escolhida na Tyxter, a cobranΓ§a nΓ£o abre. Mostrar o botΓ£o desabilitado com o\n// motivo Γ© melhor do que escondΓͺ-lo β escondido, a pergunta \"cadΓͺ o Pix?\" nΓ£o\n// tem onde ser respondida.\n// ---------------------------------------------------------------------------\nconst ACTION_CATALOG: Array<{ id: MessageActionId; label: string; kind: MessageAction['kind']; hint: string }> = [\n { id: 'confirm', label: 'Confirma', kind: 'reply', hint: 'O cliente confirma o horΓ‘rio no toque.' },\n { id: 'cancel', label: 'Cancela', kind: 'reply', hint: 'O cliente desmarca sem precisar ligar.' },\n { id: 'pay', label: 'Pagar', kind: 'payment', hint: 'O cliente recebe o Pix na conversa.' },\n]\n\n/**\n * A lista de botΓ΅es depois de ligar ou desligar um deles.\n *\n * A ordem Γ© a do catΓ‘logo e nΓ£o a do clique: os botΓ΅es chegam ao WhatsApp\n * numerados, e reordenΓ‘-los ao ligar o terceiro mudaria o que o segundo faz\n * numa mensagem que a Meta jΓ‘ aprovou.\n */\nexport function nextActions(\n current: MessageAction[], id: MessageActionId, on: boolean,\n): MessageAction[] {\n const kept = new Set(current.filter((a) => a.id !== id).map((a) => a.id))\n if (on) kept.add(id)\n const labels = new Map(current.map((a) => [a.id, a.label]))\n return ACTION_CATALOG\n .filter((a) => kept.has(a.id))\n // O rΓ³tulo que jΓ‘ existe ganha do padrΓ£o: se o texto foi personalizado,\n // ligar outro botΓ£o nΓ£o Γ© hora de reescrevΓͺ-lo.\n .map((a) => ({ id: a.id, label: labels.get(a.id) ?? a.label, kind: a.kind }))\n}\n\n// What each refusal of a test send means to the person reading the toast. The\n// codes are messaging-send's own; an unknown one falls back to its message.\nconst TEST_ERROR: Record<string, string> = {\n template_not_approved: 'O modelo ainda nΓ£o foi aprovado pela Meta β sincronize os modelos e tente de novo.',\n no_sender: 'Este app ainda nΓ£o tem um nΓΊmero de WhatsApp ativo. Veja Conversas β Tyxter.',\n not_connected: 'O WhatsApp ainda nΓ£o estΓ‘ conectado neste app. Veja Conversas β Tyxter.',\n contact_opted_out: 'Este contato pediu para nΓ£o receber mensagens.',\n invalid_recipient: 'Esse destino nΓ£o parece vΓ‘lido.',\n not_a_member: 'A sua sessΓ£o nΓ£o pertence a este negΓ³cio.',\n not_available: 'O envio de teste nΓ£o estΓ‘ disponΓvel neste ambiente.',\n email_not_configured: 'O envio de e-mail nΓ£o estΓ‘ configurado neste app.',\n template_not_found: 'Escreva a mensagem antes de testar.',\n email_rejected: 'O provedor de e-mail recusou a mensagem.',\n email_credential_rejected: 'A chave de e-mail do app foi recusada pelo provedor.',\n email_rate_limited: 'O provedor pediu uma pausa β tente de novo em instantes.',\n}\n\n/**\n * O teste que anda o caminho de verdade.\n *\n * A prΓ©via acima substitui variΓ‘veis localmente e nΓ£o pode mentir sobre o texto\n * β mas sΓ³ o envio real revela o resto: modelo aprovado, nΓΊmero ativo, chave da\n * plataforma. Por isso o teste chama a MESMA funΓ§Γ£o do envio da automaΓ§Γ£o, com\n * a sessΓ£o da pessoa no lugar do segredo da plataforma e um assunto 'test' que\n * nenhum botΓ£o consegue transformar em aΓ§Γ£o sobre um registro real.\n */\nfunction TestSendStrip({ eventKey, channel, placeholders, template }: {\n eventKey: string\n channel: MessageChannel\n placeholders: string[]\n /** Email only: the draft on screen goes with the test, saved or not. */\n template?: { subject: string; body: string }\n}) {\n const isEmail = channel === 'email'\n const [recipient, setRecipient] = React.useState('')\n const [sending, setSending] = React.useState(false)\n const valid = isEmail\n ? /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(recipient.trim())\n : recipient.replace(/\\D/g, '').length >= 10\n\n const send = async () => {\n setSending(true)\n try {\n const variables = Object.fromEntries(placeholders.map((p) => {\n const key = p.replace(/[{}]/g, '').trim()\n return [key, SAMPLE[key] ?? key]\n }))\n const result = await sendTestMessage({ eventKey, channel, to: recipient.trim(), variables, template })\n if (result.ok) {\n toast.success(isEmail\n ? 'Teste enviado β confira a caixa de entrada desse e-mail'\n : 'Teste enviado β confira o WhatsApp desse nΓΊmero')\n } else {\n toast.error(TEST_ERROR[result.error ?? ''] ?? result.message ?? 'NΓ£o foi possΓvel enviar o teste')\n }\n } finally {\n setSending(false)\n }\n }\n\n return (\n // Sem moldura prΓ³pria: o strip vive dentro do Card da aba Testar, e uma\n // borda aqui era o anel duplicado de sempre.\n <div className=\"mt-3 flex flex-wrap items-end gap-2\">\n <div className=\"min-w-0 flex-1\">\n <label className=\"mb-1 block text-xs font-medium text-muted-foreground\">\n {isEmail ? 'E-mail que recebe o teste' : 'NΓΊmero que recebe o teste'}\n </label>\n {isEmail ? (\n <input\n type=\"email\"\n value={recipient}\n onChange={(e) => setRecipient(e.target.value)}\n placeholder=\"voce@exemplo.com\"\n disabled={sending}\n aria-label=\"E-mail que recebe o teste\"\n className=\"w-full rounded-input border border-input bg-card px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring\"\n />\n ) : (\n <PhoneField\n value={recipient}\n onChange={setRecipient}\n placeholder=\"(21) 99999-9999\"\n disabled={sending}\n aria-label=\"NΓΊmero que recebe o teste\"\n />\n )}\n </div>\n <Button variant=\"outline\" onClick={() => void send()} disabled={!valid || sending}>\n <Send className=\"mr-2 h-3.5 w-3.5\" />\n {sending ? 'Enviandoβ¦' : 'Enviar teste'}\n </Button>\n </div>\n )\n}\n\nconst TABS: { value: ViewTab; label: string }[] = [\n { value: 'preview', label: 'PrΓ©via' },\n { value: 'code', label: 'CΓ³digo' },\n // O que jΓ‘ aconteceu. Fica ao lado do texto, e nΓ£o numa tela Γ parte, porque\n // Γ© a mesma pergunta em dois tempos: o que vai sair, e o que saiu.\n { value: 'runs', label: 'ExecuΓ§Γ΅es' },\n]\n\n// SΓ³ aparece nos canais que tΓͺm envio de teste (WhatsApp, e-mail).\nconst TEST_TAB: { value: ViewTab; label: string } = { value: 'test', label: 'Testar' }\n\nconst CHANNEL_LABEL: Record<MessageChannel, string> = {\n email: 'E-mail', whatsapp: 'WhatsApp', sms: 'SMS', push: 'Push', webchat: 'Chat',\n}\n\n// The channel is what distinguishes this screen from its siblings (the same\n// event exists per channel), so the identity slot carries the CHANNEL's face β\n// and WhatsApp's face is its mark, not a generic bubble.\nconst CHANNEL_ICON: Record<MessageChannel, React.ComponentType<{ className?: string }>> = {\n email: Mail, whatsapp: WhatsAppIcon, sms: Smartphone, push: MessageSquare, webchat: MessageSquare,\n}\n\n/** Dados de exemplo da prΓ©via. NΓ£o sΓ£o de ninguΓ©m β a tela diz isso. */\n// ---------------------------------------------------------------------------\n// A mensagem, escrita pelo assistente.\n//\n// Client-plane e `mode: 'read'` de propΓ³sito: a ferramenta NΓO grava nada β ela\n// preenche o rascunho do editor ao lado, e o Salvar continua sendo um clique de\n// uma pessoa. Declarar `persist` aqui pediria uma confirmaΓ§Γ£o para escrever num\n// campo de texto, e avisaria as listas do app de uma mudanΓ§a que nΓ£o houve.\n// ---------------------------------------------------------------------------\nconst WRITE_MESSAGE_TOOL: PluginAITool = {\n id: 'automations.writeMessage',\n name: 'writeAutomationMessage',\n description:\n 'Writes the subject and body of the automation message the user has open, into the editor (it does NOT save β the user does). '\n + 'Use ONLY the placeholders listed in the surface state, spelled exactly, including the braces: an invented one renders as literal text in a message a customer reads. '\n + 'Match the channel: e-mail takes a subject and paragraphs; WhatsApp and SMS take no subject and few lines.',\n icon: 'MessageSquare',\n mode: 'read',\n execution: { plane: 'client' },\n category: 'Automations',\n parameters: {\n type: 'object',\n properties: {\n subject: { type: 'string', description: 'Subject line. Leave empty for channels that have none.' },\n body: { type: 'string', description: 'Message body, with placeholders where they belong.' },\n },\n required: ['body'],\n },\n}\n\nconst SAMPLE: Record<string, string> = {\n store_name: 'Sua Loja', company_name: 'Sua Empresa',\n customer_name: 'Maria Silva', contact_name: 'Maria Silva', lead_name: 'Maria Silva',\n order_number: '1042', order_total: 'R$ 189,90',\n order_items: '1 Γ Camiseta ClΓ‘ssica β R$ 89,90\\n2 Γ Caneca Esmaltada β R$ 100,00',\n tracking_code: 'BR123456789BR', cart_url: 'https://sualoja.com.br/carrinho',\n deal_name: 'Proposta β Reforma da fachada', deal_value: 'R$ 12.400,00',\n stage_name: 'NegociaΓ§Γ£o', owner_name: 'JoΓ£o Pereira',\n appointment_date: '12/08/2026', appointment_time: '14:30',\n}\n\nexport interface AutomationDetailPageProps {\n eventKey?: string\n channel?: string\n store: MessageTemplateStore\n /** Para onde o \"voltar\" leva β a lista pode morar no menu ou nas\n * configuraΓ§Γ΅es, e a pessoa tem que voltar por onde entrou. */\n backTo?: string\n /**\n * Montada na coluna da direita, ao lado da lista, em vez de ser a tela.\n *\n * Some o cabeΓ§alho prΓ³prio: quem nomeia a coluna e oferece a volta Γ© o\n * cabeΓ§alho dela, e desenhar o nosso ali embaixo era o mesmo tΓtulo duas\n * vezes, com dois jeitos de sair.\n */\n embedded?: boolean\n /**\n * Como sair, quando sair NΓO Γ© navegar.\n *\n * Aberta pela coluna a partir de outra tela (o raio do CRM), a saΓda Γ© fechar\n * a coluna e continuar onde se estava β `backTo` levaria embora justamente a\n * tela que se queria manter.\n */\n onDone?: () => void\n}\n\nexport function AutomationDetailPage({ eventKey, channel, store, backTo = '/automations', embedded, onDone }: AutomationDetailPageProps) {\n const tenantId = useOrganizationStoreLike()\n const runtime = usePluginRuntimeOptional()\n const fayzConnection = React.useMemo(() => resolveFayzAgentConnection(), [])\n const [message, setMessage] = React.useState<ResolvedMessage | null | undefined>(undefined)\n const [tab, setTab] = React.useState<ViewTab>('preview')\n const [device, setDevice] = React.useState<'desktop' | 'mobile'>('desktop')\n const [draft, setDraft] = React.useState<{ subject: string; body: string } | null>(null)\n // O texto de cada botΓ£o enquanto se digita. Grava no blur, nΓ£o por tecla:\n // cada gravaΓ§Γ£o vai direto ao banco (como o interruptor ao lado), e um PATCH\n // por caractere seria uma automaΓ§Γ£o salva vinte vezes por palavra.\n const [labelDrafts, setLabelDrafts] = React.useState<Record<string, string>>({})\n const [saving, setSaving] = React.useState(false)\n const providerTemplates = useProviderTemplates()\n const { readiness, loading: readinessLoading } = usePaymentReadiness()\n\n const back = React.useCallback(\n () => (onDone ? onDone() : adminNavigateTo(backTo)),\n [onDone, backTo],\n )\n\n // --- assistant surface ---------------------------------------------------\n const surfaceRef = React.useRef({ message, draft })\n surfaceRef.current = { message, draft }\n\n const agentSurface = React.useMemo<AgentSurfaceContribution>(() => ({\n id: 'automations.message',\n pluginId: 'automations',\n instructions:\n 'The user is editing one automation message. `placeholders` in the surface state are the ONLY variables that resolve β copy them verbatim, braces included. '\n + 'Call writeAutomationMessage once with the whole text; the editor fills and the user reviews before saving.',\n describe: () => {\n const o = surfaceRef.current\n if (!o.message) return { title: 'AutomaΓ§Γ£o' }\n const current = o.draft ?? { subject: o.message.subject, body: o.message.body }\n return {\n title: `AutomaΓ§Γ£o β ${o.message.event?.title ?? o.message.event?.name ?? ''}`,\n state: {\n event: o.message.event?.name ?? null,\n channel: o.message.channel,\n hasSubject: o.message.channel === 'email',\n placeholders: Object.keys(SAMPLE).map((key) => `{{${key}}}`),\n currentSubject: current.subject,\n currentBody: current.body,\n },\n }\n },\n tools: [{\n tool: WRITE_MESSAGE_TOOL,\n execute: (args: Record<string, unknown>) => {\n const o = surfaceRef.current\n if (!o.message) return { ok: false, error: 'no_message_open' }\n const current = o.draft ?? { subject: o.message.subject, body: o.message.body }\n const body = String(args.body ?? '').trim()\n if (!body) return { ok: false, error: 'empty_body' }\n const subject = args.subject === undefined ? current.subject : String(args.subject)\n setDraft({ subject, body })\n // Leva para a aba do texto: ele acabou de mudar e a prΓ©-visualizaΓ§Γ£o\n // nΓ£o mostra onde mexer.\n setTab('code')\n return { ok: true, filled: true, saved: false, note: 'Draft filled β the user still has to press Save.' }\n },\n }],\n }), [])\n useAgentSurface(agentSurface)\n\n const reload = React.useCallback(async () => {\n if (!eventKey || !channel) { setMessage(null); return }\n let overrides: Awaited<ReturnType<MessageTemplateStore['list']>> = []\n try {\n overrides = await store.list(tenantId)\n } catch (err) {\n console.warn('[automations] could not load overrides; showing defaults', err)\n }\n const found = resolveMessage(decodeURIComponent(eventKey), channel as MessageChannel, overrides, runtime?.events ?? [])\n setMessage(found)\n if (found) setDraft({ subject: found.subject, body: found.body })\n }, [eventKey, channel, store, tenantId, runtime])\n\n React.useEffect(() => { void reload() }, [reload])\n\n const header = embedded ? null : (\n <SubpageHeader\n title={message === undefined ? '' : (message?.override?.name ?? message?.event.title ?? message?.event.name ?? 'AutomaΓ§Γ£o')}\n parentLabel=\"AutomaΓ§Γ΅es\"\n onBack={back}\n />\n )\n\n if (message === undefined) {\n return (\n <div className=\"space-y-4\">\n {header}\n <div className=\"h-8 w-64 animate-pulse rounded bg-muted\" />\n <Card className=\"h-96 animate-pulse\" />\n </div>\n )\n }\n\n if (!message) {\n return (\n <>\n {header}\n <Card className=\"flex flex-col items-center gap-2 p-12 text-center\">\n <Mail className=\"h-9 w-9 text-muted-foreground/40\" strokeWidth={1.5} />\n <p className=\"font-semibold\">AutomaΓ§Γ£o nΓ£o encontrada</p>\n <p className=\"max-w-sm text-sm text-muted-foreground\">\n O evento <code className=\"font-mono\">{eventKey}</code> nΓ£o estΓ‘ no catΓ‘logo β o mΓ³dulo\n que o registra pode nΓ£o estar instalado nesta conta.\n </p>\n <Button variant=\"outline\" className=\"mt-2\" onClick={back}>Voltar para AutomaΓ§Γ΅es</Button>\n </Card>\n </>\n )\n }\n\n const event = message.event\n // O texto de fΓ‘brica: o que \"restaurar padrΓ£o\" devolve. Vem do registro de\n // padrΓ΅es, nΓ£o do evento β o evento Γ© o fato, nΓ£o a mensagem.\n const fallback = { subject: message.override ? undefined : message.subject, body: message.body }\n const ChannelIcon = CHANNEL_ICON[message.channel] ?? Zap\n const isWhatsapp = message.channel === 'whatsapp'\n const current = draft ?? { subject: message.subject, body: message.body }\n const dirty = current.subject !== message.subject || current.body !== message.body\n const hasSubject = message.channel === 'email'\n\n const patch = async (input: Parameters<MessageTemplateStore['upsert']>[0]) => {\n setSaving(true)\n try {\n await store.upsert(input, tenantId)\n await reload()\n } catch (err) {\n console.warn('[automations] save failed', err)\n toast.error('NΓ£o foi possΓvel salvar')\n } finally {\n setSaving(false)\n }\n }\n\n const save = () => void patch({\n eventKey: event.name,\n channel: message.channel,\n // Igual ao padrΓ£o volta a ser \"sem personalizaΓ§Γ£o\", nΓ£o uma cΓ³pia.\n subject: current.subject.trim() === (fallback?.subject ?? '') ? null : current.subject.trim() || null,\n body: current.body.trim() === fallback?.body ? null : current.body.trim() || null,\n })\n\n const reset = async () => {\n setDraft({ subject: fallback?.subject ?? '', body: fallback?.body ?? '' })\n setSaving(true)\n try {\n // Apaga a linha inteira: com ela fora, o padrΓ£o volta a valer e melhorias\n // no texto de fΓ‘brica voltam a chegar aqui.\n await store.reset(event.name, message.channel, tenantId)\n await reload()\n toast.success('Texto restaurado')\n } catch (err) {\n console.warn('[automations] reset failed', err)\n toast.error('NΓ£o foi possΓvel restaurar')\n } finally {\n setSaving(false)\n }\n }\n\n const previewSubject = renderMessageTemplate(current.subject, SAMPLE)\n const previewBody = renderMessageTemplate(current.body, SAMPLE)\n\n return (\n <div className=\"space-y-5\">\n {header}\n\n {/* Identidade e controles.\n Numa pΓ‘gina larga cabem na mesma linha. Na coluna nΓ£o cabem: as\n pastilhas quebravam uma por linha, a descriΓ§Γ£o virava uma coluna de\n trΓͺs palavras e \"Restaurar padrΓ£o\" por extenso empurrava o Salvar para\n fora β por isso na coluna eles sΓ£o duas faixas empilhadas, com o\n restaurar reduzido ao seu glifo. */}\n <div className={embedded ? 'space-y-3' : 'flex flex-wrap items-start gap-3'}>\n <div className={embedded ? 'flex items-start gap-3' : 'contents'}>\n <span\n className={`flex h-9 w-9 shrink-0 items-center justify-center rounded-lg border ${\n isWhatsapp\n ? 'border-[#25D366]/30 bg-[#25D366]/10 text-[#1faf55]'\n : 'border-border text-muted-foreground'\n }`}\n >\n <ChannelIcon className=\"h-4 w-4\" />\n </span>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <Badge variant=\"outline\">{CHANNEL_LABEL[message.channel]}</Badge>\n <Badge variant=\"outline\">{message.kind === 'marketing' ? 'Marketing' : 'Transacional'}</Badge>\n {message.customized && <Badge variant=\"info\">Personalizado</Badge>}\n </div>\n <p className=\"mt-0.5 text-sm text-muted-foreground\">{event.description}</p>\n {/* Aqui a pastilha aparece MESMO quando estΓ‘ tudo certo, e traz o\n motivo junto: Γ© a tela onde se decide o que fazer com uma\n recusa, e \"recusado\" sem o motivo nΓ£o deixa ninguΓ©m agir. */}\n <div className=\"mt-1.5\">\n <ProviderTemplateBadge\n approval={providerApprovalFor(providerTemplates, event.name, message.channel)}\n showDetail\n />\n </div>\n </div>\n </div>\n\n <div className={embedded ? 'flex items-center gap-2' : 'flex shrink-0 flex-wrap items-center gap-2'}>\n {/* O mesmo interruptor da lista: liga na hora, sem passar pelo Salvar\n β que aqui Γ© sΓ³ do TEXTO. Vem primeiro na coluna porque Γ© o que se\n toca com mais frequΓͺncia, e porque ligar nΓ£o Γ© salvar. */}\n <Switch\n size=\"md\"\n checked={message.enabled}\n onCheckedChange={(next) => void patch({ eventKey: event.name, channel: message.channel, enabled: next })}\n disabled={saving}\n label={message.enabled ? 'Ativa' : 'Inativa'}\n />\n <div className={embedded ? 'ml-auto flex items-center gap-2' : 'contents'}>\n <Hint label=\"Descarta o texto personalizado e volta ao padrΓ£o do produto.\">\n <span>\n <Button\n variant={embedded ? 'ghost' : 'outline'}\n size={embedded ? 'icon' : undefined}\n onClick={() => void reset()}\n disabled={!message.customized || saving}\n aria-label={embedded ? 'Restaurar padrΓ£o' : undefined}\n >\n <RotateCcw className={embedded ? 'h-4 w-4' : 'mr-2 h-4 w-4'} />\n {!embedded && 'Restaurar padrΓ£o'}\n </Button>\n </span>\n </Hint>\n {/* Escrever a mensagem Γ o trabalho desta tela, e Γ© o trabalho que\n um modelo faz melhor que um campo vazio. A ferramenta preenche o\n RASCUNHO β quem salva continua sendo a pessoa, no botΓ£o ao lado. */}\n <AskAIButton\n variant={embedded ? 'ghost' : 'outline'}\n label={embedded ? '' : undefined}\n hint=\"Descreva o tom da mensagemβ¦\"\n intro={{\n role: 'setup',\n persona: 'Redator das automaΓ§Γ΅es',\n pitch: 'Diga como esta mensagem deve soar.',\n description:\n 'Escrevo o assunto e o corpo desta automaΓ§Γ£o usando as variΓ‘veis que ela tem Γ disposiΓ§Γ£o. O texto cai no editor ao lado para vocΓͺ revisar β nada Γ© salvo sem vocΓͺ.',\n suggestions: [\n { label: 'Mais curta e direta' },\n { label: 'Mais calorosa, com o nome do cliente' },\n { label: 'Formal, para um pΓΊblico corporativo' },\n ],\n }}\n />\n {/* Uma tela, um CTA: o Salvar sΓ³ se veste de botΓ£o primΓ‘rio quando\n hΓ‘ o que salvar. \"Salvo\" nΓ£o Γ© uma aΓ§Γ£o β desenhΓ‘-lo como um\n botΓ£o apagado deixava um CTA morto no lugar mais nobre da\n coluna; como confirmaΓ§Γ£o silenciosa, ele diz o estado e sai do\n caminho. */}\n {dirty || saving ? (\n <Button onClick={save} disabled={saving}>\n {saving ? 'Salvandoβ¦' : 'Salvar'}\n </Button>\n ) : (\n <span className=\"inline-flex h-9 items-center gap-1 px-2 text-xs font-medium text-muted-foreground\">\n <Check className=\"h-3.5 w-3.5\" />\n Salvo\n </span>\n )}\n </div>\n </div>\n </div>\n\n <HeaderTabs\n tabs={isWhatsapp || message.channel === 'email' ? [...TABS, TEST_TAB] : TABS}\n value={tab}\n onChange={setTab}\n aria-label=\"VisualizaΓ§Γ£o\"\n />\n\n <div className=\"flex flex-wrap items-center gap-x-6 gap-y-2 border-b border-border pb-4 text-xs text-muted-foreground\">\n <span className=\"inline-flex items-center gap-1.5\">\n <Zap className=\"h-3.5 w-3.5\" />\n Gatilho:\n <code className=\"rounded bg-muted px-1.5 py-0.5 font-mono text-[11px] text-foreground\">{event.name}</code>\n </span>\n <span className=\"inline-flex items-center gap-1.5\">\n <Clock className=\"h-3.5 w-3.5\" />\n {event.trigger}\n </span>\n {hasSubject && current.subject && <span className=\"min-w-0 truncate\">Assunto: {current.subject}</span>}\n </div>\n\n {tab === 'runs' ? (\n // AtrΓ‘s de um projeto Fayz o histΓ³rico verdadeiro Γ© o da plataforma β\n // Γ© ela quem executa. Fora dele, o coletor local continua valendo.\n fayzConnection ? (\n <FayzRunLog connection={fayzConnection} eventKey={event.name} tenantId={tenantId} enabled={message.enabled} />\n ) : (\n <RunLog eventKey={event.name} tenantId={tenantId} enabled={message.enabled} />\n )\n ) : tab === 'preview' ? (\n <Card className=\"overflow-hidden\">\n {/* Na coluna, a aba ativa jΓ‘ diz \"PrΓ©via\" logo acima β repetir o\n tΓtulo dentro do cartΓ£o era o mesmo nome duas vezes a um dedo de\n distΓ’ncia. A faixa sΓ³ existe na pΓ‘gina larga, onde carrega a\n comparaΓ§Γ£o computador/celular. */}\n {!embedded && (\n <div className=\"flex items-center justify-between gap-3 border-b border-border px-4 py-2.5\">\n <span className=\"text-sm font-medium\">PrΓ©via</span>\n {/* Computador/celular Γ© uma COMPARAΓΓO de larguras, e a coluna tem\n uma sΓ³: os dois botΓ΅es levavam ao mesmo desenho, e um controle\n que nΓ£o muda nada Γ© pior do que controle nenhum. */}\n <div className=\"flex items-center gap-1\">\n {(['desktop', 'mobile'] as const).map((d) => (\n <button\n key={d}\n type=\"button\"\n onClick={() => setDevice(d)}\n aria-label={d === 'desktop' ? 'Computador' : 'Celular'}\n className={`flex h-7 w-7 items-center justify-center rounded-md transition-colors ${\n device === d ? 'bg-muted text-foreground' : 'text-muted-foreground hover:bg-muted/60'\n }`}\n >\n {d === 'desktop' ? <Monitor className=\"h-4 w-4\" /> : <Smartphone className=\"h-4 w-4\" />}\n </button>\n ))}\n </div>\n </div>\n )}\n\n <div className={embedded ? 'bg-muted/30 p-4' : 'bg-muted/30 p-6'}>\n {/* WhatsApp/SMS nΓ£o tΓͺm assunto nem cabeΓ§alho de remetente β mostrar\n a moldura de e-mail neles prometeria uma forma que o canal nΓ£o\n tem. */}\n {/* Uma aresta sΓ³: a moldura interna vive de sombra e cantos\n clipados β borda aqui somava um segundo anel dentro do Card. */}\n <div\n className={`mx-auto overflow-hidden rounded-card bg-card shadow-sm transition-[max-width] ${\n device === 'mobile' ? 'max-w-[380px]' : hasSubject ? 'max-w-[600px]' : 'max-w-[420px]'\n }`}\n >\n {hasSubject ? (\n <>\n {/* Moldura de navegador (Safari): a prΓ©via de e-mail Γ© \"como\n o cliente vΓͺ no Gmail\", e a janela diz isso sem legenda.\n SemΓ‘foro decorativo β nada aqui Γ© clicΓ‘vel. */}\n <div aria-hidden className=\"flex items-center gap-1.5 border-b border-border bg-muted/40 px-4 py-2.5\">\n <span className=\"h-3 w-3 rounded-full bg-[#ff5f57]\" />\n <span className=\"h-3 w-3 rounded-full bg-[#febc2e]\" />\n <span className=\"h-3 w-3 rounded-full bg-[#28c840]\" />\n </div>\n <div className=\"px-6 pb-4 pt-5\">\n <p className=\"text-base font-semibold leading-snug\">{previewSubject}</p>\n {/* A linha do remetente, como no Gmail: avatar + nome no\n topo-esquerdo, destinatΓ‘rio embaixo, hora Γ direita. */}\n <div className=\"mt-4 flex items-center gap-3\">\n <span className=\"flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-primary/10 text-sm font-semibold text-primary\">\n {(SAMPLE.store_name ?? 'S').charAt(0)}\n </span>\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-semibold\">{SAMPLE.store_name}</p>\n <p className=\"text-xs text-muted-foreground\">para mim</p>\n </div>\n <span className=\"ml-auto shrink-0 text-xs text-muted-foreground\">09:41</span>\n </div>\n </div>\n <div className=\"whitespace-pre-wrap border-t border-border px-6 py-5 text-sm leading-relaxed\">{previewBody}</div>\n </>\n ) : (\n <div\n className=\"p-4\"\n // O papel de parede real do WhatsApp: quem escreve vΓͺ a\n // mensagem no palco em que ela vai aparecer. O balΓ£o Γ©\n // sempre o de saΓda (verde) β Γ© o negΓ³cio falando. Sem\n // raio prΓ³prio: a moldura clipa os cantos.\n style={isWhatsapp ? { backgroundImage: `url(${WHATSAPP_PREVIEW_BG})`, backgroundSize: 'cover', backgroundPosition: 'center' } : undefined}\n >\n <div className=\"whitespace-pre-wrap rounded-2xl rounded-tl-sm bg-[#dcf8c6] px-3 py-2 text-sm leading-relaxed text-[#111b21] shadow-sm\">\n {previewBody}\n </div>\n {/* Os botΓ΅es fazem parte da mensagem, entΓ£o fazem parte da\n prΓ©via: quem escreve o texto precisa ver que Confirmar e\n Cancelar jΓ‘ dizem o que a ΓΊltima linha ia dizer. */}\n {message.actions.length > 0 && (\n <div className=\"mt-1 space-y-1\">\n {message.actions.map((action) => (\n <div\n key={action.id}\n // Chips brancos, como o WhatsApp desenha reply buttons β\n // no papel de parede o verde do balΓ£o os engolia.\n className=\"rounded-lg bg-white px-3 py-1.5 text-center text-sm font-medium text-[#1e7fd6] shadow-sm\"\n >\n {action.label}\n </div>\n ))}\n </div>\n )}\n </div>\n )}\n </div>\n <p className=\"mt-4 text-center text-xs text-muted-foreground\">\n Dados de exemplo β nenhum registro real foi usado.\n </p>\n </div>\n </Card>\n ) : tab === 'test' ? (\n <Card className=\"p-4\">\n <p className=\"text-sm text-muted-foreground\">\n {isWhatsapp\n ? 'Envio real, pelo mesmo caminho da automaΓ§Γ£o β modelo aprovado, nΓΊmero ativo e entrega de verdade, com os dados de exemplo.'\n : 'Envio real, pelo mesmo caminho da automaΓ§Γ£o β vai o texto que estΓ‘ na tela, salvo ou nΓ£o, com os dados de exemplo.'}\n </p>\n <TestSendStrip\n eventKey={event.name}\n channel={message.channel}\n placeholders={message.placeholders}\n // WhatsApp must ride the Meta-approved template; email tests\n // exactly the text on screen, saved or not.\n template={message.channel === 'email'\n ? { subject: current.subject, body: current.body }\n : undefined}\n />\n </Card>\n ) : (\n <Card className=\"space-y-4 p-4\">\n {hasSubject && (\n <div>\n <label className=\"mb-1 block text-xs font-medium text-muted-foreground\">Assunto</label>\n <input\n value={current.subject}\n onChange={(e) => setDraft({ ...current, subject: e.target.value })}\n className=\"w-full rounded-input border border-input bg-card px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring\"\n />\n </div>\n )}\n <div>\n <label className=\"mb-1 block text-xs font-medium text-muted-foreground\">Mensagem</label>\n <textarea\n rows={14}\n value={current.body}\n onChange={(e) => setDraft({ ...current, body: e.target.value })}\n className=\"w-full rounded-input border border-input bg-card px-3 py-2 font-mono text-xs leading-relaxed focus:outline-none focus:ring-2 focus:ring-ring\"\n />\n </div>\n {message.channel === 'whatsapp' && (\n <div>\n <p className=\"mb-1.5 text-xs font-medium text-muted-foreground\">\n BotΓ΅es β o cliente responde no toque, sem digitar\n </p>\n <div className=\"space-y-2\">\n {ACTION_CATALOG.map((action) => {\n const active = message.actions.find((a) => a.id === action.id)\n const on = Boolean(active)\n // `pay` Γ© o ΓΊnico que pergunta a alguΓ©m de fora se pode.\n const gated = action.id === 'pay' && !canOfferPayment(readiness)\n const blocked = gated && !readinessLoading\n const labelValue = labelDrafts[action.id] ?? active?.label ?? action.label\n const commitLabel = () => {\n const next = labelValue.trim()\n setLabelDrafts((d) => { const { [action.id]: _, ...rest } = d; return rest })\n if (!active || !next || next === active.label) return\n void patch({\n eventKey: event.name,\n channel: message.channel,\n actions: message.actions.map((a) => (a.id === action.id ? { ...a, label: next } : a)),\n })\n }\n return (\n <div key={action.id} className=\"flex flex-wrap items-center gap-x-3 gap-y-1\">\n <Switch\n size=\"md\"\n checked={on}\n disabled={saving || gated}\n onCheckedChange={(next) => void patch({\n eventKey: event.name,\n channel: message.channel,\n actions: nextActions(message.actions, action.id, next),\n })}\n label={on ? '' : action.label}\n />\n {on && (\n // O texto do botΓ£o como a cliente vΓͺ. 25 caracteres Γ© o\n // teto da Meta para QUICK_REPLY; mudar o texto de um\n // modelo jΓ‘ aprovado dispara nova aprovaΓ§Γ£o β a\n // pastilha de status acima conta essa histΓ³ria.\n <input\n value={labelValue}\n maxLength={25}\n disabled={saving}\n aria-label={`Texto do botΓ£o ${action.label}`}\n onChange={(e) => setLabelDrafts((d) => ({ ...d, [action.id]: e.target.value }))}\n onBlur={commitLabel}\n onKeyDown={(e) => { if (e.key === 'Enter') (e.target as HTMLInputElement).blur() }}\n className=\"w-36 rounded-input border border-input bg-card px-2 py-1 text-sm focus:outline-none focus:ring-2 focus:ring-ring\"\n />\n )}\n <p className=\"text-xs text-muted-foreground\">\n {blocked\n ? 'Para cobrar por aqui, configure a conta de pagamento em Conversas β Tyxter.'\n : action.hint}\n </p>\n </div>\n )\n })}\n </div>\n </div>\n )}\n <div>\n <p className=\"mb-1.5 text-xs font-medium text-muted-foreground\">\n Campos deste evento β o envio substitui pelo dado real\n </p>\n <div className=\"flex flex-wrap gap-1\">\n {message.placeholders.map((p) => (\n <span key={p} className=\"rounded bg-muted px-1.5 py-0.5 font-mono text-[11px] text-muted-foreground\">\n {p}\n </span>\n ))}\n </div>\n </div>\n </Card>\n )}\n </div>\n )\n}\n","import type { UnifiedConnector } from '@fayz-ai/admin'\nimport type { ConnectorDelivery } from '@fayz-ai/core'\n\n// ---------------------------------------------------------------------------\n// As automaΓ§Γ΅es que a INTEGRAΓΓO Γ© dona.\n//\n// A tela de automaΓ§Γ΅es lia uma fonte sΓ³: mensagens. \"Quando um horΓ‘rio Γ©\n// agendado β manda um e-mail\" Γ© uma preferΓͺncia que alguΓ©m escolheu, mora numa\n// linha de `plg_automations_templates` e pode ser apagada. \"Quando um horΓ‘rio Γ©\n// agendado β cria o evento no Google Calendar\" nΓ£o Γ© preferΓͺncia nenhuma: Γ© o\n// que a integraΓ§Γ£o Γ. Por isso Γ© uma SEGUNDA fonte de linhas, e nΓ£o um texto\n// padrΓ£o fingido β um texto padrΓ£o viraria uma linha que o usuΓ‘rio pode apagar,\n// deixando a integraΓ§Γ£o conectada e meio ligada em silΓͺncio.\n//\n// Elas existem sΓ³ enquanto a conexΓ£o estΓ‘ viva. Desconectar Γ© a saΓda, e Γ© a\n// ΓΊnica β o contrato estΓ‘ em ConnectorManagedAutomation (@fayz-ai/core).\n// ---------------------------------------------------------------------------\n\nexport interface ConnectorAutomationRow {\n connectorId: string\n connectorName: string\n /** Onde a integraΓ§Γ£o Γ© configurada β para onde a linha leva. */\n hostPluginId?: string\n /** A cara da integraΓ§Γ£o, resolvida como em qualquer outra tela (ConnectorMark). */\n icon?: string\n logoUrl?: string\n eventKey: string\n label: string\n /** O locatΓ‘rio pode desligar esta e seguir conectado. */\n optional: boolean\n /** Registro a registro: o que chegou no provedor. Ausente = a integraΓ§Γ£o nΓ£o conta. */\n listDeliveries?: (options?: { eventKey?: string; limit?: number }) => Promise<ConnectorDelivery[]>\n}\n\n/** As linhas de automaΓ§Γ£o dos conectores CONECTADOS. Nada dos demais. */\nexport function connectorAutomationRows(connectors: UnifiedConnector[]): ConnectorAutomationRow[] {\n const out: ConnectorAutomationRow[] = []\n for (const connector of connectors) {\n if (connector.state !== 'connected') continue\n for (const auto of connector.definition?.managedAutomations ?? []) {\n out.push({\n connectorId: connector.id,\n connectorName: connector.name,\n hostPluginId: connector.hostPluginId,\n icon: connector.icon,\n logoUrl: connector.logoUrl,\n eventKey: auto.eventKey,\n label: auto.label,\n optional: auto.optional ?? false,\n ...(connector.definition?.listDeliveries\n ? { listDeliveries: connector.definition.listDeliveries.bind(connector.definition) }\n : {}),\n })\n }\n }\n return out\n}\n\n/** Agrupadas por conector: o dono precisa estar escrito em cima das linhas. */\nexport function groupConnectorAutomations(\n rows: ConnectorAutomationRow[],\n): {\n connectorId: string\n connectorName: string\n hostPluginId?: string\n icon?: string\n logoUrl?: string\n items: ConnectorAutomationRow[]\n}[] {\n const groups: ReturnType<typeof groupConnectorAutomations> = []\n for (const row of rows) {\n let group = groups.find((g) => g.connectorId === row.connectorId)\n if (!group) {\n group = {\n connectorId: row.connectorId,\n connectorName: row.connectorName,\n hostPluginId: row.hostPluginId,\n icon: row.icon,\n logoUrl: row.logoUrl,\n items: [],\n }\n groups.push(group)\n }\n group.items.push(row)\n }\n return groups\n}\n","import React from 'react'\nimport { ChevronRight } from 'lucide-react'\nimport { Card } from '@fayz-ai/ui'\nimport { adminNavigateTo, connectorRoute, ConnectorDeliveries, ConnectorMark } from '@fayz-ai/admin'\nimport {\n groupConnectorAutomations,\n type ConnectorAutomationRow,\n} from '../lib/connector-automations'\n\n// ---------------------------------------------------------------------------\n// As linhas que a integraΓ§Γ£o Γ© dona.\n//\n// Sem interruptor e sem lixeira, de propΓ³sito: uma linha apagada deixaria a\n// integraΓ§Γ£o conectada e meio ligada, e semanas depois isso chega como \"o\n// Google Calendar parou de funcionar\". A saΓda Γ© desconectar, e a linha diz\n// isso em texto β nΓ£o em botΓ£o cinza, que se lΓͺ como algo que o usuΓ‘rio poderia\n// consertar (mesmo padrΓ£o de ConnectorDetail β \"faz parte do app\").\n// ---------------------------------------------------------------------------\n\nexport function ConnectorAutomations({ rows }: { rows: ConnectorAutomationRow[] }) {\n if (rows.length === 0) return null\n\n return (\n <>\n {groupConnectorAutomations(rows).map((group) => {\n const href = connectorRoute({ hostPluginId: group.hostPluginId })\n return (\n <div key={group.connectorId} className=\"space-y-3\">\n <p className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n {group.connectorName}\n </p>\n {group.items.map((row) => (\n <AutomationCard\n key={`${group.connectorId}:${row.eventKey}`}\n row={row}\n group={group}\n href={href}\n />\n ))}\n </div>\n )\n })}\n </>\n )\n}\n\n/**\n * Uma linha da integraΓ§Γ£o, e β quando a integraΓ§Γ£o sabe responder β o que de\n * fato chegou lΓ‘.\n *\n * A tela dizia que o gatilho existe. NΓ£o dizia se o pedido subiu, que Γ© a\n * pergunta que alguΓ©m tem depois de cadastrar. As duas metades eram contadas por\n * sistemas diferentes e nenhum conhecia o outro.\n */\nfunction AutomationCard({\n row,\n group,\n href,\n}: {\n row: ConnectorAutomationRow\n group: { connectorId: string; connectorName: string; icon?: string; logoUrl?: string }\n href: string\n}) {\n const [open, setOpen] = React.useState(false)\n\n return (\n <Card className=\"overflow-hidden\">\n <div\n role=\"button\"\n tabIndex={0}\n onClick={() => adminNavigateTo(href)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); adminNavigateTo(href) }\n }}\n className=\"flex cursor-pointer items-start gap-4 p-4 transition-colors hover:bg-muted/30 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {/* A mesma cara que a integraΓ§Γ£o tem em qualquer outra tela: um plugue\n cinza aqui e o logo do Bling na tela de conectores Γ© a mesma coisa\n parecendo duas. */}\n <ConnectorMark\n connector={{\n id: group.connectorId,\n name: group.connectorName,\n icon: group.icon,\n logoUrl: group.logoUrl,\n }}\n size=\"sm\"\n />\n <div className=\"min-w-0 flex-1\">\n <p className=\"font-medium\">{row.label}</p>\n <p className=\"text-sm text-muted-foreground\">\n Quando <code className=\"font-mono text-xs\">{row.eventKey}</code> acontece aqui.\n </p>\n </div>\n <span className=\"shrink-0 pt-0.5 text-right text-xs text-muted-foreground\">\n {row.optional\n ? `Opcional β desligue em ${group.connectorName}`\n : `Ligada pela integraΓ§Γ£o Β· sai ao desconectar ${group.connectorName}`}\n </span>\n </div>\n\n {row.listDeliveries && (\n <>\n <button\n type=\"button\"\n onClick={() => setOpen(!open)}\n aria-expanded={open}\n className=\"flex w-full items-center gap-2 border-t border-border px-4 py-2 text-left transition-colors hover:bg-muted/40\"\n >\n <ChevronRight className={`h-3.5 w-3.5 shrink-0 text-muted-foreground transition-transform ${open ? 'rotate-90' : ''}`} />\n <span className=\"text-xs font-medium\">O que jΓ‘ foi para o {group.connectorName}</span>\n </button>\n {open && (\n <div className=\"border-t border-border p-4\">\n <ConnectorDeliveries\n load={(options) => row.listDeliveries!({ ...options, eventKey: row.eventKey })}\n providerName={group.connectorName}\n />\n </div>\n )}\n </>\n )}\n </Card>\n )\n}\n","import { errorMessage } from '@fayz-ai/core'\nimport React from 'react'\nimport * as LucideIcons from 'lucide-react'\nimport { ChevronRight, Mail, Megaphone, MessageSquare, Receipt, Smartphone, WandSparkles, Zap } from 'lucide-react'\nimport { Card, PageHeaderActions, PageTabs, Switch, toast, WhatsAppIcon } from '@fayz-ai/ui'\nimport {\n adminNavigateTo, useConnectors, askAI, PageActions, RightRailPage, SettingsTabs, useAgentSurface,\n type AgentSurfaceContribution,\n} from '@fayz-ai/admin'\nimport type { PluginAITool } from '@fayz-ai/core'\n\n// ---------------------------------------------------------------------------\n// A lista inteira, entregue ao assistente.\n//\n// Da lista dΓ‘ para fazer as duas coisas que se faz aqui β ligar/desligar e\n// escrever o texto β sem abrir uma por uma, que Γ© a diferenΓ§a entre \"revise as\n// mensagens de pedido\" e catorze cliques. Passa pelo MESMO `store.upsert` do\n// interruptor e do botΓ£o Salvar.\n//\n// `persist` de propΓ³sito, ao contrΓ‘rio da ferramenta da tela de detalhe: aqui o\n// texto vai direto para o registro, sem passar por um editor onde alguΓ©m leia\n// antes. A confirmaΓ§Γ£o obrigatΓ³ria Γ© o que pΓ΅e uma pessoa entre o modelo e uma\n// mensagem que um cliente vai receber.\n// ---------------------------------------------------------------------------\nconst CONFIGURE_TOOL: PluginAITool = {\n id: 'automations.configure',\n name: 'configureAutomation',\n description:\n 'Turns an automation on or off, and/or rewrites its message. Use the `event` and `channel` values exactly as they appear in the surface state. '\n + 'Placeholders must come from that automation\\'s own list β an invented one renders as literal text in a message a customer reads. '\n + 'To review several, call once per automation.',\n icon: 'Zap',\n mode: 'persist',\n execution: { plane: 'client' },\n category: 'Automations',\n parameters: {\n type: 'object',\n properties: {\n event: { type: 'string', description: 'Event key from the surface state.' },\n channel: { type: 'string', description: 'Channel of that automation (email | whatsapp | sms | in_app).' },\n enabled: { type: 'boolean', description: 'Turn it on or off. Omit to leave as is.' },\n subject: { type: 'string', description: 'New subject. Email only.' },\n body: { type: 'string', description: 'New message body.' },\n },\n required: ['event', 'channel'],\n },\n}\nimport { AutomationDetailPage } from './AutomationDetailPage'\nimport { resolveMessages, useOrganizationStoreLike } from '../lib/runtime'\nimport { usePluginRuntimeOptional } from '@fayz-ai/core'\nimport type { MessageChannel, MessageKind, ResolvedMessage } from '@fayz-ai/core'\nimport type { MessageTemplateStore } from '../data/templates'\nimport { connectorAutomationRows } from '../lib/connector-automations'\nimport { ConnectorAutomations } from './ConnectorAutomations'\nimport {\n ProviderTemplateBadge, providerApprovalFor, useProviderTemplates,\n} from './ProviderTemplateStatus'\n\n// ---------------------------------------------------------------------------\n// AutomaΓ§Γ΅es β quando ISTO acontece, mande AQUILO.\n//\n// Cada linha Γ© uma automaΓ§Γ£o inteira: o gatilho Γ esquerda, o canal na\n// pastilha, o interruptor Γ direita. NΓ£o existe \"modelo\" separado do \"fluxo\" β\n// um texto sem gatilho nunca sai, e um fluxo de um passo Γ© o texto com o\n// gatilho escrito na frente.\n//\n// Agrupado por MΓDULO (Loja, CRM, Agenda) e nΓ£o por canal, porque Γ© assim que a\n// pergunta chega: \"o que a gente manda quando um pedido Γ© enviado?\" β e a\n// resposta pode ser um e-mail, um WhatsApp, ou os dois. Separar por canal, como\n// fazia a tela de e-mails, obriga a visitar dois menus para responder isso.\n//\n// Cada linha Γ© um par eventoΓcanal. O evento aparece uma vez, com uma pastilha\n// por canal ofertado: Γ© o desenho que o RD Station e o Kommo usam para nΓ£o\n// esconder que \"confirmaΓ§Γ£o de pedido\" e \"confirmaΓ§Γ£o por WhatsApp\" sΓ£o o mesmo\n// gatilho com duas saΓdas.\n//\n// Duas fontes de linha, e nΓ£o uma: alΓ©m das mensagens, as automaΓ§Γ΅es que uma\n// integraΓ§Γ£o conectada Γ© dona β ../lib/connector-automations.ts diz por quΓͺ.\n// ---------------------------------------------------------------------------\n\n// A porta de IA desta tela, fora do JSX para a aΓ§Γ£o poder ser declarada.\nconst ASK_AI_ACTION = {\n label: 'Criar com IA',\n hint: 'O que revisar nas automaΓ§Γ΅esβ¦',\n intro: {\n role: 'setup' as const,\n persona: 'Redator das automaΓ§Γ΅es',\n pitch: 'Diga o que revisar nas automaΓ§Γ΅es.',\n description:\n 'Vejo todas as automaΓ§Γ΅es deste app, quais estΓ£o ligadas e o texto de cada uma. Posso ligar, desligar e reescrever β em uma ou em vΓ‘rias de uma vez. VocΓͺ confirma cada mudanΓ§a.',\n suggestions: [\n { label: 'Revise as mensagens de pedido no tom da minha marca' },\n { label: 'Ligue as automaΓ§Γ΅es de entrega' },\n { label: 'Deixe as mensagens de WhatsApp mais curtas' },\n ],\n },\n}\n\nconst CHANNEL_ICON: Record<MessageChannel, React.ComponentType<{ className?: string }>> = {\n email: Mail,\n // The brand glyph, not a generic bubble: in a list of channels, WhatsApp\n // is recognized by its mark before its label.\n whatsapp: WhatsAppIcon,\n sms: Smartphone,\n push: MessageSquare,\n webchat: MessageSquare,\n}\n\nconst CHANNEL_LABEL: Record<MessageChannel, string> = {\n email: 'E-mail', whatsapp: 'WhatsApp', sms: 'SMS', push: 'Push', webchat: 'Chat',\n}\n\nconst KIND_TABS: { value: MessageKind | 'all'; label: string; icon: React.ComponentType<{ className?: string }> }[] = [\n { value: 'all', label: 'Todos', icon: Zap },\n { value: 'transactional', label: 'Transacionais', icon: Receipt },\n { value: 'marketing', label: 'Marketing', icon: Megaphone },\n]\n\nconst KIND_HINT: Record<string, string> = {\n all: 'Tudo que o produto sabe enviar, por qualquer canal.',\n transactional: 'Disparados por uma aΓ§Γ£o da pessoa. NΓ£o precisam de opt-in.',\n marketing: 'Iniciativa da empresa. SΓ³ para quem aceitou receber.',\n}\n\nfunction iconFor(name?: string): React.ComponentType<{ className?: string }> {\n if (!name) return Zap\n const icons = LucideIcons as unknown as Record<string, React.ComponentType<{ className?: string }>>\n return icons[name] ?? Zap\n}\n\n/**\n * Qual automaΓ§Γ£o a URL estΓ‘ pedindo. `null` = nenhuma, e a coluna fica com o\n * assistente.\n *\n * A URL continua sendo a verdade mesmo com o detalhe na coluna: Γ© o que faz o\n * link direto funcionar e o botΓ£o voltar do navegador FECHAR o painel em vez de\n * sair da lista.\n */\nfunction readSelection(basePath: string): { eventKey: string; channel: string } | null {\n const hash = window.location.hash.slice(1) || '/'\n if (!hash.startsWith(basePath + '/')) return null\n const [eventKey, channel] = hash.slice(basePath.length + 1).split('/')\n if (!eventKey || !channel) return null\n return { eventKey, channel }\n}\n\nexport function AutomationsList({ store, variant = 'page', basePath = '/automations' }: {\n store: MessageTemplateStore\n /**\n * Onde esta lista mora, e portanto sob que caminho o detalhe abre.\n *\n * A lista pode estar no menu (`/automations`) ou dentro de ConfiguraΓ§Γ΅es\n * (`/settings/automations`) β e o detalhe tem que abrir SOB ela, senΓ£o clicar\n * numa linha dentro de ConfiguraΓ§Γ΅es jogava a pessoa para fora da tela em que\n * ela estava.\n */\n basePath?: string\n /**\n * Onde a lista estΓ‘ montada, e portanto que faixa de abas ela desenha.\n *\n * 'page' a tela Γ© dela: a faixa Γ© a sub-cabeΓ§a do mΓ³dulo, sangra atΓ© as\n * bordas e sua rΓ©gua encontra a barra da shell.\n * 'panel' ela Γ© o conteΓΊdo de uma aba de ConfiguraΓ§Γ΅es, onde a shell jΓ‘\n * escreveu \"β ConfiguraΓ§Γ΅es / AutomaΓ§Γ΅es\". AΓ vale a MESMA faixa dos\n * outros painΓ©is de configuraΓ§Γ£o (Agenda, CRM, FormulΓ‘rios), que\n * comeΓ§a e termina onde o conteΓΊdo comeΓ§a e termina.\n */\n variant?: 'page' | 'panel'\n}) {\n const tenantId = useOrganizationStoreLike()\n // Os eventos vΓͺm do runtime: sΓ³ os plugins ATIVOS anunciam fatos.\n const runtime = usePluginRuntimeOptional()\n const [messages, setMessages] = React.useState<ResolvedMessage[] | null>(null)\n const [kind, setKind] = React.useState<MessageKind | 'all'>('all')\n // A segunda fonte de linhas: as automaΓ§Γ΅es que a integraΓ§Γ£o Γ© dona. Mesmo\n // loader dos conectores β duas leituras seriam duas respostas para \"o Google\n // Calendar estΓ‘ ligado?\". Sem grants e sem catΓ‘logo: nada disso vira linha\n // aqui, e assim a tela nΓ£o faz rede nenhuma.\n const { connectors } = useConnectors({ includeGrants: false, includeCatalog: false })\n const owned = React.useMemo(() => connectorAutomationRows(connectors ?? []), [connectors])\n // O que a Meta respondeu sobre cada modelo de WhatsApp. Uma leitura por tela,\n // e sem ela a lista continua inteira β sΓ³ sem a pastilha.\n const providerTemplates = useProviderTemplates()\n\n // A automaΓ§Γ£o aberta na coluna da direita, lida da URL.\n const [selected, setSelected] = React.useState(() => readSelection(basePath))\n React.useEffect(() => {\n const sync = () => setSelected(readSelection(basePath))\n sync()\n window.addEventListener('hashchange', sync)\n return () => window.removeEventListener('hashchange', sync)\n }, [basePath])\n\n const reload = React.useCallback(async () => {\n // Uma leitura que falha ainda mostra o catΓ‘logo inteiro nos padrΓ΅es: os\n // eventos sΓ£o cΓ³digo, entΓ£o \"sem personalizaΓ§Γ£o\" Γ© um estado vΓ‘lido e\n // completo, nΓ£o uma tela vazia.\n let overrides: Awaited<ReturnType<MessageTemplateStore['list']>> = []\n try {\n overrides = await store.list(tenantId)\n } catch (err) {\n console.warn('[automations] could not load template overrides; showing defaults', err)\n }\n setMessages(resolveMessages(overrides, runtime?.events ?? []))\n }, [store, tenantId, runtime])\n\n React.useEffect(() => { void reload() }, [reload])\n\n // --- assistant surface ---------------------------------------------------\n const surfaceRef = React.useRef({ messages, store, tenantId, reload, basePath })\n surfaceRef.current = { messages, store, tenantId, reload, basePath }\n\n const agentSurface = React.useMemo<AgentSurfaceContribution>(() => ({\n id: 'automations.list',\n pluginId: 'automations',\n instructions:\n 'The user is on the automations list. `automations` in the surface state is the complete set β use each entry\\'s `event` and `channel` verbatim, and each entry\\'s own `placeholders` when rewriting its text. '\n + 'Call configureAutomation once per automation you change; say afterwards which ones you touched.',\n describe: () => {\n const o = surfaceRef.current\n return {\n title: 'AutomaΓ§Γ΅es',\n state: {\n automations: (o.messages ?? []).map((m) => ({\n event: m.event.name,\n title: m.event.title,\n channel: m.channel,\n enabled: m.enabled,\n customized: Boolean(m.customized),\n subject: m.subject,\n body: m.body,\n // `fields` Γ© o contrato do evento β os mesmos descritores que viram\n // as merge fields do editor. Γ de lΓ‘ que saem os placeholders.\n placeholders: (m.event.fields ?? []).map((f) => `{{${f.name}}}`),\n })),\n },\n }\n },\n tools: [{\n tool: CONFIGURE_TOOL,\n execute: async (args: Record<string, unknown>) => {\n const o = surfaceRef.current\n const found = (o.messages ?? []).find(\n (m) => m.event.name === args.event && m.channel === args.channel,\n )\n if (!found) {\n return {\n ok: false,\n error: 'unknown_automation',\n available: (o.messages ?? []).map((m) => `${m.event.name}/${m.channel}`),\n }\n }\n try {\n await o.store.upsert({\n eventKey: found.event.name,\n channel: found.channel,\n ...(args.enabled === undefined ? {} : { enabled: Boolean(args.enabled) }),\n ...(args.subject === undefined ? {} : { subject: String(args.subject) }),\n ...(args.body === undefined ? {} : { body: String(args.body) }),\n }, o.tenantId)\n await o.reload()\n // `ref.path` decorates the reply with a goto chip (RecordChip) β the\n // user lands on what the agent just changed. `path`, not archetype:\n // an automation is a settings destination, not a record.\n return {\n ok: true,\n event: found.event.name,\n channel: found.channel,\n ref: {\n id: `${found.event.name}/${found.channel}`,\n label: `${found.event.title ?? found.event.name} β ${CHANNEL_LABEL[found.channel] ?? found.channel}`,\n path: `${o.basePath}/${encodeURIComponent(found.event.name)}/${found.channel}`,\n },\n }\n } catch (e) {\n return { ok: false, error: errorMessage(e) }\n }\n },\n }],\n }), [])\n useAgentSurface(agentSurface)\n\n const toggle = async (m: ResolvedMessage, enabled: boolean) => {\n setMessages((prev) => prev?.map((x) =>\n x.event.name === m.event.name && x.channel === m.channel ? { ...x, enabled } : x) ?? null)\n try {\n await store.upsert({ eventKey: m.event.name, channel: m.channel, enabled }, tenantId)\n await reload()\n } catch (err) {\n console.warn('[automations] toggle failed', err)\n toast.error('NΓ£o foi possΓvel salvar')\n await reload()\n }\n }\n\n const visible = (messages ?? []).filter((m) => kind === 'all' || m.kind === kind)\n // As linhas do conector nΓ£o sΓ£o mensagens, entΓ£o nΓ£o tΓͺm \"kind\" β aparecem na\n // aba Todos. Contam no total porque estΓ£o rodando: omiti-las faria o contador\n // dizer menos automaΓ§Γ΅es ativas do que o negΓ³cio tem.\n const ownedVisible = kind === 'all' ? owned : []\n const activeCount = (messages ?? []).filter((m) => m.enabled).length + owned.length\n const totalCount = (messages?.length ?? 0) + owned.length\n\n // Agrupa por mΓ³dulo preservando a ordem de registro dos plugins.\n const groups: { module: string; label: string; items: ResolvedMessage[] }[] = []\n for (const m of visible) {\n let g = groups.find((x) => x.module === m.event.pluginId)\n if (!g) { g = { module: m.event.pluginId, label: m.event.pluginName, items: [] }; groups.push(g) }\n g.items.push(m)\n }\n\n const counter = messages !== null && (\n <span className=\"text-sm text-muted-foreground\">\n {activeCount} de {totalCount} automaΓ§Γ΅es ativas\n </span>\n )\n\n return (\n <div className=\"space-y-6\">\n {/* Declarado, nΓ£o desenhado: o <AskAIButton> cru ficava no cabeΓ§alho no\n celular, onde toda outra tela jΓ‘ entrega a aΓ§Γ£o ao polegar. */}\n {variant !== 'panel' ? (\n <PageHeaderActions>\n <PageActions\n actions={[{\n id: 'automations-ai',\n label: ASK_AI_ACTION.label,\n icon: WandSparkles,\n intent: 'primary',\n creates: true,\n onSelect: () => askAI({ hint: ASK_AI_ACTION.hint, intro: ASK_AI_ACTION.intro }),\n }]}\n />\n </PageHeaderActions>\n ) : null}\n\n {variant === 'panel' ? (\n <SettingsTabs\n tabs={KIND_TABS.map((t) => ({ id: t.value, label: t.label, IconComp: t.icon }))}\n value={kind}\n onChange={(id) => setKind(id as MessageKind | 'all')}\n aria-label=\"AutomaΓ§Γ΅es\"\n actions={counter}\n />\n ) : (\n /* Mesma faixa das listas e da sub-nav de mΓ³dulo. */\n <PageTabs\n className=\"mb-0\"\n tabs={KIND_TABS.map((t) => ({ value: t.value, label: t.label, icon: t.icon }))}\n value={kind}\n onChange={setKind}\n aria-label=\"AutomaΓ§Γ΅es\"\n actions={counter}\n />\n )}\n\n <p className=\"text-sm text-muted-foreground\">{KIND_HINT[kind]}</p>\n\n {messages === null ? (\n <div className=\"space-y-3\">\n {Array.from({ length: 4 }).map((_, i) => (\n <Card key={i} className=\"p-4\">\n <div className=\"h-4 w-40 animate-pulse rounded bg-muted\" />\n <div className=\"mt-2 h-3 w-64 animate-pulse rounded bg-muted\" />\n </Card>\n ))}\n </div>\n ) : groups.length === 0 && ownedVisible.length === 0 ? (\n <Card className=\"flex flex-col items-center gap-1 p-12 text-center\">\n <Zap className=\"mb-2 h-9 w-9 text-muted-foreground/40\" strokeWidth={1.5} />\n <p className=\"text-base font-semibold\">Nenhuma automaΓ§Γ£o nesta aba</p>\n <p className=\"max-w-sm text-sm text-muted-foreground\">\n Os eventos vΓͺm dos mΓ³dulos instalados β a loja traz os do pedido, o CRM os do funil.\n </p>\n </Card>\n ) : groups.map((group) => (\n <div key={group.module} className=\"space-y-3\">\n <p className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n {group.label}\n </p>\n {group.items.map((m) => {\n const Icon = iconFor(m.event.icon ?? m.event.pluginIcon)\n const ChannelIcon = CHANNEL_ICON[m.channel]\n const href = `${basePath}/${encodeURIComponent(m.event.name)}/${m.channel}`\n // A linha cujo detalhe estΓ‘ aberto na coluna ao lado. Sem a marca,\n // com o rail aberto a lista nΓ£o diz de QUEM ele fala.\n const isOpen = selected != null\n && decodeURIComponent(selected.eventKey) === m.event.name\n && selected.channel === m.channel\n return (\n <Card\n key={`${m.event.name}:${m.channel}`}\n role=\"button\"\n tabIndex={0}\n aria-current={isOpen || undefined}\n onClick={() => adminNavigateTo(href)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); adminNavigateTo(href) }\n }}\n // Outline, not border/ring: the glass surface forces the card's\n // border-color to transparent and owns its box-shadow, so both\n // utilities are silently defeated there. Outline is the one\n // edge the glass system does not touch, and inline style keeps\n // it out of Tailwind's content-scan lottery.\n style={isOpen ? { outline: '2px solid hsl(var(--primary) / 0.65)', outlineOffset: '-2px' } : undefined}\n className={`cursor-pointer overflow-hidden transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-ring ${\n isOpen ? '' : 'hover:border-primary/40'\n }`}\n >\n <div className=\"flex items-start gap-4 p-4\">\n <span className=\"flex h-9 w-9 shrink-0 items-center justify-center rounded-lg border border-border text-muted-foreground\">\n <Icon className=\"h-4 w-4\" />\n </span>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <p className=\"font-medium\">{m.override?.name ?? m.event.title ?? m.event.name}</p>\n <span className=\"inline-flex items-center gap-1 rounded-full bg-muted px-2 py-0.5 text-[11px] text-muted-foreground\">\n <ChannelIcon className=\"h-3 w-3\" />\n {CHANNEL_LABEL[m.channel]}\n </span>\n {m.customized && (\n <span className=\"rounded-full bg-primary/10 px-2 py-0.5 text-[11px] text-primary\">\n personalizado\n </span>\n )}\n {/* Ligado nΓ£o quer dizer que vai sair: no WhatsApp a Meta\n ainda precisa aprovar o modelo. */}\n <ProviderTemplateBadge\n approval={providerApprovalFor(providerTemplates, m.event.name, m.channel)}\n />\n </div>\n <p className=\"text-sm text-muted-foreground\">{m.event.description}</p>\n <div className=\"mt-2 flex flex-wrap items-center gap-x-4 gap-y-1 text-xs text-muted-foreground\">\n <span className=\"inline-flex items-center gap-1\">\n <Zap className=\"h-3 w-3\" />\n {m.event.trigger}\n </span>\n {m.subject && <span className=\"truncate\">Assunto: {m.subject}</span>}\n </div>\n </div>\n <div className=\"flex shrink-0 items-center gap-3\">\n {/* Switch e nΓ£o checkbox: isto vale na hora, nΓ£o quando\n algum Salvar for clicado. */}\n <Switch\n checked={m.enabled}\n onCheckedChange={(next) => void toggle(m, next)}\n label={m.enabled ? 'Ativo' : 'Inativo'}\n aria-label={`${m.event.title} β ${CHANNEL_LABEL[m.channel]}`}\n />\n <ChevronRight className=\"h-4 w-4 text-muted-foreground\" />\n </div>\n </div>\n </Card>\n )\n })}\n </div>\n ))}\n\n {messages !== null && <ConnectorAutomations rows={ownedVisible} />}\n\n {/* O detalhe abre AO LADO da lista, nΓ£o no lugar dela: escolher o que uma\n automaΓ§Γ£o diz Γ© olhar as outras que jΓ‘ existem, e a tela cheia tirava\n exatamente isso de vista. O nome sai da linha que jΓ‘ estΓ‘ carregada β\n a coluna se nomeia antes de o detalhe terminar de carregar. */}\n {selected && (\n <RightRailPage\n title={\n (messages ?? []).find(\n (m) => m.event.name === decodeURIComponent(selected.eventKey) && m.channel === selected.channel,\n )?.event.title ?? 'AutomaΓ§Γ£o'\n }\n open\n onClose={() => adminNavigateTo(basePath)}\n width=\"max-w-2xl\"\n >\n <div className=\"min-h-0 flex-1 overflow-y-auto p-4\">\n <AutomationDetailPage\n eventKey={selected.eventKey}\n channel={selected.channel}\n store={store}\n backTo={basePath}\n embedded\n />\n </div>\n </RightRailPage>\n )}\n </div>\n )\n}\n","import { getSupabaseClientOptional, normalizeMessageActions } from '@fayz-ai/core'\nimport type { MessageTemplate, UpsertMessageTemplateInput } from '@fayz-ai/core'\n\n// ---------------------------------------------------------------------------\n// Acesso aos modelos personalizados. SΓ³ as PERSONALIZAΓΓES: o catΓ‘logo Γ©\n// cΓ³digo, e uma leitura que falha ainda deve mostrar a lista inteira nos\n// padrΓ΅es β ver `resolveMessages`.\n// ---------------------------------------------------------------------------\n\nconst TABLE = 'plg_automations_templates'\n\nfunction rowToTemplate(row: any): MessageTemplate {\n return {\n id: row.id,\n tenantId: row.tenant_id,\n eventKey: row.event_key,\n channel: row.channel ?? 'email',\n // NULL fica NULL: quem decide o padrΓ£o Γ© o catΓ‘logo, nΓ£o este mapeamento.\n // Colapsar para `false` aqui desligaria em silΓͺncio todo modelo cuja linha\n // sΓ³ existe porque o texto foi editado.\n enabled: row.enabled ?? null,\n // String vazia e NULL significam a mesma coisa β \"sem personalizaΓ§Γ£o\" β,\n // senΓ£o um assunto apagado sairia em branco em vez de voltar ao padrΓ£o.\n subject: row.subject || null,\n body: row.body || null,\n name: row.name || null,\n // NULL fica NULL pelo mesmo motivo do `enabled`; lista vazia Γ© uma escolha\n // (\"sem botΓ΅es\"), nΓ£o a ausΓͺncia de uma.\n actions: normalizeMessageActions(row.actions),\n updatedAt: row.updated_at ?? row.created_at,\n }\n}\n\nexport interface MessageTemplateStore {\n list(tenantId?: string): Promise<MessageTemplate[]>\n upsert(input: UpsertMessageTemplateInput, tenantId?: string): Promise<MessageTemplate>\n /** Descarta a personalizaΓ§Γ£o inteira β a linha some e o padrΓ£o volta a valer. */\n reset(eventKey: string, channel: string, tenantId?: string): Promise<void>\n}\n\nexport function createSupabaseTemplateStore(): MessageTemplateStore {\n const db = () => {\n const client = getSupabaseClientOptional()\n if (!client) throw new Error('@fayz-ai/plugin-automations: Supabase client not initialized')\n return client as any\n }\n\n return {\n async list(tenantId) {\n let q = db().from(TABLE).select('*')\n if (tenantId) q = q.eq('tenant_id', tenantId)\n const { data, error } = await q\n if (error) throw error\n return (data ?? []).map(rowToTemplate)\n },\n\n async upsert(input, tenantId) {\n const payload: Record<string, unknown> = {\n tenant_id: tenantId,\n event_key: input.eventKey,\n channel: input.channel,\n }\n // SΓ³ o que veio: omitir uma chave tem de significar \"nΓ£o mexa nisso\",\n // senΓ£o salvar o texto apagaria o ligado/desligado junto.\n if (input.enabled !== undefined) payload.enabled = input.enabled\n if (input.subject !== undefined) payload.subject = input.subject\n if (input.body !== undefined) payload.body = input.body\n if (input.name !== undefined) payload.name = input.name\n if (input.actions !== undefined) payload.actions = input.actions\n\n const { data, error } = await db()\n .from(TABLE)\n .upsert(payload, { onConflict: 'tenant_id,event_key,channel' })\n .select().single()\n if (error) throw error\n return rowToTemplate(data)\n },\n\n async reset(eventKey, channel, tenantId) {\n let q = db().from(TABLE).delete().eq('event_key', eventKey).eq('channel', channel)\n if (tenantId) q = q.eq('tenant_id', tenantId)\n const { error } = await q\n if (error) throw error\n },\n }\n}\n","import React from 'react'\nimport { Workflow } from 'lucide-react'\nimport {\n Modal, ModalContent, ModalHeader, ModalTitle, ModalBody, ModalFooter,\n Button, Input,\n Select, SelectTrigger, SelectValue, SelectContent, SelectItem,\n toast,\n} from '@fayz-ai/ui'\nimport { errorMessage, useTranslation, usePluginRuntimeOptional } from '@fayz-ai/core'\n\n// ---------------------------------------------------------------------------\n// Nova cadΓͺncia.\n//\n// Era `window.prompt` duas vezes β uma para o nome e outra pedindo que se\n// DIGITASSE `crm.lead_created`. Quem nΓ£o conhece o catΓ‘logo de eventos nΓ£o tem\n// como acertar, e errar nΓ£o dΓ‘ erro: cria um fluxo que espera por um fato que\n// nunca chega, e o ecrΓ£ fica mostrando uma cadΓͺncia ativa com zero pessoas.\n//\n// As trΓͺs perguntas que definem uma cadΓͺncia, e nenhuma a mais:\n//\n// QUEM ENTRA um fato do catΓ‘logo (sΓ³ os plugins ativos anunciam fatos),\n// escolhido numa lista β nΓ£o digitado.\n// QUEM SAI o fato que faz alguΓ©m parar de receber. Γ o campo que\n// separa uma rΓ©gua de uma perseguiΓ§Γ£o: sem ele, quem jΓ‘\n// respondeu continua recebendo a mensagem do dia 5.\n// COMO SE CHAMA para o operador achar de novo.\n//\n// Os passos NΓO entram aqui. Uma cadΓͺncia nasce vazia e desligada, e os passos\n// se montam na tabela do painel, onde se vΓͺ o que cada um jΓ‘ enviou. Um\n// formulΓ‘rio que pedisse nome, gatilho, saΓda e trΓͺs mensagens de uma vez seria\n// abandonado no terceiro campo.\n// ---------------------------------------------------------------------------\n\nexport function CadenceComposer({ open, onClose, onCreate }: {\n open: boolean\n onClose: () => void\n onCreate: (input: { name: string; entryEvent: string; exitEvents: string[] }) => Promise<void>\n}) {\n const t = useTranslation()\n const runtime = usePluginRuntimeOptional()\n // SΓ³ os plugins ATIVOS anunciam fatos: oferecer um gatilho de um mΓ³dulo que\n // nΓ£o estΓ‘ montado Γ© prometer uma cadΓͺncia que nunca dispara.\n const events = runtime?.events ?? []\n\n const [name, setName] = React.useState('')\n const [entryEvent, setEntryEvent] = React.useState('')\n const [exitEvent, setExitEvent] = React.useState('')\n const [saving, setSaving] = React.useState(false)\n\n React.useEffect(() => {\n if (!open) return\n setName(''); setExitEvent('')\n setEntryEvent(events.find((e) => e.name === 'crm.lead_created')?.name ?? events[0]?.name ?? '')\n }, [open])\n\n const entry = events.find((e) => e.name === entryEvent)\n\n async function submit() {\n if (!name.trim() || !entryEvent || saving) return\n setSaving(true)\n try {\n await onCreate({\n name: name.trim(),\n entryEvent,\n exitEvents: exitEvent ? [exitEvent] : [],\n })\n onClose()\n } catch (e) {\n toast.error(errorMessage(e))\n } finally {\n setSaving(false)\n }\n }\n\n return (\n <Modal open={open} onOpenChange={(o) => { if (!o) onClose() }}>\n <ModalContent size=\"md\">\n <ModalHeader>\n <ModalTitle>{t('automations.flow.newTitle')}</ModalTitle>\n </ModalHeader>\n <ModalBody className=\"space-y-4\">\n <label className=\"block space-y-1.5\">\n <span className=\"text-sm font-medium text-foreground\">{t('automations.flow.nameLabel')}</span>\n <Input value={name} onChange={(e) => setName(e.target.value)} placeholder={t('automations.flow.namePlaceholder')} />\n </label>\n\n <label className=\"block space-y-1.5\">\n <span className=\"text-sm font-medium text-foreground\">{t('automations.flow.entryLabel')}</span>\n {events.length > 0 ? (\n <Select value={entryEvent} onValueChange={setEntryEvent}>\n <SelectTrigger><SelectValue placeholder={t('automations.flow.entryPlaceholder')} /></SelectTrigger>\n <SelectContent>\n {events.map((e) => <SelectItem key={e.name} value={e.name}>{e.title ?? e.name}</SelectItem>)}\n </SelectContent>\n </Select>\n ) : (\n <p className=\"rounded-lg border border-dashed px-3 py-2 text-xs text-muted-foreground\">\n {t('automations.flow.noEvents')}\n </p>\n )}\n {entry?.trigger && <span className=\"text-[11px] text-muted-foreground\">{entry.trigger}</span>}\n </label>\n\n <label className=\"block space-y-1.5\">\n <span className=\"text-sm font-medium text-foreground\">{t('automations.flow.exitLabel')}</span>\n <Select value={exitEvent || '__none__'} onValueChange={(v) => setExitEvent(v === '__none__' ? '' : v)}>\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n <SelectItem value=\"__none__\">{t('automations.flow.exitNone')}</SelectItem>\n {events.filter((e) => e.name !== entryEvent).map((e) => (\n <SelectItem key={e.name} value={e.name}>{e.title ?? e.name}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n <span className=\"text-[11px] text-muted-foreground\">{t('automations.flow.exitHint')}</span>\n </label>\n\n <p className=\"flex items-start gap-2 rounded-lg bg-muted/40 px-3 py-2 text-[11px] text-muted-foreground\">\n <Workflow className=\"mt-0.5 h-3.5 w-3.5 shrink-0\" />\n {t('automations.flow.bornOffHint')}\n </p>\n </ModalBody>\n <ModalFooter>\n <Button variant=\"outline\" onClick={onClose}>{t('common.cancel')}</Button>\n <Button onClick={() => { void submit() }} disabled={saving || !name.trim() || !entryEvent}>\n {t('automations.flow.create')}\n </Button>\n </ModalFooter>\n </ModalContent>\n </Modal>\n )\n}\n","import { getSupabaseClientOptional, getActiveTenantId } from '@fayz-ai/core'\n\n// ---------------------------------------------------------------------------\n// Cadence flows: the rows behind \"day 0 message, day 2 call, day 5 message\".\n//\n// Read and write only. The ENGINE is SQL β `automations_flows_run_due` on the\n// minute tick β and nothing here advances an enrolment. That split is the point:\n// a cadence that depended on a browser being open would stop at 6pm.\n//\n// Enrolments are read-only by policy too (the operator leaves a flow through\n// `automations_flow_exit`, never by editing a pointer), so this module exposes\n// no write for them.\n// ---------------------------------------------------------------------------\n\nconst FLOWS = 'plg_automations_flows'\nconst STEPS = 'plg_automations_flow_steps'\nconst ENROLLMENTS = 'plg_automations_enrollments'\nconst STEP_STATS = 'v_automations_flow_steps'\n\nexport interface CadenceFlow {\n id: string\n tenantId: string\n name: string\n description: string | null\n /** The event that puts somebody in, e.g. `crm.lead_created`. */\n entryEvent: string\n /** Events that take somebody out. Empty means \"only ends by running out\". */\n exitEvents: string[]\n isActive: boolean\n createdAt: string\n updatedAt: string\n}\n\nexport type CadenceStepKind = 'message' | 'task'\n\nexport interface CadenceStep {\n id: string\n flowId: string\n position: number\n /** Minutes to wait AFTER THE PREVIOUS STEP β not since enrolment. */\n delayMinutes: number\n kind: CadenceStepKind\n templateKey: string | null\n /** NULL lets the recipient's own preference choose. */\n channel: string | null\n taskTitle: string | null\n taskDueDays: number | null\n}\n\n/** A step plus what actually happened on it. Per step, never per flow: the\n * question a cadence is judged by is WHERE people stop. */\nexport interface CadenceStepStats extends CadenceStep {\n queued: number\n sent: number\n blocked: number\n failed: number\n cancelled: number\n}\n\nexport interface FlowCounts {\n active: number\n completed: number\n exited: number\n}\n\nexport interface CadenceFlowStore {\n listFlows(): Promise<CadenceFlow[]>\n saveFlow(input: Partial<CadenceFlow> & { name: string; entryEvent: string }): Promise<CadenceFlow>\n setFlowActive(id: string, isActive: boolean): Promise<void>\n deleteFlow(id: string): Promise<void>\n listSteps(flowId: string): Promise<CadenceStepStats[]>\n saveStep(flowId: string, input: Partial<CadenceStep>): Promise<void>\n deleteStep(id: string): Promise<void>\n countsFor(flowId: string): Promise<FlowCounts>\n}\n\nfunction rowToFlow(r: any): CadenceFlow {\n return {\n id: r.id,\n tenantId: r.tenant_id,\n name: r.name,\n description: r.description ?? null,\n entryEvent: r.entry_event,\n exitEvents: Array.isArray(r.exit_events) ? r.exit_events : [],\n isActive: r.is_active === true,\n createdAt: r.created_at,\n updatedAt: r.updated_at ?? r.created_at,\n }\n}\n\nfunction rowToStepStats(r: any): CadenceStepStats {\n return {\n id: r.step_id ?? r.id,\n flowId: r.flow_id,\n position: r.position,\n delayMinutes: r.delay_minutes ?? 0,\n kind: (r.kind === 'task' ? 'task' : 'message'),\n templateKey: r.template_key ?? null,\n channel: r.channel ?? null,\n taskTitle: r.task_title ?? null,\n taskDueDays: r.task_due_days ?? null,\n queued: Number(r.queued ?? 0),\n sent: Number(r.sent ?? 0),\n blocked: Number(r.blocked ?? 0),\n failed: Number(r.failed ?? 0),\n cancelled: Number(r.cancelled ?? 0),\n }\n}\n\n/**\n * Sparse positions (10, 20, 30β¦) so that inserting a step between two others\n * does not renumber the ones after it β an enrolment's pointer names a\n * position, and renumbering would move people to a step they already had.\n */\nexport function nextPosition(steps: Array<{ position: number }>): number {\n if (steps.length === 0) return 10\n return Math.max(...steps.map((s) => s.position)) + 10\n}\n\n/** Minutes as a salesperson says them. 2880 is \"2 days\", not \"two thousand\". */\nexport function describeDelay(minutes: number, t: (k: string, v?: Record<string, string>) => string): string {\n if (minutes <= 0) return t('automations.flow.delayNow')\n if (minutes % 1440 === 0) return t('automations.flow.delayDays', { count: String(minutes / 1440) })\n if (minutes % 60 === 0) return t('automations.flow.delayHours', { count: String(minutes / 60) })\n return t('automations.flow.delayMinutes', { count: String(minutes) })\n}\n\nexport function createSupabaseFlowStore(): CadenceFlowStore {\n function client() {\n const supabase = getSupabaseClientOptional() as any\n if (!supabase) throw new Error('Supabase not initialized')\n return supabase\n }\n\n const store: CadenceFlowStore = {\n async listFlows() {\n const { data, error } = await client().from(FLOWS).select('*').order('name')\n if (error) throw new Error(error.message)\n return (data ?? []).map(rowToFlow)\n },\n\n async saveFlow(input) {\n const row: any = {\n name: input.name,\n description: input.description ?? null,\n entry_event: input.entryEvent,\n exit_events: input.exitEvents ?? [],\n }\n if (input.id) {\n const { data, error } = await client().from(FLOWS).update(row).eq('id', input.id).select().single()\n if (error) throw new Error(error.message)\n return rowToFlow(data)\n }\n row.tenant_id = getActiveTenantId()\n // A new flow is born INACTIVE. `is_active` defaults false in the table and\n // is not set here on purpose: a cadence that starts sending the moment\n // somebody saves a draft is a cadence that sends a draft.\n const { data, error } = await client().from(FLOWS).insert(row).select().single()\n if (error) throw new Error(error.message)\n return rowToFlow(data)\n },\n\n async setFlowActive(id, isActive) {\n const { error } = await client().from(FLOWS)\n .update({ is_active: isActive, updated_at: new Date().toISOString() }).eq('id', id)\n if (error) throw new Error(error.message)\n },\n\n async deleteFlow(id) {\n const { error } = await client().from(FLOWS).delete().eq('id', id)\n if (error) throw new Error(error.message)\n },\n\n async listSteps(flowId) {\n // The stats view, not the table: the numbers are the reason to look.\n const { data, error } = await client().from(STEP_STATS)\n .select('*').eq('flow_id', flowId).order('position')\n if (error) throw new Error(error.message)\n return (data ?? []).map(rowToStepStats)\n },\n\n async saveStep(flowId, input) {\n const row: any = {\n flow_id: flowId,\n position: input.position,\n delay_minutes: input.delayMinutes ?? 0,\n kind: input.kind ?? 'message',\n template_key: input.kind === 'task' ? null : (input.templateKey ?? null),\n channel: input.kind === 'task' ? null : (input.channel ?? null),\n task_title: input.kind === 'task' ? (input.taskTitle ?? null) : null,\n task_due_days: input.kind === 'task' ? (input.taskDueDays ?? null) : null,\n }\n if (input.id) {\n const { error } = await client().from(STEPS).update(row).eq('id', input.id)\n if (error) throw new Error(error.message)\n return\n }\n row.tenant_id = getActiveTenantId()\n const { error } = await client().from(STEPS).insert(row)\n if (error) throw new Error(error.message)\n },\n\n async deleteStep(id) {\n const { error } = await client().from(STEPS).delete().eq('id', id)\n if (error) throw new Error(error.message)\n },\n\n async countsFor(flowId) {\n const { data, error } = await client().from(ENROLLMENTS).select('status').eq('flow_id', flowId)\n if (error) throw new Error(error.message)\n const rows = (data ?? []) as Array<{ status: string }>\n return {\n active: rows.filter((r) => r.status === 'active').length,\n completed: rows.filter((r) => r.status === 'completed').length,\n exited: rows.filter((r) => r.status === 'exited').length,\n }\n },\n }\n\n return store\n}\n","import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { ChevronRight, Clock, ListChecks, Loader2, MessageSquare, Plus, Trash2 } from 'lucide-react'\nimport { Card, DataTable, PageHeaderActions, Switch, toast } from '@fayz-ai/ui'\nimport { CadenceComposer } from './CadenceComposer'\nimport { PageActions } from '@fayz-ai/admin'\nimport { errorMessage, useTranslation } from '@fayz-ai/core'\nimport {\n createSupabaseFlowStore, describeDelay, nextPosition,\n type CadenceFlow, type CadenceStepStats, type FlowCounts,\n} from '../data/flows'\n\n// ---------------------------------------------------------------------------\n// Cadence flows.\n//\n// The list answers \"what is running\"; the panel answers \"where do people stop\".\n// Those are the only two questions a cadence screen has to answer, and the\n// second one is why the step table carries the numbers instead of a chart\n// somewhere else: the third message being the one nobody answers is a fact\n// about a ROW, and it belongs next to the row.\n//\n// Nothing here advances a cadence. The engine is `automations_flows_run_due` on\n// the minute tick β a cadence that needed this page open would stop at 6pm.\n// ---------------------------------------------------------------------------\n\nconst store = createSupabaseFlowStore()\n\n/** The delays a cadence is actually built from, in minutes. */\nconst DELAY_CHOICES = [0, 60, 1440, 2880, 4320, 10080]\n\nfunction useStepColumns(onDelete: (id: string) => void): ColumnDef<CadenceStepStats, any>[] {\n const t = useTranslation()\n return useMemo(() => [\n {\n accessorKey: 'position', header: '#',\n cell: ({ getValue }) => <span className=\"text-xs tabular-nums text-muted-foreground\">{getValue() as number}</span>,\n },\n {\n id: 'step', header: t('automations.flow.colStep'),\n cell: ({ row }) => {\n const s = row.original\n const isTask = s.kind === 'task'\n return (\n <span className=\"inline-flex items-center gap-1.5 text-sm\">\n {isTask ? <ListChecks className=\"h-3.5 w-3.5 text-muted-foreground\" />\n : <MessageSquare className=\"h-3.5 w-3.5 text-muted-foreground\" />}\n {isTask ? s.taskTitle : s.templateKey}\n {!isTask && s.channel && (\n <span className=\"rounded bg-muted px-1.5 py-0.5 text-[10px] text-muted-foreground\">{s.channel}</span>\n )}\n </span>\n )\n },\n },\n {\n accessorKey: 'delayMinutes', header: t('automations.flow.colWait'),\n cell: ({ getValue }) => (\n <span className=\"inline-flex items-center gap-1 text-xs text-muted-foreground\">\n <Clock className=\"h-3 w-3\" />{describeDelay(getValue() as number, t)}\n </span>\n ),\n },\n // The scoreboard. Zeroes are shown rather than hidden: a step that has never\n // sent is the finding, not an empty cell.\n {\n accessorKey: 'queued', header: t('automations.flow.colQueued'),\n cell: ({ getValue }) => <span className=\"text-xs tabular-nums\">{getValue() as number}</span>,\n },\n {\n accessorKey: 'sent', header: t('automations.flow.colSent'),\n cell: ({ getValue }) => <span className=\"text-xs tabular-nums\">{getValue() as number}</span>,\n },\n {\n accessorKey: 'blocked', header: t('automations.flow.colBlocked'),\n cell: ({ getValue }) => {\n const n = getValue() as number\n return <span className={`text-xs tabular-nums ${n > 0 ? 'text-warning' : ''}`}>{n}</span>\n },\n },\n {\n accessorKey: 'failed', header: t('automations.flow.colFailed'),\n cell: ({ getValue }) => {\n const n = getValue() as number\n return <span className={`text-xs tabular-nums ${n > 0 ? 'text-destructive' : ''}`}>{n}</span>\n },\n },\n {\n id: 'actions', header: '',\n cell: ({ row }) => (\n <div className=\"flex justify-end\">\n <button\n onClick={(e) => { e.stopPropagation(); onDelete(row.original.id) }}\n title={t('automations.flow.deleteStep')}\n className=\"inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-destructive\"\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n ),\n },\n ], [t, onDelete])\n}\n\nfunction StepComposer({ steps, onAdd }: {\n steps: CadenceStepStats[]\n onAdd: (input: { kind: 'message' | 'task'; delayMinutes: number; templateKey?: string; channel?: string; taskTitle?: string; position: number }) => void\n}) {\n const t = useTranslation()\n const [kind, setKind] = useState<'message' | 'task'>('message')\n const [delay, setDelay] = useState(1440)\n const [value, setValue] = useState('')\n\n const submit = () => {\n if (!value.trim()) {\n toast.error(t(kind === 'task' ? 'automations.flow.needTitle' : 'automations.flow.needTemplate'))\n return\n }\n onAdd({\n kind, delayMinutes: delay, position: nextPosition(steps),\n ...(kind === 'task' ? { taskTitle: value.trim() } : { templateKey: value.trim() }),\n })\n setValue('')\n }\n\n return (\n <div className=\"mt-3 flex flex-wrap items-center gap-2 rounded-lg border border-dashed p-3\">\n <select\n value={kind}\n onChange={(e) => { setKind(e.target.value as 'message' | 'task'); setValue('') }}\n className=\"rounded-md border bg-background px-2 py-1.5 text-sm\"\n >\n <option value=\"message\">{t('automations.flow.kindMessage')}</option>\n <option value=\"task\">{t('automations.flow.kindTask')}</option>\n </select>\n <select\n value={delay}\n onChange={(e) => setDelay(Number(e.target.value))}\n className=\"rounded-md border bg-background px-2 py-1.5 text-sm\"\n >\n {DELAY_CHOICES.map((m) => (\n <option key={m} value={m}>{describeDelay(m, t)}</option>\n ))}\n </select>\n <input\n value={value}\n onChange={(e) => setValue(e.target.value)}\n onKeyDown={(e) => { if (e.key === 'Enter') submit() }}\n placeholder={t(kind === 'task' ? 'automations.flow.titlePlaceholder' : 'automations.flow.templatePlaceholder')}\n className=\"min-w-[200px] flex-1 rounded-md border bg-background px-2 py-1.5 text-sm\"\n />\n <button\n onClick={submit}\n className=\"inline-flex items-center gap-1 rounded-md bg-primary px-3 py-1.5 text-sm text-primary-foreground hover:opacity-90\"\n >\n <Plus className=\"h-3.5 w-3.5\" />{t('automations.flow.addStep')}\n </button>\n </div>\n )\n}\n\nexport function FlowsPage() {\n const t = useTranslation()\n const [flows, setFlows] = useState<CadenceFlow[]>([])\n const [loading, setLoading] = useState(true)\n const [selectedId, setSelectedId] = useState<string | null>(null)\n const [steps, setSteps] = useState<CadenceStepStats[]>([])\n const [counts, setCounts] = useState<FlowCounts | null>(null)\n const [composerOpen, setComposerOpen] = useState(false)\n\n const load = useCallback(async () => {\n setLoading(true)\n try {\n setFlows(await store.listFlows())\n } catch (e) {\n toast.error(errorMessage(e))\n } finally {\n setLoading(false)\n }\n }, [])\n\n // `selectedId` lives in a ref so a late answer can be checked against the\n // selection as it is NOW, without re-creating the callback on every change.\n const selectedRef = useRef<string | null>(null)\n selectedRef.current = selectedId\n\n const loadDetail = useCallback(async (flowId: string) => {\n try {\n const [s, c] = await Promise.all([store.listSteps(flowId), store.countsFor(flowId)])\n // Two selections can resolve out of order, and the panel renders whatever\n // `steps` holds. Applying the wrong flow's rows is not cosmetic: the trash\n // icon deletes `row.original.id`, so a click in that window removes a step\n // from the flow the operator is no longer looking at.\n if (selectedRef.current !== flowId) return\n setSteps(s); setCounts(c)\n } catch (e) {\n toast.error(errorMessage(e))\n }\n }, [])\n\n const deleteStep = useCallback((id: string) => {\n void (async () => {\n try {\n await store.deleteStep(id)\n if (selectedId) await loadDetail(selectedId)\n } catch (e) { toast.error(errorMessage(e)) }\n })()\n }, [selectedId, loadDetail])\n const stepColumns = useStepColumns(deleteStep)\n\n useEffect(() => { void load() }, [load])\n useEffect(() => {\n // Clear FIRST. The panel opens as soon as `selectedId` flips, so without\n // this it shows the previous flow's steps and counts until the fetch lands\n // β and forever if it throws, since `loadDetail` only toasts.\n setSteps([]); setCounts(null)\n if (selectedId) void loadDetail(selectedId)\n }, [selectedId, loadDetail])\n\n const selected = flows.find((f) => f.id === selectedId) ?? null\n\n async function createFlow(input: { name: string; entryEvent: string; exitEvents: string[] }) {\n const flow = await store.saveFlow(input)\n await load()\n // Abre o painel dela na hora: uma cadΓͺncia sem passos nΓ£o faz nada, e o\n // prΓ³ximo ato Γ© sempre adicionar o primeiro.\n setSelectedId(flow.id)\n toast.success(t('automations.flow.created'))\n }\n\n async function toggleActive(flow: CadenceFlow) {\n // Turning a flow ON with no steps would enrol people into nothing: they\n // would sit in `active` forever, and the screen would show a cadence that\n // never sends. Cheaper to refuse than to explain.\n if (!flow.isActive) {\n // Always ask. Reading the shared `steps` when `flow.id === selectedId`\n // meant that during the window above β selection flipped, fetch not back\n // β an empty list let a flow with no steps switch itself on, which is the\n // one thing this guard exists to stop.\n const s = await store.listSteps(flow.id)\n if (s.length === 0) {\n toast.error(t('automations.flow.needStepsToActivate'))\n return\n }\n }\n try {\n await store.setFlowActive(flow.id, !flow.isActive)\n await load()\n } catch (e) {\n toast.error(errorMessage(e))\n }\n }\n\n // Esqueleto com a FORMA da lista, nΓ£o uma linha de texto centrada: a tela\n // que aparece depois tem cartΓ΅es empilhados, e um \"Carregandoβ¦\" faz o\n // conteΓΊdo saltar quando chega.\n if (loading) {\n return <div className=\"space-y-2\" aria-busy=\"true\" aria-label={t('automations.flow.loading')}>\n {[0, 1, 2].map((i) => (\n <Card key={i} className=\"p-3\">\n <div className=\"flex items-center gap-3\">\n <div className=\"h-4 w-4 shrink-0 animate-pulse rounded bg-muted/40\" />\n <div className=\"h-3.5 animate-pulse rounded bg-muted/40\" style={{ width: `${34 - i * 6}%` }} />\n <div className=\"h-4 w-28 animate-pulse rounded-full bg-muted/30\" />\n <div className=\"ml-auto h-5 w-9 animate-pulse rounded-full bg-muted/30\" />\n </div>\n </Card>\n ))}\n </div>\n }\n\n return (\n <div className=\"space-y-4\">\n <PageHeaderActions>\n <PageActions\n actions={[{\n id: 'new-flow', label: t('automations.flow.new'), icon: Plus,\n intent: 'primary' as const, creates: true, onSelect: () => setComposerOpen(true),\n }]}\n />\n </PageHeaderActions>\n\n <CadenceComposer\n open={composerOpen}\n onClose={() => setComposerOpen(false)}\n onCreate={createFlow}\n />\n\n {flows.length === 0 ? (\n <Card className=\"flex flex-col items-center gap-1 border-dashed py-12 text-center\">\n <p className=\"text-sm font-medium\">{t('automations.flow.emptyTitle')}</p>\n <p className=\"max-w-md text-xs text-muted-foreground\">{t('automations.flow.emptyHint')}</p>\n </Card>\n ) : (\n <div className=\"space-y-2\">\n {flows.map((flow) => (\n <Card key={flow.id} className=\"p-3\">\n <div className=\"flex items-center gap-3\">\n <button\n onClick={() => setSelectedId(selectedId === flow.id ? null : flow.id)}\n className=\"flex flex-1 items-center gap-2 text-left\"\n >\n <ChevronRight\n className={`h-4 w-4 text-muted-foreground transition-transform ${selectedId === flow.id ? 'rotate-90' : ''}`}\n />\n <span className=\"text-sm font-medium\">{flow.name}</span>\n <span className=\"rounded bg-muted px-1.5 py-0.5 text-[10px] text-muted-foreground\">\n {flow.entryEvent}\n </span>\n </button>\n {/* The switch says what it will do, not what it is: a flow with\n no steps cannot be turned on, and the refusal explains. */}\n <Switch\n checked={flow.isActive}\n onCheckedChange={() => { void toggleActive(flow) }}\n aria-label={t('automations.flow.toggle')}\n />\n </div>\n\n {selectedId === flow.id && (\n <div className=\"mt-3 border-t pt-3\">\n {counts && (\n <p className=\"mb-2 text-xs text-muted-foreground\">\n {t('automations.flow.counts', {\n active: String(counts.active),\n completed: String(counts.completed),\n exited: String(counts.exited),\n })}\n </p>\n )}\n <DataTable\n columns={stepColumns}\n data={steps}\n emptyMessage={\n <p className=\"py-4 text-xs text-muted-foreground\">{t('automations.flow.noSteps')}</p>\n }\n />\n\n <StepComposer\n steps={steps}\n onAdd={(input) => {\n void (async () => {\n try {\n await store.saveStep(flow.id, input)\n await loadDetail(flow.id)\n } catch (e) { toast.error(errorMessage(e)) }\n })()\n }}\n />\n </div>\n )}\n </Card>\n ))}\n </div>\n )}\n </div>\n )\n}\n","// automations.* β the cadence screen. The plugin's older views still carry\n// their pt-BR copy inline; new UI ships both locales (CONTRIBUTING).\nexport const en: Record<string, string> = {\n \"automations.flow.newTitle\": \"New cadence\",\n \"automations.flow.nameLabel\": \"Name\",\n \"automations.flow.namePlaceholder\": \"e.g. New lead sequence\",\n \"automations.flow.entryLabel\": \"Who enters\",\n \"automations.flow.entryPlaceholder\": \"Pick the fact that puts somebody in\",\n \"automations.flow.exitLabel\": \"Who leaves\",\n \"automations.flow.exitNone\": \"Only leaves when the steps run out\",\n \"automations.flow.exitHint\": \"The fact that stops the sequence. Without it, someone who already replied still gets the day-5 message.\",\n \"automations.flow.bornOffHint\": \"A cadence is born off and empty. Add the steps below and switch it on when it is ready.\",\n \"automations.flow.noEvents\": \"No active module announces facts in this app β no trigger, no cadence.\",\n \"automations.flow.create\": \"Create cadence\",\n \"automations.flow.new\": \"New flow\",\n \"automations.flow.loading\": \"Loading flowsβ¦\",\n \"automations.flow.emptyTitle\": \"No cadence flows yet\",\n \"automations.flow.emptyHint\": \"A flow touches the same lead more than once β a message today, a call in two days, another message on Friday β and stops on its own when they answer.\",\n \"automations.flow.namePrompt\": \"Name this flow\",\n \"automations.flow.entryPrompt\": \"Which event puts someone in?\",\n \"automations.flow.created\": \"Flow created. It starts switched off.\",\n \"automations.flow.toggle\": \"Active\",\n \"automations.flow.needStepsToActivate\": \"Add a step first β an empty flow enrols people into nothing.\",\n \"automations.flow.noSteps\": \"No steps yet.\",\n \"automations.flow.counts\": \"{{active}} in the flow Β· {{completed}} finished Β· {{exited}} left early\",\n \"automations.flow.colStep\": \"Step\",\n \"automations.flow.colWait\": \"Wait\",\n \"automations.flow.colQueued\": \"Queued\",\n \"automations.flow.colSent\": \"Sent\",\n \"automations.flow.colBlocked\": \"Blocked\",\n \"automations.flow.colFailed\": \"Failed\",\n \"automations.flow.addStep\": \"Add step\",\n \"automations.flow.deleteStep\": \"Remove step\",\n \"automations.flow.kindMessage\": \"Message\",\n \"automations.flow.kindTask\": \"Task\",\n \"automations.flow.templatePlaceholder\": \"Template key, e.g. lead.followup\",\n \"automations.flow.titlePlaceholder\": \"What should somebody do?\",\n \"automations.flow.needTemplate\": \"A message step needs a template.\",\n \"automations.flow.needTitle\": \"A task step needs a title.\",\n \"automations.flow.delayNow\": \"Right away\",\n \"automations.flow.delayMinutes\": \"{{count}} min later\",\n \"automations.flow.delayHours\": \"{{count}}h later\",\n \"automations.flow.delayDays\": \"{{count}} days later\",\n}\n","// automations.* β a tela de cadΓͺncia.\nexport const ptBR: Record<string, string> = {\n \"automations.flow.newTitle\": \"Nova cadΓͺncia\",\n \"automations.flow.nameLabel\": \"Nome\",\n \"automations.flow.namePlaceholder\": \"ex.: RΓ©gua do lead novo\",\n \"automations.flow.entryLabel\": \"Quem entra\",\n \"automations.flow.entryPlaceholder\": \"Escolha o fato que coloca alguΓ©m na rΓ©gua\",\n \"automations.flow.exitLabel\": \"Quem sai\",\n \"automations.flow.exitNone\": \"SΓ³ sai quando os passos acabam\",\n \"automations.flow.exitHint\": \"O fato que faz a pessoa parar de receber. Sem ele, quem jΓ‘ respondeu continua recebendo a mensagem do dia 5.\",\n \"automations.flow.bornOffHint\": \"A cadΓͺncia nasce desligada e sem passos. Monte os passos abaixo e ligue quando estiver pronta.\",\n \"automations.flow.noEvents\": \"Nenhum mΓ³dulo ativo anuncia fatos neste app β sem gatilho nΓ£o hΓ‘ cadΓͺncia.\",\n \"automations.flow.create\": \"Criar cadΓͺncia\",\n \"automations.flow.new\": \"Novo fluxo\",\n \"automations.flow.loading\": \"Carregando fluxosβ¦\",\n \"automations.flow.emptyTitle\": \"Nenhum fluxo de cadΓͺncia ainda\",\n \"automations.flow.emptyHint\": \"Um fluxo toca o mesmo lead mais de uma vez β uma mensagem hoje, uma ligaΓ§Γ£o em dois dias, outra mensagem na sexta β e para sozinho quando a pessoa responde.\",\n \"automations.flow.namePrompt\": \"Nome do fluxo\",\n \"automations.flow.entryPrompt\": \"Qual evento coloca alguΓ©m aqui?\",\n \"automations.flow.created\": \"Fluxo criado. Ele nasce desligado.\",\n \"automations.flow.toggle\": \"Ativo\",\n \"automations.flow.needStepsToActivate\": \"Adicione um passo antes β um fluxo vazio inscreve gente em nada.\",\n \"automations.flow.noSteps\": \"Nenhum passo ainda.\",\n \"automations.flow.counts\": \"{{active}} no fluxo Β· {{completed}} concluΓram Β· {{exited}} saΓram antes\",\n \"automations.flow.colStep\": \"Passo\",\n \"automations.flow.colWait\": \"Espera\",\n \"automations.flow.colQueued\": \"Na fila\",\n \"automations.flow.colSent\": \"Enviados\",\n \"automations.flow.colBlocked\": \"Bloqueados\",\n \"automations.flow.colFailed\": \"Falharam\",\n \"automations.flow.addStep\": \"Adicionar passo\",\n \"automations.flow.deleteStep\": \"Remover passo\",\n \"automations.flow.kindMessage\": \"Mensagem\",\n \"automations.flow.kindTask\": \"Tarefa\",\n \"automations.flow.templatePlaceholder\": \"Chave do modelo, ex.: lead.followup\",\n \"automations.flow.titlePlaceholder\": \"O que alguΓ©m precisa fazer?\",\n \"automations.flow.needTemplate\": \"Um passo de mensagem precisa de um modelo.\",\n \"automations.flow.needTitle\": \"Um passo de tarefa precisa de um tΓtulo.\",\n \"automations.flow.delayNow\": \"Na hora\",\n \"automations.flow.delayMinutes\": \"{{count}} min depois\",\n \"automations.flow.delayHours\": \"{{count}}h depois\",\n \"automations.flow.delayDays\": \"{{count}} dias depois\",\n}\n","import { en } from './en'\nimport { ptBR } from './pt-BR'\n\nexport const automationsLocales: Record<string, Record<string, string>> = {\n en,\n 'pt-BR': ptBR,\n}\n","// AUTO-GENERATED from 000_baseline.sql, 001_the_flow_has_steps.sql β regenerate with scripts/embed-migrations.mjs\n// SQL files are the source of truth; this inline copy lets the manifest declare\n// migrations as data. Do not edit by hand β run the embed script instead.\n\nexport const MIGRATION_000_BASELINE = `-- ============================================================================\n-- plugins/plugin-automations/migrations/000_baseline.sql β what installing this provisions, as one file.\n--\n-- GENERATED by scripts/emit-unit-baselines.mjs (#338). Do not edit by hand:\n-- change the schema, regenerate, and let scripts/check-chain-equivalence.mjs\n-- prove the result still matches.\n--\n-- This replaced 4 migration files. They are kept, unapplied, in\n-- migrations.archive/ β a year of decisions is worth reading even when it is no\n-- longer worth replaying.\n--\n-- Object order is fixed rather than dependency-sorted: schemas, types,\n-- sequences, tables, defaults, functions, constraints, views, indexes, foreign\n-- keys, triggers, row security, policies, grants. Dependencies BETWEEN units\n-- are carried by the order packages/db/chain.json declares.\n-- ============================================================================\n\n-- A LANGUAGE sql function binds its body at CREATE time, and 570 functions\n-- sorted by name are not sorted by who calls whom. This is what lets them load\n-- in any order; every body is still compiled on first call, so a genuinely\n-- broken reference surfaces then rather than never. Session-scoped.\nSET check_function_bodies = false;\n\n\n\n-- ββ default privileges: reset βββββββββββββββββββββββββββββββββββββββββββ\n-- Cleared BEFORE anything is created, so every object below gets the ACL the\n-- dump describes rather than the image's defaults on top of it. Restored at\n-- the end of this file.\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public REVOKE ALL ON SEQUENCES FROM anon, authenticated, service_role, fayz_connector$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public REVOKE ALL ON SEQUENCES FROM anon, authenticated, service_role, fayz_connector$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public REVOKE ALL ON SEQUENCES FROM anon, authenticated, service_role, fayz_connector$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public REVOKE ALL ON SEQUENCES FROM anon, authenticated, service_role, fayz_connector$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public REVOKE ALL ON FUNCTIONS FROM anon, authenticated, service_role, fayz_connector$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public REVOKE ALL ON FUNCTIONS FROM anon, authenticated, service_role, fayz_connector$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public REVOKE ALL ON FUNCTIONS FROM anon, authenticated, service_role, fayz_connector$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public REVOKE ALL ON FUNCTIONS FROM anon, authenticated, service_role, fayz_connector$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public REVOKE ALL ON TABLES FROM anon, authenticated, service_role, fayz_connector$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public REVOKE ALL ON TABLES FROM anon, authenticated, service_role, fayz_connector$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public REVOKE ALL ON TABLES FROM anon, authenticated, service_role, fayz_connector$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public REVOKE ALL ON TABLES FROM anon, authenticated, service_role, fayz_connector$stmt$;\nEND $dp$;\n\n\n-- ββ table βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nCREATE TABLE public.plg_automations_provider_templates (\n id uuid DEFAULT gen_random_uuid() NOT NULL,\n tenant_id uuid,\n event_key text NOT NULL,\n channel text DEFAULT 'whatsapp'::text NOT NULL,\n provider text DEFAULT 'tyxter'::text NOT NULL,\n provider_template_id text,\n template_name text NOT NULL,\n language text DEFAULT 'pt_BR'::text NOT NULL,\n variable_map jsonb DEFAULT '[]'::jsonb NOT NULL,\n actions_map jsonb DEFAULT '[]'::jsonb NOT NULL,\n status text DEFAULT 'draft'::text NOT NULL,\n rejection_reason text,\n body_snapshot text,\n submitted_at timestamp with time zone,\n approved_at timestamp with time zone,\n created_at timestamp with time zone DEFAULT now() NOT NULL,\n updated_at timestamp with time zone DEFAULT now() NOT NULL,\n CONSTRAINT plg_automations_provider_templates_status_check CHECK ((status = ANY (ARRAY['draft'::text, 'submitted'::text, 'approved'::text, 'rejected'::text, 'paused'::text, 'disabled'::text])))\n);\n\nCREATE TABLE public.plg_automations_templates (\n id uuid DEFAULT gen_random_uuid() NOT NULL,\n tenant_id uuid NOT NULL,\n event_key text NOT NULL,\n channel text DEFAULT 'email'::text NOT NULL,\n enabled boolean,\n subject text,\n body text,\n name text,\n created_at timestamp with time zone DEFAULT now() NOT NULL,\n updated_at timestamp with time zone DEFAULT now() NOT NULL,\n actions jsonb\n);\n\n\n-- ββ function ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nCREATE FUNCTION public.automations_set_updated_at() RETURNS trigger\n LANGUAGE plpgsql\n AS $$\nBEGIN\n NEW.updated_at = now();\n RETURN NEW;\nEND $$;\n\n\n-- ββ constraint ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nALTER TABLE ONLY public.plg_automations_provider_templates\n ADD CONSTRAINT plg_automations_provider_templates_pkey PRIMARY KEY (id);\n\nALTER TABLE ONLY public.plg_automations_templates\n ADD CONSTRAINT plg_automations_templates_pkey PRIMARY KEY (id);\n\n\n-- ββ index βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nCREATE INDEX idx_plg_automations_provider_templates_lookup ON public.plg_automations_provider_templates USING btree (event_key, channel, provider, status);\n\nCREATE INDEX plg_automations_templates_tenant_idx ON public.plg_automations_templates USING btree (tenant_id);\n\nCREATE UNIQUE INDEX plg_automations_templates_unique_idx ON public.plg_automations_templates USING btree (tenant_id, event_key, channel);\n\nCREATE UNIQUE INDEX uq_plg_automations_provider_templates_owner ON public.plg_automations_provider_templates USING btree (COALESCE(tenant_id, '00000000-0000-0000-0000-000000000000'::uuid), event_key, channel, provider);\n\nCREATE UNIQUE INDEX uq_plg_automations_provider_templates_provider_id ON public.plg_automations_provider_templates USING btree (provider, provider_template_id) WHERE (provider_template_id IS NOT NULL);\n\n\n-- ββ fk constraint βββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nALTER TABLE ONLY public.plg_automations_provider_templates\n ADD CONSTRAINT plg_automations_provider_templates_tenant_id_fkey FOREIGN KEY (tenant_id) REFERENCES public.tenants(id) ON DELETE CASCADE;\n\n\n-- ββ trigger βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nCREATE TRIGGER plg_automations_provider_templates_set_updated_at BEFORE UPDATE ON public.plg_automations_provider_templates FOR EACH ROW EXECUTE FUNCTION public.automations_set_updated_at();\n\nCREATE TRIGGER plg_automations_templates_set_updated_at BEFORE UPDATE ON public.plg_automations_templates FOR EACH ROW EXECUTE FUNCTION public.automations_set_updated_at();\n\n\n-- ββ row security ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nALTER TABLE public.plg_automations_provider_templates ENABLE ROW LEVEL SECURITY;\n\nALTER TABLE public.plg_automations_templates ENABLE ROW LEVEL SECURITY;\n\n\n-- ββ policy ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nCREATE POLICY plg_automations_provider_templates_select ON public.plg_automations_provider_templates FOR SELECT TO authenticated USING (((tenant_id IS NULL) OR (tenant_id IN ( SELECT public.user_tenant_ids() AS user_tenant_ids))));\n\nCREATE POLICY plg_automations_templates_member_all ON public.plg_automations_templates TO authenticated USING ((tenant_id IN ( SELECT public.user_tenant_ids() AS user_tenant_ids))) WITH CHECK ((tenant_id IN ( SELECT public.user_tenant_ids() AS user_tenant_ids)));\n\n\n-- ββ acl βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nGRANT ALL ON FUNCTION public.automations_set_updated_at() TO authenticated;\nGRANT ALL ON FUNCTION public.automations_set_updated_at() TO service_role;\n\nGRANT MAINTAIN ON TABLE public.plg_automations_provider_templates TO anon;\nGRANT ALL ON TABLE public.plg_automations_provider_templates TO authenticated;\nGRANT ALL ON TABLE public.plg_automations_provider_templates TO service_role;\n\nGRANT MAINTAIN ON TABLE public.plg_automations_templates TO anon;\nGRANT ALL ON TABLE public.plg_automations_templates TO authenticated;\nGRANT ALL ON TABLE public.plg_automations_templates TO service_role;\n\n\n-- ββ comment βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nCOMMENT ON COLUMN public.plg_automations_templates.actions IS 'Channel-neutral message actions: [{id: confirm|cancel|pay, label, kind: reply|payment}]. NULL = the catalog default; [] = deliberately no buttons.';\n\n\n-- ββ default privileges: restore βββββββββββββββββββββββββββββββββββββββββ\n-- Put back, so the NEXT thing installed inherits what the chain had.\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON SEQUENCES TO postgres$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON SEQUENCES TO postgres$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON SEQUENCES TO anon$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON SEQUENCES TO anon$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON SEQUENCES TO authenticated$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON SEQUENCES TO authenticated$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON SEQUENCES TO service_role$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON SEQUENCES TO service_role$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON SEQUENCES TO postgres$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON SEQUENCES TO postgres$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON SEQUENCES TO anon$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON SEQUENCES TO anon$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON SEQUENCES TO authenticated$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON SEQUENCES TO authenticated$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON SEQUENCES TO service_role$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON SEQUENCES TO service_role$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON FUNCTIONS TO postgres$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON FUNCTIONS TO postgres$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON FUNCTIONS TO authenticated$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON FUNCTIONS TO authenticated$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON FUNCTIONS TO service_role$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON FUNCTIONS TO service_role$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON FUNCTIONS TO postgres$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON FUNCTIONS TO postgres$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON FUNCTIONS TO anon$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON FUNCTIONS TO anon$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON FUNCTIONS TO authenticated$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON FUNCTIONS TO authenticated$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON FUNCTIONS TO service_role$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON FUNCTIONS TO service_role$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON TABLES TO postgres$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON TABLES TO postgres$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT MAINTAIN ON TABLES TO anon$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT MAINTAIN ON TABLES TO anon$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON TABLES TO authenticated$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON TABLES TO authenticated$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON TABLES TO service_role$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON TABLES TO service_role$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON TABLES TO postgres$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON TABLES TO postgres$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON TABLES TO anon$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON TABLES TO anon$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON TABLES TO authenticated$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON TABLES TO authenticated$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON TABLES TO service_role$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT ALL ON TABLES TO service_role$stmt$;\nEND $dp$;\n\nDO $dp$ BEGIN\n EXECUTE $stmt$--\n-- PostgreSQL database dump complete\n--$stmt$;\nEXCEPTION WHEN insufficient_privilege OR undefined_object THEN\n RAISE NOTICE 'baseline: not ours to set β %', $stmt$--\n-- PostgreSQL database dump complete\n--$stmt$;\nEND $dp$;\n`\n\nexport const MIGRATION_001_THE_FLOW_HAS_STEPS = `-- 001_the_flow_has_steps.sql\n--\n-- A CADENCE: the same lead touched on day 0, day 2 and day 5, by itself.\n--\n-- This plugin's README has promised \"multi-step sequences, and enrollment\n-- stats\" since M1, and \\`AutomationsList.tsx\\` says plainly what shipped instead:\n-- \"um fluxo de um passo Γ© o texto com o gatilho escrito na frente\". One row per\n-- (event, channel). Nothing waits, nothing remembers where a person got to, and\n-- nothing stops when they reply.\n--\n-- WHAT THIS DOES NOT BUILD, BECAUSE IT ALREADY EXISTS.\n--\n-- * The clock. \\`fayz_event_runner\\` is a pg_cron job that already calls\n-- \\`event_runner_tick(200)\\` every minute. This adds a fifth call to it\n-- (packages/db 046), guarded like the other four.\n-- * The delay. \\`notifications_enqueue(..., p_scheduled_for, p_dedupe_key)\\`\n-- already means \"send this at time T, and not twice\". A cadence step is a\n-- row in that queue with a computed \\`scheduled_for\\`.\n-- * Consent, channel preference and quiet-channel fallback β all inside\n-- \\`notifications_resolve_channel\\`, which plugin-notifications 002 just\n-- taught to read the opt-out correctly. A cadence that dodged the queue\n-- would dodge consent with it, which is the whole reason it does not.\n-- * The claim-and-retry shape. \\`marketing_run_due\\` / \\`marketing_campaign_run\\`\n-- already solve \"advance a set of enrolled people on a tick\" with\n-- \\`FOR UPDATE SKIP LOCKED\\`. \\`automations_flows_run_due\\` is that function\n-- with a step pointer.\n--\n-- THE THREE DECISIONS WORTH ARGUING WITH.\n--\n-- 1. THE DELAY IS AN OFFSET FROM THE PREVIOUS STEP, NOT FROM ENROLMENT.\n-- \"Two days after the call\" is how a salesperson describes a cadence, and it\n-- survives inserting a step in the middle. Absolute offsets from day 0 mean\n-- every later step silently shifts when you add one.\n--\n-- 2. THE ENROLMENT CARRIES THE STEP POINTER, AND THE DEDUPE KEY CARRIES THE\n-- POSITION. \\`flow:<enrolment>:<position>\\` means replaying a tick, or two\n-- workers taking the same row, cannot send a step twice β\n-- \\`notifications_enqueue\\` refuses a repeated \\`dedupe_key\\` before it writes\n-- anything. The SKIP LOCKED claim is the first defence; this is the one that\n-- survives a crash between the enqueue and the pointer update.\n--\n-- 3. A FLOW IS BORN INACTIVE. \\`is_active\\` defaults false. A cadence that starts\n-- sending the moment somebody saves a draft is a cadence that sends a draft.\n--\n-- WHAT IS STILL MISSING AFTER THIS, AND IS NOT PRETENDED OTHERWISE: e-mail and\n-- SMS still resolve to \\`notifications_send_to_log\\`, which records and sends\n-- nothing. A cadence on those channels will enqueue, drain, and deliver to a\n-- log row. WhatsApp reaches a provider; in-app reaches the bell.\n\nSET check_function_bodies = false;\n\n-- ββ tables ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nCREATE TABLE IF NOT EXISTS public.plg_automations_flows (\n id uuid DEFAULT gen_random_uuid() NOT NULL,\n tenant_id uuid NOT NULL,\n unit_id uuid,\n name text NOT NULL,\n description text,\n -- The fact that puts somebody in. Names an event from the aggregated plugin\n -- catalog (\\`crm.lead_created\\`, \\`crm.stage_changed\\`, β¦); it is text and not a\n -- foreign key because the catalog is assembled at runtime from whichever\n -- plugins an app mounts.\n entry_event text NOT NULL,\n -- The facts that take somebody out. Empty means the flow only ends by\n -- running out of steps.\n exit_events text[] DEFAULT '{}'::text[] NOT NULL,\n is_active boolean DEFAULT false NOT NULL,\n owner_id uuid,\n created_at timestamptz DEFAULT now() NOT NULL,\n updated_at timestamptz DEFAULT now() NOT NULL,\n CONSTRAINT plg_automations_flows_pkey PRIMARY KEY (id)\n);\n\nCREATE TABLE IF NOT EXISTS public.plg_automations_flow_steps (\n id uuid DEFAULT gen_random_uuid() NOT NULL,\n tenant_id uuid NOT NULL,\n flow_id uuid NOT NULL,\n -- Sparse on purpose (10, 20, 30β¦): inserting between two steps should not\n -- renumber the ones after it, and the enrolment's pointer names a position.\n position integer NOT NULL,\n -- Minutes to wait AFTER THE PREVIOUS STEP. The first step's delay is measured\n -- from enrolment, so 0 means \"right away\".\n delay_minutes integer DEFAULT 0 NOT NULL,\n kind text DEFAULT 'message' NOT NULL,\n -- kind='message': which template, and optionally force a channel. NULL\n -- channel lets notifications_resolve_channel pick, which is what honours the\n -- recipient's preference.\n template_key text,\n channel text,\n -- kind='task': what the human is asked to do, and by when.\n task_title text,\n task_due_days integer,\n created_at timestamptz DEFAULT now() NOT NULL,\n updated_at timestamptz DEFAULT now() NOT NULL,\n CONSTRAINT plg_automations_flow_steps_pkey PRIMARY KEY (id),\n CONSTRAINT plg_automations_flow_steps_kind_check\n CHECK (kind = ANY (ARRAY['message'::text, 'task'::text])),\n CONSTRAINT plg_automations_flow_steps_delay_check CHECK (delay_minutes >= 0),\n -- A message step with no template has nothing to send; a task step with no\n -- title gives the human nothing to read. Either is a step that would fail at\n -- 3am rather than at save time.\n CONSTRAINT plg_automations_flow_steps_payload_check CHECK (\n (kind = 'message' AND template_key IS NOT NULL)\n OR (kind = 'task' AND task_title IS NOT NULL)\n )\n);\n\nCREATE TABLE IF NOT EXISTS public.plg_automations_enrollments (\n id uuid DEFAULT gen_random_uuid() NOT NULL,\n tenant_id uuid NOT NULL,\n flow_id uuid NOT NULL,\n person_id uuid NOT NULL,\n -- What put them here, for the timeline: ('lead', <id>) or ('deal', <id>).\n subject_type text,\n subject_id uuid,\n status text DEFAULT 'active' NOT NULL,\n -- The position of the step that runs NEXT. NULL once nothing is left.\n current_position integer,\n next_run_at timestamptz DEFAULT now() NOT NULL,\n entered_at timestamptz DEFAULT now() NOT NULL,\n exited_at timestamptz,\n exit_reason text,\n created_at timestamptz DEFAULT now() NOT NULL,\n updated_at timestamptz DEFAULT now() NOT NULL,\n CONSTRAINT plg_automations_enrollments_pkey PRIMARY KEY (id),\n CONSTRAINT plg_automations_enrollments_status_check\n CHECK (status = ANY (ARRAY['active'::text, 'completed'::text, 'exited'::text]))\n);\n\n-- ββ constraint ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nALTER TABLE public.plg_automations_flows\n DROP CONSTRAINT IF EXISTS plg_automations_flows_tenant_fkey;\nALTER TABLE public.plg_automations_flows\n ADD CONSTRAINT plg_automations_flows_tenant_fkey\n FOREIGN KEY (tenant_id) REFERENCES public.tenants(id) ON DELETE CASCADE;\n\nALTER TABLE public.plg_automations_flow_steps\n DROP CONSTRAINT IF EXISTS plg_automations_flow_steps_flow_fkey;\nALTER TABLE public.plg_automations_flow_steps\n ADD CONSTRAINT plg_automations_flow_steps_flow_fkey\n FOREIGN KEY (flow_id) REFERENCES public.plg_automations_flows(id) ON DELETE CASCADE;\n\nALTER TABLE public.plg_automations_enrollments\n DROP CONSTRAINT IF EXISTS plg_automations_enrollments_flow_fkey;\nALTER TABLE public.plg_automations_enrollments\n ADD CONSTRAINT plg_automations_enrollments_flow_fkey\n FOREIGN KEY (flow_id) REFERENCES public.plg_automations_flows(id) ON DELETE CASCADE;\n\n-- ββ index βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nCREATE UNIQUE INDEX IF NOT EXISTS plg_automations_flow_steps_position_uq\n ON public.plg_automations_flow_steps (flow_id, position);\nCREATE INDEX IF NOT EXISTS plg_automations_flows_tenant_idx\n ON public.plg_automations_flows (tenant_id);\nCREATE INDEX IF NOT EXISTS plg_automations_flows_entry_idx\n ON public.plg_automations_flows (tenant_id, entry_event) WHERE is_active;\n\n-- One live enrolment per person per flow. Re-entering a cadence somebody is\n-- already in would double every remaining message.\nCREATE UNIQUE INDEX IF NOT EXISTS plg_automations_enrollments_live_uq\n ON public.plg_automations_enrollments (flow_id, person_id) WHERE status = 'active';\n-- The claim index: the runner only ever asks for due, active rows.\nCREATE INDEX IF NOT EXISTS plg_automations_enrollments_due_idx\n ON public.plg_automations_enrollments (next_run_at) WHERE status = 'active';\nCREATE INDEX IF NOT EXISTS plg_automations_enrollments_person_idx\n ON public.plg_automations_enrollments (tenant_id, person_id);\n\n-- ββ row security ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\n-- ENABLE **and** FORCE. Without FORCE the table owner β which is the role that\n-- runs migrations and every SECURITY DEFINER function here β bypasses these\n-- policies entirely, and \\`packages/db/test/pgtap/900_verification/001_posture.sql\\`\n-- (N14b) fails the whole pool for it.\nALTER TABLE public.plg_automations_flows ENABLE ROW LEVEL SECURITY;\nALTER TABLE public.plg_automations_flows FORCE ROW LEVEL SECURITY;\nALTER TABLE public.plg_automations_flow_steps ENABLE ROW LEVEL SECURITY;\nALTER TABLE public.plg_automations_flow_steps FORCE ROW LEVEL SECURITY;\nALTER TABLE public.plg_automations_enrollments ENABLE ROW LEVEL SECURITY;\nALTER TABLE public.plg_automations_enrollments FORCE ROW LEVEL SECURITY;\n\nDROP POLICY IF EXISTS plg_automations_flows_authz_select ON public.plg_automations_flows;\nCREATE POLICY plg_automations_flows_authz_select ON public.plg_automations_flows\n FOR SELECT TO authenticated USING (\n tenant_id = (SELECT app.current_tenant_id())\n AND (SELECT app.has_permission('automations.read', NULL::uuid)));\n\nDROP POLICY IF EXISTS plg_automations_flows_authz_insert ON public.plg_automations_flows;\nCREATE POLICY plg_automations_flows_authz_insert ON public.plg_automations_flows\n FOR INSERT TO authenticated WITH CHECK (\n tenant_id = (SELECT app.current_tenant_id())\n AND (SELECT app.has_permission('automations.edit', NULL::uuid)));\n\nDROP POLICY IF EXISTS plg_automations_flows_authz_update ON public.plg_automations_flows;\nCREATE POLICY plg_automations_flows_authz_update ON public.plg_automations_flows\n FOR UPDATE TO authenticated USING (\n tenant_id = (SELECT app.current_tenant_id())\n AND (SELECT app.has_permission('automations.edit', NULL::uuid)))\n WITH CHECK (\n tenant_id = (SELECT app.current_tenant_id())\n AND (SELECT app.has_permission('automations.edit', NULL::uuid)));\n\nDROP POLICY IF EXISTS plg_automations_flows_authz_delete ON public.plg_automations_flows;\nCREATE POLICY plg_automations_flows_authz_delete ON public.plg_automations_flows\n FOR DELETE TO authenticated USING (\n tenant_id = (SELECT app.current_tenant_id())\n AND (SELECT app.has_permission('automations.edit', NULL::uuid)));\n\nDROP POLICY IF EXISTS plg_automations_flow_steps_authz_select ON public.plg_automations_flow_steps;\nCREATE POLICY plg_automations_flow_steps_authz_select ON public.plg_automations_flow_steps\n FOR SELECT TO authenticated USING (\n tenant_id = (SELECT app.current_tenant_id())\n AND (SELECT app.has_permission('automations.read', NULL::uuid)));\n\nDROP POLICY IF EXISTS plg_automations_flow_steps_authz_insert ON public.plg_automations_flow_steps;\n-- The parent flow is checked, not just the stamped tenant. A tenant-only\n-- WITH CHECK lets a caller stamp their OWN tenant_id on a step and hang it off\n-- somebody else's flow β and the engine looks steps up by flow_id alone, so the\n-- injected step runs in that tenant's cadence.\nCREATE POLICY plg_automations_flow_steps_authz_insert ON public.plg_automations_flow_steps\n FOR INSERT TO authenticated WITH CHECK (\n tenant_id = (SELECT app.current_tenant_id())\n AND (SELECT app.has_permission('automations.edit', NULL::uuid))\n AND EXISTS (SELECT 1 FROM public.plg_automations_flows f\n WHERE f.id = flow_id AND f.tenant_id = (SELECT app.current_tenant_id())));\n\nDROP POLICY IF EXISTS plg_automations_flow_steps_authz_update ON public.plg_automations_flow_steps;\nCREATE POLICY plg_automations_flow_steps_authz_update ON public.plg_automations_flow_steps\n FOR UPDATE TO authenticated USING (\n tenant_id = (SELECT app.current_tenant_id())\n AND (SELECT app.has_permission('automations.edit', NULL::uuid)))\n WITH CHECK (\n tenant_id = (SELECT app.current_tenant_id())\n AND (SELECT app.has_permission('automations.edit', NULL::uuid)));\n\nDROP POLICY IF EXISTS plg_automations_flow_steps_authz_delete ON public.plg_automations_flow_steps;\nCREATE POLICY plg_automations_flow_steps_authz_delete ON public.plg_automations_flow_steps\n FOR DELETE TO authenticated USING (\n tenant_id = (SELECT app.current_tenant_id())\n AND (SELECT app.has_permission('automations.edit', NULL::uuid)));\n\n-- Enrolments are READ-ONLY to the operator. They are written by the engine, and\n-- a hand-edited step pointer is a cadence nobody can explain afterwards.\n-- Leaving a flow is \\`automations_flow_exit\\`, not an UPDATE.\nDROP POLICY IF EXISTS plg_automations_enrollments_authz_select ON public.plg_automations_enrollments;\nCREATE POLICY plg_automations_enrollments_authz_select ON public.plg_automations_enrollments\n FOR SELECT TO authenticated USING (\n tenant_id = (SELECT app.current_tenant_id())\n AND (SELECT app.has_permission('automations.read', NULL::uuid)));\n\nGRANT SELECT, INSERT, UPDATE, DELETE ON public.plg_automations_flows TO authenticated;\nGRANT ALL ON public.plg_automations_flows TO service_role;\nGRANT SELECT, INSERT, UPDATE, DELETE ON public.plg_automations_flow_steps TO authenticated;\nGRANT ALL ON public.plg_automations_flow_steps TO service_role;\nGRANT SELECT ON public.plg_automations_enrollments TO authenticated;\nGRANT ALL ON public.plg_automations_enrollments TO service_role;\n\nINSERT INTO app.scaffold_registry\n (table_schema, table_name, resource_type, plugin, owner_scoping, mode, previous_policies, audit_hook, scope, distributable)\nVALUES\n ('public', 'plg_automations_flows', 'automations.flow', 'automations', false, 'enforce', ARRAY[]::text[], false, 'unit_optional', false),\n ('public', 'plg_automations_flow_steps', 'automations.flow_step', 'automations', false, 'enforce', ARRAY[]::text[], false, 'tenant', false),\n ('public', 'plg_automations_enrollments', 'automations.enrollment', 'automations', false, 'enforce', ARRAY[]::text[], false, 'tenant', false)\nON CONFLICT DO NOTHING;\n\n-- ββ function ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\n-- Put somebody into a flow. Returns the enrolment, or NULL when the flow is\n-- inactive, has no steps, or the person is already in it.\nCREATE OR REPLACE FUNCTION public.automations_flow_enroll(\n p_tenant_id uuid, p_flow_id uuid, p_person_id uuid,\n p_subject_type text DEFAULT NULL, p_subject_id uuid DEFAULT NULL\n) RETURNS uuid\nLANGUAGE plpgsql SECURITY DEFINER\nSET search_path TO ''\nAS $$\nDECLARE v_first record; v_id uuid;\nBEGIN\n SELECT s.position, s.delay_minutes INTO v_first\n FROM public.plg_automations_flow_steps s\n JOIN public.plg_automations_flows f ON f.id = s.flow_id\n WHERE s.flow_id = p_flow_id AND f.tenant_id = p_tenant_id AND f.is_active\n ORDER BY s.position\n LIMIT 1;\n\n -- An inactive flow, or one with no steps, enrols nobody. Silently: this is\n -- called from an event handler, and raising would fail the whole delivery.\n IF v_first.position IS NULL THEN RETURN NULL; END IF;\n\n INSERT INTO public.plg_automations_enrollments\n (tenant_id, flow_id, person_id, subject_type, subject_id, current_position, next_run_at)\n VALUES\n (p_tenant_id, p_flow_id, p_person_id, p_subject_type, p_subject_id,\n v_first.position, now() + make_interval(mins => v_first.delay_minutes))\n ON CONFLICT DO NOTHING\n RETURNING id INTO v_id;\n\n RETURN v_id;\nEND $$;\n\n-- Take somebody out of every flow they are in. The reason is kept, because\n-- \"left because they replied\" and \"left because the deal was lost\" are the two\n-- halves of whether a cadence works.\nCREATE OR REPLACE FUNCTION public.automations_flow_exit(\n p_tenant_id uuid, p_person_id uuid, p_reason text, p_flow_ids uuid[] DEFAULT NULL\n) RETURNS integer\nLANGUAGE plpgsql SECURITY DEFINER\nSET search_path TO ''\nAS $$\nDECLARE v_n integer; v_gone uuid[];\nBEGIN\n -- SCOPED TO THE FLOWS THAT ASKED. \\`p_flow_ids\\` NULL still means \"every flow\",\n -- which is what a manual \"take this person out\" wants; the event handler\n -- passes the flows whose own \\`exit_events\\` name the fact.\n --\n -- Without the scope, one flow declaring \\`crm.deal_won\\` pulled the person out\n -- of EVERY flow they were in and cancelled every queued step β including a\n -- flow that declared no exits at all, whose comment says it \"only ends by\n -- running out of steps\". Flow-level exit_events were meaningless the moment a\n -- second flow existed.\n WITH gone AS (\n UPDATE public.plg_automations_enrollments\n SET status = 'exited', exited_at = now(), exit_reason = p_reason,\n current_position = NULL, updated_at = now()\n WHERE tenant_id = p_tenant_id AND person_id = p_person_id AND status = 'active'\n AND (p_flow_ids IS NULL OR flow_id = ANY (p_flow_ids))\n RETURNING id\n )\n SELECT count(*)::integer, array_agg(id) INTO v_n, v_gone FROM gone;\n\n -- A step already in the queue but not yet sent must not go out after the\n -- person left. \\`cancelled\\` was in the status CHECK from the beginning and\n -- nothing ever wrote it; this is what it was for.\n --\n -- Keyed by the ENROLMENTS that just left, not by \\`flow:%\\` β the wide pattern\n -- cancelled the pending steps of flows the person is still in.\n IF v_n > 0 AND to_regclass('public.plg_notifications_queue') IS NOT NULL THEN\n UPDATE public.plg_notifications_queue q\n SET status = 'cancelled', last_error = 'left the flow: ' || p_reason\n WHERE q.tenant_id = p_tenant_id\n AND q.person_id = p_person_id\n AND q.status = 'pending'\n AND split_part(q.dedupe_key, ':', 1) = 'flow'\n AND split_part(q.dedupe_key, ':', 2) = ANY (SELECT unnest(v_gone)::text);\n END IF;\n\n RETURN v_n;\nEND $$;\n\n-- The tick. Claims due enrolments, runs ONE step each, moves the pointer.\nCREATE OR REPLACE FUNCTION public.automations_flows_run_due(p_limit integer DEFAULT 50)\nRETURNS jsonb\nLANGUAGE plpgsql SECURITY DEFINER\nSET search_path TO ''\nAS $$\nDECLARE\n e record; v_step record; v_next record; v_error text;\n v_ran integer := 0; v_done integer := 0; v_failed integer := 0;\nBEGIN\n -- JOINED to the flow, and \\`f.is_active\\` checked here rather than only in\n -- \\`automations_flow_enroll\\`. Switching a flow off used to stop new entrants\n -- and nothing else: everybody already mid-cadence kept receiving messages\n -- from a flow the operator had just turned off, which is the opposite of what\n -- the switch promises.\n FOR e IN\n SELECT en.* FROM public.plg_automations_enrollments en\n JOIN public.plg_automations_flows f ON f.id = en.flow_id AND f.is_active\n WHERE en.status = 'active' AND en.next_run_at <= now()\n ORDER BY en.next_run_at\n LIMIT greatest(p_limit, 0)\n FOR UPDATE OF en SKIP LOCKED\n LOOP\n SELECT * INTO v_step FROM public.plg_automations_flow_steps s\n WHERE s.flow_id = e.flow_id AND s.position = e.current_position;\n\n -- The step was deleted while somebody stood on it. Move on rather than\n -- spinning on a pointer that will never resolve.\n IF v_step.id IS NULL THEN\n SELECT * INTO v_next FROM public.plg_automations_flow_steps s\n WHERE s.flow_id = e.flow_id AND s.position > coalesce(e.current_position, -1)\n ORDER BY s.position LIMIT 1;\n ELSE\n BEGIN\n IF v_step.kind = 'message' THEN\n PERFORM public.notifications_enqueue(\n e.tenant_id, v_step.template_key, e.person_id,\n jsonb_build_object('flow_id', e.flow_id, 'enrollment_id', e.id, 'step', v_step.position),\n 'flow:' || e.id::text || ':' || v_step.position::text,\n now(),\n v_step.channel\n );\n ELSIF v_step.kind = 'task' AND to_regclass('public.tasks') IS NOT NULL THEN\n -- \\`tasks_source_uniq (tenant_id, source, source_key)\\` makes this\n -- idempotent for free β the same step cannot raise two tasks.\n INSERT INTO public.tasks\n (tenant_id, title, description, status, due_date, source, source_key)\n VALUES\n (e.tenant_id, v_step.task_title,\n 'Automation flow step ' || v_step.position::text,\n 'todo',\n CASE WHEN v_step.task_due_days IS NOT NULL\n THEN (now() + make_interval(days => v_step.task_due_days))::date END,\n 'automation:flow', e.id::text || ':' || v_step.position::text)\n ON CONFLICT DO NOTHING;\n END IF;\n v_ran := v_ran + 1;\n EXCEPTION WHEN OTHERS THEN\n -- One bad step must not stop the tick for everybody else, so the\n -- enrolment still leaves this step: a template that no longer exists\n -- would otherwise wedge the person forever.\n --\n -- But it does NOT read as a finished cadence. The first cut let the\n -- loop fall through to \\`completed\\`, and because a failed step never\n -- produces a queue row, \\`v_automations_flow_steps\\` β which counts queue\n -- statuses β could not show it either. The screen built to answer\n -- \"where do people stop\" reported the person as having finished.\n v_failed := v_failed + 1;\n v_error := SQLERRM;\n RAISE NOTICE 'automations_flows_run_due: step % of enrolment % failed (%)',\n v_step.position, e.id, SQLERRM;\n END;\n\n SELECT * INTO v_next FROM public.plg_automations_flow_steps s\n WHERE s.flow_id = e.flow_id AND s.position > v_step.position\n ORDER BY s.position LIMIT 1;\n END IF;\n\n IF v_next.id IS NULL THEN\n UPDATE public.plg_automations_enrollments\n SET status = 'completed', current_position = NULL,\n exited_at = now(), updated_at = now(),\n -- A cadence that ended on a step that could not run did not\n -- finish; saying so is the difference between \"nobody answers the\n -- third message\" and \"the third message never left\".\n exit_reason = CASE WHEN v_error IS NOT NULL\n THEN 'last step failed: ' || v_error END\n WHERE id = e.id;\n v_done := v_done + 1;\n ELSE\n UPDATE public.plg_automations_enrollments\n SET current_position = v_next.position,\n next_run_at = now() + make_interval(mins => v_next.delay_minutes),\n updated_at = now()\n WHERE id = e.id;\n END IF;\n\n v_next := NULL; v_step := NULL; v_error := NULL;\n END LOOP;\n\n RETURN jsonb_build_object('steps_ran', v_ran, 'completed', v_done, 'failed', v_failed);\nEND $$;\n\nREVOKE ALL ON FUNCTION public.automations_flow_enroll(uuid, uuid, uuid, text, uuid) FROM PUBLIC;\nGRANT EXECUTE ON FUNCTION public.automations_flow_enroll(uuid, uuid, uuid, text, uuid) TO service_role;\nREVOKE ALL ON FUNCTION public.automations_flow_exit(uuid, uuid, text, uuid[]) FROM PUBLIC;\nGRANT EXECUTE ON FUNCTION public.automations_flow_exit(uuid, uuid, text, uuid[]) TO authenticated;\nGRANT EXECUTE ON FUNCTION public.automations_flow_exit(uuid, uuid, text, uuid[]) TO service_role;\nREVOKE ALL ON FUNCTION public.automations_flows_run_due(integer) FROM PUBLIC;\nGRANT EXECUTE ON FUNCTION public.automations_flows_run_due(integer) TO service_role;\n\n-- ββ the two handlers the event log calls ββββββββββββββββββββββββββββββββ\n\n-- Who the event is about.\n--\n-- \\`consume_event_log\\` calls a handler with \\`to_jsonb(v_event)\\` β the whole\n-- \\`event_log\\` ROW. So \\`tenant_id\\`, \\`event_key\\`, \\`subject_type\\` and \\`subject_id\\`\n-- are at the top level and everything the emitter chose to send is nested under\n-- \\`payload\\`. The first cut read \\`person_id\\` at the top level, where it never is:\n-- every delivery answered \"payload carries no tenant, person or event\", was\n-- marked DELIVERED, and the cadence enrolled nobody, ever, with nothing\n-- reporting it.\n--\n-- \\`subject_id\\` first, because that is the convention the shipped handlers use\n-- (\\`plg_notifications_on_fulfillment_completed\\` reads exactly that), and it is\n-- \\`text\\` on the row. The payload fallbacks are for emitters that name the person\n-- there instead.\nCREATE OR REPLACE FUNCTION public.automations_event_person(p_event jsonb)\nRETURNS uuid\nLANGUAGE sql IMMUTABLE\nSET search_path TO ''\nAS $$\n SELECT nullif(coalesce(\n CASE WHEN p_event ->> 'subject_type' IN ('lead', 'person', 'contact')\n THEN p_event ->> 'subject_id' END,\n p_event -> 'payload' ->> 'person_id',\n p_event -> 'payload' ->> 'lead_id',\n p_event -> 'payload' ->> 'contact_id',\n p_event ->> 'person_id',\n p_event ->> 'lead_id'\n ), '')::uuid\n$$;\n\nREVOKE ALL ON FUNCTION public.automations_event_person(jsonb) FROM PUBLIC;\nGRANT EXECUTE ON FUNCTION public.automations_event_person(jsonb) TO service_role;\n\n-- Enrol on the flow's entry event. The payload names the person; a fact that\n-- does not carry one cannot start a cadence.\nCREATE OR REPLACE FUNCTION public.plg_automations_on_entry_event(p_event jsonb)\nRETURNS jsonb\nLANGUAGE plpgsql SECURITY DEFINER\nSET search_path TO ''\nAS $$\nDECLARE\n v_tenant uuid := nullif(p_event ->> 'tenant_id', '')::uuid;\n v_event text := p_event ->> 'event_key';\n v_person uuid := public.automations_event_person(p_event);\n f record; v_n integer := 0;\nBEGIN\n IF v_tenant IS NULL OR v_person IS NULL OR v_event IS NULL THEN\n RETURN jsonb_build_object('enrolled', 0, 'reason', 'event carries no tenant, person or key');\n END IF;\n\n FOR f IN SELECT id FROM public.plg_automations_flows\n WHERE tenant_id = v_tenant AND entry_event = v_event AND is_active\n LOOP\n IF public.automations_flow_enroll(\n v_tenant, f.id, v_person,\n p_event ->> 'subject_type', nullif(p_event ->> 'subject_id', '')::uuid) IS NOT NULL THEN\n v_n := v_n + 1;\n END IF;\n END LOOP;\n\n RETURN jsonb_build_object('enrolled', v_n);\nEND $$;\n\n-- Leave the flows whose own \\`exit_events\\` name this fact.\nCREATE OR REPLACE FUNCTION public.plg_automations_on_exit_event(p_event jsonb)\nRETURNS jsonb\nLANGUAGE plpgsql SECURITY DEFINER\nSET search_path TO ''\nAS $$\nDECLARE\n v_tenant uuid := nullif(p_event ->> 'tenant_id', '')::uuid;\n v_event text := p_event ->> 'event_key';\n v_person uuid := public.automations_event_person(p_event);\n v_flows uuid[]; v_n integer := 0;\nBEGIN\n IF v_tenant IS NULL OR v_person IS NULL OR v_event IS NULL THEN\n RETURN jsonb_build_object('exited', 0, 'reason', 'event carries no tenant, person or key');\n END IF;\n\n SELECT array_agg(id) INTO v_flows\n FROM public.plg_automations_flows\n WHERE tenant_id = v_tenant AND is_active AND v_event = ANY (exit_events);\n\n IF v_flows IS NOT NULL THEN\n v_n := public.automations_flow_exit(v_tenant, v_person, v_event, v_flows);\n END IF;\n\n RETURN jsonb_build_object('exited', v_n);\nEND $$;\n\nREVOKE ALL ON FUNCTION public.plg_automations_on_entry_event(jsonb) FROM PUBLIC;\nGRANT EXECUTE ON FUNCTION public.plg_automations_on_entry_event(jsonb) TO service_role;\nREVOKE ALL ON FUNCTION public.plg_automations_on_exit_event(jsonb) FROM PUBLIC;\nGRANT EXECUTE ON FUNCTION public.plg_automations_on_exit_event(jsonb) TO service_role;\n\n-- ββ subscription ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\n-- The manifest DECLARES the reaction; this is what makes the event log call it.\n-- Both handlers on every CRM fact, because which fact opens a cadence and which\n-- closes it is the operator's choice: the handler looks the flow up and returns\n-- immediately when no flow in that tenant names the event.\n-- Written out one call per line rather than looped over an array. The loop was\n-- shorter and \\`check-event-contract\\` could not read it: its registration parser\n-- matches literal arguments, so a FOREACH registering fourteen subscriptions\n-- looked like zero. Same lesson as the manifest side β the gate reads source,\n-- so the source has to say it.\nSELECT public.register_event_subscription('automations', 'crm.lead_created', 'plg_automations_on_entry_event',\n 'Enrol into flows whose entry event is crm.lead_created', 5);\nSELECT public.register_event_subscription('automations', 'crm.lead_created', 'plg_automations_on_exit_event',\n 'Leave flows that exit on crm.lead_created', 5);\nSELECT public.register_event_subscription('automations', 'crm.stage_changed', 'plg_automations_on_entry_event',\n 'Enrol into flows whose entry event is crm.stage_changed', 5);\nSELECT public.register_event_subscription('automations', 'crm.stage_changed', 'plg_automations_on_exit_event',\n 'Leave flows that exit on crm.stage_changed', 5);\nSELECT public.register_event_subscription('automations', 'crm.quote_sent', 'plg_automations_on_entry_event',\n 'Enrol into flows whose entry event is crm.quote_sent', 5);\nSELECT public.register_event_subscription('automations', 'crm.quote_sent', 'plg_automations_on_exit_event',\n 'Leave flows that exit on crm.quote_sent', 5);\nSELECT public.register_event_subscription('automations', 'crm.quote_approved', 'plg_automations_on_entry_event',\n 'Enrol into flows whose entry event is crm.quote_approved', 5);\nSELECT public.register_event_subscription('automations', 'crm.quote_approved', 'plg_automations_on_exit_event',\n 'Leave flows that exit on crm.quote_approved', 5);\nSELECT public.register_event_subscription('automations', 'crm.deal_won', 'plg_automations_on_entry_event',\n 'Enrol into flows whose entry event is crm.deal_won', 5);\nSELECT public.register_event_subscription('automations', 'crm.deal_won', 'plg_automations_on_exit_event',\n 'Leave flows that exit on crm.deal_won', 5);\nSELECT public.register_event_subscription('automations', 'crm.deal_lost', 'plg_automations_on_entry_event',\n 'Enrol into flows whose entry event is crm.deal_lost', 5);\nSELECT public.register_event_subscription('automations', 'crm.deal_lost', 'plg_automations_on_exit_event',\n 'Leave flows that exit on crm.deal_lost', 5);\nSELECT public.register_event_subscription('automations', 'crm.deal_idle', 'plg_automations_on_entry_event',\n 'Enrol into flows whose entry event is crm.deal_idle', 5);\nSELECT public.register_event_subscription('automations', 'crm.deal_idle', 'plg_automations_on_exit_event',\n 'Leave flows that exit on crm.deal_idle', 5);\n\n-- ββ view ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\n-- Per-step numbers, which is the question a cadence is judged by: where do\n-- people stop. Aggregating per FLOW would hide that the third message is the\n-- one nobody answers.\nCREATE OR REPLACE VIEW public.v_automations_flow_steps WITH (security_invoker='true') AS\n SELECT\n s.tenant_id, s.flow_id, s.id AS step_id, s.position, s.kind,\n s.template_key, s.channel, s.delay_minutes, s.task_title,\n count(q.id) FILTER (WHERE q.id IS NOT NULL) AS queued,\n count(q.id) FILTER (WHERE q.status = 'sent') AS sent,\n count(q.id) FILTER (WHERE q.status = 'blocked') AS blocked,\n count(q.id) FILTER (WHERE q.status = 'failed') AS failed,\n count(q.id) FILTER (WHERE q.status = 'cancelled') AS cancelled\n FROM public.plg_automations_flow_steps s\n LEFT JOIN public.plg_automations_enrollments e ON e.flow_id = s.flow_id\n LEFT JOIN public.plg_notifications_queue q\n ON q.dedupe_key = 'flow:' || e.id::text || ':' || s.position::text\n GROUP BY s.tenant_id, s.flow_id, s.id, s.position, s.kind,\n s.template_key, s.channel, s.delay_minutes, s.task_title;\n\nGRANT SELECT ON public.v_automations_flow_steps TO authenticated;\nGRANT SELECT ON public.v_automations_flow_steps TO service_role;\n`\n\nexport const MIGRATIONS: Array<{ id: string; sql: string }> = [\n { id: \"000_baseline\", sql: MIGRATION_000_BASELINE },\n { id: \"001_the_flow_has_steps\", sql: MIGRATION_001_THE_FLOW_HAS_STEPS },\n]\n","import React from 'react'\nimport type { PluginManifest, PluginScope, VerticalId } from '@fayz-ai/core'\nimport { startEventLog } from '@fayz-ai/core'\nimport { resolveFayzAgentConnection, registerRailPage, type RailPageProps } from '@fayz-ai/admin'\nimport { AutomationsList } from './views/AutomationsList'\nimport { AutomationDetailPage } from './views/AutomationDetailPage'\nimport { createSupabaseTemplateStore, type MessageTemplateStore } from './data/templates'\nimport { createFayzTemplateStore } from './data/fayz'\nimport { FlowsPage } from './views/FlowsPage'\nimport { automationsLocales } from './locales'\nimport { MIGRATIONS } from './migrations'\n\n\n// ---------------------------------------------------------------------------\n// @fayz-ai/plugin-automations β everything the product SENDS, in one place.\n//\n// ONE automation = when THIS happens, send THAT over THIS channel.\n//\n// Events do NOT live here. Each module DECLARES them in its own manifest\n// (`events`) and the runtime aggregates the active plugins' β the store brings\n// the order's, the CRM the pipeline's. If this screen had to import store and\n// CRM, an app installing only the CRM would carry the store catalog too, and\n// every new module would mean another import in here.\n//\n// The same catalog feeds integrations (webhooks) and audit: three readers of the\n// SAME fact, which is why the message text is not part of it.\n// ---------------------------------------------------------------------------\n\nexport interface AutomationsPluginOptions {\n navPosition?: number\n navSection?: 'main' | 'secondary' | 'settings'\n navLabel?: string\n /**\n * Where the list lives.\n *\n * 'settings' (default) uma aba dentro de ConfiguraΓ§Γ΅es, sem linha no menu.\n * AutomaΓ§Γ£o Γ© regra: escreve-se uma vez e revisita-se por mΓͺs.\n * Uma linha fixa no rail cobrava atenΓ§Γ£o TODO DIA por uma tela\n * mensal, ao lado de destinos que se abrem a cada hora.\n * 'nav' linha prΓ³pria no menu β para o aplicativo em que disparar Γ©\n * rotina diΓ‘ria, como a loja.\n */\n placement?: 'nav' | 'settings'\n scope?: PluginScope\n verticalId?: VerticalId\n /** Swaps data access (tests, mock mode). */\n store?: MessageTemplateStore\n}\n\nexport function createAutomationsPlugin(options?: AutomationsPluginOptions): PluginManifest {\n // Built once per manifest: the store holds no state, and rebuilding it every\n // render would remount the effects that depend on it.\n // Behind a Fayz project the platform executes the automations, so the\n // customisations live there; outside one, the local table keeps working.\n const connection = resolveFayzAgentConnection()\n const store = options?.store\n ?? (connection ? createFayzTemplateStore(connection) : createSupabaseTemplateStore())\n\n // Turns on the trigger history. Idempotent, and from here on EVERY event the\n // app emits is recorded, not only those with a message β it is the same\n // history webhooks and audit read.\n startEventLog()\n\n // ConfiguraΓ§Γ΅es Γ© o padrΓ£o: quem quer a linha no rail pede `placement: 'nav'`.\n const inSettings = options?.placement !== 'nav'\n\n const ListPage: React.ComponentType<unknown> = () =>\n React.createElement(AutomationsList, { store })\n ListPage.displayName = 'AutomationsList'\n\n // A mesma lista servida DENTRO de ConfiguraΓ§Γ΅es: a shell jΓ‘ nomeou a tela, e\n // as abas tΓͺm de ser as dos outros painΓ©is de lΓ‘, nΓ£o a faixa de um mΓ³dulo.\n // `basePath` leva o detalhe junto β dentro de ConfiguraΓ§Γ΅es ele abre sob\n // `/settings/automations`, para a pessoa nΓ£o ser jogada para fora da tela.\n const SettingsListPage: React.ComponentType<unknown> = () =>\n React.createElement(AutomationsList, { store, variant: 'panel', basePath: '/settings/automations' })\n SettingsListPage.displayName = 'AutomationsSettings'\n\n // O detalhe, oferecido para quem quiser abri-lo na coluna sem sair da tela em\n // que estΓ‘. O raio do CRM Γ© o primeiro a pedir: ele aponta para o MESMO fato\n // que a linha do tempo mostra, e mandar a pessoa para outra pΓ‘gina para ver\n // \"o que este fato dispara\" custava o funil que ela estava lendo.\n const RailDetail: React.FC<RailPageProps> = ({ params, onClose }) =>\n React.createElement(AutomationDetailPage, {\n eventKey: params.eventKey,\n channel: params.channel,\n store,\n backTo: inSettings ? '/settings/automations' : '/automations',\n embedded: true,\n onDone: onClose,\n })\n RailDetail.displayName = 'AutomationRailDetail'\n registerRailPage('automations.detail', RailDetail)\n\n const READ = { feature: 'automations', action: 'read' as const }\n\n return {\n id: 'automations',\n defaultAgentRole: 'setup',\n name: options?.navLabel ?? 'AutomaΓ§Γ΅es',\n icon: 'Zap',\n version: '2.0.0',\n scope: options?.scope ?? 'universal',\n verticalId: options?.verticalId,\n defaultEnabled: true,\n dependencies: [],\n declaredFeatures: [{ id: 'automations', label: 'Automations', group: 'Automate' }],\n navigation: inSettings ? [] : [\n {\n section: options?.navSection ?? 'main',\n position: options?.navPosition ?? 6,\n label: options?.navLabel ?? 'AutomaΓ§Γ΅es',\n route: '/automations',\n icon: 'Zap',\n permission: READ,\n indexChild: false,\n },\n // SEM linha para `/automations/flows`.\n //\n // A rΓ©gua de relacionamento tem UMA tela e ela se planeja no Marketing\n // (`cadenceSurface`), que Γ© onde \"como a casa fala com quem ainda nΓ£o\n // comprou\" Γ© decisΓ£o. A linha aqui era a segunda porta para a mesma tela,\n // pendurada como filha de AutomaΓ§Γ΅es β e AutomaΓ§Γ΅es Γ© uma tela sΓ³, que\n // abre inteira. A rota continua de pΓ© (ver `routes`), entΓ£o quem chega\n // pelo Marketing ou por link direto nΓ£o perde nada.\n ],\n // The SAME list, served inside settings β not a second screen.\n settings: inSettings ? [\n { id: 'automations', label: options?.navLabel ?? 'AutomaΓ§Γ΅es', icon: 'Zap', component: SettingsListPage, permission: READ },\n ] : [],\n routes: [\n { path: '/automations', component: ListPage, permission: READ },\n // O detalhe de uma automaΓ§Γ£o Γ© a MESMA tela com a coluna da direita\n // aberta β a lista continua atrΓ‘s dela. Por isso o curinga aponta para o\n // mesmo componente: a shell colapsa '/x' e '/x/*' na mesma chave, entΓ£o a\n // pΓ‘gina nΓ£o remonta ao abrir o painel (ver AdminShell.routeKey). Um\n // segundo componente aqui traria de volta a troca de tela.\n // Flows are their OWN route, not a tab of the list. A one-step automation\n // and a cadence answer different questions β \"does the order confirmation\n // go out\" versus \"where do people stop\" β and the wildcard above already\n // owns the right rail, so a tab here would fight it for the same URL.\n { path: '/automations/flows', component: FlowsPage, permission: READ },\n { path: '/automations/*', component: ListPage, permission: READ },\n ],\n // A flow names its own entry and exit events, but a SUBSCRIPTION is a row:\n // static, written at install time. So both handlers listen to the whole CRM\n // fact catalogue and each one decides whether any flow cares β the handler\n // is a lookup against `plg_automations_flows`, and a tenant with no flow on\n // that event does one indexed read and returns.\n //\n // Both handlers on every event on purpose: which facts open a cadence and\n // which close it is the operator's choice, not ours. A house may well start\n // a win-back flow on `crm.deal_lost`.\n //\n // Written out one by one rather than generated from CADENCE_FACTS. The\n // generated form read better and was invisible to `check-event-contract`,\n // whose regex needs a literal `subscribesTo: [ β¦ ]` with literal event and\n // handler strings β so fourteen subscriptions that nothing registered\n // passed the gate in silence. A contract a checker cannot read is not a\n // contract.\n subscribesTo: [\n { event: 'crm.lead_created', handler: 'plg_automations_on_entry_event', description: 'Enrol into flows entered by a new lead', maxAttempts: 5 },\n { event: 'crm.lead_created', handler: 'plg_automations_on_exit_event', description: 'Leave flows that exit on a new lead', maxAttempts: 5 },\n { event: 'crm.stage_changed', handler: 'plg_automations_on_entry_event', description: 'Enrol into flows entered by a stage change', maxAttempts: 5 },\n { event: 'crm.stage_changed', handler: 'plg_automations_on_exit_event', description: 'Leave flows that exit on a stage change', maxAttempts: 5 },\n { event: 'crm.quote_sent', handler: 'plg_automations_on_entry_event', description: 'Enrol into flows entered by a sent quote', maxAttempts: 5 },\n { event: 'crm.quote_sent', handler: 'plg_automations_on_exit_event', description: 'Leave flows that exit on a sent quote', maxAttempts: 5 },\n { event: 'crm.quote_approved', handler: 'plg_automations_on_entry_event', description: 'Enrol into flows entered by an approved quote', maxAttempts: 5 },\n { event: 'crm.quote_approved', handler: 'plg_automations_on_exit_event', description: 'Leave flows that exit on an approved quote', maxAttempts: 5 },\n { event: 'crm.deal_won', handler: 'plg_automations_on_entry_event', description: 'Enrol into flows entered by a won deal', maxAttempts: 5 },\n { event: 'crm.deal_won', handler: 'plg_automations_on_exit_event', description: 'Leave flows that exit on a won deal', maxAttempts: 5 },\n { event: 'crm.deal_lost', handler: 'plg_automations_on_entry_event', description: 'Enrol into flows entered by a lost deal', maxAttempts: 5 },\n { event: 'crm.deal_lost', handler: 'plg_automations_on_exit_event', description: 'Leave flows that exit on a lost deal', maxAttempts: 5 },\n { event: 'crm.deal_idle', handler: 'plg_automations_on_entry_event', description: 'Enrol into flows entered by an idle deal', maxAttempts: 5 },\n { event: 'crm.deal_idle', handler: 'plg_automations_on_exit_event', description: 'Leave flows that exit on an idle deal', maxAttempts: 5 },\n ],\n // The barrel an app installing this plugin applies. Without it the tables\n // and functions below simply do not exist there: `chain.json` provisions a\n // CLUSTER, and the manifest is what provisions an app β this plugin had\n // neither a `migrations` key nor a barrel to point it at, so fourteen\n // subscriptions and a whole screen shipped over nothing.\n migrations: MIGRATIONS.map((m) => ({\n id: `automations-${m.id}`,\n version: '1.0.0',\n sql: m.sql,\n description: m.id,\n })),\n locales: automationsLocales,\n widgets: [],\n }\n}\n\nexport { createSupabaseTemplateStore }\nexport { createFayzTemplateStore } from './data/fayz'\nexport type { MessageTemplateStore }\n// O que a Meta respondeu sobre cada modelo. Exportado porque a decisΓ£o \"esta\n// automaΓ§Γ£o de WhatsApp vai mesmo sair?\" Γ© lida fora desta lista β o painel do\n// conector e o provisionamento perguntam a mesma coisa.\nexport {\n loadProviderTemplates, providerTemplateFor, PROVIDER_TEMPLATES_TABLE,\n type ProviderTemplateRow, type ProviderTemplateStatus,\n} from './data/provider-templates'\nexport { providerApprovalFor, type ProviderApproval } from './views/ProviderTemplateStatus'\n\n// ---------------------------------------------------------------------------\n// A tela das cadΓͺncias, exportada como COMPONENTE.\n//\n// Uma cadΓͺncia Γ© o mesmo objeto visto de dois lugares: quem automatiza o funil\n// chega por /automations/flows; quem planeja a rΓ©gua de relacionamento chega\n// pelo Marketing. Exportar a superfΓcie (em vez de o Marketing reimplementΓ‘-la,\n// ou importar este pacote) Γ© o que mantΓ©m UMA tela e UM motor: o app injeta\n// isto no `cadenceSurface` do plugin-marketing e os dois caminhos mostram as\n// mesmas linhas.\n// ---------------------------------------------------------------------------\nexport { FlowsPage as CadenceFlowsSurface } from './views/FlowsPage'\n"]}
|