# Submission confirmation email sent within 5 minutes with a status link

- **Pattern:** `ab-001082` (`directory-submissions-moderation.moderation.confirmation-email`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001082
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001082)

## Why it matters

When a submitter clicks submit and gets no email back, they assume the form dropped the request and either re-submit (creating duplicate moderation work) or abandon the directory entirely. Confirmation emails with a tracked submission ID and status link reduce duplicate submissions, cut support volume on "did you get my listing?" tickets, and give the business a legitimate re-engagement channel when the listing is approved. Absent confirmation also breaks CAN-SPAM and GDPR Article 13 transparency expectations around acknowledging data collection at the point of intake.

## Severity rationale

High because missing confirmation drives duplicate submissions, support load, and transparency gaps without directly exposing data.

## Remediation

In `app/api/listings/submit/route.ts`, generate a stable `submission_id` inside the same transaction that inserts the listing, then enqueue the confirmation email so the response is not blocked by SMTP latency. The email body must include the ID and a status URL the submitter can revisit:

```ts
await sendEmail({
  to: data.contactEmail,
  subject: 'Your listing submission has been received',
  html: `Submission ID: ${submissionId}<br><a href="https://yourdomain.com/submissions/${submissionId}/status">Check Status</a>`
})
```

Queue the send via a background job so the API returns within 500ms.

## Detection

- **ID:** `confirmation-email`
- **Severity:** `high`
- **What to look for:** After a submission is created, check whether a confirmation email is sent to the submitter. The email should contain: (1) a unique submission reference ID, (2) a link to check the status (approved/pending/rejected), (3) sent within 5 minutes. Look for email templates and background job logic.
- **Pass criteria:** Enumerate all relevant code paths. A confirmation email is sent to the submitter's email within 5 minutes of submission. The email includes a submission ID and a link to check the status (e.g., `/submissions/:id/status`). with at least 1 verified instance.
- **Fail criteria:** No confirmation email is sent, or the email is sent but lacks a status link, or the email takes longer than 5 minutes to arrive.
- **Skip (N/A) when:** The project has no email infrastructure.
- **Detail on fail:** `"Users receive no confirmation after submitting a listing. They don't know if the submission was received or when it will be reviewed."` or `"Email sent but contains no way to track the status."`
- **Remediation:** Send a confirmation email with a status link:

  ```ts
  // app/api/listings/submit/route.ts
  import { sendEmail } from '@/lib/email'
  import { v4 as uuidv4 } from 'uuid'

  export async function POST(req: Request) {
    const data = await req.json()

    const submissionId = uuidv4()
    const listing = await db.listings.create({
      data: { ...data, submission_id: submissionId, status: 'pending' }
    })

    // Send confirmation email
    await sendEmail({
      to: data.contactEmail,
      subject: 'Your listing submission has been received',
      html: `
        <p>Thank you for submitting your listing to our directory.</p>
        <p><strong>Submission ID:</strong> ${submissionId}</p>
        <p>Your listing is currently being reviewed by our team. You can check the status anytime:</p>
        <p><a href="https://yourdomain.com/submissions/${submissionId}/status">Check Status</a></p>
        <p>We'll send you an email once your listing is approved or if we need more information.</p>
      `
    })

    return Response.json({ id: listing.id }, { status: 201 })
  }
  ```

## External references

- gdpr Art. 13

Taxons: user-experience

HTML version: https://auditbuffet.com/patterns/ab-001082
