from fastapi import FastAPI, HTTPException, Form from fastapi.responses import HTMLResponse import os, json, uuid from datetime import datetime DATA = "/data/inventory.json" app = FastAPI(redirect_slashes=False) def load(): if os.path.exists(DATA): with open(DATA) as f: return json.load(f) return {} def save(d): with open(DATA, "w") as f: json.dump(d, f, indent=2) @app.get("/api/list") def list_items(): items = load() return sorted( [{"id": k, **v} for k, v in items.items()], key=lambda x: (x.get("category", ""), x.get("name", "").lower()) ) @app.post("/api/add") def add(name: str = Form(""), category: str = Form(""), quantity: str = Form("1"), unit: str = Form(""), location: str = Form(""), expires: str = Form(""), notes: str = Form("")): items = load() fid = uuid.uuid4().hex[:12] try: qty = float(quantity or 1) except: qty = 1 items[fid] = { "name": name, "category": category, "quantity": qty, "unit": unit, "location": location, "expires": expires, "notes": notes, "added": datetime.utcnow().isoformat() } save(items) return {"id": fid} @app.patch("/api/update/{fid}") def update(fid: str, name: str = Form(None), category: str = Form(None), quantity: str = Form(None), unit: str = Form(None), location: str = Form(None), expires: str = Form(None), notes: str = Form(None)): items = load() if fid not in items: raise HTTPException(404) for k, v in {"name": name, "category": category, "unit": unit, "location": location, "expires": expires, "notes": notes}.items(): if v is not None: items[fid][k] = v if quantity is not None: try: items[fid]["quantity"] = float(quantity) except: pass save(items) return {"ok": True} @app.post("/api/adjust/{fid}") def adjust(fid: str, delta: str = Form(...)): items = load() if fid not in items: raise HTTPException(404) try: cur = float(items[fid].get("quantity", 0)) items[fid]["quantity"] = max(0, cur + float(delta)) except: raise HTTPException(400, "Invalid delta") save(items) return {"ok": True, "quantity": items[fid]["quantity"]} @app.delete("/api/delete/{fid}") def delete(fid: str): items = load() if fid not in items: raise HTTPException(404) del items[fid] save(items) return {"ok": True} @app.get("/", response_class=HTMLResponse) def root(): with open("/static/index.html") as f: return f.read()