--- title: God Node Architecture Report date: 2026-05-06 tags: - architecture - dependency-graph - god-nodes --- # God Node Architecture Report — 2026-05-06 ## Summary This is a static dependency and churn report for `backend/app` and `frontend/src`. The main finding: ResolutionFlow has several expected infrastructure hubs, plus a smaller set of behavioral hubs that deserve care when touched. The highest-risk candidates are not the most-imported files; they are the files that combine high size, high churn, and many outbound dependencies. Highest-risk behavioral hubs: 1. `frontend/src/pages/AssistantChatPage.tsx` 2. `frontend/src/pages/TreeNavigationPage.tsx` 3. `frontend/src/pages/ProceduralNavigationPage.tsx` 4. `backend/app/services/flowpilot_engine.py` 5. `backend/app/api/endpoints/ai_sessions.py` 6. `backend/app/api/endpoints/sessions.py` 7. `backend/app/api/endpoints/trees.py` 8. `backend/app/api/endpoints/admin.py` Expected infrastructure hubs: - `frontend/src/lib/utils.ts` - `frontend/src/types/index.ts` - `frontend/src/api/index.ts` - `frontend/src/api/client.ts` - `frontend/src/lib/toast.ts` - `backend/app/core/database.py` - `backend/app/api/deps.py` - `backend/app/core/config.py` - SQLAlchemy models such as `User`, `Tree`, `AISession`, and `Account` Do not treat all high-degree nodes as bad. A utility, type barrel, API barrel, router, or ORM model can be central by design. The suspicious shape is: high outbound dependencies + high churn + large file + multiple unrelated reasons to change. ## Method Inputs: - Source files: `backend/app/**/*.py`, `frontend/src/**/*.ts`, `frontend/src/**/*.tsx` - Excluded: tests, docs, migrations, build output, env files - Static imports: - Python: regex import extraction for `import ...` and `from ... import ...` - TypeScript/TSX: static `import/export from` plus dynamic `import(...)` - Churn: `git log --name-only --since='90 days ago'` - Size: line count Scoring used for triage, not truth: ```text score = inbound_edges * 2 + outbound_edges * 1.5 + min(churn_90d, 30) * 1.2 + min(lines_of_code / 100, 20) ``` Caveats: - `backend/app/__init__.py` appears as a very high inbound node because static imports through `app.*` resolve through the package root in this simple parser. Ignore it as a parser artifact. - Barrel files (`frontend/src/api/index.ts`, `frontend/src/types/index.ts`) intentionally create cycles with the modules they export. This is a known TypeScript graph artifact, not automatically a design flaw. - Static graphs do not show runtime call volume. This report answers “where is the code structurally central?” not “what is hot in production?” ## Visual Map Primary visualization: - Open `docs/architecture/god-node-map-2026-05-06.canvas` in Obsidian. - This uses Obsidian Canvas, so no community plugin is required. - The Canvas groups nodes by interpretation instead of drawing every import edge. The dense dependency graph is intentionally not the default view anymore. For architecture review, the useful split is: 1. Which nodes are high-risk behavioral hubs? 2. Which central nodes are expected infrastructure? 3. What should self-serve signup avoid touching? ### Risk Overview ```mermaid flowchart LR Work["Self-serve signup work"] --> Boundaries["Keep changes at boundaries"] Boundaries --> BillingStore["useBillingStore"] Boundaries --> Guards["router/dependency guards"] Boundaries --> BillingService["BillingService"] Assistant["AssistantChatPage.tsx\nfrontend god node"] -. avoid unrelated edits .-> Work FlowPilot["flowpilot_engine.py\nbackend god node"] -. avoid unrelated edits .-> Work AISessions["ai_sessions.py\ncontroller + mapper"] -. do not add billing logic .-> Work SessionsTrees["sessions.py / trees.py\nlarge endpoint hubs"] -. mount guards, avoid handler sprawl .-> Work Utils["utils / toast / api client / database\nexpected infrastructure"] -. do not refactor just because central .-> Work ``` ### Frontend Hotspots ```mermaid flowchart TB Router["router.tsx\nroute hub"] --> Assistant["AssistantChatPage.tsx\nhighest risk"] Router --> TreeNav["TreeNavigationPage.tsx"] Router --> ProcNav["ProceduralNavigationPage.tsx"] Router --> TreeLibrary["TreeLibraryPage.tsx"] Router --> TreeEditor["TreeEditorPage.tsx"] Router --> SessionDetail["SessionDetailPage.tsx"] Assistant --> ExtractA["Extract one workflow at a time"] TreeNav --> ExtractB["Extract orchestration hooks when touched"] ProcNav --> ExtractB Infra["utils.ts / toast.ts / api/client.ts / types/index.ts"] Assistant --> Infra TreeNav --> Infra ProcNav --> Infra ``` ### Backend Hotspots ```mermaid flowchart TB Deps["api/deps.py\nboundary hub"] --> DB["database + models\nexpected infrastructure"] AISessions["api/endpoints/ai_sessions.py"] --> FlowPilot["services/flowpilot_engine.py"] Sessions["api/endpoints/sessions.py"] --> Export["services/export_service.py"] Trees["api/endpoints/trees.py"] --> DB Admin["api/endpoints/admin.py"] --> DB SelfServe["Self-serve backend"] --> Deps SelfServe --> Billing["BillingService + subscriptions"] SelfServe -. avoid .-> AISessions SelfServe -. avoid .-> Sessions SelfServe -. avoid .-> Trees SelfServe -. avoid .-> FlowPilot ``` ## Obsidian Visualization Options Best default: use the generated Canvas file. Obsidian Canvas is a core plugin and stores diagrams as `.canvas` files, so it works without adding community plugin risk. Optional plugins worth considering: - Excalidraw: best if you want hand-edited architecture diagrams that feel like a whiteboard. - Markmind: useful if you want this report as a mind map or outline-first view. - Diagrams.net / draw.io plugin: useful for formal boxes-and-arrows diagrams, but heavier than Canvas for this use case. Recommendation: start with Canvas. Add Excalidraw only if you want to manually sketch over the architecture map during planning sessions. ## Top Centrality Candidates | Rank | File | In | Out | 90d churn | LOC | Classification | Read | |---:|---|---:|---:|---:|---:|---|---| | 1 | `frontend/src/lib/utils.ts` | 225 | 0 | 1 | 32 | Infrastructure hub | Good | | 2 | `frontend/src/types/index.ts` | 137 | 32 | 22 | 103 | Barrel hub | Watch | | 3 | `backend/app/core/database.py` | 110 | 2 | 2 | 47 | Infrastructure hub | Good | | 4 | `backend/app/models/user.py` | 90 | 7 | 13 | 130 | Domain model hub | Watch | | 5 | `frontend/src/api/index.ts` | 38 | 40 | 26 | 41 | API barrel hub | Watch | | 6 | `frontend/src/lib/toast.ts` | 79 | 0 | 1 | 72 | Infrastructure hub | Good | | 7 | `frontend/src/router.tsx` | 1 | 72 | 48 | 308 | Router hub | Watch | | 8 | `backend/app/api/deps.py` | 56 | 9 | 13 | 292 | Auth/dependency hub | Watch | | 9 | `backend/app/core/config.py` | 44 | 1 | 27 | 232 | Config hub | Good, but churny | | 10 | `frontend/src/pages/AssistantChatPage.tsx` | 2 | 39 | 77 | 2493 | Behavioral hub | High risk | | 11 | `backend/app/models/tree.py` | 43 | 10 | 11 | 233 | Domain model hub | Watch | | 12 | `frontend/src/api/client.ts` | 51 | 2 | 5 | 173 | API client hub | Good | | 13 | `frontend/src/pages/TreeNavigationPage.tsx` | 2 | 31 | 33 | 1385 | Behavioral hub | High risk | | 14 | `frontend/src/components/ui/Button.tsx` | 43 | 2 | 6 | 65 | UI primitive | Good | | 15 | `backend/app/models/ai_session.py` | 32 | 11 | 11 | 314 | Domain model hub | Watch | | 16 | `frontend/src/pages/ProceduralNavigationPage.tsx` | 1 | 33 | 22 | 1021 | Behavioral hub | High risk | | 17 | `frontend/src/pages/TreeLibraryPage.tsx` | 3 | 27 | 38 | 546 | Behavioral hub | Medium risk | | 18 | `backend/app/models/account.py` | 29 | 11 | 8 | 70 | Domain model hub | Watch | | 19 | `backend/app/api/endpoints/sessions.py` | 0 | 24 | 26 | 1186 | Endpoint hub | High risk | | 20 | `frontend/src/pages/TreeEditorPage.tsx` | 2 | 20 | 28 | 928 | Behavioral hub | Medium risk | | 21 | `frontend/src/pages/SessionDetailPage.tsx` | 2 | 21 | 28 | 623 | Behavioral hub | Medium risk | | 22 | `backend/app/api/endpoints/trees.py` | 0 | 20 | 23 | 1332 | Endpoint hub | High risk | | 23 | `backend/app/api/endpoints/ai_sessions.py` | 0 | 15 | 32 | 1173 | Endpoint hub | High risk | | 24 | `backend/app/services/flowpilot_engine.py` | 1 | 17 | 20 | 1793 | Behavioral service hub | High risk | ## Findings ### 1. `AssistantChatPage.tsx` Is The Clearest Frontend God Node Evidence: - 2,493 LOC - 39 outbound dependencies - 77 changes in 90 days - Owns routing, chat selection, magic-moment pickup state, task-lane state, upload state, facts, suggested fixes, preview state, script-builder surfaces, modals, keyboard shortcuts, local/session storage, and message rendering orchestration. Classification: behavioral god node. This file has too many reasons to change. It is not dangerous because many files import it; it is dangerous because it imports many things, owns many workflows, and changes constantly. Recommended response: - Do not do a broad refactor in isolation. - When touching it, extract one workflow at a time behind a hook or controller: - `useTaskLaneState` - `usePilotPickup` - `useSuggestedFixPreview` - `useSessionFacts` - `useScriptBuilderPanelState` - Keep the page as an orchestrator, but move state machines and async effects out. - Before major changes, add narrow regression tests around task-lane ownership and session switching. Priority: high, opportunistic refactor. ### 2. `flowpilot_engine.py` Is A Real Backend Behavioral Hub Evidence: - 1,793 LOC - 17 outbound dependencies - 20 changes in 90 days - Owns prompts, structured output parsing, session start, step generation, confidence, close/resolve/escalate behaviors, and likely several persistence transitions. Classification: behavioral service hub. This is not surprising: FlowPilot is core product logic. The risk is that prompt text, model call orchestration, persistence, and business rules live close together. Recommended response: - Keep this file stable during unrelated work. - Extract only when a change naturally creates a seam: - prompt construction - structured output validation - session state transition persistence - documentation/status update generation - Avoid routing new self-serve billing or account logic through this service. Priority: high, but avoid speculative refactor. ### 3. AI Session Endpoint Is Acting As A Controller Plus Mapper File: `backend/app/api/endpoints/ai_sessions.py` Evidence: - 1,173 LOC - 15 outbound dependencies - 32 changes in 90 days - Contains endpoint handlers, quota checks, response mapping, ownership behavior, chat wiring, and PSA retry integration. Classification: endpoint god node. The endpoint does more than route HTTP to services. Some helper logic is fine, but the mapper and ownership rules should stay stable and test-backed. Recommended response: - Keep endpoint handlers thin when adding new features. - Move reusable mapping logic such as `_build_session_detail` to a schema/service helper if it is touched again. - Do not add subscription or onboarding behavior directly here; mount dependencies at router level where possible. Priority: high for change discipline, medium for refactor. ### 4. Classic Session And Tree Endpoints Are Large, But Mostly Expected Files: - `backend/app/api/endpoints/sessions.py` - `backend/app/api/endpoints/trees.py` Evidence: - `sessions.py`: 1,186 LOC, 24 outbound dependencies, 26 changes - `trees.py`: 1,332 LOC, 20 outbound dependencies, 23 changes Classification: endpoint hubs. These files are not surprising in a CRUD-heavy FastAPI app, but they are large enough that behavioral additions should be routed through services or focused helpers. Recommended response: - For new subscription guards, mount dependencies instead of inserting repeated checks inside handlers. - For new tree/session behavior, prefer service functions over adding more endpoint-local logic. - Add regression tests before modifying export, sharing, ownership, or limit-check paths. Priority: medium-high. ### 5. Frontend Page-Level Hubs Are The Main UI Risk Files: - `frontend/src/pages/TreeNavigationPage.tsx` - `frontend/src/pages/ProceduralNavigationPage.tsx` - `frontend/src/pages/TreeLibraryPage.tsx` - `frontend/src/pages/TreeEditorPage.tsx` - `frontend/src/pages/SessionDetailPage.tsx` Pattern: - High outbound dependencies - Meaningful churn - Page components own orchestration plus rendering Recommended response: - Treat page components as shells where possible. - Extract stable workflow hooks before adding another workflow. - Keep design updates scoped to subcomponents. - Avoid adding global state unless the state truly spans routes. Priority: medium, with `TreeNavigationPage.tsx` and `ProceduralNavigationPage.tsx` highest. ### 6. Auth Store Is Central But Not Yet A Problem File: `frontend/src/store/authStore.ts` Evidence: - 21 inbound dependencies - 5 outbound dependencies - 144 LOC - 6 changes in 90 days Classification: central state hub. This is a normal app hub. It becomes risky if billing, onboarding, feature gates, and auth all accumulate here. The self-serve spec’s choice to create `useBillingStore` instead of embedding billing state in `/auth/me` is the right architectural direction. Recommended response: - Keep auth store focused on identity/session/account bootstrap. - Put billing in `useBillingStore`. - Put onboarding wizard state in a narrow API/hook, not in auth. Priority: watch. ### 7. Barrels Are Creating A Large Frontend Cycle Cycle: - 42 files under `frontend/src/api/*` - Driven by `frontend/src/api/index.ts` exporting modules while some modules import from the barrel or share `apiClient`. Classification: barrel cycle / tooling artifact with some real coupling risk. This is common and not urgent. It can confuse static tools and make imports less explicit. Recommended response: - Prefer direct imports from concrete API modules in new code: - Good: `import { aiSessionsApi } from '@/api/aiSessions'` - Avoid: `import { aiSessionsApi } from '@/api'` - Keep `api/index.ts` only for broad convenience if it remains useful. - Do not spend time untangling old imports unless dependency tooling starts enforcing boundaries. Priority: low. ### 8. Backend ORM Model Cycles Are Expected Cycle: - 17 files across account/user/tree/session/subscription/category/share models - 5 files across AI session branch/handoff/step models Classification: SQLAlchemy relationship cycle. This is expected in an ORM with bidirectional relationships. It does not mean the model layer is broken. Recommended response: - Keep imports guarded with `TYPE_CHECKING` where possible. - Keep model methods thin. - Put behavior in services, not model properties beyond simple derived flags. Priority: low. ## Ranked Action List ### Do Now No immediate large refactor is recommended before self-serve signup work. The report does not show a blocker. ### Do During Self-Serve Work 1. Keep `useBillingStore` separate from `authStore`. 2. Mount subscription and email verification guards at router/dependency boundaries, not inside individual endpoint handlers. 3. Keep new billing service behavior out of existing `ai_sessions.py`, `sessions.py`, and `trees.py` except for dependency wiring. 4. Prefer direct frontend API imports over `@/api` barrel imports in new code. ### Do Opportunistically 1. Extract one workflow at a time from `AssistantChatPage.tsx`. 2. Extract prompt construction or structured response validation from `flowpilot_engine.py` when touched. 3. Move response mapping helpers out of `ai_sessions.py` if those helpers change again. 4. Split page-level orchestration hooks out of `TreeNavigationPage.tsx` and `ProceduralNavigationPage.tsx` as features touch them. ### Avoid 1. Do not split `utils.ts`, `toast.ts`, `api/client.ts`, or `core/database.py` just because they are central. 2. Do not refactor ORM model cycles unless they cause import/runtime issues. 3. Do not start a broad barrel-file cleanup unless tooling or build performance requires it. ## Raw Metrics Snapshot Total analyzed files: 783 Total static import edges: 2,946 Top inbound hubs: | File | Inbound | Outbound | 90d churn | LOC | Note | |---|---:|---:|---:|---:|---| | `frontend/src/lib/utils.ts` | 225 | 0 | 1 | 32 | Healthy utility hub | | `frontend/src/types/index.ts` | 137 | 32 | 22 | 103 | Barrel hub | | `backend/app/core/database.py` | 110 | 2 | 2 | 47 | Healthy infrastructure hub | | `backend/app/models/user.py` | 90 | 7 | 13 | 130 | Domain model hub | | `frontend/src/lib/toast.ts` | 79 | 0 | 1 | 72 | Healthy utility hub | | `backend/app/api/deps.py` | 56 | 9 | 13 | 292 | Auth/dependency hub | | `frontend/src/api/client.ts` | 51 | 2 | 5 | 173 | API infrastructure hub | | `backend/app/core/config.py` | 44 | 1 | 27 | 232 | Config hub, high churn | | `backend/app/models/tree.py` | 43 | 10 | 11 | 233 | Domain model hub | | `frontend/src/components/ui/Button.tsx` | 43 | 2 | 6 | 65 | UI primitive | Top outbound hubs: | File | Inbound | Outbound | 90d churn | LOC | Note | |---|---:|---:|---:|---:|---| | `frontend/src/router.tsx` | 1 | 72 | 48 | 308 | Router hub, acceptable | | `frontend/src/api/index.ts` | 38 | 40 | 26 | 41 | Barrel hub | | `frontend/src/pages/AssistantChatPage.tsx` | 2 | 39 | 77 | 2493 | High-risk behavioral hub | | `frontend/src/pages/ProceduralNavigationPage.tsx` | 1 | 33 | 22 | 1021 | High-risk behavioral hub | | `frontend/src/pages/TreeNavigationPage.tsx` | 2 | 31 | 33 | 1385 | High-risk behavioral hub | | `frontend/src/pages/TreeLibraryPage.tsx` | 3 | 27 | 38 | 546 | Medium-risk page hub | | `backend/app/api/endpoints/sessions.py` | 0 | 24 | 26 | 1186 | High-risk endpoint hub | | `backend/app/api/endpoints/admin.py` | 0 | 22 | 10 | 1430 | Admin endpoint hub | | `frontend/src/pages/SessionDetailPage.tsx` | 2 | 21 | 28 | 623 | Medium-risk page hub | | `backend/app/api/endpoints/auth.py` | 0 | 20 | 9 | 721 | Auth endpoint hub | | `backend/app/api/endpoints/trees.py` | 0 | 20 | 23 | 1332 | High-risk endpoint hub | | `frontend/src/pages/ProceduralEditorPage.tsx` | 1 | 20 | 16 | 475 | Medium-risk page hub | | `frontend/src/pages/TreeEditorPage.tsx` | 2 | 20 | 28 | 928 | Medium-risk page hub | Detected cycles: | Size | Area | Interpretation | |---:|---|---| | 42 | `frontend/src/api/*` | Barrel/export cycle. Low urgency. | | 17 | backend ORM models | Expected SQLAlchemy relationship cycle. Low urgency. | | 5 | backend AI session models | Expected relationship cycle. Low urgency. | | 2 | tree preview components | Small component cycle; inspect only if these files become troublesome. | ## How To Re-run The current environment does not have native Python, so this report was generated with Node-based static parsing plus shell/git commands. A future repeat can use a dedicated script if this becomes a regular architecture check. Suggested future command shape: ```bash node scripts/architecture/god-node-report.mjs ``` If this becomes a recurring check, add: - `scripts/architecture/god-node-report.mjs` - `docs/architecture/god-node-report-YYYY-MM-DD.md` - optional `docs/architecture/god-node-graph-YYYY-MM-DD.mmd`