Files
boc/landvex-admin-backend/app/routers/invitations.py
T
Bernt aee0f09db8 landvex: Fixar och tester klara för alla komponenter
- Datafabrik: Dockerfile fix, agentorkestrering fungerar
- Vision: Identify-modell, FAISS, OCR alla testade
- API: Alla 7 integrationstester passerade
- Upplösare: Entitetsupplösning verifierad
2026-07-05 06:41:32 +00:00

94 lines
2.9 KiB
Python

"""Invitation endpoints."""
from typing import Optional
from uuid import UUID
from fastapi import APIRouter, Depends, Query
from sqlalchemy.ext.asyncio import AsyncSession
from app.database import get_db
from app.dependencies import get_current_user, require_admin, require_manager
from app.models import User
from app.schemas import InvitationCreate, InvitationOut, AcceptInvitationRequest, UserOut
from app.services.invitation_service import InvitationService
router = APIRouter(prefix="/invitations", tags=["Invitations"])
@router.get("", response_model=list[InvitationOut])
async def list_invitations(
tenant_id: Optional[UUID] = Query(None),
pending_only: bool = Query(True),
skip: int = Query(0, ge=0),
limit: int = Query(100, ge=1, le=500),
current_user: User = Depends(require_manager),
db: AsyncSession = Depends(get_db),
):
service = InvitationService(db)
effective_tenant = tenant_id
if not current_user.is_superuser and current_user.role.value == "manager":
effective_tenant = current_user.tenant_id
items, total = await service.list_invitations(
tenant_id=effective_tenant,
pending_only=pending_only,
skip=skip,
limit=limit,
)
return items
@router.post("", response_model=InvitationOut, status_code=201)
async def create_invitation(
data: InvitationCreate,
current_user: User = Depends(require_admin),
db: AsyncSession = Depends(get_db),
):
service = InvitationService(db)
invitation = await service.create_invitation(data, invited_by=current_user)
return InvitationOut.model_validate(invitation)
@router.post("/accept", response_model=UserOut)
async def accept_invitation(
data: AcceptInvitationRequest,
db: AsyncSession = Depends(get_db),
):
service = InvitationService(db)
user = await service.accept_invitation(data)
return UserOut.model_validate(user)
@router.get("/validate/{token}")
async def validate_invitation(
token: str,
db: AsyncSession = Depends(get_db),
):
service = InvitationService(db)
invitation = await service.get_by_token(token)
if invitation is None:
return {"valid": False, "reason": "not_found"}
if invitation.accepted_at is not None:
return {"valid": False, "reason": "already_accepted"}
if invitation.expires_at < datetime.utcnow():
return {"valid": False, "reason": "expired"}
return {
"valid": True,
"email": invitation.email,
"role": invitation.role.value,
"expires_at": invitation.expires_at.isoformat(),
}
@router.delete("/{invitation_id}", status_code=204)
async def revoke_invitation(
invitation_id: UUID,
current_user: User = Depends(require_admin),
db: AsyncSession = Depends(get_db),
):
service = InvitationService(db)
await service.revoke_invitation(invitation_id, actor=current_user)
return None
from datetime import datetime