Skip to main content

Milestone 17: Add-ons (post–first launch)

Purpose: Optional post-launch features: SSO (SAML/OIDC), Gmail Push, Microsoft Graph change notifications, and advanced reporting refinements.

Exit state: Each add-on implemented and gated by entitlement where applicable; or explicitly deferred with doc reference.

Spec reference: §2.5 SSO, §2.2 Inbox Management (aliases), §5.21b InboxAlias, §8.3 Gmail Push, §8.4 Microsoft Graph change notifications, §2.12 Advanced reporting.

Prerequisites: M16 (launch-ready). These are optional; order can be adjusted.


17.1 SSO (SAML / OIDC)

Tasks

  1. Entitlement

    • Gated by sso entitlement (Enterprise). Section 2.5.
  2. IdP configuration

    • Settings → SSO (Enterprise only): form for IdP metadata URL or XML upload; attribute mapping (email, name, subject id). Store config per tenant (encrypted or in dedicated table). Section 6.10.
  3. Sign-in

    • Login page: "Sign in with SSO" when tenant has SSO enabled (detect by email domain or tenant selection). Redirect to IdP; after callback, validate response; link or create user by email/subject; create session; redirect to app. Section 2.5. Use library (e.g. SAML2, OIDC client).
  4. Linking

    • Existing users: match by email or subject id; add session. New users: create user and tenant membership from IdP attributes (if allowed by product).

Acceptance criteria

CriterionStatus
Admin can configure SSO in Settings (Enterprise); sign-in with SSO works for configured tenant.Pending
Existing users linked by email; new users created or blocked per product decision.Pending
SSO gated by sso entitlement.Pending

17.2 Gmail Push (Pub/Sub)

Tasks

  1. Infrastructure

  2. Watch registration

    • When Gmail inbox connected (or re-auth): call users.watch() via Gmail API; store expiration in inboxes.gmail_watch_expires_at. Section 8.3, 5.4.
  3. Push endpoint

    • POST /api/webhooks/gmail-push: verify Pub/Sub JWT; parse message (historyId, emailAddress); find inbox by email; enqueue Inngest "fetch messages" for that inbox. Section 8.3.
  4. Renewal cron

    • Daily: find inboxes where gmail_watch_expires_at < now() + 24h; call users.watch() again; update gmail_watch_expires_at. Section 4.8, 8.3.

Acceptance criteria

CriterionStatus
New mail to Gmail inbox triggers push; worker fetches promptly; latency < 30s when push active.Pending
Watch renewal cron runs; expiry updated; fallback polling still works if push lapses.Pending
Optional: can ship without push (polling only) and add in M17.Pending

17.3 Microsoft Graph change notifications

Tasks

  1. Subscription

    • When Microsoft inbox connected: POST /subscriptions (resource me/mailFolders('Inbox')/messages, changeType created); notificationUrl = https://<app>/api/webhooks/graph-push; store subscription id and expiration in inboxes. Section 8.4, 5.4.
  2. Push endpoint

    • POST /api/webhooks/graph-push: if validationToken query param, return it as text/plain (handshake). Else validate client state; parse notification; enqueue Inngest "fetch messages" for inbox. Section 8.4.
  3. Renewal cron

    • Every 12 hours: find inboxes where graph_subscription_expires_at < now() + 24h; PATCH /subscriptions/{id} to renew; update graph_subscription_expires_at. Section 4.8, 8.4.

Acceptance criteria

CriterionStatus
New mail to Graph inbox triggers notification; worker fetches; latency < 30s when subscription active.Pending
Validation handshake and renewal work; fallback polling when subscription expires.Pending
Optional: can ship with polling only and add in M17.Pending

17.4 Inbox aliases (optional)

Purpose: Multiple addresses per inbox (e.g. support@ and help@ map to same inbox); inbound matching and reply-from. Deferred from M05; post-launch or M17.

Tasks

  1. Schema and CRUD

    • Table inbox_aliases (or equivalent per Section 5.21b): inbox_id, alias_email, tenant_id; unique (tenant_id, alias_email). Settings → Inboxes → [inbox] → Aliases tab: add/remove alias addresses; validate format and uniqueness.
  2. Inbound matching

    • When creating ticket from inbound (M06): match To/Cc/Bcc against inbox email_address and any inbox_aliases for that inbox; assign ticket to that inbox. Section 2.2.
  3. Reply-from

    • When sending reply: allow choosing From (primary or alias) if inbox has aliases; set Reply-To or From per provider (IMAP/SMTP, Gmail, Graph). Section 2.2.

Acceptance criteria

CriterionStatus
Admin can add/remove alias addresses per inbox; inbound to alias creates ticket in that inbox.Pending
Reply can be sent from primary or alias where supported.Pending
Optional: can remain in post-launch backlog; no milestone dependency.Pending

17.5 Advanced reporting refinements

Tasks

  1. Scope

    • Per Section 2.12, advanced reporting includes SLA compliance, tag distribution, workload, CSV export — already in M13. M17 can add: additional metrics, custom date ranges, scheduled reports, or extra visualizations. Define scope (e.g. "Scheduled email report" or "Custom dashboard") and implement if needed.
  2. Documentation

    • If deferred: document in product backlog with Section 2.12 reference; no code change in M17.

Acceptance criteria

CriterionStatus
Any new reporting features implemented and gated by advanced_reports; or scope documented and deferred.Pending
Milestone 17 sign-off: add-ons done or explicitly deferred.Pending
Implementation plan complete; product launch-ready.Pending

Milestone 17 sign-off

CriterionStatus
SSO and/or Gmail Push and/or Graph notifications implemented per product priority; or explicitly deferred with doc.Pending
Inbox aliases: implemented (17.4) or explicitly in post-launch backlog.Pending
Advanced reporting scope clear; implemented or backlogged.Pending
E2E: Add-on flows if implemented (SSO, Gmail/Graph connect; see INDEX — Testing strategy).Pending
All 17 milestones documented; implementation plan complete.Pending