4.0.0 (2026-09-26)
⚠ BREAKING CHANGES
- grz-db,grzctl:
grzctl db submission populaterefuses to replace or remove a stored value without--forceor--allow-overwrite. Its--submission_dateoption is renamed to--submission-date. Without it,populatetakes the upload date from the metadata.json object in the inbox, and stops if the inbox has none.grzctl uploadis removed. Usegrz-cli upload.grzctl db backfillskips a submission with an undeclared destructive change, instead of writing the rest of it. grz-db removesSubmissionChangeSet.withhold_destructive,SubmissionDiffCollection.withhold_destructive,SubmissionDiffCollection.has_pending_destructiveandDonorsDiffCollection.has_pending_destructive. UseSubmissionChangeSet.undeclared_destructive_changes()instead. - grzctl:
db submission modifyand--ignore-fieldtakelocal_case_idwhere they tookpseudonym. In JSON outputpseudonymis now the case's psn (null until assigned); the former value is underlocal_case_id.
Features
- grz-cli,grz-common,grz-db,grzctl: record why a submission failed and classify S3 errors (#690) (f1d3fc8)
- grz-common: recommend grz-cli 3.0.0 in the bundled version policy (bf3e6bf)
- grz-db,grzctl: add case tracking for submissions (#633) (68c75dc)
- grz-db,grzctl: add db case list-unlinked and list-ambiguous-keys (68c75dc)
- grz-db,grzctl: add processing states and make populate and backfill overwrite only declared fields (#681) (4c012dc)
- grz-db,grzctl: track which inbox a submission came from and use it for decryption (#696) (ce95f8c)
- grz-db: let a psn-keyed deployment resolve cases through diff and (68c75dc)
- grz-db: withhold destructive changes from a whole change set (bdd6321)
- grz-pydantic-models,grz-common: keep a parsed submission lossless and redact it by one rule (#654) (ec46603)
- grz-pydantic-models: add get_raw_dict for the document as (ec46603)
- grz-pydantic-models: publish PCT_DEV_CUTOFF (a0e1bfe)
- grzctl: add db case commands and link submissions to cases on (68c75dc)
- grzctl: explain why a case is listed in the Detailprüfung report (a0e1bfe)
- grzctl: fail a rival initial submission's basic QC during validate (68c75dc)
- grzctl: report QC deviations without failing and add recompute-qc backfill (#656) (a0e1bfe)
- grzctl: sign archived files with the private key of the (ce95f8c)
Bug Fixes
- grz-cli,grz-common,grz-db,grzctl: require grz-common 4, grz-db 4 and grz-pydantic-models 4 (#688) (bf3e6bf)
- grz-common: require grz-pydantic-models >=3.1 for (ec46603)
- grz-db: apply a change set as one transaction (ec46603)
- grz-db: consult the resolver assert_no_duplicate_initial is (68c75dc)
- grz-db: export db_backend from grz_db.testing (ec46603)
- grz-db: leave a local case ID reused across patients unlinked (68c75dc)
- grz-db: let SQLite connections wait 60 s for a lock (#699) (700868f)
- grz-db: pass the database password to the migrations (700868f)
- grz-db: raise the grz-pydantic-models floor to 3.1 (a0e1bfe)
- grz-db: require grz-pydantic-models >=3.1 for (68c75dc), closes #632
- grzctl: abort cleanly on a duplicate case key and a malformed (68c75dc)
- grzctl: hold back donor overwrites in db backfill (#677) (bdd6321)
- grzctl: keep the stored upload date in db submission populate (f1d3fc8)
- grzctl: name the submission fields the database actually has (ec46603)
- grzctl: stop backfill counting an updated submission as not updated (68c75dc)