mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-22 03:49:18 +02:00
Add soft-delete for system maintenance tasks
This commit is contained in:
@@ -177,7 +177,11 @@ async def get_maintenance_types(
|
||||
):
|
||||
"""Get all maintenance types."""
|
||||
await ensure_default_types(db)
|
||||
result = await db.execute(select(MaintenanceType).order_by(MaintenanceType.is_system.desc(), MaintenanceType.name))
|
||||
result = await db.execute(
|
||||
select(MaintenanceType)
|
||||
.where(MaintenanceType.is_deleted.is_(False))
|
||||
.order_by(MaintenanceType.is_system.desc(), MaintenanceType.name)
|
||||
)
|
||||
return result.scalars().all()
|
||||
|
||||
|
||||
@@ -230,20 +234,40 @@ async def delete_maintenance_type(
|
||||
db: AsyncSession = Depends(get_db),
|
||||
_: User | None = RequirePermissionIfAuthEnabled(Permission.MAINTENANCE_DELETE),
|
||||
):
|
||||
"""Delete a custom maintenance type."""
|
||||
"""Delete a maintenance type."""
|
||||
result = await db.execute(select(MaintenanceType).where(MaintenanceType.id == type_id))
|
||||
maint_type = result.scalar_one_or_none()
|
||||
if not maint_type:
|
||||
raise HTTPException(status_code=404, detail="Maintenance type not found")
|
||||
|
||||
if maint_type.is_system:
|
||||
raise HTTPException(status_code=400, detail="Cannot delete system maintenance type")
|
||||
maint_type.is_deleted = True
|
||||
await db.commit()
|
||||
return {"status": "deleted"}
|
||||
|
||||
await db.delete(maint_type)
|
||||
await db.commit()
|
||||
return {"status": "deleted"}
|
||||
|
||||
|
||||
@router.post("/types/restore-defaults")
|
||||
async def restore_default_maintenance_types(
|
||||
db: AsyncSession = Depends(get_db),
|
||||
_: User | None = RequirePermissionIfAuthEnabled(Permission.MAINTENANCE_DELETE),
|
||||
):
|
||||
"""Restore deleted default maintenance types."""
|
||||
await ensure_default_types(db)
|
||||
result = await db.execute(
|
||||
select(MaintenanceType).where(MaintenanceType.is_system.is_(True)).where(MaintenanceType.is_deleted.is_(True))
|
||||
)
|
||||
deleted_types = result.scalars().all()
|
||||
for maint_type in deleted_types:
|
||||
maint_type.is_deleted = False
|
||||
|
||||
await db.commit()
|
||||
return {"restored": len(deleted_types)}
|
||||
|
||||
|
||||
# ============== Printer Maintenance ==============
|
||||
|
||||
|
||||
@@ -264,7 +288,7 @@ async def _get_printer_maintenance_internal(
|
||||
total_hours = await get_printer_total_hours(db, printer_id)
|
||||
|
||||
# Get all maintenance types
|
||||
result = await db.execute(select(MaintenanceType))
|
||||
result = await db.execute(select(MaintenanceType).where(MaintenanceType.is_deleted.is_(False)))
|
||||
all_types = result.scalars().all()
|
||||
|
||||
# Get printer's maintenance items
|
||||
|
||||
@@ -188,6 +188,13 @@ async def run_migrations(conn):
|
||||
# Column already exists
|
||||
pass
|
||||
|
||||
# Migration: Add is_deleted column to maintenance_types for soft-deletes
|
||||
try:
|
||||
await conn.execute(text("ALTER TABLE maintenance_types ADD COLUMN is_deleted BOOLEAN DEFAULT 0"))
|
||||
except OperationalError:
|
||||
# Column already exists
|
||||
pass
|
||||
|
||||
# Migration: Add custom_interval_type column to printer_maintenance
|
||||
try:
|
||||
await conn.execute(text("ALTER TABLE printer_maintenance ADD COLUMN custom_interval_type VARCHAR(20)"))
|
||||
|
||||
@@ -22,6 +22,7 @@ class MaintenanceType(Base):
|
||||
icon: Mapped[str | None] = mapped_column(String(50)) # Icon name for UI
|
||||
wiki_url: Mapped[str | None] = mapped_column(String(500)) # Documentation link
|
||||
is_system: Mapped[bool] = mapped_column(Boolean, default=False) # Pre-defined vs custom
|
||||
is_deleted: Mapped[bool] = mapped_column(Boolean, default=False) # Hidden/removed type
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now())
|
||||
|
||||
# Relationships
|
||||
|
||||
@@ -137,7 +137,7 @@ def find_import_shadowing(file_path: Path) -> list[tuple[str, int, str]]:
|
||||
Returns list of (name, line_number, function_name) tuples.
|
||||
"""
|
||||
try:
|
||||
with open(file_path) as f:
|
||||
with open(file_path, encoding="utf-8") as f:
|
||||
source = f.read()
|
||||
tree = ast.parse(source)
|
||||
visitor = DangerousImportVisitor()
|
||||
|
||||
Reference in New Issue
Block a user