First commit

This commit is contained in:
Ettore
2026-05-06 01:51:22 +02:00
commit 78fca8ebc2
56 changed files with 2584 additions and 0 deletions

123
src/core/schemas.py Normal file
View 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]