A debt-settlement portal built to Russian federal law
A self-service portal where people settle a debt without a phone call, built end to end as sole developer for a licensed Russian collection organisation. Federal law set the architecture: personal data stays in the country, and every login code is counted against a legal contact allowance, the conservative reading of an unsettled question; both are enforced in code and at build time.
Settlement calculator
| Months | Discount | Monthly | Last payment |
|---|---|---|---|
| 1 | 30% | 42,000 ₽ | 42,000 ₽ |
| 2 | 25% | 22,500 ₽ | 22,500 ₽ |
| 3 | 25% | 15,000 ₽ | 15,000 ₽ |
| 4 | 20% | 12,000 ₽ | 12,000 ₽ |
| 5 | 20% | 9,600 ₽ | 9,600 ₽ |
| 6 | 20% | 8,000 ₽ | 8,000 ₽ |
| 7 | 15% | 7,286 ₽ | 7,284 ₽ |
| 8 | 15% | 6,375 ₽ | 6,375 ₽ |
| 9 | 15% | 5,667 ₽ | 5,664 ₽ |
| 10 | 15% | 5,100 ₽ | 5,100 ₽ |
| 11 | 15% | 4,637 ₽ | 4,630 ₽ |
| 12 | 15% | 4,250 ₽ | 4,250 ₽ |
| 13 | 10% | 4,154 ₽ | 4,152 ₽ |
| 14 | 10% | 3,858 ₽ | 3,846 ₽ |
| 15 | 10% | 3,600 ₽ | 3,600 ₽ |
| 16 | 10% | 3,375 ₽ | 3,375 ₽ |
| 17 | 10% | 3,177 ₽ | 3,168 ₽ |
| 18 | 10% | 3,000 ₽ | 3,000 ₽ |
| 19 | 10% | 2,843 ₽ | 2,826 ₽ |
| 20 | 10% | 2,700 ₽ | 2,700 ₽ |
| 21 | 10% | 2,572 ₽ | 2,560 ₽ |
| 22 | 10% | 2,455 ₽ | 2,445 ₽ |
| 23 | 10% | 2,348 ₽ | 2,344 ₽ |
| 24 | 10% | 2,250 ₽ | 2,250 ₽ |
| 26 | 5% | 2,193 ₽ | 2,175 ₽ |
| 27 | 5% | 2,112 ₽ | 2,088 ₽ |
| 28 | 5% | 2,036 ₽ | 2,028 ₽ |
| 29 | 5% | 1,966 ₽ | 1,952 ₽ |
| 30 | 5% | 1,900 ₽ | 1,900 ₽ |
| 31 | 5% | 1,839 ₽ | 1,830 ₽ |
| 32 | 5% | 1,782 ₽ | 1,758 ₽ |
| 33 | 5% | 1,728 ₽ | 1,704 ₽ |
| 34 | 5% | 1,677 ₽ | 1,659 ₽ |
| 35 | 5% | 1,629 ₽ | 1,614 ₽ |
| 36 | 5% | 1,584 ₽ | 1,560 ₽ |
The login’s statutory cost, in messages
No code requested yet.
Calls are a separate channel with separate caps — 1 a day, 2 a week, 8 a month — and the login path is forbidden by a build gate from importing them.
| Window | Messages allowed |
|---|---|
| 24 hours | 2 |
| 7 days | 4 |
| 30 days | 16 |
The product
People in debt avoid the phone call, so the product is the opposite of one: look the debt up, see what a settlement would cost and over what schedule, and reach an SBP payment screen whose amount the server recomputes — without speaking to anyone. I am the only developer, building it end to end for a licensed collection organisation: the debtor flow, the arithmetic, the statutory limits, the disclosures, and the build gates that keep them true.
What the law set
Two federal laws decided the architecture before any product decision did. 152-FZ keeps personal data in the country, which ruled out foreign hosting, foreign font CDNs and foreign analytics: the portal runs in a Russian cloud region with self-hosted Cyrillic typography, and zero third-party origins is a build gate rather than a policy.
230-FZ caps creditor-initiated contact, and a login code is an electronic message. Whether a code the debtor asked for counts is not settled, so the code names the question, documents all three readings, and ships the conservative one — one contact per verification episode — with the reason written as an asymmetry: if counsel says it does not count, a constant flips; had it shipped permissive, the state machine would need rewriting. The abuse throttle runs before the statutory counter, so an attacker cannot spend a real debtor’s allowance for them.
Money you can audit
Every amount is integer kopecks and every discount integer basis points; a float never touches money. The discount is floored, recurring payments round up to a whole rouble and the final payment absorbs the remainder, a single payment is exact to the kopeck, and the offered terms are pruned so that no longer term ever costs more a month than a shorter one. The payment step recomputes the amount on the server from the chosen term and the debtor’s own obligation; it never accepts an amount from the browser, and no debt data ever travels in a URL.
Compliance enforced at build time
Because calls and messages have different ceilings, importing the wrong set at a send site is a compliance bug no happy-path test would catch. The telephone caps live in their own module, and a static check forbids the login path from importing them — matching static imports, dynamic imports and require calls alike. A display component that publishes both caps on the rights page is banned only from the route that actually sends and counts.
Standards are build gates rather than intentions: types, lint, contrast computed from the design tokens, origin compliance, a JavaScript size ratchet, and accessibility 100 as a hard failure. The layout-shift gate is 0.05 and the measured value is 0 on every audited route; the suite declares 226 unit tests and runs 146 end-to-end cases.
The gates are held to the same standard as the product: a boolean audit takes the worst of its runs, never the median, and a server is ready when it answers a request, not when it prints a log line — an assertion measured against an environment no real visitor uses is not a guard.
- sole developer and project lead
- in active development
- a licensed collection organisation; not named here
- Next.js 16 · React 19 · Turbopack · Tailwind 4 · Yandex Cloud