import type { ActuateDB } from './db/client-types.js';
import { type RelationLookup } from './fields/relations.js';
export interface ActionContext {
    userId: string;
    role: string;
    locale?: string;
    /** PrismaClient instance — typed as unknown to avoid hard coupling at config level. */
    db: unknown;
}
export interface ListOptions {
    collection: string;
    page?: number;
    pageSize?: number;
    sort?: string;
    order?: 'asc' | 'desc';
    filters?: Record<string, unknown>;
    locale?: string;
    status?: string;
    folderId?: string;
    /**
     * Exact-match filter on the document `slug` column. `@@unique([collection,
     * slug])` guarantees at most one match, so this is the canonical way to
     * resolve a human-friendly slug to a document ID (used by the MCP
     * relationship resolver, WS-C C2) without paging the whole collection.
     */
    slug?: string;
    /**
     * Filters on JSON `data` fields — powers the admin collection-list facet
     * filters (taxonomy Phase B). Callers (the API route) are responsible for
     * validating the field against the collection config before passing it in.
     */
    dataFilters?: DataFieldFilter[];
}
export interface DataFieldFilter {
    field: string;
    value: string;
    /**
     * `scalar` = exact match on a text/select value.
     * `array` = containment on a tag-shaped array — matches both the canonical
     * `[{ tag: "AI" }]` row shape and legacy plain-string `["AI"]` arrays.
     */
    kind: 'scalar' | 'array';
}
export interface ListResult {
    docs: Record<string, unknown>[];
    total: number;
    page: number;
    pageSize: number;
    totalPages: number;
}
/**
 * Public wrapper around the internal per-collection access gate. Lets API
 * handlers that don't go through the standard CRUD actions (e.g. the read-only
 * SEO analysis endpoints) still enforce a collection's `access[operation]`
 * rule. Throws `Access denied: …` when the rule rejects the user.
 */
export declare function assertCollectionAccess(collection: string, operation: 'read' | 'create' | 'update' | 'delete', ctx: ActionContext, doc?: Record<string, unknown>): Promise<void>;
/**
 * Build a {@link RelationLookup} backed by the active Prisma client. The
 * lookup batches by collection and filters out soft-deleted docs so a
 * relation that points at a tombstoned record is treated as broken.
 *
 * Exported so the API layer (resolve, list, get) can reuse it without
 * pulling in the entire actions module.
 */
export declare function buildRelationLookup(db: ActuateDB): RelationLookup;
/** Create a new document in a collection. */
export declare function createDocument(collection: string, data: Record<string, unknown>, ctx: ActionContext): Promise<Record<string, unknown>>;
/** Update an existing document. Merges incoming data with existing to prevent field loss. */
export declare function updateDocument(collection: string, id: string, data: Record<string, unknown>, ctx: ActionContext): Promise<Record<string, unknown>>;
/**
 * Update SEO metadata on a document through the data layer.
 *
 * SEO fields (`canonical`, `og*`, `focusKeyword`, `structuredData`, `noindex`,
 * …) are a cross-cutting convention that collections are not required to
 * declare as fields. Unlike {@link updateDocument} this therefore does NOT run
 * field-access stripping — that strips any key without a matching field
 * definition and would silently drop these undeclared SEO keys. It still:
 *   - enforces the collection's `update` access rule (no cross-collection edits),
 *   - snapshots a `Version` row (audit trail),
 *   - recomputes `plainText`/`contentHash` (search index stays consistent),
 *   - fires the `afterUpdate` + cache-invalidate effects.
 *
 * `seoFields` MUST be pre-validated and length-bounded by the caller (the API
 * layer enforces type + length); this function trusts the shapes it receives.
 */
export declare function updateDocumentSeoFields(collection: string, id: string, seoFields: Record<string, unknown>, ctx: ActionContext): Promise<Record<string, unknown>>;
/** Soft-delete a document. Creates a version snapshot before deletion. */
export declare function deleteDocument(collection: string, id: string, ctx: ActionContext): Promise<void>;
/** Retrieve a single document by ID. */
export declare function getDocument(collection: string, id: string, ctx: ActionContext): Promise<Record<string, unknown> | null>;
/** List documents with pagination, sorting, and filtering. */
export declare function listDocuments(options: ListOptions, ctx: ActionContext): Promise<ListResult>;
/** Duplicate a document, resetting status to DRAFT and appending "(Copy)" to the title. */
export declare function duplicateDocument(collection: string, sourceId: string, ctx: ActionContext): Promise<Record<string, unknown>>;
/** Retrieve a global's data. Globals are stored as single-row collections keyed by slug. */
export declare function getGlobal(slug: string, ctx: ActionContext): Promise<Record<string, unknown> | null>;
/** Update a global's data. Creates the document if it doesn't exist (upsert). */
export declare function updateGlobal(slug: string, data: Record<string, unknown>, ctx: ActionContext): Promise<Record<string, unknown>>;
//# sourceMappingURL=actions.d.ts.map