How it works

Build analytics once. Deliver them three ways.

GitHub → ingestion → Postgres → Embedded Canvas → public OpenDev, a customer product, and internal operations. OpenDev is the host. Embedded Canvas owns the semantic layer, the hosted runtime, and tenant isolation.

The pipeline

  1. GitHub public data is ingested by a worker. Visitor page loads never call GitHub.
  2. Postgres is the warehouse: orgs, repos, PRs, issues, commits, reviews.
  3. Embedded Canvas connects to that warehouse, owns the semantic layer where metrics are defined, and hosts the dashboard runtime that serves every chart on this site.
  4. Two read paths share those definitions: the dashboards OpenDev embeds, and a governed metrics API the host queries directly for the KPI cards above each chart. Neither path recomputes a metric in the host.
  5. Three audiences reuse the same dashboards: public OpenDev (unscoped session + host filters), DevMetrics customer (RLS on org_id), DevMetrics internal (skipTenantRls).

The same metrics, three surfaces

median_cycle_time

Median PR cycle time

percentile_cont(0.5) of (merged_at - created_at) in hours

Source pull_requests · measure PullRequests.medianCycleHours

Inclusion: merged_at is not null

  • OpenDev public
  • DevMetrics customer
  • DevMetrics internal

median_first_review

Median time to first review

percentile_cont(0.5) of (first_review_at - created_at) in hours

Source pull_requests · measure PullRequests.medianFirstReviewHours

Inclusion: first_review_at is not null

  • OpenDev public
  • DevMetrics customer
  • DevMetrics internal

prs_merged

PRs merged

count of pull requests where merged_at is not null

Source pull_requests · measure PullRequests.count over PullRequests.mergedAt

Inclusion: merged_at is not null

  • OpenDev public
  • DevMetrics customer
  • DevMetrics internal

Switch audience

Public product → customer view → internal view. Same deployment, same metric definitions, same analytics components, different security context.

Open DevMetrics as Vercel · Open internal operations · Back to public Vercel

Tenant isolation

Same dashboards. The BFF derives customerId from an HttpOnly cookie (customer) or sets skipTenantRls (internal). The forged body field is ignored.

Open a customer view first so the tenant cookie is set, then try forging another org id.

Launch proof

  • Native embedded analytics (chromeless, host-owned chrome)
  • Organization filtering via host filters
  • Interactive org → repo drill-down in the dashboard you register
  • Same metric definitions on every surface
  • Host-rendered KPI cards served by the governed metrics API — every card on this site resolves through the catalog, none are computed in the host
  • Customer tenant isolation (HttpOnly cookie → customerId)
  • Internal cross-customer analytics (skipTenantRls)

Want analytics like this inside your product?

OpenDev is a customer of Embedded Canvas: session mint from a BFF, chromeless @embeddedcanvas/embed-sdk, row-level security on org_id.

See the customer embed →