Files
mockupAWS/src/repositories/report.py
Luca Sacchi Ricciardi a5fc85897b
Some checks failed
E2E Tests / Run E2E Tests (push) Has been cancelled
E2E Tests / Visual Regression Tests (push) Has been cancelled
E2E Tests / Smoke Tests (push) Has been cancelled
feat: implement v0.4.0 - Reports, Charts, Comparison, Dark Mode, E2E Testing
Backend (@backend-dev):
- Add ReportService with PDF/CSV generation (reportlab, pandas)
- Implement Report API endpoints (POST, GET, DELETE, download)
- Add ReportRepository and schemas
- Configure storage with auto-cleanup (30 days)
- Rate limiting: 10 downloads/minute
- Professional PDF templates with charts support

Frontend (@frontend-dev):
- Integrate Recharts for data visualization
- Add CostBreakdown, TimeSeries, ComparisonBar charts
- Implement scenario comparison page with multi-select
- Add dark/light mode toggle with ThemeProvider
- Create Reports page with generation form and list
- Add new UI components: checkbox, dialog, tabs, label, skeleton
- Implement useComparison and useReports hooks

QA (@qa-engineer):
- Setup Playwright E2E testing framework
- Create 7 test spec files with 94 test cases
- Add visual regression testing with baselines
- Configure multi-browser testing (Chrome, Firefox, WebKit)
- Add mobile responsive tests
- Create test fixtures and helpers
- Setup GitHub Actions CI workflow

Documentation (@spec-architect):
- Create detailed kanban-v0.4.0.md with 27 tasks
- Update progress.md with v0.4.0 tracking
- Create v0.4.0 planning prompt

Features:
 PDF/CSV Report Generation
 Interactive Charts (Pie, Area, Bar)
 Scenario Comparison (2-4 scenarios)
 Dark/Light Mode Toggle
 E2E Test Suite (94 tests)

Dependencies added:
- Backend: reportlab, pandas, slowapi
- Frontend: recharts, date-fns, @radix-ui/react-checkbox/dialog/tabs
- Testing: @playwright/test

27 tasks completed, 100% v0.4.0 implementation
2026-04-07 16:11:47 +02:00

55 lines
1.7 KiB
Python

"""Report repository with specific methods."""
from typing import Optional, List
from uuid import UUID
from datetime import datetime
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, update, desc
from src.models.report import Report
from src.repositories.base import BaseRepository
class ReportRepository(BaseRepository[Report]):
"""Repository for Report model with specific methods."""
def __init__(self):
super().__init__(Report)
async def get_by_scenario(
self, db: AsyncSession, scenario_id: UUID, skip: int = 0, limit: int = 100
) -> List[Report]:
"""Get reports for a specific scenario."""
query = (
select(Report)
.where(Report.scenario_id == scenario_id)
.order_by(desc(Report.created_at))
.offset(skip)
.limit(limit)
)
result = await db.execute(query)
return result.scalars().all()
async def count_by_scenario(self, db: AsyncSession, scenario_id: UUID) -> int:
"""Count reports for a specific scenario."""
query = select(Report).where(Report.scenario_id == scenario_id)
result = await db.execute(query)
return len(result.scalars().all())
async def update_file_size(
self, db: AsyncSession, report_id: UUID, file_size_bytes: int
) -> Optional[Report]:
"""Update report file size."""
result = await db.execute(
update(Report)
.where(Report.id == report_id)
.values(file_size_bytes=file_size_bytes)
.returning(Report)
)
await db.commit()
return result.scalar_one_or_none()
# Singleton instance
report_repository = ReportRepository()