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
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
"""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)
|
||||
Reference in New Issue
Block a user