The data lived in the ERP. Access didn't. I led the design of Portal 3.0's reporting module, moving insight from request-driven static tables to a self-serve widget and dashboard builder that lets operators compose their own answers from live data.
Some data and figures altered to respect client confidentiality.
Rollout in progress: adoption metrics not yet available.
I was the design lead on the reporting module, widget builder, role-based dashboard system, composition behaviour, and migration of legacy KPI screens into Portal 3.0. The BA authored the BRD and owned requirements; I owned how the builder, role views, and dashboard lifecycle would feel in the product.
The design problem wasn't "add more charts." ERP 2.0 held orders, inventory, sales, accounting, finance, product, and purchasing data, but every non-standard question became a report request routed through the team. Operators waited or decided blind. I reframed the goal as self-serve access, not report production.
Not in the ERP. Unless someone else builds it for you. That loop doesn't scale at 16,000 SKUs.
This became the design brief: stop producing reports for people: build a system they compose themselves. Widgets they create, dashboards they arrange, role views that arrive already relevant.
Partnered discovery, not solo ethnography. Before opening Figma I worked with the BA to map role personas against the metrics each group actually acts on. I audited legacy KPI 2.0 screens, sat with engineering on Phase 1 data exposure, and traced how non-standard questions became report requests. Signals below are paraphrased from stakeholder sessions. Not verbatim quotes.
Receivables, settlement, reconciliation. Not revenue mix.
Revenue mix, margin, P&L, cross-domain summary needs.
SKU performance, returns, reviews, catalog-level decisions.
Stock levels, POs, supplier lead times, inventory-first.
Cross-domain summary, revenue, growth, risk at a glance.
Configures role visibility, who sees which dashboards and metrics.
Every role needed a different answer from shared ERP data. Not one dashboard for everyone.
Sales Summary and Sales Breakdown were the only KPI views used without workaround, their filters and defaults had to carry forward.
Stakeholders didn't ask for more chart types first, they asked to stop waiting. Self-serve was the unmet need behind every feature request.
Engineering could expose Orders and Inventory first; Products and PO would follow. The builder had to work within that without feeling broken.
Add more chart types to existing KPI screens, expand the fixed library the team already maintained.
Stop producing reports for people; build a system they compose: widgets they create, dashboards they arrange, role views that arrive already relevant.
Faster to ship incrementally, but doesn't scale, every new question still routes through the team and the queue stays.
Rejected on cost, data governance, and fit: operators needed insight in the same session as orders and inventory, not a separate login.
Moves access upstream to the user, scales across roles, stays inside Portal 3.0's permission model, at the cost of a far more complex interaction design problem. Prototype evidence in Section 07.
I designed the builder as a guided sequence, not a free-form query tool. Domain → measures → dimensions → filters → visualisation → aggregate, each step constrains the next so invalid combinations can't be assembled. That was how I balanced configurability with usability for non-analysts.
More clicks for power users; higher completion rate for the audiences this module is actually for.
Group-by and certain chart types simply don't appear when they don't apply, prevents failure instead of explaining it.
Measures, dimensions, and chart types filtered by selected domain.
Multiple metrics selectable; one primary for visualisation, incompatible series never share a chart.
Enabled for grouped bar, line, horizontal bar, disabled elsewhere, not errored.
Each role lands on ~8–10 metrics it acts on; admins configure visibility.
One range cascades to all widgets; last-7-days default on system dashboards.
Favourite, default landing, PNG export; duplicates scoped to their dashboard.
One lifecycle, three surfaces. I designed the product as create a widget, arrange it on a dashboard, then consume the right view for your role. Screens below appear only after the rationale for each step.
Select a step · rationale before screenshot
Domain gates everything downstream: invalid combinations can't be assembled.
Answer a specific question from live ERP data without filing a report request.
Guided sequence: domain → measures → dimensions → filters → visualisation → aggregate. Invalid options hidden, not errored.
I chose progressive disclosure over one dense form, non-analysts complete the path; power users accept the extra clicks.
A saved widget scoped to a dashboard, exportable as PNG, name capped at 50 characters.
Information order: Domain first. The gate that filters every downstream field.
Trade-off: More steps than a single query box. I accepted that because error prevention mattered more than speed for this audience.
Grid-constrained layout, readable on every device, not free-form chaos.
Arrange saved and pre-defined widgets into a view they'll return to weekly.
Drag, drop, resize on grid; global date filter cascades; per-widget view, edit, export, remove.
I rejected free-form canvas, looks flexible in demos, breaks on mobile. Grid-constrained resize keeps proportions readable.
A composable dashboard, favourite, set as default landing, duplicate widgets scoped to this board.
Layout: Grid lock-in over free drag, uneven gutters kill chart readability on tablet and mobile.
Trade-off: Less "canvas" flexibility. Production reliability beat demo flash.
The dashboard arrives already relevant, focus tool, not just security gate.
Land on the KPIs that match their responsibility: filter by date, drill when needed.
Role-scoped default dashboards (~8–10 metrics); admin-configurable visibility; backend RBAC filters data per user.
I migrated legacy Sales Summary and Breakdown as system dashboards, preserved operator trust while the builder rolled out alongside.
Self-serve insight in the same session as orders and inventory, no separate BI login, no report queue.
Defaults: Last-7-days on system dashboards, matches how operators already reviewed legacy screens.
Trade-off: One system, seven role views to configure. Admins need control; operators need relevance on arrival.
| 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.
Re-skinned Sales Summary and Breakdown as read-only system dashboards, preserved operator trust while the builder rolled out alongside.
Free drag looks flexible in demos and breaks on mobile. Locking resize to the grid kept charts readable across devices.
Rollout in progress, no adoption percentages yet. Purchasing and Finance onboarded first (Phase 1 domain coverage). I'm measuring whether self-serve replaces the behaviours that created the queue, not widget counts for their own sake.
Report-request volume before vs after; time from question to answer (request → delivery vs build → view).
Widgets created, dashboards saved, generation latency vs <8s NFR-02, Excel export workaround usage.
Operators who exported tables to Excel for weekly reviews are building dashboards instead, anecdotal, not quantified.
Measured adoption data not yet available. This section gets numbers when rollout produces them.
How much trust lived in two legacy screens. Migration wasn't a nice-to-have, it was the adoption bridge for the whole module.
I initially overweighted chart variety. Discovery showed the queue. Not chart types, was the pain. Self-serve access was the real unmet need.
Start validation metrics earlier in rollout, even lightweight queue-volume tracking, instead of waiting for full adoption 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 · ERP Portal 3.0
Validation in progress, no measured results yet. The manual builder is shipped; the AI layer collapses configuration to a sentence. I designed it to fill the same domain-gated structure. The user still owns the widget.
AI proposes; the operator verifies. Same trust pattern as HikeOn use cases: suggestion → visible config → accept, edit, or dismiss. Screens below show the validation prototype, rationale before evidence.
Select a step · describe → draft → verify → preview
Plain language alongside the manual builder. Not a replacement.
Skip clicking through six builder steps when they already know what they want.
I kept manual path visible: trust grows when users know they're not locked in.
Parsed configuration surfaced before apply. Not a black box.
Maps request to domain, measures, dimensions, filters, visualisation: same structure manual builder enforces.
Ambiguity and confidence surfaced when parse isn't certain, false precision erodes trust faster than honest uncertainty.
Editable fields. The visible config is the "why this?"
AI fills the same domain-gated guardrails, it can't produce an invalid widget because the manual builder's constraints apply to AI output too.
Chart and data table: same confirmation as manual flow.
Parse accuracy against real operator requests; trust and edit rate vs manual builder; time-to-widget. Sessions with Purchasing and Finance operators who already use the shipped builder.
No measured results yet. This section gets numbers when sessions produce them, not before.