Skip to content

Accounts — tasks

Responsibilities

The accounts tasks contain asynchronous background jobs related to account and onboarding communication.

They are responsible for:

  • sending invite emails
  • sending password reset emails
  • retrying transient email-delivery failures
  • rendering email templates with the correct context

They are not responsible for:

  • deciding whether a workflow should happen
  • validating request payloads
  • changing invite/auth business rules
  • handling HTTP requests
  • storing long-running domain state

In this app, tasks are the asynchronous delivery layer for account-related notifications.


Main tasks

send_invite_email

Sends an invite email for an existing Invite.

  • Inputs
  • invite_id
  • Behavior
  • loads the Invite and related organization
  • builds the frontend invite link using FRONTEND_INVITE_URL
  • prepares template context
  • renders text and HTML email templates
  • sends the email via Django email backend
  • Templates
  • emails/invite.txt
  • emails/invite.html
  • Settings used
  • FRONTEND_INVITE_URL
  • APP_NAME
  • DEFAULT_FROM_EMAIL
  • Return value
  • dictionary containing the recipient email
  • Retry behavior
  • retries automatically on exception
  • exponential backoff enabled
  • maximum retries: 5

This task is triggered after invite creation and invite resend flows.

Context passed to templates

  • app_name
  • org_name
  • role
  • invite_type
  • invite_link

send_password_reset_email

Sends a password reset email for an existing user.

  • Inputs
  • user_id
  • uid
  • token
  • Behavior
  • loads the target user
  • builds the frontend reset link using FRONTEND_PASSWORD_RESET_URL
  • prepares template context
  • renders text and HTML email templates
  • sends the email via Django email backend
  • Templates
  • emails/password_reset.txt
  • emails/password_reset.html
  • Settings used
  • FRONTEND_PASSWORD_RESET_URL
  • APP_NAME
  • DEFAULT_FROM_EMAIL
  • Return value
  • dictionary containing the recipient email
  • Retry behavior
  • retries automatically on exception
  • exponential backoff enabled
  • maximum retries: 5

This task is triggered by the forgot-password flow after the account has been resolved and reset credentials have been generated.

Context passed to templates

  • app_name
  • user
  • reset_link

Task relationship overview

flowchart TD
    InviteService["services.invite.create_invite / resend_invite"]
    AuthService["services.auth.issue_password_reset"]

    SendInviteTask["send_invite_email"]
    SendResetTask["send_password_reset_email"]

    Invite["Invite"]
    User["User"]
    EmailTemplates["Email templates"]
    MailBackend["Django email backend"]

    InviteService --> SendInviteTask
    AuthService --> SendResetTask

    SendInviteTask --> Invite
    SendInviteTask --> EmailTemplates
    SendInviteTask --> MailBackend

    SendResetTask --> User
    SendResetTask --> EmailTemplates
    SendResetTask --> MailBackend

Delivery flow examples

Invite email flow

sequenceDiagram
    participant View as InviteListCreateView / ResendInviteView
    participant Service as services.invite
    participant Task as send_invite_email
    participant Invite as Invite
    participant Mail as Email backend

    View->>Service: create_invite(...) / resend_invite(...)
    Service->>Task: delay(invite.id)
    Task->>Invite: load invite + org
    Task->>Task: render templates
    Task->>Mail: send email
    Mail-->>Task: delivery result

Password reset email flow

sequenceDiagram
    participant View as ForgotPasswordView
    participant Service as services.auth.issue_password_reset
    participant Task as send_password_reset_email
    participant User as User
    participant Mail as Email backend

    View->>Service: issue_password_reset(email)
    Service->>Task: delay(user.id, uid, token)
    Task->>User: load user
    Task->>Task: render templates
    Task->>Mail: send email
    Mail-->>Task: delivery result

Retry strategy

Both tasks are configured as Celery shared tasks with automatic retries.

Configuration • bind=True • autoretry_for=(Exception,) • retry_backoff=True • retry_kwargs={"max_retries": 5}

Meaning • any uncaught exception triggers a retry • backoff increases between attempts • retries stop after five attempts

This makes email delivery more resilient to temporary SMTP/network issues without complicating the service layer.

⸻

Template expectations

Invite templates

The invite templates should: • explain that the recipient has been invited • identify the organization • mention the intended role if relevant • include the invite link • avoid exposing unnecessary internal system details

Password reset templates

The reset templates should: • explain that a password reset was requested • include the reset link • make clear that ignoring the email is safe if the request was not intended

Because the tasks only render and send, the templates should remain presentation-focused and should not encode business logic.