Guard / foldkit-guard
Who the client is: Me
"Show the Admin link", "show a sign-in page rather than a 404" and "who am
I signed in as" are questions about the visitor, not about a row.
Guards.me declares them as one Entity with one row, me: everyone reads
their own and no one writes it. It holds signedIn, key (the principal's
key, Option.none() for a visitor) and may for the interactions named
here; GuardServer.me serves it, deciding may with the Policy.
ts
const OpenAdmin = Interaction.make('OpenAdmin')
// Shared domain code, beside the other Entities.
export const Me = Guards.me(G, {
interactions: { [OpenAdmin.key]: [G.isAdmin] },
})
// The server: one Source among the others.
const MeSource = GuardServer.me(Me, Policy)- The client reads
Methrough Remote like any row (Entity.select(Me, { signedIn: true, key: true, may: true })), so it isLoading,Readyor stale as data is, survives SSR, andRemote.forgeton any change of principal (a sign-in as much as a sign-out) drops it.May.can(me.may, OpenAdmin.key)is the server's answer; no rule runs on the client. - Its Read is
Guards.anyone, whatever the set leavesunguarded, and its writes are nobody's, as the matrix prints them.Guards.anyoneserves any surface that is public under a set that denies the rest: a Read of it restricts no one, so a Sync document over its rows needs no readers andvalidatelets a Source share them. mayis read with the row, as anymayis: a principal whose role changes sees it whenMeis read again.