Underwritetenant/underwrite-demo
Role
Request a demo

Operator surfaces: queues, clocks, correspondence, billing.

Advance fees are a data model problem

CROA says no fee before the service is fully performed. Most systems treat that as a policy. It is cheaper to treat it as a foreign key.

CROA 15 U.S.C. 1679b(b) is one sentence long in substance: no credit repair organisation may charge or receive any money for the performance of any service before that service is fully performed. Every operator we have worked with knows this. Most of them still have a system that can produce an invoice against work that has not happened.

The usual shape, and why it leaks

The normal design has a customer, a subscription, and a billing date. Services live somewhere else entirely, usually attached to a case. Nothing in the schema connects the money to the work, so the rule has to live in a person: someone is supposed to check before the run.

That works right up until the month somebody is on leave, or the billing job runs before the overnight import, or a case closes and reopens. The failure is never dramatic. It is one invoice, for one client, for work that had not landed yet.

Making the rule a foreign key

An invoice line in our schema cannot exist without a service line, and a service line has exactly one field that matters here: performed_at. It is null until the work reaches a performed state with evidence attached, and it is written by the state machine rather than by a person.

POST /v3/invoices

409 Conflict
{
  "error": "fee_before_performance",
  "rule": "CROA 15 U.S.C. 1679b(b)",
  "unperformed_lines": [
    { "line": "SL-4417-DISPUTE", "performed_at": null }
  ]
}

The response names the line. That detail matters more than it looks: a generic conflict teaches people to retry, and a named line teaches them to go and look at the case.

The argument we lost, and were glad to

The first version had a force parameter, for the reasonable sounding case where an operator knows the work is done but the evidence has not landed. We removed it after one conversation with a compliance officer, who pointed out that the first thing an examiner asks about an override is the log of who used it, and the second is why the number is not zero.

Now there is no parameter and no role that can supply one. If the evidence has not landed, the fix is to land the evidence, which takes a minute and leaves a record.

What about subscriptions

Operators who bill monthly usually structure a month as a set of service lines rather than as a single subscription. The month invoices for the lines that were fully performed inside it. That is more work to model and it produces an invoice a client can actually read, which turns out to reduce disputes about the invoice itself.

The telephone case

If an operator sells by telephone, the Telemarketing Sales Rule at 16 CFR part 310 also applies, and its advance fee provisions for credit repair are stricter than CROA. The platform records which channel a sale came through so that the applicable rule is on the case rather than in somebody's memory. Which rule governs a given sale is a question for your counsel, and the point of recording the channel is to make that question answerable.

The general lesson

Any obligation of the form do not do X before Y can be a schema constraint instead of a procedure. Procedures need people. Constraints need a migration. Only one of those two is still working at three in the afternoon on the last Friday of the month.