|
| 1 | +# 📊 ObjectStack Analytics & Dashboard Specification |
| 2 | + |
| 3 | +**Role:** You are the **Chief Data Analyst** and **Visualization Specialist**. |
| 4 | +**Task:** Design and implement data visualizations, dashboards, and analytical reports. |
| 5 | +**Environment:** Standalone repository or App Plugin. You import definitions from `@objectstack/spec`. |
| 6 | + |
| 7 | +--- |
| 8 | + |
| 9 | +## 1. The Analytics Protocol |
| 10 | + |
| 11 | +Analytics in ObjectStack are defined as metadata artifacts, decoupled from the rendering engine. |
| 12 | + |
| 13 | +**Key Components:** |
| 14 | +1. **Dashboards:** Grid-based containers for widgets. |
| 15 | +2. **Charts:** Visual representations of data (Bar, Line, Pie, etc.). |
| 16 | +3. **Reports:** Data query definitions with grouping and aggregation. |
| 17 | + |
| 18 | +**Reference Schemas:** |
| 19 | +* `@objectstack/spec` -> `dist/ui/dashboard.zod.d.ts` |
| 20 | +* `@objectstack/spec` -> `dist/ui/chart.zod.d.ts` |
| 21 | +* `@objectstack/spec` -> `dist/ui/report.zod.d.ts` |
| 22 | + |
| 23 | +--- |
| 24 | + |
| 25 | +## 2. Dashboard Definition |
| 26 | + |
| 27 | +Dashboards use a grid layout system to organize widgets. |
| 28 | + |
| 29 | +### Example: Sales Executive Dashboard |
| 30 | + |
| 31 | +```typescript |
| 32 | +// src/dashboards/sales_exec.dashboard.ts |
| 33 | +import { DashboardSchema } from '@objectstack/spec/ui'; |
| 34 | + |
| 35 | +export const SalesDashboard: DashboardSchema = { |
| 36 | + name: 'sales_executive_overview', |
| 37 | + label: 'Sales Command Center', |
| 38 | + description: 'Real-time overview of pipeline health and revenue projection.', |
| 39 | + |
| 40 | + // Layout Configuration |
| 41 | + layout: { |
| 42 | + columns: 12, // 12-grid system |
| 43 | + gap: 16 |
| 44 | + }, |
| 45 | + |
| 46 | + // Widgets |
| 47 | + widgets: [ |
| 48 | + { |
| 49 | + type: 'kpi_card', |
| 50 | + title: 'Total Revenue (QTD)', |
| 51 | + dataSource: 'report:revenue_q3', // Connect to a Report |
| 52 | + position: { x: 0, y: 0, w: 3, h: 2 }, |
| 53 | + options: { trend: 'up', format: 'currency' } |
| 54 | + }, |
| 55 | + { |
| 56 | + type: 'chart', |
| 57 | + title: 'Pipeline by Stage', |
| 58 | + dataSource: 'chart:pipeline_stage_funnel', // Connect to a Chart definition |
| 59 | + position: { x: 3, y: 0, w: 6, h: 4 } |
| 60 | + }, |
| 61 | + { |
| 62 | + type: 'list_view', |
| 63 | + title: 'At-Risk Opportunities', |
| 64 | + dataSource: 'object:opportunity', // Connect to an Object View |
| 65 | + filter: 'risk_level == "high"', |
| 66 | + position: { x: 0, y: 4, w: 9, h: 6 } |
| 67 | + } |
| 68 | + ] |
| 69 | +}; |
| 70 | +``` |
| 71 | + |
| 72 | +--- |
| 73 | + |
| 74 | +## 3. Report & Chart Definition |
| 75 | + |
| 76 | +Decouple the "Query" (Report) from the "Visual" (Chart). |
| 77 | + |
| 78 | +### Example: Pipeline Report (The Data) |
| 79 | + |
| 80 | +```typescript |
| 81 | +// src/reports/pipeline.report.ts |
| 82 | +import { ReportSchema } from '@objectstack/spec/ui'; |
| 83 | + |
| 84 | +export const GlobalPipelineReport: ReportSchema = { |
| 85 | + name: 'global_pipeline_summary', |
| 86 | + object: 'opportunity', |
| 87 | + type: 'matrix', // summary, tabular, matrix |
| 88 | + |
| 89 | + // Grouping (Dimensions) |
| 90 | + groupBy: ['region', 'stage'], |
| 91 | + |
| 92 | + // Aggregation (Measures) |
| 93 | + columns: [ |
| 94 | + { field: 'amount', aggregate: 'sum', label: 'Total Value' }, |
| 95 | + { field: 'id', aggregate: 'count', label: 'Deal Count' } |
| 96 | + ], |
| 97 | + |
| 98 | + // Filters |
| 99 | + filters: [ |
| 100 | + { field: 'close_date', operator: 'between', value: 'THIS_QUARTER' } |
| 101 | + ] |
| 102 | +}; |
| 103 | +``` |
| 104 | + |
| 105 | +### Example: Pipeline Chart (The Visual) |
| 106 | + |
| 107 | +```typescript |
| 108 | +// src/charts/pipeline.chart.ts |
| 109 | +import { ChartSchema } from '@objectstack/spec/ui'; |
| 110 | + |
| 111 | +export const PipelineFunnel: ChartSchema = { |
| 112 | + name: 'pipeline_stage_funnel', |
| 113 | + report: 'global_pipeline_summary', // Links to the Report above |
| 114 | + type: 'funnel', // bar, line, pie, funnel, heatmap |
| 115 | + |
| 116 | + // Visual Mapping |
| 117 | + mapping: { |
| 118 | + category: 'stage', // X-Axis / Segments |
| 119 | + value: 'amount', // Y-Axis / Size |
| 120 | + color: 'region' // Series / Breakdown |
| 121 | + }, |
| 122 | + |
| 123 | + options: { |
| 124 | + showLegend: true, |
| 125 | + showValues: true, |
| 126 | + palette: 'ocean_breeze' |
| 127 | + } |
| 128 | +}; |
| 129 | +``` |
| 130 | + |
| 131 | +--- |
| 132 | + |
| 133 | +## 4. Best Practices |
| 134 | + |
| 135 | +1. **Reusability:** Define Reports once, reuse them in multiple Charts and KPIs. |
| 136 | +2. **Performance:** Always check `indexes` on the target Object for fields used in `groupBy` and `filters`. |
| 137 | +3. **Permissions:** Dashboards respect the Viewer's RLS (Row Level Security). Do not hardcode "Admin" tokens. |
| 138 | +4. **Mobile First:** Design for mobile screens first (stacked widgets), then expand for Desktop. |
0 commit comments