fix+feat(everything): lot of things
Some checks failed
Deploy to Development / build-and-deploy (push) Failing after 20s

This commit is contained in:
EvanChal
2026-01-25 22:14:48 +01:00
parent 5bbe05000e
commit dfeaecce73
15 changed files with 871 additions and 43 deletions

View File

@@ -19,40 +19,76 @@ async def create_event(
current_user: User = Depends(get_current_active_user)
):
"""Create a new event."""
event_dict = event_data.dict(exclude={'invited_user_ids'})
event = Event(
**event_data.dict(),
**event_dict,
creator_id=current_user.id
)
db.add(event)
db.commit()
db.refresh(event)
# Create participations for all active users
users = db.query(User).filter(User.is_active == True).all()
for user in users:
participation = EventParticipation(
event_id=event.id,
user_id=user.id,
status=ParticipationStatus.PENDING
)
db.add(participation)
# Gérer les invitations selon le type d'événement
if event.is_private:
# Événement privé : inviter uniquement les utilisateurs sélectionnés
invited_user_ids = event_data.invited_user_ids or []
# Toujours inclure le créateur
if current_user.id not in invited_user_ids:
invited_user_ids.append(current_user.id)
# Create notification
if user.id != current_user.id:
notification = Notification(
for user_id in invited_user_ids:
user = db.query(User).filter(User.id == user_id, User.is_active == True).first()
if user:
participation = EventParticipation(
event_id=event.id,
user_id=user.id,
status=ParticipationStatus.PENDING
)
db.add(participation)
# Create notification
if user.id != current_user.id:
notification = Notification(
user_id=user.id,
type=NotificationType.EVENT_INVITATION,
title=f"Invitation à un événement privé: {event.title}",
message=f"{current_user.full_name} vous a invité à un événement privé",
link=f"/events/{event.id}"
)
db.add(notification)
# Send email notification
try:
send_event_notification(user.email, event)
except:
pass
else:
# Événement public : inviter tous les utilisateurs actifs
users = db.query(User).filter(User.is_active == True).all()
for user in users:
participation = EventParticipation(
event_id=event.id,
user_id=user.id,
type=NotificationType.EVENT_INVITATION,
title=f"Nouvel événement: {event.title}",
message=f"{current_user.full_name} a créé un nouvel événement",
link=f"/events/{event.id}"
status=ParticipationStatus.PENDING
)
db.add(notification)
db.add(participation)
# Send email notification (async task would be better)
try:
send_event_notification(user.email, event)
except:
pass # Don't fail if email sending fails
# Create notification
if user.id != current_user.id:
notification = Notification(
user_id=user.id,
type=NotificationType.EVENT_INVITATION,
title=f"Nouvel événement: {event.title}",
message=f"{current_user.full_name} a créé un nouvel événement",
link=f"/events/{event.id}"
)
db.add(notification)
# Send email notification
try:
send_event_notification(user.email, event)
except:
pass
db.commit()
return format_event_response(event, db)
@@ -75,7 +111,23 @@ async def get_events(
# If upcoming is None, return all events
events = query.order_by(Event.date.desc()).all()
return [format_event_response(event, db) for event in events]
# Filtrer les événements privés : ne montrer que ceux où l'utilisateur est invité
filtered_events = []
for event in events:
if event.is_private:
# Vérifier si l'utilisateur est invité (a une participation)
participation = db.query(EventParticipation).filter(
EventParticipation.event_id == event.id,
EventParticipation.user_id == current_user.id
).first()
if participation or event.creator_id == current_user.id or current_user.is_admin:
filtered_events.append(event)
else:
# Événement public : visible par tous
filtered_events.append(event)
return [format_event_response(event, db) for event in filtered_events]
@router.get("/upcoming", response_model=List[EventResponse])
async def get_upcoming_events(
@@ -86,7 +138,21 @@ async def get_upcoming_events(
events = db.query(Event).options(joinedload(Event.creator)).filter(
Event.date >= datetime.utcnow()
).order_by(Event.date).all()
return [format_event_response(event, db) for event in events]
# Filtrer les événements privés
filtered_events = []
for event in events:
if event.is_private:
participation = db.query(EventParticipation).filter(
EventParticipation.event_id == event.id,
EventParticipation.user_id == current_user.id
).first()
if participation or event.creator_id == current_user.id or current_user.is_admin:
filtered_events.append(event)
else:
filtered_events.append(event)
return [format_event_response(event, db) for event in filtered_events]
@router.get("/past", response_model=List[EventResponse])
async def get_past_events(
@@ -97,7 +163,21 @@ async def get_past_events(
events = db.query(Event).options(joinedload(Event.creator)).filter(
Event.date < datetime.utcnow()
).order_by(Event.date.desc()).all()
return [format_event_response(event, db) for event in events]
# Filtrer les événements privés
filtered_events = []
for event in events:
if event.is_private:
participation = db.query(EventParticipation).filter(
EventParticipation.event_id == event.id,
EventParticipation.user_id == current_user.id
).first()
if participation or event.creator_id == current_user.id or current_user.is_admin:
filtered_events.append(event)
else:
filtered_events.append(event)
return [format_event_response(event, db) for event in filtered_events]
@router.get("/{event_id}", response_model=EventResponse)
async def get_event(
@@ -112,6 +192,19 @@ async def get_event(
status_code=status.HTTP_404_NOT_FOUND,
detail="Event not found"
)
# Vérifier l'accès pour les événements privés
if event.is_private:
participation = db.query(EventParticipation).filter(
EventParticipation.event_id == event.id,
EventParticipation.user_id == current_user.id
).first()
if not participation and event.creator_id != current_user.id and not current_user.is_admin:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="You don't have access to this private event"
)
return format_event_response(event, db)
@router.put("/{event_id}", response_model=EventResponse)
@@ -166,6 +259,74 @@ async def delete_event(
db.commit()
return {"message": "Event deleted successfully"}
@router.post("/{event_id}/invite", response_model=EventResponse)
async def invite_users_to_event(
event_id: int,
user_ids: List[int],
db: Session = Depends(get_db),
current_user: User = Depends(get_current_active_user)
):
"""Invite users to a private 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"
)
# Vérifier que l'événement est privé et que l'utilisateur est le créateur ou admin
if not event.is_private:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="This endpoint is only for private events"
)
if event.creator_id != current_user.id and not current_user.is_admin:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Only the event creator can invite users"
)
# Inviter les utilisateurs
for user_id in user_ids:
# Vérifier si l'utilisateur existe et est actif
user = db.query(User).filter(User.id == user_id, User.is_active == True).first()
if not user:
continue
# Vérifier si l'utilisateur n'est pas déjà invité
existing_participation = db.query(EventParticipation).filter(
EventParticipation.event_id == event_id,
EventParticipation.user_id == user_id
).first()
if not existing_participation:
participation = EventParticipation(
event_id=event.id,
user_id=user.id,
status=ParticipationStatus.PENDING
)
db.add(participation)
# Créer une notification
notification = Notification(
user_id=user.id,
type=NotificationType.EVENT_INVITATION,
title=f"Invitation à un événement privé: {event.title}",
message=f"{current_user.full_name} vous a invité à un événement privé",
link=f"/events/{event.id}"
)
db.add(notification)
# Envoyer un email
try:
send_event_notification(user.email, event)
except:
pass
db.commit()
return format_event_response(event, db)
@router.put("/{event_id}/participation", response_model=EventResponse)
async def update_participation(
event_id: int,
@@ -174,6 +335,25 @@ async def update_participation(
current_user: User = Depends(get_current_active_user)
):
"""Update user participation status 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"
)
# Pour les événements privés, vérifier que l'utilisateur est invité
if event.is_private:
participation_check = db.query(EventParticipation).filter(
EventParticipation.event_id == event_id,
EventParticipation.user_id == current_user.id
).first()
if not participation_check and event.creator_id != current_user.id and not current_user.is_admin:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="You are not invited to this private event"
)
participation = db.query(EventParticipation).filter(
EventParticipation.event_id == event_id,
EventParticipation.user_id == current_user.id
@@ -236,6 +416,7 @@ def format_event_response(event: Event, db: Session) -> dict:
"end_date": event.end_date,
"creator_id": event.creator_id,
"cover_image": event.cover_image,
"is_private": event.is_private if event.is_private is not None else False,
"created_at": event.created_at,
"updated_at": event.updated_at,
"creator_name": creator.full_name if creator else "Unknown",