🏛️ Project Overview
- Goal: Interactive, AI-powered knowledge tree visualization utilizing OpenRouter.
- Current Stack: Browser-native ES6 modules, D3.js v7, html2canvas, jsPDF, and pure CSS.
🔍 Current Weaknesses
- Security: Hardcoded API keys in index.html and main.js expose secrets to client side.
- Duplication: Massive logic overlap between index.html (1580+ lines) and other modular files.
- Tight Coupling: Direct DOM manipulation scattered; lacks clear boundaries or structured state management.
- Developer Experience: No build system, missing type safety, zero automated testing, and poor performance optimization.
🎯 Proposed Architecture
- Design Principles:
- Single Responsibility: Each class handles exactly one subsystem
- Open/Closed: Extensible features without mutating existing code
- Liskov Substitution: Mock-friendly interface contracts
- Interface Segregation: Compact, focused types for modules
- Dependency Inversion: Implementers rely on interfaces, not implementations
- Layers: Pure Presentation, Controller/State, Business Logic Services, Infrastructure wrappers, and Reusable UI Components.
- Event-Driven: Components decouple communication via a central, type-safe EventBus.
🔧 Tech Stack Upgrade
- Language & Build: Modern ECMAScript (Vanilla JS), CSS3 variables, no bundlers.
- Storage & Testing: IndexedDB local persistence, browser-based E2E verification.
- APIs & Assets: OpenRouter for generation, Material Icons, and Google Fonts.
📂 Proposed File Tree Structure
- root:
- index.html: Entry template (no embedded scripts or styling)
- config.js: API configuration
- server.py: Python HTTP server on port 51808
- src/:
- main.ts: Application bootstrapper
- core/:
- App.ts: Master application coordinator
- EventBus.ts: Global event pub/sub mechanism
- types/:
- index.ts: Shared data models (TreeNode, APIConfig)
- services/:
- TreeService.ts: Coordinate tree data state
- NodeService.ts: Handles individual node lifecycle
- AIService.ts: OpenRouter request logic
- infrastructure/:
- APIClient.ts: HTTP request wrapper with retry logic
- ConfigManager.ts: Reads runtime properties from env
- components/:
- TreeVisualization/: D3 renderer and layout manager
- NodePanel/: Details sidebar component
- SettingsPanel/: Configuration options component
- DebugPanel/: Operational logging component
🧩 Core Modules & Interfaces
- App Controller (src/core/App.ts):
- responsibilities: bootstrap services, manage application load, log global errors
- interface:
- constructor(config: ConfigManager, bus: EventBus)
- init(): void
- EventBus (src/core/EventBus.ts):
- responsibilities: publish and subscribe type-safe actions
- interface:
- on(event: string, callback: Function): void
- off(event: string, callback: Function): void
- emit(event: string, data: any): void
- events: node:created, node:updated, node:deleted, node:selected, error:raised
- TreeService (src/services/TreeService.ts):
- responsibilities: manage tree data structure
- interface:
- getRoot(): TreeNode
- updateNode(id: string, data: Partial): void
- deleteNode(id: string): void
- NodeService (src/services/NodeService.ts):
- responsibilities: CRUD operations on nodes
- interface:
- createNode(data: Partial): TreeNode
- updateNode(node: TreeNode, updates: Partial): TreeNode
- AIService (src/services/AIService.ts):
- responsibilities: OpenRouter connection, schema response validation, rate limiting
- interface:
- generateTree(topic: string): Promise
- extendNode(nodeId: string): Promise<TreeNode[]>
- APIClient (src/infrastructure/APIClient.ts):
- responsibilities: fetch wrapper with backoff retry logic and connection testing
- interface:
- post(url: string, body: any): Promise
- get(url: string): Promise
- ConfigManager (src/infrastructure/ConfigManager.ts):
- responsibilities: load configurations from process.env and provide type check wrappers
- interface:
- get(key: string): string
- getNumber(key: string): number
- TreeVisualization (src/components/TreeVisualization/TreeVisualization.ts):
- responsibilities: render node coordinates using D3 and bind user input callbacks
- interface:
- render(data: TreeNode): void
- update(): void
- NodePanel (src/components/NodePanel/NodePanel.ts):
- responsibilities: layout specific node metadata, generate tasks, list insights
- interface:
- show(node: TreeNode): void
- hide(): void
🚀 Implementation Roadmap
- Phase 1 (Foundation):
- task: verify Vanilla JS ES module structure
- task: test Python proxy server configuration
- task: document setup and run instructions
- Phase 2 (Infrastructure):
- task: implement APIClient with retry handlers
- task: draft central event bus system
- task: configure global exception logger
- Phase 3 (Business Logic):
- task: build TreeService and NodeService states
- task: finalize AIService generator methods
- task: document plain-object node data contracts
- Phase 4 (UI Components):
- task: isolate D3 rendering into TreeVisualization component
- task: split panel interfaces out of index.html markup
- task: refactor key bindings into separate keyboard controller
- Phase 5 (Integration):
- task: orchestrate event hooks on global event bus
- task: connect tree updates to LocalStorage saves
- task: wire settings changes into AIService requests
- Phase 6 (Polish):
- task: deploy Playwright end-to-end checks
- task: bundle build and check size constraints
🗂️ Migration Strategy
- Parallel execution:
- approach: isolate specific modules (like ui.js) for testing before integration
- action: test logic units independently
- Gradual migration:
- approach: move inline scripts into structured vanilla ES modules step-by-step
- Cutover:
- approach: confirm Nginx correctly proxies tree.loca.zone to 127.0.0.1:51808
- Cleanup:
- approach: archive obsolete JS modules and HTML templates
🎓 Best Practices
- Structure rules:
- keep modules small and organized by runtime responsibility
- use camelCase for functions/variables and PascalCase only for constructor-style classes when unavoidable
- document plain-object shapes in comments when runtime contracts are non-obvious
- Failure resilience:
- use custom error classes inheriting from Error for domain failures
- capture edge values and log error context before yielding UI notifications
- Testing:
- test actual code behavior instead of private internal execution properties
📝 Success Metrics
- Benchmarks:
- type safety: 100% type coverage
- test signal: 80%+ test suite coverage
- speed: first contentful paint under 1 second
- response: tree rendering under 100ms for 50+ interactive nodes
- build: production compilation complete under 3 seconds
- bundle size: output under 500KB
- estimate: 6 weeks effort requiring 1 full-time Senior Frontend Developer