/** * What a resolver hands to erp-kit, before anything has decided whether the call * is allowed. `actorId` is `null` for an anonymous caller — the platform issues an * anonymous JWT rather than rejecting a request with no credentials, so a resolver * that declares no `permission` is reachable without one. * * {@link defineCommand} rejects a null `actorId` before the implementation runs, so * a command always receives {@link CommandContext} with a definite actor. Queries * carry no gate of their own — access is decided by the resolver's `permission` in * `tailor.config.ts` — so a query that scopes its result to the caller receives this * type and has to say what an absent actor means. */ export interface CallerContext { actorId: string | null; permissions?: readonly string[]; companyId?: string | null; } export interface QueryContext { actorId: string; permissions?: readonly string[]; companyId?: string | null; } export interface CommandContext { actorId: string; permissions: readonly string[]; companyId?: string | null; } import type { Kysely } from "@tailor-platform/sdk/kysely"; // Strips write methods (updateTable, insertInto, deleteFrom) from a Kysely DB instance. // Query handlers use this instead of the full DB type to get compile-time write prevention. // Without a type parameter, defaults to any Kysely instance (used by Query type and cross-module interfaces). // eslint-disable-next-line @typescript-eslint/no-explicit-any export type ReadonlyDB> = Pick; export interface PaginationInput { limit?: number; offset?: number; orderBy?: "id" | TOrderBy; orderDirection?: "asc" | "desc"; } export interface PaginatedResult { items: T[]; total?: number; hasNextPage: boolean; }