refactor use cases

This commit is contained in:
2026-01-08 15:34:51 +01:00
parent d984ab24a8
commit 52e9a2f6a7
362 changed files with 5192 additions and 8409 deletions

View File

@@ -7,7 +7,7 @@ import { IAvatarRepository } from '@core/media/domain/repositories/IAvatarReposi
import { FaceValidationPort } from '@core/media/application/ports/FaceValidationPort';
import { AvatarGenerationPort } from '@core/media/application/ports/AvatarGenerationPort';
import { MediaStoragePort } from '@core/media/application/ports/MediaStoragePort';
import type { Logger, UseCaseOutputPort } from '@core/shared/application';
import type { Logger } from '@core/shared/application';
// Import use cases
import { RequestAvatarGenerationUseCase } from '@core/media/application/use-cases/RequestAvatarGenerationUseCase';
@@ -17,14 +17,6 @@ import { DeleteMediaUseCase } from '@core/media/application/use-cases/DeleteMedi
import { GetAvatarUseCase } from '@core/media/application/use-cases/GetAvatarUseCase';
import { UpdateAvatarUseCase } from '@core/media/application/use-cases/UpdateAvatarUseCase';
// Import result types
import type { RequestAvatarGenerationResult } from '@core/media/application/use-cases/RequestAvatarGenerationUseCase';
import type { UploadMediaResult } from '@core/media/application/use-cases/UploadMediaUseCase';
import type { GetMediaResult } from '@core/media/application/use-cases/GetMediaUseCase';
import type { DeleteMediaResult } from '@core/media/application/use-cases/DeleteMediaUseCase';
import type { GetAvatarResult } from '@core/media/application/use-cases/GetAvatarUseCase';
import type { UpdateAvatarResult } from '@core/media/application/use-cases/UpdateAvatarUseCase';
// Import presenters
import { RequestAvatarGenerationPresenter } from './presenters/RequestAvatarGenerationPresenter';
import { UploadMediaPresenter } from './presenters/UploadMediaPresenter';
@@ -47,12 +39,6 @@ import {
DELETE_MEDIA_USE_CASE_TOKEN,
GET_AVATAR_USE_CASE_TOKEN,
UPDATE_AVATAR_USE_CASE_TOKEN,
REQUEST_AVATAR_GENERATION_OUTPUT_PORT_TOKEN,
UPLOAD_MEDIA_OUTPUT_PORT_TOKEN,
GET_MEDIA_OUTPUT_PORT_TOKEN,
DELETE_MEDIA_OUTPUT_PORT_TOKEN,
GET_AVATAR_OUTPUT_PORT_TOKEN,
UPDATE_AVATAR_OUTPUT_PORT_TOKEN,
} from './MediaTokens';
export * from './MediaTokens';
@@ -133,66 +119,41 @@ export const MediaProviders: Provider[] = createLoggedProviders([
provide: LOGGER_TOKEN,
useClass: MockLogger,
},
// Output ports
{
provide: REQUEST_AVATAR_GENERATION_OUTPUT_PORT_TOKEN,
useExisting: RequestAvatarGenerationPresenter,
},
{
provide: UPLOAD_MEDIA_OUTPUT_PORT_TOKEN,
useExisting: UploadMediaPresenter,
},
{
provide: GET_MEDIA_OUTPUT_PORT_TOKEN,
useExisting: GetMediaPresenter,
},
{
provide: DELETE_MEDIA_OUTPUT_PORT_TOKEN,
useExisting: DeleteMediaPresenter,
},
{
provide: GET_AVATAR_OUTPUT_PORT_TOKEN,
useExisting: GetAvatarPresenter,
},
{
provide: UPDATE_AVATAR_OUTPUT_PORT_TOKEN,
useExisting: UpdateAvatarPresenter,
},
// Use cases
// Use cases - simplified without output ports
{
provide: REQUEST_AVATAR_GENERATION_USE_CASE_TOKEN,
useFactory: (avatarRepo: IAvatarGenerationRepository, faceValidation: FaceValidationPort, avatarGeneration: AvatarGenerationPort, output: UseCaseOutputPort<RequestAvatarGenerationResult>, logger: Logger) =>
new RequestAvatarGenerationUseCase(avatarRepo, faceValidation, avatarGeneration, output, logger),
inject: [AVATAR_GENERATION_REPOSITORY_TOKEN, FACE_VALIDATION_PORT_TOKEN, AVATAR_GENERATION_PORT_TOKEN, REQUEST_AVATAR_GENERATION_OUTPUT_PORT_TOKEN, LOGGER_TOKEN],
useFactory: (avatarRepo: IAvatarGenerationRepository, faceValidation: FaceValidationPort, avatarGeneration: AvatarGenerationPort, logger: Logger) =>
new RequestAvatarGenerationUseCase(avatarRepo, faceValidation, avatarGeneration, logger),
inject: [AVATAR_GENERATION_REPOSITORY_TOKEN, FACE_VALIDATION_PORT_TOKEN, AVATAR_GENERATION_PORT_TOKEN, LOGGER_TOKEN],
},
{
provide: UPLOAD_MEDIA_USE_CASE_TOKEN,
useFactory: (mediaRepo: IMediaRepository, mediaStorage: MediaStoragePort, output: UseCaseOutputPort<UploadMediaResult>, logger: Logger) =>
new UploadMediaUseCase(mediaRepo, mediaStorage, output, logger),
inject: [MEDIA_REPOSITORY_TOKEN, MEDIA_STORAGE_PORT_TOKEN, UPLOAD_MEDIA_OUTPUT_PORT_TOKEN, LOGGER_TOKEN],
useFactory: (mediaRepo: IMediaRepository, mediaStorage: MediaStoragePort, logger: Logger) =>
new UploadMediaUseCase(mediaRepo, mediaStorage, logger),
inject: [MEDIA_REPOSITORY_TOKEN, MEDIA_STORAGE_PORT_TOKEN, LOGGER_TOKEN],
},
{
provide: GET_MEDIA_USE_CASE_TOKEN,
useFactory: (mediaRepo: IMediaRepository, output: UseCaseOutputPort<GetMediaResult>, logger: Logger) =>
new GetMediaUseCase(mediaRepo, output, logger),
inject: [MEDIA_REPOSITORY_TOKEN, GET_MEDIA_OUTPUT_PORT_TOKEN, LOGGER_TOKEN],
useFactory: (mediaRepo: IMediaRepository, logger: Logger) =>
new GetMediaUseCase(mediaRepo, logger),
inject: [MEDIA_REPOSITORY_TOKEN, LOGGER_TOKEN],
},
{
provide: DELETE_MEDIA_USE_CASE_TOKEN,
useFactory: (mediaRepo: IMediaRepository, mediaStorage: MediaStoragePort, output: UseCaseOutputPort<DeleteMediaResult>, logger: Logger) =>
new DeleteMediaUseCase(mediaRepo, mediaStorage, output, logger),
inject: [MEDIA_REPOSITORY_TOKEN, MEDIA_STORAGE_PORT_TOKEN, DELETE_MEDIA_OUTPUT_PORT_TOKEN, LOGGER_TOKEN],
useFactory: (mediaRepo: IMediaRepository, mediaStorage: MediaStoragePort, logger: Logger) =>
new DeleteMediaUseCase(mediaRepo, mediaStorage, logger),
inject: [MEDIA_REPOSITORY_TOKEN, MEDIA_STORAGE_PORT_TOKEN, LOGGER_TOKEN],
},
{
provide: GET_AVATAR_USE_CASE_TOKEN,
useFactory: (avatarRepo: IAvatarRepository, output: UseCaseOutputPort<GetAvatarResult>, logger: Logger) =>
new GetAvatarUseCase(avatarRepo, output, logger),
inject: [AVATAR_REPOSITORY_TOKEN, GET_AVATAR_OUTPUT_PORT_TOKEN, LOGGER_TOKEN],
useFactory: (avatarRepo: IAvatarRepository, logger: Logger) =>
new GetAvatarUseCase(avatarRepo, logger),
inject: [AVATAR_REPOSITORY_TOKEN, LOGGER_TOKEN],
},
{
provide: UPDATE_AVATAR_USE_CASE_TOKEN,
useFactory: (avatarRepo: IAvatarRepository, output: UseCaseOutputPort<UpdateAvatarResult>, logger: Logger) =>
new UpdateAvatarUseCase(avatarRepo, output, logger),
inject: [AVATAR_REPOSITORY_TOKEN, UPDATE_AVATAR_OUTPUT_PORT_TOKEN, LOGGER_TOKEN],
useFactory: (avatarRepo: IAvatarRepository, logger: Logger) =>
new UpdateAvatarUseCase(avatarRepo, logger),
inject: [AVATAR_REPOSITORY_TOKEN, LOGGER_TOKEN],
},
], initLogger);

View File

@@ -7,11 +7,12 @@ describe('MediaService', () => {
it('requestAvatarGeneration returns presenter response on success', async () => {
const requestAvatarGenerationPresenter = {
transform: vi.fn((result) => ({ success: true, requestId: result.requestId, avatarUrls: result.avatarUrls, errorMessage: '' })),
responseModel: { success: true, requestId: 'r1', avatarUrls: ['u1'], errorMessage: '' },
};
const requestAvatarGenerationUseCase = {
execute: vi.fn(async () => Result.ok(undefined)),
execute: vi.fn(async () => Result.ok({ requestId: 'r1', status: 'completed', avatarUrls: ['u1'] })),
};
const service = new MediaService(
@@ -39,6 +40,7 @@ describe('MediaService', () => {
facePhotoData: {} as any,
suitColor: 'red',
});
expect(requestAvatarGenerationPresenter.transform).toHaveBeenCalledWith({ requestId: 'r1', status: 'completed', avatarUrls: ['u1'] });
});
it('requestAvatarGeneration returns failure DTO on error', async () => {
@@ -69,8 +71,11 @@ describe('MediaService', () => {
});
it('uploadMedia returns presenter response on success', async () => {
const uploadMediaPresenter = { responseModel: { success: true, mediaId: 'm1' } };
const uploadMediaUseCase = { execute: vi.fn(async () => Result.ok(undefined)) };
const uploadMediaPresenter = {
transform: vi.fn((result) => ({ success: true, mediaId: result.mediaId })),
responseModel: { success: true, mediaId: 'm1' }
};
const uploadMediaUseCase = { execute: vi.fn(async () => Result.ok({ mediaId: 'm1', url: 'https://example.com/m1.png' })) };
const service = new MediaService(
{ execute: vi.fn() } as any,
@@ -100,10 +105,15 @@ describe('MediaService', () => {
uploadedBy: 'u1',
metadata: { a: 1 },
});
expect(uploadMediaPresenter.transform).toHaveBeenCalledWith({ mediaId: 'm1', url: 'https://example.com/m1.png' });
});
it('uploadMedia uses empty uploadedBy when userId missing', async () => {
const uploadMediaUseCase = { execute: vi.fn(async () => Result.ok(undefined)) };
const uploadMediaUseCase = { execute: vi.fn(async () => Result.ok({ mediaId: 'm1', url: 'https://example.com/m1.png' })) };
const uploadMediaPresenter = {
transform: vi.fn((result) => ({ success: true, mediaId: result.mediaId })),
responseModel: { success: true, mediaId: 'm1' }
};
const service = new MediaService(
{ execute: vi.fn() } as any,
@@ -114,7 +124,7 @@ describe('MediaService', () => {
{ execute: vi.fn() } as any,
logger as any,
{ responseModel: {} } as any,
{ responseModel: { success: true, mediaId: 'm1' } } as any,
uploadMediaPresenter as any,
{ responseModel: {} } as any,
{ responseModel: {} } as any,
{ responseModel: {} } as any,
@@ -123,6 +133,7 @@ describe('MediaService', () => {
await expect(service.uploadMedia({ file: {} as any } as any)).resolves.toEqual({ success: true, mediaId: 'm1' });
expect(uploadMediaUseCase.execute).toHaveBeenCalledWith({ file: {} as any, uploadedBy: '', metadata: {} });
expect(uploadMediaPresenter.transform).toHaveBeenCalledWith({ mediaId: 'm1', url: 'https://example.com/m1.png' });
});
it('uploadMedia returns failure DTO on error', async () => {
@@ -153,8 +164,12 @@ describe('MediaService', () => {
});
it('getMedia returns presenter response on success', async () => {
const getMediaUseCase = { execute: vi.fn(async () => Result.ok(undefined)) };
const getMediaPresenter = { responseModel: { mediaId: 'm1' } };
const uploadedAt = new Date();
const getMediaUseCase = { execute: vi.fn(async () => Result.ok({ media: { id: 'm1', filename: 'test.png', originalName: 'test.png', mimeType: 'image/png', size: 100, url: 'https://example.com/m1.png', type: 'image', uploadedBy: 'u1', uploadedAt } })) };
const getMediaPresenter = {
transform: vi.fn((result) => ({ id: result.media.id, url: result.media.url, type: result.media.type, uploadedAt: result.media.uploadedAt, size: result.media.size })),
responseModel: { id: 'm1', url: 'https://example.com/m1.png', type: 'image', uploadedAt, size: 100 }
};
const service = new MediaService(
{ execute: vi.fn() } as any,
@@ -172,8 +187,10 @@ describe('MediaService', () => {
{ responseModel: {} } as any,
);
await expect(service.getMedia('m1')).resolves.toEqual({ mediaId: 'm1' });
const result = await service.getMedia('m1');
expect(result).toEqual({ id: 'm1', url: 'https://example.com/m1.png', type: 'image', uploadedAt, size: 100 });
expect(getMediaUseCase.execute).toHaveBeenCalledWith({ mediaId: 'm1' });
expect(getMediaPresenter.transform).toHaveBeenCalledWith({ media: { id: 'm1', filename: 'test.png', originalName: 'test.png', mimeType: 'image/png', size: 100, url: 'https://example.com/m1.png', type: 'image', uploadedBy: 'u1', uploadedAt } });
});
it('getMedia returns null on MEDIA_NOT_FOUND', async () => {
@@ -217,8 +234,11 @@ describe('MediaService', () => {
});
it('deleteMedia returns presenter response on success', async () => {
const deleteMediaUseCase = { execute: vi.fn(async () => Result.ok(undefined)) };
const deleteMediaPresenter = { responseModel: { success: true } };
const deleteMediaUseCase = { execute: vi.fn(async () => Result.ok({ mediaId: 'm1', deleted: true })) };
const deleteMediaPresenter = {
transform: vi.fn((result) => ({ success: result.deleted })),
responseModel: { success: true }
};
const service = new MediaService(
{ execute: vi.fn() } as any,
@@ -238,6 +258,7 @@ describe('MediaService', () => {
await expect(service.deleteMedia('m1')).resolves.toEqual({ success: true });
expect(deleteMediaUseCase.execute).toHaveBeenCalledWith({ mediaId: 'm1' });
expect(deleteMediaPresenter.transform).toHaveBeenCalledWith({ mediaId: 'm1', deleted: true });
});
it('deleteMedia returns failure DTO on error', async () => {
@@ -261,8 +282,12 @@ describe('MediaService', () => {
});
it('getAvatar returns presenter response on success', async () => {
const getAvatarUseCase = { execute: vi.fn(async () => Result.ok(undefined)) };
const getAvatarPresenter = { responseModel: { avatarUrl: 'u1' } };
const selectedAt = new Date();
const getAvatarUseCase = { execute: vi.fn(async () => Result.ok({ avatar: { id: 'a1', driverId: 'd1', mediaUrl: 'https://example.com/avatar.png', selectedAt } })) };
const getAvatarPresenter = {
transform: vi.fn((result) => ({ avatarUrl: result.avatar.mediaUrl })),
responseModel: { avatarUrl: 'https://example.com/avatar.png' }
};
const service = new MediaService(
{ execute: vi.fn() } as any,
@@ -280,8 +305,9 @@ describe('MediaService', () => {
{ responseModel: {} } as any,
);
await expect(service.getAvatar('d1')).resolves.toEqual({ avatarUrl: 'u1' });
await expect(service.getAvatar('d1')).resolves.toEqual({ avatarUrl: 'https://example.com/avatar.png' });
expect(getAvatarUseCase.execute).toHaveBeenCalledWith({ driverId: 'd1' });
expect(getAvatarPresenter.transform).toHaveBeenCalledWith({ avatar: { id: 'a1', driverId: 'd1', mediaUrl: 'https://example.com/avatar.png', selectedAt } });
});
it('getAvatar returns null on AVATAR_NOT_FOUND', async () => {
@@ -325,8 +351,11 @@ describe('MediaService', () => {
});
it('updateAvatar returns presenter response on success', async () => {
const updateAvatarUseCase = { execute: vi.fn(async () => Result.ok(undefined)) };
const updateAvatarPresenter = { responseModel: { success: true } };
const updateAvatarUseCase = { execute: vi.fn(async () => Result.ok({ avatarId: 'a1', driverId: 'd1' })) };
const updateAvatarPresenter = {
transform: vi.fn(() => ({ success: true })),
responseModel: { success: true }
};
const service = new MediaService(
{ execute: vi.fn() } as any,
@@ -346,6 +375,7 @@ describe('MediaService', () => {
await expect(service.updateAvatar('d1', { avatarUrl: 'u1' } as any)).resolves.toEqual({ success: true });
expect(updateAvatarUseCase.execute).toHaveBeenCalledWith({ driverId: 'd1', mediaUrl: 'u1' });
expect(updateAvatarPresenter.transform).toHaveBeenCalledWith({ avatarId: 'a1', driverId: 'd1' });
});
it('updateAvatar returns failure DTO on error', async () => {
@@ -507,4 +537,4 @@ describe('MediaService', () => {
error: 'Failed to update avatar',
});
});
});
});

View File

@@ -25,7 +25,7 @@ import { DeleteMediaUseCase } from '@core/media/application/use-cases/DeleteMedi
import { GetAvatarUseCase } from '@core/media/application/use-cases/GetAvatarUseCase';
import { UpdateAvatarUseCase } from '@core/media/application/use-cases/UpdateAvatarUseCase';
// Presenters
// Presenters (now transformers)
import { RequestAvatarGenerationPresenter } from './presenters/RequestAvatarGenerationPresenter';
import { UploadMediaPresenter } from './presenters/UploadMediaPresenter';
import { GetMediaPresenter } from './presenters/GetMediaPresenter';
@@ -90,7 +90,7 @@ export class MediaService {
};
}
return this.requestAvatarGenerationPresenter.responseModel;
return this.requestAvatarGenerationPresenter.transform(result.unwrap());
}
async uploadMedia(
@@ -112,7 +112,7 @@ export class MediaService {
};
}
return this.uploadMediaPresenter.responseModel;
return this.uploadMediaPresenter.transform(result.unwrap());
}
async getMedia(mediaId: string): Promise<GetMediaOutputDTO | null> {
@@ -128,7 +128,7 @@ export class MediaService {
throw new Error(error.details?.message ?? 'Failed to get media');
}
return this.getMediaPresenter.responseModel;
return this.getMediaPresenter.transform(result.unwrap());
}
async deleteMedia(mediaId: string): Promise<DeleteMediaOutputDTO> {
@@ -144,7 +144,7 @@ export class MediaService {
};
}
return this.deleteMediaPresenter.responseModel;
return this.deleteMediaPresenter.transform(result.unwrap());
}
async getAvatar(driverId: string): Promise<GetAvatarOutputDTO | null> {
@@ -160,7 +160,7 @@ export class MediaService {
throw new Error(error.details?.message ?? 'Failed to get avatar');
}
return this.getAvatarPresenter.responseModel;
return this.getAvatarPresenter.transform(result.unwrap());
}
async updateAvatar(driverId: string, input: UpdateAvatarInput): Promise<UpdateAvatarOutputDTO> {
@@ -189,7 +189,7 @@ export class MediaService {
};
}
return this.updateAvatarPresenter.responseModel;
return this.updateAvatarPresenter.transform(result.unwrap());
}
async validateFacePhoto(input: ValidateFaceInputDTO): Promise<ValidateFaceOutputDTO> {
@@ -211,4 +211,4 @@ export class MediaService {
return { isValid: true };
}
}
}

View File

@@ -11,11 +11,4 @@ export const UPLOAD_MEDIA_USE_CASE_TOKEN = 'UploadMediaUseCase';
export const GET_MEDIA_USE_CASE_TOKEN = 'GetMediaUseCase';
export const DELETE_MEDIA_USE_CASE_TOKEN = 'DeleteMediaUseCase';
export const GET_AVATAR_USE_CASE_TOKEN = 'GetAvatarUseCase';
export const UPDATE_AVATAR_USE_CASE_TOKEN = 'UpdateAvatarUseCase';
export const REQUEST_AVATAR_GENERATION_OUTPUT_PORT_TOKEN = 'RequestAvatarGenerationOutputPort';
export const UPLOAD_MEDIA_OUTPUT_PORT_TOKEN = 'UploadMediaOutputPort';
export const GET_MEDIA_OUTPUT_PORT_TOKEN = 'GetMediaOutputPort';
export const DELETE_MEDIA_OUTPUT_PORT_TOKEN = 'DeleteMediaOutputPort';
export const GET_AVATAR_OUTPUT_PORT_TOKEN = 'GetAvatarOutputPort';
export const UPDATE_AVATAR_OUTPUT_PORT_TOKEN = 'UpdateAvatarOutputPort';
export const UPDATE_AVATAR_USE_CASE_TOKEN = 'UpdateAvatarUseCase';

View File

@@ -1,20 +1,20 @@
import type { UseCaseOutputPort } from '@core/shared/application';
import type { DeleteMediaResult } from '@core/media/application/use-cases/DeleteMediaUseCase';
import type { DeleteMediaOutputDTO } from '../dtos/DeleteMediaOutputDTO';
type DeleteMediaResponseModel = DeleteMediaOutputDTO;
export class DeleteMediaPresenter implements UseCaseOutputPort<DeleteMediaResult> {
export class DeleteMediaPresenter {
private model: DeleteMediaResponseModel | null = null;
reset(): void {
this.model = null;
}
present(result: DeleteMediaResult): void {
transform(result: DeleteMediaResult): DeleteMediaResponseModel {
this.model = {
success: result.deleted,
};
return this.model;
}
getResponseModel(): DeleteMediaResponseModel | null {
@@ -25,4 +25,4 @@ export class DeleteMediaPresenter implements UseCaseOutputPort<DeleteMediaResult
if (!this.model) throw new Error('Presenter not presented');
return this.model;
}
}
}

View File

@@ -1,20 +1,20 @@
import type { UseCaseOutputPort } from '@core/shared/application';
import type { GetAvatarResult } from '@core/media/application/use-cases/GetAvatarUseCase';
import type { GetAvatarOutputDTO } from '../dtos/GetAvatarOutputDTO';
export type GetAvatarResponseModel = GetAvatarOutputDTO | null;
export class GetAvatarPresenter implements UseCaseOutputPort<GetAvatarResult> {
export class GetAvatarPresenter {
private model: GetAvatarResponseModel | null = null;
reset(): void {
this.model = null;
}
present(result: GetAvatarResult): void {
transform(result: GetAvatarResult): GetAvatarResponseModel {
this.model = {
avatarUrl: result.avatar.mediaUrl,
};
return this.model;
}
getResponseModel(): GetAvatarResponseModel | null {

View File

@@ -1,17 +1,16 @@
import type { UseCaseOutputPort } from '@core/shared/application';
import type { GetMediaResult } from '@core/media/application/use-cases/GetMediaUseCase';
import type { GetMediaOutputDTO } from '../dtos/GetMediaOutputDTO';
export type GetMediaResponseModel = GetMediaOutputDTO | null;
export class GetMediaPresenter implements UseCaseOutputPort<GetMediaResult> {
export class GetMediaPresenter {
private model: GetMediaResponseModel | null = null;
reset(): void {
this.model = null;
}
present(result: GetMediaResult): void {
transform(result: GetMediaResult): GetMediaResponseModel {
const media = result.media;
const model: GetMediaResponseModel = {
@@ -29,6 +28,7 @@ export class GetMediaPresenter implements UseCaseOutputPort<GetMediaResult> {
}
this.model = model;
return model;
}
getResponseModel(): GetMediaResponseModel | null {

View File

@@ -1,22 +1,22 @@
import type { UseCaseOutputPort } from '@core/shared/application';
import type { RequestAvatarGenerationResult } from '@core/media/application/use-cases/RequestAvatarGenerationUseCase';
import type { RequestAvatarGenerationOutputDTO } from '../dtos/RequestAvatarGenerationOutputDTO';
type RequestAvatarGenerationResponseModel = RequestAvatarGenerationOutputDTO;
export class RequestAvatarGenerationPresenter implements UseCaseOutputPort<RequestAvatarGenerationResult> {
export class RequestAvatarGenerationPresenter {
private model: RequestAvatarGenerationResponseModel | null = null;
reset() {
this.model = null;
}
present(result: RequestAvatarGenerationResult): void {
transform(result: RequestAvatarGenerationResult): RequestAvatarGenerationResponseModel {
this.model = {
success: result.status === 'completed',
requestId: result.requestId,
avatarUrls: result.avatarUrls || [],
};
return this.model;
}
getResponseModel(): RequestAvatarGenerationResponseModel | null {

View File

@@ -1,22 +1,22 @@
import type { UseCaseOutputPort } from '@core/shared/application';
import type { UpdateAvatarResult } from '@core/media/application/use-cases/UpdateAvatarUseCase';
import type { UpdateAvatarOutputDTO } from '../dtos/UpdateAvatarOutputDTO';
type UpdateAvatarResponseModel = UpdateAvatarOutputDTO;
export class UpdateAvatarPresenter implements UseCaseOutputPort<UpdateAvatarResult> {
export class UpdateAvatarPresenter {
private model: UpdateAvatarResponseModel | null = null;
reset(): void {
this.model = null;
}
present(result: UpdateAvatarResult): void {
transform(result: UpdateAvatarResult): UpdateAvatarResponseModel {
void result;
this.model = {
success: true,
};
return this.model;
}
getResponseModel(): UpdateAvatarResponseModel | null {

View File

@@ -1,17 +1,16 @@
import type { UseCaseOutputPort } from '@core/shared/application';
import type { UploadMediaResult } from '@core/media/application/use-cases/UploadMediaUseCase';
import type { UploadMediaOutputDTO } from '../dtos/UploadMediaOutputDTO';
type UploadMediaResponseModel = UploadMediaOutputDTO;
export class UploadMediaPresenter implements UseCaseOutputPort<UploadMediaResult> {
export class UploadMediaPresenter {
private model: UploadMediaResponseModel | null = null;
reset(): void {
this.model = null;
}
present(result: UploadMediaResult): void {
transform(result: UploadMediaResult): UploadMediaResponseModel {
const model: UploadMediaResponseModel = {
success: true,
mediaId: result.mediaId,
@@ -22,6 +21,7 @@ export class UploadMediaPresenter implements UseCaseOutputPort<UploadMediaResult
}
this.model = model;
return model;
}
getResponseModel(): UploadMediaResponseModel | null {
@@ -32,4 +32,4 @@ export class UploadMediaPresenter implements UseCaseOutputPort<UploadMediaResult
if (!this.model) throw new Error('Presenter not presented');
return this.model;
}
}
}