Skip to content

Purav fix bell notification for meetings - #1677

Merged
one-community merged 31 commits into
developmentfrom
Gopika_Fix_Bell_notification_for_meetings
Jul 26, 2026
Merged

Purav fix bell notification for meetings#1677
one-community merged 31 commits into
developmentfrom
Gopika_Fix_Bell_notification_for_meetings

Conversation

@gopikalakshmia

@gopikalakshmia gopikalakshmia commented Aug 22, 2025

Copy link
Copy Markdown
Contributor

PR #1677 — Bell Notification for Meetings (Backend)

Branch: Gopika_Fix_Bell_notification_for_meetingsdevelopment
Related Frontend PR: HighestGoodNetworkApp #3946


Summary

This PR adds the backend for the Meeting Bell Notification feature. It allows Administrators, Managers, and Owners to schedule meetings for team members. Participants receive a bell notification when a meeting is scheduled within the next 3 days. The notification resets (clears) once the participant views it.

Files changed (feature only — no unrelated changes)

File Change
src/models/meeting.js New Mongoose schema for meetings
src/controllers/meetingController.js New controller with 6 handlers
src/routes/meetingRouter.js New router — 6 endpoints mounted at /api
src/startup/routes.js Registers meetingRouter
src/utilities/createInitialPermissions.js Adds scheduleMeetings permission to Administrator, Manager, Owner

How to Run the Backend Locally

Prerequisites

  • Node.js ≥ 20
  • Yarn 1.x (npm install -g yarn)
  • Access to MongoDB Atlas (hgnData_dev) — get .env credentials from a teammate

1. Clone and checkout

git clone https://github.com/OneCommunityGlobal/HGNRest.git
cd HGNRest
git checkout Gopika_Fix_Bell_notification_for_meetings

2. Install dependencies

yarn install

Use yarn install, not npm install — this repo uses yarn.lock as the lockfile.

3. Create your .env file

Create a .env file in the project root with the following variables (get values from a teammate):

user=<atlas_username>
password=<atlas_password>
cluster=<atlas_cluster_host>
dbName=hgnData_dev
appName=HGNProdDB
replicaSetName=<replica_set_name>
JWT_SECRET=hgndata
TOKEN_LIFETIME=10
TOKEN_LIFETIME_UNITS=days
DEF_PWD=123Welcome!
TIME_ARCHIVE_FIRST_NAME=TimeArchiveAccount
TIME_ARCHIVE_LAST_NAME=TimeArchiveAccount
TIME_ARCHIVE_EMAIL=TimeArchiveAccount@yopmail.com

MongoDB Atlas: make sure your current IP address is whitelisted under Network Access in Atlas, or add 0.0.0.0/0 for local dev.

4. Start the server

yarn dev

This runs from src/ directly via babel-node with auto-restart on file changes.

Do not use yarn start / npm start unless you rebuild first (yarn build). Those commands run from the compiled dist/ folder which may be stale and won't include meeting routes.

5. Confirm the server is running

You should see both of these lines in the terminal:

Started server on port 4500
connected to mongodb

The API base URL is: http://localhost:4500/api

6. Configure the frontend

In the HighestGoodNetworkApp frontend repo, set your .env:

REACT_APP_APIENDPOINT=http://localhost:4500/api

API Endpoints

All endpoints require a valid JWT in the Authorization header (raw token, no Bearer prefix). Get your token by logging in via POST /api/login.

Authentication

POST /api/login
Content-Type: application/json

{
  "email": "your@email.com",
  "password": "yourpassword"
}

Response: { "token": "<JWT>" }
Use this token in all subsequent requests as: Authorization: <JWT>


POST /api/meetings/new — Schedule a meeting

Permission required: scheduleMeetings (Administrator, Manager, Owner)

Request body:

{
  "dateOfMeeting": "2026-07-05",
  "startHour": "02",
  "startMinute": "00",
  "startTimePeriod": "PM",
  "duration": 30,
  "participantList": ["<participantUserId>"],
  "location": "Zoom",
  "locationDetails": "https://zoom.us/j/example",
  "notes": "Weekly team sync",
  "organizer": "<organizerUserId>"
}

Valid location values: "Zoom", "Phone call", "On-site" (or omit for none)

Responses:

  • 201{ "message": "Meeting saved successfully" }
  • 400 — Invalid form values, invalid/nonexistent user IDs
  • 500 — Internal server error

GET /api/meetings?startTime=&endTime= — Get meetings in a date range

Returns all meetings (with per-participant read status) within the given time window.

Query params: ISO 8601 timestamps (URL-encoded)

Example:

GET /api/meetings?startTime=2026-07-03T00%3A00%3A00.000Z&endTime=2026-07-06T23%3A59%3A59.999Z

Response: Array of meeting objects:

[
  {
    "_id": "...",
    "dateTime": "2026-07-05T19:00:00.000Z",
    "duration": 30,
    "organizer": "...",
    "location": "Zoom",
    "locationDetails": "...",
    "notes": "...",
    "recipient": "<participantId>",
    "isRead": false
  }
]

GET /api/meetings/participant/:participantId — Get unread upcoming meetings (bell popup)

Returns meetings within the next 3 days that are unread for the given participant. This is the primary endpoint the frontend bell uses to populate the notification popup.

Response:

{
  "upComingMeetings": [
    {
      "_id": "...",
      "dateTime": "2026-07-05T19:00:00.000Z",
      "organizerName": "Jane Smith",
      "duration": 30,
      "location": "Zoom",
      "locationDetails": "...",
      "notes": "...",
      "participant": "<participantId>"
    }
  ]
}
  • Returns 404 if no unread meetings within 3 days (bell should not light up)

POST /api/meetings/markRead/:meetingId/:recipient — Dismiss notification

Marks a specific meeting as read for a specific participant. Call this when the participant views/dismisses the bell popup.

Response:

  • 200{ "message": "Meeting marked as read successfully" }
  • 404 — Meeting not found or already read
  • 400 — Invalid IDs

GET /api/meetings/upcoming/:organizerId — Get organizer's future meetings

Returns all upcoming (future) meetings scheduled by the given organizer.

Query param: organizerId=<userId>

Response: Array of meeting objects with full participantList


GET /api/meeting/:meetingId/calendar — Get calendar invite data

Returns Google Calendar link and .ics content for a meeting.

Response:

{
  "googleCalendarLink": "https://calendar.google.com/...",
  "icsContent": "BEGIN:VCALENDAR\n...",
  "organizerFullName": "Jane Smith"
}

Testing the Bell Notification Feature

Test accounts setup

You need two accounts to test the full flow:

  • Organizer — a user with Administrator, Manager, or Owner role
  • Participant — any active user

Get their _id values from MongoDB (userProfiles collection) or decode them from the JWT token after login.


Test scenario 1 — Bell appears for participant

Step Action Expected result
1 Log in as organizer, get JWT 200 { "token": "..." }
2 POST /api/meetings/new with participant's ID and a date within 3 days 201 { "message": "Meeting saved successfully" }
3 Log in as participant, get JWT 200 { "token": "..." }
4 GET /api/meetings/participant/<participantId> 200 { "upComingMeetings": [ ... ] } — meeting appears
5 Load frontend as participant Bell icon should be highlighted / notification should appear

Test scenario 2 — Notification clears after viewing

Step Action Expected result
1 As participant, get meeting ID from step 4 above
2 POST /api/meetings/markRead/<meetingId>/<participantId> 200 { "message": "Meeting marked as read successfully" }
3 GET /api/meetings/participant/<participantId> again 404 — no more unread meetings
4 Reload frontend as participant Bell should no longer be highlighted

Test scenario 3 — Meeting > 3 days away does NOT trigger bell

Step Action Expected result
1 POST /api/meetings/new with a date 5+ days from now 201
2 GET /api/meetings/participant/<participantId> 404 — not within 3-day window
3 Check frontend Bell should NOT light up

Test scenario 4 — Invalid inputs are rejected

Input Expected response
Missing dateOfMeeting 400 Bad request: Invalid form values
Non-existent organizer ID 400 Bad request: Organizer ID does not exist
Non-existent participant ID 400 Bad request: Participant ID does not exist
Invalid location value (e.g. "Slack") 400 Bad request: Invalid form values
Non-ObjectId string as meetingId in markRead 400 Invalid meeting or recipient ID

Quick curl test block

Replace <TOKEN>, <ORGANIZER_ID>, <PARTICIPANT_ID> with real values.

# 1. Schedule a meeting (within next 3 days)
curl -X POST http://localhost:4500/api/meetings/new \
  -H "Authorization: <TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
    "dateOfMeeting": "2026-07-05",
    "startHour": "02",
    "startMinute": "00",
    "startTimePeriod": "PM",
    "duration": 30,
    "participantList": ["<PARTICIPANT_ID>"],
    "location": "Zoom",
    "locationDetails": "zoom.us/example",
    "notes": "Test bell notification",
    "organizer": "<ORGANIZER_ID>"
  }'

# 2. Check bell for participant (should return unread meeting)
curl http://localhost:4500/api/meetings/participant/<PARTICIPANT_ID> \
  -H "Authorization: <TOKEN>"

# 3. Get meetings in range (next 3 days)
curl "http://localhost:4500/api/meetings?startTime=$(date -u +%Y-%m-%dT%H:%M:%S.000Z)&endTime=$(date -u -d '+3 days' +%Y-%m-%dT%H:%M:%S.000Z)" \
  -H "Authorization: <TOKEN>"

# 4. Mark as read (replace <MEETING_ID>)
curl -X POST http://localhost:4500/api/meetings/markRead/<MEETING_ID>/<PARTICIPANT_ID> \
  -H "Authorization: <TOKEN>"

# 5. Confirm cleared (should return 404)
curl http://localhost:4500/api/meetings/participant/<PARTICIPANT_ID> \
  -H "Authorization: <TOKEN>"

# 6. Get calendar invite
curl http://localhost:4500/api/meeting/<MEETING_ID>/calendar \
  -H "Authorization: <TOKEN>"

Known Issues / Notes for Reviewers

  1. meetings collection does not pre-exist — MongoDB creates it automatically on the first successful POST /api/meetings/new.

  2. Calendar durationgetCalendarInvite computes end time as startTime + duration * 1000ms. The frontend sends duration in minutes; this means the calendar end time will be off (30 minutes will show as 30 seconds). A fix should multiply by 60 * 1000 instead.

  3. getAllMeetingsByOrganizer route — The route param is :organizerId but the controller reads req.query.organizerId. This will always return an empty array when called with a path param. Frontend should use ?organizerId=<id> as a query param, or the route should be fixed to use req.params.organizerId.

  4. No email/push notification on create — Meetings are saved to DB. Calendar links are available via GET /api/meeting/:id/calendar after creation, but no automatic email or push is sent when a meeting is scheduled.

  5. SonarCloud security — All user-controlled IDs are now validated and cast to mongoose.Types.ObjectId before being used in DB queries (fixed in this branch).


Permissions Added

scheduleMeetings permission added to the following default roles in createInitialPermissions.js:

Role Can schedule meetings
Administrator
Manager
Owner
All others

@one-community one-community added the High Priority - Please Review First This is an important PR we'd like to get merged as soon as possible label Aug 25, 2025

@aseemdeshmukh aseemdeshmukh left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Added comments on PR3946

@gopikalakshmia gopikalakshmia removed the High Priority - Please Review First This is an important PR we'd like to get merged as soon as possible label Sep 2, 2025
@one-community one-community added Do Not Review Do not review or look at code without full context Needs New Developer This is a PR that is partially developed but needs someone new to take it over and finish it. labels Apr 5, 2026
…ersions in package.json and package-lock.json
…r ID validation and streamline participant and organizer ID checks
@pixelpix13 pixelpix13 changed the title Gopika fix bell notification for meetings Purav fix bell notification for meetings Jul 3, 2026
@one-community one-community added High Priority - Please Review First This is an important PR we'd like to get merged as soon as possible and removed Do Not Review Do not review or look at code without full context Needs New Developer This is a PR that is partially developed but needs someone new to take it over and finish it. labels Jul 5, 2026

@kzou55 kzou55 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hi Purav,

I ran and tested the PR alongside its associated frontend.

Verified

  • Can schedule meetings
  • Can mark meetings as read
  • Gets notification if meeting is within 3 days
  • Bell notification works
  • Invalid inputs are sent back the appropriate error message

Testing

  • Getting meetings within a date range

    Image
  • Getting calendar invite

    Image
  • Scenario 1 - Bell appears for participant

    • Scheduling a meeting using admin account for
    Image - Get the meetings for the participant Image Image Image Image Image
  • Scenario 2 - Notification clears after viewing

    • Mark meeting as read
      Image

    • Verifying no more meetings
      Image

    • Bell notification icon disappeared

      Image
  • Scenario 3 - Meeting > 3 days away does not trigger bell

    • Creating a meeting > 3 days away

      Image
    • Confirming that no meeting within 3 days

      Image
    • No bell notification

      Image
  • Scenario 4 - Invalid inputs are rejected

    • Bad date of meeting value

      Image
    • Organizer ID not existing

      Image
    • Participant ID not existing

      Image
    • Invalid meeting location

    Image
    • Non object id for meeting id

      Image

Issues

  1. Not able to get upcoming meetings for organizer. Always saying invalid organizer userID. Despite the fact, I can see the meetings in MongoDB.

    Image Image

…culation in getAllMeetingsByOrganizer function

@kzou55 kzou55 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hi Purav,

I ran and retested the PR alongside the associated frontend PR.

Verified

  • The following as before:
    • Test scenario 1 - Bell appears for participant
    • Test scenario 2 - Notification clears after viewing
    • Test scenario 3 - Meeting > 3 days away does not trigger bell
    • Test scenario 4 - Invalid inputs are rejected
  • The previous issue of the getting upcoming meetings for organizer endpoint not working is now functional
Image

@sonarqubecloud

Copy link
Copy Markdown

@one-community

Copy link
Copy Markdown
Member

Thank you all, merging!

@one-community
one-community merged commit 6ecf1ae into development Jul 26, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

High Priority - Please Review First This is an important PR we'd like to get merged as soon as possible

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants