duyduc
Deploy Legolas retrieval Docker Space
ef4c4e5
Raw
History Blame Contribute Delete
5.11 kB
from datetime import datetime
from enum import StrEnum
from typing import Any
from pydantic import BaseModel, ConfigDict, Field, field_validator
class UserProvider(StrEnum):
LOCAL = "local"
GOOGLE = "google"
LOCAL_GOOGLE = "local_google"
class PlatformRole(StrEnum):
USER = "user"
PLATFORM_ADMIN = "platform_admin"
class OrganizationRole(StrEnum):
OWNER = "owner"
# Compatibility only: organization admin is not product-exposed in MVP.
LEGACY_ADMIN = "admin"
MEMBER = "member"
VIEWER = "viewer"
class SourceScope(StrEnum):
PUBLIC_VBPL = "public_vbpl"
GUEST_SESSION = "guest_session"
USER_PRIVATE = "user_private"
ORG_PRIVATE = "org_private"
class AuthorityLevel(StrEnum):
PUBLIC_LAW = "public_law"
INTERNAL_POLICY = "internal_policy"
UPLOADED_CONTEXT = "uploaded_context"
class SourceDocumentStatus(StrEnum):
ACTIVE = "active"
OUTDATED = "outdated"
DRAFT = "draft"
UNKNOWN = "unknown"
PENDING_INDEX = "pending_index"
INDEXING_FAILED = "indexing_failed"
class TokenType(StrEnum):
ACCESS = "access"
REFRESH = "refresh"
OAUTH_STATE = "oauth_state"
class UserPublic(BaseModel):
id: str
email: str
full_name: str | None = None
avatar_url: str | None = None
provider: UserProvider
# Platform administration is independent from organization ownership.
platform_role: PlatformRole
is_active: bool
is_verified: bool
created_at: datetime
updated_at: datetime
model_config = ConfigDict(from_attributes=True)
class MembershipPublic(BaseModel):
id: str
organization_id: str
organization_name: str
organization_slug: str
role: OrganizationRole
created_at: datetime
updated_at: datetime
model_config = ConfigDict(from_attributes=True)
class CurrentUserResponse(BaseModel):
user: UserPublic
memberships: list[MembershipPublic] = Field(default_factory=list)
class RegisterRequest(BaseModel):
email: str = Field(min_length=3, max_length=320)
password: str = Field(min_length=8, max_length=200)
full_name: str | None = Field(default=None, max_length=200)
model_config = ConfigDict(extra="forbid")
@field_validator("email")
@classmethod
def normalize_email(cls, value: str) -> str:
email = value.strip().lower()
if "@" not in email or email.startswith("@") or email.endswith("@"):
raise ValueError("valid email is required")
return email
class LoginRequest(BaseModel):
email: str = Field(min_length=3, max_length=320)
password: str = Field(min_length=1, max_length=200)
@field_validator("email")
@classmethod
def normalize_email(cls, value: str) -> str:
return value.strip().lower()
class RefreshTokenRequest(BaseModel):
refresh_token: str = Field(min_length=16)
class LogoutRequest(BaseModel):
refresh_token: str = Field(min_length=16)
class TokenResponse(BaseModel):
access_token: str
refresh_token: str
token_type: str = "bearer"
access_token_expires_in: int
refresh_token_expires_in: int
class OrganizationCreateRequest(BaseModel):
name: str = Field(min_length=1, max_length=200)
slug: str | None = Field(default=None, min_length=1, max_length=120)
class OrganizationPublic(BaseModel):
id: str
name: str
slug: str
created_by_user_id: str
created_at: datetime
updated_at: datetime
model_config = ConfigDict(from_attributes=True)
class OrganizationCreateResponse(BaseModel):
organization: OrganizationPublic
membership: MembershipPublic
invite_code: str
class OrganizationListResponse(BaseModel):
organizations: list[OrganizationPublic]
memberships: list[MembershipPublic]
invite_code: str | None = None
class OrganizationJoinRequest(BaseModel):
invite_code: str = Field(min_length=16, max_length=200)
class OrganizationJoinResponse(BaseModel):
organization: OrganizationPublic
membership: MembershipPublic
class InviteCodeResponse(BaseModel):
organization_id: str
invite_code: str
class OrganizationMemberPublic(BaseModel):
id: str
user_id: str
email: str
full_name: str | None = None
role: OrganizationRole
created_at: datetime
updated_at: datetime
class OrganizationMembersResponse(BaseModel):
organization_id: str
members: list[OrganizationMemberPublic]
class SourceAccessContext(BaseModel):
user_id: str | None = None
guest_session_id: str | None = None
organization_roles: dict[str, OrganizationRole] = Field(default_factory=dict)
class SourceAccessRequest(BaseModel):
source_scope: SourceScope
owner_user_id: str | None = None
guest_session_id: str | None = None
org_id: str | None = None
uploaded_by: str | None = None
authority_level: AuthorityLevel
document_status: SourceDocumentStatus = SourceDocumentStatus.UNKNOWN
source_uri: str | None = None
metadata: dict[str, Any] = Field(default_factory=dict)
class SourceAccessDecision(BaseModel):
allowed: bool
reason: str