External API Integration¶
Toodle integrates with external services to support email communication, authentication, file storage, and academic scheduling.
The main transactional email integration uses Brevo. Additional services include Auth0 for authentication, Supabase Storage for user avatars, and the Wits academic calendar website for academic term information.
These integrations allow Toodle to use established external services while keeping its core business logic and REST API within the backend application.
Brevo Transactional Email¶
Overview and Motivation¶
Toodle uses Brevo (formerly Sendinblue) to send transactional emails through its external API.
Email communication is important because tutors, lecturers, administrators, and students may not always be signed into the application when an important event occurs.
Brevo supports communication relating to tutor allocations, timesheet reviews, applications, excusals, volunteering opportunities, and problem reporting.
It was selected for its REST API, official Node.js SDK, and suitability for integration with the existing Express backend.
The integration uses the @getbrevo/brevo package, with API credentials stored in the backend environment.
Integration Architecture¶
Toodle combines in-app notifications with external email communication.
For most application workflows, the business operation is completed before notification processing is initiated. Notification processing then attempts to create an in-app record, send an email through Brevo, and update the email delivery status.
Most business services initiate this process asynchronously without waiting for it to complete.
sequenceDiagram
autonumber
actor User
participant API as Express API
participant DB as PostgreSQL
participant Notify as Notification Service
participant Brevo as Brevo API
User->>API: Submit business action
API->>DB: Process and commit changes
DB-->>API: Operation completed
API-)Notify: Initiate notification
API-->>User: Business response
Note over Notify: Notification work runs asynchronously
Notify->>DB: Attempt notification insert
Notify->>Brevo: Send transactional email
Brevo-->>Notify: Acceptance or error
Notify->>DB: Update email status if possible
This diagram illustrates the common notification flow. Some workflows behave differently: session swaps create in-app notifications within their business transaction, automated reminders await notification processing, and problem reports wait for the email result before responding.
Notification processing runs within the backend process rather than through a separate durable message queue.
Notification Events¶
Toodle generates notifications for several important system activities.
| Workflow | Notification events | Recipients |
|---|---|---|
| Tutor Allocation | Assignment, changes, and removal | Affected tutors |
| Timesheets | Submission, approval, and disputes | Course reviewers or tutors |
| Course Applications | Submission and review outcomes | Course reviewers or applicants |
| Excusals | Requests and decisions | Course reviewers or tutors |
| Overflow Opportunities | New posts, claims, and outcomes | Students, reviewers, or claimants |
| Session Swaps | Requests, responses, reviews, and reversals | Relevant participants and reviewers |
| Automated Reminders | Pending actions and deadlines | Responsible users |
| Problem Reports | User-submitted problems | Configured issues inbox |
Course reviewers consist of administrators and the coordinators assigned to the relevant course, with duplicate recipients removed.
Most of these workflows support in-app and email notifications, although some events are in-app only. For example, approved dated session-cover claims generate in-app notifications, while swap approvals also trigger emails to participating tutors.
New overflow opportunities are broadcast to users holding the STUDENT role rather than being pre-filtered to eligible volunteers.
Email Delivery and Failure Handling¶
Toodle records email outcomes to distinguish successful provider requests from failed or unavailable delivery attempts.
| Status | Meaning |
|---|---|
SENT |
Brevo accepted the email request |
FAILED |
The email request failed or could not be sent |
SKIPPED |
Brevo is not configured |
A SENT status does not guarantee that the email reached the recipient's inbox. The current integration does not implement delivery-confirmation webhooks.
For ordinary notifications, an email failure does not automatically reverse the completed business action. Existing in-app notifications remain available when email sending fails.
Notification recording is best-effort, and errors are logged when status updates cannot be stored.
Automated Reminder Deduplication¶
The reminder service uses a unique notification key to reduce duplicate reminder attempts.
When a reminder with the same key already exists, another email attempt is suppressed.
Failed notification creation can be retried during a later reminder run. However, an email that fails after successful notification creation is not automatically retried.
This prevents many duplicate reminder attempts without guaranteeing successful delivery.
In-App Problem Reporting¶
Toodle provides an in-app problem reporting feature that sends reports to a configured development-team inbox through Brevo.
The backend endpoint is:
POST /api/v1/problem-reports
The endpoint requires an authenticated user with a local account and validates incoming request data using Zod.
Reports include relevant information such as the affected page, problem description, and whether the issue is blocking the user's work.
Unlike ordinary notifications, problem reporting waits for the email provider's response.
| Result | API Response |
|---|---|
| Brevo accepts the report | 201 Created |
| Email sending fails or is unavailable | 503 Service Unavailable |
Problem reports are not stored as separate database records before email submission. If delivery fails, the frontend retains the entered report and offers an email fallback.
The report is subsequently handled through the team's bug-tracking process.
Security and Configuration¶
The Brevo integration is configured entirely within the backend. The frontend communicates with the Toodle API and does not access Brevo credentials directly.
The relevant environment variables are:
| Variable | Purpose |
|---|---|
BREVO_API_KEY |
Authenticates requests to Brevo |
BREVO_FROM_EMAIL |
Configures the email sender address |
ISSUES_EMAIL |
Identifies the problem-report recipient inbox |
Email templates use HTML escaping for several user-provided fields, including problem descriptions and application information.
However, escaping is not yet applied consistently across every dynamic email field. This remains an implementation limitation that should be addressed to strengthen email-content security.
Automated Testing¶
The email integration is covered by automated tests using Vitest, with Brevo calls mocked to avoid sending real emails during testing.
The tests cover areas including:
- Notification recipients and email templates.
- Email delivery statuses and failure handling.
- Missing Brevo configuration.
- Problem-report success and failure responses.
- Reminder scheduling and duplicate prevention.
- Frontend notification and problem-report behaviour.
Mocked provider tests verify application behaviour but do not establish successful real-world email delivery.
Other External Integrations¶
Auth0¶
Auth0 provides the application's authentication service.
The frontend uses the Auth0 React SDK for user sign-in, while the backend verifies authentication tokens and associates authenticated identities with local user accounts.
Application roles and permissions remain managed by Toodle.
Supabase Storage¶
Supabase Storage provides external object storage for user avatars.
The backend uses the Supabase SDK to upload, retrieve public URLs for, and remove avatar files.
Storage operations depend on valid service configuration. The frontend does not communicate directly with the Supabase database.
Wits Academic Calendar¶
Toodle retrieves academic term information from the University of the Witwatersrand website.
The backend fetches and parses the relevant HTML using Cheerio. Administrators can preview retrieved academic information before committing it.
This is an external website integration rather than a structured third-party API.
Calendar Subscription Feed¶
Toodle provides an in-app calendar and a read-only iCalendar (.ics) subscription feed.
Users can subscribe to the feed through compatible calendar applications, including Google Calendar, Outlook, and Apple Calendar.
The feed uses a revocable token-based URL. Toodle stores a hash of the token and supports rotation and revocation.
Calendar applications retrieve information from Toodle's feed; the application does not make outbound Google Calendar API requests.
Integration Summary¶
External integrations extend Toodle's capabilities while the Express backend remains responsible for the application's business rules, validation, and authorisation.
Brevo provides transactional email communication, Auth0 handles authentication, Supabase supports file storage, and academic calendar integrations provide scheduling information.
The implemented integrations support the project's functional requirements while maintaining separation between internal application logic and external services.