From c165af77a39e24be084e386527c13707a84a06a4 Mon Sep 17 00:00:00 2001 From: Timothy Russo Date: Tue, 20 Aug 2024 08:59:39 +0200 Subject: [PATCH 01/31] feat: add ApiClient class with dependency injection --- package.json | 1 + src/modules/network/domain/IApiClient.ts | 39 ++++++++++ src/modules/network/infra/ApiClient.ts | 95 ++++++++++++++++++++++++ tsconfig.json | 4 +- yarn.lock | 12 ++- 5 files changed, 149 insertions(+), 2 deletions(-) create mode 100644 src/modules/network/domain/IApiClient.ts create mode 100644 src/modules/network/infra/ApiClient.ts diff --git a/package.json b/package.json index 2964c5e20..eec6214d3 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "react-redux": "^8.1.2", "redux-persist": "^6.0.0", "tailwind-merge": "^2.0.0", + "tsyringe": "^4.8.0", "zod": "^3.22.2" }, "devDependencies": { diff --git a/src/modules/network/domain/IApiClient.ts b/src/modules/network/domain/IApiClient.ts new file mode 100644 index 000000000..55f80fe0f --- /dev/null +++ b/src/modules/network/domain/IApiClient.ts @@ -0,0 +1,39 @@ +export interface IApiClient { + GET( + baseUrl: string, + url: string, + token: string, + cache: RequestCache, + tags?: string, + ): Promise; + + POST( + baseUrl: string, + url: string, + token: string, + cache: RequestCache, + payload: X, + ): Promise; + + PATCH( + baseUrl: string, + url: string, + token: string, + cache: RequestCache, + payload: X, + ): Promise; + + DELETE( + baseUrl: string, + url: string, + token: string, + cache: RequestCache, + ): Promise; + + UNAUTHPOST( + baseUrl: string, + url: string, + cache: RequestCache, + payload: X, + ): Promise; +} diff --git a/src/modules/network/infra/ApiClient.ts b/src/modules/network/infra/ApiClient.ts new file mode 100644 index 000000000..07586aaf6 --- /dev/null +++ b/src/modules/network/infra/ApiClient.ts @@ -0,0 +1,95 @@ +import { injectable } from "tsyringe"; +import type { IApiClient } from "@/modules/network/domain/IApiClient"; + +@injectable() +export class ApiClient implements IApiClient { + private async sendRequest( + method: string, + baseUrl: string, + url: string, + token: string | null, + cache: RequestCache, + payload?: P, + tags?: string, + ): Promise { + const headers: Record = { + "Content-Type": "application/json", + }; + + if (token) { + headers.Cookie = token; + } + + const options: RequestInit = { + method, + headers, + cache, + body: payload ? JSON.stringify(payload) : undefined, + next: tags ? { tags: [tags] } : undefined, + }; + + const res = await fetch(`${baseUrl}/${url}`, options); + + if (!res.ok) { + throw new Error(`Status code: ${res.status}, Message: ${res.statusText}`); + } + + return (await res.json()) as T; + } + + async GET( + baseUrl: string, + url: string, + token: string, + cache: RequestCache, + tags?: string, + ): Promise { + return this.sendRequest( + "GET", + baseUrl, + url, + token, + cache, + undefined, + tags, + ); + } + + async POST( + baseUrl: string, + url: string, + token: string, + cache: RequestCache, + payload: X, + ): Promise { + return this.sendRequest("POST", baseUrl, url, token, cache, payload); + } + + async PATCH( + baseUrl: string, + url: string, + token: string, + cache: RequestCache, + payload: X, + ): Promise { + return this.sendRequest("PATCH", baseUrl, url, token, cache, payload); + } + + async DELETE( + baseUrl: string, + url: string, + token: string, + cache: RequestCache, + ): Promise { + return this.sendRequest("DELETE", baseUrl, url, token, cache); + } + + async UNAUTHPOST( + baseUrl: string, + url: string, + cache: RequestCache, + payload: X, + ): Promise { + return this.sendRequest("POST", baseUrl, url, null, cache, payload); + } +} diff --git a/tsconfig.json b/tsconfig.json index c396102d3..2227c9b9e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -29,7 +29,9 @@ "@/*": ["./src/*"], "@/public/*": ["./public/*"], "@/myVoyage/*": ["./src/app/(main)/my-voyage/[teamId]/*"], - "@/dashboard/*": ["./src/app/(main)/dashboard/*"] + "@/dashboard/*": ["./src/app/(main)/dashboard/*"], + "@/di/*": ["./src/di/*"], + "@/modules/*": ["./src/modules/*"] } }, "include": [ diff --git a/yarn.lock b/yarn.lock index 6f51f2de9..37f0d641f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6736,6 +6736,7 @@ __metadata: tailwind-merge: "npm:^2.0.0" tailwindcss: "npm:3.3.3" tsconfig-paths-webpack-plugin: "npm:^4.1.0" + tsyringe: "npm:^4.8.0" typescript: "npm:5.3.3" zod: "npm:^3.22.2" languageName: unknown @@ -15953,7 +15954,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^1.13.0, tslib@npm:^1.8.1": +"tslib@npm:^1.13.0, tslib@npm:^1.8.1, tslib@npm:^1.9.3": version: 1.14.1 resolution: "tslib@npm:1.14.1" checksum: 69ae09c49eea644bc5ebe1bca4fa4cc2c82b7b3e02f43b84bd891504edf66dbc6b2ec0eef31a957042de2269139e4acff911e6d186a258fb14069cd7f6febce2 @@ -15978,6 +15979,15 @@ __metadata: languageName: node linkType: hard +"tsyringe@npm:^4.8.0": + version: 4.8.0 + resolution: "tsyringe@npm:4.8.0" + dependencies: + tslib: "npm:^1.9.3" + checksum: e13810e8ff39c4093acd0649bc5db3c164825827631e1522cd9d5ca8694a018447fa1c24f059ea54e93b1020767b1131b9dc9ce598dabfc9aa41c11544bbfe19 + languageName: node + linkType: hard + "tty-browserify@npm:^0.0.1": version: 0.0.1 resolution: "tty-browserify@npm:0.0.1" From 4a261bbf2485a02a3f18857f8a8fcb688630e482 Mon Sep 17 00:00:00 2001 From: Timothy Russo Date: Wed, 21 Aug 2024 09:03:32 +0200 Subject: [PATCH 02/31] feat: add new Ideation Service --- src/di/config.ts | 19 ++ src/di/resolver.ts | 8 + src/di/types.ts | 7 + .../ideation/domain/AddIdeationType.ts | 3 + src/modules/ideation/domain/IdeationBody.ts | 9 + src/modules/ideation/domain/IdeationProps.ts | 25 +++ .../ideation/domain/IdeationResponse.ts | 24 +++ .../ideation/domain/IdeationWithoutTeamId.ts | 3 + .../domain/services/IIdeationService.ts | 36 ++++ .../ideation/service/IdeationService.ts | 186 ++++++++++++++++++ src/modules/network/domain/ApiParams.ts | 47 +++++ src/modules/network/domain/IApiClient.ts | 39 ---- .../repositories/IApiClientRepository.ts | 19 ++ src/modules/network/infra/ApiClient.ts | 95 --------- .../repositories/ApiClientRepository.ts | 119 +++++++++++ tsconfig.json | 2 + 16 files changed, 507 insertions(+), 134 deletions(-) create mode 100644 src/di/config.ts create mode 100644 src/di/resolver.ts create mode 100644 src/di/types.ts create mode 100644 src/modules/ideation/domain/AddIdeationType.ts create mode 100644 src/modules/ideation/domain/IdeationBody.ts create mode 100644 src/modules/ideation/domain/IdeationProps.ts create mode 100644 src/modules/ideation/domain/IdeationResponse.ts create mode 100644 src/modules/ideation/domain/IdeationWithoutTeamId.ts create mode 100644 src/modules/ideation/domain/services/IIdeationService.ts create mode 100644 src/modules/ideation/service/IdeationService.ts create mode 100644 src/modules/network/domain/ApiParams.ts delete mode 100644 src/modules/network/domain/IApiClient.ts create mode 100644 src/modules/network/domain/repositories/IApiClientRepository.ts delete mode 100644 src/modules/network/infra/ApiClient.ts create mode 100644 src/modules/network/repositories/ApiClientRepository.ts diff --git a/src/di/config.ts b/src/di/config.ts new file mode 100644 index 000000000..d9a7ff4ae --- /dev/null +++ b/src/di/config.ts @@ -0,0 +1,19 @@ +import { container } from "tsyringe"; + +import { TYPES } from "./types"; +import type { IApiClientRepository } from "@/modules/network/domain/repositories/IApiClientRepository"; +import { ApiClientRepository } from "@/modules/network/repositories/ApiClientRepository"; +import type { IIdeationService } from "@/modules/ideation/domain/services/IIdeationService"; +import { IdeationService } from "@/modules/ideation/service/IdeationService"; + +/* Services */ +container.register(TYPES.IdeationService, { + useClass: IdeationService, +}); + +/* Repositories */ +container.register(TYPES.ApiClientRepository, { + useClass: ApiClientRepository, +}); + +export default container; diff --git a/src/di/resolver.ts b/src/di/resolver.ts new file mode 100644 index 000000000..7d701adc4 --- /dev/null +++ b/src/di/resolver.ts @@ -0,0 +1,8 @@ +import type { InjectionToken } from "tsyringe"; + +import container from "./config"; + +export const resolve = + (token: InjectionToken) => + () => + container.resolve(token); diff --git a/src/di/types.ts b/src/di/types.ts new file mode 100644 index 000000000..b6c65dd1f --- /dev/null +++ b/src/di/types.ts @@ -0,0 +1,7 @@ +export const TYPES = { + /* Repositories */ + ApiClientRepository: Symbol.for("ApiClientRepository"), + + /* Services */ + IdeationService: Symbol.for("IdeationService"), +}; diff --git a/src/modules/ideation/domain/AddIdeationType.ts b/src/modules/ideation/domain/AddIdeationType.ts new file mode 100644 index 000000000..d9d4367e8 --- /dev/null +++ b/src/modules/ideation/domain/AddIdeationType.ts @@ -0,0 +1,3 @@ +import type { IdeationProps } from "./IdeationProps"; + +export type AddIdeationType = Pick; diff --git a/src/modules/ideation/domain/IdeationBody.ts b/src/modules/ideation/domain/IdeationBody.ts new file mode 100644 index 000000000..599f639c8 --- /dev/null +++ b/src/modules/ideation/domain/IdeationBody.ts @@ -0,0 +1,9 @@ +export interface IdeationBody { + title: string; + description: string; + vision: string; +} + +export interface AddIdeationBody extends IdeationBody {} + +export interface EditIdeationBody extends Partial {} diff --git a/src/modules/ideation/domain/IdeationProps.ts b/src/modules/ideation/domain/IdeationProps.ts new file mode 100644 index 000000000..5aa2fe31d --- /dev/null +++ b/src/modules/ideation/domain/IdeationProps.ts @@ -0,0 +1,25 @@ +import type { AddIdeationType } from "./AddIdeationType"; +import type { EditIdeationBody, IdeationBody } from "./IdeationBody"; +import type { IdeationWithoutTeamId } from "./IdeationWithoutTeamId"; + +export interface IdeationProps { + teamId: number; + ideationId: number; +} + +export interface AddIdeationProps extends AddIdeationType, IdeationBody { + baseUrl: string; +} + +export type EditIdeationProps = EditIdeationBody & + IdeationWithoutTeamId & { baseUrl: string }; + +export type DeleteIdeationProps = IdeationWithoutTeamId & { baseUrl: string }; + +export type IdeationVoteProps = IdeationWithoutTeamId & { baseUrl: string }; + +export type FetchIdeationsProps = Pick; + +export interface FinalizeIdeationProps extends IdeationProps { + baseUrl: string; +} diff --git a/src/modules/ideation/domain/IdeationResponse.ts b/src/modules/ideation/domain/IdeationResponse.ts new file mode 100644 index 000000000..484103645 --- /dev/null +++ b/src/modules/ideation/domain/IdeationResponse.ts @@ -0,0 +1,24 @@ +import type { IdeationBody } from "./IdeationBody"; + +export interface IdeationResponse { + id: number; + voyageTeamMemberId: number; + createdAt: Date; + updatedAt: Date; +} + +export interface AddIdeationResponse extends IdeationResponse, IdeationBody {} + +export interface EditIdeationResponse extends AddIdeationResponse {} + +export interface DeleteIdeationResponse extends AddIdeationResponse {} + +export interface FinalizeIdeationResponse + extends IdeationResponse, + IdeationBody { + isSelected: boolean; +} + +export interface IdeationVoteResponse extends IdeationResponse { + projectIdeaId: number; +} diff --git a/src/modules/ideation/domain/IdeationWithoutTeamId.ts b/src/modules/ideation/domain/IdeationWithoutTeamId.ts new file mode 100644 index 000000000..b069f039d --- /dev/null +++ b/src/modules/ideation/domain/IdeationWithoutTeamId.ts @@ -0,0 +1,3 @@ +import type { IdeationProps } from "./IdeationProps"; + +export type IdeationWithoutTeamId = Omit; diff --git a/src/modules/ideation/domain/services/IIdeationService.ts b/src/modules/ideation/domain/services/IIdeationService.ts new file mode 100644 index 000000000..618f4cdad --- /dev/null +++ b/src/modules/ideation/domain/services/IIdeationService.ts @@ -0,0 +1,36 @@ +import type { + AddIdeationProps, + DeleteIdeationProps, + EditIdeationProps, + FinalizeIdeationProps, + IdeationVoteProps, +} from "@/modules/ideation/domain/IdeationProps"; +import type { + AddIdeationResponse, + DeleteIdeationResponse, + EditIdeationResponse, + FinalizeIdeationResponse, + IdeationVoteResponse, +} from "@/modules/ideation/domain/IdeationResponse"; +import type { AsyncActionResponse } from "@/utils/handleAsync"; + +export interface IIdeationService { + addIdeation: ( + props: AddIdeationProps, + ) => Promise>; + editIdeation: ( + props: EditIdeationProps, + ) => Promise>; + deleteIdeation: ( + props: DeleteIdeationProps, + ) => Promise>; + addIdeationVote: ( + props: IdeationVoteProps, + ) => Promise>; + removeIdeationVote: ( + props: IdeationVoteProps, + ) => Promise>; + finalizeIdeation: ( + props: FinalizeIdeationProps, + ) => Promise>; +} diff --git a/src/modules/ideation/service/IdeationService.ts b/src/modules/ideation/service/IdeationService.ts new file mode 100644 index 000000000..72889b54e --- /dev/null +++ b/src/modules/ideation/service/IdeationService.ts @@ -0,0 +1,186 @@ +import { inject, injectable } from "tsyringe"; +import { revalidateTag } from "next/cache"; +import type { + AddIdeationBody, + EditIdeationBody, +} from "@/modules/ideation/domain/IdeationBody"; +import type { + AddIdeationResponse, + DeleteIdeationResponse, + EditIdeationResponse, + FinalizeIdeationResponse, + IdeationVoteResponse, +} from "@/modules/ideation/domain/IdeationResponse"; +import type { IIdeationService } from "@/modules/ideation/domain/services/IIdeationService"; +import type { + AddIdeationProps, + EditIdeationProps, + DeleteIdeationProps, + IdeationVoteProps, + FinalizeIdeationProps, +} from "@/modules/ideation/domain/IdeationProps"; +import { ApiClientRepository } from "@/modules/network/repositories/ApiClientRepository"; +import { getAccessToken } from "@/utils/getCookie"; +import type { AsyncActionResponse } from "@/utils/handleAsync"; +import { handleAsync } from "@/utils/handleAsync"; +import { CacheTag } from "@/utils/cacheTag"; +import { TYPES } from "@/di/types"; + +@injectable() +export class IdeationService implements IIdeationService { + constructor( + @inject(TYPES.ApiClientRepository) + private readonly apiClient: ApiClientRepository, + ) {} + + async addIdeation({ + teamId, + title, + description, + vision, + baseUrl, + }: AddIdeationProps): Promise> { + const token = getAccessToken(); + + const addIdeationAsync = () => + this.apiClient.POST({ + baseUrl, + url: `api/v1/voyages/teams/${teamId}/ideations`, + token, + cache: "default", + payload: { title, description, vision }, + }); + + const [res, error] = await handleAsync(addIdeationAsync); + + if (res) { + revalidateTag(CacheTag.ideation); + } + + return [res, error]; + } + + async editIdeation({ + ideationId, + title, + description, + vision, + baseUrl, + }: EditIdeationProps): Promise> { + const token = getAccessToken(); + + const editIdeationAsync = () => + this.apiClient.PATCH({ + baseUrl, + url: `api/v1/voyages/ideations/${ideationId}`, + token, + cache: "default", + payload: { title, description, vision }, + }); + + const [res, error] = await handleAsync(editIdeationAsync); + + if (res) { + revalidateTag(CacheTag.ideation); + } + + return [res, error]; + } + + async deleteIdeation({ + ideationId, + baseUrl, + }: DeleteIdeationProps): Promise< + AsyncActionResponse + > { + const token = getAccessToken(); + + const deleteIdeationAsync = () => + this.apiClient.DELETE({ + baseUrl, + url: `api/v1/voyages/ideations/${ideationId}`, + token, + cache: "default", + }); + + const [res, error] = await handleAsync(deleteIdeationAsync); + + if (res) { + revalidateTag(CacheTag.ideation); + } + + return [res, error]; + } + + async addIdeationVote({ + ideationId, + baseUrl, + }: IdeationVoteProps): Promise> { + const token = getAccessToken(); + + const addIdeationVoteAsync = () => + this.apiClient.POST({ + baseUrl, + url: `api/v1/voyages/ideations/${ideationId}/ideation-votes`, + token, + cache: "default", + }); + + const [res, error] = await handleAsync(addIdeationVoteAsync); + + if (res) { + revalidateTag(CacheTag.ideation); + } + + return [res, error]; + } + + async removeIdeationVote({ + ideationId, + baseUrl, + }: IdeationVoteProps): Promise> { + const token = getAccessToken(); + + const removeIdeationVoteAsync = () => + this.apiClient.DELETE({ + baseUrl, + url: `api/v1/voyages/ideations/${ideationId}/ideation-votes`, + token, + cache: "default", + }); + + const [res, error] = await handleAsync(removeIdeationVoteAsync); + + if (res) { + revalidateTag(CacheTag.ideation); + } + + return [res, error]; + } + + async finalizeIdeation({ + teamId, + ideationId, + baseUrl, + }: FinalizeIdeationProps): Promise< + AsyncActionResponse + > { + const token = getAccessToken(); + + const finalizeIdeationAsync = () => + this.apiClient.POST({ + baseUrl, + url: `api/v1/voyages/teams/${teamId}/ideations/${ideationId}/select`, + token, + cache: "default", + }); + + const [res, error] = await handleAsync(finalizeIdeationAsync); + + if (res) { + revalidateTag(CacheTag.ideation); + } + + return [res, error]; + } +} diff --git a/src/modules/network/domain/ApiParams.ts b/src/modules/network/domain/ApiParams.ts new file mode 100644 index 000000000..bc1caabe2 --- /dev/null +++ b/src/modules/network/domain/ApiParams.ts @@ -0,0 +1,47 @@ +export interface SendRequestParams

{ + method: string; + baseUrl: string; + url: string; + token: string | null; + cache: RequestCache; + payload?: P; + tags?: string; +} + +export interface GetParams { + baseUrl: string; + url: string; + token: string; + cache: RequestCache; + tags?: string; +} + +export interface PostParams { + baseUrl: string; + url: string; + token: string; + cache: RequestCache; + payload?: X; +} + +export interface PatchParams { + baseUrl: string; + url: string; + token: string; + cache: RequestCache; + payload: X; +} + +export interface DeleteParams { + baseUrl: string; + url: string; + token: string; + cache: RequestCache; +} + +export interface UnauthPostParams { + baseUrl: string; + url: string; + cache: RequestCache; + payload: X; +} diff --git a/src/modules/network/domain/IApiClient.ts b/src/modules/network/domain/IApiClient.ts deleted file mode 100644 index 55f80fe0f..000000000 --- a/src/modules/network/domain/IApiClient.ts +++ /dev/null @@ -1,39 +0,0 @@ -export interface IApiClient { - GET( - baseUrl: string, - url: string, - token: string, - cache: RequestCache, - tags?: string, - ): Promise; - - POST( - baseUrl: string, - url: string, - token: string, - cache: RequestCache, - payload: X, - ): Promise; - - PATCH( - baseUrl: string, - url: string, - token: string, - cache: RequestCache, - payload: X, - ): Promise; - - DELETE( - baseUrl: string, - url: string, - token: string, - cache: RequestCache, - ): Promise; - - UNAUTHPOST( - baseUrl: string, - url: string, - cache: RequestCache, - payload: X, - ): Promise; -} diff --git a/src/modules/network/domain/repositories/IApiClientRepository.ts b/src/modules/network/domain/repositories/IApiClientRepository.ts new file mode 100644 index 000000000..53bc5d704 --- /dev/null +++ b/src/modules/network/domain/repositories/IApiClientRepository.ts @@ -0,0 +1,19 @@ +import type { + DeleteParams, + GetParams, + PatchParams, + PostParams, + UnauthPostParams, +} from "@/modules/network/domain/ApiParams"; + +export interface IApiClientRepository { + GET(params: GetParams): Promise; + + POST(params: PostParams): Promise; + + PATCH(params: PatchParams): Promise; + + DELETE(params: DeleteParams): Promise; + + UNAUTHPOST(params: UnauthPostParams): Promise; +} diff --git a/src/modules/network/infra/ApiClient.ts b/src/modules/network/infra/ApiClient.ts deleted file mode 100644 index 07586aaf6..000000000 --- a/src/modules/network/infra/ApiClient.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { injectable } from "tsyringe"; -import type { IApiClient } from "@/modules/network/domain/IApiClient"; - -@injectable() -export class ApiClient implements IApiClient { - private async sendRequest( - method: string, - baseUrl: string, - url: string, - token: string | null, - cache: RequestCache, - payload?: P, - tags?: string, - ): Promise { - const headers: Record = { - "Content-Type": "application/json", - }; - - if (token) { - headers.Cookie = token; - } - - const options: RequestInit = { - method, - headers, - cache, - body: payload ? JSON.stringify(payload) : undefined, - next: tags ? { tags: [tags] } : undefined, - }; - - const res = await fetch(`${baseUrl}/${url}`, options); - - if (!res.ok) { - throw new Error(`Status code: ${res.status}, Message: ${res.statusText}`); - } - - return (await res.json()) as T; - } - - async GET( - baseUrl: string, - url: string, - token: string, - cache: RequestCache, - tags?: string, - ): Promise { - return this.sendRequest( - "GET", - baseUrl, - url, - token, - cache, - undefined, - tags, - ); - } - - async POST( - baseUrl: string, - url: string, - token: string, - cache: RequestCache, - payload: X, - ): Promise { - return this.sendRequest("POST", baseUrl, url, token, cache, payload); - } - - async PATCH( - baseUrl: string, - url: string, - token: string, - cache: RequestCache, - payload: X, - ): Promise { - return this.sendRequest("PATCH", baseUrl, url, token, cache, payload); - } - - async DELETE( - baseUrl: string, - url: string, - token: string, - cache: RequestCache, - ): Promise { - return this.sendRequest("DELETE", baseUrl, url, token, cache); - } - - async UNAUTHPOST( - baseUrl: string, - url: string, - cache: RequestCache, - payload: X, - ): Promise { - return this.sendRequest("POST", baseUrl, url, null, cache, payload); - } -} diff --git a/src/modules/network/repositories/ApiClientRepository.ts b/src/modules/network/repositories/ApiClientRepository.ts new file mode 100644 index 000000000..e39cf1877 --- /dev/null +++ b/src/modules/network/repositories/ApiClientRepository.ts @@ -0,0 +1,119 @@ +import { injectable } from "tsyringe"; +import type { + DeleteParams, + GetParams, + PatchParams, + PostParams, + SendRequestParams, + UnauthPostParams, +} from "@/modules/network/domain/ApiParams"; +import type { IApiClientRepository } from "@/modules/network/domain/repositories/IApiClientRepository"; + +@injectable() +export class ApiClientRepository implements IApiClientRepository { + private async sendRequest({ + method, + baseUrl, + url, + token, + cache, + payload, + tags, + }: SendRequestParams

): Promise { + const headers: Record = { + "Content-Type": "application/json", + }; + + if (token) { + headers.Cookie = token; + } + + const options: RequestInit = { + method, + headers, + cache, + body: payload ? JSON.stringify(payload) : undefined, + next: tags ? { tags: [tags] } : undefined, + }; + + const res = await fetch(`${baseUrl}/${url}`, options); + + if (!res.ok) { + throw new Error(`Status code: ${res.status}, Message: ${res.statusText}`); + } + + return (await res.json()) as T; + } + + async GET({ baseUrl, url, token, cache, tags }: GetParams): Promise { + return this.sendRequest({ + method: "GET", + baseUrl, + url, + token, + cache, + payload: undefined, + tags, + }); + } + + async POST({ + baseUrl, + url, + token, + cache, + payload, + }: PostParams): Promise { + return this.sendRequest({ + method: "POST", + baseUrl, + url, + token, + cache, + payload, + }); + } + + async PATCH({ + baseUrl, + url, + token, + cache, + payload, + }: PatchParams): Promise { + return this.sendRequest({ + method: "PATCH", + baseUrl, + url, + token, + cache, + payload, + }); + } + + async DELETE({ baseUrl, url, token, cache }: DeleteParams): Promise { + return this.sendRequest({ + method: "DELETE", + baseUrl, + url, + token, + cache, + }); + } + + async UNAUTHPOST({ + baseUrl, + url, + cache, + payload, + }: UnauthPostParams): Promise { + return this.sendRequest({ + method: "POST", + baseUrl, + url, + token: null, + cache, + payload, + }); + } +} diff --git a/tsconfig.json b/tsconfig.json index 2227c9b9e..1f945204a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -20,6 +20,8 @@ "isolatedModules": true, "jsx": "preserve", "incremental": true, + "experimentalDecorators": true, + "emitDecoratorMetadata": true, "plugins": [ { "name": "next" From 480996a69fbf67cfe40d28277ab63ef84267c934 Mon Sep 17 00:00:00 2001 From: Timothy Russo Date: Wed, 21 Aug 2024 09:04:12 +0200 Subject: [PATCH 03/31] feat: tsyring configuration --- src/di/resolver.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/di/resolver.ts b/src/di/resolver.ts index 7d701adc4..a87dd8dbb 100644 --- a/src/di/resolver.ts +++ b/src/di/resolver.ts @@ -4,5 +4,5 @@ import container from "./config"; export const resolve = (token: InjectionToken) => - () => - container.resolve(token); + () => + container.resolve(token); From ee520144ab32cf59f15e854a1777613ab3d21ac7 Mon Sep 17 00:00:00 2001 From: Timothy Russo Date: Wed, 21 Aug 2024 09:05:27 +0200 Subject: [PATCH 04/31] feat: tsyring configuration --- src/di/resolver.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/di/resolver.ts b/src/di/resolver.ts index a87dd8dbb..7d701adc4 100644 --- a/src/di/resolver.ts +++ b/src/di/resolver.ts @@ -4,5 +4,5 @@ import container from "./config"; export const resolve = (token: InjectionToken) => - () => - container.resolve(token); + () => + container.resolve(token); From c1e39ff0509a3b6d8114a0fb920bcf17f601611e Mon Sep 17 00:00:00 2001 From: Timothy Russo Date: Wed, 21 Aug 2024 09:05:51 +0200 Subject: [PATCH 05/31] feat: tsyring configuration --- src/di/resolver.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/di/resolver.ts b/src/di/resolver.ts index 7d701adc4..ca4d78ed8 100644 --- a/src/di/resolver.ts +++ b/src/di/resolver.ts @@ -3,6 +3,4 @@ import type { InjectionToken } from "tsyringe"; import container from "./config"; export const resolve = - (token: InjectionToken) => - () => - container.resolve(token); + (token: InjectionToken) => () => container.resolve(token); From 673017dfcbea68293a6a784cf4dd979a112720dc Mon Sep 17 00:00:00 2001 From: Timothy Russo Date: Wed, 21 Aug 2024 09:06:16 +0200 Subject: [PATCH 06/31] feat: tsyring configuration --- src/di/resolver.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/di/resolver.ts b/src/di/resolver.ts index ca4d78ed8..f6daa89ac 100644 --- a/src/di/resolver.ts +++ b/src/di/resolver.ts @@ -3,4 +3,8 @@ import type { InjectionToken } from "tsyringe"; import container from "./config"; export const resolve = - (token: InjectionToken) => () => container.resolve(token); + (token: InjectionToken) => + // eslint-disable-next-line indent + () => + // eslint-disable-next-line indent + container.resolve(token); From b8821980d39f6887babe9861b87460f194789e6a Mon Sep 17 00:00:00 2001 From: Timothy Russo Date: Thu, 22 Aug 2024 08:42:24 +0200 Subject: [PATCH 07/31] feat: add ideation use cases --- src/di/config.ts | 4 +- src/di/types.ts | 4 +- src/modules/ideation/domain/IdeationProps.ts | 14 +- src/modules/ideation/domain/IdeationUrls.ts | 9 ++ .../ideation/service/IdeationService.ts | 127 +++++++++--------- .../ideation/usecases/AddIdeationUseCase.ts | 47 +++++++ .../usecases/AddIdeationVoteUseCase.ts | 47 +++++++ .../usecases/DeleteIdeationUseCase.ts | 47 +++++++ .../ideation/usecases/EditIdeationUseCases.ts | 47 +++++++ .../usecases/FinalizeIdeationUseCase.ts | 47 +++++++ .../usecases/RemoveIdeationVoteUseCase.ts | 47 +++++++ .../repositories/ApiClientRepository.ts | 50 +++++++ 12 files changed, 417 insertions(+), 73 deletions(-) create mode 100644 src/modules/ideation/domain/IdeationUrls.ts create mode 100644 src/modules/ideation/usecases/AddIdeationUseCase.ts create mode 100644 src/modules/ideation/usecases/AddIdeationVoteUseCase.ts create mode 100644 src/modules/ideation/usecases/DeleteIdeationUseCase.ts create mode 100644 src/modules/ideation/usecases/EditIdeationUseCases.ts create mode 100644 src/modules/ideation/usecases/FinalizeIdeationUseCase.ts create mode 100644 src/modules/ideation/usecases/RemoveIdeationVoteUseCase.ts diff --git a/src/di/config.ts b/src/di/config.ts index d9a7ff4ae..28094cfad 100644 --- a/src/di/config.ts +++ b/src/di/config.ts @@ -7,12 +7,12 @@ import type { IIdeationService } from "@/modules/ideation/domain/services/IIdeat import { IdeationService } from "@/modules/ideation/service/IdeationService"; /* Services */ -container.register(TYPES.IdeationService, { +container.register(TYPES.IIdeationService, { useClass: IdeationService, }); /* Repositories */ -container.register(TYPES.ApiClientRepository, { +container.register(TYPES.IApiClientRepository, { useClass: ApiClientRepository, }); diff --git a/src/di/types.ts b/src/di/types.ts index b6c65dd1f..9f26a6e4c 100644 --- a/src/di/types.ts +++ b/src/di/types.ts @@ -1,7 +1,7 @@ export const TYPES = { /* Repositories */ - ApiClientRepository: Symbol.for("ApiClientRepository"), + IApiClientRepository: Symbol.for("IApiClientRepository"), /* Services */ - IdeationService: Symbol.for("IdeationService"), + IIdeationService: Symbol.for("IIdeationService"), }; diff --git a/src/modules/ideation/domain/IdeationProps.ts b/src/modules/ideation/domain/IdeationProps.ts index 5aa2fe31d..a0c71d07f 100644 --- a/src/modules/ideation/domain/IdeationProps.ts +++ b/src/modules/ideation/domain/IdeationProps.ts @@ -9,17 +9,25 @@ export interface IdeationProps { export interface AddIdeationProps extends AddIdeationType, IdeationBody { baseUrl: string; + token: string; } export type EditIdeationProps = EditIdeationBody & - IdeationWithoutTeamId & { baseUrl: string }; + IdeationWithoutTeamId & { baseUrl: string; token: string }; -export type DeleteIdeationProps = IdeationWithoutTeamId & { baseUrl: string }; +export type DeleteIdeationProps = IdeationWithoutTeamId & { + baseUrl: string; + token: string; +}; -export type IdeationVoteProps = IdeationWithoutTeamId & { baseUrl: string }; +export type IdeationVoteProps = IdeationWithoutTeamId & { + baseUrl: string; + token: string; +}; export type FetchIdeationsProps = Pick; export interface FinalizeIdeationProps extends IdeationProps { baseUrl: string; + token: string; } diff --git a/src/modules/ideation/domain/IdeationUrls.ts b/src/modules/ideation/domain/IdeationUrls.ts new file mode 100644 index 000000000..134027dee --- /dev/null +++ b/src/modules/ideation/domain/IdeationUrls.ts @@ -0,0 +1,9 @@ +export const IdeationUrls = { + BASE_URL_IDEATIONS: "api/v1/voyages/ideations", + BASE_URL_TEAMS: "api/v1/voyages/teams", + SUB_URLS: { + IDEATIONS: "ideations", + IDEATION_VOTES: "ideation-votes", + SELECT: "select", + }, +} as const; diff --git a/src/modules/ideation/service/IdeationService.ts b/src/modules/ideation/service/IdeationService.ts index 72889b54e..4fde1f5c0 100644 --- a/src/modules/ideation/service/IdeationService.ts +++ b/src/modules/ideation/service/IdeationService.ts @@ -1,5 +1,5 @@ import { inject, injectable } from "tsyringe"; -import { revalidateTag } from "next/cache"; +import { IdeationUrls } from "@/modules/ideation/domain/IdeationUrls"; import type { AddIdeationBody, EditIdeationBody, @@ -19,168 +19,163 @@ import type { IdeationVoteProps, FinalizeIdeationProps, } from "@/modules/ideation/domain/IdeationProps"; -import { ApiClientRepository } from "@/modules/network/repositories/ApiClientRepository"; -import { getAccessToken } from "@/utils/getCookie"; import type { AsyncActionResponse } from "@/utils/handleAsync"; import { handleAsync } from "@/utils/handleAsync"; -import { CacheTag } from "@/utils/cacheTag"; import { TYPES } from "@/di/types"; +import { type IApiClientRepository } from "@/modules/network/domain/repositories/IApiClientRepository"; +/** + * Service class for handling ideation-related operations. + */ @injectable() export class IdeationService implements IIdeationService { constructor( - @inject(TYPES.ApiClientRepository) - private readonly apiClient: ApiClientRepository, + @inject(TYPES.IApiClientRepository) + private readonly apiClient: IApiClientRepository, ) {} + /** + * Adds a new ideation. + * + * @param {AddIdeationProps} props - The properties required to add an ideation. + * @returns {Promise>} - The response from the addIdeation method. + */ async addIdeation({ teamId, title, description, vision, baseUrl, + token, }: AddIdeationProps): Promise> { - const token = getAccessToken(); - const addIdeationAsync = () => this.apiClient.POST({ baseUrl, - url: `api/v1/voyages/teams/${teamId}/ideations`, + url: `${IdeationUrls.BASE_URL_TEAMS}/${teamId}/${IdeationUrls.SUB_URLS.IDEATIONS}`, token, cache: "default", payload: { title, description, vision }, }); - const [res, error] = await handleAsync(addIdeationAsync); - - if (res) { - revalidateTag(CacheTag.ideation); - } - - return [res, error]; + return await handleAsync(addIdeationAsync); } + /** + * Edits an existing ideation. + * + * @param {EditIdeationProps} props - The properties required to edit an ideation. + * @returns {Promise>} - The response from the editIdeation method. + */ async editIdeation({ ideationId, title, description, vision, baseUrl, + token, }: EditIdeationProps): Promise> { - const token = getAccessToken(); - const editIdeationAsync = () => this.apiClient.PATCH({ baseUrl, - url: `api/v1/voyages/ideations/${ideationId}`, + url: `${IdeationUrls.BASE_URL_IDEATIONS}/${ideationId}`, token, cache: "default", payload: { title, description, vision }, }); - const [res, error] = await handleAsync(editIdeationAsync); - - if (res) { - revalidateTag(CacheTag.ideation); - } - - return [res, error]; + return await handleAsync(editIdeationAsync); } + /** + * Deletes an existing ideation. + * + * @param {DeleteIdeationProps} props - The properties required to delete an ideation. + * @returns {Promise>} - The response from the deleteIdeation method. + */ async deleteIdeation({ ideationId, baseUrl, + token, }: DeleteIdeationProps): Promise< AsyncActionResponse > { - const token = getAccessToken(); - const deleteIdeationAsync = () => this.apiClient.DELETE({ baseUrl, - url: `api/v1/voyages/ideations/${ideationId}`, + url: `${IdeationUrls.BASE_URL_IDEATIONS}/${ideationId}`, token, cache: "default", }); - const [res, error] = await handleAsync(deleteIdeationAsync); - - if (res) { - revalidateTag(CacheTag.ideation); - } - - return [res, error]; + return await handleAsync(deleteIdeationAsync); } + /** + * Adds a vote to an ideation. + * + * @param {IdeationVoteProps} props - The properties required to add a vote to an ideation. + * @returns {Promise>} - The response from the addIdeationVote method. + */ async addIdeationVote({ ideationId, baseUrl, + token, }: IdeationVoteProps): Promise> { - const token = getAccessToken(); - const addIdeationVoteAsync = () => this.apiClient.POST({ baseUrl, - url: `api/v1/voyages/ideations/${ideationId}/ideation-votes`, + url: `${IdeationUrls.BASE_URL_IDEATIONS}/${ideationId}/${IdeationUrls.SUB_URLS.IDEATION_VOTES}`, token, cache: "default", }); - const [res, error] = await handleAsync(addIdeationVoteAsync); - - if (res) { - revalidateTag(CacheTag.ideation); - } - - return [res, error]; + return await handleAsync(addIdeationVoteAsync); } + /** + * Removes a vote from an ideation. + * + * @param {IdeationVoteProps} props - The properties required to remove a vote from an ideation. + * @returns {Promise>} - The response from the removeIdeationVote method. + */ async removeIdeationVote({ ideationId, baseUrl, + token, }: IdeationVoteProps): Promise> { - const token = getAccessToken(); - const removeIdeationVoteAsync = () => this.apiClient.DELETE({ baseUrl, - url: `api/v1/voyages/ideations/${ideationId}/ideation-votes`, + url: `${IdeationUrls.BASE_URL_IDEATIONS}/${ideationId}/${IdeationUrls.SUB_URLS.IDEATION_VOTES}`, token, cache: "default", }); - const [res, error] = await handleAsync(removeIdeationVoteAsync); - - if (res) { - revalidateTag(CacheTag.ideation); - } - - return [res, error]; + return await handleAsync(removeIdeationVoteAsync); } + /** + * Finalizes an ideation. + * + * @param {FinalizeIdeationProps} props - The properties required to finalize an ideation. + * @returns {Promise>} - The response from the finalizeIdeation method. + */ async finalizeIdeation({ teamId, ideationId, baseUrl, + token, }: FinalizeIdeationProps): Promise< AsyncActionResponse > { - const token = getAccessToken(); - const finalizeIdeationAsync = () => this.apiClient.POST({ baseUrl, - url: `api/v1/voyages/teams/${teamId}/ideations/${ideationId}/select`, + url: `${IdeationUrls.BASE_URL_TEAMS}/${teamId}/${IdeationUrls.SUB_URLS.IDEATIONS}/${ideationId}/${IdeationUrls.SUB_URLS.SELECT}`, token, cache: "default", }); - const [res, error] = await handleAsync(finalizeIdeationAsync); - - if (res) { - revalidateTag(CacheTag.ideation); - } - - return [res, error]; + return await handleAsync(finalizeIdeationAsync); } } diff --git a/src/modules/ideation/usecases/AddIdeationUseCase.ts b/src/modules/ideation/usecases/AddIdeationUseCase.ts new file mode 100644 index 000000000..4fb74afad --- /dev/null +++ b/src/modules/ideation/usecases/AddIdeationUseCase.ts @@ -0,0 +1,47 @@ +"use server"; + +import { inject } from "tsyringe"; +import { revalidateTag } from "next/cache"; +import type { AddIdeationProps } from "@/modules/ideation/domain/IdeationProps"; +import type { AddIdeationResponse } from "@/modules/ideation/domain/IdeationResponse"; +import { type IIdeationService } from "@/modules/ideation/domain/services/IIdeationService"; +import { TYPES } from "@/di/types"; +import type { AsyncActionResponse } from "@/utils/handleAsync"; +import { getAccessToken } from "@/utils/getCookie"; +import { CacheTag } from "@/utils/cacheTag"; + +export class AddIdeationUseCase { + constructor( + @inject(TYPES.IIdeationService) + private readonly ideationService: IIdeationService, + ) {} + + /** + * Executes the use case to add an ideation. + * + * @param {AddIdeationProps} props - The properties required to add an ideation. + * @returns {Promise>} - The response from the addIdeation method. + */ + async execute( + props: AddIdeationProps, + ): Promise> { + const token = getAccessToken(); + const baseUrl = process.env.NEXT_PUBLIC_API_URL; + + if (!baseUrl) { + throw new Error("Base URL is not defined"); + } + + const [res, error] = await this.ideationService.addIdeation({ + ...props, + token, + baseUrl, + }); + + if (res) { + revalidateTag(CacheTag.ideation); + } + + return [res, error]; + } +} diff --git a/src/modules/ideation/usecases/AddIdeationVoteUseCase.ts b/src/modules/ideation/usecases/AddIdeationVoteUseCase.ts new file mode 100644 index 000000000..3d5818fe9 --- /dev/null +++ b/src/modules/ideation/usecases/AddIdeationVoteUseCase.ts @@ -0,0 +1,47 @@ +"use server"; + +import { inject } from "tsyringe"; +import { revalidateTag } from "next/cache"; +import type { IdeationVoteProps } from "@/modules/ideation/domain/IdeationProps"; +import type { IdeationVoteResponse } from "@/modules/ideation/domain/IdeationResponse"; +import { type IIdeationService } from "@/modules/ideation/domain/services/IIdeationService"; +import { TYPES } from "@/di/types"; +import type { AsyncActionResponse } from "@/utils/handleAsync"; +import { getAccessToken } from "@/utils/getCookie"; +import { CacheTag } from "@/utils/cacheTag"; + +export class AddIdeationVoteUseCase { + constructor( + @inject(TYPES.IIdeationService) + private readonly ideationService: IIdeationService, + ) {} + + /** + * Executes the use case to add an ideation vote. + * + * @param {IdeationVoteProps} props - The properties required to add an ideation vote. + * @returns {Promise>} - The response from the addIdeationVote method. + */ + async execute( + props: IdeationVoteProps, + ): Promise> { + const token = getAccessToken(); + const baseUrl = process.env.NEXT_PUBLIC_API_URL; + + if (!baseUrl) { + throw new Error("Base URL is not defined"); + } + + const [res, error] = await this.ideationService.addIdeationVote({ + ...props, + token, + baseUrl, + }); + + if (res) { + revalidateTag(CacheTag.ideation); + } + + return [res, error]; + } +} diff --git a/src/modules/ideation/usecases/DeleteIdeationUseCase.ts b/src/modules/ideation/usecases/DeleteIdeationUseCase.ts new file mode 100644 index 000000000..73dce758b --- /dev/null +++ b/src/modules/ideation/usecases/DeleteIdeationUseCase.ts @@ -0,0 +1,47 @@ +"use server"; + +import { inject } from "tsyringe"; +import { revalidateTag } from "next/cache"; +import type { DeleteIdeationProps } from "@/modules/ideation/domain/IdeationProps"; +import type { DeleteIdeationResponse } from "@/modules/ideation/domain/IdeationResponse"; +import { type IIdeationService } from "@/modules/ideation/domain/services/IIdeationService"; +import { TYPES } from "@/di/types"; +import type { AsyncActionResponse } from "@/utils/handleAsync"; +import { getAccessToken } from "@/utils/getCookie"; +import { CacheTag } from "@/utils/cacheTag"; + +export class DeleteIdeationUseCase { + constructor( + @inject(TYPES.IIdeationService) + private readonly ideationService: IIdeationService, + ) {} + + /** + * Executes the use case to delete an ideation. + * + * @param {DeleteIdeationProps} props - The properties required to delete an ideation. + * @returns {Promise>} - The response from the deleteIdeation method. + */ + async execute( + props: DeleteIdeationProps, + ): Promise> { + const token = getAccessToken(); + const baseUrl = process.env.NEXT_PUBLIC_API_URL; + + if (!baseUrl) { + throw new Error("Base URL is not defined"); + } + + const [res, error] = await this.ideationService.deleteIdeation({ + ...props, + token, + baseUrl, + }); + + if (res) { + revalidateTag(CacheTag.ideation); + } + + return [res, error]; + } +} diff --git a/src/modules/ideation/usecases/EditIdeationUseCases.ts b/src/modules/ideation/usecases/EditIdeationUseCases.ts new file mode 100644 index 000000000..5e3cc72db --- /dev/null +++ b/src/modules/ideation/usecases/EditIdeationUseCases.ts @@ -0,0 +1,47 @@ +"use server"; + +import { inject } from "tsyringe"; +import { revalidateTag } from "next/cache"; +import type { EditIdeationProps } from "@/modules/ideation/domain/IdeationProps"; +import type { EditIdeationResponse } from "@/modules/ideation/domain/IdeationResponse"; +import { type IIdeationService } from "@/modules/ideation/domain/services/IIdeationService"; +import { TYPES } from "@/di/types"; +import type { AsyncActionResponse } from "@/utils/handleAsync"; +import { getAccessToken } from "@/utils/getCookie"; +import { CacheTag } from "@/utils/cacheTag"; + +export class EditIdeationUseCase { + constructor( + @inject(TYPES.IIdeationService) + private readonly ideationService: IIdeationService, + ) {} + + /** + * Executes the use case to edit an ideation. + * + * @param {EditIdeationProps} props - The properties required to edit an ideation. + * @returns {Promise>} - The response from the editIdeation method. + */ + async execute( + props: EditIdeationProps, + ): Promise> { + const token = getAccessToken(); + const baseUrl = process.env.NEXT_PUBLIC_API_URL; + + if (!baseUrl) { + throw new Error("Base URL is not defined"); + } + + const [res, error] = await this.ideationService.editIdeation({ + ...props, + token, + baseUrl, + }); + + if (res) { + revalidateTag(CacheTag.ideation); + } + + return [res, error]; + } +} diff --git a/src/modules/ideation/usecases/FinalizeIdeationUseCase.ts b/src/modules/ideation/usecases/FinalizeIdeationUseCase.ts new file mode 100644 index 000000000..bb16d0231 --- /dev/null +++ b/src/modules/ideation/usecases/FinalizeIdeationUseCase.ts @@ -0,0 +1,47 @@ +"use server"; + +import { inject } from "tsyringe"; +import { revalidateTag } from "next/cache"; +import type { FinalizeIdeationProps } from "@/modules/ideation/domain/IdeationProps"; +import type { FinalizeIdeationResponse } from "@/modules/ideation/domain/IdeationResponse"; +import { type IIdeationService } from "@/modules/ideation/domain/services/IIdeationService"; +import { TYPES } from "@/di/types"; +import type { AsyncActionResponse } from "@/utils/handleAsync"; +import { getAccessToken } from "@/utils/getCookie"; +import { CacheTag } from "@/utils/cacheTag"; + +export class FinalizeIdeationUseCase { + constructor( + @inject(TYPES.IIdeationService) + private readonly ideationService: IIdeationService, + ) {} + + /** + * Executes the use case to finalize an ideation. + * + * @param {FinalizeIdeationProps} props - The properties required to finalize an ideation. + * @returns {Promise>} - The response from the finalizeIdeation method. + */ + async execute( + props: FinalizeIdeationProps, + ): Promise> { + const token = getAccessToken(); + const baseUrl = process.env.NEXT_PUBLIC_API_URL; + + if (!baseUrl) { + throw new Error("Base URL is not defined"); + } + + const [res, error] = await this.ideationService.finalizeIdeation({ + ...props, + token, + baseUrl, + }); + + if (res) { + revalidateTag(CacheTag.ideation); + } + + return [res, error]; + } +} diff --git a/src/modules/ideation/usecases/RemoveIdeationVoteUseCase.ts b/src/modules/ideation/usecases/RemoveIdeationVoteUseCase.ts new file mode 100644 index 000000000..54f6a823e --- /dev/null +++ b/src/modules/ideation/usecases/RemoveIdeationVoteUseCase.ts @@ -0,0 +1,47 @@ +"use server"; + +import { inject } from "tsyringe"; +import { revalidateTag } from "next/cache"; +import type { IdeationVoteProps } from "@/modules/ideation/domain/IdeationProps"; +import type { IdeationVoteResponse } from "@/modules/ideation/domain/IdeationResponse"; +import { type IIdeationService } from "@/modules/ideation/domain/services/IIdeationService"; +import { TYPES } from "@/di/types"; +import type { AsyncActionResponse } from "@/utils/handleAsync"; +import { getAccessToken } from "@/utils/getCookie"; +import { CacheTag } from "@/utils/cacheTag"; + +export class RemoveIdeationVoteUseCase { + constructor( + @inject(TYPES.IIdeationService) + private readonly ideationService: IIdeationService, + ) {} + + /** + * Executes the use case to remove an ideation vote. + * + * @param {IdeationVoteProps} props - The properties required to remove an ideation vote. + * @returns {Promise>} - The response from the removeIdeationVote method. + */ + async execute( + props: IdeationVoteProps, + ): Promise> { + const token = getAccessToken(); + const baseUrl = process.env.NEXT_PUBLIC_API_URL; + + if (!baseUrl) { + throw new Error("Base URL is not defined"); + } + + const [res, error] = await this.ideationService.removeIdeationVote({ + ...props, + token, + baseUrl, + }); + + if (res) { + revalidateTag(CacheTag.ideation); + } + + return [res, error]; + } +} diff --git a/src/modules/network/repositories/ApiClientRepository.ts b/src/modules/network/repositories/ApiClientRepository.ts index e39cf1877..643897c6f 100644 --- a/src/modules/network/repositories/ApiClientRepository.ts +++ b/src/modules/network/repositories/ApiClientRepository.ts @@ -9,8 +9,20 @@ import type { } from "@/modules/network/domain/ApiParams"; import type { IApiClientRepository } from "@/modules/network/domain/repositories/IApiClientRepository"; +/** + * ApiClientRepository is a custom API client and is responsible for making HTTP requests. + * It implements the IApiClientRepository interface. + */ @injectable() export class ApiClientRepository implements IApiClientRepository { + /** + * Sends an HTTP request to the specified URL with the given parameters. + * + * @template T - The expected response type. + * @template P - The type of the payload. + * @param {SendRequestParams

} params - The parameters for the request. + * @returns {Promise} - The response from the API. + */ private async sendRequest({ method, baseUrl, @@ -45,6 +57,13 @@ export class ApiClientRepository implements IApiClientRepository { return (await res.json()) as T; } + /** + * Sends a GET request to the specified URL. + * + * @template T - The expected response type. + * @param {GetParams} params - The parameters for the GET request. + * @returns {Promise} - The response from the API. + */ async GET({ baseUrl, url, token, cache, tags }: GetParams): Promise { return this.sendRequest({ method: "GET", @@ -57,6 +76,14 @@ export class ApiClientRepository implements IApiClientRepository { }); } + /** + * Sends a POST request to the specified URL. + * + * @template X - The type of the payload. + * @template Y - The expected response type. + * @param {PostParams} params - The parameters for the POST request. + * @returns {Promise} - The response from the API. + */ async POST({ baseUrl, url, @@ -74,6 +101,14 @@ export class ApiClientRepository implements IApiClientRepository { }); } + /** + * Sends a PATCH request to the specified URL. + * + * @template X - The type of the payload. + * @template Y - The expected response type. + * @param {PatchParams} params - The parameters for the PATCH request. + * @returns {Promise} - The response from the API. + */ async PATCH({ baseUrl, url, @@ -91,6 +126,13 @@ export class ApiClientRepository implements IApiClientRepository { }); } + /** + * Sends a DELETE request to the specified URL. + * + * @template X - The expected response type. + * @param {DeleteParams} params - The parameters for the DELETE request. + * @returns {Promise} - The response from the API. + */ async DELETE({ baseUrl, url, token, cache }: DeleteParams): Promise { return this.sendRequest({ method: "DELETE", @@ -101,6 +143,14 @@ export class ApiClientRepository implements IApiClientRepository { }); } + /** + * Sends an unauthenticated POST request to the specified URL. + * + * @template X - The type of the payload. + * @template Y - The expected response type. + * @param {UnauthPostParams} params - The parameters for the unauthenticated POST request. + * @returns {Promise} - The response from the API. + */ async UNAUTHPOST({ baseUrl, url, From fe1455f67bb3f650552822d5cdd998b4c3408a05 Mon Sep 17 00:00:00 2001 From: Timothy Russo Date: Thu, 22 Aug 2024 09:00:32 +0200 Subject: [PATCH 08/31] feat: add injection utils --- package.json | 1 + src/di/injectables.ts | 30 +++++++++++++++++++ src/di/resolveInjection.ts | 9 ++++++ src/di/types.ts | 8 +++++ src/hooks/useInjection.ts | 18 +++++++++++ ...tionUseCases.ts => EditIdeationUseCase.ts} | 0 yarn.lock | 8 +++++ 7 files changed, 74 insertions(+) create mode 100644 src/di/injectables.ts create mode 100644 src/di/resolveInjection.ts create mode 100644 src/hooks/useInjection.ts rename src/modules/ideation/usecases/{EditIdeationUseCases.ts => EditIdeationUseCase.ts} (100%) diff --git a/package.json b/package.json index eec6214d3..1c6684ced 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "react-hook-form": "^7.46.2", "react-redux": "^8.1.2", "redux-persist": "^6.0.0", + "reflect-metadata": "^0.2.2", "tailwind-merge": "^2.0.0", "tsyringe": "^4.8.0", "zod": "^3.22.2" diff --git a/src/di/injectables.ts b/src/di/injectables.ts new file mode 100644 index 000000000..46e2376d4 --- /dev/null +++ b/src/di/injectables.ts @@ -0,0 +1,30 @@ +import { container } from "tsyringe"; +import { TYPES } from "./types"; +import type { AddIdeationUseCase } from "@/modules/ideation/usecases/AddIdeationUseCase"; +import type { AddIdeationVoteUseCase } from "@/modules/ideation/usecases/AddIdeationVoteUseCase"; +import type { DeleteIdeationUseCase } from "@/modules/ideation/usecases/DeleteIdeationUseCase"; +import type { EditIdeationUseCase } from "@/modules/ideation/usecases/EditIdeationUseCase"; +import type { FinalizeIdeationUseCase } from "@/modules/ideation/usecases/FinalizeIdeationUseCase"; +import type { RemoveIdeationVoteUseCase } from "@/modules/ideation/usecases/RemoveIdeationVoteUseCase"; + +export const injectables = { + /* Ideation */ + addIdeationUseCase: container.resolve( + TYPES.AddIdeationUseCase, + ), + addIdeationVoteUseCase: container.resolve( + TYPES.AddIdeationVoteUseCase, + ), + deleteIdeationUseCase: container.resolve( + TYPES.DeleteIdeationUseCase, + ), + editIdeationUseCase: container.resolve( + TYPES.EditIdeationUseCase, + ), + finalizeIdeationUseCase: container.resolve( + TYPES.FinalizeIdeationUseCase, + ), + removeIdeationVoteUseCase: container.resolve( + TYPES.RemoveIdeationVoteUseCase, + ), +} as const; diff --git a/src/di/resolveInjection.ts b/src/di/resolveInjection.ts new file mode 100644 index 000000000..31627165d --- /dev/null +++ b/src/di/resolveInjection.ts @@ -0,0 +1,9 @@ +import "reflect-metadata"; + +import { injectables } from "./injectables"; + +const resolveInjection = () => ({ + ...injectables, +}); + +export default resolveInjection; diff --git a/src/di/types.ts b/src/di/types.ts index 9f26a6e4c..3cbc9bb50 100644 --- a/src/di/types.ts +++ b/src/di/types.ts @@ -4,4 +4,12 @@ export const TYPES = { /* Services */ IIdeationService: Symbol.for("IIdeationService"), + + /* UseCases */ + AddIdeationUseCase: Symbol.for("AddIdeationUseCase"), + AddIdeationVoteUseCase: Symbol.for("AddIdeationVoteUseCase"), + DeleteIdeationUseCase: Symbol.for("DeleteIdeationUseCase"), + EditIdeationUseCase: Symbol.for("EditIdeationUseCase"), + FinalizeIdeationUseCase: Symbol.for("FinalizeIdeationUseCase"), + RemoveIdeationVoteUseCase: Symbol.for("RemoveIdeationVoteUseCase"), }; diff --git a/src/hooks/useInjection.ts b/src/hooks/useInjection.ts new file mode 100644 index 000000000..c23a03686 --- /dev/null +++ b/src/hooks/useInjection.ts @@ -0,0 +1,18 @@ +import "reflect-metadata"; + +import { useMemo } from "react"; + +import { injectables } from "@/di/injectables"; + +const useInjection = () => { + const injection = useMemo( + () => ({ + ...injectables, + }), + [], + ); + + return injection; +}; + +export default useInjection; diff --git a/src/modules/ideation/usecases/EditIdeationUseCases.ts b/src/modules/ideation/usecases/EditIdeationUseCase.ts similarity index 100% rename from src/modules/ideation/usecases/EditIdeationUseCases.ts rename to src/modules/ideation/usecases/EditIdeationUseCase.ts diff --git a/yarn.lock b/yarn.lock index 37f0d641f..b8060fe39 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6732,6 +6732,7 @@ __metadata: react-hook-form: "npm:^7.46.2" react-redux: "npm:^8.1.2" redux-persist: "npm:^6.0.0" + reflect-metadata: "npm:^0.2.2" storybook: "npm:^7.6.4" tailwind-merge: "npm:^2.0.0" tailwindcss: "npm:3.3.3" @@ -14224,6 +14225,13 @@ __metadata: languageName: node linkType: hard +"reflect-metadata@npm:^0.2.2": + version: 0.2.2 + resolution: "reflect-metadata@npm:0.2.2" + checksum: 1cd93a15ea291e420204955544637c264c216e7aac527470e393d54b4bb075f10a17e60d8168ec96600c7e0b9fcc0cb0bb6e91c3fbf5b0d8c9056f04e6ac1ec2 + languageName: node + linkType: hard + "reflect.getprototypeof@npm:^1.0.4": version: 1.0.4 resolution: "reflect.getprototypeof@npm:1.0.4" From 77393e3f638c65f8c43b1bda5031c080b761383c Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Mon, 2 Sep 2024 19:03:28 -0400 Subject: [PATCH 09/31] rest api module implementation --- src/di/config.ts | 8 +- .../repositories/IApiClientRepository.ts | 19 -- .../repositories/ApiClientRepository.ts | 169 ------------------ .../domain/entities/requestOptions.ts | 5 + .../domain/entities/restApiParams.ts} | 25 +-- .../domain/ports/IRestApiRepository.ts | 19 ++ .../adapters/NextJsRestApiRepository.ts | 152 ++++++++++++++++ 7 files changed, 186 insertions(+), 211 deletions(-) delete mode 100644 src/modules/network/domain/repositories/IApiClientRepository.ts delete mode 100644 src/modules/network/repositories/ApiClientRepository.ts create mode 100644 src/modules/rest-api/domain/entities/requestOptions.ts rename src/modules/{network/domain/ApiParams.ts => rest-api/domain/entities/restApiParams.ts} (51%) create mode 100644 src/modules/rest-api/domain/ports/IRestApiRepository.ts create mode 100644 src/modules/rest-api/infrastructure/adapters/NextJsRestApiRepository.ts diff --git a/src/di/config.ts b/src/di/config.ts index 28094cfad..8a64ac9b6 100644 --- a/src/di/config.ts +++ b/src/di/config.ts @@ -1,8 +1,8 @@ import { container } from "tsyringe"; import { TYPES } from "./types"; -import type { IApiClientRepository } from "@/modules/network/domain/repositories/IApiClientRepository"; -import { ApiClientRepository } from "@/modules/network/repositories/ApiClientRepository"; +import type { IRestApiRepository } from "@/modules/api/domain/repositories/IRestApiRepository"; +import { RestApiRepository } from "@/modules/api/repositories/RestApiRepository"; import type { IIdeationService } from "@/modules/ideation/domain/services/IIdeationService"; import { IdeationService } from "@/modules/ideation/service/IdeationService"; @@ -12,8 +12,8 @@ container.register(TYPES.IIdeationService, { }); /* Repositories */ -container.register(TYPES.IApiClientRepository, { - useClass: ApiClientRepository, +container.register(TYPES.IApiClientRepository, { + useClass: RestApiRepository, }); export default container; diff --git a/src/modules/network/domain/repositories/IApiClientRepository.ts b/src/modules/network/domain/repositories/IApiClientRepository.ts deleted file mode 100644 index 53bc5d704..000000000 --- a/src/modules/network/domain/repositories/IApiClientRepository.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type { - DeleteParams, - GetParams, - PatchParams, - PostParams, - UnauthPostParams, -} from "@/modules/network/domain/ApiParams"; - -export interface IApiClientRepository { - GET(params: GetParams): Promise; - - POST(params: PostParams): Promise; - - PATCH(params: PatchParams): Promise; - - DELETE(params: DeleteParams): Promise; - - UNAUTHPOST(params: UnauthPostParams): Promise; -} diff --git a/src/modules/network/repositories/ApiClientRepository.ts b/src/modules/network/repositories/ApiClientRepository.ts deleted file mode 100644 index 643897c6f..000000000 --- a/src/modules/network/repositories/ApiClientRepository.ts +++ /dev/null @@ -1,169 +0,0 @@ -import { injectable } from "tsyringe"; -import type { - DeleteParams, - GetParams, - PatchParams, - PostParams, - SendRequestParams, - UnauthPostParams, -} from "@/modules/network/domain/ApiParams"; -import type { IApiClientRepository } from "@/modules/network/domain/repositories/IApiClientRepository"; - -/** - * ApiClientRepository is a custom API client and is responsible for making HTTP requests. - * It implements the IApiClientRepository interface. - */ -@injectable() -export class ApiClientRepository implements IApiClientRepository { - /** - * Sends an HTTP request to the specified URL with the given parameters. - * - * @template T - The expected response type. - * @template P - The type of the payload. - * @param {SendRequestParams

} params - The parameters for the request. - * @returns {Promise} - The response from the API. - */ - private async sendRequest({ - method, - baseUrl, - url, - token, - cache, - payload, - tags, - }: SendRequestParams

): Promise { - const headers: Record = { - "Content-Type": "application/json", - }; - - if (token) { - headers.Cookie = token; - } - - const options: RequestInit = { - method, - headers, - cache, - body: payload ? JSON.stringify(payload) : undefined, - next: tags ? { tags: [tags] } : undefined, - }; - - const res = await fetch(`${baseUrl}/${url}`, options); - - if (!res.ok) { - throw new Error(`Status code: ${res.status}, Message: ${res.statusText}`); - } - - return (await res.json()) as T; - } - - /** - * Sends a GET request to the specified URL. - * - * @template T - The expected response type. - * @param {GetParams} params - The parameters for the GET request. - * @returns {Promise} - The response from the API. - */ - async GET({ baseUrl, url, token, cache, tags }: GetParams): Promise { - return this.sendRequest({ - method: "GET", - baseUrl, - url, - token, - cache, - payload: undefined, - tags, - }); - } - - /** - * Sends a POST request to the specified URL. - * - * @template X - The type of the payload. - * @template Y - The expected response type. - * @param {PostParams} params - The parameters for the POST request. - * @returns {Promise} - The response from the API. - */ - async POST({ - baseUrl, - url, - token, - cache, - payload, - }: PostParams): Promise { - return this.sendRequest({ - method: "POST", - baseUrl, - url, - token, - cache, - payload, - }); - } - - /** - * Sends a PATCH request to the specified URL. - * - * @template X - The type of the payload. - * @template Y - The expected response type. - * @param {PatchParams} params - The parameters for the PATCH request. - * @returns {Promise} - The response from the API. - */ - async PATCH({ - baseUrl, - url, - token, - cache, - payload, - }: PatchParams): Promise { - return this.sendRequest({ - method: "PATCH", - baseUrl, - url, - token, - cache, - payload, - }); - } - - /** - * Sends a DELETE request to the specified URL. - * - * @template X - The expected response type. - * @param {DeleteParams} params - The parameters for the DELETE request. - * @returns {Promise} - The response from the API. - */ - async DELETE({ baseUrl, url, token, cache }: DeleteParams): Promise { - return this.sendRequest({ - method: "DELETE", - baseUrl, - url, - token, - cache, - }); - } - - /** - * Sends an unauthenticated POST request to the specified URL. - * - * @template X - The type of the payload. - * @template Y - The expected response type. - * @param {UnauthPostParams} params - The parameters for the unauthenticated POST request. - * @returns {Promise} - The response from the API. - */ - async UNAUTHPOST({ - baseUrl, - url, - cache, - payload, - }: UnauthPostParams): Promise { - return this.sendRequest({ - method: "POST", - baseUrl, - url, - token: null, - cache, - payload, - }); - } -} diff --git a/src/modules/rest-api/domain/entities/requestOptions.ts b/src/modules/rest-api/domain/entities/requestOptions.ts new file mode 100644 index 000000000..865d13ff3 --- /dev/null +++ b/src/modules/rest-api/domain/entities/requestOptions.ts @@ -0,0 +1,5 @@ +export interface RequestOptions { + token?: string; + cache?: RequestCache; + tags?: string; +} diff --git a/src/modules/network/domain/ApiParams.ts b/src/modules/rest-api/domain/entities/restApiParams.ts similarity index 51% rename from src/modules/network/domain/ApiParams.ts rename to src/modules/rest-api/domain/entities/restApiParams.ts index bc1caabe2..3f368fda7 100644 --- a/src/modules/network/domain/ApiParams.ts +++ b/src/modules/rest-api/domain/entities/restApiParams.ts @@ -1,47 +1,34 @@ -export interface SendRequestParams

{ - method: string; - baseUrl: string; - url: string; - token: string | null; - cache: RequestCache; - payload?: P; - tags?: string; -} +import { type RequestOptions } from "./requestOptions"; export interface GetParams { baseUrl: string; url: string; - token: string; - cache: RequestCache; - tags?: string; + options: RequestOptions; } export interface PostParams { baseUrl: string; url: string; - token: string; - cache: RequestCache; + options: RequestOptions; payload?: X; } export interface PatchParams { baseUrl: string; url: string; - token: string; - cache: RequestCache; + options: RequestOptions; payload: X; } export interface DeleteParams { baseUrl: string; url: string; - token: string; - cache: RequestCache; + options: RequestOptions; } export interface UnauthPostParams { baseUrl: string; url: string; - cache: RequestCache; + options: RequestOptions; payload: X; } diff --git a/src/modules/rest-api/domain/ports/IRestApiRepository.ts b/src/modules/rest-api/domain/ports/IRestApiRepository.ts new file mode 100644 index 000000000..fe6271fb4 --- /dev/null +++ b/src/modules/rest-api/domain/ports/IRestApiRepository.ts @@ -0,0 +1,19 @@ +import type { + DeleteParams, + GetParams, + PatchParams, + PostParams, + UnauthPostParams, +} from "@/modules/rest-api/domain/entities/restApiParams"; + +export interface IRestApiRepository { + get(params: GetParams): Promise; + + post(params: PostParams): Promise; + + patch(params: PatchParams): Promise; + + delete(params: DeleteParams): Promise; + + unauthpost(params: UnauthPostParams): Promise; +} diff --git a/src/modules/rest-api/infrastructure/adapters/NextJsRestApiRepository.ts b/src/modules/rest-api/infrastructure/adapters/NextJsRestApiRepository.ts new file mode 100644 index 000000000..be0303d09 --- /dev/null +++ b/src/modules/rest-api/infrastructure/adapters/NextJsRestApiRepository.ts @@ -0,0 +1,152 @@ +import { type IRestApiRepository } from "@/modules/rest-api/domain/ports/IRestApiRepository"; +import type { + DeleteParams, + PatchParams, + PostParams, + UnauthPostParams, + GetParams, +} from "@/modules/rest-api/domain/entities/restApiParams"; +import { type RequestOptions } from "@/modules/rest-api/domain/entities/requestOptions"; + +type NextJsAuthRequestOptions = Required< + Pick +> & + Omit; + +type NextJsUnAuthRequestionOptions = Required> & + Omit; + +interface NextJsGetParams extends Omit { + options: NextJsAuthRequestOptions; +} + +interface NextJsPostParams extends Omit, "options"> { + options: NextJsAuthRequestOptions; +} + +interface NextJsPatchParams extends Omit, "options"> { + options: NextJsAuthRequestOptions; +} + +interface NextJsDeleteParams extends Omit { + options: NextJsAuthRequestOptions; +} + +interface NextJsUnauthParams extends Omit, "options"> { + options: NextJsUnAuthRequestionOptions; +} + +export class NextJsRestApiRepository implements IRestApiRepository { + private baseUrl: string; + + constructor(baseUrl: string) { + this.baseUrl = baseUrl; + } + + async get({ url, options }: NextJsGetParams): Promise { + const { token, cache, tags } = options; + + const res = await fetch(`${this.baseUrl}/${url}`, { + method: "GET", + headers: { + Cookie: token, + }, + cache, + next: { + tags: [tags ?? ""], + }, + }); + + if (!res.ok) { + throw new Error(`Status code: ${res.status}, Message: ${res.statusText}`); + } + + return res.json() as Promise; + } + + async post({ url, options, payload }: NextJsPostParams): Promise { + const { token, cache } = options; + + const res = await fetch(`${this.baseUrl}/${url}`, { + method: "POST", + headers: { + "Content-Type": "application/json", + Cookie: token, + }, + body: payload ? JSON.stringify(payload) : undefined, + cache, + }); + + if (!res.ok) { + throw new Error(`Status code: ${res.status}, Message: ${res.statusText}`); + } + + return res.json() as Promise; + } + + async patch({ + url, + options, + payload, + }: NextJsPatchParams): Promise { + const { token, cache } = options; + + const res = await fetch(`${this.baseUrl}/${url}`, { + method: "PATCH", + headers: { + "Content-Type": "application/json", + Cookie: token, + }, + body: JSON.stringify(payload), + cache, + }); + + if (!res.ok) { + throw new Error(`Status code: ${res.status}, Message: ${res.statusText}`); + } + + return res.json() as Promise; + } + + async delete({ url, options }: NextJsDeleteParams): Promise { + const { token, cache } = options; + + const res = await fetch(`${this.baseUrl}/${url}`, { + method: "DELETE", + headers: { + "Content-Type": "application/json", + Cookie: token, + }, + cache, + }); + + if (!res.ok) { + throw new Error(`Status code: ${res.status}, Message: ${res.statusText}`); + } + + return res.json() as Promise; + } + + async unauthpost({ + url, + options, + payload, + }: NextJsUnauthParams): Promise { + const { cache } = options; + + const res = await fetch(`${this.baseUrl}/${url}`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(payload), + cache, + }); + + if (!res.ok) { + throw new Error(`Status code: ${res.status}, Message: ${res.statusText}`); + } + + return res.json() as Promise; + } +} From e8800cf5225eda4eb32661b5777b5f68de47093c Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Mon, 2 Sep 2024 20:11:44 -0400 Subject: [PATCH 10/31] add dtos --- .../ideation/domain/dtos/common.dto.ts | 12 ++++++++++ .../ideation/domain/dtos/request.dto.ts | 19 +++++++++++++++ .../ideation/domain/dtos/response.dto.ts | 24 +++++++++++++++++++ .../ideation/domain/entities/Ideation.ts | 17 +++++++++++++ .../ideation/domain/entities/IdeationVotes.ts | 13 ++++++++++ ...tApiRepository.ts => restApiRepository.ts} | 2 +- .../adapters/NextJsRestApiRepository.ts | 12 +++++----- 7 files changed, 92 insertions(+), 7 deletions(-) create mode 100644 src/modules/ideation/domain/dtos/common.dto.ts create mode 100644 src/modules/ideation/domain/dtos/request.dto.ts create mode 100644 src/modules/ideation/domain/dtos/response.dto.ts create mode 100644 src/modules/ideation/domain/entities/Ideation.ts create mode 100644 src/modules/ideation/domain/entities/IdeationVotes.ts rename src/modules/rest-api/domain/ports/{IRestApiRepository.ts => restApiRepository.ts} (91%) diff --git a/src/modules/ideation/domain/dtos/common.dto.ts b/src/modules/ideation/domain/dtos/common.dto.ts new file mode 100644 index 000000000..5283ba52c --- /dev/null +++ b/src/modules/ideation/domain/dtos/common.dto.ts @@ -0,0 +1,12 @@ +import { type Ideation } from "@/modules/ideation/domain/entities/Ideation"; + +export type IdeationBodyDto = Pick< + Ideation, + "title" | "description" | "vision" +>; + +// IdeationProps +export interface IdeationRequestDto { + teamId: number; + ideationId: number; +} diff --git a/src/modules/ideation/domain/dtos/request.dto.ts b/src/modules/ideation/domain/dtos/request.dto.ts new file mode 100644 index 000000000..da26edfde --- /dev/null +++ b/src/modules/ideation/domain/dtos/request.dto.ts @@ -0,0 +1,19 @@ +import { type IdeationRequestDto, type IdeationBodyDto } from "./common.dto"; + +interface AddIdeationBodyDto extends IdeationBodyDto {} + +interface EditIdeationBodyDto extends Partial {} + +interface AddIdeationRequestDto + extends Pick, + IdeationBodyDto {} + +type EditIdeationRequestDto = EditIdeationBodyDto & + Omit; + +type DeleteIdeationRequestDto = Omit; + +type IdeationVoteRequestDto = Omit; +type FetchIdeationsRequestDto = Pick; + +interface FinalizeIdeationRequestDto extends IdeationRequestDto {} diff --git a/src/modules/ideation/domain/dtos/response.dto.ts b/src/modules/ideation/domain/dtos/response.dto.ts new file mode 100644 index 000000000..aadab9648 --- /dev/null +++ b/src/modules/ideation/domain/dtos/response.dto.ts @@ -0,0 +1,24 @@ +import { type IdeationBodyDto } from "./common.dto"; + +interface IdeationResponseDto { + id: number; + voyageTeamMemberId: number; + createdAt: Date; + updatedAt: Date; +} + +interface AddIdeationResponseDto extends IdeationResponseDto, IdeationBodyDto {} + +interface EditIdeationResponseDto extends AddIdeationResponseDto {} + +interface DeleteIdeationResponseDto extends AddIdeationResponseDto {} + +interface FinalizeIdeationResponseDto + extends IdeationResponseDto, + IdeationBodyDto { + isSelected: boolean; +} + +interface IdeationVoteResponseDto extends IdeationResponseDto { + projectIdeaId: number; +} diff --git a/src/modules/ideation/domain/entities/Ideation.ts b/src/modules/ideation/domain/entities/Ideation.ts new file mode 100644 index 000000000..dcd539d59 --- /dev/null +++ b/src/modules/ideation/domain/entities/Ideation.ts @@ -0,0 +1,17 @@ +import { type IdeationVotes } from "./IdeationVotes"; +import { type VoyageMember } from "@/store/features/ideation/ideationSlice"; + +// importing the voyage member from the store for now but it would ideally be imported from a different domain in modules folder +export interface Ideation { + id: number; + title: string; + description: string; + vision: string; + isSelected: boolean; + createdAt: Date; + updatedAt: Date; + contributedBy: { + member: VoyageMember; + }; + projectIdeaVotes: IdeationVotes[]; +} diff --git a/src/modules/ideation/domain/entities/IdeationVotes.ts b/src/modules/ideation/domain/entities/IdeationVotes.ts new file mode 100644 index 000000000..2b40962c4 --- /dev/null +++ b/src/modules/ideation/domain/entities/IdeationVotes.ts @@ -0,0 +1,13 @@ +import { type VoyageMember } from "@/store/features/ideation/ideationSlice"; + +// importing the voyage member from the store for now but it would ideally be imported from a different domain in modules folder +export interface IdeationVotes { + id: number; + voyageTeamMemberId: number; + projectIdeaId: number; + createdAt: Date; + updatedAt: Date; + votedBy: { + member: VoyageMember; + }; +} diff --git a/src/modules/rest-api/domain/ports/IRestApiRepository.ts b/src/modules/rest-api/domain/ports/restApiRepository.ts similarity index 91% rename from src/modules/rest-api/domain/ports/IRestApiRepository.ts rename to src/modules/rest-api/domain/ports/restApiRepository.ts index fe6271fb4..07da834cf 100644 --- a/src/modules/rest-api/domain/ports/IRestApiRepository.ts +++ b/src/modules/rest-api/domain/ports/restApiRepository.ts @@ -6,7 +6,7 @@ import type { UnauthPostParams, } from "@/modules/rest-api/domain/entities/restApiParams"; -export interface IRestApiRepository { +export interface RestApiRepository { get(params: GetParams): Promise; post(params: PostParams): Promise; diff --git a/src/modules/rest-api/infrastructure/adapters/NextJsRestApiRepository.ts b/src/modules/rest-api/infrastructure/adapters/NextJsRestApiRepository.ts index be0303d09..727510cc1 100644 --- a/src/modules/rest-api/infrastructure/adapters/NextJsRestApiRepository.ts +++ b/src/modules/rest-api/infrastructure/adapters/NextJsRestApiRepository.ts @@ -1,4 +1,4 @@ -import { type IRestApiRepository } from "@/modules/rest-api/domain/ports/IRestApiRepository"; +import { type RestApiRepository } from "@/modules/rest-api/domain/ports/restApiRepository"; import type { DeleteParams, PatchParams, @@ -17,26 +17,26 @@ type NextJsUnAuthRequestionOptions = Required> & Omit; interface NextJsGetParams extends Omit { - options: NextJsAuthRequestOptions; + options: NextJsAuthRequestOptions; // Enforce required options } interface NextJsPostParams extends Omit, "options"> { - options: NextJsAuthRequestOptions; + options: NextJsAuthRequestOptions; // Enforce required options } interface NextJsPatchParams extends Omit, "options"> { - options: NextJsAuthRequestOptions; + options: NextJsAuthRequestOptions; // Enforce required options } interface NextJsDeleteParams extends Omit { - options: NextJsAuthRequestOptions; + options: NextJsAuthRequestOptions; // Enforce required options } interface NextJsUnauthParams extends Omit, "options"> { options: NextJsUnAuthRequestionOptions; } -export class NextJsRestApiRepository implements IRestApiRepository { +export class NextJsRestApiRepository implements RestApiRepository { private baseUrl: string; constructor(baseUrl: string) { From 75aab331014b31360a19645f0ff3260f5816df4e Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Mon, 2 Sep 2024 21:01:22 -0400 Subject: [PATCH 11/31] add ideation api repository implementation --- src/di/types.ts | 2 +- .../{domain => constants}/IdeationUrls.ts | 0 .../ideation/domain/AddIdeationType.ts | 3 - src/modules/ideation/domain/IdeationBody.ts | 9 - src/modules/ideation/domain/IdeationProps.ts | 33 ---- .../ideation/domain/IdeationResponse.ts | 24 --- .../ideation/domain/IdeationWithoutTeamId.ts | 3 - .../ideation/domain/dtos/request.dto.ts | 35 +++- .../ideation/domain/dtos/response.dto.ts | 18 +- .../domain/ports/ideationApiRepository.ts | 36 ++++ .../domain/services/IIdeationService.ts | 36 ---- .../adapters/ideationApiRepositoryImpl.ts | 131 +++++++++++++ .../ideation/service/IdeationService.ts | 181 ------------------ .../rest-api/domain/entities/restApiParams.ts | 5 - .../domain/ports/restApiRepository.ts | 4 +- 15 files changed, 205 insertions(+), 315 deletions(-) rename src/modules/ideation/{domain => constants}/IdeationUrls.ts (100%) delete mode 100644 src/modules/ideation/domain/AddIdeationType.ts delete mode 100644 src/modules/ideation/domain/IdeationBody.ts delete mode 100644 src/modules/ideation/domain/IdeationProps.ts delete mode 100644 src/modules/ideation/domain/IdeationResponse.ts delete mode 100644 src/modules/ideation/domain/IdeationWithoutTeamId.ts create mode 100644 src/modules/ideation/domain/ports/ideationApiRepository.ts delete mode 100644 src/modules/ideation/domain/services/IIdeationService.ts create mode 100644 src/modules/ideation/infrastructure/adapters/ideationApiRepositoryImpl.ts delete mode 100644 src/modules/ideation/service/IdeationService.ts diff --git a/src/di/types.ts b/src/di/types.ts index 3cbc9bb50..6a4f3ee76 100644 --- a/src/di/types.ts +++ b/src/di/types.ts @@ -1,6 +1,6 @@ export const TYPES = { /* Repositories */ - IApiClientRepository: Symbol.for("IApiClientRepository"), + RestApiRepository: Symbol.for("RestApiRepository"), /* Services */ IIdeationService: Symbol.for("IIdeationService"), diff --git a/src/modules/ideation/domain/IdeationUrls.ts b/src/modules/ideation/constants/IdeationUrls.ts similarity index 100% rename from src/modules/ideation/domain/IdeationUrls.ts rename to src/modules/ideation/constants/IdeationUrls.ts diff --git a/src/modules/ideation/domain/AddIdeationType.ts b/src/modules/ideation/domain/AddIdeationType.ts deleted file mode 100644 index d9d4367e8..000000000 --- a/src/modules/ideation/domain/AddIdeationType.ts +++ /dev/null @@ -1,3 +0,0 @@ -import type { IdeationProps } from "./IdeationProps"; - -export type AddIdeationType = Pick; diff --git a/src/modules/ideation/domain/IdeationBody.ts b/src/modules/ideation/domain/IdeationBody.ts deleted file mode 100644 index 599f639c8..000000000 --- a/src/modules/ideation/domain/IdeationBody.ts +++ /dev/null @@ -1,9 +0,0 @@ -export interface IdeationBody { - title: string; - description: string; - vision: string; -} - -export interface AddIdeationBody extends IdeationBody {} - -export interface EditIdeationBody extends Partial {} diff --git a/src/modules/ideation/domain/IdeationProps.ts b/src/modules/ideation/domain/IdeationProps.ts deleted file mode 100644 index a0c71d07f..000000000 --- a/src/modules/ideation/domain/IdeationProps.ts +++ /dev/null @@ -1,33 +0,0 @@ -import type { AddIdeationType } from "./AddIdeationType"; -import type { EditIdeationBody, IdeationBody } from "./IdeationBody"; -import type { IdeationWithoutTeamId } from "./IdeationWithoutTeamId"; - -export interface IdeationProps { - teamId: number; - ideationId: number; -} - -export interface AddIdeationProps extends AddIdeationType, IdeationBody { - baseUrl: string; - token: string; -} - -export type EditIdeationProps = EditIdeationBody & - IdeationWithoutTeamId & { baseUrl: string; token: string }; - -export type DeleteIdeationProps = IdeationWithoutTeamId & { - baseUrl: string; - token: string; -}; - -export type IdeationVoteProps = IdeationWithoutTeamId & { - baseUrl: string; - token: string; -}; - -export type FetchIdeationsProps = Pick; - -export interface FinalizeIdeationProps extends IdeationProps { - baseUrl: string; - token: string; -} diff --git a/src/modules/ideation/domain/IdeationResponse.ts b/src/modules/ideation/domain/IdeationResponse.ts deleted file mode 100644 index 484103645..000000000 --- a/src/modules/ideation/domain/IdeationResponse.ts +++ /dev/null @@ -1,24 +0,0 @@ -import type { IdeationBody } from "./IdeationBody"; - -export interface IdeationResponse { - id: number; - voyageTeamMemberId: number; - createdAt: Date; - updatedAt: Date; -} - -export interface AddIdeationResponse extends IdeationResponse, IdeationBody {} - -export interface EditIdeationResponse extends AddIdeationResponse {} - -export interface DeleteIdeationResponse extends AddIdeationResponse {} - -export interface FinalizeIdeationResponse - extends IdeationResponse, - IdeationBody { - isSelected: boolean; -} - -export interface IdeationVoteResponse extends IdeationResponse { - projectIdeaId: number; -} diff --git a/src/modules/ideation/domain/IdeationWithoutTeamId.ts b/src/modules/ideation/domain/IdeationWithoutTeamId.ts deleted file mode 100644 index b069f039d..000000000 --- a/src/modules/ideation/domain/IdeationWithoutTeamId.ts +++ /dev/null @@ -1,3 +0,0 @@ -import type { IdeationProps } from "./IdeationProps"; - -export type IdeationWithoutTeamId = Omit; diff --git a/src/modules/ideation/domain/dtos/request.dto.ts b/src/modules/ideation/domain/dtos/request.dto.ts index da26edfde..d505b2a99 100644 --- a/src/modules/ideation/domain/dtos/request.dto.ts +++ b/src/modules/ideation/domain/dtos/request.dto.ts @@ -1,19 +1,34 @@ import { type IdeationRequestDto, type IdeationBodyDto } from "./common.dto"; -interface AddIdeationBodyDto extends IdeationBodyDto {} +export interface AddIdeationBodyDto extends IdeationBodyDto {} -interface EditIdeationBodyDto extends Partial {} +export interface EditIdeationBodyDto extends Partial {} -interface AddIdeationRequestDto +export interface AddIdeationRequestDto extends Pick, - IdeationBodyDto {} + IdeationBodyDto { + cache?: RequestCache; + token?: string; +} -type EditIdeationRequestDto = EditIdeationBodyDto & - Omit; +export type EditIdeationRequestDto = EditIdeationBodyDto & + Omit & { + cache?: RequestCache; + token?: string; + }; -type DeleteIdeationRequestDto = Omit; +export type DeleteIdeationRequestDto = Omit & { + cache?: RequestCache; + token?: string; +}; -type IdeationVoteRequestDto = Omit; -type FetchIdeationsRequestDto = Pick; +export type IdeationVoteRequestDto = Omit & { + cache?: RequestCache; + token?: string; +}; +export type FetchIdeationsRequestDto = Pick; -interface FinalizeIdeationRequestDto extends IdeationRequestDto {} +export interface FinalizeIdeationRequestDto extends IdeationRequestDto { + cache?: RequestCache; + token?: string; +} diff --git a/src/modules/ideation/domain/dtos/response.dto.ts b/src/modules/ideation/domain/dtos/response.dto.ts index aadab9648..7157fa3b3 100644 --- a/src/modules/ideation/domain/dtos/response.dto.ts +++ b/src/modules/ideation/domain/dtos/response.dto.ts @@ -7,18 +7,20 @@ interface IdeationResponseDto { updatedAt: Date; } -interface AddIdeationResponseDto extends IdeationResponseDto, IdeationBodyDto {} +export interface AddIdeationResponseDto + extends IdeationResponseDto, + IdeationBodyDto {} + +export interface EditIdeationResponseDto extends AddIdeationResponseDto {} -interface EditIdeationResponseDto extends AddIdeationResponseDto {} +export interface DeleteIdeationResponseDto extends AddIdeationResponseDto {} -interface DeleteIdeationResponseDto extends AddIdeationResponseDto {} +export interface IdeationVoteResponseDto extends IdeationResponseDto { + projectIdeaId: number; +} -interface FinalizeIdeationResponseDto +export interface FinalizeIdeationResponseDto extends IdeationResponseDto, IdeationBodyDto { isSelected: boolean; } - -interface IdeationVoteResponseDto extends IdeationResponseDto { - projectIdeaId: number; -} diff --git a/src/modules/ideation/domain/ports/ideationApiRepository.ts b/src/modules/ideation/domain/ports/ideationApiRepository.ts new file mode 100644 index 000000000..c3f55bb91 --- /dev/null +++ b/src/modules/ideation/domain/ports/ideationApiRepository.ts @@ -0,0 +1,36 @@ +import type { + AddIdeationRequestDto, + DeleteIdeationRequestDto, + EditIdeationRequestDto, + FinalizeIdeationRequestDto, + IdeationVoteRequestDto, +} from "@/modules/ideation/domain/dtos/request.dto"; + +import type { + AddIdeationResponseDto, + DeleteIdeationResponseDto, + EditIdeationResponseDto, + FinalizeIdeationResponseDto, + IdeationVoteResponseDto, +} from "@/modules/ideation/domain/dtos/response.dto"; + +export interface IdeationApiRepository { + addIdeation: ( + props: AddIdeationRequestDto, + ) => Promise; + editIdeation: ( + props: EditIdeationRequestDto, + ) => Promise; + deleteIdeation: ( + props: DeleteIdeationRequestDto, + ) => Promise; + addIdeationVote: ( + props: IdeationVoteRequestDto, + ) => Promise; + removeIdeationVote: ( + props: IdeationVoteRequestDto, + ) => Promise; + finalizeIdeation: ( + props: FinalizeIdeationRequestDto, + ) => Promise; +} diff --git a/src/modules/ideation/domain/services/IIdeationService.ts b/src/modules/ideation/domain/services/IIdeationService.ts deleted file mode 100644 index 618f4cdad..000000000 --- a/src/modules/ideation/domain/services/IIdeationService.ts +++ /dev/null @@ -1,36 +0,0 @@ -import type { - AddIdeationProps, - DeleteIdeationProps, - EditIdeationProps, - FinalizeIdeationProps, - IdeationVoteProps, -} from "@/modules/ideation/domain/IdeationProps"; -import type { - AddIdeationResponse, - DeleteIdeationResponse, - EditIdeationResponse, - FinalizeIdeationResponse, - IdeationVoteResponse, -} from "@/modules/ideation/domain/IdeationResponse"; -import type { AsyncActionResponse } from "@/utils/handleAsync"; - -export interface IIdeationService { - addIdeation: ( - props: AddIdeationProps, - ) => Promise>; - editIdeation: ( - props: EditIdeationProps, - ) => Promise>; - deleteIdeation: ( - props: DeleteIdeationProps, - ) => Promise>; - addIdeationVote: ( - props: IdeationVoteProps, - ) => Promise>; - removeIdeationVote: ( - props: IdeationVoteProps, - ) => Promise>; - finalizeIdeation: ( - props: FinalizeIdeationProps, - ) => Promise>; -} diff --git a/src/modules/ideation/infrastructure/adapters/ideationApiRepositoryImpl.ts b/src/modules/ideation/infrastructure/adapters/ideationApiRepositoryImpl.ts new file mode 100644 index 000000000..ea7eed9b7 --- /dev/null +++ b/src/modules/ideation/infrastructure/adapters/ideationApiRepositoryImpl.ts @@ -0,0 +1,131 @@ +import { inject, injectable } from "tsyringe"; +import { IdeationUrls } from "@/modules/ideation/constants/IdeationUrls"; +import { TYPES } from "@/di/types"; +import { type IdeationApiRepository } from "@/modules/ideation/domain/ports/ideationApiRepository"; +import { type RestApiRepository } from "@/modules/rest-api/domain/ports/restApiRepository"; +import type { + AddIdeationBodyDto, + AddIdeationRequestDto, + DeleteIdeationRequestDto, + EditIdeationBodyDto, + EditIdeationRequestDto, + FinalizeIdeationRequestDto, + IdeationVoteRequestDto, +} from "@/modules/ideation/domain/dtos/request.dto"; +import type { + EditIdeationResponseDto, + AddIdeationResponseDto, + DeleteIdeationResponseDto, + IdeationVoteResponseDto, + FinalizeIdeationResponseDto, +} from "@/modules/ideation/domain/dtos/response.dto"; + +/** + * Repository (adapter) implementing the port + */ +@injectable() +export class IdeationApiRepositoryImpl implements IdeationApiRepository { + constructor( + @inject(TYPES.RestApiRepository) + private readonly apiClient: RestApiRepository, + ) {} + + async addIdeation({ + teamId, + title, + description, + vision, + cache, + token, + }: AddIdeationRequestDto): Promise { + return await this.apiClient.post< + AddIdeationBodyDto, + AddIdeationResponseDto + >({ + url: `${IdeationUrls.BASE_URL_TEAMS}/${teamId}/${IdeationUrls.SUB_URLS.IDEATIONS}`, + options: { + cache, + token, + }, + payload: { title, description, vision }, + }); + } + + async editIdeation({ + ideationId, + title, + description, + vision, + cache, + token, + }: EditIdeationRequestDto): Promise { + return await this.apiClient.patch< + EditIdeationBodyDto, + EditIdeationResponseDto + >({ + url: `${IdeationUrls.BASE_URL_IDEATIONS}/${ideationId}`, + options: { + cache, + token, + }, + payload: { title, description, vision }, + }); + } + + async deleteIdeation({ + ideationId, + cache, + token, + }: DeleteIdeationRequestDto): Promise { + return await this.apiClient.delete({ + url: `${IdeationUrls.BASE_URL_IDEATIONS}/${ideationId}`, + options: { + cache, + token, + }, + }); + } + + async addIdeationVote({ + ideationId, + cache, + token, + }: IdeationVoteRequestDto): Promise { + return await this.apiClient.post({ + url: `${IdeationUrls.BASE_URL_IDEATIONS}/${ideationId}/${IdeationUrls.SUB_URLS.IDEATION_VOTES}`, + options: { + cache, + token, + }, + }); + } + + async removeIdeationVote({ + ideationId, + cache, + token, + }: IdeationVoteRequestDto): Promise { + return await this.apiClient.delete({ + url: `${IdeationUrls.BASE_URL_IDEATIONS}/${ideationId}/${IdeationUrls.SUB_URLS.IDEATION_VOTES}`, + options: { + cache, + token, + }, + }); + } + + async finalizeIdeation({ + teamId, + ideationId, + cache, + token, + }: FinalizeIdeationRequestDto): Promise { + return await this.apiClient.post({ + url: `${IdeationUrls.BASE_URL_TEAMS}/${teamId}/${IdeationUrls.SUB_URLS.IDEATIONS}/${ideationId}/${IdeationUrls.SUB_URLS.SELECT}`, + options: { + cache, + token, + }, + }); + } +} diff --git a/src/modules/ideation/service/IdeationService.ts b/src/modules/ideation/service/IdeationService.ts deleted file mode 100644 index 4fde1f5c0..000000000 --- a/src/modules/ideation/service/IdeationService.ts +++ /dev/null @@ -1,181 +0,0 @@ -import { inject, injectable } from "tsyringe"; -import { IdeationUrls } from "@/modules/ideation/domain/IdeationUrls"; -import type { - AddIdeationBody, - EditIdeationBody, -} from "@/modules/ideation/domain/IdeationBody"; -import type { - AddIdeationResponse, - DeleteIdeationResponse, - EditIdeationResponse, - FinalizeIdeationResponse, - IdeationVoteResponse, -} from "@/modules/ideation/domain/IdeationResponse"; -import type { IIdeationService } from "@/modules/ideation/domain/services/IIdeationService"; -import type { - AddIdeationProps, - EditIdeationProps, - DeleteIdeationProps, - IdeationVoteProps, - FinalizeIdeationProps, -} from "@/modules/ideation/domain/IdeationProps"; -import type { AsyncActionResponse } from "@/utils/handleAsync"; -import { handleAsync } from "@/utils/handleAsync"; -import { TYPES } from "@/di/types"; -import { type IApiClientRepository } from "@/modules/network/domain/repositories/IApiClientRepository"; - -/** - * Service class for handling ideation-related operations. - */ -@injectable() -export class IdeationService implements IIdeationService { - constructor( - @inject(TYPES.IApiClientRepository) - private readonly apiClient: IApiClientRepository, - ) {} - - /** - * Adds a new ideation. - * - * @param {AddIdeationProps} props - The properties required to add an ideation. - * @returns {Promise>} - The response from the addIdeation method. - */ - async addIdeation({ - teamId, - title, - description, - vision, - baseUrl, - token, - }: AddIdeationProps): Promise> { - const addIdeationAsync = () => - this.apiClient.POST({ - baseUrl, - url: `${IdeationUrls.BASE_URL_TEAMS}/${teamId}/${IdeationUrls.SUB_URLS.IDEATIONS}`, - token, - cache: "default", - payload: { title, description, vision }, - }); - - return await handleAsync(addIdeationAsync); - } - - /** - * Edits an existing ideation. - * - * @param {EditIdeationProps} props - The properties required to edit an ideation. - * @returns {Promise>} - The response from the editIdeation method. - */ - async editIdeation({ - ideationId, - title, - description, - vision, - baseUrl, - token, - }: EditIdeationProps): Promise> { - const editIdeationAsync = () => - this.apiClient.PATCH({ - baseUrl, - url: `${IdeationUrls.BASE_URL_IDEATIONS}/${ideationId}`, - token, - cache: "default", - payload: { title, description, vision }, - }); - - return await handleAsync(editIdeationAsync); - } - - /** - * Deletes an existing ideation. - * - * @param {DeleteIdeationProps} props - The properties required to delete an ideation. - * @returns {Promise>} - The response from the deleteIdeation method. - */ - async deleteIdeation({ - ideationId, - baseUrl, - token, - }: DeleteIdeationProps): Promise< - AsyncActionResponse - > { - const deleteIdeationAsync = () => - this.apiClient.DELETE({ - baseUrl, - url: `${IdeationUrls.BASE_URL_IDEATIONS}/${ideationId}`, - token, - cache: "default", - }); - - return await handleAsync(deleteIdeationAsync); - } - - /** - * Adds a vote to an ideation. - * - * @param {IdeationVoteProps} props - The properties required to add a vote to an ideation. - * @returns {Promise>} - The response from the addIdeationVote method. - */ - async addIdeationVote({ - ideationId, - baseUrl, - token, - }: IdeationVoteProps): Promise> { - const addIdeationVoteAsync = () => - this.apiClient.POST({ - baseUrl, - url: `${IdeationUrls.BASE_URL_IDEATIONS}/${ideationId}/${IdeationUrls.SUB_URLS.IDEATION_VOTES}`, - token, - cache: "default", - }); - - return await handleAsync(addIdeationVoteAsync); - } - - /** - * Removes a vote from an ideation. - * - * @param {IdeationVoteProps} props - The properties required to remove a vote from an ideation. - * @returns {Promise>} - The response from the removeIdeationVote method. - */ - async removeIdeationVote({ - ideationId, - baseUrl, - token, - }: IdeationVoteProps): Promise> { - const removeIdeationVoteAsync = () => - this.apiClient.DELETE({ - baseUrl, - url: `${IdeationUrls.BASE_URL_IDEATIONS}/${ideationId}/${IdeationUrls.SUB_URLS.IDEATION_VOTES}`, - token, - cache: "default", - }); - - return await handleAsync(removeIdeationVoteAsync); - } - - /** - * Finalizes an ideation. - * - * @param {FinalizeIdeationProps} props - The properties required to finalize an ideation. - * @returns {Promise>} - The response from the finalizeIdeation method. - */ - async finalizeIdeation({ - teamId, - ideationId, - baseUrl, - token, - }: FinalizeIdeationProps): Promise< - AsyncActionResponse - > { - const finalizeIdeationAsync = () => - this.apiClient.POST({ - baseUrl, - url: `${IdeationUrls.BASE_URL_TEAMS}/${teamId}/${IdeationUrls.SUB_URLS.IDEATIONS}/${ideationId}/${IdeationUrls.SUB_URLS.SELECT}`, - token, - cache: "default", - }); - - return await handleAsync(finalizeIdeationAsync); - } -} diff --git a/src/modules/rest-api/domain/entities/restApiParams.ts b/src/modules/rest-api/domain/entities/restApiParams.ts index 3f368fda7..4155d3d79 100644 --- a/src/modules/rest-api/domain/entities/restApiParams.ts +++ b/src/modules/rest-api/domain/entities/restApiParams.ts @@ -1,33 +1,28 @@ import { type RequestOptions } from "./requestOptions"; export interface GetParams { - baseUrl: string; url: string; options: RequestOptions; } export interface PostParams { - baseUrl: string; url: string; options: RequestOptions; payload?: X; } export interface PatchParams { - baseUrl: string; url: string; options: RequestOptions; payload: X; } export interface DeleteParams { - baseUrl: string; url: string; options: RequestOptions; } export interface UnauthPostParams { - baseUrl: string; url: string; options: RequestOptions; payload: X; diff --git a/src/modules/rest-api/domain/ports/restApiRepository.ts b/src/modules/rest-api/domain/ports/restApiRepository.ts index 07da834cf..b2a0c32a5 100644 --- a/src/modules/rest-api/domain/ports/restApiRepository.ts +++ b/src/modules/rest-api/domain/ports/restApiRepository.ts @@ -7,13 +7,13 @@ import type { } from "@/modules/rest-api/domain/entities/restApiParams"; export interface RestApiRepository { - get(params: GetParams): Promise; + get(params: GetParams): Promise; post(params: PostParams): Promise; patch(params: PatchParams): Promise; - delete(params: DeleteParams): Promise; + delete(params: DeleteParams): Promise; unauthpost(params: UnauthPostParams): Promise; } From de507830510dfd7c67453919a76e9e1d324185af Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Mon, 2 Sep 2024 21:42:53 -0400 Subject: [PATCH 12/31] refactor usecases --- src/di/config.ts | 18 ++++--- src/di/injectables.ts | 12 ++--- src/di/types.ts | 4 +- .../usecases/AddIdeationUseCase.ts | 18 +++++++ .../usecases/AddIdeationVoteUseCase.ts | 20 ++++++++ .../usecases/DeleteIdeationUseCase.ts | 20 ++++++++ .../usecases/EditIdeationUseCase.ts | 21 +++++++++ .../usecases/FinalizeIdeationUseCase.ts | 20 ++++++++ .../usecases/RemoveIdeationVoteUseCase.ts | 20 ++++++++ .../ideation/domain/dtos/request.dto.ts | 3 +- .../ideation/usecases/AddIdeationUseCase.ts | 47 ------------------- .../usecases/AddIdeationVoteUseCase.ts | 47 ------------------- .../usecases/DeleteIdeationUseCase.ts | 47 ------------------- .../ideation/usecases/EditIdeationUseCase.ts | 47 ------------------- .../usecases/FinalizeIdeationUseCase.ts | 47 ------------------- .../usecases/RemoveIdeationVoteUseCase.ts | 47 ------------------- 16 files changed, 136 insertions(+), 302 deletions(-) create mode 100644 src/modules/ideation/application/usecases/AddIdeationUseCase.ts create mode 100644 src/modules/ideation/application/usecases/AddIdeationVoteUseCase.ts create mode 100644 src/modules/ideation/application/usecases/DeleteIdeationUseCase.ts create mode 100644 src/modules/ideation/application/usecases/EditIdeationUseCase.ts create mode 100644 src/modules/ideation/application/usecases/FinalizeIdeationUseCase.ts create mode 100644 src/modules/ideation/application/usecases/RemoveIdeationVoteUseCase.ts delete mode 100644 src/modules/ideation/usecases/AddIdeationUseCase.ts delete mode 100644 src/modules/ideation/usecases/AddIdeationVoteUseCase.ts delete mode 100644 src/modules/ideation/usecases/DeleteIdeationUseCase.ts delete mode 100644 src/modules/ideation/usecases/EditIdeationUseCase.ts delete mode 100644 src/modules/ideation/usecases/FinalizeIdeationUseCase.ts delete mode 100644 src/modules/ideation/usecases/RemoveIdeationVoteUseCase.ts diff --git a/src/di/config.ts b/src/di/config.ts index 8a64ac9b6..05e1db6d1 100644 --- a/src/di/config.ts +++ b/src/di/config.ts @@ -1,19 +1,17 @@ import { container } from "tsyringe"; import { TYPES } from "./types"; -import type { IRestApiRepository } from "@/modules/api/domain/repositories/IRestApiRepository"; -import { RestApiRepository } from "@/modules/api/repositories/RestApiRepository"; -import type { IIdeationService } from "@/modules/ideation/domain/services/IIdeationService"; -import { IdeationService } from "@/modules/ideation/service/IdeationService"; +import { type IdeationApiRepository } from "@/modules/ideation/domain/ports/ideationApiRepository"; +import { NextJsRestApiRepository } from "@/modules/rest-api/infrastructure/adapters/nextJsRestApiRepository"; +import { IdeationApiRepositoryImpl } from "@/modules/ideation/infrastructure/adapters/ideationApiRepositoryImpl"; +import { type RestApiRepository } from "@/modules/rest-api/domain/ports/restApiRepository"; -/* Services */ -container.register(TYPES.IIdeationService, { - useClass: IdeationService, +container.register(TYPES.IdeationApiRepository, { + useClass: IdeationApiRepositoryImpl, }); -/* Repositories */ -container.register(TYPES.IApiClientRepository, { - useClass: RestApiRepository, +container.register(TYPES.RestApiRepository, { + useClass: NextJsRestApiRepository, }); export default container; diff --git a/src/di/injectables.ts b/src/di/injectables.ts index 46e2376d4..184cc5de1 100644 --- a/src/di/injectables.ts +++ b/src/di/injectables.ts @@ -1,11 +1,11 @@ import { container } from "tsyringe"; import { TYPES } from "./types"; -import type { AddIdeationUseCase } from "@/modules/ideation/usecases/AddIdeationUseCase"; -import type { AddIdeationVoteUseCase } from "@/modules/ideation/usecases/AddIdeationVoteUseCase"; -import type { DeleteIdeationUseCase } from "@/modules/ideation/usecases/DeleteIdeationUseCase"; -import type { EditIdeationUseCase } from "@/modules/ideation/usecases/EditIdeationUseCase"; -import type { FinalizeIdeationUseCase } from "@/modules/ideation/usecases/FinalizeIdeationUseCase"; -import type { RemoveIdeationVoteUseCase } from "@/modules/ideation/usecases/RemoveIdeationVoteUseCase"; +import type { AddIdeationUseCase } from "@/modules/ideation/application/usecases/AddIdeationUseCase"; +import type { AddIdeationVoteUseCase } from "@/modules/ideation/application/usecases/AddIdeationVoteUseCase"; +import type { DeleteIdeationUseCase } from "@/modules/ideation/application/usecases/DeleteIdeationUseCase"; +import type { EditIdeationUseCase } from "@/modules/ideation/application/usecases/EditIdeationUseCase"; +import type { FinalizeIdeationUseCase } from "@/modules/ideation/application/usecases/FinalizeIdeationUseCase"; +import type { RemoveIdeationVoteUseCase } from "@/modules/ideation/application/usecases/RemoveIdeationVoteUseCase"; export const injectables = { /* Ideation */ diff --git a/src/di/types.ts b/src/di/types.ts index 6a4f3ee76..f487ccc47 100644 --- a/src/di/types.ts +++ b/src/di/types.ts @@ -1,9 +1,7 @@ export const TYPES = { /* Repositories */ RestApiRepository: Symbol.for("RestApiRepository"), - - /* Services */ - IIdeationService: Symbol.for("IIdeationService"), + IdeationApiRepository: Symbol.for("IdeationApiRepository"), /* UseCases */ AddIdeationUseCase: Symbol.for("AddIdeationUseCase"), diff --git a/src/modules/ideation/application/usecases/AddIdeationUseCase.ts b/src/modules/ideation/application/usecases/AddIdeationUseCase.ts new file mode 100644 index 000000000..92504674e --- /dev/null +++ b/src/modules/ideation/application/usecases/AddIdeationUseCase.ts @@ -0,0 +1,18 @@ +import { inject } from "tsyringe"; +import { TYPES } from "@/di/types"; +import { type IdeationApiRepository } from "@/modules/ideation/domain/ports/ideationApiRepository"; +import { type AddIdeationRequestDto } from "@/modules/ideation/domain/dtos/request.dto"; +import { type AddIdeationResponseDto } from "@/modules/ideation/domain/dtos/response.dto"; + +export class AddIdeationUseCase { + constructor( + @inject(TYPES.IdeationApiRepository) + private readonly ideationApiRepository: IdeationApiRepository, + ) {} + + async execute(props: AddIdeationRequestDto): Promise { + return await this.ideationApiRepository.addIdeation({ + ...props, + }); + } +} diff --git a/src/modules/ideation/application/usecases/AddIdeationVoteUseCase.ts b/src/modules/ideation/application/usecases/AddIdeationVoteUseCase.ts new file mode 100644 index 000000000..2afc7cec7 --- /dev/null +++ b/src/modules/ideation/application/usecases/AddIdeationVoteUseCase.ts @@ -0,0 +1,20 @@ +import { inject } from "tsyringe"; +import { TYPES } from "@/di/types"; +import { type IdeationApiRepository } from "@/modules/ideation/domain/ports/ideationApiRepository"; +import { type IdeationVoteRequestDto } from "@/modules/ideation/domain/dtos/request.dto"; +import { type IdeationVoteResponseDto } from "@/modules/ideation/domain/dtos/response.dto"; + +export class AddIdeationVoteUseCase { + constructor( + @inject(TYPES.IdeationApiRepository) + private readonly ideationApiRepository: IdeationApiRepository, + ) {} + + async execute( + props: IdeationVoteRequestDto, + ): Promise { + return await this.ideationApiRepository.addIdeationVote({ + ...props, + }); + } +} diff --git a/src/modules/ideation/application/usecases/DeleteIdeationUseCase.ts b/src/modules/ideation/application/usecases/DeleteIdeationUseCase.ts new file mode 100644 index 000000000..a12b5eec4 --- /dev/null +++ b/src/modules/ideation/application/usecases/DeleteIdeationUseCase.ts @@ -0,0 +1,20 @@ +import { inject } from "tsyringe"; +import { TYPES } from "@/di/types"; +import { type IdeationApiRepository } from "@/modules/ideation/domain/ports/ideationApiRepository"; +import { type DeleteIdeationRequestDto } from "@/modules/ideation/domain/dtos/request.dto"; +import { type DeleteIdeationResponseDto } from "@/modules/ideation/domain/dtos/response.dto"; + +export class DeleteIdeationUseCase { + constructor( + @inject(TYPES.IdeationApiRepository) + private readonly ideationApiRepository: IdeationApiRepository, + ) {} + + async execute( + props: DeleteIdeationRequestDto, + ): Promise { + return await this.ideationApiRepository.deleteIdeation({ + ...props, + }); + } +} diff --git a/src/modules/ideation/application/usecases/EditIdeationUseCase.ts b/src/modules/ideation/application/usecases/EditIdeationUseCase.ts new file mode 100644 index 000000000..9bc8e1aed --- /dev/null +++ b/src/modules/ideation/application/usecases/EditIdeationUseCase.ts @@ -0,0 +1,21 @@ +import { inject } from "tsyringe"; +import { TYPES } from "@/di/types"; + +import { type IdeationApiRepository } from "@/modules/ideation/domain/ports/ideationApiRepository"; +import { type EditIdeationRequestDto } from "@/modules/ideation/domain/dtos/request.dto"; +import { type EditIdeationResponseDto } from "@/modules/ideation/domain/dtos/response.dto"; + +export class EditIdeationUseCase { + constructor( + @inject(TYPES.IdeationApiRepository) + private readonly ideationApiRepository: IdeationApiRepository, + ) {} + + async execute( + props: EditIdeationRequestDto, + ): Promise { + return await this.ideationApiRepository.editIdeation({ + ...props, + }); + } +} diff --git a/src/modules/ideation/application/usecases/FinalizeIdeationUseCase.ts b/src/modules/ideation/application/usecases/FinalizeIdeationUseCase.ts new file mode 100644 index 000000000..4ea2e1f98 --- /dev/null +++ b/src/modules/ideation/application/usecases/FinalizeIdeationUseCase.ts @@ -0,0 +1,20 @@ +import { inject } from "tsyringe"; +import { TYPES } from "@/di/types"; +import { type IdeationApiRepository } from "@/modules/ideation/domain/ports/ideationApiRepository"; +import { type FinalizeIdeationRequestDto } from "@/modules/ideation/domain/dtos/request.dto"; +import { type FinalizeIdeationResponseDto } from "@/modules/ideation/domain/dtos/response.dto"; + +export class FinalizeIdeationUseCase { + constructor( + @inject(TYPES.IdeationApiRepository) + private readonly ideationApiRepository: IdeationApiRepository, + ) {} + + async execute( + props: FinalizeIdeationRequestDto, + ): Promise { + return await this.ideationApiRepository.finalizeIdeation({ + ...props, + }); + } +} diff --git a/src/modules/ideation/application/usecases/RemoveIdeationVoteUseCase.ts b/src/modules/ideation/application/usecases/RemoveIdeationVoteUseCase.ts new file mode 100644 index 000000000..72179f641 --- /dev/null +++ b/src/modules/ideation/application/usecases/RemoveIdeationVoteUseCase.ts @@ -0,0 +1,20 @@ +import { inject } from "tsyringe"; +import { TYPES } from "@/di/types"; +import { type IdeationApiRepository } from "@/modules/ideation/domain/ports/ideationApiRepository"; +import { type IdeationVoteRequestDto } from "@/modules/ideation/domain/dtos/request.dto"; +import { type IdeationVoteResponseDto } from "@/modules/ideation/domain/dtos/response.dto"; + +export class RemoveIdeationVoteUseCase { + constructor( + @inject(TYPES.IdeationApiRepository) + private readonly ideationApiRepository: IdeationApiRepository, + ) {} + + async execute( + props: IdeationVoteRequestDto, + ): Promise { + return await this.ideationApiRepository.removeIdeationVote({ + ...props, + }); + } +} diff --git a/src/modules/ideation/domain/dtos/request.dto.ts b/src/modules/ideation/domain/dtos/request.dto.ts index d505b2a99..1d6045755 100644 --- a/src/modules/ideation/domain/dtos/request.dto.ts +++ b/src/modules/ideation/domain/dtos/request.dto.ts @@ -1,5 +1,7 @@ import { type IdeationRequestDto, type IdeationBodyDto } from "./common.dto"; +export type FetchIdeationsRequestDto = Pick; + export interface AddIdeationBodyDto extends IdeationBodyDto {} export interface EditIdeationBodyDto extends Partial {} @@ -26,7 +28,6 @@ export type IdeationVoteRequestDto = Omit & { cache?: RequestCache; token?: string; }; -export type FetchIdeationsRequestDto = Pick; export interface FinalizeIdeationRequestDto extends IdeationRequestDto { cache?: RequestCache; diff --git a/src/modules/ideation/usecases/AddIdeationUseCase.ts b/src/modules/ideation/usecases/AddIdeationUseCase.ts deleted file mode 100644 index 4fb74afad..000000000 --- a/src/modules/ideation/usecases/AddIdeationUseCase.ts +++ /dev/null @@ -1,47 +0,0 @@ -"use server"; - -import { inject } from "tsyringe"; -import { revalidateTag } from "next/cache"; -import type { AddIdeationProps } from "@/modules/ideation/domain/IdeationProps"; -import type { AddIdeationResponse } from "@/modules/ideation/domain/IdeationResponse"; -import { type IIdeationService } from "@/modules/ideation/domain/services/IIdeationService"; -import { TYPES } from "@/di/types"; -import type { AsyncActionResponse } from "@/utils/handleAsync"; -import { getAccessToken } from "@/utils/getCookie"; -import { CacheTag } from "@/utils/cacheTag"; - -export class AddIdeationUseCase { - constructor( - @inject(TYPES.IIdeationService) - private readonly ideationService: IIdeationService, - ) {} - - /** - * Executes the use case to add an ideation. - * - * @param {AddIdeationProps} props - The properties required to add an ideation. - * @returns {Promise>} - The response from the addIdeation method. - */ - async execute( - props: AddIdeationProps, - ): Promise> { - const token = getAccessToken(); - const baseUrl = process.env.NEXT_PUBLIC_API_URL; - - if (!baseUrl) { - throw new Error("Base URL is not defined"); - } - - const [res, error] = await this.ideationService.addIdeation({ - ...props, - token, - baseUrl, - }); - - if (res) { - revalidateTag(CacheTag.ideation); - } - - return [res, error]; - } -} diff --git a/src/modules/ideation/usecases/AddIdeationVoteUseCase.ts b/src/modules/ideation/usecases/AddIdeationVoteUseCase.ts deleted file mode 100644 index 3d5818fe9..000000000 --- a/src/modules/ideation/usecases/AddIdeationVoteUseCase.ts +++ /dev/null @@ -1,47 +0,0 @@ -"use server"; - -import { inject } from "tsyringe"; -import { revalidateTag } from "next/cache"; -import type { IdeationVoteProps } from "@/modules/ideation/domain/IdeationProps"; -import type { IdeationVoteResponse } from "@/modules/ideation/domain/IdeationResponse"; -import { type IIdeationService } from "@/modules/ideation/domain/services/IIdeationService"; -import { TYPES } from "@/di/types"; -import type { AsyncActionResponse } from "@/utils/handleAsync"; -import { getAccessToken } from "@/utils/getCookie"; -import { CacheTag } from "@/utils/cacheTag"; - -export class AddIdeationVoteUseCase { - constructor( - @inject(TYPES.IIdeationService) - private readonly ideationService: IIdeationService, - ) {} - - /** - * Executes the use case to add an ideation vote. - * - * @param {IdeationVoteProps} props - The properties required to add an ideation vote. - * @returns {Promise>} - The response from the addIdeationVote method. - */ - async execute( - props: IdeationVoteProps, - ): Promise> { - const token = getAccessToken(); - const baseUrl = process.env.NEXT_PUBLIC_API_URL; - - if (!baseUrl) { - throw new Error("Base URL is not defined"); - } - - const [res, error] = await this.ideationService.addIdeationVote({ - ...props, - token, - baseUrl, - }); - - if (res) { - revalidateTag(CacheTag.ideation); - } - - return [res, error]; - } -} diff --git a/src/modules/ideation/usecases/DeleteIdeationUseCase.ts b/src/modules/ideation/usecases/DeleteIdeationUseCase.ts deleted file mode 100644 index 73dce758b..000000000 --- a/src/modules/ideation/usecases/DeleteIdeationUseCase.ts +++ /dev/null @@ -1,47 +0,0 @@ -"use server"; - -import { inject } from "tsyringe"; -import { revalidateTag } from "next/cache"; -import type { DeleteIdeationProps } from "@/modules/ideation/domain/IdeationProps"; -import type { DeleteIdeationResponse } from "@/modules/ideation/domain/IdeationResponse"; -import { type IIdeationService } from "@/modules/ideation/domain/services/IIdeationService"; -import { TYPES } from "@/di/types"; -import type { AsyncActionResponse } from "@/utils/handleAsync"; -import { getAccessToken } from "@/utils/getCookie"; -import { CacheTag } from "@/utils/cacheTag"; - -export class DeleteIdeationUseCase { - constructor( - @inject(TYPES.IIdeationService) - private readonly ideationService: IIdeationService, - ) {} - - /** - * Executes the use case to delete an ideation. - * - * @param {DeleteIdeationProps} props - The properties required to delete an ideation. - * @returns {Promise>} - The response from the deleteIdeation method. - */ - async execute( - props: DeleteIdeationProps, - ): Promise> { - const token = getAccessToken(); - const baseUrl = process.env.NEXT_PUBLIC_API_URL; - - if (!baseUrl) { - throw new Error("Base URL is not defined"); - } - - const [res, error] = await this.ideationService.deleteIdeation({ - ...props, - token, - baseUrl, - }); - - if (res) { - revalidateTag(CacheTag.ideation); - } - - return [res, error]; - } -} diff --git a/src/modules/ideation/usecases/EditIdeationUseCase.ts b/src/modules/ideation/usecases/EditIdeationUseCase.ts deleted file mode 100644 index 5e3cc72db..000000000 --- a/src/modules/ideation/usecases/EditIdeationUseCase.ts +++ /dev/null @@ -1,47 +0,0 @@ -"use server"; - -import { inject } from "tsyringe"; -import { revalidateTag } from "next/cache"; -import type { EditIdeationProps } from "@/modules/ideation/domain/IdeationProps"; -import type { EditIdeationResponse } from "@/modules/ideation/domain/IdeationResponse"; -import { type IIdeationService } from "@/modules/ideation/domain/services/IIdeationService"; -import { TYPES } from "@/di/types"; -import type { AsyncActionResponse } from "@/utils/handleAsync"; -import { getAccessToken } from "@/utils/getCookie"; -import { CacheTag } from "@/utils/cacheTag"; - -export class EditIdeationUseCase { - constructor( - @inject(TYPES.IIdeationService) - private readonly ideationService: IIdeationService, - ) {} - - /** - * Executes the use case to edit an ideation. - * - * @param {EditIdeationProps} props - The properties required to edit an ideation. - * @returns {Promise>} - The response from the editIdeation method. - */ - async execute( - props: EditIdeationProps, - ): Promise> { - const token = getAccessToken(); - const baseUrl = process.env.NEXT_PUBLIC_API_URL; - - if (!baseUrl) { - throw new Error("Base URL is not defined"); - } - - const [res, error] = await this.ideationService.editIdeation({ - ...props, - token, - baseUrl, - }); - - if (res) { - revalidateTag(CacheTag.ideation); - } - - return [res, error]; - } -} diff --git a/src/modules/ideation/usecases/FinalizeIdeationUseCase.ts b/src/modules/ideation/usecases/FinalizeIdeationUseCase.ts deleted file mode 100644 index bb16d0231..000000000 --- a/src/modules/ideation/usecases/FinalizeIdeationUseCase.ts +++ /dev/null @@ -1,47 +0,0 @@ -"use server"; - -import { inject } from "tsyringe"; -import { revalidateTag } from "next/cache"; -import type { FinalizeIdeationProps } from "@/modules/ideation/domain/IdeationProps"; -import type { FinalizeIdeationResponse } from "@/modules/ideation/domain/IdeationResponse"; -import { type IIdeationService } from "@/modules/ideation/domain/services/IIdeationService"; -import { TYPES } from "@/di/types"; -import type { AsyncActionResponse } from "@/utils/handleAsync"; -import { getAccessToken } from "@/utils/getCookie"; -import { CacheTag } from "@/utils/cacheTag"; - -export class FinalizeIdeationUseCase { - constructor( - @inject(TYPES.IIdeationService) - private readonly ideationService: IIdeationService, - ) {} - - /** - * Executes the use case to finalize an ideation. - * - * @param {FinalizeIdeationProps} props - The properties required to finalize an ideation. - * @returns {Promise>} - The response from the finalizeIdeation method. - */ - async execute( - props: FinalizeIdeationProps, - ): Promise> { - const token = getAccessToken(); - const baseUrl = process.env.NEXT_PUBLIC_API_URL; - - if (!baseUrl) { - throw new Error("Base URL is not defined"); - } - - const [res, error] = await this.ideationService.finalizeIdeation({ - ...props, - token, - baseUrl, - }); - - if (res) { - revalidateTag(CacheTag.ideation); - } - - return [res, error]; - } -} diff --git a/src/modules/ideation/usecases/RemoveIdeationVoteUseCase.ts b/src/modules/ideation/usecases/RemoveIdeationVoteUseCase.ts deleted file mode 100644 index 54f6a823e..000000000 --- a/src/modules/ideation/usecases/RemoveIdeationVoteUseCase.ts +++ /dev/null @@ -1,47 +0,0 @@ -"use server"; - -import { inject } from "tsyringe"; -import { revalidateTag } from "next/cache"; -import type { IdeationVoteProps } from "@/modules/ideation/domain/IdeationProps"; -import type { IdeationVoteResponse } from "@/modules/ideation/domain/IdeationResponse"; -import { type IIdeationService } from "@/modules/ideation/domain/services/IIdeationService"; -import { TYPES } from "@/di/types"; -import type { AsyncActionResponse } from "@/utils/handleAsync"; -import { getAccessToken } from "@/utils/getCookie"; -import { CacheTag } from "@/utils/cacheTag"; - -export class RemoveIdeationVoteUseCase { - constructor( - @inject(TYPES.IIdeationService) - private readonly ideationService: IIdeationService, - ) {} - - /** - * Executes the use case to remove an ideation vote. - * - * @param {IdeationVoteProps} props - The properties required to remove an ideation vote. - * @returns {Promise>} - The response from the removeIdeationVote method. - */ - async execute( - props: IdeationVoteProps, - ): Promise> { - const token = getAccessToken(); - const baseUrl = process.env.NEXT_PUBLIC_API_URL; - - if (!baseUrl) { - throw new Error("Base URL is not defined"); - } - - const [res, error] = await this.ideationService.removeIdeationVote({ - ...props, - token, - baseUrl, - }); - - if (res) { - revalidateTag(CacheTag.ideation); - } - - return [res, error]; - } -} From 7065ad1da18395e8e1d7a77ff0ce85791a624d52 Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Tue, 3 Sep 2024 00:02:31 -0400 Subject: [PATCH 13/31] refactor add ideation in service --- .../[teamId]/ideation/ideationService.ts | 81 +++++++++++++++---- src/app/layout.tsx | 2 + src/di/config.ts | 7 +- .../usecases/AddIdeationUseCase.ts | 3 +- .../ideation/domain/dtos/request.dto.ts | 4 + 5 files changed, 80 insertions(+), 17 deletions(-) diff --git a/src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts b/src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts index fa2ae7590..3e50b86ff 100644 --- a/src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts +++ b/src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts @@ -5,6 +5,11 @@ import { getAccessToken } from "@/utils/getCookie"; import { DELETE, PATCH, POST } from "@/utils/requests"; import { type AsyncActionResponse, handleAsync } from "@/utils/handleAsync"; import { CacheTag } from "@/utils/cacheTag"; +import { AddIdeationUseCase } from "@/modules/ideation/application/usecases/AddIdeationUseCase"; +import type { AddIdeationUsecaseDto } from "@/modules/ideation/domain/dtos/request.dto"; +import { NextJsRestApiRepository } from "@/modules/rest-api/infrastructure/adapters/nextJsRestApiRepository"; +import { IdeationApiRepositoryImpl } from "@/modules/ideation/infrastructure/adapters/ideationApiRepositoryImpl"; +import { type AddIdeationResponseDto } from "@/modules/ideation/domain/dtos/response.dto"; interface IdeationProps { teamId: number; @@ -53,31 +58,77 @@ export interface IdeationVoteResponse extends IdeationResponse { projectIdeaId: number; } +const nextJsRestApiRepository = new NextJsRestApiRepository( + process.env.NEXT_PUBLIC_API_URL!, +); +const ideationApiRepository = new IdeationApiRepositoryImpl( + nextJsRestApiRepository, +); + export async function addIdeation({ teamId, title, description, vision, -}: AddIdeationProps): Promise> { +}: AddIdeationUsecaseDto): Promise< + AsyncActionResponse +> { const token = getAccessToken(); - - const addIdeationAsync = () => - POST( - `api/v1/voyages/teams/${teamId}/ideations`, + const addIdeationUseCase = new AddIdeationUseCase(ideationApiRepository); + + // const addIdeationUseCase = container.resolve( + // TYPES.AddIdeationUseCase, + // ); + + try { + const addIdeationAsync = await addIdeationUseCase.execute({ + teamId, + title, + description, + vision, + cache: "default", token, - "default", - { title, description, vision }, - ); - - const [res, error] = await handleAsync(addIdeationAsync); - - if (res) { - revalidateTag(CacheTag.ideation); + }); + + if (addIdeationAsync) { + revalidateTag(CacheTag.ideation); + } + + return [addIdeationAsync, null]; + } catch (error) { + if (error instanceof Error) { + return [null, { message: error.message }]; + } else { + throw error; + } } - - return [res, error]; } +// export async function addIdeation({ +// teamId, +// title, +// description, +// vision, +// }: AddIdeationProps): Promise> { +// const token = getAccessToken(); + +// const addIdeationAsync = () => +// POST( +// `api/v1/voyages/teams/${teamId}/ideations`, +// token, +// "default", +// { title, description, vision }, +// ); + +// const [res, error] = await handleAsync(addIdeationAsync); + +// if (res) { +// revalidateTag(CacheTag.ideation); +// } + +// return [res, error]; +// } + export async function editIdeation({ ideationId, title, diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 2ac5ac26a..6cd832248 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -4,6 +4,8 @@ import { Inter } from "next/font/google"; import StoreProvider from "@/components/providers/StoreProvider"; import ThemeProvider from "@/components/providers/ThemeProvider"; import ModalProvider from "@/components/providers/ModalProvider"; +import "reflect-metadata"; +import "@/di/config"; export const metadata: Metadata = { title: "Chingu Dashboard", diff --git a/src/di/config.ts b/src/di/config.ts index 05e1db6d1..531808d9e 100644 --- a/src/di/config.ts +++ b/src/di/config.ts @@ -5,13 +5,18 @@ import { type IdeationApiRepository } from "@/modules/ideation/domain/ports/idea import { NextJsRestApiRepository } from "@/modules/rest-api/infrastructure/adapters/nextJsRestApiRepository"; import { IdeationApiRepositoryImpl } from "@/modules/ideation/infrastructure/adapters/ideationApiRepositoryImpl"; import { type RestApiRepository } from "@/modules/rest-api/domain/ports/restApiRepository"; +import { AddIdeationUseCase } from "@/modules/ideation/application/usecases/AddIdeationUseCase"; container.register(TYPES.IdeationApiRepository, { useClass: IdeationApiRepositoryImpl, }); container.register(TYPES.RestApiRepository, { - useClass: NextJsRestApiRepository, + useValue: new NextJsRestApiRepository(process.env.NEXT_PUBLIC_API_URL!), +}); + +container.register(TYPES.AddIdeationUseCase, { + useClass: AddIdeationUseCase, }); export default container; diff --git a/src/modules/ideation/application/usecases/AddIdeationUseCase.ts b/src/modules/ideation/application/usecases/AddIdeationUseCase.ts index 92504674e..60883dc4c 100644 --- a/src/modules/ideation/application/usecases/AddIdeationUseCase.ts +++ b/src/modules/ideation/application/usecases/AddIdeationUseCase.ts @@ -1,9 +1,10 @@ -import { inject } from "tsyringe"; +import { inject, injectable } from "tsyringe"; import { TYPES } from "@/di/types"; import { type IdeationApiRepository } from "@/modules/ideation/domain/ports/ideationApiRepository"; import { type AddIdeationRequestDto } from "@/modules/ideation/domain/dtos/request.dto"; import { type AddIdeationResponseDto } from "@/modules/ideation/domain/dtos/response.dto"; +@injectable() export class AddIdeationUseCase { constructor( @inject(TYPES.IdeationApiRepository) diff --git a/src/modules/ideation/domain/dtos/request.dto.ts b/src/modules/ideation/domain/dtos/request.dto.ts index 1d6045755..7cb47854e 100644 --- a/src/modules/ideation/domain/dtos/request.dto.ts +++ b/src/modules/ideation/domain/dtos/request.dto.ts @@ -13,6 +13,10 @@ export interface AddIdeationRequestDto token?: string; } +export interface AddIdeationUsecaseDto + extends Pick, + IdeationBodyDto {} + export type EditIdeationRequestDto = EditIdeationBodyDto & Omit & { cache?: RequestCache; From 16865eece67e4061b5308c52e22634e399711ac6 Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Tue, 3 Sep 2024 00:16:59 -0400 Subject: [PATCH 14/31] test --- .../(main)/my-voyage/[teamId]/ideation/ideationService.ts | 2 +- src/di/config.ts | 4 ++-- .../infrastructure/adapters/ideationApiRepositoryImpl.ts | 2 +- .../{rest-api => restApi}/domain/entities/requestOptions.ts | 0 .../{rest-api => restApi}/domain/entities/restApiParams.ts | 0 .../{rest-api => restApi}/domain/ports/restApiRepository.ts | 2 +- .../infrastructure/adapters/nextJsRestApiRepository.ts} | 6 +++--- 7 files changed, 8 insertions(+), 8 deletions(-) rename src/modules/{rest-api => restApi}/domain/entities/requestOptions.ts (100%) rename src/modules/{rest-api => restApi}/domain/entities/restApiParams.ts (100%) rename src/modules/{rest-api => restApi}/domain/ports/restApiRepository.ts (86%) rename src/modules/{rest-api/infrastructure/adapters/NextJsRestApiRepository.ts => restApi/infrastructure/adapters/nextJsRestApiRepository.ts} (93%) diff --git a/src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts b/src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts index 3e50b86ff..ef5fff03c 100644 --- a/src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts +++ b/src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts @@ -7,7 +7,7 @@ import { type AsyncActionResponse, handleAsync } from "@/utils/handleAsync"; import { CacheTag } from "@/utils/cacheTag"; import { AddIdeationUseCase } from "@/modules/ideation/application/usecases/AddIdeationUseCase"; import type { AddIdeationUsecaseDto } from "@/modules/ideation/domain/dtos/request.dto"; -import { NextJsRestApiRepository } from "@/modules/rest-api/infrastructure/adapters/nextJsRestApiRepository"; +import { NextJsRestApiRepository } from "@/modules/restApi/infrastructure/adapters/nextJsRestApiRepository"; import { IdeationApiRepositoryImpl } from "@/modules/ideation/infrastructure/adapters/ideationApiRepositoryImpl"; import { type AddIdeationResponseDto } from "@/modules/ideation/domain/dtos/response.dto"; diff --git a/src/di/config.ts b/src/di/config.ts index 531808d9e..297af7b03 100644 --- a/src/di/config.ts +++ b/src/di/config.ts @@ -2,9 +2,9 @@ import { container } from "tsyringe"; import { TYPES } from "./types"; import { type IdeationApiRepository } from "@/modules/ideation/domain/ports/ideationApiRepository"; -import { NextJsRestApiRepository } from "@/modules/rest-api/infrastructure/adapters/nextJsRestApiRepository"; +import { NextJsRestApiRepository } from "@/modules/restApi/infrastructure/adapters/nextJsRestApiRepository"; import { IdeationApiRepositoryImpl } from "@/modules/ideation/infrastructure/adapters/ideationApiRepositoryImpl"; -import { type RestApiRepository } from "@/modules/rest-api/domain/ports/restApiRepository"; +import { type RestApiRepository } from "@/modules/restApi/domain/ports/restApiRepository"; import { AddIdeationUseCase } from "@/modules/ideation/application/usecases/AddIdeationUseCase"; container.register(TYPES.IdeationApiRepository, { diff --git a/src/modules/ideation/infrastructure/adapters/ideationApiRepositoryImpl.ts b/src/modules/ideation/infrastructure/adapters/ideationApiRepositoryImpl.ts index ea7eed9b7..212f66322 100644 --- a/src/modules/ideation/infrastructure/adapters/ideationApiRepositoryImpl.ts +++ b/src/modules/ideation/infrastructure/adapters/ideationApiRepositoryImpl.ts @@ -2,7 +2,7 @@ import { inject, injectable } from "tsyringe"; import { IdeationUrls } from "@/modules/ideation/constants/IdeationUrls"; import { TYPES } from "@/di/types"; import { type IdeationApiRepository } from "@/modules/ideation/domain/ports/ideationApiRepository"; -import { type RestApiRepository } from "@/modules/rest-api/domain/ports/restApiRepository"; +import { type RestApiRepository } from "@/modules/restApi/domain/ports/restApiRepository"; import type { AddIdeationBodyDto, AddIdeationRequestDto, diff --git a/src/modules/rest-api/domain/entities/requestOptions.ts b/src/modules/restApi/domain/entities/requestOptions.ts similarity index 100% rename from src/modules/rest-api/domain/entities/requestOptions.ts rename to src/modules/restApi/domain/entities/requestOptions.ts diff --git a/src/modules/rest-api/domain/entities/restApiParams.ts b/src/modules/restApi/domain/entities/restApiParams.ts similarity index 100% rename from src/modules/rest-api/domain/entities/restApiParams.ts rename to src/modules/restApi/domain/entities/restApiParams.ts diff --git a/src/modules/rest-api/domain/ports/restApiRepository.ts b/src/modules/restApi/domain/ports/restApiRepository.ts similarity index 86% rename from src/modules/rest-api/domain/ports/restApiRepository.ts rename to src/modules/restApi/domain/ports/restApiRepository.ts index b2a0c32a5..2e70f75d5 100644 --- a/src/modules/rest-api/domain/ports/restApiRepository.ts +++ b/src/modules/restApi/domain/ports/restApiRepository.ts @@ -4,7 +4,7 @@ import type { PatchParams, PostParams, UnauthPostParams, -} from "@/modules/rest-api/domain/entities/restApiParams"; +} from "@/modules/restApi/domain/entities/restApiParams"; export interface RestApiRepository { get(params: GetParams): Promise; diff --git a/src/modules/rest-api/infrastructure/adapters/NextJsRestApiRepository.ts b/src/modules/restApi/infrastructure/adapters/nextJsRestApiRepository.ts similarity index 93% rename from src/modules/rest-api/infrastructure/adapters/NextJsRestApiRepository.ts rename to src/modules/restApi/infrastructure/adapters/nextJsRestApiRepository.ts index 727510cc1..a2846847c 100644 --- a/src/modules/rest-api/infrastructure/adapters/NextJsRestApiRepository.ts +++ b/src/modules/restApi/infrastructure/adapters/nextJsRestApiRepository.ts @@ -1,12 +1,12 @@ -import { type RestApiRepository } from "@/modules/rest-api/domain/ports/restApiRepository"; +import { type RestApiRepository } from "@/modules/restApi/domain/ports/restApiRepository"; import type { DeleteParams, PatchParams, PostParams, UnauthPostParams, GetParams, -} from "@/modules/rest-api/domain/entities/restApiParams"; -import { type RequestOptions } from "@/modules/rest-api/domain/entities/requestOptions"; +} from "@/modules/restApi/domain/entities/restApiParams"; +import { type RequestOptions } from "@/modules/restApi/domain/entities/requestOptions"; type NextJsAuthRequestOptions = Required< Pick From 83dc75e745401299c1f9c593f0b5859d9d124c71 Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Tue, 3 Sep 2024 01:09:26 -0400 Subject: [PATCH 15/31] move dtos --- .../(main)/my-voyage/[teamId]/ideation/ideationService.ts | 4 ++-- src/modules/ideation/application/dtos/dtos.ts | 8 ++++++++ .../ideation/application/usecases/AddIdeationUseCase.ts | 4 ++-- .../application/usecases/AddIdeationVoteUseCase.ts | 4 ++-- .../application/usecases/DeleteIdeationUseCase.ts | 4 ++-- .../ideation/application/usecases/EditIdeationUseCase.ts | 4 ++-- .../application/usecases/FinalizeIdeationUseCase.ts | 4 ++-- .../application/usecases/RemoveIdeationVoteUseCase.ts | 4 ++-- .../ideation/domain/ports/ideationApiRepository.ts | 4 ++-- .../infrastructure/adapters/ideationApiRepositoryImpl.ts | 6 +++--- .../{domain => infrastructure}/dtos/common.dto.ts | 0 .../{domain => infrastructure}/dtos/request.dto.ts | 4 ---- .../{domain => infrastructure}/dtos/response.dto.ts | 0 .../infrastructure/adapters/nextJsRestApiRepository.ts | 2 +- 14 files changed, 28 insertions(+), 24 deletions(-) create mode 100644 src/modules/ideation/application/dtos/dtos.ts rename src/modules/ideation/{domain => infrastructure}/dtos/common.dto.ts (100%) rename src/modules/ideation/{domain => infrastructure}/dtos/request.dto.ts (89%) rename src/modules/ideation/{domain => infrastructure}/dtos/response.dto.ts (100%) diff --git a/src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts b/src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts index ef5fff03c..c3600ceb4 100644 --- a/src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts +++ b/src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts @@ -6,10 +6,10 @@ import { DELETE, PATCH, POST } from "@/utils/requests"; import { type AsyncActionResponse, handleAsync } from "@/utils/handleAsync"; import { CacheTag } from "@/utils/cacheTag"; import { AddIdeationUseCase } from "@/modules/ideation/application/usecases/AddIdeationUseCase"; -import type { AddIdeationUsecaseDto } from "@/modules/ideation/domain/dtos/request.dto"; +import type { AddIdeationUsecaseDto } from "@/modules/ideation/application/dtos/dtos"; import { NextJsRestApiRepository } from "@/modules/restApi/infrastructure/adapters/nextJsRestApiRepository"; import { IdeationApiRepositoryImpl } from "@/modules/ideation/infrastructure/adapters/ideationApiRepositoryImpl"; -import { type AddIdeationResponseDto } from "@/modules/ideation/domain/dtos/response.dto"; +import { type AddIdeationResponseDto } from "@/modules/ideation/infrastructure/dtos/response.dto"; interface IdeationProps { teamId: number; diff --git a/src/modules/ideation/application/dtos/dtos.ts b/src/modules/ideation/application/dtos/dtos.ts new file mode 100644 index 000000000..f555072da --- /dev/null +++ b/src/modules/ideation/application/dtos/dtos.ts @@ -0,0 +1,8 @@ +import type { + IdeationBodyDto, + IdeationRequestDto, +} from "@/modules/ideation/infrastructure/dtos/common.dto"; + +export interface AddIdeationUsecaseDto + extends Pick, + IdeationBodyDto {} diff --git a/src/modules/ideation/application/usecases/AddIdeationUseCase.ts b/src/modules/ideation/application/usecases/AddIdeationUseCase.ts index 60883dc4c..f78e17d4f 100644 --- a/src/modules/ideation/application/usecases/AddIdeationUseCase.ts +++ b/src/modules/ideation/application/usecases/AddIdeationUseCase.ts @@ -1,8 +1,8 @@ import { inject, injectable } from "tsyringe"; import { TYPES } from "@/di/types"; import { type IdeationApiRepository } from "@/modules/ideation/domain/ports/ideationApiRepository"; -import { type AddIdeationRequestDto } from "@/modules/ideation/domain/dtos/request.dto"; -import { type AddIdeationResponseDto } from "@/modules/ideation/domain/dtos/response.dto"; +import { type AddIdeationRequestDto } from "@/modules/ideation/infrastructure/dtos/request.dto"; +import { type AddIdeationResponseDto } from "@/modules/ideation/infrastructure/dtos/response.dto"; @injectable() export class AddIdeationUseCase { diff --git a/src/modules/ideation/application/usecases/AddIdeationVoteUseCase.ts b/src/modules/ideation/application/usecases/AddIdeationVoteUseCase.ts index 2afc7cec7..2c0cd8cb7 100644 --- a/src/modules/ideation/application/usecases/AddIdeationVoteUseCase.ts +++ b/src/modules/ideation/application/usecases/AddIdeationVoteUseCase.ts @@ -1,8 +1,8 @@ import { inject } from "tsyringe"; import { TYPES } from "@/di/types"; import { type IdeationApiRepository } from "@/modules/ideation/domain/ports/ideationApiRepository"; -import { type IdeationVoteRequestDto } from "@/modules/ideation/domain/dtos/request.dto"; -import { type IdeationVoteResponseDto } from "@/modules/ideation/domain/dtos/response.dto"; +import { type IdeationVoteRequestDto } from "@/modules/ideation/infrastructure/dtos/request.dto"; +import { type IdeationVoteResponseDto } from "@/modules/ideation/infrastructure/dtos/response.dto"; export class AddIdeationVoteUseCase { constructor( diff --git a/src/modules/ideation/application/usecases/DeleteIdeationUseCase.ts b/src/modules/ideation/application/usecases/DeleteIdeationUseCase.ts index a12b5eec4..865ebb4a2 100644 --- a/src/modules/ideation/application/usecases/DeleteIdeationUseCase.ts +++ b/src/modules/ideation/application/usecases/DeleteIdeationUseCase.ts @@ -1,8 +1,8 @@ import { inject } from "tsyringe"; import { TYPES } from "@/di/types"; import { type IdeationApiRepository } from "@/modules/ideation/domain/ports/ideationApiRepository"; -import { type DeleteIdeationRequestDto } from "@/modules/ideation/domain/dtos/request.dto"; -import { type DeleteIdeationResponseDto } from "@/modules/ideation/domain/dtos/response.dto"; +import { type DeleteIdeationRequestDto } from "@/modules/ideation/infrastructure/dtos/request.dto"; +import { type DeleteIdeationResponseDto } from "@/modules/ideation/infrastructure/dtos/response.dto"; export class DeleteIdeationUseCase { constructor( diff --git a/src/modules/ideation/application/usecases/EditIdeationUseCase.ts b/src/modules/ideation/application/usecases/EditIdeationUseCase.ts index 9bc8e1aed..dd6657f9f 100644 --- a/src/modules/ideation/application/usecases/EditIdeationUseCase.ts +++ b/src/modules/ideation/application/usecases/EditIdeationUseCase.ts @@ -2,8 +2,8 @@ import { inject } from "tsyringe"; import { TYPES } from "@/di/types"; import { type IdeationApiRepository } from "@/modules/ideation/domain/ports/ideationApiRepository"; -import { type EditIdeationRequestDto } from "@/modules/ideation/domain/dtos/request.dto"; -import { type EditIdeationResponseDto } from "@/modules/ideation/domain/dtos/response.dto"; +import { type EditIdeationRequestDto } from "@/modules/ideation/infrastructure/dtos/request.dto"; +import { type EditIdeationResponseDto } from "@/modules/ideation/infrastructure/dtos/response.dto"; export class EditIdeationUseCase { constructor( diff --git a/src/modules/ideation/application/usecases/FinalizeIdeationUseCase.ts b/src/modules/ideation/application/usecases/FinalizeIdeationUseCase.ts index 4ea2e1f98..ee8c30730 100644 --- a/src/modules/ideation/application/usecases/FinalizeIdeationUseCase.ts +++ b/src/modules/ideation/application/usecases/FinalizeIdeationUseCase.ts @@ -1,8 +1,8 @@ import { inject } from "tsyringe"; import { TYPES } from "@/di/types"; import { type IdeationApiRepository } from "@/modules/ideation/domain/ports/ideationApiRepository"; -import { type FinalizeIdeationRequestDto } from "@/modules/ideation/domain/dtos/request.dto"; -import { type FinalizeIdeationResponseDto } from "@/modules/ideation/domain/dtos/response.dto"; +import { type FinalizeIdeationRequestDto } from "@/modules/ideation/infrastructure/dtos/request.dto"; +import { type FinalizeIdeationResponseDto } from "@/modules/ideation/infrastructure/dtos/response.dto"; export class FinalizeIdeationUseCase { constructor( diff --git a/src/modules/ideation/application/usecases/RemoveIdeationVoteUseCase.ts b/src/modules/ideation/application/usecases/RemoveIdeationVoteUseCase.ts index 72179f641..05e77da27 100644 --- a/src/modules/ideation/application/usecases/RemoveIdeationVoteUseCase.ts +++ b/src/modules/ideation/application/usecases/RemoveIdeationVoteUseCase.ts @@ -1,8 +1,8 @@ import { inject } from "tsyringe"; import { TYPES } from "@/di/types"; import { type IdeationApiRepository } from "@/modules/ideation/domain/ports/ideationApiRepository"; -import { type IdeationVoteRequestDto } from "@/modules/ideation/domain/dtos/request.dto"; -import { type IdeationVoteResponseDto } from "@/modules/ideation/domain/dtos/response.dto"; +import { type IdeationVoteRequestDto } from "@/modules/ideation/infrastructure/dtos/request.dto"; +import { type IdeationVoteResponseDto } from "@/modules/ideation/infrastructure/dtos/response.dto"; export class RemoveIdeationVoteUseCase { constructor( diff --git a/src/modules/ideation/domain/ports/ideationApiRepository.ts b/src/modules/ideation/domain/ports/ideationApiRepository.ts index c3f55bb91..6de05ac99 100644 --- a/src/modules/ideation/domain/ports/ideationApiRepository.ts +++ b/src/modules/ideation/domain/ports/ideationApiRepository.ts @@ -4,7 +4,7 @@ import type { EditIdeationRequestDto, FinalizeIdeationRequestDto, IdeationVoteRequestDto, -} from "@/modules/ideation/domain/dtos/request.dto"; +} from "@/modules/ideation/infrastructure/dtos/request.dto"; import type { AddIdeationResponseDto, @@ -12,7 +12,7 @@ import type { EditIdeationResponseDto, FinalizeIdeationResponseDto, IdeationVoteResponseDto, -} from "@/modules/ideation/domain/dtos/response.dto"; +} from "@/modules/ideation/infrastructure/dtos/response.dto"; export interface IdeationApiRepository { addIdeation: ( diff --git a/src/modules/ideation/infrastructure/adapters/ideationApiRepositoryImpl.ts b/src/modules/ideation/infrastructure/adapters/ideationApiRepositoryImpl.ts index 212f66322..f0e02d788 100644 --- a/src/modules/ideation/infrastructure/adapters/ideationApiRepositoryImpl.ts +++ b/src/modules/ideation/infrastructure/adapters/ideationApiRepositoryImpl.ts @@ -1,5 +1,5 @@ import { inject, injectable } from "tsyringe"; -import { IdeationUrls } from "@/modules/ideation/constants/IdeationUrls"; +import { IdeationUrls } from "@/modules/ideation/constants/ideationUrls"; import { TYPES } from "@/di/types"; import { type IdeationApiRepository } from "@/modules/ideation/domain/ports/ideationApiRepository"; import { type RestApiRepository } from "@/modules/restApi/domain/ports/restApiRepository"; @@ -11,14 +11,14 @@ import type { EditIdeationRequestDto, FinalizeIdeationRequestDto, IdeationVoteRequestDto, -} from "@/modules/ideation/domain/dtos/request.dto"; +} from "@/modules/ideation/infrastructure/dtos/request.dto"; import type { EditIdeationResponseDto, AddIdeationResponseDto, DeleteIdeationResponseDto, IdeationVoteResponseDto, FinalizeIdeationResponseDto, -} from "@/modules/ideation/domain/dtos/response.dto"; +} from "@/modules/ideation/infrastructure/dtos/response.dto"; /** * Repository (adapter) implementing the port diff --git a/src/modules/ideation/domain/dtos/common.dto.ts b/src/modules/ideation/infrastructure/dtos/common.dto.ts similarity index 100% rename from src/modules/ideation/domain/dtos/common.dto.ts rename to src/modules/ideation/infrastructure/dtos/common.dto.ts diff --git a/src/modules/ideation/domain/dtos/request.dto.ts b/src/modules/ideation/infrastructure/dtos/request.dto.ts similarity index 89% rename from src/modules/ideation/domain/dtos/request.dto.ts rename to src/modules/ideation/infrastructure/dtos/request.dto.ts index 7cb47854e..1d6045755 100644 --- a/src/modules/ideation/domain/dtos/request.dto.ts +++ b/src/modules/ideation/infrastructure/dtos/request.dto.ts @@ -13,10 +13,6 @@ export interface AddIdeationRequestDto token?: string; } -export interface AddIdeationUsecaseDto - extends Pick, - IdeationBodyDto {} - export type EditIdeationRequestDto = EditIdeationBodyDto & Omit & { cache?: RequestCache; diff --git a/src/modules/ideation/domain/dtos/response.dto.ts b/src/modules/ideation/infrastructure/dtos/response.dto.ts similarity index 100% rename from src/modules/ideation/domain/dtos/response.dto.ts rename to src/modules/ideation/infrastructure/dtos/response.dto.ts diff --git a/src/modules/restApi/infrastructure/adapters/nextJsRestApiRepository.ts b/src/modules/restApi/infrastructure/adapters/nextJsRestApiRepository.ts index a2846847c..7a4c5a781 100644 --- a/src/modules/restApi/infrastructure/adapters/nextJsRestApiRepository.ts +++ b/src/modules/restApi/infrastructure/adapters/nextJsRestApiRepository.ts @@ -33,7 +33,7 @@ interface NextJsDeleteParams extends Omit { } interface NextJsUnauthParams extends Omit, "options"> { - options: NextJsUnAuthRequestionOptions; + options: NextJsUnAuthRequestionOptions; // Enforce required options } export class NextJsRestApiRepository implements RestApiRepository { From b5dcce9c4148c5fceed3984ab01b0bcdc015c920 Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Tue, 3 Sep 2024 20:50:13 -0400 Subject: [PATCH 16/31] refactor folder structure --- .../[teamId]/ideation/ideationService.ts | 45 ++++++++----------- src/di/config.ts | 21 ++++----- src/di/injectables.ts | 12 ++--- src/di/types.ts | 10 +++-- .../secondary/ideationApiAdapter.ts} | 17 +++---- .../{dtos.ts => addIdeationUsecaseDto.ts} | 2 +- .../dtos/common.dto.ts | 3 +- .../dtos/request.dto.ts | 0 .../dtos/response.dto.ts | 0 .../entities/ideation.ts} | 2 +- .../entities/ideationVotes.ts} | 0 .../usecases/AddIdeationUseCase.ts | 12 ++--- .../usecases/AddIdeationVoteUseCase.ts | 12 ++--- .../usecases/DeleteIdeationUseCase.ts | 12 ++--- .../usecases/EditIdeationUseCase.ts | 13 +++--- .../usecases/FinalizeIdeationUseCase.ts | 12 ++--- .../usecases/RemoveIdeationVoteUseCase.ts | 12 ++--- .../ideation/ports/primary/addIdeationPort.ts | 6 +++ .../ports/primary/addIdeationVotePort.ts | 8 ++++ .../ports/primary/deleteIdeationPort.ts | 8 ++++ .../ports/primary/editIdeationPort.ts | 6 +++ .../ports/primary/finalizeIdeationPort.ts | 8 ++++ .../ports/primary/removeIdeationVotePort.ts | 8 ++++ .../secondary/ideationApiPort.ts} | 6 +-- .../secondary/nextJsRestApiAdapter.ts} | 8 ++-- .../entities/requestOptions.ts | 0 .../entities/restApiParams.ts | 0 .../secondary/restApiPort.ts} | 4 +- 28 files changed, 138 insertions(+), 109 deletions(-) rename src/modules/ideation/{infrastructure/adapters/ideationApiRepositoryImpl.ts => adapters/secondary/ideationApiAdapter.ts} (84%) rename src/modules/ideation/application/dtos/{dtos.ts => addIdeationUsecaseDto.ts} (73%) rename src/modules/ideation/{infrastructure => application}/dtos/common.dto.ts (64%) rename src/modules/ideation/{infrastructure => application}/dtos/request.dto.ts (100%) rename src/modules/ideation/{infrastructure => application}/dtos/response.dto.ts (100%) rename src/modules/ideation/{domain/entities/Ideation.ts => application/entities/ideation.ts} (89%) rename src/modules/ideation/{domain/entities/IdeationVotes.ts => application/entities/ideationVotes.ts} (100%) create mode 100644 src/modules/ideation/ports/primary/addIdeationPort.ts create mode 100644 src/modules/ideation/ports/primary/addIdeationVotePort.ts create mode 100644 src/modules/ideation/ports/primary/deleteIdeationPort.ts create mode 100644 src/modules/ideation/ports/primary/editIdeationPort.ts create mode 100644 src/modules/ideation/ports/primary/finalizeIdeationPort.ts create mode 100644 src/modules/ideation/ports/primary/removeIdeationVotePort.ts rename src/modules/ideation/{domain/ports/ideationApiRepository.ts => ports/secondary/ideationApiPort.ts} (84%) rename src/modules/restApi/{infrastructure/adapters/nextJsRestApiRepository.ts => adapters/secondary/nextJsRestApiAdapter.ts} (92%) rename src/modules/restApi/{domain => application}/entities/requestOptions.ts (100%) rename src/modules/restApi/{domain => application}/entities/restApiParams.ts (100%) rename src/modules/restApi/{domain/ports/restApiRepository.ts => ports/secondary/restApiPort.ts} (78%) diff --git a/src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts b/src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts index c3600ceb4..7ae51f310 100644 --- a/src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts +++ b/src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts @@ -5,11 +5,11 @@ import { getAccessToken } from "@/utils/getCookie"; import { DELETE, PATCH, POST } from "@/utils/requests"; import { type AsyncActionResponse, handleAsync } from "@/utils/handleAsync"; import { CacheTag } from "@/utils/cacheTag"; -import { AddIdeationUseCase } from "@/modules/ideation/application/usecases/AddIdeationUseCase"; -import type { AddIdeationUsecaseDto } from "@/modules/ideation/application/dtos/dtos"; -import { NextJsRestApiRepository } from "@/modules/restApi/infrastructure/adapters/nextJsRestApiRepository"; -import { IdeationApiRepositoryImpl } from "@/modules/ideation/infrastructure/adapters/ideationApiRepositoryImpl"; -import { type AddIdeationResponseDto } from "@/modules/ideation/infrastructure/dtos/response.dto"; +import { AddIdeationUseCase } from "@/modules/ideation/application/usecases/addIdeationUseCase"; +import { type AddIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; +import { NextJsRestApiAdapter } from "@/modules/restApi/adapters/secondary/nextJsRestApiAdapter"; +import { IdeationApiAdapter } from "@/modules/ideation/adapters/secondary/ideationApiAdapter"; +import { type AddIdeationUsecaseDto } from "@/modules/ideation/application/dtos/addIdeationUsecaseDto"; interface IdeationProps { teamId: number; @@ -58,12 +58,10 @@ export interface IdeationVoteResponse extends IdeationResponse { projectIdeaId: number; } -const nextJsRestApiRepository = new NextJsRestApiRepository( +const nextJsRestApiAdapter = new NextJsRestApiAdapter( process.env.NEXT_PUBLIC_API_URL!, ); -const ideationApiRepository = new IdeationApiRepositoryImpl( - nextJsRestApiRepository, -); +const ideationApiPort = new IdeationApiAdapter(nextJsRestApiAdapter); export async function addIdeation({ teamId, @@ -74,14 +72,11 @@ export async function addIdeation({ AsyncActionResponse > { const token = getAccessToken(); - const addIdeationUseCase = new AddIdeationUseCase(ideationApiRepository); - - // const addIdeationUseCase = container.resolve( - // TYPES.AddIdeationUseCase, - // ); + const addIdeationUseCase = new AddIdeationUseCase(ideationApiPort); - try { - const addIdeationAsync = await addIdeationUseCase.execute({ + // refactor this later to not expect a function + const addIdeationAsync = async () => + await addIdeationUseCase.execute({ teamId, title, description, @@ -90,18 +85,14 @@ export async function addIdeation({ token, }); - if (addIdeationAsync) { - revalidateTag(CacheTag.ideation); - } - - return [addIdeationAsync, null]; - } catch (error) { - if (error instanceof Error) { - return [null, { message: error.message }]; - } else { - throw error; - } + const [res, error] = + await handleAsync(addIdeationAsync); + + if (res) { + revalidateTag(CacheTag.ideation); } + + return [res, error]; } // export async function addIdeation({ diff --git a/src/di/config.ts b/src/di/config.ts index 297af7b03..7bc62de24 100644 --- a/src/di/config.ts +++ b/src/di/config.ts @@ -1,22 +1,17 @@ import { container } from "tsyringe"; import { TYPES } from "./types"; -import { type IdeationApiRepository } from "@/modules/ideation/domain/ports/ideationApiRepository"; -import { NextJsRestApiRepository } from "@/modules/restApi/infrastructure/adapters/nextJsRestApiRepository"; -import { IdeationApiRepositoryImpl } from "@/modules/ideation/infrastructure/adapters/ideationApiRepositoryImpl"; -import { type RestApiRepository } from "@/modules/restApi/domain/ports/restApiRepository"; -import { AddIdeationUseCase } from "@/modules/ideation/application/usecases/AddIdeationUseCase"; +import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; +import { IdeationApiAdapter } from "@/modules/ideation/adapters/secondary/ideationApiAdapter"; +import { type RestApiPort } from "@/modules/restApi/ports/secondary/restApiPort"; +import { NextJsRestApiAdapter } from "@/modules/restApi/adapters/secondary/nextJsRestApiAdapter"; -container.register(TYPES.IdeationApiRepository, { - useClass: IdeationApiRepositoryImpl, +container.register(TYPES.IdeationApiPort, { + useClass: IdeationApiAdapter, }); -container.register(TYPES.RestApiRepository, { - useValue: new NextJsRestApiRepository(process.env.NEXT_PUBLIC_API_URL!), -}); - -container.register(TYPES.AddIdeationUseCase, { - useClass: AddIdeationUseCase, +container.register(TYPES.RestApiPort, { + useValue: new NextJsRestApiAdapter(process.env.NEXT_PUBLIC_API_URL!), }); export default container; diff --git a/src/di/injectables.ts b/src/di/injectables.ts index 184cc5de1..b65700683 100644 --- a/src/di/injectables.ts +++ b/src/di/injectables.ts @@ -1,11 +1,11 @@ import { container } from "tsyringe"; import { TYPES } from "./types"; -import type { AddIdeationUseCase } from "@/modules/ideation/application/usecases/AddIdeationUseCase"; -import type { AddIdeationVoteUseCase } from "@/modules/ideation/application/usecases/AddIdeationVoteUseCase"; -import type { DeleteIdeationUseCase } from "@/modules/ideation/application/usecases/DeleteIdeationUseCase"; -import type { EditIdeationUseCase } from "@/modules/ideation/application/usecases/EditIdeationUseCase"; -import type { FinalizeIdeationUseCase } from "@/modules/ideation/application/usecases/FinalizeIdeationUseCase"; -import type { RemoveIdeationVoteUseCase } from "@/modules/ideation/application/usecases/RemoveIdeationVoteUseCase"; +import type { AddIdeationUseCase } from "@/modules/ideation/application/usecases/addIdeationUseCase"; +import type { AddIdeationVoteUseCase } from "@/modules/ideation/application/usecases/addIdeationVoteUseCase"; +import type { DeleteIdeationUseCase } from "@/modules/ideation/application/usecases/deleteIdeationUseCase"; +import type { EditIdeationUseCase } from "@/modules/ideation/application/usecases/editIdeationUseCase"; +import type { FinalizeIdeationUseCase } from "@/modules/ideation/application/usecases/finalizeIdeationUseCase"; +import type { RemoveIdeationVoteUseCase } from "@/modules/ideation/application/usecases/removeIdeationVoteUseCase"; export const injectables = { /* Ideation */ diff --git a/src/di/types.ts b/src/di/types.ts index f487ccc47..9138fcf34 100644 --- a/src/di/types.ts +++ b/src/di/types.ts @@ -1,7 +1,11 @@ export const TYPES = { - /* Repositories */ - RestApiRepository: Symbol.for("RestApiRepository"), - IdeationApiRepository: Symbol.for("IdeationApiRepository"), + /* Ports */ + RestApiPort: Symbol.for("RestApiPort"), + IdeationApiPort: Symbol.for("IdeationApiPort"), + + /* Adapters */ + // NextJsRestApiAdapter: Symbol.for("NextJsRestApiAdapter"), + IdeationApiAdapter: Symbol.for("IdeationApiAdapter"), /* UseCases */ AddIdeationUseCase: Symbol.for("AddIdeationUseCase"), diff --git a/src/modules/ideation/infrastructure/adapters/ideationApiRepositoryImpl.ts b/src/modules/ideation/adapters/secondary/ideationApiAdapter.ts similarity index 84% rename from src/modules/ideation/infrastructure/adapters/ideationApiRepositoryImpl.ts rename to src/modules/ideation/adapters/secondary/ideationApiAdapter.ts index f0e02d788..764602534 100644 --- a/src/modules/ideation/infrastructure/adapters/ideationApiRepositoryImpl.ts +++ b/src/modules/ideation/adapters/secondary/ideationApiAdapter.ts @@ -1,8 +1,8 @@ import { inject, injectable } from "tsyringe"; import { IdeationUrls } from "@/modules/ideation/constants/ideationUrls"; import { TYPES } from "@/di/types"; -import { type IdeationApiRepository } from "@/modules/ideation/domain/ports/ideationApiRepository"; -import { type RestApiRepository } from "@/modules/restApi/domain/ports/restApiRepository"; +import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; +import { type RestApiPort } from "@/modules/restApi/ports/secondary/restApiPort"; import type { AddIdeationBodyDto, AddIdeationRequestDto, @@ -11,23 +11,20 @@ import type { EditIdeationRequestDto, FinalizeIdeationRequestDto, IdeationVoteRequestDto, -} from "@/modules/ideation/infrastructure/dtos/request.dto"; +} from "@/modules/ideation/application/dtos/request.dto"; import type { EditIdeationResponseDto, AddIdeationResponseDto, DeleteIdeationResponseDto, IdeationVoteResponseDto, FinalizeIdeationResponseDto, -} from "@/modules/ideation/infrastructure/dtos/response.dto"; +} from "@/modules/ideation/application/dtos/response.dto"; -/** - * Repository (adapter) implementing the port - */ @injectable() -export class IdeationApiRepositoryImpl implements IdeationApiRepository { +export class IdeationApiAdapter implements IdeationApiPort { constructor( - @inject(TYPES.RestApiRepository) - private readonly apiClient: RestApiRepository, + @inject(TYPES.RestApiPort) + private readonly apiClient: RestApiPort, ) {} async addIdeation({ diff --git a/src/modules/ideation/application/dtos/dtos.ts b/src/modules/ideation/application/dtos/addIdeationUsecaseDto.ts similarity index 73% rename from src/modules/ideation/application/dtos/dtos.ts rename to src/modules/ideation/application/dtos/addIdeationUsecaseDto.ts index f555072da..d747f3874 100644 --- a/src/modules/ideation/application/dtos/dtos.ts +++ b/src/modules/ideation/application/dtos/addIdeationUsecaseDto.ts @@ -1,7 +1,7 @@ import type { IdeationBodyDto, IdeationRequestDto, -} from "@/modules/ideation/infrastructure/dtos/common.dto"; +} from "@/modules/ideation/application/dtos/common.dto"; export interface AddIdeationUsecaseDto extends Pick, diff --git a/src/modules/ideation/infrastructure/dtos/common.dto.ts b/src/modules/ideation/application/dtos/common.dto.ts similarity index 64% rename from src/modules/ideation/infrastructure/dtos/common.dto.ts rename to src/modules/ideation/application/dtos/common.dto.ts index 5283ba52c..f6fbf7238 100644 --- a/src/modules/ideation/infrastructure/dtos/common.dto.ts +++ b/src/modules/ideation/application/dtos/common.dto.ts @@ -1,11 +1,10 @@ -import { type Ideation } from "@/modules/ideation/domain/entities/Ideation"; +import { type Ideation } from "@/modules/ideation/application/entities/ideation"; export type IdeationBodyDto = Pick< Ideation, "title" | "description" | "vision" >; -// IdeationProps export interface IdeationRequestDto { teamId: number; ideationId: number; diff --git a/src/modules/ideation/infrastructure/dtos/request.dto.ts b/src/modules/ideation/application/dtos/request.dto.ts similarity index 100% rename from src/modules/ideation/infrastructure/dtos/request.dto.ts rename to src/modules/ideation/application/dtos/request.dto.ts diff --git a/src/modules/ideation/infrastructure/dtos/response.dto.ts b/src/modules/ideation/application/dtos/response.dto.ts similarity index 100% rename from src/modules/ideation/infrastructure/dtos/response.dto.ts rename to src/modules/ideation/application/dtos/response.dto.ts diff --git a/src/modules/ideation/domain/entities/Ideation.ts b/src/modules/ideation/application/entities/ideation.ts similarity index 89% rename from src/modules/ideation/domain/entities/Ideation.ts rename to src/modules/ideation/application/entities/ideation.ts index dcd539d59..ac2f2e523 100644 --- a/src/modules/ideation/domain/entities/Ideation.ts +++ b/src/modules/ideation/application/entities/ideation.ts @@ -1,4 +1,4 @@ -import { type IdeationVotes } from "./IdeationVotes"; +import { type IdeationVotes } from "./ideationVotes"; import { type VoyageMember } from "@/store/features/ideation/ideationSlice"; // importing the voyage member from the store for now but it would ideally be imported from a different domain in modules folder diff --git a/src/modules/ideation/domain/entities/IdeationVotes.ts b/src/modules/ideation/application/entities/ideationVotes.ts similarity index 100% rename from src/modules/ideation/domain/entities/IdeationVotes.ts rename to src/modules/ideation/application/entities/ideationVotes.ts diff --git a/src/modules/ideation/application/usecases/AddIdeationUseCase.ts b/src/modules/ideation/application/usecases/AddIdeationUseCase.ts index f78e17d4f..2afcc8755 100644 --- a/src/modules/ideation/application/usecases/AddIdeationUseCase.ts +++ b/src/modules/ideation/application/usecases/AddIdeationUseCase.ts @@ -1,18 +1,18 @@ import { inject, injectable } from "tsyringe"; import { TYPES } from "@/di/types"; -import { type IdeationApiRepository } from "@/modules/ideation/domain/ports/ideationApiRepository"; -import { type AddIdeationRequestDto } from "@/modules/ideation/infrastructure/dtos/request.dto"; -import { type AddIdeationResponseDto } from "@/modules/ideation/infrastructure/dtos/response.dto"; +import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; +import { type AddIdeationRequestDto } from "@/modules/ideation/application/dtos/request.dto"; +import { type AddIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; @injectable() export class AddIdeationUseCase { constructor( - @inject(TYPES.IdeationApiRepository) - private readonly ideationApiRepository: IdeationApiRepository, + @inject(TYPES.IdeationApiPort) + private readonly ideationApi: IdeationApiPort, ) {} async execute(props: AddIdeationRequestDto): Promise { - return await this.ideationApiRepository.addIdeation({ + return await this.ideationApi.addIdeation({ ...props, }); } diff --git a/src/modules/ideation/application/usecases/AddIdeationVoteUseCase.ts b/src/modules/ideation/application/usecases/AddIdeationVoteUseCase.ts index 2c0cd8cb7..1c604b76b 100644 --- a/src/modules/ideation/application/usecases/AddIdeationVoteUseCase.ts +++ b/src/modules/ideation/application/usecases/AddIdeationVoteUseCase.ts @@ -1,19 +1,19 @@ import { inject } from "tsyringe"; import { TYPES } from "@/di/types"; -import { type IdeationApiRepository } from "@/modules/ideation/domain/ports/ideationApiRepository"; -import { type IdeationVoteRequestDto } from "@/modules/ideation/infrastructure/dtos/request.dto"; -import { type IdeationVoteResponseDto } from "@/modules/ideation/infrastructure/dtos/response.dto"; +import { type IdeationVoteRequestDto } from "@/modules/ideation/application/dtos/request.dto"; +import { type IdeationVoteResponseDto } from "@/modules/ideation/application/dtos/response.dto"; +import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; export class AddIdeationVoteUseCase { constructor( - @inject(TYPES.IdeationApiRepository) - private readonly ideationApiRepository: IdeationApiRepository, + @inject(TYPES.IdeationApiPort) + private readonly ideationApi: IdeationApiPort, ) {} async execute( props: IdeationVoteRequestDto, ): Promise { - return await this.ideationApiRepository.addIdeationVote({ + return await this.ideationApi.addIdeationVote({ ...props, }); } diff --git a/src/modules/ideation/application/usecases/DeleteIdeationUseCase.ts b/src/modules/ideation/application/usecases/DeleteIdeationUseCase.ts index 865ebb4a2..58b56290d 100644 --- a/src/modules/ideation/application/usecases/DeleteIdeationUseCase.ts +++ b/src/modules/ideation/application/usecases/DeleteIdeationUseCase.ts @@ -1,19 +1,19 @@ import { inject } from "tsyringe"; import { TYPES } from "@/di/types"; -import { type IdeationApiRepository } from "@/modules/ideation/domain/ports/ideationApiRepository"; -import { type DeleteIdeationRequestDto } from "@/modules/ideation/infrastructure/dtos/request.dto"; -import { type DeleteIdeationResponseDto } from "@/modules/ideation/infrastructure/dtos/response.dto"; +import { type DeleteIdeationRequestDto } from "@/modules/ideation/application/dtos/request.dto"; +import { type DeleteIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; +import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; export class DeleteIdeationUseCase { constructor( - @inject(TYPES.IdeationApiRepository) - private readonly ideationApiRepository: IdeationApiRepository, + @inject(TYPES.IdeationApiPort) + private readonly ideationApi: IdeationApiPort, ) {} async execute( props: DeleteIdeationRequestDto, ): Promise { - return await this.ideationApiRepository.deleteIdeation({ + return await this.ideationApi.deleteIdeation({ ...props, }); } diff --git a/src/modules/ideation/application/usecases/EditIdeationUseCase.ts b/src/modules/ideation/application/usecases/EditIdeationUseCase.ts index dd6657f9f..540c1c203 100644 --- a/src/modules/ideation/application/usecases/EditIdeationUseCase.ts +++ b/src/modules/ideation/application/usecases/EditIdeationUseCase.ts @@ -1,20 +1,19 @@ import { inject } from "tsyringe"; import { TYPES } from "@/di/types"; - -import { type IdeationApiRepository } from "@/modules/ideation/domain/ports/ideationApiRepository"; -import { type EditIdeationRequestDto } from "@/modules/ideation/infrastructure/dtos/request.dto"; -import { type EditIdeationResponseDto } from "@/modules/ideation/infrastructure/dtos/response.dto"; +import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; +import { type EditIdeationRequestDto } from "@/modules/ideation/application/dtos/request.dto"; +import { type EditIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; export class EditIdeationUseCase { constructor( - @inject(TYPES.IdeationApiRepository) - private readonly ideationApiRepository: IdeationApiRepository, + @inject(TYPES.IdeationApiPort) + private readonly ideationApi: IdeationApiPort, ) {} async execute( props: EditIdeationRequestDto, ): Promise { - return await this.ideationApiRepository.editIdeation({ + return await this.ideationApi.editIdeation({ ...props, }); } diff --git a/src/modules/ideation/application/usecases/FinalizeIdeationUseCase.ts b/src/modules/ideation/application/usecases/FinalizeIdeationUseCase.ts index ee8c30730..46364836b 100644 --- a/src/modules/ideation/application/usecases/FinalizeIdeationUseCase.ts +++ b/src/modules/ideation/application/usecases/FinalizeIdeationUseCase.ts @@ -1,19 +1,19 @@ import { inject } from "tsyringe"; import { TYPES } from "@/di/types"; -import { type IdeationApiRepository } from "@/modules/ideation/domain/ports/ideationApiRepository"; -import { type FinalizeIdeationRequestDto } from "@/modules/ideation/infrastructure/dtos/request.dto"; -import { type FinalizeIdeationResponseDto } from "@/modules/ideation/infrastructure/dtos/response.dto"; +import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; +import { type FinalizeIdeationRequestDto } from "@/modules/ideation/application/dtos/request.dto"; +import { type FinalizeIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; export class FinalizeIdeationUseCase { constructor( - @inject(TYPES.IdeationApiRepository) - private readonly ideationApiRepository: IdeationApiRepository, + @inject(TYPES.IdeationApiPort) + private readonly ideationApi: IdeationApiPort, ) {} async execute( props: FinalizeIdeationRequestDto, ): Promise { - return await this.ideationApiRepository.finalizeIdeation({ + return await this.ideationApi.finalizeIdeation({ ...props, }); } diff --git a/src/modules/ideation/application/usecases/RemoveIdeationVoteUseCase.ts b/src/modules/ideation/application/usecases/RemoveIdeationVoteUseCase.ts index 05e77da27..e1be4f03d 100644 --- a/src/modules/ideation/application/usecases/RemoveIdeationVoteUseCase.ts +++ b/src/modules/ideation/application/usecases/RemoveIdeationVoteUseCase.ts @@ -1,19 +1,19 @@ import { inject } from "tsyringe"; import { TYPES } from "@/di/types"; -import { type IdeationApiRepository } from "@/modules/ideation/domain/ports/ideationApiRepository"; -import { type IdeationVoteRequestDto } from "@/modules/ideation/infrastructure/dtos/request.dto"; -import { type IdeationVoteResponseDto } from "@/modules/ideation/infrastructure/dtos/response.dto"; +import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; +import { type IdeationVoteRequestDto } from "@/modules/ideation/application/dtos/request.dto"; +import { type IdeationVoteResponseDto } from "@/modules/ideation/application/dtos/response.dto"; export class RemoveIdeationVoteUseCase { constructor( - @inject(TYPES.IdeationApiRepository) - private readonly ideationApiRepository: IdeationApiRepository, + @inject(TYPES.IdeationApiPort) + private readonly ideationApi: IdeationApiPort, ) {} async execute( props: IdeationVoteRequestDto, ): Promise { - return await this.ideationApiRepository.removeIdeationVote({ + return await this.ideationApi.removeIdeationVote({ ...props, }); } diff --git a/src/modules/ideation/ports/primary/addIdeationPort.ts b/src/modules/ideation/ports/primary/addIdeationPort.ts new file mode 100644 index 000000000..70d4d73f4 --- /dev/null +++ b/src/modules/ideation/ports/primary/addIdeationPort.ts @@ -0,0 +1,6 @@ +import type { AddIdeationRequestDto } from "@/modules/ideation/application/dtos/request.dto"; +import type { AddIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; + +export interface AddIdeationPort { + execute(props: AddIdeationRequestDto): Promise; +} diff --git a/src/modules/ideation/ports/primary/addIdeationVotePort.ts b/src/modules/ideation/ports/primary/addIdeationVotePort.ts new file mode 100644 index 000000000..7716da22c --- /dev/null +++ b/src/modules/ideation/ports/primary/addIdeationVotePort.ts @@ -0,0 +1,8 @@ +import { type IdeationVoteRequestDto } from "@/modules/ideation/application/dtos/request.dto"; +import { type IdeationVoteResponseDto } from "@/modules/ideation/application/dtos/response.dto"; + +export interface AddIdeationVotePort { + addIdeationVote( + props: IdeationVoteRequestDto, + ): Promise; +} diff --git a/src/modules/ideation/ports/primary/deleteIdeationPort.ts b/src/modules/ideation/ports/primary/deleteIdeationPort.ts new file mode 100644 index 000000000..765c9ac1b --- /dev/null +++ b/src/modules/ideation/ports/primary/deleteIdeationPort.ts @@ -0,0 +1,8 @@ +import { type DeleteIdeationRequestDto } from "@/modules/ideation/application/dtos/request.dto"; +import { type DeleteIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; + +export interface DeleteIdeationPort { + deleteIdeation( + props: DeleteIdeationRequestDto, + ): Promise; +} diff --git a/src/modules/ideation/ports/primary/editIdeationPort.ts b/src/modules/ideation/ports/primary/editIdeationPort.ts new file mode 100644 index 000000000..af3414dc4 --- /dev/null +++ b/src/modules/ideation/ports/primary/editIdeationPort.ts @@ -0,0 +1,6 @@ +import { type EditIdeationRequestDto } from "@/modules/ideation/application/dtos/request.dto"; +import { type EditIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; + +export interface EditIdeationPort { + editIdeation(props: EditIdeationRequestDto): Promise; +} diff --git a/src/modules/ideation/ports/primary/finalizeIdeationPort.ts b/src/modules/ideation/ports/primary/finalizeIdeationPort.ts new file mode 100644 index 000000000..3daf6526a --- /dev/null +++ b/src/modules/ideation/ports/primary/finalizeIdeationPort.ts @@ -0,0 +1,8 @@ +import { type FinalizeIdeationRequestDto } from "@/modules/ideation/application/dtos/request.dto"; +import { type FinalizeIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; + +export interface FinalizeIdeationPort { + finalizeIdeation( + props: FinalizeIdeationRequestDto, + ): Promise; +} diff --git a/src/modules/ideation/ports/primary/removeIdeationVotePort.ts b/src/modules/ideation/ports/primary/removeIdeationVotePort.ts new file mode 100644 index 000000000..116435af3 --- /dev/null +++ b/src/modules/ideation/ports/primary/removeIdeationVotePort.ts @@ -0,0 +1,8 @@ +import { type IdeationVoteRequestDto } from "@/modules/ideation/application/dtos/request.dto"; +import { type IdeationVoteResponseDto } from "@/modules/ideation/application/dtos/response.dto"; + +export interface RemoveIdeationVotePort { + removeIdeationVote( + props: IdeationVoteRequestDto, + ): Promise; +} diff --git a/src/modules/ideation/domain/ports/ideationApiRepository.ts b/src/modules/ideation/ports/secondary/ideationApiPort.ts similarity index 84% rename from src/modules/ideation/domain/ports/ideationApiRepository.ts rename to src/modules/ideation/ports/secondary/ideationApiPort.ts index 6de05ac99..2174ef961 100644 --- a/src/modules/ideation/domain/ports/ideationApiRepository.ts +++ b/src/modules/ideation/ports/secondary/ideationApiPort.ts @@ -4,7 +4,7 @@ import type { EditIdeationRequestDto, FinalizeIdeationRequestDto, IdeationVoteRequestDto, -} from "@/modules/ideation/infrastructure/dtos/request.dto"; +} from "@/modules/ideation/application/dtos/request.dto"; import type { AddIdeationResponseDto, @@ -12,9 +12,9 @@ import type { EditIdeationResponseDto, FinalizeIdeationResponseDto, IdeationVoteResponseDto, -} from "@/modules/ideation/infrastructure/dtos/response.dto"; +} from "@/modules/ideation/application/dtos/response.dto"; -export interface IdeationApiRepository { +export interface IdeationApiPort { addIdeation: ( props: AddIdeationRequestDto, ) => Promise; diff --git a/src/modules/restApi/infrastructure/adapters/nextJsRestApiRepository.ts b/src/modules/restApi/adapters/secondary/nextJsRestApiAdapter.ts similarity index 92% rename from src/modules/restApi/infrastructure/adapters/nextJsRestApiRepository.ts rename to src/modules/restApi/adapters/secondary/nextJsRestApiAdapter.ts index 7a4c5a781..bcb7feed2 100644 --- a/src/modules/restApi/infrastructure/adapters/nextJsRestApiRepository.ts +++ b/src/modules/restApi/adapters/secondary/nextJsRestApiAdapter.ts @@ -1,12 +1,12 @@ -import { type RestApiRepository } from "@/modules/restApi/domain/ports/restApiRepository"; +import { type RestApiPort } from "@/modules/restApi/ports/secondary/restApiPort"; import type { DeleteParams, PatchParams, PostParams, UnauthPostParams, GetParams, -} from "@/modules/restApi/domain/entities/restApiParams"; -import { type RequestOptions } from "@/modules/restApi/domain/entities/requestOptions"; +} from "@/modules/restApi/application/entities/restApiParams"; +import { type RequestOptions } from "@/modules/restApi/application/entities/requestOptions"; type NextJsAuthRequestOptions = Required< Pick @@ -36,7 +36,7 @@ interface NextJsUnauthParams extends Omit, "options"> { options: NextJsUnAuthRequestionOptions; // Enforce required options } -export class NextJsRestApiRepository implements RestApiRepository { +export class NextJsRestApiAdapter implements RestApiPort { private baseUrl: string; constructor(baseUrl: string) { diff --git a/src/modules/restApi/domain/entities/requestOptions.ts b/src/modules/restApi/application/entities/requestOptions.ts similarity index 100% rename from src/modules/restApi/domain/entities/requestOptions.ts rename to src/modules/restApi/application/entities/requestOptions.ts diff --git a/src/modules/restApi/domain/entities/restApiParams.ts b/src/modules/restApi/application/entities/restApiParams.ts similarity index 100% rename from src/modules/restApi/domain/entities/restApiParams.ts rename to src/modules/restApi/application/entities/restApiParams.ts diff --git a/src/modules/restApi/domain/ports/restApiRepository.ts b/src/modules/restApi/ports/secondary/restApiPort.ts similarity index 78% rename from src/modules/restApi/domain/ports/restApiRepository.ts rename to src/modules/restApi/ports/secondary/restApiPort.ts index 2e70f75d5..eba80fff4 100644 --- a/src/modules/restApi/domain/ports/restApiRepository.ts +++ b/src/modules/restApi/ports/secondary/restApiPort.ts @@ -4,9 +4,9 @@ import type { PatchParams, PostParams, UnauthPostParams, -} from "@/modules/restApi/domain/entities/restApiParams"; +} from "@/modules/restApi/application/entities/restApiParams"; -export interface RestApiRepository { +export interface RestApiPort { get(params: GetParams): Promise; post(params: PostParams): Promise; From effa6d9dacfaabe3503a584b52541ae742cedaf5 Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Tue, 3 Sep 2024 21:35:14 -0400 Subject: [PATCH 17/31] usecase implement port --- .../ideation/application/usecases/AddIdeationUseCase.ts | 3 ++- .../ideation/application/usecases/AddIdeationVoteUseCase.ts | 3 ++- .../ideation/application/usecases/DeleteIdeationUseCase.ts | 3 ++- .../ideation/application/usecases/EditIdeationUseCase.ts | 3 ++- .../ideation/application/usecases/FinalizeIdeationUseCase.ts | 3 ++- .../application/usecases/RemoveIdeationVoteUseCase.ts | 3 ++- src/modules/ideation/ports/primary/addIdeationVotePort.ts | 4 +--- src/modules/ideation/ports/primary/deleteIdeationPort.ts | 4 +--- src/modules/ideation/ports/primary/editIdeationPort.ts | 2 +- src/modules/ideation/ports/primary/finalizeIdeationPort.ts | 2 +- src/modules/ideation/ports/primary/removeIdeationVotePort.ts | 4 +--- 11 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/modules/ideation/application/usecases/AddIdeationUseCase.ts b/src/modules/ideation/application/usecases/AddIdeationUseCase.ts index 2afcc8755..3f7298120 100644 --- a/src/modules/ideation/application/usecases/AddIdeationUseCase.ts +++ b/src/modules/ideation/application/usecases/AddIdeationUseCase.ts @@ -3,9 +3,10 @@ import { TYPES } from "@/di/types"; import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; import { type AddIdeationRequestDto } from "@/modules/ideation/application/dtos/request.dto"; import { type AddIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; +import { type AddIdeationPort } from "@/modules/ideation/ports/primary/addIdeationPort"; @injectable() -export class AddIdeationUseCase { +export class AddIdeationUseCase implements AddIdeationPort { constructor( @inject(TYPES.IdeationApiPort) private readonly ideationApi: IdeationApiPort, diff --git a/src/modules/ideation/application/usecases/AddIdeationVoteUseCase.ts b/src/modules/ideation/application/usecases/AddIdeationVoteUseCase.ts index 1c604b76b..78f3c283b 100644 --- a/src/modules/ideation/application/usecases/AddIdeationVoteUseCase.ts +++ b/src/modules/ideation/application/usecases/AddIdeationVoteUseCase.ts @@ -3,8 +3,9 @@ import { TYPES } from "@/di/types"; import { type IdeationVoteRequestDto } from "@/modules/ideation/application/dtos/request.dto"; import { type IdeationVoteResponseDto } from "@/modules/ideation/application/dtos/response.dto"; import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; +import { type AddIdeationVotePort } from "@/modules/ideation/ports/primary/addIdeationVotePort"; -export class AddIdeationVoteUseCase { +export class AddIdeationVoteUseCase implements AddIdeationVotePort { constructor( @inject(TYPES.IdeationApiPort) private readonly ideationApi: IdeationApiPort, diff --git a/src/modules/ideation/application/usecases/DeleteIdeationUseCase.ts b/src/modules/ideation/application/usecases/DeleteIdeationUseCase.ts index 58b56290d..898130085 100644 --- a/src/modules/ideation/application/usecases/DeleteIdeationUseCase.ts +++ b/src/modules/ideation/application/usecases/DeleteIdeationUseCase.ts @@ -3,8 +3,9 @@ import { TYPES } from "@/di/types"; import { type DeleteIdeationRequestDto } from "@/modules/ideation/application/dtos/request.dto"; import { type DeleteIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; +import { type DeleteIdeationPort } from "@/modules/ideation/ports/primary/deleteIdeationPort"; -export class DeleteIdeationUseCase { +export class DeleteIdeationUseCase implements DeleteIdeationPort { constructor( @inject(TYPES.IdeationApiPort) private readonly ideationApi: IdeationApiPort, diff --git a/src/modules/ideation/application/usecases/EditIdeationUseCase.ts b/src/modules/ideation/application/usecases/EditIdeationUseCase.ts index 540c1c203..bd3749640 100644 --- a/src/modules/ideation/application/usecases/EditIdeationUseCase.ts +++ b/src/modules/ideation/application/usecases/EditIdeationUseCase.ts @@ -3,8 +3,9 @@ import { TYPES } from "@/di/types"; import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; import { type EditIdeationRequestDto } from "@/modules/ideation/application/dtos/request.dto"; import { type EditIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; +import { type EditIdeationPort } from "@/modules/ideation/ports/primary/editIdeationPort"; -export class EditIdeationUseCase { +export class EditIdeationUseCase implements EditIdeationPort { constructor( @inject(TYPES.IdeationApiPort) private readonly ideationApi: IdeationApiPort, diff --git a/src/modules/ideation/application/usecases/FinalizeIdeationUseCase.ts b/src/modules/ideation/application/usecases/FinalizeIdeationUseCase.ts index 46364836b..da258f340 100644 --- a/src/modules/ideation/application/usecases/FinalizeIdeationUseCase.ts +++ b/src/modules/ideation/application/usecases/FinalizeIdeationUseCase.ts @@ -3,8 +3,9 @@ import { TYPES } from "@/di/types"; import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; import { type FinalizeIdeationRequestDto } from "@/modules/ideation/application/dtos/request.dto"; import { type FinalizeIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; +import { type FinalizeIdeationPort } from "@/modules/ideation/ports/primary/finalizeIdeationPort"; -export class FinalizeIdeationUseCase { +export class FinalizeIdeationUseCase implements FinalizeIdeationPort { constructor( @inject(TYPES.IdeationApiPort) private readonly ideationApi: IdeationApiPort, diff --git a/src/modules/ideation/application/usecases/RemoveIdeationVoteUseCase.ts b/src/modules/ideation/application/usecases/RemoveIdeationVoteUseCase.ts index e1be4f03d..b194ff537 100644 --- a/src/modules/ideation/application/usecases/RemoveIdeationVoteUseCase.ts +++ b/src/modules/ideation/application/usecases/RemoveIdeationVoteUseCase.ts @@ -3,8 +3,9 @@ import { TYPES } from "@/di/types"; import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; import { type IdeationVoteRequestDto } from "@/modules/ideation/application/dtos/request.dto"; import { type IdeationVoteResponseDto } from "@/modules/ideation/application/dtos/response.dto"; +import { type RemoveIdeationVotePort } from "@/modules/ideation/ports/primary/removeIdeationVotePort"; -export class RemoveIdeationVoteUseCase { +export class RemoveIdeationVoteUseCase implements RemoveIdeationVotePort { constructor( @inject(TYPES.IdeationApiPort) private readonly ideationApi: IdeationApiPort, diff --git a/src/modules/ideation/ports/primary/addIdeationVotePort.ts b/src/modules/ideation/ports/primary/addIdeationVotePort.ts index 7716da22c..c5708a48e 100644 --- a/src/modules/ideation/ports/primary/addIdeationVotePort.ts +++ b/src/modules/ideation/ports/primary/addIdeationVotePort.ts @@ -2,7 +2,5 @@ import { type IdeationVoteRequestDto } from "@/modules/ideation/application/dtos import { type IdeationVoteResponseDto } from "@/modules/ideation/application/dtos/response.dto"; export interface AddIdeationVotePort { - addIdeationVote( - props: IdeationVoteRequestDto, - ): Promise; + execute(props: IdeationVoteRequestDto): Promise; } diff --git a/src/modules/ideation/ports/primary/deleteIdeationPort.ts b/src/modules/ideation/ports/primary/deleteIdeationPort.ts index 765c9ac1b..ec79ef261 100644 --- a/src/modules/ideation/ports/primary/deleteIdeationPort.ts +++ b/src/modules/ideation/ports/primary/deleteIdeationPort.ts @@ -2,7 +2,5 @@ import { type DeleteIdeationRequestDto } from "@/modules/ideation/application/dt import { type DeleteIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; export interface DeleteIdeationPort { - deleteIdeation( - props: DeleteIdeationRequestDto, - ): Promise; + execute(props: DeleteIdeationRequestDto): Promise; } diff --git a/src/modules/ideation/ports/primary/editIdeationPort.ts b/src/modules/ideation/ports/primary/editIdeationPort.ts index af3414dc4..44fddba47 100644 --- a/src/modules/ideation/ports/primary/editIdeationPort.ts +++ b/src/modules/ideation/ports/primary/editIdeationPort.ts @@ -2,5 +2,5 @@ import { type EditIdeationRequestDto } from "@/modules/ideation/application/dtos import { type EditIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; export interface EditIdeationPort { - editIdeation(props: EditIdeationRequestDto): Promise; + execute(props: EditIdeationRequestDto): Promise; } diff --git a/src/modules/ideation/ports/primary/finalizeIdeationPort.ts b/src/modules/ideation/ports/primary/finalizeIdeationPort.ts index 3daf6526a..bd459ffb9 100644 --- a/src/modules/ideation/ports/primary/finalizeIdeationPort.ts +++ b/src/modules/ideation/ports/primary/finalizeIdeationPort.ts @@ -2,7 +2,7 @@ import { type FinalizeIdeationRequestDto } from "@/modules/ideation/application/ import { type FinalizeIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; export interface FinalizeIdeationPort { - finalizeIdeation( + execute( props: FinalizeIdeationRequestDto, ): Promise; } diff --git a/src/modules/ideation/ports/primary/removeIdeationVotePort.ts b/src/modules/ideation/ports/primary/removeIdeationVotePort.ts index 116435af3..f4bdd700c 100644 --- a/src/modules/ideation/ports/primary/removeIdeationVotePort.ts +++ b/src/modules/ideation/ports/primary/removeIdeationVotePort.ts @@ -2,7 +2,5 @@ import { type IdeationVoteRequestDto } from "@/modules/ideation/application/dtos import { type IdeationVoteResponseDto } from "@/modules/ideation/application/dtos/response.dto"; export interface RemoveIdeationVotePort { - removeIdeationVote( - props: IdeationVoteRequestDto, - ): Promise; + execute(props: IdeationVoteRequestDto): Promise; } From 2a7235134345ebfb2c5ab2b4b24929f09a3b8565 Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Tue, 3 Sep 2024 21:41:35 -0400 Subject: [PATCH 18/31] test --- src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts | 2 +- src/modules/ideation/adapters/secondary/ideationApiAdapter.ts | 2 +- .../IdeationUrls.ts => application/constants/ideationUrls.ts} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename src/modules/ideation/{constants/IdeationUrls.ts => application/constants/ideationUrls.ts} (100%) diff --git a/src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts b/src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts index 7ae51f310..8a7dcf987 100644 --- a/src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts +++ b/src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts @@ -5,11 +5,11 @@ import { getAccessToken } from "@/utils/getCookie"; import { DELETE, PATCH, POST } from "@/utils/requests"; import { type AsyncActionResponse, handleAsync } from "@/utils/handleAsync"; import { CacheTag } from "@/utils/cacheTag"; -import { AddIdeationUseCase } from "@/modules/ideation/application/usecases/addIdeationUseCase"; import { type AddIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; import { NextJsRestApiAdapter } from "@/modules/restApi/adapters/secondary/nextJsRestApiAdapter"; import { IdeationApiAdapter } from "@/modules/ideation/adapters/secondary/ideationApiAdapter"; import { type AddIdeationUsecaseDto } from "@/modules/ideation/application/dtos/addIdeationUsecaseDto"; +import { AddIdeationUseCase } from "@/modules/ideation/application/usecases/addIdeationUseCase"; interface IdeationProps { teamId: number; diff --git a/src/modules/ideation/adapters/secondary/ideationApiAdapter.ts b/src/modules/ideation/adapters/secondary/ideationApiAdapter.ts index 764602534..2a31e7f93 100644 --- a/src/modules/ideation/adapters/secondary/ideationApiAdapter.ts +++ b/src/modules/ideation/adapters/secondary/ideationApiAdapter.ts @@ -1,5 +1,4 @@ import { inject, injectable } from "tsyringe"; -import { IdeationUrls } from "@/modules/ideation/constants/ideationUrls"; import { TYPES } from "@/di/types"; import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; import { type RestApiPort } from "@/modules/restApi/ports/secondary/restApiPort"; @@ -19,6 +18,7 @@ import type { IdeationVoteResponseDto, FinalizeIdeationResponseDto, } from "@/modules/ideation/application/dtos/response.dto"; +import { IdeationUrls } from "@/modules/ideation/application/constants/ideationUrls"; @injectable() export class IdeationApiAdapter implements IdeationApiPort { diff --git a/src/modules/ideation/constants/IdeationUrls.ts b/src/modules/ideation/application/constants/ideationUrls.ts similarity index 100% rename from src/modules/ideation/constants/IdeationUrls.ts rename to src/modules/ideation/application/constants/ideationUrls.ts From 6b789c37e1ee1aa6940f92f709c253dbd00f5a7f Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Tue, 3 Sep 2024 21:57:18 -0400 Subject: [PATCH 19/31] test --- src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts b/src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts index 8a7dcf987..d1f910a58 100644 --- a/src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts +++ b/src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts @@ -95,6 +95,7 @@ export async function addIdeation({ return [res, error]; } +// test // export async function addIdeation({ // teamId, // title, From 98f341b66c1e226043ef1f2581eb42d1a0e85efa Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Tue, 3 Sep 2024 22:45:56 -0400 Subject: [PATCH 20/31] why is this so annoying --- .../usecases/AddIdeationUseCase.ts | 20 ------------------ .../usecases/AddIdeationVoteUseCase.ts | 21 ------------------- .../usecases/DeleteIdeationUseCase.ts | 21 ------------------- .../usecases/EditIdeationUseCase.ts | 21 ------------------- .../usecases/FinalizeIdeationUseCase.ts | 21 ------------------- .../usecases/RemoveIdeationVoteUseCase.ts | 21 ------------------- 6 files changed, 125 deletions(-) delete mode 100644 src/modules/ideation/application/usecases/AddIdeationUseCase.ts delete mode 100644 src/modules/ideation/application/usecases/AddIdeationVoteUseCase.ts delete mode 100644 src/modules/ideation/application/usecases/DeleteIdeationUseCase.ts delete mode 100644 src/modules/ideation/application/usecases/EditIdeationUseCase.ts delete mode 100644 src/modules/ideation/application/usecases/FinalizeIdeationUseCase.ts delete mode 100644 src/modules/ideation/application/usecases/RemoveIdeationVoteUseCase.ts diff --git a/src/modules/ideation/application/usecases/AddIdeationUseCase.ts b/src/modules/ideation/application/usecases/AddIdeationUseCase.ts deleted file mode 100644 index 3f7298120..000000000 --- a/src/modules/ideation/application/usecases/AddIdeationUseCase.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { inject, injectable } from "tsyringe"; -import { TYPES } from "@/di/types"; -import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; -import { type AddIdeationRequestDto } from "@/modules/ideation/application/dtos/request.dto"; -import { type AddIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; -import { type AddIdeationPort } from "@/modules/ideation/ports/primary/addIdeationPort"; - -@injectable() -export class AddIdeationUseCase implements AddIdeationPort { - constructor( - @inject(TYPES.IdeationApiPort) - private readonly ideationApi: IdeationApiPort, - ) {} - - async execute(props: AddIdeationRequestDto): Promise { - return await this.ideationApi.addIdeation({ - ...props, - }); - } -} diff --git a/src/modules/ideation/application/usecases/AddIdeationVoteUseCase.ts b/src/modules/ideation/application/usecases/AddIdeationVoteUseCase.ts deleted file mode 100644 index 78f3c283b..000000000 --- a/src/modules/ideation/application/usecases/AddIdeationVoteUseCase.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { inject } from "tsyringe"; -import { TYPES } from "@/di/types"; -import { type IdeationVoteRequestDto } from "@/modules/ideation/application/dtos/request.dto"; -import { type IdeationVoteResponseDto } from "@/modules/ideation/application/dtos/response.dto"; -import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; -import { type AddIdeationVotePort } from "@/modules/ideation/ports/primary/addIdeationVotePort"; - -export class AddIdeationVoteUseCase implements AddIdeationVotePort { - constructor( - @inject(TYPES.IdeationApiPort) - private readonly ideationApi: IdeationApiPort, - ) {} - - async execute( - props: IdeationVoteRequestDto, - ): Promise { - return await this.ideationApi.addIdeationVote({ - ...props, - }); - } -} diff --git a/src/modules/ideation/application/usecases/DeleteIdeationUseCase.ts b/src/modules/ideation/application/usecases/DeleteIdeationUseCase.ts deleted file mode 100644 index 898130085..000000000 --- a/src/modules/ideation/application/usecases/DeleteIdeationUseCase.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { inject } from "tsyringe"; -import { TYPES } from "@/di/types"; -import { type DeleteIdeationRequestDto } from "@/modules/ideation/application/dtos/request.dto"; -import { type DeleteIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; -import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; -import { type DeleteIdeationPort } from "@/modules/ideation/ports/primary/deleteIdeationPort"; - -export class DeleteIdeationUseCase implements DeleteIdeationPort { - constructor( - @inject(TYPES.IdeationApiPort) - private readonly ideationApi: IdeationApiPort, - ) {} - - async execute( - props: DeleteIdeationRequestDto, - ): Promise { - return await this.ideationApi.deleteIdeation({ - ...props, - }); - } -} diff --git a/src/modules/ideation/application/usecases/EditIdeationUseCase.ts b/src/modules/ideation/application/usecases/EditIdeationUseCase.ts deleted file mode 100644 index bd3749640..000000000 --- a/src/modules/ideation/application/usecases/EditIdeationUseCase.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { inject } from "tsyringe"; -import { TYPES } from "@/di/types"; -import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; -import { type EditIdeationRequestDto } from "@/modules/ideation/application/dtos/request.dto"; -import { type EditIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; -import { type EditIdeationPort } from "@/modules/ideation/ports/primary/editIdeationPort"; - -export class EditIdeationUseCase implements EditIdeationPort { - constructor( - @inject(TYPES.IdeationApiPort) - private readonly ideationApi: IdeationApiPort, - ) {} - - async execute( - props: EditIdeationRequestDto, - ): Promise { - return await this.ideationApi.editIdeation({ - ...props, - }); - } -} diff --git a/src/modules/ideation/application/usecases/FinalizeIdeationUseCase.ts b/src/modules/ideation/application/usecases/FinalizeIdeationUseCase.ts deleted file mode 100644 index da258f340..000000000 --- a/src/modules/ideation/application/usecases/FinalizeIdeationUseCase.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { inject } from "tsyringe"; -import { TYPES } from "@/di/types"; -import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; -import { type FinalizeIdeationRequestDto } from "@/modules/ideation/application/dtos/request.dto"; -import { type FinalizeIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; -import { type FinalizeIdeationPort } from "@/modules/ideation/ports/primary/finalizeIdeationPort"; - -export class FinalizeIdeationUseCase implements FinalizeIdeationPort { - constructor( - @inject(TYPES.IdeationApiPort) - private readonly ideationApi: IdeationApiPort, - ) {} - - async execute( - props: FinalizeIdeationRequestDto, - ): Promise { - return await this.ideationApi.finalizeIdeation({ - ...props, - }); - } -} diff --git a/src/modules/ideation/application/usecases/RemoveIdeationVoteUseCase.ts b/src/modules/ideation/application/usecases/RemoveIdeationVoteUseCase.ts deleted file mode 100644 index b194ff537..000000000 --- a/src/modules/ideation/application/usecases/RemoveIdeationVoteUseCase.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { inject } from "tsyringe"; -import { TYPES } from "@/di/types"; -import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; -import { type IdeationVoteRequestDto } from "@/modules/ideation/application/dtos/request.dto"; -import { type IdeationVoteResponseDto } from "@/modules/ideation/application/dtos/response.dto"; -import { type RemoveIdeationVotePort } from "@/modules/ideation/ports/primary/removeIdeationVotePort"; - -export class RemoveIdeationVoteUseCase implements RemoveIdeationVotePort { - constructor( - @inject(TYPES.IdeationApiPort) - private readonly ideationApi: IdeationApiPort, - ) {} - - async execute( - props: IdeationVoteRequestDto, - ): Promise { - return await this.ideationApi.removeIdeationVote({ - ...props, - }); - } -} From 5972f545019b068091dff690905b546ac99a8efa Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Tue, 3 Sep 2024 22:48:14 -0400 Subject: [PATCH 21/31] update filename casing --- .../usecases/addIdeationUseCase.ts | 20 ++++++++++++++++++ .../usecases/addIdeationVoteUseCase.ts | 21 +++++++++++++++++++ .../usecases/deleteIdeationUseCase.ts | 21 +++++++++++++++++++ .../usecases/editIdeationUseCase.ts | 21 +++++++++++++++++++ .../usecases/finalizeIdeationUseCase.ts | 21 +++++++++++++++++++ .../usecases/removeIdeationVoteUseCase.ts | 21 +++++++++++++++++++ 6 files changed, 125 insertions(+) create mode 100644 src/modules/ideation/application/usecases/addIdeationUseCase.ts create mode 100644 src/modules/ideation/application/usecases/addIdeationVoteUseCase.ts create mode 100644 src/modules/ideation/application/usecases/deleteIdeationUseCase.ts create mode 100644 src/modules/ideation/application/usecases/editIdeationUseCase.ts create mode 100644 src/modules/ideation/application/usecases/finalizeIdeationUseCase.ts create mode 100644 src/modules/ideation/application/usecases/removeIdeationVoteUseCase.ts diff --git a/src/modules/ideation/application/usecases/addIdeationUseCase.ts b/src/modules/ideation/application/usecases/addIdeationUseCase.ts new file mode 100644 index 000000000..3f7298120 --- /dev/null +++ b/src/modules/ideation/application/usecases/addIdeationUseCase.ts @@ -0,0 +1,20 @@ +import { inject, injectable } from "tsyringe"; +import { TYPES } from "@/di/types"; +import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; +import { type AddIdeationRequestDto } from "@/modules/ideation/application/dtos/request.dto"; +import { type AddIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; +import { type AddIdeationPort } from "@/modules/ideation/ports/primary/addIdeationPort"; + +@injectable() +export class AddIdeationUseCase implements AddIdeationPort { + constructor( + @inject(TYPES.IdeationApiPort) + private readonly ideationApi: IdeationApiPort, + ) {} + + async execute(props: AddIdeationRequestDto): Promise { + return await this.ideationApi.addIdeation({ + ...props, + }); + } +} diff --git a/src/modules/ideation/application/usecases/addIdeationVoteUseCase.ts b/src/modules/ideation/application/usecases/addIdeationVoteUseCase.ts new file mode 100644 index 000000000..78f3c283b --- /dev/null +++ b/src/modules/ideation/application/usecases/addIdeationVoteUseCase.ts @@ -0,0 +1,21 @@ +import { inject } from "tsyringe"; +import { TYPES } from "@/di/types"; +import { type IdeationVoteRequestDto } from "@/modules/ideation/application/dtos/request.dto"; +import { type IdeationVoteResponseDto } from "@/modules/ideation/application/dtos/response.dto"; +import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; +import { type AddIdeationVotePort } from "@/modules/ideation/ports/primary/addIdeationVotePort"; + +export class AddIdeationVoteUseCase implements AddIdeationVotePort { + constructor( + @inject(TYPES.IdeationApiPort) + private readonly ideationApi: IdeationApiPort, + ) {} + + async execute( + props: IdeationVoteRequestDto, + ): Promise { + return await this.ideationApi.addIdeationVote({ + ...props, + }); + } +} diff --git a/src/modules/ideation/application/usecases/deleteIdeationUseCase.ts b/src/modules/ideation/application/usecases/deleteIdeationUseCase.ts new file mode 100644 index 000000000..898130085 --- /dev/null +++ b/src/modules/ideation/application/usecases/deleteIdeationUseCase.ts @@ -0,0 +1,21 @@ +import { inject } from "tsyringe"; +import { TYPES } from "@/di/types"; +import { type DeleteIdeationRequestDto } from "@/modules/ideation/application/dtos/request.dto"; +import { type DeleteIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; +import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; +import { type DeleteIdeationPort } from "@/modules/ideation/ports/primary/deleteIdeationPort"; + +export class DeleteIdeationUseCase implements DeleteIdeationPort { + constructor( + @inject(TYPES.IdeationApiPort) + private readonly ideationApi: IdeationApiPort, + ) {} + + async execute( + props: DeleteIdeationRequestDto, + ): Promise { + return await this.ideationApi.deleteIdeation({ + ...props, + }); + } +} diff --git a/src/modules/ideation/application/usecases/editIdeationUseCase.ts b/src/modules/ideation/application/usecases/editIdeationUseCase.ts new file mode 100644 index 000000000..bd3749640 --- /dev/null +++ b/src/modules/ideation/application/usecases/editIdeationUseCase.ts @@ -0,0 +1,21 @@ +import { inject } from "tsyringe"; +import { TYPES } from "@/di/types"; +import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; +import { type EditIdeationRequestDto } from "@/modules/ideation/application/dtos/request.dto"; +import { type EditIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; +import { type EditIdeationPort } from "@/modules/ideation/ports/primary/editIdeationPort"; + +export class EditIdeationUseCase implements EditIdeationPort { + constructor( + @inject(TYPES.IdeationApiPort) + private readonly ideationApi: IdeationApiPort, + ) {} + + async execute( + props: EditIdeationRequestDto, + ): Promise { + return await this.ideationApi.editIdeation({ + ...props, + }); + } +} diff --git a/src/modules/ideation/application/usecases/finalizeIdeationUseCase.ts b/src/modules/ideation/application/usecases/finalizeIdeationUseCase.ts new file mode 100644 index 000000000..da258f340 --- /dev/null +++ b/src/modules/ideation/application/usecases/finalizeIdeationUseCase.ts @@ -0,0 +1,21 @@ +import { inject } from "tsyringe"; +import { TYPES } from "@/di/types"; +import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; +import { type FinalizeIdeationRequestDto } from "@/modules/ideation/application/dtos/request.dto"; +import { type FinalizeIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; +import { type FinalizeIdeationPort } from "@/modules/ideation/ports/primary/finalizeIdeationPort"; + +export class FinalizeIdeationUseCase implements FinalizeIdeationPort { + constructor( + @inject(TYPES.IdeationApiPort) + private readonly ideationApi: IdeationApiPort, + ) {} + + async execute( + props: FinalizeIdeationRequestDto, + ): Promise { + return await this.ideationApi.finalizeIdeation({ + ...props, + }); + } +} diff --git a/src/modules/ideation/application/usecases/removeIdeationVoteUseCase.ts b/src/modules/ideation/application/usecases/removeIdeationVoteUseCase.ts new file mode 100644 index 000000000..b194ff537 --- /dev/null +++ b/src/modules/ideation/application/usecases/removeIdeationVoteUseCase.ts @@ -0,0 +1,21 @@ +import { inject } from "tsyringe"; +import { TYPES } from "@/di/types"; +import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; +import { type IdeationVoteRequestDto } from "@/modules/ideation/application/dtos/request.dto"; +import { type IdeationVoteResponseDto } from "@/modules/ideation/application/dtos/response.dto"; +import { type RemoveIdeationVotePort } from "@/modules/ideation/ports/primary/removeIdeationVotePort"; + +export class RemoveIdeationVoteUseCase implements RemoveIdeationVotePort { + constructor( + @inject(TYPES.IdeationApiPort) + private readonly ideationApi: IdeationApiPort, + ) {} + + async execute( + props: IdeationVoteRequestDto, + ): Promise { + return await this.ideationApi.removeIdeationVote({ + ...props, + }); + } +} From 99ae94b659738ba8b50462bad455a37f9807f190 Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Tue, 3 Sep 2024 23:51:35 -0400 Subject: [PATCH 22/31] not so optimal solution to enforcing cache and token --- .../my-voyage/[teamId]/ideation/ideationService.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts b/src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts index d1f910a58..692b37519 100644 --- a/src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts +++ b/src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts @@ -10,6 +10,7 @@ import { NextJsRestApiAdapter } from "@/modules/restApi/adapters/secondary/nextJ import { IdeationApiAdapter } from "@/modules/ideation/adapters/secondary/ideationApiAdapter"; import { type AddIdeationUsecaseDto } from "@/modules/ideation/application/dtos/addIdeationUsecaseDto"; import { AddIdeationUseCase } from "@/modules/ideation/application/usecases/addIdeationUseCase"; +import { type AddIdeationRequestDto } from "@/modules/ideation/application/dtos/request.dto"; interface IdeationProps { teamId: number; @@ -63,6 +64,12 @@ const nextJsRestApiAdapter = new NextJsRestApiAdapter( ); const ideationApiPort = new IdeationApiAdapter(nextJsRestApiAdapter); +interface NextJsAddIdeationAdapter extends AddIdeationUseCase { + execute( + props: Required, + ): Promise; +} + export async function addIdeation({ teamId, title, @@ -72,7 +79,9 @@ export async function addIdeation({ AsyncActionResponse > { const token = getAccessToken(); - const addIdeationUseCase = new AddIdeationUseCase(ideationApiPort); + const addIdeationUseCase: NextJsAddIdeationAdapter = new AddIdeationUseCase( + ideationApiPort, + ); // refactor this later to not expect a function const addIdeationAsync = async () => From 1c6d39946db30d06c54d50067008d3cce7a64213 Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Mon, 30 Sep 2024 23:27:40 -0400 Subject: [PATCH 23/31] refactor server action as a functon to act as a wrapper calling a method from a class --- .../adapters/ideationClientAdapter.ts | 51 +++++++++++++++++++ .../{ => adapters}/ideationService.ts | 48 ++++------------- .../ideation/components/IdeationForm.tsx | 2 +- .../[teamId]/ideation/components/VoteCard.tsx | 2 +- src/di/types.ts | 1 + .../usecases/addIdeationUseCase.ts | 3 +- .../usecases/addIdeationVoteUseCase.ts | 3 +- .../usecases/deleteIdeationUseCase.ts | 3 +- .../usecases/editIdeationUseCase.ts | 3 +- .../usecases/finalizeIdeationUseCase.ts | 3 +- .../usecases/removeIdeationVoteUseCase.ts | 3 +- .../ports/primary/ideationClientPort.ts | 14 +++++ 12 files changed, 83 insertions(+), 53 deletions(-) create mode 100644 src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationClientAdapter.ts rename src/app/(main)/my-voyage/[teamId]/ideation/{ => adapters}/ideationService.ts (80%) create mode 100644 src/modules/ideation/ports/primary/ideationClientPort.ts diff --git a/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationClientAdapter.ts b/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationClientAdapter.ts new file mode 100644 index 000000000..d8c60f38a --- /dev/null +++ b/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationClientAdapter.ts @@ -0,0 +1,51 @@ +import { revalidateTag } from "next/cache"; +import { type IdeationClientPort } from "@/modules/ideation/ports/primary/ideationClientPort"; +import { type AddIdeationUsecaseDto } from "@/modules/ideation/application/dtos/addIdeationUsecaseDto"; +import { handleAsync, type AsyncActionResponse } from "@/utils/handleAsync"; +import { type AddIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; +import { AddIdeationUseCase } from "@/modules/ideation/application/usecases/addIdeationUseCase"; +import { getAccessToken } from "@/utils/getCookie"; +import { NextJsRestApiAdapter } from "@/modules/restApi/adapters/secondary/nextJsRestApiAdapter"; +import { IdeationApiAdapter } from "@/modules/ideation/adapters/secondary/ideationApiAdapter"; +import { CacheTag } from "@/utils/cacheTag"; + +const nextJsRestApiAdapter = new NextJsRestApiAdapter( + process.env.NEXT_PUBLIC_API_URL!, +); +const ideationApiPort = new IdeationApiAdapter(nextJsRestApiAdapter); + +export class IdeationClientAdapter implements IdeationClientPort { + constructor() {} + + async addIdeation({ + teamId, + title, + description, + vision, + }: AddIdeationUsecaseDto): Promise< + AsyncActionResponse + > { + const token = getAccessToken(); + const addIdeationUseCase = new AddIdeationUseCase(ideationApiPort); + + // refactor this later to not expect a function + const addIdeationAsync = async () => + await addIdeationUseCase.execute({ + teamId, + title, + description, + vision, + cache: "default", + token, + }); + + const [res, error] = + await handleAsync(addIdeationAsync); + + if (res) { + revalidateTag(CacheTag.ideation); + } + + return [res, error]; + } +} diff --git a/src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts b/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationService.ts similarity index 80% rename from src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts rename to src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationService.ts index 692b37519..18af9e06e 100644 --- a/src/app/(main)/my-voyage/[teamId]/ideation/ideationService.ts +++ b/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationService.ts @@ -1,16 +1,13 @@ "use server"; import { revalidateTag } from "next/cache"; +import { IdeationClientAdapter } from "./ideationClientAdapter"; import { getAccessToken } from "@/utils/getCookie"; import { DELETE, PATCH, POST } from "@/utils/requests"; import { type AsyncActionResponse, handleAsync } from "@/utils/handleAsync"; import { CacheTag } from "@/utils/cacheTag"; import { type AddIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; -import { NextJsRestApiAdapter } from "@/modules/restApi/adapters/secondary/nextJsRestApiAdapter"; -import { IdeationApiAdapter } from "@/modules/ideation/adapters/secondary/ideationApiAdapter"; import { type AddIdeationUsecaseDto } from "@/modules/ideation/application/dtos/addIdeationUsecaseDto"; -import { AddIdeationUseCase } from "@/modules/ideation/application/usecases/addIdeationUseCase"; -import { type AddIdeationRequestDto } from "@/modules/ideation/application/dtos/request.dto"; interface IdeationProps { teamId: number; @@ -59,17 +56,6 @@ export interface IdeationVoteResponse extends IdeationResponse { projectIdeaId: number; } -const nextJsRestApiAdapter = new NextJsRestApiAdapter( - process.env.NEXT_PUBLIC_API_URL!, -); -const ideationApiPort = new IdeationApiAdapter(nextJsRestApiAdapter); - -interface NextJsAddIdeationAdapter extends AddIdeationUseCase { - execute( - props: Required, - ): Promise; -} - export async function addIdeation({ teamId, title, @@ -78,30 +64,14 @@ export async function addIdeation({ }: AddIdeationUsecaseDto): Promise< AsyncActionResponse > { - const token = getAccessToken(); - const addIdeationUseCase: NextJsAddIdeationAdapter = new AddIdeationUseCase( - ideationApiPort, - ); - - // refactor this later to not expect a function - const addIdeationAsync = async () => - await addIdeationUseCase.execute({ - teamId, - title, - description, - vision, - cache: "default", - token, - }); - - const [res, error] = - await handleAsync(addIdeationAsync); - - if (res) { - revalidateTag(CacheTag.ideation); - } - - return [res, error]; + const addIdeationClientAdapter = new IdeationClientAdapter(); + + return addIdeationClientAdapter.addIdeation({ + teamId, + title, + description, + vision, + }); } // test diff --git a/src/app/(main)/my-voyage/[teamId]/ideation/components/IdeationForm.tsx b/src/app/(main)/my-voyage/[teamId]/ideation/components/IdeationForm.tsx index 12e46f4cd..4df02e51c 100644 --- a/src/app/(main)/my-voyage/[teamId]/ideation/components/IdeationForm.tsx +++ b/src/app/(main)/my-voyage/[teamId]/ideation/components/IdeationForm.tsx @@ -18,7 +18,7 @@ import { type EditIdeationProps, addIdeation, deleteIdeation, -} from "@/app/(main)/my-voyage/[teamId]/ideation/ideationService"; +} from "@/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationService"; import useServerAction from "@/hooks/useServerAction"; import { persistor } from "@/store/store"; import { onOpenModal } from "@/store/features/modal/modalSlice"; diff --git a/src/app/(main)/my-voyage/[teamId]/ideation/components/VoteCard.tsx b/src/app/(main)/my-voyage/[teamId]/ideation/components/VoteCard.tsx index 042aa0ffb..51e3042af 100644 --- a/src/app/(main)/my-voyage/[teamId]/ideation/components/VoteCard.tsx +++ b/src/app/(main)/my-voyage/[teamId]/ideation/components/VoteCard.tsx @@ -13,7 +13,7 @@ import useServerAction from "@/hooks/useServerAction"; import { addIdeationVote, removeIdeationVote, -} from "@/app/(main)/my-voyage/[teamId]/ideation/ideationService"; +} from "@/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationService"; import { onOpenModal } from "@/store/features/modal/modalSlice"; import AvatarGroup from "@/components/avatar/AvatarGroup"; import Avatar from "@/components/avatar/Avatar"; diff --git a/src/di/types.ts b/src/di/types.ts index 9138fcf34..e2f538ec0 100644 --- a/src/di/types.ts +++ b/src/di/types.ts @@ -2,6 +2,7 @@ export const TYPES = { /* Ports */ RestApiPort: Symbol.for("RestApiPort"), IdeationApiPort: Symbol.for("IdeationApiPort"), + IdeationClientPort: Symbol.for("IdeationClientPort"), /* Adapters */ // NextJsRestApiAdapter: Symbol.for("NextJsRestApiAdapter"), diff --git a/src/modules/ideation/application/usecases/addIdeationUseCase.ts b/src/modules/ideation/application/usecases/addIdeationUseCase.ts index 3f7298120..2afcc8755 100644 --- a/src/modules/ideation/application/usecases/addIdeationUseCase.ts +++ b/src/modules/ideation/application/usecases/addIdeationUseCase.ts @@ -3,10 +3,9 @@ import { TYPES } from "@/di/types"; import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; import { type AddIdeationRequestDto } from "@/modules/ideation/application/dtos/request.dto"; import { type AddIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; -import { type AddIdeationPort } from "@/modules/ideation/ports/primary/addIdeationPort"; @injectable() -export class AddIdeationUseCase implements AddIdeationPort { +export class AddIdeationUseCase { constructor( @inject(TYPES.IdeationApiPort) private readonly ideationApi: IdeationApiPort, diff --git a/src/modules/ideation/application/usecases/addIdeationVoteUseCase.ts b/src/modules/ideation/application/usecases/addIdeationVoteUseCase.ts index 78f3c283b..1c604b76b 100644 --- a/src/modules/ideation/application/usecases/addIdeationVoteUseCase.ts +++ b/src/modules/ideation/application/usecases/addIdeationVoteUseCase.ts @@ -3,9 +3,8 @@ import { TYPES } from "@/di/types"; import { type IdeationVoteRequestDto } from "@/modules/ideation/application/dtos/request.dto"; import { type IdeationVoteResponseDto } from "@/modules/ideation/application/dtos/response.dto"; import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; -import { type AddIdeationVotePort } from "@/modules/ideation/ports/primary/addIdeationVotePort"; -export class AddIdeationVoteUseCase implements AddIdeationVotePort { +export class AddIdeationVoteUseCase { constructor( @inject(TYPES.IdeationApiPort) private readonly ideationApi: IdeationApiPort, diff --git a/src/modules/ideation/application/usecases/deleteIdeationUseCase.ts b/src/modules/ideation/application/usecases/deleteIdeationUseCase.ts index 898130085..58b56290d 100644 --- a/src/modules/ideation/application/usecases/deleteIdeationUseCase.ts +++ b/src/modules/ideation/application/usecases/deleteIdeationUseCase.ts @@ -3,9 +3,8 @@ import { TYPES } from "@/di/types"; import { type DeleteIdeationRequestDto } from "@/modules/ideation/application/dtos/request.dto"; import { type DeleteIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; -import { type DeleteIdeationPort } from "@/modules/ideation/ports/primary/deleteIdeationPort"; -export class DeleteIdeationUseCase implements DeleteIdeationPort { +export class DeleteIdeationUseCase { constructor( @inject(TYPES.IdeationApiPort) private readonly ideationApi: IdeationApiPort, diff --git a/src/modules/ideation/application/usecases/editIdeationUseCase.ts b/src/modules/ideation/application/usecases/editIdeationUseCase.ts index bd3749640..540c1c203 100644 --- a/src/modules/ideation/application/usecases/editIdeationUseCase.ts +++ b/src/modules/ideation/application/usecases/editIdeationUseCase.ts @@ -3,9 +3,8 @@ import { TYPES } from "@/di/types"; import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; import { type EditIdeationRequestDto } from "@/modules/ideation/application/dtos/request.dto"; import { type EditIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; -import { type EditIdeationPort } from "@/modules/ideation/ports/primary/editIdeationPort"; -export class EditIdeationUseCase implements EditIdeationPort { +export class EditIdeationUseCase { constructor( @inject(TYPES.IdeationApiPort) private readonly ideationApi: IdeationApiPort, diff --git a/src/modules/ideation/application/usecases/finalizeIdeationUseCase.ts b/src/modules/ideation/application/usecases/finalizeIdeationUseCase.ts index da258f340..46364836b 100644 --- a/src/modules/ideation/application/usecases/finalizeIdeationUseCase.ts +++ b/src/modules/ideation/application/usecases/finalizeIdeationUseCase.ts @@ -3,9 +3,8 @@ import { TYPES } from "@/di/types"; import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; import { type FinalizeIdeationRequestDto } from "@/modules/ideation/application/dtos/request.dto"; import { type FinalizeIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; -import { type FinalizeIdeationPort } from "@/modules/ideation/ports/primary/finalizeIdeationPort"; -export class FinalizeIdeationUseCase implements FinalizeIdeationPort { +export class FinalizeIdeationUseCase { constructor( @inject(TYPES.IdeationApiPort) private readonly ideationApi: IdeationApiPort, diff --git a/src/modules/ideation/application/usecases/removeIdeationVoteUseCase.ts b/src/modules/ideation/application/usecases/removeIdeationVoteUseCase.ts index b194ff537..e1be4f03d 100644 --- a/src/modules/ideation/application/usecases/removeIdeationVoteUseCase.ts +++ b/src/modules/ideation/application/usecases/removeIdeationVoteUseCase.ts @@ -3,9 +3,8 @@ import { TYPES } from "@/di/types"; import { type IdeationApiPort } from "@/modules/ideation/ports/secondary/ideationApiPort"; import { type IdeationVoteRequestDto } from "@/modules/ideation/application/dtos/request.dto"; import { type IdeationVoteResponseDto } from "@/modules/ideation/application/dtos/response.dto"; -import { type RemoveIdeationVotePort } from "@/modules/ideation/ports/primary/removeIdeationVotePort"; -export class RemoveIdeationVoteUseCase implements RemoveIdeationVotePort { +export class RemoveIdeationVoteUseCase { constructor( @inject(TYPES.IdeationApiPort) private readonly ideationApi: IdeationApiPort, diff --git a/src/modules/ideation/ports/primary/ideationClientPort.ts b/src/modules/ideation/ports/primary/ideationClientPort.ts new file mode 100644 index 000000000..8a6a22c80 --- /dev/null +++ b/src/modules/ideation/ports/primary/ideationClientPort.ts @@ -0,0 +1,14 @@ +import { type AddIdeationUsecaseDto } from "@/modules/ideation/application/dtos/addIdeationUsecaseDto"; +import { type AsyncActionResponse } from "@/utils/handleAsync"; +import { type AddIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; + +export interface IdeationClientPort { + addIdeation({ + teamId, + title, + description, + vision, + }: AddIdeationUsecaseDto): Promise< + AsyncActionResponse + >; +} From 5109f3dd329bcfc62d5d69acd2446e100f73c147 Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Mon, 30 Sep 2024 23:28:59 -0400 Subject: [PATCH 24/31] rename ideation service file --- .../ideation/adapters/{ideationService.ts => ideationSA.ts} | 0 .../my-voyage/[teamId]/ideation/components/IdeationForm.tsx | 2 +- .../(main)/my-voyage/[teamId]/ideation/components/VoteCard.tsx | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename src/app/(main)/my-voyage/[teamId]/ideation/adapters/{ideationService.ts => ideationSA.ts} (100%) diff --git a/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationService.ts b/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationSA.ts similarity index 100% rename from src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationService.ts rename to src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationSA.ts diff --git a/src/app/(main)/my-voyage/[teamId]/ideation/components/IdeationForm.tsx b/src/app/(main)/my-voyage/[teamId]/ideation/components/IdeationForm.tsx index 4df02e51c..019df3ffb 100644 --- a/src/app/(main)/my-voyage/[teamId]/ideation/components/IdeationForm.tsx +++ b/src/app/(main)/my-voyage/[teamId]/ideation/components/IdeationForm.tsx @@ -18,7 +18,7 @@ import { type EditIdeationProps, addIdeation, deleteIdeation, -} from "@/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationService"; +} from "@/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationSA"; import useServerAction from "@/hooks/useServerAction"; import { persistor } from "@/store/store"; import { onOpenModal } from "@/store/features/modal/modalSlice"; diff --git a/src/app/(main)/my-voyage/[teamId]/ideation/components/VoteCard.tsx b/src/app/(main)/my-voyage/[teamId]/ideation/components/VoteCard.tsx index 51e3042af..4f2a5046e 100644 --- a/src/app/(main)/my-voyage/[teamId]/ideation/components/VoteCard.tsx +++ b/src/app/(main)/my-voyage/[teamId]/ideation/components/VoteCard.tsx @@ -13,7 +13,7 @@ import useServerAction from "@/hooks/useServerAction"; import { addIdeationVote, removeIdeationVote, -} from "@/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationService"; +} from "@/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationSA"; import { onOpenModal } from "@/store/features/modal/modalSlice"; import AvatarGroup from "@/components/avatar/AvatarGroup"; import Avatar from "@/components/avatar/Avatar"; From f9a2a4c5e805a03618618bd8b32cfaedb863dc69 Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Mon, 30 Sep 2024 23:37:56 -0400 Subject: [PATCH 25/31] move types --- .../[teamId]/ideation/adapters/ideationClientAdapter.ts | 3 ++- .../my-voyage/[teamId]/ideation/adapters/ideationSA.ts | 3 ++- src/modules/ideation/ports/primary/ideationClientPort.ts | 2 +- src/modules/shared/types.ts | 6 ++++++ src/types/types.ts | 4 ---- src/utils/handleAsync.ts | 8 ++++---- 6 files changed, 15 insertions(+), 11 deletions(-) create mode 100644 src/modules/shared/types.ts diff --git a/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationClientAdapter.ts b/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationClientAdapter.ts index d8c60f38a..2af4601af 100644 --- a/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationClientAdapter.ts +++ b/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationClientAdapter.ts @@ -1,7 +1,8 @@ import { revalidateTag } from "next/cache"; import { type IdeationClientPort } from "@/modules/ideation/ports/primary/ideationClientPort"; import { type AddIdeationUsecaseDto } from "@/modules/ideation/application/dtos/addIdeationUsecaseDto"; -import { handleAsync, type AsyncActionResponse } from "@/utils/handleAsync"; +import { handleAsync } from "@/utils/handleAsync"; +import { type AsyncActionResponse } from "@/modules/shared/types"; import { type AddIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; import { AddIdeationUseCase } from "@/modules/ideation/application/usecases/addIdeationUseCase"; import { getAccessToken } from "@/utils/getCookie"; diff --git a/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationSA.ts b/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationSA.ts index 18af9e06e..79305a8d2 100644 --- a/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationSA.ts +++ b/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationSA.ts @@ -4,7 +4,8 @@ import { revalidateTag } from "next/cache"; import { IdeationClientAdapter } from "./ideationClientAdapter"; import { getAccessToken } from "@/utils/getCookie"; import { DELETE, PATCH, POST } from "@/utils/requests"; -import { type AsyncActionResponse, handleAsync } from "@/utils/handleAsync"; +import { handleAsync } from "@/utils/handleAsync"; +import { type AsyncActionResponse } from "@/modules/shared/types"; import { CacheTag } from "@/utils/cacheTag"; import { type AddIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; import { type AddIdeationUsecaseDto } from "@/modules/ideation/application/dtos/addIdeationUsecaseDto"; diff --git a/src/modules/ideation/ports/primary/ideationClientPort.ts b/src/modules/ideation/ports/primary/ideationClientPort.ts index 8a6a22c80..09ad5cf6c 100644 --- a/src/modules/ideation/ports/primary/ideationClientPort.ts +++ b/src/modules/ideation/ports/primary/ideationClientPort.ts @@ -1,5 +1,5 @@ import { type AddIdeationUsecaseDto } from "@/modules/ideation/application/dtos/addIdeationUsecaseDto"; -import { type AsyncActionResponse } from "@/utils/handleAsync"; +import { type AsyncActionResponse } from "@/modules/shared/types"; import { type AddIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; export interface IdeationClientPort { diff --git a/src/modules/shared/types.ts b/src/modules/shared/types.ts new file mode 100644 index 000000000..587476253 --- /dev/null +++ b/src/modules/shared/types.ts @@ -0,0 +1,6 @@ +export interface AppError { + message: string; +} + +export type AsyncFunction = () => Promise; +export type AsyncActionResponse = [X | null, AppError | null]; diff --git a/src/types/types.ts b/src/types/types.ts index 2fb4ad92e..077b0ae33 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -1,5 +1 @@ // only put global types here - -export interface AppError { - message: string; -} diff --git a/src/utils/handleAsync.ts b/src/utils/handleAsync.ts index de3264f70..3ca6f810c 100644 --- a/src/utils/handleAsync.ts +++ b/src/utils/handleAsync.ts @@ -1,7 +1,7 @@ -import { type AppError } from "@/types/types"; - -type AsyncFunction = () => Promise; -export type AsyncActionResponse = [X | null, AppError | null]; +import { + type AsyncActionResponse, + type AsyncFunction, +} from "@/modules/shared/types"; export async function handleAsync( asyncFn: AsyncFunction, From a857f8608529cbd392603a4d657391adf892e384 Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Tue, 1 Oct 2024 00:07:01 -0400 Subject: [PATCH 26/31] fix build errors --- src/app/(auth)/AuthProvider.tsx | 2 +- src/app/(auth)/authService.ts | 3 ++- .../voyage-dashboard/getDashboardData.ts | 3 +-- .../components/DirectoryComponentWrapper.tsx | 3 ++- .../[teamId]/directory/directoryService.ts | 3 ++- .../components/FeaturesComponentWrapper.tsx | 3 ++- .../[teamId]/features/featuresService.ts | 3 ++- .../[teamId]/ideation/adapters/ideationSA.ts | 26 ------------------- .../components/IdeationComponentWrapper.tsx | 5 ++-- .../components/ConfirmationButton.tsx | 2 +- .../RedirectToCurrentSprintWrapper.tsx | 3 ++- .../sprints/components/SprintWrapper.tsx | 3 ++- .../components/WeeklyCheckInWrapper.tsx | 3 ++- .../[teamId]/sprints/sprintsService.ts | 3 ++- .../[teamId]/tech-stack/techStackService.ts | 3 ++- .../voyage-resources/resourcesService.ts | 3 ++- src/hooks/useServerAction.ts | 2 +- src/store/features/modal/modalSlice.ts | 4 +-- src/utils/getCurrentVoyageData.ts | 3 +-- src/utils/getCurrentVoyageTeam.ts | 2 +- src/utils/getUser.ts | 3 ++- 21 files changed, 35 insertions(+), 50 deletions(-) diff --git a/src/app/(auth)/AuthProvider.tsx b/src/app/(auth)/AuthProvider.tsx index f5b51f2a2..e34395fd1 100644 --- a/src/app/(auth)/AuthProvider.tsx +++ b/src/app/(auth)/AuthProvider.tsx @@ -5,7 +5,7 @@ import { formatInTimeZone } from "date-fns-tz"; import { clientSignIn, clientSignOut } from "@/store/features/auth/authSlice"; import { useAppDispatch } from "@/store/hooks"; import { type User, getUserState } from "@/store/features/user/userSlice"; -import { type AppError } from "@/types/types"; +import { type AppError } from "@/modules/shared/types"; import { currentDate } from "@/utils/getCurrentSprint"; interface AuthProviderProps { diff --git a/src/app/(auth)/authService.ts b/src/app/(auth)/authService.ts index 2a8c54999..d5d12121f 100644 --- a/src/app/(auth)/authService.ts +++ b/src/app/(auth)/authService.ts @@ -1,7 +1,8 @@ "use server"; import { cookies } from "next/headers"; -import { type AsyncActionResponse, handleAsync } from "@/utils/handleAsync"; +import { handleAsync } from "@/utils/handleAsync"; +import { type AsyncActionResponse } from "@/modules/shared/types"; import { getAccessToken, getRefreshToken } from "@/utils/getCookie"; import { POST, UNAUTHPOST } from "@/utils/requests"; diff --git a/src/app/(main)/dashboard/components/voyage-dashboard/getDashboardData.ts b/src/app/(main)/dashboard/components/voyage-dashboard/getDashboardData.ts index 4e235a30e..30f0cfdab 100644 --- a/src/app/(main)/dashboard/components/voyage-dashboard/getDashboardData.ts +++ b/src/app/(main)/dashboard/components/voyage-dashboard/getDashboardData.ts @@ -2,7 +2,7 @@ import { fetchSprints } from "@/myVoyage/sprints/components/RedirectToCurrentSpr import { fetchMeeting } from "@/myVoyage/sprints/components/SprintWrapper"; import type { User } from "@/store/features/user/userSlice"; import type { Sprint, Voyage } from "@/store/features/sprint/sprintSlice"; -import type { AppError } from "@/types/types"; +import type { AppError, AsyncActionResponse } from "@/modules/shared/types"; import { getCurrentSprint } from "@/utils/getCurrentSprint"; import { getCurrentVoyageData } from "@/utils/getCurrentVoyageData"; import { fetchResources } from "@/app/(main)/my-voyage/[teamId]/voyage-resources/components/ResourcesComponentWrapper"; @@ -13,7 +13,6 @@ import { type FeaturesList } from "@/store/features/features/featuresSlice"; import { type IdeationData } from "@/store/features/ideation/ideationSlice"; import { type TechStackData } from "@/store/features/techStack/techStackSlice"; import { type ResourceData } from "@/store/features/resources/resourcesSlice"; -import type { AsyncActionResponse } from "@/utils/handleAsync"; import { ErrorType } from "@/utils/error"; interface GetDashboardDataResponse { diff --git a/src/app/(main)/my-voyage/[teamId]/directory/components/DirectoryComponentWrapper.tsx b/src/app/(main)/my-voyage/[teamId]/directory/components/DirectoryComponentWrapper.tsx index 59a863f66..a83604e55 100644 --- a/src/app/(main)/my-voyage/[teamId]/directory/components/DirectoryComponentWrapper.tsx +++ b/src/app/(main)/my-voyage/[teamId]/directory/components/DirectoryComponentWrapper.tsx @@ -9,7 +9,8 @@ import ErrorComponent from "@/components/Error"; import { type TeamDirectory } from "@/store/features/directory/directorySlice"; import { getAccessToken } from "@/utils/getCookie"; -import { type AsyncActionResponse, handleAsync } from "@/utils/handleAsync"; +import { handleAsync } from "@/utils/handleAsync"; +import { type AsyncActionResponse } from "@/modules/shared/types"; import { GET } from "@/utils/requests"; import { CacheTag } from "@/utils/cacheTag"; import { type User } from "@/store/features/user/userSlice"; diff --git a/src/app/(main)/my-voyage/[teamId]/directory/directoryService.ts b/src/app/(main)/my-voyage/[teamId]/directory/directoryService.ts index 299774e73..1910d21cb 100644 --- a/src/app/(main)/my-voyage/[teamId]/directory/directoryService.ts +++ b/src/app/(main)/my-voyage/[teamId]/directory/directoryService.ts @@ -2,7 +2,8 @@ import { revalidateTag } from "next/cache"; import { getAccessToken } from "@/utils/getCookie"; -import { type AsyncActionResponse, handleAsync } from "@/utils/handleAsync"; +import { handleAsync } from "@/utils/handleAsync"; +import { type AsyncActionResponse } from "@/modules/shared/types"; import { PATCH } from "@/utils/requests"; import { CacheTag } from "@/utils/cacheTag"; diff --git a/src/app/(main)/my-voyage/[teamId]/features/components/FeaturesComponentWrapper.tsx b/src/app/(main)/my-voyage/[teamId]/features/components/FeaturesComponentWrapper.tsx index 008df74e6..10a6212d5 100644 --- a/src/app/(main)/my-voyage/[teamId]/features/components/FeaturesComponentWrapper.tsx +++ b/src/app/(main)/my-voyage/[teamId]/features/components/FeaturesComponentWrapper.tsx @@ -16,7 +16,8 @@ import { getUser } from "@/utils/getUser"; import { getAccessToken } from "@/utils/getCookie"; import { GET } from "@/utils/requests"; import { CacheTag } from "@/utils/cacheTag"; -import { type AsyncActionResponse, handleAsync } from "@/utils/handleAsync"; +import { handleAsync } from "@/utils/handleAsync"; +import { type AsyncActionResponse } from "@/modules/shared/types"; import { ErrorType } from "@/utils/error"; function transformData(features: Features[]): FeaturesList[] { diff --git a/src/app/(main)/my-voyage/[teamId]/features/featuresService.ts b/src/app/(main)/my-voyage/[teamId]/features/featuresService.ts index 318be5f40..47361c620 100644 --- a/src/app/(main)/my-voyage/[teamId]/features/featuresService.ts +++ b/src/app/(main)/my-voyage/[teamId]/features/featuresService.ts @@ -4,7 +4,8 @@ import { revalidateTag } from "next/cache"; import { type Features } from "@/store/features/features/featuresSlice"; import { CacheTag } from "@/utils/cacheTag"; import { getAccessToken } from "@/utils/getCookie"; -import { type AsyncActionResponse, handleAsync } from "@/utils/handleAsync"; +import { handleAsync } from "@/utils/handleAsync"; +import { type AsyncActionResponse } from "@/modules/shared/types"; import { DELETE, PATCH, POST } from "@/utils/requests"; interface SaveOrderProps { diff --git a/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationSA.ts b/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationSA.ts index 79305a8d2..2414740cb 100644 --- a/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationSA.ts +++ b/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationSA.ts @@ -75,32 +75,6 @@ export async function addIdeation({ }); } -// test -// export async function addIdeation({ -// teamId, -// title, -// description, -// vision, -// }: AddIdeationProps): Promise> { -// const token = getAccessToken(); - -// const addIdeationAsync = () => -// POST( -// `api/v1/voyages/teams/${teamId}/ideations`, -// token, -// "default", -// { title, description, vision }, -// ); - -// const [res, error] = await handleAsync(addIdeationAsync); - -// if (res) { -// revalidateTag(CacheTag.ideation); -// } - -// return [res, error]; -// } - export async function editIdeation({ ideationId, title, diff --git a/src/app/(main)/my-voyage/[teamId]/ideation/components/IdeationComponentWrapper.tsx b/src/app/(main)/my-voyage/[teamId]/ideation/components/IdeationComponentWrapper.tsx index 29d74891d..413d1f779 100644 --- a/src/app/(main)/my-voyage/[teamId]/ideation/components/IdeationComponentWrapper.tsx +++ b/src/app/(main)/my-voyage/[teamId]/ideation/components/IdeationComponentWrapper.tsx @@ -5,7 +5,7 @@ import FinalizedIdeationCard from "./FinalizedIdeationCard"; import IdeationContainer from "./IdeationContainer"; import IdeationProvider from "./IdeationProvider"; import VoteCard from "./VoteCard"; -import { type FetchIdeationsProps } from "@/app/(main)/my-voyage/[teamId]/ideation/ideationService"; +import { type FetchIdeationsProps } from "@/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationSA"; import Banner from "@/components/banner/Banner"; import VoyagePageBannerContainer from "@/components/banner/VoyagePageBannerContainer"; import ErrorComponent from "@/components/Error"; @@ -15,7 +15,8 @@ import { CacheTag } from "@/utils/cacheTag"; import { getAccessToken } from "@/utils/getCookie"; import { getCurrentVoyageData } from "@/utils/getCurrentVoyageData"; import { getUser } from "@/utils/getUser"; -import { handleAsync, type AsyncActionResponse } from "@/utils/handleAsync"; +import { handleAsync } from "@/utils/handleAsync"; +import { type AsyncActionResponse } from "@/modules/shared/types"; import { GET } from "@/utils/requests"; import routePaths from "@/utils/routePaths"; import { ErrorType } from "@/utils/error"; diff --git a/src/app/(main)/my-voyage/[teamId]/ideation/finalize/components/ConfirmationButton.tsx b/src/app/(main)/my-voyage/[teamId]/ideation/finalize/components/ConfirmationButton.tsx index a8a59cd67..77931595b 100644 --- a/src/app/(main)/my-voyage/[teamId]/ideation/finalize/components/ConfirmationButton.tsx +++ b/src/app/(main)/my-voyage/[teamId]/ideation/finalize/components/ConfirmationButton.tsx @@ -2,7 +2,7 @@ import { useParams, useRouter } from "next/navigation"; import { type FinalizedIdeation } from "./FinalizeIdeationList"; import useServerAction from "@/hooks/useServerAction"; import Button from "@/components/Button"; -import { finalizeIdeation } from "@/myVoyage/ideation/ideationService"; +import { finalizeIdeation } from "@/myVoyage/ideation/adapters/ideationSA"; import routePaths from "@/utils/routePaths"; import { useAppDispatch } from "@/store/hooks"; import { onOpenModal } from "@/store/features/modal/modalSlice"; diff --git a/src/app/(main)/my-voyage/[teamId]/sprints/components/RedirectToCurrentSprintWrapper.tsx b/src/app/(main)/my-voyage/[teamId]/sprints/components/RedirectToCurrentSprintWrapper.tsx index cdf368a7f..7357515ab 100644 --- a/src/app/(main)/my-voyage/[teamId]/sprints/components/RedirectToCurrentSprintWrapper.tsx +++ b/src/app/(main)/my-voyage/[teamId]/sprints/components/RedirectToCurrentSprintWrapper.tsx @@ -16,7 +16,8 @@ import { getUser } from "@/utils/getUser"; import { getCurrentSprint } from "@/utils/getCurrentSprint"; import { GET } from "@/utils/requests"; import { CacheTag } from "@/utils/cacheTag"; -import { type AsyncActionResponse, handleAsync } from "@/utils/handleAsync"; +import { handleAsync } from "@/utils/handleAsync"; +import { type AsyncActionResponse } from "@/modules/shared/types"; import { type Sprint } from "@/store/features/sprint/sprintSlice"; import { getCurrentVoyageData } from "@/utils/getCurrentVoyageData"; import routePaths from "@/utils/routePaths"; diff --git a/src/app/(main)/my-voyage/[teamId]/sprints/components/SprintWrapper.tsx b/src/app/(main)/my-voyage/[teamId]/sprints/components/SprintWrapper.tsx index 4f9e7a93c..6923111ac 100644 --- a/src/app/(main)/my-voyage/[teamId]/sprints/components/SprintWrapper.tsx +++ b/src/app/(main)/my-voyage/[teamId]/sprints/components/SprintWrapper.tsx @@ -25,7 +25,8 @@ import { } from "@/store/features/sprint/sprintSlice"; import { getCurrentSprint } from "@/utils/getCurrentSprint"; -import { type AsyncActionResponse, handleAsync } from "@/utils/handleAsync"; +import { handleAsync } from "@/utils/handleAsync"; +import { type AsyncActionResponse } from "@/modules/shared/types"; import { GET } from "@/utils/requests"; import { getAccessToken } from "@/utils/getCookie"; import { getUser } from "@/utils/getUser"; diff --git a/src/app/(main)/my-voyage/[teamId]/sprints/components/WeeklyCheckInWrapper.tsx b/src/app/(main)/my-voyage/[teamId]/sprints/components/WeeklyCheckInWrapper.tsx index fc21649b9..0367de0a7 100644 --- a/src/app/(main)/my-voyage/[teamId]/sprints/components/WeeklyCheckInWrapper.tsx +++ b/src/app/(main)/my-voyage/[teamId]/sprints/components/WeeklyCheckInWrapper.tsx @@ -9,7 +9,8 @@ import { getAccessToken } from "@/utils/getCookie"; import { getUser } from "@/utils/getUser"; import { GET } from "@/utils/requests"; import { CacheTag } from "@/utils/cacheTag"; -import { type AsyncActionResponse, handleAsync } from "@/utils/handleAsync"; +import { handleAsync } from "@/utils/handleAsync"; +import { type AsyncActionResponse } from "@/modules/shared/types"; import { getCurrentVoyageData } from "@/utils/getCurrentVoyageData"; import routePaths from "@/utils/routePaths"; import { Forms } from "@/utils/form/formsEnums"; diff --git a/src/app/(main)/my-voyage/[teamId]/sprints/sprintsService.ts b/src/app/(main)/my-voyage/[teamId]/sprints/sprintsService.ts index 31f7313d8..0d4b5a3a6 100644 --- a/src/app/(main)/my-voyage/[teamId]/sprints/sprintsService.ts +++ b/src/app/(main)/my-voyage/[teamId]/sprints/sprintsService.ts @@ -3,7 +3,8 @@ import { revalidateTag } from "next/cache"; import { getAccessToken } from "@/utils/getCookie"; import { DELETE, PATCH, POST } from "@/utils/requests"; -import { type AsyncActionResponse, handleAsync } from "@/utils/handleAsync"; +import { handleAsync } from "@/utils/handleAsync"; +import { type AsyncActionResponse } from "@/modules/shared/types"; import { CacheTag } from "@/utils/cacheTag"; import { getSprintCache } from "@/utils/getSprintCache"; diff --git a/src/app/(main)/my-voyage/[teamId]/tech-stack/techStackService.ts b/src/app/(main)/my-voyage/[teamId]/tech-stack/techStackService.ts index f2362218a..63d2924e6 100644 --- a/src/app/(main)/my-voyage/[teamId]/tech-stack/techStackService.ts +++ b/src/app/(main)/my-voyage/[teamId]/tech-stack/techStackService.ts @@ -4,7 +4,8 @@ import { revalidateTag } from "next/cache"; import type { Category } from "./finalize/types"; import { CacheTag } from "@/utils/cacheTag"; import { getAccessToken } from "@/utils/getCookie"; -import { type AsyncActionResponse, handleAsync } from "@/utils/handleAsync"; +import { handleAsync } from "@/utils/handleAsync"; +import { type AsyncActionResponse } from "@/modules/shared/types"; import { DELETE, PATCH, POST } from "@/utils/requests"; import { type TechStackItem } from "@/store/features/techStack/techStackSlice"; diff --git a/src/app/(main)/my-voyage/[teamId]/voyage-resources/resourcesService.ts b/src/app/(main)/my-voyage/[teamId]/voyage-resources/resourcesService.ts index 3c3fe3fda..2bce5661a 100644 --- a/src/app/(main)/my-voyage/[teamId]/voyage-resources/resourcesService.ts +++ b/src/app/(main)/my-voyage/[teamId]/voyage-resources/resourcesService.ts @@ -3,7 +3,8 @@ import { revalidateTag } from "next/cache"; import { getAccessToken } from "@/utils/getCookie"; import { POST, DELETE } from "@/utils/requests"; -import { type AsyncActionResponse, handleAsync } from "@/utils/handleAsync"; +import { handleAsync } from "@/utils/handleAsync"; +import { type AsyncActionResponse } from "@/modules/shared/types"; import { CacheTag } from "@/utils/cacheTag"; interface ResourceProps { diff --git a/src/hooks/useServerAction.ts b/src/hooks/useServerAction.ts index 0427b8c9e..71fd5ddba 100644 --- a/src/hooks/useServerAction.ts +++ b/src/hooks/useServerAction.ts @@ -1,7 +1,7 @@ "use client"; import { useCallback, useState } from "react"; -import { type AsyncActionResponse } from "@/utils/handleAsync"; +import { type AsyncActionResponse } from "@/modules/shared/types"; type ActionType = (arg: X) => Promise>; diff --git a/src/store/features/modal/modalSlice.ts b/src/store/features/modal/modalSlice.ts index b157c3e9c..65c4fbd8a 100644 --- a/src/store/features/modal/modalSlice.ts +++ b/src/store/features/modal/modalSlice.ts @@ -9,12 +9,12 @@ import { type DeleteIdeationProps, type DeleteIdeationResponse, type deleteIdeation, -} from "@/myVoyage/ideation/ideationService"; +} from "@/myVoyage/ideation/adapters/ideationSA"; import { type DeleteFeatureProps, type deleteFeature, } from "@/myVoyage/features/featuresService"; -import { type AsyncActionResponse } from "@/utils/handleAsync"; +import { type AsyncActionResponse } from "@/modules/shared/types"; import { type DeleteAgendaTopicProps, type DeleteAgendaTopicResponse, diff --git a/src/utils/getCurrentVoyageData.ts b/src/utils/getCurrentVoyageData.ts index 4ec6e78bd..02de6ee3c 100644 --- a/src/utils/getCurrentVoyageData.ts +++ b/src/utils/getCurrentVoyageData.ts @@ -1,7 +1,6 @@ -import { type AsyncActionResponse } from "./handleAsync"; import { getCurrentVoyageTeam } from "./getCurrentVoyageTeam"; +import type { AsyncActionResponse, AppError } from "@/modules/shared/types"; import { type User } from "@/store/features/user/userSlice"; -import { type AppError } from "@/types/types"; interface GetCurrentVoyageDataProps { teamId: number; diff --git a/src/utils/getCurrentVoyageTeam.ts b/src/utils/getCurrentVoyageTeam.ts index 3f98c7ac8..466a6bd79 100644 --- a/src/utils/getCurrentVoyageTeam.ts +++ b/src/utils/getCurrentVoyageTeam.ts @@ -1,4 +1,4 @@ -import { type AppError } from "@/types/types"; +import { type AppError } from "@/modules/shared/types"; import { type User, type VoyageTeamMember, diff --git a/src/utils/getUser.ts b/src/utils/getUser.ts index b5c8efe7b..8865369be 100644 --- a/src/utils/getUser.ts +++ b/src/utils/getUser.ts @@ -1,6 +1,7 @@ import { getAccessToken } from "./getCookie"; -import { type AsyncActionResponse, handleAsync } from "./handleAsync"; +import { handleAsync } from "./handleAsync"; import { GET } from "./requests"; +import { type AsyncActionResponse } from "@/modules/shared/types"; import { type User } from "@/store/features/user/userSlice"; export function getUser(): Promise> { From 5641cfb3b34798de56f2499cfa6e46654428dc97 Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Tue, 1 Oct 2024 00:31:44 -0400 Subject: [PATCH 27/31] move class instantiation out of the function --- .../(main)/my-voyage/[teamId]/ideation/adapters/ideationSA.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationSA.ts b/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationSA.ts index 2414740cb..35838500a 100644 --- a/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationSA.ts +++ b/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationSA.ts @@ -57,6 +57,8 @@ export interface IdeationVoteResponse extends IdeationResponse { projectIdeaId: number; } +const addIdeationClientAdapter = new IdeationClientAdapter(); + export async function addIdeation({ teamId, title, @@ -65,8 +67,6 @@ export async function addIdeation({ }: AddIdeationUsecaseDto): Promise< AsyncActionResponse > { - const addIdeationClientAdapter = new IdeationClientAdapter(); - return addIdeationClientAdapter.addIdeation({ teamId, title, From 2ab73648f8ffeb01434f3766bc70d486af5de087 Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Tue, 1 Oct 2024 01:18:32 -0400 Subject: [PATCH 28/31] refactor server action and adapter --- .../adapters/ideationClientAdapter.ts | 42 ++++++------------- .../[teamId]/ideation/adapters/ideationSA.ts | 25 ++++++++--- .../ports/primary/ideationClientPort.ts | 5 +-- 3 files changed, 32 insertions(+), 40 deletions(-) diff --git a/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationClientAdapter.ts b/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationClientAdapter.ts index 2af4601af..256b95167 100644 --- a/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationClientAdapter.ts +++ b/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationClientAdapter.ts @@ -1,14 +1,9 @@ -import { revalidateTag } from "next/cache"; import { type IdeationClientPort } from "@/modules/ideation/ports/primary/ideationClientPort"; -import { type AddIdeationUsecaseDto } from "@/modules/ideation/application/dtos/addIdeationUsecaseDto"; -import { handleAsync } from "@/utils/handleAsync"; -import { type AsyncActionResponse } from "@/modules/shared/types"; import { type AddIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; import { AddIdeationUseCase } from "@/modules/ideation/application/usecases/addIdeationUseCase"; -import { getAccessToken } from "@/utils/getCookie"; import { NextJsRestApiAdapter } from "@/modules/restApi/adapters/secondary/nextJsRestApiAdapter"; import { IdeationApiAdapter } from "@/modules/ideation/adapters/secondary/ideationApiAdapter"; -import { CacheTag } from "@/utils/cacheTag"; +import { type AddIdeationRequestDto } from "@/modules/ideation/application/dtos/request.dto"; const nextJsRestApiAdapter = new NextJsRestApiAdapter( process.env.NEXT_PUBLIC_API_URL!, @@ -16,37 +11,24 @@ const nextJsRestApiAdapter = new NextJsRestApiAdapter( const ideationApiPort = new IdeationApiAdapter(nextJsRestApiAdapter); export class IdeationClientAdapter implements IdeationClientPort { - constructor() {} - async addIdeation({ teamId, title, description, vision, - }: AddIdeationUsecaseDto): Promise< - AsyncActionResponse - > { - const token = getAccessToken(); + token, + cache, + }: Required): Promise { const addIdeationUseCase = new AddIdeationUseCase(ideationApiPort); // refactor this later to not expect a function - const addIdeationAsync = async () => - await addIdeationUseCase.execute({ - teamId, - title, - description, - vision, - cache: "default", - token, - }); - - const [res, error] = - await handleAsync(addIdeationAsync); - - if (res) { - revalidateTag(CacheTag.ideation); - } - - return [res, error]; + return await addIdeationUseCase.execute({ + teamId, + title, + description, + vision, + cache, + token, + }); } } diff --git a/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationSA.ts b/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationSA.ts index 35838500a..008f3e20d 100644 --- a/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationSA.ts +++ b/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationSA.ts @@ -67,12 +67,25 @@ export async function addIdeation({ }: AddIdeationUsecaseDto): Promise< AsyncActionResponse > { - return addIdeationClientAdapter.addIdeation({ - teamId, - title, - description, - vision, - }); + const token = getAccessToken(); + + const addIdeationAsync = () => + addIdeationClientAdapter.addIdeation({ + teamId, + title, + description, + vision, + token, + cache: "default", + }); + + const [res, error] = await handleAsync(addIdeationAsync); + + if (res) { + revalidateTag(CacheTag.ideation); + } + + return [res, error]; } export async function editIdeation({ diff --git a/src/modules/ideation/ports/primary/ideationClientPort.ts b/src/modules/ideation/ports/primary/ideationClientPort.ts index 09ad5cf6c..68260bbd4 100644 --- a/src/modules/ideation/ports/primary/ideationClientPort.ts +++ b/src/modules/ideation/ports/primary/ideationClientPort.ts @@ -1,5 +1,4 @@ import { type AddIdeationUsecaseDto } from "@/modules/ideation/application/dtos/addIdeationUsecaseDto"; -import { type AsyncActionResponse } from "@/modules/shared/types"; import { type AddIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; export interface IdeationClientPort { @@ -8,7 +7,5 @@ export interface IdeationClientPort { title, description, vision, - }: AddIdeationUsecaseDto): Promise< - AsyncActionResponse - >; + }: AddIdeationUsecaseDto): Promise; } From 8aa077f4b88b2ae4943e8994853d082e90442be0 Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Tue, 1 Oct 2024 01:28:07 -0400 Subject: [PATCH 29/31] refactor types --- src/app/(auth)/AuthProvider.tsx | 2 +- src/app/(auth)/authService.ts | 2 +- .../components/voyage-dashboard/getDashboardData.ts | 3 ++- .../directory/components/DirectoryComponentWrapper.tsx | 2 +- .../my-voyage/[teamId]/directory/directoryService.ts | 2 +- .../features/components/FeaturesComponentWrapper.tsx | 2 +- .../(main)/my-voyage/[teamId]/features/featuresService.ts | 2 +- .../my-voyage/[teamId]/ideation/adapters/ideationSA.ts | 2 +- .../ideation/components/IdeationComponentWrapper.tsx | 2 +- .../sprints/components/RedirectToCurrentSprintWrapper.tsx | 2 +- .../[teamId]/sprints/components/SprintWrapper.tsx | 2 +- .../[teamId]/sprints/components/WeeklyCheckInWrapper.tsx | 2 +- .../(main)/my-voyage/[teamId]/sprints/sprintsService.ts | 2 +- .../my-voyage/[teamId]/tech-stack/techStackService.ts | 2 +- .../[teamId]/voyage-resources/resourcesService.ts | 2 +- src/hooks/useServerAction.ts | 2 +- src/modules/shared/types.ts | 6 ------ src/store/features/modal/modalSlice.ts | 2 +- src/types/types.ts | 3 +++ src/utils/getCurrentVoyageData.ts | 3 ++- src/utils/getCurrentVoyageTeam.ts | 2 +- src/utils/getUser.ts | 2 +- src/utils/handleAsync.ts | 8 ++++---- 23 files changed, 29 insertions(+), 30 deletions(-) delete mode 100644 src/modules/shared/types.ts diff --git a/src/app/(auth)/AuthProvider.tsx b/src/app/(auth)/AuthProvider.tsx index e34395fd1..f5b51f2a2 100644 --- a/src/app/(auth)/AuthProvider.tsx +++ b/src/app/(auth)/AuthProvider.tsx @@ -5,7 +5,7 @@ import { formatInTimeZone } from "date-fns-tz"; import { clientSignIn, clientSignOut } from "@/store/features/auth/authSlice"; import { useAppDispatch } from "@/store/hooks"; import { type User, getUserState } from "@/store/features/user/userSlice"; -import { type AppError } from "@/modules/shared/types"; +import { type AppError } from "@/types/types"; import { currentDate } from "@/utils/getCurrentSprint"; interface AuthProviderProps { diff --git a/src/app/(auth)/authService.ts b/src/app/(auth)/authService.ts index d5d12121f..24df5341b 100644 --- a/src/app/(auth)/authService.ts +++ b/src/app/(auth)/authService.ts @@ -2,7 +2,7 @@ import { cookies } from "next/headers"; import { handleAsync } from "@/utils/handleAsync"; -import { type AsyncActionResponse } from "@/modules/shared/types"; +import { type AsyncActionResponse } from "@/utils/handleAsync"; import { getAccessToken, getRefreshToken } from "@/utils/getCookie"; import { POST, UNAUTHPOST } from "@/utils/requests"; diff --git a/src/app/(main)/dashboard/components/voyage-dashboard/getDashboardData.ts b/src/app/(main)/dashboard/components/voyage-dashboard/getDashboardData.ts index 30f0cfdab..ecbe3e859 100644 --- a/src/app/(main)/dashboard/components/voyage-dashboard/getDashboardData.ts +++ b/src/app/(main)/dashboard/components/voyage-dashboard/getDashboardData.ts @@ -2,7 +2,8 @@ import { fetchSprints } from "@/myVoyage/sprints/components/RedirectToCurrentSpr import { fetchMeeting } from "@/myVoyage/sprints/components/SprintWrapper"; import type { User } from "@/store/features/user/userSlice"; import type { Sprint, Voyage } from "@/store/features/sprint/sprintSlice"; -import type { AppError, AsyncActionResponse } from "@/modules/shared/types"; +import { type AppError } from "@/types/types"; +import { type AsyncActionResponse } from "@/utils/handleAsync"; import { getCurrentSprint } from "@/utils/getCurrentSprint"; import { getCurrentVoyageData } from "@/utils/getCurrentVoyageData"; import { fetchResources } from "@/app/(main)/my-voyage/[teamId]/voyage-resources/components/ResourcesComponentWrapper"; diff --git a/src/app/(main)/my-voyage/[teamId]/directory/components/DirectoryComponentWrapper.tsx b/src/app/(main)/my-voyage/[teamId]/directory/components/DirectoryComponentWrapper.tsx index a83604e55..0139b856d 100644 --- a/src/app/(main)/my-voyage/[teamId]/directory/components/DirectoryComponentWrapper.tsx +++ b/src/app/(main)/my-voyage/[teamId]/directory/components/DirectoryComponentWrapper.tsx @@ -10,7 +10,7 @@ import { type TeamDirectory } from "@/store/features/directory/directorySlice"; import { getAccessToken } from "@/utils/getCookie"; import { handleAsync } from "@/utils/handleAsync"; -import { type AsyncActionResponse } from "@/modules/shared/types"; +import { type AsyncActionResponse } from "@/utils/handleAsync"; import { GET } from "@/utils/requests"; import { CacheTag } from "@/utils/cacheTag"; import { type User } from "@/store/features/user/userSlice"; diff --git a/src/app/(main)/my-voyage/[teamId]/directory/directoryService.ts b/src/app/(main)/my-voyage/[teamId]/directory/directoryService.ts index 1910d21cb..eaf9dc43d 100644 --- a/src/app/(main)/my-voyage/[teamId]/directory/directoryService.ts +++ b/src/app/(main)/my-voyage/[teamId]/directory/directoryService.ts @@ -3,7 +3,7 @@ import { revalidateTag } from "next/cache"; import { getAccessToken } from "@/utils/getCookie"; import { handleAsync } from "@/utils/handleAsync"; -import { type AsyncActionResponse } from "@/modules/shared/types"; +import { type AsyncActionResponse } from "@/utils/handleAsync"; import { PATCH } from "@/utils/requests"; import { CacheTag } from "@/utils/cacheTag"; diff --git a/src/app/(main)/my-voyage/[teamId]/features/components/FeaturesComponentWrapper.tsx b/src/app/(main)/my-voyage/[teamId]/features/components/FeaturesComponentWrapper.tsx index 10a6212d5..ca81309b8 100644 --- a/src/app/(main)/my-voyage/[teamId]/features/components/FeaturesComponentWrapper.tsx +++ b/src/app/(main)/my-voyage/[teamId]/features/components/FeaturesComponentWrapper.tsx @@ -17,7 +17,7 @@ import { getAccessToken } from "@/utils/getCookie"; import { GET } from "@/utils/requests"; import { CacheTag } from "@/utils/cacheTag"; import { handleAsync } from "@/utils/handleAsync"; -import { type AsyncActionResponse } from "@/modules/shared/types"; +import { type AsyncActionResponse } from "@/utils/handleAsync"; import { ErrorType } from "@/utils/error"; function transformData(features: Features[]): FeaturesList[] { diff --git a/src/app/(main)/my-voyage/[teamId]/features/featuresService.ts b/src/app/(main)/my-voyage/[teamId]/features/featuresService.ts index 47361c620..3597c1b47 100644 --- a/src/app/(main)/my-voyage/[teamId]/features/featuresService.ts +++ b/src/app/(main)/my-voyage/[teamId]/features/featuresService.ts @@ -5,7 +5,7 @@ import { type Features } from "@/store/features/features/featuresSlice"; import { CacheTag } from "@/utils/cacheTag"; import { getAccessToken } from "@/utils/getCookie"; import { handleAsync } from "@/utils/handleAsync"; -import { type AsyncActionResponse } from "@/modules/shared/types"; +import { type AsyncActionResponse } from "@/utils/handleAsync"; import { DELETE, PATCH, POST } from "@/utils/requests"; interface SaveOrderProps { diff --git a/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationSA.ts b/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationSA.ts index 008f3e20d..9ff0741f4 100644 --- a/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationSA.ts +++ b/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationSA.ts @@ -5,7 +5,7 @@ import { IdeationClientAdapter } from "./ideationClientAdapter"; import { getAccessToken } from "@/utils/getCookie"; import { DELETE, PATCH, POST } from "@/utils/requests"; import { handleAsync } from "@/utils/handleAsync"; -import { type AsyncActionResponse } from "@/modules/shared/types"; +import { type AsyncActionResponse } from "@/utils/handleAsync"; import { CacheTag } from "@/utils/cacheTag"; import { type AddIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; import { type AddIdeationUsecaseDto } from "@/modules/ideation/application/dtos/addIdeationUsecaseDto"; diff --git a/src/app/(main)/my-voyage/[teamId]/ideation/components/IdeationComponentWrapper.tsx b/src/app/(main)/my-voyage/[teamId]/ideation/components/IdeationComponentWrapper.tsx index 413d1f779..277dd5b65 100644 --- a/src/app/(main)/my-voyage/[teamId]/ideation/components/IdeationComponentWrapper.tsx +++ b/src/app/(main)/my-voyage/[teamId]/ideation/components/IdeationComponentWrapper.tsx @@ -16,7 +16,7 @@ import { getAccessToken } from "@/utils/getCookie"; import { getCurrentVoyageData } from "@/utils/getCurrentVoyageData"; import { getUser } from "@/utils/getUser"; import { handleAsync } from "@/utils/handleAsync"; -import { type AsyncActionResponse } from "@/modules/shared/types"; +import { type AsyncActionResponse } from "@/utils/handleAsync"; import { GET } from "@/utils/requests"; import routePaths from "@/utils/routePaths"; import { ErrorType } from "@/utils/error"; diff --git a/src/app/(main)/my-voyage/[teamId]/sprints/components/RedirectToCurrentSprintWrapper.tsx b/src/app/(main)/my-voyage/[teamId]/sprints/components/RedirectToCurrentSprintWrapper.tsx index 7357515ab..96a6acab9 100644 --- a/src/app/(main)/my-voyage/[teamId]/sprints/components/RedirectToCurrentSprintWrapper.tsx +++ b/src/app/(main)/my-voyage/[teamId]/sprints/components/RedirectToCurrentSprintWrapper.tsx @@ -17,7 +17,7 @@ import { getCurrentSprint } from "@/utils/getCurrentSprint"; import { GET } from "@/utils/requests"; import { CacheTag } from "@/utils/cacheTag"; import { handleAsync } from "@/utils/handleAsync"; -import { type AsyncActionResponse } from "@/modules/shared/types"; +import { type AsyncActionResponse } from "@/utils/handleAsync"; import { type Sprint } from "@/store/features/sprint/sprintSlice"; import { getCurrentVoyageData } from "@/utils/getCurrentVoyageData"; import routePaths from "@/utils/routePaths"; diff --git a/src/app/(main)/my-voyage/[teamId]/sprints/components/SprintWrapper.tsx b/src/app/(main)/my-voyage/[teamId]/sprints/components/SprintWrapper.tsx index 6923111ac..f22bfe474 100644 --- a/src/app/(main)/my-voyage/[teamId]/sprints/components/SprintWrapper.tsx +++ b/src/app/(main)/my-voyage/[teamId]/sprints/components/SprintWrapper.tsx @@ -26,7 +26,7 @@ import { import { getCurrentSprint } from "@/utils/getCurrentSprint"; import { handleAsync } from "@/utils/handleAsync"; -import { type AsyncActionResponse } from "@/modules/shared/types"; +import { type AsyncActionResponse } from "@/utils/handleAsync"; import { GET } from "@/utils/requests"; import { getAccessToken } from "@/utils/getCookie"; import { getUser } from "@/utils/getUser"; diff --git a/src/app/(main)/my-voyage/[teamId]/sprints/components/WeeklyCheckInWrapper.tsx b/src/app/(main)/my-voyage/[teamId]/sprints/components/WeeklyCheckInWrapper.tsx index 0367de0a7..2e30a26fe 100644 --- a/src/app/(main)/my-voyage/[teamId]/sprints/components/WeeklyCheckInWrapper.tsx +++ b/src/app/(main)/my-voyage/[teamId]/sprints/components/WeeklyCheckInWrapper.tsx @@ -10,7 +10,7 @@ import { getUser } from "@/utils/getUser"; import { GET } from "@/utils/requests"; import { CacheTag } from "@/utils/cacheTag"; import { handleAsync } from "@/utils/handleAsync"; -import { type AsyncActionResponse } from "@/modules/shared/types"; +import { type AsyncActionResponse } from "@/utils/handleAsync"; import { getCurrentVoyageData } from "@/utils/getCurrentVoyageData"; import routePaths from "@/utils/routePaths"; import { Forms } from "@/utils/form/formsEnums"; diff --git a/src/app/(main)/my-voyage/[teamId]/sprints/sprintsService.ts b/src/app/(main)/my-voyage/[teamId]/sprints/sprintsService.ts index 0d4b5a3a6..275d8e9aa 100644 --- a/src/app/(main)/my-voyage/[teamId]/sprints/sprintsService.ts +++ b/src/app/(main)/my-voyage/[teamId]/sprints/sprintsService.ts @@ -4,7 +4,7 @@ import { revalidateTag } from "next/cache"; import { getAccessToken } from "@/utils/getCookie"; import { DELETE, PATCH, POST } from "@/utils/requests"; import { handleAsync } from "@/utils/handleAsync"; -import { type AsyncActionResponse } from "@/modules/shared/types"; +import { type AsyncActionResponse } from "@/utils/handleAsync"; import { CacheTag } from "@/utils/cacheTag"; import { getSprintCache } from "@/utils/getSprintCache"; diff --git a/src/app/(main)/my-voyage/[teamId]/tech-stack/techStackService.ts b/src/app/(main)/my-voyage/[teamId]/tech-stack/techStackService.ts index 63d2924e6..9f8963d42 100644 --- a/src/app/(main)/my-voyage/[teamId]/tech-stack/techStackService.ts +++ b/src/app/(main)/my-voyage/[teamId]/tech-stack/techStackService.ts @@ -5,7 +5,7 @@ import type { Category } from "./finalize/types"; import { CacheTag } from "@/utils/cacheTag"; import { getAccessToken } from "@/utils/getCookie"; import { handleAsync } from "@/utils/handleAsync"; -import { type AsyncActionResponse } from "@/modules/shared/types"; +import { type AsyncActionResponse } from "@/utils/handleAsync"; import { DELETE, PATCH, POST } from "@/utils/requests"; import { type TechStackItem } from "@/store/features/techStack/techStackSlice"; diff --git a/src/app/(main)/my-voyage/[teamId]/voyage-resources/resourcesService.ts b/src/app/(main)/my-voyage/[teamId]/voyage-resources/resourcesService.ts index 2bce5661a..6b7aa428b 100644 --- a/src/app/(main)/my-voyage/[teamId]/voyage-resources/resourcesService.ts +++ b/src/app/(main)/my-voyage/[teamId]/voyage-resources/resourcesService.ts @@ -4,7 +4,7 @@ import { revalidateTag } from "next/cache"; import { getAccessToken } from "@/utils/getCookie"; import { POST, DELETE } from "@/utils/requests"; import { handleAsync } from "@/utils/handleAsync"; -import { type AsyncActionResponse } from "@/modules/shared/types"; +import { type AsyncActionResponse } from "@/utils/handleAsync"; import { CacheTag } from "@/utils/cacheTag"; interface ResourceProps { diff --git a/src/hooks/useServerAction.ts b/src/hooks/useServerAction.ts index 71fd5ddba..0427b8c9e 100644 --- a/src/hooks/useServerAction.ts +++ b/src/hooks/useServerAction.ts @@ -1,7 +1,7 @@ "use client"; import { useCallback, useState } from "react"; -import { type AsyncActionResponse } from "@/modules/shared/types"; +import { type AsyncActionResponse } from "@/utils/handleAsync"; type ActionType = (arg: X) => Promise>; diff --git a/src/modules/shared/types.ts b/src/modules/shared/types.ts deleted file mode 100644 index 587476253..000000000 --- a/src/modules/shared/types.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface AppError { - message: string; -} - -export type AsyncFunction = () => Promise; -export type AsyncActionResponse = [X | null, AppError | null]; diff --git a/src/store/features/modal/modalSlice.ts b/src/store/features/modal/modalSlice.ts index 65c4fbd8a..282efceaf 100644 --- a/src/store/features/modal/modalSlice.ts +++ b/src/store/features/modal/modalSlice.ts @@ -14,7 +14,7 @@ import { type DeleteFeatureProps, type deleteFeature, } from "@/myVoyage/features/featuresService"; -import { type AsyncActionResponse } from "@/modules/shared/types"; +import { type AsyncActionResponse } from "@/utils/handleAsync"; import { type DeleteAgendaTopicProps, type DeleteAgendaTopicResponse, diff --git a/src/types/types.ts b/src/types/types.ts index 077b0ae33..cf150593d 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -1 +1,4 @@ // only put global types here +export interface AppError { + message: string; +} diff --git a/src/utils/getCurrentVoyageData.ts b/src/utils/getCurrentVoyageData.ts index 02de6ee3c..c70a2a77a 100644 --- a/src/utils/getCurrentVoyageData.ts +++ b/src/utils/getCurrentVoyageData.ts @@ -1,5 +1,6 @@ import { getCurrentVoyageTeam } from "./getCurrentVoyageTeam"; -import type { AsyncActionResponse, AppError } from "@/modules/shared/types"; +import { type AppError } from "@/types/types"; +import { type AsyncActionResponse } from "@/utils/handleAsync"; import { type User } from "@/store/features/user/userSlice"; interface GetCurrentVoyageDataProps { diff --git a/src/utils/getCurrentVoyageTeam.ts b/src/utils/getCurrentVoyageTeam.ts index 466a6bd79..3f98c7ac8 100644 --- a/src/utils/getCurrentVoyageTeam.ts +++ b/src/utils/getCurrentVoyageTeam.ts @@ -1,4 +1,4 @@ -import { type AppError } from "@/modules/shared/types"; +import { type AppError } from "@/types/types"; import { type User, type VoyageTeamMember, diff --git a/src/utils/getUser.ts b/src/utils/getUser.ts index 8865369be..84e5c7b7f 100644 --- a/src/utils/getUser.ts +++ b/src/utils/getUser.ts @@ -1,7 +1,7 @@ import { getAccessToken } from "./getCookie"; import { handleAsync } from "./handleAsync"; import { GET } from "./requests"; -import { type AsyncActionResponse } from "@/modules/shared/types"; +import { type AsyncActionResponse } from "@/utils/handleAsync"; import { type User } from "@/store/features/user/userSlice"; export function getUser(): Promise> { diff --git a/src/utils/handleAsync.ts b/src/utils/handleAsync.ts index 3ca6f810c..3bf8ffbd6 100644 --- a/src/utils/handleAsync.ts +++ b/src/utils/handleAsync.ts @@ -1,7 +1,7 @@ -import { - type AsyncActionResponse, - type AsyncFunction, -} from "@/modules/shared/types"; +import { type AppError } from "@/types/types"; + +export type AsyncFunction = () => Promise; +export type AsyncActionResponse = [X | null, AppError | null]; export async function handleAsync( asyncFn: AsyncFunction, From 23f220af43e54ec67d4292732a709d8dc0bd12dd Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Tue, 1 Oct 2024 02:01:59 -0400 Subject: [PATCH 30/31] remove unnecessary interface --- .../ideation/application/dtos/addIdeationUsecaseDto.ts | 8 -------- src/modules/ideation/ports/primary/addIdeationPort.ts | 6 ------ src/modules/ideation/ports/primary/ideationClientPort.ts | 4 ++-- 3 files changed, 2 insertions(+), 16 deletions(-) delete mode 100644 src/modules/ideation/application/dtos/addIdeationUsecaseDto.ts delete mode 100644 src/modules/ideation/ports/primary/addIdeationPort.ts diff --git a/src/modules/ideation/application/dtos/addIdeationUsecaseDto.ts b/src/modules/ideation/application/dtos/addIdeationUsecaseDto.ts deleted file mode 100644 index d747f3874..000000000 --- a/src/modules/ideation/application/dtos/addIdeationUsecaseDto.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { - IdeationBodyDto, - IdeationRequestDto, -} from "@/modules/ideation/application/dtos/common.dto"; - -export interface AddIdeationUsecaseDto - extends Pick, - IdeationBodyDto {} diff --git a/src/modules/ideation/ports/primary/addIdeationPort.ts b/src/modules/ideation/ports/primary/addIdeationPort.ts deleted file mode 100644 index 70d4d73f4..000000000 --- a/src/modules/ideation/ports/primary/addIdeationPort.ts +++ /dev/null @@ -1,6 +0,0 @@ -import type { AddIdeationRequestDto } from "@/modules/ideation/application/dtos/request.dto"; -import type { AddIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; - -export interface AddIdeationPort { - execute(props: AddIdeationRequestDto): Promise; -} diff --git a/src/modules/ideation/ports/primary/ideationClientPort.ts b/src/modules/ideation/ports/primary/ideationClientPort.ts index 68260bbd4..9efd9db1a 100644 --- a/src/modules/ideation/ports/primary/ideationClientPort.ts +++ b/src/modules/ideation/ports/primary/ideationClientPort.ts @@ -1,5 +1,5 @@ -import { type AddIdeationUsecaseDto } from "@/modules/ideation/application/dtos/addIdeationUsecaseDto"; import { type AddIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; +import { type AddIdeationRequestDto } from "@/modules/ideation/application/dtos/request.dto"; export interface IdeationClientPort { addIdeation({ @@ -7,5 +7,5 @@ export interface IdeationClientPort { title, description, vision, - }: AddIdeationUsecaseDto): Promise; + }: AddIdeationRequestDto): Promise; } From eaa93a95527c9362183a9e553812df63ee046b1e Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Tue, 1 Oct 2024 02:04:48 -0400 Subject: [PATCH 31/31] fix build error --- .../(main)/my-voyage/[teamId]/ideation/adapters/ideationSA.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationSA.ts b/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationSA.ts index 9ff0741f4..36e357d6d 100644 --- a/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationSA.ts +++ b/src/app/(main)/my-voyage/[teamId]/ideation/adapters/ideationSA.ts @@ -8,7 +8,7 @@ import { handleAsync } from "@/utils/handleAsync"; import { type AsyncActionResponse } from "@/utils/handleAsync"; import { CacheTag } from "@/utils/cacheTag"; import { type AddIdeationResponseDto } from "@/modules/ideation/application/dtos/response.dto"; -import { type AddIdeationUsecaseDto } from "@/modules/ideation/application/dtos/addIdeationUsecaseDto"; +import { type AddIdeationRequestDto } from "@/modules/ideation/application/dtos/request.dto"; interface IdeationProps { teamId: number; @@ -64,7 +64,7 @@ export async function addIdeation({ title, description, vision, -}: AddIdeationUsecaseDto): Promise< +}: AddIdeationRequestDto): Promise< AsyncActionResponse > { const token = getAccessToken();