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