updated services api
This commit is contained in:
2
ServicesApi/Validations/a.txt
Normal file
2
ServicesApi/Validations/a.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
result_with_keys_dict {'Employees.id': 3, 'Employees.uu_id': UUID('2b757a5c-01bb-4213-9cf1-402480e73edc'), 'People.id': 2, 'People.uu_id': UUID('d945d320-2a4e-48db-a18c-6fd024beb517'), 'Users.id': 3, 'Users.uu_id': UUID('bdfa84d9-0e05-418c-9406-d6d1d41ae2a1'), 'Companies.id': 1, 'Companies.uu_id': UUID('da1de172-2f89-42d2-87f3-656b36a79d5b'), 'Departments.id': 3, 'Departments.uu_id': UUID('4edcec87-e072-408d-a780-3a62151b3971'), 'Duty.id': 9, 'Duty.uu_id': UUID('00d29292-c29e-4435-be41-9704ccf4b24d'), 'Addresses.id': None, 'Addresses.letter_address': None}
|
||||
56
ServicesApi/Validations/defaults/validations.py
Normal file
56
ServicesApi/Validations/defaults/validations.py
Normal file
@@ -0,0 +1,56 @@
|
||||
from fastapi import Header, Request, Response
|
||||
from pydantic import BaseModel
|
||||
|
||||
from config import api_config
|
||||
|
||||
|
||||
class CommonHeaders(BaseModel):
|
||||
language: str | None = None
|
||||
domain: str | None = None
|
||||
timezone: str | None = None
|
||||
token: str | None = None
|
||||
request: Request | None = None
|
||||
response: Response | None = None
|
||||
operation_id: str | None = None
|
||||
|
||||
model_config = {
|
||||
"arbitrary_types_allowed": True
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def as_dependency(
|
||||
cls,
|
||||
request: Request,
|
||||
response: Response,
|
||||
language: str = Header(None, alias="language"),
|
||||
domain: str = Header(None, alias="domain"),
|
||||
tz: str = Header(None, alias="timezone"),
|
||||
):
|
||||
token = request.headers.get(api_config.ACCESS_TOKEN_TAG, None)
|
||||
|
||||
# Extract operation_id from the route
|
||||
operation_id = None
|
||||
if hasattr(request.scope.get("route"), "operation_id"):
|
||||
operation_id = request.scope.get("route").operation_id
|
||||
|
||||
return cls(
|
||||
language=language,
|
||||
domain=domain,
|
||||
timezone=tz,
|
||||
token=token,
|
||||
request=request,
|
||||
response=response,
|
||||
operation_id=operation_id,
|
||||
)
|
||||
|
||||
def get_headers_dict(self):
|
||||
"""Convert the headers to a dictionary format used in the application"""
|
||||
import uuid
|
||||
|
||||
return {
|
||||
"language": self.language or "",
|
||||
"domain": self.domain or "",
|
||||
"eys-ext": f"{str(uuid.uuid4())}",
|
||||
"tz": self.timezone or "GMT+3",
|
||||
"token": self.token,
|
||||
}
|
||||
17
ServicesApi/Validations/pydantic_core.py
Normal file
17
ServicesApi/Validations/pydantic_core.py
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
|
||||
class BaseModelCore(BaseModel):
|
||||
|
||||
"""
|
||||
BaseModelCore
|
||||
model_dump override for alias support Users.name -> Table[Users] Field(alias="name")
|
||||
"""
|
||||
__abstract__ = True
|
||||
|
||||
class Config:
|
||||
validate_by_name = True
|
||||
use_enum_values = True
|
||||
|
||||
def model_dump(self, *args, **kwargs):
|
||||
data = super().model_dump(*args, **kwargs)
|
||||
return {self.__class__.model_fields[field].alias: value for field, value in data.items()}
|
||||
4
ServicesApi/Validations/response/__init__.py
Normal file
4
ServicesApi/Validations/response/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
from .pagination import PaginateOnly, ListOptions, PaginationConfig
|
||||
from .result import Pagination, PaginationResult
|
||||
from .base import PostgresResponseSingle, PostgresResponse, ResultQueryJoin, ResultQueryJoinSingle
|
||||
from .api import EndpointResponse, CreateEndpointResponse
|
||||
60
ServicesApi/Validations/response/api.py
Normal file
60
ServicesApi/Validations/response/api.py
Normal file
@@ -0,0 +1,60 @@
|
||||
from .result import PaginationResult
|
||||
from .base import PostgresResponseSingle
|
||||
from pydantic import BaseModel
|
||||
from typing import Any, Type
|
||||
|
||||
|
||||
class EndpointResponse(BaseModel):
|
||||
"""Endpoint response model."""
|
||||
|
||||
completed: bool = True
|
||||
message: str = "Success"
|
||||
pagination_result: PaginationResult
|
||||
|
||||
@property
|
||||
def response(self):
|
||||
"""Convert response to dictionary format."""
|
||||
result_data = getattr(self.pagination_result, "data", None)
|
||||
if not result_data:
|
||||
return {
|
||||
"completed": False,
|
||||
"message": "MSG0004-NODATA",
|
||||
"data": None,
|
||||
"pagination": None,
|
||||
}
|
||||
result_pagination = getattr(self.pagination_result, "pagination", None)
|
||||
if not result_pagination:
|
||||
raise ValueError("Invalid pagination result pagination.")
|
||||
pagination_dict = getattr(result_pagination, "as_dict", None)
|
||||
if not pagination_dict:
|
||||
raise ValueError("Invalid pagination result as_dict.")
|
||||
return {
|
||||
"completed": self.completed,
|
||||
"message": self.message,
|
||||
"data": result_data,
|
||||
"pagination": pagination_dict,
|
||||
}
|
||||
|
||||
model_config = {
|
||||
"arbitrary_types_allowed": True
|
||||
}
|
||||
|
||||
class CreateEndpointResponse(BaseModel):
|
||||
"""Create endpoint response model."""
|
||||
|
||||
completed: bool = True
|
||||
message: str = "Success"
|
||||
data: PostgresResponseSingle
|
||||
|
||||
@property
|
||||
def response(self):
|
||||
"""Convert response to dictionary format."""
|
||||
return {
|
||||
"completed": self.completed,
|
||||
"message": self.message,
|
||||
"data": self.data.data,
|
||||
}
|
||||
|
||||
model_config = {
|
||||
"arbitrary_types_allowed": True
|
||||
}
|
||||
193
ServicesApi/Validations/response/base.py
Normal file
193
ServicesApi/Validations/response/base.py
Normal file
@@ -0,0 +1,193 @@
|
||||
"""
|
||||
Response handler for PostgreSQL query results.
|
||||
|
||||
This module provides a wrapper class for SQLAlchemy query results,
|
||||
adding convenience methods for accessing data and managing query state.
|
||||
"""
|
||||
|
||||
from typing import Any, Dict, Optional, TypeVar, Generic, Union
|
||||
|
||||
from pydantic import BaseModel
|
||||
from sqlalchemy.orm import Query
|
||||
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
|
||||
class PostgresResponse(Generic[T]):
|
||||
"""
|
||||
Wrapper for PostgreSQL/SQLAlchemy query results.
|
||||
|
||||
Properties:
|
||||
count: Total count of results
|
||||
query: Get query object
|
||||
as_dict: Convert response to dictionary format
|
||||
"""
|
||||
|
||||
def __init__(self, query: Query, base_model: Optional[BaseModel] = None):
|
||||
self._query = query
|
||||
self._count: Optional[int] = None
|
||||
self._base_model: Optional[BaseModel] = base_model
|
||||
self.single = False
|
||||
|
||||
@property
|
||||
def query(self) -> Query:
|
||||
"""Get query object."""
|
||||
return self._query
|
||||
|
||||
@property
|
||||
def data(self) -> Union[list[T], T]:
|
||||
"""Get query object."""
|
||||
return self._query.all()
|
||||
|
||||
@property
|
||||
def count(self) -> int:
|
||||
"""Get query object."""
|
||||
return self._query.count()
|
||||
|
||||
@property
|
||||
def to_dict(self, **kwargs) -> list[dict]:
|
||||
"""Get query object."""
|
||||
if self._base_model:
|
||||
return [self._base_model(**item.to_dict()).model_dump(**kwargs) for item in self.data]
|
||||
return [item.to_dict() for item in self.data]
|
||||
|
||||
@property
|
||||
def as_dict(self) -> Dict[str, Any]:
|
||||
"""Convert response to dictionary format."""
|
||||
return {
|
||||
"query": str(self.query),
|
||||
"count": self.count,
|
||||
"data": self.to_dict,
|
||||
}
|
||||
|
||||
|
||||
class PostgresResponseSingle(Generic[T]):
|
||||
"""
|
||||
Wrapper for PostgreSQL/SQLAlchemy query results.
|
||||
|
||||
Properties:
|
||||
count: Total count of results
|
||||
query: Get query object
|
||||
as_dict: Convert response to dictionary format
|
||||
data: Get query object
|
||||
"""
|
||||
|
||||
def __init__(self, query: Query, base_model: Optional[BaseModel] = None):
|
||||
self._query = query
|
||||
self._count: Optional[int] = None
|
||||
self._base_model: Optional[BaseModel] = base_model
|
||||
self.single = True
|
||||
|
||||
@property
|
||||
def query(self) -> Query:
|
||||
"""Get query object."""
|
||||
return self._query
|
||||
|
||||
@property
|
||||
def to_dict(self, **kwargs) -> dict:
|
||||
"""Get query object."""
|
||||
if self._base_model:
|
||||
return self._base_model(**self._query.first().to_dict()).model_dump(**kwargs)
|
||||
return self._query.first().to_dict()
|
||||
|
||||
@property
|
||||
def data(self) -> T:
|
||||
"""Get query object."""
|
||||
return self._query.first()
|
||||
|
||||
@property
|
||||
def count(self) -> int:
|
||||
"""Get query object."""
|
||||
return self._query.count()
|
||||
|
||||
@property
|
||||
def as_dict(self) -> Dict[str, Any]:
|
||||
"""Convert response to dictionary format."""
|
||||
return {"query": str(self.query),"data": self.to_dict, "count": self.count}
|
||||
|
||||
|
||||
class ResultQueryJoin:
|
||||
"""
|
||||
ResultQueryJoin
|
||||
params:
|
||||
list_of_instrumented_attributes: list of instrumented attributes
|
||||
query: query object
|
||||
"""
|
||||
|
||||
def __init__(self, list_of_instrumented_attributes, query):
|
||||
"""Initialize ResultQueryJoin"""
|
||||
self.list_of_instrumented_attributes = list_of_instrumented_attributes
|
||||
self._query = query
|
||||
|
||||
@property
|
||||
def query(self):
|
||||
"""Get query object."""
|
||||
return self._query
|
||||
|
||||
@property
|
||||
def to_dict(self):
|
||||
"""Convert response to dictionary format."""
|
||||
list_of_dictionaries, result = [], dict()
|
||||
for user_orders_shipping_iter in self.query.all():
|
||||
for index, instrumented_attribute_iter in enumerate(self.list_of_instrumented_attributes):
|
||||
result[str(instrumented_attribute_iter)] = user_orders_shipping_iter[index]
|
||||
list_of_dictionaries.append(result)
|
||||
return list_of_dictionaries
|
||||
|
||||
@property
|
||||
def count(self):
|
||||
"""Get count of query."""
|
||||
return self.query.count()
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
"""Get query object."""
|
||||
return self.query.all()
|
||||
|
||||
@property
|
||||
def as_dict(self):
|
||||
"""Convert response to dictionary format."""
|
||||
return {"query": str(self.query), "data": self.data, "count": self.count}
|
||||
|
||||
|
||||
class ResultQueryJoinSingle:
|
||||
"""
|
||||
ResultQueryJoinSingle
|
||||
params:
|
||||
list_of_instrumented_attributes: list of instrumented attributes
|
||||
query: query object
|
||||
"""
|
||||
|
||||
def __init__(self, list_of_instrumented_attributes, query):
|
||||
"""Initialize ResultQueryJoinSingle"""
|
||||
self.list_of_instrumented_attributes = list_of_instrumented_attributes
|
||||
self._query = query
|
||||
|
||||
@property
|
||||
def query(self):
|
||||
"""Get query object."""
|
||||
return self._query
|
||||
|
||||
@property
|
||||
def to_dict(self):
|
||||
"""Convert response to dictionary format."""
|
||||
data, result = self.query.first(), dict()
|
||||
for index, instrumented_attribute_iter in enumerate(self.list_of_instrumented_attributes):
|
||||
result[str(instrumented_attribute_iter)] = data[index]
|
||||
return result
|
||||
|
||||
@property
|
||||
def count(self):
|
||||
"""Get count of query."""
|
||||
return self.query.count()
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
"""Get query object."""
|
||||
return self._query.first()
|
||||
|
||||
@property
|
||||
def as_dict(self):
|
||||
"""Convert response to dictionary format."""
|
||||
return {"query": str(self.query), "data": self.data, "count": self.count}
|
||||
19
ServicesApi/Validations/response/example.py
Normal file
19
ServicesApi/Validations/response/example.py
Normal file
@@ -0,0 +1,19 @@
|
||||
|
||||
|
||||
class UserPydantic(BaseModel):
|
||||
|
||||
username: str = Field(..., alias='user.username')
|
||||
account_balance: float = Field(..., alias='user.account_balance')
|
||||
preferred_category_id: Optional[int] = Field(None, alias='user.preferred_category_id')
|
||||
last_ordered_product_id: Optional[int] = Field(None, alias='user.last_ordered_product_id')
|
||||
supplier_rating_id: Optional[int] = Field(None, alias='user.supplier_rating_id')
|
||||
other_rating_id: Optional[int] = Field(None, alias='product.supplier_rating_id')
|
||||
id: int = Field(..., alias='user.id')
|
||||
|
||||
class Config:
|
||||
validate_by_name = True
|
||||
use_enum_values = True
|
||||
|
||||
def model_dump(self, *args, **kwargs):
|
||||
data = super().model_dump(*args, **kwargs)
|
||||
return {self.__class__.model_fields[field].alias: value for field, value in data.items()}
|
||||
70
ServicesApi/Validations/response/pagination.py
Normal file
70
ServicesApi/Validations/response/pagination.py
Normal file
@@ -0,0 +1,70 @@
|
||||
from typing import Any, Dict, Optional, Union, TypeVar, Type
|
||||
from sqlalchemy import desc, asc
|
||||
from pydantic import BaseModel
|
||||
|
||||
from .base import PostgresResponse
|
||||
|
||||
# Type variable for class methods returning self
|
||||
T = TypeVar("T", bound="BaseModel")
|
||||
|
||||
|
||||
class PaginateConfig:
|
||||
"""
|
||||
Configuration for pagination settings.
|
||||
|
||||
Attributes:
|
||||
DEFAULT_SIZE: Default number of items per page (10)
|
||||
MIN_SIZE: Minimum allowed page size (10)
|
||||
MAX_SIZE: Maximum allowed page size (40)
|
||||
"""
|
||||
|
||||
DEFAULT_SIZE = 10
|
||||
MIN_SIZE = 5
|
||||
MAX_SIZE = 100
|
||||
|
||||
|
||||
class ListOptions(BaseModel):
|
||||
"""
|
||||
Query for list option abilities
|
||||
"""
|
||||
|
||||
page: Optional[int] = 1
|
||||
size: Optional[int] = 10
|
||||
orderField: Optional[Union[tuple[str], list[str]]] = ["uu_id"]
|
||||
orderType: Optional[Union[tuple[str], list[str]]] = ["asc"]
|
||||
# include_joins: Optional[list] = None
|
||||
|
||||
|
||||
class PaginateOnly(ListOptions):
|
||||
"""
|
||||
Query for list option abilities
|
||||
"""
|
||||
|
||||
query: Optional[dict] = None
|
||||
|
||||
|
||||
class PaginationConfig(BaseModel):
|
||||
"""
|
||||
Configuration for pagination settings.
|
||||
|
||||
Attributes:
|
||||
page: Current page number (default: 1)
|
||||
size: Items per page (default: 10)
|
||||
orderField: Field to order by (default: "created_at")
|
||||
orderType: Order direction (default: "desc")
|
||||
"""
|
||||
|
||||
page: int = 1
|
||||
size: int = 10
|
||||
orderField: Optional[Union[tuple[str], list[str]]] = ["created_at"]
|
||||
orderType: Optional[Union[tuple[str], list[str]]] = ["desc"]
|
||||
|
||||
def __init__(self, **data):
|
||||
super().__init__(**data)
|
||||
if self.orderField is None:
|
||||
self.orderField = ["created_at"]
|
||||
if self.orderType is None:
|
||||
self.orderType = ["desc"]
|
||||
|
||||
|
||||
default_paginate_config = PaginateConfig()
|
||||
180
ServicesApi/Validations/response/result.py
Normal file
180
ServicesApi/Validations/response/result.py
Normal file
@@ -0,0 +1,180 @@
|
||||
from typing import Optional, Union, Type, Any, Dict, TypeVar
|
||||
from pydantic import BaseModel
|
||||
from sqlalchemy.orm import Query
|
||||
from sqlalchemy import asc, desc
|
||||
|
||||
from .pagination import default_paginate_config
|
||||
from .base import PostgresResponse
|
||||
from .pagination import PaginationConfig
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
class Pagination:
|
||||
"""
|
||||
Handles pagination logic for query results.
|
||||
|
||||
Manages page size, current page, ordering, and calculates total pages
|
||||
and items based on the data source.
|
||||
|
||||
Attributes:
|
||||
DEFAULT_SIZE: Default number of items per page (10)
|
||||
MIN_SIZE: Minimum allowed page size (10)
|
||||
MAX_SIZE: Maximum allowed page size (40)
|
||||
"""
|
||||
|
||||
DEFAULT_SIZE = default_paginate_config.DEFAULT_SIZE
|
||||
MIN_SIZE = default_paginate_config.MIN_SIZE
|
||||
MAX_SIZE = default_paginate_config.MAX_SIZE
|
||||
|
||||
def __init__(self, data: PostgresResponse):
|
||||
self.query = data
|
||||
self.size: int = self.DEFAULT_SIZE
|
||||
self.page: int = 1
|
||||
self.orderField: Optional[Union[tuple[str], list[str]]] = ["uu_id"]
|
||||
self.orderType: Optional[Union[tuple[str], list[str]]] = ["asc"]
|
||||
self.page_count: int = 1
|
||||
self.total_count: int = 0
|
||||
self.all_count: int = 0
|
||||
self.total_pages: int = 1
|
||||
self._update_page_counts()
|
||||
|
||||
def change(self, **kwargs) -> None:
|
||||
"""Update pagination settings from config."""
|
||||
config = PaginationConfig(**kwargs)
|
||||
self.size = (
|
||||
config.size
|
||||
if self.MIN_SIZE <= config.size <= self.MAX_SIZE
|
||||
else self.DEFAULT_SIZE
|
||||
)
|
||||
self.page = config.page
|
||||
self.orderField = config.orderField
|
||||
self.orderType = config.orderType
|
||||
self._update_page_counts()
|
||||
|
||||
def feed(self, data: PostgresResponse) -> None:
|
||||
"""Calculate pagination based on data source."""
|
||||
self.query = data
|
||||
self._update_page_counts()
|
||||
|
||||
def _update_page_counts(self) -> None:
|
||||
"""Update page counts and validate current page."""
|
||||
if self.query:
|
||||
self.total_count = self.query.count()
|
||||
self.all_count = self.query.count()
|
||||
|
||||
self.size = (
|
||||
self.size
|
||||
if self.MIN_SIZE <= self.size <= self.MAX_SIZE
|
||||
else self.DEFAULT_SIZE
|
||||
)
|
||||
self.total_pages = max(1, (self.total_count + self.size - 1) // self.size)
|
||||
self.page = max(1, min(self.page, self.total_pages))
|
||||
self.page_count = (
|
||||
self.total_count % self.size
|
||||
if self.page == self.total_pages and self.total_count % self.size
|
||||
else self.size
|
||||
)
|
||||
|
||||
def refresh(self) -> None:
|
||||
"""Reset pagination state to defaults."""
|
||||
self._update_page_counts()
|
||||
|
||||
def reset(self) -> None:
|
||||
"""Reset pagination state to defaults."""
|
||||
self.size = self.DEFAULT_SIZE
|
||||
self.page = 1
|
||||
self.orderField = "uu_id"
|
||||
self.orderType = "asc"
|
||||
|
||||
@property
|
||||
def next_available(self) -> bool:
|
||||
if self.page < self.total_pages:
|
||||
return True
|
||||
return False
|
||||
|
||||
@property
|
||||
def back_available(self) -> bool:
|
||||
if self.page > 1:
|
||||
return True
|
||||
return False
|
||||
|
||||
@property
|
||||
def as_dict(self) -> Dict[str, Any]:
|
||||
"""Convert pagination state to dictionary format."""
|
||||
self.refresh()
|
||||
return {
|
||||
"size": self.size,
|
||||
"page": self.page,
|
||||
"allCount": self.all_count,
|
||||
"totalCount": self.total_count,
|
||||
"totalPages": self.total_pages,
|
||||
"pageCount": self.page_count,
|
||||
"orderField": self.orderField,
|
||||
"orderType": self.orderType,
|
||||
"next": self.next_available,
|
||||
"back": self.back_available,
|
||||
}
|
||||
|
||||
|
||||
class PaginationResult:
|
||||
"""
|
||||
Result of a paginated query.
|
||||
|
||||
Contains the query result and pagination state.
|
||||
data: PostgresResponse of query results
|
||||
pagination: Pagination state
|
||||
|
||||
Attributes:
|
||||
_query: Original query object
|
||||
pagination: Pagination state
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
data: PostgresResponse,
|
||||
pagination: Pagination,
|
||||
is_list: bool = True,
|
||||
response_model: Type[T] = None,
|
||||
):
|
||||
self._query = data
|
||||
self.pagination = pagination
|
||||
self.response_type = is_list
|
||||
self.limit = self.pagination.size
|
||||
self.offset = self.pagination.size * (self.pagination.page - 1)
|
||||
self.order_by = self.pagination.orderField
|
||||
self.response_model = response_model
|
||||
|
||||
def dynamic_order_by(self):
|
||||
"""
|
||||
Dynamically order a query by multiple fields.
|
||||
Returns:
|
||||
Ordered query object.
|
||||
"""
|
||||
if not len(self.order_by) == len(self.pagination.orderType):
|
||||
raise ValueError(
|
||||
"Order by fields and order types must have the same length."
|
||||
)
|
||||
order_criteria = zip(self.order_by, self.pagination.orderType)
|
||||
for field, direction in order_criteria:
|
||||
if hasattr(self._query.column_descriptions[0]["entity"], field):
|
||||
if direction.lower().startswith("d"):
|
||||
self._query = self._query.order_by(
|
||||
desc(
|
||||
getattr(self._query.column_descriptions[0]["entity"], field)
|
||||
)
|
||||
)
|
||||
else:
|
||||
self._query = self._query.order_by(
|
||||
asc(
|
||||
getattr(self._query.column_descriptions[0]["entity"], field)
|
||||
)
|
||||
)
|
||||
return self._query
|
||||
|
||||
@property
|
||||
def data(self) -> Union[list | dict]:
|
||||
"""Get query object."""
|
||||
query_paginated = self.dynamic_order_by().limit(self.limit).offset(self.offset)
|
||||
queried_data = (query_paginated.all() if self.response_type else query_paginated.first())
|
||||
data = ([result.get_dict() for result in queried_data] if self.response_type else queried_data.get_dict())
|
||||
return [self.response_model(**item).model_dump() for item in data] if self.response_model else data
|
||||
123
ServicesApi/Validations/token/validations.py
Normal file
123
ServicesApi/Validations/token/validations.py
Normal file
@@ -0,0 +1,123 @@
|
||||
from enum import Enum
|
||||
from pydantic import BaseModel
|
||||
from typing import Optional, Union
|
||||
|
||||
|
||||
class UserType(Enum):
|
||||
|
||||
employee = 1
|
||||
occupant = 2
|
||||
|
||||
|
||||
class Credentials(BaseModel):
|
||||
|
||||
person_id: int
|
||||
person_name: str
|
||||
|
||||
|
||||
class ApplicationToken(BaseModel):
|
||||
# Application Token Object -> is the main object for the user
|
||||
|
||||
user_type: int = UserType.occupant.value
|
||||
credential_token: str = ""
|
||||
|
||||
user_uu_id: str
|
||||
user_id: int
|
||||
|
||||
person_id: int
|
||||
person_uu_id: str
|
||||
|
||||
request: Optional[dict] = None # Request Info of Client
|
||||
expires_at: Optional[float] = None # Expiry timestamp
|
||||
|
||||
|
||||
class OccupantToken(BaseModel):
|
||||
|
||||
# Selection of the occupant type for a build part is made by the user
|
||||
|
||||
living_space_id: int # Internal use
|
||||
living_space_uu_id: str # Outer use
|
||||
|
||||
occupant_type_id: int
|
||||
occupant_type_uu_id: str
|
||||
occupant_type: str
|
||||
|
||||
build_id: int
|
||||
build_uuid: str
|
||||
build_part_id: int
|
||||
build_part_uuid: str
|
||||
|
||||
responsible_company_id: Optional[int] = None
|
||||
responsible_company_uuid: Optional[str] = None
|
||||
responsible_employee_id: Optional[int] = None
|
||||
responsible_employee_uuid: Optional[str] = None
|
||||
|
||||
# ID list of reachable event codes as "endpoint_code": ["UUID", "UUID"]
|
||||
reachable_event_codes: Optional[dict[str, str]] = None
|
||||
|
||||
# ID list of reachable applications as "page_url": ["UUID", "UUID"]
|
||||
reachable_app_codes: Optional[dict[str, str]] = None
|
||||
|
||||
|
||||
class CompanyToken(BaseModel):
|
||||
|
||||
# Selection of the company for an employee is made by the user
|
||||
company_id: int
|
||||
company_uu_id: str
|
||||
|
||||
department_id: int # ID list of departments
|
||||
department_uu_id: str # ID list of departments
|
||||
|
||||
duty_id: int
|
||||
duty_uu_id: str
|
||||
|
||||
staff_id: int
|
||||
staff_uu_id: str
|
||||
|
||||
employee_id: int
|
||||
employee_uu_id: str
|
||||
bulk_duties_id: int
|
||||
|
||||
# ID list of reachable event codes as "endpoint_code": ["UUID", "UUID"]
|
||||
reachable_event_codes: Optional[dict[str, str]] = None
|
||||
|
||||
# ID list of reachable applications as "page_url": ["UUID", "UUID"]
|
||||
reachable_app_codes: Optional[dict[str, str]] = None
|
||||
|
||||
|
||||
class OccupantTokenObject(ApplicationToken):
|
||||
# Occupant Token Object -> Requires selection of the occupant type for a specific build part
|
||||
|
||||
available_occupants: dict = None
|
||||
selected_occupant: Optional[OccupantToken] = None # Selected Occupant Type
|
||||
|
||||
@property
|
||||
def is_employee(self) -> bool:
|
||||
return False
|
||||
|
||||
@property
|
||||
def is_occupant(self) -> bool:
|
||||
return True
|
||||
|
||||
|
||||
class EmployeeTokenObject(ApplicationToken):
|
||||
# Full hierarchy Employee[staff_id] -> Staff -> Duty -> Department -> Company
|
||||
|
||||
companies_id_list: list[int] # List of company objects
|
||||
companies_uu_id_list: list[str] # List of company objects
|
||||
|
||||
duty_id_list: list[int] # List of duty objects
|
||||
duty_uu_id_list: list[str] # List of duty objects
|
||||
|
||||
selected_company: Optional[CompanyToken] = None # Selected Company Object
|
||||
|
||||
@property
|
||||
def is_employee(self) -> bool:
|
||||
return True
|
||||
|
||||
@property
|
||||
def is_occupant(self) -> bool:
|
||||
return False
|
||||
|
||||
|
||||
TokenDictType = Union[EmployeeTokenObject, OccupantTokenObject]
|
||||
Reference in New Issue
Block a user