resolve manual DTOs

This commit is contained in:
2025-12-18 22:19:40 +01:00
parent 4a3087ae35
commit d617654928
179 changed files with 3716 additions and 1257 deletions

View File

@@ -1,12 +1,27 @@
import { Controller, Post, Body, HttpStatus, Res } from '@nestjs/common';
import { ApiTags, ApiResponse, ApiOperation } from '@nestjs/swagger';
import { Controller, Post, Get, Delete, Put, Body, HttpStatus, Res, Param, UseInterceptors, UploadedFile } from '@nestjs/common';
import { ApiTags, ApiResponse, ApiOperation, ApiParam, ApiConsumes } from '@nestjs/swagger';
import { Response } from 'express';
import { FileInterceptor } from '@nestjs/platform-express';
import { MediaService } from './MediaService';
import type { RequestAvatarGenerationInputDTO } from './dtos/RequestAvatarGenerationInputDTO';
import type { RequestAvatarGenerationOutputDTO } from './dtos/RequestAvatarGenerationOutputDTO';
import type { UploadMediaInputDTO } from './dtos/UploadMediaInputDTO';
import type { UploadMediaOutputDTO } from './dtos/UploadMediaOutputDTO';
import type { GetMediaOutputDTO } from './dtos/GetMediaOutputDTO';
import type { DeleteMediaOutputDTO } from './dtos/DeleteMediaOutputDTO';
import type { GetAvatarOutputDTO } from './dtos/GetAvatarOutputDTO';
import type { UpdateAvatarInputDTO } from './dtos/UpdateAvatarInputDTO';
import type { UpdateAvatarOutputDTO } from './dtos/UpdateAvatarOutputDTO';
type RequestAvatarGenerationInput = RequestAvatarGenerationInputDTO;
type RequestAvatarGenerationOutput = RequestAvatarGenerationOutputDTO;
type UploadMediaInput = UploadMediaInputDTO;
type UploadMediaOutput = UploadMediaOutputDTO;
type GetMediaOutput = GetMediaOutputDTO;
type DeleteMediaOutput = DeleteMediaOutputDTO;
type GetAvatarOutput = GetAvatarOutputDTO;
type UpdateAvatarInput = UpdateAvatarInputDTO;
type UpdateAvatarOutput = UpdateAvatarOutputDTO;
@ApiTags('media')
@Controller('media')
@@ -27,4 +42,79 @@ export class MediaController {
res.status(HttpStatus.BAD_REQUEST).json(result);
}
}
@Post('upload')
@UseInterceptors(FileInterceptor('file'))
@ApiOperation({ summary: 'Upload media file' })
@ApiConsumes('multipart/form-data')
@ApiResponse({ status: 201, description: 'Media uploaded successfully', type: UploadMediaOutput })
async uploadMedia(
@UploadedFile() file: Express.Multer.File,
@Body() input: UploadMediaInput,
@Res() res: Response,
): Promise<void> {
const result = await this.mediaService.uploadMedia({ ...input, file });
if (result.success) {
res.status(HttpStatus.CREATED).json(result);
} else {
res.status(HttpStatus.BAD_REQUEST).json(result);
}
}
@Get(':mediaId')
@ApiOperation({ summary: 'Get media by ID' })
@ApiParam({ name: 'mediaId', description: 'Media ID' })
@ApiResponse({ status: 200, description: 'Media details', type: GetMediaOutput })
async getMedia(
@Param('mediaId') mediaId: string,
@Res() res: Response,
): Promise<void> {
const result = await this.mediaService.getMedia(mediaId);
if (result) {
res.status(HttpStatus.OK).json(result);
} else {
res.status(HttpStatus.NOT_FOUND).json({ error: 'Media not found' });
}
}
@Delete(':mediaId')
@ApiOperation({ summary: 'Delete media by ID' })
@ApiParam({ name: 'mediaId', description: 'Media ID' })
@ApiResponse({ status: 200, description: 'Media deleted', type: DeleteMediaOutput })
async deleteMedia(
@Param('mediaId') mediaId: string,
@Res() res: Response,
): Promise<void> {
const result = await this.mediaService.deleteMedia(mediaId);
res.status(HttpStatus.OK).json(result);
}
@Get('avatar/:driverId')
@ApiOperation({ summary: 'Get avatar for driver' })
@ApiParam({ name: 'driverId', description: 'Driver ID' })
@ApiResponse({ status: 200, description: 'Avatar details', type: GetAvatarOutput })
async getAvatar(
@Param('driverId') driverId: string,
@Res() res: Response,
): Promise<void> {
const result = await this.mediaService.getAvatar(driverId);
if (result) {
res.status(HttpStatus.OK).json(result);
} else {
res.status(HttpStatus.NOT_FOUND).json({ error: 'Avatar not found' });
}
}
@Put('avatar/:driverId')
@ApiOperation({ summary: 'Update avatar for driver' })
@ApiParam({ name: 'driverId', description: 'Driver ID' })
@ApiResponse({ status: 200, description: 'Avatar updated', type: UpdateAvatarOutput })
async updateAvatar(
@Param('driverId') driverId: string,
@Body() input: UpdateAvatarInput,
@Res() res: Response,
): Promise<void> {
const result = await this.mediaService.updateAvatar(driverId, input);
res.status(HttpStatus.OK).json(result);
}
}

View File

@@ -1,9 +1,23 @@
import { Injectable, Inject } from '@nestjs/common';
import type { RequestAvatarGenerationInputDTO } from './dtos/RequestAvatarGenerationInputDTO';
import type { RequestAvatarGenerationOutputDTO } from './dtos/RequestAvatarGenerationOutputDTO';
import type { UploadMediaInputDTO } from './dtos/UploadMediaInputDTO';
import type { UploadMediaOutputDTO } from './dtos/UploadMediaOutputDTO';
import type { GetMediaOutputDTO } from './dtos/GetMediaOutputDTO';
import type { DeleteMediaOutputDTO } from './dtos/DeleteMediaOutputDTO';
import type { GetAvatarOutputDTO } from './dtos/GetAvatarOutputDTO';
import type { UpdateAvatarInputDTO } from './dtos/UpdateAvatarInputDTO';
import type { UpdateAvatarOutputDTO } from './dtos/UpdateAvatarOutputDTO';
type RequestAvatarGenerationInput = RequestAvatarGenerationInputDTO;
type RequestAvatarGenerationOutput = RequestAvatarGenerationOutputDTO;
type UploadMediaInput = UploadMediaInputDTO;
type UploadMediaOutput = UploadMediaOutputDTO;
type GetMediaOutput = GetMediaOutputDTO;
type DeleteMediaOutput = DeleteMediaOutputDTO;
type GetAvatarOutput = GetAvatarOutputDTO;
type UpdateAvatarInput = UpdateAvatarInputDTO;
type UpdateAvatarOutput = UpdateAvatarOutputDTO;
// Use cases
import { RequestAvatarGenerationUseCase } from '@core/media/application/use-cases/RequestAvatarGenerationUseCase';
@@ -33,4 +47,42 @@ export class MediaService {
}, presenter);
return presenter.viewModel;
}
async uploadMedia(input: UploadMediaInput & { file: Express.Multer.File }): Promise<UploadMediaOutput> {
this.logger.debug('[MediaService] Uploading media.');
// TODO: Implement media upload logic
return {
success: true,
mediaId: 'placeholder-media-id',
url: 'placeholder-url',
};
}
async getMedia(mediaId: string): Promise<GetMediaOutput | null> {
this.logger.debug(`[MediaService] Getting media: ${mediaId}`);
// TODO: Implement get media logic
return null;
}
async deleteMedia(mediaId: string): Promise<DeleteMediaOutput> {
this.logger.debug(`[MediaService] Deleting media: ${mediaId}`);
// TODO: Implement delete media logic
return {
success: true,
};
}
async getAvatar(driverId: string): Promise<GetAvatarOutput | null> {
this.logger.debug(`[MediaService] Getting avatar for driver: ${driverId}`);
// TODO: Implement get avatar logic
return null;
}
async updateAvatar(driverId: string, input: UpdateAvatarInput): Promise<UpdateAvatarOutput> {
this.logger.debug(`[MediaService] Updating avatar for driver: ${driverId}`);
// TODO: Implement update avatar logic
return {
success: true,
};
}
}

View File

@@ -0,0 +1,13 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsBoolean, IsString, IsOptional } from 'class-validator';
export class DeleteMediaOutputDTO {
@ApiProperty()
@IsBoolean()
success: boolean;
@ApiProperty({ required: false })
@IsString()
@IsOptional()
error?: string;
}

View File

@@ -0,0 +1,8 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString } from 'class-validator';
export class GetAvatarOutputDTO {
@ApiProperty()
@IsString()
avatarUrl: string;
}

View File

@@ -0,0 +1,29 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString, IsOptional, IsNumber } from 'class-validator';
export class GetMediaOutputDTO {
@ApiProperty()
@IsString()
id: string;
@ApiProperty()
@IsString()
url: string;
@ApiProperty()
@IsString()
type: string;
@ApiProperty()
@IsString()
@IsOptional()
category?: string;
@ApiProperty()
uploadedAt: Date;
@ApiProperty()
@IsNumber()
@IsOptional()
size?: number;
}

View File

@@ -0,0 +1,12 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString } from 'class-validator';
export class UpdateAvatarInputDTO {
@ApiProperty()
@IsString()
driverId: string;
@ApiProperty()
@IsString()
avatarUrl: string;
}

View File

@@ -0,0 +1,13 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsBoolean, IsString, IsOptional } from 'class-validator';
export class UpdateAvatarOutputDTO {
@ApiProperty()
@IsBoolean()
success: boolean;
@ApiProperty({ required: false })
@IsString()
@IsOptional()
error?: string;
}

View File

@@ -0,0 +1,16 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString, IsOptional } from 'class-validator';
export class UploadMediaInputDTO {
@ApiProperty({ type: 'string', format: 'binary' })
file: any; // File upload handled by multer
@ApiProperty()
@IsString()
type: string;
@ApiProperty({ required: false })
@IsString()
@IsOptional()
category?: string;
}

View File

@@ -0,0 +1,23 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString, IsBoolean, IsOptional } from 'class-validator';
export class UploadMediaOutputDTO {
@ApiProperty()
@IsBoolean()
success: boolean;
@ApiProperty({ required: false })
@IsString()
@IsOptional()
mediaId?: string;
@ApiProperty({ required: false })
@IsString()
@IsOptional()
url?: string;
@ApiProperty({ required: false })
@IsString()
@IsOptional()
error?: string;
}