/**
 * Data-visibility scope. The auth layer decides which scope a request is
 * allowed to claim; the repo trusts whatever the ambient context says.
 *
 * - `'user'`: filter every read by `user_id = ctx.userId`. Default.
 * - `'org'`: filter every read by membership in the requester's org, resolved
 *   via `user_id IN (ctx.orgUserIds)` rather than via a per-entity
 *   `organization_id` column. Works for every user-owned table and keeps repos
 *   single-table — the org member list is pre-resolved at the boundary.
 * - `'superuser'`: no scope filter. Engineering / internal-tools only.
 *
 * AUTHORIZATION (who is allowed to claim each scope) lives in boundary
 * middleware, not in the repo. The repo trusts the ambient context — same
 * trust model as a threaded `userId`.
 */
type RequesterScope = 'user' | 'org' | 'superuser';
interface RequesterContext {
    /**
     * The user making the request. Always present — even in `'org'` and
     * `'superuser'` scopes it is the audit-trail "who actually did this".
     */
    readonly userId: string;
    /**
     * The organization the requester belongs to. Required when
     * `scope === 'org'`; may be null for `'user'` (users with no org) and for
     * `'superuser'` (cross-org reads).
     */
    readonly organizationId: string | null;
    /**
     * Data-visibility scope. Defaults to `'user'` when omitted.
     */
    readonly scope?: RequesterScope;
    /**
     * For `scope === 'org'`: the list of user IDs in the requester's org,
     * pre-resolved by the boundary middleware that established the `'org'`
     * scope (one `SELECT users.id WHERE organization_id = X` at the trust
     * boundary). Repos use this as a literal `IN (...)` filter — they never
     * JOIN to `users` themselves. Required when `scope === 'org'`.
     */
    readonly orgUserIds?: readonly string[];
}
/**
 * Set the ambient requester context for the duration of `fn`. The context
 * propagates through `await` boundaries to all downstream calls. Nesting is
 * fine — an inner `withRequester` overrides the outer for its callback.
 */
declare function withRequester<T>(ctx: RequesterContext, fn: () => Promise<T>): Promise<T>;
/**
 * Read the ambient requester context. Throws if no context is active — by
 * design. Used by repos in strict scope-enforcement mode; an unwrapped call
 * site is a missing boundary.
 */
declare function requireRequester(): RequesterContext;
/**
 * Read the ambient requester context without throwing. Returns `undefined`
 * when no context is active. Used by repos in lenient scope-enforcement mode
 * (the default) and by code paths that legitimately run outside a request.
 */
declare function tryGetRequester(): RequesterContext | undefined;
/**
 * Resolve the effective scope for the ambient context, defaulting to `'user'`.
 */
declare function requireRequesterScope(): RequesterScope;
/**
 * Convenience helpers for setting scope explicitly. All three preserve
 * `userId` in the context (audit trail) regardless of scope.
 *
 * - `withUserScope`: regular end-user requests. Most call sites.
 * - `withOrgScope`: admin / org-shared resource access. The caller MUST verify
 *   the requester's role permits `'org'` before calling — the helper does not
 *   enforce authorization. `orgUserIds` is pre-resolved at the boundary.
 * - `withSuperuserScope`: engineering scripts / internal tools. `organizationId`
 *   is null (cross-org is the point). Same authorization caveat applies.
 */
declare function withUserScope<T>(userId: string, organizationId: string | null, fn: () => Promise<T>): Promise<T>;
declare function withOrgScope<T>(userId: string, organizationId: string, orgUserIds: readonly string[], fn: () => Promise<T>): Promise<T>;
declare function withSuperuserScope<T>(userId: string, fn: () => Promise<T>): Promise<T>;

export { type RequesterContext, type RequesterScope, requireRequester, requireRequesterScope, tryGetRequester, withOrgScope, withRequester, withSuperuserScope, withUserScope };
