Files
tolaria/CODE-HEALTH-REPORT.md

262 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Code Health Report — Laputa App
**Date:** 2026-02-17
**Branch:** `experiment/shadcn-migration`
**Overall Project Score:** 8.34 / 10.0 (Yellow — approaching Green)
**Tool:** CodeScene Code Health Analysis (project ID: 76865)
---
## Summary
The Laputa App codebase scores **8.34** overall — solid but with four files in the "Yellow" zone (< 8.0) that are dragging down maintainability. One file (`vault.rs`) is in the **Red zone** at 4.8, representing the most critical technical debt.
| Zone | Score Range | File Count | Description |
|------|------------|------------|-------------|
| Optimal | 10.0 | 4 | Perfect — optimized for human and AI comprehension |
| Green | 9.0 9.9 | 2 | High quality, minor issues only |
| Yellow | 4.0 8.9 | 4 | Problematic technical debt |
| Red | 1.0 3.9 | 0 | — |
| N/A | — | 2 | CSS files (unsupported by CodeScene) |
---
## File-by-File Scores
| File | LoC | Score | Zone | Key Issues |
|------|-----|-------|------|------------|
| `src-tauri/src/main.rs` | 6 | **10.0** | Optimal | None |
| `src-tauri/src/git.rs` | 423 | **10.0** | Optimal | None |
| `src/mock-tauri.ts` | 707 | **10.0** | Optimal | None |
| `src/components/StatusBar.tsx` | 62 | **10.0** | Optimal | None |
| `src-tauri/src/lib.rs` | 78 | **9.68** | Green | String-heavy function arguments (93%) |
| `src/components/QuickOpenPalette.tsx` | 145 | **9.55** | Green | Complex Method (cc=16) |
| `src/components/Sidebar.tsx` | 233 | **9.02** | Green | Complex Method (cc=25), Large Method (181 LoC) |
| `src/components/NoteList.tsx` | 339 | **8.11** | Yellow | Bumpy Road, Complex Method (cc=30), Large Method (166 LoC) |
| `src/components/Inspector.tsx` | 912 | **7.49** | Yellow | Bumpy Road (x2), Complex Methods (x4), Complex Conditionals |
| `src/App.tsx` | 593 | **7.13** | Yellow | Brain Method: App() at cc=56 / 381 LoC, Bumpy Road, Deep Nesting |
| `src/components/Editor.tsx` | 540 | **6.94** | Yellow | Deep Nesting, Complex Methods (cc=29), Large Method (265 LoC) |
| `src-tauri/src/vault.rs` | 815 | **4.80** | Yellow (near Red) | Bumpy Road (x2), Deep Nesting, Complex Methods (x3), Code Duplication, Large Method, String-heavy args |
| `src/App.css` | 48 | N/A | — | CSS not supported |
| `src/components/Editor.css` | 106 | N/A | — | CSS not supported |
---
## Technical Debt Hotspots
CodeScene reports **0 hotspots** from the project-level analysis (the project may need more commit history to identify change-frequency hotspots). However, based on the code health scores and file sizes, the **de facto hotspots** are:
| Priority | File | Score | LoC | Risk Factor |
|----------|------|-------|-----|-------------|
| 1 | `src-tauri/src/vault.rs` | 4.80 | 815 | Largest Rust file, near-Red health, 8 distinct code smells |
| 2 | `src/components/Editor.tsx` | 6.94 | 540 | Core editor component, deep nesting, high complexity |
| 3 | `src/App.tsx` | 7.13 | 593 | Root component, Brain Method (cc=56, 381 LoC) |
| 4 | `src/components/Inspector.tsx` | 7.49 | 912 | Largest file in codebase, 4 complex methods |
---
## Detailed Analysis — Files Scoring Below 8.0
### 1. `src-tauri/src/vault.rs` — Score: 4.80 (CRITICAL)
This is the **worst-scoring file** in the codebase and the highest priority for refactoring.
**Code Smells Found:**
| Smell | Location | Details | Severity |
|-------|----------|---------|----------|
| Bumpy Road | `update_frontmatter_content` (L452536) | 4 bumps of nested logic | High |
| Bumpy Road | `days_from_epoch` (L253285) | 3 bumps | High |
| Deep Nesting | `update_frontmatter_content` (L452536) | 4 levels of conditionals | High |
| Complex Method | `FrontmatterValue::to_yaml_value` (L371412) | cc = 17 | Medium |
| Complex Method | `update_frontmatter_content` (L452536) | cc = 16 | Medium |
| Complex Method | `days_from_epoch` (L253285) | cc = 14 | Medium |
| Complex Conditional | `to_yaml_value` (L375377) | 8 complex expressions | Medium |
| Complex Conditional | `format_yaml_key` (L565566) | 5 complex expressions | Medium |
| Complex Conditional | `days_from_epoch` (L255) | 3 complex expressions | Medium |
| Code Duplication | `update_frontmatter` / `delete_frontmatter_property` (L416449) | Near-identical functions | Medium |
| Large Method | `parse_md_file` (L101190) | 78 LoC (limit: 70) | Medium |
| String-Heavy Args | Module-wide | 63% of args are strings | Medium |
**Business Case:** Improving to industry average (5.15) yields 27% defect reduction and 13% speed improvement.
---
### 2. `src/components/Editor.tsx` — Score: 6.94
**Code Smells Found:**
| Smell | Location | Details | Severity |
|-------|----------|---------|----------|
| Deep Nesting | `expandWikilinksInContent` (L119146) | 4 levels of conditionals | High |
| Complex Method | `Editor` (L263540) | cc = 29 | Medium |
| Complex Method | `DiffView` (L148186) | cc = 13 | Medium |
| Complex Conditional | `DiffView:169` | 4 complex expressions | Medium |
| Complex Conditional | `expandWikilinksInContent:122` | 2 complex expressions | Medium |
| Large Method | `Editor` (L263540) | 265 LoC (limit: 120) | Medium |
| Overall Code Complexity | File-wide | High mean cyclomatic complexity | Medium |
**Business Case:** Improving to 9.1 yields 2740% defect reduction and 2132% speed improvement. **This is the highest-ROI refactoring target.**
---
### 3. `src/App.tsx` — Score: 7.13
**Code Smells Found:**
| Smell | Location | Details | Severity |
|-------|----------|---------|----------|
| Bumpy Road | `updateMockFrontmatter` (L2188) | 2 bumps | High |
| Deep Nesting | `updateMockFrontmatter` (L2188) | 4 levels deep | High |
| Complex Method | `App` (L131591) | cc = 56 (**Brain Method**) | Medium |
| Complex Method | `updateMockFrontmatter` (L2188) | cc = 17 | Medium |
| Large Method | `App` (L131591) | 381 LoC (limit: 120, **3x over**) | Medium |
**Business Case:** Improving to 9.1 yields 2739% defect reduction and 2031% speed improvement.
---
### 4. `src/components/Inspector.tsx` — Score: 7.49
**Code Smells Found:**
| Smell | Location | Details | Severity |
|-------|----------|---------|----------|
| Bumpy Road | `parseFrontmatter` (L78150) | 2 bumps | High |
| Bumpy Road | `DynamicPropertiesPanel` (L441516) | 2 bumps | High |
| Complex Method | `parseFrontmatter` (L78150) | cc = 21 | Medium |
| Complex Method | `DynamicPropertiesPanel` (L441516) | cc = 18 | Medium |
| Complex Method | `renderEditableValue` (L527624) | cc = 16 | Medium |
| Complex Method | `Inspector` (L806912) | cc = 14 | Medium |
| Complex Conditional | `renderEditableValue:590` | 3 complex expressions | Medium |
| Complex Conditional | `parseFrontmatter:115` | 2 complex expressions | Medium |
| Overall Code Complexity | File-wide | High mean cyclomatic complexity | Medium |
**Business Case:** Improving to 9.1 yields 2636% defect reduction and 1828% speed improvement.
---
## Quick Wins (Low Effort, High Impact)
These are targeted refactorings that can improve scores immediately:
### 1. Extract `App` component state into custom hooks
**File:** `src/App.tsx` | **Impact:** cc 56 → ~10 per hook
- Extract `useVaultData()` — vault loading, entry management
- Extract `useEditorState()` — selected entry, editor content, undo/redo
- Extract `useKeyboardShortcuts()` — all keyboard event handlers
- Extract `useSearch()` — search/filter state and logic
- The `App` component becomes a thin composition layer
### 2. Extract `updateMockFrontmatter` helper functions
**File:** `src/App.tsx` (L2188) | **Impact:** Eliminates deep nesting + bumpy road
- Extract date-comparison logic into a helper
- Extract frontmatter field-update logic per field type
- Flatten conditionals with early returns
### 3. Deduplicate `update_frontmatter` / `delete_frontmatter_property`
**File:** `src-tauri/src/vault.rs` (L416449) | **Impact:** Eliminates code duplication smell
- Both functions share the same file-read + frontmatter-parse + write-back pattern
- Extract shared logic into a `with_frontmatter<F>(path, f: F)` helper
### 4. Flatten `expandWikilinksInContent`
**File:** `src/components/Editor.tsx` (L119146) | **Impact:** Eliminates deep nesting
- Use early `continue` in the loop
- Extract inner matching logic into a `resolveWikilink()` helper
### 5. Split `DynamicPropertiesPanel` into sub-components
**File:** `src/components/Inspector.tsx` | **Impact:** Reduces 4 complex methods to focused units
- Extract `EditableValue` component for `renderEditableValue`
- Extract `FrontmatterParser` utility for `parseFrontmatter`
- Extract `PropertyRow` component for individual property rendering
---
## Larger Refactoring Plans
### Plan A: Decompose `vault.rs` (Priority 1 — Score 4.80 → 8+)
**Goal:** Raise from near-Red (4.80) to Green (9+) in 45 steps.
| Step | Action | Target Smell |
|------|--------|--------------|
| 1 | Extract `frontmatter.rs` module — move `FrontmatterValue`, `to_yaml_value`, `update_frontmatter_content`, `format_yaml_key` | Reduces file size, isolates complexity |
| 2 | Introduce `with_frontmatter()` helper to deduplicate `update_frontmatter` / `delete_frontmatter_property` | Code Duplication |
| 3 | Refactor `update_frontmatter_content` — flatten nesting with early returns, extract `apply_field_update()` helper | Deep Nesting, Bumpy Road |
| 4 | Refactor `days_from_epoch` — use a lookup table or `chrono` crate helpers instead of manual conditionals | Bumpy Road, Complex Conditional |
| 5 | Replace string args with newtype wrappers (`VaultPath`, `FilePath`, `PropertyKey`) | String-Heavy Args |
### Plan B: Decompose `Editor.tsx` (Priority 2 — Score 6.94 → 9+)
**Goal:** Raise from Yellow (6.94) to Green (9+) in 34 steps.
| Step | Action | Target Smell |
|------|--------|--------------|
| 1 | Extract `useEditorExtensions()` hook — all CodeMirror extension setup | Reduces Editor cc from 29 |
| 2 | Extract `useWikilinks()` hook — wikilink expansion, resolution | Deep Nesting, Complex Conditional |
| 3 | Extract `DiffView` into its own file `DiffView.tsx` | Complex Method (cc=13) |
| 4 | Extract `useEditorContent()` hook — content loading, saving, dirty state | Further reduces Editor complexity |
### Plan C: Decompose `App.tsx` (Priority 3 — Score 7.13 → 9+)
**Goal:** Break the Brain Method pattern. The `App` function at cc=56 and 381 LoC is the single worst function in the frontend.
| Step | Action | Target Smell |
|------|--------|--------------|
| 1 | Extract `useVaultLoader()` — vault path selection, entry loading, refresh | Reduces App cc by ~15 |
| 2 | Extract `useNoteActions()` — create, delete, rename, move note | Reduces App cc by ~10 |
| 3 | Extract `useAppKeyboard()` — all keyboard shortcut handlers | Reduces App cc by ~8 |
| 4 | Extract `useFrontmatterSync()` — mock frontmatter update logic | Eliminates Bumpy Road + Deep Nesting |
| 5 | Move layout JSX into `AppLayout.tsx` presentational component | Reduces App to pure orchestration |
### Plan D: Decompose `Inspector.tsx` (Priority 4 — Score 7.49 → 9+)
**Goal:** The largest file (912 LoC) with 4 complex methods needs structural decomposition.
| Step | Action | Target Smell |
|------|--------|--------------|
| 1 | Extract `parseFrontmatter()` to `src/utils/frontmatter.ts` shared utility | Complex Method (cc=21), Bumpy Road |
| 2 | Extract `EditableValue.tsx` component from `renderEditableValue` | Complex Method (cc=16) |
| 3 | Extract `DynamicPropertiesPanel.tsx` as standalone component | Bumpy Road, Complex Method (cc=18) |
| 4 | Simplify `Inspector` to compose sub-components | Reduces cc from 14 to ~5 |
---
## Refactoring ROI Summary
| File | Current | Target | Defect Reduction | Speed Improvement |
|------|---------|--------|------------------|-------------------|
| `Editor.tsx` | 6.94 | 9.1 | 2740% | 2132% |
| `App.tsx` | 7.13 | 9.1 | 2739% | 2031% |
| `Inspector.tsx` | 7.49 | 9.1 | 2636% | 1828% |
| `vault.rs` | 4.80 | 5.15* | 27% | 13% |
*\*vault.rs target is conservative (industry average). A full refactoring to 9+ would yield dramatically higher ROI but requires more structural work.*
---
## Recommended Execution Order
1. **`vault.rs`** — Lowest score, near-Red zone. Foundational backend code that all frontmatter operations depend on. Fix this first to prevent defect accumulation.
2. **`Editor.tsx`** — Highest ROI. Core user-facing component where bugs are most visible. Decomposition into hooks is straightforward.
3. **`App.tsx`** — Brain Method must be broken up. The cc=56 function is a maintenance trap — any new feature added here increases risk nonlinearly.
4. **`Inspector.tsx`** — Largest file but lower priority because it's more self-contained. Decompose after the above three.
5. **`NoteList.tsx`** (8.11) and **`Sidebar.tsx`** (9.02) — minor improvements, address opportunistically.
---
## Files in Good Shape
These files need no immediate attention:
- `src-tauri/src/main.rs` — 10.0 (6 LoC, clean entry point)
- `src-tauri/src/git.rs` — 10.0 (423 LoC, well-structured)
- `src/mock-tauri.ts` — 10.0 (707 LoC, clean mock layer)
- `src/components/StatusBar.tsx` — 10.0 (62 LoC, minimal component)
- `src-tauri/src/lib.rs` — 9.68 (minor: string-heavy args)
- `src/components/QuickOpenPalette.tsx` — 9.55 (minor: cc=16)
---
*Report generated by CodeScene MCP analysis. For interactive exploration, visit: https://codescene.io/projects/76865*