Skip to content

Validate calibration controls belong to the calibration's score set #751

@bencap

Description

@bencap

Summary

Add validation logic to lib/score_calibrations.py that enforces calibration controls reference variants belonging to the calibration's associated score set.

Background

Controls are restricted to variants in the calibration's score set by design — a control without a DMS score would be meaningless for calibration. This constraint must be enforced at the API layer before any controls are persisted.

Proposed Behavior

When controls are provided in a calibration create or modify request:

  1. Resolve each control's variant_urn to a Variant record
  2. Verify variant.score_set_id == calibration.score_set_id for every control
  3. Raise a ValidationError (consistent with existing validation patterns) for any controls whose variant does not belong to the score set, listing the offending URNs
  4. Raise a ValidationError if any variant_urn does not exist in MaveDB at all

Acceptance Criteria

  • A control referencing a variant from a different score set is rejected with a ValidationError naming the invalid URNs
  • A control referencing a non-existent variant_urn is rejected with a ValidationError
  • Validation runs for both create and modify operations
  • Validation is a no-op when controls is None or empty
  • New unit tests cover the validation logic and existing tests continue to pass

Implementation Notes

  • Validation should be placed in lib/score_calibrations.py, consistent with the location of other calibration validation helpers
  • Batch the DB query: look up all variant URNs in one query and diff against the submitted set — avoid per-control round trips
  • Follow the pattern of validate_index_existence_in_score_set in lib/validation/dataframe/calibration.py
  • Duplicate (calibration_id, variant_id) pairs are handled by the UNIQUE DB constraint; the API should still return a friendly validation error before hitting the DB constraint

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions