Watch
1
0
Fork
You've already forked Seyyed_arc
0
forked from hesabix/arc
Seyyed_arc/hesabixAPI/app/services/file_dependency_service.py
2026-04-14 19:34:55 +03:30

173 lines
6.5 KiB
Python
Executable file

from __future__ import annotations
from dataclasses import dataclass, asdict
from typing import List, Optional
from uuid import UUID
from sqlalchemy.orm import Session
from adapters.db.models.file_storage import FileStorage
from adapters.db.models.product import Product
from adapters.db.models.business import Business
from adapters.db.models.user import User
@dataclass
class FileDependency:
module: str
entity_type: str
entity_id: str
description: str
def to_dict(self) -> dict:
return asdict(self)
class FileDependencyService:
"""Utility service to discover and cleanup file dependencies across modules."""
def __init__(self, db: Session):
self.db = db
def get_dependencies(self, file_storage: FileStorage) -> List[FileDependency]:
ctx = (file_storage.module_context or "").lower()
handler = getattr(self, f"_collect_{ctx}", None)
if handler:
dependencies = handler(file_storage)
else:
dependencies = []
if file_storage.context_id:
dependencies.append(
FileDependency(
module=file_storage.module_context or "unknown",
entity_type="context",
entity_id=str(file_storage.context_id),
description=f"Context ID {file_storage.context_id}",
)
)
return dependencies
def cleanup_dependencies(self, file_storage: FileStorage) -> List[FileDependency]:
"""Remove references to file inside business entities. Returns dependencies removed for logging."""
ctx = (file_storage.module_context or "").lower()
handler = getattr(self, f"_cleanup_{ctx}", None)
if handler:
dependencies = handler(file_storage)
if dependencies:
self.db.commit()
return dependencies
return []
# ---- Handlers ----
def _collect_products(self, file_storage: FileStorage) -> List[FileDependency]:
deps: List[FileDependency] = []
product = self._get_product(file_storage)
if product:
deps.append(
FileDependency(
module="products",
entity_type="product",
entity_id=str(product.id),
description=f"کالا: {product.name or product.code or product.id}",
)
)
return deps
def _cleanup_products(self, file_storage: FileStorage) -> List[FileDependency]:
deps = self._collect_products(file_storage)
product = self._get_product(file_storage)
if product and product.image_file_id == str(file_storage.id):
product.image_file_id = None
self.db.flush()
return deps
def _collect_business_logo(self, file_storage: FileStorage) -> List[FileDependency]:
deps: List[FileDependency] = []
business = self._get_business(file_storage.business_id)
if business and business.logo_file_id == str(file_storage.id):
deps.append(
FileDependency(
module="business_logo",
entity_type="business",
entity_id=str(business.id),
description=f"لوگوی کسب‌وکار: {business.name or business.id}",
)
)
return deps
def _cleanup_business_logo(self, file_storage: FileStorage) -> List[FileDependency]:
deps = self._collect_business_logo(file_storage)
business = self._get_business(file_storage.business_id)
if business and business.logo_file_id == str(file_storage.id):
business.logo_file_id = None
self.db.flush()
return deps
def _collect_business_stamp(self, file_storage: FileStorage) -> List[FileDependency]:
deps: List[FileDependency] = []
business = self._get_business(file_storage.business_id)
if business and business.stamp_file_id == str(file_storage.id):
deps.append(
FileDependency(
module="business_stamp",
entity_type="business",
entity_id=str(business.id),
description=f"مهر/امضای کسب‌وکار: {business.name or business.id}",
)
)
return deps
def _cleanup_business_stamp(self, file_storage: FileStorage) -> List[FileDependency]:
deps = self._collect_business_stamp(file_storage)
business = self._get_business(file_storage.business_id)
if business and business.stamp_file_id == str(file_storage.id):
business.stamp_file_id = None
self.db.flush()
return deps
def _collect_user_signature(self, file_storage: FileStorage) -> List[FileDependency]:
deps: List[FileDependency] = []
user = self.db.query(User).filter(User.signature_file_id == str(file_storage.id)).first()
if user:
deps.append(
FileDependency(
module="user_signature",
entity_type="user",
entity_id=str(user.id),
description=f"امضای کاربر: {user.full_name or user.username or user.id}",
)
)
return deps
def _cleanup_user_signature(self, file_storage: FileStorage) -> List[FileDependency]:
deps = self._collect_user_signature(file_storage)
user = self.db.query(User).filter(User.signature_file_id == str(file_storage.id)).first()
if user:
user.signature_file_id = None
self.db.flush()
return deps
# ---- Helpers ----
def _get_product(self, file_storage: FileStorage) -> Optional[Product]:
query = self.db.query(Product)
product_id: Optional[int] = None
if file_storage.context_id:
try:
product_id = int(file_storage.context_id)
except (TypeError, ValueError):
product_id = None
if product_id:
query = query.filter(Product.id == product_id)
else:
query = query.filter(Product.image_file_id == str(file_storage.id))
if file_storage.business_id:
query = query.filter(Product.business_id == file_storage.business_id)
return query.first()
def _get_business(self, business_id: Optional[int]) -> Optional[Business]:
if not business_id:
return None
return self.db.query(Business).filter(Business.id == business_id).first()