First commit
This commit is contained in:
123
src/core/schemas.py
Normal file
123
src/core/schemas.py
Normal file
@@ -0,0 +1,123 @@
|
||||
import json
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
|
||||
from core.database import Keypass
|
||||
|
||||
|
||||
# ── Auth ──────────────────────────────────────────────────────────────────────
|
||||
|
||||
class AdminLoginRequest(BaseModel):
|
||||
username: str
|
||||
password: str
|
||||
|
||||
|
||||
class KeypassLoginRequest(BaseModel):
|
||||
code: str
|
||||
|
||||
|
||||
class TokenResponse(BaseModel):
|
||||
token: str
|
||||
token_type: str = "bearer"
|
||||
|
||||
|
||||
# ── Keypasses ─────────────────────────────────────────────────────────────────
|
||||
|
||||
class KeypassCreate(BaseModel):
|
||||
description: str
|
||||
expires_at: Optional[datetime] = None # None = never expires
|
||||
gate_ids: list[int] = [] # empty = all gates
|
||||
code: Optional[str] = None # None = auto-generate
|
||||
|
||||
|
||||
class KeypassPatch(BaseModel):
|
||||
description: Optional[str] = None
|
||||
expires_at: Optional[datetime] = None # None = never expires
|
||||
gate_ids: Optional[list[int]] = None # None = keep unchanged; [] = all gates
|
||||
|
||||
|
||||
class KeypassResponse(BaseModel):
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
id: int
|
||||
code: str
|
||||
description: str
|
||||
created_at: datetime
|
||||
expires_at: Optional[datetime]
|
||||
revoked: bool
|
||||
revoked_at: Optional[datetime] = None
|
||||
allowed_gate_ids: list[int] # empty = all gates
|
||||
|
||||
|
||||
def keypass_to_response(kp: Keypass) -> KeypassResponse:
|
||||
return KeypassResponse(
|
||||
id=kp.id,
|
||||
code=kp.code,
|
||||
description=kp.description,
|
||||
created_at=kp.created_at,
|
||||
expires_at=kp.expires_at,
|
||||
revoked=kp.revoked,
|
||||
revoked_at=kp.revoked_at,
|
||||
allowed_gate_ids=json.loads(kp.allowed_gates) if kp.allowed_gates else [],
|
||||
)
|
||||
|
||||
|
||||
# ── Gates ─────────────────────────────────────────────────────────────────────
|
||||
|
||||
class GateResponse(BaseModel):
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
id: int
|
||||
name: str
|
||||
gate_type: str
|
||||
avconnect_macro_id: str
|
||||
status: str
|
||||
|
||||
|
||||
class GateCreate(BaseModel):
|
||||
name: str
|
||||
gate_type: str # 'car' | 'pedestrian'
|
||||
avconnect_macro_id: str
|
||||
status: str = "enabled"
|
||||
|
||||
|
||||
# ── AVConnect Credentials ─────────────────────────────────────────────────────
|
||||
|
||||
class CredentialRead(BaseModel):
|
||||
id: int
|
||||
username: str
|
||||
|
||||
|
||||
class CredentialUpsert(BaseModel):
|
||||
username: str
|
||||
password: str
|
||||
|
||||
|
||||
# ── Admin users ───────────────────────────────────────────────────────────────
|
||||
|
||||
class AdminUserResponse(BaseModel):
|
||||
id: int
|
||||
username: str
|
||||
role: str # 'admin' | 'manager'
|
||||
|
||||
|
||||
class AdminUserCreate(BaseModel):
|
||||
username: str
|
||||
password: str
|
||||
role: str = "admin" # 'admin' | 'manager'
|
||||
|
||||
|
||||
# ── Statistics ────────────────────────────────────────────────────────────────
|
||||
|
||||
class AccessLogResponse(BaseModel):
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
id: int
|
||||
timestamp: datetime
|
||||
keypass_id: int
|
||||
keypass_code: str
|
||||
gate_id: int
|
||||
gate_name: str
|
||||
ip_address: Optional[str]
|
||||
user_agent: Optional[str]
|
||||
success: bool
|
||||
error: Optional[str]
|
||||
Reference in New Issue
Block a user