# [DEF:backend.src.schemas.profile:Module] # # @TIER: STANDARD # @SEMANTICS: profile, schemas, pydantic, preferences, superset, lookup # @PURPOSE: Defines API schemas for profile preference persistence and Superset account lookup flows. # @LAYER: API # @RELATION: DEPENDS_ON -> pydantic # # @INVARIANT: Schema shapes stay stable for profile UI states and dashboards filter metadata. # [SECTION: IMPORTS] from datetime import datetime from typing import List, Literal, Optional from pydantic import BaseModel, Field # [/SECTION] # [DEF:ProfilePreference:Class] # @TIER: STANDARD # @PURPOSE: Represents persisted profile preference for a single authenticated user. class ProfilePreference(BaseModel): user_id: str superset_username: Optional[str] = None superset_username_normalized: Optional[str] = None show_only_my_dashboards: bool = False created_at: datetime updated_at: datetime class Config: from_attributes = True # [/DEF:ProfilePreference:Class] # [DEF:ProfilePreferenceUpdateRequest:Class] # @TIER: STANDARD # @PURPOSE: Request payload for updating current user's dashboard filter preference. class ProfilePreferenceUpdateRequest(BaseModel): superset_username: Optional[str] = Field( default=None, description="Apache Superset username bound to current user profile.", ) show_only_my_dashboards: bool = Field( default=False, description='When true, "/dashboards" can auto-apply profile filter in main context.', ) # [/DEF:ProfilePreferenceUpdateRequest:Class] # [DEF:ProfilePreferenceResponse:Class] # @TIER: STANDARD # @PURPOSE: Response envelope for profile preference read/update endpoints. class ProfilePreferenceResponse(BaseModel): status: Literal["success", "error"] = "success" message: Optional[str] = None validation_errors: List[str] = Field(default_factory=list) preference: ProfilePreference # [/DEF:ProfilePreferenceResponse:Class] # [DEF:SupersetAccountLookupRequest:Class] # @TIER: STANDARD # @PURPOSE: Query contract for Superset account lookup by selected environment. class SupersetAccountLookupRequest(BaseModel): environment_id: str search: Optional[str] = None page_index: int = Field(default=0, ge=0) page_size: int = Field(default=20, ge=1, le=100) sort_column: str = Field(default="username") sort_order: str = Field(default="desc") # [/DEF:SupersetAccountLookupRequest:Class] # [DEF:SupersetAccountCandidate:Class] # @TIER: STANDARD # @PURPOSE: Canonical account candidate projected from Superset users payload. class SupersetAccountCandidate(BaseModel): environment_id: str username: str display_name: Optional[str] = None email: Optional[str] = None is_active: Optional[bool] = None # [/DEF:SupersetAccountCandidate:Class] # [DEF:SupersetAccountLookupResponse:Class] # @TIER: STANDARD # @PURPOSE: Response envelope for Superset account lookup (success or degraded mode). class SupersetAccountLookupResponse(BaseModel): status: Literal["success", "degraded"] environment_id: str page_index: int = Field(ge=0) page_size: int = Field(ge=1, le=100) total: int = Field(ge=0) warning: Optional[str] = None items: List[SupersetAccountCandidate] = Field(default_factory=list) # [/DEF:SupersetAccountLookupResponse:Class] # [/DEF:backend.src.schemas.profile:Module]