diff --git a/apps/api/src/storage/storage.service.ts b/apps/api/src/storage/storage.service.ts index 326ef5c..b0e61c2 100644 --- a/apps/api/src/storage/storage.service.ts +++ b/apps/api/src/storage/storage.service.ts @@ -1,9 +1,9 @@ -import { Injectable, Logger } from "@nestjs/common"; +import { Injectable, Logger, OnModuleInit } from "@nestjs/common"; import { ConfigService } from "@nestjs/config"; import * as fs from "fs"; import * as path from "path"; import { randomUUID } from "crypto"; -import { S3Client, DeleteObjectCommand, PutObjectCommand } from "@aws-sdk/client-s3"; +import { S3Client, DeleteObjectCommand, PutObjectCommand, CreateBucketCommand, HeadBucketCommand } from "@aws-sdk/client-s3"; import { getSignedUrl } from "@aws-sdk/s3-request-presigner"; import { GetObjectCommand } from "@aws-sdk/client-s3"; @@ -13,7 +13,7 @@ import { GetObjectCommand } from "@aws-sdk/client-s3"; * • Otherwise → local disk under ./uploads/ (development) */ @Injectable() -export class StorageService { +export class StorageService implements OnModuleInit { private readonly logger = new Logger(StorageService.name); private readonly uploadDir: string; private readonly baseUrl: string; @@ -50,6 +50,26 @@ export class StorageService { } } + async onModuleInit(): Promise { + if (this.s3 && this.bucket) { + await this.ensureBucket(); + } + } + + private async ensureBucket(): Promise { + try { + await this.s3!.send(new HeadBucketCommand({ Bucket: this.bucket! })); + this.logger.log(`[STORAGE] Bucket "${this.bucket}" exists`); + } catch (e: any) { + if (e.name === "NotFound" || e.$metadata?.httpStatusCode === 404) { + await this.s3!.send(new CreateBucketCommand({ Bucket: this.bucket! })); + this.logger.log(`[STORAGE] Created bucket "${this.bucket}"`); + } else { + this.logger.error(`[STORAGE] Bucket check failed: ${e.message}`); + } + } + } + get isS3Mode(): boolean { return !!this.s3; } /**