From 4c4f253c110043506e4a30949731d435a72a1a27 Mon Sep 17 00:00:00 2001 From: qzl Date: Sat, 28 Feb 2026 12:10:03 +0800 Subject: [PATCH] feat(friendships): implement dependencies and router with CRUD endpoints --- backend/src/v1/friendships/dependencies.py | 32 ++++++++ backend/src/v1/friendships/router.py | 96 ++++++++++++++++++++++ backend/src/v1/router.py | 2 + 3 files changed, 130 insertions(+) diff --git a/backend/src/v1/friendships/dependencies.py b/backend/src/v1/friendships/dependencies.py index 9d48db4..362014f 100644 --- a/backend/src/v1/friendships/dependencies.py +++ b/backend/src/v1/friendships/dependencies.py @@ -1 +1,33 @@ from __future__ import annotations + +from typing import Annotated + +from fastapi import Depends +from sqlalchemy.ext.asyncio import AsyncSession + +from core.auth.models import CurrentUser +from core.db import get_db +from v1.friendships.repository import SQLAlchemyFriendshipRepository +from v1.friendships.service import FriendshipService +from v1.users.dependencies import get_current_user +from v1.users.repository import SQLAlchemyUserRepository + + +async def get_friendship_repository( + session: Annotated[AsyncSession, Depends(get_db)], +) -> SQLAlchemyFriendshipRepository: + return SQLAlchemyFriendshipRepository(session) + + +async def get_friendship_service( + session: Annotated[AsyncSession, Depends(get_db)], + current_user: Annotated[CurrentUser, Depends(get_current_user)], +) -> FriendshipService: + friendship_repository = SQLAlchemyFriendshipRepository(session) + user_repository = SQLAlchemyUserRepository(session) + return FriendshipService( + repository=friendship_repository, + user_repository=user_repository, + session=session, + current_user=current_user, + ) diff --git a/backend/src/v1/friendships/router.py b/backend/src/v1/friendships/router.py index 9d48db4..ab03360 100644 --- a/backend/src/v1/friendships/router.py +++ b/backend/src/v1/friendships/router.py @@ -1 +1,97 @@ from __future__ import annotations + +from typing import Annotated +from uuid import UUID + +from fastapi import APIRouter, Depends, status + +from v1.friendships.dependencies import get_friendship_service +from v1.friendships.schemas import ( + FriendRequestAction, + FriendRequestCreate, + FriendRequestResponse, + FriendResponse, +) +from v1.friendships.service import FriendshipService + + +router = APIRouter(prefix="/friends", tags=["friends"]) + + +@router.post( + "/requests", + response_model=FriendRequestResponse, + status_code=status.HTTP_201_CREATED, +) +async def send_friend_request( + payload: FriendRequestCreate, + service: Annotated[FriendshipService, Depends(get_friendship_service)], +) -> FriendRequestResponse: + return await service.send_request(payload) + + +@router.get("/requests/inbox", response_model=list[FriendRequestResponse]) +async def get_inbox( + service: Annotated[FriendshipService, Depends(get_friendship_service)], +) -> list[FriendRequestResponse]: + return await service.get_inbox() + + +@router.get("/requests/outgoing", response_model=list[FriendRequestResponse]) +async def get_outgoing_requests( + service: Annotated[FriendshipService, Depends(get_friendship_service)], +) -> list[FriendRequestResponse]: + return await service.get_outgoing_requests() + + +@router.post( + "/requests/{friendship_id}/accept", + response_model=FriendRequestResponse, +) +async def accept_friend_request( + friendship_id: UUID, + _: FriendRequestAction, + service: Annotated[FriendshipService, Depends(get_friendship_service)], +) -> FriendRequestResponse: + return await service.accept_request(friendship_id) + + +@router.post( + "/requests/{friendship_id}/decline", + response_model=FriendRequestResponse, +) +async def decline_friend_request( + friendship_id: UUID, + _: FriendRequestAction, + service: Annotated[FriendshipService, Depends(get_friendship_service)], +) -> FriendRequestResponse: + return await service.decline_request(friendship_id) + + +@router.delete( + "/requests/{friendship_id}", + status_code=status.HTTP_204_NO_CONTENT, +) +async def cancel_friend_request( + friendship_id: UUID, + service: Annotated[FriendshipService, Depends(get_friendship_service)], +) -> None: + await service.cancel_request(friendship_id) + + +@router.get("", response_model=list[FriendResponse]) +async def get_friends_list( + service: Annotated[FriendshipService, Depends(get_friendship_service)], +) -> list[FriendResponse]: + return await service.get_friends_list() + + +@router.delete( + "/{friendship_id}", + status_code=status.HTTP_204_NO_CONTENT, +) +async def remove_friend( + friendship_id: UUID, + service: Annotated[FriendshipService, Depends(get_friendship_service)], +) -> None: + await service.remove_friend(friendship_id) diff --git a/backend/src/v1/router.py b/backend/src/v1/router.py index 3a7b901..f798c23 100644 --- a/backend/src/v1/router.py +++ b/backend/src/v1/router.py @@ -5,12 +5,14 @@ from fastapi import APIRouter from core.http.models import HealthResponse from v1.agent_chat.router import router as agent_chat_router from v1.auth.router import router as auth_router +from v1.friendships.router import router as friendships_router from v1.infra.router import router as infra_router from v1.users.router import router as users_router router = APIRouter(prefix="/api/v1") router.include_router(auth_router) +router.include_router(friendships_router) router.include_router(infra_router) router.include_router(users_router) router.include_router(agent_chat_router)