delete business

This commit is contained in:
2026-05-31 17:02:41 +03:30
parent a4e9761825
commit 9afd54b522
4 changed files with 34 additions and 17 deletions
+4 -7
View File
@@ -4,26 +4,24 @@ import { AttributeDefinitionEntity } from '../../entities/attribute-definition.e
import { BookingEntity } from '../../entities/booking.entity'; import { BookingEntity } from '../../entities/booking.entity';
import { BusinessAttributeValueEntity } from '../../entities/business-attribute-value.entity'; import { BusinessAttributeValueEntity } from '../../entities/business-attribute-value.entity';
import { BusinessCategoryEntity } from '../../entities/business-category.entity'; import { BusinessCategoryEntity } from '../../entities/business-category.entity';
import { BusinessServiceRequestEntity } from '../../entities/business-service-request.entity';
import { BusinessServiceEntity } from '../../entities/business-service.entity'; import { BusinessServiceEntity } from '../../entities/business-service.entity';
import { BusinessImageEntity } from '../../entities/business-image.entity'; import { BusinessImageEntity } from '../../entities/business-image.entity';
import { BusinessAvailabilitySlotEntity } from '../../entities/business-availability-slot.entity'; import { BusinessAvailabilitySlotEntity } from '../../entities/business-availability-slot.entity';
import { BusinessEntity } from '../../entities/business.entity'; import { BusinessEntity } from '../../entities/business.entity';
import { ServiceTemplateEntity } from '../../entities/service-template.entity'; import { ServiceTemplateEntity } from '../../entities/service-template.entity';
/** Remove a business and all rows that block FK deletes in production DB. */ /** Remove a business and dependent rows that block FK deletes. */
export async function deleteBusinessCascade( export async function deleteBusinessCascade(
manager: EntityManager, manager: EntityManager,
businessId: string, businessId: string,
onBeforeDeleteBusiness?: (businessId: string) => Promise<void>,
): Promise<void> { ): Promise<void> {
await manager.delete(BookingEntity, { businessId }); await manager.delete(BookingEntity, { businessId });
await manager.delete(BusinessServiceRequestEntity, { businessId });
await manager.delete(BusinessAvailabilitySlotEntity, { businessId }); await manager.delete(BusinessAvailabilitySlotEntity, { businessId });
await manager.delete(BusinessServiceEntity, { businessId }); await manager.delete(BusinessServiceEntity, { businessId });
await manager.delete(BusinessAttributeValueEntity, { businessId }); await manager.delete(BusinessAttributeValueEntity, { businessId });
await manager.delete(BusinessImageEntity, { businessId }); await manager.delete(BusinessImageEntity, { businessId });
if (onBeforeDeleteBusiness) {
await onBeforeDeleteBusiness(businessId);
}
const result = await manager.delete(BusinessEntity, businessId); const result = await manager.delete(BusinessEntity, businessId);
if (!result.affected) { if (!result.affected) {
@@ -36,10 +34,9 @@ export async function deleteCategoryCascade(
manager: EntityManager, manager: EntityManager,
categoryId: string, categoryId: string,
businessIds: string[], businessIds: string[],
onBeforeDeleteBusiness?: (businessId: string) => Promise<void>,
): Promise<void> { ): Promise<void> {
for (const businessId of businessIds) { for (const businessId of businessIds) {
await deleteBusinessCascade(manager, businessId, onBeforeDeleteBusiness); await deleteBusinessCascade(manager, businessId);
} }
await manager.delete(ServiceTemplateEntity, { categoryId }); await manager.delete(ServiceTemplateEntity, { categoryId });
@@ -89,10 +89,16 @@ export class BusinessCategoriesService {
}); });
const businessIds = businesses.map((b) => b.id); const businessIds = businesses.map((b) => b.id);
const imageUrls = (
await Promise.all(
businessIds.map((businessId) => this.images.listUrlsForBusiness(businessId)),
)
).flat();
await this.dataSource.transaction(async (manager) => { await this.dataSource.transaction(async (manager) => {
await deleteCategoryCascade(manager, id, businessIds, async (businessId) => { await deleteCategoryCascade(manager, id, businessIds);
await this.images.removeAllForBusiness(businessId);
});
}); });
this.images.deleteFiles(imageUrls);
} }
} }
@@ -116,11 +116,23 @@ export class BusinessImagesService {
} }
} }
async removeAllForBusiness(businessId: string): Promise<void> { async listUrlsForBusiness(businessId: string): Promise<string[]> {
const images = await this.imageRepo.find({ where: { businessId } }); const images = await this.imageRepo.find({
for (const image of images) { where: { businessId },
this.deleteFile(image.url); select: ['url'],
});
return images.map((image) => image.url);
}
deleteFiles(urls: string[]): void {
for (const url of urls) {
this.deleteFile(url);
} }
}
async removeAllForBusiness(businessId: string): Promise<void> {
const urls = await this.listUrlsForBusiness(businessId);
this.deleteFiles(urls);
await this.imageRepo.delete({ businessId }); await this.imageRepo.delete({ businessId });
} }
+5 -3
View File
@@ -148,11 +148,13 @@ export class BusinessesService {
async remove(id: string): Promise<void> { async remove(id: string): Promise<void> {
await this.findOne(id); await this.findOne(id);
const imageUrls = await this.images.listUrlsForBusiness(id);
await this.dataSource.transaction(async (manager) => { await this.dataSource.transaction(async (manager) => {
await deleteBusinessCascade(manager, id, async (businessId) => { await deleteBusinessCascade(manager, id);
await this.images.removeAllForBusiness(businessId);
});
}); });
this.images.deleteFiles(imageUrls);
} }
async getAvailability(businessId: string) { async getAvailability(businessId: string) {