  # #region AuthSchemas [C:5] [TYPE Module] [SEMANTICS pydantic, auth, schema, token]
  # @defgroup Schemas Module group.
  #
  # @BRIEF Pydantic schemas for authentication requests and responses.
  # @LAYER API
  # @RELATION DEPENDS_ON -> [EXT:Library:pydantic]
  #
  # @INVARIANT  Sensitive fields like password must not be included in response schemas.
  # @DATA_CONTRACT  AuthPayload -> AuthSchema
  
> from datetime import datetime
> import re
  
> from pydantic import BaseModel, ConfigDict, EmailStr, Field, field_validator
  
  
  # #region Token [C:1] [TYPE Class]
  # @BRIEF Represents a JWT access token response.
> class Token(BaseModel):
>     access_token: str
>     token_type: str
  
  
  # #endregion Token
  
  
  # #region TokenData [C:1] [TYPE Class]
  # @BRIEF Represents the data encoded in a JWT token.
> class TokenData(BaseModel):
>     username: str | None = None
>     scopes: list[str] = []
  
  
  # #endregion TokenData
  
  
  # #region PermissionSchema [C:1] [TYPE Class]
  # @BRIEF Represents a permission in API responses.
> class PermissionSchema(BaseModel):
>     id: str | None = None
>     resource: str
>     action: str
  
>     model_config = ConfigDict(from_attributes=True)
  
  
  # #endregion PermissionSchema
  
  
  # #region RoleSchema [TYPE Class]
  # @defgroup Schemas Module group.
  # @BRIEF Represents a role in API responses.
> class RoleSchema(BaseModel):
>     id: str
>     name: str
>     description: str | None = None
>     permissions: list[PermissionSchema] = []
  
>     model_config = ConfigDict(from_attributes=True)
  
  
  # #endregion RoleSchema
  
  
  # #region RoleCreate [TYPE Class]
  # @defgroup Schemas Module group.
  # @BRIEF Schema for creating a new role.
> class RoleCreate(BaseModel):
>     name: str
>     description: str | None = None
>     permissions: list[str] = []  # List of permission IDs or "resource:action" strings
  
  
  # #endregion RoleCreate
  
  
  # #region RoleUpdate [TYPE Class]
  # @defgroup Schemas Module group.
  # @BRIEF Schema for updating an existing role.
> class RoleUpdate(BaseModel):
>     name: str | None = None
>     description: str | None = None
>     permissions: list[str] | None = None
  
  
  # #endregion RoleUpdate
  
  
  # #region ADGroupMappingSchema [TYPE Class]
  # @defgroup Schemas Module group.
  # @BRIEF Represents an AD Group to Role mapping in API responses.
> class ADGroupMappingSchema(BaseModel):
>     id: str
>     ad_group: str
>     role_id: str
  
>     model_config = ConfigDict(from_attributes=True)
  
  
  # #endregion ADGroupMappingSchema
  
  
  # #region ADGroupMappingCreate [TYPE Class]
  # @defgroup Schemas Module group.
  # @BRIEF Schema for creating an AD Group mapping.
> class ADGroupMappingCreate(BaseModel):
>     ad_group: str
>     role_id: str
  
>     @field_validator("ad_group")
>     @classmethod
>     def validate_ad_group(cls, v: str) -> str:
>         if not v or not v.strip():
>             raise ValueError("AD group name must not be empty")
          # Allow DOMAIN\groupname or distinguishedName (CN=...,DC=...) formats
          # Allow DOMAIN\groupname or distinguishedName (CN=...,DC=...) formats
>         if not re.match(r'^[A-Za-z0-9_.@()=\\\\, -]+$', v):
>             raise ValueError(
>                 "AD group name contains invalid characters. "
>                 "Use format: DOMAIN\\groupname or CN=groupname,DC=domain"
>             )
>         return v.strip()
  
  
  # #endregion ADGroupMappingCreate
  
  
  # #region UserBase [TYPE Class]
  # @defgroup Schemas Module group.
  # @BRIEF Base schema for user data.
> class UserBase(BaseModel):
>     username: str
>     email: EmailStr | None = None
>     is_active: bool = True
  
  
  # #endregion UserBase
  
  
  # #region UserCreate [TYPE Class]
  # @defgroup Schemas Module group.
  # @BRIEF Schema for creating a new user.
> class UserCreate(UserBase):
>     password: str = Field(min_length=8)
>     roles: list[str] = []
  
>     @field_validator("password")
>     @classmethod
>     def validate_password_strength(cls, v: str) -> str:
>         if len(v) < 8:
!             raise ValueError("Password must be at least 8 characters")
>         if not any(c.isupper() for c in v):
>             raise ValueError("Password must contain at least one uppercase letter")
>         if not any(c.islower() for c in v):
>             raise ValueError("Password must contain at least one lowercase letter")
>         if not any(c.isdigit() for c in v):
>             raise ValueError("Password must contain at least one digit")
>         return v
  
  
  # #endregion UserCreate
  
  
  # #region UserUpdate [TYPE Class]
  # @defgroup Schemas Module group.
  # @BRIEF Schema for updating an existing user.
> class UserUpdate(BaseModel):
>     email: EmailStr | None = None
>     password: str | None = None
>     is_active: bool | None = None
>     roles: list[str] | None = None
  
  
  # #endregion UserUpdate
  
  
  # #region User [TYPE Class]
  # @defgroup Schemas Module group.
  # @BRIEF Schema for user data in API responses.
> class User(UserBase):
>     id: str
>     auth_source: str
>     created_at: datetime
>     last_login: datetime | None = None
>     roles: list[RoleSchema] = []
  
>     model_config = ConfigDict(from_attributes=True)
  
  
  # #endregion User
  
  # #endregion AuthSchemas
