
All checks were successful
Deploy to Production, build images and push to Gitea Registry / build_and_push (pull_request) Successful in 1m47s
- Changed logging level from WARNING to INFO in config.py for better visibility during development. - Adjusted chore update logic in chores.py to ensure correct payload structure. - Improved invite acceptance process in invites.py by refining error handling and updating response models for better clarity. - Updated API endpoint configurations in api-config.ts for consistency and added new endpoints for list statuses. - Enhanced UI components in ChoresPage.vue and GroupsPage.vue for improved user experience and accessibility.
79 lines
3.3 KiB
Python
79 lines
3.3 KiB
Python
# app/api/v1/endpoints/invites.py
|
|
import logging
|
|
from fastapi import APIRouter, Depends, HTTPException, status
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.database import get_transactional_session
|
|
from app.auth import current_active_user
|
|
from app.models import User as UserModel, UserRoleEnum
|
|
from app.schemas.invite import InviteAccept
|
|
from app.schemas.message import Message
|
|
from app.schemas.group import GroupPublic
|
|
from app.crud import invite as crud_invite
|
|
from app.crud import group as crud_group
|
|
from app.core.exceptions import (
|
|
InviteNotFoundError,
|
|
InviteExpiredError,
|
|
InviteAlreadyUsedError,
|
|
InviteCreationError,
|
|
GroupNotFoundError,
|
|
GroupMembershipError,
|
|
GroupOperationError
|
|
)
|
|
|
|
logger = logging.getLogger(__name__)
|
|
router = APIRouter()
|
|
|
|
@router.post(
|
|
"/accept", # Route relative to prefix "/invites"
|
|
response_model=GroupPublic,
|
|
summary="Accept Group Invite",
|
|
tags=["Invites"]
|
|
)
|
|
async def accept_invite(
|
|
invite_in: InviteAccept,
|
|
db: AsyncSession = Depends(get_transactional_session),
|
|
current_user: UserModel = Depends(current_active_user),
|
|
):
|
|
"""Accepts a group invite using the provided invite code."""
|
|
logger.info(f"User {current_user.email} attempting to accept invite code: {invite_in.code}")
|
|
|
|
# Get the invite - this function should only return valid, active invites
|
|
invite = await crud_invite.get_active_invite_by_code(db, code=invite_in.code)
|
|
if not invite:
|
|
logger.warning(f"Invalid or inactive invite code attempted by user {current_user.email}: {invite_in.code}")
|
|
# We can use a more generic error or a specific one. InviteNotFound is reasonable.
|
|
raise InviteNotFoundError(invite_in.code)
|
|
|
|
# Check if group still exists
|
|
group = await crud_group.get_group_by_id(db, group_id=invite.group_id)
|
|
if not group:
|
|
logger.error(f"Group {invite.group_id} not found for invite {invite_in.code}")
|
|
raise GroupNotFoundError(invite.group_id)
|
|
|
|
# Check if user is already a member
|
|
is_member = await crud_group.is_user_member(db, group_id=invite.group_id, user_id=current_user.id)
|
|
if is_member:
|
|
logger.warning(f"User {current_user.email} already a member of group {invite.group_id}")
|
|
raise GroupMembershipError(invite.group_id, "join (already a member)")
|
|
|
|
# Add user to the group
|
|
added_to_group = await crud_group.add_user_to_group(db, group_id=invite.group_id, user_id=current_user.id)
|
|
if not added_to_group:
|
|
logger.error(f"Failed to add user {current_user.email} to group {invite.group_id} during invite acceptance.")
|
|
# This could be a race condition or other issue, treat as an operational error.
|
|
raise GroupOperationError("Failed to add user to group.")
|
|
|
|
# Deactivate the invite so it cannot be used again
|
|
await crud_invite.deactivate_invite(db, invite=invite)
|
|
|
|
logger.info(f"User {current_user.email} successfully joined group {invite.group_id} via invite {invite_in.code}")
|
|
|
|
# Re-fetch the group to get the updated member list
|
|
updated_group = await crud_group.get_group_by_id(db, group_id=invite.group_id)
|
|
if not updated_group:
|
|
# This should ideally not happen as we found it before
|
|
logger.error(f"Could not re-fetch group {invite.group_id} after user {current_user.email} joined.")
|
|
raise GroupNotFoundError(invite.group_id)
|
|
|
|
return updated_group |