[{"data":1,"prerenderedAt":2703},["ShallowReactive",2],{"navigation_docs":3,"-docs-reference-flowdsl-sync":968,"-docs-reference-flowdsl-sync-surround":2698},[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":194,"body":970,"description":984,"extension":2692,"links":2693,"meta":2694,"navigation":2695,"path":195,"seo":2696,"stem":196,"__hash__":2697},"docs\u002Fdocs\u002F4.reference\u002F13.flowdsl-sync.md",{"type":971,"value":972,"toc":2669},"minimark",[973,978,985,990,993,996,1000,1012,1014,1018,1059,1061,1065,1075,1077,1081,1091,1099,1592,1596,1712,1714,1718,1725,1773,1777,1783,1941,1960,1962,1966,2130,2139,2141,2148,2154,2156,2160,2167,2271,2277,2343,2345,2349,2353,2359,2363,2369,2372,2395,2397,2401,2665],[974,975,977],"h1",{"id":976},"flowdsl-sync-architecture","FlowDSL Sync Architecture",[979,980,981],"blockquote",{},[982,983,984],"p",{},"How FlowDSL diagrams stay in sync with Go module code — from Studio edit to deployed container.",[986,987,989],"h2",{"id":988},"status","Status",[982,991,992],{},"Draft — proposed architecture, not yet implemented.",[994,995],"hr",{},[986,997,999],{"id":998},"the-problem","The Problem",[982,1001,1002,1003,1007,1008,1011],{},"FlowDSL ",[1004,1005,1006],"code",{},".flowdsl.yaml"," files in ",[1004,1009,1010],{},"backend\u002Fflows\u002F"," currently describe business flows as documentation only. The runtime doesn't read them. There's no enforcement that Go handlers implement all declared nodes, and changing an edge's delivery mode requires manual code changes. This document defines an architecture where the diagram is the authoritative source of wiring.",[994,1013],{},[986,1015,1017],{"id":1016},"core-assumptions","Core Assumptions",[1019,1020,1021,1029,1035,1045],"ul",{},[1022,1023,1024,1028],"li",{},[1025,1026,1027],"strong",{},"Redeploy is acceptable."," A container restart when a flow changes is fine. Hot-reload is a later optimization, not a requirement.",[1022,1030,1031,1034],{},[1025,1032,1033],{},"Compile-time safety over runtime safety."," If a node in the diagram has no handler, the build should fail — not the server at startup.",[1022,1036,1037,1040,1041,1044],{},[1025,1038,1039],{},"Modules own their nodes."," Each Go module declares which FlowDSL ",[1004,1042,1043],{},"operationId"," values it implements. The framework discovers them automatically.",[1022,1046,1047,1050,1051,1054,1055,1058],{},[1025,1048,1049],{},"Delivery mode is diagram-owned."," Changing ",[1004,1052,1053],{},"direct"," → ",[1004,1056,1057],{},"durable"," on an edge should require zero Go code changes — only the YAML changes.",[994,1060],{},[986,1062,1064],{"id":1063},"architecture-overview","Architecture Overview",[1066,1067,1072],"pre",{"className":1068,"code":1070,"language":1071},[1069],"language-text","┌──────────────────────────────────────────────────────────────────────┐\n│  1. DIAGRAM LAYER  (Studio \u002F .flowdsl.yaml)                          │\n│                                                                      │\n│  backend\u002Fflows\u002Fuser_registration.flowdsl.yaml                        │\n│  backend\u002Fflows\u002Fmodule_submission.flowdsl.yaml                        │\n│  backend\u002Fflows\u002Femail_notification.flowdsl.yaml                       │\n│  ...                                                                 │\n│                                                                      │\n│  Source of truth for: nodes, edges, delivery modes, retry policies,  │\n│  idempotency keys, packet types.                                     │\n└──────────────────────┬───────────────────────────────────────────────┘\n                       │\n                       │  go run .\u002Fcmd\u002Fgenerate\u002F flows\n                       │  (runs in CI after any .flowdsl.yaml change)\n                       ▼\n┌──────────────────────────────────────────────────────────────────────┐\n│  2. CODEGEN LAYER  (backend\u002Fflows\u002Fgen\u002F)                              │\n│                                                                      │\n│  user_registration_flow_gen.go                                       │\n│  module_submission_flow_gen.go                                       │\n│  email_notification_flow_gen.go                                      │\n│                                                                      │\n│  Generated per flow:                                                 │\n│  - Typed XxxFlowNodes struct (one field per node operationId)        │\n│  - RegisterXxxFlow(bus, nodes) wiring function                       │\n│  - Edge wiring is compiled —  delivery mode → go-events call         │\n│  - Checked into git (diff = what the diagram change produced)        │\n└──────────────────────┬───────────────────────────────────────────────┘\n                       │\n                       │  go build .\u002F...  (fails if nodes unimplemented)\n                       ▼\n┌──────────────────────────────────────────────────────────────────────┐\n│  3. NODE HANDLER LAYER  (backend\u002Fmodules\u002F*\u002Fflows.go)                 │\n│                                                                      │\n│  community\u002Fflows.go   → func (m *Module) UserRegistrationNodes()     │\n│  marketplace\u002Fflows.go → func (m *Module) ModuleSubmissionNodes()     │\n│  email\u002Fflows.go       → func (m *Module) EmailNotificationNodes()    │\n│                                                                      │\n│  Developer writes: pure business logic functions.                    │\n│  No transport knowledge. Same service layer as HTTP handlers.        │\n│  Scaffold generates stubs for new operationIds automatically.        │\n└──────────────────────┬───────────────────────────────────────────────┘\n                       │\n                       │  compiled into binary\n                       ▼\n┌──────────────────────────────────────────────────────────────────────┐\n│  4. RUNTIME  (started in cmd\u002Fapi\u002Fmain.go)                            │\n│                                                                      │\n│  flows.RegisterAll(bus, modules)                                     │\n│  → starts goroutines for durable\u002Fephemeral\u002Fstream edges              │\n│  → direct edges become inline function calls                         │\n│  → wiring is compiled in, not dynamic                                │\n└──────────────────────────────────────────────────────────────────────┘\n","text",[1004,1073,1070],{"__ignoreMap":1074},"",[994,1076],{},[986,1078,1080],{"id":1079},"what-gets-generated","What Gets Generated",[982,1082,1083,1084,1086,1087,1090],{},"For each ",[1004,1085,1006],{},", the generator produces one ",[1004,1088,1089],{},"*_flow_gen.go"," file.",[1092,1093,1095,1096],"h3",{"id":1094},"example-user_registration_flow_gengo","Example: ",[1004,1097,1098],{},"user_registration_flow_gen.go",[1066,1100,1104],{"className":1101,"code":1102,"language":1103,"meta":1074,"style":1074},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F Code generated from user_registration.flowdsl.yaml. DO NOT EDIT.\n\u002F\u002F Source: backend\u002Fflows\u002Fuser_registration.flowdsl.yaml\n\u002F\u002F Generated: 2026-04-10T11:30:00Z\npackage flows\n\nimport (\n    \"context\"\n    \"time\"\n    \"github.com\u002Fredelay\u002Fgo-framework\u002Fflowdsl\"\n)\n\n\u002F\u002F UserRegistrationFlowNodes holds all node handlers for the user_registration flow.\n\u002F\u002F Every field must be set — the compiler enforces it at construction time.\ntype UserRegistrationFlowNodes struct {\n    \u002F\u002F source: receives POST \u002Fregister\n    ReceiveRegistration flowdsl.SourceHandler\n\n    \u002F\u002F transform: validates email, password, account_type\n    ValidateRegistrationInput flowdsl.RouterHandler \u002F\u002F valid → continue, invalid → reject\n\n    \u002F\u002F router: routes by account_type (developer \u002F community \u002F customer)\n    RouteRegistrationByType flowdsl.RouterHandler\n\n    \u002F\u002F action: creates core user + community profile in MongoDB\n    CreateUserAccount flowdsl.NodeHandler\n\n    \u002F\u002F action: queues verification email via email.send event\n    SendVerificationEmail flowdsl.NodeHandler\n\n    \u002F\u002F publish: emits users.registered to Kafka\n    PublishUserRegistered flowdsl.PublishHandler\n\n    \u002F\u002F terminal: returns 400 with validation errors\n    RejectInvalidRegistration flowdsl.TerminalHandler\n}\n\n\u002F\u002F RegisterUserRegistrationFlow wires the user_registration flow using the provided handlers.\n\u002F\u002F Edge delivery modes are compiled in from the diagram — changing the YAML regenerates this function.\nfunc RegisterUserRegistrationFlow(bus flowdsl.EventBus, nodes UserRegistrationFlowNodes) {\n    \u002F\u002F Edge: RegistrationSubmitted → ValidateRegistration [direct]\n    \u002F\u002F Delivery: in-process, microsecond latency, no durability\n    \u002F\u002F (triggered externally by the HTTP handler calling nodes.ReceiveRegistration)\n\n    \u002F\u002F Edge: ValidateRegistration.valid → RouteByAccountType [direct]\n    \u002F\u002F Edge: ValidateRegistration.invalid → RejectInvalidRegistration [direct]\n    \u002F\u002F These are handled by the RouterHandler return value (port name)\n\n    \u002F\u002F Edge: RouteByAccountType.* → CreateUserAccount [durable]\n    \u002F\u002F Delivery: MongoDB-backed packet, retry x3, exponential backoff 2s\n    \u002F\u002F IdempotencyKey: {{payload.email}}-register\n    bus.Subscribe(flowdsl.DurableConsumer{\n        Topic:          \"flow.user_registration.create_account\",\n        GroupID:        \"flow.user_registration\",\n        IdempotencyKey: func(p map[string]any) string {\n            return fmt.Sprintf(\"%v-register\", p[\"email\"])\n        },\n        RetryPolicy: flowdsl.RetryPolicy{\n            MaxAttempts:  3,\n            Backoff:      flowdsl.ExponentialBackoff,\n            InitialDelay: 2 * time.Second,\n        },\n        Handler: func(ctx context.Context, packet map[string]any) error {\n            out, err := nodes.CreateUserAccount(ctx, flowdsl.NodeInput{Packet: packet})\n            if err != nil { return err }\n            return bus.Publish(ctx, \"flow.user_registration.send_verification\", out.Packet(\"out\"))\n        },\n    })\n\n    \u002F\u002F Edge: CreateUserAccount → SendVerificationEmail [durable, retry x3]\n    bus.Subscribe(flowdsl.DurableConsumer{\n        Topic:   \"flow.user_registration.send_verification\",\n        GroupID: \"flow.user_registration\",\n        RetryPolicy: flowdsl.RetryPolicy{MaxAttempts: 3, Backoff: flowdsl.ExponentialBackoff, InitialDelay: 2 * time.Second},\n        Handler: func(ctx context.Context, packet map[string]any) error {\n            out, err := nodes.SendVerificationEmail(ctx, flowdsl.NodeInput{Packet: packet})\n            if err != nil { return err }\n            return bus.Publish(ctx, \"flow.user_registration.publish_registered\", out.Packet(\"out\"))\n        },\n    })\n\n    \u002F\u002F Edge: SendVerificationEmail → PublishUserRegistered [stream, topic: users.registered]\n    bus.Subscribe(flowdsl.DurableConsumer{\n        Topic:   \"flow.user_registration.publish_registered\",\n        GroupID: \"flow.user_registration\",\n        Handler: func(ctx context.Context, packet map[string]any) error {\n            return nodes.PublishUserRegistered(ctx, flowdsl.NodeInput{Packet: packet}, \"users.registered\")\n        },\n    })\n}\n","go",[1004,1105,1106,1113,1118,1123,1128,1134,1139,1144,1149,1154,1159,1163,1168,1173,1178,1183,1188,1192,1197,1202,1206,1211,1216,1221,1227,1232,1236,1241,1247,1252,1258,1264,1269,1275,1281,1287,1292,1298,1304,1310,1316,1322,1328,1333,1339,1345,1351,1356,1362,1368,1374,1380,1386,1392,1398,1404,1410,1416,1422,1428,1434,1439,1445,1451,1457,1463,1468,1474,1479,1485,1490,1496,1502,1508,1513,1519,1524,1530,1535,1540,1544,1550,1555,1561,1566,1571,1577,1582,1587],{"__ignoreMap":1074},[1107,1108,1110],"span",{"class":1109,"line":10},"line",[1107,1111,1112],{},"\u002F\u002F Code generated from user_registration.flowdsl.yaml. DO NOT EDIT.\n",[1107,1114,1115],{"class":1109,"line":16},[1107,1116,1117],{},"\u002F\u002F Source: backend\u002Fflows\u002Fuser_registration.flowdsl.yaml\n",[1107,1119,1120],{"class":1109,"line":22},[1107,1121,1122],{},"\u002F\u002F Generated: 2026-04-10T11:30:00Z\n",[1107,1124,1125],{"class":1109,"line":51},[1107,1126,1127],{},"package flows\n",[1107,1129,1130],{"class":1109,"line":57},[1107,1131,1133],{"emptyLinePlaceholder":1132},true,"\n",[1107,1135,1136],{"class":1109,"line":102},[1107,1137,1138],{},"import (\n",[1107,1140,1141],{"class":1109,"line":108},[1107,1142,1143],{},"    \"context\"\n",[1107,1145,1146],{"class":1109,"line":114},[1107,1147,1148],{},"    \"time\"\n",[1107,1150,1151],{"class":1109,"line":120},[1107,1152,1153],{},"    \"github.com\u002Fredelay\u002Fgo-framework\u002Fflowdsl\"\n",[1107,1155,1156],{"class":1109,"line":181},[1107,1157,1158],{},")\n",[1107,1160,1161],{"class":1109,"line":186},[1107,1162,1133],{"emptyLinePlaceholder":1132},[1107,1164,1165],{"class":1109,"line":191},[1107,1166,1167],{},"\u002F\u002F UserRegistrationFlowNodes holds all node handlers for the user_registration flow.\n",[1107,1169,1170],{"class":1109,"line":197},[1107,1171,1172],{},"\u002F\u002F Every field must be set — the compiler enforces it at construction time.\n",[1107,1174,1175],{"class":1109,"line":203},[1107,1176,1177],{},"type UserRegistrationFlowNodes struct {\n",[1107,1179,1180],{"class":1109,"line":214},[1107,1181,1182],{},"    \u002F\u002F source: receives POST \u002Fregister\n",[1107,1184,1185],{"class":1109,"line":223},[1107,1186,1187],{},"    ReceiveRegistration flowdsl.SourceHandler\n",[1107,1189,1190],{"class":1109,"line":229},[1107,1191,1133],{"emptyLinePlaceholder":1132},[1107,1193,1194],{"class":1109,"line":234},[1107,1195,1196],{},"    \u002F\u002F transform: validates email, password, account_type\n",[1107,1198,1199],{"class":1109,"line":240},[1107,1200,1201],{},"    ValidateRegistrationInput flowdsl.RouterHandler \u002F\u002F valid → continue, invalid → reject\n",[1107,1203,1204],{"class":1109,"line":246},[1107,1205,1133],{"emptyLinePlaceholder":1132},[1107,1207,1208],{"class":1109,"line":251},[1107,1209,1210],{},"    \u002F\u002F router: routes by account_type (developer \u002F community \u002F customer)\n",[1107,1212,1213],{"class":1109,"line":257},[1107,1214,1215],{},"    RouteRegistrationByType flowdsl.RouterHandler\n",[1107,1217,1219],{"class":1109,"line":1218},23,[1107,1220,1133],{"emptyLinePlaceholder":1132},[1107,1222,1224],{"class":1109,"line":1223},24,[1107,1225,1226],{},"    \u002F\u002F action: creates core user + community profile in MongoDB\n",[1107,1228,1229],{"class":1109,"line":271},[1107,1230,1231],{},"    CreateUserAccount flowdsl.NodeHandler\n",[1107,1233,1234],{"class":1109,"line":277},[1107,1235,1133],{"emptyLinePlaceholder":1132},[1107,1237,1238],{"class":1109,"line":282},[1107,1239,1240],{},"    \u002F\u002F action: queues verification email via email.send event\n",[1107,1242,1244],{"class":1109,"line":1243},28,[1107,1245,1246],{},"    SendVerificationEmail flowdsl.NodeHandler\n",[1107,1248,1250],{"class":1109,"line":1249},29,[1107,1251,1133],{"emptyLinePlaceholder":1132},[1107,1253,1255],{"class":1109,"line":1254},30,[1107,1256,1257],{},"    \u002F\u002F publish: emits users.registered to Kafka\n",[1107,1259,1261],{"class":1109,"line":1260},31,[1107,1262,1263],{},"    PublishUserRegistered flowdsl.PublishHandler\n",[1107,1265,1267],{"class":1109,"line":1266},32,[1107,1268,1133],{"emptyLinePlaceholder":1132},[1107,1270,1272],{"class":1109,"line":1271},33,[1107,1273,1274],{},"    \u002F\u002F terminal: returns 400 with validation errors\n",[1107,1276,1278],{"class":1109,"line":1277},34,[1107,1279,1280],{},"    RejectInvalidRegistration flowdsl.TerminalHandler\n",[1107,1282,1284],{"class":1109,"line":1283},35,[1107,1285,1286],{},"}\n",[1107,1288,1290],{"class":1109,"line":1289},36,[1107,1291,1133],{"emptyLinePlaceholder":1132},[1107,1293,1295],{"class":1109,"line":1294},37,[1107,1296,1297],{},"\u002F\u002F RegisterUserRegistrationFlow wires the user_registration flow using the provided handlers.\n",[1107,1299,1301],{"class":1109,"line":1300},38,[1107,1302,1303],{},"\u002F\u002F Edge delivery modes are compiled in from the diagram — changing the YAML regenerates this function.\n",[1107,1305,1307],{"class":1109,"line":1306},39,[1107,1308,1309],{},"func RegisterUserRegistrationFlow(bus flowdsl.EventBus, nodes UserRegistrationFlowNodes) {\n",[1107,1311,1313],{"class":1109,"line":1312},40,[1107,1314,1315],{},"    \u002F\u002F Edge: RegistrationSubmitted → ValidateRegistration [direct]\n",[1107,1317,1319],{"class":1109,"line":1318},41,[1107,1320,1321],{},"    \u002F\u002F Delivery: in-process, microsecond latency, no durability\n",[1107,1323,1325],{"class":1109,"line":1324},42,[1107,1326,1327],{},"    \u002F\u002F (triggered externally by the HTTP handler calling nodes.ReceiveRegistration)\n",[1107,1329,1331],{"class":1109,"line":1330},43,[1107,1332,1133],{"emptyLinePlaceholder":1132},[1107,1334,1336],{"class":1109,"line":1335},44,[1107,1337,1338],{},"    \u002F\u002F Edge: ValidateRegistration.valid → RouteByAccountType [direct]\n",[1107,1340,1342],{"class":1109,"line":1341},45,[1107,1343,1344],{},"    \u002F\u002F Edge: ValidateRegistration.invalid → RejectInvalidRegistration [direct]\n",[1107,1346,1348],{"class":1109,"line":1347},46,[1107,1349,1350],{},"    \u002F\u002F These are handled by the RouterHandler return value (port name)\n",[1107,1352,1354],{"class":1109,"line":1353},47,[1107,1355,1133],{"emptyLinePlaceholder":1132},[1107,1357,1359],{"class":1109,"line":1358},48,[1107,1360,1361],{},"    \u002F\u002F Edge: RouteByAccountType.* → CreateUserAccount [durable]\n",[1107,1363,1365],{"class":1109,"line":1364},49,[1107,1366,1367],{},"    \u002F\u002F Delivery: MongoDB-backed packet, retry x3, exponential backoff 2s\n",[1107,1369,1371],{"class":1109,"line":1370},50,[1107,1372,1373],{},"    \u002F\u002F IdempotencyKey: {{payload.email}}-register\n",[1107,1375,1377],{"class":1109,"line":1376},51,[1107,1378,1379],{},"    bus.Subscribe(flowdsl.DurableConsumer{\n",[1107,1381,1383],{"class":1109,"line":1382},52,[1107,1384,1385],{},"        Topic:          \"flow.user_registration.create_account\",\n",[1107,1387,1389],{"class":1109,"line":1388},53,[1107,1390,1391],{},"        GroupID:        \"flow.user_registration\",\n",[1107,1393,1395],{"class":1109,"line":1394},54,[1107,1396,1397],{},"        IdempotencyKey: func(p map[string]any) string {\n",[1107,1399,1401],{"class":1109,"line":1400},55,[1107,1402,1403],{},"            return fmt.Sprintf(\"%v-register\", p[\"email\"])\n",[1107,1405,1407],{"class":1109,"line":1406},56,[1107,1408,1409],{},"        },\n",[1107,1411,1413],{"class":1109,"line":1412},57,[1107,1414,1415],{},"        RetryPolicy: flowdsl.RetryPolicy{\n",[1107,1417,1419],{"class":1109,"line":1418},58,[1107,1420,1421],{},"            MaxAttempts:  3,\n",[1107,1423,1425],{"class":1109,"line":1424},59,[1107,1426,1427],{},"            Backoff:      flowdsl.ExponentialBackoff,\n",[1107,1429,1431],{"class":1109,"line":1430},60,[1107,1432,1433],{},"            InitialDelay: 2 * time.Second,\n",[1107,1435,1437],{"class":1109,"line":1436},61,[1107,1438,1409],{},[1107,1440,1442],{"class":1109,"line":1441},62,[1107,1443,1444],{},"        Handler: func(ctx context.Context, packet map[string]any) error {\n",[1107,1446,1448],{"class":1109,"line":1447},63,[1107,1449,1450],{},"            out, err := nodes.CreateUserAccount(ctx, flowdsl.NodeInput{Packet: packet})\n",[1107,1452,1454],{"class":1109,"line":1453},64,[1107,1455,1456],{},"            if err != nil { return err }\n",[1107,1458,1460],{"class":1109,"line":1459},65,[1107,1461,1462],{},"            return bus.Publish(ctx, \"flow.user_registration.send_verification\", out.Packet(\"out\"))\n",[1107,1464,1466],{"class":1109,"line":1465},66,[1107,1467,1409],{},[1107,1469,1471],{"class":1109,"line":1470},67,[1107,1472,1473],{},"    })\n",[1107,1475,1477],{"class":1109,"line":1476},68,[1107,1478,1133],{"emptyLinePlaceholder":1132},[1107,1480,1482],{"class":1109,"line":1481},69,[1107,1483,1484],{},"    \u002F\u002F Edge: CreateUserAccount → SendVerificationEmail [durable, retry x3]\n",[1107,1486,1488],{"class":1109,"line":1487},70,[1107,1489,1379],{},[1107,1491,1493],{"class":1109,"line":1492},71,[1107,1494,1495],{},"        Topic:   \"flow.user_registration.send_verification\",\n",[1107,1497,1499],{"class":1109,"line":1498},72,[1107,1500,1501],{},"        GroupID: \"flow.user_registration\",\n",[1107,1503,1505],{"class":1109,"line":1504},73,[1107,1506,1507],{},"        RetryPolicy: flowdsl.RetryPolicy{MaxAttempts: 3, Backoff: flowdsl.ExponentialBackoff, InitialDelay: 2 * time.Second},\n",[1107,1509,1511],{"class":1109,"line":1510},74,[1107,1512,1444],{},[1107,1514,1516],{"class":1109,"line":1515},75,[1107,1517,1518],{},"            out, err := nodes.SendVerificationEmail(ctx, flowdsl.NodeInput{Packet: packet})\n",[1107,1520,1522],{"class":1109,"line":1521},76,[1107,1523,1456],{},[1107,1525,1527],{"class":1109,"line":1526},77,[1107,1528,1529],{},"            return bus.Publish(ctx, \"flow.user_registration.publish_registered\", out.Packet(\"out\"))\n",[1107,1531,1533],{"class":1109,"line":1532},78,[1107,1534,1409],{},[1107,1536,1538],{"class":1109,"line":1537},79,[1107,1539,1473],{},[1107,1541,1542],{"class":1109,"line":963},[1107,1543,1133],{"emptyLinePlaceholder":1132},[1107,1545,1547],{"class":1109,"line":1546},81,[1107,1548,1549],{},"    \u002F\u002F Edge: SendVerificationEmail → PublishUserRegistered [stream, topic: users.registered]\n",[1107,1551,1553],{"class":1109,"line":1552},82,[1107,1554,1379],{},[1107,1556,1558],{"class":1109,"line":1557},83,[1107,1559,1560],{},"        Topic:   \"flow.user_registration.publish_registered\",\n",[1107,1562,1564],{"class":1109,"line":1563},84,[1107,1565,1501],{},[1107,1567,1569],{"class":1109,"line":1568},85,[1107,1570,1444],{},[1107,1572,1574],{"class":1109,"line":1573},86,[1107,1575,1576],{},"            return nodes.PublishUserRegistered(ctx, flowdsl.NodeInput{Packet: packet}, \"users.registered\")\n",[1107,1578,1580],{"class":1109,"line":1579},87,[1107,1581,1409],{},[1107,1583,1585],{"class":1109,"line":1584},88,[1107,1586,1473],{},[1107,1588,1590],{"class":1109,"line":1589},89,[1107,1591,1286],{},[1092,1593,1595],{"id":1594},"what-changes-when-you-edit-the-diagram","What changes when you edit the diagram",[1597,1598,1599,1615],"table",{},[1600,1601,1602],"thead",{},[1603,1604,1605,1609,1612],"tr",{},[1606,1607,1608],"th",{},"Change in Studio",[1606,1610,1611],{},"Generated diff",[1606,1613,1614],{},"Go code change needed",[1616,1617,1618,1638,1651,1663,1675,1690,1701],"tbody",{},[1603,1619,1620,1629,1635],{},[1621,1622,1623,1624,1054,1626,1628],"td",{},"Change ",[1004,1625,1053],{},[1004,1627,1057],{}," on an edge",[1621,1630,1631,1634],{},[1004,1632,1633],{},"bus.Subscribe(DurableConsumer{...})"," added",[1621,1636,1637],{},"None",[1603,1639,1640,1643,1649],{},[1621,1641,1642],{},"Add retry policy",[1621,1644,1645,1648],{},[1004,1646,1647],{},"RetryPolicy{...}"," in consumer",[1621,1650,1637],{},[1603,1652,1653,1656,1661],{},[1621,1654,1655],{},"Add idempotency key",[1621,1657,1658,1634],{},[1004,1659,1660],{},"IdempotencyKey: func(p) ...",[1621,1662,1637],{},[1603,1664,1665,1668,1673],{},[1621,1666,1667],{},"Change stream topic name",[1621,1669,1670,1648],{},[1004,1671,1672],{},"topic: \"new-name\"",[1621,1674,1637],{},[1603,1676,1677,1680,1687],{},[1621,1678,1679],{},"Add new node",[1621,1681,1682,1683,1686],{},"New field in ",[1004,1684,1685],{},"XxxFlowNodes"," struct",[1621,1688,1689],{},"Implement the handler (build fails until you do)",[1603,1691,1692,1695,1698],{},[1621,1693,1694],{},"Remove a node",[1621,1696,1697],{},"Field removed from struct",[1621,1699,1700],{},"Remove the handler assignment (build warns)",[1603,1702,1703,1706,1709],{},[1621,1704,1705],{},"Rewire edge from A→B to A→C",[1621,1707,1708],{},"Consumer topic changes",[1621,1710,1711],{},"None (if C handler already exists)",[994,1713],{},[986,1715,1717],{"id":1716},"module-node-contract","Module Node Contract",[982,1719,1720,1721,1724],{},"Each module that contributes nodes to flows implements ",[1004,1722,1723],{},"FlowNodeProvider",":",[1066,1726,1728],{"className":1101,"code":1727,"language":1103,"meta":1074,"style":1074},"\u002F\u002F go-framework\u002Fmodules\u002Fmodule.go (new interface)\n\n\u002F\u002F FlowNodeProvider is implemented by modules that register FlowDSL node handlers.\n\u002F\u002F The generated XxxFlowNodes struct is populated from these registrations.\ntype FlowNodeProvider interface {\n    \u002F\u002F FlowNodes returns all operationId → handler mappings this module provides.\n    \u002F\u002F Called at startup by flows.RegisterAll().\n    FlowNodes() map[string]flowdsl.AnyHandler\n}\n",[1004,1729,1730,1735,1739,1744,1749,1754,1759,1764,1769],{"__ignoreMap":1074},[1107,1731,1732],{"class":1109,"line":10},[1107,1733,1734],{},"\u002F\u002F go-framework\u002Fmodules\u002Fmodule.go (new interface)\n",[1107,1736,1737],{"class":1109,"line":16},[1107,1738,1133],{"emptyLinePlaceholder":1132},[1107,1740,1741],{"class":1109,"line":22},[1107,1742,1743],{},"\u002F\u002F FlowNodeProvider is implemented by modules that register FlowDSL node handlers.\n",[1107,1745,1746],{"class":1109,"line":51},[1107,1747,1748],{},"\u002F\u002F The generated XxxFlowNodes struct is populated from these registrations.\n",[1107,1750,1751],{"class":1109,"line":57},[1107,1752,1753],{},"type FlowNodeProvider interface {\n",[1107,1755,1756],{"class":1109,"line":102},[1107,1757,1758],{},"    \u002F\u002F FlowNodes returns all operationId → handler mappings this module provides.\n",[1107,1760,1761],{"class":1109,"line":108},[1107,1762,1763],{},"    \u002F\u002F Called at startup by flows.RegisterAll().\n",[1107,1765,1766],{"class":1109,"line":114},[1107,1767,1768],{},"    FlowNodes() map[string]flowdsl.AnyHandler\n",[1107,1770,1771],{"class":1109,"line":120},[1107,1772,1286],{},[1092,1774,1776],{"id":1775},"module-implementation-pattern","Module implementation pattern",[1066,1778,1781],{"className":1779,"code":1780,"language":1071},[1069],"backend\u002Fmodules\u002Fcommunity\u002F\n  handler.go      ← HTTP handlers (unchanged)\n  service.go      ← business logic (unchanged)\n  flows.go        ← NEW: FlowDSL node handler wrappers\n                         same Service calls, different transport adapter\n",[1004,1782,1780],{"__ignoreMap":1074},[1066,1784,1786],{"className":1101,"code":1785,"language":1103,"meta":1074,"style":1074},"\u002F\u002F backend\u002Fmodules\u002Fcommunity\u002Fflows.go\n\n\u002F\u002F FlowNodes implements modules.FlowNodeProvider.\nfunc (m *Module) FlowNodes() map[string]flowdsl.AnyHandler {\n    return map[string]flowdsl.AnyHandler{\n        \"receive_registration\":          flowdsl.Source(m.flowReceiveRegistration),\n        \"validate_registration_input\":   flowdsl.Router(m.flowValidateRegistration),\n        \"route_registration_by_type\":    flowdsl.Router(m.flowRouteByAccountType),\n        \"create_user_account\":           flowdsl.Node(m.flowCreateUserAccount),\n        \"send_verification_email\":       flowdsl.Node(m.flowSendVerificationEmail),\n        \"publish_user_registered\":       flowdsl.Publish(m.flowPublishUserRegistered),\n        \"reject_invalid_registration\":   flowdsl.Terminal(m.flowRejectInvalidRegistration),\n    }\n}\n\n\u002F\u002F flowCreateUserAccount wraps m.Service.Register — same logic as the HTTP handler,\n\u002F\u002F different input adapter (NodeInput instead of http.Request).\nfunc (m *Module) flowCreateUserAccount(ctx context.Context, in flowdsl.NodeInput) (flowdsl.NodeOutput, error) {\n    var req CommunityRegisterInput\n    if err := in.Decode(&req); err != nil {\n        return flowdsl.NodeOutput{}, err\n    }\n    member, user, err := m.Service.Register(ctx, &req)\n    if err != nil {\n        return flowdsl.NodeOutput{}, err\n    }\n    return flowdsl.Out(\"out\", map[string]any{\n        \"id\":           member.GetID().Hex(),\n        \"email\":        user.Email,\n        \"account_type\": string(member.AccountType),\n    }), nil\n}\n",[1004,1787,1788,1793,1797,1802,1807,1812,1817,1822,1827,1832,1837,1842,1847,1852,1856,1860,1865,1870,1875,1880,1885,1890,1894,1899,1904,1908,1912,1917,1922,1927,1932,1937],{"__ignoreMap":1074},[1107,1789,1790],{"class":1109,"line":10},[1107,1791,1792],{},"\u002F\u002F backend\u002Fmodules\u002Fcommunity\u002Fflows.go\n",[1107,1794,1795],{"class":1109,"line":16},[1107,1796,1133],{"emptyLinePlaceholder":1132},[1107,1798,1799],{"class":1109,"line":22},[1107,1800,1801],{},"\u002F\u002F FlowNodes implements modules.FlowNodeProvider.\n",[1107,1803,1804],{"class":1109,"line":51},[1107,1805,1806],{},"func (m *Module) FlowNodes() map[string]flowdsl.AnyHandler {\n",[1107,1808,1809],{"class":1109,"line":57},[1107,1810,1811],{},"    return map[string]flowdsl.AnyHandler{\n",[1107,1813,1814],{"class":1109,"line":102},[1107,1815,1816],{},"        \"receive_registration\":          flowdsl.Source(m.flowReceiveRegistration),\n",[1107,1818,1819],{"class":1109,"line":108},[1107,1820,1821],{},"        \"validate_registration_input\":   flowdsl.Router(m.flowValidateRegistration),\n",[1107,1823,1824],{"class":1109,"line":114},[1107,1825,1826],{},"        \"route_registration_by_type\":    flowdsl.Router(m.flowRouteByAccountType),\n",[1107,1828,1829],{"class":1109,"line":120},[1107,1830,1831],{},"        \"create_user_account\":           flowdsl.Node(m.flowCreateUserAccount),\n",[1107,1833,1834],{"class":1109,"line":181},[1107,1835,1836],{},"        \"send_verification_email\":       flowdsl.Node(m.flowSendVerificationEmail),\n",[1107,1838,1839],{"class":1109,"line":186},[1107,1840,1841],{},"        \"publish_user_registered\":       flowdsl.Publish(m.flowPublishUserRegistered),\n",[1107,1843,1844],{"class":1109,"line":191},[1107,1845,1846],{},"        \"reject_invalid_registration\":   flowdsl.Terminal(m.flowRejectInvalidRegistration),\n",[1107,1848,1849],{"class":1109,"line":197},[1107,1850,1851],{},"    }\n",[1107,1853,1854],{"class":1109,"line":203},[1107,1855,1286],{},[1107,1857,1858],{"class":1109,"line":214},[1107,1859,1133],{"emptyLinePlaceholder":1132},[1107,1861,1862],{"class":1109,"line":223},[1107,1863,1864],{},"\u002F\u002F flowCreateUserAccount wraps m.Service.Register — same logic as the HTTP handler,\n",[1107,1866,1867],{"class":1109,"line":229},[1107,1868,1869],{},"\u002F\u002F different input adapter (NodeInput instead of http.Request).\n",[1107,1871,1872],{"class":1109,"line":234},[1107,1873,1874],{},"func (m *Module) flowCreateUserAccount(ctx context.Context, in flowdsl.NodeInput) (flowdsl.NodeOutput, error) {\n",[1107,1876,1877],{"class":1109,"line":240},[1107,1878,1879],{},"    var req CommunityRegisterInput\n",[1107,1881,1882],{"class":1109,"line":246},[1107,1883,1884],{},"    if err := in.Decode(&req); err != nil {\n",[1107,1886,1887],{"class":1109,"line":251},[1107,1888,1889],{},"        return flowdsl.NodeOutput{}, err\n",[1107,1891,1892],{"class":1109,"line":257},[1107,1893,1851],{},[1107,1895,1896],{"class":1109,"line":1218},[1107,1897,1898],{},"    member, user, err := m.Service.Register(ctx, &req)\n",[1107,1900,1901],{"class":1109,"line":1223},[1107,1902,1903],{},"    if err != nil {\n",[1107,1905,1906],{"class":1109,"line":271},[1107,1907,1889],{},[1107,1909,1910],{"class":1109,"line":277},[1107,1911,1851],{},[1107,1913,1914],{"class":1109,"line":282},[1107,1915,1916],{},"    return flowdsl.Out(\"out\", map[string]any{\n",[1107,1918,1919],{"class":1109,"line":1243},[1107,1920,1921],{},"        \"id\":           member.GetID().Hex(),\n",[1107,1923,1924],{"class":1109,"line":1249},[1107,1925,1926],{},"        \"email\":        user.Email,\n",[1107,1928,1929],{"class":1109,"line":1254},[1107,1930,1931],{},"        \"account_type\": string(member.AccountType),\n",[1107,1933,1934],{"class":1109,"line":1260},[1107,1935,1936],{},"    }), nil\n",[1107,1938,1939],{"class":1109,"line":1266},[1107,1940,1286],{},[982,1942,1943,1944,1951,1952,1955,1956,1959],{},"The pattern: ",[1025,1945,1946,1947,1950],{},"HTTP handlers and FlowDSL node handlers share the same ",[1004,1948,1949],{},"Service"," layer."," Only the transport adapter differs — ",[1004,1953,1954],{},"httputil.ReadJSON(r, &input)"," becomes ",[1004,1957,1958],{},"in.Decode(&input)",".",[994,1961],{},[986,1963,1965],{"id":1964},"ci-pipeline","CI Pipeline",[1066,1967,1971],{"className":1968,"code":1969,"language":1970,"meta":1074,"style":1074},"language-yaml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# .github\u002Fworkflows\u002Fci.yml\n\n- name: Validate FlowDSL diagrams\n  run: go run .\u002Fcmd\u002Fflows\u002F validate\n  # Fails if any .flowdsl.yaml has invalid syntax or broken references\n\n- name: Regenerate flow bridge code\n  run: go run .\u002Fcmd\u002Fgenerate\u002F flows\n  # Reads backend\u002Fflows\u002F*.flowdsl.yaml → writes backend\u002Fflows\u002Fgen\u002F*_flow_gen.go\n\n- name: Check for uncommitted codegen drift\n  run: git diff --exit-code backend\u002Fflows\u002Fgen\u002F\n  # Fails if .flowdsl.yaml was changed without regenerating\n  # This enforces: diagram edit → commit → regenerate → commit gen → PR\n\n- name: Build\n  run: go build .\u002F...\n  # Fails if any operationId in a generated XxxFlowNodes struct is unimplemented\n\n- name: Test\n  run: go test .\u002F...\n","yaml",[1004,1972,1973,1979,1983,1999,2009,2014,2018,2029,2038,2043,2047,2058,2067,2072,2077,2081,2092,2101,2106,2110,2121],{"__ignoreMap":1074},[1107,1974,1975],{"class":1109,"line":10},[1107,1976,1978],{"class":1977},"sHwdD","# .github\u002Fworkflows\u002Fci.yml\n",[1107,1980,1981],{"class":1109,"line":16},[1107,1982,1133],{"emptyLinePlaceholder":1132},[1107,1984,1985,1989,1993,1995],{"class":1109,"line":22},[1107,1986,1988],{"class":1987},"sMK4o","-",[1107,1990,1992],{"class":1991},"swJcz"," name",[1107,1994,1724],{"class":1987},[1107,1996,1998],{"class":1997},"sfazB"," Validate FlowDSL diagrams\n",[1107,2000,2001,2004,2006],{"class":1109,"line":51},[1107,2002,2003],{"class":1991},"  run",[1107,2005,1724],{"class":1987},[1107,2007,2008],{"class":1997}," go run .\u002Fcmd\u002Fflows\u002F validate\n",[1107,2010,2011],{"class":1109,"line":57},[1107,2012,2013],{"class":1977},"  # Fails if any .flowdsl.yaml has invalid syntax or broken references\n",[1107,2015,2016],{"class":1109,"line":102},[1107,2017,1133],{"emptyLinePlaceholder":1132},[1107,2019,2020,2022,2024,2026],{"class":1109,"line":108},[1107,2021,1988],{"class":1987},[1107,2023,1992],{"class":1991},[1107,2025,1724],{"class":1987},[1107,2027,2028],{"class":1997}," Regenerate flow bridge code\n",[1107,2030,2031,2033,2035],{"class":1109,"line":114},[1107,2032,2003],{"class":1991},[1107,2034,1724],{"class":1987},[1107,2036,2037],{"class":1997}," go run .\u002Fcmd\u002Fgenerate\u002F flows\n",[1107,2039,2040],{"class":1109,"line":120},[1107,2041,2042],{"class":1977},"  # Reads backend\u002Fflows\u002F*.flowdsl.yaml → writes backend\u002Fflows\u002Fgen\u002F*_flow_gen.go\n",[1107,2044,2045],{"class":1109,"line":181},[1107,2046,1133],{"emptyLinePlaceholder":1132},[1107,2048,2049,2051,2053,2055],{"class":1109,"line":186},[1107,2050,1988],{"class":1987},[1107,2052,1992],{"class":1991},[1107,2054,1724],{"class":1987},[1107,2056,2057],{"class":1997}," Check for uncommitted codegen drift\n",[1107,2059,2060,2062,2064],{"class":1109,"line":191},[1107,2061,2003],{"class":1991},[1107,2063,1724],{"class":1987},[1107,2065,2066],{"class":1997}," git diff --exit-code backend\u002Fflows\u002Fgen\u002F\n",[1107,2068,2069],{"class":1109,"line":197},[1107,2070,2071],{"class":1977},"  # Fails if .flowdsl.yaml was changed without regenerating\n",[1107,2073,2074],{"class":1109,"line":203},[1107,2075,2076],{"class":1977},"  # This enforces: diagram edit → commit → regenerate → commit gen → PR\n",[1107,2078,2079],{"class":1109,"line":214},[1107,2080,1133],{"emptyLinePlaceholder":1132},[1107,2082,2083,2085,2087,2089],{"class":1109,"line":223},[1107,2084,1988],{"class":1987},[1107,2086,1992],{"class":1991},[1107,2088,1724],{"class":1987},[1107,2090,2091],{"class":1997}," Build\n",[1107,2093,2094,2096,2098],{"class":1109,"line":229},[1107,2095,2003],{"class":1991},[1107,2097,1724],{"class":1987},[1107,2099,2100],{"class":1997}," go build .\u002F...\n",[1107,2102,2103],{"class":1109,"line":234},[1107,2104,2105],{"class":1977},"  # Fails if any operationId in a generated XxxFlowNodes struct is unimplemented\n",[1107,2107,2108],{"class":1109,"line":240},[1107,2109,1133],{"emptyLinePlaceholder":1132},[1107,2111,2112,2114,2116,2118],{"class":1109,"line":246},[1107,2113,1988],{"class":1987},[1107,2115,1992],{"class":1991},[1107,2117,1724],{"class":1987},[1107,2119,2120],{"class":1997}," Test\n",[1107,2122,2123,2125,2127],{"class":1109,"line":251},[1107,2124,2003],{"class":1991},[1107,2126,1724],{"class":1987},[1107,2128,2129],{"class":1997}," go test .\u002F...\n",[982,2131,2132,2135,2136,2138],{},[1025,2133,2134],{},"The drift check is the key gate:"," if a developer edits a ",[1004,2137,1006],{}," in Studio but forgets to regenerate, CI catches it before merge. The generated files are committed to git, making the diagram's impact on wiring fully visible in PR diffs.",[994,2140],{},[986,2142,2144,2145],{"id":2143},"generator-cli-backendcmdflows","Generator CLI: ",[1004,2146,2147],{},"backend\u002Fcmd\u002Fflows\u002F",[1066,2149,2152],{"className":2150,"code":2151,"language":1071},[1069],"go run .\u002Fcmd\u002Fflows\u002F validate           Validates all .flowdsl.yaml files (spec correctness)\ngo run .\u002Fcmd\u002Fflows\u002F check              Checks all operationIds have registered handlers\ngo run .\u002Fcmd\u002Fflows\u002F generate           Regenerates backend\u002Fflows\u002Fgen\u002F*_flow_gen.go\ngo run .\u002Fcmd\u002Fflows\u002F scaffold \u003Cflow>    Generates handler stubs for unimplemented nodes in a flow\ngo run .\u002Fcmd\u002Fflows\u002F diff               Shows what a diagram edit changed in human-readable form\ngo run .\u002Fcmd\u002Fflows\u002F push               Uploads flows to Redelay cloud API\n",[1004,2153,2151],{"__ignoreMap":1074},[994,2155],{},[986,2157,2159],{"id":2158},"startup-wiring","Startup Wiring",[982,2161,2162,2163,2166],{},"The generated ",[1004,2164,2165],{},"RegisterAll"," function wires all flows using the node registry:",[1066,2168,2170],{"className":1101,"code":2169,"language":1103,"meta":1074,"style":1074},"\u002F\u002F backend\u002Fflows\u002Fgen\u002Fregister_all_gen.go  ← generated\npackage flows\n\nfunc RegisterAll(bus flowdsl.EventBus, reg *modules.Registry) {\n    \u002F\u002F Collect all node handlers from FlowNodeProvider modules\n    nodes := flowdsl.BuildNodeRegistry(reg)\n\n    RegisterUserRegistrationFlow(bus, UserRegistrationFlowNodes{\n        ReceiveRegistration:        nodes.Require(\"receive_registration\"),\n        ValidateRegistrationInput:  nodes.RequireRouter(\"validate_registration_input\"),\n        RouteRegistrationByType:    nodes.RequireRouter(\"route_registration_by_type\"),\n        CreateUserAccount:          nodes.Require(\"create_user_account\"),\n        SendVerificationEmail:      nodes.Require(\"send_verification_email\"),\n        PublishUserRegistered:      nodes.RequirePublish(\"publish_user_registered\"),\n        RejectInvalidRegistration:  nodes.RequireTerminal(\"reject_invalid_registration\"),\n    })\n\n    RegisterModuleSubmissionFlow(bus, ModuleSubmissionFlowNodes{ ... })\n    RegisterEmailNotificationFlow(bus, EmailNotificationFlowNodes{ ... })\n    \u002F\u002F ...\n}\n",[1004,2171,2172,2177,2181,2185,2190,2195,2200,2204,2209,2214,2219,2224,2229,2234,2239,2244,2248,2252,2257,2262,2267],{"__ignoreMap":1074},[1107,2173,2174],{"class":1109,"line":10},[1107,2175,2176],{},"\u002F\u002F backend\u002Fflows\u002Fgen\u002Fregister_all_gen.go  ← generated\n",[1107,2178,2179],{"class":1109,"line":16},[1107,2180,1127],{},[1107,2182,2183],{"class":1109,"line":22},[1107,2184,1133],{"emptyLinePlaceholder":1132},[1107,2186,2187],{"class":1109,"line":51},[1107,2188,2189],{},"func RegisterAll(bus flowdsl.EventBus, reg *modules.Registry) {\n",[1107,2191,2192],{"class":1109,"line":57},[1107,2193,2194],{},"    \u002F\u002F Collect all node handlers from FlowNodeProvider modules\n",[1107,2196,2197],{"class":1109,"line":102},[1107,2198,2199],{},"    nodes := flowdsl.BuildNodeRegistry(reg)\n",[1107,2201,2202],{"class":1109,"line":108},[1107,2203,1133],{"emptyLinePlaceholder":1132},[1107,2205,2206],{"class":1109,"line":114},[1107,2207,2208],{},"    RegisterUserRegistrationFlow(bus, UserRegistrationFlowNodes{\n",[1107,2210,2211],{"class":1109,"line":120},[1107,2212,2213],{},"        ReceiveRegistration:        nodes.Require(\"receive_registration\"),\n",[1107,2215,2216],{"class":1109,"line":181},[1107,2217,2218],{},"        ValidateRegistrationInput:  nodes.RequireRouter(\"validate_registration_input\"),\n",[1107,2220,2221],{"class":1109,"line":186},[1107,2222,2223],{},"        RouteRegistrationByType:    nodes.RequireRouter(\"route_registration_by_type\"),\n",[1107,2225,2226],{"class":1109,"line":191},[1107,2227,2228],{},"        CreateUserAccount:          nodes.Require(\"create_user_account\"),\n",[1107,2230,2231],{"class":1109,"line":197},[1107,2232,2233],{},"        SendVerificationEmail:      nodes.Require(\"send_verification_email\"),\n",[1107,2235,2236],{"class":1109,"line":203},[1107,2237,2238],{},"        PublishUserRegistered:      nodes.RequirePublish(\"publish_user_registered\"),\n",[1107,2240,2241],{"class":1109,"line":214},[1107,2242,2243],{},"        RejectInvalidRegistration:  nodes.RequireTerminal(\"reject_invalid_registration\"),\n",[1107,2245,2246],{"class":1109,"line":223},[1107,2247,1473],{},[1107,2249,2250],{"class":1109,"line":229},[1107,2251,1133],{"emptyLinePlaceholder":1132},[1107,2253,2254],{"class":1109,"line":234},[1107,2255,2256],{},"    RegisterModuleSubmissionFlow(bus, ModuleSubmissionFlowNodes{ ... })\n",[1107,2258,2259],{"class":1109,"line":240},[1107,2260,2261],{},"    RegisterEmailNotificationFlow(bus, EmailNotificationFlowNodes{ ... })\n",[1107,2263,2264],{"class":1109,"line":246},[1107,2265,2266],{},"    \u002F\u002F ...\n",[1107,2268,2269],{"class":1109,"line":251},[1107,2270,1286],{},[982,2272,2273,2274,1724],{},"In ",[1004,2275,2276],{},"cmd\u002Fapi\u002Fmain.go",[1066,2278,2280],{"className":1101,"code":2279,"language":1103,"meta":1074,"style":1074},"func main() {\n    inst, srv, err := server.Default()\n    if err != nil { log.Fatal(err) }\n\n    \u002F\u002F Wire all FlowDSL flows after module startup\n    if err := inst.AfterStart(func(ctx context.Context) error {\n        return flows.RegisterAll(inst.EventBus, inst.Modules)\n    }); err != nil {\n        log.Fatal(err)\n    }\n\n    if err := app.Run(inst, srv); err != nil { log.Fatal(err) }\n}\n",[1004,2281,2282,2287,2292,2297,2301,2306,2311,2316,2321,2326,2330,2334,2339],{"__ignoreMap":1074},[1107,2283,2284],{"class":1109,"line":10},[1107,2285,2286],{},"func main() {\n",[1107,2288,2289],{"class":1109,"line":16},[1107,2290,2291],{},"    inst, srv, err := server.Default()\n",[1107,2293,2294],{"class":1109,"line":22},[1107,2295,2296],{},"    if err != nil { log.Fatal(err) }\n",[1107,2298,2299],{"class":1109,"line":51},[1107,2300,1133],{"emptyLinePlaceholder":1132},[1107,2302,2303],{"class":1109,"line":57},[1107,2304,2305],{},"    \u002F\u002F Wire all FlowDSL flows after module startup\n",[1107,2307,2308],{"class":1109,"line":102},[1107,2309,2310],{},"    if err := inst.AfterStart(func(ctx context.Context) error {\n",[1107,2312,2313],{"class":1109,"line":108},[1107,2314,2315],{},"        return flows.RegisterAll(inst.EventBus, inst.Modules)\n",[1107,2317,2318],{"class":1109,"line":114},[1107,2319,2320],{},"    }); err != nil {\n",[1107,2322,2323],{"class":1109,"line":120},[1107,2324,2325],{},"        log.Fatal(err)\n",[1107,2327,2328],{"class":1109,"line":181},[1107,2329,1851],{},[1107,2331,2332],{"class":1109,"line":186},[1107,2333,1133],{"emptyLinePlaceholder":1132},[1107,2335,2336],{"class":1109,"line":191},[1107,2337,2338],{},"    if err := app.Run(inst, srv); err != nil { log.Fatal(err) }\n",[1107,2340,2341],{"class":1109,"line":197},[1107,2342,1286],{},[994,2344],{},[986,2346,2348],{"id":2347},"cloud-deployment-model","Cloud Deployment Model",[1092,2350,2352],{"id":2351},"today-git-deployed","Today (Git-deployed)",[1066,2354,2357],{"className":2355,"code":2356,"language":1071},[1069],"edit YAML in Studio → export to backend\u002Fflows\u002F → commit → CI runs generator\n→ go build → docker build → docker push → container restart picks up new wiring\n",[1004,2358,2356],{"__ignoreMap":1074},[1092,2360,2362],{"id":2361},"later-cloud-managed-flows","Later (Cloud-managed flows)",[1066,2364,2367],{"className":2365,"code":2366,"language":1071},[1069],"Studio → PUT \u002Fapi\u002Fflows\u002F{id} → Redelay cloud stores YAML\n→ cloud runs generator → cloud rebuilds and redeploys container automatically\n→ OR: container watches \u002Fflows\u002F endpoint and triggers self-restart on change\n",[1004,2368,2366],{"__ignoreMap":1074},[982,2370,2371],{},"The cloud layer owns:",[1019,2373,2374,2381,2386,2392],{},[1022,2375,2376,2377,2380],{},"Kafka topic provisioning for ",[1004,2378,2379],{},"stream"," edges",[1022,2382,2383,2384,2380],{},"MongoDB collection provisioning for ",[1004,2385,1057],{},[1022,2387,2388,2389,2380],{},"Redis stream provisioning for ",[1004,2390,2391],{},"ephemeral",[1022,2393,2394],{},"Auto-scaling workers proportional to queue depth per edge",[994,2396],{},[986,2398,2400],{"id":2399},"what-to-build-ordered","What to Build (Ordered)",[1597,2402,2403,2419],{},[1600,2404,2405],{},[1603,2406,2407,2410,2413,2416],{},[1606,2408,2409],{},"#",[1606,2411,2412],{},"Component",[1606,2414,2415],{},"Location",[1606,2417,2418],{},"Unblocks",[1616,2420,2421,2439,2458,2476,2492,2509,2527,2547,2566,2583,2600,2616,2631,2646],{},[1603,2422,2423,2426,2431,2436],{},[1621,2424,2425],{},"1",[1621,2427,2428,2430],{},[1004,2429,1723],{}," interface",[1621,2432,2433],{},[1004,2434,2435],{},"go-framework\u002Fmodules\u002Fmodule.go",[1621,2437,2438],{},"Module node registration",[1603,2440,2441,2444,2450,2455],{},[1621,2442,2443],{},"2",[1621,2445,2446,2449],{},[1004,2447,2448],{},"flowdsl.NodeInput\u002FOutput\u002FAnyHandler"," types",[1621,2451,2452],{},[1004,2453,2454],{},"go-framework\u002Fflowdsl\u002Fnode.go",[1621,2456,2457],{},"Handler function signatures",[1603,2459,2460,2463,2468,2473],{},[1621,2461,2462],{},"3",[1621,2464,2465],{},[1004,2466,2467],{},"flowdsl.NodeRegistry",[1621,2469,2470],{},[1004,2471,2472],{},"go-framework\u002Fflowdsl\u002Fregistry.go",[1621,2474,2475],{},"Node discovery at startup",[1603,2477,2478,2481,2484,2489],{},[1621,2479,2480],{},"4",[1621,2482,2483],{},"Flow YAML parser (FlowDSL.com format)",[1621,2485,2486],{},[1004,2487,2488],{},"go-framework\u002Fflowdsl\u002Fspec\u002F",[1621,2490,2491],{},"Generator reads flows",[1603,2493,2494,2497,2502,2506],{},[1621,2495,2496],{},"5",[1621,2498,2499],{},[1004,2500,2501],{},"cmd\u002Fflows\u002F validate",[1621,2503,2504],{},[1004,2505,2147],{},[1621,2507,2508],{},"CI gate on diagram validity",[1603,2510,2511,2514,2519,2524],{},[1621,2512,2513],{},"6",[1621,2515,2516],{},[1004,2517,2518],{},"cmd\u002Fgenerate\u002F flows",[1621,2520,2521],{},[1004,2522,2523],{},"backend\u002Fcmd\u002Fgenerate\u002F",[1621,2525,2526],{},"Codegen from YAML",[1603,2528,2529,2532,2538,2544],{},[1621,2530,2531],{},"7",[1621,2533,2534,2535,2537],{},"Generated ",[1004,2536,1685],{}," structs",[1621,2539,2540,2543],{},[1004,2541,2542],{},"backend\u002Fflows\u002Fgen\u002F"," (generated)",[1621,2545,2546],{},"Compile-time enforcement",[1603,2548,2549,2552,2558,2563],{},[1621,2550,2551],{},"8",[1621,2553,2554,2557],{},[1004,2555,2556],{},"flows.go"," node wrappers per module",[1621,2559,2560],{},[1004,2561,2562],{},"backend\u002Fmodules\u002F*\u002Fflows.go",[1621,2564,2565],{},"Handlers wired to flows",[1603,2567,2568,2571,2576,2580],{},[1621,2569,2570],{},"9",[1621,2572,2573],{},[1004,2574,2575],{},"flows.RegisterAll()",[1621,2577,2578,2543],{},[1004,2579,2542],{},[1621,2581,2582],{},"Startup wiring",[1603,2584,2585,2588,2593,2597],{},[1621,2586,2587],{},"10",[1621,2589,2590],{},[1004,2591,2592],{},"cmd\u002Fflows\u002F scaffold",[1621,2594,2595],{},[1004,2596,2147],{},[1621,2598,2599],{},"Auto-stub for new nodes",[1603,2601,2602,2605,2608,2613],{},[1621,2603,2604],{},"11",[1621,2606,2607],{},"Direct edge execution",[1621,2609,2610],{},[1004,2611,2612],{},"go-framework\u002Fflowdsl\u002F",[1621,2614,2615],{},"Simplest flow paths",[1603,2617,2618,2621,2624,2628],{},[1621,2619,2620],{},"12",[1621,2622,2623],{},"Durable edge execution (go-events)",[1621,2625,2626],{},[1004,2627,2612],{},[1621,2629,2630],{},"Reliable business paths",[1603,2632,2633,2636,2639,2643],{},[1621,2634,2635],{},"13",[1621,2637,2638],{},"Stream\u002FEphemeral edge execution",[1621,2640,2641],{},[1004,2642,2612],{},[1621,2644,2645],{},"Full delivery mode support",[1603,2647,2648,2651,2657,2662],{},[1621,2649,2650],{},"14",[1621,2652,2653,2656],{},[1004,2654,2655],{},"\u002Fapi\u002Fflows\u002F"," module + Studio integration",[1621,2658,2659],{},[1004,2660,2661],{},"go-framework\u002Fmodules\u002Fflows\u002F",[1621,2663,2664],{},"Cloud diagram management",[2666,2667,2668],"style",{},"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 .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 .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}",{"title":1074,"searchDepth":16,"depth":16,"links":2670},[2671,2672,2673,2674,2675,2680,2683,2684,2686,2687,2691],{"id":988,"depth":16,"text":989},{"id":998,"depth":16,"text":999},{"id":1016,"depth":16,"text":1017},{"id":1063,"depth":16,"text":1064},{"id":1079,"depth":16,"text":1080,"children":2676},[2677,2679],{"id":1094,"depth":22,"text":2678},"Example: user_registration_flow_gen.go",{"id":1594,"depth":22,"text":1595},{"id":1716,"depth":16,"text":1717,"children":2681},[2682],{"id":1775,"depth":22,"text":1776},{"id":1964,"depth":16,"text":1965},{"id":2143,"depth":16,"text":2685},"Generator CLI: backend\u002Fcmd\u002Fflows\u002F",{"id":2158,"depth":16,"text":2159},{"id":2347,"depth":16,"text":2348,"children":2688},[2689,2690],{"id":2351,"depth":22,"text":2352},{"id":2361,"depth":22,"text":2362},{"id":2399,"depth":16,"text":2400},"md",null,{},{"order":197,"icon":198},{"title":194,"description":984},"V2IMR1TVP2aKs8uWHLbUw-6sDgZDI5m6R9xfNa_9GSM",[2699,2701],{"title":188,"path":189,"stem":190,"description":2700,"order":191,"icon":192,"children":-1},"Real-world FlowDSL flow definitions — from minimal single-event services to multi-module pipelines.",{"title":200,"path":201,"stem":202,"description":2702,"order":203,"icon":204,"children":-1},"Node.js SDK for Redelay — coming soon.",1790332226537]