Skip to content

fix(api): set pending when creating records via upload#1422

Open
gdevenyi wants to merge 1 commit into
mainfrom
fix/upload-sets-pending
Open

fix(api): set pending when creating records via upload#1422
gdevenyi wants to merge 1 commit into
mainfrom
fix/upload-sets-pending

Conversation

@gdevenyi

Copy link
Copy Markdown
Contributor

This is the test failure I've been flagging as pre-existing in #1418, #1419, #1420 and #1421. It turns out to be a real defect, not a stale test.

What happened

InstrumentRecordsService.upload builds its records without a pending field at all, so every bulk-uploaded record is persisted with the field absent rather than false.

PR #1404 ("fix pending tag issue which cause old data not to be visible") fixed the resulting invisibility by teaching find to match records where the field is missing:

// records created before the file instrument feature do not have the pending field at all,
// and prisma NOT filters on mongodb exclude documents where the field is missing entirely
{ OR: [{ pending: { isSet: false } }, { pending: null }, { pending: false }] }

and in the same commit added a test asserting that upload sets pending — but never made that change to upload. The test has been red on main since that PR merged (8998d811d).

So the test was correct and expressed the intent; the production half of the fix was simply missing.

Why it still matters

The comment on the compatibility clause says it exists for "records created before the file instrument feature". But because upload still omits the field, that clause is not a legacy shim — it is load-bearing for newly created data, and any query that filters on pending the natural way silently misses every uploaded record.

Confirmed against a live instance, before the fix:

record exists:                            true
has pending field:                        false
matched by a plain {pending:false} query: 0
matched by the compat OR clause:          1

Why this mirrors create instead of hardcoding false

My first cut was pending: false, which is literally what the test asserts. Then I checked whether upload can receive a file instrument — it does not reject them the way it rejects series instruments — and it can:

upload of a FILE instrument: HTTP 201
persisted: 1

Hardcoding false would therefore mark a record with no attached files as complete, and FilesService.getAssociations would then reject any attempt to attach them with Upload already completed. So this uses the same expression create already uses one function above:

pending: instrument.kind === 'FILE',

which satisfies the test (its fixture is a FORM) and keeps the two creation paths consistent.

Verified live, after the fix

form upload      pending = false     visible in the datahub
file upload      pending = true      correctly excluded until its files arrive
main behaviour   pending = ABSENT    still visible via the compatibility clause

No regression for existing data: records created before this change are still matched by the isSet: false clause, which stays exactly as it is.

Tests

The existing test now passes. Added one covering the file-instrument branch, so the create/upload consistency is pinned rather than incidental.

vitest run across the whole workspace is now fully green — 37/37 files, 254 passed, 1 skipped, 0 failed. It has had this one failure throughout.

  • tsc --noEmit on apps/api — clean
  • eslint src — clean
  • prettier --check — clean

Note

While verifying this I re-confirmed the separate issue filed as #1414: upload's return value is findMany({ groupId, instrumentId }), so uploading one record returned all 8 records for that instrument. Not touched here.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Bfen9VQemZanJLXinJ6MMG

`upload` built its records without a `pending` field at all, so every
bulk-uploaded record was persisted with the field absent rather than
false.

PR #1404 fixed the resulting invisibility by teaching `find` to match
records where the field is missing:

    { OR: [{ pending: { isSet: false } }, { pending: null }, { pending: false }] }

and added a test asserting `upload` sets `pending` -- but never made that
change to `upload`. The test has been failing on main ever since that
merge. The comment on the compatibility clause says it exists for
"records created before the file instrument feature", but with `upload`
still omitting the field it is load-bearing for newly created data too,
and any query filtering on `pending` directly does not see those records.

Confirmed against a live instance before the fix: a record created
through POST /v1/instrument-records/upload has no `pending` field, and
`{ pending: false }` matches zero documents while the compatibility
clause matches one.

Mirrors `create` rather than hardcoding false. `upload` does not reject
file instruments the way it rejects series instruments -- verified, a
file instrument upload returns 201 -- so hardcoding false would mark a
record with no attached files as complete and `FilesService` would then
reject any attempt to attach them with "Upload already completed".

After the fix, verified live: a form upload persists `pending: false` and
stays visible in the datahub, a file upload persists `pending: true` and
is correctly excluded until its files arrive, and records predating the
change remain visible through the compatibility clause.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bfen9VQemZanJLXinJ6MMG
@gdevenyi
gdevenyi requested a review from joshunrau as a code owner July 20, 2026 18:45
Copilot AI review requested due to automatic review settings July 20, 2026 18:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a production defect in the API bulk-upload path (InstrumentRecordsService.upload) where newly created instrument records were persisted without a pending field, causing them to be missed by any query filtering on pending (unless it used the legacy compatibility OR clause). The change aligns upload with the existing create behavior so newly uploaded records always have an explicit pending value.

Changes:

  • Set pending explicitly during bulk upload, matching the create logic (pending: instrument.kind === 'FILE').
  • Add a unit test to pin the FILE-instrument branch (FILE uploads remain pending: true so files can be attached later).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
apps/api/src/instrument-records/instrument-records.service.ts Ensures bulk-uploaded records always persist an explicit pending value, consistent with the single-record create path.
apps/api/src/instrument-records/tests/instrument-records.service.spec.ts Adds coverage to ensure FILE instrument uploads produce pending: true (and existing pending assertion for FORM remains satisfied).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants