Created
September 15, 2024 13:07
-
-
Save GoodnessEzeokafor/7b45ec3b312ebae3c7a8a1d89e1beb49 to your computer and use it in GitHub Desktop.
clean-code architecture
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** generic repository */ | |
/* eslint-disable @typescript-eslint/no-unused-vars */ | |
import { Model } from 'sequelize'; | |
import { IGenericRepository } from 'src/core'; | |
export class SequelizeGenericRepository<T extends Model> | |
implements IGenericRepository<T> | |
{ | |
private model: any; | |
constructor(model: any) { | |
this.model = model; | |
} | |
async findAllWithPagination( | |
query: any, | |
options?: { | |
useDefault?: boolean; | |
selectFields?: string[] | string; | |
relationFields?: string[] | string; | |
}, | |
): Promise<{ data: T[]; pagination: any }> { | |
const { perPage = 10, page = 1, order = [['createdAt', 'DESC']] } = query; | |
const where: any = {}; | |
Object.keys(query).forEach((key) => { | |
if (['limit', 'offset', 'order', 'perPage', 'page'].includes(key)) return; | |
where[key] = query[key]; | |
}); | |
const offset = (page - 1) * perPage; | |
const count = await this.model.count({ where }); | |
const data = await this.model.findAll({ | |
where, | |
order, | |
limit: perPage, | |
offset, | |
// ...(options?.selectFields ? { attributes: options.selectFields } : {}), | |
// ...(options?.relationFields | |
// ? { | |
// include: options.relationFields.map((field) => ({ | |
// required: false, | |
// })), | |
// } | |
// : {}), | |
}); | |
return { | |
data: data as T[], | |
pagination: { | |
hasPrevious: page > 1, | |
prevPage: page - 1, | |
hasNext: page < Math.ceil(count / perPage), | |
next: page + 1, | |
currentPage: Number(page), | |
pageSize: perPage, | |
lastPage: Math.ceil(count / perPage), | |
total: count, | |
}, | |
}; | |
} | |
async findOne(key: Partial<T> | Partial<T>[]): Promise<T | null> { | |
const where: any = {}; | |
Object.keys(key).forEach((k) => (where[k] = key[k])); | |
return await this.model.findOne({ | |
where, | |
}); | |
} | |
async create( | |
payload: Partial<T>, | |
options?: { transaction?: any }, | |
): Promise<T> { | |
if (options?.transaction) { | |
return await this.model.create(payload, { | |
transaction: options?.transaction, | |
}); | |
} | |
return await this.model.create(payload); | |
} | |
async length(filter: Partial<T>): Promise<number> { | |
return await this.model.count({ where: filter }); | |
} | |
async update( | |
key: Partial<T>, | |
payload: Partial<T>, | |
options?: { transaction: any }, | |
) { | |
const where: any = {}; | |
Object.keys(key).forEach((k) => (where[k] = key[k])); | |
return await this.model.update(payload, { | |
where, | |
...(options?.transaction ? { transaction: options.transaction } : {}), | |
}); | |
} | |
async delete(key: Partial<T>, options?: { transaction: any }) { | |
const where: any = {}; | |
Object.keys(key).forEach((k) => (where[k] = key[k])); | |
return await this.model.destroy({ | |
where, | |
...(options?.transaction ? { transaction: options.transaction } : {}), | |
}); | |
} | |
async bulkCreate(payload: Partial<T[]>, _options?: { transaction: any }) { | |
return await this.model.bulkCreate(payload); | |
} | |
} | |
/** abstract repository */ | |
import { CategoryEntity, FeedbackEntity } from '../entities'; | |
export abstract class IGenericRepository<T> { | |
abstract findAllWithPagination( | |
query?: any, | |
options?: { | |
useDefault?: boolean; | |
selectFields?: string[] | string; | |
relationFields?: string[] | string; | |
}, | |
): Promise<{ | |
data: any; | |
pagination: { | |
hasPrevious: boolean; | |
prevPage: number; | |
hasNext: boolean; | |
next: number; | |
currentPage: number; | |
pageSize: number; | |
lastPage: number; | |
total: any; | |
}; | |
}>; | |
abstract findOne( | |
key: Partial<T> | Partial<T>[], | |
options?: { | |
useDefault?: boolean; | |
selectFields?: string[] | string; | |
relationFields?: string[] | string; | |
relationIds?: boolean; | |
}, | |
): Promise<T>; | |
abstract create( | |
payload: Partial<T>, | |
options?: { transaction?: any }, | |
): Promise<T>; | |
abstract length(filter: Partial<T>): Promise<any>; | |
abstract delete(key: Partial<T>, options?: { transaction: any }); | |
abstract update( | |
key: Partial<T>, | |
payload: Partial<T>, | |
options?: { transaction?: any }, | |
): Promise<any>; | |
} | |
export abstract class IDatabaseServices { | |
abstract feedbacks?: IGenericRepository<FeedbackEntity>; | |
abstract categories?: IGenericRepository<CategoryEntity>; | |
} | |
/** abstract repository */ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment