from __future__ import annotations from fastapi import APIRouter, Body, Request from typing import Any from app.api.v1.endpoints.platform import ok, fail from app.db.platform_store import get_platform_store router = APIRouter(prefix="/tenants", tags=["tenant"]) def _actor(request: Request) -> str | None: auth = request.headers.get("Authorization", "") token = auth.replace("Bearer ", "").strip() return token or None @router.get("") def list_tenants() -> dict[str, Any]: return ok(get_platform_store().tenants()) @router.post("") def create_tenant(payload: dict[str, Any] = Body(...), request: Request = None) -> dict[str, Any]: store = get_platform_store() try: tenant = store.create_tenant(payload) except KeyError as e: raise fail(400, f"missing field: {e}") store.record_audit( action="tenant.create", actor_id=_actor(request) if request else None, target_type="tenant", target_id=tenant["id"], tenant_id=tenant["id"], detail=f"name={tenant.get('name')}", ) return ok(tenant) @router.get("/{tenant_id}") def get_tenant(tenant_id: str) -> dict[str, Any]: try: return ok(get_platform_store().tenant(tenant_id)) except KeyError: raise fail(404, "tenant not found") @router.put("/{tenant_id}") def update_tenant(tenant_id: str, payload: dict[str, Any] = Body(...), request: Request = None) -> dict[str, Any]: store = get_platform_store() try: tenant = store.update_tenant(tenant_id, payload) except KeyError: raise fail(404, "tenant not found") store.record_audit( action="tenant.update", actor_id=_actor(request) if request else None, target_type="tenant", target_id=tenant_id, tenant_id=tenant_id, detail=f"fields={','.join(payload.keys())}", ) return ok(tenant) @router.put("/{tenant_id}/quota") def set_quota(tenant_id: str, payload: dict[str, Any] = Body(...), request: Request = None) -> dict[str, Any]: store = get_platform_store() try: tenant = store.set_tenant_quota(tenant_id, payload.get("quota", {})) except KeyError: raise fail(404, "tenant not found") store.record_audit( action="tenant.quota.set", actor_id=_actor(request) if request else None, target_type="tenant", target_id=tenant_id, tenant_id=tenant_id, ) return ok(tenant) @router.put("/{tenant_id}/retention-policy") def set_retention(tenant_id: str, payload: dict[str, Any] = Body(...), request: Request = None) -> dict[str, Any]: store = get_platform_store() try: tenant = store.set_tenant_retention(tenant_id, payload.get("retention_policy_id")) except KeyError: raise fail(404, "tenant not found") store.record_audit( action="tenant.retention.set", actor_id=_actor(request) if request else None, target_type="tenant", target_id=tenant_id, tenant_id=tenant_id, ) return ok(tenant) @router.delete("/{tenant_id}") def delete_tenant(tenant_id: str, request: Request = None) -> dict[str, Any]: store = get_platform_store() try: tenant = store.delete_tenant(tenant_id) except KeyError: raise fail(404, "tenant not found") store.record_audit( action="tenant.delete", actor_id=_actor(request) if request else None, target_type="tenant", target_id=tenant_id, tenant_id=tenant_id, detail=f"name={tenant.get('name')}", ) return ok(tenant)