Initial commit: Rentman Clone - Phase 0-6 (T001-T023)
Completed: - Phase 0: Project Setup (T001-T003) - Docker Compose, FastAPI skeleton, React SPA - Phase 1: Auth System (T004-T008) - DB models, JWT auth, RBAC middleware, user management - Phase 2: Contacts & Tags (T009-T011) - CRUD API + UI - Phase 3: Equipment Catalog (T012-T014) - Models, API, UI with barcode/QR - Phase 4: Crew Management (T015-T017) - Models, availability, UI - Phase 5: Vehicle Fleet (T018-T020) - Models, assignments, UI - Phase 6: Projects (T021-T023) - Project hierarchy models, CRUD API, list/detail UI
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
"""Role management endpoints (admin)."""
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.api.deps import get_current_user, require_permission
|
||||
from app.db.session import get_async_session
|
||||
from app.models import User, Role
|
||||
from app.schemas.role import RoleCreateRequest, RoleUpdateRequest, RoleResponse
|
||||
|
||||
router = APIRouter(prefix="/roles", tags=["roles"])
|
||||
|
||||
|
||||
@router.get("", response_model=list[RoleResponse])
|
||||
async def list_roles(
|
||||
current_user: User = Depends(require_permission("roles:read")),
|
||||
session: AsyncSession = Depends(get_async_session),
|
||||
):
|
||||
"""List all roles within the current account."""
|
||||
account_id = current_user.account_id
|
||||
result = await session.execute(
|
||||
select(Role).where(Role.account_id == account_id).order_by(Role.name)
|
||||
)
|
||||
roles = result.scalars().all()
|
||||
return [RoleResponse.model_validate(r) for r in roles]
|
||||
|
||||
|
||||
@router.post("", response_model=RoleResponse, status_code=status.HTTP_201_CREATED)
|
||||
async def create_role(
|
||||
body: RoleCreateRequest,
|
||||
current_user: User = Depends(require_permission("roles:write")),
|
||||
session: AsyncSession = Depends(get_async_session),
|
||||
):
|
||||
"""Create a new role within the current account."""
|
||||
account_id = current_user.account_id
|
||||
|
||||
# Check name uniqueness within account
|
||||
existing = await session.execute(
|
||||
select(Role).where(Role.account_id == account_id, Role.name == body.name)
|
||||
)
|
||||
if existing.scalars().first():
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT,
|
||||
detail="A role with this name already exists in your account",
|
||||
)
|
||||
|
||||
role = Role(
|
||||
account_id=account_id,
|
||||
name=body.name,
|
||||
description=body.description,
|
||||
permissions=body.permissions,
|
||||
)
|
||||
session.add(role)
|
||||
await session.commit()
|
||||
await session.refresh(role)
|
||||
return RoleResponse.model_validate(role)
|
||||
|
||||
|
||||
@router.put("/{role_id}", response_model=RoleResponse)
|
||||
async def update_role(
|
||||
role_id: str,
|
||||
body: RoleUpdateRequest,
|
||||
current_user: User = Depends(require_permission("roles:write")),
|
||||
session: AsyncSession = Depends(get_async_session),
|
||||
):
|
||||
"""Update a role's permissions, name, or description."""
|
||||
account_id = current_user.account_id
|
||||
result = await session.execute(
|
||||
select(Role).where(Role.id == role_id, Role.account_id == account_id)
|
||||
)
|
||||
role = result.scalars().first()
|
||||
if not role:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Role not found",
|
||||
)
|
||||
|
||||
if body.name is not None:
|
||||
role.name = body.name
|
||||
if body.description is not None:
|
||||
role.description = body.description
|
||||
if body.permissions is not None:
|
||||
role.permissions = body.permissions
|
||||
|
||||
await session.commit()
|
||||
await session.refresh(role)
|
||||
return RoleResponse.model_validate(role)
|
||||
Reference in New Issue
Block a user