refactor
This commit is contained in:
@@ -8,7 +8,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 } from '@core/shared/application';
|
||||
import type { Logger, UseCaseOutputPort } from '@core/shared/application';
|
||||
|
||||
// Import use cases
|
||||
import { RequestAvatarGenerationUseCase } from '@core/media/application/use-cases/RequestAvatarGenerationUseCase';
|
||||
@@ -18,6 +18,22 @@ 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';
|
||||
import { GetMediaPresenter } from './presenters/GetMediaPresenter';
|
||||
import { DeleteMediaPresenter } from './presenters/DeleteMediaPresenter';
|
||||
import { GetAvatarPresenter } from './presenters/GetAvatarPresenter';
|
||||
import { UpdateAvatarPresenter } from './presenters/UpdateAvatarPresenter';
|
||||
|
||||
// Define injection tokens
|
||||
export const AVATAR_GENERATION_REPOSITORY_TOKEN = 'IAvatarGenerationRepository';
|
||||
export const MEDIA_REPOSITORY_TOKEN = 'IMediaRepository';
|
||||
@@ -35,6 +51,14 @@ export const DELETE_MEDIA_USE_CASE_TOKEN = 'DeleteMediaUseCase';
|
||||
export const GET_AVATAR_USE_CASE_TOKEN = 'GetAvatarUseCase';
|
||||
export const UPDATE_AVATAR_USE_CASE_TOKEN = 'UpdateAvatarUseCase';
|
||||
|
||||
// Output port tokens
|
||||
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';
|
||||
|
||||
import type { AvatarGenerationRequest } from '@core/media/domain/entities/AvatarGenerationRequest';
|
||||
import type { Media } from '@core/media/domain/entities/Media';
|
||||
import type { Avatar } from '@core/media/domain/entities/Avatar';
|
||||
@@ -110,6 +134,12 @@ class MockLogger implements Logger {
|
||||
|
||||
export const MediaProviders: Provider[] = [
|
||||
MediaService, // Provide the service itself
|
||||
RequestAvatarGenerationPresenter,
|
||||
UploadMediaPresenter,
|
||||
GetMediaPresenter,
|
||||
DeleteMediaPresenter,
|
||||
GetAvatarPresenter,
|
||||
UpdateAvatarPresenter,
|
||||
{
|
||||
provide: AVATAR_GENERATION_REPOSITORY_TOKEN,
|
||||
useClass: MockAvatarGenerationRepository,
|
||||
@@ -138,41 +168,66 @@ export const MediaProviders: Provider[] = [
|
||||
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
|
||||
{
|
||||
provide: REQUEST_AVATAR_GENERATION_USE_CASE_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],
|
||||
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],
|
||||
},
|
||||
{
|
||||
provide: UPLOAD_MEDIA_USE_CASE_TOKEN,
|
||||
useFactory: (mediaRepo: IMediaRepository, mediaStorage: MediaStoragePort, logger: Logger) =>
|
||||
new UploadMediaUseCase(mediaRepo, mediaStorage, logger),
|
||||
inject: [MEDIA_REPOSITORY_TOKEN, MEDIA_STORAGE_PORT_TOKEN, LOGGER_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],
|
||||
},
|
||||
{
|
||||
provide: GET_MEDIA_USE_CASE_TOKEN,
|
||||
useFactory: (mediaRepo: IMediaRepository, logger: Logger) =>
|
||||
new GetMediaUseCase(mediaRepo, logger),
|
||||
inject: [MEDIA_REPOSITORY_TOKEN, LOGGER_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],
|
||||
},
|
||||
{
|
||||
provide: DELETE_MEDIA_USE_CASE_TOKEN,
|
||||
useFactory: (mediaRepo: IMediaRepository, mediaStorage: MediaStoragePort, logger: Logger) =>
|
||||
new DeleteMediaUseCase(mediaRepo, mediaStorage, logger),
|
||||
inject: [MEDIA_REPOSITORY_TOKEN, MEDIA_STORAGE_PORT_TOKEN, LOGGER_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],
|
||||
},
|
||||
{
|
||||
provide: GET_AVATAR_USE_CASE_TOKEN,
|
||||
useFactory: (avatarRepo: IAvatarRepository, logger: Logger) =>
|
||||
new GetAvatarUseCase(avatarRepo, logger),
|
||||
inject: [AVATAR_REPOSITORY_TOKEN, LOGGER_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],
|
||||
},
|
||||
{
|
||||
provide: UPDATE_AVATAR_USE_CASE_TOKEN,
|
||||
useFactory: (avatarRepo: IAvatarRepository, logger: Logger) =>
|
||||
new UpdateAvatarUseCase(avatarRepo, logger),
|
||||
inject: [AVATAR_REPOSITORY_TOKEN, LOGGER_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],
|
||||
},
|
||||
];
|
||||
|
||||
@@ -59,6 +59,12 @@ export class MediaService {
|
||||
private readonly updateAvatarUseCase: UpdateAvatarUseCase,
|
||||
@Inject(LOGGER_TOKEN)
|
||||
private readonly logger: Logger,
|
||||
private readonly requestAvatarGenerationPresenter: RequestAvatarGenerationPresenter,
|
||||
private readonly uploadMediaPresenter: UploadMediaPresenter,
|
||||
private readonly getMediaPresenter: GetMediaPresenter,
|
||||
private readonly deleteMediaPresenter: DeleteMediaPresenter,
|
||||
private readonly getAvatarPresenter: GetAvatarPresenter,
|
||||
private readonly updateAvatarPresenter: UpdateAvatarPresenter,
|
||||
) {}
|
||||
|
||||
async requestAvatarGeneration(
|
||||
@@ -66,18 +72,23 @@ export class MediaService {
|
||||
): Promise<RequestAvatarGenerationOutputDTO> {
|
||||
this.logger.debug('[MediaService] Requesting avatar generation.');
|
||||
|
||||
const presenter = new RequestAvatarGenerationPresenter();
|
||||
presenter.reset();
|
||||
|
||||
const result = await this.requestAvatarGenerationUseCase.execute({
|
||||
userId: input.userId,
|
||||
facePhotoData: input.facePhotoData,
|
||||
suitColor: input.suitColor as RacingSuitColor,
|
||||
});
|
||||
|
||||
presenter.present(result);
|
||||
if (result.isErr()) {
|
||||
const error = result.unwrapErr();
|
||||
return {
|
||||
success: false,
|
||||
requestId: '',
|
||||
avatarUrls: [],
|
||||
errorMessage: error.details?.message ?? 'Failed to request avatar generation',
|
||||
};
|
||||
}
|
||||
|
||||
return presenter.responseModel;
|
||||
return this.requestAvatarGenerationPresenter.responseModel;
|
||||
}
|
||||
|
||||
async uploadMedia(
|
||||
@@ -85,69 +96,87 @@ export class MediaService {
|
||||
): Promise<UploadMediaOutputDTO> {
|
||||
this.logger.debug('[MediaService] Uploading media.');
|
||||
|
||||
const presenter = new UploadMediaPresenter();
|
||||
presenter.reset();
|
||||
|
||||
const result = await this.uploadMediaUseCase.execute({
|
||||
file: input.file,
|
||||
uploadedBy: input.userId ?? '',
|
||||
metadata: input.metadata,
|
||||
metadata: input.metadata || {},
|
||||
});
|
||||
|
||||
presenter.present(result);
|
||||
if (result.isErr()) {
|
||||
const error = result.unwrapErr();
|
||||
return {
|
||||
success: false,
|
||||
error: error.details?.message ?? 'Upload failed',
|
||||
};
|
||||
}
|
||||
|
||||
return presenter.responseModel;
|
||||
return this.uploadMediaPresenter.responseModel;
|
||||
}
|
||||
|
||||
async getMedia(mediaId: string): Promise<GetMediaOutputDTO | null> {
|
||||
this.logger.debug(`[MediaService] Getting media: ${mediaId}`);
|
||||
|
||||
const presenter = new GetMediaPresenter();
|
||||
presenter.reset();
|
||||
|
||||
const result = await this.getMediaUseCase.execute({ mediaId });
|
||||
presenter.present(result);
|
||||
|
||||
return presenter.responseModel;
|
||||
if (result.isErr()) {
|
||||
const error = result.unwrapErr();
|
||||
if (error.code === 'MEDIA_NOT_FOUND') {
|
||||
return null;
|
||||
}
|
||||
throw new Error(error.details?.message ?? 'Failed to get media');
|
||||
}
|
||||
|
||||
return this.getMediaPresenter.responseModel;
|
||||
}
|
||||
|
||||
async deleteMedia(mediaId: string): Promise<DeleteMediaOutputDTO> {
|
||||
this.logger.debug(`[MediaService] Deleting media: ${mediaId}`);
|
||||
|
||||
const presenter = new DeleteMediaPresenter();
|
||||
presenter.reset();
|
||||
|
||||
const result = await this.deleteMediaUseCase.execute({ mediaId });
|
||||
presenter.present(result);
|
||||
|
||||
return presenter.responseModel;
|
||||
if (result.isErr()) {
|
||||
const error = result.unwrapErr();
|
||||
return {
|
||||
success: false,
|
||||
error: error.details?.message ?? 'Failed to delete media',
|
||||
};
|
||||
}
|
||||
|
||||
return this.deleteMediaPresenter.responseModel;
|
||||
}
|
||||
|
||||
async getAvatar(driverId: string): Promise<GetAvatarOutputDTO | null> {
|
||||
this.logger.debug(`[MediaService] Getting avatar for driver: ${driverId}`);
|
||||
|
||||
const presenter = new GetAvatarPresenter();
|
||||
presenter.reset();
|
||||
|
||||
const result = await this.getAvatarUseCase.execute({ driverId });
|
||||
presenter.present(result);
|
||||
|
||||
return presenter.responseModel;
|
||||
if (result.isErr()) {
|
||||
const error = result.unwrapErr();
|
||||
if (error.code === 'AVATAR_NOT_FOUND') {
|
||||
return null;
|
||||
}
|
||||
throw new Error(error.details?.message ?? 'Failed to get avatar');
|
||||
}
|
||||
|
||||
return this.getAvatarPresenter.responseModel;
|
||||
}
|
||||
|
||||
async updateAvatar(driverId: string, input: UpdateAvatarInput): Promise<UpdateAvatarOutputDTO> {
|
||||
this.logger.debug(`[MediaService] Updating avatar for driver: ${driverId}`);
|
||||
|
||||
const presenter = new UpdateAvatarPresenter();
|
||||
presenter.reset();
|
||||
|
||||
const result = await this.updateAvatarUseCase.execute({
|
||||
driverId,
|
||||
mediaUrl: input.mediaUrl,
|
||||
mediaUrl: input.avatarUrl,
|
||||
});
|
||||
|
||||
presenter.present(result);
|
||||
if (result.isErr()) {
|
||||
const error = result.unwrapErr();
|
||||
return {
|
||||
success: false,
|
||||
error: error.details?.message ?? 'Failed to update avatar',
|
||||
};
|
||||
}
|
||||
|
||||
return presenter.responseModel;
|
||||
return this.updateAvatarPresenter.responseModel;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,41 +1,19 @@
|
||||
import type { Result } from '@core/shared/application/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import type {
|
||||
DeleteMediaResult,
|
||||
DeleteMediaErrorCode,
|
||||
} from '@core/media/application/use-cases/DeleteMediaUseCase';
|
||||
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 type DeleteMediaApplicationError = ApplicationErrorCode<
|
||||
DeleteMediaErrorCode,
|
||||
{ message: string }
|
||||
>;
|
||||
|
||||
export class DeleteMediaPresenter {
|
||||
export class DeleteMediaPresenter implements UseCaseOutputPort<DeleteMediaResult> {
|
||||
private model: DeleteMediaResponseModel | null = null;
|
||||
|
||||
reset(): void {
|
||||
this.model = null;
|
||||
}
|
||||
|
||||
present(result: Result<DeleteMediaResult, DeleteMediaApplicationError>): void {
|
||||
if (result.isErr()) {
|
||||
const error = result.unwrapErr();
|
||||
|
||||
this.model = {
|
||||
success: false,
|
||||
error: error.details?.message ?? 'Failed to delete media',
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
const output = result.unwrap();
|
||||
|
||||
present(result: DeleteMediaResult): void {
|
||||
this.model = {
|
||||
success: output.deleted,
|
||||
error: undefined,
|
||||
success: result.deleted,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,41 +1,19 @@
|
||||
import type { Result } from '@core/shared/application/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import type {
|
||||
GetAvatarResult,
|
||||
GetAvatarErrorCode,
|
||||
} from '@core/media/application/use-cases/GetAvatarUseCase';
|
||||
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 type GetAvatarApplicationError = ApplicationErrorCode<
|
||||
GetAvatarErrorCode,
|
||||
{ message: string }
|
||||
>;
|
||||
|
||||
export class GetAvatarPresenter {
|
||||
export class GetAvatarPresenter implements UseCaseOutputPort<GetAvatarResult> {
|
||||
private model: GetAvatarResponseModel | null = null;
|
||||
|
||||
reset(): void {
|
||||
this.model = null;
|
||||
}
|
||||
|
||||
present(result: Result<GetAvatarResult, GetAvatarApplicationError>): void {
|
||||
if (result.isErr()) {
|
||||
const error = result.unwrapErr();
|
||||
|
||||
if (error.code === 'AVATAR_NOT_FOUND') {
|
||||
this.model = null;
|
||||
return;
|
||||
}
|
||||
|
||||
throw new Error(error.details?.message ?? 'Failed to get avatar');
|
||||
}
|
||||
|
||||
const output = result.unwrap();
|
||||
|
||||
present(result: GetAvatarResult): void {
|
||||
this.model = {
|
||||
avatarUrl: output.avatar.mediaUrl,
|
||||
avatarUrl: result.avatar.mediaUrl,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,37 +1,18 @@
|
||||
import type { Result } from '@core/shared/application/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import type { GetMediaResult, GetMediaErrorCode } from '@core/media/application/use-cases/GetMediaUseCase';
|
||||
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 type GetMediaApplicationError = ApplicationErrorCode<
|
||||
GetMediaErrorCode,
|
||||
{ message: string }
|
||||
>;
|
||||
|
||||
export class GetMediaPresenter {
|
||||
export class GetMediaPresenter implements UseCaseOutputPort<GetMediaResult> {
|
||||
private model: GetMediaResponseModel | null = null;
|
||||
|
||||
reset(): void {
|
||||
this.model = null;
|
||||
}
|
||||
|
||||
present(result: Result<GetMediaResult, GetMediaApplicationError>): void {
|
||||
if (result.isErr()) {
|
||||
const error = result.unwrapErr();
|
||||
|
||||
if (error.code === 'MEDIA_NOT_FOUND') {
|
||||
this.model = null;
|
||||
return;
|
||||
}
|
||||
|
||||
throw new Error(error.details?.message ?? 'Failed to get media');
|
||||
}
|
||||
|
||||
const output = result.unwrap();
|
||||
|
||||
const media = output.media;
|
||||
present(result: GetMediaResult): void {
|
||||
const media = result.media;
|
||||
|
||||
this.model = {
|
||||
id: media.id,
|
||||
|
||||
@@ -1,50 +1,21 @@
|
||||
import type { Result } from '@core/shared/application/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import type {
|
||||
RequestAvatarGenerationResult,
|
||||
RequestAvatarGenerationErrorCode,
|
||||
} from '@core/media/application/use-cases/RequestAvatarGenerationUseCase';
|
||||
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 type RequestAvatarGenerationApplicationError = ApplicationErrorCode<
|
||||
RequestAvatarGenerationErrorCode,
|
||||
{ message: string }
|
||||
>;
|
||||
|
||||
export class RequestAvatarGenerationPresenter {
|
||||
export class RequestAvatarGenerationPresenter implements UseCaseOutputPort<RequestAvatarGenerationResult> {
|
||||
private model: RequestAvatarGenerationResponseModel | null = null;
|
||||
|
||||
reset() {
|
||||
this.model = null;
|
||||
}
|
||||
|
||||
present(
|
||||
result: Result<
|
||||
RequestAvatarGenerationResult,
|
||||
RequestAvatarGenerationApplicationError
|
||||
>,
|
||||
): void {
|
||||
if (result.isErr()) {
|
||||
const error = result.unwrapErr();
|
||||
|
||||
this.model = {
|
||||
success: false,
|
||||
requestId: '',
|
||||
avatarUrls: [],
|
||||
errorMessage: error.details?.message ?? 'Failed to request avatar generation',
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
const output = result.unwrap();
|
||||
|
||||
present(result: RequestAvatarGenerationResult): void {
|
||||
this.model = {
|
||||
success: output.status === 'completed',
|
||||
requestId: output.requestId,
|
||||
avatarUrls: output.avatarUrls,
|
||||
errorMessage: undefined,
|
||||
success: result.status === 'completed',
|
||||
requestId: result.requestId,
|
||||
avatarUrls: result.avatarUrls || [],
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,36 +1,19 @@
|
||||
import type { Result } from '@core/shared/application/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import type {
|
||||
UpdateAvatarResult,
|
||||
UpdateAvatarErrorCode,
|
||||
} from '@core/media/application/use-cases/UpdateAvatarUseCase';
|
||||
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 type UpdateAvatarApplicationError = ApplicationErrorCode<
|
||||
UpdateAvatarErrorCode,
|
||||
{ message: string }
|
||||
>;
|
||||
|
||||
export class UpdateAvatarPresenter {
|
||||
export class UpdateAvatarPresenter implements UseCaseOutputPort<UpdateAvatarResult> {
|
||||
private model: UpdateAvatarResponseModel | null = null;
|
||||
|
||||
reset(): void {
|
||||
this.model = null;
|
||||
}
|
||||
|
||||
present(result: Result<UpdateAvatarResult, UpdateAvatarApplicationError>): void {
|
||||
if (result.isErr()) {
|
||||
const error = result.unwrapErr();
|
||||
throw new Error(error.details?.message ?? 'Failed to update avatar');
|
||||
}
|
||||
|
||||
const output = result.unwrap();
|
||||
|
||||
present(result: UpdateAvatarResult): void {
|
||||
this.model = {
|
||||
success: true,
|
||||
error: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,43 +1,21 @@
|
||||
import type { Result } from '@core/shared/application/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import type {
|
||||
UploadMediaResult,
|
||||
UploadMediaErrorCode,
|
||||
} from '@core/media/application/use-cases/UploadMediaUseCase';
|
||||
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 type UploadMediaApplicationError = ApplicationErrorCode<
|
||||
UploadMediaErrorCode,
|
||||
{ message: string }
|
||||
>;
|
||||
|
||||
export class UploadMediaPresenter {
|
||||
export class UploadMediaPresenter implements UseCaseOutputPort<UploadMediaResult> {
|
||||
private model: UploadMediaResponseModel | null = null;
|
||||
|
||||
reset(): void {
|
||||
this.model = null;
|
||||
}
|
||||
|
||||
present(result: Result<UploadMediaResult, UploadMediaApplicationError>): void {
|
||||
if (result.isErr()) {
|
||||
const error = result.unwrapErr();
|
||||
|
||||
this.model = {
|
||||
success: false,
|
||||
error: error.details?.message ?? 'Upload failed',
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
const output = result.unwrap();
|
||||
|
||||
present(result: UploadMediaResult): void {
|
||||
this.model = {
|
||||
success: true,
|
||||
mediaId: output.mediaId,
|
||||
url: output.url,
|
||||
error: undefined,
|
||||
mediaId: result.mediaId,
|
||||
url: result.url,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user