Files
boc/landvex/user-management/app/schemas.py
T
Bernt aee0f09db8 landvex: Fixar och tester klara för alla komponenter
- Datafabrik: Dockerfile fix, agentorkestrering fungerar
- Vision: Identify-modell, FAISS, OCR alla testade
- API: Alla 7 integrationstester passerade
- Upplösare: Entitetsupplösning verifierad
2026-07-05 06:41:32 +00:00

148 lines
3.9 KiB
Python

"""Pydantic-scheman för request/response-validering."""
from datetime import datetime
from typing import Optional
from uuid import UUID
from pydantic import BaseModel, EmailStr, Field, ConfigDict
from app.models import UserRole, UserStatus
# ─── Shared ───────────────────────────────────────────
class UserBase(BaseModel):
email: EmailStr
first_name: str = Field(..., min_length=1, max_length=100)
last_name: str = Field(..., min_length=1, max_length=100)
role: UserRole = UserRole.VIEWER
class TenantBase(BaseModel):
name: str = Field(..., min_length=1, max_length=255)
slug: str = Field(..., min_length=1, max_length=100)
description: Optional[str] = None
# ─── Tenant ───────────────────────────────────────────
class TenantCreate(TenantBase):
pass
class TenantUpdate(BaseModel):
name: Optional[str] = Field(None, min_length=1, max_length=255)
description: Optional[str] = None
class TenantOut(TenantBase):
model_config = ConfigDict(from_attributes=True)
id: UUID
created_at: datetime
updated_at: datetime
# ─── User ─────────────────────────────────────────────
class UserCreate(UserBase):
password: Optional[str] = Field(None, min_length=8)
tenant_id: Optional[UUID] = None
class UserUpdate(BaseModel):
email: Optional[EmailStr] = None
first_name: Optional[str] = Field(None, min_length=1, max_length=100)
last_name: Optional[str] = Field(None, min_length=1, max_length=100)
role: Optional[UserRole] = None
status: Optional[UserStatus] = None
tenant_id: Optional[UUID] = None
class UserOut(UserBase):
model_config = ConfigDict(from_attributes=True)
id: UUID
status: UserStatus
is_superuser: bool
last_login_at: Optional[datetime] = None
tenant_id: Optional[UUID] = None
created_at: datetime
updated_at: datetime
class UserDetailOut(UserOut):
tenant: Optional[TenantOut] = None
class UserListOut(BaseModel):
items: list[UserOut]
total: int
# ─── Auth ─────────────────────────────────────────────
class Token(BaseModel):
access_token: str
refresh_token: str
token_type: str = "bearer"
expires_in: int
class TokenPayload(BaseModel):
sub: Optional[str] = None
type: Optional[str] = None
class LoginRequest(BaseModel):
email: EmailStr
password: str
class RefreshRequest(BaseModel):
refresh_token: str
class ChangePasswordRequest(BaseModel):
current_password: str
new_password: str = Field(..., min_length=8)
# ─── Invitation ───────────────────────────────────────
class InvitationCreate(BaseModel):
email: EmailStr
role: UserRole = UserRole.VIEWER
tenant_id: Optional[UUID] = None
class InvitationOut(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: UUID
email: str
role: UserRole
token: str
expires_at: datetime
accepted_at: Optional[datetime] = None
created_at: datetime
invited_by_id: UUID
tenant_id: Optional[UUID] = None
class AcceptInvitationRequest(BaseModel):
token: str
first_name: str = Field(..., min_length=1, max_length=100)
last_name: str = Field(..., min_length=1, max_length=100)
password: str = Field(..., min_length=8)
# ─── Password reset (future) ──────────────────────────
class PasswordResetRequest(BaseModel):
email: EmailStr
class PasswordResetConfirm(BaseModel):
token: str
new_password: str = Field(..., min_length=8)