feat: initialize aivideo project
This commit is contained in:
35
backend/app/modules/invites/repository.py
Normal file
35
backend/app/modules/invites/repository.py
Normal file
@@ -0,0 +1,35 @@
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.models.entities import InviteCode, InviteRelation, User
|
||||
|
||||
|
||||
class InviteRepository:
|
||||
def __init__(self, db: Session) -> None:
|
||||
self.db = db
|
||||
|
||||
def get_default_code(self, user_id: int) -> InviteCode | None:
|
||||
return self.db.scalar(
|
||||
select(InviteCode).where(
|
||||
InviteCode.user_id == user_id,
|
||||
InviteCode.is_default.is_(True),
|
||||
)
|
||||
)
|
||||
|
||||
def get_code(self, code_value: str) -> InviteCode | None:
|
||||
return self.db.scalar(select(InviteCode).where(InviteCode.invite_code == code_value))
|
||||
|
||||
def inviter_relations(self, user_id: int) -> list[InviteRelation]:
|
||||
return (
|
||||
self.db.query(InviteRelation)
|
||||
.filter(InviteRelation.inviter_user_id == user_id)
|
||||
.order_by(InviteRelation.id.desc())
|
||||
.all()
|
||||
)
|
||||
|
||||
def users_by_ids(self, user_ids: list[int]) -> dict[int, User]:
|
||||
if not user_ids:
|
||||
return {}
|
||||
rows = self.db.scalars(select(User).where(User.id.in_(user_ids))).all()
|
||||
return {row.id: row for row in rows}
|
||||
|
||||
43
backend/app/modules/invites/router.py
Normal file
43
backend/app/modules/invites/router.py
Normal file
@@ -0,0 +1,43 @@
|
||||
from fastapi import APIRouter, Depends
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.common.db.session import get_db
|
||||
from app.common.responses.api_response import success_response
|
||||
from app.common.security.deps import get_current_user
|
||||
from app.models.entities import User
|
||||
from app.modules.invites.service import InviteService
|
||||
|
||||
|
||||
router = APIRouter(prefix="/api/v1/invite", tags=["invite"])
|
||||
|
||||
|
||||
@router.get("")
|
||||
def get_invite_summary(
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
return success_response(InviteService(db).get_invite_summary(current_user.id))
|
||||
|
||||
|
||||
@router.post("/codes")
|
||||
def create_invite_code(
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
return success_response(InviteService(db).create_invite_code(current_user.id))
|
||||
|
||||
|
||||
@router.get("/relations")
|
||||
def list_relations(
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
return success_response(InviteService(db).list_relations(current_user.id))
|
||||
|
||||
|
||||
@router.get("/rewards")
|
||||
def list_rewards(
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
return success_response(InviteService(db).list_rewards(current_user.id))
|
||||
6
backend/app/modules/invites/schema.py
Normal file
6
backend/app/modules/invites/schema.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class CreateInviteCodeRequest(BaseModel):
|
||||
regenerate: bool = False
|
||||
|
||||
75
backend/app/modules/invites/service.py
Normal file
75
backend/app/modules/invites/service.py
Normal file
@@ -0,0 +1,75 @@
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.common.utils.id_gen import new_invite_code
|
||||
from app.models.entities import InviteCode, InviteRelation
|
||||
from app.modules.invites.repository import InviteRepository
|
||||
|
||||
|
||||
class InviteService:
|
||||
def __init__(self, db: Session) -> None:
|
||||
self.db = db
|
||||
self.repository = InviteRepository(db)
|
||||
|
||||
def get_invite_summary(self, user_id: int) -> dict:
|
||||
code = self.repository.get_default_code(user_id)
|
||||
if not code:
|
||||
code = self._create_default_code(user_id)
|
||||
relations = self.repository.inviter_relations(user_id)
|
||||
rewarded = [item for item in relations if item.reward_status == "rewarded"]
|
||||
return {
|
||||
"inviteCode": code.invite_code,
|
||||
"inviteLink": code.invite_link,
|
||||
"invitedUsers": len(relations),
|
||||
"rewardedUsers": len(rewarded),
|
||||
"rewardedPoints": sum(item.reward_points for item in rewarded),
|
||||
}
|
||||
|
||||
def create_invite_code(self, user_id: int) -> dict:
|
||||
code = self.repository.get_default_code(user_id)
|
||||
if code:
|
||||
return {"inviteCode": code.invite_code, "inviteLink": code.invite_link}
|
||||
code = self._create_default_code(user_id)
|
||||
return {"inviteCode": code.invite_code, "inviteLink": code.invite_link}
|
||||
|
||||
def list_relations(self, user_id: int) -> list[dict]:
|
||||
relations = self.repository.inviter_relations(user_id)
|
||||
users = self.repository.users_by_ids([item.invitee_user_id for item in relations])
|
||||
return [
|
||||
{
|
||||
"inviteeUserId": item.invitee_user_id,
|
||||
"inviteeNickname": users.get(item.invitee_user_id).nickname if users.get(item.invitee_user_id) else "",
|
||||
"rewardStatus": item.reward_status,
|
||||
"rewardPoints": item.reward_points,
|
||||
"createdAt": item.created_at.isoformat(),
|
||||
"rewardedAt": item.rewarded_at.isoformat() if item.rewarded_at else None,
|
||||
}
|
||||
for item in relations
|
||||
]
|
||||
|
||||
def list_rewards(self, user_id: int) -> list[dict]:
|
||||
relations = self.repository.inviter_relations(user_id)
|
||||
return [
|
||||
{
|
||||
"inviteeUserId": item.invitee_user_id,
|
||||
"rewardStatus": item.reward_status,
|
||||
"rewardPoints": item.reward_points,
|
||||
"rewardedAt": item.rewarded_at.isoformat() if item.rewarded_at else None,
|
||||
}
|
||||
for item in relations
|
||||
if item.reward_points > 0
|
||||
]
|
||||
|
||||
def _create_default_code(self, user_id: int) -> InviteCode:
|
||||
code_value = new_invite_code()
|
||||
code = InviteCode(
|
||||
user_id=user_id,
|
||||
invite_code=code_value,
|
||||
invite_link=f"http://localhost:3000/register?inviteCode={code_value}",
|
||||
status=1,
|
||||
is_default=True,
|
||||
)
|
||||
self.db.add(code)
|
||||
self.db.commit()
|
||||
self.db.refresh(code)
|
||||
return code
|
||||
|
||||
Reference in New Issue
Block a user