From 4a3e407156739c59a9799fa89dcebaa4ffaffbe0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Mendon=C3=A7a=20e=20Silva?= Date: Sun, 19 May 2024 15:58:00 -0300 Subject: [PATCH] feat: new route and service to see shelter supply changelog --- .../migrations/20240519130138_/migration.sql | 17 +++++++ prisma/schema.prisma | 16 +++++++ src/app.module.ts | 14 +++--- .../shelter-supply-log.controller.ts | 45 +++++++++++++++++++ .../shelter-supply-log.module.ts | 12 +++++ .../shelter-supply-log.service.ts | 39 ++++++++++++++++ .../shelter-supply.controller.spec.ts | 29 ++++++++++++ .../shelter-supply.service.spec.ts | 25 +++++++++++ src/shelter-supply/shelter-supply.module.ts | 4 +- src/shelter-supply/shelter-supply.service.ts | 13 +++++- 10 files changed, 204 insertions(+), 10 deletions(-) create mode 100644 prisma/migrations/20240519130138_/migration.sql create mode 100644 src/shelter-supply-logs/shelter-supply-log.controller.ts create mode 100644 src/shelter-supply-logs/shelter-supply-log.module.ts create mode 100644 src/shelter-supply-logs/shelter-supply-log.service.ts create mode 100644 src/shelter-supply-logs/shelter-supply.controller.spec.ts create mode 100644 src/shelter-supply-logs/shelter-supply.service.spec.ts diff --git a/prisma/migrations/20240519130138_/migration.sql b/prisma/migrations/20240519130138_/migration.sql new file mode 100644 index 00000000..615a5fd2 --- /dev/null +++ b/prisma/migrations/20240519130138_/migration.sql @@ -0,0 +1,17 @@ +-- CreateTable +CREATE TABLE "shelter_supply_logs" ( + "id" TEXT NOT NULL, + "shelter_suply_shelter_id" TEXT NOT NULL, + "shelter_suply_supply_id" TEXT NOT NULL, + "priority" INTEGER, + "quantity" INTEGER, + "created_at" VARCHAR(32) NOT NULL, + + CONSTRAINT "shelter_supply_logs_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE INDEX "shelter_supply_logs_shelter_suply_shelter_id_shelter_suply__idx" ON "shelter_supply_logs"("shelter_suply_shelter_id", "shelter_suply_supply_id"); + +-- AddForeignKey +ALTER TABLE "shelter_supply_logs" ADD CONSTRAINT "shelter_supply_logs_shelter_suply_shelter_id_shelter_suply_fkey" FOREIGN KEY ("shelter_suply_shelter_id", "shelter_suply_supply_id") REFERENCES "shelter_supplies"("shelter_id", "supply_id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 04d0ee48..63709e06 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -72,10 +72,26 @@ model ShelterSupply { shelter Shelter @relation(fields: [shelterId], references: [id]) supply Supply @relation(fields: [supplyId], references: [id]) + ShelterSupplyLog ShelterSupplyLog[] + @@id([shelterId, supplyId]) @@map("shelter_supplies") } +model ShelterSupplyLog { + id String @id @default(uuid()) + shelterSupplyShelterId String @map("shelter_suply_shelter_id") + shelterSupplySupplyId String @map("shelter_suply_supply_id") + priority Int? + quantity Int? + createdAt String @map("created_at") @db.VarChar(32) + + shelterSupply ShelterSupply @relation(fields: [shelterSupplyShelterId, shelterSupplySupplyId], references: [shelterId, supplyId]) + + @@index([shelterSupplyShelterId, shelterSupplySupplyId]) + @@map("shelter_supply_logs") +} + model Supply { id String @id @default(uuid()) supplyCategoryId String @map("supply_category_id") diff --git a/src/app.module.ts b/src/app.module.ts index 82663d34..d27a6851 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -1,18 +1,19 @@ import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common'; import { APP_INTERCEPTOR } from '@nestjs/core'; -import { PrismaModule } from './prisma/prisma.module'; -import { ShelterModule } from './shelter/shelter.module'; -import { SupplyModule } from './supply/supply.module'; import { ServerResponseInterceptor } from './interceptors'; import { LoggingMiddleware } from './middlewares/logging.middleware'; -import { UsersModule } from './users/users.module'; +import { PartnersModule } from './partners/partners.module'; +import { PrismaModule } from './prisma/prisma.module'; import { SessionsModule } from './sessions/sessions.module'; -import { SupplyCategoriesModule } from './supply-categories/supply-categories.module'; import { ShelterManagersModule } from './shelter-managers/shelter-managers.module'; +import { ShelterSupplyLogsModule } from './shelter-supply-logs/shelter-supply-log.module'; import { ShelterSupplyModule } from './shelter-supply/shelter-supply.module'; -import { PartnersModule } from './partners/partners.module'; +import { ShelterModule } from './shelter/shelter.module'; +import { SupplyCategoriesModule } from './supply-categories/supply-categories.module'; +import { SupplyModule } from './supply/supply.module'; import { SupportersModule } from './supporters/supporters.module'; +import { UsersModule } from './users/users.module'; @Module({ imports: [ @@ -24,6 +25,7 @@ import { SupportersModule } from './supporters/supporters.module'; SupplyCategoriesModule, ShelterManagersModule, ShelterSupplyModule, + ShelterSupplyLogsModule, PartnersModule, SupportersModule, ], diff --git a/src/shelter-supply-logs/shelter-supply-log.controller.ts b/src/shelter-supply-logs/shelter-supply-log.controller.ts new file mode 100644 index 00000000..e1887151 --- /dev/null +++ b/src/shelter-supply-logs/shelter-supply-log.controller.ts @@ -0,0 +1,45 @@ +import { + Controller, + Get, + HttpException, + Logger, + Param, + UseGuards, +} from '@nestjs/common'; +import { ApiTags } from '@nestjs/swagger'; + +import { DistributionCenterGuard } from '@/guards/distribution-center.guard'; +import { ServerResponse } from '../utils'; +import { ShelterSupplyLogsService } from './shelter-supply-log.service'; + +@ApiTags('Logs do suprimento de abrigos') +@Controller('shelter/supplies/logs') +export class ShelterSupplyLogsController { + private logger = new Logger(ShelterSupplyLogsController.name); + + constructor( + private readonly shelterSupplyLogsService: ShelterSupplyLogsService, + ) {} + + @Get(':shelterId/:supplyId') + @UseGuards(DistributionCenterGuard) + async getLogs( + @Param('shelterId') shelterId: string, + @Param('supplyId') supplyId: string, + ) { + try { + const data = await this.shelterSupplyLogsService.getLogs( + shelterId, + supplyId, + ); + return new ServerResponse( + 200, + 'Successfully get shelter supplies logs', + data, + ); + } catch (err: any) { + this.logger.error(`Failed to get shelter supplies: ${err}`); + throw new HttpException(err?.code ?? err?.name ?? `${err}`, 400); + } + } +} diff --git a/src/shelter-supply-logs/shelter-supply-log.module.ts b/src/shelter-supply-logs/shelter-supply-log.module.ts new file mode 100644 index 00000000..7d5898f7 --- /dev/null +++ b/src/shelter-supply-logs/shelter-supply-log.module.ts @@ -0,0 +1,12 @@ +import { Module } from '@nestjs/common'; + +import { PrismaModule } from '../prisma/prisma.module'; +import { ShelterSupplyLogsController } from './shelter-supply-log.controller'; +import { ShelterSupplyLogsService } from './shelter-supply-log.service'; + +@Module({ + imports: [PrismaModule], + providers: [ShelterSupplyLogsService], + controllers: [ShelterSupplyLogsController], +}) +export class ShelterSupplyLogsModule {} diff --git a/src/shelter-supply-logs/shelter-supply-log.service.ts b/src/shelter-supply-logs/shelter-supply-log.service.ts new file mode 100644 index 00000000..21007129 --- /dev/null +++ b/src/shelter-supply-logs/shelter-supply-log.service.ts @@ -0,0 +1,39 @@ +import { Injectable } from '@nestjs/common'; + +import { PrismaService } from '../prisma/prisma.service'; + +@Injectable() +export class ShelterSupplyLogsService { + constructor(private readonly prismaService: PrismaService) {} + + async getLogs(shelterId: string, supplyId: string) { + return await this.prismaService.shelterSupplyLog.findMany({ + where: { + shelterSupplyShelterId: shelterId, + shelterSupplySupplyId: supplyId, + }, + select: { + priority: true, + quantity: true, + createdAt: true, + }, + }); + } + + async addLog( + shelterId: string, + supplyId: string, + priority: number, + quantity: number, + ): Promise { + await await this.prismaService.shelterSupplyLog.create({ + data: { + shelterSupplyShelterId: shelterId, + shelterSupplySupplyId: supplyId, + priority, + quantity, + createdAt: new Date().toISOString(), + }, + }); + } +} diff --git a/src/shelter-supply-logs/shelter-supply.controller.spec.ts b/src/shelter-supply-logs/shelter-supply.controller.spec.ts new file mode 100644 index 00000000..5d95df05 --- /dev/null +++ b/src/shelter-supply-logs/shelter-supply.controller.spec.ts @@ -0,0 +1,29 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { PrismaService } from 'src/prisma/prisma.service'; +import { ShelterSupplyLogsController } from './shelter-supply-log.controller'; +import { ShelterSupplyLogsService } from './shelter-supply-log.service'; + +describe('ShelterSupplyLogsController', () => { + let controller: ShelterSupplyLogsController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [ShelterSupplyLogsController], + providers: [ShelterSupplyLogsService], + }) + .useMocker((token) => { + if (token === PrismaService) { + return {}; + } + }) + .compile(); + + controller = module.get( + ShelterSupplyLogsController, + ); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/src/shelter-supply-logs/shelter-supply.service.spec.ts b/src/shelter-supply-logs/shelter-supply.service.spec.ts new file mode 100644 index 00000000..97d93ab1 --- /dev/null +++ b/src/shelter-supply-logs/shelter-supply.service.spec.ts @@ -0,0 +1,25 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { PrismaService } from 'src/prisma/prisma.service'; +import { ShelterSupplyLogsService } from './shelter-supply-log.service'; + +describe('ShelterSupplyLogsService', () => { + let service: ShelterSupplyLogsService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ShelterSupplyLogsService], + }) + .useMocker((token) => { + if (token === PrismaService) { + return {}; + } + }) + .compile(); + + service = module.get(ShelterSupplyLogsService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/src/shelter-supply/shelter-supply.module.ts b/src/shelter-supply/shelter-supply.module.ts index 0609a149..748fd339 100644 --- a/src/shelter-supply/shelter-supply.module.ts +++ b/src/shelter-supply/shelter-supply.module.ts @@ -1,8 +1,8 @@ import { Module } from '@nestjs/common'; -import { ShelterSupplyService } from './shelter-supply.service'; -import { ShelterSupplyController } from './shelter-supply.controller'; import { PrismaModule } from '../prisma/prisma.module'; +import { ShelterSupplyController } from './shelter-supply.controller'; +import { ShelterSupplyService } from './shelter-supply.service'; @Module({ imports: [PrismaModule], diff --git a/src/shelter-supply/shelter-supply.service.ts b/src/shelter-supply/shelter-supply.service.ts index ef4cf97a..d4eddbfe 100644 --- a/src/shelter-supply/shelter-supply.service.ts +++ b/src/shelter-supply/shelter-supply.service.ts @@ -1,13 +1,13 @@ -import { z } from 'zod'; import { Injectable } from '@nestjs/common'; +import { z } from 'zod'; import { PrismaService } from '../prisma/prisma.service'; +import { SupplyPriority } from '../supply/types'; import { CreateShelterSupplySchema, UpdateManyShelterSupplySchema, UpdateShelterSupplySchema, } from './types'; -import { SupplyPriority } from '../supply/types'; @Injectable() export class ShelterSupplyService { @@ -66,6 +66,15 @@ export class ShelterSupplyService { priority, ); } + await this.prismaService.shelterSupplyLog.create({ + data: { + shelterSupplyShelterId: where.shelterId, + shelterSupplySupplyId: where.supplyId, + priority, + quantity, + createdAt: new Date().toISOString(), + }, + }); await this.prismaService.shelterSupply.update({ where: {