Spaces:
Sleeping
Sleeping
Download app/dda/masters_routes.py from coderuday21/satdetect-dev: direct link, hf CLI and curl.
- Browser
- Download file 8.54 kB
-
https://huggingface.co/spaces/coderuday21/satdetect-dev/resolve/main/app/dda/masters_routes.py
- Command line
-
hf download hf://spaces/coderuday21/satdetect-dev/app/dda/masters_routes.py
-
curl -L -o masters_routes.py https://huggingface.co/spaces/coderuday21/satdetect-dev/resolve/main/app/dda/masters_routes.py
8.54 kB
| """Zone / District and Village / Location master data.""" | |
| from __future__ import annotations | |
| from typing import Optional | |
| from fastapi import APIRouter, Depends, HTTPException | |
| from pydantic import BaseModel, Field | |
| from sqlalchemy.orm import Session | |
| from ..database import get_db | |
| from ..models import User | |
| from .models import DdaVillage, DdaZone, ImageAsset | |
| from .rbac.permissions import require_module_permission | |
| from .seed import seed_delhi_hierarchy | |
| router = APIRouter() | |
| def _require_dda(): | |
| from .config import IS_DDA_MODE | |
| if not IS_DDA_MODE: | |
| raise HTTPException(status_code=404, detail="DDA mode is not enabled") | |
| def _log_masters_action(db: Session, action: str, user: User, new_value: Optional[dict] = None) -> None: | |
| try: | |
| from .dda_auth import get_user_role | |
| from .tree.audit_service import log_action | |
| log_action( | |
| db, action, action_by=getattr(user, "email", "") or "", | |
| role=get_user_role(db, user), module="masters", new_value=new_value, | |
| ) | |
| db.commit() | |
| except Exception: | |
| import logging | |
| logging.getLogger(__name__).exception("Failed to write audit log for masters action %s", action) | |
| class ZoneBody(BaseModel): | |
| name: str = Field(..., min_length=1, max_length=128) | |
| mode: str = Field("admin", max_length=32) | |
| class VillageBody(BaseModel): | |
| name: str = Field(..., min_length=1, max_length=128) | |
| zone_id: int | |
| def _zone_dict(zone: DdaZone, village_count: int = 0) -> dict: | |
| return { | |
| "id": zone.id, | |
| "name": zone.name, | |
| "mode": zone.mode or "admin", | |
| "villageCount": village_count, | |
| "createdAt": zone.created_at.isoformat() if zone.created_at else None, | |
| } | |
| def _village_dict(village: DdaVillage, zone: Optional[DdaZone] = None) -> dict: | |
| z = zone or village.zone | |
| return { | |
| "id": village.id, | |
| "name": village.name, | |
| "zoneId": village.zone_id, | |
| "zoneName": z.name if z else "", | |
| "createdAt": village.created_at.isoformat() if village.created_at else None, | |
| } | |
| def list_zones( | |
| db: Session = Depends(get_db), | |
| user: User = Depends(require_module_permission("masters", "view")), | |
| ): | |
| _require_dda() | |
| seed_delhi_hierarchy(db) | |
| zones = db.query(DdaZone).order_by(DdaZone.name).all() | |
| counts = {} | |
| for v in db.query(DdaVillage).all(): | |
| counts[v.zone_id] = counts.get(v.zone_id, 0) + 1 | |
| return {"zones": [_zone_dict(z, counts.get(z.id, 0)) for z in zones]} | |
| def create_zone( | |
| body: ZoneBody, | |
| db: Session = Depends(get_db), | |
| user: User = Depends(require_module_permission("masters", "create")), | |
| ): | |
| _require_dda() | |
| name = body.name.strip() | |
| if db.query(DdaZone).filter(DdaZone.name == name).first(): | |
| raise HTTPException(status_code=409, detail="A zone with this name already exists.") | |
| zone = DdaZone(name=name, mode=(body.mode or "admin").strip() or "admin") | |
| db.add(zone) | |
| db.commit() | |
| db.refresh(zone) | |
| _log_masters_action(db, "create_zone", user, {"zone_id": zone.id, "name": zone.name}) | |
| return {"ok": True, "zone": _zone_dict(zone, 0)} | |
| def update_zone( | |
| zone_id: int, | |
| body: ZoneBody, | |
| db: Session = Depends(get_db), | |
| user: User = Depends(require_module_permission("masters", "edit")), | |
| ): | |
| _require_dda() | |
| zone = db.query(DdaZone).filter(DdaZone.id == zone_id).first() | |
| if not zone: | |
| raise HTTPException(status_code=404, detail="Zone not found") | |
| name = body.name.strip() | |
| clash = db.query(DdaZone).filter(DdaZone.name == name, DdaZone.id != zone_id).first() | |
| if clash: | |
| raise HTTPException(status_code=409, detail="A zone with this name already exists.") | |
| zone.name = name | |
| zone.mode = (body.mode or zone.mode or "admin").strip() | |
| db.commit() | |
| _log_masters_action(db, "update_zone", user, {"zone_id": zone.id, "name": zone.name}) | |
| count = db.query(DdaVillage).filter(DdaVillage.zone_id == zone.id).count() | |
| return {"ok": True, "zone": _zone_dict(zone, count)} | |
| def delete_zone( | |
| zone_id: int, | |
| db: Session = Depends(get_db), | |
| user: User = Depends(require_module_permission("masters", "delete")), | |
| ): | |
| _require_dda() | |
| zone = db.query(DdaZone).filter(DdaZone.id == zone_id).first() | |
| if not zone: | |
| raise HTTPException(status_code=404, detail="Zone not found") | |
| in_use = db.query(ImageAsset).filter(ImageAsset.zone_id == zone_id).count() | |
| if in_use: | |
| raise HTTPException(status_code=409, detail="This zone is used by library images and cannot be deleted.") | |
| zone_name = zone.name | |
| db.query(DdaVillage).filter(DdaVillage.zone_id == zone_id).delete(synchronize_session=False) | |
| db.delete(zone) | |
| db.commit() | |
| _log_masters_action(db, "delete_zone", user, {"zone_id": zone_id, "name": zone_name}) | |
| return {"ok": True} | |
| def list_villages( | |
| zone_id: Optional[int] = None, | |
| db: Session = Depends(get_db), | |
| user: User = Depends(require_module_permission("masters", "view")), | |
| ): | |
| _require_dda() | |
| seed_delhi_hierarchy(db) | |
| q = db.query(DdaVillage).order_by(DdaVillage.name) | |
| if zone_id: | |
| q = q.filter(DdaVillage.zone_id == zone_id) | |
| villages = q.all() | |
| zones = {z.id: z for z in db.query(DdaZone).all()} | |
| return { | |
| "villages": [_village_dict(v, zones.get(v.zone_id)) for v in villages], | |
| "zones": [_zone_dict(z) for z in sorted(zones.values(), key=lambda z: z.name)], | |
| } | |
| def create_village( | |
| body: VillageBody, | |
| db: Session = Depends(get_db), | |
| user: User = Depends(require_module_permission("masters", "create")), | |
| ): | |
| _require_dda() | |
| zone = db.query(DdaZone).filter(DdaZone.id == body.zone_id).first() | |
| if not zone: | |
| raise HTTPException(status_code=404, detail="Zone not found") | |
| name = body.name.strip() | |
| clash = ( | |
| db.query(DdaVillage) | |
| .filter(DdaVillage.zone_id == zone.id, DdaVillage.name == name) | |
| .first() | |
| ) | |
| if clash: | |
| raise HTTPException(status_code=409, detail="That location already exists in this zone.") | |
| village = DdaVillage(zone_id=zone.id, name=name) | |
| db.add(village) | |
| db.commit() | |
| db.refresh(village) | |
| _log_masters_action(db, "create_village", user, {"village_id": village.id, "name": village.name, "zone_id": zone.id}) | |
| return {"ok": True, "village": _village_dict(village, zone)} | |
| def update_village( | |
| village_id: int, | |
| body: VillageBody, | |
| db: Session = Depends(get_db), | |
| user: User = Depends(require_module_permission("masters", "edit")), | |
| ): | |
| _require_dda() | |
| village = db.query(DdaVillage).filter(DdaVillage.id == village_id).first() | |
| if not village: | |
| raise HTTPException(status_code=404, detail="Location not found") | |
| zone = db.query(DdaZone).filter(DdaZone.id == body.zone_id).first() | |
| if not zone: | |
| raise HTTPException(status_code=404, detail="Zone not found") | |
| name = body.name.strip() | |
| clash = ( | |
| db.query(DdaVillage) | |
| .filter( | |
| DdaVillage.zone_id == zone.id, | |
| DdaVillage.name == name, | |
| DdaVillage.id != village_id, | |
| ) | |
| .first() | |
| ) | |
| if clash: | |
| raise HTTPException(status_code=409, detail="That location already exists in this zone.") | |
| village.name = name | |
| village.zone_id = zone.id | |
| db.commit() | |
| _log_masters_action(db, "update_village", user, {"village_id": village.id, "name": village.name, "zone_id": zone.id}) | |
| return {"ok": True, "village": _village_dict(village, zone)} | |
| def delete_village( | |
| village_id: int, | |
| db: Session = Depends(get_db), | |
| user: User = Depends(require_module_permission("masters", "delete")), | |
| ): | |
| _require_dda() | |
| village = db.query(DdaVillage).filter(DdaVillage.id == village_id).first() | |
| if not village: | |
| raise HTTPException(status_code=404, detail="Location not found") | |
| in_use = db.query(ImageAsset).filter(ImageAsset.village_id == village_id).count() | |
| if in_use: | |
| raise HTTPException(status_code=409, detail="This location is used by library images and cannot be deleted.") | |
| village_name = village.name | |
| db.delete(village) | |
| db.commit() | |
| _log_masters_action(db, "delete_village", user, {"village_id": village_id, "name": village_name}) | |
| return {"ok": True} | |