From 45767bad01235769b30f7ced2e441b22584322c6 Mon Sep 17 00:00:00 2001 From: ddungiii Date: Wed, 22 Nov 2023 01:14:20 +0900 Subject: [PATCH 1/9] feat: init rate module --- package.json | 2 +- src/app.module.ts | 2 ++ .../interfaces/serializer/rate.serializer.ts | 12 +++++++ src/common/interfaces/structures/IRate.ts | 22 +++++++++++++ src/common/interfaces/structures/index.ts | 1 + src/modules/rates/rates.controller.ts | 19 ++++++++++-- src/modules/rates/rates.module.ts | 4 ++- src/modules/rates/rates.service.ts | 31 +++++++++++++++++-- src/prisma/repositories/rates.repository.ts | 28 +++++++++++++++++ src/settings.ts | 5 +++ 10 files changed, 120 insertions(+), 6 deletions(-) create mode 100644 src/common/interfaces/serializer/rate.serializer.ts create mode 100644 src/common/interfaces/structures/IRate.ts create mode 100644 src/prisma/repositories/rates.repository.ts diff --git a/package.json b/package.json index 8a3be446..f1180375 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "otl-nest", - "version": "0.0.1", + "version": "3.3.1.0", "description": "", "author": "", "private": true, diff --git a/src/app.module.ts b/src/app.module.ts index 661cf026..c3e14d8c 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -8,6 +8,7 @@ import { JwtCookieGuard } from './modules/auth/guard/jwt-cookie.guard'; import { MockAuthGuard } from './modules/auth/guard/mock-auth-guard'; import { CoursesModule } from './modules/courses/courses.module'; import { LecturesModule } from './modules/lectures/lectures.module'; +import { RatesModule } from './modules/rates/rates.module'; import { ReviewsModule } from './modules/reviews/reviews.module'; import { SemestersModule } from './modules/semesters/semesters.module'; import { TimetablesModule } from './modules/timetables/timetables.module'; @@ -24,6 +25,7 @@ import { PrismaModule } from './prisma/prisma.module'; UserModule, SemestersModule, TimetablesModule, + RatesModule, ], controllers: [AppController], providers: [ diff --git a/src/common/interfaces/serializer/rate.serializer.ts b/src/common/interfaces/serializer/rate.serializer.ts new file mode 100644 index 00000000..c23cd3f0 --- /dev/null +++ b/src/common/interfaces/serializer/rate.serializer.ts @@ -0,0 +1,12 @@ +import { support_rate } from '@prisma/client'; +import { IRate } from '../structures'; + +export function toJsonRate(rate: support_rate): IRate { + return { + id: rate.id, + score: rate.score, + user_id: rate.user_id, + version: rate.version, + created_datetime: rate.created_datetime, + }; +} diff --git a/src/common/interfaces/structures/IRate.ts b/src/common/interfaces/structures/IRate.ts new file mode 100644 index 00000000..ef0e00be --- /dev/null +++ b/src/common/interfaces/structures/IRate.ts @@ -0,0 +1,22 @@ +import { Type } from 'class-transformer'; +import { IsNumber, Max, Min } from 'class-validator'; + +export interface IRate extends IRate.ICommon {} + +export namespace IRate { + export interface ICommon { + id: number; + user_id: number; + score: number; + version: string; + created_datetime: Date | null; + } + + export class CreateDto { + @IsNumber() + @Max(5) + @Min(1) + @Type(() => Number) + score!: number; + } +} diff --git a/src/common/interfaces/structures/index.ts b/src/common/interfaces/structures/index.ts index c1a5d427..12f93fb2 100644 --- a/src/common/interfaces/structures/index.ts +++ b/src/common/interfaces/structures/index.ts @@ -1 +1,2 @@ export * from './IAuth'; +export * from './IRate'; diff --git a/src/modules/rates/rates.controller.ts b/src/modules/rates/rates.controller.ts index 01d34b0c..f7a819a9 100644 --- a/src/modules/rates/rates.controller.ts +++ b/src/modules/rates/rates.controller.ts @@ -1,4 +1,19 @@ -import { Controller } from '@nestjs/common'; +import { Body, Controller, Post } from '@nestjs/common'; +import { session_userprofile } from '@prisma/client'; +import { GetUser } from 'src/common/decorators/get-user.decorator'; +import { toJsonRate } from 'src/common/interfaces/serializer/rate.serializer'; +import { IRate } from 'src/common/interfaces/structures'; +import { RatesService } from './rates.service'; @Controller('rates') -export class RatesController {} +export class RatesController { + constructor(private readonly ratesService: RatesService) {} + @Post() + async createRates( + @Body() body: IRate.CreateDto, + @GetUser() user: session_userprofile, + ): Promise { + const rate = await this.ratesService.createRate(body, user); + return toJsonRate(rate); + } +} diff --git a/src/modules/rates/rates.module.ts b/src/modules/rates/rates.module.ts index 3d266852..1b64c7eb 100644 --- a/src/modules/rates/rates.module.ts +++ b/src/modules/rates/rates.module.ts @@ -1,9 +1,11 @@ import { Module } from '@nestjs/common'; +import { PrismaService } from 'src/prisma/prisma.service'; +import { RateRepository } from 'src/prisma/repositories/rates.repository'; import { RatesController } from './rates.controller'; import { RatesService } from './rates.service'; @Module({ controllers: [RatesController], - providers: [RatesService], + providers: [RatesService, RateRepository, PrismaService], }) export class RatesModule {} diff --git a/src/modules/rates/rates.service.ts b/src/modules/rates/rates.service.ts index c908c19d..8b4dc475 100644 --- a/src/modules/rates/rates.service.ts +++ b/src/modules/rates/rates.service.ts @@ -1,4 +1,31 @@ -import { Injectable } from '@nestjs/common'; +import { BadRequestException, Injectable } from '@nestjs/common'; +import { session_userprofile, support_rate } from '@prisma/client'; +import { IRate } from 'src/common/interfaces/structures'; +import { RateRepository } from 'src/prisma/repositories/rates.repository'; +import settings from 'src/settings'; @Injectable() -export class RatesService {} +export class RatesService { + constructor(private readonly rateRepository: RateRepository) {} + async createRate( + body: IRate.CreateDto, + user: session_userprofile, + ): Promise { + const { score } = body; + const year = new Date().getFullYear(); + const version = settings().getVersion(); + + const rate = await this.rateRepository.getRate(user.id, year, version); + if (rate) { + throw new BadRequestException('You already rated for current year'); + } + + const newRate = await this.rateRepository.createRate( + user.id, + score, + year, + version, + ); + return newRate; + } +} diff --git a/src/prisma/repositories/rates.repository.ts b/src/prisma/repositories/rates.repository.ts new file mode 100644 index 00000000..ad3d8972 --- /dev/null +++ b/src/prisma/repositories/rates.repository.ts @@ -0,0 +1,28 @@ +import { Injectable } from '@nestjs/common'; +import { PrismaService } from '../prisma.service'; + +@Injectable() +export class RateRepository { + constructor(private readonly prisma: PrismaService) {} + + async getRate(userId: number, year: number, version: string) { + return this.prisma.support_rate.findFirst({ + where: { + user_id: userId, + year, + version, + }, + }); + } + + async createRate( + userId: number, + score: number, + year: number, + version: string, + ) { + return this.prisma.support_rate.create({ + data: { user_id: userId, year, score, version }, + }); + } +} diff --git a/src/settings.ts b/src/settings.ts index 67977005..6da382e5 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -14,6 +14,7 @@ export default () => { getJwtConfig: () => getJwtConfig(), getSsoConfig: () => getSsoConfig(), getCorsConfig: () => getCorsConfig(), + getVersion: () => getVersion(), }; }; @@ -72,3 +73,7 @@ const getSsoConfig = (): any => { ssoSecretKey: process.env.SSO_SECRET_KEY, }; }; + +const getVersion = () => { + return String(process.env.npm_package_version); +}; From db90a60c22e149e47e37037a03519e78df7e014a Mon Sep 17 00:00:00 2001 From: ddungiii Date: Wed, 22 Nov 2023 01:38:19 +0900 Subject: [PATCH 2/9] chore: lock new package version --- package-lock.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index d04bc4e4..7f1a8519 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "otl-nest", - "version": "0.0.1", + "version": "3.3.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "otl-nest", - "version": "0.0.1", + "version": "3.3.1.0", "license": "UNLICENSED", "dependencies": { "@nestjs/common": "^9.0.0", From e819075a912d916142b1b599e1d1b11691b1feb1 Mon Sep 17 00:00:00 2001 From: ddungiii Date: Wed, 21 Feb 2024 20:41:19 +0900 Subject: [PATCH 3/9] fix: add endpoint prefix --- src/modules/rates/rates.controller.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/rates/rates.controller.ts b/src/modules/rates/rates.controller.ts index 880477b6..665e8f56 100644 --- a/src/modules/rates/rates.controller.ts +++ b/src/modules/rates/rates.controller.ts @@ -5,7 +5,7 @@ import { IRate } from 'src/common/interfaces/IRate'; import { toJsonRate } from 'src/common/interfaces/serializer/rate.serializer'; import { RatesService } from './rates.service'; -@Controller('rates') +@Controller('api/rates') export class RatesController { constructor(private readonly ratesService: RatesService) {} @Post() From 5abc441c27a5e01c47ce6187464ab9b8ed5bb42a Mon Sep 17 00:00:00 2001 From: ddungiii Date: Wed, 21 Feb 2024 20:41:33 +0900 Subject: [PATCH 4/9] fix: rate module --- src/modules/rates/rates.module.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/modules/rates/rates.module.ts b/src/modules/rates/rates.module.ts index 1b64c7eb..3cbe1d92 100644 --- a/src/modules/rates/rates.module.ts +++ b/src/modules/rates/rates.module.ts @@ -1,11 +1,12 @@ import { Module } from '@nestjs/common'; -import { PrismaService } from 'src/prisma/prisma.service'; +import { PrismaModule } from 'src/prisma/prisma.module'; import { RateRepository } from 'src/prisma/repositories/rates.repository'; import { RatesController } from './rates.controller'; import { RatesService } from './rates.service'; @Module({ + imports: [PrismaModule], controllers: [RatesController], - providers: [RatesService, RateRepository, PrismaService], + providers: [RatesService, RateRepository], }) export class RatesModule {} From 4aef640c2406ad0d2967440e114af7f874a0fd35 Mon Sep 17 00:00:00 2001 From: ddungiii Date: Wed, 21 Feb 2024 20:41:46 +0900 Subject: [PATCH 5/9] fix: add created_datetime --- src/prisma/repositories/rates.repository.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/prisma/repositories/rates.repository.ts b/src/prisma/repositories/rates.repository.ts index ad3d8972..14e86d8a 100644 --- a/src/prisma/repositories/rates.repository.ts +++ b/src/prisma/repositories/rates.repository.ts @@ -22,7 +22,13 @@ export class RateRepository { version: string, ) { return this.prisma.support_rate.create({ - data: { user_id: userId, year, score, version }, + data: { + user_id: userId, + year, + score, + version, + created_datetime: new Date(), + }, }); } } From b6a8caab7501cf7597fe02ddfb4044db5f1dd7f4 Mon Sep 17 00:00:00 2001 From: ddungiii Date: Wed, 21 Feb 2024 20:43:30 +0900 Subject: [PATCH 6/9] refactor: ICommon -> IBasic --- src/common/interfaces/IRate.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/interfaces/IRate.ts b/src/common/interfaces/IRate.ts index ef0e00be..19a476b1 100644 --- a/src/common/interfaces/IRate.ts +++ b/src/common/interfaces/IRate.ts @@ -1,10 +1,10 @@ import { Type } from 'class-transformer'; import { IsNumber, Max, Min } from 'class-validator'; -export interface IRate extends IRate.ICommon {} +export interface IRate extends IRate.IBasic {} export namespace IRate { - export interface ICommon { + export interface IBasic { id: number; user_id: number; score: number; From b3f4ac5c54e7eaa63b03cda8cff7de7ff23cc695 Mon Sep 17 00:00:00 2001 From: ddungiii Date: Wed, 28 Feb 2024 20:29:38 +0900 Subject: [PATCH 7/9] refactor: remove prefix I in Basic --- src/common/interfaces/IRate.ts | 4 +--- src/common/interfaces/serializer/rate.serializer.ts | 2 +- src/modules/rates/rates.controller.ts | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/common/interfaces/IRate.ts b/src/common/interfaces/IRate.ts index 19a476b1..0994e93e 100644 --- a/src/common/interfaces/IRate.ts +++ b/src/common/interfaces/IRate.ts @@ -1,10 +1,8 @@ import { Type } from 'class-transformer'; import { IsNumber, Max, Min } from 'class-validator'; -export interface IRate extends IRate.IBasic {} - export namespace IRate { - export interface IBasic { + export interface Basic { id: number; user_id: number; score: number; diff --git a/src/common/interfaces/serializer/rate.serializer.ts b/src/common/interfaces/serializer/rate.serializer.ts index 7ddf3177..9c0abef8 100644 --- a/src/common/interfaces/serializer/rate.serializer.ts +++ b/src/common/interfaces/serializer/rate.serializer.ts @@ -1,7 +1,7 @@ import { support_rate } from '@prisma/client'; import { IRate } from '../IRate'; -export function toJsonRate(rate: support_rate): IRate { +export function toJsonRate(rate: support_rate): IRate.Basic { return { id: rate.id, score: rate.score, diff --git a/src/modules/rates/rates.controller.ts b/src/modules/rates/rates.controller.ts index 665e8f56..addaa2bb 100644 --- a/src/modules/rates/rates.controller.ts +++ b/src/modules/rates/rates.controller.ts @@ -12,7 +12,7 @@ export class RatesController { async createRates( @Body() body: IRate.CreateDto, @GetUser() user: session_userprofile, - ): Promise { + ): Promise { const rate = await this.ratesService.createRate(body, user); return toJsonRate(rate); } From be537db4d3303e200816858529b3724340d201ab Mon Sep 17 00:00:00 2001 From: ddungiii Date: Sun, 3 Mar 2024 18:42:20 +0900 Subject: [PATCH 8/9] fix: package verion supporting sementic versioning --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index ff0c4e29..54763d68 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "otl-nest", - "version": "3.3.1.0", + "version": "3.3.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "otl-nest", - "version": "3.3.1.0", + "version": "3.3.1", "license": "UNLICENSED", "dependencies": { "@nestjs/common": "^9.0.0", diff --git a/package.json b/package.json index 4000d63f..8443a4a5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "otl-nest", - "version": "3.3.1.0", + "version": "3.3.1", "description": "", "author": "", "private": true, From 9fa55cd006ca28e044f3cda3bbbb3c4cde481dae Mon Sep 17 00:00:00 2001 From: ddungiii Date: Wed, 6 Mar 2024 22:21:51 +0900 Subject: [PATCH 9/9] feat: add default date for rate --- .../20240306130709_add_default_date_for_rate/migration.sql | 7 +++++++ src/prisma/repositories/rates.repository.ts | 1 - src/prisma/schema.prisma | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 src/prisma/migrations/20240306130709_add_default_date_for_rate/migration.sql diff --git a/src/prisma/migrations/20240306130709_add_default_date_for_rate/migration.sql b/src/prisma/migrations/20240306130709_add_default_date_for_rate/migration.sql new file mode 100644 index 00000000..9394eac8 --- /dev/null +++ b/src/prisma/migrations/20240306130709_add_default_date_for_rate/migration.sql @@ -0,0 +1,7 @@ +/* +Warnings: +- Made the column `created_datetime` on table `support_rate` required. This step will fail if there are existing NULL values in that column. +*/ +-- AlterTable +ALTER TABLE `support_rate` +MODIFY `created_datetime` DATETIME(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0); \ No newline at end of file diff --git a/src/prisma/repositories/rates.repository.ts b/src/prisma/repositories/rates.repository.ts index 14e86d8a..b03a3221 100644 --- a/src/prisma/repositories/rates.repository.ts +++ b/src/prisma/repositories/rates.repository.ts @@ -27,7 +27,6 @@ export class RateRepository { year, score, version, - created_datetime: new Date(), }, }); } diff --git a/src/prisma/schema.prisma b/src/prisma/schema.prisma index 3b5a261e..7783e81a 100644 --- a/src/prisma/schema.prisma +++ b/src/prisma/schema.prisma @@ -581,7 +581,7 @@ model support_rate { id Int @id @default(autoincrement()) score Int @db.SmallInt year Int @db.SmallInt - created_datetime DateTime? @db.DateTime(0) + created_datetime DateTime @default(now()) @db.DateTime(0) user_id Int version String @db.VarChar(20) session_userprofile session_userprofile @relation(fields: [user_id], references: [id], onUpdate: Restrict, map: "support_rate_user_id_6d69ec9d_fk_session_userprofile_id")