One investigation crossed four tools that were never designed to connect
OKLink's compliance suite is two products: On-chain AML for alerts and address and entity profiles, and Chaintelligence, a separate site for mapping fund flows. One investigation crosses four of their surfaces, but nobody had designed the path between them, so analysts finished cases in XMind and spreadsheets and usage stayed low. New regulation in Hong Kong made the suite a priority.
The four stages of an investigation, and of this case
Observing 3 compliance officers work real cases set three design principles
While the team debated what to build, I proposed watching first. I interviewed 3 compliance officers across APAC and the US and sat in on real cases, mapping each step, tool and breakdown.
Who
Compliance investigators
AML investigators working the alert queue, and compliance officers at exchanges, OTC desks and institutions. Often on a small laptop, for a full shift.
Trigger
A flagged transaction
A transfer crosses a risk rule, often around US$2,000. The analyst asks who else is involved, how much moved and whether it repeats.
Goal
A pattern, documented
Document the suspicious pattern, then close the case, escalate it, or export the fund-flow map as evidence for management or the regulator.
Findings & Principles
15–45 minutes per alert
Low and medium alerts get about 15 minutes; high and severe ones 30 to 45. Anything an analyst has to hunt for comes out of that.
1Follow the analyst's reading order
Every decision gets reviewed
Decisions go to reviewers in other regions and, in the end, to regulators. A score nobody can explain doesn't survive that.
2Every score shows its source
The real analysis happens in XMind
The real synthesis happened outside the product: colour groups and notes in XMind, comparisons in spreadsheets.
3Bring the outside work inside
And one surprise
"It lacks features like A, B and C." Shown where they were: "Oh, I didn't know those features are there. They're what we need."
So each stage made existing features findable before adding new ones.
The full investigation path
GoalIn the toolStepsPain points
1 · Assign
Get the alert to the right person.
Dashboard · Alert list
An alert fires (often around US$2,000); a team lead assigns a specialist; status becomes unreviewed.
About 15 minutes for low/medium alerts, 30–45 for high/severe — a tight budget
2 · Triage
Decide whether this alert is worth a case.
Alert detail · KYT
Ask the same four questions in order: risk share, amount, source, direction. Transfer and behaviour alerts share a similar structure.
The four answers sat in different places, out of order
3 · Profile
Spot red flags in the user profile.
User profile
Check overview, past transactions, deposit and withdrawal behaviour; nationality, KYC level, VIP status, whether they trade actively.
Had to copy a user ID into a second tab to look them up
ND-broker sub-accounts have no KYC; one sample account had 129 sub-accounts
4 · Trace
Confirm whether the funds came from illicit activity.
Fund-flow graph · Reactor
Expand counterparties by risk amount, compare addresses, look for repeating patterns.
The graph and the alert lived in two products; the real write-up went to XMind
5 · Conclude
Document findings, then close or escalate.
Case write-up · review
Write up the findings, dismiss or escalate; the decision goes to reviewers in other regions and may reach a regulator.
Evidence was often assembled outside the product, then pasted back in
The full path from sitting in on real cases, redrawn from the KYT user-flow board. It isn't linear: analysts return to the profile or the graph at any point, and a case can stay open for weeks.More from the sessionsGraph-stage detail, observations, gaps, constraints
Trace stage in detail: how the graph work went
GoalIn the toolStepsPain points
1 · Analyse
Filter down to the addresses worth following.
Create graph
Enter an address or hash, see everything connected to it, filter suspicious addresses by amount.
Tracing and the graph were two separate products
One address at a time; no way to paste ten and find common counterparties
The star layout hides direction, and adding a node re-centres the canvas
2 · Open the case
Pull everything into one picture of the chain.
Edit and save graph
Browse related addresses and transactions, group and annotate them, save, then keep updating.
Annotating replaces the node's icon
No way to annotate a group of addresses
Leaving the canvas clears it: is there autosave?
3 · Save evidence and close
Hand the evidence on.
Export → XMind → close
Export the graph, rebuild it in XMind, share a link.
The real synthesis happens in XMind: colour groups, notes, other chains
Dark suits projecting, not a full shift of reading
Detail of the Trace stage only, from the observation sessions and the workshop map. Analysts come back to add addresses at any point.
What observation surfaced that a feature request would not
A small risk percentage is not automatically safe. Analysts check how often it repeats: a known laundering pattern is many small deposits and one large withdrawal, and each deposit on its own looks minor.
Some accounts carry no identity data at all. Non-disclosure broker sub-accounts have no KYC attached, so the first question on those alerts is whether this is a sub-account or the master. The old page made analysts answer it by copying an ID into a second tab; one account in the sample had 129 sub-accounts.
Two gaps in the old graph
1Analysts think in cases; the tool thought in addresses
Three entry points (address graph, transaction map, transaction path) forced a technical choice before the analyst had any context.
2The layout hid direction
Hundreds of nodes around a centre showed what was connected, not which way the money moved.
Two constraints beyond the graph
Constraint
Labels stay internal
A label can name a person, and the bodies that receive a report don't share intelligence. Labels show to the analyst and stay off anything shared outward.
Request
Bulk tracing
"Ten addresses, then their common counterparties one layer out, two layers, up to twenty. Right now I do it in a spreadsheet." This became multi-hop tracing in section 03.
02 · Stage 1 · Triage
Alert page: four answers in the order analysts ask for them
Alert page · On-chain AML / KYTHanded over1Reading order
Every analyst asked the same four questions in the same order, so I laid the page out by those questions instead of by data source:
1What share is risky
2How much moved
3Where it came from
4Which way it went
Before
AHeader: the alert ID onlyBThe graph behind a small icon
The answers sat in four places across two sections, out of order, so part of a 15–45 minute review went on jumping between them.
After
AActionsAWhy it firedAEvidenceBUser record · fund-flow graphCAssignment, status, findings, conclusion
The answers read top to bottom in the order analysts ask, with the case log beside the evidence.
Three bandsWhy the alert fired, the evidence behind it, and the actions available.
One step to the next stageThe user record and the fund-flow graph open from the alert itself.
Write-up in placeAssignment, status, findings and conclusion sit next to what they refer to.
03 · Stage 2 · Assess
Address risk: every score traces back to the original sanctions listing
Address risk · On-chain AML / KYAShipped2Visible source
The FATF-aligned score breaks down in layers: five risk dimensions built from 14+ configurable risk factors, then three evidence tables that go down to the original sanctions listing. I made every layer open to its source, because a score nobody can explain doesn't survive review. An analyst can answer "how do you know?" without leaving the page.
Detected risks: five dimensions on a radar, the categories that fired beside it, and three tabs into the evidence.
Each blocklist row names the category, the listing body and a link to the original, so the analyst can open the OFAC record itself.
Rules for dense evidence, and multi-hop tracingMulti-hop handed over
Pagination only above five rows. Up to twenty rows scroll; beyond that the list stops rather than implying it's complete.
The category chart caps at eight slices. Long amounts switch to abbreviated notation, so a dense table stays readable.
Stablecoins and native coins resolve differently, so the transaction table treats each as its own case.
Unbuilt depth stays visible. It shows as a disabled control with a "not currently supported" note, so analysts learn where the tool stops instead of guessing.
Multi-hop tracing, from the bulk-tracing request
Trace a target address outward layer by layer, up to 50 addresses, with first and last transaction times on hover. I designed and specified it from the same research; it was with engineering when I left.
Multi-hop analysis: the risk-path list, one asset's transaction map, and the detail panel for a related address.
04 · Stage 3 · Identify
Entity profiles: a new module that shows who is behind an address
An address tells you what moved, not who you're dealing with. KYE answers that for exchanges, mixers and services. I designed how analysts get to an entity: the landing page, search and the category list. Another designer did the entity page.
Entity watch: recent searches under the search bar, and every category with its entity count below. Analysts start from a name or a category.
Results show assets on each chain and which data exists for the entity (regulatory detail, transactions, risk exposure), so analysts know what they will get before opening one.
A category opens as a list analysts can sort by risk level and compare by assets on each chain.
Both routes end on the entity page: regulatory detail, transactions, risk activity and address list. Designed by another designer; shown here to complete the flow.
Three layouts tried by colleagues; all 3 picked the split view
The design team disagreed in internal review about how to structure the entry. Rather than keep arguing, I asked 3 colleagues to try three layouts on the same tasks, such as "find the darknet-market entity in the United Kingdom".
Option 1.1 · One long page
Search, categories and the full entity table stacked on one scroll.
Option 1.2 · Split viewsPicked
Search first, then explore by category; the entity list opens from a category, not stacked on the landing page.
Option 2 · List first
No landing page; open straight on the entity table with search and a category filter.
Why 1.2
All 3 found 1.2 the easiest to understand: search comes first, and categories don't blur into entities.
Their comments also shaped the final design: "KYE" alone wasn't clear to them, but the full name was, so the navigation says "Know Your Entity".
Four releases, and what each field may claimRelease history and two data questions
MVPSearch, list and entity detail
V1.1.0Detail, list and watchlist
V1.1.1Design QA and a regression pass
V1.1.2Responsive layouts with permission variants
Many open questions weren't about layout but about what the data could honestly support, and each was settled with product and the data team before the field shipped.
Fiat accepted: a count or a list?
A count fits the table; a list is what a compliance officer needs. The answer changed the column in the entity list.
What should search match?
Exact, fuzzy or alias matching decides whether an analyst finds an entity under its local trading name or misses it.
05 · Stage 4 · Trace and report
Fund-flow graph: laid out the way money moves, and written up without leaving it
The old graph was a star that hid which way money moved, and the write-up happened in XMind after an export. The redesign follows the analyst from opening a graph to writing it up. The biggest change was the layout: I chose a left-to-right flow because analysts read a case as money moving from source to destination. The other five steps are folded below.
1
Layout: from a star to a flow
User pain point
The radial layout became a left-to-right flow that reads the way money moves.
Tools follow the selection
The scattered tool rail became three groups: save and export, add and filter, edit. Edit actions appear only for what's selected.
BeforeTools scattered down a side rail
AfterActions for the current selection
With several addresses selected
The graph offers "Show mutual counterparts", the comparison analysts had been doing by hand in a spreadsheet.
BeforeNo way to compare a selection
AfterShow mutual counterparts
Trade-off: ship in phases, not all at once
After discussing it with the PM, I split the graph redesign into phases and implemented it feature by feature, so each feature could ship when it was ready instead of waiting for the whole redesign.
The cost was that some phases went out incomplete. When one couldn't supply risk-profile data yet, we dropped that column rather than ship it blank: a column that's always empty teaches people to skim past the table, and on a compliance screen every visible field has to be trustworthy.
Five more steps: list, create, expand, add, synthesiseThe full six-step redesign
2
Graph list: one list of cases
Design insight
Analysts build a graph around a case, not a single address. Three entry types became one list of case graphs, and light mode became the default for analysis.
BeforePick a graph type first
AfterOne list of case graphs
3
Create graph: start in the middle
Design insight
The entry moved from a bar at the top to the centre of the empty canvas, styled like the address node it creates, and it takes several addresses at once.
BeforeA search bar on a dark screen
AfterThe entry reads as the first node
4
Source added: counterparties by default
User pain point
The old graph dropped one node onto an empty canvas. Now it expands one layer of senders and receivers automatically, so the analyst starts with the immediate picture.
BeforeOne node, nothing around it
AfterInflows left, outflows right
5
Add more addresses from where you are
Design insight
Investigators gather suspicious addresses offline. They can now add them from a counterparty's related-addresses panel, from empty canvas, or from the transaction panel, not only from the top bar.
BeforeOnly the top bar
AfterAdd from the related-addresses panel
6
Synthesise: bring the XMind step inside
Design insight
Analysts grouped evidence by colour and named the groups in XMind. Both moved into the tool, a colour palette for nodes and a summary label for a group, so the exported graph is already the report.
BeforeA dense star, no way to group
AfterColour and summary on the graph
Screens from the design files. Red notes inside some screens are from the original reviews, in Chinese.
06 · System
Four shared components make the four stages read as one product
One risk scale, an exchange-logo library, light and dark themes, and responsive layouts with permission variants, shared by all four stages.
One risk scale, everywhere
Five levels built once, with light, dark, text and dot variants, used by alerts, addresses and entities.
Counterparties you can recognise
Counterparties read as venues, not hashes, in alerts, the entity list and graph nodes.
Light for analysis, dark for presenting
Dark is tiring over a full shift but suits a projected review, so both ship, with light as the default.
Three widths, and who sees what
Internal investigators and external clients see different fields, so each breakpoint has permission variants.
Design QA, and a deferred export watermarkHow each release was checked
1
Global convention: a tooltip follows the direction of its arrow and always stays inside the content area. Each finding is boxed on the build, numbered and written up against the spec.
Deferred
Export watermark
I specified a watermark for exported graphs; engineering moved it out of the release, and export shipped without it.
07 · Outcome
Three stages shipped, two handed over as specs
After launch, an analyst can go from an alert to a written-up graph inside the product, and every risk score opens to its source. The alert page and multi-hop tracing went to engineering as finished specs.
Entity search, landing page and category list: MVP and three follow-up releases
Handed over
Alert page reordered around the analyst's reading order
Multi-hop tracing, designed and specified
How I'd measure it
Reading order
Alert review time
Time from opening an alert to a decision, against the 15–45 minute budget, watching high and severe alerts most closely.
Work inside
Exports to XMind
How many cases still get exported and rebuilt in XMind. If in-graph synthesis works, this should fall.
Work inside
Uses of "Show mutual counterparts"
Uses per case, as a measure of how much spreadsheet comparison it replaced.
I specified event tracking for the graph redesign, but it didn't ship before I left and no baseline was captured, so these are the measures I'd start with, not results.
What worked, and what I'd change
1
Watching the work found problems no request mentioned
The 15–45 minute budget, the detour into XMind and the copy-paste into a second tab all came from sitting in on real cases. Ordering four tools as one investigation mattered more than polishing any single screen.
2
Next time: measurement ships in the first release
The tracking was specified but didn't ship before I left, and there was no baseline, so I can describe what changed but not how much time it saved. Next time I'd agree a baseline with product during design and make tracking part of the first release.