- убраны клиент бота, транспорт обновлений, отправитель сообщений, сборка входа при старте, секция настроек и зависимость go-telegram-bot-api; из конвейера ушла доставка ответа отправителю — исход виден опросом готовности. Колонки адресата и значение источника остались в схеме: применённые шаги не переписываются - шаг 202608140003 запрещает пустого владельца у аудиозаписи и у файла; существующие строки он не проверяет, и это принято сознательно — искать их надо запросом до выкладки - ревью нашло два пред-существующих дефекта, оба закрыты: пустой второй ответ распознавателя стирал сохранённую расшифровку, а пустая расшифровка перестала быть заметной вместе с убранной доставкой. Попутно поднят golang.org/x/image до v0.45.0 — красный шаг vulns, воспроизводился и на чистом master
12 KiB
12 KiB
1. Модель записи и отображение в хранилище
- 1.1 Убрать из
entity.AudioRecordполя адресата ответаTgChatIdиTgReplyMessageId - 1.2 Оставить константу
entity.SourceTelegramи объявить её комментарием историческим значением: на неё ссылается применённый шаг схемы202608140002, переписывать который запрещено инвариантом проекта - 1.3 Сделать владельца записи обычной строкой вместо ссылки, допускающей
отсутствие, и провести это через
applyToRecordиrecordToAudioRecord - 1.4 Убрать колонки адресата из
record_mapping.goв обоих направлениях; заведёнными в схеме они при этом остаются - 1.5 Завести новый шаг схемы: колонка владельца у аудиозаписи и у файла перестаёт принимать пустое значение. Откат шага возвращает необязательность
- 1.6 Убедиться, что ни один применённый шаг схемы не изменён:
task migrationsотвечает нулём - 1.7 Проверить, что конвейер заводит приведённую копию файла с владельцем записи: без этого первый же шаг приведения упрётся в обязательность колонки
2. Служба расшифровки
- 2.1 Убрать метод приёма записи от бота
CreateJobFromTelegram - 2.2 Убрать из службы отправителя сообщений: поле, параметр конструктора, отправку текста, сообщение о неудаче и запись о недоставке
- 2.3 Убрать метрику недоставленных ответов вместе с её причинами
- 2.4 Убрать человеческие тексты отказа, которые уходили отправителю: их единственным читателем была отправка. Шаг, доводящий запись до конечного рубежа, остаётся — он двигает рубеж, — и обращений наружу не делает ни одного
- 2.5 Убрать из
internal/archrulesтранспортinternal/controller/tgиз перечня транспортов: правило требует существования названных пакетов, и без этой правки гейт краснеет удалением каталога
3. Вход и сборка сервиса
- 3.1 Удалить пакет
internal/adapter/telegramцеликом - 3.2 Удалить транспорт
internal/controller/tgцеликом - 3.3 Удалить
telegram_build.goиtelegram_build_test.go - 3.4 Убрать из
main.goсборку входа, запуск транспорта в отдельной горутине и остановку бота при завершении - 3.5 Убрать из
internal/contractдоговор об отправителе сообщений - 3.6 Убрать выставление метки
telegramу признака поднятого входа; меткаhttpостаётся
4. Настройки и зависимости
- 4.1 Убрать
TelegramConfig, её умолчания и проверку обязательности ключаtelegram.enabled - 4.2 Убрать ключ
server.users_while_listиз структуры настроек и умолчаний. Имя написано с опечаткой —whileвместоwhite, — и она стоит «Расхождением» вdocs/conventions/config.md: удаление ключа закрывает и его - 4.3 Убрать секцию
[telegram]изconfig.example.tomlвместе с пояснениями. Ключа списка допущенных в образце нет — это второе записанное «Расхождение», и оно закрывается тем же удалением - 4.4 Прогнать
go mod tidyи убедиться, чтоgo-telegram-bot-apiушёл изgo.modиgo.sum
5. Проверки
- 5.1 Поправить тесты, опирающиеся на убранный вход: приём, владение, конвейер, метрики, недоставка, завершение работы
- 5.2 Оставить проверку того, что запись без владельца не заводится: приём
без учётной записи отвечает
403и не заводит ни файла, ни записи - 5.3 Оставить проверку того, что запись без владельца не достаётся опросом: ответ тот же, что и на неизвестный идентификатор
- 5.4
task gateзелёный целиком - 5.5 Поведенческая проверка на живом сервисе: подъём с файлом настроек без
секции
[telegram], приём записи по HTTP, опрос готовности, признак поднятого входа в метриках
6. Документы канона
- 6.1 Паспорт: убрать потребителя «Пользователь Telegram» и сценарии 3 и 4; поправить строку об основном входе и сценарий 6 — сообщения о неудаче отправитель больше не получает, а видит исход опросом. Убранный вход записать событием с датой, как записаны прочие сдвиги границы
- 6.2
CLAUDE.md: убрать инвариант «Бот отвечает только тем, кто в белом списке» (critical) целиком; переписать инвариант «Остановленная запись сообщает отправителю, какой бы ни была причина» (major) в терминах опроса готовности; переписать инвариант «Принятая запись не теряется молча» (major) — он требует сообщить пользователю и называет состояниеfailed, которого нет с прошлой задачи; снять «и без ответа отправителю» из инварианта о держателе захвата; поправить раздел «Что это» (входов больше не два), «Стек» (зависимость ушла) и запрет «Боевым токеном бота не запускаться» вместе с рецептом локального подъёма черезtelegram.enabled = false - 6.3
docs/architecture.md: поправить обзор capability поимённо — буллетыintake(признак включения входа),pipeline(недоставленный ответ),access(запись из Telegram без владельца), строку «поведение прочих узлов, включая приём из Telegram, живёт только в коде», принцип «бот, HTTP-сервер и воркеры в одном бинарнике» и строку «через него идут оба входа» в «Единых точках проекта»;docs/security.md— убрать вход из периметра;docs/database.md— сказать про колонки, оставшиеся без кода;docs/conventions/— снять ключи бота и закрыть оба «Расхождения» проusers_while_list - 6.4
docs/review.md: снять род узла «транспортinternal/controller/tg» и «клиент внешнего сервисаadapter/telegram» из типовых узлов, ложноположительное про запись без владельца, вопрос «через него идут оба входа», триггер метки «трогает оба входа сразу» и рецепт живого прогона черезtelegram.enabled = false - 6.5
README.md: убрать вход из описания сервиса и из настроек - 6.6 Проза актуальных спек, которую дельты не правят: разделы Purpose у
intake,pipelineиaccess— дельты правят только требования, и проза иначе уедет в архив с обещаниями про бота
Критерии приёмки
Постановка пришла текстом и критериев не назвала. Ниже — предложенные; приняты они после ответа человека на чекпоинте.
- Ни одного упоминания входа Telegram нигде в дереве, кроме мест, где оно
законно. Оракул:
grep -ri telegramпо всему репозиторию; законны ровно четыре места — применённые шаги схемы и константа источника, архив измененийopenspec/changes/archive/, записи решенийdocs/adr/и историческая часть журнала ревью. Всё прочее — находка. Оракул нарочно шире кода: прошлые удаления теряли документы именно потому, что их сверяли грепом поinternal/. - Применённые шаги схемы не переписаны, колонки
tg_chat_id,tg_reply_message_idи значениеtelegramперечня источников на месте. Изменение добавляет ровно один новый шаг — обязательность владельца. Оракул:task migrationsотвечает нулём,git diffпо каталогу шагов показывает только добавленный файл. - Запись без владельца завести нечем ни одним путём. Оракулы: тест приёма, где
сессия не даёт учётной записи, — ответ
403, ни файла, ни аудиозаписи не заведено; тест хранилища — сохранение записи и файла с пустым владельцем отклоняется схемой. - Отправитель узнаёт об остановке опросом готовности. Оракул: тест опроса на остановленной записи — поле рубежа несёт достигнутый рубеж, поле остановки несёт истину, машинного текста отказа в ответе нет.
- Сервис поднимается с файлом настроек без секции
[telegram]и принимает запись по HTTP. Оракул: живой запуск по разделу командCLAUDE.md,POST /api/audioотвечает201,GET /api/status/:idотвечает200. - Признак поднятого входа несёт метку
httpи не несёт меткиtelegram. Оракул: чтение адреса метрик у поднятого сервиса. task gateзелёный целиком.