# OpenSpec Change: enterprise-api-plugin-analytics - **Change ID**: enterprise-api-plugin-analytics - **Package**: `@suaveplan/api-plugin-analytics` - **Category**: api/data - **Target path**: `api/data/api-plugin-analytics` - **Status**: PROPOSED - **Date**: 2026-04-24 - **Reference spec**: `/mnt/s/web/suaveplan/enterprise/api-plugin-analytics.md` --- ## Summary Deliver `@suaveplan/api-plugin-analytics` on the genesis branch from scratch at enterprise quality. Product-analytics plugin for `@suaveplan/api`. Genesis rebuild fixes all identified gaps: replaces the in-memory ring buffer with a pluggable `StorageAdapter` (in-memory for dev, SurrealDB for production), adds HTTP routes (`POST /track`, `POST /track/batch`, `POST /query/aggregate`, `POST /query/funnel`, `POST /query/cohort`, `DELETE /analytics/purge`), proper `EventMap` declaration via `src/events.ts` module augmentation (dropping `as Parameters<...>` cast), per-event-type schema validation via `@suaveplan/schema-registry`, PII masking via `@suaveplan/data-masking`, and batch idempotency via `@suaveplan/idempotency`. --- ## Available workspace deps on genesis | Package | Role | |---|---| | `@suaveplan/api` (`workspace:^`) | `definePlugin` | | `@suaveplan/api-shared` (`workspace:^`) | Helpers | | `@suaveplan/api-plugin-auth` (`workspace:^`) | `requireAuth` | | `@suaveplan/api-plugin-database` (`workspace:^`) | SurrealDB adapter | | `@suaveplan/events` (`workspace:^`) | Typed event bus | | `@suaveplan/schema-registry` (`workspace:^`) | Event schema versioning | | `@suaveplan/data-masking` (`workspace:^`) | PII masking on ingestion | | `@suaveplan/idempotency` (`workspace:^`) | Batch ingestion dedup | | `@suaveplan/error` (`workspace:^`) | `AnalyticsError` hierarchy | | `@suaveplan/rate-limiter` (`workspace:^`) | Ingestion rate limits | | `hono` + `@hono/zod-openapi` + `zod` | Routes | | `@opentelemetry/api` | OTel | --- ## Public API surface (preserves + extends existing) ```ts function createAnalyticsPlugin(config?: AnalyticsConfig): PluginDescriptor // Services (preserved) class AnalyticsService // track, aggregate, clear — now backed by StorageAdapter class FunnelAnalyzer // funnel conversion rates class CohortAnalyzer // cohort retention // Types (preserved) AnalyticsEvent, TrackEventInput, TimeGranularity, TimeSeriesPoint AggregationQuery, AggregationResult FunnelQuery, FunnelStep, FunnelStepResult, FunnelResult CohortQuery, CohortRow, CohortResult, AnalyticsEventMap // New interface StorageAdapter { track, query, purge, getStats } dateToPeriodKey (preserved) ``` ### Error codes (new) ```ts type AnalyticsErrorCode = | "ANALYTICS_INVALID_EVENT" | "ANALYTICS_STORAGE_ERROR" | "ANALYTICS_SCHEMA_MISMATCH" | "ANALYTICS_QUERY_INVALID" ``` --- ## File layout ```text api/data/api-plugin-analytics/ package.json tsconfig.json vitest.config.ts src/ index.ts events.ts types.ts errors/ adapters/storage.port.ts adapters/memory-storage.ts adapters/surreal-storage.ts analytics/analytics.ts cohort/cohort.ts funnel/funnel.ts routes/track/ routes/query/ routes/admin/ tests/integration.test.ts ``` --- ## Impact Prerequisites: `@suaveplan/api`, `@suaveplan/api-plugin-auth`, `@suaveplan/api-plugin-database`, `@suaveplan/events`, `@suaveplan/schema-registry`, `@suaveplan/data-masking`, `@suaveplan/idempotency`.