From 239368e59515726322d0bcee54ae70bad06ae519 Mon Sep 17 00:00:00 2001 From: Daniel Bedeleanu Date: Sun, 19 Apr 2026 17:08:11 +0300 Subject: [PATCH] refactor: split schemas.py into schemas/ package --- backend/schemas.py | 164 ---------------------------------- backend/schemas/__init__.py | 70 +++++++++++++++ backend/schemas/common.py | 32 +++++++ backend/schemas/items.py | 67 ++++++++++++++ backend/schemas/operations.py | 55 ++++++++++++ backend/schemas/users.py | 44 +++++++++ 6 files changed, 268 insertions(+), 164 deletions(-) delete mode 100644 backend/schemas.py create mode 100644 backend/schemas/__init__.py create mode 100644 backend/schemas/common.py create mode 100644 backend/schemas/items.py create mode 100644 backend/schemas/operations.py create mode 100644 backend/schemas/users.py diff --git a/backend/schemas.py b/backend/schemas.py deleted file mode 100644 index e891b547..00000000 --- a/backend/schemas.py +++ /dev/null @@ -1,164 +0,0 @@ -from pydantic import BaseModel -from typing import Optional, List -from datetime import datetime - -# --- Users --- -class UserBase(BaseModel): - username: str - role: str = "user" - origin: str = "local" - -class UserCreate(UserBase): - password: Optional[str] = None - -class User(UserBase): - id: int - - class Config: - from_attributes = True - -class UserUpdate(BaseModel): - username: Optional[str] = None - password: Optional[str] = None - role: Optional[str] = None - -class UserLogin(BaseModel): - username: str - password: str - -class UserPasswordUpdate(BaseModel): - old_password: Optional[str] = None - new_password: str - -class TokenResponse(BaseModel): - access_token: str - token_type: str = "bearer" - user_id: int - username: str - role: str - -# --- Categories --- -class CategoryBase(BaseModel): - name: str - description: Optional[str] = None - -class CategoryCreate(CategoryBase): - pass - -class Category(CategoryBase): - id: int - - class Config: - from_attributes = True - -# --- Colors --- -class ColorBase(BaseModel): - name: str - -class ColorCreate(ColorBase): - pass - -class Color(ColorBase): - id: int - - class Config: - from_attributes = True - -# --- Items --- -class ItemBase(BaseModel): - name: str - category: str - category_id: Optional[int] = None - type: Optional[str] = None - barcode: str - part_number: Optional[str] = None - color: Optional[str] = None - description: Optional[str] = None - connector: Optional[str] = None - size: Optional[str] = None - ocr_text: Optional[str] = None - specs: Optional[str] = None - quantity: float = 0.0 - min_quantity: float = 1.0 - image_url: Optional[str] = None - box_label: Optional[str] = None - labels_data: Optional[str] = None - -class ItemCreate(ItemBase): - pass - -class Item(ItemBase): - id: int - - class Config: - from_attributes = True - -# --- Operations (Check-in/Check-out Validation) --- -class OperationCreate(BaseModel): - barcode: str - quantity: float - user_id: int - -class BulkOperationCreate(BaseModel): - user_id: int - items: List[OperationCreate] - -class TrashOperationCreate(BaseModel): - barcode: str - quantity: float - user_id: int - reason: Optional[str] = "unspecified" - -# --- Sync --- -class SyncOperation(BaseModel): - type: str # 'CHECK_IN', 'CHECK_OUT' - barcode: str - quantity: float - uuid: Optional[str] = None - timestamp: datetime - -class SyncPayload(BaseModel): - user_id: int - operations: List[SyncOperation] - -# --- Audit Logs --- -class AuditLogResponse(BaseModel): - id: int - timestamp: datetime - user_id: int - username: Optional[str] = None - action: str - target_item_id: Optional[int] - target_item_name: Optional[str] = None - target_item_pn: Optional[str] = None - target_item_barcode: Optional[str] = None - target_snapshot: Optional[str] = None - quantity_change: Optional[float] - details: Optional[str] = None - - class Config: - from_attributes = True - -# --- System Settings --- -class SystemSettingBase(BaseModel): - key: str - value: str - -class SystemSetting(SystemSettingBase): - class Config: - from_attributes = True - -# --- Database Management --- -class BackupInfo(BaseModel): - filename: str - size_bytes: int - created_at: datetime - -class DatabaseStats(BaseModel): - backup_count: int - total_size_bytes: int - -class DbSettingsUpdate(BaseModel): - retention_count: int - schedule_hour: int - schedule_freq_days: int diff --git a/backend/schemas/__init__.py b/backend/schemas/__init__.py new file mode 100644 index 00000000..5d6e6bd7 --- /dev/null +++ b/backend/schemas/__init__.py @@ -0,0 +1,70 @@ +# Re-export all schemas for backward compatibility +from .common import ( + SystemSettingBase, + SystemSetting, + BackupInfo, + DatabaseStats, + DbSettingsUpdate, +) +from .users import ( + UserBase, + UserCreate, + User, + UserUpdate, + UserLogin, + UserPasswordUpdate, + TokenResponse, +) +from .items import ( + CategoryBase, + CategoryCreate, + Category, + ColorBase, + ColorCreate, + Color, + ItemBase, + ItemCreate, + Item, +) +from .operations import ( + OperationCreate, + BulkOperationCreate, + TrashOperationCreate, + SyncOperation, + SyncPayload, + AuditLogResponse, +) + +__all__ = [ + # common + "SystemSettingBase", + "SystemSetting", + "BackupInfo", + "DatabaseStats", + "DbSettingsUpdate", + # users + "UserBase", + "UserCreate", + "User", + "UserUpdate", + "UserLogin", + "UserPasswordUpdate", + "TokenResponse", + # items + "CategoryBase", + "CategoryCreate", + "Category", + "ColorBase", + "ColorCreate", + "Color", + "ItemBase", + "ItemCreate", + "Item", + # operations + "OperationCreate", + "BulkOperationCreate", + "TrashOperationCreate", + "SyncOperation", + "SyncPayload", + "AuditLogResponse", +] diff --git a/backend/schemas/common.py b/backend/schemas/common.py new file mode 100644 index 00000000..466b6f60 --- /dev/null +++ b/backend/schemas/common.py @@ -0,0 +1,32 @@ +from pydantic import BaseModel +from typing import Optional, List +from datetime import datetime + + +# --- System Settings --- +class SystemSettingBase(BaseModel): + key: str + value: str + + +class SystemSetting(SystemSettingBase): + class Config: + from_attributes = True + + +# --- Database Management --- +class BackupInfo(BaseModel): + filename: str + size_bytes: int + created_at: datetime + + +class DatabaseStats(BaseModel): + backup_count: int + total_size_bytes: int + + +class DbSettingsUpdate(BaseModel): + retention_count: int + schedule_hour: int + schedule_freq_days: int diff --git a/backend/schemas/items.py b/backend/schemas/items.py new file mode 100644 index 00000000..0401535a --- /dev/null +++ b/backend/schemas/items.py @@ -0,0 +1,67 @@ +from pydantic import BaseModel +from typing import Optional + + +# --- Categories --- +class CategoryBase(BaseModel): + name: str + description: Optional[str] = None + + +class CategoryCreate(CategoryBase): + pass + + +class Category(CategoryBase): + id: int + + class Config: + from_attributes = True + + +# --- Colors --- +class ColorBase(BaseModel): + name: str + + +class ColorCreate(ColorBase): + pass + + +class Color(ColorBase): + id: int + + class Config: + from_attributes = True + + +# --- Items --- +class ItemBase(BaseModel): + name: str + category: str + category_id: Optional[int] = None + type: Optional[str] = None + barcode: str + part_number: Optional[str] = None + color: Optional[str] = None + description: Optional[str] = None + connector: Optional[str] = None + size: Optional[str] = None + ocr_text: Optional[str] = None + specs: Optional[str] = None + quantity: float = 0.0 + min_quantity: float = 1.0 + image_url: Optional[str] = None + box_label: Optional[str] = None + labels_data: Optional[str] = None + + +class ItemCreate(ItemBase): + pass + + +class Item(ItemBase): + id: int + + class Config: + from_attributes = True diff --git a/backend/schemas/operations.py b/backend/schemas/operations.py new file mode 100644 index 00000000..80b1156b --- /dev/null +++ b/backend/schemas/operations.py @@ -0,0 +1,55 @@ +from pydantic import BaseModel +from typing import Optional, List +from datetime import datetime + + +# --- Operations (Check-in/Check-out Validation) --- +class OperationCreate(BaseModel): + barcode: str + quantity: float + user_id: int + + +class BulkOperationCreate(BaseModel): + user_id: int + items: List[OperationCreate] + + +class TrashOperationCreate(BaseModel): + barcode: str + quantity: float + user_id: int + reason: Optional[str] = "unspecified" + + +# --- Sync --- +class SyncOperation(BaseModel): + type: str # 'CHECK_IN', 'CHECK_OUT' + barcode: str + quantity: float + uuid: Optional[str] = None + timestamp: datetime + + +class SyncPayload(BaseModel): + user_id: int + operations: List[SyncOperation] + + +# --- Audit Logs --- +class AuditLogResponse(BaseModel): + id: int + timestamp: datetime + user_id: int + username: Optional[str] = None + action: str + target_item_id: Optional[int] + target_item_name: Optional[str] = None + target_item_pn: Optional[str] = None + target_item_barcode: Optional[str] = None + target_snapshot: Optional[str] = None + quantity_change: Optional[float] + details: Optional[str] = None + + class Config: + from_attributes = True diff --git a/backend/schemas/users.py b/backend/schemas/users.py new file mode 100644 index 00000000..2556e23c --- /dev/null +++ b/backend/schemas/users.py @@ -0,0 +1,44 @@ +from pydantic import BaseModel +from typing import Optional + + +# --- Users --- +class UserBase(BaseModel): + username: str + role: str = "user" + origin: str = "local" + + +class UserCreate(UserBase): + password: Optional[str] = None + + +class User(UserBase): + id: int + + class Config: + from_attributes = True + + +class UserUpdate(BaseModel): + username: Optional[str] = None + password: Optional[str] = None + role: Optional[str] = None + + +class UserLogin(BaseModel): + username: str + password: str + + +class UserPasswordUpdate(BaseModel): + old_password: Optional[str] = None + new_password: str + + +class TokenResponse(BaseModel): + access_token: str + token_type: str = "bearer" + user_id: int + username: str + role: str