Skip to content

Notifications — Views

Overview

The notifications.views package exposes the HTTP API for the notifications app.

These views provide endpoints for:

  • reading notifications
  • grouping and listing inbox items
  • counting unread notifications
  • marking notifications as read
  • clearing notifications
  • registering and managing push devices
  • exposing notification registry metadata

The view layer should remain thin.

Its responsibilities are to:

  • validate request input
  • read query parameters
  • call serializers and services
  • paginate results
  • return HTTP responses

Business logic belongs in services, not in views.


Responsibilities

The view layer is responsible for:

  • request/response handling
  • applying authentication and org scoping
  • serializer-based validation
  • pagination
  • mapping service results to API responses

It is not responsible for:

  • notification creation rules
  • delivery processing
  • retry logic
  • provider interaction
  • preference resolution
  • deduplication logic

View modules

notifications.py

Read-only notification feed endpoints.

Main endpoints:

  • UnreadCountView
  • MyNotificationsView
  • NotificationUngroupedView

Responsibilities:

  • return unread notification counts
  • expose the primary notification feed
  • support collapsed and uncollapsed views
  • support incremental sync via after
  • paginate response data

This module is the main read surface for the user notification inbox.


actions.py

Mutation endpoints for existing notifications.

Main endpoints:

  • ClearReadNotificationsView
  • ClearNotificationView
  • ClearNotificationGroupView
  • MarkNotificationReadView
  • MarkAllReadView
  • BulkMarkReadView

Responsibilities:

  • mark notifications read
  • clear notifications via soft-delete
  • apply bulk read updates
  • scope all mutations to current user and current org

These endpoints mutate inbox state only. They do not create notifications.


push_devices.py

Push device registration and lifecycle endpoints.

Main endpoints:

  • UpsertPushDeviceView
  • DeactivatePushDeviceView
  • PingPushDeviceView

Responsibilities:

  • register or update push tokens
  • deactivate tokens
  • keep last_seen_at fresh for active devices

These endpoints support mobile/device integration for push delivery.


registry.py

Read-only registry metadata endpoint.

Main endpoint:

  • NotificationRegistryMetaView

Responsibilities:

  • expose notification type metadata to clients
  • return normalized notification rule definitions
  • provide a stable version hash for caching

This endpoint allows frontend clients to build notification settings UIs from backend-owned definitions.


Common permissions

Most notifications endpoints use:

  • IsAuthenticated
  • HasCurrentOrg

This ensures:

  • the user is authenticated
  • the request is scoped to a valid org
  • cross-org access is prevented

Exception:

  • registry metadata is global and may not require org context if it is org-agnostic

Main read flows

Unread count flow

  1. Validate authentication and org context
  2. Query unread + non-deleted notifications for the current user
  3. Return:
  4. {"count": <int>}

Notification feed flow

  1. Parse query params such as:
  2. after
  3. collapsed
  4. Build notification query via service layer
  5. Paginate results
  6. Serialize response
  7. Return paginated payload

The feed supports both:

  • flat notification rows
  • grouped/collapsed rows

Ungrouped feed flow

  1. Parse after
  2. Query only rows with empty group_key
  3. Paginate
  4. Serialize and return

This is useful for standalone notification sections.


Main mutation flows

Mark read

  • single-notification read
  • bulk read
  • mark-all-read

These operations update:

  • read_at
  • updated_at

Clear notifications

Clearing a notification means:

  • set deleted_at
  • keep the row in the database

This is soft deletion, not hard deletion.

Read endpoints always exclude cleared rows.


Push device flows

Upsert device

  • validate provider/token payload
  • associate token with current user/org
  • reactivate device
  • update last_seen_at

Deactivate device

  • scope by provider, token, user, org
  • mark is_active=False

Ping device

  • lightweight heartbeat
  • updates last_seen_at
  • keeps device active
  • optionally refreshes device_info

Registry metadata flow

  1. Read server-side notification registry
  2. Normalize each rule into a client-safe shape
  3. Build deterministic version hash
  4. Return:
  5. version
  6. rules

This allows aggressive frontend caching and dynamic settings screens.


Pagination

Notification list endpoints use NotificationPagination.

This supports:

  • consistent page sizing
  • stable response shape
  • paginated flat feeds
  • paginated collapsed/grouped feeds

Pagination is especially important for grouped views where the response items are not direct model rows.


Parsing helpers

The views use small utility helpers for request parsing.

Examples:

  • parsing after timestamps
  • interpreting collapsed mode flags

These utilities keep view methods smaller and easier to read.


Relationship to services

Views should call services for:

  • mutation logic
  • read-model query logic
  • push device lifecycle
  • notification state changes

Typical pattern:

  1. view validates request
  2. service performs business logic
  3. serializer shapes output
  4. view returns response

flowchart TD
    A[HTTP Request] --> B[View]
    B --> C[Serializer / parsing]
    C --> D[Service]
    D --> E[Models]
    D --> F[Providers or tasks if needed]
    E --> G[Serializer output]
    G --> H[HTTP Response]

What views do not do

Views do not:

  • create notifications directly
  • resolve notification preferences
  • compute retry backoff
  • send push notifications directly
  • talk to Expo or other providers directly
  • decide deduplication or targeting rules

Those responsibilities belong to:

  • services
  • tasks
  • providers

Design principles

Thin controllers

Views should be small and explicit.

Strong scoping

All user-facing notification operations must be scoped by:

  • request.user
  • request.org

Clear transport contract

Serializers define response and request payload shape.

Service-first behavior

If view logic starts growing beyond request handling, it should move into services.


Best practices

  • always use HasCurrentOrg for org-scoped endpoints
  • keep mutations in services, not view methods
  • use serializers for request validation
  • keep grouped feed logic out of views when possible
  • soft-delete notifications instead of hard deleting in endpoints
  • paginate all inbox-style list endpoints

Summary

The notifications.views package provides the API surface for the notifications system.

It ensures clients can:

  • read inbox notifications
  • mutate read/clear state
  • manage push devices
  • inspect registry metadata

while keeping business logic in services and delivery logic in tasks/providers.