[{"data":1,"prerenderedAt":3651},["ShallowReactive",2],{"navigation_docs":3,"-docs-reference-flow-driven-endpoints":968,"-docs-reference-flow-driven-endpoints-surround":3646},[4,27,63,129,287,311,893,902,950,964],{"title":5,"path":6,"stem":7,"children":8,"order":10,"icon":11},"Overview","\u002Fdocs\u002Foverview","docs\u002F1.overview\u002Findex",[9,12,18,24],{"title":5,"path":6,"stem":7,"order":10,"icon":11},1,"i-lucide-info",{"title":13,"path":14,"stem":15,"order":16,"icon":17},"Getting Started","\u002Fdocs\u002Foverview\u002Fgetting-started","docs\u002F1.overview\u002F2.getting-started",2,"i-lucide-rocket",{"title":19,"path":20,"stem":21,"order":22,"icon":23},"Contributing","\u002Fdocs\u002Foverview\u002Fcontributing","docs\u002F1.overview\u002F3.contributing",3,"i-lucide-heart",{"title":5,"path":25,"stem":26,"order":10},"\u002Fdocs\u002Foverview\u002F_dir","docs\u002F1.overview\u002F_dir",{"title":28,"path":29,"stem":30,"children":31,"page":62},"Concepts","\u002Fdocs\u002Fconcepts","docs\u002F2.concepts",[32,37,42,47,53,59],{"title":33,"path":34,"stem":35,"order":10,"icon":36},"Events","\u002Fdocs\u002Fconcepts\u002Fevents","docs\u002F2.concepts\u002F1.events","i-lucide-zap",{"title":38,"path":39,"stem":40,"order":16,"icon":41},"Transports","\u002Fdocs\u002Fconcepts\u002Ftransports","docs\u002F2.concepts\u002F2.transports","i-lucide-network",{"title":43,"path":44,"stem":45,"order":22,"icon":46},"Module System","\u002Fdocs\u002Fconcepts\u002Fmodules","docs\u002F2.concepts\u002F3.modules","i-lucide-puzzle",{"title":48,"path":49,"stem":50,"order":51,"icon":52},"Flows","\u002Fdocs\u002Fconcepts\u002Fflows","docs\u002F2.concepts\u002F4.flows",4,"i-lucide-workflow",{"title":54,"path":55,"stem":56,"order":57,"icon":58},"Scheduler","\u002Fdocs\u002Fconcepts\u002Fscheduler","docs\u002F2.concepts\u002F5.scheduler",5,"i-lucide-clock",{"title":28,"path":60,"stem":61,"order":16},"\u002Fdocs\u002Fconcepts\u002F_dir","docs\u002F2.concepts\u002F_dir",false,{"title":64,"path":65,"stem":66,"children":67,"page":62},"Guides","\u002Fdocs\u002Fguides","docs\u002F3.guides",[68,73,77,81,85,89,93,98,104,110,116,122,126],{"title":69,"path":70,"stem":71,"order":10,"icon":72},"Creating a Go App","\u002Fdocs\u002Fguides\u002Fcreating-go-app","docs\u002F3.guides\u002F1.creating-go-app","i-lucide-terminal",{"title":74,"path":75,"stem":76},"E2E tests & demo videos","\u002Fdocs\u002Fguides\u002Fe2e-and-demo-videos","docs\u002F3.guides\u002F10.e2e-and-demo-videos",{"title":78,"path":79,"stem":80,"icon":17},"Deploying to production","\u002Fdocs\u002Fguides\u002Fdeploying-to-production","docs\u002F3.guides\u002F11.deploying-to-production",{"title":82,"path":83,"stem":84,"order":16,"icon":46},"Creating a Go Module","\u002Fdocs\u002Fguides\u002Fcreating-go-module","docs\u002F3.guides\u002F2.creating-go-module",{"title":86,"path":87,"stem":88,"order":22,"icon":36},"Adding Events","\u002Fdocs\u002Fguides\u002Fadding-events-to-go-module","docs\u002F3.guides\u002F3.adding-events-to-go-module",{"title":90,"path":91,"stem":92,"order":51,"icon":52},"FlowDSL to Service","\u002Fdocs\u002Fguides\u002Fflowdsl-to-redelay","docs\u002F3.guides\u002F4.flowdsl-to-redelay",{"title":94,"path":95,"stem":96,"order":57,"icon":97},"Choosing a Transport","\u002Fdocs\u002Fguides\u002Fchoosing-a-transport","docs\u002F3.guides\u002F5.choosing-a-transport","i-lucide-git-branch",{"title":99,"path":100,"stem":101,"order":102,"icon":103},"Module Browser (\u002Fmodules)","\u002Fdocs\u002Fguides\u002Fmodules-browser","docs\u002F3.guides\u002F6.modules-browser",6,"i-lucide-layout-dashboard",{"title":105,"path":106,"stem":107,"order":108,"icon":109},"Running Flows","\u002Fdocs\u002Fguides\u002Frunning-flows","docs\u002F3.guides\u002F7.running-flows",7,"i-lucide-play-circle",{"title":111,"path":112,"stem":113,"order":114,"icon":115},"Trace + Live Observability","\u002Fdocs\u002Fguides\u002Fobservability","docs\u002F3.guides\u002F8.observability",8,"i-lucide-activity",{"title":117,"path":118,"stem":119,"order":120,"icon":121},"Project AI Assistant","\u002Fdocs\u002Fguides\u002Fai-assistant","docs\u002F3.guides\u002F9.ai-assistant",9,"i-lucide-sparkles",{"title":123,"path":124,"stem":125},"Debug taps — trace live data through any node","\u002Fdocs\u002Fguides\u002Fdebug-taps","docs\u002F3.guides\u002F9.debug-taps",{"title":64,"path":127,"stem":128,"order":22},"\u002Fdocs\u002Fguides\u002F_dir","docs\u002F3.guides\u002F_dir",{"title":130,"path":131,"stem":132,"children":133,"page":62},"Reference","\u002Fdocs\u002Freference","docs\u002F4.reference",[134,139,143,148,153,158,163,168,172,177,182,187,193,199,205,210,215,219,225,230,236,242,247,253,259,263,267,273,278,284],{"title":135,"path":136,"stem":137,"order":10,"icon":138},"Go Framework","\u002Fdocs\u002Freference\u002Fgo-framework","docs\u002F4.reference\u002F01.go-framework","i-simple-icons-go",{"title":140,"path":141,"stem":142,"order":16,"icon":46},"Built-in Modules","\u002Fdocs\u002Freference\u002Fgo-modules","docs\u002F4.reference\u002F02.go-modules",{"title":144,"path":145,"stem":146,"order":22,"icon":147},"Domain Addon Modules","\u002Fdocs\u002Freference\u002Fgo-modules-addons","docs\u002F4.reference\u002F03.go-modules-addons","i-lucide-blocks",{"title":149,"path":150,"stem":151,"order":51,"icon":152},"Go Events","\u002Fdocs\u002Freference\u002Fgo-events","docs\u002F4.reference\u002F04.go-events","i-lucide-radio",{"title":154,"path":155,"stem":156,"order":57,"icon":157},"Email Module","\u002Fdocs\u002Freference\u002Fgo-module-email","docs\u002F4.reference\u002F05.go-module-email","i-lucide-mail",{"title":159,"path":160,"stem":161,"order":102,"icon":162},"Go Core & IR","\u002Fdocs\u002Freference\u002Fgo-core","docs\u002F4.reference\u002F06.go-core","i-lucide-cpu",{"title":164,"path":165,"stem":166,"order":108,"icon":167},"Module Definition Files","\u002Fdocs\u002Freference\u002Fgo-module-files","docs\u002F4.reference\u002F07.go-module-files","i-lucide-file-code",{"title":169,"path":170,"stem":171,"order":114,"icon":72},"CLI Reference","\u002Fdocs\u002Freference\u002Fgo-cli","docs\u002F4.reference\u002F08.go-cli",{"title":173,"path":174,"stem":175,"order":120,"icon":176},"Go Formats","\u002Fdocs\u002Freference\u002Fgo-formats","docs\u002F4.reference\u002F09.go-formats","i-lucide-file-json",{"title":178,"path":179,"stem":180,"order":181,"icon":152},"AsyncAPI Module","\u002Fdocs\u002Freference\u002Fgo-asyncapi","docs\u002F4.reference\u002F10.go-asyncapi",10,{"title":183,"path":184,"stem":185,"order":186,"icon":52},"Go FlowDSL","\u002Fdocs\u002Freference\u002Fgo-flowdsl","docs\u002F4.reference\u002F11.go-flowdsl",11,{"title":188,"path":189,"stem":190,"order":191,"icon":192},"FlowDSL Examples","\u002Fdocs\u002Freference\u002Fflowdsl-examples","docs\u002F4.reference\u002F12.flowdsl-examples",12,"i-lucide-file-code-2",{"title":194,"path":195,"stem":196,"order":197,"icon":198},"FlowDSL Sync","\u002Fdocs\u002Freference\u002Fflowdsl-sync","docs\u002F4.reference\u002F13.flowdsl-sync",13,"i-lucide-refresh-cw",{"title":200,"path":201,"stem":202,"order":203,"icon":204},"Node.js Framework","\u002Fdocs\u002Freference\u002Fjs-framework","docs\u002F4.reference\u002F14.js-framework",14,"i-simple-icons-nodedotjs",{"title":206,"path":207,"stem":208,"order":203,"icon":209},"Python Framework","\u002Fdocs\u002Freference\u002Fpy-framework","docs\u002F4.reference\u002F14.py-framework","i-simple-icons-python",{"title":211,"path":212,"stem":213,"order":214,"icon":204},"Node.js Events","\u002Fdocs\u002Freference\u002Fjs-events","docs\u002F4.reference\u002F15.js-events",15,{"title":216,"path":217,"stem":218,"order":214,"icon":209},"Python Events","\u002Fdocs\u002Freference\u002Fpy-events","docs\u002F4.reference\u002F15.py-events",{"title":220,"path":221,"stem":222,"order":223,"icon":224},"go-ai — LLM Providers, Guard, Ledger","\u002Fdocs\u002Freference\u002Fgo-ai","docs\u002F4.reference\u002F16.go-ai",16,"i-lucide-brain-circuit",{"title":226,"path":227,"stem":228,"order":229,"icon":41},"Infrastructure Modules","\u002Fdocs\u002Freference\u002Fgeneric-infra-modules","docs\u002F4.reference\u002F17.generic-infra-modules",17,{"title":231,"path":232,"stem":233,"order":234,"icon":235},"Flow Templates","\u002Fdocs\u002Freference\u002Fflow-templates","docs\u002F4.reference\u002F18.flow-templates",18,"i-lucide-library-big",{"title":237,"path":238,"stem":239,"order":240,"icon":241},"Assistant (chat + handoff)","\u002Fdocs\u002Freference\u002Fassistant","docs\u002F4.reference\u002F19.assistant",19,"i-lucide-messages-square",{"title":243,"path":244,"stem":245,"order":246,"icon":41},"Coordination","\u002Fdocs\u002Freference\u002Fcoordination","docs\u002F4.reference\u002F20.coordination",20,{"title":248,"path":249,"stem":250,"order":251,"icon":252},"Search (vector)","\u002Fdocs\u002Freference\u002Fsearch","docs\u002F4.reference\u002F21.search",21,"i-lucide-search",{"title":254,"path":255,"stem":256,"order":257,"icon":258},"Profiles","\u002Fdocs\u002Freference\u002Fprofiles","docs\u002F4.reference\u002F22.profiles",22,"i-lucide-bookmark",{"title":260,"path":261,"stem":262},"Flow-driven HTTP endpoints","\u002Fdocs\u002Freference\u002Fflow-driven-endpoints","docs\u002F4.reference\u002F23.flow-driven-endpoints",{"title":264,"path":265,"stem":266},"Deployments","\u002Fdocs\u002Freference\u002Fdeployments","docs\u002F4.reference\u002F24.deployments",{"title":268,"path":269,"stem":270,"order":271,"icon":272},"i18n (translations)","\u002Fdocs\u002Freference\u002Fi18n","docs\u002F4.reference\u002F25.i18n",25,"i-lucide-languages",{"title":274,"path":275,"stem":276,"order":277,"icon":152},"WebSockets","\u002Fdocs\u002Freference\u002Fwebsockets","docs\u002F4.reference\u002F26.websockets",26,{"title":279,"path":280,"stem":281,"order":282,"icon":283},"Localized content","\u002Fdocs\u002Freference\u002Flocalized-content","docs\u002F4.reference\u002F27.localized-content",27,"i-lucide-file-text",{"title":130,"path":285,"stem":286,"order":51},"\u002Fdocs\u002Freference\u002F_dir","docs\u002F4.reference\u002F_dir",{"title":288,"path":289,"stem":290,"children":291,"page":62},"Integrations","\u002Fdocs\u002Fintegrations","docs\u002F5.integrations",[292,296,300,304,308],{"title":293,"path":294,"stem":295,"order":10,"icon":52},"FlowDSL","\u002Fdocs\u002Fintegrations\u002Fflowdsl","docs\u002F5.integrations\u002F1.flowdsl",{"title":297,"path":298,"stem":299,"order":16,"icon":283},"OpenAPI","\u002Fdocs\u002Fintegrations\u002Fopenapi","docs\u002F5.integrations\u002F2.openapi",{"title":301,"path":302,"stem":303,"order":22,"icon":152},"AsyncAPI","\u002Fdocs\u002Fintegrations\u002Fasyncapi","docs\u002F5.integrations\u002F3.asyncapi",{"title":305,"path":306,"stem":307},"MCP Integration","\u002Fdocs\u002Fintegrations\u002Fmcp","docs\u002F5.integrations\u002F4.mcp",{"title":288,"path":309,"stem":310,"order":57},"\u002Fdocs\u002Fintegrations\u002F_dir","docs\u002F5.integrations\u002F_dir",{"title":312,"path":313,"stem":314,"children":315},"FlowDSL Node Catalog","\u002Fdocs\u002Fnodes","docs\u002F5.nodes\u002Findex",[316,317,321,325,329,333,337,341,345,349,353,357,361,365,369,373,377,381,385,389,393,397,401,405,409,413,417,421,425,429,433,437,441,445,449,453,457,461,465,469,473,477,481,485,489,493,497,501,505,509,513,517,521,525,529,533,537,541,545,549,553,557,561,565,569,573,577,581,585,589,593,597,601,605,609,613,617,621,625,629,633,637,641,645,649,653,657,661,665,669,673,677,681,685,689,693,697,701,705,709,713,717,721,725,729,733,737,741,745,749,753,757,761,765,769,773,777,781,785,789,793,797,801,805,809,813,817,821,825,829,833,837,841,845,849,853,857,861,865,869,873,877,881,885,889],{"title":312,"path":313,"stem":314},{"title":318,"path":319,"stem":320,"order":57},"Node Catalog","\u002Fdocs\u002Fnodes\u002F_dir","docs\u002F5.nodes\u002F_dir",{"title":322,"path":323,"stem":324},"Record Alert","\u002Fdocs\u002Fnodes\u002Falerts_record","docs\u002F5.nodes\u002Falerts_record",{"title":326,"path":327,"stem":328},"Log to API Log","\u002Fdocs\u002Fnodes\u002Fapilog_record","docs\u002F5.nodes\u002Fapilog_record",{"title":330,"path":331,"stem":332},"ClickHouse Exec","\u002Fdocs\u002Fnodes\u002Fclickhouse_exec","docs\u002F5.nodes\u002Fclickhouse_exec",{"title":334,"path":335,"stem":336},"ClickHouse Insert","\u002Fdocs\u002Fnodes\u002Fclickhouse_insert","docs\u002F5.nodes\u002Fclickhouse_insert",{"title":338,"path":339,"stem":340},"ClickHouse Query","\u002Fdocs\u002Fnodes\u002Fclickhouse_query","docs\u002F5.nodes\u002Fclickhouse_query",{"title":342,"path":343,"stem":344},"Array Op","\u002Fdocs\u002Fnodes\u002Fcore_array-ops","docs\u002F5.nodes\u002Fcore_array-ops",{"title":346,"path":347,"stem":348},"Assert","\u002Fdocs\u002Fnodes\u002Fcore_assert","docs\u002F5.nodes\u002Fcore_assert",{"title":350,"path":351,"stem":352},"Audit Emit","\u002Fdocs\u002Fnodes\u002Fcore_audit-emit","docs\u002F5.nodes\u002Fcore_audit-emit",{"title":354,"path":355,"stem":356},"Catch","\u002Fdocs\u002Fnodes\u002Fcore_catch","docs\u002F5.nodes\u002Fcore_catch",{"title":358,"path":359,"stem":360},"DateTime","\u002Fdocs\u002Fnodes\u002Fcore_datetime","docs\u002F5.nodes\u002Fcore_datetime",{"title":362,"path":363,"stem":364},"Dead Letter","\u002Fdocs\u002Fnodes\u002Fcore_dead-letter","docs\u002F5.nodes\u002Fcore_dead-letter",{"title":366,"path":367,"stem":368},"Delay","\u002Fdocs\u002Fnodes\u002Fcore_delay","docs\u002F5.nodes\u002Fcore_delay",{"title":370,"path":371,"stem":372},"ForEach","\u002Fdocs\u002Fnodes\u002Fcore_foreach","docs\u002F5.nodes\u002Fcore_foreach",{"title":374,"path":375,"stem":376},"Idempotency Key","\u002Fdocs\u002Fnodes\u002Fcore_idempotency-key","docs\u002F5.nodes\u002Fcore_idempotency-key",{"title":378,"path":379,"stem":380},"If","\u002Fdocs\u002Fnodes\u002Fcore_if","docs\u002F5.nodes\u002Fcore_if",{"title":382,"path":383,"stem":384},"Inspect","\u002Fdocs\u002Fnodes\u002Fcore_inspect","docs\u002F5.nodes\u002Fcore_inspect",{"title":386,"path":387,"stem":388},"JSON Merge","\u002Fdocs\u002Fnodes\u002Fcore_json-merge","docs\u002F5.nodes\u002Fcore_json-merge",{"title":390,"path":391,"stem":392},"JSON Schema Validate","\u002Fdocs\u002Fnodes\u002Fcore_json-schema-validate","docs\u002F5.nodes\u002Fcore_json-schema-validate",{"title":394,"path":395,"stem":396},"JSONPath Extract","\u002Fdocs\u002Fnodes\u002Fcore_jsonpath-extract","docs\u002F5.nodes\u002Fcore_jsonpath-extract",{"title":398,"path":399,"stem":400},"Log","\u002Fdocs\u002Fnodes\u002Fcore_log","docs\u002F5.nodes\u002Fcore_log",{"title":402,"path":403,"stem":404},"Math","\u002Fdocs\u002Fnodes\u002Fcore_math","docs\u002F5.nodes\u002Fcore_math",{"title":406,"path":407,"stem":408},"Merge","\u002Fdocs\u002Fnodes\u002Fcore_merge","docs\u002F5.nodes\u002Fcore_merge",{"title":410,"path":411,"stem":412},"Metric Counter","\u002Fdocs\u002Fnodes\u002Fcore_metric-counter","docs\u002F5.nodes\u002Fcore_metric-counter",{"title":414,"path":415,"stem":416},"Metric Gauge","\u002Fdocs\u002Fnodes\u002Fcore_metric-gauge","docs\u002F5.nodes\u002Fcore_metric-gauge",{"title":418,"path":419,"stem":420},"Mock","\u002Fdocs\u002Fnodes\u002Fcore_mock","docs\u002F5.nodes\u002Fcore_mock",{"title":422,"path":423,"stem":424},"No-op","\u002Fdocs\u002Fnodes\u002Fcore_noop","docs\u002F5.nodes\u002Fcore_noop",{"title":426,"path":427,"stem":428},"Object Omit","\u002Fdocs\u002Fnodes\u002Fcore_object-omit","docs\u002F5.nodes\u002Fcore_object-omit",{"title":430,"path":431,"stem":432},"Object Pick","\u002Fdocs\u002Fnodes\u002Fcore_object-pick","docs\u002F5.nodes\u002Fcore_object-pick",{"title":434,"path":435,"stem":436},"Parallel Fan-Out","\u002Fdocs\u002Fnodes\u002Fcore_parallel","docs\u002F5.nodes\u002Fcore_parallel",{"title":438,"path":439,"stem":440},"Raise","\u002Fdocs\u002Fnodes\u002Fcore_raise","docs\u002F5.nodes\u002Fcore_raise",{"title":442,"path":443,"stem":444},"Rate Limit Check","\u002Fdocs\u002Fnodes\u002Fcore_rate-limit-check","docs\u002F5.nodes\u002Fcore_rate-limit-check",{"title":446,"path":447,"stem":448},"Regex Extract","\u002Fdocs\u002Fnodes\u002Fcore_regex-extract","docs\u002F5.nodes\u002Fcore_regex-extract",{"title":450,"path":451,"stem":452},"Require Fields","\u002Fdocs\u002Fnodes\u002Fcore_require-fields","docs\u002F5.nodes\u002Fcore_require-fields",{"title":454,"path":455,"stem":456},"Rethrow","\u002Fdocs\u002Fnodes\u002Fcore_rethrow","docs\u002F5.nodes\u002Fcore_rethrow",{"title":458,"path":459,"stem":460},"Return","\u002Fdocs\u002Fnodes\u002Fcore_return","docs\u002F5.nodes\u002Fcore_return",{"title":462,"path":463,"stem":464},"HMAC Signature Verify","\u002Fdocs\u002Fnodes\u002Fcore_signature-verify","docs\u002F5.nodes\u002Fcore_signature-verify",{"title":466,"path":467,"stem":468},"String Op","\u002Fdocs\u002Fnodes\u002Fcore_string-ops","docs\u002F5.nodes\u002Fcore_string-ops",{"title":470,"path":471,"stem":472},"Subflow Invoke","\u002Fdocs\u002Fnodes\u002Fcore_subflow-invoke","docs\u002F5.nodes\u002Fcore_subflow-invoke",{"title":474,"path":475,"stem":476},"Switch","\u002Fdocs\u002Fnodes\u002Fcore_switch","docs\u002F5.nodes\u002Fcore_switch",{"title":478,"path":479,"stem":480},"Template Render","\u002Fdocs\u002Fnodes\u002Fcore_template-render","docs\u002F5.nodes\u002Fcore_template-render",{"title":482,"path":483,"stem":484},"Throttle","\u002Fdocs\u002Fnodes\u002Fcore_throttle","docs\u002F5.nodes\u002Fcore_throttle",{"title":486,"path":487,"stem":488},"Timeout","\u002Fdocs\u002Fnodes\u002Fcore_timeout","docs\u002F5.nodes\u002Fcore_timeout",{"title":490,"path":491,"stem":492},"Type Cast","\u002Fdocs\u002Fnodes\u002Fcore_type-cast","docs\u002F5.nodes\u002Fcore_type-cast",{"title":494,"path":495,"stem":496},"Webhook Respond","\u002Fdocs\u002Fnodes\u002Fcore_webhook-respond","docs\u002F5.nodes\u002Fcore_webhook-respond",{"title":498,"path":499,"stem":500},"File Delete","\u002Fdocs\u002Fnodes\u002Ffilesys_delete","docs\u002F5.nodes\u002Ffilesys_delete",{"title":502,"path":503,"stem":504},"Directory List","\u002Fdocs\u002Fnodes\u002Ffilesys_list","docs\u002F5.nodes\u002Ffilesys_list",{"title":506,"path":507,"stem":508},"File Read","\u002Fdocs\u002Fnodes\u002Ffilesys_read","docs\u002F5.nodes\u002Ffilesys_read",{"title":510,"path":511,"stem":512},"File Stat","\u002Fdocs\u002Fnodes\u002Ffilesys_stat","docs\u002F5.nodes\u002Ffilesys_stat",{"title":514,"path":515,"stem":516},"File Write","\u002Fdocs\u002Fnodes\u002Ffilesys_write","docs\u002F5.nodes\u002Ffilesys_write",{"title":518,"path":519,"stem":520},"FTP Delete","\u002Fdocs\u002Fnodes\u002Fftp_delete","docs\u002F5.nodes\u002Fftp_delete",{"title":522,"path":523,"stem":524},"FTP Download","\u002Fdocs\u002Fnodes\u002Fftp_download","docs\u002F5.nodes\u002Fftp_download",{"title":526,"path":527,"stem":528},"FTP List","\u002Fdocs\u002Fnodes\u002Fftp_list","docs\u002F5.nodes\u002Fftp_list",{"title":530,"path":531,"stem":532},"FTP Upload","\u002Fdocs\u002Fnodes\u002Fftp_upload","docs\u002F5.nodes\u002Fftp_upload",{"title":534,"path":535,"stem":536},"HTTP DELETE","\u002Fdocs\u002Fnodes\u002Fhttp_delete","docs\u002F5.nodes\u002Fhttp_delete",{"title":538,"path":539,"stem":540},"HTTP GET","\u002Fdocs\u002Fnodes\u002Fhttp_get","docs\u002F5.nodes\u002Fhttp_get",{"title":542,"path":543,"stem":544},"HTTP POST","\u002Fdocs\u002Fnodes\u002Fhttp_post","docs\u002F5.nodes\u002Fhttp_post",{"title":546,"path":547,"stem":548},"HTTP PUT","\u002Fdocs\u002Fnodes\u002Fhttp_put","docs\u002F5.nodes\u002Fhttp_put",{"title":550,"path":551,"stem":552},"HTTP Request","\u002Fdocs\u002Fnodes\u002Fhttp_request","docs\u002F5.nodes\u002Fhttp_request",{"title":554,"path":555,"stem":556},"Fill Translations","\u002Fdocs\u002Fnodes\u002Fi18n_fill-translations","docs\u002F5.nodes\u002Fi18n_fill-translations",{"title":558,"path":559,"stem":560},"Resolve Locale","\u002Fdocs\u002Fnodes\u002Fi18n_resolve-locale","docs\u002F5.nodes\u002Fi18n_resolve-locale",{"title":562,"path":563,"stem":564},"Translate","\u002Fdocs\u002Fnodes\u002Fi18n_translate","docs\u002F5.nodes\u002Fi18n_translate",{"title":566,"path":567,"stem":568},"Mongo AGGREGATE","\u002Fdocs\u002Fnodes\u002Fmongoops_aggregate","docs\u002F5.nodes\u002Fmongoops_aggregate",{"title":570,"path":571,"stem":572},"Mongo DELETE","\u002Fdocs\u002Fnodes\u002Fmongoops_delete","docs\u002F5.nodes\u002Fmongoops_delete",{"title":574,"path":575,"stem":576},"Mongo FIND","\u002Fdocs\u002Fnodes\u002Fmongoops_find","docs\u002F5.nodes\u002Fmongoops_find",{"title":578,"path":579,"stem":580},"Mongo FIND ONE","\u002Fdocs\u002Fnodes\u002Fmongoops_find-one","docs\u002F5.nodes\u002Fmongoops_find-one",{"title":582,"path":583,"stem":584},"Mongo INSERT","\u002Fdocs\u002Fnodes\u002Fmongoops_insert","docs\u002F5.nodes\u002Fmongoops_insert",{"title":586,"path":587,"stem":588},"Mongo UPDATE","\u002Fdocs\u002Fnodes\u002Fmongoops_update","docs\u002F5.nodes\u002Fmongoops_update",{"title":590,"path":591,"stem":592},"Postgres COPY FROM","\u002Fdocs\u002Fnodes\u002Fpostgres_copy-from","docs\u002F5.nodes\u002Fpostgres_copy-from",{"title":594,"path":595,"stem":596},"Postgres Exec","\u002Fdocs\u002Fnodes\u002Fpostgres_exec","docs\u002F5.nodes\u002Fpostgres_exec",{"title":598,"path":599,"stem":600},"Postgres Query","\u002Fdocs\u002Fnodes\u002Fpostgres_query","docs\u002F5.nodes\u002Fpostgres_query",{"title":602,"path":603,"stem":604},"Postgres Transaction","\u002Fdocs\u002Fnodes\u002Fpostgres_transaction","docs\u002F5.nodes\u002Fpostgres_transaction",{"title":606,"path":607,"stem":608},"RabbitMQ Consume","\u002Fdocs\u002Fnodes\u002Frabbitmq_consume","docs\u002F5.nodes\u002Frabbitmq_consume",{"title":610,"path":611,"stem":612},"RabbitMQ Declare","\u002Fdocs\u002Fnodes\u002Frabbitmq_declare","docs\u002F5.nodes\u002Frabbitmq_declare",{"title":614,"path":615,"stem":616},"RabbitMQ Publish","\u002Fdocs\u002Fnodes\u002Frabbitmq_publish","docs\u002F5.nodes\u002Frabbitmq_publish",{"title":618,"path":619,"stem":620},"Auth Login","\u002Fdocs\u002Fnodes\u002Fredelay_auth-login","docs\u002F5.nodes\u002Fredelay_auth-login",{"title":622,"path":623,"stem":624},"Require Permission","\u002Fdocs\u002Fnodes\u002Fredelay_auth-require-permission","docs\u002F5.nodes\u002Fredelay_auth-require-permission",{"title":626,"path":627,"stem":628},"Validate Token","\u002Fdocs\u002Fnodes\u002Fredelay_auth-validate-token","docs\u002F5.nodes\u002Fredelay_auth-validate-token",{"title":630,"path":631,"stem":632},"Render Email Template","\u002Fdocs\u002Fnodes\u002Fredelay_email-render-template","docs\u002F5.nodes\u002Fredelay_email-render-template",{"title":634,"path":635,"stem":636},"Send Email","\u002Fdocs\u002Fnodes\u002Fredelay_email-send","docs\u002F5.nodes\u002Fredelay_email-send",{"title":638,"path":639,"stem":640},"Send Templated Email","\u002Fdocs\u002Fnodes\u002Fredelay_email-send-templated","docs\u002F5.nodes\u002Fredelay_email-send-templated",{"title":642,"path":643,"stem":644},"Event Source","\u002Fdocs\u002Fnodes\u002Fredelay_event-source","docs\u002F5.nodes\u002Fredelay_event-source",{"title":646,"path":647,"stem":648},"Create Group","\u002Fdocs\u002Fnodes\u002Fredelay_groups-create-group","docs\u002F5.nodes\u002Fredelay_groups-create-group",{"title":650,"path":651,"stem":652},"Delete Group","\u002Fdocs\u002Fnodes\u002Fredelay_groups-delete-group","docs\u002F5.nodes\u002Fredelay_groups-delete-group",{"title":654,"path":655,"stem":656},"Resolve Permissions","\u002Fdocs\u002Fnodes\u002Fredelay_groups-resolve-permissions","docs\u002F5.nodes\u002Fredelay_groups-resolve-permissions",{"title":658,"path":659,"stem":660},"Update Group","\u002Fdocs\u002Fnodes\u002Fredelay_groups-update-group","docs\u002F5.nodes\u002Fredelay_groups-update-group",{"title":662,"path":663,"stem":664},"HTTP Endpoint","\u002Fdocs\u002Fnodes\u002Fredelay_http-endpoint","docs\u002F5.nodes\u002Fredelay_http-endpoint",{"title":666,"path":667,"stem":668},"JSON Stream Source","\u002Fdocs\u002Fnodes\u002Fredelay_json-stream-source","docs\u002F5.nodes\u002Fredelay_json-stream-source",{"title":670,"path":671,"stem":672},"JSON → Event","\u002Fdocs\u002Fnodes\u002Fredelay_json-to-event","docs\u002F5.nodes\u002Fredelay_json-to-event",{"title":674,"path":675,"stem":676},"Kafka Produce","\u002Fdocs\u002Fnodes\u002Fredelay_kafka-produce","docs\u002F5.nodes\u002Fredelay_kafka-produce",{"title":678,"path":679,"stem":680},"Create Short Link","\u002Fdocs\u002Fnodes\u002Fredelay_links-create","docs\u002F5.nodes\u002Fredelay_links-create",{"title":682,"path":683,"stem":684},"Delete Short Link","\u002Fdocs\u002Fnodes\u002Fredelay_links-delete","docs\u002F5.nodes\u002Fredelay_links-delete",{"title":686,"path":687,"stem":688},"Resolve Short Link","\u002Fdocs\u002Fnodes\u002Fredelay_links-resolve","docs\u002F5.nodes\u002Fredelay_links-resolve",{"title":690,"path":691,"stem":692},"LLM Chat","\u002Fdocs\u002Fnodes\u002Fredelay_llm-chat","docs\u002F5.nodes\u002Fredelay_llm-chat",{"title":694,"path":695,"stem":696},"LLM Embed","\u002Fdocs\u002Fnodes\u002Fredelay_llm-embed","docs\u002F5.nodes\u002Fredelay_llm-embed",{"title":698,"path":699,"stem":700},"LLM Guard","\u002Fdocs\u002Fnodes\u002Fredelay_llm-guard","docs\u002F5.nodes\u002Fredelay_llm-guard",{"title":702,"path":703,"stem":704},"LLM Tool Router","\u002Fdocs\u002Fnodes\u002Fredelay_llm-tool-router","docs\u002F5.nodes\u002Fredelay_llm-tool-router",{"title":706,"path":707,"stem":708},"NATS Publish","\u002Fdocs\u002Fnodes\u002Fredelay_nats-publish","docs\u002F5.nodes\u002Fredelay_nats-publish",{"title":710,"path":711,"stem":712},"Mark Notification Read","\u002Fdocs\u002Fnodes\u002Fredelay_notifications-mark-read","docs\u002F5.nodes\u002Fredelay_notifications-mark-read",{"title":714,"path":715,"stem":716},"Send Notification","\u002Fdocs\u002Fnodes\u002Fredelay_notifications-send","docs\u002F5.nodes\u002Fredelay_notifications-send",{"title":718,"path":719,"stem":720},"Redis Stream XADD","\u002Fdocs\u002Fnodes\u002Fredelay_redis-stream-publish","docs\u002F5.nodes\u002Fredelay_redis-stream-publish",{"title":722,"path":723,"stem":724},"S3 Copy Object","\u002Fdocs\u002Fnodes\u002Fredelay_s3-copy-object","docs\u002F5.nodes\u002Fredelay_s3-copy-object",{"title":726,"path":727,"stem":728},"S3 Delete Many","\u002Fdocs\u002Fnodes\u002Fredelay_s3-delete-many","docs\u002F5.nodes\u002Fredelay_s3-delete-many",{"title":730,"path":731,"stem":732},"S3 Head Object","\u002Fdocs\u002Fnodes\u002Fredelay_s3-head-object","docs\u002F5.nodes\u002Fredelay_s3-head-object",{"title":734,"path":735,"stem":736},"S3 List Objects","\u002Fdocs\u002Fnodes\u002Fredelay_s3-list-objects","docs\u002F5.nodes\u002Fredelay_s3-list-objects",{"title":738,"path":739,"stem":740},"Create Schedule","\u002Fdocs\u002Fnodes\u002Fredelay_scheduler-create-schedule","docs\u002F5.nodes\u002Fredelay_scheduler-create-schedule",{"title":742,"path":743,"stem":744},"Cron Trigger","\u002Fdocs\u002Fnodes\u002Fredelay_scheduler-cron-trigger","docs\u002F5.nodes\u002Fredelay_scheduler-cron-trigger",{"title":746,"path":747,"stem":748},"Delete Schedule","\u002Fdocs\u002Fnodes\u002Fredelay_scheduler-delete-schedule","docs\u002F5.nodes\u002Fredelay_scheduler-delete-schedule",{"title":750,"path":751,"stem":752},"Interval Trigger","\u002Fdocs\u002Fnodes\u002Fredelay_scheduler-interval-trigger","docs\u002F5.nodes\u002Fredelay_scheduler-interval-trigger",{"title":754,"path":755,"stem":756},"Search Query","\u002Fdocs\u002Fnodes\u002Fredelay_search-query","docs\u002F5.nodes\u002Fredelay_search-query",{"title":758,"path":759,"stem":760},"Search Upsert","\u002Fdocs\u002Fnodes\u002Fredelay_search-upsert","docs\u002F5.nodes\u002Fredelay_search-upsert",{"title":762,"path":763,"stem":764},"Delete Setting","\u002Fdocs\u002Fnodes\u002Fredelay_settings-delete","docs\u002F5.nodes\u002Fredelay_settings-delete",{"title":766,"path":767,"stem":768},"Get Setting","\u002Fdocs\u002Fnodes\u002Fredelay_settings-get","docs\u002F5.nodes\u002Fredelay_settings-get",{"title":770,"path":771,"stem":772},"Set Setting","\u002Fdocs\u002Fnodes\u002Fredelay_settings-set","docs\u002F5.nodes\u002Fredelay_settings-set",{"title":774,"path":775,"stem":776},"Delete File","\u002Fdocs\u002Fnodes\u002Fredelay_storage-delete","docs\u002F5.nodes\u002Fredelay_storage-delete",{"title":778,"path":779,"stem":780},"Download File","\u002Fdocs\u002Fnodes\u002Fredelay_storage-download","docs\u002F5.nodes\u002Fredelay_storage-download",{"title":782,"path":783,"stem":784},"Generate Presigned URL","\u002Fdocs\u002Fnodes\u002Fredelay_storage-presign-url","docs\u002F5.nodes\u002Fredelay_storage-presign-url",{"title":786,"path":787,"stem":788},"Upload File","\u002Fdocs\u002Fnodes\u002Fredelay_storage-upload","docs\u002F5.nodes\u002Fredelay_storage-upload",{"title":790,"path":791,"stem":792},"Subworkflow","\u002Fdocs\u002Fnodes\u002Fredelay_subworkflow","docs\u002F5.nodes\u002Fredelay_subworkflow",{"title":794,"path":795,"stem":796},"Activate User","\u002Fdocs\u002Fnodes\u002Fredelay_users-activate","docs\u002F5.nodes\u002Fredelay_users-activate",{"title":798,"path":799,"stem":800},"Create Pending User","\u002Fdocs\u002Fnodes\u002Fredelay_users-create-pending","docs\u002F5.nodes\u002Fredelay_users-create-pending",{"title":802,"path":803,"stem":804},"Create User","\u002Fdocs\u002Fnodes\u002Fredelay_users-create-user","docs\u002F5.nodes\u002Fredelay_users-create-user",{"title":806,"path":807,"stem":808},"Delete User","\u002Fdocs\u002Fnodes\u002Fredelay_users-delete-user","docs\u002F5.nodes\u002Fredelay_users-delete-user",{"title":810,"path":811,"stem":812},"Find User By Email","\u002Fdocs\u002Fnodes\u002Fredelay_users-find-by-email","docs\u002F5.nodes\u002Fredelay_users-find-by-email",{"title":814,"path":815,"stem":816},"Get User","\u002Fdocs\u002Fnodes\u002Fredelay_users-get-user","docs\u002F5.nodes\u002Fredelay_users-get-user",{"title":818,"path":819,"stem":820},"List Users","\u002Fdocs\u002Fnodes\u002Fredelay_users-list-users","docs\u002F5.nodes\u002Fredelay_users-list-users",{"title":822,"path":823,"stem":824},"Update User","\u002Fdocs\u002Fnodes\u002Fredelay_users-update-user","docs\u002F5.nodes\u002Fredelay_users-update-user",{"title":826,"path":827,"stem":828},"Request Email Verification (legacy)","\u002Fdocs\u002Fnodes\u002Fredelay_verification-request","docs\u002F5.nodes\u002Fredelay_verification-request",{"title":830,"path":831,"stem":832},"Request Email Verification","\u002Fdocs\u002Fnodes\u002Fredelay_verification-request-email","docs\u002F5.nodes\u002Fredelay_verification-request-email",{"title":834,"path":835,"stem":836},"Request SMS Verification","\u002Fdocs\u002Fnodes\u002Fredelay_verification-request-sms","docs\u002F5.nodes\u002Fredelay_verification-request-sms",{"title":838,"path":839,"stem":840},"Verify Token","\u002Fdocs\u002Fnodes\u002Fredelay_verification-verify","docs\u002F5.nodes\u002Fredelay_verification-verify",{"title":842,"path":843,"stem":844},"Redis DEL","\u002Fdocs\u002Fnodes\u002Fredisops_del","docs\u002F5.nodes\u002Fredisops_del",{"title":846,"path":847,"stem":848},"Redis EXPIRE","\u002Fdocs\u002Fnodes\u002Fredisops_expire","docs\u002F5.nodes\u002Fredisops_expire",{"title":850,"path":851,"stem":852},"Redis GET","\u002Fdocs\u002Fnodes\u002Fredisops_get","docs\u002F5.nodes\u002Fredisops_get",{"title":854,"path":855,"stem":856},"Redis HGET","\u002Fdocs\u002Fnodes\u002Fredisops_hget","docs\u002F5.nodes\u002Fredisops_hget",{"title":858,"path":859,"stem":860},"Redis HSET","\u002Fdocs\u002Fnodes\u002Fredisops_hset","docs\u002F5.nodes\u002Fredisops_hset",{"title":862,"path":863,"stem":864},"Redis INCR","\u002Fdocs\u002Fnodes\u002Fredisops_incr","docs\u002F5.nodes\u002Fredisops_incr",{"title":866,"path":867,"stem":868},"Redis LPOP","\u002Fdocs\u002Fnodes\u002Fredisops_lpop","docs\u002F5.nodes\u002Fredisops_lpop",{"title":870,"path":871,"stem":872},"Redis LPUSH","\u002Fdocs\u002Fnodes\u002Fredisops_lpush","docs\u002F5.nodes\u002Fredisops_lpush",{"title":874,"path":875,"stem":876},"Redis PUBLISH","\u002Fdocs\u002Fnodes\u002Fredisops_publish","docs\u002F5.nodes\u002Fredisops_publish",{"title":878,"path":879,"stem":880},"Redis SET","\u002Fdocs\u002Fnodes\u002Fredisops_set","docs\u002F5.nodes\u002Fredisops_set",{"title":882,"path":883,"stem":884},"SFTP Download","\u002Fdocs\u002Fnodes\u002Fsftp_download","docs\u002F5.nodes\u002Fsftp_download",{"title":886,"path":887,"stem":888},"SFTP Upload","\u002Fdocs\u002Fnodes\u002Fsftp_upload","docs\u002F5.nodes\u002Fsftp_upload",{"title":890,"path":891,"stem":892},"Send SMS","\u002Fdocs\u002Fnodes\u002Fsms_send","docs\u002F5.nodes\u002Fsms_send",{"title":894,"path":895,"stem":896,"children":897,"page":62},"Rfcs","\u002Fdocs\u002Frfcs","docs\u002F6.rfcs",[898],{"title":899,"path":900,"stem":901},"RFC 0001 — Worker Assignment for Flow Deployments","\u002Fdocs\u002Frfcs\u002F0001-worker-assignment","docs\u002F6.rfcs\u002F0001-worker-assignment",{"title":903,"path":904,"stem":905,"children":906,"page":62},"Admin","\u002Fdocs\u002Fadmin","docs\u002F7.admin",[907,912,917,922,927,932,937,941,946],{"title":5,"path":908,"stem":909,"order":910,"icon":911},"\u002Fdocs\u002Fadmin\u002Foverview","docs\u002F7.admin\u002F00.overview",0,"i-lucide-compass",{"title":913,"path":914,"stem":915,"order":10,"icon":916},"Getting started","\u002Fdocs\u002Fadmin\u002Fgetting-started","docs\u002F7.admin\u002F01.getting-started","i-lucide-play",{"title":918,"path":919,"stem":920,"order":16,"icon":921},"Layered architecture","\u002Fdocs\u002Fadmin\u002Flayered-architecture","docs\u002F7.admin\u002F02.layered-architecture","i-lucide-layers",{"title":923,"path":924,"stem":925,"order":22,"icon":926},"Building a custom admin project","\u002Fdocs\u002Fadmin\u002Fbuilding-a-custom-admin-project","docs\u002F7.admin\u002F03.building-a-custom-admin-project","i-lucide-folder-plus",{"title":928,"path":929,"stem":930,"order":51,"icon":931},"Building admin modules","\u002Fdocs\u002Fadmin\u002Fbuilding-admin-modules","docs\u002F7.admin\u002F04.building-admin-modules","i-lucide-package-plus",{"title":933,"path":934,"stem":935,"order":57,"icon":936},"Base module reference","\u002Fdocs\u002Fadmin\u002Freference-base-modules","docs\u002F7.admin\u002F05.reference-base-modules","i-lucide-boxes",{"title":938,"path":939,"stem":940,"order":102,"icon":17},"Deployment","\u002Fdocs\u002Fadmin\u002Fdeployment","docs\u002F7.admin\u002F06.deployment",{"title":942,"path":943,"stem":944,"order":108,"icon":945},"Consuming the base layer (versioned)","\u002Fdocs\u002Fadmin\u002Fconsuming-the-base-layer","docs\u002F7.admin\u002F07.consuming-the-base-layer","i-lucide-package",{"title":947,"path":948,"stem":949,"order":108},"Admin UI","\u002Fdocs\u002Fadmin\u002F_dir","docs\u002F7.admin\u002F_dir",{"title":951,"path":952,"stem":953,"children":954,"page":62},"Services","\u002Fdocs\u002Fservices","docs\u002F8.services",[955,960],{"title":956,"path":957,"stem":958,"order":10,"icon":959},"Custom development & support services","\u002Fdocs\u002Fservices\u002Fcustom-development","docs\u002F8.services\u002F1.custom-development","i-lucide-briefcase",{"title":951,"path":961,"stem":962,"icon":959,"order":963},"\u002Fdocs\u002Fservices\u002F_dir","docs\u002F8.services\u002F_dir",80,{"title":965,"path":966,"stem":967,"order":910},"Dir","\u002Fdocs\u002F_dir","docs\u002F_dir",{"id":969,"title":260,"body":970,"description":3639,"extension":3640,"links":3641,"meta":3642,"navigation":3643,"path":261,"seo":3644,"stem":262,"__hash__":3645},"docs\u002Fdocs\u002F4.reference\u002F23.flow-driven-endpoints.md",{"type":971,"value":972,"toc":3605},"minimark",[973,977,991,996,1055,1070,1074,1084,1186,1190,1350,1361,1385,1392,1396,1414,1419,1924,1927,1972,1982,1986,1992,1995,2057,2065,2095,2102,2112,2157,2185,2188,2194,2361,2374,2393,2403,2407,2410,2502,2508,2518,2522,2545,2555,2559,2562,2571,2578,2582,2591,2642,2664,2670,2674,2706,2714,2748,2787,2800,2804,2811,2872,2878,2885,2892,2895,2972,2986,2989,3102,3106,3119,3125,3128,3138,3142,3210,3213,3217,3223,3227,3233,3240,3329,3350,3354,3415,3418,3437,3441,3462,3466,3469,3601],[974,975,260],"h1",{"id":976},"flow-driven-http-endpoints",[978,979,980,981,985,986,990],"p",{},"Any FlowDSL flow whose source is a ",[982,983,984],"code",{},"redelay\u002Fhttp-endpoint"," node is\nmounted as an HTTP route by the framework. When the configured path is\nhit, the flow runs synchronously, and its terminal output is written\nas the JSON response. Domain modules don't write HTTP-handler shims —\nthey contribute ",[987,988,989],"em",{},"nodes",", and the flowexec dispatcher owns the bridge.",[992,993,995],"h2",{"id":994},"when-to-use-this","When to use this",[997,998,999,1012],"table",{},[1000,1001,1002],"thead",{},[1003,1004,1005,1009],"tr",{},[1006,1007,1008],"th",{},"Situation",[1006,1010,1011],{},"Solution",[1013,1014,1015,1028,1036,1044],"tbody",{},[1003,1016,1017,1021],{},[1018,1019,1020],"td",{},"One-off CRUD on a fixed schema",[1018,1022,1023,1024,1027],{},"Regular Go ",[982,1025,1026],{},"RoutesProvider"," handler",[1003,1029,1030,1033],{},[1018,1031,1032],{},"Multi-step business pipeline (signup, password reset, OAuth callback, account deletion, …)",[1018,1034,1035],{},"Flow-driven endpoint + per-module starter templates",[1003,1037,1038,1041],{},[1018,1039,1040],{},"Different deployments need different pipelines (e.g. add SMS confirmation only for paid tier)",[1018,1042,1043],{},"Flow-driven endpoint — admins activate a different template per environment",[1003,1045,1046,1049],{},[1018,1047,1048],{},"Pure async event reaction (no HTTP request involved)",[1018,1050,1051,1054],{},[982,1052,1053],{},"redelay\u002Fevent-source"," node, no http-endpoint",[978,1056,1057,1058,1061,1062,1065,1066,1069],{},"The fine-grained pipeline cases are why ",[982,1059,1060],{},"users\u002Fsignup"," is flow-driven\nin the framework. The flat-CRUD cases (",[982,1063,1064],{},"\u002Fusers\u002Fme",", ",[982,1067,1068],{},"\u002Fadmin\u002Fusers\u002F*",")\nstay Go-handled.",[992,1071,1073],{"id":1072},"components","Components",[1075,1076,1081],"pre",{"className":1077,"code":1079,"language":1080},[1078],"language-text","chi router\n  └── flowexec dispatcher middleware  (registered ahead of normal routes)\n       │\n       ├── matched (method, path)? → run flow synchronously,\n       │                              write output as JSON response\n       │\n       └── no match? → fall through to next handler (regular Go routes)\n","text",[982,1082,1079],{"__ignoreMap":1083},"",[997,1085,1086,1099],{},[1000,1087,1088],{},[1003,1089,1090,1093,1096],{},[1006,1091,1092],{},"Piece",[1006,1094,1095],{},"Where",[1006,1097,1098],{},"Purpose",[1013,1100,1101,1116,1137,1155,1169],{},[1003,1102,1103,1108,1113],{},[1018,1104,1105,1107],{},[982,1106,984],{}," source node",[1018,1109,1110],{},[982,1111,1112],{},"go-flowdsl\u002Fnodes\u002Fmodule.yaml",[1018,1114,1115],{},"Declarative spec — path, method, schemas, auth flag, summary",[1003,1117,1118,1121,1126],{},[1018,1119,1120],{},"Dispatcher",[1018,1122,1123],{},[982,1124,1125],{},"go-flowdsl\u002Fflowexec\u002Fmodule\u002Frouter\u002F",[1018,1127,1128,1129,1132,1133,1136],{},"Route registry + chi middleware. ",[982,1130,1131],{},"Bind"," on flow publish, ",[982,1134,1135],{},"Unbind"," on unpublish",[1003,1138,1139,1144,1149],{},[1018,1140,1141],{},[982,1142,1143],{},"DynamicRoutesProvider",[1018,1145,1146],{},[982,1147,1148],{},"go-framework\u002Fmodules\u002F",[1018,1150,1151,1152],{},"Reusable contract. Any module exposing dynamic routes implements it; openapi merges them into ",[982,1153,1154],{},"\u002Fopenapi.json",[1003,1156,1157,1162,1166],{},[1018,1158,1159],{},[982,1160,1161],{},"DynamicChannelsProvider",[1018,1163,1164],{},[982,1165,1148],{},[1018,1167,1168],{},"Same idea for AsyncAPI events emitted\u002Fconsumed by flows",[1003,1170,1171,1178,1183],{},[1018,1172,1173,1174,1177],{},"Per-module ",[982,1175,1176],{},"flowtemplates\u002F"," package",[1018,1179,1180],{},[982,1181,1182],{},"\u003Cmodule>\u002Fflowtemplates\u002F",[1018,1184,1185],{},"Starter compositions + auto-publish-on-startup",[992,1187,1189],{"id":1188},"the-http-endpoint-node","The http-endpoint node",[1075,1191,1195],{"className":1192,"code":1193,"language":1194,"meta":1083,"style":1083},"language-yaml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","- id: http\n  kind: source\n  ref: redelay\u002Fhttp-endpoint\n  config:\n    path: \u002Fapi\u002Fv1\u002Fusers\u002Fsignup     # exact-match path\n    method: POST                   # GET|POST|PUT|PATCH|DELETE\n    success_status: 201            # default 200; per-call override via output.status_code\n    auth_required: false           # see Auth gate below\n    summary: Public signup         # → openapi summary\n    description: …                 # → openapi description\n    tags: [users, public]          # → openapi tags\n","yaml",[982,1196,1197,1216,1226,1236,1244,1258,1271,1285,1299,1312,1325],{"__ignoreMap":1083},[1198,1199,1201,1205,1209,1212],"span",{"class":1200,"line":10},"line",[1198,1202,1204],{"class":1203},"sMK4o","-",[1198,1206,1208],{"class":1207},"swJcz"," id",[1198,1210,1211],{"class":1203},":",[1198,1213,1215],{"class":1214},"sfazB"," http\n",[1198,1217,1218,1221,1223],{"class":1200,"line":16},[1198,1219,1220],{"class":1207},"  kind",[1198,1222,1211],{"class":1203},[1198,1224,1225],{"class":1214}," source\n",[1198,1227,1228,1231,1233],{"class":1200,"line":22},[1198,1229,1230],{"class":1207},"  ref",[1198,1232,1211],{"class":1203},[1198,1234,1235],{"class":1214}," redelay\u002Fhttp-endpoint\n",[1198,1237,1238,1241],{"class":1200,"line":51},[1198,1239,1240],{"class":1207},"  config",[1198,1242,1243],{"class":1203},":\n",[1198,1245,1246,1249,1251,1254],{"class":1200,"line":57},[1198,1247,1248],{"class":1207},"    path",[1198,1250,1211],{"class":1203},[1198,1252,1253],{"class":1214}," \u002Fapi\u002Fv1\u002Fusers\u002Fsignup",[1198,1255,1257],{"class":1256},"sHwdD","     # exact-match path\n",[1198,1259,1260,1263,1265,1268],{"class":1200,"line":102},[1198,1261,1262],{"class":1207},"    method",[1198,1264,1211],{"class":1203},[1198,1266,1267],{"class":1214}," POST",[1198,1269,1270],{"class":1256},"                   # GET|POST|PUT|PATCH|DELETE\n",[1198,1272,1273,1276,1278,1282],{"class":1200,"line":108},[1198,1274,1275],{"class":1207},"    success_status",[1198,1277,1211],{"class":1203},[1198,1279,1281],{"class":1280},"sbssI"," 201",[1198,1283,1284],{"class":1256},"            # default 200; per-call override via output.status_code\n",[1198,1286,1287,1290,1292,1296],{"class":1200,"line":114},[1198,1288,1289],{"class":1207},"    auth_required",[1198,1291,1211],{"class":1203},[1198,1293,1295],{"class":1294},"sfNiH"," false",[1198,1297,1298],{"class":1256},"           # see Auth gate below\n",[1198,1300,1301,1304,1306,1309],{"class":1200,"line":120},[1198,1302,1303],{"class":1207},"    summary",[1198,1305,1211],{"class":1203},[1198,1307,1308],{"class":1214}," Public signup",[1198,1310,1311],{"class":1256},"         # → openapi summary\n",[1198,1313,1314,1317,1319,1322],{"class":1200,"line":181},[1198,1315,1316],{"class":1207},"    description",[1198,1318,1211],{"class":1203},[1198,1320,1321],{"class":1214}," …",[1198,1323,1324],{"class":1256},"                 # → openapi description\n",[1198,1326,1327,1330,1332,1335,1338,1341,1344,1347],{"class":1200,"line":186},[1198,1328,1329],{"class":1207},"    tags",[1198,1331,1211],{"class":1203},[1198,1333,1334],{"class":1203}," [",[1198,1336,1337],{"class":1214},"users",[1198,1339,1340],{"class":1203},",",[1198,1342,1343],{"class":1214}," public",[1198,1345,1346],{"class":1203},"]",[1198,1348,1349],{"class":1256},"          # → openapi tags\n",[978,1351,1352,1356,1357,1360],{},[1353,1354,1355],"strong",{},"Routing + spec metadata only."," The node carries the route\ncoordinates, the auth gate, and the documentation strings — nothing\nschema-shaped. Request and response bodies are typed via ",[1353,1358,1359],{},"packet\nrefs on edges"," (see next section), not via inline JSON Schema on\nthis node.",[978,1362,1363,1366,1367,1370,1371,1376,1377,1380,1381,1384],{},[1353,1364,1365],{},"Output port:"," ",[982,1368,1369],{},"request"," — emits the merged-input map described\nunder ",[1372,1373,1375],"a",{"href":1374},"#flow-input-shape","Flow input shape"," below. Downstream nodes\nread body fields directly (",[982,1378,1379],{},"{{.email}}","); request metadata lives at\n",[982,1382,1383],{},"{{._meta.*}}",".",[978,1386,1387,1388,1391],{},"The node is purely declarative. The dispatcher does the actual\nHTTP↔flow translation; the node's settings are read at flow publish\ntime to populate the ",[982,1389,1390],{},"Binding"," record.",[992,1393,1395],{"id":1394},"packet-based-schema-model","Packet-based schema model",[978,1397,1398,1399,1402,1403,1406,1407,1406,1410,1413],{},"Every flow that's mounted as an HTTP endpoint declares its\nrequest\u002Fresponse shapes as ",[1353,1400,1401],{},"packets"," — first-class document-level\ntype definitions referenced from edges. This is the same shape used\nby every other flow in the system (the assistant template's\n",[982,1404,1405],{},"ChatRequest"," \u002F ",[982,1408,1409],{},"ChatResponse",[982,1411,1412],{},"GuardRejection"," are packets); HTTP\nflows are not special.",[1415,1416,1418],"h3",{"id":1417},"authoring-ir-json-template","Authoring (IR JSON template)",[1075,1420,1424],{"className":1421,"code":1422,"language":1423,"meta":1083,"style":1083},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"id\": \"users-registration-basic\",\n  \"nodes\": [\n    {\"id\": \"http\",   \"kind\": \"start\",    \"action_ref\": \"redelay\u002Fhttp-endpoint\",\n     \"config\": { \"path\": \"\u002Fapi\u002Fv1\u002Fusers\u002Fsignup\", \"method\": \"POST\", \"success_status\": 201 }},\n    {\"id\": \"create\", \"kind\": \"action\",   \"action_ref\": \"redelay\u002Fusers-create-user\"},\n    {\"id\": \"end\",    \"kind\": \"terminal\"}\n  ],\n  \"edges\": [\n    {\"from\": \"http\",   \"to\": \"create\", \"packet\": \"#\u002Fcomponents\u002Fpackets\u002FUserCreateInput\"},\n    {\"from\": \"create\", \"to\": \"end\",    \"packet\": \"#\u002Fcomponents\u002Fpackets\u002FUserResponse\"}\n  ],\n  \"meta\": {\n    \"packets\": {\n      \"UserCreateInput\": { \"$ref\": \"openapi:default#\u002Fcomponents\u002Fschemas\u002FUserCreateInput\" },\n      \"UserResponse\":    { \"$ref\": \"openapi:default#\u002Fcomponents\u002Fschemas\u002FUserResponse\" }\n    }\n  }\n}\n","json",[982,1425,1426,1431,1456,1469,1529,1594,1650,1689,1694,1707,1763,1816,1820,1834,1846,1879,1910,1915,1920],{"__ignoreMap":1083},[1198,1427,1428],{"class":1200,"line":10},[1198,1429,1430],{"class":1203},"{\n",[1198,1432,1433,1436,1440,1443,1445,1448,1451,1453],{"class":1200,"line":16},[1198,1434,1435],{"class":1203},"  \"",[1198,1437,1439],{"class":1438},"spNyl","id",[1198,1441,1442],{"class":1203},"\"",[1198,1444,1211],{"class":1203},[1198,1446,1447],{"class":1203}," \"",[1198,1449,1450],{"class":1214},"users-registration-basic",[1198,1452,1442],{"class":1203},[1198,1454,1455],{"class":1203},",\n",[1198,1457,1458,1460,1462,1464,1466],{"class":1200,"line":22},[1198,1459,1435],{"class":1203},[1198,1461,989],{"class":1438},[1198,1463,1442],{"class":1203},[1198,1465,1211],{"class":1203},[1198,1467,1468],{"class":1203}," [\n",[1198,1470,1471,1474,1476,1479,1481,1483,1485,1488,1490,1492,1495,1498,1500,1502,1504,1507,1509,1511,1514,1517,1519,1521,1523,1525,1527],{"class":1200,"line":51},[1198,1472,1473],{"class":1203},"    {",[1198,1475,1442],{"class":1203},[1198,1477,1439],{"class":1478},"sBMFI",[1198,1480,1442],{"class":1203},[1198,1482,1211],{"class":1203},[1198,1484,1447],{"class":1203},[1198,1486,1487],{"class":1214},"http",[1198,1489,1442],{"class":1203},[1198,1491,1340],{"class":1203},[1198,1493,1494],{"class":1203},"   \"",[1198,1496,1497],{"class":1478},"kind",[1198,1499,1442],{"class":1203},[1198,1501,1211],{"class":1203},[1198,1503,1447],{"class":1203},[1198,1505,1506],{"class":1214},"start",[1198,1508,1442],{"class":1203},[1198,1510,1340],{"class":1203},[1198,1512,1513],{"class":1203},"    \"",[1198,1515,1516],{"class":1478},"action_ref",[1198,1518,1442],{"class":1203},[1198,1520,1211],{"class":1203},[1198,1522,1447],{"class":1203},[1198,1524,984],{"class":1214},[1198,1526,1442],{"class":1203},[1198,1528,1455],{"class":1203},[1198,1530,1531,1534,1537,1539,1541,1544,1546,1549,1551,1553,1555,1558,1560,1562,1564,1567,1569,1571,1573,1576,1578,1580,1582,1585,1587,1589,1591],{"class":1200,"line":57},[1198,1532,1533],{"class":1203},"     \"",[1198,1535,1536],{"class":1478},"config",[1198,1538,1442],{"class":1203},[1198,1540,1211],{"class":1203},[1198,1542,1543],{"class":1203}," {",[1198,1545,1447],{"class":1203},[1198,1547,1548],{"class":1280},"path",[1198,1550,1442],{"class":1203},[1198,1552,1211],{"class":1203},[1198,1554,1447],{"class":1203},[1198,1556,1557],{"class":1214},"\u002Fapi\u002Fv1\u002Fusers\u002Fsignup",[1198,1559,1442],{"class":1203},[1198,1561,1340],{"class":1203},[1198,1563,1447],{"class":1203},[1198,1565,1566],{"class":1280},"method",[1198,1568,1442],{"class":1203},[1198,1570,1211],{"class":1203},[1198,1572,1447],{"class":1203},[1198,1574,1575],{"class":1214},"POST",[1198,1577,1442],{"class":1203},[1198,1579,1340],{"class":1203},[1198,1581,1447],{"class":1203},[1198,1583,1584],{"class":1280},"success_status",[1198,1586,1442],{"class":1203},[1198,1588,1211],{"class":1203},[1198,1590,1281],{"class":1280},[1198,1592,1593],{"class":1203}," }},\n",[1198,1595,1596,1598,1600,1602,1604,1606,1608,1611,1613,1615,1617,1619,1621,1623,1625,1628,1630,1632,1634,1636,1638,1640,1642,1645,1647],{"class":1200,"line":102},[1198,1597,1473],{"class":1203},[1198,1599,1442],{"class":1203},[1198,1601,1439],{"class":1478},[1198,1603,1442],{"class":1203},[1198,1605,1211],{"class":1203},[1198,1607,1447],{"class":1203},[1198,1609,1610],{"class":1214},"create",[1198,1612,1442],{"class":1203},[1198,1614,1340],{"class":1203},[1198,1616,1447],{"class":1203},[1198,1618,1497],{"class":1478},[1198,1620,1442],{"class":1203},[1198,1622,1211],{"class":1203},[1198,1624,1447],{"class":1203},[1198,1626,1627],{"class":1214},"action",[1198,1629,1442],{"class":1203},[1198,1631,1340],{"class":1203},[1198,1633,1494],{"class":1203},[1198,1635,1516],{"class":1478},[1198,1637,1442],{"class":1203},[1198,1639,1211],{"class":1203},[1198,1641,1447],{"class":1203},[1198,1643,1644],{"class":1214},"redelay\u002Fusers-create-user",[1198,1646,1442],{"class":1203},[1198,1648,1649],{"class":1203},"},\n",[1198,1651,1652,1654,1656,1658,1660,1662,1664,1667,1669,1671,1673,1675,1677,1679,1681,1684,1686],{"class":1200,"line":108},[1198,1653,1473],{"class":1203},[1198,1655,1442],{"class":1203},[1198,1657,1439],{"class":1478},[1198,1659,1442],{"class":1203},[1198,1661,1211],{"class":1203},[1198,1663,1447],{"class":1203},[1198,1665,1666],{"class":1214},"end",[1198,1668,1442],{"class":1203},[1198,1670,1340],{"class":1203},[1198,1672,1513],{"class":1203},[1198,1674,1497],{"class":1478},[1198,1676,1442],{"class":1203},[1198,1678,1211],{"class":1203},[1198,1680,1447],{"class":1203},[1198,1682,1683],{"class":1214},"terminal",[1198,1685,1442],{"class":1203},[1198,1687,1688],{"class":1203},"}\n",[1198,1690,1691],{"class":1200,"line":114},[1198,1692,1693],{"class":1203},"  ],\n",[1198,1695,1696,1698,1701,1703,1705],{"class":1200,"line":120},[1198,1697,1435],{"class":1203},[1198,1699,1700],{"class":1438},"edges",[1198,1702,1442],{"class":1203},[1198,1704,1211],{"class":1203},[1198,1706,1468],{"class":1203},[1198,1708,1709,1711,1713,1716,1718,1720,1722,1724,1726,1728,1730,1733,1735,1737,1739,1741,1743,1745,1747,1750,1752,1754,1756,1759,1761],{"class":1200,"line":181},[1198,1710,1473],{"class":1203},[1198,1712,1442],{"class":1203},[1198,1714,1715],{"class":1478},"from",[1198,1717,1442],{"class":1203},[1198,1719,1211],{"class":1203},[1198,1721,1447],{"class":1203},[1198,1723,1487],{"class":1214},[1198,1725,1442],{"class":1203},[1198,1727,1340],{"class":1203},[1198,1729,1494],{"class":1203},[1198,1731,1732],{"class":1478},"to",[1198,1734,1442],{"class":1203},[1198,1736,1211],{"class":1203},[1198,1738,1447],{"class":1203},[1198,1740,1610],{"class":1214},[1198,1742,1442],{"class":1203},[1198,1744,1340],{"class":1203},[1198,1746,1447],{"class":1203},[1198,1748,1749],{"class":1478},"packet",[1198,1751,1442],{"class":1203},[1198,1753,1211],{"class":1203},[1198,1755,1447],{"class":1203},[1198,1757,1758],{"class":1214},"#\u002Fcomponents\u002Fpackets\u002FUserCreateInput",[1198,1760,1442],{"class":1203},[1198,1762,1649],{"class":1203},[1198,1764,1765,1767,1769,1771,1773,1775,1777,1779,1781,1783,1785,1787,1789,1791,1793,1795,1797,1799,1801,1803,1805,1807,1809,1812,1814],{"class":1200,"line":186},[1198,1766,1473],{"class":1203},[1198,1768,1442],{"class":1203},[1198,1770,1715],{"class":1478},[1198,1772,1442],{"class":1203},[1198,1774,1211],{"class":1203},[1198,1776,1447],{"class":1203},[1198,1778,1610],{"class":1214},[1198,1780,1442],{"class":1203},[1198,1782,1340],{"class":1203},[1198,1784,1447],{"class":1203},[1198,1786,1732],{"class":1478},[1198,1788,1442],{"class":1203},[1198,1790,1211],{"class":1203},[1198,1792,1447],{"class":1203},[1198,1794,1666],{"class":1214},[1198,1796,1442],{"class":1203},[1198,1798,1340],{"class":1203},[1198,1800,1513],{"class":1203},[1198,1802,1749],{"class":1478},[1198,1804,1442],{"class":1203},[1198,1806,1211],{"class":1203},[1198,1808,1447],{"class":1203},[1198,1810,1811],{"class":1214},"#\u002Fcomponents\u002Fpackets\u002FUserResponse",[1198,1813,1442],{"class":1203},[1198,1815,1688],{"class":1203},[1198,1817,1818],{"class":1200,"line":191},[1198,1819,1693],{"class":1203},[1198,1821,1822,1824,1827,1829,1831],{"class":1200,"line":197},[1198,1823,1435],{"class":1203},[1198,1825,1826],{"class":1438},"meta",[1198,1828,1442],{"class":1203},[1198,1830,1211],{"class":1203},[1198,1832,1833],{"class":1203}," {\n",[1198,1835,1836,1838,1840,1842,1844],{"class":1200,"line":203},[1198,1837,1513],{"class":1203},[1198,1839,1401],{"class":1478},[1198,1841,1442],{"class":1203},[1198,1843,1211],{"class":1203},[1198,1845,1833],{"class":1203},[1198,1847,1848,1851,1854,1856,1858,1860,1862,1865,1867,1869,1871,1874,1876],{"class":1200,"line":214},[1198,1849,1850],{"class":1203},"      \"",[1198,1852,1853],{"class":1280},"UserCreateInput",[1198,1855,1442],{"class":1203},[1198,1857,1211],{"class":1203},[1198,1859,1543],{"class":1203},[1198,1861,1447],{"class":1203},[1198,1863,1864],{"class":1207},"$ref",[1198,1866,1442],{"class":1203},[1198,1868,1211],{"class":1203},[1198,1870,1447],{"class":1203},[1198,1872,1873],{"class":1214},"openapi:default#\u002Fcomponents\u002Fschemas\u002FUserCreateInput",[1198,1875,1442],{"class":1203},[1198,1877,1878],{"class":1203}," },\n",[1198,1880,1881,1883,1886,1888,1890,1892,1894,1896,1898,1900,1902,1905,1907],{"class":1200,"line":223},[1198,1882,1850],{"class":1203},[1198,1884,1885],{"class":1280},"UserResponse",[1198,1887,1442],{"class":1203},[1198,1889,1211],{"class":1203},[1198,1891,1473],{"class":1203},[1198,1893,1447],{"class":1203},[1198,1895,1864],{"class":1207},[1198,1897,1442],{"class":1203},[1198,1899,1211],{"class":1203},[1198,1901,1447],{"class":1203},[1198,1903,1904],{"class":1214},"openapi:default#\u002Fcomponents\u002Fschemas\u002FUserResponse",[1198,1906,1442],{"class":1203},[1198,1908,1909],{"class":1203}," }\n",[1198,1911,1912],{"class":1200,"line":229},[1198,1913,1914],{"class":1203},"    }\n",[1198,1916,1917],{"class":1200,"line":234},[1198,1918,1919],{"class":1203},"  }\n",[1198,1921,1922],{"class":1200,"line":240},[1198,1923,1688],{"class":1203},[978,1925,1926],{},"Three rules:",[1928,1929,1930,1947,1956],"ol",{},[1931,1932,1933,1936,1937,1940,1941,1943,1944,1946],"li",{},[1353,1934,1935],{},"Define packets once"," at ",[982,1938,1939],{},"meta.packets"," (workflow-level). Use a\n",[982,1942,1864],{}," to the canonical Go-struct schema published in\n",[982,1945,1154],{}," so the type stays single-sourced — never duplicate\nJSON Schema in the template.",[1931,1948,1949,1952,1953,1384],{},[1353,1950,1951],{},"Reference packets on edges"," via ",[982,1954,1955],{},"packet: \"#\u002Fcomponents\u002Fpackets\u002F\u003CName>\"",[1931,1957,1958,1964,1965,1967,1968,1971],{},[1353,1959,1960,1961,1963],{},"Add an explicit ",[982,1962,1683],{}," node"," (typically named ",[982,1966,1666],{},") so the\nresponse packet has somewhere to attach. The dispatcher reads the\npacket on the ",[987,1969,1970],{},"incoming edge to a terminal"," as the response schema.",[978,1973,1974,1975,1978,1979,1981],{},"Authors who want to skip the named-packet declaration can still write\n",[982,1976,1977],{},"packet: \"openapi:default#\u002Fcomponents\u002Fschemas\u002F\u003CName>\""," directly on\nthe edge — the dispatcher passes external refs through unchanged.\nNamed packets are preferred when the same type is reused on multiple\nedges (every assistant-template edge that carries a ",[982,1980,1405],{},").",[1415,1983,1985],{"id":1984},"schema-lifecycle","Schema lifecycle",[1075,1987,1990],{"className":1988,"code":1989,"language":1080},[1078],"template (IR JSON)                         users.OpenAPISchemas() {…}    Go struct\n  │  meta.packets.UserCreateInput              │   UserCreateInput\n  │   = {$ref: \"openapi:default#\u002F…\"}           │\n  ▼                                            ▼\nflow document in MongoDB                  \u002Fopenapi.json#\u002Fcomponents\u002Fschemas\u002FUserCreateInput\n  │                                            │  (full reflected schema)\n  ▼                                            │\n┌───────────────────────────────────────┐      │\n│ ExtractBinding (router\u002Fextract.go)    │      │\n│   - walks edges                       │      │\n│   - resolves packet refs              │      │\n│   - strips `openapi:default#` prefix  │      │\n│   - emits in-document refs            │      │\n└──────────────┬─────────────┬──────────┘      │\n               │             │                  │\n               ▼             ▼                  │\nDynamicRouteDescriptor ──────────────────────► \u002Fopenapi.json\n{ RequestSchema: {$ref: \"#\u002Fcomponents\u002Fschemas\u002FUserCreateInput\"} }\n                                                ▲\n                                                │\n                  Scalar \u002F Swagger UI ──────────┘ resolves locally\n\nversionAsSpec (admin\u002Fhandler.go) ?format=spec\n   - calls openapi.GenerateSpec to fetch live components.schemas\n   - inlines each `openapi:default#` packet ref with the resolved schema\n   ─► Studio \u002Fflowdsl receives self-contained {type, properties, required}\n",[982,1991,1989],{"__ignoreMap":1083},[978,1993,1994],{},"The same packet ref serves three consumers, each in the form they\nexpect:",[997,1996,1997,2010],{},[1000,1998,1999],{},[1003,2000,2001,2004,2007],{},[1006,2002,2003],{},"Consumer",[1006,2005,2006],{},"Form",[1006,2008,2009],{},"Why",[1013,2011,2012,2025,2040],{},[1003,2013,2014,2017,2022],{},[1018,2015,2016],{},"Flow document (in DB)",[1018,2018,2019],{},[982,2020,2021],{},"{$ref: \"openapi:default#\u002F…\"}",[1018,2023,2024],{},"Single source of truth in Go types; templates stay thin",[1003,2026,2027,2032,2037],{},[1018,2028,2029,2031],{},[982,2030,1154],{}," request\u002Fresponse bodies",[1018,2033,2034],{},[982,2035,2036],{},"{$ref: \"#\u002Fcomponents\u002Fschemas\u002FX\"}",[1018,2038,2039],{},"Standard OpenAPI in-document refs; Scalar \u002F Swagger UI \u002F SDK gen all resolve locally",[1003,2041,2042,2048,2054],{},[1018,2043,2044,2047],{},[982,2045,2046],{},"\u002Fapi\u002Fv1\u002Fflows\u002F{id}\u002Fversions\u002F{vid}?format=spec"," (Studio)",[1018,2049,2050,2053],{},[982,2051,2052],{},"{type, properties, required, …}"," (fully inlined)",[1018,2055,2056],{},"Studio's PacketsPanel renders fields directly; \"0 fields\" gone",[1415,2058,2060,2061,2064],{"id":2059},"the-openapidefault-namespace","The ",[982,2062,2063],{},"openapi:default#"," namespace",[978,2066,2067,2069,2070,2073,2074,1065,2077,2080,2081,2083,2084,2087,2088,2091,2092,1384],{},[982,2068,1873],{}," is a ",[1353,2071,2072],{},"Redelay\u002F\nStudio-internal namespace"," used so modspec UIs can disambiguate\nmultiple loaded specs (",[982,2075,2076],{},"openapi:default",[982,2078,2079],{},"asyncapi:default",", future\nnamed specs). The dispatcher strips this prefix when emitting refs\ninto ",[982,2082,1154],{}," — leaving it in would produce\n",[982,2085,2086],{},"\"Could not resolve reference: Failed to fetch\""," in any\nstandards-compliant tool. See ",[982,2089,2090],{},"stripSpecNamespace()"," in\n",[982,2093,2094],{},"go-flowdsl\u002Fflowexec\u002Fmodule\u002Frouter\u002Fextract.go",[1415,2096,2098,2099],{"id":2097},"schema-source-schemasprovider","Schema source: ",[982,2100,2101],{},"SchemasProvider",[978,2103,2104,2105,2108,2109,1211],{},"Modules whose Go types are referenced by flow packets must expose\nthose types so they end up in ",[982,2106,2107],{},"\u002Fopenapi.json#\u002Fcomponents\u002Fschemas",".\nImplement ",[982,2110,2111],{},"modules.SchemasProvider",[1075,2113,2117],{"className":2114,"code":2115,"language":2116,"meta":1083,"style":1083},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","func (m *Module) OpenAPISchemas() []any {\n    return []any{\n        &UserCreateInput{},\n        &UserUpdateInput{},\n        &UserResponse{},\n        &UserListResponse{},\n    }\n}\n","go",[982,2118,2119,2124,2129,2134,2139,2144,2149,2153],{"__ignoreMap":1083},[1198,2120,2121],{"class":1200,"line":10},[1198,2122,2123],{},"func (m *Module) OpenAPISchemas() []any {\n",[1198,2125,2126],{"class":1200,"line":16},[1198,2127,2128],{},"    return []any{\n",[1198,2130,2131],{"class":1200,"line":22},[1198,2132,2133],{},"        &UserCreateInput{},\n",[1198,2135,2136],{"class":1200,"line":51},[1198,2137,2138],{},"        &UserUpdateInput{},\n",[1198,2140,2141],{"class":1200,"line":57},[1198,2142,2143],{},"        &UserResponse{},\n",[1198,2145,2146],{"class":1200,"line":102},[1198,2147,2148],{},"        &UserListResponse{},\n",[1198,2150,2151],{"class":1200,"line":108},[1198,2152,1914],{},[1198,2154,2155],{"class":1200,"line":114},[1198,2156,1688],{},[978,2158,2159,2160,2163,2164,1406,2167,2170,2171,2174,2175,2177,2178,2180,2181,2184],{},"Each value is reflected via the same ",[982,2161,2162],{},"openapi.SchemaRegistry"," path\nthat ",[982,2165,2166],{},"Body()",[982,2168,2169],{},"Response()"," use; the schema lands in\n",[982,2172,2173],{},"components\u002Fschemas"," keyed by the struct name. Without this contract\na flow whose packet refs ",[982,2176,1853],{}," would render\n\"Schema not found in loaded specs\" in Studio and 404 the schema in\n",[982,2179,1154],{},". Modules that already declare types via Go HTTP\nhandlers (Body\u002FResponse reflection) don't need to duplicate them\nhere — only types referenced ",[987,2182,2183],{},"only"," by FlowDSL nodes \u002F packets do.",[992,2186,1375],{"id":2187},"flow-input-shape",[978,2189,2190,2191,1211],{},"The dispatcher prepares the workflow's start payload as a single\n",[982,2192,2193],{},"map[string]any",[1075,2195,2197],{"className":1421,"code":2196,"language":1423,"meta":1083,"style":1083},"{\n  \"\u003Cevery JSON body field at top level>\": \"...\",\n  \"_meta\": {\n    \"method\":  \"POST\",\n    \"path\":    \"\u002Fapi\u002Fv1\u002Fusers\u002Fsignup\",\n    \"query\":   { \"ref\": \"ad\" },\n    \"headers\": { \"X-Whatever\": \"...\" },\n    \"remote\":  \"1.2.3.4:5678\"\n  }\n}\n",[982,2198,2199,2203,2223,2236,2254,2272,2304,2334,2353,2357],{"__ignoreMap":1083},[1198,2200,2201],{"class":1200,"line":10},[1198,2202,1430],{"class":1203},[1198,2204,2205,2207,2210,2212,2214,2216,2219,2221],{"class":1200,"line":16},[1198,2206,1435],{"class":1203},[1198,2208,2209],{"class":1438},"\u003Cevery JSON body field at top level>",[1198,2211,1442],{"class":1203},[1198,2213,1211],{"class":1203},[1198,2215,1447],{"class":1203},[1198,2217,2218],{"class":1214},"...",[1198,2220,1442],{"class":1203},[1198,2222,1455],{"class":1203},[1198,2224,2225,2227,2230,2232,2234],{"class":1200,"line":22},[1198,2226,1435],{"class":1203},[1198,2228,2229],{"class":1438},"_meta",[1198,2231,1442],{"class":1203},[1198,2233,1211],{"class":1203},[1198,2235,1833],{"class":1203},[1198,2237,2238,2240,2242,2244,2246,2248,2250,2252],{"class":1200,"line":51},[1198,2239,1513],{"class":1203},[1198,2241,1566],{"class":1478},[1198,2243,1442],{"class":1203},[1198,2245,1211],{"class":1203},[1198,2247,1435],{"class":1203},[1198,2249,1575],{"class":1214},[1198,2251,1442],{"class":1203},[1198,2253,1455],{"class":1203},[1198,2255,2256,2258,2260,2262,2264,2266,2268,2270],{"class":1200,"line":57},[1198,2257,1513],{"class":1203},[1198,2259,1548],{"class":1478},[1198,2261,1442],{"class":1203},[1198,2263,1211],{"class":1203},[1198,2265,1513],{"class":1203},[1198,2267,1557],{"class":1214},[1198,2269,1442],{"class":1203},[1198,2271,1455],{"class":1203},[1198,2273,2274,2276,2279,2281,2283,2286,2288,2291,2293,2295,2297,2300,2302],{"class":1200,"line":102},[1198,2275,1513],{"class":1203},[1198,2277,2278],{"class":1478},"query",[1198,2280,1442],{"class":1203},[1198,2282,1211],{"class":1203},[1198,2284,2285],{"class":1203},"   {",[1198,2287,1447],{"class":1203},[1198,2289,2290],{"class":1280},"ref",[1198,2292,1442],{"class":1203},[1198,2294,1211],{"class":1203},[1198,2296,1447],{"class":1203},[1198,2298,2299],{"class":1214},"ad",[1198,2301,1442],{"class":1203},[1198,2303,1878],{"class":1203},[1198,2305,2306,2308,2311,2313,2315,2317,2319,2322,2324,2326,2328,2330,2332],{"class":1200,"line":108},[1198,2307,1513],{"class":1203},[1198,2309,2310],{"class":1478},"headers",[1198,2312,1442],{"class":1203},[1198,2314,1211],{"class":1203},[1198,2316,1543],{"class":1203},[1198,2318,1447],{"class":1203},[1198,2320,2321],{"class":1280},"X-Whatever",[1198,2323,1442],{"class":1203},[1198,2325,1211],{"class":1203},[1198,2327,1447],{"class":1203},[1198,2329,2218],{"class":1214},[1198,2331,1442],{"class":1203},[1198,2333,1878],{"class":1203},[1198,2335,2336,2338,2341,2343,2345,2347,2350],{"class":1200,"line":114},[1198,2337,1513],{"class":1203},[1198,2339,2340],{"class":1478},"remote",[1198,2342,1442],{"class":1203},[1198,2344,1211],{"class":1203},[1198,2346,1435],{"class":1203},[1198,2348,2349],{"class":1214},"1.2.3.4:5678",[1198,2351,2352],{"class":1203},"\"\n",[1198,2354,2355],{"class":1200,"line":120},[1198,2356,1919],{"class":1203},[1198,2358,2359],{"class":1200,"line":181},[1198,2360,1688],{"class":1203},[978,2362,2363,2366,2367,2369,2370,2373],{},[1353,2364,2365],{},"Body merging."," When the request body is JSON, every top-level field\nis merged into the input root so flow templates can write\n",[982,2368,1379],{}," instead of ",[982,2371,2372],{},"{{.body.email}}",". Non-JSON bodies are not\ninspected (forms \u002F multipart \u002F binary not supported in v1).",[978,2375,2376,1366,2379,2382,2383,2386,2387,2390,2391,1384],{},[1353,2377,2378],{},"Header redaction.",[982,2380,2381],{},"Authorization"," and ",[982,2384,2385],{},"Cookie"," are stripped from\n",[982,2388,2389],{},"_meta.headers"," so flow logs and node-output payloads (which can be\ninspected via the run-events SSE stream) never contain credentials.\nFlows that need to read the bearer token must use a dedicated auth\nnode instead of pulling it from ",[982,2392,2229],{},[978,2394,2395,2398,2399,2402],{},[1353,2396,2397],{},"Body cap."," Hard 1 MiB limit on the request body. Larger requests\nreturn 413 before the flow runs. Bump per-route via a future\n",[982,2400,2401],{},"max_body_bytes"," node setting (not in v1).",[992,2404,2406],{"id":2405},"output-convention","Output convention",[978,2408,2409],{},"The flow's terminal node populates the workflow output map. The\ndispatcher recognises four well-known keys (all optional):",[997,2411,2412,2424],{},[1000,2413,2414],{},[1003,2415,2416,2419,2422],{},[1006,2417,2418],{},"Key",[1006,2420,2421],{},"Type",[1006,2423,1098],{},[1013,2425,2426,2442,2467,2484],{},[1003,2427,2428,2433,2436],{},[1018,2429,2430],{},[982,2431,2432],{},"status_code",[1018,2434,2435],{},"int",[1018,2437,2438,2439,2441],{},"HTTP status. Defaults to the node's ",[982,2440,1584],{}," (201 for signup-style endpoints).",[1003,2443,2444,2449,2452],{},[1018,2445,2446],{},[982,2447,2448],{},"body",[1018,2450,2451],{},"any",[1018,2453,2454,2455,1366,2458,2460,2461,2460,2463,2466],{},"JSON-serialisable response body. When absent, every key in the output map ",[987,2456,2457],{},"except",[982,2459,2432],{},"\u002F",[982,2462,2310],{},[982,2464,2465],{},"error"," becomes the body.",[1003,2468,2469,2473,2478],{},[1018,2470,2471],{},[982,2472,2310],{},[1018,2474,2475],{},[982,2476,2477],{},"map[string]string",[1018,2479,2480,2481,1384],{},"Extra response headers, applied before ",[982,2482,2483],{},"WriteHeader",[1003,2485,2486,2490,2493],{},[1018,2487,2488],{},[982,2489,2465],{},[1018,2491,2492],{},"string",[1018,2494,2495,2496,2498,2499,1384],{},"When non-empty AND ",[982,2497,2432],{}," is unset, the dispatcher returns 400 with ",[982,2500,2501],{},"{\"error\":..., \"message\":\u003Cvalue>}",[978,2503,2504,2505,2507],{},"This is enough to express the canonical signup outcomes without a\nseparate \"respond\" node. Flow authors who want a structured response\njust set ",[982,2506,2448],{}," directly; minimalist authors dump fields and accept\nthe 201 default.",[978,2509,2510,2513,2514,2517],{},[1353,2511,2512],{},"Run-failure mapping."," If the flow itself fails (handler returns\nnon-nil error, no terminal node fires, executor times out), the\ndispatcher returns 500 with the flowexec sink owning the actual error\ndetail. The HTTP response body is ",[982,2515,2516],{},"{\"error\":\"Internal Server Error\",\"message\":\"flow execution failed\"}","\n— the caller does not see the stack trace; ops triages via the run\nlog in Studio.",[992,2519,2521],{"id":2520},"auth-gate","Auth gate",[978,2523,2524,2527,2528,2530,2531,2534,2535,2538,2539,2542,2543,1384],{},[982,2525,2526],{},"auth_required: true"," on the http-endpoint node makes the dispatcher\nreject requests that arrive without an ",[982,2529,2381],{}," header (returns\n401, flow does not run, ",[982,2532,2533],{},"Runs()"," counter does not increment). The\ndispatcher itself does ",[1353,2536,2537],{},"not"," validate the JWT — it trusts the\nupstream ",[982,2540,2541],{},"auth.AuthMiddleware"," (registered ahead of the dispatcher in\nthe chain) to populate request context with claims when the token is\nvalid. Flows that need claims-aware logic read them from a dedicated\nauth-claims node, not from ",[982,2544,2229],{},[978,2546,2547,2548,1065,2551,2554],{},"Granular options (",[982,2549,2550],{},"require_superuser",[982,2552,2553],{},"require_permission",") are\ndeferred. Add them as additional node settings when a real use case\narrives — both are additive and don't break the v1 contract.",[992,2556,2558],{"id":2557},"route-shadowing","Route shadowing",[978,2560,2561],{},"Published flow routes shadow Go-registered routes at the same\n(method, path). The dispatcher middleware sits ahead of chi's main\nmatcher; on match, the flow runs and the Go handler is never invoked.\nOn unpublish (or flow delete), the binding is removed and the Go\nhandler resumes serving the route — no restart required.",[978,2563,2564,2565,2567,2568,2570],{},"This is why ",[982,2566,1060],{}," doesn't have a Go handler at all: the\nframework auto-publishes a default registration template at first\nstartup, so ",[982,2569,1557],{}," is always flow-driven, but the\nspecific flow can be swapped without touching code.",[978,2572,2573,2574,2577],{},"Conflicts between two flows wanting the same (method, path) are\nrejected: ",[982,2575,2576],{},"Dispatcher.Bind"," returns an error when the path is already\nbound to a different flow ID. Admins resolve by unpublishing the\nexisting binding first.",[992,2579,2581],{"id":2580},"spec-discoverability","Spec discoverability",[978,2583,2584,2585,2382,2587,2590],{},"Both ",[982,2586,1154],{},[982,2588,2589],{},"\u002Fasyncapi.json"," are spec contributors:",[2592,2593,2594,2623],"ul",{},[1931,2595,2596,2599,2600],{},[982,2597,2598],{},"openapi.Module"," collects:\n",[2592,2601,2602,2609,2616],{},[1931,2603,2604,2605,2608],{},"regular routes via ",[982,2606,2607],{},"RoutesProvider.Routes()"," (existing)",[1931,2610,2611,2612,2615],{},"flow-mounted routes via ",[982,2613,2614],{},"DynamicRoutesProvider.DynamicRoutes()"," (new — implemented by flowexec)",[1931,2617,2618,2619,2622],{},"schema types via ",[982,2620,2621],{},"SchemasProvider.OpenAPISchemas()"," (new — for types referenced only by FlowDSL packets)",[1931,2624,2625,2599,2628],{},[982,2626,2627],{},"asyncapi.Module",[2592,2629,2630,2636],{},[1931,2631,2632,2633,2608],{},"declared events via ",[982,2634,2635],{},"EventsProvider.Events()",[1931,2637,2638,2639,2615],{},"flow-emitted\u002Fconsumed channels via ",[982,2640,2641],{},"DynamicChannelsProvider.DynamicChannels()",[978,2643,2644,2645,2648,2649,2652,2653,2656,2657,2660,2661,2663],{},"Flow-mounted routes carry an ",[982,2646,2647],{},"x-source: \"flow:\u003CflowID>\""," extension on\ntheir OpenAPI path entries so SDK generators \u002F clients can identify\nthem. Their request and response schemas come from the ",[1353,2650,2651],{},"packet refs\non flow edges"," — see ",[1372,2654,1395],{"href":2655},"#packet-based-schema-model","\nabove. The dispatcher derives them at flow-publish time (in\n",[982,2658,2659],{},"ExtractBinding",") and stores them on the binding; the openapi\ngenerator reads bindings on every ",[982,2662,1154],{}," request.",[978,2665,2666,2667,2669],{},"The merge happens at request time (when admin hits ",[982,2668,1154],{},"),\nnot at boot — so newly published flows show up in the spec immediately\nwithout a restart.",[1415,2671,2673],{"id":2672},"idempotent-route-prefixing","Idempotent route prefixing",[978,2675,2676,2679,2680,2683,2684,2686,2687,2690,2691,2694,2695,2698,2699,2702,2703,2705],{},[982,2677,2678],{},"ROUTE_PREFIX"," (default ",[982,2681,2682],{},"\u002Fapi\u002Fv1",") is applied ",[1353,2685,2183],{}," to relative\nmodule-route paths. Dynamic routes carry the full absolute path on\ntheir ",[982,2688,2689],{},"DynamicRouteDescriptor.Path"," field — the dispatcher binds chi\nat that exact path with no prefix added at routing time. The openapi\nservice (",[982,2692,2693],{},"go-framework\u002Fmodules\u002Fopenapi\u002Fservice.go",") checks\n",[982,2696,2697],{},"strings.HasPrefix(path, m.routePrefix+\"\u002F\")"," and skips re-prefixing\nwhen the path is already absolute. Without this, the spec advertised\n",[982,2700,2701],{},"\u002Fapi\u002Fv1\u002Fapi\u002Fv1\u002Fusers\u002Fsignup"," while the route actually lived at\n",[982,2704,1557],{},", producing 404s for any client that trusted\nthe spec.",[2707,2708,2710,2711],"h4",{"id":2709},"routes-outside-the-prefix-absolutepath","Routes outside the prefix — ",[982,2712,2713],{},"AbsolutePath",[978,2715,2060,2716,2719,2720,2723,2724,1366,2727,2729,2730,2733,2734,2736,2737,2740,2741,2743,2744,2747],{},[982,2717,2718],{},"HasPrefix"," check handles a route that is ",[987,2721,2722],{},"already"," prefixed, but\nnot one that genuinely lives ",[1353,2725,2726],{},"outside",[982,2728,2678],{}," — a top-level\nmount such as ",[982,2731,2732],{},"\u002Fws\u002Fhealth",", which does not start with ",[982,2735,2682],{}," and\nwould otherwise be re-prefixed to ",[982,2738,2739],{},"\u002Fapi\u002Fv1\u002Fws\u002Fhealth"," while its handler\nstays at ",[982,2742,2732],{},". Set ",[982,2745,2746],{},"AbsolutePath: true"," on the descriptor for\nthese:",[1075,2749,2751],{"className":2114,"code":2750,"language":2116,"meta":1083,"style":1083},"func (m *Module) DynamicRoutes() []modules.DynamicRouteDescriptor {\n    return []modules.DynamicRouteDescriptor{{\n        Method: \"GET\", Path: \"\u002Fws\u002Fhealth\",\n        Source: \"ws\", SuccessStatus: 200,\n        AbsolutePath: true,   \u002F\u002F emit verbatim, never prefix\n    }}\n}\n",[982,2752,2753,2758,2763,2768,2773,2778,2783],{"__ignoreMap":1083},[1198,2754,2755],{"class":1200,"line":10},[1198,2756,2757],{},"func (m *Module) DynamicRoutes() []modules.DynamicRouteDescriptor {\n",[1198,2759,2760],{"class":1200,"line":16},[1198,2761,2762],{},"    return []modules.DynamicRouteDescriptor{{\n",[1198,2764,2765],{"class":1200,"line":22},[1198,2766,2767],{},"        Method: \"GET\", Path: \"\u002Fws\u002Fhealth\",\n",[1198,2769,2770],{"class":1200,"line":51},[1198,2771,2772],{},"        Source: \"ws\", SuccessStatus: 200,\n",[1198,2774,2775],{"class":1200,"line":57},[1198,2776,2777],{},"        AbsolutePath: true,   \u002F\u002F emit verbatim, never prefix\n",[1198,2779,2780],{"class":1200,"line":102},[1198,2781,2782],{},"    }}\n",[1198,2784,2785],{"class":1200,"line":108},[1198,2786,1688],{},[978,2788,2789,2791,2792,2795,2796,2799],{},[982,2790,2713],{}," carries an internal ",[982,2793,2794],{},"x-absolute-path"," marker through\nspec generation; the prefixer leaves the path untouched and strips the\nmarker before the document is served. The ",[1372,2797,2798],{"href":275},"WebSocket\nhub"," is the first consumer.",[992,2801,2803],{"id":2802},"auto-publish-bootstrap","Auto-publish bootstrap",[978,2805,2806,2807,2810],{},"A module that ships starter templates can auto-publish a default at\nfirst startup so its endpoint works out of the box. Pattern (used by\n",[982,2808,2809],{},"users\u002Fflowtemplates","):",[1075,2812,2814],{"className":2114,"code":2813,"language":2116,"meta":1083,"style":1083},"func (m *Module) Startup(ctx context.Context) error {\n    fx := flowexecmod.Current()                  \u002F\u002F nil-safe\n    if fx == nil {\n        return nil\n    }\n    _, _, _ = fx.EnsurePublishedAtPath(ctx,\n        \"POST\", \"\u002Fapi\u002Fv1\u002Fusers\u002Fsignup\",\n        \"users\u002Fregistration-basic\",              \u002F\u002F template ID\n    )\n    return nil\n}\n",[982,2815,2816,2821,2826,2831,2836,2840,2845,2850,2858,2863,2868],{"__ignoreMap":1083},[1198,2817,2818],{"class":1200,"line":10},[1198,2819,2820],{},"func (m *Module) Startup(ctx context.Context) error {\n",[1198,2822,2823],{"class":1200,"line":16},[1198,2824,2825],{},"    fx := flowexecmod.Current()                  \u002F\u002F nil-safe\n",[1198,2827,2828],{"class":1200,"line":22},[1198,2829,2830],{},"    if fx == nil {\n",[1198,2832,2833],{"class":1200,"line":51},[1198,2834,2835],{},"        return nil\n",[1198,2837,2838],{"class":1200,"line":57},[1198,2839,1914],{},[1198,2841,2842],{"class":1200,"line":102},[1198,2843,2844],{},"    _, _, _ = fx.EnsurePublishedAtPath(ctx,\n",[1198,2846,2847],{"class":1200,"line":108},[1198,2848,2849],{},"        \"POST\", \"\u002Fapi\u002Fv1\u002Fusers\u002Fsignup\",\n",[1198,2851,2852,2855],{"class":1200,"line":114},[1198,2853,2854],{},"        \"users\u002Fregistration-basic\",",[1198,2856,2857],{},"              \u002F\u002F template ID\n",[1198,2859,2860],{"class":1200,"line":120},[1198,2861,2862],{},"    )\n",[1198,2864,2865],{"class":1200,"line":181},[1198,2866,2867],{},"    return nil\n",[1198,2869,2870],{"class":1200,"line":186},[1198,2871,1688],{},[978,2873,2874,2877],{},[982,2875,2876],{},"EnsurePublishedAtPath"," is idempotent: if any flow is already bound\nat the (method, path), it leaves the existing binding alone. So a\nproject that has activated a different template (email-confirm,\nsms-confirm, custom) won't have it overwritten on restart.",[992,2879,2881,2882],{"id":2880},"template-dependencies-metapublish_with","Template dependencies — ",[982,2883,2884],{},"meta.publish_with",[978,2886,2887,2888,2891],{},"Some flow-driven endpoints can't complete their request\u002Fresponse cycle\non their own — they need an event-driven handler running alongside.\nConfirmation-style signup is the canonical case: the registration flow\ncreates an inactive user and dispatches a verification token, then\nhands off to an event handler that flips ",[982,2889,2890],{},"is_active=true"," when the\nuser clicks the link.",[978,2893,2894],{},"A template declares those runtime dependencies in its IR meta:",[1075,2896,2898],{"className":1421,"code":2897,"language":1423,"meta":1083,"style":1083},"{\n  \"id\": \"users-registration-email-confirm\",\n  ...\n  \"meta\": {\n    \"publish_with\": [\"users\u002Femail-verify-handler\"]\n  }\n}\n",[982,2899,2900,2904,2923,2929,2941,2964,2968],{"__ignoreMap":1083},[1198,2901,2902],{"class":1200,"line":10},[1198,2903,1430],{"class":1203},[1198,2905,2906,2908,2910,2912,2914,2916,2919,2921],{"class":1200,"line":16},[1198,2907,1435],{"class":1203},[1198,2909,1439],{"class":1438},[1198,2911,1442],{"class":1203},[1198,2913,1211],{"class":1203},[1198,2915,1447],{"class":1203},[1198,2917,2918],{"class":1214},"users-registration-email-confirm",[1198,2920,1442],{"class":1203},[1198,2922,1455],{"class":1203},[1198,2924,2925],{"class":1200,"line":22},[1198,2926,2928],{"class":2927},"sTEyZ","  ...\n",[1198,2930,2931,2933,2935,2937,2939],{"class":1200,"line":51},[1198,2932,1435],{"class":1203},[1198,2934,1826],{"class":1438},[1198,2936,1442],{"class":1203},[1198,2938,1211],{"class":1203},[1198,2940,1833],{"class":1203},[1198,2942,2943,2945,2948,2950,2952,2954,2956,2959,2961],{"class":1200,"line":57},[1198,2944,1513],{"class":1203},[1198,2946,2947],{"class":1478},"publish_with",[1198,2949,1442],{"class":1203},[1198,2951,1211],{"class":1203},[1198,2953,1334],{"class":1203},[1198,2955,1442],{"class":1203},[1198,2957,2958],{"class":1214},"users\u002Femail-verify-handler",[1198,2960,1442],{"class":1203},[1198,2962,2963],{"class":1203},"]\n",[1198,2965,2966],{"class":1200,"line":102},[1198,2967,1919],{"class":1203},[1198,2969,2970],{"class":1200,"line":108},[1198,2971,1688],{"class":1203},[978,2973,2974,2975,2978,2979,2981,2982,2985],{},"When ",[982,2976,2977],{},"ActivateTemplate"," runs, it walks ",[982,2980,2947],{}," and calls\n",[982,2983,2984],{},"EnsureTemplatePublished"," on each — idempotent, reuses already-running\nhandlers. This is how confirmation signup ships intact: one click\non the activation button publishes BOTH the registration flow AND the\nmatching verify handler.",[978,2987,2988],{},"The activation response echoes which dependencies were freshly\npublished (already-running ones are silent so re-activations stay\nquiet):",[1075,2990,2992],{"className":1421,"code":2991,"language":1423,"meta":1083,"style":1083},"{\n  \"flow_id\":        \"flow.…\",\n  \"template_id\":    \"users\u002Fregistration-email-confirm\",\n  \"method\":         \"POST\",\n  \"path\":           \"\u002Fapi\u002Fv1\u002Fusers\u002Fsignup\",\n  \"published_with\": [\"users\u002Femail-verify-handler\"]\n}\n",[982,2993,2994,2998,3019,3039,3058,3077,3098],{"__ignoreMap":1083},[1198,2995,2996],{"class":1200,"line":10},[1198,2997,1430],{"class":1203},[1198,2999,3000,3002,3005,3007,3009,3012,3015,3017],{"class":1200,"line":16},[1198,3001,1435],{"class":1203},[1198,3003,3004],{"class":1438},"flow_id",[1198,3006,1442],{"class":1203},[1198,3008,1211],{"class":1203},[1198,3010,3011],{"class":1203},"        \"",[1198,3013,3014],{"class":1214},"flow.…",[1198,3016,1442],{"class":1203},[1198,3018,1455],{"class":1203},[1198,3020,3021,3023,3026,3028,3030,3032,3035,3037],{"class":1200,"line":22},[1198,3022,1435],{"class":1203},[1198,3024,3025],{"class":1438},"template_id",[1198,3027,1442],{"class":1203},[1198,3029,1211],{"class":1203},[1198,3031,1513],{"class":1203},[1198,3033,3034],{"class":1214},"users\u002Fregistration-email-confirm",[1198,3036,1442],{"class":1203},[1198,3038,1455],{"class":1203},[1198,3040,3041,3043,3045,3047,3049,3052,3054,3056],{"class":1200,"line":51},[1198,3042,1435],{"class":1203},[1198,3044,1566],{"class":1438},[1198,3046,1442],{"class":1203},[1198,3048,1211],{"class":1203},[1198,3050,3051],{"class":1203},"         \"",[1198,3053,1575],{"class":1214},[1198,3055,1442],{"class":1203},[1198,3057,1455],{"class":1203},[1198,3059,3060,3062,3064,3066,3068,3071,3073,3075],{"class":1200,"line":57},[1198,3061,1435],{"class":1203},[1198,3063,1548],{"class":1438},[1198,3065,1442],{"class":1203},[1198,3067,1211],{"class":1203},[1198,3069,3070],{"class":1203},"           \"",[1198,3072,1557],{"class":1214},[1198,3074,1442],{"class":1203},[1198,3076,1455],{"class":1203},[1198,3078,3079,3081,3084,3086,3088,3090,3092,3094,3096],{"class":1200,"line":102},[1198,3080,1435],{"class":1203},[1198,3082,3083],{"class":1438},"published_with",[1198,3085,1442],{"class":1203},[1198,3087,1211],{"class":1203},[1198,3089,1334],{"class":1203},[1198,3091,1442],{"class":1203},[1198,3093,2958],{"class":1214},[1198,3095,1442],{"class":1203},[1198,3097,2963],{"class":1203},[1198,3099,3100],{"class":1200,"line":108},[1198,3101,1688],{"class":1203},[992,3103,3105],{"id":3104},"subscriber-deployments","Subscriber deployments",[978,3107,3108,3109,3112,3113,3116,3117,1211],{},"Templates without an ",[982,3110,3111],{},"http-endpoint"," source — typically event-driven\nhandlers — get wrapped in a ",[1353,3114,3115],{},"subscriber deployment"," when published\nvia ",[982,3118,2984],{},[1075,3120,3123],{"className":3121,"code":3122,"language":1080},[1078],"flowexec.EnsureTemplatePublished(ctx, \"users\u002Femail-verify-handler\")\n  │\n  ├── publishes flow with x-template-id label\n  ├── ensureSubscriberDeployment(...)\n  │     ID:     subscriber-users-email-verify-handler\n  │     Labels: x-kind=subscriber, x-event=verification.token_verified,\n  │             x-event-filter=payload.kind == \"email\"\n  │             x-template-id=users\u002Femail-verify-handler\n  └── stable variant points at the freshly-published flow\n",[982,3124,3122],{"__ignoreMap":1083},[978,3126,3127],{},"Same lifecycle contract as route deployments — idempotent ID,\ndisable\u002Fenable toggle, canary\u002FA-B variants — but routing happens via\nthe event bus instead of HTTP. Multiple subscriber deployments\nlistening to the same event channel is legitimate fan-out (route\nuniqueness doesn't apply here).",[978,3129,3130,3131,3133,3134,3137],{},"See ",[1372,3132,264],{"href":265}," for the full\ndeployment-layer reference, including the ",[982,3135,3136],{},"disabled"," flag, route\nuniqueness invariant, spec contributions, and admin endpoints.",[992,3139,3141],{"id":3140},"module-package-convention","Module package convention",[997,3143,3144,3157],{},[1000,3145,3146],{},[1003,3147,3148,3151,3154],{},[1006,3149,3150],{},"Subpackage",[1006,3152,3153],{},"Contents",[1006,3155,3156],{},"Blank-imported by",[1013,3158,3159,3172,3185,3198],{},[1003,3160,3161,3166,3169],{},[1018,3162,3163],{},[982,3164,3165],{},"\u003Cmodule>\u002F",[1018,3167,3168],{},"core: Service, model, settings, module-owned Go HTTP handlers (only flat CRUD-shaped)",[1018,3170,3171],{},"every binary that needs the module",[1003,3173,3174,3179,3182],{},[1018,3175,3176],{},[982,3177,3178],{},"\u003Cmodule>\u002Fadmin\u002F",[1018,3180,3181],{},"admin endpoints, masking, write paths",[1018,3183,3184],{},"admin-api binary only",[1003,3186,3187,3192,3195],{},[1018,3188,3189],{},[982,3190,3191],{},"\u003Cmodule>\u002Fflowdsl\u002F",[1018,3193,3194],{},"FlowDSL nodes (operators) + handlers calling parent Service",[1018,3196,3197],{},"binaries that participate in flows",[1003,3199,3200,3204,3207],{},[1018,3201,3202],{},[982,3203,1182],{},[1018,3205,3206],{},"starter flow compositions + auto-publish-on-startup bootstrap",[1018,3208,3209],{},"binaries that want opinionated defaults",[978,3211,3212],{},"All four are independently optional. A project can take core+admin\nwithout flowdsl (no flow integration), or core+flowdsl without\nflowtemplates (use my own flows), or all four (full opinionated\nexperience).",[992,3214,3216],{"id":3215},"reference-users-registration-endpoint","Reference: users registration endpoint",[978,3218,3219,3220,3222],{},"The first end-to-end consumer of this infrastructure is the users\nmodule's ",[982,3221,1557],{},". Captured here as a worked example of\nhow a domain module flips its public endpoint to flow-driven without\ntouching the framework HTTP layer.",[1415,3224,3226],{"id":3225},"architecture","Architecture",[1075,3228,3231],{"className":3229,"code":3230,"language":1080},[1078],"admin (UI)              users-flowtemplates           flowexec\n  │                          │                          │\n  │ POST \u002Fadmin\u002Fusers\u002F       │                          │\n  │ registration\u002F            │                          │\n  │ activate-template        │                          │\n  ├─────────────────────────►│ ActivateTemplate(...)   │\n  │                          ├─────────────────────────►│ unbind old\n  │                          │                          │ create flow\n  │                          │                          │ publish version\n  │                          │                          │ rebind\n  │ ◄────────────────────────┴──────────────────────────┤ flow_id\n  │                                                     │\n  │ POST \u002Fapi\u002Fv1\u002Fusers\u002Fsignup ──────────────────────────►│ dispatcher matches\n  │                                                     │ runs flow\n  │                                                     │   ┌─ http-endpoint (source)\n  │                                                     │   ├─ users-create-pending  ┐\n  │                                                     │   └─ verification-request-email\n  │ ◄───────────────────────────────────────────────────┤ output → 202 + body\n",[982,3232,3230],{"__ignoreMap":1083},[1415,3234,3236,3237],{"id":3235},"six-templates-ship-in-usersflowtemplates","Six templates ship in ",[982,3238,3239],{},"users\u002Fflowtemplates\u002F",[997,3241,3242,3255],{},[1000,3243,3244],{},[1003,3245,3246,3249,3252],{},[1006,3247,3248],{},"Template ID",[1006,3250,3251],{},"Bound at",[1006,3253,3254],{},"Pipeline",[1013,3256,3257,3270,3281,3293,3305,3317],{},[1003,3258,3259,3264,3267],{},[1018,3260,3261],{},[982,3262,3263],{},"users\u002Fregistration-basic",[1018,3265,3266],{},"POST \u002Fapi\u002Fv1\u002Fusers\u002Fsignup",[1018,3268,3269],{},"http → users-create-user → end (201)",[1003,3271,3272,3276,3278],{},[1018,3273,3274],{},[982,3275,3034],{},[1018,3277,3266],{},[1018,3279,3280],{},"http → users-create-pending → verification-request-email → end (202)",[1003,3282,3283,3288,3290],{},[1018,3284,3285],{},[982,3286,3287],{},"users\u002Fregistration-sms-confirm",[1018,3289,3266],{},[1018,3291,3292],{},"http → users-create-pending → verification-request-sms → end (202)",[1003,3294,3295,3300,3302],{},[1018,3296,3297],{},[982,3298,3299],{},"users\u002Fregistration-dual-confirm",[1018,3301,3266],{},[1018,3303,3304],{},"http → users-create-pending → verification-request-email → verification-request-sms → end (202)",[1003,3306,3307,3311,3314],{},[1018,3308,3309],{},[982,3310,2958],{},[1018,3312,3313],{},"(event-driven)",[1018,3315,3316],{},"event-source(verification.token_verified, kind=email) → users-activate",[1003,3318,3319,3324,3326],{},[1018,3320,3321],{},[982,3322,3323],{},"users\u002Fsms-verify-handler",[1018,3325,3313],{},[1018,3327,3328],{},"event-source(verification.token_verified, kind=phone) → users-find-by-email → users-activate",[978,3330,3331,3332,3334,3335,3337,3338,3340,3341,3343,3344,3346,3347,1384],{},"All four HTTP-mounted templates declare two packets at ",[982,3333,1939],{},"\n— ",[982,3336,1853],{}," (request) and ",[982,3339,1885],{}," (response) — both\n",[982,3342,1864],{},"-ing the ",[982,3345,2076],{}," namespace. The user types come from\n",[982,3348,3349],{},"users.Module.OpenAPISchemas()",[1415,3351,3353],{"id":3352},"admin-endpoints","Admin endpoints",[997,3355,3356,3368],{},[1000,3357,3358],{},[1003,3359,3360,3363,3366],{},[1006,3361,3362],{},"Method",[1006,3364,3365],{},"Path",[1006,3367,1098],{},[1013,3369,3370,3385,3401],{},[1003,3371,3372,3377,3382],{},[1018,3373,3374],{},[982,3375,3376],{},"GET",[1018,3378,3379],{},[982,3380,3381],{},"\u002Fapi\u002Fv1\u002Fadmin\u002Fflows\u002Ftemplates?source=users",[1018,3383,3384],{},"List the 6 starter templates (filter applied client-side)",[1003,3386,3387,3391,3396],{},[1018,3388,3389],{},[982,3390,3376],{},[1018,3392,3393],{},[982,3394,3395],{},"\u002Fapi\u002Fv1\u002Fadmin\u002Fusers\u002Fregistration\u002Factive",[1018,3397,3398,3399],{},"Read flow currently serving ",[982,3400,1557],{},[1003,3402,3403,3407,3412],{},[1018,3404,3405],{},[982,3406,1575],{},[1018,3408,3409],{},[982,3410,3411],{},"\u002Fapi\u002Fv1\u002Fadmin\u002Fusers\u002Fregistration\u002Factivate-template",[1018,3413,3414],{},"One-click switch — unbinds old flow + publishes new from template",[1415,3416,2803],{"id":3417},"auto-publish-bootstrap-1",[978,3419,3420,3421,3424,3425,3428,3429,3432,3433,3436],{},"On first startup, ",[982,3422,3423],{},"users-flowtemplates"," calls\n",[982,3426,3427],{},"flowexec.EnsurePublishedAtPath(\"POST\", \"\u002Fapi\u002Fv1\u002Fusers\u002Fsignup\", \"users\u002Fregistration-basic\")",". The call is idempotent: if any flow is\nalready bound at that path (admin-activated or auto-published on a\nprior boot), the call no-ops and the existing binding survives. Set\n",[982,3430,3431],{},"USERS_AUTO_PUBLISH_TEMPLATE"," to override the default; set\n",[982,3434,3435],{},"USERS_AUTO_PUBLISH_DISABLED=true"," to skip entirely.",[1415,3438,3440],{"id":3439},"backward-compatibility","Backward compatibility",[978,3442,3443,3444,3447,3448,3450,3451,3453,3454,3457,3458,3461],{},"Pre-2026-04 the users module owned ",[982,3445,3446],{},"handleSignup"," directly. The\nremoval is a breaking change in the strict sense — the Go function\nno longer exists — but the public HTTP contract (",[982,3449,3266],{},") is preserved by ",[982,3452,3263],{},"\nauto-publishing on first boot. Projects that had\n",[982,3455,3456],{},"USERS_EMAIL_CONFIRMATION_ENABLED=true"," should set\n",[982,3459,3460],{},"USERS_AUTO_PUBLISH_TEMPLATE=users\u002Fregistration-email-confirm"," to\nmatch prior behavior; everything else continues working without\nchanges.",[992,3463,3465],{"id":3464},"why-these-decisions","Why these decisions",[978,3467,3468],{},"A few design choices captured for posterity:",[2592,3470,3471,3496,3524,3536,3562,3589],{},[1931,3472,3473,3476,3477,3480,3481,3484,3485,3487,3488,3491,3492,3495],{},[1353,3474,3475],{},"Packets on edges, not schemas on the source node."," Earlier\niterations of this design carried ",[982,3478,3479],{},"request_schema"," and\n",[982,3482,3483],{},"response_schema"," as JSON-Schema-typed settings on the\n",[982,3486,984],{}," node. Two reasons that's gone: (1) it's\ninconsistent with every other node in the catalog (LLM, RAG, guard,\n…) where typed I\u002FO is declared via input\u002Foutput ports + edge\npackets; (2) Studio rendered the inline JSON as a ",[982,3489,3490],{},"[object Object]","\ntextarea because the field has no obvious editor for an arbitrary\nJSON Schema. The packet model puts schema attribution where it\nbelongs (the ",[987,3493,3494],{},"type"," of the data flowing between two nodes) and\nStudio renders it like every other edge.",[1931,3497,3498,3501,3502,3505,3506,3509,3510,3512,3513,3516,3517,3520,3521,3523],{},[1353,3499,3500],{},"Single packet ref, three rendered forms."," The dispatcher's\n",[982,3503,3504],{},"resolvePacket"," + ",[982,3507,3508],{},"stripSpecNamespace"," (for ",[982,3511,1154],{},") and\nthe admin module's ",[982,3514,3515],{},"inlinePacketRefs"," (for Studio's\n",[982,3518,3519],{},"?format=spec",") are the only two pieces of code that know about\nthe ",[982,3522,2063],{}," namespace. Templates use the namespaced\nform (single source of truth, Studio resolves it via modspec\ncache); consumers each get the form they understand. Templates\nnever duplicate Go-struct definitions.",[1931,3525,3526,1366,3529,3531,3532,3535],{},[1353,3527,3528],{},"Idempotent prefix.",[982,3530,2678],{}," had been blindly prepended\nto every path in the openapi response. That worked for module\nroutes (declared without a prefix) but doubled dynamic-route\npaths. The fix — skip prepending when the path already starts\nwith the prefix — is the safest possible change: it's a no-op\nfor any module route declared the canonical way (without\n",[982,3533,3534],{},"\u002Fapi\u002Fv1\u002F","), and it stops doing the wrong thing for absolute\npaths. Module authors who hardcoded the prefix in their route\ndeclarations get the now-correct behavior automatically.",[1931,3537,3538,3545,3546,1065,3548,1065,3550,1065,3552,3554,3555,3558,3559,3561],{},[1353,3539,3540,3541,3544],{},"Output convention vs. dedicated ",[982,3542,3543],{},"respond"," node."," The convention\n(",[982,3547,2432],{},[982,3549,2448],{},[982,3551,2310],{},[982,3553,2465],{}," keys on the workflow\noutput map) keeps templates compact — a successful signup is\n",[982,3556,3557],{},"{\"id\": user.id, \"email\": user.email}"," on a single end node, no\nceremony. A dedicated respond node would force every template to\ncarry one. Authors who want structure can still set ",[982,3560,2448],{},"\nexplicitly; minimalist authors dump fields. Both work.",[1931,3563,3564,3569,3570,3572,3573,3575,3576,3578,3579,1065,3581,1065,3583,3585,3586,3588],{},[1353,3565,3566,3568],{},[982,3567,2229],{}," envelope vs. flat input."," Body fields at top level keeps\nflow expressions short (",[982,3571,1379],{}," not ",[982,3574,2372],{},"). Request\nmetadata under a single ",[982,3577,2229],{}," namespace prevents collisions with\nbody fields named ",[982,3580,1566],{},[982,3582,1548],{},[982,3584,2310],{},", etc. The redaction\nrule (Authorization + Cookie stripped) defaults to safe — flow\noutput payloads land in the run-events SSE stream which inherits the\nframework's audit hygiene by accident if ",[982,3587,2229],{}," is dumped wholesale.",[1931,3590,3591,3594,3595,1455,3597,3600],{},[1353,3592,3593],{},"Auth gate as boolean."," Granular variants (",[982,3596,2550],{},[982,3598,3599],{},"require_permission: \"...\"",") are doable as additional node settings\nlater. Booleans cover the immediate need (signup is public, account\ndeletion is authenticated) and avoid defining a permission-string\ncontract before a real use case lands. Both extensions are additive.",[3602,3603,3604],"style",{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}",{"title":1083,"searchDepth":16,"depth":16,"links":3606},[3607,3608,3609,3610,3618,3619,3620,3621,3622,3625,3626,3628,3629,3630,3638],{"id":994,"depth":16,"text":995},{"id":1072,"depth":16,"text":1073},{"id":1188,"depth":16,"text":1189},{"id":1394,"depth":16,"text":1395,"children":3611},[3612,3613,3614,3616],{"id":1417,"depth":22,"text":1418},{"id":1984,"depth":22,"text":1985},{"id":2059,"depth":22,"text":3615},"The openapi:default# namespace",{"id":2097,"depth":22,"text":3617},"Schema source: SchemasProvider",{"id":2187,"depth":16,"text":1375},{"id":2405,"depth":16,"text":2406},{"id":2520,"depth":16,"text":2521},{"id":2557,"depth":16,"text":2558},{"id":2580,"depth":16,"text":2581,"children":3623},[3624],{"id":2672,"depth":22,"text":2673},{"id":2802,"depth":16,"text":2803},{"id":2880,"depth":16,"text":3627},"Template dependencies — meta.publish_with",{"id":3104,"depth":16,"text":3105},{"id":3140,"depth":16,"text":3141},{"id":3215,"depth":16,"text":3216,"children":3631},[3632,3633,3635,3636,3637],{"id":3225,"depth":22,"text":3226},{"id":3235,"depth":22,"text":3634},"Six templates ship in users\u002Fflowtemplates\u002F",{"id":3352,"depth":22,"text":3353},{"id":3417,"depth":22,"text":2803},{"id":3439,"depth":22,"text":3440},{"id":3464,"depth":16,"text":3465},"Mount FlowDSL flows as HTTP routes. Domain modules contribute nodes;\nflowexec owns the HTTP↔flow bridge. Schemas attach to edges as\npackets (one ref → three rendered forms: stored, \u002Fopenapi.json,\nStudio); the http-endpoint source node carries only routing +\nspec metadata. Flow templates ship in per-module flowtemplates\u002F\npackages and auto-publish at startup so endpoints work out of\nthe box.\n","md",null,{},true,{"title":260,"description":3639},"bkbsAJtqpkn4JXiBgwVvHaBIe2-v3bOaYhFIgyAu9zA",[3647,3649],{"title":254,"path":255,"stem":256,"description":3648,"order":257,"icon":258,"children":-1},"Reusable, admin-editable config bundles — one dropdown on a FlowDSL node replaces eight hand-configured fields. Works for LLM chat, guard, databases, FTP, storage, any connection-bearing node.",{"title":264,"path":265,"stem":266,"description":3650,"children":-1},"The dispatch unit between modules and flows. Wraps every published\nflow with a stable ID, canary\u002FA-B variant routing, an enable\u002Fdisable\ntoggle, and a contract describing what the flow contributes to\n\u002Fopenapi.json + \u002Fasyncapi.json.\n",1790332226537]