Files
orion/models/schema/vendor_domain.py

128 lines
3.5 KiB
Python

# models/schema/vendor_domain.py
"""
Pydantic schemas for Vendor Domain operations.
Schemas include:
- VendorDomainCreate: For adding custom domains
- VendorDomainUpdate: For updating domain settings
- VendorDomainResponse: Standard domain response
- VendorDomainListResponse: Paginated domain list
- DomainVerificationInstructions: DNS verification instructions
"""
import re
from datetime import datetime
from typing import List, Optional, Dict
from pydantic import BaseModel, ConfigDict, Field, field_validator
class VendorDomainCreate(BaseModel):
"""Schema for adding a custom domain to vendor."""
domain: str = Field(
...,
description="Custom domain (e.g., myshop.com or shop.mybrand.com)",
min_length=3,
max_length=255
)
is_primary: bool = Field(
default=False,
description="Set as primary domain for the vendor"
)
@field_validator('domain')
@classmethod
def validate_domain(cls, v: str) -> str:
"""Validate and normalize domain."""
# Remove protocol if present
domain = v.replace("https://", "").replace("http://", "")
# Remove trailing slash
domain = domain.rstrip("/")
# Convert to lowercase
domain = domain.lower().strip()
# Basic validation
if not domain or '/' in domain:
raise ValueError("Invalid domain format")
if '.' not in domain:
raise ValueError("Domain must have at least one dot")
# Check for reserved subdomains
reserved = ['www', 'admin', 'api', 'mail', 'smtp', 'ftp', 'cpanel', 'webmail']
first_part = domain.split('.')[0]
if first_part in reserved:
raise ValueError(f"Domain cannot start with reserved subdomain: {first_part}")
# Validate domain format (basic regex)
domain_pattern = r'^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?(\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$'
if not re.match(domain_pattern, domain):
raise ValueError("Invalid domain format")
return domain
class VendorDomainUpdate(BaseModel):
"""Schema for updating vendor domain settings."""
is_primary: Optional[bool] = Field(None, description="Set as primary domain")
is_active: Optional[bool] = Field(None, description="Activate or deactivate domain")
model_config = ConfigDict(from_attributes=True)
class VendorDomainResponse(BaseModel):
"""Standard schema for vendor domain response."""
model_config = ConfigDict(from_attributes=True)
id: int
vendor_id: int
domain: str
is_primary: bool
is_active: bool
is_verified: bool
ssl_status: str
verification_token: Optional[str] = None
verified_at: Optional[datetime] = None
ssl_verified_at: Optional[datetime] = None
created_at: datetime
updated_at: datetime
class VendorDomainListResponse(BaseModel):
"""Schema for paginated vendor domain list."""
domains: List[VendorDomainResponse]
total: int
class DomainVerificationInstructions(BaseModel):
"""DNS verification instructions for domain ownership."""
domain: str
verification_token: str
instructions: Dict[str, str]
txt_record: Dict[str, str]
common_registrars: Dict[str, str]
model_config = ConfigDict(from_attributes=True)
class DomainVerificationResponse(BaseModel):
"""Response after domain verification."""
message: str
domain: str
verified_at: datetime
is_verified: bool
class DomainDeletionResponse(BaseModel):
"""Response after domain deletion."""
message: str
domain: str
vendor_id: int