// `session.me` — the caller's resolved identity. The editor's SSR gate reads it // to decide render-vs-redirect-to-login, and it proves the auth loop end to end: // no cookie → anonymous Subject; sign in via POST /auth/sign-in → a `user` // Subject. Browser-safe descriptor — no server imports here. import { defineAction } from '@voltro/protocol' import { Schema } from 'effect' export const me = defineAction({ name: 'session.me', // The ONE open procedure in this app, and it has to be. Every `content.*` // procedure beside it carries a `content:*` guard that an anonymous caller // cannot satisfy — which is correct — but the SSR auth gate has to be able to // ask "who am I" while it is still nobody, or it has nothing to branch on and // the redirect to /login never happens. // // Safe because the answer is a projection of the caller's own request: the // Subject `voltroPasswordStrategy` resolved from the cookie they sent. It // reads no table and can say nothing about anybody else. openAccess: 'echoes the caller\'s own resolved Subject (type/id/tenantId) — reads no table and reveals ' + 'nothing the caller did not present. Anonymous callers must reach it, or the SSR gate ' + 'cannot redirect them to sign in.', input: Schema.Struct({}), output: Schema.Struct({ type: Schema.String, id: Schema.NullOr(Schema.String), tenantId: Schema.NullOr(Schema.String), }), })