docs: add Media Manager V2 architecture and mockup

This commit is contained in:
Ben Miller
2025-12-28 07:06:22 -07:00
parent 8554ae9610
commit a9cb63fd67
2 changed files with 111 additions and 0 deletions

View File

@ -0,0 +1,111 @@
# Media Manager V2 Design & Architecture
## Overview
The **Media Manager V2** transforms the product image management experience from a simple upload utility to a full-featured "WYSIWYG" editor. It introduces a persistent "Draft" state, drag-and-drop reordering, and a robust generic synchronization engine that reconciles state between Google Drive (Source of Truth) and Shopify.
## UI UX Design
### Launch Logic
To work around Google Apps Script limitations (triggers cannot open modals):
1. **Watcher Sidebar**: A lightweight sidebar remains open, polling for selection changes.
2. **Context Action**: When a user selects a cell in **Column A** (Product Image), the sidebar presents a large **"Edit Media"** button.
3. **Modal**: Clicking the button launches the full Media Manager Modal.
### Interface Features
- **Grid Layout**: Drag-and-drop sortable grid.
- **Badges**:
- ☁️ **Drive Only**: New uploads or files not yet synced.
- 🛍️ **Shopify Only**: Media found on Shopify but missing from Drive (will be backfilled).
-**Synced**: Verifiable link between Drive and Shopify.
- **Video Support**:
- Grid: Videos play silently loop (`muted autoplay`).
- Preview: Full modal with controls.
- **Details Mode**: A togglable text view listing pending operations (e.g., "Deleting 2 files, Reordering 3...").
![Media Manager Mockup](./images/media_manager_mockup.png)
## Data Architecture
### 1. Naming Convention
Files in Drive function as the source of truth for order.
- **Pattern**: `[SKU]_[Index].[Extension]`
- **Example**: `TSHIRT-001_0001.jpg`, `TSHIRT-001_0002.mp4`
- **Padding**: 4 digits to support >10 items cleanly.
### 2. Session Recovery (Draft State)
To prevent data loss during browser refreshes or crashes, the edit state is persisted immediately to `UserProperties`.
- **Storage**: `PropertiesService.getUserProperties()`
- **Key**: `MEDIA_SESSION_[SKU]`
- **Schema**:
```json
{
"schemaVersion": 1,
"timestamp": 1234567890,
"sku": "SKU-123",
"items": [
{
"id": "drive_file_id_or_shopify_id",
"source": "drive|shopify|new",
"filename": "original_name.jpg",
"status": "active|deleted|staged",
"thumbnail": "data:image..."
}
]
}
```
### 3. Synchronization Logic (Two-Way Reconcile)
#### Phase A: Load & Match (Read-Only)
Executed when opening the manager.
1. **Fetch**: Get all Drive Files in SKU folder and all Shopify Media via GraphQL.
2. **Match**:
- **Strong Verification**: `Drive.appProperties.shopify_media_id === Shopify.media.id`
- **Legacy Fallback**: `Drive.name === Shopify.filename` (Only if no ID match)
3. **Conflict Resolution**: If duplicates found, prefer high-res/latest.
#### Phase B: Save (Transactional)
Executed when user clicks "Save".
1. **Delete**: Process items marked `deleted` (Remove from Shopify & Trash in Drive).
2. **Backfill**: Download "Shopify Only" items to Drive -> Set `appProperties`.
3. **Upload**: Upload "Drive Only" items -> Create Media -> Set `appProperties`.
4. **Reorder**: Execute `productReorderMedia` GraphQL mutation with final ID list.
5. **Finalize**:
- Rename all Drive files to `SKU_{index}` sequence.
- Clear `MEDIA_SESSION_[SKU]` property.
## Technical Components
### Frontend
- **HTML/CSS**: Glassmorphism aesthetic (Inter font, backdrop-filter).
- **JS**: Vanilla JS with HTML5 Drag & Drop API.
### Backend Services
- **`MediaService`**: Orchestrates the Phase A/B logic.
- **`ShopifyMediaService`**: Handles GraphQL mutations (`productCreateMedia`, `productReorderMedia`).
- **`GASDriveService`**: Manages File renaming and `appProperties` metadata.
## Future Proofing
- **Metadata**: We avoid relying on file hashes/sizes due to Shopify's aggressive image compression. We rely strictly on stored IDs (`appProperties`) where possible.
- **Scale**: Pagination may be needed if SKUs usually exceed 50 images (current limit 250 in GraphQL).
## Development Roadmap
- [ ] **Backend Implementation**
- [ ] Update `getMediaForSku` to return combined state (Drive + Shopify + Session)
- [ ] Implement `saveMediaChanges(sku, changes)` transaction logic
- [ ] Renaming files (`SKU_####.ext`)
- [ ] Deleting/Trashing files
- [ ] Uploading/Backfilling
- [ ] Implement Session Recovery (Read/Write `UserProperties`)
- [ ] **Frontend Implementation**
- [ ] **Watcher Sidebar**: Create `MediaSidebar.html` to poll for selection.
- [ ] **Manager Modal**: Refactor `MediaManager.html`.
- [ ] State Management (Staging)
- [ ] Drag-and-Drop Grid
- [ ] Preview Modal (Image + Video)
- [ ] "Details..." View
- [ ] **Verification**
- [ ] Manual Test: Drag & Drop ordering
- [ ] Manual Test: Save & Sync
- [ ] Manual Test: Session Recovery (Reload browser mid-edit)