Я не писал ТЗ на тридцать страниц. Требования формулировались словами, из них сборка разворачивал схему данных, код, тесты и миграции, а я держал постановку, проверку и разбор спорных мест: там, где ошибка стоит денег, решение остаётся за человеком.
01Деньги как книга записей, а не как остаток в ячейке
Каждое движение денег пишется в отдельную книгу, где строку нельзя переписать задним числом. Баланс нигде не хранится числом, которое можно перезаписать: есть только история операций, а остаток из неё вычисляется. Поверх стоит правило, которое обязано выполняться всегда (на языке разработчиков это инвариант): итог по книге обязан сойтись с остатком. Сходится до копейки, и проверяет это не мой глаз, а программа. Долги гасятся по очереди, сначала самый старый (FIFO), без ручного выбора «какой платёж к какому счёту отнести».
02Личные кабинеты
Клиент заходит и видит своё: баланс, операции, историю, документы. Вопрос «а сколько у меня сейчас» перестал быть вопросом к менеджеру.
03Документы кодом
Агентские акты и отчёты генерируются в PDF и DOCX из тех же данных, что показаны в кабинете, на 144 клиента разом. Документ собирается прямо из денежной книги, поэтому разойтись с ним он не может: в шаблон никто ничего не вставляет руками.
04Сверка с внешней системой
Портал импортирует отчёты внешних сервисов и сверяется с Google-таблицами, которые остались в обиходе у людей. Ручной учёт не ломался об внедрение: две картины мира сравниваются программно, расхождения видно сразу.
05Тесты и миграции как страховка
1300+ автотестов и 40+ миграций базы: структура базы менялась больше сорока раз, и ни один раз это не уронило работу клиентов. Это не про красивую отчётность разработчика: система с деньгами меняется постоянно, и без тестов каждое изменение превращается в лотерею. Здесь правки выкатываются спокойно, потому что сначала падает тест, а не месячный акт клиента.
06Боевой прод вместо демо
Пять сервисов, systemd, база, регламент обновления. Портал работает ежедневно, на нём висит живая операционка. Это единственная честная проверка бэкенда.