Skip to content

Commit

Permalink
Merge pull request #522 from Northeastern-Electric-Racing/#487-refact…
Browse files Browse the repository at this point in the history
…oring-desc-bullets

#487: put changes on new branch
  • Loading branch information
anthonybernardi authored Jan 9, 2023
2 parents 46b93f9 + 0fa2495 commit f8b203d
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 86 deletions.
76 changes: 14 additions & 62 deletions src/backend/src/controllers/description-bullets.controllers.ts
Original file line number Diff line number Diff line change
@@ -1,64 +1,16 @@
import { WBS_Element_Status } from '@prisma/client';
import { Request, Response } from 'express';
import prisma from '../prisma/prisma';
import { hasBulletCheckingPermissions } from '../utils/description-bullets.utils';

export const checkDescriptionBullet = async (req: Request, res: Response) => {
const { body } = req;
const { userId, descriptionId } = body;

const originalDB = await prisma.description_Bullet.findUnique({
where: { descriptionId },
include: {
workPackageDeliverables: { include: { wbsElement: true } },
workPackageExpectedActivities: { include: { wbsElement: true } }
import { NextFunction, Request, Response } from 'express';
import DescriptionBulletsService from '../services/description-bullets.services';
import { getCurrentUser } from '../utils/utils';

export default class DescriptionBulletsController {
static async checkDescriptionBullet(req: Request, res: Response, next: NextFunction) {
try {
const { descriptionId } = req.body;
const user = await getCurrentUser(res);
const updatedDB = await DescriptionBulletsService.checkDescriptionBullet(user, descriptionId);
res.status(200).json(updatedDB);
} catch (error: unknown) {
next(error);
}
});

if (!originalDB) {
return res.status(404).json({ message: `Description Bullet with id ${descriptionId} not found` });
}

if (originalDB.dateDeleted) {
return res.status(400).json({ message: 'Cant edit a deleted Description Bullet' });
}

const workPackage = originalDB.workPackageDeliverables || originalDB.workPackageExpectedActivities;
if (!workPackage) {
return res.status(400).json({
message: 'This description bullet is not tied to a workpackage deliverable or expected activity!'
});
}

if (workPackage.wbsElement.status !== WBS_Element_Status.ACTIVE) {
return res.status(400).json({ message: 'Cannot check a description bullet on an inactive work package!' });
}

const hasPerms = await hasBulletCheckingPermissions(userId, descriptionId);

if (!hasPerms) {
return res.status(403).json({ message: 'Access Denied' });
}

let updatedDB;

if (originalDB.userCheckedId) {
updatedDB = await prisma.description_Bullet.update({
where: { descriptionId },
data: {
userCheckedId: null,
dateTimeChecked: null
}
});
} else {
updatedDB = await prisma.description_Bullet.update({
where: { descriptionId },
data: {
userCheckedId: userId,
dateTimeChecked: new Date()
}
});
}

return res.status(200).json(updatedDB);
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Prisma } from '@prisma/client';

const descriptionBulletQueryArgs = Prisma.validator<Prisma.Description_BulletArgs>()({
include: { userChecked: true }
});

export default descriptionBulletQueryArgs;
6 changes: 3 additions & 3 deletions src/backend/src/prisma-query-args/work-packages.query-args.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Prisma } from '@prisma/client';
import { descBulletArgs } from '../utils/description-bullets.utils';
import descriptionBulletQueryArgs from '../prisma-query-args/description-bullets.query-args';

const workPackageQueryArgs = Prisma.validator<Prisma.Work_PackageArgs>()({
include: {
Expand All @@ -15,8 +15,8 @@ const workPackageQueryArgs = Prisma.validator<Prisma.Work_PackageArgs>()({
changes: { include: { implementer: true }, orderBy: { dateImplemented: 'asc' } }
}
},
expectedActivities: { where: { dateDeleted: null }, ...descBulletArgs },
deliverables: { where: { dateDeleted: null }, ...descBulletArgs },
expectedActivities: { where: { dateDeleted: null }, ...descriptionBulletQueryArgs },
deliverables: { where: { dateDeleted: null }, ...descriptionBulletQueryArgs },
dependencies: { where: { dateDeleted: null } }
}
});
Expand Down
5 changes: 2 additions & 3 deletions src/backend/src/routes/description-bullets.routes.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import express from 'express';
import { body } from 'express-validator';
import { checkDescriptionBullet } from '../controllers/description-bullets.controllers';
import DescriptionBulletsController from '../controllers/description-bullets.controllers';
import { validateInputs } from '../utils/utils';

const descriptionBulletsRouter = express.Router();

descriptionBulletsRouter.post(
'/check',
body('userId').isInt({ min: 0 }).not().isString(),
body('descriptionId').isInt({ min: 0 }).not().isString(),
validateInputs,
checkDescriptionBullet
DescriptionBulletsController.checkDescriptionBullet
);

export default descriptionBulletsRouter;
65 changes: 65 additions & 0 deletions src/backend/src/services/description-bullets.services.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { User, WBS_Element_Status } from '@prisma/client';
import prisma from '../prisma/prisma';
import { hasBulletCheckingPermissions } from '../utils/description-bullets.utils';
import { AccessDeniedException, HttpException, NotFoundException } from '../utils/errors.utils';
import descriptionBulletTransformer from '../transformers/description-bullets.transformer';
import descriptionBulletQueryArgs from '../prisma-query-args/description-bullets.query-args';
import { DescriptionBullet } from 'shared';

export default class DescriptionBulletsService {
/**
* Checks the description bullet
* @param user user that checks the description bullet
* @param descriptionId description of bullet that is being checked
* @throws if bullet doesn't exist or if the bullet is not linked to anything valid
* @returns a checked description bullet
*/
static async checkDescriptionBullet(user: User, descriptionId: number): Promise<DescriptionBullet> {
const originalDB = await prisma.description_Bullet.findUnique({
where: { descriptionId },
include: {
workPackageDeliverables: { include: { wbsElement: true } },
workPackageExpectedActivities: { include: { wbsElement: true } }
}
});
if (!originalDB) throw new NotFoundException('Description Bullet', descriptionId);

if (originalDB.dateDeleted) throw new HttpException(400, 'Cant edit a deleted Description Bullet!');

const workPackage = originalDB.workPackageDeliverables || originalDB.workPackageExpectedActivities;

if (!workPackage)
throw new HttpException(400, 'This description bullet is not tied to a workpackage deliverable or expected activity');

if (workPackage.wbsElement.status !== WBS_Element_Status.ACTIVE)
throw new HttpException(400, 'Cannot check a description bullet on an inactive work package!');

const hasPerms = await hasBulletCheckingPermissions(user.userId, descriptionId);

if (!hasPerms) throw new AccessDeniedException();

let updatedDB;

if (originalDB.userCheckedId) {
updatedDB = await prisma.description_Bullet.update({
where: { descriptionId },
data: {
userCheckedId: null,
dateTimeChecked: null
},
...descriptionBulletQueryArgs
});
} else {
updatedDB = await prisma.description_Bullet.update({
where: { descriptionId },
data: {
userCheckedId: user.userId,
dateTimeChecked: new Date()
},
...descriptionBulletQueryArgs
});
}

return descriptionBulletTransformer(updatedDB);
}
}
17 changes: 17 additions & 0 deletions src/backend/src/transformers/description-bullets.transformer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Prisma } from '@prisma/client';
import { DescriptionBullet } from 'shared';
import descriptionBulletQueryArgs from '../prisma-query-args/description-bullets.query-args';

const descriptionBulletTransformer = (
descBullet: Prisma.Description_BulletGetPayload<typeof descriptionBulletQueryArgs>
): DescriptionBullet => {
return {
id: descBullet.descriptionId,
detail: descBullet.detail,
dateAdded: descBullet.dateAdded,
dateDeleted: descBullet.dateDeleted ?? undefined,
userChecked: descBullet.userChecked ?? undefined
};
};

export default descriptionBulletTransformer;
6 changes: 3 additions & 3 deletions src/backend/src/transformers/work-packages.transformer.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Prisma } from '@prisma/client';
import { calculateEndDate, calculatePercentExpectedProgress, calculateTimelineStatus, WorkPackage } from 'shared';
import workPackageQueryArgs from '../prisma-query-args/work-packages.query-args';
import { descBulletTransformer } from '../utils/description-bullets.utils';
import descriptionBulletTransformer from '../transformers/description-bullets.transformer';
import { userTransformer } from '../utils/users.utils';
import { convertStatus, wbsNumOf } from '../utils/utils';
import { calculateWorkPackageProgress } from '../utils/work-packages.utils';
Expand All @@ -18,8 +18,8 @@ const workPackageTransformer = (wpInput: Prisma.Work_PackageGetPayload<typeof wo
progress,
startDate: wpInput.startDate,
duration: wpInput.duration,
expectedActivities: wpInput.expectedActivities.map(descBulletTransformer),
deliverables: wpInput.deliverables.map(descBulletTransformer),
expectedActivities: wpInput.expectedActivities.map(descriptionBulletTransformer),
deliverables: wpInput.deliverables.map(descriptionBulletTransformer),
dependencies: wpInput.dependencies.map(wbsNumOf),
projectManager: wpInput.wbsElement.projectManager ? userTransformer(wpInput.wbsElement.projectManager) : undefined,
projectLead: wpInput.wbsElement.projectLead ? userTransformer(wpInput.wbsElement.projectLead) : undefined,
Expand Down
16 changes: 1 addition & 15 deletions src/backend/src/utils/description-bullets.utils.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,5 @@
import prisma from '../prisma/prisma';
import { Prisma, Role } from '@prisma/client';

export const descBulletArgs = Prisma.validator<Prisma.Description_BulletArgs>()({
include: { userChecked: true }
});

export const descBulletTransformer = (descBullet: Prisma.Description_BulletGetPayload<typeof descBulletArgs>) => {
return {
id: descBullet.descriptionId,
detail: descBullet.detail,
dateAdded: descBullet.dateAdded,
dateDeleted: descBullet.dateDeleted ?? undefined,
userChecked: descBullet.userChecked ?? undefined
};
};
import { Role } from '@prisma/client';

export const hasBulletCheckingPermissions = async (userId: number, descriptionId: number) => {
const user = await prisma.user.findUnique({ where: { userId } });
Expand Down

0 comments on commit f8b203d

Please sign in to comment.