2025-07-01 12:54:48 +00:00

326 lines
9.4 KiB
Python

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from typing import List
from app.db.base import get_db
from app.models.user import User
from app.models.ministry import (
Ministry,
MinistryMember,
MinistryActivity,
MinistryRequest,
MinistryRole,
)
from app.schemas.ministry import (
MinistryCreate,
MinistryUpdate,
MinistryResponse,
MinistryMemberResponse,
MinistryActivityCreate,
MinistryActivityResponse,
MinistryJoinRequest,
MinistryRequestResponse,
)
from app.api.auth import get_current_user
router = APIRouter()
@router.post("/", response_model=MinistryResponse)
def create_ministry(
ministry: MinistryCreate,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
"""Create a new ministry"""
db_ministry = Ministry(**ministry.dict(), leader_id=current_user.id)
db.add(db_ministry)
db.commit()
db.refresh(db_ministry)
# Add creator as leader
member = MinistryMember(
ministry_id=db_ministry.id, user_id=current_user.id, role=MinistryRole.LEADER
)
db.add(member)
db.commit()
db_ministry.leader_name = f"{current_user.first_name} {current_user.last_name}"
db_ministry.member_count = 1
db_ministry.is_member = True
db_ministry.user_role = MinistryRole.LEADER
return db_ministry
@router.get("/", response_model=List[MinistryResponse])
def get_ministries(
skip: int = 0,
limit: int = 100,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
"""Get all ministries"""
ministries = (
db.query(Ministry).filter(Ministry.is_active).offset(skip).limit(limit).all()
)
for ministry in ministries:
ministry.leader_name = (
f"{ministry.leader.first_name} {ministry.leader.last_name}"
)
ministry.member_count = (
db.query(MinistryMember)
.filter(MinistryMember.ministry_id == ministry.id, MinistryMember.is_active)
.count()
)
# Check if current user is a member and their role
member = (
db.query(MinistryMember)
.filter(
MinistryMember.ministry_id == ministry.id,
MinistryMember.user_id == current_user.id,
MinistryMember.is_active,
)
.first()
)
ministry.is_member = member is not None
ministry.user_role = member.role if member else None
return ministries
@router.get("/my-ministries", response_model=List[MinistryResponse])
def get_my_ministries(
db: Session = Depends(get_db), current_user: User = Depends(get_current_user)
):
"""Get ministries where current user is a member"""
memberships = (
db.query(MinistryMember)
.filter(MinistryMember.user_id == current_user.id, MinistryMember.is_active)
.all()
)
ministries = []
for membership in memberships:
ministry = membership.ministry
ministry.leader_name = (
f"{ministry.leader.first_name} {ministry.leader.last_name}"
)
ministry.member_count = (
db.query(MinistryMember)
.filter(MinistryMember.ministry_id == ministry.id, MinistryMember.is_active)
.count()
)
ministry.is_member = True
ministry.user_role = membership.role
ministries.append(ministry)
return ministries
@router.get("/{ministry_id}", response_model=MinistryResponse)
def get_ministry(
ministry_id: int,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
"""Get specific ministry"""
ministry = db.query(Ministry).filter(Ministry.id == ministry_id).first()
if not ministry:
raise HTTPException(status_code=404, detail="Ministry not found")
ministry.leader_name = f"{ministry.leader.first_name} {ministry.leader.last_name}"
ministry.member_count = (
db.query(MinistryMember)
.filter(MinistryMember.ministry_id == ministry.id, MinistryMember.is_active)
.count()
)
member = (
db.query(MinistryMember)
.filter(
MinistryMember.ministry_id == ministry.id,
MinistryMember.user_id == current_user.id,
MinistryMember.is_active,
)
.first()
)
ministry.is_member = member is not None
ministry.user_role = member.role if member else None
return ministry
@router.put("/{ministry_id}", response_model=MinistryResponse)
def update_ministry(
ministry_id: int,
ministry_update: MinistryUpdate,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
"""Update ministry (leaders only)"""
ministry = db.query(Ministry).filter(Ministry.id == ministry_id).first()
if not ministry:
raise HTTPException(status_code=404, detail="Ministry not found")
# Check if user is leader or co-leader
member = (
db.query(MinistryMember)
.filter(
MinistryMember.ministry_id == ministry_id,
MinistryMember.user_id == current_user.id,
MinistryMember.is_active,
)
.first()
)
if not member or member.role not in [MinistryRole.LEADER, MinistryRole.CO_LEADER]:
raise HTTPException(status_code=403, detail="Only leaders can update ministry")
for field, value in ministry_update.dict(exclude_unset=True).items():
setattr(ministry, field, value)
db.commit()
db.refresh(ministry)
return ministry
@router.post("/{ministry_id}/join", response_model=MinistryRequestResponse)
def request_to_join_ministry(
ministry_id: int,
join_request: MinistryJoinRequest,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
"""Request to join a ministry"""
ministry = db.query(Ministry).filter(Ministry.id == ministry_id).first()
if not ministry:
raise HTTPException(status_code=404, detail="Ministry not found")
# Check if already a member
existing_member = (
db.query(MinistryMember)
.filter(
MinistryMember.ministry_id == ministry_id,
MinistryMember.user_id == current_user.id,
MinistryMember.is_active,
)
.first()
)
if existing_member:
raise HTTPException(status_code=400, detail="Already a member of this ministry")
# Check if already has pending request
existing_request = (
db.query(MinistryRequest)
.filter(
MinistryRequest.ministry_id == ministry_id,
MinistryRequest.user_id == current_user.id,
MinistryRequest.status == "pending",
)
.first()
)
if existing_request:
raise HTTPException(status_code=400, detail="Already have a pending request")
request = MinistryRequest(
ministry_id=ministry_id, user_id=current_user.id, message=join_request.message
)
db.add(request)
db.commit()
db.refresh(request)
request.user_name = f"{current_user.first_name} {current_user.last_name}"
request.ministry_name = ministry.name
return request
@router.get("/{ministry_id}/members", response_model=List[MinistryMemberResponse])
def get_ministry_members(
ministry_id: int,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
"""Get ministry members"""
ministry = db.query(Ministry).filter(Ministry.id == ministry_id).first()
if not ministry:
raise HTTPException(status_code=404, detail="Ministry not found")
members = (
db.query(MinistryMember)
.filter(MinistryMember.ministry_id == ministry_id, MinistryMember.is_active)
.all()
)
for member in members:
member.user_name = f"{member.user.first_name} {member.user.last_name}"
member.ministry_name = ministry.name
return members
@router.get("/{ministry_id}/activities", response_model=List[MinistryActivityResponse])
def get_ministry_activities(
ministry_id: int,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
"""Get ministry activities"""
activities = (
db.query(MinistryActivity)
.filter(MinistryActivity.ministry_id == ministry_id)
.order_by(MinistryActivity.activity_date.desc())
.all()
)
for activity in activities:
activity.creator_name = (
f"{activity.creator.first_name} {activity.creator.last_name}"
)
return activities
@router.post("/{ministry_id}/activities", response_model=MinistryActivityResponse)
def create_ministry_activity(
ministry_id: int,
activity: MinistryActivityCreate,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
"""Create ministry activity (members only)"""
# Check if user is a member
member = (
db.query(MinistryMember)
.filter(
MinistryMember.ministry_id == ministry_id,
MinistryMember.user_id == current_user.id,
MinistryMember.is_active,
)
.first()
)
if not member:
raise HTTPException(
status_code=403, detail="Only ministry members can create activities"
)
db_activity = MinistryActivity(
**activity.dict(), ministry_id=ministry_id, created_by=current_user.id
)
db.add(db_activity)
db.commit()
db.refresh(db_activity)
db_activity.creator_name = f"{current_user.first_name} {current_user.last_name}"
return db_activity