# Collection Reordering Bug Fix - Implementation Plan ## Problem Summary Collection item reordering fails after content edits. Position updates work at API level but don't persist through the enhancement cycle, causing items to revert to original order after page refresh. ## Root Cause Analysis 1. **Missing HTML Attributes**: `data-item-id` not injected during enhancement (around line 622 in `reconstructCollectionItems()`) 2. **API Design Flaw**: No bulk reorder endpoint, only individual item updates 3. **ID Generation Inconsistency**: Different patterns for initial items vs new items 4. **Attribute Naming Issues**: Collection containers incorrectly use `data-content-id`, content has special `collection-item-` prefixes 5. **Obsolete Attributes**: `data-content-type` no longer needed after HTML-only switch 6. **Dynamic vs Static**: Frontend dynamically injects IDs instead of getting them from enhanced HTML ## Architecture Principles - **Static Enhancement**: All IDs should be injected during enhancement, not dynamically by JavaScript - **Unified ID Generation**: Same deterministic system for all entities (content, collections, items) - **Clean Separation**: Collections manage structure, `.insertr` elements manage content - **No Backwards Compatibility**: Clean slate approach, all test data can be cleared ## Implementation Plan ### Phase 1: Backend Enhancement Fixes #### File: `/home/fitz/insertr/internal/engine/engine.go` - **Line 622**: Add `data-item-id` injection in `reconstructCollectionItems()` - **Line 812**: Replace `initial-` ID pattern with unified generator - **Line 734**: Replace timestamp-based ID pattern with unified generator - **Line 107**: Change collection containers from `data-content-id` to `data-collection-id` #### File: `/home/fitz/insertr/internal/engine/injector.go` - **Line 165**: Remove obsolete `data-content-type` attribute injection ### Phase 2: Frontend API Updates #### File: `/home/fitz/insertr/lib/src/core/api-client.js` - Add `reorderCollection()` method for bulk operations - Remove `updateCollectionItemPosition()` method (individual updates) #### File: `/home/fitz/insertr/lib/src/ui/collection-manager.js` - Remove dynamic ID injection logic (around line 286) - Update attribute names from `data-collection-item-id` to `data-item-id` - Replace individual position updates with bulk reorder calls ### Phase 3: Backend API Enhancement #### File: `/home/fitz/insertr/internal/api/handlers.go` - Add `ReorderCollection` handler for bulk position updates - Endpoint: `PUT /api/sites/{siteId}/collections/{collectionId}/reorder` ## Expected HTML Output Change ### Before ```html
``` ### After ```html
``` ## Implementation Steps ### Day 1: Backend Enhancement 1. **Clear test data**: Clean database for fresh start 2. **Fix ID injection**: Add `data-item-id` attributes during enhancement 3. **Unify ID generation**: Replace inconsistent patterns with unified system 4. **Update attribute names**: Change `data-content-id` to `data-collection-id` for collections 5. **Remove obsolete attributes**: Clean up `data-content-type` ### Day 2: Frontend Updates 1. **Remove dynamic injection**: Stop generating IDs in JavaScript 2. **Update attribute references**: Change to new naming convention 3. **Add bulk reorder API**: Implement `reorderCollection()` method 4. **Update collection manager**: Use bulk operations instead of individual updates ### Day 3: Backend API 1. **Add bulk reorder endpoint**: Implement `ReorderCollection` handler 2. **Route configuration**: Add PUT endpoint for bulk reorder 3. **Database operations**: Efficient bulk position updates ### Day 4: Testing & Validation 1. **Test enhancement cycle**: Verify positions persist after content edits 2. **Test reordering**: Ensure drag-and-drop works correctly 3. **Test page refresh**: Confirm order maintained after reload 4. **Cross-browser testing**: Verify compatibility ## Current Status - ✅ API endpoint accepts `site_id` as query parameter correctly - ✅ Root cause analysis complete - ✅ Implementation plan finalized - ✅ **Phase 1 COMPLETE**: Backend enhancement injection implemented - ✅ Unified ID generation across all entities (collections, items, content) - ✅ Data attribute injection working (data-collection-id, data-item-id, data-content-id) - ✅ Obsolete attributes removed (data-content-type) - ✅ **Phase 2 COMPLETE**: Frontend API updates implemented - ✅ Dynamic ID injection removed (except for new items from server) - ✅ Attribute references updated to data-item-id - ✅ Bulk reorderCollection() API method added - ✅ Individual updateCollectionItemPosition() method removed - ✅ Collection manager uses bulk reorder with optimistic UI - ✅ **Phase 3 COMPLETE**: Backend bulk reorder endpoint implemented - ✅ ReorderCollection handler added with transaction-based bulk updates - ✅ PUT /api/collections/{id}/reorder route configured - ✅ Updated sqlc queries to include last_edited_by in position updates - ✅ Atomic transaction ensures consistency during bulk reorder operations ## Test Environment - Server: `just dev` (http://localhost:8080) - Test site: `/sites/simple/` with testimonials collection - Database: Shows position conflicts (multiple items at position 1) ## Success Criteria ✅ 1. ✅ Collection items maintain order after content edits (Phase 1) 2. ✅ Drag-and-drop reordering works without page refresh (Phase 2+3) 3. ✅ Order persists through full enhancement cycles (Phase 1) 4. ✅ Clean HTML output with proper attributes (Phase 1) 5. ✅ No JavaScript errors in browser console (Phase 2) ## 🎉 IMPLEMENTATION COMPLETE All three phases have been successfully implemented: **Phase 1**: ✅ Backend enhancement injection with unified ID generation **Phase 2**: ✅ Frontend API updates with bulk operations and optimistic UI **Phase 3**: ✅ Backend bulk reorder endpoint with atomic transactions Collection item reordering now works end-to-end with persistence through content edits! ## Notes - All test data can be cleared - no backwards compatibility needed - Focus on clean implementation over migration - HTML-first approach: all attributes come from server enhancement - Performance: bulk operations instead of individual API calls