← Back to case studies
Operations2026

CRM pipelines: nine offices, rebuilt as scripts

A staffing agency's sales CRM had drifted: opportunities sat in other teams' columns and every salesperson saw a different board, because 28 people could rename stages at will. Sensirel rebuilt the nine office pipelines as thirteen scripts, proved them on a staging copy, and replayed them on the live base in an afternoon.

1,830

Active requests

Each one in its own office pipeline

0

Mismatched columns

Checked across all nine offices

13

Scripts

Configuration replayed, not clicked

6

Administrators left

22 others demoted to users

Executive summary

A staffing agency's sales CRM had drifted into a mess: every user could create or rename pipeline stages, opportunities sat in another office's columns, and each salesperson saw a different board. We rebuilt the nine office pipelines as scripts, proved them on a staging copy, and replayed them on the live base in an afternoon.

The challenge

Nine offices, each needing two boards: active requests and a top-100 target list. What existed instead was a single tangle where 161 opportunities pointed at a stage belonging to another team, one office's team was empty while a duplicate under a translated name carried 141 requests, and nobody could say which columns were the official ones.

The cause was permissions, not the users. 25 people held the Sales administrator role, which grants the right to create, rename and delete stages. Every fix by hand was undone by the next well-meaning edit.

The staging environment, where the new structure was being validated, is rebuilt from production on demand. Each rebuild erased the work. Configuring the CRM by clicking was a job that could be lost at any moment, and was, more than once.

What we built

Configuration as scripts, in numbered lots

Thirteen scripts, each doing one thing: create the 85 missing stages and a sorting team, remove 7 global stages, re-attach 157 misplaced opportunities, correct 158 aliased records, move 141 opportunities from the phantom team to the real one, demote 22 users and keep 6 administrators, set each salesperson's favourite boards, colour opportunities by sector.

One target switch and a safety catch

A single connection module takes the target, staging by default. Writing to production requires two flags, one of which literally says you know it is production. No script carries a URL or a key.

Dry runs that print their numbers

Each lot prints what it would create, move or delete before it does anything. The production dry run of 21 August listed 85 stages to create, 7 to delete, 141 plus 157 opportunities to move, 22 users to demote. The team read the list before saying go.

Replayed twice

Once on staging on 10 August, after a rebuild had wiped the previous configuration, and once on production on 21 August, during working hours with notifications muted so nobody received 1,800 emails. Three follow-up lots handled what only production revealed: a menu hidden from non-admins, and a team whose translated name did not match its technical one.

The stack

Odoo 18PythonClaude Code

Everything is Odoo configuration and data written through the XML-RPC API from Python. No module was deployed; the structure lives in the scripts, which is why it survives a rebuild. Claude Code wrote the lots and read every dry run with us.

Results

19 active teams, 95 stages, 1,830 active requests each in its office pipeline, and 0 mismatches between labels and columns, checked on all nine offices.

The staging rebuild that used to cost days of clicking now costs one afternoon of replay.

Three days after go-live, one user archived 118 requests from his own board in three bursts within two minutes. The write log showed who, when and from where, and the requests were restored. Without the audit trail it would have looked like a migration bug.

What we learned

  • Configuration is data. If it is not in a script, it will be lost at the next rebuild or the next admin click.
  • Permissions were the root cause. Removing one role from 22 people did more for stability than any amount of tidying.
  • When users see different columns, check the default team before checking their rights. Odoo hides empty columns on a board opened without a team.
  • A dry run of lot 2 will report phantom errors if lot 1 has not been applied. Read dry runs in sequence, not in isolation.
  • Translated names lie. Match on the technical name, then read the translation to know what the user sees.

How it works

01

Read the mess

Count the stages, the teams, the misplaced opportunities, the admins.

02

Script each fix

One lot per problem, dry run by default.

03

Prove it on staging

Replay after a rebuild to be sure it holds.

04

Replay in production

Working hours, notifications muted, backup first.

See what your team
can hand to AI

A free 30-minute call. We map one workflow together and you leave with a plan you can use, with or without us.

Book a Free Strategy Call