From 87ec7f90778ecf2b284ca5da58893943ca7e19e6 Mon Sep 17 00:00:00 2001 From: solufa Date: Wed, 17 Jul 2024 12:02:39 +0900 Subject: [PATCH] refactor: generate signedUrl in toTaskDto --- compose.yml | 2 +- server/api/private/tasks/controller.ts | 2 +- server/api/private/tasks/di/controller.ts | 2 +- server/domain/task/model/taskEntity.ts | 3 ++- server/domain/task/model/taskMethod.ts | 13 ++++--------- server/domain/task/repository/taskCommand.ts | 6 +++--- server/domain/task/repository/taskQuery.ts | 10 +++------- server/domain/task/service/toTaskDto.ts | 6 +++++- server/domain/task/useCase/taskUseCase.ts | 8 ++++---- 9 files changed, 24 insertions(+), 28 deletions(-) diff --git a/compose.yml b/compose.yml index f056490..a754bd4 100644 --- a/compose.yml +++ b/compose.yml @@ -1,6 +1,6 @@ services: magnito: - image: frourio/magnito:0.13.0 + image: frourio/magnito:0.15.2 ports: - 5050:5050 - 5051:5051 diff --git a/server/api/private/tasks/controller.ts b/server/api/private/tasks/controller.ts index 9f05bee..89e8520 100644 --- a/server/api/private/tasks/controller.ts +++ b/server/api/private/tasks/controller.ts @@ -12,7 +12,7 @@ export default defineController(() => ({ status: 200, body: await taskQuery .listByAuthorId(prismaClient, user.id, query?.limit) - .then((tasks) => tasks.map(toTaskDto)), + .then((tasks) => Promise.all(tasks.map(toTaskDto))), }), post: { validators: { body: taskValidator.taskCreate }, diff --git a/server/api/private/tasks/di/controller.ts b/server/api/private/tasks/di/controller.ts index 48f4257..086febc 100644 --- a/server/api/private/tasks/di/controller.ts +++ b/server/api/private/tasks/di/controller.ts @@ -8,6 +8,6 @@ export default defineController({ listByAuthorId: taskQuery.listByAuthorId }, (d status: 200, body: await taskQuery.findManyWithDI .inject(deps)(prismaClient, user.id) - .then((tasks) => tasks.map(toTaskDto)), + .then((tasks) => Promise.all(tasks.map(toTaskDto))), }), })); diff --git a/server/domain/task/model/taskEntity.ts b/server/domain/task/model/taskEntity.ts index 64458e9..a24b5f2 100644 --- a/server/domain/task/model/taskEntity.ts +++ b/server/domain/task/model/taskEntity.ts @@ -3,8 +3,9 @@ import type { TaskDto } from 'common/types/task'; import type { EntityId } from 'service/brandedId'; import type { S3PutParams } from 'service/s3Client'; -export type TaskEntity = Omit & { +export type TaskEntity = Omit & { id: EntityId['task']; + imageKey: string | undefined; author: Omit & { id: EntityId['user'] }; }; diff --git a/server/domain/task/model/taskMethod.ts b/server/domain/task/model/taskMethod.ts index 1cbc042..5fcaa7b 100644 --- a/server/domain/task/model/taskMethod.ts +++ b/server/domain/task/model/taskMethod.ts @@ -3,30 +3,25 @@ import type { TaskUpdateDoneDto } from 'common/types/task'; import type { UserDto } from 'common/types/user'; import { labelValidator } from 'common/validators/task'; import { brandedId } from 'service/brandedId'; -import { s3 } from 'service/s3Client'; import { ulid } from 'ulid'; import type { TaskCreateServerVal, TaskDeleteVal, TaskEntity, TaskSaveVal } from './taskEntity'; export const taskMethod = { - create: async (user: UserDto, val: TaskCreateServerVal): Promise => { + create: (user: UserDto, val: TaskCreateServerVal): TaskSaveVal => { const task: TaskEntity = { id: brandedId.task.entity.parse(ulid()), done: false, label: labelValidator.parse(val.label), - image: undefined, + imageKey: undefined, createdTime: Date.now(), author: { id: brandedId.user.entity.parse(user.id), signInName: user.signInName }, }; if (val.image === undefined) return { task }; - const s3Key = `tasks/images/${ulid()}.${val.image.filename.split('.').at(-1)}`; - const url = await s3.getSignedUrl(s3Key); + const imageKey = `tasks/images/${ulid()}.${val.image.filename.split('.').at(-1)}`; - return { - task: { ...task, image: { s3Key, url } }, - s3Params: { key: s3Key, data: val.image }, - }; + return { task: { ...task, imageKey }, s3Params: { key: imageKey, data: val.image } }; }, update: (user: UserDto, task: TaskEntity, dto: TaskUpdateDoneDto): TaskSaveVal => { assert(user.id === String(task.author.id)); diff --git a/server/domain/task/repository/taskCommand.ts b/server/domain/task/repository/taskCommand.ts index 644a5b8..6c00cda 100644 --- a/server/domain/task/repository/taskCommand.ts +++ b/server/domain/task/repository/taskCommand.ts @@ -9,12 +9,12 @@ export const taskCommand = { await tx.task.upsert({ where: { id: val.task.id }, - update: { label: val.task.label, done: val.task.done, imageKey: val.task.image?.s3Key }, + update: { label: val.task.label, done: val.task.done, imageKey: val.task.imageKey }, create: { id: val.task.id, label: val.task.label, done: val.task.done, - imageKey: val.task.image?.s3Key, + imageKey: val.task.imageKey, createdAt: new Date(val.task.createdTime), authorId: val.task.author.id, }, @@ -25,6 +25,6 @@ export const taskCommand = { await tx.task.delete({ where: { id: val.task.id } }); - if (val.task.image !== undefined) await s3.delete(val.task.image.s3Key); + if (val.task.imageKey !== undefined) await s3.delete(val.task.imageKey); }, }; diff --git a/server/domain/task/repository/taskQuery.ts b/server/domain/task/repository/taskQuery.ts index f94e49a..5d24af4 100644 --- a/server/domain/task/repository/taskQuery.ts +++ b/server/domain/task/repository/taskQuery.ts @@ -1,18 +1,14 @@ import type { Prisma, Task, User } from '@prisma/client'; import type { DtoId, MaybeId } from 'common/types/brandedId'; import { brandedId } from 'service/brandedId'; -import { s3 } from 'service/s3Client'; import { depend } from 'velona'; import type { TaskEntity } from '../model/taskEntity'; -const toEntity = async (prismaTask: Task & { Author: User }): Promise => ({ +const toEntity = (prismaTask: Task & { Author: User }): TaskEntity => ({ id: brandedId.task.entity.parse(prismaTask.id), label: prismaTask.label, done: prismaTask.done, - image: - prismaTask.imageKey === null - ? undefined - : { url: await s3.getSignedUrl(prismaTask.imageKey), s3Key: prismaTask.imageKey }, + imageKey: prismaTask.imageKey ?? undefined, author: { id: brandedId.user.entity.parse(prismaTask.authorId), signInName: prismaTask.Author.signInName, @@ -32,7 +28,7 @@ const listByAuthorId = async ( include: { Author: true }, }); - return Promise.all(prismaTasks.map(toEntity)); + return prismaTasks.map(toEntity); }; export const taskQuery = { diff --git a/server/domain/task/service/toTaskDto.ts b/server/domain/task/service/toTaskDto.ts index 2af01f4..ddc502f 100644 --- a/server/domain/task/service/toTaskDto.ts +++ b/server/domain/task/service/toTaskDto.ts @@ -1,9 +1,13 @@ import type { TaskDto } from 'common/types/task'; import { brandedId } from 'service/brandedId'; +import { s3 } from 'service/s3Client'; import type { TaskEntity } from '../model/taskEntity'; -export const toTaskDto = (task: TaskEntity): TaskDto => ({ +export const toTaskDto = async (task: TaskEntity): Promise => ({ ...task, id: brandedId.task.dto.parse(task.id), + image: task.imageKey + ? { s3Key: task.imageKey, url: await s3.getSignedUrl(task.imageKey) } + : undefined, author: { ...task.author, id: brandedId.user.dto.parse(task.author.id) }, }); diff --git a/server/domain/task/useCase/taskUseCase.ts b/server/domain/task/useCase/taskUseCase.ts index a57ab97..ed4a747 100644 --- a/server/domain/task/useCase/taskUseCase.ts +++ b/server/domain/task/useCase/taskUseCase.ts @@ -12,11 +12,11 @@ import { toTaskDto } from '../service/toTaskDto'; export const taskUseCase = { create: (user: UserDto, val: TaskCreateServerVal): Promise => transaction('RepeatableRead', async (tx) => { - const created = await taskMethod.create(user, val); + const created = taskMethod.create(user, val); await taskCommand.save(tx, created); - const dto = toTaskDto(created.task); + const dto = await toTaskDto(created.task); taskEvent.created(user, dto); return dto; @@ -28,7 +28,7 @@ export const taskUseCase = { await taskCommand.save(tx, updated); - const dto = toTaskDto(updated.task); + const dto = await toTaskDto(updated.task); taskEvent.updated(user, dto); return dto; @@ -40,7 +40,7 @@ export const taskUseCase = { await taskCommand.delete(tx, deleted); - const dto = toTaskDto(deleted.task); + const dto = await toTaskDto(deleted.task); taskEvent.deleted(user, dto); return dto;