/** * Evidence resource * * CRUD operations for compliance evidence records. * Evidence can be created with a file upload, with data fields only, or both. * File upload/download operations are handled separately from metadata operations. * All file-backed evidence is created with pending_upload status. */ import type { AtomicBatchResult, ConfirmEvidenceUploadInput, CreateEvidenceInput, EvidenceFilter, EvidenceSort, ListOptions, OcrStructuredResult, PaginatedResponse, PartialBatchResult, PresignedEvidenceDownloadUrl, PresignedEvidenceUploadUrl, UpdateEvidenceInput, UpsertEvidenceInput, UpsertResult } from "@artu-ai/shared"; import { Evidence, type EvidenceData } from "../models/Evidence"; import { type ProgressCallback, type UploadableFile } from "../utils/upload"; import { BaseResource } from "./base"; /** * Result of creating an evidence record. * * - With contentType: Returns evidence + presigned upload URL * - Without contentType: Returns evidence only (no-file evidence) */ export interface CreateEvidenceResult { /** The created evidence record */ evidence: Evidence; /** Presigned URL for uploading the file (only when contentType is provided) */ upload?: PresignedEvidenceUploadUrl; } /** * Input for uploading an evidence file. * Combines evidence metadata with upload options. */ export type UploadEvidenceInput = Omit & { /** Optional content type override. If not provided, will be inferred from file. */ contentType?: string; }; /** * Options for the upload operation. */ export interface UploadOptions { /** * Progress callback, called with a value from 0 to 1. * Only works in browser environments. */ onProgress?: ProgressCallback; /** * AbortSignal for cancelling the upload. * @example * const controller = new AbortController(); * sdk.evidence.upload(file, data, { signal: controller.signal }); * // Later: controller.abort(); */ signal?: AbortSignal; /** * Upload timeout in milliseconds. * @default 300000 (5 minutes) */ timeout?: number; } /** * Evidence resource for managing compliance evidence records. * * @example * ```typescript * // Create an evidence record * const { evidence, upload } = await sdk.evidence.create({ * scope: "MX", * type: "contrato_compraventa", * contentType: "application/pdf", * transactionIds: ["txn_123"], * }); * * // Upload file directly via PUT * await fetch(upload.url, { * method: "PUT", * body: file, * headers: { "Content-Type": file.type }, * }); * * // Confirm upload * await sdk.evidence.confirmUpload({ * id: evidence.id, * filename: file.name, * contentType: file.type, * size: file.size, * }); * * // Or use the high-level upload helper * const confirmed = await sdk.evidence.upload(file, { * scope: "MX", * type: "contrato_compraventa", * transactionIds: ["txn_123"], * }); * ``` */ export declare class EvidenceResource extends BaseResource { /** * Creates a new evidence record. * * When contentType is provided, returns the record and a presigned upload URL. * When contentType is omitted, creates a no-file (data-only) evidence record. * * After file upload, call `confirmUpload()` to transition status to "uploaded". * * @param data - Evidence creation data * @returns The created evidence and optional presigned upload URL */ create(data: CreateEvidenceInput): Promise; /** * Confirms that a file has been uploaded to storage. * * Call this after uploading a file via the presigned URL returned by `create()`. * This transitions the evidence status from "pending_upload" to "uploaded". * * @param data - Upload confirmation data including filename, contentType, and size * @returns The updated evidence record */ confirmUpload(data: ConfirmEvidenceUploadInput): Promise; /** * Uploads a file and creates an evidence record in one operation. * * Combines: * 1. Creating an evidence record with presigned URL * 2. Uploading the file directly to storage * 3. Confirming the upload * * For more control over each step, use `create()`, manual upload, and * `confirmUpload()` separately. * * @param file - The file to upload (File, Blob, or UploadableFile) * @param data - Evidence metadata (scope, type, etc.) * @param options - Upload options (progress callback, abort signal, timeout) * @returns The created and confirmed evidence record * * @example * ```typescript * // Simple upload * const evidence = await sdk.evidence.upload(file, { * scope: "MX", * type: "contrato_compraventa", * }); * * // With progress tracking * const evidence = await sdk.evidence.upload(file, { * scope: "MX", * type: "contrato_compraventa", * }, { * onProgress: (progress) => { * console.log(`Upload: ${Math.round(progress * 100)}%`); * }, * }); * ``` * * @throws {FileTooLargeError} If file exceeds 25 MB limit * @throws {UploadError} If upload fails at any stage * @throws {UploadAbortedError} If upload is cancelled via AbortSignal * @throws {UploadTimeoutError} If upload times out */ upload(file: File | Blob | UploadableFile, data: UploadEvidenceInput, options?: UploadOptions): Promise; /** * Regenerates a presigned upload URL for an evidence record that is * stuck in `pending_upload` after a failed upload attempt. * * The record retains its original `storagePath` and `contentType`, so * the new URL is signed against the same path with the same content-type * restriction. After re-uploading, call `confirmUpload()` as usual. * * @param id - Evidence ID (must be in `pending_upload` status) * @returns Fresh presigned upload URL with expiration */ getUploadUrl(id: string): Promise; /** * Retries a failed upload for an evidence record stuck in `pending_upload`. * * Combines: * 1. Regenerating the presigned upload URL (`getUploadUrl`) * 2. Uploading the file directly to storage * 3. Confirming the upload * * Use this when the original `upload()` call failed at the storage PUT * step (network error, S3 throttling, etc.) but the evidence record was * created successfully. * * @param id - Evidence ID (must be in `pending_upload` status) * @param file - The file to upload (must match the original contentType) * @param options - Upload options (progress callback, abort signal, timeout) * @returns The confirmed evidence record * * @throws {UploadError} If upload fails at any stage * @throws {UploadAbortedError} If upload is cancelled via AbortSignal * @throws {UploadTimeoutError} If upload times out */ retryUpload(id: string, file: File | Blob | UploadableFile, options?: UploadOptions): Promise; /** * Gets a presigned URL for downloading/viewing an evidence file. * * @param id - Evidence ID * @returns Presigned download URL with expiration */ getDownloadUrl(id: string): Promise; /** * Retrieves an evidence record by ID * * @param id - Evidence ID * @returns The evidence record */ retrieve(id: string): Promise; /** * Retrieves an evidence record by metadata key/value. * * @param key - Metadata key to search * @param value - Expected metadata value (string) * @returns The first evidence record matching the key/value pair */ retrieveByMetadata(key: string, value: string): Promise; /** * Updates an evidence record's metadata or fields. * * Note: Status cannot be updated directly — it is managed by the system. * * @param id - Evidence ID * @param data - Fields to update * @returns The updated evidence record */ update(id: string, data: UpdateEvidenceInput): Promise; /** * Soft-deletes an evidence record * * @param id - Evidence ID */ delete(id: string): Promise; /** * Submit an uploaded evidence record for officer review. * Transitions: uploaded → pending_review. * * @param id - Evidence ID * @returns The updated evidence record */ submit(id: string): Promise; /** * Verify a pending_review evidence record. * Transitions: pending_review → verified. * * @param id - Evidence ID * @returns The updated evidence record */ verify(id: string): Promise; /** * Reject a pending_review evidence record with a reason. * Transitions: pending_review → rejected. * * @param id - Evidence ID * @param input - Rejection details * @returns The updated evidence record */ reject(id: string, input: { reason: string; }): Promise; /** * Extract structured fields from an evidence record via the OCR pipeline. * Status transitions: uploaded → processing → pending_review on success. * * @param evidenceId - Evidence ID * @returns Structured OCR extraction result */ extract(evidenceId: string): Promise; /** * Lists evidence records with optional filtering and pagination. * * @param options - List options with filter, cursor, and limit * @returns Paginated list of evidence records */ list(options?: ListOptions): Promise>; /** * Counts evidence records matching the given filter. * * @param filter - Optional filter criteria * @returns The count of matching evidence records */ count(filter?: EvidenceFilter): Promise; /** * Async iterator over evidence records with optional filtering. * * @param options - Filter and sort options * @yields Evidence records one at a time */ iterate(options?: ListOptions): AsyncGenerator; /** * Checks whether a transaction has at least one evidence of a given type. * * Useful for completeness checks — for example, "does this transaction have * a verified CFDI?" Pass `status: "verified"` to restrict to verified evidence. * * @param transactionId - Transaction ID * @param type - Evidence type string (e.g. "factura_cfdi_4_0") * @returns `true` if at least one matching evidence record exists and is available */ hasEvidenceType(transactionId: string, type: string): Promise; /** * Links this evidence to a transaction. * * @param input - Evidence ID and transaction ID to link */ linkTransaction(input: { evidenceId: string; transactionId: string; }): Promise; /** * Unlinks this evidence from a transaction. * * @param input - Evidence ID and transaction ID to unlink */ unlinkTransaction(input: { evidenceId: string; transactionId: string; }): Promise; /** * Replaces all transaction links for this evidence with the given transaction IDs. * * @param input - Evidence ID and new list of transaction IDs */ setTransactions(input: { evidenceId: string; transactionIds: string[]; }): Promise; /** * Lists all transaction IDs linked to an evidence record. * * @param evidenceId - Evidence ID * @returns Array of linked transaction UUIDs */ listLinkedTransactions(evidenceId: string): Promise; /** * Lists all evidence records linked to a transaction. * * @param transactionId - Transaction ID * @returns Paginated list of evidence records for the transaction */ listForTransaction(transactionId: string): Promise>; /** * Creates multiple evidence records in a batch. * * @param items - Array of evidence creation data * @param options - Batch options (atomic: true by default) * @returns Atomic result with data array, or partial result with succeeded/failed */ createMany(items: CreateEvidenceInput[], options?: { atomic?: true; }): Promise>; createMany(items: CreateEvidenceInput[], options: { atomic: false; }): Promise>; /** * Updates multiple evidence records in a batch. * * @param updates - Array of { id, data } objects * @param options - Batch options (atomic: true by default) * @returns Atomic result with data array, or partial result with succeeded/failed */ updateMany(updates: { id: string; data: UpdateEvidenceInput; }[], options?: { atomic?: true; }): Promise>; updateMany(updates: { id: string; data: UpdateEvidenceInput; }[], options: { atomic: false; }): Promise>; /** * Creates or updates an evidence record by externalId. * * @param data - Evidence upsert data (must include externalId) * @returns The created or updated evidence record with action indicator */ upsertByExternalId(data: UpsertEvidenceInput): Promise>; /** * Creates or updates multiple evidence records by externalId in a single request. * * @param items - Array of evidence upsert data (each must include externalId) * @param options - Batch options (atomic: true by default) * @returns Atomic or partial batch result */ upsertManyByExternalId(items: UpsertEvidenceInput[], options?: { atomic?: true; }): Promise>>; upsertManyByExternalId(items: UpsertEvidenceInput[], options: { atomic: false; }): Promise>>; /** * Instantiates an Evidence model from raw data. * Override in subclasses to return scope-specific models. */ protected instantiate(data: EvidenceData): Evidence; }