Files
calminer/routes/maintenance.py
zwitschi 434be86b76 feat: Enhance dashboard metrics and summary statistics
- Added new summary fields: variance, 5th percentile, 95th percentile, VaR (95%), and expected shortfall (95%) to the dashboard.
- Updated the display logic for summary metrics to handle non-finite values gracefully.
- Modified the chart rendering to include additional percentile points and tail risk metrics in tooltips.

test: Introduce unit tests for consumption, costs, and other modules

- Created a comprehensive test suite for consumption, costs, equipment, maintenance, production, reporting, and simulation modules.
- Implemented fixtures for database setup and teardown using an in-memory SQLite database for isolated testing.
- Added tests for creating, listing, and validating various entities, ensuring proper error handling and response validation.

refactor: Consolidate parameter tests and remove deprecated files

- Merged parameter-related tests into a new test file for better organization and clarity.
- Removed the old parameter test file that was no longer in use.
- Improved test coverage for parameter creation, listing, and validation scenarios.

fix: Ensure proper validation and error handling in API endpoints

- Added validation to reject negative amounts in consumption and production records.
- Implemented checks to prevent duplicate scenario creation and ensure proper error messages are returned.
- Enhanced reporting endpoint tests to validate input formats and expected outputs.
2025-10-20 22:06:39 +02:00

93 lines
2.6 KiB
Python

from datetime import date
from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, status
from pydantic import BaseModel, ConfigDict, PositiveFloat
from sqlalchemy.orm import Session
from config.database import SessionLocal
from models.maintenance import Maintenance
router = APIRouter(prefix="/api/maintenance", tags=["Maintenance"])
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
class MaintenanceBase(BaseModel):
equipment_id: int
scenario_id: int
maintenance_date: date
description: Optional[str] = None
cost: PositiveFloat
class MaintenanceCreate(MaintenanceBase):
pass
class MaintenanceUpdate(MaintenanceBase):
pass
class MaintenanceRead(MaintenanceBase):
id: int
model_config = ConfigDict(from_attributes=True)
def _get_maintenance_or_404(db: Session, maintenance_id: int) -> Maintenance:
maintenance = db.query(Maintenance).filter(
Maintenance.id == maintenance_id).first()
if maintenance is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Maintenance record {maintenance_id} not found",
)
return maintenance
@router.post("/", response_model=MaintenanceRead, status_code=status.HTTP_201_CREATED)
def create_maintenance(maintenance: MaintenanceCreate, db: Session = Depends(get_db)):
db_maintenance = Maintenance(**maintenance.model_dump())
db.add(db_maintenance)
db.commit()
db.refresh(db_maintenance)
return db_maintenance
@router.get("/", response_model=List[MaintenanceRead])
def list_maintenance(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
return db.query(Maintenance).offset(skip).limit(limit).all()
@router.get("/{maintenance_id}", response_model=MaintenanceRead)
def get_maintenance(maintenance_id: int, db: Session = Depends(get_db)):
return _get_maintenance_or_404(db, maintenance_id)
@router.put("/{maintenance_id}", response_model=MaintenanceRead)
def update_maintenance(
maintenance_id: int,
payload: MaintenanceUpdate,
db: Session = Depends(get_db),
):
db_maintenance = _get_maintenance_or_404(db, maintenance_id)
for field, value in payload.model_dump().items():
setattr(db_maintenance, field, value)
db.commit()
db.refresh(db_maintenance)
return db_maintenance
@router.delete("/{maintenance_id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_maintenance(maintenance_id: int, db: Session = Depends(get_db)):
db_maintenance = _get_maintenance_or_404(db, maintenance_id)
db.delete(db_maintenance)
db.commit()