Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,29 @@ jest.mock('@/tasks/evidence-export/evidence-attachment-streamer', () => ({
createFilenameTracker: jest.fn(),
}));

import { streamArchiveToS3 } from './export-organization-evidence';
import {
exportOrganizationEvidenceTask,
streamArchiveToS3,
} from './export-organization-evidence';

describe('exportOrganizationEvidenceTask config', () => {
// schemaTask is mocked to return its config, so the task IS its config object.
const config = exportOrganizationEvidenceTask as unknown as {
id: string;
maxDuration: number;
};

it('allows large orgs at least an hour before Trigger.dev kills the run', () => {
// Regression: orgs with high automation volume + large outputs exceeded the
// old 30-minute (60 * 30 = 1800s) budget, so Trigger.dev killed the run
// (retry maxAttempts: 0), leaving it in a non-COMPLETED terminal state that
// the browser surfaces as a failed export with no download link. The task
// must be allowed at least an hour to finish streaming the ZIP to S3.
expect(config.maxDuration).toBeGreaterThanOrEqual(60 * 60);
// maxDuration is in SECONDS — guard against the ms form (which would be days).
expect(config.maxDuration).toBeLessThan(24 * 60 * 60);
});
});

describe('streamArchiveToS3', () => {
const s3Client = {} as never;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,12 @@ export const exportOrganizationEvidenceTask = schemaTask({
// concurrencyLimit 1 + a per-org concurrencyKey (passed at trigger time) means
// at most one export runs per org at a time; different orgs still run in parallel.
queue: { name: 'evidence-export', concurrencyLimit: 1 },
maxDuration: 60 * 30,
// maxDuration is max compute time in SECONDS. Orgs with high automation
// volume + large outputs were exceeding the old 30-minute budget, so
// Trigger.dev killed the run (retry maxAttempts: 0) — a non-COMPLETED
// terminal state the browser reports as a failed export with no download
// link. Give the single-threaded stream-to-S3 pass up to an hour to finish.
maxDuration: 60 * 60,
retry: { maxAttempts: 0 },
schema: z.object({
organizationId: z.string(),
Expand Down
Loading