Skip to content

Aliquot/tube nomenclature: align with lab usage (aliquot = one part of a sample) #99

@olsonjp

Description

@olsonjp

Summary

As a lab technician, the current aliquot/tube nomenclature is confusing. In standard lab usage, an aliquot is a single portion or division of a sample—i.e., one physical item (one tube). The app currently uses aliquot to mean a batch of tubes (one Aliquot record with quantity N that has many AliquotTube children). This issue describes the changes needed so that one aliquot = one part of a sample (one tube), and aliquot is the general term for individual items.

Current behavior

  • Sample – Top-level entity (e.g. cell line, patient sample).
  • Aliquot – Belongs to a Sample; has quantity (e.g. 5); represents a batch of tubes. One Aliquot = many tubes.
  • AliquotTube – Belongs to an Aliquot; has tube_number, disposition. One physical tube.
  • AliquotLocation – Stores which (aliquot, tube_number) is in which box position.

So today: creating "one aliquot" with quantity 3 creates one Aliquot and three AliquotTube rows. The UI says "New Aliquot" but we are really creating one batch and multiple tubes. Lab language would call each of those tubes an aliquot (a part of the sample).

Desired behavior

  • Aliquot = one individual item (one physical tube / one part of a sample). Each tube is an aliquot.
  • Sample has many aliquots; each aliquot is one trackable item (one tube).
  • Batch creation can still be supported as UX: e.g. "Create 5 aliquots" creates 5 aliquot records (and optionally 5 tubes or a single batch operation), not one "aliquot" with 5 tubes.

Proposed direction

  1. Model / schema

    • Treat one aliquot as one physical item: either merge Aliquot and AliquotTube so that the aliquot row is the tube, or make Aliquot 1:1 with the physical item (e.g. one Aliquot per tube, no quantity on Aliquot).
    • AliquotLocation would reference one aliquot (one item) per slot instead of (aliquot + tube_number).
    • Decide whether to keep a separate concept for "batch" or "aliquot set" (e.g. for "create 5 aliquots from this sample") as a grouping only, not as the primary entity.
  2. Forms and creation flow

    • AliquotForm: remove or repurpose quantity; creation creates one aliquot (one item). Optionally add "Create N aliquots" (N separate aliquots or one batch operation).
    • Box assignment: assign one aliquot (one item) to one slot; no tube_number in location if aliquot = tube.
  3. Views and URLs

    • Detail view: one detail page per aliquot (the single item). Current tube_detail could become aliquot_detail (one aliquot = one tube).
    • sample_create?type=aliquot creates one aliquot (one item); batch creation as separate flow or parameter.
  4. Templates and copy

    • Replace wording that implies "aliquot = multiple tubes" (e.g. "Total Tubes", "X/Y tubes") with aliquot-centric wording (e.g. one aliquot per slot, "Stored aliquots").
    • tube_detail.html / tube-specific UI can be refactored to aliquot_detail where the aliquot is the single item.
  5. Tests and docs

    • Update tests that create aliquots with quantity and assert on AliquotTube counts.
    • Update AGENTS.md, DATA_IMPORT.md, and any user-facing docs to use the new meaning of aliquot.
  6. Import process

    • The CSV/data import must be updated to match the new model. Currently it creates one sample.aliquot per CSV row with quantity from "Number of Aliquots Total", then N sample.aliquottube rows and sample.aliquotlocation (e.g. for tube 1 only). After the change, import should create one aliquot per physical item (one aliquot per tube): e.g. one CSV row with "Number of Aliquots Total" = 5 should produce 5 aliquot records (and 5 locations if storage columns are set), not one aliquot with 5 tubes.
    • Person app: DataImportView.convert_csv_to_fixtures() in person/views.py builds fixture lists for sample.aliquot, sample.aliquottube, sample.aliquotlocation; this logic must be refactored so each imported "tube" is one aliquot (and optionally one location per aliquot). Preview counts ("X aliquots, Y tubes") should be updated to the new semantics (e.g. "X aliquots" only, or "X aliquots (Y with locations)").
    • Docs: DATA_IMPORT.md describes "Aliquots", "Tubes", and "Number of Aliquots Total"; update to describe that each row can represent one or many aliquots (one per tube), and that the CSV column indicates how many aliquot records to create per row.
    • Tests: person/tests.py (e.g. DataImportViewTest.test_convert_csv_to_fixtures_method) expects sample.aliquot, sample.aliquottube, and tube counts; update expectations to the new schema and counts.

Areas to touch (non-exhaustive)

Area Notes
sample/models/aliquot.py Aliquot vs AliquotTube vs AliquotLocation; 1:1 or merged model
sample/forms.py AliquotForm quantity, box assignment
sample/views/create.py Create one aliquot (one item); create_tubes logic
sample/views/detail.py Detail by aliquot (one item); TubeDetailView → AliquotDetailView or merged
sample/urls.py tube/<int:pk>/aliquot/<int:pk>/ or keep and repurpose
storage (assign/location) Assign one aliquot per slot; no tube_number in location
sample/signals.py create_tubes / create_aliquot_tubes semantics
Templates (detail, list, storage, home) "Aliquot" = one item; "tubes" wording
person/models.py Activity types aliquot_created / aliquot_updated (unchanged conceptually)
Fixtures / migrations Data migration: existing Aliquot + AliquotTubes → one Aliquot per tube (or chosen strategy)
Import process person/views.py (DataImportView, convert_csv_to_fixtures): create one aliquot per tube; DATA_IMPORT.md: column semantics and wording; person/tests.py: import tests and expected fixture models/counts; person admin (if it has duplicate import logic): align with views

Migration strategy

  • Data migration: Existing Aliquot rows with quantity > 1 need a strategy: e.g. create one Aliquot per current AliquotTube (and migrate AliquotLocation to point to the new aliquot IDs) or keep a "batch" table and make aliquots reference it. Document chosen approach in the issue or a follow-up.

Acceptance criteria

  • In the app, "aliquot" consistently means one part of a sample (one physical item / one tube).
  • Sample has many aliquots; each aliquot is one trackable item.
  • Creating an aliquot creates one item; batch creation (e.g. "create 5 aliquots") is supported without implying one aliquot = many tubes.
  • Storage locations reference one aliquot per slot; no tube_number on location if redundant.
  • Docs and UI copy match the new nomenclature.
  • Tests and fixtures updated; data migration path documented and implemented.
  • Import process updated: CSV import creates one aliquot per physical item (per tube); DATA_IMPORT.md and import preview/counts use the new nomenclature; import tests pass.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions