Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(api): move preset into handlers #492

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
},
"scripts": {
"test": "dotenv -e .env.test -- tap --ts --reporter=terse './test/**/*.test.ts' --before=test/before-test.ts",
"test:coverage": "dotenv -e .env.test -- tap --ts --reporter=terse --coverage-report=html './test/**/*.test.ts' --before=test/before-test.ts --save=tests.txt",
"test:ci": "dotenv -e .env.test -- tap --no-check-coverage --ts './test/**/*.test.ts' --before=test/before-test.ts",
"start": "npm run build:ts && fastify start -l info dist/app.js",
"typecheck": "tsc --noEmit --skipLibCheck --project tsconfig.json",
Expand Down Expand Up @@ -41,7 +42,7 @@
"@fastify/swagger": "^8.2.1",
"@fastify/type-provider-typebox": "^2.4.0",
"@prisma/client": "^4.8.0",
"@sinclair/typebox": "^0.25.16",
"@sinclair/typebox": "^0.25.24",
"close-with-grace": "^1.1.0",
"dotenv": "^16.0.3",
"dotenv-cli": "^6.0.0",
Expand Down
9 changes: 7 additions & 2 deletions apps/api/src/modules/preset/domain/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import {Preset} from '@codeimage/prisma-models';
export type PresetCreateRequest = Pick<Preset, 'name' | 'data' | 'ownerId'>;
export type PresetCreateResponse = Preset;

export type PresetCreateRequest = Pick<
Preset,
'name' | 'data' | 'ownerId' | 'version'
>;

export type PresetUpdateRequest = Pick<Preset, 'name' | 'data'>;
12 changes: 12 additions & 0 deletions apps/api/src/modules/preset/exceptions/NotFoundPresetException.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {NotFoundEntityException} from '../../../common/exceptions/NotFoundEntityException';

type Params = {
id: string;
ownerId: string;
};

export class NotFoundPresetException extends NotFoundEntityException<Params> {
createMessage({id, ownerId}: Params): string {
return `Preset with id ${id} for user ${ownerId} not found`;
}
}
30 changes: 30 additions & 0 deletions apps/api/src/modules/preset/handlers/create.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {HandlerBuilder} from '../../../common/domainFunctions/builder';
import {PresetCreateDto} from '../schema/preset-create-dto.schema';
import {PresetDto} from '../schema/preset-dto.schema';
import {PresetHandlerDependencies} from './';

export const create =
HandlerBuilder.withDependencies<PresetHandlerDependencies>()
.withName('createPreset')
.withImplementation(({repository, mapper}) => {
return async (
ownerId: string,
data: PresetCreateDto,
): Promise<PresetDto> => {
const createdPreset = await repository.create({
name: data.name,
data: data.data,
version: BigInt(1),
ownerId: ownerId,
});

return mapper.fromEntityToDto(createdPreset);
};
})
.build();

declare module '@api/domain' {
interface DomainHandlerMap {
createPreset: typeof create;
}
}
20 changes: 20 additions & 0 deletions apps/api/src/modules/preset/handlers/delete.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {HandlerBuilder} from '../../../common/domainFunctions/builder';
import {PresetHandlerDependencies} from './';

export const remove =
HandlerBuilder.withDependencies<PresetHandlerDependencies>()
.withName('deletePreset')
.withImplementation(({repository}, {handlers}) => {
return async (userId: string, id: string) => {
const preset = await handlers.findPresetById(userId, id);

return await repository.deletePreset(preset.id);
};
})
.build();

declare module '@api/domain' {
interface DomainHandlerMap {
deletePreset: typeof remove;
}
}
20 changes: 20 additions & 0 deletions apps/api/src/modules/preset/handlers/findAll.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {HandlerBuilder} from '../../../common/domainFunctions/builder';
import {PresetDto} from '../schema/preset-dto.schema';
import {PresetHandlerDependencies} from './';

export const findAll =
HandlerBuilder.withDependencies<PresetHandlerDependencies>()
.withName('findAllPresets')
.withImplementation(({repository, mapper}) => {
return async (ownerId: string): Promise<PresetDto[]> => {
const preset = await repository.findAllByOwnerId(ownerId);
return preset.map(mapper.fromEntityToDto);
};
})
.build();

declare module '@api/domain' {
interface DomainHandlerMap {
findAllPresets: typeof findAll;
}
}
24 changes: 24 additions & 0 deletions apps/api/src/modules/preset/handlers/findById.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {HandlerBuilder} from '../../../common/domainFunctions/builder';
import {NotFoundPresetException} from '../exceptions/NotFoundPresetException';
import {PresetDto} from '../schema/preset-dto.schema';
import {PresetHandlerDependencies} from './';

export const findById =
HandlerBuilder.withDependencies<PresetHandlerDependencies>()
.withName('findPresetById')
.withImplementation(({repository, mapper}) => {
return async (ownerId: string, id: string): Promise<PresetDto> => {
const preset = await repository.findByIdAndOwnerId(id, ownerId);
if (!preset) {
throw new NotFoundPresetException({id, ownerId});
}
return mapper.fromEntityToDto(preset);
};
})
.build();

declare module '@api/domain' {
interface DomainHandlerMap {
findPresetById: typeof findById;
}
}
7 changes: 7 additions & 0 deletions apps/api/src/modules/preset/handlers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import {PresetMapper} from '../mapper';
import {PresetRepository} from '../repository';

export type PresetHandlerDependencies = {
repository: PresetRepository;
mapper: PresetMapper;
};
68 changes: 0 additions & 68 deletions apps/api/src/modules/preset/handlers/preset.service.ts

This file was deleted.

22 changes: 22 additions & 0 deletions apps/api/src/modules/preset/handlers/update.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import {HandlerBuilder} from '../../../common/domainFunctions/builder';
import {PresetDto} from '../schema/preset-dto.schema';
import {PresetUpdateDto} from '../schema/preset-update-dto.schema';
import {PresetHandlerDependencies} from './';

export const update =
HandlerBuilder.withDependencies<PresetHandlerDependencies>()
.withName('updatePreset')
.withImplementation(({repository, mapper}, {handlers}) => {
return async (
userId: string,
id: string,
data: PresetUpdateDto,
): Promise<PresetDto> => {
await handlers.findPresetById(userId, id);

const updatedPreset = await repository.update(id, data);

return mapper.fromEntityToDto(updatedPreset);
};
})
.build();
29 changes: 22 additions & 7 deletions apps/api/src/modules/preset/index.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,38 @@
import {PresetRepository} from './repository/preset.repository';
import {ComposeHandlers} from '@api/domain';
import {FastifyPluginAsync} from 'fastify';
import {makePresetService, PresetService} from './handlers/preset.service';
import {makePrismaPresetRepository} from './infra/prisma/prisma-preset.repository';
import {registerHandlers} from '../../common/domainFunctions/handlers';
import {create} from './handlers/create';
import {remove} from './handlers/delete';
import {findAll} from './handlers/findAll';
import {findById} from './handlers/findById';
import {update} from './handlers/update';
import {PresetMapper} from './mapper';
import {PresetRepository} from './repository';
import {PrismaPresetRepository} from './repository/prisma-preset.repository';

const handlers = [create, remove, findById, update, findAll] as const;

const preset: FastifyPluginAsync = async fastify => {
const mapper = new PresetMapper();

export const preset: FastifyPluginAsync = async fastify => {
fastify.decorate(
'presetRepository',
makePrismaPresetRepository(fastify.prisma),
new PrismaPresetRepository(fastify.prisma),
);
fastify.decorate(
'presetService',
makePresetService(fastify.presetRepository, fastify.httpErrors),
registerHandlers(
handlers,
{repository: fastify.presetRepository, mapper},
fastify.handlerRegistry,
),
);
};

declare module 'fastify' {
interface FastifyInstance {
presetRepository: PresetRepository;
presetService: PresetService;
presetService: ComposeHandlers<typeof handlers>;
}
}
export default preset;

This file was deleted.

18 changes: 18 additions & 0 deletions apps/api/src/modules/preset/mapper/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {Preset} from '@codeimage/prisma-models';
import {PresetDto} from '../schema/preset-dto.schema';

export interface PresetMapper {
fromEntityToDto(entity: Preset): PresetDto;
}

export class PresetMapper implements PresetMapper {
fromEntityToDto(entity: Preset): PresetDto {
return {
id: entity.id,
name: entity.name,
version: Number(entity.version),
createdAt: entity.createdAt,
updatedAt: entity.updatedAt,
} as const;
}
}
17 changes: 11 additions & 6 deletions apps/api/src/modules/preset/repository/preset.repository.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import {PresetCreateRequest} from './../domain/index';
import {PresetCreateResponse} from '../domain';
import {Preset} from '@codeimage/prisma-models';
import {PresetCreateRequest, PresetUpdateRequest} from '../domain';

export interface PresetRepository {
findById(id: string): Promise<PresetCreateResponse | null>;
create(data: PresetCreateRequest): Promise<PresetCreateResponse>;
update(id: string, data: PresetCreateRequest): Promise<PresetCreateResponse>;
deletePreset(id: string): Promise<PresetCreateResponse>;
findByIdAndOwnerId(id: string, ownerId: string): Promise<Preset | null>;

findAllByOwnerId(ownerId: string): Promise<readonly Preset[]>;

create(data: PresetCreateRequest): Promise<Preset>;

update(id: string, data: PresetUpdateRequest): Promise<Preset>;

deletePreset(id: string): Promise<Preset>;
}
Loading