Trial accounts could not delete their own sites, and the complaint blamed the delete button. We read it that way too. It turned out to be a problem with a number that looked sensible but answered the wrong question.

What the page was supposed to do

The site belonged to a customer. Think of it like a family tree with three shelves. The whole site sat at the top. Groups sat beneath it. Units sat beneath those. Someone could delete the whole site from an admin page, but not in every case. If the site was large enough, or if the customer had put enough money into it, the page was meant to stop the deletion and say, “Please contact support.”

That basic idea made sense. Deleting a site could mean wiping out a year of schedules, and in some cases a person should take a second look before that happens.

Counting in the browser

The first version made that decision in the browser, meaning the page open on the customer’s computer. The page received an org graph, which is just a saved map of how the site, groups, and units were connected. Then it counted the units itself.

It did this with 35 lines of code and three nested loops. One loop went through the site’s children. The next went through their children. The third went through those children. Whenever it found something called a unit, it added one to the count.

Picture somebody trying to count all the apples in three crates by opening the first crate, then every smaller box inside it, then every bag inside those boxes. It can work if the packing arrangement never changes. But it is a fragile way to learn a fact that the stockroom already knows.

The page needed that count for one small decision: show the delete button, or show the contact-support message. It was doing all that counting even though the official system already kept the unit total. Worse, its three-loop plan only knew about three levels. If the organization later gained a fourth level, the page could count too few units. Nothing had to crash for that to happen. The answer would simply drift away from reality.

That approach also cost a trial user an unnecessary support email and some patience. An empty evaluation site that should have been easy to remove was being treated like an account that needed a human conversation first.

The price tag that nobody had paid

The unit count was not the only problem. The rule also looked at something called package value. That was the listed dollar value of the plan assigned to an account. The old page stopped a deletion if there were more than 20 units, or if that package value was above 100.

Here is the important difference. A plan can have a price on it even when no money has been paid. The trial account had a plan with a value above that old cutoff, but it had paid nothing. The policy was supposed to protect sites where a customer had actually invested money. The code was instead asking what plan name was attached to the account.

Those are not the same question.

The page successfully found a number, compared it to a cutoff, and did exactly what it had been told to do. The trouble was that nobody had stopped to check whether the number meant what the rule needed it to mean.

Moving both facts to the server

We fixed it by moving both facts to the server, the place where the official records live. Instead of making the page reconstruct the unit count from a map, the system asked directly for the number of units. Instead of using the listed price of a plan, it added up transactions marked as paid.

The new rule became much easier to say out loud: require contact if there are more than 20 units, or if more than a set amount has actually been received. A trial account with zero paid dollars falls below the money cutoff. It can delete its own evaluation site, which was the intended result.

The page became simpler too. It no longer had to walk through the organization tree or compare several fields. It received one small yes-or-no label, contactToDelete. If the label was yes, it showed the support message. If the label was no, the deletion could proceed.

That is a modest change, but the people using the page never see the hidden machinery. They see only whether a button does what it appears to do. When a rule gets in their way, it has to be based on the real thing it claims to measure.

A trial account at zero paid dollars was blocked from deleting an empty site because the rule read a plan’s listed value. If you have a rule that blocks customers, look at which number it reads, and whether that number is a sticker price or money that actually arrived.