import { BadRequestException, Body, Controller, Get, Param, Patch, Post, Query, UploadedFile, UseGuards, UseInterceptors, } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { FileInterceptor } from '@nestjs/platform-express'; import { diskStorage } from 'multer'; import { extname } from 'path'; import { JwtAuthGuard } from '../auth/jwt-auth.guard'; import { PermissionsGuard } from '../auth/permissions.guard'; import { RequirePermissions } from '../auth/permissions.decorator'; import { CurrentUser } from '../auth/current-user.decorator'; import { IMAGE_MIME, PLUGIN_IMAGES_DIR, ensureUploadsDirs, publicApiBase, } from '../uploads/uploads.util'; import { ApprovePurchaseDto, CreateCatalogSettingDto, SaveCatalogItemDto, } from './dto/plugin-store.dto'; import { PluginStoreService } from './plugin-store.service'; @Controller('plugins/store') @UseGuards(JwtAuthGuard, PermissionsGuard) export class PluginStoreController { constructor( private readonly store: PluginStoreService, private readonly config: ConfigService, ) {} @Get('catalog') @RequirePermissions('plugins:read') catalog() { return this.store.listCatalogAdmin(); } @Post('upload-image') @RequirePermissions('plugins:write') @UseInterceptors( FileInterceptor('file', { storage: diskStorage({ destination: (_req, _file, cb) => { ensureUploadsDirs(); cb(null, PLUGIN_IMAGES_DIR); }, filename: (_req, file, cb) => { const safeExt = extname(file.originalname).toLowerCase() || '.png'; const name = `plugin_${Date.now()}_${Math.random().toString(36).slice(2, 8)}${safeExt}`; cb(null, name); }, }), limits: { fileSize: 2 * 1024 * 1024 }, fileFilter: (_req, file, cb) => { if (!IMAGE_MIME.test(file.mimetype)) { cb(new BadRequestException('فقط تصویر (jpg/png/gif/webp/svg) مجاز است') as any, false); return; } cb(null, true); }, }), ) uploadImage(@UploadedFile() file: Express.Multer.File) { if (!file) throw new BadRequestException('فایل ارسال نشده است'); const base = publicApiBase(this.config); return { url: `${base}/uploads/plugins/${file.filename}` }; } @Patch('catalog/:id') @RequirePermissions('plugins:write') saveItem( @Param('id') id: string, @Body() dto: SaveCatalogItemDto, @CurrentUser() user: { id: string }, ) { return this.store.saveCatalogItem(id, dto, user.id); } @Post('catalog') @RequirePermissions('plugins:write') createSetting( @Body() dto: CreateCatalogSettingDto, @CurrentUser() user: { id: string }, ) { return this.store.createCatalogSetting(dto, user.id); } @Get('requests') @RequirePermissions('plugins:read') requests(@Query('status') status?: string) { return this.store.listRequestsAdmin(status); } @Post('requests/:id/approve') @RequirePermissions('plugins:write') approve( @Param('id') id: string, @Body() dto: ApprovePurchaseDto, @CurrentUser() user: { id: string }, ) { return this.store.approveRequest(id, dto, user.id); } @Post('requests/:id/reject') @RequirePermissions('plugins:write') reject(@Param('id') id: string, @CurrentUser() user: { id: string }) { return this.store.rejectRequest(id, user.id); } }