Skip to content

refactor(meeting): reduce complexity in join_room and implement test …#46

Merged
aniebietafia merged 1 commit intomainfrom
feat/room_meeting_management
Apr 3, 2026
Merged

refactor(meeting): reduce complexity in join_room and implement test …#46
aniebietafia merged 1 commit intomainfrom
feat/room_meeting_management

Conversation

@aniebietafia
Copy link
Copy Markdown
Contributor

@aniebietafia aniebietafia commented Apr 3, 2026

…suite

  • Refactor MeetingService.join_room into smaller helper methods to reduce cyclomatic complexity from 15 to under 10, resolving Ruff C901.
  • Implement comprehensive unit tests for MeetingService covering room lifecycle, participant management, and edge cases.
  • Add integration tests for meeting router using httpx.AsyncClient to ensure compatibility with Windows proactor event loops.
  • Resolve 21 Mypy type errors across service.py, router.py, and state.py related to dynamic attribute injection and async Redis interactions.

Summary by CodeRabbit

Release Notes

  • New Features
    • Meeting room creation and management with unique access codes
    • Guest support for joining meetings without authentication
    • Meeting history with pagination and filtering
    • Room invitations via email
    • Real-time participant tracking and active speaker detection
    • Configurable room settings (capacity, transcription, lock status)
    • Enhanced authentication supporting optional bearer tokens

…suite

- Refactor `MeetingService.join_room` into smaller helper methods to reduce cyclomatic
  complexity from 15 to under 10, resolving Ruff C901.
- Implement comprehensive unit tests for `MeetingService` covering room lifecycle,
  participant management, and edge cases.
- Add integration tests for meeting router using `httpx.AsyncClient` to ensure
  compatibility with Windows proactor event loops.
- Resolve 21 Mypy type errors across `service.py`, `router.py`, and `state.py`
  related to dynamic attribute injection and async Redis interactions.

Signed-off-by: aniebietafia <aniebietafia87@gmail.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 3, 2026

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

Introduces a complete meeting room management system with database models, Alembic migrations, service layer, Redis state synchronization, FastAPI routing, and authentication improvements. Includes room creation, participant joining/management, meeting history, bulk invitations, and configuration updates, supported by comprehensive unit tests and email templates.

Changes

Cohort / File(s) Summary
Database Migrations
alembic/versions/a9a4f2fb79b5_create_rooms_participants_and_.py, alembic/versions/a37ad6ed5842_create_rooms_participants_and_.py
Creates rooms, meeting_invitations, and participants tables with indexes and constraints; subsequent migration adds guest_session_id and display_name to participants, alters user_id nullability, and adds composite unique constraints.
Data Models
app/meeting/models.py, app/models/__init__.py
Defines SQLAlchemy ORM models for Room, Participant, and MeetingInvitation with relationships, constraints, and JSON settings; re-exports models for schema visibility.
Service Layer
app/meeting/repository.py, app/meeting/service.py, app/meeting/state.py
Implements MeetingRepository for CRUD operations, MeetingService for business logic (room lifecycle, joins, history, invitations), and MeetingStateService for Redis-backed ephemeral state (participants, lobby, active speaker).
API Layer
app/meeting/router.py, app/meeting/schemas.py, app/meeting/dependencies.py
Defines 10 REST endpoints for room/participant operations, Pydantic schemas for requests/responses, and FastAPI dependency injection for service resolution.
Authentication Changes
app/auth/router.py, app/core/dependencies.py
Adds explicit missing-credential validation to login endpoint; introduces optional OAuth2/Bearer token handling and new get_current_user_optional dependency for guest/optional auth flows.
Meeting Configuration
app/meeting/constants.py, app/routers/api.py
Centralizes room/status/role enums and message constants; registers meeting router under /meetings prefix.
Tests
tests/meeting/test_meeting_service.py
Comprehensive unit test suite covering room creation, joining flows, state transitions, host operations, error handling, and invitation logic with mocked dependencies.
Templates & Documentation
templates/email/meeting_invite.html, issues/..., issue.md
Adds email template for meeting invitations; includes feature specs for room management, meeting history, AI audio processing, WebSocket audio/captions, and real-time signaling.
Removed Tests
tests/test_auth/test_auth_refresh.py
Deletes obsolete refresh-token integration test suite (418 lines).

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant API as API Router
    participant Svc as MeetingService
    participant Repo as MeetingRepository
    participant DB as Database
    participant Redis as Redis State
    
    User->>API: POST /meetings (RoomCreate)
    API->>Svc: create_room(host, name, settings, scheduled_at)
    loop Retry until unique
        Svc->>Repo: room_code_exists(code)
        Repo->>DB: Query rooms table
        DB-->>Repo: exists: bool
        Repo-->>Svc: code_exists
    end
    Svc->>Repo: create_room(Room)
    Repo->>DB: INSERT Room
    DB-->>Repo: Room with id
    Svc->>Repo: create_participant(Participant)
    Repo->>DB: INSERT Participant (host)
    DB-->>Repo: Participant
    Svc->>Redis: add_participant(room_code, host_id)
    Redis-->>Svc: ok
    Svc-->>API: Room
    API-->>User: RoomApiResponse {room_code, join_url}
Loading
sequenceDiagram
    actor User
    participant API as API Router
    participant Svc as MeetingService
    participant Repo as MeetingRepository
    participant DB as Database
    participant Redis as Redis State
    
    User->>API: POST /meetings/{room_code}/join (JoinRoomRequest)
    API->>Svc: join_room(room_code, user/guest_session_id, guest_name, language)
    Svc->>Repo: get_room_by_code(room_code)
    Repo->>DB: Query rooms
    DB-->>Repo: Room
    Repo-->>Svc: Room
    
    alt Room is active/pending
        Svc->>Redis: get_participants(room_code)
        Redis-->>Svc: participants dict
        alt Capacity exceeded or locked
            Svc->>Redis: add_to_lobby(room_code, user_id, display_name)
            Redis-->>Svc: ok
        else Can join
            Svc->>Repo: create_or_update_participant(Participant)
            Repo->>DB: INSERT/UPDATE participant
            DB-->>Repo: Participant
            Svc->>Redis: add_participant(room_code, user_id, language)
            Redis-->>Svc: ok
        end
    else Room ended/scheduled
        Svc-->>API: BadRequestException
        API-->>User: Error response
    end
    
    Svc-->>API: {room_code, participants, join_url}
    API-->>User: JSONResponse
Loading
sequenceDiagram
    actor User
    participant API as API Router
    participant Svc as MeetingService
    participant Repo as MeetingRepository
    participant DB as Database
    
    User->>API: GET /meetings/history?role=all&page=1
    API->>Svc: get_meeting_history(user_id, role_filter, page, page_size)
    Svc->>Repo: get_meeting_history(user_id, role_filter, offset, limit)
    Repo->>DB: Query rooms/participants (grouped)<br/>with duration & counts
    DB-->>Repo: (total_count, Row[])
    Repo-->>Svc: (total_count, results)
    
    loop For each meeting row
        Svc->>Svc: Transform to MeetingHistoryItem<br/>(room_code, name, duration_minutes, participant_count)
    end
    
    Svc-->>API: {total, page, page_size, items[]}
    API-->>User: MeetingHistoryApiResponse
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

  • Room & Meeting Management #7: Implements the full Room & Meeting Management feature with SQLAlchemy models, migrations, service/repository/state layers, and REST endpoints for room creation, joining, hosting, and participant management.
  • Meeting Management Supplementary Endpoints #33: Implements meeting history pagination and room config update endpoints (GET /history, PATCH /{room_code}/config) with corresponding schemas, service methods, and host-only authorization.
  • Kafka Infrastructure & AI Pipeline Foundation #8: Adds the AI audio processing pipeline specification (Kafka topics, worker consumers, WebSocket egress) as documentation in issues/ai_audio_processing.md.

Possibly related PRs

Suggested labels

backend, tests, migrations, size/XL

Poem

🐰 A warren of rooms, now built and alive,
With guests hopping in, and histories to revive,
Redis hops fast, the database stays true,
From pending to active, this meeting's debut! 🌱✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 32.17% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: refactoring join_room for complexity reduction and implementing tests for MeetingService.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/room_meeting_management

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@aniebietafia aniebietafia linked an issue Apr 3, 2026 that may be closed by this pull request
11 tasks
Comment thread app/meeting/service.py
)
sent_count += 1
except Exception as e:
logger.error(f"Failed to queue Kafka event for email to {email}: {e}")
Comment thread app/meeting/router.py
)
if payload.get("type") == "guest":
return payload.get("sub") # type: ignore[no-any-return]
except Exception:
Comment thread app/meeting/state.py

import json
import logging
from collections.abc import Awaitable
Comment thread app/meeting/state.py
import json
import logging
from collections.abc import Awaitable
from typing import Any, cast
@aniebietafia aniebietafia merged commit cbea73d into main Apr 3, 2026
10 of 12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Room & Meeting Management

2 participants