export type NexusBulkTarget = "role" | "server"; export type NexusBulkJobState = "requested" | "running" | "completed" | "failed" | "cancelled"; export type NexusBulkRecipientOutcome = "credited" | "balance_cap" | "bot" | "left" | "duplicate" | "failed"; export interface NexusBulkJob { jobId: string; guildId: string; actorUserId: string | null; operationKey: string; targetType: NexusBulkTarget; roleId: string | null; amount: number; privateReason: string | null; previewEstimate: number; previewDigest: string; state: NexusBulkJobState; memberCursor: string | null; creditedCount: number; balanceCapCount: number; botCount: number; leftCount: number; duplicateCount: number; failedCount: number; totalCredited: string; attemptCount: number; failureCode: string | null; createdAt: Date; completedAt: Date | null; updatedAt: Date; } export type NexusManagedBulkJob = Omit & { hasPrivateReason: boolean; }; export interface NexusManagedBulkRecipient { recipientId: string; memberId: string | null; outcome: NexusBulkRecipientOutcome; transactionId: string | null; processedAt: Date; } export interface NexusBulkService { listJobs(input: { guildId: string; search?: string; state?: NexusBulkJobState; targetType?: NexusBulkTarget; limit: number; offset: number; }): Promise<{ items: readonly NexusManagedBulkJob[]; total: number; }>; createJob(input: { jobId?: string; guildId: string; actorUserId: string; operationKey: string; targetType: NexusBulkTarget; roleId?: string; amount: number; privateReason: string; previewEstimate: number; previewDigest: string; }): Promise<{ job: NexusBulkJob; replayed: boolean; }>; getJob(input: { guildId: string; jobId: string; }): Promise; claimJob?(input: { guildId: string; jobId: string; leaseOwner: string; leaseDurationMs: number; }): Promise<{ job: NexusBulkJob; leaseGeneration: number; } | null>; listRecipients(input: { guildId: string; jobId: string; search?: string; outcome?: NexusBulkRecipientOutcome; limit: number; offset: number; }): Promise<{ items: readonly NexusManagedBulkRecipient[]; total: number; }>; markRunning(input: { guildId: string; jobId: string; }): Promise; recordRecipient(input: { guildId: string; jobId: string; memberId: string; outcome: NexusBulkRecipientOutcome; transactionId?: string; }): Promise<{ recorded: boolean; }>; recordRecipientClaimed?(input: { guildId: string; jobId: string; leaseGeneration: number; memberId: string; outcome: NexusBulkRecipientOutcome; transactionId?: string; }): Promise<{ recorded: boolean; leaseValid: boolean; }>; postRecipientClaimed?(input: { guildId: string; jobId: string; leaseGeneration: number; memberId: string; operationKey: string; amount: number; actorUserId?: string; privateReason: string; }): Promise<{ leaseValid: false; recorded: false; } | { leaseValid: true; recorded: false; } | { leaseValid: true; recorded: true; transactionId: string; replayed: boolean; }>; advance(input: { guildId: string; jobId: string; memberCursor: string; }): Promise; advanceClaimed?(input: { guildId: string; jobId: string; leaseGeneration: number; memberCursor: string; }): Promise<{ advanced: boolean; }>; recordRetry(input: { guildId: string; jobId: string; safeCode: string; attemptLimit: number; }): Promise<{ failed: boolean; attemptCount: number; }>; recordRetryClaimed?(input: { guildId: string; jobId: string; leaseGeneration: number; safeCode: string; attemptLimit: number; }): Promise<{ failed: boolean; attemptCount: number; leaseValid: boolean; }>; complete(input: { guildId: string; jobId: string; }): Promise; completeClaimed?(input: { guildId: string; jobId: string; leaseGeneration: number; }): Promise<{ completed: boolean; }>; cancel(input: { guildId: string; jobId: string; }): Promise; fail(input: { guildId: string; jobId: string; safeCode: string; }): Promise; failClaimed?(input: { guildId: string; jobId: string; leaseGeneration: number; safeCode: string; }): Promise<{ failed: boolean; }>; releaseJobClaim?(input: { guildId: string; jobId: string; leaseGeneration: number; }): Promise<{ released: boolean; }>; }