хранилище переехало с PocketBase на SQLite со своим каталогом файлов
- база своя: два пула, захват одним UPDATE ... RETURNING, шаги схемы на goose под файловым замком, одна миграция начальной схемы вместо семи прежних - транспорт переписан на net/http: свои слои, свой ограничитель частоты, отдача файла с проверкой владельца; панель /_/ и пространство /api/ исчезли - по находкам ревью: журнал не пишет путь под корнем приложения, ключ бюджета читается справа налево, узнавание известного идёт читающим пулом
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
## Why
|
||||
|
||||
Встроенное хранилище куплено ради трёх вещей — панели владельца, файлов рядом с
|
||||
базой и входа через его провайдера, — и третья отпала 2026-08-22: пришедшего
|
||||
называет обратный прокси, а учётную запись заводит сам сервис. Оставшееся
|
||||
хранилище держит не только хранение: оно же маршрутизатор, цепочка слоёв,
|
||||
ограничитель частоты, отдача файлов и второй периметр на том же порту. Второй
|
||||
периметр опубликован в интернет вместе с панелью, его барьер обходится подменой
|
||||
знака в адресе, а закрыть его целиком нельзя — за файлами записей туда ходит
|
||||
браузер человека.
|
||||
|
||||
Момент назначен обстоятельством: на сервере данных нет и сервис остановлен,
|
||||
поэтому смена стоит только кода. Дешевле она не станет — код входов прирастает
|
||||
чужими типами с каждой задачей.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Сервис работает с базой напрямую и заводит свою схему своими шагами, двигая их
|
||||
библиотекой `goose`. Раскладка каталога данных меняется — **BREAKING**,
|
||||
необратимое.
|
||||
- Файлы записей ложатся в свой каталог со своей раскладкой и отдаются своим
|
||||
адресом сервиса. Право пройти по ссылке даёт узнавание и владение записью, а
|
||||
не короткий токен, выданный хранилищем на предъявителя.
|
||||
- Панель администратора исчезает и **не заменяется ничем** — **BREAKING**.
|
||||
Остановленную запись возвращает в работу подкоманда набора инструментов
|
||||
разработчика — через домен и с событием журнала записи, — а экраны владельца
|
||||
приносят отдельные задачи.
|
||||
- Второго адресного пространства у сервиса не остаётся: адреса хранилища и адрес
|
||||
панели перестают существовать — **BREAKING**. Корень приложения остаётся тем
|
||||
же, и контракт приложения не меняется ни одним полем.
|
||||
- Собственного входа у хранилища больше нет — вместе с самим хранилищем, — и
|
||||
требования, закрывавшие его наглухо, теряют предмет. Узнавание остаётся
|
||||
прежним: заголовок доверенного источника на каждом запросе.
|
||||
- Пароль владельца от панели пропадает — секрет, которого до перевода не было.
|
||||
- Очередь остаётся своей таблицей, а захват — одним неделимым шагом с
|
||||
возвратом идентификатора и признака захвата.
|
||||
- Ограничитель частоты под корнем приложения становится своим и перестаёт зависеть
|
||||
от настроек чужой поверхности.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
Новых capability изменение не заводит: предмет тот же, меняется его норма.
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `storage`: раскладка каталога данных и шаги схемы становятся своими; файл
|
||||
отдаётся адресом сервиса с проверкой владельца вместо ссылки хранилища с
|
||||
коротким токеном; требования о панели владельца, о пароле от неё и о закрытии
|
||||
собственной поверхности хранилища снимаются вместе с предметом; закрытость
|
||||
содержимого переписывается со словаря коллекций и правил доступа на словарь
|
||||
таблиц и адресов сервиса.
|
||||
- `access`: требование, выключавшее собственные входы хранилища, снимается вместе
|
||||
с ними; область узнавания перестаёт обходить чужую поверхность и перестаёт
|
||||
включать выдачу токена файла; запрет на печать значения, дающего доступ,
|
||||
теряет упоминание короткого токена.
|
||||
- `archive`: адреса приложения перестают соседствовать с чужим пространством —
|
||||
соседа больше нет; ограничитель частоты под корнем приложения становится
|
||||
своим, и объявленная частота опроса по-прежнему выводится из его бюджета.
|
||||
- `intake`: имя файла в хранилище задаёт сервис, и умолчания, которое строило имя
|
||||
из имени отправителя, больше не существует; отказ узнанному без учётной записи
|
||||
теряет свой единственный случай — владельца панели с собственным токеном.
|
||||
- `webapp`: перечень корней сервиса, из которого выводится правило неизвестного
|
||||
пути, теряет корень хранилища и корень панели; журнал у сервиса остаётся один.
|
||||
- `pipeline`: возврат остановленной записи в работу перестаёт быть правкой в
|
||||
панели и становится подкомандой оснастки, идущей через домен; перечень полей,
|
||||
которые возврат обязан сбросить, называется целиком и в одном месте, и к нему
|
||||
добавляется обязанность писать событие журнала записи; норма о том, что шаг
|
||||
пишет только свои поля, остаётся в силе с прежней ценой.
|
||||
- `recognition`: сохранённый ответ провайдера переезжает из вложения чужого
|
||||
хранилища в отдельный файл каталога данных, а его закрытость переписывается с
|
||||
пометки поля и правила просмотра коллекции на проверку владельца в обработчике
|
||||
сервиса. Зачем ответ хранится целиком и где лежит попытка распознавания, смена
|
||||
хранилища не трогает.
|
||||
|
||||
## Impact
|
||||
|
||||
- Публичный контракт HTTP: пространство адресов хранилища и адрес панели
|
||||
исчезают, корень приложения остаётся. Формы запросов и ответов приложения не
|
||||
меняются.
|
||||
- Раскладка каталога данных: файл базы и каталог файлов записей — необратимое,
|
||||
цена сегодня нулевая (стройка, на сервере пусто).
|
||||
- Модель угроз: из периметра уходят панель, её пароль, дефект с подменой знака в
|
||||
адресе и правило прокси на чужое пространство; приходит своя отдача файла и
|
||||
свой ограничитель частоты.
|
||||
- Инструмент владельца: панели нет; возврат остановленной записи в работу делает
|
||||
подкоманда `cmd/devtools`, прочая правка ждёт экранов.
|
||||
- Зависимости сборки: библиотека хранилища и всё, что достижимо только через
|
||||
неё, уходят; драйвер базы без CGO остаётся; приходит `pressly/goose/v3` —
|
||||
библиотекой, без командной строки.
|
||||
- Настройки: ключ каталога данных остаётся, ключей панели не заводится, и
|
||||
заводятся два ключа базы — ожидание занятой базы и число соединений чтения.
|
||||
- Шаги схемы: применённые шаги прежнего каталога удаляются целиком и заменяются
|
||||
одним шагом начальной схемы — разовое снятие инварианта «применённая миграция
|
||||
не переписывается» решением владельца от 2026-08-22.
|
||||
Reference in New Issue
Block a user