Implement ecosystem contract v2: capabilities, shared ledgers, attachments
- GET /v1/capabilities and the extended sync entity allowlist (§0, §1). - Shared ledgers (§7): ledgers, members and hashed one-time invite codes; X-Balance-Ledger selects the space on /v1/sync and /v1/attachments with its own records, change stream and cursor. Personal space keeps the v1 tables and behaviour; the migration only adds tables. - Attachments (§8): SHA-256, size and media type checks, blob files in BALANCE_ATTACHMENTS_DIR (default: attachments next to the database), garbage collection of unreferenced blobs with a grace period for fresh uploads, and ledger deletion removes its blobs. - Tests for every new endpoint and error code; API, sync, data model, security, deployment and README docs updated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
10272f3851
commit
dfb4fe4e1a
17 files changed
+2496
-56
No files matched your search
@@ -131,6 +131,35 @@ Server не должен предполагать, что все изменен
|
||||
|
||||
Нельзя молча трактовать неизвестный/просроченный cursor как актуальный.
|
||||
|
||||
## Пространства (контракт v2)
|
||||
|
||||
`POST /v1/sync` работает в одном пространстве данных:
|
||||
|
||||
- без `X-Balance-Ledger` — личное пространство пользователя, таблицы
|
||||
`records`/`changes`, поведение v1 без изменений;
|
||||
- с `X-Balance-Ledger: <id>` — общее пространство, таблицы
|
||||
`ledger_records`/`ledger_changes`. Доступ проверяется на каждый запрос.
|
||||
|
||||
У общего пространства свой поток изменений: `sequence` берётся из отдельного
|
||||
AUTOINCREMENT `ledger_changes`, а pull фильтрует по `ledger_id`. Курсор личного
|
||||
пространства и курсор каждого ledger независимы, клиент хранит их раздельно.
|
||||
Все участники пишут в одно пространство с тем же last-write-wins по
|
||||
`updatedAt`; идемпотентность, пагинация (500), лимиты и транзакционность те же.
|
||||
|
||||
Удаление пространства физически удаляет его записи и историю изменений.
|
||||
Удалённый участник теряет доступ (`403`), записи остаются в пространстве.
|
||||
|
||||
## Вложения и сборка мусора
|
||||
|
||||
Байты вложений загружаются отдельно (`PUT /v1/attachments/{sha256}`) до записи
|
||||
`attachment` в sync. Файл пространства считается мусором, когда ни одна живая
|
||||
(`deleted=0`) запись `attachment` этого пространства не ссылается на его
|
||||
`sha256` (сравнение без учёта регистра). Сборка выполняется в той же транзакции,
|
||||
что и sync-запрос, содержащий изменения `attachment`, и при каждом PUT.
|
||||
Файл, ни разу не получивший ссылки, хранится не меньше 24 часов с последней
|
||||
загрузки, чтобы не удалить байты, чья запись ещё не синхронизирована; повторная
|
||||
загрузка перезапускает этот срок.
|
||||
|
||||
## Security
|
||||
|
||||
Sync endpoint всегда ограничен текущим authenticated user.
|
||||
|
||||
Reference in new issue
Block a user