feat: workflow permission

This commit is contained in:
Methapon Metanipat 2024-10-24 15:56:03 +07:00
parent 447a99e4f7
commit 85b99bf0a1
3 changed files with 108 additions and 6 deletions

View file

@ -0,0 +1,11 @@
/*
Warnings:
- Added the required column `registeredBranchId` to the `WorkflowTemplate` table without a default value. This is not possible if the table is not empty.
*/
-- AlterTable
ALTER TABLE "WorkflowTemplate" ADD COLUMN "registeredBranchId" TEXT NOT NULL;
-- AddForeignKey
ALTER TABLE "WorkflowTemplate" ADD CONSTRAINT "WorkflowTemplate_registeredBranchId_fkey" FOREIGN KEY ("registeredBranchId") REFERENCES "Branch"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

View file

@ -259,6 +259,7 @@ model Branch {
customerRegistration Customer[] customerRegistration Customer[]
productGroup ProductGroup[] productGroup ProductGroup[]
quotation Quotation[] quotation Quotation[]
workflowTemplate WorkflowTemplate[]
} }
model BranchBank { model BranchBank {
@ -894,6 +895,9 @@ model WorkflowTemplate {
step WorkflowTemplateStep[] step WorkflowTemplateStep[]
registeredBranch Branch @relation(fields: [registeredBranchId], references: [id])
registeredBranchId String
status Status @default(CREATED) status Status @default(CREATED)
statusOrder Int @default(0) statusOrder Int @default(0)

View file

@ -1,6 +1,28 @@
import { Body, Controller, Delete, Get, Path, Post, Put, Query, Request, Route, Tags } from "tsoa"; import {
Body,
Controller,
Delete,
Get,
Path,
Post,
Put,
Query,
Request,
Route,
Security,
Tags,
} from "tsoa";
import { RequestWithUser } from "../interfaces/user"; import { RequestWithUser } from "../interfaces/user";
import prisma from "../db"; import prisma from "../db";
import { Prisma } from "@prisma/client";
import {
branchRelationPermInclude,
createPermCheck,
createPermCondition,
} from "../services/permission";
import HttpError from "../interfaces/http-error";
import HttpStatus from "../interfaces/http-status";
import { notFoundError } from "../utils/error";
type WorkflowPayload = { type WorkflowPayload = {
name: string; name: string;
@ -10,19 +32,39 @@ type WorkflowPayload = {
value?: string[]; value?: string[];
responsiblePersonId?: string[]; responsiblePersonId?: string[];
}[]; }[];
registeredBranchId?: string;
}; };
const permissionCondCompany = createPermCondition((_) => true);
const permissionCheckCompany = createPermCheck((_) => true);
@Route("api/v1/workflow-template") @Route("api/v1/workflow-template")
@Tags("Workflow") @Tags("Workflow")
@Security("keycloak")
export class FlowTemplateController extends Controller { export class FlowTemplateController extends Controller {
@Get() @Get()
async getFlowTemplate( async getFlowTemplate(
@Request() _req: RequestWithUser, @Request() req: RequestWithUser,
@Query() page: number = 1, @Query() page: number = 1,
@Query() pageSize: number = 30, @Query() pageSize: number = 30,
@Query() query = "",
) { ) {
const where = {
OR: [
{ name: { contains: query } },
{
step: {
some: { name: { contains: query } },
},
},
],
registeredBranch: {
OR: permissionCondCompany(req.user),
},
} satisfies Prisma.WorkflowTemplateWhereInput;
const [result, total] = await prisma.$transaction([ const [result, total] = await prisma.$transaction([
prisma.workflowTemplate.findMany({ prisma.workflowTemplate.findMany({
where,
include: { include: {
step: { step: {
include: { include: {
@ -37,7 +79,7 @@ export class FlowTemplateController extends Controller {
take: pageSize, take: pageSize,
skip: (page - 1) * pageSize, skip: (page - 1) * pageSize,
}), }),
prisma.workflowTemplate.count(), prisma.workflowTemplate.count({ where }),
]); ]);
return { result, page, pageSize, total }; return { result, page, pageSize, total };
} }
@ -61,10 +103,29 @@ export class FlowTemplateController extends Controller {
} }
@Post() @Post()
async createFlowTemplate(@Request() _req: RequestWithUser, @Body() body: WorkflowPayload) { async createFlowTemplate(@Request() req: RequestWithUser, @Body() body: WorkflowPayload) {
const userAffiliatedBranch = await prisma.branch.findFirst({
include: branchRelationPermInclude(req.user),
where: body.registeredBranchId
? { id: body.registeredBranchId }
: {
user: { some: { userId: req.user.sub } },
},
});
if (!userAffiliatedBranch) {
throw new HttpError(
HttpStatus.BAD_REQUEST,
"You must be affilated with at least one branch or specifiy branch to be registered (System permission required).",
"reqMinAffilatedBranch",
);
}
await permissionCheckCompany(req.user, userAffiliatedBranch);
return await prisma.workflowTemplate.create({ return await prisma.workflowTemplate.create({
data: { data: {
...body, ...body,
registeredBranchId: userAffiliatedBranch.id,
step: { step: {
create: body.step.map((v, i) => ({ create: body.step.map((v, i) => ({
type: v.type, type: v.type,
@ -88,10 +149,23 @@ export class FlowTemplateController extends Controller {
@Put("{templateId}") @Put("{templateId}")
async updateFlowTemplate( async updateFlowTemplate(
@Request() _req: RequestWithUser, @Request() req: RequestWithUser,
@Path() templateId: string, @Path() templateId: string,
@Body() body: WorkflowPayload, @Body() body: WorkflowPayload,
) { ) {
const record = await prisma.workflowTemplate.findUnique({
where: { id: templateId },
include: {
registeredBranch: {
include: branchRelationPermInclude(req.user),
},
},
});
if (!record) throw notFoundError("Workflow");
await permissionCheckCompany(req.user, record.registeredBranch);
return await prisma.workflowTemplate.update({ return await prisma.workflowTemplate.update({
where: { id: templateId }, where: { id: templateId },
data: { data: {
@ -114,7 +188,20 @@ export class FlowTemplateController extends Controller {
} }
@Delete("{templateId}") @Delete("{templateId}")
async deleteFlowTemplateById(@Path() templateId: string) { async deleteFlowTemplateById(@Request() req: RequestWithUser, @Path() templateId: string) {
const record = await prisma.workflowTemplate.findUnique({
where: { id: templateId },
include: {
registeredBranch: {
include: branchRelationPermInclude(req.user),
},
},
});
if (!record) throw notFoundError("Workflow");
await permissionCheckCompany(req.user, record.registeredBranch);
return await prisma.workflowTemplate.delete({ return await prisma.workflowTemplate.delete({
where: { id: templateId }, where: { id: templateId },
}); });