Skip to content

feat: wire notifications into enrollment and session creation events#55

Open
ayesha1145 wants to merge 1 commit intoalphaonelabs:mainfrom
ayesha1145:feat/notification-triggers
Open

feat: wire notifications into enrollment and session creation events#55
ayesha1145 wants to merge 1 commit intoalphaonelabs:mainfrom
ayesha1145:feat/notification-triggers

Conversation

@ayesha1145
Copy link
Copy Markdown
Contributor

@ayesha1145 ayesha1145 commented Apr 25, 2026

Connects the merged notifications system (PR #48) to real platform events by calling _create_notification() in two key handlers.

Changes

api_join:

  • When a student enrolls in an activity, the activity host is notified with a new_enrollment notification
  • Notification includes the joiner's decrypted name and the activity title
  • Errors are caught and logged via capture_exception so enrollment never fails due to a notification error

api_create_session:

  • When a host creates a new session, all enrolled participants are notified with a new_session notification
  • Each enrolled user (except the host) receives a notification with the session title
  • Errors are caught per-user so one failure doesn't block others

Design

  • All notification calls are wrapped in try/except — parent operations are never interrupted
  • Follows the same encrypt/decrypt pattern as the rest of the codebase
  • Notification types: new_enrollment, new_session

Testing

  • All 273 existing tests passing ✅

Purpose

Integrate the notifications system into two platform events so hosts and participants receive timely alerts for enrollments and new sessions.

Key Changes

api_join

  • After inserting an enrollment, looks up the activity host and the joiner's decrypted display name and sends a best-effort notification to the host.
  • Notification type: new_enrollment
  • Payload: joiner's decrypted name + activity title
  • Wrapped in try/except and logs errors with capture_exception so enrollment always succeeds even if notification fails.

api_create_session

  • After creating a session, queries active (non-inactive) enrollments for the activity and sends a best-effort notification to each enrolled participant except the session creator.
  • Notification type: new_session
  • Payload: session title
  • Per-user try/except ensures one notification failure doesn't block others; errors are logged with capture_exception and session creation still succeeds.

Implementation details

  • Both handlers call the existing _create_notification() helper and follow repository encrypt/decrypt patterns when constructing notification content.
  • Notifications are best-effort (errors do not impact the primary operation) and reported to Sentry via capture_exception().

Impact

Hosts receive a new_enrollment notice when students join; enrolled participants are notified of new sessions via new_session notifications. These additions improve engagement without changing API behaviour or risking operation failures due to notification errors.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 25, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: alphaonelabs/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 73a57491-1bdb-4873-a913-28d018b8485c

📥 Commits

Reviewing files that changed from the base of the PR and between 8df6cfe and 494ef7c.

📒 Files selected for processing (1)
  • src/worker.py

Walkthrough

Two API endpoints in src/worker.py now send best-effort notifications: api_join notifies the activity host after enrollment, and api_create_session notifies enrolled, non-inactive participants (excluding the creator) after session creation. Notification errors are captured to Sentry and do not alter primary responses.

Changes

Cohort / File(s) Summary
Notification Logic
src/worker.py
Added post-operation notification blocks: api_join performs DB lookups for host and joiner display name and calls _create_notification with type_="new_enrollment"; api_create_session queries active enrolled users (excluding creator) and calls _create_notification with type_="new_session". Both blocks are wrapped in try/except that reports exceptions to Sentry via capture_exception and do not change endpoint success responses.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant api_join
    participant Database
    participant NotificationService
    participant Sentry

    Client->>api_join: POST /join (user, activity)
    api_join->>Database: Insert enrollment
    Database-->>api_join: Enrollment confirmed
    api_join->>Database: Query activity.host_id, decrypt joiner name
    Database-->>api_join: host_id, joiner_name

    alt Notification attempt
        api_join->>NotificationService: _create_notification(type="new_enrollment", to=host, msg=joiner_name + activity.title)
        NotificationService-->>api_join: OK
    else Error occurs
        NotificationService-->>api_join: Error
        api_join->>Sentry: capture_exception(error)
        Sentry-->>api_join: Acknowledged
    end

    api_join-->>Client: 200 OK (join response)
Loading
sequenceDiagram
    participant Client
    participant api_create_session
    participant Database
    participant NotificationService
    participant Sentry

    Client->>api_create_session: POST /sessions (creator, activity, title, ...)
    api_create_session->>Database: Insert session record
    Database-->>api_create_session: Session created
    api_create_session->>Database: Query enrolled users (active, non-inactive), exclude creator
    Database-->>api_create_session: participant_list

    alt Notification attempt
        api_create_session->>NotificationService: _create_notification(type="new_session", to=each participant, msg=title)
        NotificationService-->>api_create_session: OK
    else Error occurs
        NotificationService-->>api_create_session: Error
        api_create_session->>Sentry: capture_exception(error)
        Sentry-->>api_create_session: Acknowledged
    end

    api_create_session-->>Client: 200 OK (session response)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title directly and clearly summarizes the main change: adding notification functionality to enrollment and session creation workflows.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/worker.py`:
- Around line 1098-1115: The SQL uses "JOIN users u ON u.id = ?" which is
intentional to fetch the joiner's row via a bind param rather than expressing a
relationship to activities, but this is confusing; add a brief clarifying inline
comment immediately above the env.DB.prepare call (in the block that builds
act_detail) stating that the JOIN is used solely to fetch the user row by bind
param (or alternatively split into two queries: one to fetch the activity via
prepare(...).bind(...).first() and another to fetch the user by id) so future
readers won't mistake the JOIN for an activity→user relation; keep the rest of
the logic (decrypt, _create_notification, variable names) unchanged.
- Around line 1229-1246: The current try/except around the entire enrolled loop
causes one failure to abort notifications for all users; change the structure so
the DB query (env.DB.prepare(...).bind(act_id).all()) remains in its own
try/except, then iterate over enrolled.results and wrap each per-row
notification call to _create_notification in its own try/except that calls
capture_exception(exc, env=env, where="api_create_session.notify_enrolled",
extra={"user_id": row.user_id, "activity_id": act_id}) so each user failure is
isolated; keep the outer exception handling just for the DB query and consider
switching to batching later if enrollments grow.
- Around line 1098-1118: Replace the deprecated synchronous shim calls with
their async counterparts: in the join notification block where decrypt(...) is
called (referenced in the api_join notify_host flow, act_detail.joiner_name),
change to await decrypt_aes(...) and await the result; in _create_notification
where encrypt(...) is used for title and message, replace those calls with await
encrypt_aes(...) so the encrypted values are awaited before DB insert; and in
api_list_notifications where decrypt(...) is used to read stored notifications,
replace with await decrypt_aes(...). Ensure the surrounding functions are async
(or already async), import the async helpers if needed, and await the calls so
exceptions surface properly rather than hitting the deprecated stubs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: alphaonelabs/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: f83a81cd-dc23-42fb-a453-b3b45d974681

📥 Commits

Reviewing files that changed from the base of the PR and between 98c9aca and 8df6cfe.

📒 Files selected for processing (1)
  • src/worker.py

Comment thread src/worker.py
Comment thread src/worker.py
Comment thread src/worker.py
@ayesha1145 ayesha1145 force-pushed the feat/notification-triggers branch from defc01c to 494ef7c Compare April 25, 2026 18:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant