Date : 29 décembre 2024 Durée : Session longue (plusieurs heures) Objectif : Refactoring architecture + préparation déploiement multi-instance
Session majeure de refactoring de QwikPress pour :
Les credentials Supabase étaient accessibles dans plusieurs fichiers, risque de fuite vers le frontend.
Plugin@data.ts (SEUL accès aux credentials)
↓
sharedMap.set('storage', StorageService)
↓
server$ accède via this.sharedMap.get('storage')
src/routes/plugin@data.ts - Refactorisé pour isolation credentialssrc/services/storage/supabase-storage.service.ts - Reçoit client injectésrc/services/data/supabase-data.service.ts - Deprecated, redirige vers storageDeux systèmes parallèles : IDataService (ancien, 56 fichiers) et StorageService (nouveau).
src/services/storage/data-service-adapter.ts - Adaptateur IDataService → StorageServicesrc/services/storage/index.ts - Exports unifiés// Pages
getPage, getPageBySlug, getAllPages, getChildPages, savePage, deletePage, slugExists
// Config
getConfig, saveConfig
// Connectors
getConnector, getAllConnectors, saveConnector, deleteConnector
// Common Modules
getCommonModule, getAllCommonModules, saveCommonModule, deleteCommonModule
// Redirections
getRedirection, getAllRedirections, saveRedirection, deleteRedirection
getRedirectionConfig, saveRedirectionConfig, getRedirectionLogs, addRedirectionLog
// Media
listMedia, getMedia, uploadMedia, deleteMedia, getMediaUrl
Images passées comme string = le frontend découvre la taille = CLS, mauvais SSR.
interface MediaRef {
src: string;
width: number;
height: number;
ratio: number;
mimeType: string;
alt: string; // Obligatoire accessibilité
dominantColor?: string;
srcset?: string;
}
createMediaRef() - Créer un MediaRefgetResizedUrl() - URL avec params resizegetResizedDimensions() - Calcul dimensionsgetResizedMediaRef() - MediaRef redimensionnésrc/types/media.ts - Types et helpers médiassrc/services/storage/sync.service.ts - Service de syncsrc/routes/api/sync/export/index.ts - API GET téléchargement ZIPsrc/routes/api/sync/import/index.ts - API POST upload ZIPGET /api/sync/export → Télécharger ZIP
GET /api/sync/export?includeMedias=false
POST /api/sync/import → Importer ZIP (backup auto)
QwikPress = moteur réutilisable pour tous les projets :
qwikpress:needfinder → Dashboard NeedFinderqwikpress:spacemessage → Site SpaceMessageChaque projet a son propre SCHÉMA et BUCKET :
Schéma: qwikpress_needfinder
Bucket: medias-needfinder
Schéma: qwikpress_spacemessage
Bucket: medias-spacemessage
Aucune interférence possible entre projets.
conf.prod.gouroubleu.yml - Config déploiement PRODconf.dev.gouroubleu.yml - Config déploiement DEVconf.template.gouroubleu.yml - Template multi-instanceDockerfile - Multi-stage optimisé (Alpine)src/routes/api/health/index.ts - Endpoint healthcheckscripts/supabase-new-project.sql - Script création schéma| Projet | Port PROD | Port DEV |
|---|---|---|
| needfinder | 4700 | 4800 |
| spacemessage | 4701 | 4801 |
| lifetracker | 4702 | 4802 |
| polititrack | 4703 | 4803 |
| storykids | 4704 | 4804 |
mets en prod qwikpress:needfinder
mets en dev qwikpress:spacemessage
Avec l'isolation par schéma, on peut avoir plusieurs versions :
qwikpress_needfinder → Production
qwikpress_needfinder_v2 → Staging
qwikpress_needfinder_backup → Sauvegarde
Changer SUPABASE_SCHEMA dans l'environnement = switch de version.
Sections ajoutées/mises à jour :
| Fichier | Description |
|---|---|
src/types/media.ts |
Types MediaRef + helpers resize |
src/services/storage/data-service-adapter.ts |
Adaptateur IDataService |
src/services/storage/sync.service.ts |
Service synchronisation |
src/routes/api/sync/export/index.ts |
API export ZIP |
src/routes/api/sync/import/index.ts |
API import ZIP |
src/routes/api/health/index.ts |
Healthcheck Docker |
conf.prod.gouroubleu.yml |
Config déploiement PROD |
conf.dev.gouroubleu.yml |
Config déploiement DEV |
conf.template.gouroubleu.yml |
Template multi-instance |
scripts/supabase-new-project.sql |
Script création schéma Supabase |
backlog/29-12-2024-qwikpress-vision-manifeste.md |
Vision projet |
| Fichier | Modification |
|---|---|
src/routes/plugin@data.ts |
Schéma dynamique, isolation credentials |
src/services/storage/supabase-storage.service.ts |
Suppression site_id, client injecté |
src/services/storage/index.ts |
Exports unifiés + sync |
Dockerfile |
Multi-stage Alpine optimisé |
CLAUDE.md |
Documentation complète mise à jour |
mets en prod qwikpress:needfinder// ✅ BON
const result = await something();
if (!result) {
return { success: false, error: 'Message' };
}
return { success: true, data: result };
// ❌ INTERDIT
try { ... } catch { ... }
qwikpress_{slug}/
├── config (1 ligne)
├── pages
├── common_modules
├── connectors
├── redirections
├── redirection_config
├── redirection_logs
└── medias (métadonnées)
SITE_SLUG=needfinder
SUPABASE_SCHEMA=qwikpress_needfinder # Auto si non défini
SUPABASE_BUCKET=medias-needfinder # Auto si non défini
DATA_MODE=supabase # ou 'file'
Session terminée avec succès. QwikPress est prêt pour le multi-instance !