From 47258bf1be678cc72825589d10a76d688c6722b3 Mon Sep 17 00:00:00 2001 From: Claude Integration Date: Sun, 31 May 2026 12:20:35 +0000 Subject: [PATCH] feat(plugin): image-gallery-aquarelle-seed hook + upload script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hook onEnable du plugin image-gallery-aquarelle-seed : - Pour chaque carbet démo, crée une entrée Media qui pointe vers son aquarelle hébergée dans MinIO sous karbe-medias/seed/aquarelle/. - s3Key préfixé seed/aquarelle/ pour faciliter le détachement au disable. - Idempotent (skip si Media existe déjà). Hook onDisable : - Supprime tous les Media avec s3Key startsWith seed/aquarelle/. - Les fichiers MinIO restent (pas de coût de redéploiement). Script scripts/upload-aquarelles.sh : - Upload depuis /tmp/karbe-aquarelles/*.{jpg,png} vers le bucket karbe-medias. - Applique la policy public-download au bucket pour que media.karbe.cosmolan.fr serve les fichiers sans auth. - À exécuter une fois après génération des illustrations. --- scripts/upload-aquarelles.sh | 35 +++++++++++++ src/lib/plugins/hooks.ts | 15 ++++++ src/lib/plugins/seeds/aquarelle-media.ts | 64 ++++++++++++++++++++++++ 3 files changed, 114 insertions(+) create mode 100755 scripts/upload-aquarelles.sh create mode 100644 src/lib/plugins/seeds/aquarelle-media.ts diff --git a/scripts/upload-aquarelles.sh b/scripts/upload-aquarelles.sh new file mode 100755 index 0000000..a208a38 --- /dev/null +++ b/scripts/upload-aquarelles.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +# Upload des illustrations aquarelles dans MinIO sous karbe-medias/seed/aquarelle/ +# + applique policy download (public-read) pour qu'elles soient servies via +# media.karbe.cosmolan.fr. +# +# Prerequis : +# - Fichiers présents dans /tmp/karbe-aquarelles/ +# - MinIO container karbe-minio en up + bucket karbe-medias existant +# - .env.production accessible pour récupérer MINIO_ROOT_USER/PASSWORD +# +# Usage : ./scripts/upload-aquarelles.sh + +set -euo pipefail + +SRC="${1:-/tmp/karbe-aquarelles}" +BUCKET="karbe-medias" +PREFIX="seed/aquarelle" + +ENV_FILE="/home/ubuntu/karbe/.env.production" +USER=$(sudo grep -oP '^MINIO_ROOT_USER=\K.*' "$ENV_FILE") +PASS=$(sudo grep -oP '^MINIO_ROOT_PASSWORD=\K.*' "$ENV_FILE") + +echo " upload depuis $SRC vers minio://$BUCKET/$PREFIX/" +docker run --rm \ + --network karbe-net \ + -v "$SRC:/data:ro" \ + --entrypoint sh \ + minio/mc:latest \ + -c " + mc alias set karbe http://karbe-minio:9000 '$USER' '$PASS' >/dev/null + mc cp /data/*.jpg /data/*.png karbe/$BUCKET/$PREFIX/ + mc anonymous set download karbe/$BUCKET || true + echo '---' + mc ls karbe/$BUCKET/$PREFIX/ | head -20 + " diff --git a/src/lib/plugins/hooks.ts b/src/lib/plugins/hooks.ts index 20c7f87..d3ff76e 100644 --- a/src/lib/plugins/hooks.ts +++ b/src/lib/plugins/hooks.ts @@ -30,6 +30,7 @@ import { seedPirogueProviders, } from "./seeds/pirogue-providers-default"; import { seedEnglishContentPages } from "./seeds/content-pages-en"; +import { detachAquarelleMedia, seedAquarelleMedia } from "./seeds/aquarelle-media"; import { prisma } from "@/lib/prisma"; // Mutuelle exclusion theme-guyane / theme-aquarelle : activer l'un @@ -119,4 +120,18 @@ export const pluginHooks: Record = { await disableOtherTheme("theme-aquarelle"); }, }, + "image-gallery-aquarelle-seed": { + onEnable: async () => { + const { attached } = await seedAquarelleMedia(); + console.log( + `[plugin image-gallery-aquarelle-seed] ${attached} Media attachés aux carbets démo`, + ); + }, + onDisable: async () => { + const count = await detachAquarelleMedia(); + console.log( + `[plugin image-gallery-aquarelle-seed] ${count} Media seedés détachés`, + ); + }, + }, }; diff --git a/src/lib/plugins/seeds/aquarelle-media.ts b/src/lib/plugins/seeds/aquarelle-media.ts new file mode 100644 index 0000000..75162b9 --- /dev/null +++ b/src/lib/plugins/seeds/aquarelle-media.ts @@ -0,0 +1,64 @@ +/** + * Seed du plugin `image-gallery-aquarelle-seed`. + * + * Crée des entrées Media qui pointent vers les illustrations aquarelle uploadées + * dans MinIO (bucket karbe-medias/seed/aquarelle/...). Une par carbet démo, + * + une « hero » et 4 « scènes » accessibles séparément via l'URL theme. + * + * Les fichiers MinIO doivent être uploadés AVANT activation du plugin + * (cf. scripts/upload-aquarelles.sh). Si les fichiers ne sont pas là, le seed + * crée quand même les Media (URLs publiques 404, mais le toggle reste réversible). + */ + +import { prisma } from "@/lib/prisma"; +import { MediaType } from "@/generated/prisma/enums"; +import { aquarelleUrl } from "@/lib/theme"; + +const CARBET_AQUARELLES: { slug: string; file: string }[] = [ + { slug: "demo-karbe-awara-maroni", file: "02-planche-carbet-awara.png" }, + { slug: "demo-karbe-wapa-comte", file: "03-planche-carbet-wapa.png" }, + { slug: "demo-karbe-maripa-approuague", file: "04-planche-carbet-maripa.png" }, + { slug: "demo-karbe-paripou-oyapock", file: "05-planche-carbet-paripou.png" }, + { slug: "demo-karbe-mahury-ce-hopital", file: "06-planche-carbet-mahury.png" }, + { slug: "demo-karbe-kourou-couleuvre", file: "07-planche-carbet-kourou.png" }, +]; + +const SEED_PREFIX = "seed/aquarelle/"; + +export async function seedAquarelleMedia(): Promise<{ attached: number }> { + let attached = 0; + for (const { slug, file } of CARBET_AQUARELLES) { + const carbet = await prisma.carbet.findUnique({ where: { slug } }); + if (!carbet) continue; + + const s3Key = `${SEED_PREFIX}${file}`; + const url = aquarelleUrl(file); + + // Existe déjà ? upsert manuel via s3Key (pas d'unique sur s3Key, on filtre). + const existing = await prisma.media.findFirst({ + where: { carbetId: carbet.id, s3Key }, + }); + if (existing) { + attached += 1; + continue; + } + await prisma.media.create({ + data: { + carbetId: carbet.id, + type: MediaType.PHOTO, + s3Key, + s3Url: url, + sortOrder: 0, + }, + }); + attached += 1; + } + return { attached }; +} + +export async function detachAquarelleMedia(): Promise { + const result = await prisma.media.deleteMany({ + where: { s3Key: { startsWith: SEED_PREFIX } }, + }); + return result.count; +}