saveLead в одной IMMEDIATE-транзакции: заявка с тем же телефоном
моложе 10 минут → уточнение, если имя, интерес или комментарий
отличаются от последней версии, иначе повтор без записи. Окно от
created_at заявки, уточнения его не продлевают. Ответ 200 duplicate,
notifier получает id уточнения и список изменившихся полей.
db/: better-sqlite3 по DB_PATH (WAL, foreign_keys), миграции через
PRAGMA user_version, схема leads и lead_clarifications по плану.
createApp(deps) с инъекцией базы, часов и notifier (пока no-op, зовётся
после ответа). POST /api/lead: только JSON (415), тело до 16 КБ (413),
validateLead → 400, запись → 201. index.ts: env и graceful shutdown.
normalizeBelarusPhone/phoneError/formatBelarusPhone: любые форматы ввода
→ +375XXXXXXXXX, коды 25/29/33/44/17, подсказки по причине ошибки.
validateLead: типы POST /api/lead, ошибки по полям, honeypot, очистка
касаний. Тесты Vitest.
План по итогам интервью (docs/plan.md), GLOSSARY.md, ADR о двух
сервисах и о боте как канале администрирования, docs/ai-log.md,
.gitignore для секретов, базы и артефактов.