from fastapi import FastAPI, HTTPException from fastapi.middleware.cors import CORSMiddleware from pydantic import BaseModel from typing import Optional import json, os DB_FILE = "db.json" app = FastAPI( title="Vehicle Maintenance API", docs_url="/", # Swagger UI served at root redoc_url="/redoc" # optional: keep ReDoc at /redoc ) # Allow frontend calls for testing app.add_middleware( CORSMiddleware, allow_origins=["*"], # you can restrict this in production allow_methods=["*"], allow_headers=["*"], ) # ---------------- Pydantic Models ---------------- class Vehicle(BaseModel): regNo: str category: str currentOdometer: int date: str id: Optional[int] = None class Part(BaseModel): partName: str category: str durationDays: int intervalKM: int id: Optional[int] = None class MaintenanceLog(BaseModel): regNo: str partName: str category: str date: str nextServiceDate: str nextServiceKM: int nextDay: int nextKM: int id: Optional[int] = None # ---------------- Helpers ---------------- def load_db(): if not os.path.exists(DB_FILE): return {"vehicles": [], "parts": [], "maintenance_logs": []} try: with open(DB_FILE, "r") as f: content = f.read().strip() if not content: return {"vehicles": [], "parts": [], "maintenance_logs": []} return json.loads(content) except (json.JSONDecodeError, IOError): # fallback: reset db if corrupted return {"vehicles": [], "parts": [], "maintenance_logs": []} def save_db(data): with open(DB_FILE, "w") as f: json.dump(data, f, indent=2) def generate_id(items): if not items: return 1 ids = [item["id"] for item in items if item.get("id") is not None] return (max(ids, default=0) if ids else 0) + 1 # ---------------- Vehicles CRUD ---------------- @app.get("/vehicles") def get_vehicles(): return load_db()["vehicles"] @app.post("/vehicles") def create_vehicle(vehicle: Vehicle): data = load_db() vehicle.id = generate_id(data["vehicles"]) data["vehicles"].append(vehicle.dict()) save_db(data) return vehicle @app.put("/vehicles/{vid}") def update_vehicle(vid: int, vehicle: Vehicle): data = load_db() for v in data["vehicles"]: if v["id"] == vid: v.update(vehicle.dict()) save_db(data) return v raise HTTPException(status_code=404, detail="Vehicle not found") @app.delete("/vehicles/{vid}") def delete_vehicle(vid: int): data = load_db() new_list = [v for v in data["vehicles"] if v["id"] != vid] if len(new_list) == len(data["vehicles"]): raise HTTPException(status_code=404, detail="Vehicle not found") data["vehicles"] = new_list save_db(data) return {"success": True} # ---------------- Parts CRUD ---------------- @app.get("/parts") def get_parts(): return load_db()["parts"] @app.post("/parts") def create_part(part: Part): data = load_db() part.id = generate_id(data["parts"]) data["parts"].append(part.dict()) save_db(data) return part @app.put("/parts/{pid}") def update_part(pid: int, part: Part): data = load_db() for p in data["parts"]: if p["id"] == pid: p.update(part.dict()) save_db(data) return p raise HTTPException(status_code=404, detail="Part not found") @app.delete("/parts/{pid}") def delete_part(pid: int): data = load_db() new_list = [p for p in data["parts"] if p["id"] != pid] if len(new_list) == len(data["parts"]): raise HTTPException(status_code=404, detail="Part not found") data["parts"] = new_list save_db(data) return {"success": True} # ---------------- Maintenance CRUD ---------------- @app.get("/maintenance") def get_maintenance(): return load_db()["maintenance_logs"] @app.post("/maintenance") def create_maintenance(log: MaintenanceLog): data = load_db() log.id = generate_id(data["maintenance_logs"]) data["maintenance_logs"].append(log.dict()) save_db(data) return log @app.put("/maintenance/{mid}") def update_maintenance(mid: int, log: MaintenanceLog): data = load_db() for l in data["maintenance_logs"]: if l["id"] == mid: l.update(log.dict()) save_db(data) return l raise HTTPException(status_code=404, detail="Maintenance log not found") @app.delete("/maintenance/{mid}") def delete_maintenance(mid: int): data = load_db() new_list = [l for l in data["maintenance_logs"] if l["id"] != mid] if len(new_list) == len(data["maintenance_logs"]): raise HTTPException(status_code=404, detail="Maintenance log not found") data["maintenance_logs"] = new_list save_db(data) return {"success": True}