# /opt/docker/dev/service_finder/backend/app/api/v1/endpoints/finance_admin.py """ Finance Admin API endpoints for managing Issuers with strict RBAC protection. Only users with rank >= 90 (Superadmin/Finance Admin) can access these endpoints. """ from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select from typing import List from app.api import deps from app.models.identity import User, UserRole from app.models.marketplace.finance import Issuer from app.schemas.finance import IssuerResponse, IssuerUpdate router = APIRouter() async def check_finance_admin_access( current_user: User = Depends(deps.get_current_active_user) ): """ RBAC protection: only users with rank >= 90 (Superadmin/Finance Admin) can access. In our system, this translates to role being 'superadmin' or 'admin'. """ if current_user.role not in [UserRole.superadmin, UserRole.admin]: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Not enough permissions. Rank >= 90 (Superadmin/Finance Admin) required." ) return current_user @router.get("/", response_model=List[IssuerResponse], tags=["finance-admin"]) async def list_issuers( db: AsyncSession = Depends(deps.get_db), admin: User = Depends(check_finance_admin_access) ): """ List all Issuers (billing entities). Only accessible by Superadmin/Finance Admin (rank >= 90). """ result = await db.execute(select(Issuer).order_by(Issuer.id)) issuers = result.scalars().all() return issuers @router.patch("/{issuer_id}", response_model=IssuerResponse, tags=["finance-admin"]) async def update_issuer( issuer_id: int, issuer_update: IssuerUpdate, db: AsyncSession = Depends(deps.get_db), admin: User = Depends(check_finance_admin_access) ): """ Update an Issuer's details (activate/deactivate, revenue limit, API config). Only accessible by Superadmin/Finance Admin (rank >= 90). """ result = await db.execute(select(Issuer).where(Issuer.id == issuer_id)) issuer = result.scalar_one_or_none() if not issuer: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"Issuer with ID {issuer_id} not found." ) # Update fields if provided update_data = issuer_update.model_dump(exclude_unset=True) for field, value in update_data.items(): setattr(issuer, field, value) await db.commit() await db.refresh(issuer) return issuer