Skip to main content

Milestone 11: SLA and business hours

Purpose: Admins configure SLA policies and business hours; tickets show SLA status; breach and near-breach trigger notifications.

Exit state: SLA CRUD (policy + business hours); SLA status on ticket (on track / due soon / breached); SLA cron for notifications.

Spec reference: §2.4 SLA, Business hours, §4.8 SLA checks, §5.10 SlaPolicy, §5.21 BusinessHours, §6.10 settings/sla, §10.7 SLA lifecycle.

Prerequisites: M10 (Billing). Notifications (M08) for breach emails.


11.1 SLA policies and business hours

Tasks

  1. SLA policies CRUD

    • tRPC: list, create, update, delete. sla_policies: tenant_id, inbox_id (nullable = all inboxes), name, first_response_hours, resolution_hours, business_hours_only. Section 5.10.
    • Settings → SLA: list policies (name, targets, inbox assignment); "New policy" form (name, first response hours, resolution hours, inbox or "All inboxes", business hours only toggle). Edit/delete with confirm. Section 6.10.
  2. Business hours

    • business_hours table: tenant_id, timezone, monday_start/end through sunday_start/end (time or null = closed). One row per tenant. Section 5.21. Default when missing: e.g. Mon–Fri 09:00–17:00 Europe/Berlin (Section 5.21). tRPC get/upsert for tenant.
    • Settings → SLA: Business hours section — timezone select, per-day rows with "Open" toggle and start/end time pickers. Section 6.10.
  3. Assign policy to ticket

    • When creating ticket (from email or manual): assign sla_policy_id from inbox (policy for that inbox_id or tenant-wide null inbox_id). Optional: allow manual override in ticket edit. Section 5.5.

Acceptance criteria

CriterionStatus
Admin can create and edit SLA policies and business hours; policies can be per-inbox or global.Pending
New tickets get policy from inbox or default; business hours default when no row.Pending

11.2 SLA status computation

Tasks

  1. First response target

    • Policy first_response_hours; ticket first_response_at null → deadline = created_at + first_response_hours (in business hours if business_hours_only). Elapsed = now - created_at (business-hours count only if policy.business_hours_only). Status: breached if elapsed > target and first_response_at null; due_soon if within 20% of target; on_track else.
  2. Resolution target

    • Policy resolution_hours; ticket resolved_at null → deadline = created_at + resolution_hours (business hours). Elapsed same. Status: breached if elapsed > target and resolved_at null; due_soon; on_track. When status = waiting, pause SLA clock (do not count waiting time toward target). Section 2.4.
  3. Helper

    • Function: computeSlaStatus(ticket, policy, businessHours) → returns { firstResponse: 'on_track'|'due_soon'|'breached', resolution: same }. Use in API and cron.
  4. Display on ticket

    • Ticket sidebar or header: show SLA status (e.g. "First response: on track", "Resolution: due in 2h" or "Breached"). Section 6.5.

Acceptance criteria

CriterionStatus
SLA status correct for business-hours and calendar-hours policies; waiting status pauses clock.Pending
Ticket detail shows current SLA status; updates when ticket or time changes.Pending
SLA status and breach state on ticket reflected in real time when cron or status changes (SSE: ticket.updated triggers refetch; Section 4.11).Pending

11.3 SLA cron and notifications

Tasks

  1. Cron (periodic)

    • Inngest cron: e.g. every 15 min. Query tickets with sla_policy_id not null, status not in (resolved, closed). For each, compute SLA status; if first_response or resolution = breached (or due_soon per product), create notification for assignee and tenant admins (type sla_breach or sla_due_soon); send email if preference allows. Section 4.8, 2.10.
    • Idempotent: do not spam; e.g. one notification per ticket per breach event (store last_notified_at or event id).
  2. Templates

    • sla-breach email (already in M08): ticket_number, ticket_subject, sla_type, breached_at, ticket_url. Section 2.10b.

Acceptance criteria

CriterionStatus
Cron runs; breached (and optionally due_soon) tickets trigger in-app and email notifications.Pending
No duplicate notifications for same breach; assignee and admins notified.Pending

Milestone 11 sign-off

CriterionStatus
All tasks in 11.1–11.3 complete.Pending
All acceptance criteria met.Pending
SLA and business hours configurable; ticket shows status; breach notifications work.Pending
E2E: SLA config and ticket status/breach UI (see INDEX — Testing strategy).Pending
Ready for M12 (Search).Pending