Designing an auditable video transformation module for AI training data operations — and learning when a good hypothesis is still the wrong answer.
Video transformation pipeline relied on 3 separate tools, Slack threads, and zero audit trail.
3→1 tools; ~60% less footage prep time; model errors traceable in <5 minutes.
UX Designer (fresher) — end-to-end design including a failed V1.
First principles beat convention. The V1 failure taught me more than the shipped design.
It was not bad thinking. It was untested thinking. That distinction is what this case study is about.
Nymo.ai runs AI models on live security camera footage — detecting faces, number plates, objects, and activity in real time. But a model is only as good as the data it trains on. And training data only becomes usable after it has been cleaned, formatted, and segmented. The Transform module is that preparation layer. It sits between raw footage ingestion and the annotation pipeline. Every video that trains a Nymo model passes through it.
Before this module existed, that work happened outside the platform — in personal software, on local machines, with no shared standards and no record of what anyone did.
UX Designer — research, IA, interaction design, prototype, handoff. Solo designer on this module. This was one of my earliest enterprise UX engagements — I was a fresher UX designer at the time, and the V1 failure was one of the most formative lessons in my career.
End-to-end module. Sprint 7, v0.7. Enterprise B2B — video analytics / AI training data operations. 8 research sessions across 3 user types. 2 rounds of usability testing.
Analysts were using a combination of VLC, FFmpeg via command line, and local video editors to prepare footage. The work got done — but the process had three structural failures that compounded over time.
Who did what, to which file, when — unknowable. Transformation history lived in Slack threads and personal folders.
Different resolution and fps across analysts. Downstream models trained on mismatched data without anyone realising.
Operations leads had no real-time project status. Checking progress meant messaging multiple analysts individually.
FFmpeg errors produced no alerts. Analysts discovered failures only after annotation had already blocked — sometimes an hour of lost work later.
My initial design was a multi-step wizard. The hypothesis behind it was specific: data ops analysts who were less confident with technical parameters were making format errors because all choices were visible at once. A wizard that surfaced one decision at a time — files first, then format and quality, then confirm — would reduce those errors by narrowing focus at each step.
It was a reasonable hypothesis. It was wrong.
Two rounds of testing. Three versions of the same problem. The feedback was consistent enough that I stopped mid-session two to discuss the architecture rather than the interaction.
"I need to be able to check what files are in the project while I'm setting the parameters. The wizard closes everything else. I kept going back and forth and losing my settings." — Data ops analyst, usability session 1
"I don't understand why the job status is in a different place from the project. I have to go to two places to understand what's happening to one thing." — Operations lead, usability session 1
"The wizard made me feel like I was doing one thing at a time. In reality I'm running three projects. I kept getting confused about which project I was transforming." — Data ops analyst, usability session 2
Three separate complaints. Same root cause: the wizard was built around a task-completion mental model. Analysts did not think of "run a transformation" as a discrete task to finish and move on from. They thought of it as a setting to apply to files inside a project they were already working in.
I scrapped the architecture entirely after session two. Not refined — scrapped.
I ran structured sessions with three user types. Each had a different relationship with the transformation workflow and a different definition of what success would look like.
V1 failing wasn't a dead end — it was a signal. I went back to structured discovery: 3 contextual interviews (60 min) with analysts watching them work, 2 interviews (45 min) with operations leads, 2 sessions (30 min) with ML engineers downstream. Four findings shaped everything that followed.
None of the analysts tracked the origin of any file they worked on. When I asked how they would trace a model failure back to source data, not one could answer. That single gap became the driving requirement for the Tree view.
"I download the file, run it through ffmpeg, re-upload it. I do this 30 or 40 times a day. If something goes wrong I find out when annotation fails — by then it's already cost me an hour."
— Data ops analyst, discovery session 1
Analysts weren't asking for more powerful tools. Convert, merge, split are simple operations. The difficulty was performing them reliably at scale — hundreds of files, dozens of projects. In every session, every answer was a variation of: "less clicking, fewer steps."
When a conversion failed, there was no alert. Analysts discovered failures downstream — in annotation or from a client complaint. Across all analyst sessions, every participant described discovering a failed conversion only after it had blocked something else.
In 3 out of 3 analyst sessions, the question "if your model underperforms, how would you trace it back?" produced the same result: a pause of 10+ seconds, then "I honestly don't know." This was not a process gap — it was a missing mental model.
Analysts run transformations on multiple projects simultaneously. Any design that serialised their work — forcing one operation to complete before starting another — would be rejected immediately. In task-based testing, every analyst had at least two project tabs open before the session started.
The mental model was relational, not sequential. Analysts were not completing a task. They were managing a state — across multiple projects, multiple operations running simultaneously. A wizard serialised their work. It forced context-switching. It separated status from the project it belonged to.
Transformation is a tab inside a project, not a separate workflow.
Everything else followed from that.
Rather than separate screens for separate concerns, I built three nested layers: a project table for leads monitoring across projects, a five-tab project detail view for analysts working within a project, and an audit layer embedded inside each project rather than stored elsewhere.
Dense by design. Every project shows ID, name, category, status, progress, size, duration, and file count. No summaries, no abstractions. Leads need information density, not whitespace.
The Transform tab sits inside the project detail view. Left: file grid with thumbnails and duration overlays. Right: parameter panel with Convert, Merge, and Split tabs.
When an operation is triggered, the user returns to the project list immediately. A toast confirms the job started. The new child project appears at the top of the table in In Progress status with the three-number indicator updating in real time.
Every project has a History tab showing a chronological activity timeline. Avatar, timestamp, plain-language action. Conversational format because the audience is not only engineers — leads and client stakeholders read this log. A plain sentence is more useful than a system event string.
Every transformation creates a child project. The Tree tab shows this hierarchy: the original at the root, transform branches below it, each labelled with operation type and current status.
These are not the most visible decisions in the interface. They are the ones that required the clearest trade-off thinking — and the ones most likely to be questioned in a design review.
The decision: show three raw counts (total / processed / errored) in colour rather than a single percentage bar.
Why it matters: A percentage bar collapses the most critical information. A project showing 95% complete looks like success. Three numbers show the truth: 95 processed, 5 errored out of 100. Operations leads cannot act on a percentage — they can act on knowing 5 files have failed. The counts also communicate scale that a bar cannot: 5 errors in a 10-file project is a crisis; 5 errors in a 1,000-file project is noise. Same percentage, completely different meaning.
The decision: open file preview as an inline panel within the content area, not as a modal or new screen.
Why it matters: This decision came directly from V1 testing. The wizard closed context when analysts navigated away. Any pattern that interrupts the parameter-setting workflow — even a modal — would repeat the same failure. An inline panel means the analyst can check a file's metadata (resolution, fps, duration) and immediately continue setting parameters without losing any state. The cost is screen complexity. The benefit is that a usability failure I already observed does not happen again.
The decision: build a hierarchical tree showing full transformation lineage, not an extended flat history log.
Why it matters: The History log answers "what happened in this project." The Tree answers "where did this file come from and what happened to it." These are different questions. When an ML engineer is debugging model underperformance, they need to navigate lineage spatially — to see that the file they're looking at is three transformations removed from the original, that two ran cleanly, and that one produced an error. A flat log requires reading and mental reconstruction. The tree makes the structure visible at a glance. This was the single feature that changed how the team diagnosed training data failures.
The Tree view started as an audit feature for compliance. It ended up becoming a diagnostic tool for performance debugging — something none of us anticipated when it was a sticky note on a Miro board. ML engineers used it to trace model failures to specific transformations and parameters. That shift only happened because I kept talking to the people downstream of this work.