## 1. Foundation & Database Migrations - [x] 1.1 Create migration `023_add_analytics_events.sql` — `analytics_events(id, tenant_id, date, metric_type, count, PRIMARY KEY(tenant_id, date, metric_type))` - [x] 1.2 Create migration `024_add_tenant_tiers.sql` — `tenant_tiers(tenant_id FK, tier ENUM('free','pro','enterprise'), created_at, updated_at)` - [x] 1.3 Add `TIER_CONFIG` constant to `src/config/tiers.ts` with free/pro/enterprise limits - [x] 1.4 Add `ANALYTICS_ENABLED`, `TIER_ENFORCEMENT`, `COMPLIANCE_ENABLED` env vars to `.env.example` and `src/config/env.ts` - [x] 1.5 Run migrations in test environment and verify table creation ## 2. WS3 — Analytics Backend - [x] 2.1 Create `src/services/AnalyticsService.ts` — `recordEvent(tenantId, metricType)`, `getTokenTrend(tenantId, days)`, `getAgentActivity(tenantId)`, `getAgentUsageSummary(tenantId)` with JSDoc - [x] 2.2 Add analytics event recording to `OAuth2Service.issueToken()` — fire-and-forget (non-blocking) - [x] 2.3 Add analytics event recording to `AgentService.create()` and `AgentService.deactivate()` - [x] 2.4 Create `src/controllers/AnalyticsController.ts` — GET /api/analytics/tokens, GET /api/analytics/agents/activity, GET /api/analytics/agents - [x] 2.5 Create `src/routes/analytics.ts` and register under `/api/analytics` in `src/app.ts` (guarded by `ANALYTICS_ENABLED` flag) - [x] 2.6 Add input validation: `days` param capped at 90, tenant scoping enforced on all queries ## 3. WS3 — Analytics Portal Pages - [x] 3.1 Add `recharts` and `date-fns` to `portal/package.json` - [x] 3.2 Create `portal/src/components/charts/TokenTrendChart.tsx` — recharts LineChart, lazy-loadable - [x] 3.3 Create `portal/src/components/charts/AgentHeatmap.tsx` — recharts custom heatmap, lazy-loadable - [x] 3.4 Create `portal/src/pages/analytics/index.tsx` — uses `next/dynamic` for chart components, fetches from `/api/analytics/*` - [x] 3.5 Add `/analytics` route to portal navigation (`portal/src/components/Sidebar.tsx` or equivalent) - [x] 3.6 Verify `next build` succeeds and analytics chunk is separate from main bundle ## 4. WS4 — API Gateway Tiers Backend - [x] 4.1 Create `src/middleware/tierEnforcement.ts` — reads `req.tenant.tier`, checks Redis `rate:tier:calls:` against `TIER_CONFIG`, sets rate limit headers on all responses - [x] 4.2 Register `tierEnforcement` middleware in `src/app.ts` after auth middleware, before routes (skip when `TIER_ENFORCEMENT=false`) - [x] 4.3 Add agent count enforcement in `AgentService.create()` — query active agent count vs. tier limit, throw typed `TierLimitError` if exceeded - [x] 4.4 Create `src/services/TierService.ts` — `getStatus(tenantId)`, `initiateUpgrade(tenantId, targetTier)`, `applyUpgrade(tenantId, tier)` (called from Stripe webhook) - [x] 4.5 Create `src/controllers/TierController.ts` — GET /api/tiers/status, POST /api/tiers/upgrade - [x] 4.6 Create `src/routes/tiers.ts` and register under `/api/tiers` in `src/app.ts` - [x] 4.7 Update Stripe webhook handler (`src/services/BillingService.ts`) to call `TierService.applyUpgrade()` on `checkout.session.completed` for tier upgrade events - [x] 4.8 Add `TierLimitError` to error hierarchy in `src/errors/index.ts` — HTTP 429, `tier_limit_exceeded` code ## 5. WS4 — Tier Portal Page - [x] 5.1 Create `portal/src/pages/settings/tier.tsx` — displays current tier, limits, usage, upgrade button - [x] 5.2 Upgrade button calls `POST /api/tiers/upgrade` and redirects to Stripe checkout URL - [x] 5.3 Enterprise tier view shows "Unlimited" with no upgrade button - [x] 5.4 Add `/settings/tier` to portal navigation ## 6. WS6 — AGNTCY Compliance Backend - [x] 6.1 Create `src/services/ComplianceService.ts` — `generateReport(tenantId)` building all compliance sections, `exportAgentCards(tenantId)`, Redis cache with 5-minute TTL - [x] 6.2 Implement `agent-identity` section: check all active agents for valid DID, non-expired credential, agent card presence - [x] 6.3 Implement `audit-trail` section: verify Merkle chain integrity for tenant's audit events - [x] 6.4 Implement agent card export: map agent records to AGNTCY agent card JSON schema v1.0 - [x] 6.5 Create `src/controllers/ComplianceController.ts` — GET /api/compliance/report, GET /api/compliance/agent-cards - [x] 6.6 Create `src/routes/compliance.ts` and register under `/api/compliance` in `src/app.ts` (guarded by `COMPLIANCE_ENABLED` flag) ## 7. WS6 — AGNTCY Conformance Test Suite - [x] 7.1 Create `tests/agntcy-conformance/` directory with Jest config - [x] 7.2 Write conformance test: agent registration creates DID:WEB identifier - [x] 7.3 Write conformance test: token issuance for agent client - [x] 7.4 Write conformance test: A2A delegation chain create + verify - [x] 7.5 Write conformance test: compliance report generation returns valid structure - [x] 7.6 Add `test:agntcy-conformance` npm script to `package.json` ## 8. QA & Release - [x] 8.1 Write unit tests for `AnalyticsService` — event recording, trend query, heatmap query, usage summary (>80% coverage) - [x] 8.2 Write unit tests for `TierService` — tier status, upgrade initiation, tier limit enforcement - [x] 8.3 Write unit tests for `ComplianceService` — report generation, agent card export, cache hit/miss - [x] 8.4 Write integration tests for all analytics endpoints (`/api/analytics/*`) - [x] 8.5 Write integration tests for all tier endpoints (`/api/tiers/*`) including Stripe webhook - [x] 8.6 Write integration tests for compliance endpoints (`/api/compliance/*`) including feature flag behavior - [x] 8.7 Run full test suite — verify >80% coverage on all new services - [x] 8.8 Run `tsc --noEmit` across API, portal, and CLI — zero errors - [x] 8.9 Run `next build` for portal — verify clean build and code-split chunks - [x] 8.10 Verify feature flags: `ANALYTICS_ENABLED=false` → 404 on analytics routes; `TIER_ENFORCEMENT=false` → no 429s; `COMPLIANCE_ENABLED=false` → 404 on compliance routes - [x] 8.11 Run AGNTCY conformance suite — all tests pass - [x] 8.12 Commit Phase 6 with message `feat(phase-6): WS3+WS4+WS6 — Analytics, Tiers, AGNTCY Compliance`