/**
 * Per-user admin read models for the User detail drawer (Overview / Security /
 * Sessions / Activity / Permissions tabs).
 *
 * Pure data shaping over the Prisma client — no config or request coupling — so
 * it unit-tests cleanly. The API layer supplies `workspaceDomain` (for the
 * external-domain flag) and the viewer's `currentSessionId` (to mark the
 * "this device" session). Mirrors the conventions in `team.ts`.
 */
import { type DisplayRole, type UserRoleEnum, type Permission } from './roles.js';
export type MemberStatus = 'active' | 'suspended' | 'locked' | 'deactivated';
export interface UserDetailOptions {
    workspaceDomain?: string | null;
    currentUserId?: string;
}
export interface UserDetail {
    id: string;
    name: string;
    email: string;
    avatarUrl: string | null;
    initials: string;
    role: UserRoleEnum;
    roleName: DisplayRole;
    status: MemberStatus;
    mfaEnabled: boolean;
    mfaRequired: boolean;
    passwordSet: boolean;
    forcePasswordReset: boolean;
    failedLoginCount: number;
    lockedAt: string | null;
    suspendedAt: string | null;
    authProvider: string | null;
    oauthProviders: string[];
    /** True when the account can only sign in via an external identity provider. */
    ssoOnly: boolean;
    emailVerified: boolean;
    lastLoginAt: string | null;
    lastActiveAt: string | null;
    acceptedInviteAt: string | null;
    createdAt: string;
    invitedBy: {
        id: string;
        name: string;
        email: string;
    } | null;
    externalDomain: boolean;
    contentOwnedCount: number;
    isCurrentUser: boolean;
}
export interface SessionInfo {
    id: string;
    deviceLabel: string;
    browser: string;
    os: string;
    ipCountry: string | null;
    createdAt: string;
    lastSeenAt: string;
    expiresAt: string;
    revokedAt: string | null;
    current: boolean;
    active: boolean;
}
export interface ActivityEvent {
    id: string;
    event: string;
    /** Whether the user was the actor or the target of the event. */
    role: 'actor' | 'target';
    ipAddress: string | null;
    timestamp: string;
    details: Record<string, unknown> | null;
}
export interface PermissionView {
    role: UserRoleEnum;
    roleName: DisplayRole;
    permissions: Permission[];
}
/**
 * Best-effort User-Agent parsing into a friendly device label. Intentionally
 * dependency-free and conservative: an unknown UA degrades to "Unknown device"
 * rather than guessing. This is presentational only — never used for auth.
 */
export declare function parseUserAgent(ua: string | null | undefined): {
    browser: string;
    os: string;
    deviceLabel: string;
};
export declare function getUserDetail(db: any, userId: string, opts?: UserDetailOptions): Promise<UserDetail | null>;
export declare function listUserSessions(db: any, userId: string, currentSessionId?: string): Promise<SessionInfo[]>;
export declare function listUserActivity(db: any, userId: string, limit?: number): Promise<ActivityEvent[]>;
export declare function getUserPermissionView(role: string): PermissionView;
export interface TransferResult {
    documents: number;
    media: number;
    templates: number;
    total: number;
}
/**
 * Count the content a user *owns* (authored documents, uploaded media,
 * created templates). Soft-deleted documents are included so the count
 * reflects everything a transfer would reassign — nothing is silently
 * orphaned. Immutable history (versions, audit logs) is never counted.
 */
export declare function countOwnedContent(db: any, userId: string): Promise<number>;
/**
 * Reassign every piece of content owned by `fromUserId` to `toUserId`:
 * authored documents (`Document.createdById`), uploaded media
 * (`Media.uploadedById`), and created templates (`ContentTemplate.createdById`).
 *
 * Deliberately does NOT touch `updatedById`, version history, or audit logs —
 * those record *who did what* and rewriting them would falsify the trail. This
 * only moves the "owner of record" so content survives a user's removal.
 *
 * Returns the per-type counts actually reassigned. Each model is guarded so a
 * trimmed Prisma schema (or test double) that lacks one of them is a no-op for
 * that type rather than a hard failure.
 */
export declare function transferContentOwnership(db: any, fromUserId: string, toUserId: string): Promise<TransferResult>;
//# sourceMappingURL=user-admin.d.ts.map