feat(data): one document per entity + delegate isolation fully to the SDK

Festipod now follows the correct SDK logic: each entity (event, participation,
profile, notification) is created as its OWN document in its scope
(rule_document-per-entity), via the SDK create call — the store-root write path
and the FESTIPOD_MULTISTORE flag are gone. Reads subscribe the per-entity docs
with instant visibility on create; seed/bootstrap rewritten per-entity.

Removed all app-side access logic: utils/isolation.ts (applyIsolation) deleted.
The app only declares its identity (login) and its own bilateral connections
(sharing act), reads via the SDK, and trusts it — no access filtering in the app.
This makes the SDK's per-document ReadCap the sole, real isolation.

Unit-proven in the lib (89 tests). @data/@e2e validation deferred: the NextGraph
broker is unreachable — to be re-run in T03.d. Follow-up: unify app connection
principals (user IRI) onto the username key used by the SDK's cap owner.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sylvain Duchesne
2026-07-04 10:40:44 +02:00
parent 82c2cb5f27
commit 3ad06dfaec
6 changed files with 160 additions and 171 deletions
+5 -4
View File
@@ -14,7 +14,6 @@ import { FestipodDataProvider, useFestipodData } from '../context/FestipodDataCo
// useShape routed through the lib (SDK-identical surface); caps from /polyfill.
import { useShape, docs, inbox as docsInbox } from '@ng-eventually/client';
import { getCaps, getCurrentUser, setCurrentUser, resetCaps, declareConnections } from '@ng-eventually/client/polyfill';
import { isolation as ngIsolation } from '@ng-eventually/client';
import { hostInboxNuri as regInboxNuri } from '../data/registration';
import type { DeepSignalSet } from '@ng-eventually/client';
// doc_create goes through the lib's `docs` primitive (T01.a): it calls the REAL
@@ -302,10 +301,12 @@ function ConnectedHarness() {
setCurrentUser(reader);
setFilterActive(true);
},
/** Declare the owner↔reader connection to the SDK (domain sharing act).
* The SDK then issues the protected doc's read cap to the connection. */
/** Declare a BILATERAL owner↔reader connection to the SDK (domain sharing
* act). Each side asserts the other (bound to that identity); only then
* does the SDK issue the protected doc's read cap to the connection. */
connect(a: string, b: string) {
declareConnections(ngIsolation.connectionsFromLinks([{ a, b }]));
declareConnections([b], a); // a asserts b
declareConnections([a], b); // b asserts a → bilateral link materializes
},
/** Does the CURRENT user read the public entity document — through the
* SDK's own cap check — regardless of the protected caps? */