Complete backend core implementation (BE-001 to BE-005): BE-001: Database Connection & Session Management - Create src/core/database.py with async SQLAlchemy 2.0 - Configure engine with pool_size=20 - Implement get_db() FastAPI dependency BE-002: SQLAlchemy Models (5 models) - Base model with TimestampMixin - Scenario: status enum, relationships, cost tracking - ScenarioLog: message hash, PII detection, metrics - ScenarioMetric: time-series with extra_data (JSONB) - AwsPricing: service pricing with region support - Report: format enum, file tracking, extra_data BE-003: Pydantic Schemas - Scenario: Create, Update, Response, List schemas - Log: Ingest, Response schemas - Metric: Summary, CostBreakdown, MetricsResponse - Common: PaginatedResponse generic type BE-004: Base Repository Pattern - Generic BaseRepository[T] with CRUD operations - Methods: get, get_multi, count, create, update, delete - Dynamic filter support BE-005: Scenario Repository - Extends BaseRepository[Scenario] - Specific methods: get_by_name, list_by_status, list_by_region - Business methods: update_status, increment_total_requests, update_total_cost - ScenarioStatus enum - Singleton instance: scenario_repository All models, schemas and repositories tested and working. Tasks: BE-001, BE-002, BE-003, BE-004, BE-005 complete
30 lines
949 B
Python
30 lines
949 B
Python
"""Report model."""
|
|
|
|
import uuid
|
|
from sqlalchemy import Column, String, Integer, DateTime, ForeignKey, Enum
|
|
from sqlalchemy.dialects.postgresql import UUID, JSONB
|
|
from sqlalchemy.orm import relationship
|
|
|
|
from src.models.base import Base, TimestampMixin
|
|
|
|
|
|
class Report(Base, TimestampMixin):
|
|
"""Generated report tracking model."""
|
|
|
|
__tablename__ = "reports"
|
|
|
|
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
scenario_id = Column(
|
|
UUID(as_uuid=True),
|
|
ForeignKey("scenarios.id", ondelete="CASCADE"),
|
|
nullable=False,
|
|
)
|
|
format = Column(Enum("pdf", "csv", name="report_format"), nullable=False)
|
|
file_path = Column(String(500), nullable=False)
|
|
file_size_bytes = Column(Integer, nullable=True)
|
|
generated_by = Column(String(100), nullable=True)
|
|
extra_data = Column(JSONB, default=dict)
|
|
|
|
# Relationships
|
|
scenario = relationship("Scenario", back_populates="reports")
|