TorbatYar/backend/services/delivery/app/validators/foundation.py
Mortezakoohjani 5c6a2e78cf feat(platform): seed service registry, deploy all modules, and fix homepage catalog.
Register all active platform services and base features in core DB so admin can manage them, add delivery/hospitality/sports-center backend phases, update apps catalog and production deploy tooling.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-27 12:39:51 +03:30

56 lines
1.7 KiB
Python

"""Reusable validators for Delivery foundation."""
from __future__ import annotations
import re
from typing import Any
from shared.exceptions import AppError
CODE_RE = re.compile(r"^[a-zA-Z0-9][a-zA-Z0-9_\-]{1,49}$")
class ValidationError(AppError):
def __init__(self, message: str, details: dict[str, Any] | None = None):
super().__init__(
message=message,
error_code="validation_error",
status_code=422,
details=details or {},
)
def validate_non_empty(value: str | None, field: str) -> str:
if value is None or not str(value).strip():
raise ValidationError(f"{field} الزامی است", {"field": field})
return str(value).strip()
def validate_code(code: str) -> str:
code = validate_non_empty(code, "code")
if not CODE_RE.match(code):
raise ValidationError(
"کد نامعتبر است",
{"field": "code", "pattern": CODE_RE.pattern},
)
return code
def validate_currency_code(code: str) -> str:
code = validate_non_empty(code, "currency_code").upper()
if len(code) != 3:
raise ValidationError("currency_code باید ۳ حرفی باشد", {"field": "currency_code"})
return code
def ensure_optimistic_version(entity: Any, expected: int) -> None:
current = getattr(entity, "version", None)
if current is None:
return
if current != expected:
raise AppError(
"نسخه موجودیت هم‌خوان نیست",
error_code="version_conflict",
status_code=409,
details={"expected": expected, "actual": current},
)