Harness Intelligence Wiki
SpecsCLIIP-138-backoffice-project-usage

Spec: Backoffice Project Usage Visibility

Spec: Backoffice Project Usage Visibility

User Input

$linear:linear https://linear.app/devpunks/issue/IP-138/build-harness-intelligence-backoffice-for-project-usage-visibility https://linear.app/devpunks/issue/IP-143/harness-reports-are-triaged-in-backoffice-and-linked-to-github https://linear.app/devpunks/issue/IP-142/backoffice-shows-project-usage-adoption-dashboards https://linear.app/devpunks/issue/IP-141/backoffice-uses-authenticated-operator-identity https://linear.app/devpunks/issue/IP-140/cli-submits-happy-path-project-usage-events https://linear.app/devpunks/issue/IP-139/api-persists-project-usage-aggregates-and-observed-repositories

$delivery-phase lets go

Initial Situation

M4 implemented product telemetry and CLI-backed report submission. The database already has project_usage, observed_repository, cli_usage_event, and harness_report tables. The API can ingest telemetry and reports, and the CLI emits only the locked happy-path product events.

The missing M4.5 capability is the internal operational surface: maintainers still cannot inspect project adoption, map repositories into a project usage aggregate, or triage reports without reading raw database rows.

Issue

Harness maintainers need a first-party internal backoffice that answers adoption and support questions at the product level. OTel is not the right surface because it describes runtime behavior, not project usage. Linear is not the right default destination for reports because report follow-up is closer to implementation and tooling work.

Solution

Add a separate apps/backoffice Next.js app backed by typed API read/update contracts in packages/contract and Effect handlers in apps/api. The API exposes project usage summaries, project usage details, repository mapping, report status updates, and GitHub follow-up linking. The app presents project-level adoption and report triage while treating operator identity as audit/contact context only.

Child Coverage

ChildRequired outcomeCovered by
IP-139API persists and exposes ProjectUsage aggregates with 1:n observed repositories.DB-backed read model and repository mapping endpoint.
IP-140CLI submits only happy-path usage events with filterable source/noise metadata.Existing IP-105 event taxonomy plus dashboard filters for counted sources.
IP-141Better Auth operator identity is canonical; git identity is fallback/context only.Better Auth bearer/device auth and operator-only UI presentation.
IP-142Backoffice shows project usage list/detail dashboards and manual repository mapping.apps/backoffice list, detail, and mapping controls.
IP-143CLI-submitted reports are triaged in backoffice and linked to GitHub issue/PR follow-up.Report list/detail controls, status transitions, and GitHub URL updates.

Non-Goals

  • No developer ranking, scoring, comparison, or KPI dashboards.
  • No OTel dashboard embedded as the product adoption UI.
  • No new product events beyond the five locked v1 happy-path events.
  • No automatic GitHub issue creation without explicit credentials/config.
  • No consumer-repo business logic inside apps/cli.
  • No public web or customer-facing backoffice surface.

Acceptance Criteria

  • apps/backoffice exists as a separate internal app, not inside apps/web.
  • Root Turborepo scripts delegate backoffice development/build/typecheck through package tasks.
  • Better Auth bearer/device authorization supports canonical operator identity for CLI/API/backoffice sessions.
  • Git identity remains stored and displayed only as observed metadata/fallback context.
  • packages/contract exposes typed backoffice project usage and report triage endpoints.
  • apps/api exposes authenticated backoffice read/update handlers backed by Postgres when database persistence is enabled.
  • Project usage list shows project name/id, repository count, counted event count, open report count, latest CLI version, latest baseline/channel/version, and last activity.
  • Project usage detail shows mapped observed repositories, recent happy-path events, and recent/open reports.
  • Backoffice can ignore local/test/debug/CI events in adoption counts.
  • Backoffice can map an observed repository into an existing project usage aggregate.
  • Backoffice report triage supports at least new, triaged, accepted, wontfix, and resolved.
  • Backoffice can link a report to a GitHub issue or pull request URL.
  • Project dashboards surface open/recent reports without merging reports into happy-path product stats.
  • UI shows operator/developer information only as audit/contact fields such as initialized by, last updated by, and report submitted by.

Constraints

  • Use ProjectUsage as the aggregate. Do not collapse project usage into repository identity.
  • apps/api owns backend/control-plane reads and writes. apps/backoffice consumes the API.
  • packages/contract is the shared typed boundary for API/backoffice contract.
  • Product telemetry remains separate from OTel.
  • Portless local URLs remain the docs/env baseline.
  • Root scripts must delegate through Turborepo package tasks.
  • Backoffice is internal/private. apps/web stays parked public surface.

Technical Notes

  • Existing telemetry/report stores derive stable project and repository ids from explicit projectUsageId or safe repository remote identity.
  • Current database persistence keeps reports and usage events nullable when no repository/project identity exists. Backoffice should surface linked data where present and not manufacture project usage from report titles.
  • Backoffice read APIs can return a purpose-built read model instead of exposing raw Drizzle rows.
  • Local token-based development remains usable as an explicit development escape hatch.

Validation Plan

  • Contract schema tests for backoffice summary/detail/report update payloads.
  • API tests for project usage summary/detail, source filtering, repository mapping, and report status/GitHub updates.
  • Backoffice typecheck and build.
  • Browser smoke for the backoffice dashboard at the local dev URL.
  • Root bun run check-types and targeted package tests.

Decision Log

DecisionRationale
Create one parent-scoped spec for IP-138 through IP-143The child stories form one dependency graph and one product capability.
Keep reports separate from adoption eventsReports are friction/support evidence, not happy-path usage stats.
Use GitHub URL linking before automatic issue creationIt satisfies v1 follow-up without requiring GitHub credentials in the backoffice.
Keep Better Auth bearer/device auth as the identity flowLocal development can keep token auth while production can use authenticated operator sessions.

Open Questions

#QuestionAffectsOwnerStatus
1Which exact production auth host and cookie-domain env values are canonical?Deployment docsDeliveryNon-blocking; deployment-specific values live outside the spec.

On this page