diff --git a/prisma/migrations/20240701062318_user_relation/migration.sql b/prisma/migrations/20240701062318_user_relation/migration.sql new file mode 100644 index 0000000..2525562 --- /dev/null +++ b/prisma/migrations/20240701062318_user_relation/migration.sql @@ -0,0 +1,238 @@ +/* + Warnings: + + - You are about to drop the column `createdBy` on the `Branch` table. All the data in the column will be lost. + - You are about to drop the column `updatedBy` on the `Branch` table. All the data in the column will be lost. + - You are about to drop the column `createdBy` on the `BranchContact` table. All the data in the column will be lost. + - You are about to drop the column `updatedBy` on the `BranchContact` table. All the data in the column will be lost. + - You are about to drop the column `createdBy` on the `BranchUser` table. All the data in the column will be lost. + - You are about to drop the column `updatedBy` on the `BranchUser` table. All the data in the column will be lost. + - You are about to drop the column `createdBy` on the `Customer` table. All the data in the column will be lost. + - You are about to drop the column `updatedBy` on the `Customer` table. All the data in the column will be lost. + - You are about to drop the column `createdBy` on the `CustomerBranch` table. All the data in the column will be lost. + - You are about to drop the column `updatedBy` on the `CustomerBranch` table. All the data in the column will be lost. + - You are about to drop the column `createdBy` on the `Employee` table. All the data in the column will be lost. + - You are about to drop the column `updatedBy` on the `Employee` table. All the data in the column will be lost. + - You are about to drop the column `createdBy` on the `EmployeeCheckup` table. All the data in the column will be lost. + - You are about to drop the column `updatedBy` on the `EmployeeCheckup` table. All the data in the column will be lost. + - You are about to drop the column `updatedBy` on the `EmployeeHistory` table. All the data in the column will be lost. + - You are about to drop the column `createdBy` on the `EmployeeOtherInfo` table. All the data in the column will be lost. + - You are about to drop the column `updatedBy` on the `EmployeeOtherInfo` table. All the data in the column will be lost. + - You are about to drop the column `createdBy` on the `EmployeeWork` table. All the data in the column will be lost. + - You are about to drop the column `updatedBy` on the `EmployeeWork` table. All the data in the column will be lost. + - You are about to drop the column `createdBy` on the `Product` table. All the data in the column will be lost. + - You are about to drop the column `updatedBy` on the `Product` table. All the data in the column will be lost. + - You are about to drop the column `createdBy` on the `ProductGroup` table. All the data in the column will be lost. + - You are about to drop the column `updatedBy` on the `ProductGroup` table. All the data in the column will be lost. + - You are about to drop the column `createdBy` on the `ProductType` table. All the data in the column will be lost. + - You are about to drop the column `updatedBy` on the `ProductType` table. All the data in the column will be lost. + - You are about to drop the column `createdBy` on the `Service` table. All the data in the column will be lost. + - You are about to drop the column `updatedBy` on the `Service` table. All the data in the column will be lost. + - You are about to drop the column `createdBy` on the `User` table. All the data in the column will be lost. + - You are about to drop the column `updatedBy` on the `User` table. All the data in the column will be lost. + - You are about to drop the column `createdBy` on the `Work` table. All the data in the column will be lost. + - You are about to drop the column `updatedBy` on the `Work` table. All the data in the column will be lost. + - You are about to drop the column `createdBy` on the `WorkProduct` table. All the data in the column will be lost. + - You are about to drop the column `updatedBy` on the `WorkProduct` table. All the data in the column will be lost. + +*/ +-- AlterTable +ALTER TABLE "Branch" DROP COLUMN "createdBy", +DROP COLUMN "updatedBy", +ADD COLUMN "createdByUserId" TEXT, +ADD COLUMN "updatedByUserId" TEXT; + +-- AlterTable +ALTER TABLE "BranchContact" DROP COLUMN "createdBy", +DROP COLUMN "updatedBy", +ADD COLUMN "createdByUserId" TEXT, +ADD COLUMN "updatedByUserId" TEXT; + +-- AlterTable +ALTER TABLE "BranchUser" DROP COLUMN "createdBy", +DROP COLUMN "updatedBy", +ADD COLUMN "createdByUserId" TEXT, +ADD COLUMN "updatedByUserId" TEXT; + +-- AlterTable +ALTER TABLE "Customer" DROP COLUMN "createdBy", +DROP COLUMN "updatedBy", +ADD COLUMN "createdByUserId" TEXT, +ADD COLUMN "updatedByUserId" TEXT; + +-- AlterTable +ALTER TABLE "CustomerBranch" DROP COLUMN "createdBy", +DROP COLUMN "updatedBy", +ADD COLUMN "createdByUserId" TEXT, +ADD COLUMN "updatedByUserId" TEXT; + +-- AlterTable +ALTER TABLE "Employee" DROP COLUMN "createdBy", +DROP COLUMN "updatedBy", +ADD COLUMN "createdByUserId" TEXT, +ADD COLUMN "updatedByUserId" TEXT; + +-- AlterTable +ALTER TABLE "EmployeeCheckup" DROP COLUMN "createdBy", +DROP COLUMN "updatedBy", +ADD COLUMN "createdByUserId" TEXT, +ADD COLUMN "updatedByUserId" TEXT; + +-- AlterTable +ALTER TABLE "EmployeeHistory" DROP COLUMN "updatedBy", +ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, +ADD COLUMN "createdByUserId" TEXT, +ALTER COLUMN "updatedAt" DROP DEFAULT; + +-- AlterTable +ALTER TABLE "EmployeeOtherInfo" DROP COLUMN "createdBy", +DROP COLUMN "updatedBy", +ADD COLUMN "createdByUserId" TEXT, +ADD COLUMN "updatedByUserId" TEXT; + +-- AlterTable +ALTER TABLE "EmployeeWork" DROP COLUMN "createdBy", +DROP COLUMN "updatedBy", +ADD COLUMN "createdByUserId" TEXT, +ADD COLUMN "updatedByUserId" TEXT; + +-- AlterTable +ALTER TABLE "Product" DROP COLUMN "createdBy", +DROP COLUMN "updatedBy", +ADD COLUMN "createdByUserId" TEXT, +ADD COLUMN "updatedByUserId" TEXT; + +-- AlterTable +ALTER TABLE "ProductGroup" DROP COLUMN "createdBy", +DROP COLUMN "updatedBy", +ADD COLUMN "createdByUserId" TEXT, +ADD COLUMN "updatedByUserId" TEXT; + +-- AlterTable +ALTER TABLE "ProductType" DROP COLUMN "createdBy", +DROP COLUMN "updatedBy", +ADD COLUMN "createdByUserId" TEXT, +ADD COLUMN "updatedByUserId" TEXT; + +-- AlterTable +ALTER TABLE "Service" DROP COLUMN "createdBy", +DROP COLUMN "updatedBy", +ADD COLUMN "createdByUserId" TEXT, +ADD COLUMN "updatedByUserId" TEXT; + +-- AlterTable +ALTER TABLE "User" DROP COLUMN "createdBy", +DROP COLUMN "updatedBy", +ADD COLUMN "createdByUserId" TEXT, +ADD COLUMN "updatedByUserId" TEXT; + +-- AlterTable +ALTER TABLE "Work" DROP COLUMN "createdBy", +DROP COLUMN "updatedBy", +ADD COLUMN "createdByUserId" TEXT, +ADD COLUMN "updatedByUserId" TEXT; + +-- AlterTable +ALTER TABLE "WorkProduct" DROP COLUMN "createdBy", +DROP COLUMN "updatedBy", +ADD COLUMN "createdByUserId" TEXT, +ADD COLUMN "updatedByUserId" TEXT; + +-- AddForeignKey +ALTER TABLE "Branch" ADD CONSTRAINT "Branch_createdByUserId_fkey" FOREIGN KEY ("createdByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Branch" ADD CONSTRAINT "Branch_updatedByUserId_fkey" FOREIGN KEY ("updatedByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "BranchContact" ADD CONSTRAINT "BranchContact_createdByUserId_fkey" FOREIGN KEY ("createdByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "BranchContact" ADD CONSTRAINT "BranchContact_updatedByUserId_fkey" FOREIGN KEY ("updatedByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "BranchUser" ADD CONSTRAINT "BranchUser_createdByUserId_fkey" FOREIGN KEY ("createdByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "BranchUser" ADD CONSTRAINT "BranchUser_updatedByUserId_fkey" FOREIGN KEY ("updatedByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "User" ADD CONSTRAINT "User_createdByUserId_fkey" FOREIGN KEY ("createdByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "User" ADD CONSTRAINT "User_updatedByUserId_fkey" FOREIGN KEY ("updatedByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Customer" ADD CONSTRAINT "Customer_createdByUserId_fkey" FOREIGN KEY ("createdByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Customer" ADD CONSTRAINT "Customer_updatedByUserId_fkey" FOREIGN KEY ("updatedByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "CustomerBranch" ADD CONSTRAINT "CustomerBranch_createdByUserId_fkey" FOREIGN KEY ("createdByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "CustomerBranch" ADD CONSTRAINT "CustomerBranch_updatedByUserId_fkey" FOREIGN KEY ("updatedByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Employee" ADD CONSTRAINT "Employee_createdByUserId_fkey" FOREIGN KEY ("createdByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Employee" ADD CONSTRAINT "Employee_updatedByUserId_fkey" FOREIGN KEY ("updatedByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "EmployeeHistory" ADD CONSTRAINT "EmployeeHistory_createdByUserId_fkey" FOREIGN KEY ("createdByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "EmployeeCheckup" ADD CONSTRAINT "EmployeeCheckup_createdByUserId_fkey" FOREIGN KEY ("createdByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "EmployeeCheckup" ADD CONSTRAINT "EmployeeCheckup_updatedByUserId_fkey" FOREIGN KEY ("updatedByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "EmployeeWork" ADD CONSTRAINT "EmployeeWork_createdByUserId_fkey" FOREIGN KEY ("createdByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "EmployeeWork" ADD CONSTRAINT "EmployeeWork_updatedByUserId_fkey" FOREIGN KEY ("updatedByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "EmployeeOtherInfo" ADD CONSTRAINT "EmployeeOtherInfo_createdByUserId_fkey" FOREIGN KEY ("createdByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "EmployeeOtherInfo" ADD CONSTRAINT "EmployeeOtherInfo_updatedByUserId_fkey" FOREIGN KEY ("updatedByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Service" ADD CONSTRAINT "Service_createdByUserId_fkey" FOREIGN KEY ("createdByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Service" ADD CONSTRAINT "Service_updatedByUserId_fkey" FOREIGN KEY ("updatedByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Work" ADD CONSTRAINT "Work_createdByUserId_fkey" FOREIGN KEY ("createdByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Work" ADD CONSTRAINT "Work_updatedByUserId_fkey" FOREIGN KEY ("updatedByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "WorkProduct" ADD CONSTRAINT "WorkProduct_createdByUserId_fkey" FOREIGN KEY ("createdByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "WorkProduct" ADD CONSTRAINT "WorkProduct_updatedByUserId_fkey" FOREIGN KEY ("updatedByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "ProductGroup" ADD CONSTRAINT "ProductGroup_createdByUserId_fkey" FOREIGN KEY ("createdByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "ProductGroup" ADD CONSTRAINT "ProductGroup_updatedByUserId_fkey" FOREIGN KEY ("updatedByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "ProductType" ADD CONSTRAINT "ProductType_createdByUserId_fkey" FOREIGN KEY ("createdByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "ProductType" ADD CONSTRAINT "ProductType_updatedByUserId_fkey" FOREIGN KEY ("updatedByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Product" ADD CONSTRAINT "Product_createdByUserId_fkey" FOREIGN KEY ("createdByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Product" ADD CONSTRAINT "Product_updatedByUserId_fkey" FOREIGN KEY ("updatedByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 3912749..f60e04e 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -22,7 +22,7 @@ model Menu { createdBy String? createdAt DateTime @default(now()) - updatedBy String? + updatedBy String? updatedAt DateTime @updatedAt parent Menu? @relation(name: "MenuRelation", fields: [parentId], references: [id]) @@ -45,7 +45,7 @@ model RoleMenuPermission { createdBy String? createdAt DateTime @default(now()) - updatedBy String? + updatedBy String? updatedAt DateTime @updatedAt } @@ -62,7 +62,7 @@ model UserMenuPermission { createdBy String? createdAt DateTime @default(now()) - updatedBy String? + updatedBy String? updatedAt DateTime @updatedAt } @@ -77,7 +77,7 @@ model MenuComponent { createdBy String? createdAt DateTime @default(now()) - updatedBy String? + updatedBy String? updatedAt DateTime @updatedAt roleMenuComponentPermission RoleMenuComponentPermission[] userMennuComponentPermission UserMenuComponentPermission[] @@ -94,7 +94,7 @@ model RoleMenuComponentPermission { createdBy String? createdAt DateTime @default(now()) - updatedBy String? + updatedBy String? updatedAt DateTime @updatedAt } @@ -116,7 +116,7 @@ model UserMenuComponentPermission { createdBy String? createdAt DateTime @default(now()) - updatedBy String? + updatedBy String? updatedAt DateTime @updatedAt } @@ -127,7 +127,7 @@ model Province { createdBy String? createdAt DateTime @default(now()) - updatedBy String? + updatedBy String? updatedAt DateTime @updatedAt district District[] @@ -148,7 +148,7 @@ model District { createdBy String? createdAt DateTime @default(now()) - updatedBy String? + updatedBy String? updatedAt DateTime @updatedAt subDistrict SubDistrict[] @@ -169,7 +169,7 @@ model SubDistrict { createdBy String? createdAt DateTime @default(now()) - updatedBy String? + updatedBy String? updatedAt DateTime @updatedAt branch Branch[] @@ -220,10 +220,12 @@ model Branch { status Status @default(CREATED) statusOrder Int @default(0) - createdBy String? - createdAt DateTime @default(now()) - updatedBy String? - updatedAt DateTime @updatedAt + createdAt DateTime @default(now()) + createdBy User? @relation(name: "BranchCreatedByUser", fields: [createdByUserId], references: [id], onDelete: SetNull) + createdByUserId String? + updatedAt DateTime @updatedAt + updatedBy User? @relation(name: "BranchUpdatedByUser", fields: [updatedByUserId], references: [id], onDelete: SetNull) + updatedByUserId String? branch Branch[] @relation(name: "HeadOfficeRelation") contact BranchContact[] @@ -237,10 +239,12 @@ model BranchContact { branch Branch @relation(fields: [branchId], references: [id], onDelete: Cascade) branchId String - createdBy String? - createdAt DateTime @default(now()) - updatedBy String? - updatedAt DateTime @updatedAt + createdAt DateTime @default(now()) + createdBy User? @relation(name: "BranchContactCreatedByUser", fields: [createdByUserId], references: [id], onDelete: SetNull) + createdByUserId String? + updatedAt DateTime @updatedAt + updatedBy User? @relation(name: "BranchContactUpdatedByUser", fields: [updatedByUserId], references: [id], onDelete: SetNull) + updatedByUserId String? } model BranchUser { @@ -252,10 +256,12 @@ model BranchUser { user User @relation(fields: [userId], references: [id], onDelete: Cascade) userId String - createdBy String? - createdAt DateTime @default(now()) - updatedBy String? - updatedAt DateTime @updatedAt + createdAt DateTime @default(now()) + createdBy User? @relation(name: "BranchUserCreatedByUser", fields: [createdByUserId], references: [id], onDelete: SetNull) + createdByUserId String? + updatedAt DateTime @updatedAt + updatedBy User? @relation(name: "BranchUserUpdatedByUser", fields: [updatedByUserId], references: [id], onDelete: SetNull) + updatedByUserId String? } enum UserType { @@ -321,15 +327,51 @@ model User { status Status @default(CREATED) statusOrder Int @default(0) - createdBy String? - createdAt DateTime @default(now()) - updatedBy String? - updatedAt DateTime @updatedAt + createdAt DateTime @default(now()) + createdBy User? @relation(name: "UserCreatedByUser", fields: [createdByUserId], references: [id], onDelete: SetNull) + createdByUserId String? + updatedAt DateTime @updatedAt + updatedBy User? @relation(name: "UserUpdatedByUser", fields: [updatedByUserId], references: [id], onDelete: SetNull) + updatedByUserId String? branch BranchUser[] userMenuPermission UserMenuPermission[] userMenuComponentPermission UserMenuComponentPermission[] - employeeHistory EmployeeHistory[] + + userCreated User[] @relation("UserCreatedByUser") + userUpdated User[] @relation("UserUpdatedByUser") + branchCreated Branch[] @relation("BranchCreatedByUser") + branchUpdated Branch[] @relation("BranchUpdatedByUser") + branchContactCreated BranchContact[] @relation("BranchContactCreatedByUser") + branchContactUpdated BranchContact[] @relation("BranchContactUpdatedByUser") + branchUserCreated BranchUser[] @relation("BranchUserCreatedByUser") + branchUserUpdated BranchUser[] @relation("BranchUserUpdatedByUser") + customerCreated Customer[] @relation("CustomerCreatedByUser") + customerUpdated Customer[] @relation("CustomerUpdatedByUser") + customerBranchCreated CustomerBranch[] @relation("CustomerBranchCreatedByUser") + customerBranchUpdated CustomerBranch[] @relation("CustomerBranchUpdatedByUser") + emplyeeCreated Employee[] @relation("EmployeeCreatedByUser") + employeUpdated Employee[] @relation("EmployeeUpdatedByUser") + employeeHistoryCreated EmployeeHistory[] @relation("EmployeeHistoryCreatedByUser") + employeeHistoryUpdated EmployeeHistory[] @relation("EmployeeHistoryUpdatedByUser") + employeeCheckupCreated EmployeeCheckup[] @relation("EmployeeCheckupCreatedByUser") + employeeCheckupUpdated EmployeeCheckup[] @relation("EmployeeCheckupUpdatedByUser") + employeeWorkCreated EmployeeWork[] @relation("EmployeeWorkCreatedByUser") + employeeWorkUpdated EmployeeWork[] @relation("EmployeeWorkUpdatedByUser") + employeeOtherInfoCreated EmployeeOtherInfo[] @relation("EmployeeOtherInfoCreatedByUser") + employeeOtherInfoUpdated EmployeeOtherInfo[] @relation("EmployeeOtherInfoUpdatedByUser") + serviceCreated Service[] @relation("ServiceCreatedByUser") + serviceUpdated Service[] @relation("ServiceUpdatedByUser") + workCreated Work[] @relation("WorkCreatedByUser") + workUpdated Work[] @relation("WorkUpdatedByUser") + workProductCreated WorkProduct[] @relation("WorkProductCreatedByUser") + workProductUpdated WorkProduct[] @relation("WorkProductUpdatedByUser") + productGroupCreated ProductGroup[] @relation("ProductGroupCreatedByUser") + productGroupUpdated ProductGroup[] @relation("ProductGroupUpdatedByUser") + productTypeCreated ProductType[] @relation("ProductTypeCreatedByUser") + productTypeUpdated ProductType[] @relation("ProductTypeUpdatedByUser") + productCreated Product[] @relation("ProductCreatedByUser") + productUpdated Product[] @relation("ProductUpdatedByUser") } enum CustomerType { @@ -350,10 +392,12 @@ model Customer { status Status @default(CREATED) statusOrder Int @default(0) - createdBy String? - createdAt DateTime @default(now()) - updatedBy String? - updatedAt DateTime @updatedAt + createdAt DateTime @default(now()) + createdBy User? @relation(name: "CustomerCreatedByUser", fields: [createdByUserId], references: [id], onDelete: SetNull) + createdByUserId String? + updatedAt DateTime @updatedAt + updatedBy User? @relation(name: "CustomerUpdatedByUser", fields: [updatedByUserId], references: [id], onDelete: SetNull) + updatedByUserId String? branch CustomerBranch[] } @@ -405,10 +449,12 @@ model CustomerBranch { status Status @default(CREATED) statusOrder Int @default(0) - createdBy String? - createdAt DateTime @default(now()) - updatedBy String? - updatedAt DateTime @updatedAt + createdAt DateTime @default(now()) + createdBy User? @relation(name: "CustomerBranchCreatedByUser", fields: [createdByUserId], references: [id], onDelete: SetNull) + createdByUserId String? + updatedAt DateTime @updatedAt + updatedBy User? @relation(name: "CustomerBranchUpdatedByUser", fields: [updatedByUserId], references: [id], onDelete: SetNull) + updatedByUserId String? employee Employee[] } @@ -465,10 +511,12 @@ model Employee { status Status @default(CREATED) statusOrder Int @default(0) - createdBy String? - createdAt DateTime @default(now()) - updatedBy String? - updatedAt DateTime @updatedAt + createdAt DateTime @default(now()) + createdBy User? @relation(name: "EmployeeCreatedByUser", fields: [createdByUserId], references: [id], onDelete: SetNull) + createdByUserId String? + updatedAt DateTime @updatedAt + updatedBy User? @relation(name: "EmployeeUpdatedByUser", fields: [updatedByUserId], references: [id], onDelete: SetNull) + updatedByUserId String? employeeCheckup EmployeeCheckup[] employeeWork EmployeeWork[] @@ -485,10 +533,12 @@ model EmployeeHistory { timestamp DateTime @default(now()) + createdAt DateTime @default(now()) + createdBy User? @relation(name: "EmployeeHistoryCreatedByUser", fields: [createdByUserId], references: [id], onDelete: SetNull) + createdByUserId String? + updatedAt DateTime @updatedAt + updatedBy User? @relation(name: "EmployeeHistoryUpdatedByUser", fields: [updatedByUserId], references: [id], onDelete: SetNull) updatedByUserId String? - updatedByUser User? @relation(fields: [updatedByUserId], references: [id]) - updatedBy String? - updatedAt DateTime @default(now()) masterId String master Employee @relation(fields: [masterId], references: [id], onDelete: Cascade) @@ -513,10 +563,12 @@ model EmployeeCheckup { coverageStartDate DateTime? coverageExpireDate DateTime? - createdBy String? - createdAt DateTime @default(now()) - updatedBy String? - updatedAt DateTime @updatedAt + createdAt DateTime @default(now()) + createdBy User? @relation(name: "EmployeeCheckupCreatedByUser", fields: [createdByUserId], references: [id], onDelete: SetNull) + createdByUserId String? + updatedAt DateTime @updatedAt + updatedBy User? @relation(name: "EmployeeCheckupUpdatedByUser", fields: [updatedByUserId], references: [id], onDelete: SetNull) + updatedByUserId String? } model EmployeeWork { @@ -535,10 +587,12 @@ model EmployeeWork { workEndDate DateTime? remark String? - createdBy String? - createdAt DateTime @default(now()) - updatedBy String? - updatedAt DateTime @updatedAt + createdAt DateTime @default(now()) + createdBy User? @relation(name: "EmployeeWorkCreatedByUser", fields: [createdByUserId], references: [id], onDelete: SetNull) + createdByUserId String? + updatedAt DateTime @updatedAt + updatedBy User? @relation(name: "EmployeeWorkUpdatedByUser", fields: [updatedByUserId], references: [id], onDelete: SetNull) + updatedByUserId String? } model EmployeeOtherInfo { @@ -560,10 +614,12 @@ model EmployeeOtherInfo { motherFirstNameEN String? motherLastNameEN String? - createdBy String? - createdAt DateTime @default(now()) - updatedBy String? - updatedAt DateTime @updatedAt + createdAt DateTime @default(now()) + createdBy User? @relation(name: "EmployeeOtherInfoCreatedByUser", fields: [createdByUserId], references: [id], onDelete: SetNull) + createdByUserId String? + updatedAt DateTime @updatedAt + updatedBy User? @relation(name: "EmployeeOtherInfoUpdatedByUser", fields: [updatedByUserId], references: [id], onDelete: SetNull) + updatedByUserId String? } model Service { @@ -579,10 +635,12 @@ model Service { work Work[] - createdBy String? - createdAt DateTime @default(now()) - updatedBy String? - updatedAt DateTime @updatedAt + createdAt DateTime @default(now()) + createdBy User? @relation(name: "ServiceCreatedByUser", fields: [createdByUserId], references: [id], onDelete: SetNull) + createdByUserId String? + updatedAt DateTime @updatedAt + updatedBy User? @relation(name: "ServiceUpdatedByUser", fields: [updatedByUserId], references: [id], onDelete: SetNull) + updatedByUserId String? } model Work { @@ -598,10 +656,12 @@ model Work { service Service? @relation(fields: [serviceId], references: [id], onDelete: Cascade) serviceId String? - createdBy String? - createdAt DateTime @default(now()) - updatedBy String? - updatedAt DateTime @updatedAt + createdAt DateTime @default(now()) + createdBy User? @relation(name: "WorkCreatedByUser", fields: [createdByUserId], references: [id], onDelete: SetNull) + createdByUserId String? + updatedAt DateTime @updatedAt + updatedBy User? @relation(name: "WorkUpdatedByUser", fields: [updatedByUserId], references: [id], onDelete: SetNull) + updatedByUserId String? productOnWork WorkProduct[] } @@ -613,10 +673,12 @@ model WorkProduct { product Product @relation(fields: [productId], references: [id], onDelete: Cascade) productId String - createdBy String? - createdAt DateTime @default(now()) - updatedBy String? - updatedAt DateTime @updatedAt + createdAt DateTime @default(now()) + createdBy User? @relation(name: "WorkProductCreatedByUser", fields: [createdByUserId], references: [id], onDelete: SetNull) + createdByUserId String? + updatedAt DateTime @updatedAt + updatedBy User? @relation(name: "WorkProductUpdatedByUser", fields: [updatedByUserId], references: [id], onDelete: SetNull) + updatedByUserId String? @@id([workId, productId]) } @@ -632,10 +694,12 @@ model ProductGroup { status Status @default(CREATED) statusOrder Int @default(0) - createdBy String? - createdAt DateTime @default(now()) - updatedBy String? - updatedAt DateTime @updatedAt + createdAt DateTime @default(now()) + createdBy User? @relation(name: "ProductGroupCreatedByUser", fields: [createdByUserId], references: [id], onDelete: SetNull) + createdByUserId String? + updatedAt DateTime @updatedAt + updatedBy User? @relation(name: "ProductGroupUpdatedByUser", fields: [updatedByUserId], references: [id], onDelete: SetNull) + updatedByUserId String? type ProductType[] } @@ -651,10 +715,12 @@ model ProductType { status Status @default(CREATED) statusOrder Int @default(0) - createdBy String? - createdAt DateTime @default(now()) - updatedBy String? - updatedAt DateTime @updatedAt + createdAt DateTime @default(now()) + createdBy User? @relation(name: "ProductTypeCreatedByUser", fields: [createdByUserId], references: [id], onDelete: SetNull) + createdByUserId String? + updatedAt DateTime @updatedAt + updatedBy User? @relation(name: "ProductTypeUpdatedByUser", fields: [updatedByUserId], references: [id], onDelete: SetNull) + updatedByUserId String? productGroup ProductGroup @relation(fields: [productGroupId], references: [id], onDelete: Cascade) productGroupId String @@ -683,8 +749,10 @@ model Product { workProduct WorkProduct[] - createdBy String? - createdAt DateTime @default(now()) - updatedBy String? - updatedAt DateTime @updatedAt + createdAt DateTime @default(now()) + createdBy User? @relation(name: "ProductCreatedByUser", fields: [createdByUserId], references: [id], onDelete: SetNull) + createdByUserId String? + updatedAt DateTime @updatedAt + updatedBy User? @relation(name: "ProductUpdatedByUser", fields: [updatedByUserId], references: [id], onDelete: SetNull) + updatedByUserId String? } diff --git a/src/app.ts b/src/app.ts index d9c0a8f..b933540 100644 --- a/src/app.ts +++ b/src/app.ts @@ -6,6 +6,8 @@ import swaggerDocument from "./swagger.json"; import error from "./middlewares/error"; import { RegisterRoutes } from "./routes"; import logMiddleware from "./middlewares/log"; +import { addUserRoles, createUser, getRoleByName, listUser } from "./services/keycloak"; +import prisma from "./db"; const APP_HOST = process.env.APP_HOST || "0.0.0.0"; const APP_PORT = +(process.env.APP_PORT || 3000); @@ -13,6 +15,53 @@ const APP_PORT = +(process.env.APP_PORT || 3000); (async () => { const app = express(); + let users = await (async () => { + let list = await listUser(); + while (!list) { + list = await listUser(); + await new Promise((resolve) => setTimeout(resolve, 1000)); + } + return list; + })(); + + if (users.length === 0) { + const role = await getRoleByName("system"); + const userId = await createUser("admin", "1234", { + firstName: "Admin", + lastName: "System", + email: "admin@jws.local", + requiredActions: ["UPDATE_PASSWORD"], + enabled: true, + }); + + if (!userId || typeof userId !== "string") { + throw new Error("Error create user with keycloak service."); + } + + if (role) await addUserRoles(userId, [role]); + + await prisma.user.create({ + include: { province: true, district: true, subDistrict: true }, + data: { + id: userId, + email: "admin@jws.local", + gender: "", + address: "", + addressEN: "", + zipCode: "", + userType: "USER", + userRole: "system", + telephoneNo: "", + firstName: "Admin", + firstNameEN: "Admin", + lastName: "System", + lastNameEN: "System", + statusOrder: 0, + username: "admin", + }, + }); + } + app.use(cors()); app.use(json()); app.use(urlencoded({ extended: true })); diff --git a/src/config.json b/src/config.json new file mode 100644 index 0000000..88ff9cb --- /dev/null +++ b/src/config.json @@ -0,0 +1,8 @@ +{ + "branch": { + "maxHeadOfficeBranch": 10 + }, + "personnel": { + "type": ["USER", "MESSENGER", "DELEGATE", "AGENCY"] + } +} diff --git a/src/controllers/branch-contact-controller.ts b/src/controllers/branch-contact-controller.ts index d98c966..b46e8cb 100644 --- a/src/controllers/branch-contact-controller.ts +++ b/src/controllers/branch-contact-controller.ts @@ -79,7 +79,7 @@ export class BranchContactController extends Controller { throw new HttpError(HttpStatus.BAD_REQUEST, "Branch cannot be found.", "branchBadReq"); } const record = await prisma.branchContact.create({ - data: { ...body, branchId, createdBy: req.user.name, updatedBy: req.user.name }, + data: { ...body, branchId, createdByUserId: req.user.sub, updatedByUserId: req.user.sub }, }); this.setStatus(HttpStatus.CREATED); @@ -107,7 +107,7 @@ export class BranchContactController extends Controller { } const record = await prisma.branchContact.update({ - data: { ...body, updatedBy: req.user.name }, + data: { ...body, updatedByUserId: req.user.sub }, where: { id: contactId, branchId }, }); diff --git a/src/controllers/branch-controller.ts b/src/controllers/branch-controller.ts index 50bce01..e5516a4 100644 --- a/src/controllers/branch-controller.ts +++ b/src/controllers/branch-controller.ts @@ -286,8 +286,8 @@ export class BranchController extends Controller { district: { connect: districtId ? { id: districtId } : undefined }, subDistrict: { connect: subDistrictId ? { id: subDistrictId } : undefined }, headOffice: { connect: headOfficeId ? { id: headOfficeId } : undefined }, - createdBy: req.user.name, - updatedBy: req.user.name, + createdBy: { connect: { id: req.user.sub } }, + updatedBy: { connect: { id: req.user.sub } }, }, }); }, @@ -403,7 +403,7 @@ export class BranchController extends Controller { connect: headOfficeId ? { id: headOfficeId } : undefined, disconnect: headOfficeId === null || undefined, }, - updatedBy: req.user.name, + updatedBy: { connect: { id: req.user.sub } }, }, where: { id: branchId }, }); diff --git a/src/controllers/branch-user-controller.ts b/src/controllers/branch-user-controller.ts index 7dfed95..2d8100c 100644 --- a/src/controllers/branch-user-controller.ts +++ b/src/controllers/branch-user-controller.ts @@ -1,4 +1,4 @@ -import { Branch, Prisma, Status, User, UserType } from "@prisma/client"; +import { Branch, Prisma, Status, User } from "@prisma/client"; import { Body, Controller, @@ -113,11 +113,7 @@ export class BranchUserController extends Controller { ]); if (!branch) { - throw new HttpError( - HttpStatus.BAD_REQUEST, - "Branch cannot be found.", - "branchBadReq", - ); + throw new HttpError(HttpStatus.BAD_REQUEST, "Branch cannot be found.", "branchBadReq"); } if (user.length !== body.user.length) { @@ -139,8 +135,8 @@ export class BranchUserController extends Controller { .map((v) => ({ branchId, userId: v.id, - createdBy: req.user.name, - updatedBy: req.user.name, + createdByUserId: req.user.sub, + updatedByUserId: req.user.sub, })), }), ]); @@ -249,8 +245,8 @@ export class UserBranchController extends Controller { .map((v) => ({ branchId: v.id, userId, - createdBy: req.user.name, - updatedBy: req.user.name, + createdByUserId: req.user.sub, + updatedByUserId: req.user.sub, })), }); diff --git a/src/controllers/customer-branch-controller.ts b/src/controllers/customer-branch-controller.ts index d07d7b4..6692cb8 100644 --- a/src/controllers/customer-branch-controller.ts +++ b/src/controllers/customer-branch-controller.ts @@ -294,8 +294,8 @@ export class CustomerBranchController extends Controller { province: { connect: provinceId ? { id: provinceId } : undefined }, district: { connect: districtId ? { id: districtId } : undefined }, subDistrict: { connect: subDistrictId ? { id: subDistrictId } : undefined }, - createdBy: req.user.name, - updatedBy: req.user.name, + createdBy: { connect: { id: req.user.sub } }, + updatedBy: { connect: { id: req.user.sub } }, }, }); }, @@ -380,8 +380,7 @@ export class CustomerBranchController extends Controller { connect: subDistrictId ? { id: subDistrictId } : undefined, disconnect: subDistrictId === null || undefined, }, - createdBy: req.user.name, - updatedBy: req.user.name, + updatedBy: { connect: { id: req.user.sub } }, }, }); diff --git a/src/controllers/customer-controller.ts b/src/controllers/customer-controller.ts index 23b1e8d..ad4b756 100644 --- a/src/controllers/customer-controller.ts +++ b/src/controllers/customer-controller.ts @@ -305,13 +305,13 @@ export class CustomerController extends Controller { ...v, branchNo: i + 1, code: `${last.key.slice(9)}${last.value.toString().padStart(6, "0")}-${(i + 1).toString().padStart(2, "0")}`, - createdBy: req.user.name, - updatedBy: req.user.name, + createdByUserId: req.user.sub, + updatedByUserId: req.user.sub, })) || [], }, }, - createdBy: req.user.name, - updatedBy: req.user.name, + createdByUserId: req.user.sub, + updatedByUserId: req.user.sub, }, }); }, @@ -436,20 +436,20 @@ export class CustomerController extends Controller { ...v, branchNo: i + 1, code: `${customer.code}-${(i + 1).toString().padStart(2, "0")}`, - createdBy: req.user.name, - updatedBy: req.user.name, + createdByUserId: req.user.sub, + updatedByUserId: req.user.sub, id: undefined, }, update: { ...v, branchNo: i + 1, code: `${customer.code}-${(i + 1).toString().padStart(2, "0")}`, - updatedBy: req.user.name, + updatedByUserId: req.user.sub, }, })), }) || undefined, - updatedBy: req.user.name, + updatedByUserId: req.user.sub, }, }) .then((v) => { diff --git a/src/controllers/employee-checkup-controller.ts b/src/controllers/employee-checkup-controller.ts index 21fb896..e3ee273 100644 --- a/src/controllers/employee-checkup-controller.ts +++ b/src/controllers/employee-checkup-controller.ts @@ -90,8 +90,8 @@ export class EmployeeCheckupController extends Controller { ...rest, province: { connect: provinceId ? { id: provinceId } : undefined }, employee: { connect: { id: employeeId } }, - createdBy: req.user.name, - updatedBy: req.user.name, + createdBy: { connect: { id: req.user.sub } }, + updatedBy: { connect: { id: req.user.sub } }, }, }); @@ -142,8 +142,7 @@ export class EmployeeCheckupController extends Controller { data: { ...rest, province: { connect: provinceId ? { id: provinceId } : undefined }, - createdBy: req.user.name, - updatedBy: req.user.name, + updatedBy: { connect: { id: req.user.sub } }, }, }); diff --git a/src/controllers/employee-controller.ts b/src/controllers/employee-controller.ts index c366aa2..0739099 100644 --- a/src/controllers/employee-controller.ts +++ b/src/controllers/employee-controller.ts @@ -418,8 +418,8 @@ export class EmployeeController extends Controller { district: { connect: districtId ? { id: districtId } : undefined }, subDistrict: { connect: subDistrictId ? { id: subDistrictId } : undefined }, customerBranch: { connect: { id: customerBranchId } }, - createdBy: req.user.name, - updatedBy: req.user.name, + createdBy: { connect: { id: req.user.sub } }, + updatedBy: { connect: { id: req.user.sub } }, }, }); }, @@ -578,13 +578,13 @@ export class EmployeeController extends Controller { where: { id: v.id || "" }, create: { ...v, - createdBy: req.user.name, - updatedBy: req.user.name, + createdByUserId: req.user.sub, + updatedByUserId: req.user.sub, id: undefined, }, update: { ...v, - updatedBy: req.user.name, + updatedByUserId: req.user.sub, }, })), } @@ -602,13 +602,13 @@ export class EmployeeController extends Controller { create: { ...v, provinceId: !v.provinceId ? undefined : v.provinceId, - createdBy: req.user.name, - updatedBy: req.user.name, + createdByUserId: req.user.sub, + updatedByUserId: req.user.sub, id: undefined, }, update: { ...v, - updatedBy: req.user.name, + updatedByUserId: req.user.sub, }, })), } @@ -631,8 +631,8 @@ export class EmployeeController extends Controller { connect: subDistrictId ? { id: subDistrictId } : undefined, disconnect: subDistrictId === null || undefined, }, - createdBy: req.user.name, - updatedBy: req.user.name, + createdBy: { connect: { id: req.user.sub } }, + updatedBy: { connect: { id: req.user.sub } }, }, }); }); diff --git a/src/controllers/employee-other-info-controller.ts b/src/controllers/employee-other-info-controller.ts index a479de7..023f392 100644 --- a/src/controllers/employee-other-info-controller.ts +++ b/src/controllers/employee-other-info-controller.ts @@ -51,18 +51,14 @@ export class EmployeeOtherInfo extends Controller { @Body() body: EmployeeOtherInfoPayload, ) { if (!(await prisma.employee.findUnique({ where: { id: employeeId } }))) - throw new HttpError( - HttpStatus.BAD_REQUEST, - "Employee cannot be found.", - "employeeBadReq", - ); + throw new HttpError(HttpStatus.BAD_REQUEST, "Employee cannot be found.", "employeeBadReq"); const record = await prisma.employeeOtherInfo.create({ data: { ...body, employee: { connect: { id: employeeId } }, - createdBy: req.user.name, - updatedBy: req.user.name, + createdBy: { connect: { id: req.user.sub } }, + updatedBy: { connect: { id: req.user.sub } }, }, }); @@ -88,7 +84,7 @@ export class EmployeeOtherInfo extends Controller { const record = await prisma.employeeOtherInfo.update({ where: { id: otherInfoId, employeeId }, - data: { ...body, createdBy: req.user.name, updatedBy: req.user.name }, + data: { ...body, updatedByUserId: req.user.sub }, }); this.setStatus(HttpStatus.CREATED); diff --git a/src/controllers/employee-work-controller.ts b/src/controllers/employee-work-controller.ts index 85c12f4..de90d1d 100644 --- a/src/controllers/employee-work-controller.ts +++ b/src/controllers/employee-work-controller.ts @@ -46,7 +46,11 @@ export class EmployeeWorkController extends Controller { where: { id: workId, employeeId }, }); if (!record) { - throw new HttpError(HttpStatus.NOT_FOUND, "Employee work cannot be found.", "employeeWorkNotFound"); + throw new HttpError( + HttpStatus.NOT_FOUND, + "Employee work cannot be found.", + "employeeWorkNotFound", + ); } return record; } @@ -58,18 +62,14 @@ export class EmployeeWorkController extends Controller { @Body() body: EmployeeWorkPayload, ) { if (!(await prisma.employee.findUnique({ where: { id: employeeId } }))) - throw new HttpError( - HttpStatus.BAD_REQUEST, - "Employee cannot be found.", - "employeeBadReq", - ); + throw new HttpError(HttpStatus.BAD_REQUEST, "Employee cannot be found.", "employeeBadReq"); const record = await prisma.employeeWork.create({ data: { ...body, employee: { connect: { id: employeeId } }, - createdBy: req.user.name, - updatedBy: req.user.name, + createdBy: { connect: { id: req.user.sub } }, + updatedBy: { connect: { id: req.user.sub } }, }, }); @@ -86,12 +86,16 @@ export class EmployeeWorkController extends Controller { @Body() body: EmployeeWorkPayload, ) { if (!(await prisma.employeeWork.findUnique({ where: { id: workId, employeeId } }))) { - throw new HttpError(HttpStatus.NOT_FOUND, "Employee work cannot be found.", "employeeWorkNotFound"); + throw new HttpError( + HttpStatus.NOT_FOUND, + "Employee work cannot be found.", + "employeeWorkNotFound", + ); } const record = await prisma.employeeWork.update({ where: { id: workId, employeeId }, - data: { ...body, createdBy: req.user.name, updatedBy: req.user.name }, + data: { ...body, updatedByUserId: req.user.sub }, }); this.setStatus(HttpStatus.CREATED); @@ -104,7 +108,11 @@ export class EmployeeWorkController extends Controller { const record = await prisma.employeeWork.findFirst({ where: { id: workId, employeeId } }); if (!record) { - throw new HttpError(HttpStatus.NOT_FOUND, "Employee work cannot be found.", "employeeWorkNotFound"); + throw new HttpError( + HttpStatus.NOT_FOUND, + "Employee work cannot be found.", + "employeeWorkNotFound", + ); } return await prisma.employeeWork.delete({ where: { id: workId, employeeId } }); diff --git a/src/controllers/keycloak-controller.ts b/src/controllers/keycloak-controller.ts index 69ed2de..6b827c8 100644 --- a/src/controllers/keycloak-controller.ts +++ b/src/controllers/keycloak-controller.ts @@ -4,7 +4,7 @@ import { createUser, deleteUser, editUser, - getRoles, + listRole, removeUserRoles, } from "../services/keycloak"; @@ -38,7 +38,7 @@ export class KeycloakController extends Controller { @Get("role") async getRole() { - const role = await getRoles(); + const role = await listRole(); if (Array.isArray(role)) return role.filter( (a) => @@ -49,7 +49,7 @@ export class KeycloakController extends Controller { @Post("{userId}/role") async addRole(@Path() userId: string, @Body() body: { role: string[] }) { - const list = await getRoles(); + const list = await listRole(); if (!Array.isArray(list)) throw new Error("Failed. Cannot get role(s) data from the server."); @@ -63,7 +63,7 @@ export class KeycloakController extends Controller { @Delete("{userId}/role/{roleId}") async deleteRole(@Path() userId: string, @Path() roleId: string) { - const list = await getRoles(); + const list = await listRole(); if (!Array.isArray(list)) throw new Error("Failed. Cannot get role(s) data from the server."); diff --git a/src/controllers/product/group-controller.ts b/src/controllers/product/group-controller.ts index 2d676c4..2d93e22 100644 --- a/src/controllers/product/group-controller.ts +++ b/src/controllers/product/group-controller.ts @@ -143,8 +143,8 @@ export class ProductGroup extends Controller { ...body, statusOrder: +(body.status === "INACTIVE"), code: `G${last.value.toString().padStart(2, "0")}`, - createdBy: req.user.name, - updatedBy: req.user.name, + createdByUserId: req.user.sub, + updatedByUserId: req.user.sub, }, }); }, @@ -171,7 +171,7 @@ export class ProductGroup extends Controller { } const record = await prisma.productGroup.update({ - data: { ...body, statusOrder: +(body.status === "INACTIVE"), updatedBy: req.user.name }, + data: { ...body, statusOrder: +(body.status === "INACTIVE"), updatedByUserId: req.user.sub }, where: { id: groupId }, }); diff --git a/src/controllers/product/product-controller.ts b/src/controllers/product/product-controller.ts index 340ab9f..e8d8e75 100644 --- a/src/controllers/product/product-controller.ts +++ b/src/controllers/product/product-controller.ts @@ -173,8 +173,8 @@ export class ProductController extends Controller { ...body, statusOrder: +(body.status === "INACTIVE"), code: `${body.code.toLocaleUpperCase()}${last.value.toString().padStart(3, "0")}`, - createdBy: req.user.name, - updatedBy: req.user.name, + createdByUserId: req.user.sub, + updatedByUserId: req.user.sub, }, }); }, @@ -230,7 +230,7 @@ export class ProductController extends Controller { } const record = await prisma.product.update({ - data: { ...body, statusOrder: +(body.status === "INACTIVE"), updatedBy: req.user.name }, + data: { ...body, statusOrder: +(body.status === "INACTIVE"), updatedByUserId: req.user.sub }, where: { id: productId }, }); diff --git a/src/controllers/product/type-controller.ts b/src/controllers/product/type-controller.ts index 786c1da..36a9a12 100644 --- a/src/controllers/product/type-controller.ts +++ b/src/controllers/product/type-controller.ts @@ -132,8 +132,8 @@ export class ProductType extends Controller { ...body, statusOrder: +(body.status === "INACTIVE"), code: `T${productGroup.code}${last.value.toString().padStart(2, "0")}`, - createdBy: req.user.name, - updatedBy: req.user.name, + createdByUserId: req.user.sub, + updatedByUserId: req.user.sub, }, }); }, @@ -178,7 +178,7 @@ export class ProductType extends Controller { } const record = await prisma.productType.update({ - data: { ...body, statusOrder: +(body.status === "INACTIVE"), updatedBy: req.user.name }, + data: { ...body, statusOrder: +(body.status === "INACTIVE"), updatedByUserId: req.user.sub }, where: { id: typeId }, }); diff --git a/src/controllers/service/service-controller.ts b/src/controllers/service/service-controller.ts index a565620..c99d1af 100644 --- a/src/controllers/service/service-controller.ts +++ b/src/controllers/service/service-controller.ts @@ -245,8 +245,8 @@ export class ServiceController extends Controller { statusOrder: +(body.status === "INACTIVE"), code: `${body.code.toLocaleUpperCase()}${last.value.toString().padStart(3, "0")}`, work: { connect: workList.map((v) => ({ id: v.id })) }, - createdBy: req.user.name, - updatedBy: req.user.name, + createdByUserId: req.user.sub, + updatedByUserId: req.user.sub, }, }); }, @@ -308,7 +308,7 @@ export class ServiceController extends Controller { deleteMany: {}, connect: workList.map((v) => ({ id: v.id })), }, - updatedBy: req.user.name, + updatedByUserId: req.user.sub, }, where: { id: serviceId }, }); diff --git a/src/controllers/user-controller.ts b/src/controllers/user-controller.ts index 9f88d73..89855ab 100644 --- a/src/controllers/user-controller.ts +++ b/src/controllers/user-controller.ts @@ -24,7 +24,7 @@ import { createUser, deleteUser, editUser, - getRoles, + listRole, getUserRoles, removeUserRoles, } from "../services/keycloak"; @@ -256,7 +256,7 @@ export class UserController extends Controller { const { provinceId, districtId, subDistrictId, username, ...rest } = body; - let list = await getRoles(); + let list = await listRole(); if (!Array.isArray(list)) throw new Error("Failed. Cannot get role(s) data from the server."); if (Array.isArray(list)) { @@ -297,8 +297,8 @@ export class UserController extends Controller { province: { connect: provinceId ? { id: provinceId } : undefined }, district: { connect: districtId ? { id: districtId } : undefined }, subDistrict: { connect: subDistrictId ? { id: subDistrictId } : undefined }, - createdBy: req.user.name, - updatedBy: req.user.name, + createdBy: { connect: { id: req.user.sub } }, + updatedBy: { connect: { id: req.user.sub } }, }, }); @@ -355,7 +355,7 @@ export class UserController extends Controller { let userRole: string | undefined; if (body.userRole) { - let list = await getRoles(); + let list = await listRole(); if (!Array.isArray(list)) throw new Error("Failed. Cannot get role(s) data from the server."); if (Array.isArray(list)) { @@ -438,7 +438,7 @@ export class UserController extends Controller { connect: subDistrictId ? { id: subDistrictId } : undefined, disconnect: subDistrictId === null || undefined, }, - updatedBy: req.user.name, + updatedBy: { connect: { id: req.user.sub } }, }, where: { id: userId }, }); diff --git a/src/controllers/work/work-controller.ts b/src/controllers/work/work-controller.ts index 24577b7..f73f017 100644 --- a/src/controllers/work/work-controller.ts +++ b/src/controllers/work/work-controller.ts @@ -183,13 +183,13 @@ export class WorkController extends Controller { data: productId.map((v, i) => ({ order: i + 1, productId: v, - createdBy: req.user.name, - updatedBy: req.user.name, + createdByUserId: req.user.sub, + updatedByUserId: req.user.sub, })), }, }, - createdBy: req.user.name, - updatedBy: req.user.name, + createdByUserId: req.user.sub, + updatedByUserId: req.user.sub, }, }); @@ -281,13 +281,13 @@ export class WorkController extends Controller { create: { order: i + 1, productId: v, - createdBy: req.user.name, - updatedBy: req.user.name, + createdByUserId: req.user.sub, + updatedByUserId: req.user.sub, }, })), } : undefined, - updatedBy: req.user.name, + updatedByUserId: req.user.sub, }, }); diff --git a/src/services/keycloak.ts b/src/services/keycloak.ts index 984817f..4690e1f 100644 --- a/src/services/keycloak.ts +++ b/src/services/keycloak.ts @@ -59,6 +59,61 @@ export async function getToken() { return token; } +/** + * Get keycloak user list + * + * @returns user list if success, false otherwise. + */ +export async function listUser(search = "", page = 1, pageSize = 30) { + const res = await fetch( + `${KC_URL}/admin/realms/${KC_REALM}/users?first=${(page - 1) * pageSize}&max=${pageSize}`.concat( + !!search ? `&search=${search}` : "", + ), + { + headers: { + authorization: `Bearer ${await getToken()}`, + "content-type": `application/json`, + }, + }, + ).catch((e) => console.log("Keycloak Error: ", e)); + + if (!res) return; + if (!res.ok) { + return console.error("Keycloak Error Response: ", await res.json()); + } + return ((await res.json()) as any[]).map((v: Record) => ({ + id: v.id, + username: v.username, + firstName: v.firstName, + lastName: v.lastName, + email: v.email, + attributes: v.attributes, + })); +} + +/** + * Count user in the system. Can be use for pagination purpose. + * + * @returns numer of user on success. + */ +export async function countUser(search = "") { + const res = await fetch( + `${KC_URL}/admin/realms/${KC_REALM}/users/count`.concat(!!search ? `?search=${search}` : ""), + { + headers: { + authorization: `Bearer ${await getToken()}`, + "content-type": `application/json`, + }, + }, + ).catch((e) => console.log("Keycloak Error: ", e)); + + if (!res) return; + if (!res.ok) { + return console.error("Keycloak Error Response: ", await res.json()); + } + return (await res.json()) as number; +} + /** * Create keycloak user by given username and password with roles * @@ -151,36 +206,42 @@ export async function deleteUser(userId: string) { /** * Get roles list or specific role data - * - * Client must have permission to get realms roles - * - * @returns role's info (array if not specify name) if success, null if not found, false otherwise. */ -export async function getRoles(name?: string) { - const res = await fetch( - `${KC_URL}/admin/realms/${KC_REALM}/roles`.concat((name && `/${name}`) || ""), - { - // prettier-ignore - headers: { - "authorization": `Bearer ${await getToken()}`, +export async function listRole() { + const res = await fetch(`${KC_URL}/admin/realms/${KC_REALM}/roles`, { + headers: { + authorization: `Bearer ${await getToken()}`, }, - }, - ).catch((e) => console.log(e)); + }).catch((e) => console.log(e)); - if (!res) return false; + if (!res) return; if (!res.ok && res.status !== 404) { - return Boolean(console.error("Keycloak Error Response: ", await res.json())); + return console.error("Keycloak Error Response: ", await res.json()); } if (res.status === 404) { return null; } - const data = await res.json(); + const data = (await res.json()) as any[]; - if (Array.isArray(data)) { - return data.map((v: Record) => ({ id: v.id, name: v.name })); + return data.map((v: Record) => ({ id: v.id, name: v.name })); +} + +export async function getRoleByName(name: string) { + const res = await fetch(`${KC_URL}/admin/realms/${KC_REALM}/roles`.concat(`/${name}`), { + headers: { + authorization: `Bearer ${await getToken()}`, + }, + }).catch((e) => console.log(e)); + + if (!res) return; + if (!res.ok && res.status !== 404) { + return console.error("Keycloak Error Response: ", await res.json()); } + if (res.status === 404) return null; + + const data = (await res.json()) as any; return { id: data.id, @@ -285,7 +346,7 @@ export async function removeUserRoles(userId: string, roles: { id: string; name: export default { createUser, - getRoles, + listRole, addUserRoles, removeUserRoles, };