# 📊 Component Size Violation Analysis & Refactoring Guide **Document Date:** December 25, 2025 **Total Violations:** 8 components, 4,146 LOC over limit **Target State:** 0 violations, 325 LOC total --- ## 📈 Complete Violation List ### Tier 1: Critical (800+ LOC) | # | Component | Path | Current | Target | Reduction | Priority | |---|-----------|------|---------|--------|-----------|----------| | 1 | GitHubActionsFetcher | `src/components/` | 887 | 95 | 89% ↓ | 🔴 P0 | | 2 | NerdModeIDE | `src/components/` | 733 | 110 | 85% ↓ | 🔴 P0 | | 3 | LuaEditor | `src/components/` | 686 | 120 | 82% ↓ | 🔴 P0 | ### Tier 2: High (500-700 LOC) | # | Component | Path | Current | Target | Reduction | Priority | |---|-----------|------|---------|--------|-----------|----------| | 4 | SchemaEditor | `src/components/` | 520 | 100 | 80% ↓ | 🟡 P1 | | 5 | ComponentConfigDialog | `src/components/` | 450 | 90 | 80% ↓ | 🟡 P1 | | 6 | PropertyInspector | `src/components/` | 380 | 85 | 77% ↓ | 🟡 P1 | ### Tier 3: Medium (200-400 LOC) | # | Component | Path | Current | Target | Reduction | Priority | |---|-----------|------|---------|--------|-----------|----------| | 7 | IRCWebchat | `src/components/` | 290 | 85 | 70% ↓ | 🟢 P2 | | 8 | AuditLogViewer | `src/components/` | 210 | 70 | 66% ↓ | 🟢 P2 | **Totals:** - **Before:** 4,156 LOC across 8 files - **After:** 755 LOC across 40+ smaller files - **Expected New Components:** 32+ child components + 8+ hooks - **Overall Reduction:** 81.8% ↓ --- ## 🔴 TIER 1 DETAILED ANALYSIS ### Component 1: GitHubActionsFetcher.tsx (887 LOC) **Current Architecture:** ``` ┌─ GitHubActionsFetcher (887 LOC, monolithic) ├─ useState: │ ├─ runs (workflow runs) │ ├─ loading │ ├─ error │ ├─ filters (status, branch) │ ├─ sortBy │ ├─ autoRefresh │ ├─ refreshInterval │ └─ selectedRun ├─ Effects: │ ├─ Initial fetch │ ├─ Auto-refresh interval │ ├─ Local storage sync │ └─ Search debounce ├─ API Calls: │ ├─ fetchWorkflowRuns() │ ├─ downloadRunLogs() │ ├─ retryFailedRun() │ └─ analyzeRunLogs() └─ Render: ├─ Filters UI ├─ Runs table (200+ LOC) ├─ Run details modal ├─ Analysis panel └─ Download progress ``` **Issues:** 1. **Mixed responsibilities:** API integration + UI rendering + state management 2. **Hardcoded logic:** Analysis features, filtering, sorting all in JSX 3. **No reusability:** Hooks can't be used elsewhere 4. **Hard to test:** Too many moving parts, complex mocking needed 5. **Performance:** Re-renders entire tree on any state change **Refactoring Strategy:** ``` BEFORE: GitHubActionsFetcher.tsx (887 LOC) ├─ API integration (200 LOC) ├─ State management (150 LOC) ├─ Analysis logic (100 LOC) └─ Rendering (437 LOC) AFTER: useGitHubFetcher.ts (65 LOC) ← API + polling ├─ Fetch runs ├─ Cache + refetch └─ Auto-refresh logic useAnalyzeRuns.ts (45 LOC) ← Analysis logic ├─ Analyze single run ├─ Analyze logs └─ Generate insights WorkflowRunCard.tsx (48 LOC) ← Single run display ├─ Run info ├─ Status badge └─ Quick actions WorkflowFilterBar.tsx (42 LOC) ← Filters ├─ Status filter ├─ Branch filter └─ Sort dropdown WorkflowRunsTable.tsx (65 LOC) ← Table view ├─ Column headers ├─ Row rendering (uses WorkflowRunCard) └─ Pagination WorkflowAnalysisPanel.tsx (52 LOC) ← Analysis UI ├─ Performance insights ├─ Job breakdown └─ Error summary GitHubActionsFetcher.tsx (85 LOC) ← Container ├─ Wire hooks ├─ Compose components └─ Handle interactions ``` **Implementation Checklist:** **Step 1: Create useGitHubFetcher Hook** (90 min) ```typescript // src/hooks/useGitHubFetcher.ts export interface UseGitHubFetcherOptions { autoRefresh?: boolean; refreshInterval?: number; filters?: WorkflowFilter; } export function useGitHubFetcher(options: UseGitHubFetcherOptions) { return { runs: WorkflowRun[], loading: boolean, error: Error | null, refresh: () => Promise, setFilters: (filters: WorkflowFilter) => void, setSortBy: (field: string, direction: 'asc' | 'desc') => void, } } ``` **Responsibilities:** - Fetch runs from GitHub API - Handle auth and errors - Manage auto-refresh interval - Cache results with stale-while-revalidate - Expose refresh and filter controls **Tests:** - Test successful fetch - Test auth errors - Test network errors - Test auto-refresh interval - Test filter application - Test cache invalidation --- **Step 2: Create useAnalyzeRuns Hook** (60 min) ```typescript // src/hooks/useAnalyzeRuns.ts export interface AnalysisResult { totalRuns: number; successRate: number; averageDuration: number; failureReasons: Map; slowestJobs: Job[]; } export function useAnalyzeRuns() { return { analyze: (runs: WorkflowRun[]) => AnalysisResult, analyzeRun: (run: WorkflowRun) => RunAnalysis, analyzeLogs: (logs: string) => LogAnalysis, } } ``` **Tests:** - Test success rate calculation - Test duration averaging - Test failure categorization - Test slowest job detection --- **Step 3: Create WorkflowRunCard Component** (45 min) ```typescript // src/components/WorkflowRunCard.tsx (48 LOC) interface WorkflowRunCardProps { run: WorkflowRun; onSelect: (run: WorkflowRun) => void; onRetry: (run: WorkflowRun) => void; onDownloadLogs: (run: WorkflowRun) => void; } export function WorkflowRunCard({ run, onSelect, onRetry, onDownloadLogs, }: WorkflowRunCardProps) { return (
{run.status}

{run.name}

{run.branch} • {formatDate(run.createdAt)}

{formatDuration(run.duration)}
{run.status === 'failed' && ( )}
); } ``` **Tests:** - Test card rendering with different statuses - Test button clicks - Test conditional rendering (retry button) --- **Step 4-6: Create Other Components** (2 hours each) - WorkflowFilterBar: Status/branch filters + sort - WorkflowRunsTable: List of WorkflowRunCard components - WorkflowAnalysisPanel: Statistics from useAnalyzeRuns --- **Step 7: Refactor Container Component** (60 min) ```typescript // src/components/GitHubActionsFetcher.tsx (85 LOC) export function GitHubActionsFetcher() { const { runs, loading, error, refresh, setFilters, setSortBy } = useGitHubFetcher({ autoRefresh: true, refreshInterval: 30000, }); const { analyze } = useAnalyzeRuns(); const analysis = useMemo(() => analyze(runs), [runs]); const [selectedRun, setSelectedRun] = useState(null); if (loading) return ; if (error) return ; return (
{selectedRun && ( )}
); } ``` **Keep API same:** Consumers of GitHubActionsFetcher shouldn't notice any change. --- **Step 8: Add Tests** (90 min) ```typescript // src/hooks/useGitHubFetcher.test.ts describe('useGitHubFetcher', () => { it('should fetch workflow runs on mount', async () => { // Test setup with mock API // Verify hook returns runs }); it('should handle authentication errors', async () => { // Mock API error // Verify error is returned }); it('should auto-refresh at specified interval', async () => { // Mock timer // Verify refetch occurs }); // ... 8+ more tests }); // src/components/WorkflowRunCard.test.tsx describe('WorkflowRunCard', () => { it('should render run information', () => { // Render component with mock run // Verify all fields displayed }); it('should call onSelect when clicked', () => { // Click Details button // Verify onSelect called }); // ... 4+ more tests }); ``` --- **Effort Summary:** | Task | Effort | Cumulative | |------|--------|-----------| | useGitHubFetcher hook | 90 min | 90 min | | useAnalyzeRuns hook | 60 min | 150 min | | WorkflowRunCard | 45 min | 195 min | | WorkflowFilterBar | 45 min | 240 min | | WorkflowRunsTable | 60 min | 300 min | | WorkflowAnalysisPanel | 55 min | 355 min | | Container refactor | 60 min | 415 min | | Tests | 90 min | 505 min | | **Total:** | | **505 min (8.4 hours)** | --- ### Component 2: NerdModeIDE.tsx (733 LOC) **Current Issues:** - File tree navigation + code editor + console + git all combined - Complex state: expandedNodes, openFiles, activeTab, editorContent, unsavedChanges - Keyboard shortcuts hardcoded - Theme/settings not configurable **Refactoring Plan:** ``` BEFORE: NerdModeIDE.tsx (733 LOC) ├─ File tree logic ├─ Editor state ├─ Console management └─ Git integration AFTER: useFileTree.ts (85 LOC) ← Tree operations useCodeEditor.ts (68 LOC) ← Editor state useConsoleOutput.ts (42 LOC) ← Console management useGitStatus.ts (38 LOC) ← Git info FileTreePanel.tsx (72 LOC) ← Tree UI EditorPanel.tsx (80 LOC) ← Editor UI ConsoleOutput.tsx (55 LOC) ← Console UI GitStatusBar.tsx (35 LOC) ← Git UI NerdModeIDE.tsx (110 LOC) ← Container ``` **Key Hooks:** ```typescript // src/hooks/useFileTree.ts interface FileTreeState { expandedNodes: Set; selectedFile: string | null; searchTerm: string; } export function useFileTree(projectRoot: string) { return { tree: FileNode[], state: FileTreeState, toggleNode: (nodeId: string) => void, selectFile: (path: string) => void, createFile: (path: string) => Promise, deleteFile: (path: string) => Promise, renameFile: (oldPath: string, newPath: string) => Promise, } } // src/hooks/useCodeEditor.ts export function useCodeEditor(language: string) { return { content: string, setContent: (content: string) => void, openTabs: EditorTab[], activeTab: EditorTab | null, switchTab: (tabId: string) => void, closeTab: (tabId: string) => void, hasUnsavedChanges: boolean, save: () => Promise, } } ``` **Effort:** 25 hours (including all components and tests) --- ### Component 3: LuaEditor.tsx (686 LOC) **Current Issues:** - Script editing + preview + console combined - Hardcoded syntax highlighting - No script library integration - Limited error reporting **Refactoring Plan:** ``` BEFORE: LuaEditor.tsx (686 LOC) ├─ Script editing ├─ Preview/execution └─ Console output AFTER: useLuaScript.ts (55 LOC) ← Script CRUD useLuaPreview.ts (48 LOC) ← Execution ScriptEditor.tsx (65 LOC) ← Edit UI ScriptPreview.tsx (48 LOC) ← Preview UI LuaEditor.tsx (120 LOC) ← Container ``` **Key Hooks:** ```typescript // src/hooks/useLuaScript.ts export function useLuaScript(scriptId?: string) { return { content: string, setContent: (content: string) => void, save: () => Promise, metadata: ScriptMetadata, updateMetadata: (metadata: Partial) => void, } } // src/hooks/useLuaPreview.ts export function useLuaPreview(script: string) { return { output: string, errors: LuaError[], run: (context: Record) => Promise, clear: () => void, } } ``` **Effort:** 20 hours --- ## 🟡 TIER 2 ANALYSIS (Medium Components) ### Component 4: SchemaEditor.tsx (520 LOC) **Issues:** Form builder + schema display + validation all combined **Refactoring:** Extract form builder to hooks, split into: - SchemaForm.tsx (80 LOC) - SchemaPreview.tsx (70 LOC) - useSchemaBuilder.ts (90 LOC) - Container (60 LOC) **Effort:** 10 hours --- ### Component 5: ComponentConfigDialog.tsx (450 LOC) **Issues:** Too many tabs and config sections **Refactoring:** Each config section as separate tab component - TabSelector.tsx (40 LOC) - GeneralTab.tsx (60 LOC) - StylesTab.tsx (70 LOC) - PropsTab.tsx (65 LOC) - Container (90 LOC) **Effort:** 8 hours --- ### Component 6: PropertyInspector.tsx (380 LOC) **Issues:** Different prop types rendered in single component **Refactoring:** Prop type components - PropertyInput.tsx (45 LOC) - PropertySelect.tsx (40 LOC) - PropertyColorPicker.tsx (35 LOC) - PropertyToggle.tsx (30 LOC) - Container (75 LOC) **Effort:** 7 hours --- ## 🟢 TIER 3 ANALYSIS (Smaller Components) ### Component 7: IRCWebchat.tsx (290 LOC) **Issues:** Chat UI + message rendering + input handling **Refactoring:** - MessageList.tsx (65 LOC) - ChatInput.tsx (45 LOC) - useChatMessages.ts (50 LOC) - Container (60 LOC) **Effort:** 4 hours --- ### Component 8: AuditLogViewer.tsx (210 LOC) **Issues:** Table view + filtering + search **Refactoring:** - AuditLogTable.tsx (85 LOC) - AuditLogFilter.tsx (50 LOC) - Container (50 LOC) **Effort:** 3 hours --- ## 📊 Summary Table | Component | Current | Target | Components | Hooks | Effort | Start | |-----------|---------|--------|------------|-------|--------|-------| | GitHubActionsFetcher | 887 | 85 | 6 | 2 | 8.4h | Week 1 | | NerdModeIDE | 733 | 110 | 4 | 4 | 25h | Week 1 | | LuaEditor | 686 | 120 | 2 | 2 | 20h | Week 2 | | SchemaEditor | 520 | 100 | 3 | 1 | 10h | Week 2 | | ComponentConfigDialog | 450 | 90 | 5 | 0 | 8h | Week 2 | | PropertyInspector | 380 | 85 | 4 | 0 | 7h | Week 3 | | IRCWebchat | 290 | 85 | 2 | 1 | 4h | Week 3 | | AuditLogViewer | 210 | 70 | 1 | 0 | 3h | Week 3 | | **TOTALS** | **4,156** | **755** | **32** | **10** | **85.4h** | | --- ## ✅ Testing Strategy ### Unit Tests (Per Component) - Props validation - State management - Event handlers - Edge cases ### Hook Tests - Initial state - State updates - Side effects - Error handling ### Integration Tests - Component composition - Data flow through hierarchy - Performance (re-renders) ### E2E Tests - Full workflows - Multi-component interactions - Performance under load --- ## 🎯 Success Criteria ### Per Component - [ ] All child components < 150 LOC - [ ] All hooks < 100 LOC - [ ] Unit test coverage > 90% - [ ] No console warnings - [ ] Props fully documented with JSDoc - [ ] Accessibility compliant (WCAG 2.1 AA) - [ ] Performance: no regression in metrics ### Overall - [ ] 0 violations remaining - [ ] 4,156 → 755 LOC reduction - [ ] 40+ small components + 10 reusable hooks - [ ] All tests passing - [ ] All code reviewed - [ ] Documentation complete --- ## 📋 Execution Checklist ### Pre-Refactoring (Day 1) - [ ] Create feature branch - [ ] Set up test environment - [ ] Create Storybook stories (optional) - [ ] Document current API/props ### Refactoring Phase - [ ] Create hooks - [ ] Create child components - [ ] Add unit tests - [ ] Refactor container - [ ] Update parent imports - [ ] Test integration ### Post-Refactoring - [ ] Code review - [ ] E2E tests - [ ] Performance testing - [ ] Documentation - [ ] Merge to main --- ## 🚀 Recommended Refactoring Order 1. **GitHubActionsFetcher** (8.4h) - Simpler, good learning example 2. **NerdModeIDE** (25h) - Most complex, but infrastructure ready 3. **LuaEditor** (20h) - Complex but fewer dependencies 4. **SchemaEditor** (10h) - Medium complexity 5. **ComponentConfigDialog** (8h) - Straightforward tab separation 6. **PropertyInspector** (7h) - Similar patterns to PropertyInspector 7. **IRCWebchat** (4h) - Simple message list pattern 8. **AuditLogViewer** (3h) - Simple table pattern **Total Timeline:** 8.5 weeks (1 developer, sequential) --- ## 🎓 Learning Resources ### Component Decomposition Patterns - [React docs: Composition vs Inheritance](https://react.dev/learn/thinking-in-react) - [Atomic Design Methodology](https://bradfrost.com/blog/post/atomic-web-design/) ### Hook Development - [React Hooks API Reference](https://react.dev/reference/react) - [Separating Concerns with Hooks](https://react.dev/learn/separating-concerns-with-effects) ### Testing - [React Testing Library](https://testing-library.com/docs/react-testing-library/intro) - [Jest Documentation](https://jestjs.io/docs/getting-started) --- **Generated:** December 25, 2025 **Next Review:** After Phase 1A completion