Basic event management

This commit is contained in:
James Pattinson
2025-11-12 18:08:11 +00:00
parent e5fdd0ecb8
commit 107c208746
9 changed files with 791 additions and 79 deletions

View File

@@ -1,5 +1,5 @@
from fastapi import APIRouter
from . import auth, users, tiers, memberships, payments, email, email_templates
from . import auth, users, tiers, memberships, payments, email, email_templates, events
api_router = APIRouter()
@@ -10,3 +10,4 @@ api_router.include_router(memberships.router, prefix="/memberships", tags=["memb
api_router.include_router(payments.router, prefix="/payments", tags=["payments"])
api_router.include_router(email.router, prefix="/email", tags=["email"])
api_router.include_router(email_templates.router, prefix="/email-templates", tags=["email-templates"])
api_router.include_router(events.router, prefix="/events", tags=["events"])

View File

@@ -0,0 +1,207 @@
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from typing import List
from datetime import datetime
from ...core.database import get_db
from ...models.models import Event, EventRSVP, User, EventStatus
from ...schemas import (
EventCreate, EventUpdate, EventResponse, EventRSVPResponse, EventRSVPUpdate, MessageResponse
)
from ...api.dependencies import get_current_active_user, get_admin_user
router = APIRouter()
@router.get("/", response_model=List[EventResponse])
async def get_events(
current_user: User = Depends(get_current_active_user),
db: Session = Depends(get_db)
):
"""Get all events (admin) or published events (members)"""
if current_user.role in ['admin', 'super_admin']:
events = db.query(Event).order_by(Event.event_date).all()
else:
events = db.query(Event).filter(
Event.status == EventStatus.PUBLISHED
).order_by(Event.event_date).all()
return events
@router.get("/upcoming", response_model=List[EventResponse])
async def get_upcoming_events(
current_user: User = Depends(get_current_active_user),
db: Session = Depends(get_db)
):
"""Get upcoming events"""
now = datetime.now()
events = db.query(Event).filter(
Event.event_date >= now.date(),
Event.status == EventStatus.PUBLISHED
).order_by(Event.event_date).all()
return events
@router.post("/", response_model=EventResponse, status_code=status.HTTP_201_CREATED)
async def create_event(
event_data: EventCreate,
current_user: User = Depends(get_admin_user),
db: Session = Depends(get_db)
):
"""Create a new event (admin only)"""
# Validate event date is in the future
if event_data.event_date < datetime.now():
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Event date must be in the future"
)
event = Event(
title=event_data.title,
description=event_data.description,
event_date=event_data.event_date,
event_time=event_data.event_time,
location=event_data.location,
max_attendees=event_data.max_attendees,
status=EventStatus.DRAFT,
created_by=current_user.id
)
db.add(event)
db.commit()
db.refresh(event)
return event
@router.put("/{event_id}", response_model=EventResponse)
async def update_event(
event_id: int,
event_data: EventUpdate,
current_user: User = Depends(get_admin_user),
db: Session = Depends(get_db)
):
"""Update an event (admin only)"""
event = db.query(Event).filter(Event.id == event_id).first()
if not event:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Event not found"
)
# Update fields
for field, value in event_data.dict(exclude_unset=True).items():
setattr(event, field, value)
event.updated_at = datetime.now()
db.commit()
db.refresh(event)
return event
@router.delete("/{event_id}", response_model=MessageResponse)
async def delete_event(
event_id: int,
current_user: User = Depends(get_admin_user),
db: Session = Depends(get_db)
):
"""Delete an event (admin only)"""
event = db.query(Event).filter(Event.id == event_id).first()
if not event:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Event not found"
)
db.delete(event)
db.commit()
return {"message": "Event deleted successfully"}
@router.get("/{event_id}/rsvps", response_model=List[EventRSVPResponse])
async def get_event_rsvps(
event_id: int,
current_user: User = Depends(get_admin_user),
db: Session = Depends(get_db)
):
"""Get RSVPs for an event (admin only)"""
event = db.query(Event).filter(Event.id == event_id).first()
if not event:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Event not found"
)
rsvps = db.query(EventRSVP).filter(EventRSVP.event_id == event_id).all()
return rsvps
@router.post("/{event_id}/rsvp", response_model=EventRSVPResponse)
async def create_or_update_rsvp(
event_id: int,
rsvp_data: EventRSVPUpdate,
current_user: User = Depends(get_current_active_user),
db: Session = Depends(get_db)
):
"""Create or update RSVP for an event"""
event = db.query(Event).filter(Event.id == event_id).first()
if not event:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Event not found"
)
if event.status != EventStatus.PUBLISHED:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Event is not available for RSVP"
)
# Check if RSVP already exists
existing_rsvp = db.query(EventRSVP).filter(
EventRSVP.event_id == event_id,
EventRSVP.user_id == current_user.id
).first()
if existing_rsvp:
# Update existing RSVP
existing_rsvp.status = rsvp_data.status
if rsvp_data.notes is not None:
existing_rsvp.notes = rsvp_data.notes
existing_rsvp.updated_at = datetime.now()
db.commit()
db.refresh(existing_rsvp)
return existing_rsvp
else:
# Check attendee limit
if event.max_attendees:
current_rsvp_count = db.query(EventRSVP).filter(
EventRSVP.event_id == event_id,
EventRSVP.status == 'attending'
).count()
if current_rsvp_count >= event.max_attendees:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Event is at maximum capacity"
)
# Create new RSVP
rsvp = EventRSVP(
event_id=event_id,
user_id=current_user.id,
status=rsvp_data.status,
notes=rsvp_data.notes
)
db.add(rsvp)
db.commit()
db.refresh(rsvp)
return rsvp
@router.get("/my-rsvps", response_model=List[EventRSVPResponse])
async def get_my_rsvps(
current_user: User = Depends(get_current_active_user),
db: Session = Depends(get_db)
):
"""Get current user's RSVPs"""
rsvps = db.query(EventRSVP).filter(EventRSVP.user_id == current_user.id).all()
return rsvps