Skip to content

Commit

Permalink
feat: add Subrecipient and Project to the schema
Browse files Browse the repository at this point in the history
  • Loading branch information
dysmento committed Dec 9, 2023
1 parent b327df6 commit f2db323
Show file tree
Hide file tree
Showing 12 changed files with 1,513 additions and 544 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
-- CreateTable
CREATE TABLE "Subrecipient" (
"id" SERIAL NOT NULL,
"name" TEXT NOT NULL,
"organizationId" INTEGER NOT NULL,
"startDate" DATE NOT NULL,
"endDate" DATE NOT NULL,
"certifiedAt" TIMESTAMPTZ(6),
"certifiedById" INTEGER,
"originationUploadId" INTEGER NOT NULL,
"createdAt" TIMESTAMPTZ(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMPTZ(6) NOT NULL,

CONSTRAINT "Subrecipient_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "Project" (
"id" SERIAL NOT NULL,
"code" TEXT NOT NULL,
"name" TEXT NOT NULL,
"agencyId" INTEGER NOT NULL,
"organizationId" INTEGER NOT NULL,
"status" TEXT NOT NULL,
"description" TEXT NOT NULL,
"originationPeriodId" INTEGER NOT NULL,
"createdAt" TIMESTAMPTZ(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMPTZ(6) NOT NULL,

CONSTRAINT "Project_pkey" PRIMARY KEY ("id")
);

-- AddForeignKey
ALTER TABLE "Subrecipient" ADD CONSTRAINT "Subrecipient_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "Subrecipient" ADD CONSTRAINT "Subrecipient_certifiedById_fkey" FOREIGN KEY ("certifiedById") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "Subrecipient" ADD CONSTRAINT "Subrecipient_originationUploadId_fkey" FOREIGN KEY ("originationUploadId") REFERENCES "Upload"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "Project" ADD CONSTRAINT "Project_agencyId_fkey" FOREIGN KEY ("agencyId") REFERENCES "Agency"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "Project" ADD CONSTRAINT "Project_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "Project" ADD CONSTRAINT "Project_originationPeriodId_fkey" FOREIGN KEY ("originationPeriodId") REFERENCES "ReportingPeriod"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
38 changes: 38 additions & 0 deletions api/db/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ model Agency {
users User[]
uploads Upload[]
uploadValidations UploadValidation[]
projects Project[]
}

model Organization {
Expand All @@ -28,6 +29,8 @@ model Organization {
name String
uploads Upload[]
uploadValidations UploadValidation[]
subrecipients Subrecipient[]
projects Project[]
}

model User {
Expand All @@ -46,6 +49,7 @@ model User {
uploaded Upload[]
validated UploadValidation[] @relation("ValidatedUploads")
invalidated UploadValidation[] @relation("InvalidatedUploads")
subrecipients Subrecipient[]
}

model Role {
Expand Down Expand Up @@ -95,6 +99,7 @@ model ReportingPeriod {
createdAt DateTime @default(now()) @db.Timestamptz(6)
updatedAt DateTime @db.Timestamptz(6)
uploads Upload[]
projects Project[]
}

model ExpenditureCategory {
Expand Down Expand Up @@ -122,6 +127,7 @@ model Upload {
createdAt DateTime @default(now()) @db.Timestamptz(6)
updatedAt DateTime @db.Timestamptz(6)
validations UploadValidation[]
subrecipients Subrecipient[]
}

model UploadValidation {
Expand All @@ -144,4 +150,36 @@ model UploadValidation {
invalidatedBy User? @relation("InvalidatedUploads", fields: [invalidatedById], references: [id])
createdAt DateTime @default(now()) @db.Timestamptz(6)
updatedAt DateTime @db.Timestamptz(6)
}

model Subrecipient {
id Int @id @default(autoincrement())
name String
organizationId Int
organization Organization @relation(fields: [organizationId], references: [id])
startDate DateTime @db.Date
endDate DateTime @db.Date
certifiedAt DateTime? @db.Timestamptz(6)
certifiedById Int?
certifiedBy User? @relation(fields: [certifiedById], references: [id])
originationUploadId Int
originationUpload Upload @relation(fields: [originationUploadId], references: [id])
createdAt DateTime @default(now()) @db.Timestamptz(6)
updatedAt DateTime @db.Timestamptz(6)
}

model Project {
id Int @id @default(autoincrement())
code String
name String
agencyId Int
agency Agency @relation(fields: [agencyId], references: [id])
organizationId Int
organization Organization @relation(fields: [organizationId], references: [id])
status String
description String
originationPeriodId Int
originationPeriod ReportingPeriod @relation(fields: [originationPeriodId], references: [id])
createdAt DateTime @default(now()) @db.Timestamptz(6)
updatedAt DateTime @db.Timestamptz(6)
}
48 changes: 48 additions & 0 deletions api/src/graphql/projects.sdl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
export const schema = gql`
type Project {
id: Int!
code: String!
name: String!
agencyId: Int!
agency: Agency!
organizationId: Int!
organization: Organization!
status: String!
description: String!
originationPeriodId: Int!
originationPeriod: ReportingPeriod!
createdAt: DateTime!
updatedAt: DateTime!
}
type Query {
projects: [Project!]! @requireAuth
project(id: Int!): Project @requireAuth
}
input CreateProjectInput {
code: String!
name: String!
agencyId: Int!
organizationId: Int!
status: String!
description: String!
originationPeriodId: Int!
}
input UpdateProjectInput {
code: String
name: String
agencyId: Int
organizationId: Int
status: String
description: String
originationPeriodId: Int
}
type Mutation {
createProject(input: CreateProjectInput!): Project! @requireAuth
updateProject(id: Int!, input: UpdateProjectInput!): Project! @requireAuth
deleteProject(id: Int!): Project! @requireAuth
}
`
52 changes: 52 additions & 0 deletions api/src/graphql/subrecipients.sdl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
export const schema = gql`
type Subrecipient {
id: Int!
name: String!
organizationId: Int!
organization: Organization!
startDate: DateTime!
endDate: DateTime!
certifiedAt: DateTime
certifiedById: Int
certifiedBy: User
originationUploadId: Int!
originationUpload: Upload!
createdAt: DateTime!
updatedAt: DateTime!
}
type Query {
subrecipients: [Subrecipient!]! @requireAuth
subrecipient(id: Int!): Subrecipient @requireAuth
}
input CreateSubrecipientInput {
name: String!
organizationId: Int!
startDate: DateTime!
endDate: DateTime!
certifiedAt: DateTime
certifiedById: Int
originationUploadId: Int!
}
input UpdateSubrecipientInput {
name: String
organizationId: Int
startDate: DateTime
endDate: DateTime
certifiedAt: DateTime
certifiedById: Int
originationUploadId: Int
}
type Mutation {
createSubrecipient(input: CreateSubrecipientInput!): Subrecipient!
@requireAuth
updateSubrecipient(
id: Int!
input: UpdateSubrecipientInput!
): Subrecipient! @requireAuth
deleteSubrecipient(id: Int!): Subrecipient! @requireAuth
}
`
79 changes: 79 additions & 0 deletions api/src/services/projects/projects.scenarios.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import type { Prisma, Project } from '@prisma/client'

Check failure on line 1 in api/src/services/projects/projects.scenarios.ts

View workflow job for this annotation

GitHub Actions / qa / Lint JavaScript

There should be at least one empty line between import groups
import type { ScenarioData } from '@redwoodjs/testing/api'

export const standard = defineScenario<Prisma.ProjectCreateArgs>({
project: {
one: {
data: {
code: 'String',
name: 'String',
status: 'String',
description: 'String',
updatedAt: '2023-12-09T14:50:29.322Z',
agency: { create: { name: 'String', code: 'String' } },
organization: { create: { name: 'String' } },
originationPeriod: {
create: {
name: 'String',
startDate: '2023-12-09T14:50:29.322Z',
endDate: '2023-12-09T14:50:29.322Z',
updatedAt: '2023-12-09T14:50:29.322Z',
inputTemplate: {
create: {
name: 'String',
version: 'String',
effectiveDate: '2023-12-09T14:50:29.322Z',
updatedAt: '2023-12-09T14:50:29.322Z',
},
},
outputTemplate: {
create: {
name: 'String',
version: 'String',
effectiveDate: '2023-12-09T14:50:29.322Z',
updatedAt: '2023-12-09T14:50:29.322Z',
},
},
},
},
},
},
two: {
data: {
code: 'String',
name: 'String',
status: 'String',
description: 'String',
updatedAt: '2023-12-09T14:50:29.322Z',
agency: { create: { name: 'String', code: 'String' } },
organization: { create: { name: 'String' } },
originationPeriod: {
create: {
name: 'String',
startDate: '2023-12-09T14:50:29.322Z',
endDate: '2023-12-09T14:50:29.322Z',
updatedAt: '2023-12-09T14:50:29.322Z',
inputTemplate: {
create: {
name: 'String',
version: 'String',
effectiveDate: '2023-12-09T14:50:29.322Z',
updatedAt: '2023-12-09T14:50:29.322Z',
},
},
outputTemplate: {
create: {
name: 'String',
version: 'String',
effectiveDate: '2023-12-09T14:50:29.322Z',
updatedAt: '2023-12-09T14:50:29.322Z',
},
},
},
},
},
},
},
})

export type StandardScenario = ScenarioData<Project, 'project'>
75 changes: 75 additions & 0 deletions api/src/services/projects/projects.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import type { Project } from '@prisma/client'

import {
projects,
project,
createProject,
updateProject,
deleteProject,
} from './projects'
import type { StandardScenario } from './projects.scenarios'

// Generated boilerplate tests do not account for all circumstances
// and can fail without adjustments, e.g. Float.
// Please refer to the RedwoodJS Testing Docs:
// https://redwoodjs.com/docs/testing#testing-services
// https://redwoodjs.com/docs/testing#jest-expect-type-considerations

describe('projects', () => {
scenario('returns all projects', async (scenario: StandardScenario) => {
const result = await projects()

expect(result.length).toEqual(Object.keys(scenario.project).length)
})

scenario('returns a single project', async (scenario: StandardScenario) => {
const result = await project({ id: scenario.project.one.id })

expect(result).toEqual(scenario.project.one)
})

scenario('creates a project', async (scenario: StandardScenario) => {
const result = await createProject({
input: {
code: 'String',
name: 'String',
agencyId: scenario.project.two.agencyId,
organizationId: scenario.project.two.organizationId,
status: 'String',
description: 'String',
originationPeriodId: scenario.project.two.originationPeriodId,
updatedAt: '2023-12-09T14:50:29.223Z',
},
})

expect(result.code).toEqual('String')
expect(result.name).toEqual('String')
expect(result.agencyId).toEqual(scenario.project.two.agencyId)
expect(result.organizationId).toEqual(scenario.project.two.organizationId)
expect(result.status).toEqual('String')
expect(result.description).toEqual('String')
expect(result.originationPeriodId).toEqual(
scenario.project.two.originationPeriodId
)
expect(result.updatedAt).toEqual(new Date('2023-12-09T14:50:29.223Z'))
})

scenario('updates a project', async (scenario: StandardScenario) => {
const original = (await project({ id: scenario.project.one.id })) as Project
const result = await updateProject({
id: original.id,
input: { code: 'String2' },
})

expect(result.code).toEqual('String2')
})

scenario('deletes a project', async (scenario: StandardScenario) => {
const original = (await deleteProject({
id: scenario.project.one.id,
})) as Project
const result = await project({ id: original.id })

expect(result).toEqual(null)
})
})
Loading

0 comments on commit f2db323

Please sign in to comment.