-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: add DI container and refactor student repository
- Loading branch information
1 parent
35a69b4
commit ec10c14
Showing
28 changed files
with
233 additions
and
110 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
import 'reflect-metadata'; | ||
|
||
export * from './prisma'; | ||
export * from './util'; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,3 @@ | ||
export * from './subject'; | ||
export * from './student'; | ||
export * from './shared'; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './interfaces'; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { Score } from '@prisma/client'; | ||
import { LearningResult } from '../subject'; | ||
import { GetById } from '@infra/student'; | ||
|
||
export interface ICalculateScoreService { | ||
getLearningResult(scores: Score[]): LearningResult; | ||
getAverageScore(student: GetById): number; | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './interfaces'; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export interface ExpandFields {} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './interfaces'; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { StudentQueryResult } from '@infra/index'; | ||
import { ExpandFields } from '../shared'; | ||
|
||
export interface StudentExpandFields extends ExpandFields { | ||
withScores?: boolean; | ||
} | ||
|
||
export interface IStudentRepository { | ||
getById( | ||
id: string, | ||
expandFields?: StudentExpandFields, | ||
): Promise<StudentQueryResult>; | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import Container from 'typedi'; | ||
import { Cradle } from './cradle'; | ||
import { CalculateScoreService } from '@infra/score'; | ||
import { StudentRepository } from '@infra/student'; | ||
|
||
export const container: Cradle = { | ||
// Services | ||
calculateScoreService: Container.get(CalculateScoreService), | ||
|
||
// Repositories | ||
studentRepository: Container.get(StudentRepository), | ||
}; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { CalculateScoreService } from '@infra/score'; | ||
import { StudentRepository } from '@infra/student'; | ||
|
||
export interface Cradle { | ||
// Services | ||
calculateScoreService: CalculateScoreService; | ||
// Repositories | ||
studentRepository: StudentRepository; | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './container'; | ||
export * from './cradle'; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,7 @@ | ||
import 'reflect-metadata'; | ||
|
||
export * from './application'; | ||
export * from './domain'; | ||
export * from './infra'; | ||
export * from './shared'; | ||
export * from './container'; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,54 +1,56 @@ | ||
import { LearningResult } from '@application/ports'; | ||
import { isPassedSubject, shouldCalculateScore } from '@application/util'; | ||
import { AlphabetToTetraScore } from '@domain/index'; | ||
import { StudentWithScoresAndSubjects } from '@infra/index'; | ||
import { StudentQueryResult } from '@infra/index'; | ||
import { Score } from '@prisma/client'; | ||
import { Service } from 'typedi'; | ||
|
||
@Service() | ||
export class CalculateScoreService { | ||
getLearningResult(scores: Score[]): LearningResult { | ||
const passed = scores.filter((score) => isPassedSubject(score)).length; | ||
const failed = scores.length - passed; | ||
|
||
return { | ||
passed, | ||
failed, | ||
}; | ||
} | ||
|
||
getAverageScore(student?: StudentQueryResult): number { | ||
if (!student) throw new Error('Student not found'); | ||
|
||
const { scores } = student; | ||
|
||
const totalAverageScore = scores.reduce((acc, score) => { | ||
if (shouldCalculateScore(score)) { | ||
if ( | ||
!score.alphabetScore || | ||
!(score.alphabetScore in AlphabetToTetraScore) | ||
) { | ||
return acc; | ||
} | ||
|
||
return ( | ||
acc + | ||
// * This is an enum so it's safe to ignore this | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
AlphabetToTetraScore[score.alphabetScore] * | ||
score.subject.numberOfCredits | ||
); | ||
} | ||
return acc; | ||
}, 0); | ||
|
||
export const getLearningResult = (scores: Score[]): LearningResult => { | ||
const passed = scores.filter((score) => isPassedSubject(score)).length; | ||
const failed = scores.length - passed; | ||
|
||
return { | ||
passed, | ||
failed, | ||
}; | ||
}; | ||
|
||
export const getAverageScore = ( | ||
student?: StudentWithScoresAndSubjects, | ||
): number => { | ||
if (!student) throw new Error('Student not found'); | ||
|
||
const { scores } = student; | ||
|
||
const totalAverageScore = scores.reduce((acc, score) => { | ||
if (shouldCalculateScore(score)) { | ||
if ( | ||
!score.alphabetScore || | ||
!(score.alphabetScore in AlphabetToTetraScore) | ||
) { | ||
return acc; | ||
const totalCredits = scores.reduce((acc, score) => { | ||
if (shouldCalculateScore(score)) { | ||
return acc + score.subject.numberOfCredits; | ||
} | ||
return acc; | ||
}, 0); | ||
|
||
return ( | ||
acc + | ||
// * This is an enum so it's safe to ignore this | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
AlphabetToTetraScore[score.alphabetScore] * | ||
score.subject.numberOfCredits | ||
); | ||
} | ||
return acc; | ||
}, 0); | ||
|
||
const totalCredits = scores.reduce((acc, score) => { | ||
if (shouldCalculateScore(score)) { | ||
return acc + score.subject.numberOfCredits; | ||
} | ||
return acc; | ||
}, 0); | ||
|
||
const averageScore = totalAverageScore / totalCredits; | ||
return Number(averageScore.toFixed(2)); | ||
}; | ||
const averageScore = totalAverageScore / totalCredits; | ||
return Number(averageScore.toFixed(2)); | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { Prisma } from '@prisma/client'; | ||
|
||
export const studentIncludeScoreAndSubject = | ||
Prisma.validator<Prisma.StudentDefaultArgs>()({ | ||
include: { | ||
scores: { | ||
include: { | ||
subject: true, | ||
}, | ||
}, | ||
}, | ||
}); |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
export * from './studentPersistence'; | ||
export * from './studentRepository'; | ||
export * from './types'; |
This file was deleted.
Oops, something went wrong.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { prisma } from '@application/index'; | ||
import { IStudentRepository, StudentExpandFields } from '@application/ports'; | ||
import { Prisma } from '@prisma/client'; | ||
import { Repository } from 'shared'; | ||
import { StudentQueryResult } from './types'; | ||
|
||
@Repository() | ||
export class StudentRepository implements IStudentRepository { | ||
async getById(id: string, expandFields: StudentExpandFields) { | ||
// TODO: Implement a better solution for dynamic include | ||
const include: Prisma.StudentInclude = { | ||
scores: expandFields.withScores | ||
? { | ||
include: { | ||
subject: true, | ||
}, | ||
where: { | ||
studentId: id, | ||
}, | ||
} | ||
: {}, | ||
}; | ||
|
||
const student = await prisma.student.findUnique({ | ||
include, | ||
where: { | ||
id: id, | ||
}, | ||
}); | ||
|
||
return student as unknown as StudentQueryResult; | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,12 @@ | ||
import { Prisma } from '@prisma/client'; | ||
import { getStudentWithScoreById } from '@infra/student'; | ||
import { studentIncludeScoreAndSubject } from './include'; | ||
|
||
export type StudentWithScoresAndSubjects = Prisma.PromiseReturnType< | ||
typeof getStudentWithScoreById | ||
/** | ||
* * This is a type that is used to dynamically include the fields of the student | ||
* * This will resolve type error when we use the `include` option of Prisma dynamically | ||
* TODO: Remove this when Prisma support dynamic include types or when we have better solution | ||
* https://github.com/prisma/prisma/issues/20816#issuecomment-1873546485 | ||
*/ | ||
export type StudentQueryResult = Prisma.StudentGetPayload< | ||
typeof studentIncludeScoreAndSubject | ||
>; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './repository'; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { ClassConstructor } from 'shared/types'; | ||
import { Service } from 'typedi'; | ||
|
||
export function Repository<T>() { | ||
return function (target: ClassConstructor<T>) { | ||
// Apply the TypeDI Service decorator | ||
Service()(target); | ||
}; | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './decorators'; | ||
export * from './types'; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
export type ClassConstructor<T> = new (...args: any[]) => T; |
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
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
Oops, something went wrong.