Skip to content

KPI cockpit

The KPI cockpit is Workspace Control’s executive view: every strategic metric your apps track, grouped by app, with progress bars against targets.

This is the page you check at the start of the day to know where the company stands without drilling into 5 different apps.

KPIs aren’t a separate platform feature — they’re just app records with record_type='kpi'. Any app can publish KPIs by inserting (or updating) a row in linkworld_user_app_records with the agreed-upon JSON shape:

{
"metric": "x_followers",
"value": 132,
"target": 500,
"unit": "followers",
"period": "day",
"trend": "+12 vs last week",
"label": "X Followers"
}
FieldRequiredNotes
metricyesUnique per app, used as the card key
valueyesNumeric (or numeric string — coerced)
targetnoWhen set, progress bar appears
unitnoDisplay only (“EUR”, “followers”, “deals”)
periodnoFree-form chip (“day”, “week”, “Q4”)
trendnoFree-form line beneath the value
labelnoDisplay label override (default: metric)

Per app:

  • App ID heading
  • A grid of KPI cards (responsive, ~220 px min)
  • Each card: label, period chip, value (compact format — 132, 8.5k, 2.4M), target line, progress bar, trend line, last-updated time

Progress bar color tracks percent of target:

BucketColor
≥ 100 %Green (target reached)
75–99 %Blue (on track)
40–74 %Amber (mid)
< 40 %Red (low)

Auto-refresh: every 60 seconds while the screen is open.

If no app has published KPIs yet, the cockpit shows the empty state with the JSON schema. This is on purpose — it tells admins (and app authors) exactly how to make KPIs appear.

Any time your app’s logic updates a metric (e.g. a heartbeat just read the X follower count), insert / update an app_records row:

  • Tenant: scoped automatically
  • app_id: your app slug
  • record_type: "kpi"
  • data: the JSON shape above

Use dedup_key='metric' so re-running the same heartbeat updates the existing row instead of creating duplicates. The cockpit picks it up on the next refresh.

App authors don’t need a special API — they use the same ctx.tools.call('app_records_insert', …) they already use for their other records, just with the KPI shape.

  • No history charts in v1. The cockpit shows the current value
    • the trend string the app provides. If you want time-series, that’s what the audit log + your app’s own data store does.
  • No alerts. The amber/red color coding is informational; no email when a KPI dips. Use heartbeats with pre-filters for “wake me when X drops below Y”.
  • No tenant-defined targets. The target lives on the KPI record itself, set by the publishing app. If you want a different target, edit it in the source app, not the cockpit.

These are deliberate v1 omissions to keep the surface small and focused. They can ship later as Tier-3 follow-ups, possibly as a separate dedicated app (ceo-cockpit) since the data model is already app-agnostic.

A KPI per major metric: ARR, MRR, headcount, churn, NPS, support backlog. Each owned by the app that has the data closest to source (Sales, Finance, HR, Support). The cockpit becomes the morning “how are we doing?” surface.

For a focused 7-day sprint, publish one KPI per goal: “x_followers” (target 500), “signups” (target 100), “posts” (target 14). Watch the bars fill across the week.

Marketing publishes engagement metrics; Sales publishes pipeline metrics; Finance publishes cash. The cockpit’s per-app grouping gives you a single page that answers “how are all my departments doing?”.

  • Cap: 200 KPIs per cockpit fetch (sorted by updated_at desc). Beyond that, drill into specific apps.
  • Per-card content: bounded by the JSON shape (no images, no embedded charts in v1).
  • Refresh cycle: 60 seconds.