Skip to content

Commit

Permalink
Refactor structure (#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
gardusig authored Sep 24, 2024
1 parent 5c742cf commit f597be8
Show file tree
Hide file tree
Showing 24 changed files with 382 additions and 258 deletions.
8 changes: 7 additions & 1 deletion app/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"@nestjs/terminus": "^10.2.0",
"@prisma/client": "^5.8.1",
"axios": "1.7.4",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
"jest": "29.1.1",
"js-yaml": "^4.1.0",
Expand Down Expand Up @@ -73,4 +74,4 @@
"tsconfig-paths": "^4.2.0",
"typescript": "5.1.6"
}
}
}
48 changes: 48 additions & 0 deletions app/server/api/abstract/abstract.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import {
Logger,
HttpException,
HttpStatus,
NotFoundException,
ConflictException,
applyDecorators,
} from '@nestjs/common'
import { ApiHeader } from '@nestjs/swagger'
import { AbstractService } from './abstract.service'

const knownExceptions = new Set([NotFoundException, ConflictException])

export function ApiAuthHeaders() {
return applyDecorators(
ApiHeader({
name: 'username',
description: 'Username for authentication',
required: true,
}),
ApiHeader({
name: 'password',
description: 'Password for authentication',
required: true,
})
)
}

export abstract class AbstractController<T> {
protected readonly logger = new Logger(AbstractController.name)
protected readonly service: AbstractService<T>

constructor(service: AbstractService<T>) {
this.service = service
}

protected handleHttpException(error: any): Error {
this.logger.error(`Error processing request: ${error.message}`)
this.logger.verbose(error.stack)
if (!knownExceptions.has(error.constructor)) {
throw new HttpException(
`Internal Server Error: ${error.constructor.name} - ${error.message}`,
HttpStatus.INTERNAL_SERVER_ERROR
)
}
return error
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Logger } from '@nestjs/common'
import { NotFoundException, ConflictException } from '@nestjs/common'
import { Logger } from '@nestjs/common'

interface DatabaseMethods {
findUnique: (params: any) => Promise<any>;
Expand All @@ -9,18 +9,22 @@ interface DatabaseMethods {
delete: (params: any) => Promise<any>;
}

export abstract class GenericDatabase<T> {
protected readonly logger = new Logger(GenericDatabase.name)
export abstract class AbstractDatabase<T> {
protected readonly logger = new Logger(AbstractDatabase.name)

protected readonly dbClient: DatabaseMethods
protected readonly idKey: string

constructor(dbClient: DatabaseMethods, idKey: string) {
if (!dbClient) {
this.logger.error('Prisma database client is undefined in GenericDatabase constructor.')
throw new Error(
'Prisma database client is undefined in AbstractReadDatabase constructor.'
)
}
if (!idKey) {
this.logger.error('ID key is undefined in GenericDatabase constructor.')
throw new Error(
'ID key is undefined in AbstractReadDatabase constructor.'
)
}
this.dbClient = dbClient
this.idKey = idKey
Expand All @@ -33,7 +37,6 @@ export abstract class GenericDatabase<T> {
},
})
if (!existingRecord) {
this.logger.warn(`Record with ID ${id} not found. Update operation skipped.`)
throw new NotFoundException(`Record with ID ${id} not found.`)
}
return existingRecord
Expand All @@ -44,7 +47,6 @@ export abstract class GenericDatabase<T> {
}

async create(data: T, id: string): Promise<T> {
this.logger.debug(`Creating record with ID ${id}...`)
const existingRecord = await this.dbClient.findUnique({
where: {
[this.idKey]: id,
Expand Down
29 changes: 29 additions & 0 deletions app/server/api/abstract/abstract.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { DynamicModule, InjectionToken, Type } from '@nestjs/common'

interface GenericModuleOptions {
controller: Type<any>;
service: Type<any>;
serviceToken: InjectionToken;
dbImplementation: Type<any>;
dbToken: InjectionToken;
}

export class AbstractModule {
static configure(options: GenericModuleOptions): DynamicModule {
return {
module: AbstractModule,
controllers: [options.controller],
providers: [
{
provide: options.serviceToken,
useClass: options.service,
},
{
provide: options.dbToken,
useClass: options.dbImplementation,
},
],
exports: [options.serviceToken, options.dbToken],
}
}
}
17 changes: 17 additions & 0 deletions app/server/api/abstract/abstract.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Logger } from '@nestjs/common'
import { AbstractDatabase } from './abstract.database'

export abstract class AbstractService<T> {
protected readonly logger = new Logger(AbstractService.name)
protected readonly database: AbstractDatabase<T>

constructor(database: AbstractDatabase<T>) {
this.database = database
}

abstract findById(id: string): Promise<T>;
abstract findAll(): Promise<T[]>;
abstract create(entity: T): Promise<T>;
abstract update(id: string, entity: T): Promise<T>;
abstract delete(id: string): Promise<T>;
}
85 changes: 0 additions & 85 deletions app/server/api/abstract/controller.ts

This file was deleted.

46 changes: 0 additions & 46 deletions app/server/api/abstract/module.ts

This file was deleted.

30 changes: 0 additions & 30 deletions app/server/api/abstract/service.ts

This file was deleted.

11 changes: 0 additions & 11 deletions app/server/api/random_object/controller.ts

This file was deleted.

13 changes: 0 additions & 13 deletions app/server/api/random_object/database.ts

This file was deleted.

Loading

0 comments on commit f597be8

Please sign in to comment.