You develop a CRM for years and still cannot answer this: who uses this screen?
There are guesses. “I think accounting uses that page a lot.” But when you need to remove or rewrite a feature, a guess is not enough.
So I wrote a separate panel into the CRM: a screen that shows usage live.
First, make it visible
The panel is a dark, separate shell. In the middle is a graph: nodes are users and modules, edges mean “this person is in there right now”.
When someone opens a page that edge lights up and a pulse travels along it. Watch for five minutes and you see what the company is doing.
A few deliberate visual decisions:
- Nodes are never pinned. They float and drift slightly. A frozen graph looks dead.
- No teleporting when an edge appears. The simulation starts without a warm-up phase so nodes slide into place.
- Graph data is only rebuilt when the topology changes. Rebuilding on every event makes the scene jump constantly.
Then depth: what happens inside a panel
“The invoice module is heavily used” is useless. The real question is what is done inside it.
The collector was already recording this: the selector of the clicked element, the endpoint called, the focused field. Nobody was looking at it. So I added a drill-down endpoint:
module: invoice · panel: list · last 60 min
most clicked
.btn-export 412
.filter-period 97
.row-detail 88
most called endpoints
/invoice/?xhr=1 1,204
/invoice/pdf/ 412
most focused fields
input[name=search] 203
That table said something immediately: the export button was pressed four times more often than the list was filtered. People were not using the data in the system; they were taking it to Excel.
That is a missing feature. And it had never come up in any meeting.
Finding the repetitions
Next step: find the steps a user repeats in the same order.
The method is simple — count pairs and triples in the event stream:
site/list → site/detail → invoice/list × 47
account/list → account/statement × 31
invoice/list → invoice/pdf → invoice/list × 26
The third line is the interesting one: the person goes back to the list and does the same thing again. They are exporting PDFs one at a time. Bulk export either does not exist or cannot be found.
And the AI layer
I handed those patterns to a model and asked for automation proposals. The output is structured, not free text:
{
"title": "One-by-one invoice PDF loop",
"pattern": "invoice/list → invoice/pdf → invoice/list ×26",
"insight": "The user returns to the list and repeats the same action",
"suggestion": "Multi-select on the list screen plus bulk PDF",
"impact": "high"
}
Here too the model’s job is not to produce data but to look at a pattern and name it. The numbers come from the database; the model only answers “what does this mean”.
1. Timeouts. In a long reasoning mode the model produced thousands of tokens and blew past a 50-second request limit. The panel said “could not generate” while the work was in fact completing on the other side. Lowering the reasoning effort and setting an output cap brought it to 12 seconds.
2. A key embedded in code. An existing module kept its API key directly in a source file. I did not repeat that: the new layer reads the key from the environment, and the feature turns itself off if it is absent. The old leak went on the to-do list.
And the limits
This panel sees a lot: pointer movement, scrolling, clicks, focus. So three rules were set at the start:
- Retention is bounded. Raw events are deleted after 30 days.
- Access is narrow. Collection from everyone, visibility only for an administrative role.
- The purpose is written down. This data is collected to improve workflows, not to evaluate performance.
The third is not a technical rule and it is the most important. The same data can serve two very different purposes, and if you do not write the purpose down it drifts.
What I learned
Developing a system without knowing how it is used is like rearranging a room in the dark. You think you put the furniture in the right place.
The most valuable thing the panel showed me was not a feature — it was which features were never used. Three screens we had been maintaining for years were opened nine times in sixty days.