Files
insertr/COLLECTION_REORDER_FIX.md
Joakim 824719f07d Implement collection item reordering with bulk operations and persistent HTML attributes
- 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
2025-10-07 22:59:00 +02:00

6.6 KiB

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

<div class="testimonials insertr-add" data-content-id="index-testimonials-3ef43e">
  <div class="testimonial-item">  <!-- Missing data-item-id -->
    <blockquote class="insertr" data-content-id="collection-item-blockquote-756544" data-content-type="html">

After

<div class="testimonials insertr-add" data-collection-id="index-testimonials-3ef43e">
  <div class="testimonial-item" data-item-id="index-testimonials-3ef43e-abc123">
    <blockquote class="insertr" data-content-id="index-blockquote-def456">

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