add business categories CRUD module

This commit is contained in:
2026-05-07 19:11:14 +03:30
parent 53113d8108
commit 729cc9f4b9
16 changed files with 3263 additions and 1 deletions
@@ -0,0 +1,61 @@
import {
Column,
CreateDateColumn,
Entity,
JoinColumn,
ManyToOne,
OneToMany,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from 'typeorm';
import { BusinessAttributeValueEntity } from './business-attribute-value.entity';
import { BusinessCategoryEntity } from './business-category.entity';
export enum AttributeType {
BOOLEAN = 'boolean',
TEXT = 'text',
NUMBER = 'number',
SELECT = 'select',
}
@Entity('attribute_definitions')
export class AttributeDefinitionEntity {
@PrimaryGeneratedColumn('uuid')
id!: string;
@Column({ length: 120 })
title!: string;
@Column({ length: 120 })
key!: string;
@Column({ type: 'enum', enum: AttributeType })
type!: AttributeType;
@Column({ type: 'simple-array', nullable: true })
options!: string[] | null;
@Column({ default: false })
required!: boolean;
@Column({ default: true })
isFilterable!: boolean;
@ManyToOne(() => BusinessCategoryEntity, (category) => category.attributeDefinitions, {
onDelete: 'CASCADE',
})
@JoinColumn({ name: 'categoryId' })
category!: BusinessCategoryEntity;
@Column('uuid')
categoryId!: string;
@OneToMany(() => BusinessAttributeValueEntity, (value) => value.attributeDefinition)
values!: BusinessAttributeValueEntity[];
@CreateDateColumn()
createdAt!: Date;
@UpdateDateColumn()
updatedAt!: Date;
}
+63
View File
@@ -0,0 +1,63 @@
import {
Column,
CreateDateColumn,
Entity,
JoinColumn,
ManyToOne,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from 'typeorm';
import { BusinessEntity } from './business.entity';
import { BusinessServiceEntity } from './business-service.entity';
import { UserEntity } from './user.entity';
export enum BookingStatus {
PENDING = 'pending',
CONFIRMED = 'confirmed',
CANCELLED = 'cancelled',
COMPLETED = 'completed',
}
@Entity('bookings')
export class BookingEntity {
@PrimaryGeneratedColumn('uuid')
id!: string;
@ManyToOne(() => UserEntity, (user) => user.bookings, { onDelete: 'RESTRICT' })
@JoinColumn({ name: 'customerId' })
customer!: UserEntity;
@Column('uuid')
customerId!: string;
@ManyToOne(() => BusinessEntity, (business) => business.bookings, { onDelete: 'RESTRICT' })
@JoinColumn({ name: 'businessId' })
business!: BusinessEntity;
@Column('uuid')
businessId!: string;
@ManyToOne(() => BusinessServiceEntity, (service) => service.bookings, {
onDelete: 'RESTRICT',
})
@JoinColumn({ name: 'businessServiceId' })
businessService!: BusinessServiceEntity;
@Column('uuid')
businessServiceId!: string;
@Column({ type: 'timestamptz' })
scheduledAt!: Date;
@Column({ type: 'enum', enum: BookingStatus, default: BookingStatus.PENDING })
status!: BookingStatus;
@Column({ type: 'text', nullable: true })
note!: string | null;
@CreateDateColumn()
createdAt!: Date;
@UpdateDateColumn()
updatedAt!: Date;
}
@@ -0,0 +1,46 @@
import {
Column,
CreateDateColumn,
Entity,
JoinColumn,
ManyToOne,
PrimaryGeneratedColumn,
Unique,
UpdateDateColumn,
} from 'typeorm';
import { AttributeDefinitionEntity } from './attribute-definition.entity';
import { BusinessEntity } from './business.entity';
@Entity('business_attribute_values')
@Unique('UQ_business_attribute_value', ['businessId', 'attributeDefinitionId'])
export class BusinessAttributeValueEntity {
@PrimaryGeneratedColumn('uuid')
id!: string;
@ManyToOne(() => BusinessEntity, (business) => business.attributes, {
onDelete: 'CASCADE',
})
@JoinColumn({ name: 'businessId' })
business!: BusinessEntity;
@Column('uuid')
businessId!: string;
@ManyToOne(() => AttributeDefinitionEntity, (definition) => definition.values, {
onDelete: 'CASCADE',
})
@JoinColumn({ name: 'attributeDefinitionId' })
attributeDefinition!: AttributeDefinitionEntity;
@Column('uuid')
attributeDefinitionId!: string;
@Column({ type: 'text', nullable: true })
value!: string | null;
@CreateDateColumn()
createdAt!: Date;
@UpdateDateColumn()
updatedAt!: Date;
}
+41
View File
@@ -0,0 +1,41 @@
import {
Column,
CreateDateColumn,
Entity,
OneToMany,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from 'typeorm';
import { AttributeDefinitionEntity } from './attribute-definition.entity';
import { BusinessEntity } from './business.entity';
import { ServiceTemplateEntity } from './service-template.entity';
@Entity('business_categories')
export class BusinessCategoryEntity {
@PrimaryGeneratedColumn('uuid')
id!: string;
@Column({ unique: true, length: 100 })
slug!: string;
@Column({ length: 150 })
title!: string;
@Column({ default: true })
isActive!: boolean;
@OneToMany(() => BusinessEntity, (business) => business.category)
businesses!: BusinessEntity[];
@OneToMany(() => ServiceTemplateEntity, (service) => service.category)
serviceTemplates!: ServiceTemplateEntity[];
@OneToMany(() => AttributeDefinitionEntity, (attribute) => attribute.category)
attributeDefinitions!: AttributeDefinitionEntity[];
@CreateDateColumn()
createdAt!: Date;
@UpdateDateColumn()
updatedAt!: Date;
}
+57
View File
@@ -0,0 +1,57 @@
import {
Column,
CreateDateColumn,
Entity,
JoinColumn,
ManyToOne,
OneToMany,
PrimaryGeneratedColumn,
Unique,
UpdateDateColumn,
} from 'typeorm';
import { BookingEntity } from './booking.entity';
import { BusinessEntity } from './business.entity';
import { ServiceTemplateEntity } from './service-template.entity';
@Entity('business_services')
@Unique('UQ_business_service', ['businessId', 'serviceTemplateId'])
export class BusinessServiceEntity {
@PrimaryGeneratedColumn('uuid')
id!: string;
@ManyToOne(() => BusinessEntity, (business) => business.services, {
onDelete: 'CASCADE',
})
@JoinColumn({ name: 'businessId' })
business!: BusinessEntity;
@Column('uuid')
businessId!: string;
@ManyToOne(() => ServiceTemplateEntity, (serviceTemplate) => serviceTemplate.businessServices, {
onDelete: 'RESTRICT',
})
@JoinColumn({ name: 'serviceTemplateId' })
serviceTemplate!: ServiceTemplateEntity;
@Column('uuid')
serviceTemplateId!: string;
@Column({ type: 'numeric', precision: 12, scale: 2 })
price!: string;
@Column({ type: 'int', nullable: true })
durationMinutes!: number | null;
@Column({ default: true })
isActive!: boolean;
@OneToMany(() => BookingEntity, (booking) => booking.businessService)
bookings!: BookingEntity[];
@CreateDateColumn()
createdAt!: Date;
@UpdateDateColumn()
updatedAt!: Date;
}
+79
View File
@@ -0,0 +1,79 @@
import {
Column,
CreateDateColumn,
Entity,
JoinColumn,
ManyToOne,
OneToMany,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from 'typeorm';
import { BookingEntity } from './booking.entity';
import { BusinessAttributeValueEntity } from './business-attribute-value.entity';
import { BusinessCategoryEntity } from './business-category.entity';
import { BusinessServiceEntity } from './business-service.entity';
import { UserEntity } from './user.entity';
@Entity('businesses')
export class BusinessEntity {
@PrimaryGeneratedColumn('uuid')
id!: string;
@Column({ length: 150 })
title!: string;
@Column({ unique: true, length: 120 })
slug!: string;
@Column({ nullable: true, length: 500 })
description!: string | null;
@Column({ nullable: true, length: 20 })
contactPhone!: string | null;
@Column({ nullable: true, length: 500 })
address!: string | null;
@Column({ type: 'double precision', nullable: true })
latitude!: number | null;
@Column({ type: 'double precision', nullable: true })
longitude!: number | null;
@Column({ default: true })
isActive!: boolean;
@ManyToOne(() => BusinessCategoryEntity, (category) => category.businesses, {
onDelete: 'RESTRICT',
})
@JoinColumn({ name: 'categoryId' })
category!: BusinessCategoryEntity;
@Column('uuid')
categoryId!: string;
@ManyToOne(() => UserEntity, (user) => user.ownedBusinesses, {
nullable: true,
onDelete: 'SET NULL',
})
@JoinColumn({ name: 'ownerId' })
owner!: UserEntity | null;
@Column({ type: 'uuid', nullable: true })
ownerId!: string | null;
@OneToMany(() => BusinessServiceEntity, (service) => service.business)
services!: BusinessServiceEntity[];
@OneToMany(() => BusinessAttributeValueEntity, (attr) => attr.business)
attributes!: BusinessAttributeValueEntity[];
@OneToMany(() => BookingEntity, (booking) => booking.business)
bookings!: BookingEntity[];
@CreateDateColumn()
createdAt!: Date;
@UpdateDateColumn()
updatedAt!: Date;
}
+51
View File
@@ -0,0 +1,51 @@
import {
Column,
CreateDateColumn,
Entity,
JoinColumn,
ManyToOne,
OneToMany,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from 'typeorm';
import { BusinessCategoryEntity } from './business-category.entity';
import { BusinessServiceEntity } from './business-service.entity';
@Entity('service_templates')
export class ServiceTemplateEntity {
@PrimaryGeneratedColumn('uuid')
id!: string;
@Column({ length: 120 })
title!: string;
@Column({ unique: true, length: 120 })
slug!: string;
@Column({ nullable: true, length: 400 })
description!: string | null;
@Column({ type: 'int', default: 30 })
defaultDurationMinutes!: number;
@Column({ default: true })
isActive!: boolean;
@ManyToOne(() => BusinessCategoryEntity, (category) => category.serviceTemplates, {
onDelete: 'CASCADE',
})
@JoinColumn({ name: 'categoryId' })
category!: BusinessCategoryEntity;
@Column('uuid')
categoryId!: string;
@OneToMany(() => BusinessServiceEntity, (service) => service.serviceTemplate)
businessServices!: BusinessServiceEntity[];
@CreateDateColumn()
createdAt!: Date;
@UpdateDateColumn()
updatedAt!: Date;
}
+46
View File
@@ -0,0 +1,46 @@
import {
Column,
CreateDateColumn,
Entity,
OneToMany,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from 'typeorm';
import { BookingEntity } from './booking.entity';
import { BusinessEntity } from './business.entity';
export enum UserRole {
CUSTOMER = 'customer',
BUSINESS_OWNER = 'business_owner',
ADMIN = 'admin',
}
@Entity('users')
export class UserEntity {
@PrimaryGeneratedColumn('uuid')
id!: string;
@Column({ unique: true, length: 20 })
mobile!: string;
@Column({ nullable: true, length: 150 })
fullName!: string | null;
@Column({ type: 'enum', enum: UserRole, default: UserRole.CUSTOMER })
role!: UserRole;
@Column({ default: true })
isActive!: boolean;
@OneToMany(() => BusinessEntity, (business) => business.owner)
ownedBusinesses!: BusinessEntity[];
@OneToMany(() => BookingEntity, (booking) => booking.customer)
bookings!: BookingEntity[];
@CreateDateColumn()
createdAt!: Date;
@UpdateDateColumn()
updatedAt!: Date;
}