Files
Homepage/ORDER-PERSISTENCE.md

3.5 KiB

Order Persistence - Server-Side Storage

Overview

Service order (drag-and-drop positioning) is now persisted server-side using SQLite database, with localStorage as a fallback/cache.

Architecture

Browser (drag-drop) → localStorage (immediate)
                    → /api/order (async save to server)
                                   ↓
                            order-service (Flask)
                                   ↓
                            SQLite Database
                            (/data/services-order.db)

Components

Backend Service: order-service.py

  • Port: 8082 (internal)
  • Database: SQLite at /data/services-order.db
  • Volume: order-data (persistent across container restarts)

API Endpoints

GET /api/order?user_id=default

  • Retrieves saved service order for a user
  • Returns: JSON object mapping group names to ordered service IDs
  • Example response:
    {
      "Management": ["portainer", "uptime-kuma", "scrutiny"],
      "Media": ["jellyfin", "jellyseer", "transmission"]
    }
    

POST /api/order

  • Saves service order for a user
  • Request body:
    {
      "user_id": "default",
      "order": {
        "Management": ["portainer", "uptime-kuma"],
        ...
      }
    }
    
  • Response: {"success": true, "message": "Order saved"}

DELETE /api/order?user_id=default

  • Resets order to default (deletes saved order)
  • Response: {"success": true, "message": "Order deleted"}

Database Schema

CREATE TABLE service_order (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    user_id TEXT NOT NULL DEFAULT 'default',
    order_data TEXT NOT NULL,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Behavior

On Page Load

  1. JavaScript calls /api/order?user_id=default
  2. If server has data, use it and cache in localStorage
  3. If server returns empty, fall back to localStorage
  4. If both empty, use default XML order

On Drag-Drop

  1. Save to localStorage immediately (instant response)
  2. Async POST to /api/order in background
  3. If server save fails, localStorage still works as fallback

Benefits

  • Cross-device sync: Order syncs across browsers/devices
  • Persistent: Survives container restarts, browser clearing
  • Fallback: localStorage works if server is down
  • Fast: Instant UI update, async server save

Data Location

  • Server: Docker volume services-homepage_order-data
    • Inspect: docker volume inspect services-homepage_order-data
    • Location: /var/lib/docker/volumes/services-homepage_order-data/_data/
  • Client: Browser localStorage key services-order

Backup/Restore

Backup Server Data

# Copy database from volume
docker run --rm -v services-homepage_order-data:/data -v $(pwd):/backup \
  alpine cp /data/services-order.db /backup/order-backup.db

Restore Server Data

# Copy database to volume
docker run --rm -v services-homepage_order-data:/data -v $(pwd):/backup \
  alpine cp /backup/order-backup.db /data/services-order.db

# Restart service to load new data
docker restart services-homepage-order-service

Reset All Orders

# Delete all saved orders
curl -X DELETE "http://192.168.2.180:8088/api/order?user_id=default"

# Or restart with fresh database
docker compose down
docker volume rm services-homepage_order-data
docker compose up -d

Future Enhancements

  • Multi-user support (authentication)
  • Order history/versioning
  • Export/import order via UI
  • Sync status indicator in UI
  • Conflict resolution for concurrent edits