хранилище, файлы записей и очередь переведены на встроенную PocketBase
- записи, метаданные и файлы съехались под один каталог данных; появилась панель владельца, а gin, goqu, goose и требование CGO ушли - захват задачи стал одним запросом с RETURNING; заведены число попыток, состояние dead и нарастающая пауза вместо признака is_error - имя файла в хранилище задаёт сервис и в журнал не идёт: вместе с идентификатором записи оно собирало бы ссылку на скачивание
This commit is contained in:
@@ -15,6 +15,9 @@
|
||||
|
||||
- **PK сущности — TEXT ULID** (26 символов Crockford base32), генерируется
|
||||
**приложением** в момент создания записи.
|
||||
*Расхождение:* идентификаторы записей выдаёт хранилище — 15 знаков
|
||||
собственного алфавита. Своей точки генерации у приложения нет, и `ORDER BY id`
|
||||
хронологией не является: порядок берут по колонке времени с ключом.
|
||||
- Почему ULID: сортируем по времени создания (`ORDER BY id` = хронология),
|
||||
компактен и удобен в URL и логах (без дефисов — grep и двойной клик берут id
|
||||
целиком), глобально уникален между таблицами — поиск по голому id находит все
|
||||
@@ -43,14 +46,21 @@
|
||||
|
||||
- Enum-поля (`state`, `source`, …) — обычный `TEXT` без `CHECK`; допустимые
|
||||
значения держит код.
|
||||
*Расхождение:* перечень состояний задачи закрыт схемой (`SelectField`), а не
|
||||
кодом — ради панели владельца: правка руками не должна заводить состояние,
|
||||
которого конвейер не знает. Цена названа: шестое состояние потребует нового
|
||||
шага схемы.
|
||||
- Временные метки — `TEXT` в **RFC 3339, UTC (суффикс `Z`)**, например
|
||||
`2006-01-02T15:04:05Z` (секундная точность). Фиксированная ширина сохраняет
|
||||
лексикографическую сортировку TEXT, то есть хронологию (`ORDER BY created_at`).
|
||||
Единая точка генерации — приложение, а не умолчание в схеме: так забытая
|
||||
вставка падает громко. Измерение длительности — не метка времени.
|
||||
- Миграции — goose (`migrations/`): SQL-файлы для DDL; Go-миграции
|
||||
(`goose.AddMigrationContext`) — когда нужен код (генерация id, заполнение
|
||||
задним числом). При изменении структуры обновляем схему
|
||||
- Миграции — шаги PocketBase на Go (`internal/adapter/repo/pocketbase`):
|
||||
коллекции и их поля заводятся кодом. При изменении структуры обновляем схему
|
||||
[../database.md](../database.md) тем же изменением.
|
||||
- Добавляя колонку, соблюдай инвариант «Новая колонка правится во всех четырёх
|
||||
местах» — [CLAUDE.md](../../CLAUDE.md), «Инварианты».
|
||||
- Время в **сыром запросе** кладётся и сравнивается тем же видом, каким
|
||||
хранилище пишет свои `created`/`updated`. Сравнение строк побайтово, и
|
||||
разошедшийся вид обращает условие в постоянную истину или ложь — молча.
|
||||
- Выборка «следующей» записи с `LIMIT 1` дополняется ключом в `ORDER BY`:
|
||||
сравнение по неуникальному значению делает порядок обработки
|
||||
невоспроизводимым.
|
||||
|
||||
Reference in New Issue
Block a user