import { Injectable, Logger, OnModuleInit } from '@nestjs/common'; import * as Minio from 'minio'; import { loadEnv } from '../config/env'; import type { FileStorage } from './file-storage'; /** Seul fichier du dépôt autorisé à importer le SDK MinIO (règle ESLint). */ @Injectable() export class MinioStorageService implements FileStorage, OnModuleInit { private readonly logger = new Logger(MinioStorageService.name); private readonly client: Minio.Client; private readonly bucket: string; constructor() { const env = loadEnv(); this.bucket = env.MINIO_BUCKET; this.client = new Minio.Client({ endPoint: env.MINIO_ENDPOINT, port: env.MINIO_PORT, useSSL: env.MINIO_USE_SSL === 'true', accessKey: env.MINIO_ACCESS_KEY, secretKey: env.MINIO_SECRET_KEY, }); } /** Le bucket est créé au démarrage — aucune étape manuelle au déploiement. */ async onModuleInit(): Promise { try { if (!(await this.client.bucketExists(this.bucket))) { await this.client.makeBucket(this.bucket); this.logger.log(`Bucket « ${this.bucket} » créé.`); } } catch (e) { // Le stockage peut être en retard au boot : /health le signalera. this.logger.warn(`Stockage indisponible au démarrage : ${String(e)}`); } } async healthCheck(): Promise { await this.client.listBuckets(); } async putObject(key: string, body: Buffer, contentType: string): Promise { await this.client.putObject(this.bucket, key, body, body.length, { 'Content-Type': contentType, }); } async getObjectStream(key: string): Promise { return this.client.getObject(this.bucket, key); } async removeObject(key: string): Promise { await this.client.removeObject(this.bucket, key); } }