# 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: ```json { "Management": ["portainer", "uptime-kuma", "scrutiny"], "Media": ["jellyfin", "jellyseer", "transmission"] } ``` #### POST `/api/order` - Saves service order for a user - Request body: ```json { "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 ```sql 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 ```bash # 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 ```bash # 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 ```bash # 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