Modeler

Replatforming Birst's data integration from a legacy Flash admin tool into a modern three-part system for connecting, preparing, and relating data from any source.

Infor’s integration

Birst’s integration

Role: Co-Lead Designer (1 of 2 designers).
Timeline: 2017 to 2026; original v1 shipped 2019; integrated into Infor's broader product portfolio 2023 to 2026
Team: 2 designers, ~6 PMs, 50+ engineers, 25+ QA; expanded beyond the core team as a company-wide effort, with executive stakeholder involvement.
Platform: Web (Infor Birst BI Cloud Platform).
Status: Shipped and actively in production; later adapted as the architectural basis for Infor's own platform-wide data connection flow.
My contributions: Owned Connect end-to-end; led transform design in Prep (null handling, ignore, filter, merge); co-designed Relate 50/50 with my design partner.


The Problem

Birst's original data integration experience was a Flash admin tool, built before the company employed any UX designers. It was functional but clunky, unresponsive in a browser window, and for the most part confusing to use. Adding a new source, which was needed to use any of our products, was something that users dreaded.

That was a major problem for Birst's product vision. The platform's competitive edge was its ability to unify data across any source a customer had, from databases and SaaS tools to spreadsheets and APIs. But if customers avoided adding new sources because the experience was painful, we had a roadblock in front of them getting the most insightful data into the platform.

Three forces converged to make the rebuild urgent:

  • Adobe's announcement of Flash end-of-life. Flash was scheduled for deprecation by the end of 2020, and browser vendors were already making it progressively harder to use. We needed to get ahead of the shutdown rather than scramble at the last minute.

  • Customer frustration was eroding value. Every time a customer avoided adding a new source because the tool was painful, the platform's value proposition took a hit. We were undermining our own differentiator.

  • Competitors had the advantage of being late. Newer BI platforms had never built on Flash in the first place, so they already had modern HTML-based data integration tools. We were behind them specifically on this workflow.


Constraints and stakes

A few things made this project harder than a typical product redesign:

The scale of what we were connecting to. Customers weren't just connecting to two or three sources. Some had tens, others hundreds, spanning SQL databases, Salesforce, NetSuite, Jira, Google Analytics, REST APIs, JSON endpoints, Dropbox, SFTP drops, the Infor Data Lake, ad-hoc Excel uploads, and Networked BI sources. The UI had to handle all of those options with their own unique configurations without becoming bloatware.

We couldn't disrupt existing customers mid-transition. The old Flash tool was kept running for customers who were live on the platform while the new tool was built alongside it. Customers could access a beta to give the new tool a try while we built it out. This was helpful for feedback. We designed a seamless migration path where legacy connections continued to function and automatically surfaced in the new experience, giving customers a single source of truth across both tools as they migrated.

Two designers on a massive cross-functional effort. While the project had a dedicated core team, the scope pulled in people from across engineering, QA, and product. It was effectively a company-wide effort. Because of the heavy resources being pulled in, my design partner and I had to design fast, defend decisions clearly, and work with executive stakeholders who were actively engaged in key reviews.


Process and exploration

Getting oriented

We started with a mix of PM briefings, competitive analysis, and our own hands-on testing. The PM team delivered initial scope verbally early on and later broke the work down into Jira tickets per feature. In parallel, we ran teardowns of how competitors handled the same problem, testing data import flows in Tableau, Power BI, Salesforce, and Oracle. We extracted what worked, identified what didn't, and designed our own flow from scratch rather than copying anyone.

The first major decision came quickly: Modeler needed to be three distinct modules, not one monolithic tool.

  • Connect: establishing and authenticating connections, choosing which tables and columns to bring in

  • Prepare: transforming and standardizing data after import

  • Relate: visually linking sources together into a unified, queryable model

Splitting the workflow this way gave each module a clear purpose and let users focus on one kind of work at a time. My manager assigned initial module ownership between me and my co-designer, and while we bled into each other's work throughout the project, this split gave us the structure we needed to move fast.

Three modules vs. one: the first real fight

The PM team's initial direction was to build this as a single module. Engineering didn't want to build what they saw as three separate products. Both sides argued that consolidation would be faster to ship and less context-switching for users. My co-designer and I pushed back hard.

A single module would have required users to navigate connection setup, data transformation, and source linking all in the same workspace, with all of those tools fighting for the same screen real estate. Our competitors who had attempted this required users to be data engineers to navigate it at all. Birst's competitive edge was opening this work to business users who were not data engineers, and a monolithic workspace would have killed that.

We built prototypes of both approaches and ran them through stakeholders: PMs, engineering leads, the Head of Engineering, and the CEO. We watched them navigate the prototypes without instructions to see if they could figure it out from scratch. The single-module version failed consistently. Users got lost hunting for tools across a crowded screen. The three-module version mapped cleanly to how data scientists and admins actually thought about the work, a natural progression from high-level connections, to transforming the data, to linking prepared sources together. It was essentially a step-by-step wizard for adding data to a model.

It took several meetings and many internal design reviews. We made the case in working sessions, defended it under pressure, and eventually won. The split into Connect, Prep, and Relate was the single decision that made everything else possible.

How we worked

Our workflow followed a pattern across every feature:

  • Paper sketches and rough explorations to find the conceptual model

  • Wireframes in Photoshop (the industry-standard toolkit at Birst in that era, before we moved to Figma later)

  • Interactive prototypes shared with PMs and the Head of Product for flow review

  • Iteration based on stakeholder feedback

  • Engineering handoff with specs and interaction notes

Because the project was so large, we often had multiple features in different stages at the same time, which meant constant context-switching and aggressive prioritization.


Key Design Decisions

Connect: progressive disclosure for complex setup

Connect supported a wide range of connection types, including SaaS sources like Salesforce, Jira, and Google Analytics; file-based sources like Dropbox and SFTP drops; API connections like REST and JSON endpoints; SQL databases of various flavors; the Infor Data Lake; and more. Each connection type came with its own configuration requirements, and the list of options varied significantly depending on what the user was connecting to. A SQL database connection might require a server name, host, port, database type, username, and password, with OAuth available as an alternative. A SaaS connection might require Client ID, Client Secret, Endpoint, environment, Account ID, and Role internal ID. A file-based connection had a different shape entirely. If we exposed every possible field up-front, the page would overwhelm anyone setting up their first connection.

The solution was progressive disclosure. Users picked their connection type, named the connection, entered the core credentials specific to that connection type, and then selected the specific tables and columns they wanted to pull. Less common configurations, the ones that only power users or super admins would typically know they needed, lived in a collapsible "Advanced" area that stayed out of the way until someone needed it. This kept the primary flow approachable for typical users without limiting what was possible for technical ones. Some connections, that had support for it, included a "Test Connection" button that validated the inputs before users committed to the rest of the setup.

A decision to hide advanced features

PMs initially wanted every input visible at all times, with some marked mandatory and others optional. The argument was discoverability. Users could see what was available and decide what to use. We disagreed. A panel full of optional configurations requiring a scroll is intimidating to a less technical user, even when the truly required fields are clearly marked. Especially for users who were not the seasoned data engineers PMs sometimes designed for, the cognitive load of just deciding what to fill out was a barrier.

We launched the first beta of Connect with all fields visible. Analytics showed high error rates on the advanced fields, with users frequently misconfiguring them and getting failed connections. When we moved the advanced configurations (language, timezone, source prefixes, ports, fetch sizes, custom data source URLs, headers, SSL certificates, environment choices, API versions, algorithm choices, public keys, and others) behind a collapsible Advanced section, connection completion rates went up immediately with beta users. Less technical users completed their setups without hitting walls, and advanced users still had everything they needed one click away.

Test Connection: standardizing what most connections didn't natively support

During research, we learned that some connection types had a native way to test a connection before committing to a full data pull. The connection would send back a packet confirming whether authentication succeeded and the silo was reachable. I pushed for this to be available on every connection that could possibly support it. The cost of a failed full pull was significant: the platform consumed real load during a pull, and users wouldn't realize they'd misconfigured something until after that load had already been spent.

Engineering had to research every connection option to determine which ones supported native testing and which didn't. For the ones that didn't, I worked with engineers to design workarounds that mimicked the test, often by initiating a stub connection and then blocking the data pull as soon as authentication succeeded. The Test Connection button got its own standardized placement next to the Extract button across every connection panel, so the affordance was consistent regardless of the underlying technical reality. From the user's perspective, every connection had a Test button. They didn't need to know which ones were native and which ones we'd engineered around.


Prepare: making data transformation approachable without hiding the power

Prepare, or ‘Prep’ internally, was where business users ran into territory traditionally reserved for data engineers. Users needed to be able to filter, handle nulls, merge, split, pivot, summarize, rename, and convert data types across tables that could contain millions of rows. We needed non-technical users to feel confident here, without making the tool feel dumbed-down to power users.

Two design choices shaped Prep:

A column-first selection model. Users started by choosing one of the connections they'd already established in Connect from a side panel, then drilled into a specific table from that connection. The selected table's columns and rows displayed in the main area of the screen. From there, users could select one or more columns and apply transforms to them. Relevant transform tools surfaced in a side panel with clear icons for each operation, so the interaction stayed direct: pick the columns you want to change, then pick what to do with them. No hunting through menus.

An interactive transform pipeline. Every transform applied to a table was recorded as a step in a visual pipeline that showed the full lineage of the data. Users could insert new transforms between existing ones, delete steps from the middle of the pipeline, or modify earlier steps without losing the work that came after. The pipeline made it possible to audit, modify, and understand the state of any table at a glance, which mattered as much for one person revisiting their own work weeks later as it did for someone inheriting a teammate's prep work.

Among the transforms I designed directly were null handling, ignore, filter, and merge. Each one needed its own interaction model to feel appropriate to what it did.

Visual indicators: a small fight that mattered for clarity

Engineering initially didn't want to invest in the visual pipeline indicators across every transform. Their proposal was to apply transforms in place and update the table view, with no persistent visualization of what had happened. My co-designer and I pushed for a persistent indicator system: highlighting columns being imported, adding filter icons on columns with active transforms, and showing a visible pipeline of steps at the bottom of the screen.

Without these indicators, users would only see the resulting transformed table. They had no way to know what was being done to the data or in what order, and that ambiguity created exactly the kind of mistrust we were trying to eliminate. We argued that the cost of building the indicator system was small compared to the cost of users losing confidence in what the tool was actually doing to their data. The visual pipeline was eventually shipped and became one of the most-used and most-loved features of Prep.

Interactive pipeline: a design fight against engineering's first proposal

Other BI tools at the time had visual transform pipelines, but they were largely read-only. You could see the steps that had been applied to a table, but you couldn't reach back into the pipeline and modify them. We knew that wasn't enough. Real data work is iterative. Users needed to be able to delete steps, edit existing steps, insert new steps between existing ones, and click any step to see the table's state before that transform was applied.

Engineering initially pushed back on the level of interactivity I was proposing. The complexity of allowing arbitrary insertions and deletions across a pipeline meant managing dependencies between steps. If a user inserted a transform that broke a downstream step, what happened? I made the case alongside my co-designer that read-only pipelines were not actually useful, just decorative, and that the real value was letting users explore and iterate.

We landed on a design philosophy I've used since. We always let the user proceed, with a warning if something downstream might break. If a user inserted a transform that risked breaking the next step (a common case was renaming a column that a downstream step depended on), the system flagged it with a warning, but let them through. If they knew what they were doing, they could proceed and fix the downstream step. If they didn't, they could explore and recover. Forcing users to delete downstream steps to insert something new was a roadblock, and roadblocks were what we were trying to remove.


Relate: a visual canvas instead of a join builder

Relate was the module where users connected their sources into a unified data model. Sources could be either prepared sources (those that had been through the Prep module to apply transforms) or raw sources (those imported through Connect that didn't need any transforming and could go straight into Relate). The typical BI pattern for this at the time was a SQL-style join builder: a form or query writer that let you specify joins between tables with dropdowns. A few BI competitors had begun moving toward more visual approaches to connecting sources, but those implementations still came with significant usability limitations.

The visual canvas vs. the SQL join builder

The SQL approach was the painful incumbent at Birst. It was the main pain point in the product and was, in fact, the last part of the platform that received a design update during this era of redesigns. The original join experience had been built by developers in the company's earliest days, with no UX input, and while it technically worked, it required users to think in SQL to use it. The audience we were targeting (business users who avoided SQL like the plague) couldn't get past it.

A form-based join builder was discussed early on as a faster path to ship. Even some of our PMs got lost testing the form approach during prototype reviews, which told us everything we needed to know. The visual canvas was significantly more expensive to build, but the cost was paid back by every prospect who could imagine themselves successfully linking their own data without hiring a data scientist or learning SQL. The form-based version would have shipped faster and lost us the customers we were trying to win.

The canvas started empty. As users built relationships between their sources, those sources appeared as nodes on the canvas, connected by single lines. Each line represented a relationship between two sources, regardless of how many column-to-column joins actually existed underneath. This kept the high-level star schema legible at any scale, even when the underlying joins were complex.

To inspect or build the actual joins between two sources, users clicked the first source to open a panel on the right, then clicked the second source to open a panel on the left. A transparent white overlay settled over the rest of the canvas, focusing attention on the two panels. Each panel showed the columns of its source. Lines drawn between the panels represented the column-level joins, with Venn-diagram icons in the middle of each line showing the join type (inner, outer, left, right). Users could click any join icon to change the type directly. Each panel could be dismissed independently, returning the user to the canvas view.

The decision to keep join-type icons off the high-level star schema was deliberate. Two sources can have multiple joins between them with different types, and surfacing all of that complexity on the canvas would have created visual chaos and ambiguity. Collapsing to one line per source pair kept the schema readable at a glance, while the panel view preserved the full detail for anyone who needed it.

For users who already knew exactly what they wanted, a SQL join builder is more efficient. But for users who were still figuring out how their data fit together, a visual canvas made the relationships discoverable. You could see what was connected to what, which sources were underutilized, and where gaps existed.


Preventing collapse at scale: real lessons from cluttered canvases

The canvas worked well at small scales. The problems started showing up at fifty or more sources, where nodes and lines began crowding each other and lines could pass underneath unrelated nodes, creating the visual illusion that three sources were linked when only two were. We knew this would mislead users, who would think the canvas was telling them the data was connected when it wasn't.

We used connection information from the underlying data model to group related sources spatially. The layout algorithm grouped connected sources near each other, so lines stayed short and users didn't have to click and pan to follow a relationship across the canvas. We also defined rules to route lines around unrelated nodes rather than under them, eliminating the ambiguity entirely.


Outcome

Modeler shipped in 2019 and was well-received almost immediately. The pattern was consistent: customers who had been avoiding the old Flash tool started adding connections rapidly, then testing data sources they'd previously given up on. The complexity that had been blocking them was essentially gone. Once customers realized how easy it was to pull in new data, they started exploring use cases they hadn't previously thought were feasible, which in turn expanded their understanding of what the Birst platform could do for their organization.

A few specific outcomes:

  • Still in production today, with new connection types added continuously. The core interaction model my design partner and I shipped in 2019 has held up across years of feature additions.

  • Became the architectural basis for Infor's own data connection flow. After Birst proved the model, Infor adapted Modeler's approach into their broader product portfolio, unifying data acquisition across what had previously been siloed products. I worked on that adaptation alongside my co-designer, who led the initial port into Infor's design language.

  • Customer enablement. By removing the friction of adding sources, Modeler let customers use Birst the way it was meant to be used: unifying everything and asking bigger questions of it.


The Infor integration

Infor acquired Birst specifically to bring our data integration approach into Infor's broader product portfolio. Infor had a rudimentary, product-siloed analytics tool, where data lived inside each individual product with no way to view it across products. Our work on Modeler was one of the main reasons Infor was interested in Birst in the first place. Centralizing Infor's data across all of its products was the end goal of the acquisition.

I spearheaded the integration work alongside my original Modeler co-designer, starting roughly three years before my departure from Infor. Infor already had a connection layer that linked their products to each other, but they were missing the transform and lineage experience that Modeler had built at Birst. Their existing tool was essentially a Prep and Relate in one module but with no star schema canvas and no transform pipeline. Just tables with results applied.

Infor leadership asked us to keep their connection flow intact but adapt the Modeler transform and pipeline patterns into their product. That meant:

Designing the pipeline within Infor's design system. We couldn't bring over the Birst component library wholesale. Infor's UX team had a defined design style guide, but it didn't include the custom components we needed (fan menus on pipeline nodes, styled connectors between steps, draggable panels for transform configurations, layouts that varied based on transform type). We worked alongside Infor's design and engineering teams to expand the style guide to include the components needed to communicate data flow clearly.

Bringing over 21 transform types into Infor's product. I designed and adapted many of these, including filters and joins specifically (the screens I'm including in this section show the Infor filter and join transforms). Each transform needed its own interaction model that fit Infor's design language while preserving what made Modeler work.

Designing the pipeline node interaction. I specifically designed the pipeline visualization within the Infor product, including the nodes representing each transform step, the lines and arrows connecting them, and the fan menu that opens when a user clicks a node to edit, delete, or view the table at that step. The pipeline pattern was central to letting Infor customers actually understand how their data was being parsed during this centralization push.

Adapting panel layouts to fit complex transforms. Infor's existing layouts couldn't accommodate the configuration depth that some transforms required. We designed new popouts, side panels, and bottom panels depending on the transform type and the space its configuration required. Some transforms needed wide horizontal space to show before/after data states. Some needed deep vertical space for complex parameter inputs. We codified those layout decisions into Infor's expanded style guide.

This work mattered because it took a pattern that had succeeded inside one product and proved it across Infor's broader portfolio. The architectural decisions my co-designer and I made on Modeler in 2017 to 2019 became the basis for how Infor's customers experience data integration across the entire suite.


Post-launch iteration

Modeler shipped and customers accelerated. They went from one of the clunkiest experiences in the industry to an industry-leading data integration flow, and they noticed. Adoption analytics from the production product showed customers adding source types they had historically avoided.

A few specific changes happened after launch:

  • Module navigation got better. Customers wanted faster ways to move between Connect, Prep, and Relate, so we added shortcut buttons to each module in the header and built coach marks and help screens to introduce the three-module flow to first-time users.

  • Mid-pipeline transform insertion came from customers. The original interactive pipeline supported delete and edit, but users started asking for the ability to insert new transforms between existing ones. We added it.

  • The Publish button moved. Initially, Publish lived only in Relate, on the theory that Relate was the final step. We missed the use case where customers had clean raw data that didn't need transforming or joining. We rolled Publish out to all three modules and turned the button into a status indicator that showed the last publish date, current progress, and let users revert to a previous publish if needed.

  • Two entry points stayed. Customers split on how they added a new connection in Connect, with about half clicking the icon in the main window and half using the plus icon in the side panel. Both worked. We kept both. Trying to consolidate them would have broken half of our customer base's muscle memory.


Reflection

Modeler forced me to learn a system that most product designers never get near. Big data was intimidating when I first joined Birst, and on this project I had to learn concepts that data scientists spend years developing. Like how data is structured, how it flows, how transformations compose, how joins behave at scale. It's rare in our industry for UX designers to dive this deep into the technical substrate of what they're designing. This project made me do it, and I'm genuinely grateful for that.

It also changed how engineers viewed the role of design on the team. I was relatively young in a room of senior engineers, and Modeler was where I stopped being "some designer" and started being a colleague who could actually speak the system's language. That shift of respect was one of the most valuable things I took from the project.

The row limit fight: the one I didn't win

The Prep table preview originally capped at 50 rows. Customers in the beta hated this immediately. They said 50 was way too low and that they couldn't get a feel for whether their transforms were actually doing what they wanted. My co-designer and I fought for a higher cap and proposed I came up with a rule-based approach where the row count scaled to the number of columns. Few columns, more rows. Many columns, fewer rows. The browser performance argument PMs were making was real but addressable through smart conditional loading.

We didn't win that one. PMs wanted consistency over conditional behavior. We compromised on raising the cap from 50 to 100 rows across all tables. That worked for most cases but left the underlying problem unsolved.

I did get the lazy loading through, though. I pointed out that we already used lazy loading on dashboards, where reports only loaded when scrolled into view to manage browser performance, and made the case that we should bring the same pattern to Prep table previews. The compromise was a 100-row default preview that users could expand by scrolling to lazy-load the rest of the data. They could see all of their rows if they wanted them, just not all at once.

In hindsight, conditional rows based on column count would have been the better default. Infor's later adaptation of Modeler tightened the layout enough to fit more rows comfortably, which was the right call.

More than anything, Modeler is the project that taught me to hold the whole system in my head while still being able to get granular on a single interaction. Every case study talks about "systems thinking," but this one is where I actually learned what that meant.