Files
minerops/backend/app/frontend/router.py
T
2026-08-17 18:43:20 +00:00

142 lines
4.2 KiB
Python

"""HTTP routes for the MinerOps Internal Alpha application shell."""
from pathlib import Path
from typing import Annotated
from uuid import UUID
from fastapi import APIRouter, Depends, Query
from fastapi.responses import HTMLResponse, Response
from app.frontend.views import render_app_page
from app.identity import require_permission, safe_next_path, user_has_permission
router = APIRouter(tags=["frontend"])
STATIC_ROOT = Path(__file__).with_name("static")
DashboardUser = Annotated[dict, Depends(require_permission("dashboard.view"))]
MapUser = Annotated[dict, Depends(require_permission("locations.view"))]
RepairUser = Annotated[dict, Depends(require_permission("repairs.view"))]
MinerUser = Annotated[dict, Depends(require_permission("miners.view"))]
def render_page(view: str, current_user: dict, **context) -> str:
return render_app_page(
view,
current_user,
lambda permission: user_has_permission(current_user, permission),
**context,
)
@router.get("/assets/minerops-app.css", include_in_schema=False)
def frontend_styles() -> Response:
return Response(
(STATIC_ROOT / "app.css").read_text(encoding="utf-8"),
media_type="text/css",
headers={"Cache-Control": "no-store"},
)
@router.get("/assets/minerops-app.js", include_in_schema=False)
def frontend_script() -> Response:
return Response(
(STATIC_ROOT / "app.js").read_text(encoding="utf-8"),
media_type="text/javascript",
headers={"Cache-Control": "no-store"},
)
@router.get("/assets/minerops-dashboard.js", include_in_schema=False)
def dashboard_script() -> Response:
return Response(
(STATIC_ROOT / "dashboard.js").read_text(encoding="utf-8"),
media_type="text/javascript",
headers={"Cache-Control": "no-store"},
)
@router.get("/assets/minerops-mine-map.js", include_in_schema=False)
def mine_map_script() -> Response:
return Response(
(STATIC_ROOT / "mine-map.js").read_text(encoding="utf-8"),
media_type="text/javascript",
headers={"Cache-Control": "no-store"},
)
@router.get("/assets/minerops-fleet.js", include_in_schema=False)
def fleet_script() -> Response:
return Response(
(STATIC_ROOT / "fleet.js").read_text(encoding="utf-8"),
media_type="text/javascript",
headers={"Cache-Control": "no-store"},
)
@router.get("/assets/minerops-repair-center.js", include_in_schema=False)
def repair_center_script() -> Response:
return Response(
(STATIC_ROOT / "repair-center.js").read_text(encoding="utf-8"),
media_type="text/javascript",
headers={"Cache-Control": "no-store"},
)
@router.get("/assets/minerops-miner-detail.js", include_in_schema=False)
def miner_detail_script() -> Response:
return Response(
(STATIC_ROOT / "miner-detail.js").read_text(encoding="utf-8"),
media_type="text/javascript",
headers={"Cache-Control": "no-store"},
)
@router.get("/dashboard", response_class=HTMLResponse, include_in_schema=False)
def dashboard_page(current_user: DashboardUser) -> str:
return render_page("dashboard", current_user)
@router.get(
"/monitoring/map",
response_class=HTMLResponse,
include_in_schema=False,
)
def mine_map_page(current_user: MapUser) -> str:
return render_page("map", current_user)
@router.get(
"/operations/repairs",
response_class=HTMLResponse,
include_in_schema=False,
)
def repair_center_page(current_user: RepairUser) -> str:
return render_page("repairs", current_user)
@router.get(
"/assets/miners",
response_class=HTMLResponse,
include_in_schema=False,
)
def miners_page(current_user: MinerUser) -> str:
return render_page("miners", current_user)
@router.get(
"/miners/{miner_id}/detail",
response_class=HTMLResponse,
include_in_schema=False,
)
def miner_detail_page(
miner_id: UUID,
current_user: MinerUser,
return_to: Annotated[str | None, Query(max_length=2048)] = None,
) -> str:
safe_return = safe_next_path(return_to) if return_to else None
if safe_return != return_to:
safe_return = None
return render_page("miner_detail", current_user, miner_id=str(miner_id),
return_to=safe_return)