From e3216360d0035d41535845119e84a52c1f20b738 Mon Sep 17 00:00:00 2001 From: vmanawat Date: Thu, 6 Jun 2024 15:58:25 -0700 Subject: [PATCH 1/3] dryrun dto, prisma+flyway updates --- backend/prisma/schema.prisma | 18 ++++-- backend/src/app.module.ts | 4 +- backend/src/dryrun/dryrun.controller.spec.ts | 20 ++++++ backend/src/dryrun/dryrun.controller.ts | 35 +++++++++++ backend/src/dryrun/dryrun.module.ts | 9 +++ backend/src/dryrun/dryrun.service.spec.ts | 18 ++++++ backend/src/dryrun/dryrun.service.ts | 27 ++++++++ backend/src/dryrun/dto/create-dryrun.dto.ts | 13 ++++ backend/src/dryrun/dto/dryrun.dto.ts | 46 ++++++++++++++ backend/src/dryrun/dto/update-dryrun.dto.ts | 3 + backend/src/dryrun/entities/dryrun.entity.ts | 1 + docker-compose.yml | 9 ++- frontend/package-lock.json | 18 ++++-- frontend/package.json | 1 + frontend/src/components/Dashboard.tsx | 13 +--- migrations/sql/V1.0.0__init.sql | 24 ------- .../sql/V1.0.0__submission_status_code.sql | 63 +++++++++++++++++++ migrations/sql/V1.0.1__alter_user_seq.sql | 1 - migrations/sql/V1.0.1__file_submission.sql | 18 ++++++ 19 files changed, 290 insertions(+), 51 deletions(-) create mode 100644 backend/src/dryrun/dryrun.controller.spec.ts create mode 100644 backend/src/dryrun/dryrun.controller.ts create mode 100644 backend/src/dryrun/dryrun.module.ts create mode 100644 backend/src/dryrun/dryrun.service.spec.ts create mode 100644 backend/src/dryrun/dryrun.service.ts create mode 100644 backend/src/dryrun/dto/create-dryrun.dto.ts create mode 100644 backend/src/dryrun/dto/dryrun.dto.ts create mode 100644 backend/src/dryrun/dto/update-dryrun.dto.ts create mode 100644 backend/src/dryrun/entities/dryrun.entity.ts delete mode 100644 migrations/sql/V1.0.0__init.sql create mode 100644 migrations/sql/V1.0.0__submission_status_code.sql delete mode 100644 migrations/sql/V1.0.1__alter_user_seq.sql create mode 100644 migrations/sql/V1.0.1__file_submission.sql diff --git a/backend/prisma/schema.prisma b/backend/prisma/schema.prisma index c1947b34..3288d868 100644 --- a/backend/prisma/schema.prisma +++ b/backend/prisma/schema.prisma @@ -1,15 +1,21 @@ generator client { - provider = "prisma-client-js" + provider = "prisma-client-js" previewFeatures = ["metrics"] } datasource db { provider = "postgresql" - url = env("DATABASE_URL") + url = env("POSTGRESQL_URL") } -model users { - id Decimal @id(map: "USER_PK") @default(dbgenerated("nextval('\"USER_SEQ\"'::regclass)")) @db.Decimal - name String @db.VarChar(200) - email String @db.VarChar(200) +/// This model or at least one of its fields has comments in the database, and requires an additional setup for migrations: Read more: https://pris.ly/d/database-comments +model submission_status_code { + submission_status_code String @id(map: "submission_status_code_pk") @db.VarChar(20) + description String @db.VarChar(250) + display_order Int + active_ind Boolean @default(true) + create_user_id String @db.VarChar(200) + create_utc_timestamp DateTime @db.Timestamp(6) + update_user_id String @db.VarChar(200) + update_utc_timestamp DateTime @db.Timestamp(6) } diff --git a/backend/src/app.module.ts b/backend/src/app.module.ts index 472e5da0..34e93ce6 100644 --- a/backend/src/app.module.ts +++ b/backend/src/app.module.ts @@ -9,6 +9,7 @@ import { AppController } from "./app.controller"; import { MetricsController } from "./metrics.controller"; import { TerminusModule } from '@nestjs/terminus'; import { HealthController } from "./health.controller"; +import { DryrunModule } from './dryrun/dryrun.module'; const DB_HOST = process.env.POSTGRES_HOST || "localhost"; const DB_USER = process.env.POSTGRES_USER || "postgres"; @@ -45,7 +46,8 @@ function getMiddlewares() { middlewares: getMiddlewares(), }, }), - UsersModule + UsersModule, + DryrunModule ], controllers: [AppController,MetricsController, HealthController], providers: [AppService] diff --git a/backend/src/dryrun/dryrun.controller.spec.ts b/backend/src/dryrun/dryrun.controller.spec.ts new file mode 100644 index 00000000..f8803df1 --- /dev/null +++ b/backend/src/dryrun/dryrun.controller.spec.ts @@ -0,0 +1,20 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { DryrunController } from './dryrun.controller'; +import { DryrunService } from './dryrun.service'; + +describe('DryrunController', () => { + let controller: DryrunController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [DryrunController], + providers: [DryrunService], + }).compile(); + + controller = module.get(DryrunController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/backend/src/dryrun/dryrun.controller.ts b/backend/src/dryrun/dryrun.controller.ts new file mode 100644 index 00000000..cd21dc8c --- /dev/null +++ b/backend/src/dryrun/dryrun.controller.ts @@ -0,0 +1,35 @@ +import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common'; +import { DryrunService } from './dryrun.service'; +import { CreateDryrunDto } from './dto/create-dryrun.dto'; +import { UpdateDryrunDto } from './dto/update-dryrun.dto'; + +@Controller('dryrun') +export class DryrunController { + constructor(private readonly dryrunService: DryrunService) {} + + @Post() + create(@Body() createDryrunDto: CreateDryrunDto) { + console.log("I AM HERE!!!"); + return this.dryrunService.create(createDryrunDto); + } + + @Get() + findAll() { + return this.dryrunService.findAll(); + } + + @Get(':id') + findOne(@Param('id') id: string) { + return this.dryrunService.findOne(+id); + } + + @Patch(':id') + update(@Param('id') id: string, @Body() updateDryrunDto: UpdateDryrunDto) { + return this.dryrunService.update(+id, updateDryrunDto); + } + + @Delete(':id') + remove(@Param('id') id: string) { + return this.dryrunService.remove(+id); + } +} diff --git a/backend/src/dryrun/dryrun.module.ts b/backend/src/dryrun/dryrun.module.ts new file mode 100644 index 00000000..5bc6ffe8 --- /dev/null +++ b/backend/src/dryrun/dryrun.module.ts @@ -0,0 +1,9 @@ +import { Module } from '@nestjs/common'; +import { DryrunService } from './dryrun.service'; +import { DryrunController } from './dryrun.controller'; + +@Module({ + controllers: [DryrunController], + providers: [DryrunService], +}) +export class DryrunModule {} diff --git a/backend/src/dryrun/dryrun.service.spec.ts b/backend/src/dryrun/dryrun.service.spec.ts new file mode 100644 index 00000000..461b47c0 --- /dev/null +++ b/backend/src/dryrun/dryrun.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { DryrunService } from './dryrun.service'; + +describe('DryrunService', () => { + let service: DryrunService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [DryrunService], + }).compile(); + + service = module.get(DryrunService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/backend/src/dryrun/dryrun.service.ts b/backend/src/dryrun/dryrun.service.ts new file mode 100644 index 00000000..96023a7d --- /dev/null +++ b/backend/src/dryrun/dryrun.service.ts @@ -0,0 +1,27 @@ +import { Injectable } from '@nestjs/common'; +import { CreateDryrunDto } from './dto/create-dryrun.dto'; +import { UpdateDryrunDto } from './dto/update-dryrun.dto'; + +@Injectable() +export class DryrunService { + create(createDryrunDto: CreateDryrunDto) { + console.log("I WILL SEND THE POST FROM HERE!!!"); + return 'This action adds a new dryrun'; + } + + findAll() { + return `This action returns all dryrun`; + } + + findOne(id: number) { + return `This action returns a #${id} dryrun`; + } + + update(id: number, updateDryrunDto: UpdateDryrunDto) { + return `This action updates a #${id} dryrun`; + } + + remove(id: number) { + return `This action removes a #${id} dryrun`; + } +} diff --git a/backend/src/dryrun/dto/create-dryrun.dto.ts b/backend/src/dryrun/dto/create-dryrun.dto.ts new file mode 100644 index 00000000..72b0f581 --- /dev/null +++ b/backend/src/dryrun/dto/create-dryrun.dto.ts @@ -0,0 +1,13 @@ +import { PickType } from "@nestjs/swagger"; +import { DryrunDto } from "./dryrun.dto"; + +export class CreateDryrunDto extends PickType(DryrunDto, [ + 'submission_status_code', + 'description', + 'display_order', + 'active_ind', + 'create_user_id', + 'create_utc_timestamp', + 'update_user_id', + 'update_utc_timestamp', +] as const) {} \ No newline at end of file diff --git a/backend/src/dryrun/dto/dryrun.dto.ts b/backend/src/dryrun/dto/dryrun.dto.ts new file mode 100644 index 00000000..f6b89273 --- /dev/null +++ b/backend/src/dryrun/dto/dryrun.dto.ts @@ -0,0 +1,46 @@ +import { ApiProperty } from '@nestjs/swagger'; + +export class DryrunDto { + @ApiProperty({ + description: 'Unique identifies for the submitted file', + // default: '9999', + }) + submission_status_code: string; + + @ApiProperty({ + description: 'Full name of the code', + // default: 'username', + }) + description: string; + + @ApiProperty({ + description: 'Order in which the code appears', + }) + display_order: number; + + @ApiProperty({ + description: 'True if active, false otherwise', + default: true, + }) + active_ind: boolean + + @ApiProperty({ + description: 'The id of the user that created the record', + }) + create_user_id: string; + + @ApiProperty({ + description: 'When the user created the record', + }) + create_utc_timestamp: Date; + + @ApiProperty({ + description: 'The id of the user that last updated the record', + }) + update_user_id: string; + + @ApiProperty({ + description: 'When the user last updated the record', + }) + update_utc_timestamp: Date; +} diff --git a/backend/src/dryrun/dto/update-dryrun.dto.ts b/backend/src/dryrun/dto/update-dryrun.dto.ts new file mode 100644 index 00000000..d8a0d416 --- /dev/null +++ b/backend/src/dryrun/dto/update-dryrun.dto.ts @@ -0,0 +1,3 @@ +import { CreateDryrunDto } from './create-dryrun.dto'; + +export class UpdateDryrunDto extends CreateDryrunDto {} diff --git a/backend/src/dryrun/entities/dryrun.entity.ts b/backend/src/dryrun/entities/dryrun.entity.ts new file mode 100644 index 00000000..2498479d --- /dev/null +++ b/backend/src/dryrun/entities/dryrun.entity.ts @@ -0,0 +1 @@ +export class Dryrun {} diff --git a/docker-compose.yml b/docker-compose.yml index d758cfac..c2538c55 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,12 +8,17 @@ x-var: default - &POSTGRES_DATABASE postgres + - &POSTGRES_HOST + localhost:5432 + - &POSTGRES_SCHEMA + ENMODS x-postgres-vars: &postgres-vars - POSTGRES_HOST: database + POSTGRES_HOST: *POSTGRES_HOST POSTGRES_USER: *POSTGRES_USER POSTGRES_PASSWORD: *POSTGRES_PASSWORD POSTGRES_DATABASE: *POSTGRES_DATABASE + POSTGRES_SCHEMA: *POSTGRES_SCHEMA services: database: @@ -35,7 +40,7 @@ services: FLYWAY_USER: *POSTGRES_USER FLYWAY_PASSWORD: *POSTGRES_PASSWORD FLYWAY_BASELINE_ON_MIGRATE: true - FLYWAY_DEFAULT_SCHEMA: USERS + FLYWAY_DEFAULT_SCHEMA: *POSTGRES_SCHEMA depends_on: database: condition: service_healthy diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 248dbcee..d272bf38 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -22,6 +22,7 @@ "react-dom": "^18.2.0", "react-router": "^6.12.1", "react-router-dom": "^6.12.1", + "redux": "^5.0.1", "vite": "^5.0.0", "vite-tsconfig-paths": "^4.2.0" }, @@ -4209,6 +4210,14 @@ "redux": "^4.0.4" } }, + "node_modules/dnd-core/node_modules/redux": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", + "dependencies": { + "@babel/runtime": "^7.9.2" + } + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -8579,12 +8588,9 @@ } }, "node_modules/redux": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", - "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", - "dependencies": { - "@babel/runtime": "^7.9.2" - } + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", + "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==" }, "node_modules/reflect.getprototypeof": { "version": "1.0.6", diff --git a/frontend/package.json b/frontend/package.json index 6b8a7872..2513a6c2 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -28,6 +28,7 @@ "react-dom": "^18.2.0", "react-router": "^6.12.1", "react-router-dom": "^6.12.1", + "redux": "^5.0.1", "vite": "^5.0.0", "vite-tsconfig-paths": "^4.2.0" }, diff --git a/frontend/src/components/Dashboard.tsx b/frontend/src/components/Dashboard.tsx index 93f111b7..3b664e28 100644 --- a/frontend/src/components/Dashboard.tsx +++ b/frontend/src/components/Dashboard.tsx @@ -41,18 +41,9 @@ export default function Dashboard() { useEffect(() => { apiService .getAxiosInstance() - .get('/v1/users') + .post('/v1/dryrun') .then((response: AxiosResponse) => { - const users = [] - for (const user of response.data) { - const userDto = { - id: user.id, - name: user.name, - email: user.email, - } - users.push(userDto) - } - setData(users) + console.log(response) }) .catch((error) => { console.error(error) diff --git a/migrations/sql/V1.0.0__init.sql b/migrations/sql/V1.0.0__init.sql deleted file mode 100644 index 2be16859..00000000 --- a/migrations/sql/V1.0.0__init.sql +++ /dev/null @@ -1,24 +0,0 @@ -CREATE SCHEMA IF NOT EXISTS USERS; - -CREATE SEQUENCE IF NOT EXISTS USERS."USER_SEQ" - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 100; - -CREATE TABLE IF NOT EXISTS USERS.USERS -( - ID numeric not null - constraint "USER_PK" - primary key DEFAULT nextval('USERS."USER_SEQ"'), - NAME varchar(200) not null, - EMAIL varchar(200) not null -); -INSERT INTO USERS.USERS (NAME, EMAIL) -VALUES ('John', 'John.ipsum@test.com'), - ('Jane', 'Jane.ipsum@test.com'), - ('Jack', 'Jack.ipsum@test.com'), - ('Jill', 'Jill.ipsum@test.com'), - ('Joe', 'Joe.ipsum@test.com'); - diff --git a/migrations/sql/V1.0.0__submission_status_code.sql b/migrations/sql/V1.0.0__submission_status_code.sql new file mode 100644 index 00000000..cd30257d --- /dev/null +++ b/migrations/sql/V1.0.0__submission_status_code.sql @@ -0,0 +1,63 @@ +CREATE SCHEMA IF NOT EXISTS ENMODS; +CREATE TABLE IF NOT EXISTS ENMODS.submission_status_code ( + submission_status_code varchar(20) NOT NULL, + description varchar(250) NOT NULL, + display_order int4 NOT NULL, + active_ind boolean DEFAULT true NOT NULL, + create_user_id varchar(200) NOT NULL, + create_utc_timestamp timestamp NOT NULL, + update_user_id varchar(200) NOT NULL, + update_utc_timestamp timestamp NOT NULL, + CONSTRAINT submission_status_code_pk PRIMARY KEY (submission_status_code) +); +INSERT INTO ENMODS.submission_status_code( + submission_status_code, + description, + display_order, + active_ind, + create_user_id, + create_utc_timestamp, + update_user_id, + update_utc_timestamp + ) +values ( + 'SUBMITTED', + 'Submitted', + 0, + true, + 'VMANAWAT', + (now() at time zone 'utc'), + 'VMANAWAT', + (now() at time zone 'utc') + ), + ( + 'INPROGRESS', + 'In Progress', + 5, + true, + 'VMANAWAT', + (now() at time zone 'utc'), + 'VMANAWAT', + (now() at time zone 'utc') + ), + ( + 'VALIDATED', + 'Validated', + 10, + true, + 'VMANAWAT', + (now() at time zone 'utc'), + 'VMANAWAT', + (now() at time zone 'utc') + ), + ( + 'REJECTED', + 'Rejected', + 15, + true, + 'VMANAWAT', + (now() at time zone 'utc'), + 'VMANAWAT', + (now() at time zone 'utc') + ); + \ No newline at end of file diff --git a/migrations/sql/V1.0.1__alter_user_seq.sql b/migrations/sql/V1.0.1__alter_user_seq.sql deleted file mode 100644 index 6be8cd5b..00000000 --- a/migrations/sql/V1.0.1__alter_user_seq.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER SEQUENCE USERS."USER_SEQ" RESTART WITH 6 CACHE 1; diff --git a/migrations/sql/V1.0.1__file_submission.sql b/migrations/sql/V1.0.1__file_submission.sql new file mode 100644 index 00000000..be464919 --- /dev/null +++ b/migrations/sql/V1.0.1__file_submission.sql @@ -0,0 +1,18 @@ +CREATE TABLE IF NOT EXISTS ENMODS.file_submissions ( + submission_id UUID PRIMARY KEY NOT NULL DEFAULT gen_random_uuid(), + file_name varchar(200) NOT NULL, + submission_date timestamp NOT NULL, + submitter_user_id varchar(200) NOT NULL, + submission_status_code varchar(10) NOT NULL, + submitter_agency_name varchar(200) NOT NULL, + sample_count int4 NULL, + results_count int4 NULL, + active_ind boolean NOT NULL DEFAULT true, + error_log text NULL, + organization_guid NULL, + create_user_id varchar(200) NOT NULL, + create_utc_timestamp timestamp NOT NULL, + update_user_id varchar(200) NOT NULL, + update_utc_timestamp timestamp NOT NULL, + CONSTRAINT submission_status_code_fk FOREIGN KEY (submission_status_code.submission_status_code) +); From 2a800e1d517d8da14d4ee4af063aa434d9592093 Mon Sep 17 00:00:00 2001 From: vmanawat <109625428+vmanawat@users.noreply.github.com> Date: Fri, 7 Jun 2024 09:36:58 -0700 Subject: [PATCH 2/3] fixing prisma and flyway scripts --- backend/prisma/schema.prisma | 36 ++++++++++++++----- .../sql/V1.0.0__submission_status_code.sql | 6 ++-- migrations/sql/V1.0.1__file_submission.sql | 10 +++--- 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/backend/prisma/schema.prisma b/backend/prisma/schema.prisma index 3288d868..229b7290 100644 --- a/backend/prisma/schema.prisma +++ b/backend/prisma/schema.prisma @@ -10,12 +10,32 @@ datasource db { /// This model or at least one of its fields has comments in the database, and requires an additional setup for migrations: Read more: https://pris.ly/d/database-comments model submission_status_code { - submission_status_code String @id(map: "submission_status_code_pk") @db.VarChar(20) - description String @db.VarChar(250) - display_order Int - active_ind Boolean @default(true) - create_user_id String @db.VarChar(200) - create_utc_timestamp DateTime @db.Timestamp(6) - update_user_id String @db.VarChar(200) - update_utc_timestamp DateTime @db.Timestamp(6) + submission_status_code String @id(map: "submission_status_code_pk") @db.VarChar(20) + description String @db.VarChar(250) + display_order Int + active_ind Boolean @default(true) + create_user_id String @db.VarChar(200) + create_utc_timestamp DateTime @db.Timestamp(6) + update_user_id String @db.VarChar(200) + update_utc_timestamp DateTime @db.Timestamp(6) + file_submissions_file_submissions_submission_status_codeTosubmission_status_code file_submissions[] @relation("file_submissions_submission_status_codeTosubmission_status_code") +} + +model file_submissions { + submission_id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid + file_name String @db.VarChar(200) + submission_date DateTime @db.Timestamp(6) + submitter_user_id String @db.VarChar(200) + submission_status_code String @db.VarChar(10) + submitter_agency_name String @db.VarChar(200) + sample_count Int? + results_count Int? + active_ind Boolean @default(true) + error_log String? + organization_guid String? @db.Uuid + create_user_id String @db.VarChar(200) + create_utc_timestamp DateTime @db.Timestamp(6) + update_user_id String @db.VarChar(200) + update_utc_timestamp DateTime @db.Timestamp(6) + submission_status_code_file_submissions_submission_status_codeTosubmission_status_code submission_status_code @relation("file_submissions_submission_status_codeTosubmission_status_code", fields: [submission_status_code], references: [submission_status_code], onDelete: NoAction, onUpdate: NoAction, map: "submission_status_code_fk") } diff --git a/migrations/sql/V1.0.0__submission_status_code.sql b/migrations/sql/V1.0.0__submission_status_code.sql index cd30257d..b627807b 100644 --- a/migrations/sql/V1.0.0__submission_status_code.sql +++ b/migrations/sql/V1.0.0__submission_status_code.sql @@ -1,5 +1,5 @@ -CREATE SCHEMA IF NOT EXISTS ENMODS; -CREATE TABLE IF NOT EXISTS ENMODS.submission_status_code ( +CREATE SCHEMA IF NOT EXISTS enmods; +CREATE TABLE IF NOT EXISTS enmods.submission_status_code ( submission_status_code varchar(20) NOT NULL, description varchar(250) NOT NULL, display_order int4 NOT NULL, @@ -10,7 +10,7 @@ CREATE TABLE IF NOT EXISTS ENMODS.submission_status_code ( update_utc_timestamp timestamp NOT NULL, CONSTRAINT submission_status_code_pk PRIMARY KEY (submission_status_code) ); -INSERT INTO ENMODS.submission_status_code( +INSERT INTO enmods.submission_status_code( submission_status_code, description, display_order, diff --git a/migrations/sql/V1.0.1__file_submission.sql b/migrations/sql/V1.0.1__file_submission.sql index be464919..1a50b115 100644 --- a/migrations/sql/V1.0.1__file_submission.sql +++ b/migrations/sql/V1.0.1__file_submission.sql @@ -1,4 +1,4 @@ -CREATE TABLE IF NOT EXISTS ENMODS.file_submissions ( +CREATE TABLE IF NOT EXISTS enmods.file_submissions ( submission_id UUID PRIMARY KEY NOT NULL DEFAULT gen_random_uuid(), file_name varchar(200) NOT NULL, submission_date timestamp NOT NULL, @@ -9,10 +9,12 @@ CREATE TABLE IF NOT EXISTS ENMODS.file_submissions ( results_count int4 NULL, active_ind boolean NOT NULL DEFAULT true, error_log text NULL, - organization_guid NULL, + organization_guid UUID NULL, create_user_id varchar(200) NOT NULL, create_utc_timestamp timestamp NOT NULL, update_user_id varchar(200) NOT NULL, update_utc_timestamp timestamp NOT NULL, - CONSTRAINT submission_status_code_fk FOREIGN KEY (submission_status_code.submission_status_code) -); + CONSTRAINT submission_status_code_fk + FOREIGN KEY(submission_status_code) + REFERENCES enmods.submission_status_code(submission_status_code) +); \ No newline at end of file From 15e102c4038d52264f50d998478e5322a27c9102 Mon Sep 17 00:00:00 2001 From: vmanawat <109625428+vmanawat@users.noreply.github.com> Date: Tue, 11 Jun 2024 14:46:51 -0700 Subject: [PATCH 3/3] Updating flyway scripts + dryRun service updates + removing users dto --- backend/src/app.module.ts | 2 - backend/src/dryrun/dryrun.controller.ts | 6 +- backend/src/dryrun/dryrun.service.ts | 13 +- backend/src/users/dto/create-user.dto.ts | 7 - backend/src/users/dto/update-user.dto.ts | 3 - backend/src/users/dto/user.dto.ts | 21 -- backend/src/users/users.controller.spec.ts | 180 ------------ backend/src/users/users.controller.ts | 65 ----- backend/src/users/users.module.ts | 10 - backend/src/users/users.service.spec.ts | 259 ------------------ backend/src/users/users.service.ts | 156 ----------- frontend/src/components/Dashboard.tsx | 2 +- .../sql/V1.0.0__submission_status_code.sql | 5 +- migrations/sql/V1.0.1__file_submission.sql | 68 +++-- 14 files changed, 68 insertions(+), 729 deletions(-) delete mode 100644 backend/src/users/dto/create-user.dto.ts delete mode 100644 backend/src/users/dto/update-user.dto.ts delete mode 100644 backend/src/users/dto/user.dto.ts delete mode 100644 backend/src/users/users.controller.spec.ts delete mode 100644 backend/src/users/users.controller.ts delete mode 100644 backend/src/users/users.module.ts delete mode 100644 backend/src/users/users.service.spec.ts delete mode 100644 backend/src/users/users.service.ts diff --git a/backend/src/app.module.ts b/backend/src/app.module.ts index 34e93ce6..5e522b85 100644 --- a/backend/src/app.module.ts +++ b/backend/src/app.module.ts @@ -3,7 +3,6 @@ import { Logger, MiddlewareConsumer, Module, RequestMethod } from "@nestjs/commo import { HTTPLoggerMiddleware } from "./middleware/req.res.logger"; import { loggingMiddleware, PrismaModule } from "nestjs-prisma"; import { ConfigModule } from "@nestjs/config"; -import { UsersModule } from "./users/users.module"; import { AppService } from "./app.service"; import { AppController } from "./app.controller"; import { MetricsController } from "./metrics.controller"; @@ -46,7 +45,6 @@ function getMiddlewares() { middlewares: getMiddlewares(), }, }), - UsersModule, DryrunModule ], controllers: [AppController,MetricsController, HealthController], diff --git a/backend/src/dryrun/dryrun.controller.ts b/backend/src/dryrun/dryrun.controller.ts index cd21dc8c..dfca2a46 100644 --- a/backend/src/dryrun/dryrun.controller.ts +++ b/backend/src/dryrun/dryrun.controller.ts @@ -2,8 +2,11 @@ import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/commo import { DryrunService } from './dryrun.service'; import { CreateDryrunDto } from './dto/create-dryrun.dto'; import { UpdateDryrunDto } from './dto/update-dryrun.dto'; +import { ApiTags } from '@nestjs/swagger'; +import { DryrunDto } from './dto/dryrun.dto'; -@Controller('dryrun') +@ApiTags("dryrun") +@Controller({path: "dryrun", version: "1"}) export class DryrunController { constructor(private readonly dryrunService: DryrunService) {} @@ -15,6 +18,7 @@ export class DryrunController { @Get() findAll() { + console.log('FIND ALL HERE!!!') return this.dryrunService.findAll(); } diff --git a/backend/src/dryrun/dryrun.service.ts b/backend/src/dryrun/dryrun.service.ts index 96023a7d..7a6abd23 100644 --- a/backend/src/dryrun/dryrun.service.ts +++ b/backend/src/dryrun/dryrun.service.ts @@ -1,16 +1,25 @@ import { Injectable } from '@nestjs/common'; import { CreateDryrunDto } from './dto/create-dryrun.dto'; import { UpdateDryrunDto } from './dto/update-dryrun.dto'; +import { PrismaService } from 'nestjs-prisma'; +import { Prisma } from "@prisma/client"; +import { DryrunDto } from './dto/dryrun.dto'; @Injectable() export class DryrunService { + constructor( + private prisma: PrismaService + ) { + } + create(createDryrunDto: CreateDryrunDto) { console.log("I WILL SEND THE POST FROM HERE!!!"); return 'This action adds a new dryrun'; } - findAll() { - return `This action returns all dryrun`; + async findAll() { + const files = await this.prisma.file_submissions.findMany(); + console.log(files) } findOne(id: number) { diff --git a/backend/src/users/dto/create-user.dto.ts b/backend/src/users/dto/create-user.dto.ts deleted file mode 100644 index 039e11df..00000000 --- a/backend/src/users/dto/create-user.dto.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { PickType } from '@nestjs/swagger'; -import { UserDto } from './user.dto'; - -export class CreateUserDto extends PickType(UserDto, [ - 'email', - 'name', -] as const) {} diff --git a/backend/src/users/dto/update-user.dto.ts b/backend/src/users/dto/update-user.dto.ts deleted file mode 100644 index 9b35b94b..00000000 --- a/backend/src/users/dto/update-user.dto.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { CreateUserDto } from './create-user.dto'; - -export class UpdateUserDto extends CreateUserDto {} diff --git a/backend/src/users/dto/user.dto.ts b/backend/src/users/dto/user.dto.ts deleted file mode 100644 index 89eb7f0d..00000000 --- a/backend/src/users/dto/user.dto.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { ApiProperty } from '@nestjs/swagger'; - -export class UserDto { - @ApiProperty({ - description: 'The ID of the user', - // default: '9999', - }) - id: number; - - @ApiProperty({ - description: 'The name of the user', - // default: 'username', - }) - name: string; - - @ApiProperty({ - description: 'The contact email of the user', - default: '', - }) - email: string; -} diff --git a/backend/src/users/users.controller.spec.ts b/backend/src/users/users.controller.spec.ts deleted file mode 100644 index 73ebe8a9..00000000 --- a/backend/src/users/users.controller.spec.ts +++ /dev/null @@ -1,180 +0,0 @@ -import {Test, TestingModule} from "@nestjs/testing"; -import {UsersController} from "./users.controller"; -import {UsersService} from "./users.service"; -import * as request from 'supertest'; -import {HttpException, INestApplication} from "@nestjs/common"; -import {CreateUserDto} from "./dto/create-user.dto"; -import {UpdateUserDto} from "./dto/update-user.dto"; -import {UserDto} from "./dto/user.dto"; -import { PrismaService } from "nestjs-prisma"; - -describe("UserController", () => { - let controller: UsersController; - let usersService: UsersService; - let app: INestApplication; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - controllers: [UsersController], - providers: [ - UsersService, - { - provide: PrismaService, - useValue: {}, - }, - ], - }).compile(); - usersService = module.get(UsersService); - controller = module.get(UsersController); - app = module.createNestApplication(); - await app.init(); - }); - // Close the app after each test - afterEach(async () => { - await app.close(); - }); - - it("should be defined", () => { - expect(controller).toBeDefined(); - }); - - describe('create', () => { - it('should call the service create method with the given dto and return the result', async () => { - // Arrange - const createUserDto: CreateUserDto = { - email: 'test@example.com', - name: 'Test User', - }; - const expectedResult = { - id: 1, - ...createUserDto, - }; - jest.spyOn(usersService, 'create').mockResolvedValue(expectedResult); - - // Act - const result = await controller.create(createUserDto); - - // Assert - expect(usersService.create).toHaveBeenCalledWith(createUserDto); - expect(result).toEqual(expectedResult); - }); - }); - describe('findAll', () => { - it('should return an array of users', async () => { - const result = []; - result.push({id: 1, name: 'Alice', email: 'test@gmail.com'}); - jest.spyOn(usersService, 'findAll').mockResolvedValue(result); - expect(await controller.findAll()).toBe(result); - }); - }); - describe('findOne', () => { - it('should return a user object', async () => { - const result: UserDto = { id: 1, name:"john", email:'John_Doe@gmail.com'}; - jest.spyOn(usersService, 'findOne').mockResolvedValue(result); - expect(await controller.findOne('1')).toBe(result); - }); - it('should throw error if user not found', async () => { - jest.spyOn(usersService, 'findOne').mockResolvedValue(undefined); - try { - await controller.findOne('1'); - }catch (e) { - expect(e).toBeInstanceOf(HttpException); - expect(e.message).toBe('User not found.'); - } - }); - }); - describe('update', () => { - it('should update and return a user object', async () => { - const id = '1'; - const updateUserDto: UpdateUserDto = { - email: 'johndoe@example.com', - name: 'John Doe', - }; - const userDto: UserDto = { - id: 1, - name: 'John Doe', - email: 'johndoe@example.com', - }; - jest.spyOn(usersService, 'update').mockResolvedValue(userDto); - - expect(await controller.update(id, updateUserDto)).toBe(userDto); - expect(usersService.update).toHaveBeenCalledWith(+id, updateUserDto); - }); - }); - describe('remove', () => { - it('should remove a user', async () => { - const id = '1'; - jest.spyOn(usersService, 'remove').mockResolvedValue(undefined); - - expect(await controller.remove(id)).toBeUndefined(); - expect(usersService.remove).toHaveBeenCalledWith(+id); - }); - }); - // Test the GET /users/search endpoint - describe('GET /users/search', () => { - // Test with valid query parameters - it('given valid query parameters_should return an array of users with pagination metadata', async () => { - // Mock the usersService.searchUsers method to return a sample result - const result = { - users: [ - {id: 1, name: 'Alice', email: 'alice@example.com'}, - {id: 2, name: 'Adam', email: 'Adam@example.com'}, - ], - page: 1, - limit: 10, - sort: '{"name":"ASC"}', - filter: '[{"key":"name","operation":"like","value":"A"}]', - total: 2, - totalPages: 1, - }; - jest.spyOn(usersService, 'searchUsers').mockImplementation(async () => result); - - // Make a GET request with query parameters and expect a 200 status code and the result object - return request(app.getHttpServer()) - .get('/users/search') - .query({ - page: 1, - limit: 10, - sort: '{"name":"ASC"}', - filter: '[{"key":"name","operation":"like","value":"A"}]', - }) - .expect(200) - .expect(result); - }); - - // Test with invalid query parameters - it('given invalid query parameters_should return a 400 status code with an error message', async () => { - // Make a GET request with invalid query parameters and expect a 400 status code and an error message - return request(app.getHttpServer()) - .get('/users/search') - .query({ - page: 'invalid', - limit: 'invalid', - }) - .expect(400) - .expect({ - statusCode: 400, - message: 'Invalid query parameters' - }); - }); - it('given sort and filter as invalid query parameters_should return a 400 status code with an error message', async () => { - // Make a GET request with invalid query parameters and expect a 400 status code and an error message - jest.spyOn(usersService, 'searchUsers').mockImplementation(async () => { - throw new HttpException('Invalid query parameters', 400) - }); - return request(app.getHttpServer()) - .get('/users/search') - .query({ - page: 1, - limit: 10, - sort: 'invalid', - filter: 'invalid', - }) - .expect(400) - .expect({ - statusCode: 400, - message: 'Invalid query parameters' - }); - }); - }); -}); diff --git a/backend/src/users/users.controller.ts b/backend/src/users/users.controller.ts deleted file mode 100644 index 36fd258f..00000000 --- a/backend/src/users/users.controller.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { - Controller, - Get, - Post, - Body, - Put, - Param, - Delete, Query, HttpException, -} from "@nestjs/common"; -import {ApiTags} from "@nestjs/swagger"; -import {UsersService} from "./users.service"; -import {CreateUserDto} from "./dto/create-user.dto"; -import {UpdateUserDto} from "./dto/update-user.dto"; -import { UserDto } from "./dto/user.dto"; - -@ApiTags("users") -@Controller({path: "users", version: "1"}) -export class UsersController { - constructor(private readonly usersService: UsersService) { - } - - @Post() - create(@Body() createUserDto: CreateUserDto) { - return this.usersService.create(createUserDto); - } - - @Get() - findAll() : Promise { - return this.usersService.findAll(); - } - - @Get("search") // it must be ahead of the below Get(":id") to avoid conflict - async searchUsers( - @Query("page") page: number, - @Query("limit") limit: number, - @Query("sort") sort: string, // JSON string to store sort key and sort value, ex: {name: "ASC"} - @Query("filter") filter: string // JSON array for key, operation and value, ex: [{key: "name", operation: "like", value: "Peter"}] - ) { - if (isNaN(page) || isNaN(limit)) { - throw new HttpException("Invalid query parameters", 400); - } - return this.usersService.searchUsers(page, limit, sort, filter); - } - - @Get(":id") - async findOne(@Param("id") id: string) { - const user = await this.usersService.findOne(+id); - if (!user) { - throw new HttpException("User not found.", 404); - } - return user; - } - - @Put(":id") - update(@Param("id") id: string, @Body() updateUserDto: UpdateUserDto) { - return this.usersService.update(+id, updateUserDto); - } - - @Delete(":id") - remove(@Param("id") id: string) { - return this.usersService.remove(+id); - } - - -} diff --git a/backend/src/users/users.module.ts b/backend/src/users/users.module.ts deleted file mode 100644 index d71b73d9..00000000 --- a/backend/src/users/users.module.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Module } from "@nestjs/common"; -import { UsersService } from "./users.service"; -import { UsersController } from "./users.controller"; - -@Module({ - controllers: [UsersController], - providers: [UsersService] -}) -export class UsersModule { -} diff --git a/backend/src/users/users.service.spec.ts b/backend/src/users/users.service.spec.ts deleted file mode 100644 index a6cae8e1..00000000 --- a/backend/src/users/users.service.spec.ts +++ /dev/null @@ -1,259 +0,0 @@ -import type { TestingModule } from "@nestjs/testing"; -import { Test } from "@nestjs/testing"; -import { UsersService } from "./users.service"; -import { PrismaService } from "nestjs-prisma"; -import { Prisma } from "@prisma/client"; - -describe("UserService", () => { - let service: UsersService; - let prisma: PrismaService; - - const savedUser1 = { - id: new Prisma.Decimal(1), - name: "Test Numone", - email: "numone@test.com" - }; - const savedUser2 = { - id: new Prisma.Decimal(2), - name: "Test Numtwo", - email: "numtwo@test.com" - }; - const oneUser = { - id: 1, - name: "Test Numone", - email: "numone@test.com" - }; - const updateUser = { - id: 1, - name: "Test Numone update", - email: "numoneupdate@test.com" - }; - const updatedUser = { - id: new Prisma.Decimal(1), - name: "Test Numone update", - email: "numoneupdate@test.com" - }; - - const twoUser = { - id: 2, - name: "Test Numtwo", - email: "numtwo@test.com" - }; - - const threeUser = { - id: 3, - name: "Test Numthree", - email: "numthree@test.com" - }; - - const userArray = [oneUser, twoUser]; - const savedUserArray = [savedUser1, savedUser2]; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [ - UsersService, - { - provide: PrismaService, - useValue: { - users: { - findMany: jest.fn().mockResolvedValue(savedUserArray), - findUnique: jest.fn().mockResolvedValue(savedUser1), - create: jest.fn().mockResolvedValue(savedUser1), - update: jest.fn().mockResolvedValue(updatedUser), - delete: jest.fn().mockResolvedValue(true), - count: jest.fn() - } - } - } - ] - }).compile(); - - service = module.get(UsersService); - prisma = module.get(PrismaService); - }); - - it("should be defined", () => { - expect(service).toBeDefined(); - }); - - describe("createOne", () => { - it("should successfully add a user", () => { - expect(service.create(oneUser)).resolves.toEqual(oneUser); - expect(prisma.users.create).toBeCalledTimes(1); - }); - }); - - describe("findAll", () => { - it("should return an array of users", async () => { - const users = await service.findAll(); - expect(users).toEqual(userArray); - }); - }); - - describe("findOne", () => { - it("should get a single user", () => { - expect(service.findOne(1)).resolves.toEqual(oneUser); - }); - }); - - describe("update", () => { - it("should call the update method", async () => { - const user = await service.update(1, updateUser); - expect(user).toEqual(updateUser); - expect(prisma.users.update).toBeCalledTimes(1); - }); - }); - - describe("remove", () => { - it("should return {deleted: true}", () => { - expect(service.remove(2)).resolves.toEqual({ deleted: true }); - }); - it("should return {deleted: false, message: err.message}", () => { - const repoSpy = jest - .spyOn(prisma.users, "delete") - .mockRejectedValueOnce(new Error("Bad Delete Method.")); - expect(service.remove(-1)).resolves.toEqual({ - deleted: false, - message: "Bad Delete Method." - }); - expect(repoSpy).toBeCalledTimes(1); - }); - }); - - describe("searchUsers", () => { - it("should return a list of users with pagination and filtering", async () => { - const page = 1; - const limit = 10; - const sortObject: Prisma.SortOrder = "asc"; - const sort: any = `[{ "name": "${sortObject}" }]`; - const filter: any = - "[{ \"name\": { \"equals\": \"Peter\" } }]"; - - jest.spyOn(prisma.users, "findMany") - .mockResolvedValue([]); - jest.spyOn(prisma.users, "count") - .mockResolvedValue(0); - const result = await service.searchUsers(page, limit, sort, filter); - - expect(result).toEqual({ - users: [], - page, - limit, - total: 0, - totalPages: 0 - }); - }); - - it("given no page should return a list of users with pagination and filtering with default page 1", async () => { - const limit = 10; - const sortObject: Prisma.SortOrder = "asc"; - const sort: any = `[{ "name": "${sortObject}" }]`; - const filter: any = - "[{ \"name\": { \"equals\": \"Peter\" } }]"; - - jest.spyOn(prisma.users, "findMany") - .mockResolvedValue([]); - jest.spyOn(prisma.users, "count") - .mockResolvedValue(0); - const result = await service.searchUsers(null, limit, sort, filter); - - expect(result).toEqual({ - users: [], - page: 1, - limit, - total: 0, - totalPages: 0 - }); - }); - it("given no limit should return a list of users with pagination and filtering with default limit 10", async () => { - const page = 1; - const sortObject: Prisma.SortOrder = "asc"; - const sort: any = `[{ "name": "${sortObject}" }]`; - const filter: any = - "[{ \"name\": { \"equals\": \"Peter\" } }]"; - - jest.spyOn(prisma.users, "findMany") - .mockResolvedValue([]); - jest.spyOn(prisma.users, "count") - .mockResolvedValue(0); - const result = await service.searchUsers(page, null, sort, filter); - - expect(result).toEqual({ - users: [], - page: 1, - limit: 10, - total: 0, - totalPages: 0 - }); - }); - - it("given limit greater than 200 should return a list of users with pagination and filtering with default limit 10", async () => { - const page = 1; - const limit = 201; - const sortObject: Prisma.SortOrder = "asc"; - const sort: any = `[{ "name": "${sortObject}" }]`; - const filter: any = - "[{ \"name\": { \"equals\": \"Peter\" } }]"; - - jest.spyOn(prisma.users, "findMany") - .mockResolvedValue([]); - jest.spyOn(prisma.users, "count") - .mockResolvedValue(0); - const result = await service.searchUsers(page, limit, sort, filter); - - expect(result).toEqual({ - users: [], - page: 1, - limit: 10, - total: 0, - totalPages: 0 - }); - }); - it("given invalid JSON should throw error", async () => { - const page = 1; - const limit = 201; - const sortObject: Prisma.SortOrder = "asc"; - const sort: any = `[{ "name" "${sortObject}" }]`; - const filter: any = - "[{ \"name\": { \"equals\": \"Peter\" } }]"; - try { - await service.searchUsers(page, limit, sort, filter); - } catch (e) { - expect(e).toEqual(new Error("Invalid query parameters")); - } - }); - }); - describe("convertFiltersToPrismaFormat", () => { - it("should convert input filters to prisma's filter format", () => { - const inputFilter = [ - { key: 'a', operation: 'like', value: '1' }, - { key: 'b', operation: 'eq', value: '2' }, - { key: 'c', operation: 'neq', value: '3' }, - { key: 'd', operation: 'gt', value: '4' }, - { key: 'e', operation: 'gte', value: '5' }, - { key: 'f', operation: 'lt', value: '6' }, - { key: 'g', operation: 'lte', value: '7' }, - { key: 'h', operation: 'in', value: ['8'] }, - { key: 'i', operation: 'notin', value: ['9'] }, - { key: 'j', operation: 'isnull', value: '10' } - ]; - - const expectedOutput = { - 'a': { contains: '1' }, - 'b': { equals: '2' }, - 'c': { not: { equals: '3' } }, - 'd': { gt: '4' }, - 'e': { gte: '5' }, - 'f': { lt: '6' }, - 'g': { lte: '7' }, - 'h': { in: ['8'] }, - 'i': { not: { in: ['9'] } }, - 'j': { equals: null } - }; - - expect(service.convertFiltersToPrismaFormat(inputFilter)) - .toStrictEqual(expectedOutput); - }); - }); -}); diff --git a/backend/src/users/users.service.ts b/backend/src/users/users.service.ts deleted file mode 100644 index e04d825b..00000000 --- a/backend/src/users/users.service.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { Injectable } from "@nestjs/common"; -import { PrismaService } from "nestjs-prisma"; - -import { CreateUserDto } from "./dto/create-user.dto"; -import { UpdateUserDto } from "./dto/update-user.dto"; -import { UserDto } from "./dto/user.dto"; -import { Prisma } from "@prisma/client"; - -@Injectable() -export class UsersService { - constructor( - private prisma: PrismaService - ) { - } - - async create(user: CreateUserDto): Promise { - const savedUser = await this.prisma.users.create({ - data: { - name: user.name, - email: user.email - } - }); - - return { - id: savedUser.id.toNumber(), - name: savedUser.name, - email: savedUser.email - }; - } - - async findAll(): Promise { - const users = await this.prisma.users.findMany(); - return users.flatMap(user => { - const userDto: UserDto = { - id: user.id.toNumber(), - name: user.name, - email: user.email - }; - return userDto; - }); - } - - async findOne(id: number): Promise { - const user = await this.prisma.users.findUnique({ - where: { - id: new Prisma.Decimal(id) - } - }); - return { - id: user.id.toNumber(), - name: user.name, - email: user.email - }; - } - - async update(id: number, updateUserDto: UpdateUserDto): Promise { - const user = await this.prisma.users.update({ - where: { - id: new Prisma.Decimal(id) - }, - data: { - name: updateUserDto.name, - email: updateUserDto.email - } - }); - return { - id: user.id.toNumber(), - name: user.name, - email: user.email - }; - } - - async remove(id: number): Promise<{ deleted: boolean; message?: string }> { - try { - await this.prisma.users.delete({ - where: { - id: new Prisma.Decimal(id) - } - }); - return { deleted: true }; - } catch (err) { - return { deleted: false, message: err.message }; - } - } - - async searchUsers(page: number, - limit: number, - sort: string, // JSON string to store sort key and sort value, ex: [{"name":"desc"},{"email":"asc"}] - filter: string // JSON array for key, operation and value, ex: [{"key": "name", "operation": "like", "value": "Jo"}] - ): Promise { - - page = page || 1; - if (!limit || limit > 200) { - limit = 10; - } - - let sortObj=[]; - let filterObj = {}; - try { - sortObj = JSON.parse(sort); - filterObj = JSON.parse(filter); - } catch (e) { - throw new Error("Invalid query parameters"); - } - const users = await this.prisma.users.findMany({ - skip: (page - 1) * limit, - take: parseInt(String(limit)), - orderBy: sortObj, - where: this.convertFiltersToPrismaFormat(filterObj) - }); - - const count = await this.prisma.users.count({ - orderBy: sortObj, - where: this.convertFiltersToPrismaFormat(filterObj) - }); - - return { - users, - page, - limit, - total: count, - totalPages: Math.ceil(count / limit) - }; - } - - public convertFiltersToPrismaFormat(filterObj): any { - - let prismaFilterObj = {}; - - for (const item of filterObj) { - - if (item.operation === "like") { - prismaFilterObj[item.key] = { contains: item.value }; - } else if (item.operation === "eq") { - prismaFilterObj[item.key] = { equals: item.value }; - } else if (item.operation === "neq") { - prismaFilterObj[item.key] = { not: { equals: item.value } }; - } else if (item.operation === "gt") { - prismaFilterObj[item.key] = { gt: item.value }; - } else if (item.operation === "gte") { - prismaFilterObj[item.key] = { gte: item.value }; - } else if (item.operation === "lt") { - prismaFilterObj[item.key] = { lt: item.value }; - } else if (item.operation === "lte") { - prismaFilterObj[item.key] = { lte: item.value }; - } else if (item.operation === "in") { - prismaFilterObj[item.key] = { in: item.value }; - } else if (item.operation === "notin") { - prismaFilterObj[item.key] = { not: { in: item.value } }; - } else if (item.operation === "isnull") { - prismaFilterObj[item.key] = { equals: null }; - } - } - return prismaFilterObj; - } -} diff --git a/frontend/src/components/Dashboard.tsx b/frontend/src/components/Dashboard.tsx index 3b664e28..d4636911 100644 --- a/frontend/src/components/Dashboard.tsx +++ b/frontend/src/components/Dashboard.tsx @@ -41,7 +41,7 @@ export default function Dashboard() { useEffect(() => { apiService .getAxiosInstance() - .post('/v1/dryrun') + .get('/v1/dryrun') .then((response: AxiosResponse) => { console.log(response) }) diff --git a/migrations/sql/V1.0.0__submission_status_code.sql b/migrations/sql/V1.0.0__submission_status_code.sql index b627807b..73924bbc 100644 --- a/migrations/sql/V1.0.0__submission_status_code.sql +++ b/migrations/sql/V1.0.0__submission_status_code.sql @@ -29,7 +29,7 @@ values ( (now() at time zone 'utc'), 'VMANAWAT', (now() at time zone 'utc') - ), + ), ( 'INPROGRESS', 'In Progress', @@ -59,5 +59,4 @@ values ( (now() at time zone 'utc'), 'VMANAWAT', (now() at time zone 'utc') - ); - \ No newline at end of file + ); \ No newline at end of file diff --git a/migrations/sql/V1.0.1__file_submission.sql b/migrations/sql/V1.0.1__file_submission.sql index 1a50b115..b8a691ce 100644 --- a/migrations/sql/V1.0.1__file_submission.sql +++ b/migrations/sql/V1.0.1__file_submission.sql @@ -1,20 +1,50 @@ CREATE TABLE IF NOT EXISTS enmods.file_submissions ( - submission_id UUID PRIMARY KEY NOT NULL DEFAULT gen_random_uuid(), - file_name varchar(200) NOT NULL, - submission_date timestamp NOT NULL, - submitter_user_id varchar(200) NOT NULL, - submission_status_code varchar(10) NOT NULL, - submitter_agency_name varchar(200) NOT NULL, - sample_count int4 NULL, - results_count int4 NULL, - active_ind boolean NOT NULL DEFAULT true, - error_log text NULL, - organization_guid UUID NULL, - create_user_id varchar(200) NOT NULL, - create_utc_timestamp timestamp NOT NULL, - update_user_id varchar(200) NOT NULL, - update_utc_timestamp timestamp NOT NULL, - CONSTRAINT submission_status_code_fk - FOREIGN KEY(submission_status_code) - REFERENCES enmods.submission_status_code(submission_status_code) -); \ No newline at end of file + submission_id UUID PRIMARY KEY NOT NULL DEFAULT gen_random_uuid(), + file_name varchar(200) NOT NULL, + submission_date timestamp NOT NULL, + submitter_user_id varchar(200) NOT NULL, + submission_status_code varchar(10) NOT NULL, + submitter_agency_name varchar(200) NOT NULL, + sample_count int4 NULL, + results_count int4 NULL, + active_ind boolean NOT NULL DEFAULT true, + error_log text NULL, + organization_guid UUID NULL, + create_user_id varchar(200) NOT NULL, + create_utc_timestamp timestamp NOT NULL, + update_user_id varchar(200) NOT NULL, + update_utc_timestamp timestamp NOT NULL, + CONSTRAINT submission_status_code_fk FOREIGN KEY(submission_status_code) REFERENCES enmods.submission_status_code(submission_status_code) +); +INSERT INTO enmods.file_submissions ( + file_name, + submission_date, + submitter_user_id, + submission_status_code, + submitter_agency_name, + sample_count, + results_count, + active_ind, + error_log, + organization_guid, + create_user_id, + create_utc_timestamp, + update_user_id, + update_utc_timestamp + ) +VALUES ( + 'testFile1', + (now() at time zone 'utc'), + 'VMANAWAT', + 'SUBMITTED', + 'MANAWAT CORP', + 12, + 50, + true, + 'THIS IS TEST ERROR LOG', + gen_random_uuid(), + 'VMANAWAT', + (now() at time zone 'utc'), + 'VMANAWAT', + (now() at time zone 'utc') + ); \ No newline at end of file