Replacing fixed, request-driven reports with a builder that lets seven business roles answer their own questions from live ERP data — without waiting on the team to produce a one-off view.
Some data and figures altered to respect client confidentiality.
What I owned. The widget-builder interaction model, the role-based dashboard system, dashboard composition, and the migration of the legacy KPI screens into Portal 3.0.
What this initiative focused on. Moving insight from request-driven reports to self-serve; making each role's view relevant by default; reducing the report-request load on the team.
The business analyst authored the BRD and stayed the requirements owner through build. Design owned the parts the requirements listed but didn't specify how they'd feel in the product — the builder flow, the role-view system, and composition behaviour.
The failure. ERP 2.0 reporting was static tables filtered by date — no charts, no custom widgets, no dashboards, no period comparison, no role views. Operators could see a slice of history; they couldn't ask a new question.
Why it was systemic. Insight was gated: every non-standard question became a report request routed through the team. The ERP held orders, inventory, sales, accounting, finance, product, and purchasing data — but turning that data into an answer required someone else to build the view.
Why it compounded at scale. 16,000+ SKUs, multiple domains, and seven business roles meant bespoke-report demand grew faster than the team could serve it. Each new product line and warehouse added more questions the static screens couldn't answer.
Who bore the cost. Operators waited on reports or decided blind — exporting tables to Excel for weekly reviews. The team spent its time producing one-off views instead of designing the product forward.
How I researched. Before opening Figma I worked with the BA to map role personas across the five role audiences in the brief — Accounting, Finance, Product, Purchasing, and CEO/overview — against the metrics each group actually acts on, not just the ones they could technically access. I audited the two legacy KPI 2.0 screens (Sales Summary and Sales Breakdown) to see what operators already trusted, sat with engineering on what the ERP data layer could expose per domain in Phase 1, and traced how non-standard questions currently became report requests.
Signals from the research (paraphrased from stakeholder sessions — not verbatim quotes):
The key insight. The same data served seven roles, but every role needed a different slice — and the report queue was the bottleneck, not the data. That shifted the goal from "more reports" to "self-serve."
Add more chart types and reports to the existing KPI screens — expand the fixed library the team already maintained.
Stop producing reports for people; build a system they compose themselves — widgets they create, dashboards they arrange, role views that arrive already relevant.
Alternatives explored — and why each was rejected or chosen:
Expand the fixed report library. Faster to ship incrementally, but doesn't scale — every new question still routes through the team and the queue stays.
Embed a third-party BI tool. Looked attractive on paper; rejected on cost, data governance, and fit inside the ERP — operators needed insight in the same session as orders and inventory, not a separate login.
A self-serve widget + dashboard builder. Moves access upstream to the user, scales across roles, and stays inside Portal 3.0's permission model — at the cost of a far more complex interaction design problem.
Core mechanism. A widget is a guided sequence — domain → measure(s) → dimension(s) → filters → visualisation → aggregate function — where each step constrains the next so an invalid combination can't be assembled.
The source of truth: domain-as-gate. Picking a domain (Phase 1: Orders, Inventory) filters which measures, dimensions, and charts are even offered — so a purchasing head can't accidentally build a widget the data layer can't support.
The key tradeoff balanced. Configurability vs usability — a builder deep enough to answer real questions, shaped into a short guided path a non-analyst can complete without training.
Progressive disclosure over a single dense form. Engineering could have shipped one long configuration panel. A stepped builder means more clicks for power users; the payoff is completion rate for the audiences this module is actually for.
Disable invalid options, don't error on them. Group-by and certain chart types simply don't appear when they don't apply — prevents the failure instead of explaining it.
Rather than walking module-by-module, the product reads as a single lifecycle: create a widget, arrange it on a dashboard, then consume the right view for your role.
Build a widget — the guided builder.
Domain selection gates everything downstream. The user picks measures and dimensions, sets filters, chooses a visualisation and aggregate function, and saves — or duplicates via "Save as New" scoped to the dashboard they're in. Name capped at 50 characters; export as PNG; auto-refresh on a toggle.
Compose a dashboard — drag, resize, arrange.
Users build a dashboard from saved and pre-defined widgets, then drag, drop, and resize on a grid-constrained layout so proportions stay readable on every device. Per-widget controls: view (data table in a new page), edit/duplicate, export PNG, remove. Global date filter cascades to every widget. Set a default landing dashboard; favourite for quick retrieval.
Consume by role — default views and the permission model.
Each role gets a dashboard scoped to the KPIs that match its responsibility — with admins able to configure what's visible per role, and data filtered per-user at the backend. Role views are a focus tool, not just a security gate: the dashboard arrives already relevant.
Feature & permission matrix (from BRD; role columns subject to final sign-off):
| Capability | Admin | Accounting | Finance | Product | Purchasing | CEO |
|---|---|---|---|---|---|---|
| Create widget | ✓ | ✓ | ✓ | ✓ | ✓ | — |
| Save dashboard | ✓ | ✓ | ✓ | ✓ | ✓ | — |
| Download / export | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Filters / sort | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Group by | ✓ | ✓ | ✓ | ✓ | ✓ | — |
| Expanded view | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Favourite | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Resize widgets | ✓ | ✓ | ✓ | ✓ | ✓ | — |
| Metric domain | Accounting | Finance | Product | Purchasing | CEO / Overall |
|---|---|---|---|---|---|
| Accounting metrics | ✓ | ✓ | — | — | ✓ |
| Revenue metrics | — | ✓ | ✓ | — | ✓ |
| Product metrics | — | — | ✓ | ✓ | ✓ |
| Orders / inventory | — | ✓ | ✓ | ✓ | ✓ |
Matrix structure follows the BRD; exact role permissions were marked "not finalized" in the source document.
Migrate legacy screens as system dashboards instead of rebuilding them. Sales Summary and Sales Breakdown already had operator trust. Re-skinning them as read-only system dashboards preserved that trust while the new builder rolled out alongside.
Grid-constrained resize instead of free-form canvas. Free drag looks flexible in a demo and breaks in production — uneven gutters, unreadable charts on mobile. Locking resize to the grid was the fork I chose.
Portal 3.0 KPI is in staged rollout — Purchasing and Finance teams onboarded first because their Phase 1 domains (Orders, Inventory) were complete. The honest baseline isn't adoption percentages yet; it's whether self-serve replaces the behaviours that created the queue.
What shipped (factual):
Measured signal: Rollout in progress — early signals being measured. No adoption percentages to report yet; the module hasn't been live long enough for quantified usage data.
When several roles need different answers from the same data, don't build several reports — build one system that adapts to who's asking. — Principle carried forward
The manual builder is powerful, but it's still a sequence — domain, measures, dimensions, filters, chart. The AI widget builder, now in validation, collapses that to a sentence: a user describes the answer they want, and the system drafts a complete widget — filling the same guided structure — for the user to verify and adjust.
How it works (in validation — flow subject to change):
Why it reuses the manual builder's guardrails. Because the AI fills the same domain-gated structure, it can't produce an invalid widget — domain constraints, valid measure/dimension pairings, and chart rules apply to AI output the same way they apply to a human clicking through the steps.
Trust design (same AI-cell pattern as the HikeOn use cases): the draft is the suggestion; ambiguity and confidence are surfaced when the parse isn't certain; the visible config is the "why this?"; and the user can accept, edit, or dismiss. The AI proposes; the user still owns the widget.
What we're testing. Parse accuracy against real operator requests; whether users trust and keep the draft or heavily edit it; time-to-widget vs the manual builder flow. Sessions with Purchasing and Finance operators who already use the shipped builder.
Status. Validation in progress — no measured results yet. This section gets numbers when the sessions produce them, not before.