256 lines
31 KiB
Markdown
256 lines
31 KiB
Markdown
# Feature Specification: Product Usage & Adoption Telemetry
|
|
|
|
**Feature Branch**: `243-product-usage-adoption-telemetry`
|
|
**Created**: 2026-04-26
|
|
**Status**: Ready for implementation
|
|
**Input**: User description: "Promote the roadmap-fit candidate Product Usage & Adoption Telemetry as a narrow, implementation-ready slice that introduces a privacy-aware internal product telemetry contract for high-signal adoption events across onboarding readiness, support diagnostics, tenant-bound operations, stored reports, and review-pack generation. The slice should reuse existing workspace and tenant context resolution plus existing source records, keep telemetry truth separate from AuditLog and OperationRun truth, and surface only one basic operator-facing aggregate on the existing system dashboard. Out of scope: third-party analytics, passive page-view tracking, session recording, customer-facing analytics dashboards, marketing attribution, free-text metadata, or a broad BI platform."
|
|
|
|
## Spec Candidate Check *(mandatory — SPEC-GATE-001)*
|
|
|
|
- **Problem**: TenantPilot still lacks a product-owned signal for whether high-value product capabilities are actually being used after onboarding. Founder and system operators must infer adoption from support conversations, raw database inspection, or unrelated logs.
|
|
- **Today's failure**: The product cannot answer which tenant-bound workflows are being adopted, where usage is stalling, or whether support, stored-report, and review-pack features are being used at all without mixing advisory telemetry into AuditLog or reading domain tables manually.
|
|
- **User-visible improvement**: A platform operator can open the existing system dashboard and see one privacy-aware adoption summary for a bounded set of high-signal product milestones, while later health-score and lifecycle features can consume the same telemetry truth instead of re-inventing their own counters.
|
|
- **Smallest enterprise-capable version**: Introduce one tenant-owned telemetry event ledger plus one code-owned event catalog for a bounded first slice of user-initiated milestones only: onboarding checkpoint completed, support diagnostics opened, tenant-bound operation started, stored report created, and review-pack generation requested. Surface only an aggregate KPI-style summary on the existing `/system` dashboard.
|
|
- **Explicit non-goals**: No third-party analytics vendor, no passive page-view or session replay tracking, no customer-facing analytics, no marketing attribution, no full event browser, no broad BI dashboard, no telemetry for pre-tenant onboarding drafts, no raw payload capture, no free-text metadata, and no repurposing of `AuditLog`, `OperationRun`, or `UserTenantPreference` as the telemetry store.
|
|
- **Permanent complexity imported**: One new tenant-owned table and model, one bounded telemetry catalog, one recorder and summary query path, one system dashboard widget, one retention/pruning rule, and focused unit plus feature coverage.
|
|
- **Why now**: Self-Service Tenant Onboarding & Connection Readiness is already Spec 240, Support Diagnostic Pack is already Spec 241, and Operational Controls is already Spec 242. Customer Health Score, lifecycle communication, and later AI-governed product operations all depend on reliable adoption signals rather than anecdotes.
|
|
- **Why not local**: Local counters on one page or model would either mix telemetry into unrelated source-of-truth tables or leave future adoption consumers to scrape several different domain records with inconsistent semantics.
|
|
- **Approval class**: Core Enterprise
|
|
- **Red flags triggered**: New persistence, new meta-infrastructure, foundation-sounding theme. Defense: the slice is explicitly limited to five code-owned event names, one aggregate dashboard widget, tenant-owned rows only, and no customer-facing analytics or generic instrumentation platform.
|
|
- **Score**: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexität: 1 | Produktnähe: 1 | Wiederverwendung: 2 | **Gesamt: 10/12**
|
|
- **Decision**: approve
|
|
|
|
## Spec Scope Fields *(mandatory)*
|
|
|
|
- **Scope**: platform, workspace, tenant
|
|
- **Primary Routes**:
|
|
- `/system` existing system dashboard for aggregate telemetry visibility
|
|
- `/admin/onboarding/{onboardingDraft}` and the linked `/admin/onboarding` resume flow when a tenant is already linked and an onboarding checkpoint transition occurs
|
|
- Tenant-bound support diagnostics entry points on the tenant dashboard and canonical operation detail viewer
|
|
- Existing tenant-bound operation start, stored-report creation, and review-pack generation seams
|
|
- **Data Ownership**: `product_usage_events` is tenant-owned telemetry truth. Every row must include `workspace_id` and `tenant_id` as non-null scope columns. Source truth remains on `TenantOnboardingSession`, `OperationRun`, `StoredReport`, `ReviewPack`, and the existing support-diagnostics actions. The system dashboard reads aggregate summaries over those tenant-owned rows but does not become the source of truth.
|
|
- **RBAC**: Telemetry writes occur only after the originating admin-plane action or service has already resolved workspace membership, tenant entitlement, and any required capability. No tenant/admin plane telemetry viewer is introduced. Aggregate read access remains system-plane only through the existing system dashboard access rules; tenant/admin users cannot query raw telemetry rows in this slice.
|
|
|
|
For canonical-view specs, the spec MUST define:
|
|
|
|
- **Default filter behavior when tenant-context is active**: N/A - the first visibility surface is the existing `/system` dashboard, not an admin-plane tenant-context collection view.
|
|
- **Explicit entitlement checks preventing cross-tenant leakage**: Tenant telemetry rows stay tenant-owned, and the system dashboard surfaces only aggregate counts and bounded labels in v1. No raw event list or cross-tenant record drilldown is introduced.
|
|
|
|
## Cross-Cutting / Shared Pattern Reuse *(mandatory when the feature touches notifications, status messaging, action links, header actions, dashboard signals/cards, alerts, navigation entry points, evidence/report viewers, or any other existing shared operator interaction family; otherwise write `N/A - no shared interaction family touched`)*
|
|
|
|
- **Cross-cutting feature?**: yes
|
|
- **Interaction class(es)**: dashboard signals/cards, onboarding milestone capture, support action capture, operation-start capture, report-generation capture
|
|
- **Systems touched**: system dashboard widget composition, onboarding lifecycle transitions, support diagnostics actions, tenant-bound operation start services, stored-report generation services, review-pack generation service, and existing tenant-context resolution at the app boundary
|
|
- **Existing pattern(s) to extend**: existing system dashboard widget pattern, source-owned service/action seams, and current workspace/tenant context derivation before writes
|
|
- **Shared contract / presenter / builder / renderer to reuse**: `App\Filament\System\Pages\Dashboard`, `App\Filament\System\Widgets\ControlTowerKpis`, `App\Services\Onboarding\OnboardingLifecycleService`, `App\Support\SupportDiagnostics\SupportDiagnosticBundleBuilder`, `App\Services\OperationRunService`, `App\Services\EntraAdminRoles\EntraAdminRolesReportService`, `App\Services\PermissionPosture\PermissionPostureFindingGenerator`, and `App\Services\ReviewPackService`
|
|
- **Why the existing shared path is sufficient or insufficient**: The repo already has trustworthy source seams for when a high-signal milestone happens, and it already has a native system dashboard widget surface. What it does not have is one bounded telemetry contract that records those milestones without overloading AuditLog, OperationRun, or user preference state.
|
|
- **Allowed deviation and why**: One new `ProductTelemetryRecorder` plus a code-owned event catalog are allowed because telemetry semantics do not belong on existing audit or operation models. No page-local counters or domain-specific side ledgers are allowed.
|
|
- **Consistency impact**: Event names, feature-area labels, safe metadata keys, dashboard labels, and time-window semantics must stay aligned across all emission seams and the aggregate widget.
|
|
- **Review focus**: Reviewers must verify that no telemetry write piggybacks on `AuditLog`, no raw provider payload or free text is stored, no passive page-view spam is introduced, and no source seam writes telemetry before entitlement or source success is established.
|
|
|
|
## OperationRun UX Impact *(mandatory when the feature creates, queues, deduplicates, resumes, blocks, completes, or deep-links to an `OperationRun`; otherwise write `N/A - no OperationRun start or link semantics touched`)*
|
|
|
|
- **Touches OperationRun start/completion/link UX?**: no
|
|
- **Shared OperationRun UX contract/layer reused**: N/A - the slice may observe already-started tenant-bound runs as telemetry source events, but it does not change start, completion, link, or notification behavior.
|
|
- **Delegated start/completion UX behaviors**: N/A
|
|
- **Local surface-owned behavior that remains**: N/A
|
|
- **Queued DB-notification policy**: N/A
|
|
- **Terminal notification path**: N/A
|
|
- **Exception required?**: none
|
|
|
|
## Provider Boundary / Platform Core Check *(mandatory when the feature changes shared provider/platform seams, identity scope, governed-subject taxonomy, compare strategy selection, provider connection descriptors, or operator vocabulary that may leak provider-specific semantics into platform-core truth; otherwise write `N/A - no shared provider/platform boundary touched`)*
|
|
|
|
- **Shared provider/platform boundary touched?**: yes
|
|
- **Boundary classification**: mixed
|
|
- **Seams affected**: operation-type labels, report-type labels, review-pack generation source semantics, safe metadata keys, aggregate widget labels
|
|
- **Neutral platform terms preserved or introduced**: product telemetry, usage event, feature area, subject reference, occurred at, workspace, tenant, active workspace count, recent signals
|
|
- **Provider-specific semantics retained and why**: Existing canonical operation types and report types may appear in metadata when they already represent stable product-owned identifiers. Raw Graph endpoints, payloads, provider error bodies, or provider-only vocabulary stay out of telemetry rows.
|
|
- **Why this does not deepen provider coupling accidentally**: The telemetry contract records product event names and canonical source identifiers, not provider transport or payload truth. It treats provider-backed events as source references only.
|
|
- **Follow-up path**: Customer Health Score and lifecycle communication can reuse this contract later, but they remain separate specs.
|
|
|
|
## UI / Surface Guardrail Impact *(mandatory when operator-facing surfaces are changed; otherwise write `N/A`)*
|
|
|
|
| Surface / Change | Operator-facing surface change? | Native vs Custom | Shared-Family Relevance | State Layers Touched | Exception Needed? | Low-Impact / `N/A` Note |
|
|
|---|---|---|---|---|---|---|
|
|
| System dashboard telemetry widget | yes | Native Filament + shared stats widget | dashboard signals/cards | page, widget, window query | no | Read-only KPI addition on the existing `/system` dashboard |
|
|
| Source emission seams | no | N/A | none | none | no | `N/A - server-side capture only` |
|
|
|
|
## Decision-First Surface Role *(mandatory when operator-facing surfaces are changed)*
|
|
|
|
| Surface | Decision Role | Human-in-the-loop Moment | Immediately Visible for First Decision | On-Demand Detail / Evidence | Why This Is Primary or Why Not | Workflow Alignment | Attention-load Reduction |
|
|
|---|---|---|---|---|---|---|---|
|
|
| System dashboard telemetry widget | Secondary Context Surface | A platform operator reviews recent product adoption and decides whether onboarding, support, operations, stored-report, or review-pack usage needs follow-up elsewhere | Five visible event-family counts, active workspace count, and selected time window | Raw event rows are intentionally out of scope in v1; follow-up happens on existing onboarding, operations, support, stored-report, and review-pack surfaces | Not primary because this slice does not create a new queue or workflow hub; it adds context for product-operability decisions | Fits the founder/system-operator control-tower loop | Replaces manual log and database inspection with one bounded product signal summary |
|
|
|
|
## UI/UX Surface Classification *(mandatory when operator-facing surfaces are changed)*
|
|
|
|
| Surface | Action Surface Class | Surface Type | Likely Next Operator Action | Primary Inspect/Open Model | Row Click | Secondary Actions Placement | Destructive Actions Placement | Canonical Collection Route | Canonical Detail Route | Scope Signals | Canonical Noun | Critical Truth Visible by Default | Exception Type / Justification |
|
|
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
| System dashboard telemetry widget | Dashboard / Overview / KPI widget | System observability summary | Continue monitoring or open the existing product surface that needs follow-up | In-page stats widget on the system dashboard | forbidden | Existing dashboard actions remain outside the widget | none | `/system` | `/system` | Existing dashboard time window plus bounded telemetry event families | Product telemetry / Product telemetry summary | Recent high-signal usage counts and active-workspace participation | none |
|
|
|
|
## Operator Surface Contract *(mandatory when operator-facing surfaces are changed)*
|
|
|
|
| Surface | Primary Persona | Decision / Operator Action Supported | Surface Type | Primary Operator Question | Default-visible Information | Diagnostics-only Information | Status Dimensions Used | Mutation Scope | Primary Actions | Dangerous Actions |
|
|
|---|---|---|---|---|---|---|---|---|---|---|
|
|
| System dashboard telemetry widget | Platform operator / founder | Decide whether onboarding, support, operations, stored reports, and review packs show real recent adoption | Dashboard widget | Which tenant-bound product capabilities are being used recently, and across how many workspaces? | Five visible event-family counts, active workspace count, and selected time window | Raw event rows, subject-specific drilldowns, and customer-facing reporting remain out of scope | adoption volume, signal freshness | none | existing dashboard window selection only | none |
|
|
|
|
## UI Action Matrix *(mandatory when Filament is changed)*
|
|
|
|
| Surface | Location | Header Actions | Inspect Affordance (List/Table) | Row Actions (max 2 visible) | Bulk Actions (grouped) | Empty-State CTA(s) | View Header Actions | Create/Edit Save+Cancel | Audit log? | Notes / Exemptions |
|
|
|---|---|---|---|---|---|---|---|---|---|---|
|
|
| System dashboard telemetry widget | `App\Filament\System\Pages\Dashboard` + `App\Filament\System\Widgets\ProductTelemetryKpis` | Reuse the existing dashboard `Time window` action; no new header action for telemetry | n/a | none | none | none added; widget renders its own zero-state summary | n/a | n/a | no | Read-only stats widget only; no new action group, no drilldown list, no destructive behavior |
|
|
|
|
## Proportionality Review *(mandatory when structural complexity is introduced)*
|
|
|
|
- **New source of truth?**: yes
|
|
- **New persisted entity/table/artifact?**: yes
|
|
- **New abstraction?**: yes
|
|
- **New enum/state/reason family?**: yes, one bounded telemetry event catalog and feature-area classification
|
|
- **New cross-domain UI framework/taxonomy?**: no
|
|
- **Current operator problem**: Product operability decisions still depend on anecdotes and log inspection because the platform has no bounded telemetry truth for adoption milestones.
|
|
- **Existing structure is insufficient because**: `AuditLog` records compliance and mutation truth, `OperationRun` records execution truth, `StoredReport` and `ReviewPack` record artifact truth, and `UserTenantPreference` records tenant affinity. None of them can safely answer cross-feature adoption without semantic drift.
|
|
- **Narrowest correct implementation**: Add one tenant-owned event table for a bounded first-slice catalog, record events only from user-initiated high-signal source seams, and show only an aggregate KPI summary on the existing system dashboard.
|
|
- **Ownership cost**: One new model and migration, one bounded support namespace, one widget, one pruning rule, and a focused set of unit plus feature tests.
|
|
- **Alternative intentionally rejected**: Piggyback on `AuditLog`, overloading `OperationRun` context, extending `UserTenantPreference` with counters, raw page-view tracking, or integrating a third-party analytics platform.
|
|
- **Release truth**: current-release truth
|
|
|
|
### Compatibility posture
|
|
|
|
This feature assumes a pre-production environment.
|
|
|
|
Backward compatibility, legacy aliases, migration shims, historical fixtures, and compatibility-specific tests are out of scope unless explicitly required by this spec.
|
|
|
|
Canonical replacement is preferred over preservation.
|
|
|
|
## Testing / Lane / Runtime Impact *(mandatory for runtime behavior changes)*
|
|
|
|
- **Test purpose / classification**: Unit, Feature
|
|
- **Validation lane(s)**: fast-feedback, confidence
|
|
- **Why this classification and these lanes are sufficient**: Unit tests can prove event-catalog legality, metadata normalization, tenant-scope requirements, and aggregate summary queries. Feature tests can prove source capture from real service and action seams plus system-dashboard visibility and authorization without browser automation.
|
|
- **New or expanded test families**: One focused `ProductTelemetry` unit family plus targeted feature coverage for onboarding capture, support diagnostics capture, operation-start capture, report and review-pack capture, dashboard visibility, and authorization or isolation rules.
|
|
- **Fixture / helper cost impact**: Moderate. Reuse existing workspaces, tenants, users, onboarding sessions, operation runs, stored reports, and review packs. Add only one feature-local telemetry factory and a small set of feature-local assertions for safe metadata.
|
|
- **Heavy-family visibility / justification**: none
|
|
- **Special surface test profile**: standard-native-filament
|
|
- **Standard-native relief or required special coverage**: ordinary feature coverage is sufficient for the system dashboard widget. Source seams require server-side feature tests, not browser flow tests.
|
|
- **Reviewer handoff**: Reviewers must verify that no telemetry write piggybacks on `AuditLog`, no raw provider payload or free text is stored, no passive page-view spam is introduced, no source seam writes telemetry before entitlement or source success is established, and no tenant/admin telemetry viewer is introduced.
|
|
- **Budget / baseline / trend impact**: Low-to-moderate increase in narrow unit plus feature coverage only.
|
|
- **Escalation needed**: none
|
|
- **Active feature PR close-out entry**: Guardrail
|
|
- **Planned validation commands**:
|
|
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/ProductTelemetry/ProductUsageEventCatalogTest.php tests/Unit/Support/ProductTelemetry/ProductTelemetryRecorderTest.php tests/Unit/Support/ProductTelemetry/ProductTelemetrySummaryQueryTest.php tests/Unit/Support/ProductTelemetry/ProductTelemetrySafeMetadataTest.php`
|
|
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Onboarding/ProductTelemetryOnboardingCaptureTest.php tests/Feature/SupportDiagnostics/ProductTelemetrySupportDiagnosticsCaptureTest.php tests/Feature/Operations/ProductTelemetryOperationStartCaptureTest.php tests/Feature/Reports/ProductTelemetryReportCaptureTest.php`
|
|
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/System/ProductTelemetry/ProductTelemetryDashboardWidgetTest.php tests/Feature/System/ProductTelemetry/ProductTelemetryAuthorizationTest.php tests/Feature/System/ProductTelemetry/ProductTelemetryRetentionTest.php tests/Feature/System/ProductTelemetry/NoAdHocTelemetryBypassTest.php`
|
|
|
|
## User Scenarios & Testing *(mandatory)*
|
|
|
|
### User Story 1 - Record high-signal tenant usage centrally (Priority: P1)
|
|
|
|
As a platform owner, I need one bounded telemetry contract that records real tenant-bound product milestones from existing source seams so later health and lifecycle features do not have to guess adoption from unrelated models.
|
|
|
|
**Why this priority**: Without a trustworthy write path, any dashboard or health score would be based on scraped or inconsistent source data.
|
|
|
|
**Independent Test**: Trigger each supported source milestone once with an entitled tenant admin user and confirm exactly one tenant-bound telemetry row is written with safe metadata only.
|
|
|
|
**Acceptance Scenarios**:
|
|
|
|
1. **Given** an entitled tenant admin completes an onboarding checkpoint after a tenant is already linked, **When** the checkpoint transition succeeds, **Then** the system writes one telemetry event referencing the tenant, workspace, user, and onboarding subject without recording free text or raw provider data.
|
|
2. **Given** an entitled user opens support diagnostics, starts a tenant-bound operation, creates a stored report, or requests review-pack generation, **When** the source action succeeds, **Then** the system writes exactly one bounded telemetry event for that source milestone.
|
|
3. **Given** the source action fails or the tenant context is not yet established, **When** the action exits, **Then** no telemetry event is written in v1.
|
|
|
|
---
|
|
|
|
### User Story 2 - See bounded adoption signals on the system dashboard (Priority: P1)
|
|
|
|
As a platform operator, I want one read-only dashboard summary for recent product adoption so I can see whether onboarding, support, operations, stored-report, and review-pack flows are actually being used.
|
|
|
|
**Why this priority**: The telemetry foundation is not useful unless it is queryable without database inspection.
|
|
|
|
**Independent Test**: Seed bounded telemetry events across multiple workspaces and confirm the existing system dashboard shows aggregate counts for the selected time window without exposing raw rows.
|
|
|
|
**Acceptance Scenarios**:
|
|
|
|
1. **Given** recent telemetry rows exist for multiple tenants and workspaces, **When** an authorized platform user opens `/system`, **Then** the dashboard shows aggregate counts by event family and the number of active workspaces for the selected time window.
|
|
2. **Given** no recent telemetry exists in the selected window, **When** the dashboard renders, **Then** the telemetry widget shows an explicit zero-state summary instead of failing or implying missing data is healthy.
|
|
|
|
---
|
|
|
|
### User Story 3 - Keep telemetry private, tenant-bound, and cheap (Priority: P2)
|
|
|
|
As the product owner, I need telemetry to remain privacy-aware and scoped so the feature does not become a second audit log, a second operation store, or an uncontrolled analytics system.
|
|
|
|
**Why this priority**: Telemetry that leaks tenant detail or grows through noisy page events would create trust and maintenance debt immediately.
|
|
|
|
**Independent Test**: Generate supported telemetry events, inspect the stored rows and retention path, and verify that only tenant-bound safe metadata is stored and that old rows can be pruned without touching source truth.
|
|
|
|
**Acceptance Scenarios**:
|
|
|
|
1. **Given** a supported source event carries identifiers, **When** telemetry is written, **Then** only bounded IDs and enumerated metadata are stored and no raw provider payload, no email address, and no arbitrary notes are persisted.
|
|
2. **Given** a user lacks system dashboard access, **When** they attempt to read aggregate telemetry, **Then** the system denies access through the existing system-plane access rules and does not expose raw rows anywhere else.
|
|
3. **Given** telemetry rows are older than the configured 90-day retention window, **When** the daily `tenantpilot:product-usage:prune` path runs, **Then** those rows are deleted without affecting `AuditLog`, `OperationRun`, `StoredReport`, or `ReviewPack` truth.
|
|
|
|
### Edge Cases
|
|
|
|
- An onboarding draft can exist before a tenant is linked; v1 must not emit telemetry for pre-tenant onboarding activity.
|
|
- A tenant-bound `OperationRun` can be system-initiated or scheduled; v1 must not treat system-started or initiator-null runs as user-adoption signals.
|
|
- A support-diagnostics action can re-render or refresh within Livewire; v1 must emit telemetry only on the explicit successful open action, not on page render.
|
|
- A stored report or review-pack request can reuse existing source truth; v1 should emit only when a real create or request seam succeeds, not when a page merely displays an existing record.
|
|
- The selected system dashboard window can contain zero rows; the widget must render an explicit empty summary without falling back to logs or raw queries.
|
|
|
|
## Requirements *(mandatory)*
|
|
|
|
**Constitution alignment (required):** This feature adds no new Microsoft Graph call path and no new tenant-changing action. It introduces a new tenant-owned observability truth for product adoption only. It must not change existing operation, report, or review-pack execution semantics.
|
|
|
|
**Constitution alignment (PROP-001 / ABSTR-001 / PERSIST-001 / STATE-001 / BLOAT-001):** The feature introduces one new persisted truth because current-release product operability now needs a bounded adoption ledger. The design stays narrow: a tenant-owned event table, a bounded event catalog, a recorder, a summary query, and a dashboard widget. No generic analytics framework or page-view tracker is allowed.
|
|
|
|
**Constitution alignment (XCUT-001):** This slice is cross-cutting across dashboard signals and source-owned milestone seams. It must reuse the existing system dashboard widget pattern and the existing source services or actions instead of adding page-local counters.
|
|
|
|
**Constitution alignment (PROV-001):** Telemetry fields stay platform-neutral. Existing canonical operation types and report types may appear only as stable source identifiers, not as provider payload or Graph truth.
|
|
|
|
**Constitution alignment (TEST-GOV-001):** Proof stays in narrow unit and feature lanes. No browser or heavy-governance family is justified.
|
|
|
|
**Constitution alignment (RBAC-UX):** Writes occur only after the source action has already passed its existing tenant and workspace authorization. Reads remain system-plane only and rely on the existing system dashboard access rules. No tenant/admin raw telemetry viewer exists in v1.
|
|
|
|
**Constitution alignment (OPS-UX):** Existing `OperationRun` lifecycle, status, outcome, and notification rules remain unchanged. Telemetry may observe a successful user-initiated tenant-bound start but must not alter run creation or feedback.
|
|
|
|
**Constitution alignment (BADGE-001):** The system dashboard widget uses native stat presentation only; no new status-badge family is introduced.
|
|
|
|
**Constitution alignment (UI-FIL-001):** The only operator-facing addition is one native Filament system widget on the existing dashboard.
|
|
|
|
**Constitution alignment (UI-NAMING-001):** Operator-facing labels remain simple and platform-neutral, such as `Product telemetry`, `Onboarding checkpoints`, `Support diagnostics`, `Operations started`, `Stored reports`, and `Review packs requested`.
|
|
|
|
**Constitution alignment (DECIDE-001):** The widget is a secondary context surface only. It must not become a new queue or broad analytics workbench in this slice.
|
|
|
|
**Constitution alignment (OPSURF-001):** Default-visible content stays operator-first: recent counts and active-workspace participation. Raw event rows, subject lists, and payload detail remain out of scope.
|
|
|
|
### Functional Requirements
|
|
|
|
- **FR-243-001**: The system MUST define one bounded, code-owned telemetry event catalog for the first slice, limited to user-initiated tenant-bound milestones such as onboarding checkpoint completed, support diagnostics opened, tenant operation started, stored report created, and review-pack generation requested.
|
|
- **FR-243-002**: The system MUST persist telemetry in a dedicated tenant-owned table with `workspace_id` and `tenant_id` as non-null scope columns and MUST NOT store telemetry in `AuditLog`, `OperationRun`, `StoredReport`, `ReviewPack`, or `UserTenantPreference`.
|
|
- **FR-243-003**: Telemetry rows MUST record a stable event name, feature area, actor reference, subject type, subject ID, occurred-at timestamp, and safe metadata only.
|
|
- **FR-243-004**: Safe metadata MUST be limited to bounded IDs, enums, booleans, timestamps, and canonical type strings. Free-text notes, email addresses, raw provider payloads, tokens, and arbitrary JSON blobs are forbidden.
|
|
- **FR-243-005**: Telemetry capture MUST run only after the originating source action or service has succeeded and only when a real tenant context exists.
|
|
- **FR-243-006**: Pre-tenant onboarding activity and initiator-null or scheduled system actions MUST NOT be recorded as product-adoption telemetry in v1.
|
|
- **FR-243-007**: The implementation MUST instrument the existing source seams rather than page renders: onboarding checkpoint transition, support-diagnostics open action, tenant-bound user-initiated operation start, stored-report creation, and review-pack generation request.
|
|
- **FR-243-008**: The system MUST provide one aggregate, read-only telemetry summary on the existing system dashboard that reports five visible event families in v1 (`Onboarding checkpoints`, `Support diagnostics`, `Operations started`, `Stored reports`, and `Review packs requested`) plus active-workspace participation for the selected time window.
|
|
- **FR-243-009**: Only platform users who already satisfy the existing system dashboard access rules may view telemetry aggregates in v1. No tenant/admin-plane telemetry viewer or raw event list is allowed.
|
|
- **FR-243-010**: When the selected time window contains no telemetry rows, the dashboard summary MUST render an explicit zero-state rather than failing or inferring adoption from unrelated source tables.
|
|
- **FR-243-011**: Telemetry retention MUST default to 90 days through `tenantpilot.product_usage_event_retention_days`, and rows older than that window MUST be removed by the daily `tenantpilot:product-usage:prune` schedule entry in `apps/platform/routes/console.php` without touching source-of-truth records.
|
|
- **FR-243-012**: The system MUST keep telemetry query cost bounded through a summary query path and appropriate table indexes; the dashboard must not scan arbitrary application logs.
|
|
|
|
## Success Criteria
|
|
|
|
- The existing `/system` dashboard shows exactly five visible event families (`Onboarding checkpoints`, `Support diagnostics`, `Operations started`, `Stored reports`, and `Review packs requested`) plus active-workspace participation for the selected time window and renders an explicit zero state when the window has no telemetry rows.
|
|
- 100% of v1 telemetry rows store non-null `workspace_id` and `tenant_id` and originate only from the declared user-initiated source seams.
|
|
- 0 telemetry rows in v1 store raw provider payloads, email addresses, or free-text notes.
|
|
- The daily `tenantpilot:product-usage:prune` path removes telemetry rows older than the configured 90-day retention window without mutating `AuditLog`, `OperationRun`, `StoredReport`, or `ReviewPack` records.
|
|
|
|
## Assumptions
|
|
|
|
- The first implementation slice records only tenant-bound, user-initiated admin-plane usage signals.
|
|
- System dashboard access rules remain the only read gate for aggregate telemetry in v1.
|
|
- Existing operation, report, and review-pack services expose reliable success seams that can emit telemetry without inventing new workflow steps.
|
|
|
|
## Risks
|
|
|
|
- If emission is attached to noisy render paths instead of explicit service or action seams, the ledger will become unusably chatty.
|
|
- If event catalog growth is not kept bounded, the feature could drift into a generic analytics platform.
|
|
- Pre-tenant onboarding drop-off remains out of scope until a later slice can justify a separate workspace-owned telemetry truth. |