This commit addresses multiple collection management issues to improve user experience:
## Template Selection Modal Improvements
- Replace inline styles with CSS classes for reliable visual feedback
- Fix default template selection conflicts that showed multiple templates as selected
- Add styled template previews that show actual CSS styling differences
- Improve modal responsiveness and visual hierarchy
## Collection Item Creation Fixes
- Fix empty collection items with no content/height that were unclickable
- Preserve template placeholder content during item creation instead of clearing it
- Implement proper positioning system using GetMaxPosition to place new items at collection end
- Add position calculation logic to prevent new items from jumping to beginning
## Backend Positioning System
- Add GetMaxPosition method to all repository implementations (SQLite, PostgreSQL, HTTPClient)
- Update CreateCollectionItemFromTemplate to calculate correct position (maxPos + 1)
- Maintain reconstruction ordering by position ASC for consistent item placement
## Frontend Template Selection
- CSS class-based selection states replace problematic inline style manipulation
- Template previews now render actual HTML with real page styling
- Improved hover states and selection visual feedback
- Fixed auto-selection interference with user interaction
These changes ensure collection items appear in expected order and template selection
provides clear visual feedback with actual styling previews.
Restore missing content hydration logic in reconstructCollectionItems method that was accidentally removed during the engine file split (b46f643). Collection items were appearing empty instead of displaying original developer content. This fix restores the database-first behavior where content is properly extracted, stored, and injected back into .insertr elements within collection items.
Replace nil context with context.Background() in content.go to prevent database operations from hanging indefinitely. Clean up outdated documentation files and add current project structure analysis.
Split monolithic engine.go (776 lines) into specialized files:
- engine.go: Core orchestration (142 lines, 82% reduction)
- collection.go: Collection processing and management (445 lines)
- content.go: Content injection and extraction (152 lines)
- discovery.go: Element discovery and DOM traversal (85 lines)
Benefits:
- Single responsibility principle applied to each file
- Better code organization and navigation
- Improved testability of individual components
- Easier team development and code reviews
- Maintained full API compatibility with no breaking changes
- Move addClass and setAttribute from ContentEngine/Injector to utils.go
- Remove duplicate hasInsertrClass implementation
- Add RemoveClass and HasClass utilities for completeness
- Eliminates 74+ lines of exact duplication across files
- Implement complete mushroom foraging blog with chanterelles article
- Add rich demonstration of .insertr and .insertr-add functionality
- Include comprehensive documentation for future .insertr-content vision
- Update project styling and configuration to support blog demo
- Enhance engine and API handlers for improved content management
- Remove dan-eden-portfolio and devigo-web demo sites
- Clean up demo testing infrastructure and scripts
- Remove frontend test files (html-preservation, style-detection tests)
- Update configuration and auth improvements
- Simplify demo structure to focus on core functionality
This cleanup reduces repository size and focuses on essential demos.
- Remove auto-discovery entirely (~450 lines)
* Delete internal/content/discoverer.go
* Simplify enhancer to single-phase processing
* Remove duplicate container expansion logic
- Consolidate repository implementations
* Move internal/content/client.go → internal/db/http_client.go
* Group all repository implementations in db/ package
- Add file utilities to engine following Go stdlib patterns
* Add engine.ProcessFile() and ProcessDirectory() methods
* Engine now handles both content processing AND file operations
- Move site management to dedicated package
* Move internal/content/site_manager.go → internal/sites/manager.go
* Clear separation of site lifecycle from content processing
- Preserve container expansion (syntactic sugar)
* .insertr on containers still auto-applies to viable children
* Container detection logic consolidated in engine/utils.go
Result: Clean architecture with single source of truth for .insertr processing
- Replace type switching with clean repository pattern using sqlc-generated code
- Move ContentRepository interface and domain models to db package
- Create separate SQLiteRepository and PostgreSQLRepository implementations
- Remove unnecessary RepositoryAdapter and ContentClient interface duplication
- Update all clients (HTTP, Mock) to implement db.ContentRepository directly
- Add context.Context parameters to all repository methods (Go best practice)
- Eliminate duplicate domain models and type conversions
- Remove type aliases - use db package types directly throughout codebase
- Update engine, content managers, and API handlers to use repositories directly
Benefits:
- Zero runtime type switching overhead
- Single source of truth for domain models
- Clean package boundaries and separation of concerns
- Standard Go interface patterns with context support
- Easier testing with mockable repository interface
- Maintainable: adding new database types requires no changes to existing code
- Add bulk reorder API endpoint (PUT /api/collections/{id}/reorder) with atomic transactions
- Replace individual position updates with efficient bulk operations in frontend
- Implement unified ID generation and proper data-item-id injection during enhancement
- Fix collection item position persistence through content edit cycles
- Add optimistic UI with rollback capability for better user experience
- Update sqlc queries to include last_edited_by fields in position updates
- Remove obsolete data-content-type attributes and unify naming conventions
Consolidates duplicate code and removes technical debt accumulated during rapid development. This cleanup improves maintainability while preserving all functionality.
Backend cleanup:
- Remove unused legacy function findViableChildrenLegacy()
- Consolidate duplicate SQL null string helper functions into shared utils
- Unify text extraction functions across utils, engine, and id_generator
- Consolidate duplicate attribute getter functions into single implementation
Frontend cleanup:
- Remove duplicate authentication methods (authenticateWithOAuth vs performOAuthFlow)
- Remove unused hasPermission() method from auth.js
- Centralize repetitive API endpoint construction in api-client.js
- Reduce excessive console logging while preserving important error logs
Impact: -144 lines of code, improved maintainability, no functionality changes
All tests pass and builds succeed
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
• Add full multi-table schema for collections with normalized design (collections, collection_templates, collection_items, collection_item_versions)
• Implement collection detection and processing in enhancement pipeline for .insertr-add elements
• Add template extraction and storage from existing HTML children with multi-variant support
• Enable collection reconstruction from database on server restart with proper DOM rebuilding
• Extend ContentClient interface with collection operations and full database integration
• Update enhance command to use engine.DatabaseClient for collection persistence support
Major architectural simplification removing content type complexity:
Database Schema:
- Remove 'type' field from content and content_versions tables
- Simplify to pure HTML storage with html_content + original_template
- Regenerate all sqlc models for SQLite and PostgreSQL
API Simplification:
- Remove content type routing and validation
- Eliminate type-specific handlers (text/markdown/structured)
- Unified HTML-first approach for all content operations
- Simplify CreateContent and UpdateContent to HTML-only
Backend Enhancements:
- Update enhancer to only generate data-content-id (no data-content-type)
- Improve container expansion utilities with comprehensive block/inline rules
- Add Phase 3 preparation with boundary-respecting traversal logic
- Strengthen element classification for viable children detection
Documentation:
- Update TODO.md to reflect Phase 1-3 completion status
- Add WORKING_ON.md documenting the architectural transformation
- Mark container expansion and HTML-first architecture as complete
This completes the transition to a unified HTML-first content management system
with automatic style detection and element-based behavior, eliminating the
complex multi-type system in favor of semantic HTML-driven editing.
- Add backend container transformation in engine.go following syntactic sugar specification
- Containers with .insertr get class removed and viable children get .insertr added
- Remove incorrect frontend container expansion - frontend only finds enhanced elements
- Fix StyleAwareEditor hasMultiPropertyElements runtime error
- Add addClass/removeClass methods to ContentEngine for class manipulation
- Update frontend to match HTML-first approach with no runtime container logic
- Test verified: container <section class='insertr'> transforms to individual h1.insertr, p.insertr, button.insertr
This completes the container expansion functionality per CLASSES.md:
Developer convenience (one .insertr enables section editing) + granular control (individual element editing)
- Add sibling context detection to identify unique heading content
- Include parent container context with enhanced class filtering
- Look for heading siblings (h1-h6) that provide unique container context
- Extract up to 12 chars of sibling heading text for differentiation
Results:
✅ Collision Elimination: From 8 collisions to 0 collisions
✅ Unique Base IDs: Each element gets distinct ID (no -1, -2, -3 suffixes)
✅ Better Context: 'Example 1', 'Example 2' headings provide unique signatures
✅ Maintained Stability: Same elements still get same IDs across runs
Before: index-p-cad2a8, index-p-cad2a8-1, index-p-cad2a8-2... (8 collisions)
After: index-p-1198e8, index-p-215de9, index-p-604e11... (0 collisions)
- Remove content preview from ID generation for stable structural IDs
- Implement database-first approach to check content existence before creation
- Add enhanced DOM path, semantic context, and precise sibling indexing
- Replace HTML attribute checking with reliable database lookups
- Add collision handling with increment counters for similar elements
Fixes:
✅ UNIQUE constraint errors eliminated (multiple enhancement runs work)
✅ Structural stability (same element keeps same ID regardless of content changes)
✅ Database-driven workflow (single source of truth for content existence)
✅ Enhanced collision resistance with detailed structural differentiation
Results: No more 'Failed to store content' errors, stable enhance workflow.
- Replace random UUID with 6-component deterministic signature
- Use filePath|domPath|tag|classes|contentPreview|siblingIndex for uniqueness
- Enhance sibling positioning with insertr-aware index calculation
- Improve DOM path generation with meaningful class inclusion
- Restore ID consistency across enhancement runs for reliable content injection
Results:
✅ ID Consistency: Same elements always get same IDs (index-p-639460)
✅ Collision Resistance: Different elements get different IDs (4c7206, 23df20, 5a975d)
✅ File Scoping: Same structure in different files gets different IDs
✅ Enhanced Workflow: API edit → enhance button → content injected successfully
Fixes enhance button by ensuring API content IDs match enhancement-generated IDs.
- Replace random UUID suffix with deterministic hash-based signature
- Use element DOM path, sibling position, and content preview for uniqueness
- Ensure same elements always get the same content ID across enhancements
- Fix critical bug where content updates weren't being injected into static files
This resolves the enhance button workflow: API content updates → enhance trigger → static file injection.
- Replace value field with html_content for direct HTML storage
- Add original_template field for style detection preservation
- Remove all markdown processing from injector (delete markdown.go)
- Fix critical content extraction/injection bugs in engine
- Add missing UpdateContent PUT handler for content persistence
- Fix API client field names and add updateContent() method
- Resolve content type validation (only allow text/link types)
- Add UUID-based ID generation to prevent collisions
- Complete first-pass processing workflow for unprocessed elements
- Verify end-to-end: Enhancement → Database → API → Editor → Persistence
All 37 files updated for HTML-first content management system.
Phase 3a implementation complete and production ready.
- Remove complex style preservation system from editor
- Simplify markdown conversion back to straightforward approach
- Remove StyleContext class and style-aware conversion methods
- Switch content type from 'html' back to 'markdown' for consistency
- Clean up editor workflow to focus on core markdown editing
- Remove ~500 lines of unnecessary style complexity
This completes the UI unification cleanup by removing the overly complex
style preservation system that was making the editor harder to maintain.
- Add StyleContext class for extracting and applying HTML attributes/styles
- Enhance MarkdownConverter with style-aware conversion methods
- Switch backend storage from markdown to HTML with 'html' content type
- Update editor workflow to preserve CSS classes, IDs, and attributes
- Maintain markdown editing UX while storing HTML for style preservation
- Support complex attributes like rel, data-*, aria-*, etc.
This enables editing styled content like <a class="fancy" rel="me">text</a>
while preserving all styling attributes through the markdown editing process.
- Rebuild JavaScript library with delayed control panel initialization
- Update server assets to include latest UI behavior changes
- Ensure built assets reflect invisible UI for regular visitors
The control panel now only appears after gate activation, maintaining
the invisible CMS principle for end users.
- Migrate from inline CSS to external insertr.css with cascade layer architecture
- Add CSS CDN serving capability (ServeInsertrCSS handler and /insertr.css route)
- Implement hybrid approach: @layer insertr for modern browsers + html body selectors for legacy browsers
- Remove scattered inline CSS from JavaScript modules for better maintainability
- Solve form element spacing conflicts with aggressive site CSS resets like '* {margin:0; padding:0}'
- Enable proper CSS caching and separation of concerns
- Restructure demo directory from test-sites/ to demos/ with flattened layout
- Add auto-enhancement on server startup for all sites with auto_enhance: true
- Fix inconsistent content ID generation that prevented dan-eden-portfolio content persistence
- Update server configuration to enhance from source to separate output directories
- Remove manual enhancement from justfile in favor of automatic server enhancement
- Clean up legacy test files and unused restore command
- Update build system to use CDN endpoint instead of file copying
- Replace dual script injection (external + inline) with single script approach
- Pass site configuration via data attributes instead of inline JavaScript
- Update library auto-initialization to read config from script data attributes
- Reduce HTML bloat by eliminating 30+ lines of inline initialization code
- Maintain future-proof CDN compatibility and duplication prevention
Enhanced files now contain only one clean script tag with configuration.
- Replace complex multi-server setup (live-server + API) with unified Go server
- Serve all sites at /sites/{site_id} endpoints, eliminating port conflicts
- Fix content-type middleware to serve proper MIME types for static files
- Prevent script injection duplication with future-proof CDN-compatible detection
- Remove auto page reload from enhance button to eliminate editing interruptions
- Enable seamless content editing workflow with manual enhancement control
Development now requires only 'just dev' instead of complex demo commands.
All sites immediately available at localhost:8080 without hot reload conflicts.
- Remove obsolete cmd/auto_enhance.go command (replaced by unified enhance)
- Implement EnhanceInPlace method using unified pipeline
- Remove generated demo files from git tracking
- Verify all functionality works after cleanup:
* go build successful
* enhance command working correctly
* unified pipeline (discovery → ID generation → content injection) verified
* clean command structure (only enhance, serve, restore commands)
The codebase is now clean with no legacy auto-enhance references or stub implementations. All functionality consolidated into the unified Discoverer + Enhancer architecture.
- Move all ContentItem, ContentClient, ContentResponse types to engine/types.go as single source of truth
- Remove duplicate type definitions from content/types.go
- Update all imports across codebase to use engine types
- Enhance engine to extract existing data-content-id from HTML markup
- Simplify frontend to always send html_markup, let server handle ID extraction/generation
- Fix contentId reference errors in frontend error handling
- Add getAttribute helper method to engine for ID extraction
- Add GetAllContent method to engine.DatabaseClient
- Update enhancer to use engine.ContentClient interface
- All builds and API endpoints verified working
This resolves the 400 Bad Request errors and creates a unified architecture where the server is the single source of truth for all ID generation and content type management.
Database Structure Cleanup:
- Move all SQL files from ./db/ to ./internal/db/
- Update sqlc.yaml to use new paths (preserving schema+setup.sql hack)
- Consolidate database-related code in single directory
- Remove empty ./db/ directory
Injector Migration:
- Move injector.go from content package to engine package
- Update ContentClient interface to return map instead of slice for GetBulkContent
- Update database client implementation to match interface
- Remove injector dependency from enhancer (stub implementation)
Demo-Site Consolidation:
- Move demo-site to test-sites/demo-site for better organization
- Update build scripts to use new demo-site location
- Maintain all functionality while improving project structure
This continues the unified architecture consolidation by moving core content
processing logic to the engine and organizing related files properly.
- Remove internal/parser package and all legacy ID generation logic
- Update enhancer and auto_enhancer to use unified engine functions
- Migrate utility functions (FindViableChildren, HasEditableContent) to engine
- Create stub enhancer implementation that uses unified engine architecture
- Ensure all enhancement workflows now go through single unified system
- Remove parser dependencies and consolidate content processing logic
This completes the cleanup phase - all components now use unified engine
instead of fragmented ID generation systems.
- Create internal/engine module as single source of truth for content processing
- Consolidate 4 separate ID generation systems into one unified engine
- Update API handlers to use engine for consistent server-side ID generation
- Remove frontend client-side ID generation, delegate to server engine
- Ensure identical HTML markup + file path produces identical content IDs
- Resolve content persistence failures caused by ID fragmentation between manual editing and enhancement processes