Spaces:
Running
Running
| # MediaRouter Analytics & Insights | |
| ## Status | |
| The current working tree implements the bounded Analytics service at | |
| `app/analytics/`, exposes `/v1/analytics` routes, and provides frontend, | |
| TypeScript/Python SDK, MCP, and n8n transport surfaces. PostgreSQL schema, | |
| RLS certification, Docker/Hugging Face runtime verification, and provider | |
| certification remain deferred until all planned product phases are complete. | |
| ## Architecture | |
| Phase 10 extends the authoritative Social analytics boundary. Provider calls | |
| remain behind `SocialProviderAdapter.get_metrics`, OAuth execution remains | |
| inside `OAuthService`/`TokenService`, and credentials never enter analytics | |
| records or transports. | |
| The flow is: | |
| `REST/MCP/SDK/n8n -> AnalyticsDomainService -> AnalyticsRepository -> | |
| Social AnalyticsService -> provider adapter -> normalized snapshots` | |
| Workspace and project dashboards read durable normalized snapshots. They never | |
| call providers directly and never synthesize missing metrics. | |
| ## Database | |
| Migration `app/social/migrations/0010_analytics_insights.sql` is additive and | |
| creates: | |
| - `analytics_sync_runs` | |
| - `analytics_metric_snapshots` | |
| - `analytics_post_metrics` | |
| - `analytics_platform_metrics` | |
| Common values are normalized into typed columns. JSON dimensions are bounded | |
| provider-specific metadata, not complete provider responses. Snapshot | |
| uniqueness is workspace + provider + external object + metric + bucket. | |
| All four tables enable and force PostgreSQL RLS using the transaction-local | |
| `app.workspace_id`. Social post, target, and account foreign keys enforce | |
| authoritative publishing relationships. Project references are verified | |
| through `ProjectService`; project and Social databases may be independently | |
| configured, so an unsafe cross-database foreign key is not introduced. | |
| ## Permissions and rate limits | |
| - `analytics:read` reads dashboards, posts, capabilities, and sync status. | |
| - `analytics:sync` queues or cancels synchronization. | |
| - `analytics:export` is reserved for a future explicitly bounded export API. | |
| Viewer roles receive read access. Operator and developer roles receive sync | |
| access. Analytics reads use the established analytics rate-limit category; | |
| sync mutations use a stricter bounded category. SDK, MCP, and n8n calls pass | |
| through the same authentication, authorization, and rate limits. | |
| ## Metrics and capabilities | |
| The common metric vocabulary currently includes views, impressions, likes, | |
| comments, shares, and engagement rate. A provider advertises these controls | |
| only when its existing registered analytics capability is enabled. Missing | |
| values stay `null`. Unsupported and unsynchronized states are distinct from | |
| zero. | |
| Provider limitations remain explicit: | |
| - YouTube channel analytics requires a separate authorized product flow. | |
| - Facebook and Instagram analytics require explicit analytics consent/scopes. | |
| - TikTok metrics require a resolvable public video identity. | |
| - X is limited to authorized public metrics. | |
| - LinkedIn support depends on member/organization authorization. | |
| - Telegram and WhatsApp analytics remain unsupported unless their registered | |
| adapters acquire verified provider contracts. | |
| No provider certification claim is made by this phase. | |
| ## Synchronization | |
| `POST /v1/analytics/sync` creates a durable idempotent run and returns `202`. | |
| The worker atomically claims bounded runs and follows: | |
| `queued -> running -> succeeded | partial | failed | cancelled` | |
| Retries use bounded exponential backoff with jitter. A run is partial when | |
| some targets return authoritative metrics and others are unavailable. Existing | |
| external post IDs connect MediaRouter publishing targets to provider metrics. | |
| No manual or heuristic post mapping is used. | |
| Audit events are bounded: | |
| - `analytics.sync_requested` | |
| - `analytics.sync_started` | |
| - `analytics.sync_completed` | |
| - `analytics.sync_failed` | |
| - `analytics.sync_cancelled` | |
| They contain IDs, status, provider, and counts only. | |
| ## API | |
| - `GET /v1/analytics/capabilities` | |
| - `GET /v1/analytics/overview` | |
| - `GET /v1/analytics/timeseries` | |
| - `GET /v1/analytics/platforms` | |
| - `GET /v1/analytics/platforms/{provider}` | |
| - `GET /v1/analytics/posts` | |
| - `GET /v1/analytics/posts/{post_id}` | |
| - `GET /v1/analytics/projects/{project_id}` | |
| - `GET /v1/analytics/sync-runs` | |
| - `GET /v1/analytics/sync-runs/{run_id}` | |
| - `POST /v1/analytics/sync-runs/{run_id}/cancel` | |
| - `POST /v1/analytics/sync` | |
| Date ranges are limited to 366 days, pagination is bounded, sorting uses a | |
| closed enum, and timezones must be valid IANA names. UTC is returned explicitly | |
| when no authoritative workspace timezone is supplied. | |
| ## Frontend | |
| `/analytics` and `/projects/[projectId]/analytics` use the Workspace shell, | |
| TanStack Query, authenticated BFF, existing cards and chart containers. UI | |
| controls are capability-driven. Empty, unavailable, unsupported, error, | |
| loading, partial, and freshness states are represented without zero-filling. | |
| Search can deep-link authoritative analytics post results. Commands include | |
| Open Analytics, View Top Content, and permission-gated Sync Analytics. | |
| ## SDK, MCP, and n8n | |
| The TypeScript and Python clients expose `client.analytics` with capabilities, | |
| overview, time series, platforms, posts, project analytics, sync, sync status, | |
| sync listing, and cancellation. | |
| MCP exposes narrow typed analytics tools rather than arbitrary query or | |
| provider execution. The official n8n Social node uses the SDK for overview, | |
| time series, platform, project, top-content, sync, and sync-status operations. | |
| ## Runtime status | |
| Provider live certification, PostgreSQL/RLS runtime verification, Docker, | |
| Hugging Face startup, production OpenAPI verification, and final production | |
| certification are intentionally **DEFERRED** until all planned MediaRouter | |
| product phases are complete. | |