From ba94e7cc7dd2e0f51379b1d1d4efe658d03f57c6 Mon Sep 17 00:00:00 2001 From: Michael SCHAL Date: Tue, 24 Mar 2026 21:19:49 +0100 Subject: [PATCH] feat: Add MinIO endpoint/public URL configuration via settings UI Store endpointUrl and publicUrl in cloudinary_config DB table so MinIO connection can be fully configured from the app settings without needing environment variables. - DB migration: adds endpoint_url and public_url columns - Schema: adds endpointUrl/publicUrl to cloudinaryConfig table - MinIO service: reads endpoint from DB (falls back to MINIO_ENDPOINT env) - buildMinioUrl: accepts optional publicUrl override from DB config - All routes updated to pass config.publicUrl to buildMinioUrl - Settings UI (desktop + mobile): adds Endpoint URL and Public URL fields Co-Authored-By: Claude Sonnet 4.6 --- client/src/pages/mobile/settings.tsx | 38 +++++++++++++++++++++++++++- client/src/pages/settings.tsx | 36 +++++++++++++++++++++++++- server/migrate.ts | 12 +++++++++ server/routes.ts | 4 +-- server/routes/reels.ts | 4 +-- server/routes/remotion.ts | 2 +- server/services/minio.ts | 28 ++++++++++---------- shared/schema.ts | 2 ++ 8 files changed, 105 insertions(+), 21 deletions(-) diff --git a/client/src/pages/mobile/settings.tsx b/client/src/pages/mobile/settings.tsx index 4901190..4014866 100644 --- a/client/src/pages/mobile/settings.tsx +++ b/client/src/pages/mobile/settings.tsx @@ -20,6 +20,8 @@ export default function SettingsMobile() { const [cloudName, setCloudName] = useState(""); const [apiKey, setApiKey] = useState(""); const [apiSecret, setApiSecret] = useState(""); + const [endpointUrl, setEndpointUrl] = useState(""); + const [publicUrl, setPublicUrl] = useState(""); const [openrouterApiKey, setOpenrouterApiKey] = useState(""); const [openrouterModel, setOpenrouterModel] = useState("anthropic/claude-3.5-sonnet"); const [openrouterSystemPrompt, setOpenrouterSystemPrompt] = useState("Tu es un expert en marketing des réseaux sociaux. Génère 3 variations de textes engageants pour des publications Facebook et Instagram à partir des informations produit fournies. Chaque variation doit être unique, captivante et optimisée pour l'engagement."); @@ -50,6 +52,8 @@ export default function SettingsMobile() { if (cloudinaryConfig) { setCloudName((cloudinaryConfig as any).cloudName || ""); setApiKey((cloudinaryConfig as any).apiKey || ""); + setEndpointUrl((cloudinaryConfig as any).endpointUrl || ""); + setPublicUrl((cloudinaryConfig as any).publicUrl || ""); if ((cloudinaryConfig as any).logoUrl) { setLogoPreview((cloudinaryConfig as any).logoUrl); @@ -70,6 +74,8 @@ export default function SettingsMobile() { mutationFn: () => { const payload: any = { cloudName, + endpointUrl: endpointUrl || undefined, + publicUrl: publicUrl || undefined, }; if (apiKey && apiKey.trim() !== "") { @@ -368,7 +374,7 @@ export default function SettingsMobile() { Configuration Stockage MinIO - Configurez MinIO pour le stockage des médias (endpoint via variable MINIO_ENDPOINT) + Configurez MinIO pour le stockage des médias @@ -414,6 +420,36 @@ export default function SettingsMobile() { Votre Secret Key restera sécurisé et ne sera jamais exposé

+
+ + setEndpointUrl(e.target.value)} + placeholder="http://minio:9000" + className="min-h-[48px]" + data-testid="input-endpoint-url" + /> +

+ URL interne de votre serveur MinIO (ex: http://192.168.1.10:9000) +

+
+
+ + setPublicUrl(e.target.value)} + placeholder="https://media.votre-domaine.com" + className="min-h-[48px]" + data-testid="input-public-url" + /> +

+ URL publique pour accéder aux fichiers depuis internet +

+