Add an event notification system to the existing Conference Manager API. Notifications are generated automatically when key actions occur, and an activity feed shows recent activity across an event.
- id (auto-generated integer)
- recipientId (required, references Attendee)
- type (required string - one of: "registration", "waitlist_promotion", "talk_updated", "new_rating")
- message (required string - human-readable description)
- referenceType (required string - "talk" or "registration")
- referenceId (required integer - ID of the referenced entity)
- read (boolean, default false)
- createdAt (timestamp, auto-set on creation)
- GET /notifications?attendee=:attendeeId - list notifications for an attendee, newest first
- PUT /notifications/:id/read - mark a single notification as read, return the updated notification
- PUT /notifications/read-all?attendee=:attendeeId - mark all notifications for an attendee as read, return 200 with
{"updated": N} - GET /notifications/unread-count?attendee=:attendeeId - return
{"count": N} - GET /events/:id/activity - activity feed for an event (see below)
Notifications are created automatically when the following actions occur:
- Recipient: the attendee being registered
- Type: "registration"
- Message: "You are registered for {talk title}"
- Reference: type="talk", id=talkId
- Recipient: the promoted attendee
- Type: "waitlist_promotion"
- Message: "You have been promoted from the waitlist for {talk title}"
- Reference: type="talk", id=talkId
- Recipients: all attendees registered for this talk
- Type: "talk_updated"
- Message: "The talk {talk title} has been updated"
- Reference: type="talk", id=talkId
- Only generate notifications if the talk's startTime, roomId, or title actually changed
- Recipient: the speaker (find the attendee with the same email as the speaker, if one exists at the same event)
- Type: "new_rating"
- Message: "Your talk {talk title} received a new rating"
- Reference: type="talk", id=talkId
- If no attendee exists with the speaker's email, skip (no notification)
GET /events/:id/activity returns a combined feed of recent actions across the event, ordered by time (newest first). Return format:
[
{
"type": "registration",
"message": "Charlie Brown registered for Keynote: Future of Tech",
"timestamp": "2025-06-15T08:30:00",
"talkId": 1,
"attendeeId": 1
},
{
"type": "rating",
"message": "Keynote: Future of Tech received a rating of 5",
"timestamp": "2025-06-15T18:00:00",
"talkId": 1
}
]The activity feed includes:
- All registrations for talks at this event
- All ratings for talks at this event
- All waitlist promotions for talks at this event
Limit to the 50 most recent entries.
- Do not modify any existing tests - all existing tests must continue to pass
- Notifications are fire-and-forget - if notification creation fails, the original action (registration, rating, etc.) should still succeed
- The activity feed is read-only and derived from notifications and other data
- Notification generation must not break existing endpoint behavior or response formats