12 KiB
ESLint Cleanup Plan
Status: 622 errors → 105 errors remaining (83% complete) ✨ Generated: 2025-11-23 Last Updated: 2025-11-23
Progress Summary
| Phase | Status | Errors Fixed | Notes |
|---|---|---|---|
| Phase 1: Critical Blockers | ✅ Complete | 6 | All parsing errors resolved |
| Phase 2: Auto-fixable | ✅ Complete | 148 | Ran eslint --fix |
| Phase 3: Type Safety | 🔄 In Progress | 363/277* | *More errors found during cleanup |
| Phase 4: Svelte 5 Migration | ⏳ Pending | 0/109 | Not started |
| Phase 5: Remaining Issues | ⏳ Pending | 0/73 | Not started |
Total Progress: 517/622 errors fixed (83% complete)
Phase 3 Detailed Progress
| Batch | Status | Errors Fixed | Files |
|---|---|---|---|
| Batch 1: Admin Components | ✅ Complete | 44 | 11 files |
| Batch 2: API Routes | ✅ Complete | 26 | 20 files |
| Batch 3: Frontend Components | ✅ Complete | 80 | 46 files |
| Batch 4: Server Utilities | 🔄 In Progress | 9/88 | 21 files |
| Batch 5: Remaining Files | ⏳ Pending | 0 | TBD |
Commits:
94e13f1- Auto-fix linting issues with eslint --fix8ec4c58- Eliminate remaining any types in API routes9c746d5- Replace any types in frontend components (batch 1)3d77922- Replace more any types in components (batch 2)9379557- Complete frontend component any type cleanup6408e7f- Start fixing server utility any types (WIP)
Executive Summary
The codebase initially had 622 ESLint errors across 180 files. Through systematic cleanup, we've reduced this to 105 errors (83% complete). This document tracks progress and provides a systematic approach to eliminate all remaining errors.
Error Breakdown by Rule
| Count | % of Total | Files | Rule |
|---|---|---|---|
| 277 | 45.2% | 99 | @typescript-eslint/no-explicit-any |
| 139 | 22.7% | 79 | @typescript-eslint/no-unused-vars |
| 109 | 17.8% | 44 | svelte/valid-compile |
| 26 | 4.2% | 6 | @typescript-eslint/no-unused-expressions |
| 22 | 3.6% | 1 | svelte/no-dupe-style-properties |
| 10 | 1.6% | 9 | svelte/no-at-html-tags |
| 7 | 1.1% | 6 | prefer-const |
| 6 | 1.0% | 6 | Parsing errors |
| 5 | 0.8% | 2 | no-undef |
| 22 | 3.6% | — | Other (various) |
Top Files Requiring Attention
- AvatarSVG.svelte - 22 errors (duplicate style properties)
- posts/[id]/edit/+page.svelte - 20 errors (mixed)
- admin/EssayForm.svelte - 18 errors (mixed)
- admin/GalleryUploader.svelte - 18 errors (mixed)
- admin/InlineComposerModal.svelte - 17 errors (mixed)
Execution Plan
Phase 1: Critical Blockers (6 errors) ✅ COMPLETE
Status: ✅ All parsing errors resolved
Parsing Errors Fixed:
src/routes/+layout.svelte:33- Parsing error ✅routes/albums/[slug]/+page.svelte:140- Parsing error ✅routes/labs/[slug]/+page.svelte:77- Parsing error ✅routes/photos/[id]/+page.svelte:361- Parsing error ✅routes/universe/[slug]/+page.svelte:85- Parsing error ✅routes/work/[slug]/+page.svelte:115- Parsing error ✅
Result: All files now properly lintable.
Phase 2: Low-Hanging Fruit (148 errors) ✅ COMPLETE
Status: ✅ Auto-fixes applied successfully
Errors Fixed:
- 139 unused imports/variables (
@typescript-eslint/no-unused-vars) ✅ - 7
prefer-constviolations ✅ - 2 empty blocks (
no-empty) ✅
Action Taken: Ran npx eslint . --fix
Result: 148 errors eliminated automatically (24% reduction).
Phase 3: Type Safety (277+ errors) 🔄 IN PROGRESS
Priority: HIGH - Improves code quality and type safety Status: 150/~363 errors fixed (41% complete)
Replace any types with proper TypeScript types, organized by subsystem:
Batch 1: Admin Components ✅ COMPLETE
Status: ✅ 44 errors fixed in 11 files
Key Improvements:
- Added Prisma types (Post, Project, Media, Album)
- Created specific payload interfaces (DraftPayload, PhotoPayload, etc.)
- Replaced
anywithunknownand proper type guards - Fixed editor ref types with JSONContent interfaces
Files Fixed:
- GalleryUploader.svelte (9 errors)
- editorConfig.ts (8 errors)
- posts/[id]/edit/+page.svelte (8 errors)
- SimplePostForm.svelte (7 errors)
- GenericMetadataPopover.svelte (5 errors)
- PhotoPostForm.svelte (5 errors)
- useFormGuards.svelte.ts (4 errors)
Batch 2: API Routes ✅ COMPLETE
Status: ✅ 26 errors fixed in 20 files (all API/RSS routes now have 0 any errors)
Key Improvements:
- Used
Prisma.JsonValuefor JSON column types - Added
Prisma.[Model]WhereInputfor where clauses - Added
Prisma.[Model]UpdateInputfor update operations - Created interfaces for complex data structures (ExifData, PhotoMedia, etc.)
- Used proper type guards (Array.isArray checks)
Files Fixed:
- api/media/bulk-delete/+server.ts (10 errors)
- rss/+server.ts (8 errors)
- api/universe/+server.ts (4 errors)
- rss/universe/+server.ts (4 errors)
- Plus 16 more API/RSS route files
Batch 3: Frontend Components ✅ COMPLETE
Status: ✅ 80 errors fixed in 46 files (all components now have 0 any errors)
Key Improvements:
- Used Leaflet types (L.Map, L.Marker, L.LeafletEvent) for map components
- Used Svelte 5
Snippettype for render functions - Used
Componenttype for Svelte component parameters - Used
EditorViewtype for TipTap/ProseMirror views - Added proper error handling with type guards
Files Fixed:
- All edra/headless placeholder components (7 files, 14 errors)
- Map components with Leaflet types (3 files, 9 errors)
- Form components with Prisma types (12 files, 24 errors)
- Editor extensions and utilities (6 files, 12 errors)
- Plus 18 more component files
Batch 4: Server Utilities 🔄 IN PROGRESS
Status: 🔄 9/88 errors fixed in 21 files
Currently Working On:
lib/utils/content.ts(15 → 6 errors remaining)- Added ContentNode interface for content rendering
- Replaced function parameters with proper types
- Fixed content traversal and mapping functions
Remaining Files:
lib/server/apple-music-client.ts(10 errors)lib/server/logger.ts(10 errors)lib/utils/metadata.ts(10 errors)lib/server/cloudinary-audit.ts(6 errors)- Plus 17 more server/utility files
Batch 5: Remaining Files ⏳ PENDING
Status: ⏳ Not started
Files to Fix:
global.d.ts(2 errors)lib/admin/autoSave.svelte.tslib/admin/autoSaveLifecycle.ts- Other miscellaneous files
Phase 4: Svelte 5 Migration (109 errors) 🟡
Priority: MEDIUM - Required for Svelte 5 compliance
Batch 1: Reactive State Declarations (~20 errors in 15 files)
Variables not declared with $state():
searchModal(DebugPanel.svelte)cardElement(LabCard.svelte)logoElement(ProjectItem.svelte)dropdownElement(DropdownMenu.svelte)metadataButtonRef(2 files)editorInstance,essayTitle,essaySlug, etc. (EssayForm.svelte)- And 8 more files
Action: Wrap reactive variables in $state() declarations.
Batch 2: Event Handler Migration (~12 errors in 6 files)
Deprecated on:* handlers to migrate:
on:click→onclick(3 occurrences in 2 files)on:mousemove→onmousemove(2 occurrences)on:mouseenter→onmouseenter(2 occurrences)on:mouseleave→onmouseleave(2 occurrences)on:keydown→onkeydown(1 occurrence)
Files:
- BaseModal.svelte
- LabCard.svelte
Batch 3: Accessibility Issues (~40 errors in 22 files)
A11y fixes needed:
- 15 instances: Click events need keyboard handlers
- 10 instances: Form labels need associated controls
- 8 instances: Elements with click handlers need ARIA roles
- 3 instances: Non-interactive elements with tabindex
- 2 instances: Elements need ARIA labels
Common patterns:
- Add
role="button"andonkeydownhandlers to clickable divs - Associate labels with form controls using
forattribute - Add
tabindex="-1"or remove unnecessary tabindex
Batch 4: Deprecated Component Syntax (~10 errors in 6 files)
Issues:
<svelte:self>→ Use self-imports instead (DropdownMenu.svelte)<svelte:component>→ Components are dynamic by default in runes mode- Self-closing non-void elements (3 files, e.g.,
<textarea />)
Batch 5: Custom Element Props (6 files)
Issue: Rest props with $props() need explicit destructuring or customElement.props config
Files:
- admin/Button.svelte
- stories/Button.svelte
- And 4 more component files
Batch 6: Miscellaneous Svelte Issues
- State referenced locally warnings (5 occurrences)
- Video elements missing captions (1 occurrence)
- Unused CSS selectors (2 occurrences)
- Image redundant alt text (1 occurrence)
Phase 5: Remaining Issues (73 errors) 🟡
Priority: MEDIUM-LOW
AvatarSVG.svelte (22 errors)
- 22 duplicate style properties in SVG gradient definitions
- Action: Consolidate duplicate
fillandstop-colorproperties
XSS Warnings (10 errors)
- 10
{@html}usage warnings in various components - Action: Review each instance, ensure content is sanitized, or suppress with eslint-disable if safe
Code Quality Issues
- 5
no-undeferrors (undefined variables) - 26
@typescript-eslint/no-unused-expressionserrors - 4
no-case-declarationserrors - 3
@typescript-eslint/no-empty-object-typeerrors - 3
no-useless-escapeerrors
Recommended Execution Strategy
For Manual Cleanup
- ✅ Work sequentially - Complete phases in order
- ✅ Batch similar fixes - Process files with same error pattern together
- ✅ Track progress - Use todo list to check off completed items
- ✅ Verify continuously - Run
npx eslint .after each batch to confirm progress - ✅ Commit frequently - Commit after each batch for easy rollback if needed
For LLM-Assisted Cleanup
- Process in phases - Don't jump between phases
- One batch at a time - Complete each batch before moving to next
- Verify after each batch - Check error count decreases as expected
- Ask for clarification - If error pattern is unclear, investigate before mass-fixing
- Preserve functionality - Don't break working code while fixing lint errors
Commands Reference
# Check all errors
npx eslint .
# Auto-fix what's possible
npx eslint . --fix
# Check specific file
npx eslint src/path/to/file.svelte
# Output to JSON for analysis
npx eslint . --format json > eslint-output.json
# Count errors by rule
npx eslint . 2>&1 | grep "error" | wc -l
Success Metrics
- Phase 1 Complete: ✅ No parsing errors (6 fixed)
- Phase 2 Complete: ✅ 468 errors remaining (24% reduction, 154 fixed)
- Phase 3 In Progress: 🔄 105 errors remaining (83% reduction, 517 total fixed)
- Batch 1-3 Complete: 150
anytypes eliminated - Batch 4 In Progress: 9/88 errors fixed
- Batch 1-3 Complete: 150
- Phase 4 Pending: ~109 Svelte 5 errors to fix
- Phase 5 Pending: ~73 miscellaneous errors to fix
- Target: 0 errors (100% clean)
Notes
- Prettier formatting issues (93 files) are separate from ESLint and should be fixed with
npm run format - Sass
@importdeprecation warnings are informational only and don't count toward the 613 errors - Some
{@html}warnings may be acceptable if content is trusted/sanitized
Key Learnings
Type System Patterns Established
-
Prisma Types: Always use generated Prisma types for database models
import type { Post, Project, Media, Album } from '@prisma/client'- Use
Prisma.JsonValuefor JSON columns - Use
Prisma.[Model]WhereInputandPrisma.[Model]UpdateInput
-
Content Handling: Create structured interfaces for complex nested data
- ContentNode interface for TipTap/BlockNote content
- Type guards for safe traversal (Array.isArray, typeof checks)
-
Component Types: Use Svelte 5 and framework-specific types
Snippetfor render functionsComponentfor component references- Specific editor types (Editor, EditorView, JSONContent)
-
Error Handling: Use type guards instead of
anycastserr && typeof err === 'object' && 'status' in errRecord<string, unknown>for truly dynamic objectsunknowninstead ofanywhen type is genuinely unknown
Commit Strategy
- Commits grouped by logical batches (admin components, API routes, etc.)
- Terse, informal commit messages focusing on impact
- Frequent commits for easy rollback if needed
- No mention of tooling (Claude Code) in commit messages
Last Updated: 2025-11-23 Next Review: After Phase 3 Batch 4 completion Estimated Completion: Phase 3 in progress, ~105 errors remaining