# Developer D — Engagement, Tenants & Analytics

**Scope:** the `engagement` and `analytics` databases. Everything users *experience around*
learning: the notification platform, marketing, support, forums/groups/live sessions,
gamification config, the affiliate portal runtime, the four B2B tenant portals (corporate,
CSR, organization, sponsor), institute portal, webhooks/API dispatch, and all
dashboards/analytics/reporting/monitoring.
**Depends on Track A for:** auth, tenant accounts + `TenantGate`, billing events, API-key admin.
**Depends on Track B for:** `CatalogService` (campaign targeting, content references).
**Depends on Track C for:** `ProgressService`, learning events (analytics sources).
**No track depends on D's implementation** — D is the sink. (Others depend only on D's
`NotificationService` interface, shipped in T-D-01.)

Legend: `DEPS:` = hard dependency (must be DONE). `DEPS⚡:` = contract-only.

---

## PHASE 0 — Engagement Foundations

### T-D-01 · Notification platform (interface for all tracks)
- `App\Services\Engagement\NotificationService` (interface — **contract A/B/C already
  compile against**): `notify(userId, category, payload)`, `critical(userId, ...)`.
- `notifications` table (engagement): user, category, critical flag, channels, read state,
  deep link, payload; `notification_preferences` (per-category toggles, per-channel
  in-app/email/push/SMS, quiet hours, digest time, real-time vs digest).
- **Critical alerts (security, assessment results, subscription, maintenance) can never be
  muted/batched — always real-time on all enabled channels.** Preferences apply to new
  notifications only. SMS only with verified phone; push only with registered token.
- Dispatcher: consumes `NotificationRequested` events + direct calls; channel adapters
  (in-app = table, email/SMS = adapter interface with test doubles); retry/fallback per
  system settings (A, DEPS⚡ T-A-23); digests bundle only non-critical.
- `GET /notifications` (unread count), mark-read/all-read/delete/clear,
  `GET/PUT /notification/preferences`, `POST /push-token`.
- **DEPS:** T-A-01, T-A-06, T-A-05
- **AC:** critical notification delivered even when category muted (test); quiet hours hold
  non-critical only (test); digest contains only non-critical (test); unread count correct
  across channels (test); A/B/C feature tests can inject the interface (already true in Phase 0).

### T-D-02 · `analytics` DB conventions + event ingestion
- `BaseAnalyticsModel` ($connection = 'analytics'); migration folder `database/migrations/analytics/`.
- **Analytics is write-once:** ingestion ONLY via queued jobs consuming A/B/C domain events
  (README event contracts). Transactional domains never read analytics; consumers of
  aggregates are D's read endpoints.
- `event_ingestion` tables per event family + idempotent upsert by (event_id) — duplicate
  delivery = no-op (test).
- 15-min freshness SLA where specified (dashboard reads serve last-computed aggregate +
  `as_of` timestamp).
- **DEPS:** T-A-01, T-A-06
- **AC:** ingestion job for each of the 15 contract events; duplicate event idempotent (test);
  no transactional-domain code path reads `analytics` connection (lint/test); every read
  endpoint returns `as_of`.

### T-D-03 · Engagement base model + `GamificationConfigService`
- `BaseEngagementModel` ($connection = 'engagement'); models in `app/Models/Engagement/`.
- `GamificationConfigService` (contract C consumes, DEPS⚡ T-C-07): point rules, badge
  criteria, leaderboard settings, challenge definitions — real CRUD in T-D-08.
- **DEPS:** T-A-01
- **AC:** connection lock test; C can inject `GamificationConfigService` via mock.

### T-D-04 · Live sessions (scheduling + runtime + recordings)
- `live_sessions`: type (class/doubt-clearing/webinar), teacher, course, start/duration,
  status (scheduled/active/completed/cancelled), recurring (end date/count), access scope;
  config: Q&A (off/teacher-moderated/anonymous), whiteboard (request-to-draw), recording
  on/off + retention, max group size.
- Rules: **no past-dated sessions; no teacher double-booking (conflict flagged before save,
  409)**; cancellation notifies all enrolled (never silent); group size enforced; empty
  session flagged; full office-hours slot rejects joins.
- `enrollments`/attendance (attended/missed/late — **no-shows ≠ late joiners**), chat
  (moderated per session rules), Q&A (upvotes, ranked; unanswered → doubt list),
  polls/in-session quiz (live results), whiteboard (instructor-controlled; student
  annotation only where enabled; saved with session), breakout rooms, materials
  (retained post-session), recordings (resume position, retention sweep, replacement
  preserves original until confirmed, access per enrollment), feedback (once per session,
  anonymous to instructor).
- Doubt bookings: 1-on-1/group/office-hours slots; **plan entitlement caps bookings**
  (blocked with reason via A's `SubscriptionService`, DEPS⚡ T-A-17); AI resolution above
  confidence threshold not escalated; student can always request human; escalation carries
  context.
- Webinars: external expert access scoped to session only; targeting by grade/exam type.
- Session analytics (attendance rate, engagement composite, watch time, completion,
  re-watches, quality score) → `analytics`.
- **DEPS:** T-D-01, DEPS⚡ T-A-17, DEPS⚡ T-B-05
- **AC:** double-booked teacher → 409 (test); cancellation → enrolled users notified
  (test); entitlement-exceeded booking → 409 with reason (test); late-join admitted
  mid-session (test); recording retention sweep expires planted recording (test);
  feedback once-per-session enforced (test).

### T-D-05 · Forums, study groups, peer Q&A, moderation
- `forums` (active/paused/archived), `threads` (lock/move/remove; pins ordered, expiry,
  auto-unpin), `posts` (own-post edit/delete only; moderation state pending/approved/
  removed), follows (reply → author notification; followed thread → reply notification).
- `study_groups`: status pending → approved/active | rejected (min/max size; pending not
  joinable; rejection notifies with reason); chat moderation (filter/mute/remove);
  resources (size/type limits, group-only vs public); group sessions (attendance,
  cancellable).
- Peer Q&A: pre-post approval mode (invisible until approved), merge (canonical redirect),
  remove with reason; problems (solved only when solution accepted; helpful marks).
- Community reputation (valid contributions only; decay on inactivity; level-gated
  privileges); upvotes (one per user, no self-vote, burst voting flagged).
- Moderation: reports (content/user) → review → action/dismiss (reason) → close; outcome
  communicated to reporter; appeal where allowed; **moderation log immutable — overturn is
  a new referencing entry**; search config (visibility, weights, recency tie-break;
  archived excluded by default).
- Subscribes to A's `POST /moderation/reports` intake (T-B-09) for cross-surface content.
- **DEPS:** T-D-01, T-D-03
- **AC:** pre-post mode: unapproved post invisible to others (test); merge redirects (test);
  self-vote rejected (test); group at max size rejects join (test); moderation overturn
  creates referencing entry (log intact, test); forum tier gating per subscription (test).

---

## PHASE 1 — Support, Marketing, Gamification

### T-D-06 · Customer support (tickets, chat, knowledge base)
- `tickets`: channel (email/chat/phone), priority (low/medium/high/urgent), status open →
  pending → resolved; assignment (priority-based routing rules; agent load considered);
  **SLA per ticket (deadline; met/at-risk/breached, tracked continuously; escalation
  workflow beyond agent level)**; reopen window.
- `chat_sessions`: chatbot phase → human handoff (user request or complexity); transcript
  retained.
- Knowledge base: FAQs, tutorials, video guides, troubleshooting (issue→solution); linked to
  tickets (article suggestions).
- `account_requests` (password reset, profile update, plan change): pending → processed |
  rejected; SLA + auto-escalation (owner → super admin); resolution requires recorded
  outcome.
- Support metrics (response times, volume, SLA status) → dashboard tile + `analytics`.
- AI doubt escalation (from C, T-C-09) lands here as ticket.
- **DEPS:** T-D-01, DEPS⚡ T-A-09
- **AC:** SLA breach detection (test with short SLA); priority routing assigns to correct
  queue (test); ticket without resolution note cannot close (422); handoff preserves
  transcript (test); escalation path owner→super-admin (test).

### T-D-07 · Affiliate portal runtime
- Consumes A's config (T-A-16: structure/levels/payout config) — **referral tools
  unlocked only after enrollment approval** (gate checked first thing on portal routes).
- `referral_links` (unique token, click/signup/purchase counts, regenerable; **QR
  auto-regenerates on link change — stale QR invalid**), tracked links (label =
  campaign/channel; reported separately from main link; deletable).
- Attribution engine: click → signup → purchase journey per channel/campaign; conversion
  records; **emits commission accrual to A's ledger** (`commission_entries` pending).
- Discount codes (create gated by program tier — A's grant, DEPS⚡ T-A-15); marketing
  material library (banners/social/graphics); promo content packs (per course,
  campaign-updated); one-click social post (requires connected channel; every post
  tracked); leaderboard (rank by referrals|conversions|commission, period-scoped).
- Referred customers: renewals tracked (renewed/lapsed) → recurring commission events to A;
  customer activity feed.
- Multi-tier: exactly two tiers (T1 direct, T2 sub-affiliates); downline tree; recruitment
  link → sub-affiliate joins referrer's Tier 2; leadership bonus dual-gated.
- Payouts: **minimum threshold enforced** (409 below); payment methods (verification
  required before payout; active-autoflow method not implicitly default-removed);
  payment request → A's approval workflow; statements (one per payout, downloadable).
- Commission disputes: open → under review → resolved, with platform response;
  **commission entries immutable — corrections via dispute only**.
- Performance incentives: milestone tiers (Bronze→Platinum; **rate increases with tier**,
  change history), exclusive materials (top tiers only), seasonal campaigns (explicit
  join, boosted), target tracking (on-track/at-risk vs bonus at stake).
- Marketing automation: sequences (follow-up/nurture/win-back/testimonial; triggers new
  lead/inactivity/milestone; win-back targets inactive leads only); scheduled promotions
  (future-dated only editable/cancellable; auto-publish at date); conversion attribution
  per sequence and per social post.
- Affiliate Academy: courses, certification (**issued only on passing assessment;
  retakeable; displayed on profile**), learning path position, webinars (monthly,
  recordings, Q&A), dedicated manager (messages, 1:1), community (moderated,
  topic-categorized), co-marketing (application per campaign).
- Notifications: commission/payout/campaign/milestone alerts — **critical system alerts
  never muted** (T-D-01).
- **DEPS:** T-D-01, DEPS⚡ T-A-16, DEPS⚡ T-A-15
- **AC:** unapproved affiliate → all referral tool endpoints 403 (test); QR stale after
  regeneration (test: old QR token 410); payout below threshold 409 (test); commission
  entry not modifiable via any endpoint (test); win-back sequence fires only for inactive
  leads (test fixture); tier-up changes effective rate on new accruals only (test).

### T-D-08 · Gamification config + leaderboards
- `point_rules` (value per action — applied at earning time, **never retroactive**; bonus
  rules; expiry policy rolling), `badge_definitions` (all-or-nothing criteria; streak
  milestones 7/30/100 exact; revocation with reason), `leaderboard` settings (scope
  class/grade/subject; period weekly/monthly/all-time with rollover reset; **opt-in naming
  requires consent else anonymous**; school-policy flag), `challenges` (draft → active →
  completed; entry eligibility + max entries; tie-break documented; reward issuance
  recorded, unissued flagged).
- **C executes (ledger/streaks/badges earned) — D owns the config + read APIs +
  `GamificationConfigService` real impl.**
- Celebrations (type, personal message, visible to both parent+child), shared goals
  (parent proposes → **child must agree** before tracked; adjustments recorded), check-ins,
  real-world rewards, digital tokens (earning rules, balance visible to both), unlock
  privileges (learning-criteria-gated), achievement showcase (highlight).
- Leaderboard computation jobs (schedule-based, not fully real-time) → `analytics`.
- **DEPS:** T-D-03, DEPS⚡ T-C-07
- **AC:** rule change non-retroactive (C ledger test); anonymous leaderboard default —
  named only with consent (test); challenge at max entries rejects (test); shared goal
  without child agreement not tracked (test); token balance visible to parent+child (test).

### T-D-09 · Marketing & communication
- `campaigns`: type (email/SMS/in-app), audience segments (criteria type/grade/region;
  members), state draft → scheduled → active → completed; A/B variants (stable assignment
  per user); performance (open/click/conversion) → `analytics`.
- Drip campaigns (trigger-driven: signup, course start; sequences + timing);
  re-engagement rules (inactivity 7/30 days).
- In-app notifications: push/banner/popup (offer type/value/code); trigger (event/schedule)
  + audience + date window; popup frequency cap (once/daily).
- Templates: channel, subject, body, variables, branding, **versioned (version number +
  change notes)**; SMS: OTP (via A's TokenService), typed alerts (payment/expiry/security),
  bulk broadcast (delivery rate, regional language).
- A owns discount/campaign *definitions* (T-A-15) — D owns *delivery* + performance.
- **DEPS:** T-D-01, DEPS⚡ T-A-15, DEPS⚡ T-B-05
- **AC:** campaign state machine (illegal transition 409, test); A/B stable per user
  (test); popup frequency cap (test); template version history (test); SMS OTP delegates
  to A's token flow (test).

---

## PHASE 2 — Tenant Portals

### T-D-10 · Corporate tenant portal
- All routes behind A's `TenantGate` (verified/active only) + CORP role checks
  (Corporate Admin / Department Manager / HR Manager / Employee; billing admin-only;
  role changes effective next session).
- Onboarding checklist (steps: verify domain [A], add employees, assign seats, create dept,
  set billing; per-step timestamps, dismissible).
- Employee management: `employees` (work email **must match verified domain**; seat
  required at creation — inactive without one; **enrollment fails without a seat, never
  auto-expands plan**), bulk import (≤10,000 rows; invalid emails fail never guessed;
  duplicates skipped; per-row all-or-nothing; CSV error report), departments (unique per
  account; nestable teams; one primary dept per employee; delete blocked while members —
  archive after emptying; merge keeps records), seat ops (assign/revoke/transfer via
  A's seat service, DEPS⚡ T-A-21; revocation deactivates access ≤1 min; completed
  records retained).
- Mandatory training: `mandatory_assignments` (deadline always required; dept assignment
  covers current employees only unless **ongoing**), `compliance_obligations`
  (pending/overdue/verified-complete; clears only when all modules done AND assessment ≥
  min passing score — default 70% per-course; re-verification after content changes),
  **escalation ladder: reminders 7/3/1 days pre-deadline; overdue → employee; 14 days →
  dept manager; 30 days → Corporate Admin; configurable but never <1 day; escalations stop
  on completion; resolution notice on completion**.
- Learning paths (recommended vs mandatory; sequential locks next step; withdraw keeps
  records); certifications (grant on verified completion; validity; **lapsed must be
  re-earned, not renewed**; records immutable — corrections = new version); skill mapping
  (skill→building course; demonstrated only on verified completion; gap recommendations
  are suggestions until assigned).
- HRIS/LMS/SIS connectors (config + sync state; **HRIS = source of truth while active —
  manual roster edits overridden by next sync**; inbound completions deduped by activity
  ID; failed sync exponential backoff ≤24h; offboarding → deactivate + revoke seat within
  one sync cycle, records preserved; auto-enroll new joiners queued when no seat).
- Budgets (annual, per cost center; mid-year edit history) + **80%/100% alerts once per
  budget period**; cost-center statements (every seat allocated for clean statement).
- Dashboard (15-min freshness, via T-D-02 aggregates): employee overview (active = ≥1
  learning event in 30d), learning progress (completion %, hours = video+quiz+reading),
  compliance score (met/total obligations ×100), overdue mandatory, expiring
  certifications (window configurable), department breakdown (compare ≤4 depts).
- Reports (HR monthly; cost-per-employee = period billing/active seats; scheduled
  delivery 00:00 account timezone; recipients must belong to account).
- **DEPS:** T-D-01, T-D-02, DEPS⚡ T-A-12, DEPS⚡ T-A-21, DEPS⚡ T-C-11
- **AC:** import with 2 bad emails → those rows failed, rest imported (test); seatless
  enrollment 409 (test); escalation at day 14 goes to dept manager not employee (test
  fixture); HRIS override: manual dept change reverted by sync (test); compliance score
  math (test); 80% budget alert fires once per period (test).

### T-D-11 · CSR tenant portal (funding)
- `csr_programs` (created new OR **funds existing platform/ORG program** —
  `catalog_program_id` nullable — resolution of open question), funding agreement with
  **CSR-admin approval workflow before release**, `budget_allocations` (categories:
  content/delivery/scholarships/operations × periods = **tranches**; reallocation needs
  approval per limits; history), `disbursements` (strict lifecycle scheduled → released |
  pending/failed; receipt + reference), program milestones (targets, due dates; **delay →
  alert + program at-risk status**).
- Beneficiaries (funded student/institute; progress, at-risk flag; **per-student identity
  MASKED in CSR views — aggregates OK** (response transform, not raw data)).
- Certificates (verification link, re-issue request); beneficiary feedback (satisfaction
  score, themes).
- Billing: funding invoices **raised to the CSR by platform** (draft/issued/paid/overdue),
  payments reconciled, reconciliation (committed vs disbursed vs invoiced; variance by
  program; unresolved items), funding statements (monthly/quarterly; PDF/Excel; email).
- Impact reports (analytics): beneficiary outcomes (enrollment, attendance, score
  distribution, completion, certificates; period comparison), funded-student progress
  (masked per-student), ROI (cost per beneficiary/completion/certificate), custom impact
  report (programs × periods × metrics × segments; saved templates; scheduled; share
  link).
- Dashboard: funded program summary, program health (milestones, **budget burn rate**,
  engagement; on-track/at-risk/completed), impact metrics, budget utilization
  (overspend/underspend indicators).
- Notifications: milestone/program alerts, impact report cadence (monthly digest /
  quarterly deep-dive / annual), per-program subscriptions (types: milestones/progress/
  completion; delivery log).
- **DEPS:** T-D-01, T-D-02, DEPS⚡ T-A-12, DEPS⚡ T-C-16
- **AC:** funding without CSR-admin approval 403 (test); disbursement lifecycle (illegal
  transition 409, test); masking: per-student response contains no name/email (test
  asserts fields absent); milestone delay → at-risk + alert (test); reconciliation
  variance report (test).

### T-D-12 · Webhook/API dispatch engine
- Consumes A's `webhook_endpoints`/`api_keys`/`rate_limits` (T-A-24) — D implements the
  **dispatch**: event → signed payload (HMAC-SHA256), at-least-once, non-2xx retried
  exponential backoff ≤24h, exhausted → **dead-letter** (reprocessable, removed on
  success), sustained unreachable → endpoint down + alert; IP allowlist enforced.
- API-key enforcement middleware (scope check → 403 + logged; usage counters;
  per-key/endpoint/global rate-limit hierarchy → 429 + Retry-After).
- Sync run tracking (last sync, records, backlog; immutable history; manual vs automated;
  slow/backlog thresholds alerted); consistency checks (mismatch → report-only |
  auto-fix (source of truth applied + logged) | manual review; **never deletes records**);
  error log grouping (transient retried; permanent → dead-letter; auth error → suspend
  integration + high-severity alert).
- Embed widgets: domain allowlist (non-allowlisted → error state), scoped token (revoked
  stops loading), refresh interval clamped.
- **DEPS:** T-D-01, DEPS⚡ T-A-24
- **AC:** webhook delivered with valid signature (test verifies HMAC); failing endpoint
  retried 3× then dead-lettered (test); DLQ reprocess clears (test); over-scope API call
  403 + logged (test); rate-limit hierarchy: endpoint stricter than global wins (test);
  auto-fix applies source-of-truth + audit row (test).

### T-D-13 · Organization (NGO/gov/board) tenant portal
- ORG roles (super/program/finance/compliance admin + learner/mentor/coordinator);
  multi-admin setup (primary admin verified first; additional invited with roles).
- `org_programs` (objective, duration, selected courses, target depts/groups;
  editable/archivable), `curricula` (courses+modules+assessments assigned to program
  stages; learning-path order; **versioned with change history**), `cohorts` (batch within
  program; unit of progress/completion tracking; cohort comparison), program milestones
  (deadline reminders to users; delay alerts).
- Seats at **department/group granularity** (differs from CORP individual — shared
  `seats` table with `granularity` column per A's T-A-21 resolution); bulk enroll
  (CSV validate → error report → accepted/rejected summary → history); SSO JIT
  provisioning (creates user on first login; disabling SSO keeps password login).
- Compliance: mandatory training tracking (completion by dept/program; overdue +
  reminders), certification compliance (required per role; expiry alerts; compliance
  rate), **compliance-rate-threshold alerts** (recipient management), audit reports
  (user activity, enrollment changes, compliance events, admin actions; period-scoped),
  data exports (users/programs/progress/compliance; **scheduled exports**).
- **Government invoicing: tax invoice format + purchase-order reference + statutory
  fields + approval workflow before issue + archive** (generic `approval_workflow` entity
  reused for CSR funding + SPON placement + account verification — resolution of open
  question); budget across programs/departments/periods (variance report); cost centers
  per program/department.
- LMS connections (course sync in, user sync in, progress sync out; conflict detection +
  handling surfaced, never auto-resolved without policy), data sync jobs (scheduled/
  on-demand; scope; conflict history), API keys (A's admin, D's dispatch T-D-12).
- Dashboard: program overview (enrolled per program, completion rates), enrolled users
  (by dept/group, growth trend), compliance status, resource utilization (seat used vs
  allocated; **underutilization alerts**).
- **DEPS:** T-D-01, T-D-02, T-D-12, DEPS⚡ T-A-12, DEPS⚡ T-A-21
- **AC:** curriculum change creates v2 with history (test); gov invoice without PO ref →
  422 (test); approval workflow gates issue (test); JIT provisioning on first SSO login
  (test); cohort comparison report (test); underutilization alert at threshold (test).

### T-D-14 · Sponsor tenant portal
- Sponsorship: targeted course/content; **tier bronze/silver/gold/platinum**; duration;
  placements (course pages / content players / certificates / landing pages) with
  **approval workflow + preview before go-live** (reuses generic `approval_workflow`,
  T-D-13); **auto-removal on expiry**; renewal (opt-in; pre-expiry offer; tier change;
  mid-cycle proration).
- Scholarships: funded programs, count, **eligibility criteria**, disbursement schedule,
  recipient list (**privacy-masked to sponsor**), completion tracking.
- Visibility (analytics): logo placement (impressions/clicks/active period), sponsored
  content views (watch time, completion, audience; top performers), brand mentions
  (reach, sentiment, trend), exposure reports (monthly/quarterly; PDF/Excel; archive).
- Impact: students reached (by segment), sponsored-student outcomes (completion,
  assessment, certificates; period comparison), ROI (cost per impression/student/
  completion), impact story export (branded PDF; share link).
- Billing: sponsorship invoices (draft/issued/paid/overdue), payment schedules
  (installments; upcoming reminders), renewal billing (tier-change pricing; proration),
  spend summary (by period/sponsorship/tier vs budget; archive).
- Dashboard: sponsored items summary, sponsorship health (duration progress, visibility
  performance, renewal status; performing/underperforming/expiring-soon), visibility
  metrics (monthly trend), audience reach (segments, geo, new vs returning).
- Notifications: milestone alerts (start, halfway, completion, **scholarship
  disbursement events**), visibility digest, expiring reminders, renewal offers;
  per-sponsorship subscriptions (types: visibility/milestones/renewal; delivery log).
- **DEPS:** T-D-01, T-D-02, DEPS⚡ T-A-12, DEPS⚡ T-B-06
- **AC:** unverified sponsor → no placement (403, test); placement live only after
  approval + preview (test); expiry → placement auto-removed (test fixture); recipient
  masking (test); renewal proration math (test).

---

## PHASE 3 — Dashboards, Reporting, Monitoring

### T-D-15 · Super-admin + tenant dashboards
- `GET /dashboard/summary` (composite) + per-tile endpoints: users (totals by type,
  signups, active/inactive over defined window), revenue (active subs, trends, payment
  status), content (library stats, upload/approval state split), system health (uptime vs
  99.9%, error/incident counts), engagement (DAU/WAU/MAU), support (tickets by state,
  SLA met/at-risk/breached).
- All tiles = aggregate reads from `analytics` (T-D-02) with `as_of`; **pure read, no
  writes**; every view audit-logged with period/timestamp.
- Tenant dashboard variants (CORP/CSR/ORG/SPON per T-D-10..14) share the read-model
  pattern: source events → aggregate job → read endpoint with `as_of`.
- **DEPS:** T-D-02, DEPS⚡ T-A-20, DEPS⚡ T-C-16
- **AC:** every tile returns aggregate + `as_of` (test per tile); no tile endpoint writes
  (lint); planted event → aggregate updates within SLA (test with sync dispatch).

### T-D-16 · Custom reporting
- `report_configs` (type revenue/user/content/affiliate/institute; parameters/filters;
  period; saved name — **reusable templates**), on-demand generation (pure function of
  type+params+period), `report_schedules` (daily/weekly/monthly; active/paused/
  completed), report runs (status; output), exports (formats; secure expiring links;
  **entitled data only**).
- Report payloads: revenue by course/period/region, subscription vs one-time, refunds/
  adjustments, acquisition by source, **churn (rate + reason: price/content/support)**,
  growth by type/segment, content performance (completion, drop-off, question accuracy,
  feedback), affiliate conversion/commission/top performers, institute license utilization
  + batch comparison + course completion.
- Scheduled delivery (frequency × recipients by email; delivery history).
- **DEPS:** T-D-15
- **AC:** saved config re-run reproduces output (test); schedule pause/resume (test);
  institute report scoped to its records (test); churn report carries reason dimension
  (test); export link expires (test).

### T-D-17 · Finance & revenue dashboards
- Financial KPIs: total revenue, active subscription count/revenue, pending & failed
  payments (**failure always carries reason**), refunds processed; commissions by status
  (pending → earned → paid) + payout status per affiliate; subscription health (active/
  expiring/lapsed; renewal rate = renewed/total; upgrade/downgrade from-plan→to-plan
  with amount delta); license utilization (seats used/available; **expiry alerts at
  configured threshold 30/60 days**; renewal/upgrade opportunities); trends vs configured
  target for period.
- Sources: A's `identity_billing` aggregates via T-D-02 ingestion (PaymentSucceeded/
  Failed, Subscription*, RefundProcessed, CommissionSettled, PayoutIssued).
- **DEPS:** T-D-02, DEPS⚡ T-A-20, DEPS⚡ T-A-21
- **AC:** failed payment without reason rejected at ingestion (test); renewal rate math
  (test); license expiry alert at threshold (test); upgrade tracked from→to with delta
  (test).

### T-D-18 · System health, monitoring, incident management
- Health probes: component state (healthy/degraded/down); **uptime vs 99.9% SLA** over
  daily/weekly/monthly windows; service status (up/degraded/down).
- Performance metrics: page load, video streaming quality (smooth/buffering/failed),
  DB query time, API response time; traffic; CDN status (latency, auto quality
  adjustment); scaling policy state (scaled-up/scaled-down/stable).
- Alerts: fire only on threshold cross; lifecycle sent → acknowledged → resolved.
- Incidents (outage/degradation): open → in-progress → resolved with resolution record;
  error monitoring feeds alerts; optimization tracking (DB/page; cache state cached/
  expired/cleared, clear/refresh endpoint).
- Health endpoint (`/health/status`) for orchestrators + dashboard tile.
- **DEPS:** T-D-02
- **AC:** threshold cross → alert created once (no dupes, test); incident lifecycle
  (test); uptime math over window (test); cache clear resets state (test).

### T-D-19 · Cross-tenant E2E + analytics verification
- Seed fixtures for all 4 tenants + institute + affiliate (linking to A's seeded
  tenants, B's catalog, C's learning data).
- E2E scenarios: (1) CORP import → seat → mandatory assignment → escalation →
  compliance dashboard; (2) CSR program approval → tranche → disbursement → invoice →
  impact report (masked); (3) SPON placement approval → live → impressions → renewal;
  (4) ORG cohort → curriculum v2 → compliance threshold alert; (5) affiliate click →
  signup → purchase → commission → payout; (6) learner event → analytics → dashboard
  within SLA.
- **DEPS:** T-D-15, T-D-16, T-D-17, T-D-18
- **AC:** all 6 E2E scenarios green; masking verified in scenarios 2+3 (assertions on
  response fields); `as_of` present on all dashboard reads.

---

## Phase Gates (Track D)
- **Gate 1 (end Phase 0):** `NotificationService` live — A/B/C feature tests flip from mock
  to real dispatcher; analytics ingestion idempotent.
- **Gate 2 (end Phase 1):** learner receives critical + preference-filtered notifications;
  support SLA works; affiliate portal E2E (click→payout); leaderboards anonymous by default.
- **Gate 3 (end Phase 2):** all 4 tenant portals + institute pass their gate scenarios;
  webhooks signed + dead-lettered correctly.
- **Gate 4 (end Phase 3):** every dashboard tile + report + health check live; 6 E2E
  scenarios green.

## Contract Stub Obligations (Track D must ship in Phase 0)
- `NotificationService` (real dispatcher by Gate 1 — interface merged in Phase 0),
  `GamificationConfigService` (real by T-D-08), analytics ingestion for all 15 contract
  events (idempotent), generic `approval_workflow` entity (used by A's verifications
  after T-D-13).
