feat: implement inventory, product brand, product category, product info, product, role, store, user, and vendor modules with CRUD operations

- Added Create and Update DTOs for Inventory, Product Brand, Product Category, Product Info, Product, Role, Store, User, and Vendor.
- Implemented InventoriesController, ProductBrandsController, ProductCategoriesController, ProductInfoController, ProductsController, RolesController, StoresController, UsersController, and VendorsController with respective CRUD endpoints.
- Developed InventoriesService, ProductBrandsService, ProductCategoriesService, ProductInfoService, ProductsService, RolesService, StoresService, UsersService, and VendorsService to handle business logic.
- Created PrismaModule and PrismaService for database interactions using Prisma with MariaDB adapter.
- Configured application with Swagger for API documentation and added global interceptors for logging and response mapping.
- Established e2e testing setup with Jest for the application.
This commit is contained in:
2025-12-04 21:05:57 +03:30
commit 621e15dd02
98 changed files with 26046 additions and 0 deletions
@@ -0,0 +1,172 @@
-- CreateTable
CREATE TABLE `Users` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`mobileNumber` CHAR(11) NOT NULL,
`password` VARCHAR(191) NOT NULL,
`firstName` VARCHAR(191) NOT NULL,
`lastName` VARCHAR(191) NOT NULL,
`roleId` INTEGER NOT NULL,
UNIQUE INDEX `Users_mobileNumber_key`(`mobileNumber`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `Roles` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`name` VARCHAR(100) NOT NULL,
`description` TEXT NULL,
`permissions` JSON NULL,
`createdAt` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
`updatedAt` TIMESTAMP(0) NOT NULL,
`deletedAt` TIMESTAMP(0) NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `Products` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL,
`description` TEXT NULL,
`sku` VARCHAR(100) NULL,
`barcode` VARCHAR(100) NULL,
`imageUrl` VARCHAR(255) NULL,
`attachmentId` BIGINT UNSIGNED NULL,
`unit` VARCHAR(10) NOT NULL,
`discount` DECIMAL(10, 2) NOT NULL DEFAULT 0.00,
`quantity` DECIMAL(10, 2) NOT NULL DEFAULT 0.00,
`alertQuantity` DECIMAL(10, 2) NOT NULL DEFAULT 5.00,
`isActive` BOOLEAN NOT NULL DEFAULT true,
`isFeatured` BOOLEAN NOT NULL DEFAULT false,
`createdAt` TIMESTAMP(0) NULL,
`updatedAt` TIMESTAMP(0) NULL,
`deletedAt` TIMESTAMP(0) NULL,
`productInfoId` INTEGER NOT NULL,
UNIQUE INDEX `products_sku_unique`(`sku`),
UNIQUE INDEX `products_barcode_unique`(`barcode`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `Product_info` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL,
`description` TEXT NULL,
`productType` VARCHAR(50) NULL DEFAULT 'simple',
`metaData` JSON NULL,
`createdAt` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
`updatedAt` TIMESTAMP(0) NOT NULL,
`deletedAt` TIMESTAMP(0) NULL,
`brandId` INTEGER NULL,
`categoryId` INTEGER NULL,
`vendorId` INTEGER NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `Product_brands` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`name` VARCHAR(100) NOT NULL,
`description` TEXT NULL,
`imageUrl` VARCHAR(255) NULL,
`createdAt` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
`updatedAt` TIMESTAMP(0) NOT NULL,
`deletedAt` TIMESTAMP(0) NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `Product_categories` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`name` VARCHAR(100) NOT NULL,
`description` TEXT NULL,
`imageUrl` VARCHAR(255) NULL,
`createdAt` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
`updatedAt` TIMESTAMP(0) NOT NULL,
`deletedAt` TIMESTAMP(0) NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `Vendors` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`firstName` VARCHAR(255) NOT NULL,
`lastName` VARCHAR(255) NOT NULL,
`email` VARCHAR(255) NULL,
`mobileNumber` CHAR(11) NOT NULL,
`address` TEXT NULL,
`city` VARCHAR(100) NULL,
`state` VARCHAR(100) NULL,
`country` VARCHAR(100) NULL,
`isActive` BOOLEAN NOT NULL DEFAULT true,
`createdAt` TIMESTAMP(0) NULL,
`updatedAt` TIMESTAMP(0) NULL,
`deletedAt` TIMESTAMP(0) NULL,
UNIQUE INDEX `Vendors_mobileNumber_key`(`mobileNumber`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `Customers` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`firstName` VARCHAR(255) NOT NULL,
`lastName` VARCHAR(255) NOT NULL,
`email` VARCHAR(255) NULL,
`mobileNumber` CHAR(11) NOT NULL,
`address` TEXT NULL,
`city` VARCHAR(100) NULL,
`state` VARCHAR(100) NULL,
`country` VARCHAR(100) NULL,
`isActive` BOOLEAN NOT NULL DEFAULT true,
`createdAt` TIMESTAMP(0) NULL,
`updatedAt` TIMESTAMP(0) NULL,
`deletedAt` TIMESTAMP(0) NULL,
UNIQUE INDEX `Customers_mobileNumber_key`(`mobileNumber`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `Inventories` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL,
`location` VARCHAR(255) NULL,
`isActive` BOOLEAN NOT NULL DEFAULT true,
`createdAt` TIMESTAMP(0) NOT NULL,
`updatedAt` TIMESTAMP(0) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `Stores` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL,
`location` VARCHAR(255) NULL,
`isActive` BOOLEAN NOT NULL DEFAULT true,
`createdAt` TIMESTAMP(0) NOT NULL,
`updatedAt` TIMESTAMP(0) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- AddForeignKey
ALTER TABLE `Users` ADD CONSTRAINT `Users_roleId_fkey` FOREIGN KEY (`roleId`) REFERENCES `Roles`(`id`) ON DELETE RESTRICT ON UPDATE NO ACTION;
-- AddForeignKey
ALTER TABLE `Products` ADD CONSTRAINT `Products_productInfoId_fkey` FOREIGN KEY (`productInfoId`) REFERENCES `Product_info`(`id`) ON DELETE RESTRICT ON UPDATE NO ACTION;
-- AddForeignKey
ALTER TABLE `Product_info` ADD CONSTRAINT `Product_info_brandId_fkey` FOREIGN KEY (`brandId`) REFERENCES `Product_brands`(`id`) ON DELETE SET NULL ON UPDATE NO ACTION;
-- AddForeignKey
ALTER TABLE `Product_info` ADD CONSTRAINT `Product_info_categoryId_fkey` FOREIGN KEY (`categoryId`) REFERENCES `Product_categories`(`id`) ON DELETE SET NULL ON UPDATE NO ACTION;
-- AddForeignKey
ALTER TABLE `Product_info` ADD CONSTRAINT `Product_info_vendorId_fkey` FOREIGN KEY (`vendorId`) REFERENCES `Vendors`(`id`) ON DELETE RESTRICT ON UPDATE NO ACTION;
+3
View File
@@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (e.g., Git)
provider = "mysql"
+181
View File
@@ -0,0 +1,181 @@
datasource db {
provider = "mysql"
}
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
moduleFormat = "cjs"
}
model User {
id Int @id @default(autoincrement())
mobileNumber String @unique @db.Char(11)
password String
firstName String
lastName String
roleId Int
role Role @relation("User_Role", fields: [roleId], references: [id], onUpdate: NoAction)
@@map("Users")
}
model Role {
id Int @id @default(autoincrement())
name String @db.VarChar(100)
description String? @db.Text
permissions Json?
createdAt DateTime @default(now()) @db.Timestamp(0)
updatedAt DateTime @updatedAt @db.Timestamp(0)
deletedAt DateTime? @db.Timestamp(0)
users User[] @relation("User_Role")
@@map("Roles")
}
model Product {
id Int @id @default(autoincrement())
name String @db.VarChar(255)
description String? @db.Text
sku String? @unique(map: "products_sku_unique") @db.VarChar(100)
barcode String? @unique(map: "products_barcode_unique") @db.VarChar(100)
imageUrl String? @db.VarChar(255)
attachmentId BigInt? @db.UnsignedBigInt
unit String @db.VarChar(10)
discount Decimal @default(0.00) @db.Decimal(10, 2)
quantity Decimal @default(0.00) @db.Decimal(10, 2)
alertQuantity Decimal @default(5.00) @db.Decimal(10, 2)
isActive Boolean @default(true)
isFeatured Boolean @default(false)
createdAt DateTime? @db.Timestamp(0)
updatedAt DateTime? @db.Timestamp(0)
deletedAt DateTime? @db.Timestamp(0)
productInfo ProductInfo @relation("Product_ProductInfo", fields: [productInfoId], references: [id], onUpdate: NoAction)
productInfoId Int
// is_stock_managed Boolean @default(true)
// created_by Int?
// collection_product collection_product[]
// product_batches product_batches[]
// product_stocks product_stocks[]
// attachments attachments? @relation(fields: [attachment_id], references: [id], onUpdate: NoAction, map: "products_attachment_id_foreign")
// purchase_items purchase_items[]
// sale_items sale_items[]
// @@index([attachment_id], map: "products_attachment_id_foreign")
@@map("Products")
}
model ProductInfo {
id Int @id @default(autoincrement())
name String @db.VarChar(255)
description String? @db.Text
productType String? @default("simple") @db.VarChar(50)
metaData Json?
createdAt DateTime @default(now()) @db.Timestamp(0)
updatedAt DateTime @updatedAt @db.Timestamp(0)
deletedAt DateTime? @db.Timestamp(0)
products Product[] @relation("Product_ProductInfo")
brand ProductBrand? @relation("ProductInfo_Brand", fields: [brandId], references: [id], onUpdate: NoAction)
brandId Int?
category ProductCategory? @relation("ProductInfo_Category", fields: [categoryId], references: [id], onUpdate: NoAction)
categoryId Int?
vendor Vendor @relation("ProductInfo_Vendor", fields: [vendorId], references: [id], onUpdate: NoAction)
vendorId Int
@@map("Product_info")
}
model ProductBrand {
id Int @id @default(autoincrement())
name String @db.VarChar(100)
description String? @db.Text
imageUrl String? @db.VarChar(255)
createdAt DateTime @default(now()) @db.Timestamp(0)
updatedAt DateTime @updatedAt @db.Timestamp(0)
deletedAt DateTime? @db.Timestamp(0)
productInfo ProductInfo[] @relation("ProductInfo_Brand")
@@map("Product_brands")
}
model ProductCategory {
id Int @id @default(autoincrement())
name String @db.VarChar(100)
description String? @db.Text
imageUrl String? @db.VarChar(255)
createdAt DateTime @default(now()) @db.Timestamp(0)
updatedAt DateTime @updatedAt @db.Timestamp(0)
deletedAt DateTime? @db.Timestamp(0)
productInfo ProductInfo[] @relation("ProductInfo_Category")
@@map("Product_categories")
}
model Vendor {
id Int @id @default(autoincrement())
firstName String @db.VarChar(255)
lastName String @db.VarChar(255)
email String? @db.VarChar(255)
mobileNumber String @unique @db.Char(11)
address String? @db.Text
city String? @db.VarChar(100)
state String? @db.VarChar(100)
country String? @db.VarChar(100)
isActive Boolean @default(true)
createdAt DateTime? @db.Timestamp(0)
updatedAt DateTime? @db.Timestamp(0)
deletedAt DateTime? @db.Timestamp(0)
productInfo ProductInfo[] @relation("ProductInfo_Vendor")
@@map("Vendors")
}
model Customer {
id Int @id @default(autoincrement())
firstName String @db.VarChar(255)
lastName String @db.VarChar(255)
email String? @db.VarChar(255)
mobileNumber String @unique @db.Char(11)
address String? @db.Text
city String? @db.VarChar(100)
state String? @db.VarChar(100)
country String? @db.VarChar(100)
isActive Boolean @default(true)
createdAt DateTime? @db.Timestamp(0)
updatedAt DateTime? @db.Timestamp(0)
deletedAt DateTime? @db.Timestamp(0)
@@map("Customers")
}
model Inventory {
id Int @id @default(autoincrement())
name String @db.VarChar(255)
location String? @db.VarChar(255)
isActive Boolean @default(true)
createdAt DateTime @db.Timestamp(0)
updatedAt DateTime @db.Timestamp(0)
@@map("Inventories")
}
model Store {
id Int @id @default(autoincrement())
name String @db.VarChar(255)
location String? @db.VarChar(255)
isActive Boolean @default(true)
createdAt DateTime @db.Timestamp(0)
updatedAt DateTime @db.Timestamp(0)
@@map("Stores")
}