/**
 * Account and actor database queries.
 *
 * Provides CRUD operations for the account and actor tables.
 * For v1, every account has exactly one actor (1:1).
 *
 * @module
 */
import type { QueryDeps } from '../db/query_deps.js';
import { type Account, type Actor, type CreateAccountInput, type AdminAccountEntryJson } from './account_schema.js';
/**
 * Create a new account.
 *
 * @param deps - query dependencies
 * @param input - the account fields
 * @returns the created account
 * @mutates `account` table - inserts the new row
 */
export declare const query_create_account: (deps: QueryDeps, input: CreateAccountInput) => Promise<Account>;
/**
 * Find an **active** account by id (`deleted_at IS NULL`).
 *
 * This is the auth-resolution workhorse (`build_request_context` /
 * `build_account_context`) and the admin-target lookup, so it
 * deliberately excludes soft-deleted accounts: a tombstoned account must
 * not authenticate (`delete` = soft, `purge` = hard). Purge, which must operate on
 * soft-deleted rows too, uses `query_purge_account` directly.
 */
export declare const query_account_by_id: (deps: QueryDeps, id: string) => Promise<Account | undefined>;
/**
 * Find an account by username (case-insensitive).
 */
export declare const query_account_by_username: (deps: QueryDeps, username: string) => Promise<Account | undefined>;
/**
 * Find an account by email (case-insensitive).
 */
export declare const query_account_by_email: (deps: QueryDeps, email: string) => Promise<Account | undefined>;
/**
 * Find an account by username or email.
 *
 * If the input contains `@`, tries email lookup first then username.
 * Otherwise tries username first then email. This supports a single
 * login field that accepts either format.
 *
 * Excludes soft-deleted accounts (`deleted_at IS NULL`) — this is the
 * login lookup, and a tombstoned account must not authenticate. The
 * underlying `query_account_by_username` / `query_account_by_email` stay
 * unfiltered because the invite-collision checks need to see soft-deleted
 * accounts (usernames/emails stay reserved after a soft-delete).
 *
 * @param deps - query dependencies
 * @param input - username or email address
 * @returns the matching active account, or `undefined`
 */
export declare const query_account_by_username_or_email: (deps: QueryDeps, input: string) => Promise<Account | undefined>;
/**
 * Update the password hash for an account, conditional on the current
 * stored hash matching `expected_hash` — the verify-write atomic guard.
 *
 * The condition closes the race where two concurrent password changes both
 * verify against the pre-update hash (loaded by the authorization phase
 * outside the route's transaction) and would otherwise both UPDATE,
 * silently clobbering whichever lands first. With the conditional WHERE,
 * the second UPDATE matches zero rows; the route reads the boolean
 * return and surfaces 401 instead of pretending success.
 *
 * Pass the same hash the verify ran against — typically
 * `ctx.account.password_hash` from the request context.
 *
 * @returns `true` if the row was updated, `false` if `expected_hash` no
 *   longer matched (concurrent change won — caller should treat as a
 *   stale-credential failure).
 * @mutates `account` row - updates `password_hash`, `updated_at`, and
 *   `updated_by` only when the stored hash equals `expected_hash`
 */
export declare const query_update_account_password: (deps: QueryDeps, id: string, password_hash: string, updated_by: string | null, expected_hash: string) => Promise<boolean>;
/**
 * Identifying values snapshotted into a deletion/purge audit event so the
 * identity behind a now-orphaned `audit_log` id isn't lost. Mirrors the
 * Rust `AccountIdentitySnapshot`.
 */
export interface AccountIdentitySnapshot {
    username: string;
    email: string | null;
}
/**
 * Soft-delete an account — the reversible tombstone (`delete` = soft).
 *
 * Stamps `deleted_at` + `deleted_by` (the initiator's actor) on the active
 * row — paired like `role_grant`'s `revoked_at` / `revoked_by`, and
 * deliberately leaving `updated_at` / `updated_by` untouched (deletion
 * isn't a content edit). Returns the identity snapshot for the
 * `account_delete` audit event, or `undefined` when no active row matched
 * (missing or already soft-deleted). Auth resolution
 * (`query_account_by_id`) already excludes soft-deleted accounts; the
 * caller revokes sessions/tokens.
 *
 * @mutates `account` row - sets `deleted_at` + `deleted_by` on one active row
 */
export declare const query_account_soft_delete: (deps: QueryDeps, id: string, deleted_by: string | null) => Promise<AccountIdentitySnapshot | undefined>;
/**
 * Hard-purge an account — irreversible cascading removal (`purge` = hard).
 *
 * Physically deletes the row, cascading to actors, role_grants, sessions,
 * and tokens. Operates on active OR already-soft-deleted rows. Returns the
 * identity snapshot for the `account_purge` audit event, or `undefined`
 * when no row matched. The `audit_log` identity columns carry no FK, so
 * the purged id survives on historical rows for forensic correlation back
 * to the purge event.
 *
 * **Keeper-gated, loud, irreversible** — restrict to the keeper credential
 * and confirm explicitly at the call site. The `purge` name flags the danger.
 *
 * @mutates `account` table and downstream FK rows - DELETE cascades through actors/role_grants/sessions/tokens
 */
export declare const query_purge_account: (deps: QueryDeps, id: string) => Promise<AccountIdentitySnapshot | undefined>;
/**
 * Soft-delete one actor (sets `deleted_at` + `deleted_by`). Returns `true`
 * when an active row flipped, `false` when none matched. Emitted per actor
 * alongside the account-level soft-delete.
 *
 * @mutates `actor` row - sets `deleted_at` + `deleted_by` on one active row
 */
export declare const query_actor_soft_delete: (deps: QueryDeps, id: string, deleted_by: string | null) => Promise<boolean>;
/**
 * Reactivate a soft-deleted account — clears the `deleted_at` /
 * `deleted_by` tombstone (the inverse of `query_account_soft_delete`).
 *
 * Operates only on a currently soft-deleted row (`deleted_at IS NOT NULL`)
 * and returns the identity snapshot for the `account_undelete` audit
 * event, or `undefined` when no soft-deleted row matched (missing or
 * already active). Reactivation does **not** restore the revoked
 * sessions/tokens — the account is live again but its principals re-auth
 * fresh. `updated_at` / `updated_by` stay untouched.
 *
 * @mutates `account` row - clears `deleted_at` + `deleted_by` on one soft-deleted row
 */
export declare const query_account_undelete: (deps: QueryDeps, id: string) => Promise<AccountIdentitySnapshot | undefined>;
/**
 * Reactivate one soft-deleted actor (clears `deleted_at` / `deleted_by`).
 * Returns `true` when a soft-deleted row flipped back, `false` when none
 * matched. Emitted per actor alongside the account-level reactivation.
 *
 * @mutates `actor` row - clears `deleted_at` + `deleted_by` on one soft-deleted row
 */
export declare const query_actor_undelete: (deps: QueryDeps, id: string) => Promise<boolean>;
/**
 * Check if any account exists.
 */
export declare const query_account_has_any: (deps: QueryDeps) => Promise<boolean>;
/**
 * Create a new actor for an account.
 *
 * @param deps - query dependencies
 * @param account_id - the owning account
 * @param name - display name (defaults to account username)
 * @returns the created actor
 * @mutates `actor` table - inserts the new row
 */
export declare const query_create_actor: (deps: QueryDeps, account_id: string, name: string) => Promise<Actor>;
/**
 * List every actor on an account, ordered by `created_at`.
 *
 * Used by `resolve_acting_actor` to resolve the acting actor for a
 * request: 1 actor picks transparently, multiple require an explicit
 * `acting` field on the request payload. For lookups by id, use
 * `query_actor_by_id` instead.
 */
export declare const query_actors_by_account: (deps: QueryDeps, account_id: string) => Promise<Array<Actor>>;
/**
 * Find an actor by id.
 */
export declare const query_actor_by_id: (deps: QueryDeps, id: string) => Promise<Actor | undefined>;
/**
 * Create an account and its actor in a single operation.
 *
 * For v1, every account gets exactly one actor with the same name as the username.
 *
 * @param deps - query dependencies
 * @param input - the account fields
 * @returns the created account and actor
 * @mutates `account` and `actor` tables - inserts one row in each
 */
export declare const query_create_account_with_actor: (deps: QueryDeps, input: CreateAccountInput) => Promise<{
    account: Account;
    actor: Actor;
}>;
/** Options for `query_admin_account_list`. */
export interface AdminAccountListOptions {
    /**
     * Max accounts to return. Defaults to `ADMIN_ACCOUNT_LIST_DEFAULT_LIMIT`
     * when omitted; pass `null` explicitly to disable the limit (unbounded
     * fetch — for trusted internal callers / scripts; the RPC schema bounds
     * wire callers to `[1, ADMIN_ACCOUNT_LIST_LIMIT_MAX]`).
     */
    limit?: number | null;
    /** Pagination offset. Defaults to 0. */
    offset?: number | null;
    /**
     * Include soft-deleted (tombstoned) accounts. Defaults to `false` —
     * the listing shows active accounts only, matching auth resolution.
     * Set `true` for the admin UI's "show deleted" view, which offers
     * reactivation via `account_undelete`.
     */
    include_deleted?: boolean | null;
}
/**
 * List accounts with their actors, active role_grants, and pending inbound
 * role_grant offers for admin display.
 *
 * Pages the accounts query (one round-trip), then fans out three parallel
 * lookups scoped to the page's `account_ids` (one round-trip). The role_grants
 * and offers queries use a subquery on `actor.account_id` so the page bound
 * pushes through to the DB without round-tripping `actor.id`s back to the
 * application. Pending offers surface the "offer pending — awaiting
 * acceptance" UX; `message` is intentionally excluded (cross-admin
 * visibility of grantor notes would expand beyond what the audit log
 * discloses).
 *
 * @param deps - query dependencies
 * @param options - optional `{limit, offset}`. Default limit is
 *   `ADMIN_ACCOUNT_LIST_DEFAULT_LIMIT`; pass `limit: null` to disable.
 * @returns admin account entries sorted by creation date (oldest first)
 */
export declare const query_admin_account_list: (deps: QueryDeps, options?: AdminAccountListOptions) => Promise<Array<AdminAccountEntryJson>>;
//# sourceMappingURL=account_queries.d.ts.map