Lean case study · Synthetic data

Where a card dispute spends its time

I mapped a fictional Canadian card issuer's dispute process, measured 1,200 synthetic cases in SQL, and tested five Lean changes against the same cases. Most of a dispute's life is spent waiting, and most rework starts at intake.

Fernbrook Card Services is fictional and every case comes from a seeded Python model. The process is an outside-in sketch of a typical dispute workflow and does not describe any real bank. Future-state results are estimates from stated assumptions.

01
Define

The problem

A disputed charge passes through six internal teams before the customer gets an answer: the contact centre, triage, disputes operations, the analysts, the chargeback team and customer resolution. In this model no team owns the whole path, so each queue is managed on its own.

Canada's Financial Consumer Agency (FCAC) requires banks to deal with complaints within 56 days and does not allow the clock to be paused. Its 2026 review found banks missing that limit, including one whose alert fired on day 55. I used 56 days as the outer limit for the whole dispute journey. Whether a particular dispute legally counts as a complaint is outside this study.

Questions

  1. Where does a dispute's time go: hands-on work, internal queues, the customer, or the merchant and card network?
  2. Which of the eight Lean wastes show up, and how large is each?
  3. What causes most rework, and does it differ by channel?
  4. Is the process stable week to week, and would a control chart catch a problem in time?
  5. Which changes cut the controllable lead time most, and what do they cost?

Scope

SuppliersInputsProcessOutputsCustomers
Cardholders, merchants, card network, contact centre Dispute details, transaction record, receipts, merchant response Intake, triage, documents, investigation, provisional credit, chargeback, merchant response, final decision Decision, final credit or rebill, notice to the customer, chargeback record The cardholder first, then finance, compliance and the merchant

The study covers the issuer's steps from intake to final notice. Fraud detection before a dispute exists, card replacement and the network's arbitration rules are left out.

02
Define

The current process

Seven working steps sit between the customer's first contact and the final notice, with two waits the issuer can't control. Queue times are first-pass medians and work times are averages.

Four loops send work backwards. Missing documents go back to the customer. A wrong category found during investigation goes back to triage and then to investigation again. A rejected chargeback is re-keyed, and an unreachable customer gets a second notice.

03
Measure

Data and model

TableRowsKeyOne row is
disputes1,200case_idA customer dispute with its channel, type, amount, tenure, outcome, and open and close times
process_stepsstep_event_id; unique (case_id, step_seq)One step on one case, with team, wait type, wait hours, work minutes and any rework reason
chargebackscase_idThe filing outcome and merchant response time for a case sent to the network
teams8team_idSix internal teams and two outside parties

The model in python/dispute_model.py draws every random value for a case up front with seed 2027, so a rerun produces the same files. The future-state scenarios reuse those draws and change only the process rules, which keeps luck out of the comparison.

Week 14 (6 to 12 April 2026) carries a planted analyst shortage that slows the investigation queue 2.2 times, so the control chart in section 05 can be checked against a known answer. All waits are calendar hours; there is no business-hours calendar.

SQL checks before analysis

The CSV files load into SQLite through sql/schema.sql, which sets primary keys, foreign keys and check constraints. Eleven validation queries run first, and the script stops if any of them finds a failure.

CheckFailuresResult

Medians and P90s use window functions instead of engine-specific percentile functions, so the queries move to PostgreSQL with small changes.

WITH ranked AS (
    SELECT internal_days,
           ROW_NUMBER() OVER (ORDER BY internal_days) AS r,
           COUNT(*) OVER () AS n
    FROM case_time
)
SELECT MAX(CASE WHEN r = CAST(0.5 * n AS INTEGER) THEN internal_days END) AS median_internal_days,
       MAX(CASE WHEN r = CAST(0.9 * n AS INTEGER) THEN internal_days END) AS p90_internal_days
FROM ranked;

All 18 analysis queries are in sql/analysis_queries.sql, and their output is in docs/query_results.md.

04
Measure

Where the time goes

The average dispute stays open days. Someone is working on it for hours of that.

One average case, start to finish

Each block is the average hours per case for one step, in process order. Work is drawn at a minimum width so it stays visible.

The part the issuer controls, enlarged

The same case with the customer and merchant waits removed.

Show as table

Inside the part the issuer controls (median days, P90 ), hands-on work is % of the time. The rest is cases sitting in queues between teams.

The longest single wait is outside the issuer: merchants take days on average to answer a chargeback. The issuer can't shorten that, but it can tell the customer what is happening and avoid stacking its own queues on top. Of all cases, % pass day 45 and % pass day 56.

Median queue wait before each step

Hours, first pass. P90 is in the table.

Show as table

Cases by age at closure

Share of all 1,200 cases.

Show as table
05
Analyze

Why it happens

% of cases repeat at least one step. A wrong dispute category and incomplete documents cause % of those cases, and both start at intake.

Cases with rework, by cause

Labels give each cause's case count, its share and the running total.

Show as table

Wrong category rate by intake channel

Phone and branch are wrong about twice as often as app and web.

Show as table

Cases with any rework, by channel

Phone produces the most rework, and app the least.

Show as table

Is the investigation queue stable?

An individuals (XmR) chart of the average investigation wait for cases opened each week. The limits are the mean plus or minus 2.66 times the average moving range.

Average investigation queue wait by opening week

Show as table

The chart flags week ( hours against an upper limit of ) and no other week. That is the planted shortage. The other 25 weeks vary inside the limits, so the way to lower the average wait is to change the process itself. With week 14 removed the upper limit tightens to hours, which is the limit to monitor from here.

The eight wastes

WasteWhere it shows upEvidence
DefectsWrong dispute category; chargebacks rejected for typing errors wrong-category cases and re-filed chargebacks
OverproductionNot found; work starts only when a customer raises a disputeNone
WaitingQueues before investigation, chargeback filing, triage and the final notice% of internal lead time
Non-utilized talentSpecialists investigating small disputes% of specialist hours go to disputes under $50
TransportationCases handed between teams handoffs per case, up to
InventoryWork in progress parked in queuesThe investigation queue holds waiting hours over 26 weeks
MotionTyping case details into the chargeback form by hand Chargeback Team hours
Extra processingFull investigation and chargeback for small disputes disputes under $50, averaging $

Five whys on the wrong category

  1. Investigation is repeated because the analyst finds the case was filed under the wrong dispute type and sends it back.
  2. The type was wrong because triage picks the category from the intake notes.
  3. The notes are unreliable because phone and branch intake capture a free-text story with no structured fields, and those channels are wrong about twice as often.
  4. Intake is free text because the call script is designed to keep calls short and never asks for what triage needs.
  5. The likely root cause is that no standard intake maps to the dispute categories. On real data I would confirm this with the process owners and a sample of case notes before changing anything.
06
Improve

Five changes, tested on the same cases

Each change targets one waste. I ran each one alone, then all five together at full and at half of the assumed effect.

ChangeWasteAssumed effect at full strength
Guided digital intake: required fields and document upload in the app and on the web, and a matching checklist for phone and branch agentsDefects, waitingIncomplete intake ×0.40 (app, web) and ×0.65 (phone, branch); second document requests halved; phone intake takes 1.5 minutes longer
Rule-assisted triage that suggests a category from the structured intake fieldsDefects, transportationWrong category ×0.40
Low-value fast track: non-fraud disputes under $50 from customers with at least a year of tenure are credited at triage and closed with no chargebackExtra processing, non-utilized talentThe issuer absorbs the disputed amount
A daily queue board showing work in progress and case age, with alerts at day 30 and day 45Waiting, inventoryInternal queue waits ×0.75; a surge like week 14 is caught sooner (the 2.2× slowdown becomes 1.4×)
Chargeback form pre-filled from the case recordMotion, defectsTyping errors ×0.25; four minutes less per filing

Median internal lead time by scenario

Days. Every bar runs the same 1,200 cases.

Cases past the deadline bands

Current state against all five changes at full effect.

The fast track has to pay for itself

Over a year, the fast track frees about hours of work and writes off about $ that the issuer would otherwise recover through chargebacks. That only pays if an hour of dispute work costs more than $ fully loaded. At the $ I assumed, the margin is thin, so I would pilot it with a lower dollar limit, track write-offs monthly, and keep it only if faster answers also cut repeat calls.

Recommendations, in order

Start here
A daily queue board with day-30 and day-45 alerts

It had the largest single effect in the simulation (median internal lead time days against ), it can start on a whiteboard or a shared spreadsheet, and it answers FCAC's day-55 finding directly. Waiting is % of internal lead time.

  1. Fix intake and triage together; they cover % of rework cases.
  2. Pre-fill the chargeback form to remove the re-filings and the second round of typing.
  3. Pilot the fast track behind the break-even test above.
  4. Send customers a status update during the merchant wait, the longest wait in the process and the one the issuer can't remove.
07
Control

Keeping the gains

Each measure has an owner, a review rhythm and a rule for what to do when it moves.

MeasureViewRhythmOwnerWhen it moves
Investigation queue waitXmR chart with limits from stable weeksWeeklyDisputes operations leadA point above the upper limit means checking staffing and work in progress that day
Open cases by ageDaily queue boardMorning stand-upTeam leadsPast day 30 a case gets a named owner; past day 45 it goes to the manager
Rework rate by causep-chart and monthly ParetoWeekly, monthlyTriage leadA new top cause gets a five-whys within two weeks
Fast track write-offsRun chart against budgetMonthlyFinance partnerAbove break-even, lower the dollar limit
Cases past day 56Count on the boardDailyDisputes managerThe target is zero, and each one is reviewed

What the board would have shown

On 18 March the investigation queue held cases. On 15 April, the week after the shortage, it held . A daily board puts that number in front of the team at the morning stand-up.

08
Integrity

Limits of this study

  • The data is synthetic. Rates and timings are assumptions built from public descriptions of card disputes, and no real bank's data or process is represented.
  • Future-state numbers apply assumed effects to the same cases. A real project would pilot each change and measure it.
  • The 56-day limit comes from FCAC's complaint-handling rules. Whether a dispute counts as a complaint is a legal question I haven't answered, and card network timelines, which vary by reason code, are simplified.
  • Time is calendar time with no business hours, holidays or staffing model, and queue effects are multipliers instead of a capacity simulation.
  • The $ hourly labour cost is an assumption used only for the break-even.
  • I designed the process, the assumptions and the recommendations, and checked every figure against the query output. I used Claude Code to help write the code.

Sources

Files