Skip to content

Notifications

Carbon Connect provides both email notifications (via AWS SES) and in-app notifications (database-backed).


Email Service

Source: backend/app/services/email_service.py

Overview

The email service sends transactional emails using AWS Simple Email Service (SES). It supports template-based rendering with HTML and plain-text variants.

Features

  • AWS SES integration for reliable email delivery
  • Template system with HTML and plain-text variants
  • Batch sending for notifications to multiple recipients
  • Rate limiting via Celery queue (30 emails/minute)
  • Retry logic with exponential backoff (up to 30 minutes, 5 retries)
  • SMTP fallback for development environments

Email Templates

The service includes templates for common notification types:

Template Trigger Description
welcome User registration Welcome email with getting started guide
deadline_approaching Hourly check Alert for grants with deadlines within 14 days
new_match Match calculation Notification of new high-scoring matches
application_status Status change Application status update (submitted, approved, rejected)
password_reset User request Password reset link

Usage

from backend.app.services.email_service import EmailService, get_email_service

email_service = get_email_service()

# Send a single email
await email_service.send_email(
    to="user@example.com",
    subject="New Grant Match Found",
    template="new_match",
    context={
        "user_name": "John",
        "grant_title": "Horizon Europe Clean Energy",
        "match_score": 0.85,
    },
)

# Send batch notifications
await email_service.send_batch(
    recipients=["user1@example.com", "user2@example.com"],
    subject="Deadline Approaching",
    template="deadline_approaching",
    context={"grant_title": "ERDF Energy Efficiency"},
)

Configuration

Environment Variable Description Default
AWS_SES_REGION SES region eu-north-1
EMAIL_FROM_ADDRESS Sender email Required
EMAIL_FROM_NAME Sender display name Carbon Connect

Notification Service

Source: backend/app/services/notification_service.py

Overview

The in-app notification service manages user notifications stored in the database. Notifications appear in the dashboard and can be marked as read or dismissed.

Notification Model

Field Type Description
id UUID Primary key
user_id UUID Recipient user
tenant_id UUID Tenant scope
type String Notification type (e.g., new_match, deadline, system)
title String Notification title
message String Notification body
data JSONB Additional structured data
read Boolean Whether the notification has been read
read_at DateTime When the notification was read
created_at DateTime Creation timestamp

Notification Types

Type Description
new_match A new high-scoring grant match was found
deadline_approaching A saved or matched grant has an approaching deadline
application_status An application status changed
match_refresh Match scores were recalculated
system System announcement or maintenance notice

Usage

from backend.app.services.notification_service import NotificationService

service = NotificationService(db_session)

# Create a notification
await service.create_notification(
    user_id=user.id,
    tenant_id=user.tenant_id,
    type="new_match",
    title="New Grant Match",
    message="A new grant matching your profile was found.",
    data={"grant_id": str(grant.id), "score": 0.85},
)

# Get unread notifications
notifications = await service.get_unread(user_id=user.id)

# Mark as read
await service.mark_read(notification_id=notification.id)

# Mark all as read
await service.mark_all_read(user_id=user.id)

API Endpoints

Method Endpoint Description
GET /api/v1/notifications List notifications (paginated)
PATCH /api/v1/notifications/{id}/read Mark as read
POST /api/v1/notifications/read-all Mark all as read

Celery Integration

Email and notification tasks are routed to the email queue:

Task Schedule Queue
check_deadline_notifications Every hour at :30 email
check_approaching_deadlines Every hour at :00 email
send_deadline_notifications Triggered by checks email

Rate limit: 30 emails per minute to avoid spam filter issues.

flowchart TB
    A[Celery Beat<br/>Hourly Check] --> B[Check Deadlines]
    B --> C{Approaching<br/>Deadlines?}
    C -->|Yes| D[Create Notifications]
    D --> E[Send Emails<br/>via SES]
    C -->|No| F[Skip]