"""Instance schemas for API serialization.""" from datetime import datetime from typing import Optional from uuid import UUID from pydantic import BaseModel, ConfigDict, Field class InstanceCreate(BaseModel): """Schema for creating a new instance.""" instance_id: str = Field( ..., min_length=1, max_length=255, description="Unique instance identifier (e.g., 'acme-orchestrator')", ) region: Optional[str] = Field(None, max_length=50, description="Deployment region") license_expires_at: Optional[datetime] = Field( None, description="License expiry date (None = perpetual)", ) class InstanceResponse(BaseModel): """Schema for instance API responses. Note: license_key and hub_api_key are ONLY returned on creation. """ model_config = ConfigDict(from_attributes=True) id: UUID instance_id: str client_id: UUID # License info license_key: Optional[str] = Field( None, description="ONLY returned on creation - store securely!", ) license_key_prefix: str license_status: str license_issued_at: datetime license_expires_at: Optional[datetime] # Hub API key hub_api_key: Optional[str] = Field( None, description="ONLY returned on creation - store securely!", ) # Activation state activated_at: Optional[datetime] last_activation_at: Optional[datetime] activation_count: int # Metadata region: Optional[str] version: Optional[str] last_seen_at: Optional[datetime] status: str created_at: datetime updated_at: datetime class InstanceBriefResponse(BaseModel): """Brief instance response for listings (no secrets).""" model_config = ConfigDict(from_attributes=True) id: UUID instance_id: str client_id: UUID license_key_prefix: str license_status: str license_expires_at: Optional[datetime] activated_at: Optional[datetime] activation_count: int region: Optional[str] status: str created_at: datetime # === ACTIVATION SCHEMAS === class ActivationRequest(BaseModel): """ Activation request from a client instance. PRIVACY: This schema ONLY accepts: - license_key (credential for validation) - instance_id (identifier) It NEVER accepts sensitive data fields. """ license_key: str = Field(..., description="License key (lb_inst_...)") instance_id: str = Field(..., description="Instance identifier") class ActivationResponse(BaseModel): """Response to a successful activation.""" status: str = Field("ok", description="Activation status") instance_id: str hub_api_key: str = Field( ..., description="API key for telemetry auth (or 'USE_EXISTING')", ) config: dict = Field( default_factory=dict, description="Optional configuration from Hub", ) class ActivationError(BaseModel): """Error response for failed activation.""" error: str = Field(..., description="Human-readable error message") code: str = Field( ..., description="Error code: invalid_license, expired, suspended, instance_not_found", )