> ## Documentation Index
> Fetch the complete documentation index at: https://documentation.orbitdev.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Workspace Analytics Architecture, Events, and Security

> Workspace analytics architecture for the Orbit Vite/React SPA and Supabase backend: events, aggregation, database schema, security, and not-yet-implemented items.

Orbit is a Vite/React SPA backed by Supabase, and analytics follows that architecture. This page covers the client collector, overview metrics, how to add events, the event catalog, database migration and function details, security and privacy controls, and known not-yet-implemented items.

## Architecture

The first slice records sanitized SPA page views and provides a workspace administrator overview from the existing chat and Mission Control tables. `src/lib/analytics/client.ts` is best-effort: analytics failures do not block product actions.

The collector omits query strings and identifier-like path segments, and rejects property names that commonly carry secrets or message content. The overview reads existing product records rather than copying them into a second fact table. It reports chat generations, usage ledger tokens and cost, Mission Control runs, conversations, and explicit analytics events.

Revenue and automations are not reported because a verified workspace-scoped source for those metrics is not wired into this view. Both route authorization and database policies restrict analytics to Orbit staff roles.

## Overview metrics and what is not reported

| Reported | Not reported |
| - | - |
| Chat generations | Revenue |
| Usage ledger tokens and cost | Automations |
| Mission Control runs | |
| Conversations | |
| Explicit analytics events | |

## Adding events

<Steps>
  <Step title="Add the event name">
    Add event names to `src/lib/analytics/types.ts`.
  </Step>

  <Step title="Call trackEvent">
    Call `trackEvent` after a successful product action, sending only small, non-sensitive properties.
  </Step>

  <Step title="Bind workspace context">
    `user_id` comes from the authenticated Supabase session. `workspace_id` must come from the established workspace context.
  </Step>
</Steps>

The database checks membership and RLS permits inserts only for the caller's own user id.

## Event catalog

The typed client catalog currently includes page views, conversation and message lifecycle, generation stops, agent and automation lifecycle, project and file actions, and errors. Only `page_viewed` is wired globally today. Other names are an integration contract for product actions; do not claim their charts are populated until their call sites have been connected.

Events use a generated session id scoped to the current browser tab. Supported sources are `client`, `server`, `api`, `background`, `ai`, and `system`. The current browser SDK writes `client` events.

<Warning>
  Never send passwords, credentials, API keys, message bodies, prompts, email addresses, or other personal data. The client drops sensitive-looking keys and oversized strings as defense in depth; producers remain responsible for choosing safe properties.
</Warning>

## Database migration and tables

Migration `20260926140000_add_workspace_analytics.sql` adds the following:

| Object | Purpose |
| - | - |
| `analytics_events` | Append-only event store |
| `analytics_preferences` | Workspace-scoped tracking preferences |
| Indexes | Event workspace/time, name/time, user/time access paths |
| RLS | Staff-only reads and self-only inserts |
| `get_workspace_analytics_overview` | Bounded aggregate function |

Existing `chat_generations`, `chat_usage_ledger`, `chat_threads`, and `mission_runs` remain authoritative for product counts and AI usage.

The overview function is a narrowly scoped `SECURITY DEFINER` function because the source tables intentionally expose individual rows only to their owners. It checks for an authenticated caller and `analytics_is_staff()` before aggregating. That helper requires both an existing Orbit staff role and the established `@orbitdev.org` account domain. Event reads and inserts use the same check. Execute is revoked from PUBLIC and anon and granted to authenticated users; the function itself rejects non-staff callers. It returns aggregate values only. Keep the fixed search path and authorization guard if extending it.

`analytics_preferences` is workspace scoped; workspace members can read preferences and administrators can change them. The client collector stops recording if analytics or usage tracking is disabled. Preference-management controls remain a follow-up UI integration.

## Security and privacy

* Analytics navigation and route access require the existing Orbit staff guard.
* Event reads, event inserts, and aggregate queries independently require an Orbit staff role and an `@orbitdev.org` account in the database.
* Event inserts bind the actor to `auth.uid()`. Staff can read analytics across workspaces; non-staff callers cannot use the aggregate function or read event rows.
* The overview returns aggregates and does not expose message contents, stacks, or identifiers for individual users.
* The browser collector strips query strings and masks identifier-like path components. It filters common secret or content property names and bounds string length.
* The event table is append-only for authenticated clients: no update or delete grants are issued.
* Do not introduce a service-role key into the client or use caller-supplied user ids as authorization.

## Not-yet-implemented items

The following items have not been implemented in this initial slice:

* Larger role permission set (`analytics.view`, `analytics.ai`, and related grants)
* Export endpoints
* Event explorer
* Per-user analytics
* Preference-management UI integration

Keep all new queries workspace-scoped and add matching database authorization before exposing them.

## Aggregation and scale

The overview runs a bounded, workspace and time-filtered SQL aggregate and indexes the event workspace/time, name/time, and user/time access paths. This is an initial baseline, not a materialized reporting warehouse. Benchmark and add daily rollups or partitioning as volume requires.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.