Quand un onglet est sélectionné, les produits Shopify absents du tab
peuvent appartenir à d'autres familles — ne pas les marquer 'deactivate'.
Les désactivations ne s'appliquent qu'en mode catalogue complet (sans filtre).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- GET /api/sheets/tabs : liste les onglets Google Sheets disponibles
- readSheetProducts(tab?) et fetchPendingProducts(set, tab?) acceptent un filtre
- /api/sync/preview?tab=xxx et /api/creation/preview?tab=xxx filtrent sur un onglet
- Composant FamilySelector : grille de boutons chargeant les onglets dynamiquement
- Page Sync : étape 0 de sélection famille avant l'analyse
- Page Création : étape famille avant analyse, badge de famille sélectionnée
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- /api/dashboard/stats appelle Google Drive API pour récupérer modifiedTime du Sheets
- Compare avec createdAt de la dernière SyncRun → sheetDrift: boolean
- Dashboard affiche un bandeau amber cliquable si Sheets plus récent que la dernière sync
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- table-fixed avec colgroup pour éviter que la colonne Ref écrase les autres
- overflow-x-auto pour permettre le scroll si nécessaire
- parseSheetRows : ignore les refs invalides (< 2 chars, caractères spéciaux, mots réservés)
- parseSheetRows : ignore les lignes sans prix valide (séparateurs, notes)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Nouvel endpoint /api/dashboard/stats : comptes produits Shopify (actifs/brouillons/sans image) + dernière sync depuis Prisma
- Nouvel endpoint /api/dashboard/pending : nombre de produits en attente depuis Google Sheets (lazy)
- Page dashboard remplace le stub avec 4 KPIs, bloc dernière sync, et raccourcis vers les sections
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implémente Task 4 du Plan 5:
- normalizeMetafieldKey: minuscules, accents retirés, espaces/parenth→_, max 30 chars
- matchMetafields: compare clé normalisée d'une colonne avec les clés existantes
- fetchMetafieldDefinitions: récupère les définitions Shopify existantes
- ensureMetafieldDefinition: crée une définition si manquante
- setProductMetafield: définit un métachamp sur un produit
7 tests passants (4 normalizeMetafieldKey + 3 matchMetafields).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>