у записи появился владелец: чужую больше не отдают
- колонка `owner` связью с `users` в обеих коллекциях новым шагом схемы `202608140001`; чтение задачи сужено владельцем, и чужая, ничья и несуществующая дают один ответ; правило просмотра файлов сужено им же - приём по HTTP берёт владельца из сессии, а предъявителя без учётной записи пользователя отвергает до чтения тела: позже пришлось бы убирать уложенный файл, а уборки файлов сервис не умеет. Выборка воркера владельцем не сужается - удаление учётной записи с записями отвергается стражем, и вешает его сама сборка хранилища: сборка, забывшая его позвать, теряла защиту молча
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
# ADR-2026-08-14. Учётная запись с записями не удаляется, и это осознанный тупик
|
||||
|
||||
- **Дата:** 2026-08-14
|
||||
- **Источник:** [openspec/changes/archive/2026-08-14-record-ownership/design.md](../../openspec/changes/archive/2026-08-14-record-ownership/design.md), раздел `Open Questions`
|
||||
|
||||
## Решение
|
||||
|
||||
Удаление учётной записи, у которой остались задачи расшифровки либо файлы,
|
||||
отвергается — отказом с названной причиной. Способа удалить записи в сервисе нет
|
||||
вовсе, поэтому до задачи про удаление записи такая учётная запись не удаляется
|
||||
никак: ни владельцем панели, ни самим человеком.
|
||||
|
||||
Решение принято человеком на чекпоинте задачи `record-ownership` из трёх
|
||||
предложенных способов.
|
||||
|
||||
Дословно из источника:
|
||||
|
||||
> **Что делать с записями удалённого пользователя?** Связь при выключенном
|
||||
> каскаде снимает ссылку — записи остаются, но становятся ничьими и
|
||||
> недостижимыми по API навсегда. Способы: запретить удаление учётной записи, пока
|
||||
> у неё есть записи; держать рядом со связью неизменяемый снимок идентификатора;
|
||||
> признать потерю ценой и записать её.
|
||||
|
||||
## Почему
|
||||
|
||||
Колонка владельца — связь с учётной записью, и каскадное удаление у неё
|
||||
выключено: сервис объявлен архивом и молча удалить чужой архив не вправе. Одного
|
||||
этого мало, и проверка по исходникам `pocketbase@v0.39.10` показала почему: при
|
||||
выключенном каскаде хранилище **вынимает** идентификатор из поля связи и
|
||||
сохраняет запись без проверок. Задачи остались бы на месте, но стали бы ничьими —
|
||||
а ничья запись по правилу той же задачи не достаётся по API никому. Архив
|
||||
человека исчезал бы молча, и восстановить владельца было бы нечем: прежнего
|
||||
значения не остаётся нигде.
|
||||
|
||||
Прежнее обоснование выбора связи вместо строки — «связь удержит целостность» —
|
||||
было неверным, и это выяснилось на ревью дизайна.
|
||||
|
||||
## Чем платим
|
||||
|
||||
Владелец панели упирается в отказ, а выхода из него сегодня нет: удаление записи
|
||||
приносит отдельная задача. Тупик назван прямо, а не обнаружен потом.
|
||||
|
||||
Отказ обязан доезжать до спрашивающего: хранилище пропускает наружу только свою
|
||||
ошибку роутера, а всякую другую подменяет сообщением про обязательную связь.
|
||||
Подсказка эта ведущая — единственная обязательная связь у задачи это файл, — и
|
||||
владелец панели, поверив ей, пошёл бы удалять записи руками, то есть делать ровно
|
||||
то необратимое, ради предотвращения чего запрет и заведён. Это нашло ревью кода.
|
||||
|
||||
## Что рассматривалось и отвергнуто
|
||||
|
||||
- **Неизменяемый снимок идентификатора рядом со связью.** Пережил бы удаление, и
|
||||
запись можно было бы вернуть человеку. Отвергнуто: владельцем становится любая
|
||||
строка, и целостность, ради которой выбрана связь, теряется.
|
||||
- **Признать потерю ценой и записать её.** Дешевле всего сегодня — удаления
|
||||
пользователей в сервисе нет вовсе. Отвергнуто: архив, теряемый одной кнопкой в
|
||||
панели, противоречит решению от 2026-08-11 о том, что сервис — архив.
|
||||
|
||||
## Связанное
|
||||
|
||||
Запрет ставит сама сборка хранилища, а не вызывающий: сборка, забывшая его
|
||||
позвать, теряет защиту молча — и теряла, пока его добавляли отдельной строкой
|
||||
запуска. Норма — `openspec/specs/storage`, «Учётная запись с записями не
|
||||
удаляется».
|
||||
@@ -35,6 +35,7 @@
|
||||
|
||||
| Дата | Запись | Статус |
|
||||
| --- | --- | --- |
|
||||
| 2026-08-14 | [Учётная запись с записями не удаляется, и это осознанный тупик](ADR-2026-08-14-account-with-records-is-not-deleted.md) | |
|
||||
| 2026-08-13 | [Намерение объявляется признаком, а не выводится из ключа доступа](ADR-2026-08-13-telegram-intent-declared-not-inferred.md) | |
|
||||
| 2026-08-13 | [Недоступность Telegram подъёму сервиса не мешает](ADR-2026-08-13-telegram-outage-does-not-block-startup.md) | |
|
||||
| 2026-08-12 | [Файл записи закрыт защищённым полем и отдаётся вошедшему по токену файла](ADR-2026-08-12-protected-file-behind-session.md) | |
|
||||
|
||||
Reference in New Issue
Block a user