Write

"""
Permissions Router
==================

API endpoints for permission management within projects.
"""

from datetime import datetime
from typing import Optional, List

from fastapi import APIRouter, Depends, HTTPException, status
from pydantic import BaseModel, Field
from sqlalchemy import select, and_
from sqlalchemy.ext.asyncio import AsyncSession

from ..database import get_db
from ..models import Project, Permission, PermissionRequest

router = APIRouter(prefix="/api/projects", tags=["permissions"])

# ============================================================================
# Pydantic Schemas
# ============================================================================

class PermissionResponse(BaseModel):
    """Schema for permission response."""
    id: int
    project_id: int
    permission_type: str
    permission_value: str
    granted: bool
    created_at: datetime

    class Config:
        from_attributes = True

class PermissionListResponse(BaseModel):
    """Schema for permission list response."""
    permissions: List[PermissionResponse]
    count: int

class PermissionCreate(BaseModel):
    """Schema for creating a permission."""
    permission_type: str = Field(..., min_length=1, max_length=50)
    permission_value: str = Field(..., min_length=1, max_length=500)
    granted: bool = True

class PermissionUpdate(BaseModel):
    """Schema for updating a permission."""
    granted: Optional[bool] = None

class PermissionRequestResponse(BaseModel):
    """Schema for permission request response."""
    id: int
    project_id: int
    feature_id: Optional[int]
    agent_id: str
    permission_type: str
    permission_value: str
    status: str
    requested_at: datetime
    resolved_at: Optional[datetime]

    class Config:
        from_attributes = True

class PermissionRequestListResponse(BaseModel):
    """Schema for permission request list response."""
    requests: List[PermissionRequestResponse]
    count: int

class PermissionRequestCreate(BaseModel):
    """Schema for creating a permission request."""
    agent_id: str = Field(..., min_length=1, max_length=1)  # "A" or "B"
    permission_type: str = Field(..., min_length=1, max_length=50)
    permission_value: str = Field(..., min_length=1, max_length=500)
    feature_id: Optional[int] = None

# ============================================================================
# Permission Endpoints
# ============================================================================

@router.get("/{name}/permissions", response_model=PermissionListResponse)
async def list_permissions(name: str, db: AsyncSession = Depends(get_db)):
    """List all permissions for a project."""
    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    # Get permissions
    result = await db.execute(
        select(Permission)
        .where(Permission.project_id == project.id)
        .order_by(Permission.created_at.desc())
    )
    permissions = result.scalars().all()

    return PermissionListResponse(
        permissions=[PermissionResponse.model_validate(p) for p in permissions],
        count=len(permissions)
    )

@router.post("/{name}/permissions", response_model=PermissionResponse, status_code=status.HTTP_201_CREATED)
async def create_permission(name: str, permission: PermissionCreate, db: AsyncSession = Depends(get_db)):
    """Create a new permission for a project."""
    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    # Check if permission already exists
    result = await db.execute(
        select(Permission).where(and_(
            Permission.project_id == project.id,
            Permission.permission_type == permission.permission_type,
            Permission.permission_value == permission.permission_value
        ))
    )
    existing = result.scalar_one_or_none()
    if existing:
        raise HTTPException(
            status_code=status.HTTP_409_CONFLICT,
            detail=f"Permission already exists"
        )

    # Create permission
    db_permission = Permission(
        project_id=project.id,
        permission_type=permission.permission_type,
        permission_value=permission.permission_value,
        granted=permission.granted,
    )
    db.add(db_permission)
    await db.commit()
    await db.refresh(db_permission)

    return PermissionResponse.model_validate(db_permission)

@router.get("/{name}/permissions/{permission_id}", response_model=PermissionResponse)
async def get_permission(name: str, permission_id: int, db: AsyncSession = Depends(get_db)):
    """Get a specific permission by ID."""
    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    # Get permission
    result = await db.execute(
        select(Permission).where(and_(
            Permission.id == permission_id,
            Permission.project_id == project.id
        ))
    )
    permission = result.scalar_one_or_none()

    if not permission:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Permission {permission_id} not found in project '{name}'"
        )

    return PermissionResponse.model_validate(permission)

@router.put("/{name}/permissions/{permission_id}", response_model=PermissionResponse)
async def update_permission(name: str, permission_id: int, permission_update: PermissionUpdate, db: AsyncSession = Depends(get_db)):
    """Update a permission."""
    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    # Get permission
    result = await db.execute(
        select(Permission).where(and_(
            Permission.id == permission_id,
            Permission.project_id == project.id
        ))
    )
    permission = result.scalar_one_or_none()

    if not permission:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Permission {permission_id} not found in project '{name}'"
        )

    # Update granted status
    if permission_update.granted is not None:
        permission.granted = permission_update.granted

    await db.commit()
    await db.refresh(permission)

    return PermissionResponse.model_validate(permission)

@router.delete("/{name}/permissions/{permission_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_permission(name: str, permission_id: int, db: AsyncSession = Depends(get_db)):
    """Delete a permission."""
    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    # Get permission
    result = await db.execute(
        select(Permission).where(and_(
            Permission.id == permission_id,
            Permission.project_id == project.id
        ))
    )
    permission = result.scalar_one_or_none()

    if not permission:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Permission {permission_id} not found in project '{name}'"
        )

    await db.delete(permission)
    await db.commit()

# ============================================================================
# Permission Request Endpoints
# ============================================================================

@router.get("/{name}/permission-requests", response_model=PermissionRequestListResponse)
async def list_permission_requests(
    name: str,
    status_filter: Optional[str] = None,
    db: AsyncSession = Depends(get_db)
):
    """List permission requests for a project."""
    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    # Build query
    query = select(PermissionRequest).where(PermissionRequest.project_id == project.id)

    if status_filter:
        query = query.where(PermissionRequest.status == status_filter)

    query = query.order_by(PermissionRequest.requested_at.desc())

    result = await db.execute(query)
    requests = result.scalars().all()

    return PermissionRequestListResponse(
        requests=[PermissionRequestResponse.model_validate(r) for r in requests],
        count=len(requests)
    )

@router.post("/{name}/permission-requests", response_model=PermissionRequestResponse, status_code=status.HTTP_201_CREATED)
async def create_permission_request(name: str, request: PermissionRequestCreate, db: AsyncSession = Depends(get_db)):
    """Create a new permission request (typically called by agents)."""
    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    # Create permission request
    db_request = PermissionRequest(
        project_id=project.id,
        feature_id=request.feature_id,
        agent_id=request.agent_id,
        permission_type=request.permission_type,
        permission_value=request.permission_value,
        status="pending",
    )
    db.add(db_request)
    await db.commit()
    await db.refresh(db_request)

    return PermissionRequestResponse.model_validate(db_request)

@router.post("/{name}/permission-requests/{request_id}/grant", response_model=PermissionRequestResponse)
async def grant_permission_request(name: str, request_id: int, db: AsyncSession = Depends(get_db)):
    """Grant a pending permission request."""
    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    # Get permission request
    result = await db.execute(
        select(PermissionRequest).where(and_(
            PermissionRequest.id == request_id,
            PermissionRequest.project_id == project.id
        ))
    )
    request = result.scalar_one_or_none()

    if not request:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Permission request {request_id} not found"
        )

    if request.status != "pending":
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"Permission request is already {request.status}"
        )

    # Update request status
    request.status = "granted"
    request.resolved_at = datetime.utcnow()

    # Create the actual permission
    db_permission = Permission(
        project_id=project.id,
        permission_type=request.permission_type,
        permission_value=request.permission_value,
        granted=True,
    )
    db.add(db_permission)

    await db.commit()
    await db.refresh(request)

    return PermissionRequestResponse.model_validate(request)

@router.post("/{name}/permission-requests/{request_id}/deny", response_model=PermissionRequestResponse)
async def deny_permission_request(name: str, request_id: int, db: AsyncSession = Depends(get_db)):
    """Deny a pending permission request."""
    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    # Get permission request
    result = await db.execute(
        select(PermissionRequest).where(and_(
            PermissionRequest.id == request_id,
            PermissionRequest.project_id == project.id
        ))
    )
    request = result.scalar_one_or_none()

    if not request:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Permission request {request_id} not found"
        )

    if request.status != "pending":
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"Permission request is already {request.status}"
        )

    # Update request status
    request.status = "denied"
    request.resolved_at = datetime.utcnow()

    await db.commit()
    await db.refresh(request)

    return PermissionRequestResponse.model_validate(request)


<tool_use_error>File has not been read yet. Read it first before writing to it.</tool_use_error>

Error: File has not been read yet. Read it first before writing to it.


This is very frustrating - the system keeps losing track of my file reads. Let me try reading a smaller portion and editing just that.


     1→"""
     2→Permissions Router
     3→==================
     4→
     5→API endpoints for permission management within projects.
     6→"""
     7→
     8→from datetime import datetime
     9→from typing import Optional, List
    10→
    11→from fastapi import APIRouter, Depends, HTTPException, status
    12→from pydantic import BaseModel, Field
    13→from sqlalchemy import select, and_
    14→from sqlalchemy.ext.asyncio import AsyncSession
    15→
    16→from ..database import get_db
    17→from ..models import Project, Permission, PermissionRequest
    18→
    19→router = APIRouter(prefix="/api/projects", tags=["permissions"])
    20→
    21→
    22→# ============================================================================
    23→# Pydantic Schemas
    24→# ============================================================================
    25→
    26→class PermissionResponse(BaseModel):
    27→    """Schema for permission response."""
    28→    id: int
    29→    project_id: int
    30→    permission_type: str
    31→    permission_value: str
    32→    granted: bool
    33→    created_at: datetime
    34→
    35→    class Config:
    36→        from_attributes = True
    37→
    38→
    39→class PermissionListResponse(BaseModel):
    40→    """Schema for permission list response."""
    41→    permissions: List[PermissionResponse]
    42→    count: int
    43→
    44→
    45→class PermissionCreate(BaseModel):
    46→    """Schema for creating a permission."""
    47→    permission_type: str = Field(..., min_length=1, max_length=50)
    48→    permission_value: str = Field(..., min_length=1, max_length=500)
    49→    granted: bool = True
    50→
    51→
    52→class PermissionUpdate(BaseModel):
    53→    """Schema for updating a permission."""
    54→    granted: Optional[bool] = None
    55→
    56→
    57→class PermissionRequestResponse(BaseModel):
    58→    """Schema for permission request response."""
    59→    id: int
    60→    project_id: int
    61→    feature_id: Optional[int]
    62→    agent_id: str
    63→    permission_type: str
    64→    permission_value: str
    65→    status: str
    66→    requested_at: datetime
    67→    resolved_at: Optional[datetime]
    68→
    69→    class Config:
    70→        from_attributes = True
    71→
    72→
    73→class PermissionRequestListResponse(BaseModel):
    74→    """Schema for permission request list response."""
    75→    requests: List[PermissionRequestResponse]
    76→    count: int
    77→
    78→
    79→# ============================================================================
    80→# Permission Endpoints
    81→# ============================================================================
    82→
    83→@router.get("/{name}/permissions", response_model=PermissionListResponse)
    84→async def list_permissions(name: str, db: AsyncSession = Depends(get_db)):
    85→    """List all permissions for a project."""
    86→    # Verify project exists
    87→    result = await db.execute(select(Project).where(Project.name == name))
    88→    project = result.scalar_one_or_none()
    89→
    90→    if not project:
    91→        raise HTTPException(
    92→            status_code=status.HTTP_404_NOT_FOUND,
    93→            detail=f"Project '{name}' not found"
    94→        )
    95→
    96→    # Get permissions
    97→    result = await db.execute(
    98→        select(Permission)
    99→        .where(Permission.project_id == project.id)
   100→        .order_by(Permission.created_at.desc())

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>

"""
Permissions Router
==================

API endpoints for permission management within projects.
"""

from datetime import datetime
from typing import Optional, List

from fastapi import APIRouter, Depends, HTTPException, status
from pydantic import BaseModel, Field
from sqlalchemy import select, and_
from sqlalchemy.ext.asyncio import AsyncSession

from ..database import get_db
from ..models import Project, Permission, PermissionRequest

router = APIRouter(prefix="/api/projects", tags=["permissions"])

# ============================================================================
# Pydantic Schemas
# ============================================================================

class PermissionResponse(BaseModel):
    """Schema for permission response."""
    id: int
    project_id: int
    permission_type: str
    permission_value: str
    granted: bool
    created_at: datetime

    class Config:
        from_attributes = True

class PermissionListResponse(BaseModel):
    """Schema for permission list response."""
    permissions: List[PermissionResponse]
    count: int

class PermissionCreate(BaseModel):
    """Schema for creating a permission."""
    permission_type: str = Field(..., min_length=1, max_length=50)
    permission_value: str = Field(..., min_length=1, max_length=500)
    granted: bool = True

class PermissionUpdate(BaseModel):
    """Schema for updating a permission."""
    granted: Optional[bool] = None

class PermissionRequestResponse(BaseModel):
    """Schema for permission request response."""
    id: int
    project_id: int
    feature_id: Optional[int]
    agent_id: str
    permission_type: str
    permission_value: str
    status: str
    requested_at: datetime
    resolved_at: Optional[datetime]

    class Config:
        from_attributes = True

class PermissionRequestListResponse(BaseModel):
    """Schema for permission request list response."""
    requests: List[PermissionRequestResponse]
    count: int

# ============================================================================
# Permission Endpoints
# ============================================================================

@router.get("/{name}/permissions", response_model=PermissionListResponse)
async def list_permissions(name: str, db: AsyncSession = Depends(get_db)):
    """List all permissions for a project."""
    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    # Get permissions
    result = await db.execute(
        select(Permission)
        .where(Permission.project_id == project.id)
        .order_by(Permission.created_at.desc())


Edit

class PermissionRequestListResponse(BaseModel):
    """Schema for permission request list response."""
    requests: List[PermissionRequestResponse]
    count: int

# ============================================================================
# Permission Endpoints

class PermissionRequestListResponse(BaseModel):
    """Schema for permission request list response."""
    requests: List[PermissionRequestResponse]
    count: int

class PermissionRequestCreate(BaseModel):
    """Schema for creating a permission request."""
    agent_id: str = Field(..., min_length=1, max_length=1)  # "A" or "B"
    permission_type: str = Field(..., min_length=1, max_length=50)
    permission_value: str = Field(..., min_length=1, max_length=500)
    feature_id: Optional[int] = None

# ============================================================================
# Permission Endpoints


Error: File has been unexpectedly modified. Read it again before attempting to write it.


I think there might be something constantly modifying this file. Let me check.


Bash

git -C "C:/Users/MikeSwanson/claude-projects/Autocode-remix/Autocode-fork" diff backend/app/routers/permissions.py 2>/dev/null || true

Check git diff on permissions.py


Error: Command 'true' is not in the allowed commands list


git -C "C:/Users/MikeSwanson/claude-projects/Autocode-remix/Autocode-fork" diff backend/app/routers/permissions.py

Check git diff on permissions.py


     1→"""
     2→Permissions Router
     3→==================
     4→
     5→API endpoints for permission management within projects.
     6→"""
     7→
     8→from datetime import datetime
     9→from typing import Optional, List
    10→
    11→from fastapi import APIRouter, Depends, HTTPException, status
    12→from pydantic import BaseModel, Field
    13→from sqlalchemy import select, and_
    14→from sqlalchemy.ext.asyncio import AsyncSession
    15→
    16→from ..database import get_db
    17→from ..models import Project, Permission, PermissionRequest
    18→
    19→router = APIRouter(prefix="/api/projects", tags=["permissions"])
    20→
    21→
    22→# ============================================================================
    23→# Pydantic Schemas
    24→# ============================================================================
    25→
    26→class PermissionResponse(BaseModel):
    27→    """Schema for permission response."""
    28→    id: int
    29→    project_id: int
    30→    permission_type: str
    31→    permission_value: str
    32→    granted: bool
    33→    created_at: datetime
    34→
    35→    class Config:
    36→        from_attributes = True
    37→
    38→
    39→class PermissionListResponse(BaseModel):
    40→    """Schema for permission list response."""
    41→    permissions: List[PermissionResponse]
    42→    count: int
    43→
    44→
    45→class PermissionCreate(BaseModel):
    46→    """Schema for creating a permission."""
    47→    permission_type: str = Field(..., min_length=1, max_length=50)
    48→    permission_value: str = Field(..., min_length=1, max_length=500)
    49→    granted: bool = True
    50→
    51→
    52→class PermissionUpdate(BaseModel):
    53→    """Schema for updating a permission."""
    54→    granted: Optional[bool] = None
    55→
    56→
    57→class PermissionRequestResponse(BaseModel):
    58→    """Schema for permission request response."""
    59→    id: int
    60→    project_id: int
    61→    feature_id: Optional[int]
    62→    agent_id: str
    63→    permission_type: str
    64→    permission_value: str
    65→    status: str
    66→    requested_at: datetime
    67→    resolved_at: Optional[datetime]
    68→
    69→    class Config:
    70→        from_attributes = True
    71→
    72→
    73→class PermissionRequestListResponse(BaseModel):
    74→    """Schema for permission request list response."""
    75→    requests: List[PermissionRequestResponse]
    76→    count: int
    77→
    78→
    79→# ============================================================================
    80→# Permission Endpoints
    81→# ============================================================================
    82→
    83→@router.get("/{name}/permissions", response_model=PermissionListResponse)
    84→async def list_permissions(name: str, db: AsyncSession = Depends(get_db)):
    85→    """List all permissions for a project."""
    86→    # Verify project exists
    87→    result = await db.execute(select(Project).where(Project.name == name))
    88→    project = result.scalar_one_or_none()
    89→
    90→    if not project:
    91→        raise HTTPException(
    92→            status_code=status.HTTP_404_NOT_FOUND,
    93→            detail=f"Project '{name}' not found"
    94→        )
    95→
    96→    # Get permissions
    97→    result = await db.execute(
    98→        select(Permission)
    99→        .where(Permission.project_id == project.id)
   100→        .order_by(Permission.created_at.desc())
   101→    )
   102→    permissions = result.scalars().all()
   103→
   104→    return PermissionListResponse(
   105→        permissions=[PermissionResponse.model_validate(p) for p in permissions],
   106→        count=len(permissions)
   107→    )
   108→
   109→
   110→@router.post("/{name}/permissions", response_model=PermissionResponse, status_code=status.HTTP_201_CREATED)
   111→async def create_permission(name: str, permission: PermissionCreate, db: AsyncSession = Depends(get_db)):
   112→    """Create a new permission for a project."""
   113→    # Verify project exists
   114→    result = await db.execute(select(Project).where(Project.name == name))
   115→    project = result.scalar_one_or_none()
   116→
   117→    if not project:
   118→        raise HTTPException(
   119→            status_code=status.HTTP_404_NOT_FOUND,
   120→            detail=f"Project '{name}' not found"
   121→        )
   122→
   123→    # Check if permission already exists
   124→    result = await db.execute(
   125→        select(Permission).where(and_(
   126→            Permission.project_id == project.id,
   127→            Permission.permission_type == permission.permission_type,
   128→            Permission.permission_value == permission.permission_value
   129→        ))
   130→    )
   131→    existing = result.scalar_one_or_none()
   132→    if existing:
   133→        raise HTTPException(
   134→            status_code=status.HTTP_409_CONFLICT,
   135→            detail=f"Permission already exists"
   136→        )
   137→
   138→    # Create permission
   139→    db_permission = Permission(
   140→        project_id=project.id,
   141→        permission_type=permission.permission_type,
   142→        permission_value=permission.permission_value,
   143→        granted=permission.granted,
   144→    )
   145→    db.add(db_permission)
   146→    await db.commit()
   147→    await db.refresh(db_permission)
   148→
   149→    return PermissionResponse.model_validate(db_permission)
   150→
   151→
   152→@router.get("/{name}/permissions/{permission_id}", response_model=PermissionResponse)
   153→async def get_permission(name: str, permission_id: int, db: AsyncSession = Depends(get_db)):
   154→    """Get a specific permission by ID."""
   155→    # Verify project exists
   156→    result = await db.execute(select(Project).where(Project.name == name))
   157→    project = result.scalar_one_or_none()
   158→
   159→    if not project:
   160→        raise HTTPException(
   161→            status_code=status.HTTP_404_NOT_FOUND,
   162→            detail=f"Project '{name}' not found"
   163→        )
   164→
   165→    # Get permission
   166→    result = await db.execute(
   167→        select(Permission).where(and_(
   168→            Permission.id == permission_id,
   169→            Permission.project_id == project.id
   170→        ))
   171→    )
   172→    permission = result.scalar_one_or_none()
   173→
   174→    if not permission:
   175→        raise HTTPException(
   176→            status_code=status.HTTP_404_NOT_FOUND,
   177→            detail=f"Permission {permission_id} not found in project '{name}'"
   178→        )
   179→
   180→    return PermissionResponse.model_validate(permission)
   181→
   182→
   183→@router.put("/{name}/permissions/{permission_id}", response_model=PermissionResponse)
   184→async def update_permission(name: str, permission_id: int, permission_update: PermissionUpdate, db: AsyncSession = Depends(get_db)):
   185→    """Update a permission."""
   186→    # Verify project exists
   187→    result = await db.execute(select(Project).where(Project.name == name))
   188→    project = result.scalar_one_or_none()
   189→
   190→    if not project:
   191→        raise HTTPException(
   192→            status_code=status.HTTP_404_NOT_FOUND,
   193→            detail=f"Project '{name}' not found"
   194→        )
   195→
   196→    # Get permission
   197→    result = await db.execute(
   198→        select(Permission).where(and_(
   199→            Permission.id == permission_id,
   200→            Permission.project_id == project.id
   201→        ))
   202→    )
   203→    permission = result.scalar_one_or_none()
   204→
   205→    if not permission:
   206→        raise HTTPException(
   207→            status_code=status.HTTP_404_NOT_FOUND,
   208→            detail=f"Permission {permission_id} not found in project '{name}'"
   209→        )
   210→
   211→    # Update granted status
   212→    if permission_update.granted is not None:
   213→        permission.granted = permission_update.granted
   214→
   215→    await db.commit()
   216→    await db.refresh(permission)
   217→
   218→    return PermissionResponse.model_validate(permission)
   219→
   220→
   221→@router.delete("/{name}/permissions/{permission_id}", status_code=status.HTTP_204_NO_CONTENT)
   222→async def delete_permission(name: str, permission_id: int, db: AsyncSession = Depends(get_db)):
   223→    """Delete a permission."""
   224→    # Verify project exists
   225→    result = await db.execute(select(Project).where(Project.name == name))
   226→    project = result.scalar_one_or_none()
   227→
   228→    if not project:
   229→        raise HTTPException(
   230→            status_code=status.HTTP_404_NOT_FOUND,
   231→            detail=f"Project '{name}' not found"
   232→        )
   233→
   234→    # Get permission
   235→    result = await db.execute(
   236→        select(Permission).where(and_(
   237→            Permission.id == permission_id,
   238→            Permission.project_id == project.id
   239→        ))
   240→    )
   241→    permission = result.scalar_one_or_none()
   242→
   243→    if not permission:
   244→        raise HTTPException(
   245→            status_code=status.HTTP_404_NOT_FOUND,
   246→            detail=f"Permission {permission_id} not found in project '{name}'"
   247→        )
   248→
   249→    await db.delete(permission)
   250→    await db.commit()
   251→
   252→
   253→# ============================================================================
   254→# Permission Request Endpoints
   255→# ============================================================================
   256→
   257→@router.get("/{name}/permission-requests", response_model=PermissionRequestListResponse)
   258→async def list_permission_requests(
   259→    name: str,
   260→    status_filter: Optional[str] = None,
   261→    db: AsyncSession = Depends(get_db)
   262→):
   263→    """List permission requests for a project."""
   264→    # Verify project exists
   265→    result = await db.execute(select(Project).where(Project.name == name))
   266→    project = result.scalar_one_or_none()
   267→
   268→    if not project:
   269→        raise HTTPException(
   270→            status_code=status.HTTP_404_NOT_FOUND,
   271→            detail=f"Project '{name}' not found"
   272→        )
   273→
   274→    # Build query
   275→    query = select(PermissionRequest).where(PermissionRequest.project_id == project.id)
   276→
   277→    if status_filter:
   278→        query = query.where(PermissionRequest.status == status_filter)
   279→
   280→    query = query.order_by(PermissionRequest.requested_at.desc())
   281→
   282→    result = await db.execute(query)
   283→    requests = result.scalars().all()
   284→
   285→    return PermissionRequestListResponse(
   286→        requests=[PermissionRequestResponse.model_validate(r) for r in requests],
   287→        count=len(requests)
   288→    )
   289→
   290→
   291→@router.post("/{name}/permission-requests/{request_id}/grant", response_model=PermissionRequestResponse)
   292→async def grant_permission_request(name: str, request_id: int, db: AsyncSession = Depends(get_db)):
   293→    """Grant a pending permission request."""
   294→    # Verify project exists
   295→    result = await db.execute(select(Project).where(Project.name == name))
   296→    project = result.scalar_one_or_none()
   297→
   298→    if not project:
   299→        raise HTTPException(
   300→            status_code=status.HTTP_404_NOT_FOUND,
   301→            detail=f"Project '{name}' not found"
   302→        )
   303→
   304→    # Get permission request
   305→    result = await db.execute(
   306→        select(PermissionRequest).where(and_(
   307→            PermissionRequest.id == request_id,
   308→            PermissionRequest.project_id == project.id
   309→        ))
   310→    )
   311→    request = result.scalar_one_or_none()
   312→
   313→    if not request:
   314→        raise HTTPException(
   315→            status_code=status.HTTP_404_NOT_FOUND,
   316→            detail=f"Permission request {request_id} not found"
   317→        )
   318→
   319→    if request.status != "pending":
   320→        raise HTTPException(
   321→            status_code=status.HTTP_400_BAD_REQUEST,
   322→            detail=f"Permission request is already {request.status}"
   323→        )
   324→
   325→    # Update request status
   326→    request.status = "granted"
   327→    request.resolved_at = datetime.utcnow()
   328→
   329→    # Create the actual permission
   330→    db_permission = Permission(
   331→        project_id=project.id,
   332→        permission_type=request.permission_type,
   333→        permission_value=request.permission_value,
   334→        granted=True,
   335→    )
   336→    db.add(db_permission)
   337→
   338→    await db.commit()
   339→    await db.refresh(request)
   340→
   341→    return PermissionRequestResponse.model_validate(request)
   342→
   343→
   344→@router.post("/{name}/permission-requests/{request_id}/deny", response_model=PermissionRequestResponse)
   345→async def deny_permission_request(name: str, request_id: int, db: AsyncSession = Depends(get_db)):
   346→    """Deny a pending permission request."""
   347→    # Verify project exists
   348→    result = await db.execute(select(Project).where(Project.name == name))
   349→    project = result.scalar_one_or_none()
   350→
   351→    if not project:
   352→        raise HTTPException(
   353→            status_code=status.HTTP_404_NOT_FOUND,
   354→            detail=f"Project '{name}' not found"
   355→        )
   356→
   357→    # Get permission request
   358→    result = await db.execute(
   359→        select(PermissionRequest).where(and_(
   360→            PermissionRequest.id == request_id,
   361→            PermissionRequest.project_id == project.id
   362→        ))
   363→    )
   364→    request = result.scalar_one_or_none()
   365→
   366→    if not request:
   367→        raise HTTPException(
   368→            status_code=status.HTTP_404_NOT_FOUND,
   369→            detail=f"Permission request {request_id} not found"
   370→        )
   371→
   372→    if request.status != "pending":
   373→        raise HTTPException(
   374→            status_code=status.HTTP_400_BAD_REQUEST,
   375→            detail=f"Permission request is already {request.status}"
   376→        )
   377→
   378→    # Update request status
   379→    request.status = "denied"
   380→    request.resolved_at = datetime.utcnow()
   381→
   382→    await db.commit()
   383→    await db.refresh(request)
   384→
   385→    return PermissionRequestResponse.model_validate(request)
   386→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>

"""
Permissions Router
==================

API endpoints for permission management within projects.
"""

from datetime import datetime
from typing import Optional, List

from fastapi import APIRouter, Depends, HTTPException, status
from pydantic import BaseModel, Field
from sqlalchemy import select, and_
from sqlalchemy.ext.asyncio import AsyncSession

from ..database import get_db
from ..models import Project, Permission, PermissionRequest

router = APIRouter(prefix="/api/projects", tags=["permissions"])

# ============================================================================
# Pydantic Schemas
# ============================================================================

class PermissionResponse(BaseModel):
    """Schema for permission response."""
    id: int
    project_id: int
    permission_type: str
    permission_value: str
    granted: bool
    created_at: datetime

    class Config:
        from_attributes = True

class PermissionListResponse(BaseModel):
    """Schema for permission list response."""
    permissions: List[PermissionResponse]
    count: int

class PermissionCreate(BaseModel):
    """Schema for creating a permission."""
    permission_type: str = Field(..., min_length=1, max_length=50)
    permission_value: str = Field(..., min_length=1, max_length=500)
    granted: bool = True

class PermissionUpdate(BaseModel):
    """Schema for updating a permission."""
    granted: Optional[bool] = None

class PermissionRequestResponse(BaseModel):
    """Schema for permission request response."""
    id: int
    project_id: int
    feature_id: Optional[int]
    agent_id: str
    permission_type: str
    permission_value: str
    status: str
    requested_at: datetime
    resolved_at: Optional[datetime]

    class Config:
        from_attributes = True

class PermissionRequestListResponse(BaseModel):
    """Schema for permission request list response."""
    requests: List[PermissionRequestResponse]
    count: int

# ============================================================================
# Permission Endpoints
# ============================================================================

@router.get("/{name}/permissions", response_model=PermissionListResponse)
async def list_permissions(name: str, db: AsyncSession = Depends(get_db)):
    """List all permissions for a project."""
    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    # Get permissions
    result = await db.execute(
        select(Permission)
        .where(Permission.project_id == project.id)
        .order_by(Permission.created_at.desc())
    )
    permissions = result.scalars().all()

    return PermissionListResponse(
        permissions=[PermissionResponse.model_validate(p) for p in permissions],
        count=len(permissions)
    )

@router.post("/{name}/permissions", response_model=PermissionResponse, status_code=status.HTTP_201_CREATED)
async def create_permission(name: str, permission: PermissionCreate, db: AsyncSession = Depends(get_db)):
    """Create a new permission for a project."""
    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    # Check if permission already exists
    result = await db.execute(
        select(Permission).where(and_(
            Permission.project_id == project.id,
            Permission.permission_type == permission.permission_type,
            Permission.permission_value == permission.permission_value
        ))
    )
    existing = result.scalar_one_or_none()
    if existing:
        raise HTTPException(
            status_code=status.HTTP_409_CONFLICT,
            detail=f"Permission already exists"
        )

    # Create permission
    db_permission = Permission(
        project_id=project.id,
        permission_type=permission.permission_type,
        permission_value=permission.permission_value,
        granted=permission.granted,
    )
    db.add(db_permission)
    await db.commit()
    await db.refresh(db_permission)

    return PermissionResponse.model_validate(db_permission)

@router.get("/{name}/permissions/{permission_id}", response_model=PermissionResponse)
async def get_permission(name: str, permission_id: int, db: AsyncSession = Depends(get_db)):
    """Get a specific permission by ID."""
    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    # Get permission
    result = await db.execute(
        select(Permission).where(and_(
            Permission.id == permission_id,
            Permission.project_id == project.id
        ))
    )
    permission = result.scalar_one_or_none()

    if not permission:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Permission {permission_id} not found in project '{name}'"
        )

    return PermissionResponse.model_validate(permission)

@router.put("/{name}/permissions/{permission_id}", response_model=PermissionResponse)
async def update_permission(name: str, permission_id: int, permission_update: PermissionUpdate, db: AsyncSession = Depends(get_db)):
    """Update a permission."""
    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    # Get permission
    result = await db.execute(
        select(Permission).where(and_(
            Permission.id == permission_id,
            Permission.project_id == project.id
        ))
    )
    permission = result.scalar_one_or_none()

    if not permission:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Permission {permission_id} not found in project '{name}'"
        )

    # Update granted status
    if permission_update.granted is not None:
        permission.granted = permission_update.granted

    await db.commit()
    await db.refresh(permission)

    return PermissionResponse.model_validate(permission)

@router.delete("/{name}/permissions/{permission_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_permission(name: str, permission_id: int, db: AsyncSession = Depends(get_db)):
    """Delete a permission."""
    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    # Get permission
    result = await db.execute(
        select(Permission).where(and_(
            Permission.id == permission_id,
            Permission.project_id == project.id
        ))
    )
    permission = result.scalar_one_or_none()

    if not permission:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Permission {permission_id} not found in project '{name}'"
        )

    await db.delete(permission)
    await db.commit()

# ============================================================================
# Permission Request Endpoints
# ============================================================================

@router.get("/{name}/permission-requests", response_model=PermissionRequestListResponse)
async def list_permission_requests(
    name: str,
    status_filter: Optional[str] = None,
    db: AsyncSession = Depends(get_db)
):
    """List permission requests for a project."""
    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    # Build query
    query = select(PermissionRequest).where(PermissionRequest.project_id == project.id)

    if status_filter:
        query = query.where(PermissionRequest.status == status_filter)

    query = query.order_by(PermissionRequest.requested_at.desc())

    result = await db.execute(query)
    requests = result.scalars().all()

    return PermissionRequestListResponse(
        requests=[PermissionRequestResponse.model_validate(r) for r in requests],
        count=len(requests)
    )

@router.post("/{name}/permission-requests/{request_id}/grant", response_model=PermissionRequestResponse)
async def grant_permission_request(name: str, request_id: int, db: AsyncSession = Depends(get_db)):
    """Grant a pending permission request."""
    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    # Get permission request
    result = await db.execute(
        select(PermissionRequest).where(and_(
            PermissionRequest.id == request_id,
            PermissionRequest.project_id == project.id
        ))
    )
    request = result.scalar_one_or_none()

    if not request:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Permission request {request_id} not found"
        )

    if request.status != "pending":
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"Permission request is already {request.status}"
        )

    # Update request status
    request.status = "granted"
    request.resolved_at = datetime.utcnow()

    # Create the actual permission
    db_permission = Permission(
        project_id=project.id,
        permission_type=request.permission_type,
        permission_value=request.permission_value,
        granted=True,
    )
    db.add(db_permission)

    await db.commit()
    await db.refresh(request)

    return PermissionRequestResponse.model_validate(request)

@router.post("/{name}/permission-requests/{request_id}/deny", response_model=PermissionRequestResponse)
async def deny_permission_request(name: str, request_id: int, db: AsyncSession = Depends(get_db)):
    """Deny a pending permission request."""
    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    # Get permission request
    result = await db.execute(
        select(PermissionRequest).where(and_(
            PermissionRequest.id == request_id,
            PermissionRequest.project_id == project.id
        ))
    )
    request = result.scalar_one_or_none()

    if not request:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Permission request {request_id} not found"
        )

    if request.status != "pending":
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"Permission request is already {request.status}"
        )

    # Update request status
    request.status = "denied"
    request.resolved_at = datetime.utcnow()

    await db.commit()
    await db.refresh(request)

    return PermissionRequestResponse.model_validate(request)


Write

"""
Permissions Router
==================

API endpoints for permission management within projects.
"""

from datetime import datetime
from typing import Optional, List

from fastapi import APIRouter, Depends, HTTPException, status
from pydantic import BaseModel, Field
from sqlalchemy import select, and_
from sqlalchemy.ext.asyncio import AsyncSession

from ..database import get_db
from ..models import Project, Permission, PermissionRequest

router = APIRouter(prefix="/api/projects", tags=["permissions"])

# ============================================================================
# Pydantic Schemas
# ============================================================================

class PermissionResponse(BaseModel):
    """Schema for permission response."""
    id: int
    project_id: int
    permission_type: str
    permission_value: str
    granted: bool
    created_at: datetime

    class Config:
        from_attributes = True

class PermissionListResponse(BaseModel):
    """Schema for permission list response."""
    permissions: List[PermissionResponse]
    count: int

class PermissionCreate(BaseModel):
    """Schema for creating a permission."""
    permission_type: str = Field(..., min_length=1, max_length=50)
    permission_value: str = Field(..., min_length=1, max_length=500)
    granted: bool = True

class PermissionUpdate(BaseModel):
    """Schema for updating a permission."""
    granted: Optional[bool] = None

class PermissionRequestResponse(BaseModel):
    """Schema for permission request response."""
    id: int
    project_id: int
    feature_id: Optional[int]
    agent_id: str
    permission_type: str
    permission_value: str
    status: str
    requested_at: datetime
    resolved_at: Optional[datetime]

    class Config:
        from_attributes = True

class PermissionRequestListResponse(BaseModel):
    """Schema for permission request list response."""
    requests: List[PermissionRequestResponse]
    count: int

class PermissionRequestCreate(BaseModel):
    """Schema for creating a permission request."""
    agent_id: str = Field(..., min_length=1, max_length=1)  # "A" or "B"
    permission_type: str = Field(..., min_length=1, max_length=50)
    permission_value: str = Field(..., min_length=1, max_length=500)
    feature_id: Optional[int] = None

# ============================================================================
# Permission Endpoints
# ============================================================================

@router.get("/{name}/permissions", response_model=PermissionListResponse)
async def list_permissions(name: str, db: AsyncSession = Depends(get_db)):
    """List all permissions for a project."""
    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    # Get permissions
    result = await db.execute(
        select(Permission)
        .where(Permission.project_id == project.id)
        .order_by(Permission.created_at.desc())
    )
    permissions = result.scalars().all()

    return PermissionListResponse(
        permissions=[PermissionResponse.model_validate(p) for p in permissions],
        count=len(permissions)
    )

@router.post("/{name}/permissions", response_model=PermissionResponse, status_code=status.HTTP_201_CREATED)
async def create_permission(name: str, permission: PermissionCreate, db: AsyncSession = Depends(get_db)):
    """Create a new permission for a project."""
    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    # Check if permission already exists
    result = await db.execute(
        select(Permission).where(and_(
            Permission.project_id == project.id,
            Permission.permission_type == permission.permission_type,
            Permission.permission_value == permission.permission_value
        ))
    )
    existing = result.scalar_one_or_none()
    if existing:
        raise HTTPException(
            status_code=status.HTTP_409_CONFLICT,
            detail=f"Permission already exists"
        )

    # Create permission
    db_permission = Permission(
        project_id=project.id,
        permission_type=permission.permission_type,
        permission_value=permission.permission_value,
        granted=permission.granted,
    )
    db.add(db_permission)
    await db.commit()
    await db.refresh(db_permission)

    return PermissionResponse.model_validate(db_permission)

@router.get("/{name}/permissions/{permission_id}", response_model=PermissionResponse)
async def get_permission(name: str, permission_id: int, db: AsyncSession = Depends(get_db)):
    """Get a specific permission by ID."""
    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    # Get permission
    result = await db.execute(
        select(Permission).where(and_(
            Permission.id == permission_id,
            Permission.project_id == project.id
        ))
    )
    permission = result.scalar_one_or_none()

    if not permission:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Permission {permission_id} not found in project '{name}'"
        )

    return PermissionResponse.model_validate(permission)

@router.put("/{name}/permissions/{permission_id}", response_model=PermissionResponse)
async def update_permission(name: str, permission_id: int, permission_update: PermissionUpdate, db: AsyncSession = Depends(get_db)):
    """Update a permission."""
    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    # Get permission
    result = await db.execute(
        select(Permission).where(and_(
            Permission.id == permission_id,
            Permission.project_id == project.id
        ))
    )
    permission = result.scalar_one_or_none()

    if not permission:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Permission {permission_id} not found in project '{name}'"
        )

    # Update granted status
    if permission_update.granted is not None:
        permission.granted = permission_update.granted

    await db.commit()
    await db.refresh(permission)

    return PermissionResponse.model_validate(permission)

@router.delete("/{name}/permissions/{permission_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_permission(name: str, permission_id: int, db: AsyncSession = Depends(get_db)):
    """Delete a permission."""
    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    # Get permission
    result = await db.execute(
        select(Permission).where(and_(
            Permission.id == permission_id,
            Permission.project_id == project.id
        ))
    )
    permission = result.scalar_one_or_none()

    if not permission:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Permission {permission_id} not found in project '{name}'"
        )

    await db.delete(permission)
    await db.commit()

# ============================================================================
# Permission Request Endpoints
# ============================================================================

@router.get("/{name}/permission-requests", response_model=PermissionRequestListResponse)
async def list_permission_requests(
    name: str,
    status_filter: Optional[str] = None,
    db: AsyncSession = Depends(get_db)
):
    """List permission requests for a project."""
    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    # Build query
    query = select(PermissionRequest).where(PermissionRequest.project_id == project.id)

    if status_filter:
        query = query.where(PermissionRequest.status == status_filter)

    query = query.order_by(PermissionRequest.requested_at.desc())

    result = await db.execute(query)
    requests = result.scalars().all()

    return PermissionRequestListResponse(
        requests=[PermissionRequestResponse.model_validate(r) for r in requests],
        count=len(requests)
    )

@router.post("/{name}/permission-requests", response_model=PermissionRequestResponse, status_code=status.HTTP_201_CREATED)
async def create_permission_request(name: str, request: PermissionRequestCreate, db: AsyncSession = Depends(get_db)):
    """Create a new permission request (typically called by agents)."""
    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    # Create permission request
    db_request = PermissionRequest(
        project_id=project.id,
        feature_id=request.feature_id,
        agent_id=request.agent_id,
        permission_type=request.permission_type,
        permission_value=request.permission_value,
        status="pending",
    )
    db.add(db_request)
    await db.commit()
    await db.refresh(db_request)

    return PermissionRequestResponse.model_validate(db_request)

@router.post("/{name}/permission-requests/{request_id}/grant", response_model=PermissionRequestResponse)
async def grant_permission_request(name: str, request_id: int, db: AsyncSession = Depends(get_db)):
    """Grant a pending permission request."""
    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    # Get permission request
    result = await db.execute(
        select(PermissionRequest).where(and_(
            PermissionRequest.id == request_id,
            PermissionRequest.project_id == project.id
        ))
    )
    request = result.scalar_one_or_none()

    if not request:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Permission request {request_id} not found"
        )

    if request.status != "pending":
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"Permission request is already {request.status}"
        )

    # Update request status
    request.status = "granted"
    request.resolved_at = datetime.utcnow()

    # Create the actual permission
    db_permission = Permission(
        project_id=project.id,
        permission_type=request.permission_type,
        permission_value=request.permission_value,
        granted=True,
    )
    db.add(db_permission)

    await db.commit()
    await db.refresh(request)

    return PermissionRequestResponse.model_validate(request)

@router.post("/{name}/permission-requests/{request_id}/deny", response_model=PermissionRequestResponse)
async def deny_permission_request(name: str, request_id: int, db: AsyncSession = Depends(get_db)):
    """Deny a pending permission request."""
    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    # Get permission request
    result = await db.execute(
        select(PermissionRequest).where(and_(
            PermissionRequest.id == request_id,
            PermissionRequest.project_id == project.id
        ))
    )
    request = result.scalar_one_or_none()

    if not request:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Permission request {request_id} not found"
        )

    if request.status != "pending":
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"Permission request is already {request.status}"
        )

    # Update request status
    request.status = "denied"
    request.resolved_at = datetime.utcnow()

    await db.commit()
    await db.refresh(request)

    return PermissionRequestResponse.model_validate(request)