Files
hms-licht-ton/backend/app/models/equipment.py
T
A0 Implementation Engineer e62ece1c06 feat: T03 backend core – FastAPI + DB models + Equipment API + Redis cache + health + tests
- FastAPI app with CORS, lifespan handlers
- Pydantic Settings config (DB, Redis, CORS, SMTP, JWT, Rentman)
- SQLAlchemy async engine + session (DeclarativeBase)
- 6 DB models: EquipmentCache, RentalRequest, RentalRequestItem, Contact, AdminUser, SyncLog
- Pydantic schemas: EquipmentItem, EquipmentDetail, PaginatedEquipment, ContactCreate, ContactResponse
- Redis cache helper: set/get/delete_pattern, rate limiting, equipment key builders
- Equipment router: list (search/category/sort/pagination), detail, categories – all cached
- Contact router: POST with Pydantic validation + rate limiting (5/min)
- Health router: GET /api/health with DB + Redis status
- 28 pytest tests (all pass, 90% coverage)
- Dockerfile, requirements.txt, pytest.ini, test_report.md
2026-07-09 01:26:45 +02:00

37 lines
1.7 KiB
Python

"""EquipmentCache SQLAlchemy model."""
from datetime import datetime
from sqlalchemy import JSON, Boolean, Index, Integer, Numeric, String, Text, func
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.orm import Mapped, mapped_column
from app.database import Base
class EquipmentCache(Base):
"""Cached equipment data imported from Rentman."""
__tablename__ = "equipment_cache"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
rentman_id: Mapped[str] = mapped_column(String(64), unique=True, nullable=False, index=True)
name: Mapped[str] = mapped_column(String(255), nullable=False, index=True)
number: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
category: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
subcategory: Mapped[str | None] = mapped_column(String(128), nullable=True)
description: Mapped[str | None] = mapped_column(Text, nullable=True)
specifications: Mapped[dict | None] = mapped_column(JSON, nullable=True)
images: Mapped[list | None] = mapped_column(JSON, nullable=True)
rental_price: Mapped[float | None] = mapped_column(Numeric(10, 2), nullable=True)
brand: Mapped[str | None] = mapped_column(String(128), nullable=True)
available: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
created_at: Mapped[datetime] = mapped_column(server_default=func.now(), nullable=False)
updated_at: Mapped[datetime] = mapped_column(server_default=func.now(), onupdate=func.now(), nullable=False)
__table_args__ = (
Index("idx_equipment_category", "category"),
Index("idx_equipment_name", "name"),
Index("idx_equipment_number", "number"),
)