---
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`
