Skip to content
64 changes: 57 additions & 7 deletions src/backend/src/controllers/rules.controllers.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { NextFunction, Request, Response } from 'express';
import RulesService from '../services/rules.services.js';
import { ProjectRule, Rule, Ruleset } from 'shared';
import { ProjectRule, Rule, Ruleset, RuleStatus, RuleStatusHistoryEntry } from 'shared';
import { HttpException } from '../utils/errors.utils.js';

export default class RulesController {
Expand Down Expand Up @@ -179,20 +179,70 @@ export default class RulesController {
}
}

static async setRuleCompletion(req: Request, res: Response, next: NextFunction) {
static async setRuleStatus(req: Request, res: Response, next: NextFunction) {
try {
const { ruleId } = req.params as Record<string, string>;
const { isComplete, projectId } = req.body;
const { status } = req.body as { status: RuleStatus };

const rule: Rule = await RulesService.setRuleCompletion(
const rule: Rule = await RulesService.setRuleStatus(req.currentUser, req.organization, ruleId, status);

res.status(200).json(rule);
} catch (error: unknown) {
next(error);
}
}

static async setProjectRuleStatus(req: Request, res: Response, next: NextFunction) {
try {
const { projectRuleId } = req.params as Record<string, string>;
const { status } = req.body as { status: RuleStatus };

const projectRule: ProjectRule = await RulesService.setProjectRuleStatus(
req.currentUser,
req.organization,
projectRuleId,
status
);

res.status(200).json(projectRule);
} catch (error: unknown) {
next(error);
}
}

static async resetRulesetStatuses(req: Request, res: Response, next: NextFunction) {
try {
const { rulesetId } = req.params as Record<string, string>;
const count = await RulesService.resetRulesetStatuses(req.currentUser, req.organization, rulesetId);
res.status(200).json({ count });
} catch (error: unknown) {
next(error);
}
}

static async resetProjectRuleStatuses(req: Request, res: Response, next: NextFunction) {
try {
const { rulesetId, projectId } = req.params as Record<string, string>;
const count = await RulesService.resetProjectRuleStatuses(req.currentUser, req.organization, rulesetId, projectId);
res.status(200).json({ count });
} catch (error: unknown) {
next(error);
}
}

static async getRuleStatusHistory(req: Request, res: Response, next: NextFunction) {
try {
const { ruleId } = req.params as Record<string, string>;
const { projectRuleId } = req.query as { projectRuleId?: string };

const history: RuleStatusHistoryEntry[] = await RulesService.getRuleStatusHistory(
req.currentUser,
req.organization,
ruleId,
isComplete,
projectId
projectRuleId
);

res.status(200).json(rule);
res.status(200).json(history);
} catch (error: unknown) {
next(error);
}
Expand Down
65 changes: 56 additions & 9 deletions src/backend/src/prisma-query-args/rules.query-args.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ export const getRulePreviewQueryArgs = () =>
projects: {
where: { dateDeleted: null },
select: {
projectRuleId: true,
status: true,
statusUpdatedAt: true,
statusUpdatedBy: {
select: {
firstName: true,
lastName: true
}
},
project: {
select: {
projectId: true,
Expand All @@ -46,23 +55,23 @@ export const getRulePreviewQueryArgs = () =>
}
}
}
},
_count: {
select: {
statusHistory: true
}
}
}
},
completedBy: {
statusUpdatedBy: {
select: {
firstName: true,
lastName: true
}
},
completedInProject: {
_count: {
select: {
projectId: true,
wbsElement: {
select: {
name: true
}
}
statusHistory: true
}
}
}
Expand All @@ -73,7 +82,45 @@ export type ProjectRuleQueryArgs = ReturnType<typeof getProjectRuleQueryArgs>;
export const getProjectRuleQueryArgs = () =>
Prisma.validator<Prisma.Project_RuleDefaultArgs>()({
include: {
rule: getRulePreviewQueryArgs()
rule: getRulePreviewQueryArgs(),
statusUpdatedBy: {
select: {
firstName: true,
lastName: true
}
},
_count: {
select: {
statusHistory: true
}
}
}
});

export type RuleStatusHistoryQueryArgs = ReturnType<typeof getRuleStatusHistoryQueryArgs>;

export const getRuleStatusHistoryQueryArgs = () =>
Prisma.validator<Prisma.Rule_Status_HistoryDefaultArgs>()({
include: {
updatedBy: {
select: {
firstName: true,
lastName: true
}
},
projectRule: {
select: {
project: {
select: {
wbsElement: {
select: {
name: true
}
}
}
}
}
}
}
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
-- CreateEnum
CREATE TYPE "Rule_Status" AS ENUM ('PENDING', 'PASS', 'FAIL');

-- CreateTable
CREATE TABLE "Ruleset_Type" (
"rulesetTypeId" TEXT NOT NULL,
Expand Down Expand Up @@ -36,9 +39,9 @@ CREATE TABLE "Rule" (
"imageFileIds" TEXT[],
"rulesetId" TEXT NOT NULL,
"parentRuleId" TEXT,
"isComplete" BOOLEAN NOT NULL DEFAULT false,
"completedByUserId" TEXT,
"completedInProjectId" TEXT,
"status" "Rule_Status" NOT NULL DEFAULT 'PENDING',
"statusUpdatedByUserId" TEXT,
"statusUpdatedAt" TIMESTAMP(3),
"dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"dateUpdated" TIMESTAMP(3),
"dateDeleted" TIMESTAMP(3),
Expand All @@ -54,6 +57,9 @@ CREATE TABLE "Project_Rule" (
"projectRuleId" TEXT NOT NULL,
"ruleId" TEXT NOT NULL,
"projectId" TEXT NOT NULL,
"status" "Rule_Status" NOT NULL DEFAULT 'PENDING',
"statusUpdatedByUserId" TEXT,
"statusUpdatedAt" TIMESTAMP(3),
"dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"createdByUserId" TEXT NOT NULL,
"dateDeleted" TIMESTAMP(3),
Expand Down Expand Up @@ -124,10 +130,7 @@ ALTER TABLE "Rule" ADD CONSTRAINT "Rule_rulesetId_fkey" FOREIGN KEY ("rulesetId"
ALTER TABLE "Rule" ADD CONSTRAINT "Rule_parentRuleId_fkey" FOREIGN KEY ("parentRuleId") REFERENCES "Rule"("ruleId") ON DELETE SET NULL ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "Rule" ADD CONSTRAINT "Rule_completedByUserId_fkey" FOREIGN KEY ("completedByUserId") REFERENCES "User"("userId") ON DELETE SET NULL ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "Rule" ADD CONSTRAINT "Rule_completedInProjectId_fkey" FOREIGN KEY ("completedInProjectId") REFERENCES "Project"("projectId") ON DELETE SET NULL ON UPDATE CASCADE;
ALTER TABLE "Rule" ADD CONSTRAINT "Rule_statusUpdatedByUserId_fkey" FOREIGN KEY ("statusUpdatedByUserId") REFERENCES "User"("userId") ON DELETE SET NULL ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "Rule" ADD CONSTRAINT "Rule_createdByUserId_fkey" FOREIGN KEY ("createdByUserId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE;
Expand All @@ -144,6 +147,9 @@ ALTER TABLE "Project_Rule" ADD CONSTRAINT "Project_Rule_ruleId_fkey" FOREIGN KEY
-- AddForeignKey
ALTER TABLE "Project_Rule" ADD CONSTRAINT "Project_Rule_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("projectId") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "Project_Rule" ADD CONSTRAINT "Project_Rule_statusUpdatedByUserId_fkey" FOREIGN KEY ("statusUpdatedByUserId") REFERENCES "User"("userId") ON DELETE SET NULL ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "Project_Rule" ADD CONSTRAINT "Project_Rule_createdByUserId_fkey" FOREIGN KEY ("createdByUserId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE;

Expand All @@ -161,3 +167,30 @@ ALTER TABLE "_teamRules" ADD CONSTRAINT "_teamRules_A_fkey" FOREIGN KEY ("A") RE

-- AddForeignKey
ALTER TABLE "_teamRules" ADD CONSTRAINT "_teamRules_B_fkey" FOREIGN KEY ("B") REFERENCES "Team"("teamId") ON DELETE CASCADE ON UPDATE CASCADE;

-- CreateTable
CREATE TABLE "Rule_Status_History" (
"ruleStatusHistoryId" TEXT NOT NULL,
"ruleId" TEXT NOT NULL,
"projectRuleId" TEXT,
"status" "Rule_Status" NOT NULL,
"updatedByUserId" TEXT NOT NULL,
"dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,

CONSTRAINT "Rule_Status_History_pkey" PRIMARY KEY ("ruleStatusHistoryId")
);

-- CreateIndex
CREATE INDEX "Rule_Status_History_ruleId_idx" ON "Rule_Status_History"("ruleId");

-- CreateIndex
CREATE INDEX "Rule_Status_History_projectRuleId_idx" ON "Rule_Status_History"("projectRuleId");

-- AddForeignKey
ALTER TABLE "Rule_Status_History" ADD CONSTRAINT "Rule_Status_History_ruleId_fkey" FOREIGN KEY ("ruleId") REFERENCES "Rule"("ruleId") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "Rule_Status_History" ADD CONSTRAINT "Rule_Status_History_projectRuleId_fkey" FOREIGN KEY ("projectRuleId") REFERENCES "Project_Rule"("projectRuleId") ON DELETE SET NULL ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "Rule_Status_History" ADD CONSTRAINT "Rule_Status_History_updatedByUserId_fkey" FOREIGN KEY ("updatedByUserId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE;
Loading
Loading