- убраны клиент бота, транспорт обновлений, отправитель сообщений, сборка входа при старте, секция настроек и зависимость go-telegram-bot-api; из конвейера ушла доставка ответа отправителю — исход виден опросом готовности. Колонки адресата и значение источника остались в схеме: применённые шаги не переписываются - шаг 202608140003 запрещает пустого владельца у аудиозаписи и у файла; существующие строки он не проверяет, и это принято сознательно — искать их надо запросом до выкладки - ревью нашло два пред-существующих дефекта, оба закрыты: пустой второй ответ распознавателя стирал сохранённую расшифровку, а пустая расшифровка перестала быть заметной вместе с убранной доставкой. Попутно поднят golang.org/x/image до v0.45.0 — красный шаг vulns, воспроизводился и на чистом master
78 lines
4.1 KiB
Go
78 lines
4.1 KiB
Go
package migrations
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/pocketbase/pocketbase/core"
|
|
)
|
|
|
|
// up202608140003 запрещает пустого владельца у аудиозаписи и у её файла.
|
|
//
|
|
// Прежде пустое значение допускалось, и цену за это платили записи, принятые
|
|
// ботом: связи чата Telegram с учётной записью сервис не вёл, и владельца у них
|
|
// не было вовсе. Вход Telegram убран, заводить ничью запись стало некому, и
|
|
// обязательность переезжает из приёма в схему — туда, где её держит хранилище, а
|
|
// не договорённость. Разница не косметическая: пока обязательность жила в
|
|
// приёме, ничью запись заводили руками в панели, она уходила в конвейер, стоила
|
|
// денег на распознавание и не доставалась потом никому.
|
|
//
|
|
// Существующих строк шаг **не смотрит**, и это проверено прогоном: хранилище
|
|
// держит обязательность связи проверкой записи при сохранении, а не ограничением
|
|
// таблицы, поэтому смена признака на базе с ничьей записью проходит зелёным и
|
|
// такую запись оставляет. Искать ничьи строки надо до выкладки и запросом —
|
|
// `SELECT count(*) FROM audio_records WHERE owner = ”` и то же по `files`;
|
|
// прогон самого шага на копии этого не показывает.
|
|
//
|
|
// Оставленная ничья запись становится незакрываемой: захват идёт сырым запросом
|
|
// мимо проверки и выдаёт её воркеру, а всякое сохранение — включая то, которым
|
|
// ставится признак остановки, — отказывает. Порядок выкладки поэтому начинается
|
|
// с проверки данных, а не с прогона шага.
|
|
func up202608140003(app core.App) error {
|
|
for _, name := range []string{RecordsCollection, FilesCollection} {
|
|
if err := setOwnerRequired(app, name, true); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// down202608140003 возвращает колонке необязательность. Записей это не касается:
|
|
// пустых значений среди них нет, а появиться им теперь неоткуда.
|
|
func down202608140003(app core.App) error {
|
|
for _, name := range []string{RecordsCollection, FilesCollection} {
|
|
if err := setOwnerRequired(app, name, false); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// setOwnerRequired правит признак обязательности у колонки владельца одной
|
|
// коллекции. Колонка ищется по имени и приводится к типу связи: шаг, молча
|
|
// пропустивший чужой тип, оставил бы схему в состоянии, о котором никто не
|
|
// узнает.
|
|
func setOwnerRequired(app core.App, collectionName string, required bool) error {
|
|
collection, err := app.FindCollectionByNameOrId(collectionName)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to find collection %s: %w", collectionName, err)
|
|
}
|
|
|
|
field := collection.Fields.GetByName("owner")
|
|
if field == nil {
|
|
return errors.New("collection " + collectionName + " has no owner field")
|
|
}
|
|
|
|
relation, ok := field.(*core.RelationField)
|
|
if !ok {
|
|
return errors.New("owner field of collection " + collectionName + " is not a relation")
|
|
}
|
|
|
|
relation.Required = required
|
|
|
|
if err := app.Save(collection); err != nil {
|
|
return fmt.Errorf("failed to change owner requirement in %s: %w", collectionName, err)
|
|
}
|
|
return nil
|
|
}
|