You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Connector-centric registry: one place to add an integration #22
Full analysis in docs/architecture-review.md. The trigger→action engine is sound; what doesn't scale is that connector knowledge lives in four hand-maintained registries across two languages.
Problem
Adding one action today touches:
src/dapier/engine/actions/<x>.py
the run_x import + if/elif dispatch in src/dapier/engine/__init__.py
ACTION_SPECS validation in src/dapier/triggers/email_triggers.py
the hand-mirrored designer/src/catalog.ts (comment says "Mirrors the run_* dispatch")
Adding one trigger source touches:
worker.normalize_payload branches
template.yaml (per-source queue/table/env)
api/router.py hook routing
a load_workflows() hook in matching.all_workflows
Nothing links these copies; they drift silently. Related structural limits: no data flow between steps (blocks #6, #7, #12), O(all-workflows) resolution per event (published-table scan capped at 200, silently), and per-action auth folklore (credential_id vs connection_id vs auth_secret_id).
Proposal
src/dapier/connectors/<name>/ — one package per integration: a manifest (label, events, actions + field schema), normalize(raw) -> event per ingress it owns, and run(action, ctx) per action. A connectors/registry.py replaces the dispatch chain, ACTION_SPECS, and the trigger-load hooks.
GET /api/catalog — serve the manifests as JSON; the designer renders palette/inspector from it (keep catalog.ts as a dev fallback). One registry, three consumers: engine dispatch, validation, UI.
ActionContext — ctx.connection(name) → live token (auto-refreshed), plus event, workflow, run id, and a steps namespace so later steps can template earlier outputs (first enabler for Step-to-step data mapping + Formatter #6).
One workflows table with a connector#event GSI — merge the published/email/hook/schedule stores; matching becomes a query per event instead of four scans + a linear pass. Instant-publish semantics unchanged.
Generic ingress — a route/queue/source → connector mapping with one ingress handler; per-connector queues become declared resources instead of template.yaml surgery.
Migration order (incremental, no big bang)
Registry wrapping the existing run_* functions; dispatch reads the registry. Tests keep passing.
Move normalize_payload branches into connectors; keep the SQS contract.
/api/catalog; designer consumes it; delete the TS mirror and ACTION_SPECS duplication.
Full analysis in
docs/architecture-review.md. The trigger→action engine is sound; what doesn't scale is that connector knowledge lives in four hand-maintained registries across two languages.Problem
Adding one action today touches:
src/dapier/engine/actions/<x>.pyrun_ximport + if/elif dispatch insrc/dapier/engine/__init__.pyACTION_SPECSvalidation insrc/dapier/triggers/email_triggers.pydesigner/src/catalog.ts(comment says "Mirrors the run_* dispatch")Adding one trigger source touches:
worker.normalize_payloadbranchestemplate.yaml(per-source queue/table/env)api/router.pyhook routingload_workflows()hook inmatching.all_workflowsNothing links these copies; they drift silently. Related structural limits: no data flow between steps (blocks #6, #7, #12), O(all-workflows) resolution per event (published-table scan capped at 200, silently), and per-action auth folklore (
credential_idvsconnection_idvsauth_secret_id).Proposal
src/dapier/connectors/<name>/— one package per integration: a manifest (label, events, actions + field schema),normalize(raw) -> eventper ingress it owns, andrun(action, ctx)per action. Aconnectors/registry.pyreplaces the dispatch chain,ACTION_SPECS, and the trigger-load hooks.GET /api/catalog— serve the manifests as JSON; the designer renders palette/inspector from it (keepcatalog.tsas a dev fallback). One registry, three consumers: engine dispatch, validation, UI.ActionContext—ctx.connection(name)→ live token (auto-refreshed), plus event, workflow, run id, and astepsnamespace so later steps can template earlier outputs (first enabler for Step-to-step data mapping + Formatter #6).connector#eventGSI — merge the published/email/hook/schedule stores; matching becomes a query per event instead of four scans + a linear pass. Instant-publish semantics unchanged.template.yamlsurgery.Migration order (incremental, no big bang)
run_*functions; dispatch reads the registry. Tests keep passing.normalize_payloadbranches into connectors; keep the SQS contract./api/catalog; designer consumes it; delete the TS mirror andACTION_SPECSduplication.ActionContext+steps+ unifiedconnection_id(keepcredential_id/auth_secret_idas deprecated aliases).The 23
src/*.pyback-compat shims are already removed (2026-09-25);make testwas 426 passing at filing time.