Technical debt in a company panel. The next billing change takes a month
Author:
Paweł Matusiak
·
A B2B panel and a CRM often “work”, and the firm still waits weeks for a new billing rule or a different job status. Technical debt is the deferred cost of that change: copied logic, three sources of the same document, the person who remembers where not to click. A conscious loan for the season makes sense. Without a list of shortcuts and an owner, the interest comes out of margin.
A field-service panel, a sales CRM or a job register all look much the same from the outside. Someone logs in, enters a customer, closes a document. The firm says the system works.
It works until the process moves. A different contract with a retail chain, a different billing cycle, a different visit status — and the office is told the change is not small. The screen that was meant to take a new rule in a week sits for a month. Price, status and the accounts export were once done as shortcuts, in several places at once.
Technical debt in software that is still being developed is the deferred cost of that change. The firm borrows time before the season or before a contract starts. The loan is rational when someone writes down what was postponed and comes back to it after the peak. Without a shortcut register and without a person who owns the list, the interest comes out of margin: a slower rollout of the new rule, more corrections on the invoice, more people who work around the panel in a spreadsheet.
In a small or medium-sized firm, while a panel is still growing, a simple rule will hold. Borrow time consciously. Repay against the cost of the next business change. A list of ugly places from a code review, without that measure, says nothing about whether a crew will go out tomorrow with a correct job.
Where debt comes from in a panel that is still growing
Debt does not appear on the day someone says the word in a meeting. It appears earlier, at a concrete decision. The contract has to start on the first of the month. The season will not wait. The owner wants a report in the morning. The programmer, or the firm doing the implementation, takes a shortcut. The price rule goes onto one screen, not into a shared place that the quotation, the job and the invoice all use. Visit status is written in the calendar because the job card is too slow. Parts stock stays in a comment field, for now.
Each of those shortcuts is understandable on the day it is made. The trouble starts when nobody records that it is a shortcut. A year later the panel holds several such decisions. Nobody remembers which table is true. The next change has to visit every place where the logic was copied. Sometimes one place is missed. The salesperson then sees a different amount from accounts.
The sources are usually prosaic.
- Copied logic instead of one place used by the quotation, the job and the invoice.
- A free-text field where there should be a dictionary: status, contract type, billing unit.
- An export to the accounts programme that works until somebody adds a column.
- No automated check on a rule that determines the amount on the invoice.
- A screen built for one quarter by someone who then does not return to the project.
Such an inventory does not judge the programmer. It records where the firm borrowed time. Without an inventory the loan has no instalment. It has only interest, which shows up at the next contract.
Some of the debt comes from outside. A PDF library nobody updates. A framework with no current patches. A package abandoned by its author. Who in the firm knows what sits in the panel is a separate conversation about open source in business software. Here the subject is closer to daily work: process logic that someone left half-finished in a hurry.
Example: an air-conditioning service and shortcuts that stayed after the season
Imagine a firm that services air-conditioning and ventilation. A dozen crews, a parts store by the hall, standing inspection contracts on retail and office sites. An example, not a GESOFT client story. A field-service application appeared when the spreadsheet list was no longer enough, and order in the flow from the call to the invoice did not keep up with the extra screens.
The dispatcher needed to see which site had an inspection that month. The technician in the field — what was last done on the roof. The office — whether the visit had gone onto an invoice. A customer list in a spreadsheet no longer covered that.
Over later seasons someone added screens. A crew calendar, because the phone could not handle the clashes. A field for parts used on the visit, done quickly as a comment. A separate export to accounts. An owner’s report that drops into a spreadsheet because the panel will not give margin per site. A client portal promised on one chain contract and left half-done: log-in exists, job status does not.
The trouble starts with a contract with a retail chain. The chain wants monthly billing per site, not per visit. The service owner signs. The office is to raise one invoice for a dozen locations, with an attachment of how many inspections and how many breakdowns. The programmer says job status has to be untangled first. Today the same status sits on the card, in the calendar and in the export. The amount on the invoice comes from yet another place than the price on the quotation. Nobody can total the parts comment into a stock line.
A change that in the conversation with the chain sounded like a different billing cycle splits, in the panel, across three tables and two exports. For weeks the office builds the invoice by hand. The technician on site does not know whether the breakdown sits inside the retainer or will be billed separately. The chain’s manager rings for a status and hears a different answer from the one in the dispatcher’s email.
In this story the panel needs one place for job status and one billing rule used by the card, the calendar and the invoice. Parts as lines with quantity, not as a sentence in a comment. The rest of the panel can wait. The chain will not.
The cost of the next change, not the cost of tidy code
Talk of debt often starts with programmer hours. How long to tidy up. How much to rewrite a module. Those are real sums, but they are not the first loss the firm feels.
The first loss is the cost of a change the firm already needs. The chain contract is signed. The billing cycle is to start next month. The office will raise the documents anyway. Either the panel handles them, or someone assembles them from the calendar, the comments and a spreadsheet. That person’s hours do not appear in a “tidy-up” quote. They come out of the contract’s margin.
The second loss is the error that reaches the customer. An invoice with a different amount from the quotation. An inspection marked done in the calendar and overdue on the site card. A complaint, a credit note, a call from the site manager. In air-conditioning work that call comes in a heatwave, when the crews are already spread thin. The office puts out a document fire instead of taking the next breakdown.
The third loss is pace. Each unusual contract takes longer than the last, because shortcuts accumulate. The owner starts turning down work the panel “will not handle”. Or takes it and adds manual labour. Both decisions are expensive. Neither comes from the code being ugly. They come from the process change having no single place where it can be written down.
The order of repayment comes from the business: which change is now most expensive while it sits still. In the example — billing per site. That is where the first work goes. The owner’s spreadsheet report can wait if one person runs it and nobody keeps a second, “truer” copy. A screen nobody opens does not go to the top of the list merely because a programmer would like to rewrite it.
The hours quote itself is misleading when it is set against the cost of a new application. Rewriting the whole panel looks like a clean sheet. The quote then loses the months in which the firm teaches the new system what the old one already knows: which sites have two manifolds, which contract has a weekend exception, who on the customer side takes the report. That cost appears after go-live, not in the proposal.
Crews, the office, and people who work around the screen
Debt shows first in how people behave, not in the repository. The technician does not add parts in the panel because the comment field vanishes after save. He sends a photo of the nameplate and a list of used material by messenger. In the morning the dispatcher types it onto the card — or does not, if the day is all breakdowns.
In the office someone keeps a private spreadsheet. Statuses from the panel are “for safety” corrected there. Before an invoice that person reconciles the calendar with the card and with the crew’s email. When they go on holiday, invoicing waits. Nobody else knows which field is decoration and which counts towards the amount.
In the service firm in the example that person is often a dispatcher of many years. They remember that on one screen the date must not be changed, because it breaks the export. They remember which status to enter when the visit happened but the report will arrive later. That operational knowledge is an asset of the firm. It sits in one head because the panel has no place where it could be stored as a rule.
Working around the system is rational. People want to finish the day. The problem starts when the workaround becomes the process. Then a new employee learns the spreadsheet and the messenger, not the panel. Induction takes longer. Errors return. The owner buys another training course for a programme the crew still does not use in full.
What helps here is a concrete, not a slogan about “better UX”. Job status visible on the technician’s phone before they leave. A parts list to tick on the visit, with a quantity that comes off hall stock. The dispatcher does not retype the messenger in the morning. A new employee sees the same screen as the regular. The person who “knows where not to click” can finally take holiday without stopping invoices.
If there are a few crews and one person writes jobs in a notebook, a panel on the phone will not help. A shortcut in the code is not the first problem then either. The first problem is a shared list of visits. Technical debt becomes a topic once that list already lives in a programme and people still flee it.
Parts stock, the invoice, and three versions of the same job
In air-conditioning work a part can sit in three places at once. On the shelf by the hall. In the box in the van. In the comment under the visit, if the technician managed to type it. The figure on the screen is then decoration. Purchasing is done by eye, because nobody trusts the number in the panel. A filter or a refrigerant is missing on a Friday afternoon, when a retail site will not wait until Monday.
The same job has three faces. The card says the visit is closed. The calendar — that the crew is still on site. The accounts export took the amount from the standard price list, not from the retainer in the contract. One source of truth about the job does not exist. There are three documents that someone in the office tries to reconcile before raising the invoice.
The effect is double. The store orders too much “to be sure”, or too little and the crew turns back. The invoice goes out late or with a correction. On a retainer with a chain, a late invoice spoils the month’s settlement. On a breakdown billed separately the customer gets a document they do not recognise, because on site they heard a different amount.
The shortcut that assembled this was simple. Someone did not want to build a parts dictionary and movement between hall and van, because the cooling season was already picking up. A comment “will do for this month”. After two seasons the comment is the only trace of what left the shelf. A stocktake at the hall diverges from the panel and nobody can say which number is lying.
Another report does not help here. A decision does: the job has one status and one list of lines. A part comes off van stock or hall stock at the moment the technician ticks it, not from memory in the evening. The invoice takes those same lines and the same contract rule. The calendar shows the same status as the card. The accounts export does not recalculate the amount from scratch.
If there are a dozen part numbers and one person issues them from the shelf, a spreadsheet can still suffice. The condition: nobody keeps a second stock figure on a phone. When there are a dozen crews and parts travel in vans, a comment under the visit stops being a store. Then parts movement in the panel is repayment of debt, not decoration.
When a loan for the season makes sense
Not every shortcut is a mistake. An air-conditioning service at peak has full rotas and breakdowns that will not wait for a proper table. A firm that in June stops the panel for three weeks of refactoring will lose contracts the debt was not worth. A conscious loan means someone names the shortcut a shortcut and sets a date to return.
The conditions of such a loan can be written down without a corporate-board methodology.
- The shortcut has an owner in the firm: a person who knows that the comment field is standing in for the store, and who will say so at the next change.
- The shortcut has an entry in the register: what was postponed, why, which process is fragile because of it.
- The shortcut has a review date after the peak, not the slogan “when there is time”.
- The shortcut does not go into a rule that determines the amount on the invoice, unless the office consciously agrees to assemble documents by hand until a stated date.
Without those four points the loan becomes the standing state of the panel. The season ends. The calendar empties. Nobody opens the list, because there is no list. At the next peak another shortcut is added. After a few years the panel still “works”, and every unusual contract goes back to being assembled by hand.
The register does not have to be a separate programme. A shared list in the place where work on the panel is already planned will do: a ticket, a document, a project card. What matters is that it lives next to development jobs, not in one person’s head. The service owner does not have to read code. They are entitled to know that billing per site sits on a copied price, and that the next chain will repeat the same jam.
Sometimes a shortcut stays for good, because the process will not repeat. A screen for one marketing action. An import from a spreadsheet when a handful of contracts are taken over. Then repayment makes no sense. What makes sense is switching the screen off after the action, so that nobody takes it for the proper path. Debt that is neither repaid nor switched off becomes a trap for a new employee who treats the comment as the store.
Rewrite the panel from scratch. The counter-argument and the limits
The strong counter-argument is simple. The old panel is no good. It is cheaper and safer to rewrite from scratch, or to buy an off-the-shelf programme for field service and move the customers. The old shortcuts are left behind. What remains is a new programme, a clean structure and a vendor’s contract.
In some firms that argument is right. The framework no longer receives patches. Nobody in the team understands how the invoice is calculated. There are no tests. The person who remembered the exceptions has left. Every change breaks something on the other side of the screen. Then evolution is a pretence. The firm patches holes and calls it modernisation.
Even then a full rewrite is rarely the cheapest path. The old panel holds process knowledge nobody wrote down: the weekend exception, the second manifold on the site, a different person who takes the report. The new system starts “cleaner” and for the first months learns that again, on live invoices. An off-the-shelf programme for field service is often reasonable when the visit, the part and the invoice are standard. When a chain wants a retainer per site and another customer wants a rate per unit, the off-the-shelf product often ends with a comment and a spreadsheet beside it again.
Hence a bounded rewrite: one module that blocks the most expensive change, with an explicit boundary. In the example — billing and job status, not the holiday calendar and not the owner’s report. The old screen keeps running until the new one calculates the same invoice against a set of old contracts. Only then is traffic switched. The rest of the panel stays.
The limits of the approach proposed here need to be stated plainly. A shortcut register will not repair an abandoned framework. It will not bring back the person who left. It will not make a small team able to run two panels at once for a year. Evolution works when one can point to the place from which the quotation, the job and the invoice take the rule — or when such a place can be built alongside, without switching the rest off. It does not work when the panel is a collage of screens from successive jobs and nobody can say which table is true.
Debt is sometimes political, not technical. The owner will not touch the screen because “it works”. The dispatcher does not want a shared status because their own spreadsheet gives them control. The programmer does not want a register because then it is visible what was postponed. No architecture will repay that. First one has to name who loses on assembling the invoice by hand. Only then does one choose evolution, a module, or an off-the-shelf programme.
Spreadsheet, off-the-shelf programme, or evolution of the existing panel
A few crews, one price list, one person in the office — a spreadsheet will hold the rota and the invoice if nobody keeps a second copy on a phone. A standard visit, a standard part, a standard invoice — an off-the-shelf programme often adds up more cheaply than one’s own code, even if that code could be tidied.
The firm’s own panel is justified when the process is unusual. A retainer per site beside a rate per breakdown. A part in the van and at the hall. A report that a chain customer wants on their own form. Then repayment of debt and evolution of the existing system are usually cheaper than a fresh start. A fresh start makes sense when the old one can no longer be touched safely.
GESOFT, on such an engagement, first writes the flow down: who closes the job, where the amount on the invoice comes from, what happens when a part came off the van rather than the hall. Only then is it clear whether order in the existing panel will do. In the same engagement one can do a debt inventory: list the shortcuts, show which business change they are blocking, and plan repayment or a bounded rewrite of a module.
Sometimes an integration with the accounts programme and one place for status will do. Sometimes the comment has to be replaced with a store of lines and the rest of the screens left alone. Sometimes after the flow is written down it is clear that a spreadsheet still suffices, if one person raises the invoice rather than a dozen crews. That conversation is cheaper than announcing that “the system must be rewritten because there is debt”.
What remains from the arguments is a simple order of work. Technical debt in software that is still being developed is taken on consciously and repaid from the most expensive process change. The service firm in the example does not need an ideology of clean code. It needs a list of shortcuts, one job status, and a person who will open that list again after the season. Without the list the panel still “works”. The chain contract still drops into a spreadsheet.
Frequently asked questions
- Is every shortcut in the panel technical debt?
- No. A shortcut with an owner, an entry and a review date is a loan. It becomes debt when nobody remembers that it is a shortcut, and the next process change has to visit several places at once. A screen for one action that is switched off afterwards does not have to be repaid.
- When is it better to rewrite a module than to patch the existing screen?
- When nobody understands how the invoice is calculated, when every change breaks another screen, or when the layer no longer receives patches. Even then it is usually cheaper to rewrite one module with an explicit boundary — status and billing, not the whole panel — and to compare the new invoice with old contracts before switching traffic.
- Is a spreadsheet itself debt?
- Not by itself. It becomes a problem when it is a second, “truer” copy of what sits in the panel, and when the invoice depends on the person who reconciles that sheet. A few crews and one price list in a spreadsheet kept by one person can be cheaper than an application of one’s own.
Related service:
Custom software for companies
Describe your project