feat(spaces): app-owned space membership store (#213) #220

Merged
Cordy merged 2 commits from feat-spacestore into main 2026-08-13 16:13:58 +00:00
Owner

First code step of #211 (ADR 0001). A self-contained, IdP-free store for Cairn-owned spaces.

internal/spacestore: Space{Name, Owner, Members[]} persisted as one JSON object through internal/statestore (age-encrypted in the backend on s3, exactly like shares/holds). API: Create, Get, SetMember (write|read, owner always write / not demotable), RemoveMember (owner not removable), Delete, plus query helpers RoleFor and SpacesForUser for the scope integration (#214) and List for admin. Atomic write-then-commit via a clone (failed persist leaves the cache untouched). No IdP calls — works identically under local/oidc/ldap and any key custody.

Tests cover CRUD, role change, owner-demote/remove guards, bad name/role/user, delete-missing, SpacesForUser, and a persistence round-trip.

Not yet wired (that's #214 scope + #216 API); this package stands alone and compiles/tests on its own.

First code step of #211 (ADR 0001). A self-contained, IdP-free store for Cairn-owned spaces. `internal/spacestore`: `Space{Name, Owner, Members[]}` persisted as one JSON object through `internal/statestore` (age-encrypted in the backend on s3, exactly like shares/holds). API: `Create`, `Get`, `SetMember` (write|read, owner always write / not demotable), `RemoveMember` (owner not removable), `Delete`, plus query helpers `RoleFor` and `SpacesForUser` for the scope integration (#214) and `List` for admin. Atomic write-then-commit via a clone (failed persist leaves the cache untouched). No IdP calls — works identically under local/oidc/ldap and any key custody. Tests cover CRUD, role change, owner-demote/remove guards, bad name/role/user, delete-missing, `SpacesForUser`, and a persistence round-trip. Not yet wired (that's #214 scope + #216 API); this package stands alone and compiles/tests on its own.
Cordy merged commit 76c775d807 into main 2026-08-13 16:13:58 +00:00
Cordy deleted branch feat-spacestore 2026-08-13 16:14:01 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: Cordy/Cairn#220
No description provided.