Contents
Ask an operations director why they're still running the system everybody complains about and you'll rarely hear that it works well. You'll hear about the migration.
They've been quoted a weekend cutover. They've seen one go wrong somewhere else. They have four hundred open cases, and the honest fear is not that the new system will be worse. It's that eleven of those cases will quietly go missing and nobody will notice until a client rings.
That fear is well founded, and it's mostly a product problem. Migrations go wrong when the tooling makes you commit before you can see what's about to happen.
What actually has to move
Two things, and people usually underestimate the second.
Your people. Team members, clients, client contacts, with the right roles, the right workflow visibility, the right relationships between them. A user list is rarely a flat list. It's a shape: this contact belongs to that organisation, this team member reports through there, this person is an expert on those workflows.
Your open work. Anyone can move a closed case, because a closed case is a record. An open case is a position in a process. It has a status, answers already given, documents already attached, and somebody waiting on it.
The systems that make migration terrifying are the ones that move the first and ask you to re-key the second.
Import as a job with stages, not a button
The import in SwiftCase is a job with an explicit lifecycle, and you can see which stage it's in at any point:
uploaded → parsing → validating → ready → executing → completed
Plus the ones that matter more: completed_with_errors, blocked, failed, cancelled.
Nothing writes to your live data until the job reaches executing, and it only reaches executing if you send it there from ready. Everything before that point is reading your file and telling you what it found.
blocked is the state doing the real work. A job lands there when the import can be parsed but shouldn't be committed, and it stays there until somebody fixes the file.
The dry run you can't skip
Between validating and ready, the import builds a preview. It's not a sample of the first ten rows. It's the whole file, resolved against your existing data, telling you what would happen to every record.
The preview refuses to allow a commit when it finds any of the following:
- Two columns mapped to the same target. Somebody has mapped both "Email" and "Email Address" onto the email field. One of them is going to win and nobody will remember which.
- Two columns mapped to the same profile field. Same problem, one level deeper.
- Conflicting profile user types. The file is trying to make the same person two incompatible kinds of user.
- Duplicate identities within the file itself. Two rows that would resolve to the same person. This is worth flagging separately from duplicates against existing data, because it means the export you were given is already wrong, and it usually means somebody merged two spreadsheets by hand.
- Any row that fails validation.
- Errors in the task creation configuration, if the import is creating work as well as people.
That last check is the one that saves weekends. The task side of an import is configured separately from the user side, and it's entirely possible to have a perfect user file pointed at a workflow configuration that can't accept it. Finding that out during executing is how a migration becomes an incident.
Matching, made explicit
The interesting question in any user import is what happens when the person already exists. Get it wrong in one direction and you create duplicates. Get it wrong in the other and you overwrite a live record with stale spreadsheet data.
SwiftCase makes the matching strategy something you state rather than something you discover.
Contact method matching resolves people by email or mobile. Most exports carry at least one, and it's the cheapest reliable identifier available.
Profile matching resolves against a profile field you nominate, with configurable case sensitivity. This is for the organisations whose real identifier is their own: a staff number, a client reference, a scheme code. Your identifier is usually better than ours, so use it.
Global entity reuse covers the case where the same organisation appears across many rows and should resolve to one record rather than four hundred.
Duplicate identity rejection is a switch you turn on, separately for full identities and for name-based ones. Left off, the import is permissive and you get to reconcile afterwards. Turned on, the import refuses a file with internal duplicates and tells you which rows. On a real migration you want it on.
Bringing the open work with them
Once users resolve correctly, tasks can be created in the same import, batched, with a limit you set and validation before anything runs.
Batching matters for a boring reason. An import of four hundred users with three open matters each is twelve hundred task creations, and doing that in one transaction is a good way to discover your memory limits at four in the afternoon. Batched, with an explicit ceiling, an import that fails part way tells you exactly where it stopped.
Integration imports read XLSX as well as CSV, which sounds trivial until you've received the fourth export from a legacy vendor that only knows how to produce Excel. Compound duplicate matching handles the records that need more than one field to identify them, because plenty of real data has no single unique column.
The staged cutover this makes possible
Because import is repeatable and read-only until you commit, you don't need a big bang. The pattern we recommend:
Week one: import users only. No tasks, nothing live. You now have your people, roles and relationships in SwiftCase, and you can check the shape against your own org chart. If something's wrong, fix the file and run it again.
Week two: import closed cases as history. These carry no risk, because nobody is working on them. It gives your team something realistic to search, and it exercises your workflow configuration against real data.
Week three: run one workflow live, in both systems. Pick your highest-volume, lowest-complexity process. New work of that kind starts in SwiftCase. Everything else carries on where it is. This is the week you find the three configuration details no discovery call would ever have surfaced.
Week four onwards: migrate open cases per workflow. One process at a time, its open cases imported at the point you switch it over. A workflow that goes wrong affects one process for one day.
The old system stays available, read-only, for as long as it takes to stop reaching for it. That usually happens sooner than anyone expects, and the point is that nobody had to bet the operation on a weekend.
What to ask before you commit to any migration
Whoever you're evaluating, including us:
- Can I run the import repeatedly against real data without writing anything?
- Does the preview cover every row, or a sample?
- What does it refuse to commit, and can I see that list before I start?
- How does it decide that two records are the same person?
- Can open work come across with its status and answers intact?
- If it fails halfway, what state is my data in?
Any vendor who can answer all six has done this before. A vendor whose answer is "our team handles it during the cutover weekend" is telling you the tooling doesn't exist and the risk is yours.
Further reading:
- Users and permissions: roles, matching and the user record in detail
- Implementation: how we run a SwiftCase rollout
- 30-day pilot: starting with one workflow rather than all of them
- Workflows: building the process your imported work will run through
