feat: add production deployment config

- Add docker-compose.prod.yml with env var support
- Add frontend/Dockerfile.prod with nginx for static serving
- Fix Zulip notification to run in thread pool (avoid blocking)
- Use Zulip time format for timezone-aware display
- Add Zulip @mentions for users matched by email

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Joyce
2026-01-21 14:29:52 -05:00
parent 26311c867a
commit 7fefd634f5
4 changed files with 129 additions and 13 deletions

View File

@@ -1,3 +1,4 @@
import asyncio
import logging
from uuid import UUID
@@ -146,7 +147,6 @@ async def sync_participant(participant_id: UUID, db: AsyncSession = Depends(get_
async def schedule_meeting(
data: ScheduleRequest, db: AsyncSession = Depends(get_db)
):
# 1. Validate Lead Time (2 hours)
min_start_time = datetime.now(timezone.utc) + timedelta(hours=2)
if data.start_time.replace(tzinfo=timezone.utc) < min_start_time:
raise HTTPException(
@@ -154,7 +154,6 @@ async def schedule_meeting(
detail="Meetings must be scheduled at least 2 hours in advance."
)
# 2. Fetch Participants
result = await db.execute(
select(Participant).where(Participant.id.in_(data.participant_ids))
)
@@ -166,9 +165,7 @@ async def schedule_meeting(
participant_dicts = [
{"name": p.name, "email": p.email} for p in participants
]
participant_names = [p.name for p in participants]
# 3. Send Notifications
email_success = await send_meeting_invite(
participant_dicts,
data.title,
@@ -177,10 +174,11 @@ async def schedule_meeting(
data.end_time
)
zulip_success = send_zulip_notification(
zulip_success = await asyncio.to_thread(
send_zulip_notification,
data.title,
data.start_time,
participant_names
participant_dicts
)
return {