feat: initial commit with seeded database and premium ui changes

This commit is contained in:
Dodo
2026-06-11 18:41:42 +07:00
commit edf94ae5c1
1684 changed files with 33073 additions and 0 deletions
+100
View File
@@ -0,0 +1,100 @@
from contextlib import asynccontextmanager
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel, Field
from typing import Dict, List, Optional
import logging
from fuzzy.engine import (
build_fuzzy_system,
compute_priority,
describe_inputs,
score_to_label,
)
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
_system = None
@asynccontextmanager
async def lifespan(app: FastAPI):
global _system
logger.info("Building fuzzy control system...")
_system = build_fuzzy_system()
logger.info("Fuzzy system ready.")
yield
app = FastAPI(title="Fuzzy Bansos API", lifespan=lifespan)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"],
)
class HouseholdInput(BaseModel):
id: int = 0
penghasilan: float = Field(default=1_500_000, ge=0)
tanggungan: float = Field(default=3, ge=0)
kondisi_rumah: float = Field(default=5, ge=0)
kepemilikan_aset: float = Field(default=5, ge=0)
class BatchInput(BaseModel):
households: List[HouseholdInput]
class FactorDetail(BaseModel):
kategori: str
derajat: float
class ScoreResult(BaseModel):
id: int
score: float
label: str
faktor: Optional[Dict[str, FactorDetail]] = None
def _score_household(hh: HouseholdInput, with_detail: bool = False) -> ScoreResult:
try:
score = compute_priority(
_system, hh.penghasilan, hh.tanggungan, hh.kondisi_rumah, hh.kepemilikan_aset
)
faktor = (
describe_inputs(
_system, hh.penghasilan, hh.tanggungan, hh.kondisi_rumah, hh.kepemilikan_aset
)
if with_detail else None
)
except ValueError as exc:
raise HTTPException(status_code=422, detail=str(exc))
except Exception:
logger.exception("Fuzzy computation failed for household id=%s", hh.id)
raise HTTPException(status_code=500, detail="Fuzzy computation failed")
return ScoreResult(id=hh.id, score=round(score, 2), label=score_to_label(score), faktor=faktor)
@app.get("/health")
def health():
return {"status": "ok", "system_ready": _system is not None}
@app.post("/compute", response_model=ScoreResult)
def compute_single(data: HouseholdInput):
if _system is None:
raise HTTPException(status_code=503, detail="Fuzzy system not ready")
return _score_household(data, with_detail=True)
@app.post("/batch")
def compute_batch(data: BatchInput):
if _system is None:
raise HTTPException(status_code=503, detail="Fuzzy system not ready")
results = [_score_household(hh) for hh in data.households]
return {"results": [r.model_dump(exclude_none=True) for r in results]}