Я часть проектов пишу сама, часть веду командой. Во втором случае наступает момент приёмки: разработчик говорит «готово», и надо понять, готово ли.
Этот список собран не из методологии, а из вещей, которые у меня ломались. Каждый пункт стоил времени.
1. Проект собирается с нуля, а не «у меня работает»
Первое, что я делаю, — собираю с чистой папкой сборки. Не запускаю дев-сервер, а именно собираю продакшен.
Половина случаев «а у меня всё работало» — это подхваченный кеш предыдущей сборки. Пока старые артефакты лежат на месте, проект может собираться на том, чего в репозитории уже нет.
2. Типы проверяются отдельно от сборки
Проверка типов и сборка — разные вещи, и падают они по-разному. Тайпчек может пройти, а сборка упереться в окружение. Или наоборот: сборка соберётся, а типы окажутся сломаны в файле, который в бандл не попал.
Гоняю оба и смотрю, что именно упало.
3. База поднимается на пустом месте
Проверяю не на своей базе, где всё уже есть, а на чистой. Схема должна подниматься сама.
Отдельно смотрю, что происходит со старой базой, в которую добавили поле. Если миграций в проекте нет и схема поднимается кодом, новое поле надо добавлять и в создание таблицы, и отдельной проверкой для уже существующих баз. Забыть вторую половину — обычное дело: на машине разработчика база свежая, поле есть, всё работает. На проде — падает.
4. Граница клиента и сервера
Самый неприятный класс ошибок: серверный код, утёкший в браузерный бандл. Драйвер базы тянет за собой файловую систему, сборщик спотыкается, а сообщение об ошибке указывает куда угодно, только не на причину.
Ловушка в том, что импорт одной константы из серверного файла тащит весь файл целиком. Поэтому общие вещи — типы, справочники, подписи статусов — должны лежать в отдельном модуле, который сам ничего серверного не импортирует.
Проверяю просто: ищу в клиентских компонентах импорты из серверных модулей.
5. Что происходит на чужих данных
Свои тестовые данные разработчик проходит успешно по определению — он под них и писал.
Смотрю на границы: другой часовой пояс, пустое значение там, где ожидалась строка, длинный текст в поле на одну строку, кириллица там, где тестировали на латинице.
Отдельно: если оператор или заказчик начал что-то править руками — это баг, а не особенность работы. У меня был случай, когда часть записей сохранялась с неправильным временем, и нашлось это не по логам, а потому что человек молча исправлял строки. Люди привыкают к поломке и перестают о ней сообщать.
6. Лимиты платформы названы вслух
У любой платформы есть потолки, и их лучше узнать до релиза. Ограничение по времени выполнения, размеру запроса, количеству вызовов.
Вопрос разработчику звучит так: что здесь упрётся первым и на каком объёме. Если ответа нет — значит, не считали, и упрётся оно на клиенте.
7. Шрифты и локаль
Мелочь, которая портит впечатление сразу: шрифт без нужного алфавита. Гарнитура подставляется молча, заголовки теряют вес, и на макете этого не видно, потому что макет рисовали в другом инструменте.
Проверяю живой текст на реальном языке проекта, а не «Lorem ipsum».
8. Доступы оформлены на меня или на заказчика
Пункт, который вспоминают в худший момент — когда подрядчик уже не отвечает.
Проверяю до начала работы, а не при приёмке: на кого зарегистрирован домен, чей аккаунт у хостинга, кто владелец платёжного кабинета, на чью почту заведены сторонние сервисы. Правильный ответ — заказчик или я, с разработчиком в роли приглашённого пользователя.
Ключи и токены передаются не в переписке. Если пароль от боевой базы лежит в чате, его надо считать скомпрометированным и менять при передаче проекта, а не «когда-нибудь».
Отдельно — что происходит при расставании: у кого остаётся доступ, что нужно отозвать, кто это делает. Разговор неловкий ровно один раз, в начале. В конце он неловкий и дорогой.
9. Что останется, когда разработчик уйдёт
Последний пункт, и он про меня, а не про код. Если проект нельзя передать другому человеку — он не готов.
Минимум: как поднять локально, где лежат настройки, какие внешние сервисы подключены и чьи там ключи, что делать при типовой аварии. Писать это надо в тот момент, когда объясняешь голосом второй раз. На пятый уже кажется очевидным, и в документацию не попадает.