refactor(intents): выпилить поле title из сущности Intent#242
Merged
Conversation
Удаляет мёртвую опциональную фичу title у Intent из всех слоёв: OpenAPI (source of truth), домен, application, API, EF/Infra, фронт и CLI-skill. Инвариант «card-linked intent обязан иметь title» уже снят (ADR-0052); поле ни на что существенное не завязано. Решения: - БД без новой миграции: колонки intents.title и intents_fts.title остаются orphan (приложение перестаёт их писать/читать). Миграции AddIntentTitle/IntentSearchIndex не тронуты; ThroneDbContextModelSnapshot приведён к модели (убран Title у IntentRow) — HasPendingModelChanges даёт false, старт/ef не падает. - Контракты C#/TS перегенерированы nswag + openapi-typescript из правленого openapi.yaml; генерируемые файлы руками не редактировались. - Убрано и то, чего не было в исходном плане, но что тянуло title: событие IntentTitleChanged (нигде не проецировалось в realtime) и проброс intent.State.Title через workspace-map промпт спавна терминала (WorkspaceMapPrompt/RunPreflightSpawn/PromptDelivery/Orchestrator) — строка «Заголовок интента:» в карте workspace убрана. Отброшено: - Полная чистка FTS5-схемы (drop колонки title в intents_fts): потребовала бы миграции, которая по решению не делается. bm25-веса в EfIntentSearchReader оставлены как есть — поиск по телу не ломается. - Правка EfIntentContextReader: тамошний o.Title — это board title (счётчики досок), к intent.title отношения не имеет; не трогалось. - Data-миграция для очистки существующих значений: не нужна. Ограничения: - Колонки title в intents и intents_fts остаются в БД навсегда пустыми. - ADR-0050/0052 упоминают title в прозе — текст ADR не правился (схему БД менять нельзя, правка прозы опциональна).
Ревизия прежнего решения «orphan-колонку не трогаем»: по требованию код приложения не должен знать про title никакими косвенными способами. Пока колонка оставалась в FTS, поиск позиционно завязан на неё (snippet индекс 2, bm25-вес title-слота) — это и убираем. Решения: - Новая EF-миграция DropIntentTitle: дропает FTS-триггеры и intents_fts, выполняет ALTER TABLE intents DROP COLUMN title, пересоздаёт intents_fts как (intent_id UNINDEXED, text) с триггерами без title и репопулирует из intents.text. Триггеры дропаются до колонки, иначе SQLite не даёт DROP COLUMN. Down полностью обратим (возвращает колонку и старый FTS). - EfIntentSearchReader: snippet(intents_fts, 1, …), bm25(intents_fts) без весов — text теперь единственная индексируемая колонка (позиция 1). Никаких упоминаний title в коде поиска не осталось. - ModelSnapshot/Designer сгенерированы EF; IntentRow без Title. Отброшено: - Вариант «только код, без миграции» (ограничить MATCH колонкой text, обнулить bm25-вес): убирает поведение, но snippet-индекс и слот веса структурно всё равно кодируют фантомную колонку — не полная чистка. Ограничения: - Миграция необратимо стирает legacy-значения title из БД (данные о заголовках больше не хранятся нигде).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Цель
Удалить мёртвую опциональную фичу
titleу Intent из всех слоёв: OpenAPI (source of truth), домен, application, API, EF/Infra, фронт и CLI-skill. Инвариант «card-linked intent обязан иметь title» уже снят (ADR-0052); поле ни на что существенное не завязано.Существенные изменения
specs/contracts/intents/openapi.yaml: удалён endpointPUT /api/v1/intents/{id}/title(+ его 422), полеtitleизCreateIntentRequest/IntentDetailDto/IntentListItemDto, схемаSetIntentTitleRequest. Контракты C#/TS перегенерированы (nswag + openapi-typescript) — генерируемые файлы руками не правились.Intent.SetTitle/NormalizeTitle, параметрtitleуCreate/Restore, полеIntentState.Title.SetIntentTitleHandler,SetIntentTitleOutcome,IIntentRepository.SetTitleAsync, DI-регистрация;Titleубран изCreateIntentCommand; удалено событиеIntentTitleChanged(нигде не проецировалось в realtime).SetIntentTitleEndpointи его wiring;Titleубран изIntentDtoMapperиCreateIntentEndpoint.IntentRow.Title+ маппинг/конфиг/мьютатор.intent.State.Titleв workspace-map промпт спавна (WorkspaceMapPrompt/RunPreflightSpawn/RunPreflightPromptDelivery/RunPreflightOrchestrator) — строка «Заголовок интента:» из карты workspace убрана.features/set-intent-title; шапкаIntentDetailHeaderпоказывает сниппет текста; поправленыuse-board-rowsиAddLinkForm.skills/intent/bin/throne-intent: убраны подкомандаset-titleи флаг--titleуcreate; обновлёнSKILL.md.БД / поиск (решение уточнено в ходе ревью)
Изначально договаривались оставить orphan-колонку без миграции. По требованию «код приложения не должен знать про title никакими косвенными способами» решение пересмотрено: пока колонка оставалась в FTS, поиск позиционно завязан на неё (
snippetиндекс 2,bm25-вес title-слота).DropIntentTitle: дропает FTS-триггеры иintents_fts,ALTER TABLE intents DROP COLUMN title, пересоздаётintents_ftsкак(intent_id UNINDEXED, text)с триггерами без title, репопулирует изintents.text. Триггеры дропаются до колонки (иначе SQLite блокирует DROP COLUMN).Downполностью обратим.EfIntentSearchReader:snippet(intents_fts, 1, …),bm25(intents_fts)без весов —textтеперь единственная индексируемая колонка. Упоминаний title в коде поиска не осталось.Отброшено
MATCHколонкойtext+ обнулить bm25-вес): убирает поведение, но snippet-индекс и слот веса структурно всё равно кодируют фантомную колонку — не полная чистка.EfIntentContextReader.o.Title— это board title (счётчики досок), к intent.title отношения не имеет.Ограничения
intents.titleиз БД (заголовки больше не хранятся нигде).Проверка
apps/api:dotnet build0/0;dotnet test— 1225 passed, 0 failed. Миграция применяется на живой SQLite черезMigrateAsync(в т.ч.EfSqliteRuntimeRegressionTests,EfIntentSearchTests) без ошибок.apps/web:pnpm codegen+pnpm typecheckчисто;pnpm test— 259 passed. В generatedintents/{types,endpoints}.tsнетtitle/setIntentTitle.