-- +goose Up -- Секции тела, которых разбор не покрыл. JSON-массив имён (`["stateOfMind"]`), -- пустой список — `[]`. -- -- Массивом, а не строкой с разделителем: имя ключа приходит из чужого тела и -- может содержать что угодно, включая пробел и запятую. JSON снимает вопрос -- разделителя, согласуется с колонкой headers и читается из SQLite через -- json_each, если ретеншену это понадобится. -- -- Колонка — ответ на вопрос «что останется потерянным, если тело удалить». -- Для stateOfMind ответ необратим: в экспорте Apple его нет (находка 46), -- доставки HAE для него единственный источник. ALTER TABLE delivery ADD COLUMN uncovered_sections TEXT NOT NULL DEFAULT '[]'; -- Статус parsed, поставленный кодом, который частичного разбора не различал, -- ничего не доказывает: под ним лежат и полностью разобранные доставки, и -- доставки из одних тренировок с нулём точек (48 из 99 на живом архиве). -- Ретеншен, ради которого признак и заводится, поверил бы им и срезал тела. -- -- pending — консервативный статус: ретеншен не трогает его никогда, а подбор -- pending пересвернёт доставки из архива. Свёртка идемпотентна, повторный -- прогон журнала состояния не меняет. -- -- Целевой перевод только строк с points = 0 рассматривался и отвергнут: он -- опирается на наблюдение «секции не смешиваются», собранное за двое суток -- потока, а ставить на такое наблюдение необратимое удаление тел значит -- повторять ошибку, ради которой задача и заведена. UPDATE delivery SET parse_status = 'pending' WHERE parse_status = 'parsed'; -- +goose Down -- ВНИМАНИЕ: миграция односторонняя ПО ДАННЫМ. Down снимает колонку, но какие -- доставки были parsed, восстановить неоткуда — состояние пересобирается из -- архива, а не откатом. До появления подбора pending строки останутся в этом -- статусе. ALTER TABLE delivery DROP COLUMN uncovered_sections;