diff --git a/deploy/meeting-intelligence/api/app/database.py b/deploy/meeting-intelligence/api/app/database.py index 5a577eb..cab67a5 100644 --- a/deploy/meeting-intelligence/api/app/database.py +++ b/deploy/meeting-intelligence/api/app/database.py @@ -48,29 +48,37 @@ class Database: self, limit: int = 50, offset: int = 0, - status: Optional[str] = None + status: Optional[str] = None, + conference_prefix: Optional[str] = None ) -> List[Dict[str, Any]]: - """List meetings with pagination.""" + """List meetings with pagination. Optionally filter by conference_id prefix.""" async with self.pool.acquire() as conn: + conditions = [] + params: list = [] + idx = 1 + if status: - rows = await conn.fetch(""" - SELECT id, conference_id, conference_name, title, - started_at, ended_at, duration_seconds, - status, created_at - FROM meetings - WHERE status = $1 - ORDER BY created_at DESC - LIMIT $2 OFFSET $3 - """, status, limit, offset) - else: - rows = await conn.fetch(""" - SELECT id, conference_id, conference_name, title, - started_at, ended_at, duration_seconds, - status, created_at - FROM meetings - ORDER BY created_at DESC - LIMIT $1 OFFSET $2 - """, limit, offset) + conditions.append(f"status = ${idx}") + params.append(status) + idx += 1 + + if conference_prefix: + conditions.append(f"conference_id LIKE ${idx}") + params.append(conference_prefix + "%") + idx += 1 + + where = f"WHERE {' AND '.join(conditions)}" if conditions else "" + params.extend([limit, offset]) + + rows = await conn.fetch(f""" + SELECT id, conference_id, conference_name, title, + started_at, ended_at, duration_seconds, + status, created_at + FROM meetings + {where} + ORDER BY created_at DESC + LIMIT ${idx} OFFSET ${idx + 1} + """, *params) return [dict(row) for row in rows] @@ -156,33 +164,40 @@ class Database: tokens: List[str], limit: int = 50, offset: int = 0, - status: Optional[str] = None + status: Optional[str] = None, + conference_prefix: Optional[str] = None ) -> List[Dict[str, Any]]: - """List meetings filtered by access tokens.""" + """List meetings filtered by access tokens. Optionally filter by conference_id prefix.""" if not tokens: return [] async with self.pool.acquire() as conn: + conditions = ["access_token = ANY($1)"] + params: list = [tokens] + idx = 2 + if status: - rows = await conn.fetch(""" - SELECT id, conference_id, conference_name, title, - started_at, ended_at, duration_seconds, - status, created_at - FROM meetings - WHERE access_token = ANY($1) AND status = $2 - ORDER BY created_at DESC - LIMIT $3 OFFSET $4 - """, tokens, status, limit, offset) - else: - rows = await conn.fetch(""" - SELECT id, conference_id, conference_name, title, - started_at, ended_at, duration_seconds, - status, created_at - FROM meetings - WHERE access_token = ANY($1) - ORDER BY created_at DESC - LIMIT $2 OFFSET $3 - """, tokens, limit, offset) + conditions.append(f"status = ${idx}") + params.append(status) + idx += 1 + + if conference_prefix: + conditions.append(f"conference_id LIKE ${idx}") + params.append(conference_prefix + "%") + idx += 1 + + where = " AND ".join(conditions) + params.extend([limit, offset]) + + rows = await conn.fetch(f""" + SELECT id, conference_id, conference_name, title, + started_at, ended_at, duration_seconds, + status, created_at + FROM meetings + WHERE {where} + ORDER BY created_at DESC + LIMIT ${idx} OFFSET ${idx + 1} + """, *params) return [dict(row) for row in rows] diff --git a/deploy/meeting-intelligence/api/app/routes/meetings.py b/deploy/meeting-intelligence/api/app/routes/meetings.py index f026118..a0b3b33 100644 --- a/deploy/meeting-intelligence/api/app/routes/meetings.py +++ b/deploy/meeting-intelligence/api/app/routes/meetings.py @@ -76,12 +76,14 @@ async def list_meetings( request: Request, limit: int = Query(default=50, le=100), offset: int = Query(default=0, ge=0), - status: Optional[str] = Query(default=None) + status: Optional[str] = Query(default=None), + conference_prefix: Optional[str] = Query(default=None, description="Filter by conference_id prefix (e.g. space slug)") ): """List meetings the caller has access to. Requires X-MI-Tokens header with comma-separated access tokens. Returns only meetings matching the provided tokens. + Optionally filter by conference_prefix to scope to a space. """ db = request.app.state.db tokens = get_multi_tokens(request) @@ -90,7 +92,8 @@ async def list_meetings( return MeetingListResponse(meetings=[], total=0, limit=limit, offset=offset) meetings = await db.list_meetings_by_tokens( - tokens=tokens, limit=limit, offset=offset, status=status + tokens=tokens, limit=limit, offset=offset, status=status, + conference_prefix=conference_prefix ) return MeetingListResponse(