首次提交by MimoCode

This commit is contained in:
tang1219
2026-06-15 14:50:15 +08:00
parent 584b31da50
commit ead13f863c
166 changed files with 14908 additions and 1 deletions
+33
View File
@@ -0,0 +1,33 @@
from app.schemas.user import (
UserBase,
UserCreate,
UserUpdate,
UserResponse,
UserLogin,
Token
)
from app.schemas.medicine import (
MedicineBase,
MedicineCreate,
MedicineUpdate,
MedicineResponse,
MedicineWithStock
)
from app.schemas.batch import (
BatchBase,
BatchCreate,
BatchUpdate,
BatchResponse,
BatchDispense,
BatchAddStock
)
from app.schemas.category import (
CategoryBase,
CategoryCreate,
CategoryUpdate,
CategoryResponse
)
from app.schemas.auth import (
LoginRequest,
PasswordChangeRequest
)
+11
View File
@@ -0,0 +1,11 @@
from pydantic import BaseModel
class LoginRequest(BaseModel):
username: str
password: str
class PasswordChangeRequest(BaseModel):
old_password: str
new_password: str
+42
View File
@@ -0,0 +1,42 @@
from pydantic import BaseModel, Field
from typing import Optional
from datetime import date, datetime
class BatchBase(BaseModel):
batch_no: Optional[str] = None
production_date: Optional[date] = None
expiry_date: date
quantity: int = Field(default=0, ge=0)
location: Optional[str] = None
class BatchCreate(BatchBase):
pass
class BatchUpdate(BaseModel):
batch_no: Optional[str] = None
production_date: Optional[date] = None
expiry_date: Optional[date] = None
quantity: Optional[int] = None
location: Optional[str] = None
class BatchResponse(BatchBase):
id: int
medicine_id: int
is_expired: bool
created_at: datetime
updated_at: datetime
class Config:
from_attributes = True
class BatchDispense(BaseModel):
quantity: int = Field(..., gt=0)
class BatchAddStock(BaseModel):
quantity: int = Field(..., gt=0)
+36
View File
@@ -0,0 +1,36 @@
from pydantic import BaseModel, Field
from typing import Optional, List
from datetime import datetime
class CategoryBase(BaseModel):
name: str = Field(..., min_length=1, max_length=100)
parent_id: Optional[int] = None
level: int = Field(default=1, ge=1, le=2)
icon: Optional[str] = None
sort_order: int = 0
class CategoryCreate(CategoryBase):
pass
class CategoryUpdate(BaseModel):
name: Optional[str] = None
parent_id: Optional[int] = None
level: Optional[int] = None
icon: Optional[str] = None
sort_order: Optional[int] = None
class CategoryResponse(CategoryBase):
id: int
created_at: datetime
updated_at: datetime
class Config:
from_attributes = True
class CategoryWithChildren(CategoryResponse):
children: List["CategoryResponse"] = []
+58
View File
@@ -0,0 +1,58 @@
from pydantic import BaseModel, Field
from typing import Optional, List
from datetime import datetime, date
class MedicineBase(BaseModel):
name: str = Field(..., min_length=1, max_length=200)
generic_name: Optional[str] = None
brand_name: Optional[str] = None
manufacturer: Optional[str] = None
specification: Optional[str] = None
category_id: Optional[int] = None
description: Optional[str] = None
indications: Optional[str] = None
adult_dose: Optional[str] = None
child_dose: Optional[str] = None
contraindications: Optional[str] = None
notes: Optional[str] = None
expiry_grace_days: int = Field(default=0, ge=0, le=60)
class MedicineCreate(MedicineBase):
pass
class MedicineUpdate(BaseModel):
name: Optional[str] = None
generic_name: Optional[str] = None
brand_name: Optional[str] = None
manufacturer: Optional[str] = None
specification: Optional[str] = None
category_id: Optional[int] = None
description: Optional[str] = None
indications: Optional[str] = None
adult_dose: Optional[str] = None
child_dose: Optional[str] = None
contraindications: Optional[str] = None
notes: Optional[str] = None
expiry_grace_days: Optional[int] = None
class MedicineResponse(MedicineBase):
id: int
image_front_path: Optional[str] = None
image_expiry_path: Optional[str] = None
image_leaflet_paths: Optional[List[str]] = None
created_by: Optional[int] = None
created_at: datetime
updated_at: datetime
class Config:
from_attributes = True
class MedicineWithStock(MedicineResponse):
total_quantity: int = 0
nearest_expiry_date: Optional[date] = None
batch_count: int = 0
+44
View File
@@ -0,0 +1,44 @@
from pydantic import BaseModel, Field
from typing import Optional
from datetime import datetime
class UserBase(BaseModel):
username: str = Field(..., min_length=3, max_length=50)
display_name: Optional[str] = None
email: Optional[str] = None
role: str = Field(default="user", pattern="^(admin|user|readonly)$")
notification_level: str = Field(default="normal", pattern="^(none|low|normal|high)$")
class UserCreate(UserBase):
password: str = Field(..., min_length=6)
class UserUpdate(BaseModel):
display_name: Optional[str] = None
email: Optional[str] = None
role: Optional[str] = None
notification_level: Optional[str] = None
is_active: Optional[bool] = None
class UserResponse(UserBase):
id: int
is_active: bool
created_at: datetime
updated_at: datetime
class Config:
from_attributes = True
class UserLogin(BaseModel):
username: str
password: str
class Token(BaseModel):
access_token: str
token_type: str = "bearer"
user: UserResponse