Skip to content

Commit 3c27279

Browse files
authored
Merge pull request #1194 from Northeastern-Electric-Racing/#1169-Make-Links-a-Model
#1169 make links a model
2 parents 5c5fa67 + b16b8e3 commit 3c27279

42 files changed

Lines changed: 1080 additions & 688 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.prettierignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
.env.development.local
2525
.env.test.local
2626
.env.production.local
27+
index.html
2728

2829
npm-debug.log*
2930
yarn-debug.log*

src/backend/src/controllers/projects.controllers.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,7 @@ export default class ProjectsController {
5252
goals,
5353
features,
5454
otherConstraints,
55-
googleDriveFolderLink,
56-
slideDeckLink,
57-
bomLink,
58-
taskListLink,
55+
links,
5956
projectLeadId,
6057
projectManagerId
6158
} = req.body;
@@ -71,10 +68,7 @@ export default class ProjectsController {
7168
goals,
7269
features,
7370
otherConstraints,
74-
googleDriveFolderLink,
75-
slideDeckLink,
76-
bomLink,
77-
taskListLink,
71+
links,
7872
projectLeadId || null,
7973
projectManagerId || null
8074
);
@@ -122,4 +116,13 @@ export default class ProjectsController {
122116
next(error);
123117
}
124118
}
119+
120+
static async getAllLinkTypes(_req: Request, res: Response, next: NextFunction) {
121+
try {
122+
const linkTypes = await ProjectsService.getAllLinkTypes();
123+
res.status(200).json(linkTypes);
124+
} catch (error: unknown) {
125+
next(error);
126+
}
127+
}
125128
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { Prisma } from '@prisma/client';
2+
3+
const linkTypeQueryArgs = Prisma.validator<Prisma.LinkTypeArgs>()({
4+
include: { creator: true }
5+
});
6+
7+
export default linkTypeQueryArgs;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { Prisma } from '@prisma/client';
2+
import linkTypeQueryArgs from './link-types.query-args';
3+
4+
const linkQueryArgs = Prisma.validator<Prisma.LinkArgs>()({
5+
include: { linkType: { ...linkTypeQueryArgs }, creator: true }
6+
});
7+
8+
export default linkQueryArgs;

src/backend/src/prisma-query-args/projects.query-args.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Prisma } from '@prisma/client';
22
import taskQueryArgs from './tasks.query-args';
3+
import linkQueryArgs from './links.query-args';
34

45
const projectQueryArgs = Prisma.validator<Prisma.ProjectArgs>()({
56
include: {
@@ -8,6 +9,7 @@ const projectQueryArgs = Prisma.validator<Prisma.ProjectArgs>()({
89
projectLead: true,
910
projectManager: true,
1011
tasks: { where: { dateDeleted: null }, ...taskQueryArgs },
12+
links: { ...linkQueryArgs },
1113
changes: { where: { changeRequest: { dateDeleted: null } }, include: { implementer: true } }
1214
}
1315
},
@@ -26,6 +28,7 @@ const projectQueryArgs = Prisma.validator<Prisma.ProjectArgs>()({
2628
include: {
2729
projectLead: true,
2830
projectManager: true,
31+
links: { ...linkQueryArgs },
2932
changes: { where: { changeRequest: { dateDeleted: null } }, include: { implementer: true } }
3033
}
3134
},
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
2+
-- CreateTable
3+
CREATE TABLE "LinkType" (
4+
"name" TEXT NOT NULL,
5+
"dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
6+
"creatorId" INTEGER NOT NULL,
7+
"iconName" TEXT NOT NULL,
8+
"required" BOOLEAN NOT NULL,
9+
10+
CONSTRAINT "LinkType_pkey" PRIMARY KEY ("name")
11+
);
12+
13+
-- CreateTable
14+
CREATE TABLE "Link" (
15+
"linkId" TEXT NOT NULL,
16+
"url" TEXT NOT NULL,
17+
"creatorId" INTEGER NOT NULL,
18+
"dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
19+
"dateDeleted" TIMESTAMP(3),
20+
"linkTypeName" TEXT NOT NULL,
21+
"wbsElementId" INTEGER NOT NULL,
22+
23+
CONSTRAINT "Link_pkey" PRIMARY KEY ("linkId")
24+
);
25+
26+
-- CreateIndex
27+
CREATE UNIQUE INDEX "LinkType_name_key" ON "LinkType"("name");
28+
29+
-- AddForeignKey
30+
ALTER TABLE "LinkType" ADD CONSTRAINT "LinkType_creatorId_fkey" FOREIGN KEY ("creatorId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE;
31+
32+
-- AddForeignKey
33+
ALTER TABLE "Link" ADD CONSTRAINT "Link_creatorId_fkey" FOREIGN KEY ("creatorId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE;
34+
35+
-- AddForeignKey
36+
ALTER TABLE "Link" ADD CONSTRAINT "Link_linkTypeName_fkey" FOREIGN KEY ("linkTypeName") REFERENCES "LinkType"("name") ON DELETE RESTRICT ON UPDATE CASCADE;
37+
38+
-- AddForeignKey
39+
ALTER TABLE "Link" ADD CONSTRAINT "Link_wbsElementId_fkey" FOREIGN KEY ("wbsElementId") REFERENCES "WBS_Element"("wbsElementId") ON DELETE RESTRICT ON UPDATE CASCADE;
40+
41+
/*
42+
Adds a no-op user to the database
43+
*/
44+
-- Insert
45+
INSERT INTO "User" ("userId", "firstName", "lastName", "googleAuthId", "email") VALUES (0, 'Admin', 'User', 'admin', 'admin@gmail.com');
46+
47+
/*
48+
Adds Confluence, Google Drive and BOM Link Types to the database
49+
*/
50+
-- Insert
51+
INSERT INTO "LinkType" ("name", "creatorId", "required", "iconName") VALUES ('Confluence', 0, 'true', 'description');
52+
INSERT INTO "LinkType" ("name", "creatorId", "required", "iconName") VALUES ('Google Drive', 0, 'true', 'folder');
53+
INSERT INTO "LinkType" ("name", "creatorId", "required", "iconName") VALUES ('Bill of Materials', 0, 'true', 'attach_money');
54+
55+
/*
56+
Transfer over all the slide deck links to conflunce links
57+
*/
58+
-- Insert
59+
INSERT INTO "Link" ("linkId", "url", "creatorId", "linkTypeName", "wbsElementId") SELECT gen_random_uuid(), "slideDeckLink", 0, 'Confluence', "wbsElementId" FROM "Project" WHERE "slideDeckLink" IS NOT NULL;
60+
/*
61+
Transfer over all the Google Drive Folder links to Google Drive links
62+
*/
63+
-- Insert
64+
INSERT INTO "Link" ("linkId", "url", "creatorId", "linkTypeName", "wbsElementId") SELECT gen_random_uuid(),"googleDriveFolderLink", 0, 'Google Drive', "wbsElementId" FROM "Project" WHERE "googleDriveFolderLink" IS NOT NULL;
65+
/*
66+
Transfer over all the BOM links to BOM links
67+
*/
68+
-- Insert
69+
INSERT INTO "Link" ("linkId", "url", "creatorId", "linkTypeName", "wbsElementId") SELECT gen_random_uuid(), "bomLink", 0, 'Bill of Materials', "wbsElementId" FROM "Project" WHERE "bomLink" IS NOT NULL;
70+
71+
/*
72+
Warnings:
73+
- You are about to drop the column `bomLink` on the `Project` table. All the data in the column will be lost.
74+
- You are about to drop the column `googleDriveFolderLink` on the `Project` table. All the data in the column will be lost.
75+
- You are about to drop the column `slideDeckLink` on the `Project` table. All the data in the column will be lost.
76+
- You are about to drop the column `taskListLink` on the `Project` table. All the data in the column will be lost.
77+
*/
78+
-- AlterTable
79+
ALTER TABLE "Project" DROP COLUMN "bomLink",
80+
DROP COLUMN "googleDriveFolderLink",
81+
DROP COLUMN "slideDeckLink",
82+
DROP COLUMN "taskListLink";

src/backend/src/prisma/schema.prisma

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ model User {
106106
reimbursementStatuses Reimbursement_Status[]
107107
reimbursements Reimbursement[] @relation(name: "purchaser")
108108
submittedReimbursements Reimbursement[] @relation(name: "submitter")
109+
createdLinks Link[] @relation(name: "linkCreator")
110+
createdLinkTypes LinkType[] @relation(name: "linkTypeCreator")
109111
deletedReceipts Receipt[] @relation(name: "deletedReceipts")
110112
createdReceipts Receipt[] @relation(name: "receiptsCreatedBy")
111113
}
@@ -249,28 +251,25 @@ model WBS_Element {
249251
blocking Work_Package[] @relation("blockedBy")
250252
tasks Task[]
251253
reimbursementProducts Reimbursement_Product[]
254+
links Link[] @relation(name: "links")
252255
253256
@@unique([carNumber, projectNumber, workPackageNumber], name: "wbsNumber")
254257
}
255258

256259
model Project {
257-
projectId Int @id @default(autoincrement())
258-
wbsElementId Int @unique
259-
wbsElement WBS_Element @relation(fields: [wbsElementId], references: [wbsElementId])
260-
budget Int @default(0)
261-
summary String
262-
googleDriveFolderLink String?
263-
slideDeckLink String?
264-
bomLink String?
265-
taskListLink String?
266-
rules String[]
267-
goals Description_Bullet[] @relation(name: "projectGoals")
268-
features Description_Bullet[] @relation(name: "projectFeatures")
269-
otherConstraints Description_Bullet[] @relation(name: "projectOtherConstraints")
270-
workPackages Work_Package[]
271-
teamId String?
272-
team Team? @relation(fields: [teamId], references: [teamId])
273-
favoritedBy User[] @relation(name: "favoritedBy")
260+
projectId Int @id @default(autoincrement())
261+
wbsElementId Int @unique
262+
wbsElement WBS_Element @relation(fields: [wbsElementId], references: [wbsElementId])
263+
budget Int @default(0)
264+
summary String
265+
rules String[]
266+
goals Description_Bullet[] @relation(name: "projectGoals")
267+
features Description_Bullet[] @relation(name: "projectFeatures")
268+
otherConstraints Description_Bullet[] @relation(name: "projectOtherConstraints")
269+
workPackages Work_Package[]
270+
teamId String?
271+
team Team? @relation(fields: [teamId], references: [teamId])
272+
favoritedBy User[] @relation(name: "favoritedBy")
274273
}
275274

276275
model Work_Package {
@@ -288,6 +287,29 @@ model Work_Package {
288287
stage Work_Package_Stage?
289288
}
290289

290+
model LinkType {
291+
name String @id @unique
292+
dateCreated DateTime @default(now())
293+
creatorId Int
294+
iconName String
295+
required Boolean
296+
creator User @relation(name: "linkTypeCreator", fields: [creatorId], references: [userId])
297+
links Link[] @relation(name: "linkTypes")
298+
}
299+
300+
model Link {
301+
linkId String @id @default(uuid())
302+
url String
303+
creatorId Int
304+
creator User @relation(name: "linkCreator", fields: [creatorId], references: [userId])
305+
dateCreated DateTime @default(now())
306+
dateDeleted DateTime?
307+
linkTypeName String
308+
linkType LinkType @relation(name: "linkTypes", fields: [linkTypeName], references: [name])
309+
wbsElementId Int
310+
wbsElment WBS_Element @relation(name: "links", fields: [wbsElementId], references: [wbsElementId])
311+
}
312+
291313
model Description_Bullet {
292314
descriptionId Int @id @default(autoincrement())
293315
dateAdded DateTime @default(now())

src/backend/src/prisma/seed-data/projects.seed.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*/
55

66
import { User } from '@prisma/client';
7-
import { WbsNumber } from 'shared';
7+
import { LinkCreateArgs, WbsNumber } from 'shared';
88
import projectQueryArgs from '../../prisma-query-args/projects.query-args';
99
import ProjectsService from '../../services/projects.services';
1010
import prisma from '../prisma';
@@ -27,10 +27,7 @@ export const seedProject = async (
2727
goals: string[],
2828
features: string[],
2929
otherConstraints: string[],
30-
googleDriveFolderLink: string,
31-
slideDeckLink: string,
32-
bomLink: string,
33-
taskListLink: string,
30+
links: LinkCreateArgs[],
3431
projectLeadId: number | null,
3532
projectManagerId: number | null
3633
): Promise<{ projectWbsNumber: WbsNumber; projectId: number }> => {
@@ -64,10 +61,7 @@ export const seedProject = async (
6461
otherConstraints.map((element) => {
6562
return { id: -1, detail: element };
6663
}),
67-
googleDriveFolderLink,
68-
slideDeckLink,
69-
bomLink,
70-
taskListLink,
64+
links,
7165
projectLeadId,
7266
projectManagerId
7367
);

src/backend/src/prisma/seed-data/work-packages.seed.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import { validateWBS, WbsElementStatus, WbsNumber } from 'shared';
88
import { WorkPackageStage } from 'shared';
99
import workPackageQueryArgs from '../../prisma-query-args/work-packages.query-args';
1010
import WorkPackagesService from '../../services/work-packages.services';
11-
import { descBulletConverter } from '../../utils/utils';
1211
import prisma from '../prisma';
12+
import { descBulletConverter } from '../../utils/description-bullets.utils';
1313

1414
/**
1515
* Creates a work package with the given data using service functions. This has to be done by:

0 commit comments

Comments
 (0)