Skip to content

feat: ctrl email SSE and sidebar badge wiring #90

@ssilvius

Description

@ssilvius

Goal

Add SSE for email new message events and wire unread badges into the shell sidebar.

Requirements

  • GET /api/ctrl/email/stream SSE endpoint: polls D1 for new messages every 30s, emits {type: "new_message", threadId, messageId} events. Keepalive comment every 30s
  • apps/ctrl/src/lib/sse/email-sse.ts: SSE client with auto-reconnect (exponential backoff 1s-30s)
  • On new_message event: invalidate thread list query, update mailbox unread count in sidebar
  • Toast notification for new email
  • Desktop Notification API if tab backgrounded (with permission request)
  • Wire email unread count into shell sidebar badge (red dot + number from issue Structure API v1/v2 versioning with OpenAPI #6)
  • Wire team unread indicator into shell sidebar badge (blue dot)

Out of Scope

  • Push notifications
  • IMAP integration

Complete when: New emails trigger SSE event, sidebar badge updates, toast/desktop notifications fire.

Dev Workflow

Each step is mandatory. No exceptions. No skipping steps. No committing to main. No solo merges.

  1. Branch -- Create feat/<issue#>-<description> from main. Use git worktrees for parallel work.
  2. Implement -- Write the feature. Write tests alongside code. Run pnpm test, pnpm check (oxlint + oxc-format). All must pass.
  3. Commit -- Commit to the feature branch. Descriptive message focused on the "why."
  4. Simplify -- Run /simplify on all changed files. Accept structural improvements, flatten unnecessary abstractions, remove dead code. Commit the result.
  5. PR -- Create the PR. Reference this issue number.
  6. PR Review -- Run /review-pr which launches parallel review agents (code review, silent failure hunter, type design analysis). Fix every issue found. Re-run tests after fixes.
  7. Team Review -- Post PR to the legion bullpen. Get consensus from the team before merging.
  8. Request Merge -- Only after consensus. Never merge your own PR without review.

Platform Rules

  • No any -- use unknown and narrow
  • No emoji in code, comments, or commits
  • UUIDv7 for all identifiers
  • Zod is source of truth for schemas
  • Wrangler owns all D1 migrations (never drizzle-kit)
  • pnpm only (never npm/yarn)
  • Tests in tests/ mirroring source tree, never colocated

Done When

  • Feature branch created
  • All tests pass
  • Simplify pass completed and committed
  • PR created and linked to this issue
  • PR review completed and issues fixed
  • Team consensus on the bullpen
  • Merge requested (not self-merged)

Metadata

Metadata

Assignees

No one assigned

    Labels

    ctrlctrl dashboard surfaceenhancementNew feature or requestphase-5Dashboard home + notifications

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions