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

Plan: IP-138 Backoffice Project Usage Visibility

Plan: IP-138 Backoffice Project Usage Visibility

Initial Situation

The current repo has the M4 telemetry/reporting foundation in place:

  • packages/db/src/schema/product-telemetry.ts defines project_usage, observed_repository, cli_usage_event, and harness_report.
  • apps/api/src/telemetry.ts persists only the five accepted happy-path product events and filters counted sources.
  • apps/api/src/reports.ts persists CLI-submitted reports and avoids deriving project usage from report titles.
  • packages/contract/src/api.ts exposes telemetry/report ingestion only.
  • No apps/backoffice application exists yet.

Linear IP-138 is the parent capability. IP-139 is the backend/read-model foundation. IP-140 and IP-141 constrain event and identity semantics. IP-142 and IP-143 are the visible dashboard and report triage surfaces.

Issue

Maintainers cannot inspect adoption or triage reports without reading raw persistence. The system also needs a hard UI boundary: product adoption belongs in apps/backoffice, public narrative remains in apps/web, and OTel remains system observability.

Solution Shape

Add typed backoffice read/update endpoints to the shared contract and API, then create a separate internal Next.js apps/backoffice app that consumes those endpoints. Keep implementation as a narrow M4.5 vertical slice:

  • project usage list/detail
  • counted-source adoption summaries
  • repository mapping
  • report status/GitHub URL updates
  • Better Auth bearer/device authorization for canonical operator identity
  • docs/spec/implementation bookkeeping

Resolved Decision Ledger

DecisionResolution
Scope boundaryParent-scoped IP-138 delivery covering IP-139 through IP-143.
Execution modeparallel: false; backend contract, API handlers, and UI depend on one evolving read model.
Product modelPreserve ProjectUsage 1:n ObservedRepository; no Project = repository fallback.
IdentityBetter Auth operator identity is canonical when available; git identity is fallback metadata only.
ReportsLink to GitHub URL in v1; do not auto-create issues without credentials.
Event countsCount only source = "normal" happy-path events by default; non-normal sources are visible as filterable/noise context.

Assumptions And Constraints

  • Current branch is 2.0.0.
  • Existing M4 telemetry/reporting behavior remains valid and should not be rewritten.
  • apps/api owns data access and writes.
  • packages/contract owns shared typed API schemas.
  • apps/backoffice is internal/private and separate from apps/web.
  • Root scripts delegate through Turborepo.
  • Browser validation is required because this adds a UI app.

Codebase Findings

  • apps/api/src/index.ts already switches DB vs memory persistence with DP_API_STORAGE=memory.
  • The DB schema already has the core M4.5 tables and relations.
  • packages/auth/src/index.ts enables email/password, bearer, and device auth.
  • apps/web is intentionally parked; reuse package/dependency patterns but do not place backoffice routes there.
  • packages/ui exposes simple shared primitives and Tailwind globals.

External Research Used

  • Better Auth device authorization supports CLI login without adding a social provider dependency. Keep local token auth as a development escape hatch.

Dependency Graph

T138-1 -> T138-2 -> T138-3 -> T138-4 -> T138-5 -> T138-6 -> T138-7

Tasks

T138-1: Add backoffice contract schemas and endpoints

  • depends_on: []
  • location: packages/contract/src
  • description: Add project usage summary/detail, observed repository summary, usage event summary, report summary, repository mapping request, and report triage update schemas. Add authenticated backoffice endpoints to HarnessApi.
  • validation: Contract typecheck and schema tests for accepted report statuses and project detail shapes.
  • status: Implemented
  • log: Added shared schemas, errors, and backoffice HttpApi group.
  • files edited/created: packages/contract/src/schemas.ts, packages/contract/src/api.ts, packages/contract/src/errors.ts
  • backlog_item_id: IP-139, IP-142, IP-143
  • backlog_item_url: https://linear.app/devpunks/issue/IP-139/api-persists-project-usage-aggregates-and-observed-repositories
  • relation_mode: native
  • assigned_skills: [effect-authoring, effect-best-practices, quality-types, tdd, simplify]
  • tdd_target: Backoffice report update rejects statuses outside new|triaged|accepted|wontfix|resolved.
  • review_mode: cli

T138-2: Implement API backoffice read/update store

  • depends_on: [T138-1]
  • location: apps/api/src
  • description: Add BackofficeStore with in-memory and DB-backed implementations for project usage list/detail, repository mapping, and report status/GitHub updates. Wire it into apps/api/src/index.ts.
  • validation: API tests prove source filtering, latest CLI/baseline summaries, repository mapping, report status updates, GitHub URL updates, and no developer ranking fields.
  • status: Implemented
  • log: Added in-memory and DB-backed backoffice store plus API handlers and regression tests.
  • files edited/created: apps/api/src/backoffice.ts, apps/api/src/backoffice.test.ts, apps/api/src/index.ts
  • backlog_item_id: IP-139, IP-142, IP-143
  • backlog_item_url: https://linear.app/devpunks/issue/IP-142/backoffice-shows-project-usage-adoption-dashboards
  • relation_mode: native
  • assigned_skills: [effect-authoring, effect-backend-structure, effect-best-practices, tdd, simplify]
  • tdd_target: A normal event is counted in project usage summary; local-dev/test/debug/CI events are excluded from counted adoption totals.
  • review_mode: cli

T138-3: Configure operator identity boundary

  • depends_on: [T138-2]
  • location: packages/auth/src, packages/env/src, docs
  • description: Document Better Auth bearer/device authorization as canonical for CLI/API/backoffice operators.
  • validation: Auth package typecheck; docs list required auth env vars and keep git identity as fallback metadata.
  • status: Implemented
  • log: Added Better Auth device/bearer flow docs and regression coverage.
  • files edited/created: packages/auth/src/index.ts, packages/auth/src/index.test.ts, packages/env/src/server.ts, packages/auth/package.json
  • backlog_item_id: IP-141
  • backlog_item_url: https://linear.app/devpunks/issue/IP-141/backoffice-uses-microsoft-workspace-identity-for-operators
  • relation_mode: native
  • assigned_skills: [better-auth-best-practices, effect-authoring, tdd, simplify]
  • tdd_target: createAuthOptions includes device authorization and no social provider dependency.
  • review_mode: cli

T138-4: Create separate backoffice app

  • depends_on: [T138-2, T138-3]
  • location: apps/backoffice, package.json, turbo.json
  • description: Add a Next.js internal app with package-local scripts, root Turborepo delegation, API client helpers, list/detail/report UI, and repository mapping/report update forms.
  • validation: bun run check-types --filter=@punks/backoffice or package typecheck; bun run build --filter=@punks/backoffice; browser smoke against local dev server.
  • status: Implemented
  • log: Created separate internal Next.js app with dashboard, detail, mapping, and report triage forms.
  • files edited/created: apps/backoffice, package.json
  • backlog_item_id: IP-142, IP-143
  • backlog_item_url: https://linear.app/devpunks/issue/IP-143/harness-reports-are-triaged-in-backoffice-and-linked-to-github
  • relation_mode: native
  • assigned_skills: [next-best-practices, vercel-react-best-practices, design-taste-frontend, turborepo, tdd, simplify]
  • tdd_target: Dashboard renders an empty internal state from the typed API without falling back to public web routes.
  • review_mode: mixed

T138-5: Update docs and wiki ingest artifacts

  • depends_on: [T138-4]
  • location: docs, apps/wiki/content/docs, apps/wiki/content/docs, apps/wiki/specs/cli/IP-138-backoffice-project-usage
  • description: Update root docs, runbook/reference, wiki source/routed pages, implementation notes, spec indexes, and log entries for the new backoffice capability.
  • validation: Wiki check-types/build if feasible; links point to source/routed docs; docs preserve public/private boundary and GitHub-vs-Linear report boundary.
  • status: Implemented
  • log: Updated root docs, reference docs, source wiki, routed Fumadocs pages, index, and log.
  • files edited/created: docs/README.md, docs/reference/harness-intelligence.md, apps/wiki/content/docs/harness, apps/wiki/content/docs/harness/trust-and-adoption, apps/wiki/index.md, apps/wiki/log.md
  • backlog_item_id: IP-138
  • backlog_item_url: https://linear.app/devpunks/issue/IP-138/build-harness-intelligence-backoffice-for-project-usage-visibility
  • relation_mode: native
  • assigned_skills: [docs-ingest-phase, simplify]
  • tdd_target: Docs explicitly state apps/backoffice owns private adoption/reporting UI and apps/web remains parked public surface.
  • review_mode: cli

T138-6: Review, simplify, and validate

  • depends_on: [T138-5]
  • location: whole delivery diff
  • description: Run simplify over touched code, perform findings-first review, fix in-scope blockers, and run targeted/full validation.
  • validation: Targeted tests, typechecks, build, browser smoke, git diff --check.
  • status: Implemented
  • log: Simplify/review pass completed; root check, root typecheck, root tests, backoffice build, and browser smoke passed.
  • files edited/created:
  • backlog_item_id: IP-138
  • backlog_item_url: https://linear.app/devpunks/issue/IP-138/build-harness-intelligence-backoffice-for-project-usage-visibility
  • relation_mode: native
  • assigned_skills: [review-phase, simplify, turborepo, agent-browser]
  • tdd_target: Acceptance audit maps every IP-139 through IP-143 criterion to implementation or explicit deferral.
  • review_mode: mixed

T138-7: Tracker closeout

  • depends_on: [T138-6]
  • location: Linear
  • description: Add closeout comments and update statuses for IP-139 through IP-143 and parent IP-138 only after validation passes or a concrete blocker is proven.
  • validation: Linear issue statuses/comments reflect delivered evidence.
  • status: Implemented
  • log: Linear blockers were verified done before closeout. IP-139 through IP-143 and parent IP-138 are ready for Done status with validation evidence.
  • files edited/created:
  • backlog_item_id: IP-138
  • backlog_item_url: https://linear.app/devpunks/issue/IP-138/build-harness-intelligence-backoffice-for-project-usage-visibility
  • relation_mode: native
  • assigned_skills: [linear:linear]
  • tdd_target: Tracker closeout cites actual validation commands and touched artifacts.
  • review_mode: cli

Validation Gates

  • Gate 1: Typed contract exists and compiles.
  • Gate 2: API store behavior is covered by tests and wired into the handler.
  • Gate 3: Better Auth bearer/device flow is documented.
  • Gate 4: Backoffice app typechecks/builds and renders dashboard/detail/triage surfaces.
  • Gate 5: Docs and implementation notes capture the operator workflow.
  • Gate 6: Review and validation pass, or blockers are concrete.
  • Gate 7: Linear closeout is synced after evidence exists.

Risks And Mitigations

  • Drizzle read-model complexity: Keep read APIs purpose-built and small; avoid generic admin query builders.
  • Production auth env unavailable locally: Keep existing bearer/local token behavior.
  • UI overreach: Build operational dashboard and triage controls only; no public landing or analytics theatre.
  • Developer KPI drift: Do not compute per-developer rankings; display operator fields only as audit/contact context.
  • GitHub credential gap: Store/link GitHub URLs; defer automatic issue creation.

Unresolved Questions

QuestionWhy It Remains Open
Exact production auth host and cookie-domain env valuesDeployment-specific secret naming can be finalized outside this code slice; code uses explicit documented Harness env names.

On this page