Phase 1 Batch 2: Logger & Simple Utilities
Replaced any types with proper TypeScript types across 3 files:
- logger.ts: Created LogContext type, added RequestEvent import from SvelteKit
- Defined LogContext = Record<string, string | number | boolean | null | undefined>
- Changed all context parameters from Record<string, any> to LogContext
- Changed event parameter in createRequestLogger from any to RequestEvent
- extractEmbeds.ts: Used TiptapNode type from editor.ts
- Changed content and node parameters from any to TiptapNode
- global.d.ts: Improved SVG module declarations
- Changed *.svg from any to string (raw SVG content)
- Changed *.svg?component from any to Component<any> (Svelte component)
Progress: 199 → 185 errors (91 → 77 any-type errors)
Phase 1 Batch 1: Type Definitions
Replaced any types with proper TypeScript types across 5 type definition files:
- apple-music.ts: Added AppleMusicArtistAttributes, changed type guards to use unknown
- editor.ts: Changed any to unknown for flexible block/node attributes
- lastfm.ts: Defined editorialNotes structure, changed rawResponse to unknown
- project.ts: Changed caseStudyContent to EditorData type
- photos.ts: Defined ColorPalette interface for color data
Progress: 207 → 199 errors (103 → 91 any-type errors)
- Restore AlbumForm handleSave() and validateForm() functions
- Add back missing imports (goto, zod, Button, toast)
- Restore isSaving and validationErrors state
- Add back albumSchema validation
This fixes the critical issue where AlbumForm had no way to save albums
due to over-aggressive dead code removal in previous cleanup.
Also update docs/eslint-cleanup-plan.md to reflect:
- Current branch status (207 errors remaining)
- Quality review of previous LLM work (84% good, 1 critical issue fixed)
- Detailed breakdown of remaining errors
- Actionable roadmap for completing the cleanup
- add ContentNode interface for content rendering
- replace any with proper types in content.ts (15 -> 6 errors)
- use Record<string, unknown> for dynamic content objects
- add type assertions for content arrays
- replace any with Prisma types (Post, Project, Album, Media)
- use Component type for Svelte component parameters
- use Snippet type for Svelte 5 render slots
- use Record<string, unknown> for dynamic objects
- add proper type guards for error handling
- fix editor extension types with proper generics
- all frontend components now have zero any type errors
- fix edra placeholder components with proper editor context types
- fix gallery image types with proper type assertions
- fix ProseMirror transaction types in link manager
- fix command types in composer toolbar
- replace any with unknown where type is dynamic
- use Leaflet types (L.Map, L.Marker, L.LeafletEvent) for map components
- use Post and Project types from Prisma for form components
- use JSONContent type for editor instances
- use Snippet type for Svelte 5 render functions
- use EditorView type for TipTap/ProseMirror views
- use proper type guards for error handling
- add editor interface types for save/clear methods
- use Prisma.JsonValue and Prisma input types throughout
- add proper type guards for array and object checks
- replace any with Record<string, unknown> where appropriate
- all API/RSS routes now have zero any type errors
- add ProjectUpdateBody interface for partial updates
- use Prisma.ProjectUpdateInput for update operations
- replace all remaining any types in projects endpoints
- consistent use of proper types across all API routes
- add AlbumPhoto, BlockContent, AppleMusicData types
- add ProjectCreateBody interface for request validation
- use Prisma.ProjectWhereInput for query filters
- use Prisma.JsonValue for JSON fields
- add proper type guards for content validation
- add ContentNode, GalleryItem, TextNode, ParagraphNode, DocContent types
- use Prisma.JsonValue for JSON column content
- use Prisma.ProjectUpdateInput and Prisma.PostUpdateInput for update payloads
- improve type guards for content filtering
- replace any[] with never[] for empty placeholder arrays
- add GalleryItem type for media/gallery item unions
- add EdraCommand import for editor command types
- add Post, Media imports from Prisma
- add BlockContent, DraftPayload, PostPayload, PhotoPayload types
- replace any with proper types in form handlers and callbacks
- use unknown for truly dynamic data, Record types for object props
Replace broken text extraction logic with renderEdraContent() which correctly handles TipTap marks including links, bold, italic, etc.
Before: Links were stripped from RSS content (only plain text extracted)
After: Full HTML with proper links, formatting preserved in CDATA sections
Files updated:
- src/routes/rss/+server.ts: Main RSS feed
- src/routes/rss/universe/+server.ts: Universe RSS feed
Fixes issue where content.blocks was expected but TipTap uses content.type='doc' format.
Migrate remaining Svelte 4 reactive statements to Svelte 5 $derived:
- media/audit/+page.svelte: Convert allSelected, hasSelection, selectedSize to $derived
- universe/compose/+page.svelte: Convert postType, initialContent to $derived
- Also migrated all let declarations to $state() in audit page for consistency
All reactive statements now use Svelte 5 runes mode.
Make page headers sticky with subtle shadow on scroll. Fix min-height to 90px to prevent jumping when switching tabs. Modernize layout to use full viewport height.
Convert admin components from Svelte 4 to Svelte 5 syntax using $props, $state, $derived, and $bindable runes. Simplifies AdminNavBar logic and improves type safety.
Extract BrandingToggle and BrandingSection components. Consolidate $effect blocks, add $derived state, and apply BEM naming. Reduces component size by 47% while improving maintainability.
Add live preview to branding form showing featured image, background color, and logo. Add database fields and toggles to control visibility of each element in project headers.
Add return false to drop handler so ProseMirror's Dropcursor extension can handle the actual node movement. Previously the handler would intercept drops but not perform any movement.