"""Localization & media-ref domain policies — Phase 11.5.""" from __future__ import annotations from typing import Any from app.models.types import LocalizationStatus, MediaRefStatus from app.validators.localization import ( ensure_localization_status_transition, ensure_media_ref_status_transition, ensure_no_binary_media_payload, validate_storage_file_ref, ) from shared.exceptions import AppError class SiteLocaleBindingPolicy: def assert_profile_usable(self, profile: Any) -> None: if profile is None: raise AppError( "پروفایل locale یافت نشد", error_code="locale_profile_not_found", status_code=404, ) if getattr(profile, "is_deleted", False): raise AppError( "پروفایل locale حذف‌شده قابل اتصال نیست", error_code="locale_profile_deleted", status_code=409, ) status = getattr(profile, "status", None) status_value = getattr(status, "value", status) if status_value in {"archived", "suspended", "inactive"}: raise AppError( "پروفایل locale غیرفعال قابل اتصال نیست", error_code="locale_profile_inactive", status_code=409, details={"status": status_value}, ) class LocalizationPolicy: def assert_status_change( self, *, current: LocalizationStatus, target: LocalizationStatus ) -> LocalizationStatus: ensure_localization_status_transition(current, target) return target class MediaRefPolicy: def assert_storage_ref_only( self, *, storage_file_ref: str, metadata_json: dict | None = None ) -> str: cleaned = validate_storage_file_ref(storage_file_ref) ensure_no_binary_media_payload(metadata_json) return cleaned def assert_status_change( self, *, current: MediaRefStatus, target: MediaRefStatus ) -> MediaRefStatus: ensure_media_ref_status_transition(current, target) return target