fix(evidence-export): address two follow-up review findings from prod deploy PR#2641
Merged
fix(evidence-export): address two follow-up review findings from prod deploy PR#2641
Conversation
Add explicit regression tests for the three scenarios that aren't covered by the attachment-focused happy path: - Per-task export with automations but no attachments: verifies the 01-attachments/ folder is NOT created, no S3 calls are made, and the summary PDF is rendered with attachmentsCount=0 (line omitted). - Per-task export with neither automations nor attachments: verifies the ZIP contains only the summary PDF. - Org-wide export where no task has attachments (classic pre-PR scenario): verifies manifest shows totalAttachments=0 and no 01-attachments/ folders appear anywhere. Matches exact shape of old behaviour. - Org-wide export mixing an automation-only task with an attachment-only task: verifies both appear in the same ZIP with correct contents. All 36 tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two issues cubic flagged on the production deploy PR (#2640): 1. Client-disconnect detection was listening on `req.once('close')`. In Node 16+ `req.close` fires on both disconnect AND normal request completion, which could falsely abort a successful export. Now we listen only on `res.close` and distinguish normal completion via `res.writableFinished` (true only after the full response is flushed, unlike `writableEnded` which only reflects that `.end()` was called). 2. Filename collisions were deduplicated against the raw attachment name, then wrapped into `_MISSING_<name>.txt` for placeholders. A legitimate upload named `_MISSING_foo.txt` plus a missing upload named `foo` could therefore both land at the same final ZIP path. Now the tracker sees the full final name (including any `_MISSING_` wrapping) so the collision is resolved on what actually ends up in the ZIP. Added two regression tests: normal-completion does not abort, and success/placeholder names don't collide in the final ZIP path. 38 tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
|
🎉 This PR is included in version 3.29.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes two issues cubic flagged on the production deploy PR #2640, plus adds regression tests for automation-only and mixed-org scenarios that weren't covered explicitly in #2639.
Fixes
P1 — Client-disconnect detection could falsely abort successful exports
evidence-export.controller.tslistened onreq.once('close'). In Node 16+req.closefires on both client disconnect AND normal request completion, which could falsely abort a successful export in a timing window. The guard wasres.writableEndedwhich becomes true as soon as.end()is called, not when data is actually flushed — leaving a small window where an abnormal close could be incorrectly treated as normal.Fix: listen only on
res.closeand distinguish completion viares.writableFinished(true only after all data is flushed and the'finish'event fires).P2 — Placeholder vs success filename collision
The collision tracker was being fed the raw attachment name, and the
_MISSING_<name>.txtwrapping was applied after tracking. A legitimate upload literally named_MISSING_foo.txtplus a missing upload namedfoocould both end up at the same final ZIP entry path.Fix: pass the full final name (including any
_MISSING_wrapping and.txtsuffix) through the tracker so collisions are resolved on what actually ends up in the ZIP.Also included
Regression tests from a separate follow-up covering:
01-attachments/folder is created and no S3 calls are madeTest plan
cd apps/api && npx jest src/tasks/evidence-exportevidence-export/filesClient disconnected during export (…); aborting archiveaborting archivelog appearsLinear
Follow-up on CS-279
🤖 Generated with Claude Code
Summary by cubic
Fixes false export aborts on normal completion and prevents
_MISSING_placeholder filename collisions in evidence ZIPs. Adds regression tests for automation-only, summary-only, and mixed-org exports. Linear: CS-279.res.closeonly and gate byres.writableFinishedto avoid aborting completed downloads; removereq.closelistener._MISSING_prefix and.txt), so real files like_MISSING_foo.txtdon’t collide with placeholders for missingfoo.Written for commit 8c655b3. Summary will update on new commits.