feat(modules): group-files schema + owner-relative path helpers + repo (§11.6 files C1)

Extends the §11.6 shared-collection machinery to the filesystem-backed
`files` blob store (after KV/0053 and docs/0054).

- 0055_group_files.sql: widen the group_collections kind CHECK to admit
  'files'; add a group-keyed `group_files` metadata table mirroring
  `files` (0018), CASCADE on group delete.
- files_repo: generalize the four path/IO free functions
  (shard_dir_at / final_path_at / write_atomic_at / read_verify_at) to
  take an owner-relative dir instead of `app_id`, and make them (plus the
  cursor helpers) pub(crate). The security-sensitive atomic-write +
  checksum-on-read mechanics now have a single source shared by the app
  and group repos. App behavior is unchanged (apps shard at `<app_id>/`).
- group_files_repo: FsGroupFilesRepo keyed by group_id, blobs at
  `<root>/files/groups/<group_id>/<collection>/<id[0:2]>/<id>` — a
  `groups/` infix disjoint from the per-app subtree, so the existing
  recursive orphan sweeper covers it with zero change.

Schema snapshot blessed (55 migrations); app-files fs tests still green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
MechaCat02
2026-06-30 19:35:34 +02:00
parent f552238586
commit 779d906d75
5 changed files with 524 additions and 30 deletions

View File

@@ -53,6 +53,7 @@ pub mod gc;
pub mod group_collection_repo;
pub mod group_docs_repo;
pub mod group_docs_service;
pub mod group_files_repo;
pub mod group_kv_repo;
pub mod group_kv_service;
pub mod group_members_repo;
@@ -184,6 +185,7 @@ pub use gc::{spawn_abandoned_gc, spawn_app_user_token_gc, spawn_dead_letter_gc};
pub use group_collection_repo::{GroupCollectionResolver, PostgresGroupCollectionResolver};
pub use group_docs_repo::{GroupDocsRepo, GroupDocsRepoError, PostgresGroupDocsRepo};
pub use group_docs_service::GroupDocsServiceImpl;
pub use group_files_repo::{FsGroupFilesRepo, GroupFilesRepo, GroupFilesRepoError};
pub use group_kv_repo::{GroupKvRepo, GroupKvRepoError, PostgresGroupKvRepo};
pub use group_kv_service::GroupKvServiceImpl;
pub use group_members_repo::{