feat: StorageService S3/MinIO, POST /users, invoice upload, portal dashboard §08 statuses + notifications
This commit is contained in:
@@ -3,27 +3,21 @@ import {
|
||||
UseGuards, UseInterceptors, UploadedFiles,
|
||||
} from "@nestjs/common";
|
||||
import { FilesInterceptor } from "@nestjs/platform-express";
|
||||
import { diskStorage } from "multer";
|
||||
import { extname, join } from "path";
|
||||
import { existsSync, mkdirSync } from "fs";
|
||||
import { randomUUID } from "crypto";
|
||||
import { memoryStorage } from "multer";
|
||||
import { extname } from "path";
|
||||
import { PackagesService } from "./packages.service";
|
||||
import { StorageService } from "../storage/storage.service";
|
||||
import { CreatePackageDto, UpdateStatusDto, VerifyPackageDto, SenaeDeclarationDto } from "./dto/package.dto";
|
||||
import { JwtAuthGuard, RolesGuard, Roles } from "../auth/guards/auth.guard";
|
||||
import { CurrentUser } from "../auth/decorators/current-user.decorator";
|
||||
import { ConfigService } from "@nestjs/config";
|
||||
|
||||
@Controller("packages")
|
||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||
export class PackagesController {
|
||||
private readonly apiUrl: string;
|
||||
|
||||
constructor(
|
||||
private svc: PackagesService,
|
||||
private config: ConfigService,
|
||||
) {
|
||||
this.apiUrl = this.config.get("API_URL", "http://localhost:3001");
|
||||
}
|
||||
private storage: StorageService,
|
||||
) {}
|
||||
|
||||
@Get()
|
||||
findAll(
|
||||
@@ -72,23 +66,13 @@ export class PackagesController {
|
||||
return this.svc.verifyPackage(id, dto, user.id);
|
||||
}
|
||||
|
||||
/** Bodega: upload photos via multipart form (doc §10 step 4) */
|
||||
/** Bodega: upload photos via multipart form — stored via StorageService (doc §10 step 4) */
|
||||
@Post(":id/photos")
|
||||
@Roles("OPERADOR_BODEGA", "ADMIN_EMPRESA", "SUPER_ADMIN")
|
||||
@UseInterceptors(
|
||||
FilesInterceptor("photos", 10, {
|
||||
storage: diskStorage({
|
||||
destination: (req, file, cb) => {
|
||||
const pkgId = Array.isArray(req.params.id) ? req.params.id[0] : req.params.id;
|
||||
const dir = join(process.cwd(), "uploads", "packages", pkgId);
|
||||
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
||||
cb(null, dir);
|
||||
},
|
||||
filename: (req, file, cb) => {
|
||||
cb(null, `${randomUUID()}${extname(file.originalname)}`);
|
||||
},
|
||||
}),
|
||||
fileFilter: (req, file, cb) => {
|
||||
storage: memoryStorage(),
|
||||
fileFilter: (_req, file, cb) => {
|
||||
const allowed = /jpg|jpeg|png|gif|webp/;
|
||||
cb(null, allowed.test(extname(file.originalname).toLowerCase()));
|
||||
},
|
||||
@@ -100,9 +84,15 @@ export class PackagesController {
|
||||
@UploadedFiles() files: Express.Multer.File[],
|
||||
@CurrentUser() user: any,
|
||||
): Promise<any> {
|
||||
const baseUrl = this.apiUrl;
|
||||
const photoUrls = (files || []).map(
|
||||
f => `${baseUrl}/uploads/packages/${id}/${f.filename}`,
|
||||
const photoUrls = await Promise.all(
|
||||
(files || []).map(f =>
|
||||
this.storage.saveFile(
|
||||
`packages/${id}`,
|
||||
f.originalname,
|
||||
f.buffer,
|
||||
f.mimetype,
|
||||
),
|
||||
),
|
||||
);
|
||||
return this.svc.addPhotos(id, photoUrls, user.id);
|
||||
}
|
||||
|
||||
@@ -4,9 +4,10 @@ import { PackagesController } from "./packages.controller";
|
||||
import { PrismaModule } from "../prisma/prisma.module";
|
||||
import { ConfigModule } from "@nestjs/config";
|
||||
import { NotificationsModule } from "../notifications/notifications.module";
|
||||
import { StorageModule } from "../storage/storage.module";
|
||||
|
||||
@Module({
|
||||
imports: [PrismaModule, ConfigModule, NotificationsModule],
|
||||
imports: [PrismaModule, ConfigModule, NotificationsModule, StorageModule],
|
||||
providers: [PackagesService],
|
||||
controllers: [PackagesController],
|
||||
exports: [PackagesService],
|
||||
|
||||
Reference in New Issue
Block a user