Standalone case B2B · Enterprise SaaS ERP · Web App Analytics

KPI Dashboard — a self-serve analytics system for an ERP.

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.

Product
ERP Portal 3.0
Reporting module
Role
Lead Product Designer
Builder · dashboards · migration
Team
1 BA
Design pair · eng squad · PM
Context
Restaurantware ERP
16,000+ SKUs · multi-warehouse
01 · Scope & mandate

What I owned — and what this initiative was actually for.

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.

02 · The problem, as a system

The data existed. Access to it didn't scale.

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.

03 · Discovery

Before designing the builder, I mapped who needed what — and how they got it today.

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):

  • Each role needed a different slice of the same data. Accounting cared about receivables and settlement; Purchasing about stock levels and supplier lead times; Finance about revenue mix; Product about SKU performance; the CEO view needed a cross-domain summary — not one shared dashboard.
  • The legacy screens had trust the new module had to preserve. Sales Summary and Sales Breakdown were the only KPI views operators used without workaround — their filters and defaults had to carry forward.
  • The report queue was the bottleneck, not the data. Stakeholders didn't ask for more chart types first; they asked to stop waiting. Self-serve access was the unmet need behind every feature request.
  • Phase 1 had to be honest about the data layer. Engineering could expose Orders and Inventory domains first; Products and Purchase Order would follow — the builder had to work within that constraint without feeling incomplete.

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."

04 · Constraints

The BRD set hard boundaries — and they shaped every design call.

  • Inside Portal 3.0. The module had to live within the existing ERP shell and respect role-based access control already enforced at the backend.
  • Performance. A widget must generate in under 8 seconds (NFR-02) — the builder couldn't offer combinations the data layer couldn't serve in time.
  • Migration without regression. Legacy Sales Summary and Sales Breakdown screens — and their existing filters — had to carry into 3.0 as system-defined dashboards.
  • Responsive + timestamped. Mobile-responsive across desktop, tablet, and mobile; every dashboard shows a "last updated" stamp.
  • Compliance. GDPR and SOC 2 alignment for sensitive financial data.
05 · How the thinking evolved

The reframe: from more reports to a system people compose themselves.

INITIAL FRAMING

Add more chart types and reports to the existing KPI screens — expand the fixed library the team already maintained.

SHIFTED FRAMING

Stop producing reports for people; build a system they compose themselves — widgets they create, dashboards they arrange, role views that arrive already relevant.

BEFORE · REQUEST-DRIVEN Need an answer Report request Team builds view Wait in queue Static table repeats for every new question AFTER · SELF-SERVE Compose widget + dashboard Live answer No request. No queue. No wait.
Reframe From a report queue to self-serve.

Alternatives explored — and why each was rejected or chosen:

REJECTED

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.

REJECTED

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.

CHOSEN

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.

06 · System design

Domain as gate — each step constrains the next.

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.

Domain Measures · primary metric Dimensions Filters Visualisation · aggregate each step narrows what's valid the gate · all below depends on it
System Each step only ever offers valid choices.

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.

DECISION

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.

DECISION

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.

07 · Design requirements

What the BRD required — translated into interaction rules.

  • Domain-scoped fields. Measures, dimensions, and chart types filtered by the selected domain.
  • Primary metric drives the chart; the table shows all. Multiple metrics selectable; one designated primary for the visualisation so incompatible series never share a chart.
  • Group-by on groupable charts only. Enabled for grouped bar, grouped line, and horizontal grouped bar — disabled elsewhere, not errored.
  • Aggregate functions per measure. Sum, Average, Count, Max, Min, Unique — selectable per measure and domain.
  • Role-based default dashboards. Each role lands on the ~8–10 metrics it acts on; admins configure visibility.
  • Global date filter. One range cascades to all widgets; default last-7-days on system dashboards, off on custom ones.
  • Compose / save / favourite / default / export (PNG). Duplicates scoped to their dashboard, not the global widget list.
08 · The design

Build → Compose → Consume — one lifecycle, three surfaces.

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.

Widget builder — domain through visualisation pickers
Build · guided sequence from domain to chart

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.

Composed dashboard with multiple widgets and grid layout
Compose · grid layout · global date filter

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.

One data layer Orders · Inventory · Finance Accountingpayments · reconciliation · tax Financemargin · P&L · spend ProductSKUs · returns · reviews PurchasingPOs · suppliers · stock CEO / Overviewrevenue · growth · risk role-based default view
Roles One system that adapts to who's asking.

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.

DECISION

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.

DECISION

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.

09 · Validation framework

In rollout — measuring against the report queue, not vanity metrics.

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.

  • Who onboarded first. Purchasing and Finance — highest Phase 1 domain coverage and heaviest legacy report-request volume.
  • Baseline comparison. Report-request volume before vs after rollout; time from question to answer (request → delivery vs build → view).
  • What we're measuring. Self-serve adoption (widgets created, dashboards saved); time-to-insight for a new question; widget generation latency against the <8s NFR-02 target; qualitative signal on whether operators still export to Excel for weekly reviews.
  • Early qualitative signal. Operators who previously exported tables to Excel for weekly reviews are building and saving dashboards instead — anecdotal, not yet quantified.
  • Status. Rollout in progress; measured adoption data not yet available. This section gets numbers when the rollout produces them.
10 · Impact

What shipped — factual signals only.

What shipped (factual):

12
CHART TYPES
IN PHASE 1
7
ROLE
AUDIENCES
6
AGGREGATE FUNCTIONS
SUM · AVG · COUNT · ETC.
2
LEGACY SCREENS
MIGRATED
< 8s
GENERATION TARGET
(NFR-02)
2
PHASE 1 DOMAINS
ORDERS · INVENTORY
In rollout
PORTAL 3.0
2025 → 2026
Responsive
DESKTOP · TABLET · MOBILE
+ LAST UPDATED

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.

11 · Principle carried forward

One system that adapts to who's asking.

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

12 · In validation · AI widget builder

What's next: describe the widget, and the system drafts it.

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):

  • Describe. The user types a request in plain language — e.g. "top 10 SKUs by revenue last quarter, as a bar chart."
  • Draft. The system maps the request to a widget config — domain, measure(s) with a primary, dimension(s), filters, visualisation — the same structure the manual builder enforces.
  • Verify. The drafted config is shown as editable fields, not a black box, so the user sees exactly what was built and can correct it before saving.

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.

IN VALIDATION

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.

IN VALIDATION

Status. Validation in progress — no measured results yet. This section gets numbers when the sessions produce them, not before.