Skip to content

feat(den): replace dashboard home with telemetry usage insights MVP#1658

Merged
benjaminshafii merged 8 commits intodevfrom
task/den-telemetry-dashboard
May 6, 2026
Merged

feat(den): replace dashboard home with telemetry usage insights MVP#1658
benjaminshafii merged 8 commits intodevfrom
task/den-telemetry-dashboard

Conversation

@benjaminshafii
Copy link
Copy Markdown
Member

@benjaminshafii benjaminshafii commented May 5, 2026

Summary

  • Replaces the Den /dashboard home screen with an org-facing telemetry usage insights view
  • Adds full telemetry infrastructure: DB schema, ingest + adoption API endpoints, app-side reporter, dashboard wired to real data
  • Real data: org member count, pending invites, active users (from telemetry events). Enterprise-only preview for advanced analytics (hideable)
  • Preserves the "Download OpenWork" CTA

Screenshots

Dashboard with enterprise preview expanded (active users from real telemetry)

overview

Dashboard with enterprise preview hidden (non-enterprise view)

hidden

Build verification

  • pnpm --filter @openwork-ee/den-db build — passed
  • pnpm --filter @openwork-ee/den-web build — passed

What was built

den-db

  • telemetry_events table: id, org_id, user_id, event_type, event_timestamp, created_at
  • Indexed on (org_id, event_type, event_timestamp) and (org_id, user_id)
  • Added telemetryEvent type ID prefix (tev)
  • Exported gte operator from drizzle barrel

den-api

  • POST /v1/telemetry/ingest — batch ingest, auth-extracted identity, always returns 204
  • GET /v1/telemetry/adoption — members, pending invites, active users 7d/30d, 12-week weekly trend
  • Routes isolated in src/routes/telemetry/index.ts, registered in app.ts

app

  • den-telemetry.ts — fire-and-forget reporter, lazy activation on Den sign-in, batched POSTs, no retries, no local storage
  • trackSessionActive() wired into actions-store.ts when OpenCode creates a session

dashboard

  • Calls GET /v1/telemetry/adoption, falls back to org context data if unavailable
  • Live section: OpenWork users + pending invites (always visible)
  • Enterprise preview: active users, trend chart, settings, plugin/skill tables (hideable)

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 5, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
openwork-app Ready Ready Preview, Comment May 6, 2026 0:08am
openwork-den Ready Ready Preview, Comment May 6, 2026 0:08am
openwork-den-worker-proxy Ready Ready Preview, Comment May 6, 2026 0:08am
openwork-landing Ready Ready Preview, Comment, Open in v0 May 6, 2026 0:08am
openwork-share Ready Ready Preview, Comment May 6, 2026 0:08am

…d dashboard

- den-db: add telemetry_events table with org/user/type/timestamp schema
- den-api: add POST /v1/telemetry/ingest and GET /v1/telemetry/adoption endpoints
- app: add fire-and-forget telemetry reporter that activates on Den sign-in
- app: emit session.active event when OpenCode session is created
- dashboard: wire adoption metrics to real /v1/telemetry/adoption endpoint
- typeid: register telemetryEvent type ID prefix (tev)
@benjaminshafii
Copy link
Copy Markdown
Member Author

End-to-end telemetry verification

Tested the full telemetry pipeline locally with pnpm dev:den + pnpm dev:den:seed-demo (Acme Robotics, 17 members, 3 pending invites).

Steps

  1. Pushed telemetry_event table schema via db:push
  2. Signed in as [email protected] on http://localhost:3005
  3. Called GET /api/den/v1/telemetry/adoption — returned real org data:
    {"members":17,"pendingInvites":3,"activeUsers7d":0,"activeUsers30d":0,"weeklyTrend":[0,0,0,0,0,0,0,0,0,0,0,0]}
  4. Called POST /api/den/v1/telemetry/ingest with a session.active event — returned 204
  5. Called GET /api/den/v1/telemetry/adoption again — active user count incremented:
    {"members":17,"pendingInvites":3,"activeUsers7d":1,"activeUsers30d":1,"weeklyTrend":[0,0,0,0,0,0,0,0,0,0,0,0]}

Result

Step Status
Den stack boots den-api on 8788, den-web on 3005
telemetry_event table created db:push applied
GET /v1/telemetry/adoption before ingest activeUsers7d: 0
POST /v1/telemetry/ingest with session.active 204
GET /v1/telemetry/adoption after ingest activeUsers7d: 1
Dashboard shows "From telemetry" label Real data flowing

Full pipeline working: app event → ingest endpoint → DB → adoption query → dashboard.

@benjaminshafii
Copy link
Copy Markdown
Member Author

Verification (make-pr skill)

Build

  • pnpm --filter @openwork-ee/den-db build — passed
  • pnpm --filter @openwork-ee/den-web build — passed

UI verification (Chrome MCP)

  • Signed in as [email protected] on http://localhost:3005
  • Dashboard loads with real data: 17 OpenWork users, 3 pending invites
  • Active this week: 1 with "From telemetry" label — real data from the ingested session.active event
  • Enterprise preview shows/hides correctly via toggle
  • Console errors: none
  • Failed network requests: none
  • GET /v1/telemetry/adoption returned 200

API verification

Before ingest:
{"members":17,"pendingInvites":3,"activeUsers7d":0,"activeUsers30d":0,"weeklyTrend":[0,0,0,0,0,0,0,0,0,0,0,0]}

POST /v1/telemetry/ingest → 204

After ingest:
{"members":17,"pendingInvites":3,"activeUsers7d":1,"activeUsers30d":1,"weeklyTrend":[0,0,0,0,0,0,0,0,0,0,0,0]}

Screenshots

Full pipeline verified: app event → POST /v1/telemetry/ingest → DB → GET /v1/telemetry/adoption → dashboard.

- Merge PluginIcon + SkillIcon into single GradientTile component
- Remove dead Puzzle and Zap imports
- Replace useState/useEffect adoption hook with useQuery (uses existing DashboardQueryClientProvider)
- Fix AreaChart preserveAspectRatio from 'none' to 'xMidYMid meet'
- Rename weeklyTrend constant to FALLBACK_WEEKLY_TREND with doc comment
- Extract fetchAdoption as a standalone async function for react-query
Comment thread ee/packages/den-db/src/schema/telemetry.ts Outdated
Comment thread ee/apps/den-api/src/routes/telemetry/index.ts Outdated
- den-db: rename user_id column to member_id in telemetry_events table
- den-api: resolve org context middleware to get currentMember.id
- den-api: rename response fields to activeMembers7d/activeMembers30d
- dashboard: accept both field names for backward compat
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants