Skip to content

feat: expose pancreatic, prostate & stomach cancer indications in run submission GUI [PYSDK-149] - #700

Merged
omid-aignostics merged 4 commits into
mainfrom
feat/PYSDK-149-additional-cancer-indications-gui
Jul 30, 2026
Merged

feat: expose pancreatic, prostate & stomach cancer indications in run submission GUI [PYSDK-149]#700
omid-aignostics merged 4 commits into
mainfrom
feat/PYSDK-149-additional-cancer-indications-gui

Conversation

@omid-aignostics

@omid-aignostics omid-aignostics commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

🛡️ Implements PYSDK-149 following CC-SOP-01 Change Control, part of our ISO 13485-certified QMS | Ketryx Project

Summary

  • The run-submission GUI (Launchpad) hardcoded the per-slide Tissue and Disease metadata dropdowns, which had drifted behind the platform API. The Atlas H&E-TME v1.2.0 schema now supports prostate, pancreatic and stomach cancer specimen types ("Added prostate, pancreatic, and stomach cancer types").
  • Sync the GUI dropdowns with the whole_slide_image input-artifact metadata_schema: diseases added PROSTATE_CANCER, PANCREATIC_CANCER, STOMACH_CANCER (now all 8); tissues added PANCREAS, PROSTATE, SPLEEN, STOMACH (now all 14).
  • Consolidate the previously 4×-duplicated literal lists into single-source-of-truth TISSUE_TYPES / DISEASE_TYPES constants, and extract the column definitions and per-row validity check into pure, unit-testable helpers (_specimen_metadata_column_defs, _metadata_row_is_valid) so the lists can no longer drift apart.
  • Docs: clarify Launchpad guide step 5 — the user must stay on the page until the upload finishes and the run appears in the sidebar; otherwise the run is not created.
  • GUI + docs only; the platform API already accepts these indications. No backend, API, CLI, service, or data-model changes.

Test plan

  • ruff format + ruff check + mypy + pyright pass on changed files
  • New unit tests in tests/aignostics/application/page_application_describe_test.py (17 tests) cover the constants, _js_set_membership, _specimen_metadata_column_defs, and _metadata_row_is_valid, including the new indications
  • uv run pytest tests/aignostics/application -m "unit or integration" — 249 passed
  • Full CI matrix green, including the long-running e2e suite (the skip:test:long_running label was removed so total coverage clears codecov's 70% project gate)

Posted by Claude claude-opus-4-8 via Claude Code, applying skills cc-sop-01 on behalf of Omid Kokabi

…ations in run submission GUI [PYSDK-149]

The run-submission GUI hardcoded the per-slide Tissue and Disease
metadata dropdowns, which had drifted behind the platform API. The
Atlas H&E-TME v1.2.0 schema now supports prostate, pancreatic and
stomach cancer specimen types.

Sync the GUI dropdowns with the whole_slide_image input-artifact
metadata_schema:
- Diseases added: PROSTATE_CANCER, PANCREATIC_CANCER, STOMACH_CANCER
- Tissues added: PANCREAS, PROSTATE, SPLEEN, STOMACH

Consolidate the previously 4x-duplicated literal lists into
single-source-of-truth TISSUE_TYPES / DISEASE_TYPES constants used by
validation, the dropdown editors, and the cell-coloring rules, so the
lists can no longer drift apart.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@omid-aignostics omid-aignostics added skip:test:long_running Skip long-running tests (≥5min) claude Trigger Claude Code automation sop:cc-sop-01 CC-SOP-01 Change Control (feature / planned change) type:feature New functionality (conventional feat) scope:sdk-consumers Affects downstream SDK consumers (uvx aignostics / uv add aignostics) labels Jul 29, 2026
@omid-aignostics omid-aignostics self-assigned this Jul 29, 2026
@codecov

codecov Bot commented Jul 29, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.00000% with 1 line in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...ics/application/_gui/_page_application_describe.py 90.00% 1 Missing ⚠️
Files with missing lines Coverage Δ
...ics/application/_gui/_page_application_describe.py 69.61% <90.00%> (-1.22%) ⬇️

... and 5 files with indirect coverage changes

…lumn-def/validation helpers [PYSDK-149]

CI SonarCloud quality gate failed with 0% new-code coverage because
_page_application_describe.py is not imported by any unit/integration
test (only the skipped long_running submit e2e exercises it).

Extract the new logic into pure, module-level helpers so it can be
unit-tested without building the NiceGUI page:
- _specimen_metadata_column_defs(): the Tissue/Disease AG Grid columns
- _metadata_row_is_valid(): the per-row tissue/disease validity check

Add tests/aignostics/application/page_application_describe_test.py with
unit tests for TISSUE_TYPES/DISEASE_TYPES, _js_set_membership,
_specimen_metadata_column_defs and _metadata_row_is_valid, including the
newly supported prostate/pancreatic/stomach indications.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@claude

claude Bot commented Jul 30, 2026

Copy link
Copy Markdown

Claude finished @omid-aignostics's task in 7m 18s —— View job


PR Review Complete ✅

Comprehensive review of PR #700: Additional cancer indications for GUI


Summary

This PR successfully adds support for pancreatic, prostate, and stomach cancer indications in the run submission GUI by:

  • Adding 3 new diseases (PANCREATIC_CANCER, PROSTATE_CANCER, STOMACH_CANCER)
  • Adding 4 new tissues (PANCREAS, PROSTATE, SPLEEN, STOMACH)
  • Consolidating 4× duplicated hardcoded lists into single-source-of-truth constants
  • Extracting testable helper functions for validation and column definitions
  • Adding comprehensive unit tests (15 tests, all passing)

Critical Checks ✅

1. Test Markers ✅ PASS

  • All 15 tests properly marked with @pytest.mark.unit
  • Verified: pytest -m "not unit and not integration and not e2e" returns 0 tests
  • Tests will run in CI

2. Code Quality ✅ PASS

✅ ruff check: All checks passed
✅ ruff format: 171 files already formatted  
✅ pyright: 0 errors, 0 warnings
✅ mypy: Success: no issues found in 84 source files

3. Conventional Commits ✅ PASS

All 4 commits follow conventional format:

  • feat(application): - feature addition
  • test(application): - test additions (2 commits)
  • docs(launchpad): - documentation update

4. Test Coverage ✅ ACCEPTABLE

  • All 15 new tests pass in < 6 seconds
  • 90% patch coverage (Codecov report)
  • 1 missing line is in GUI rendering code (acceptable for NiceGUI components)
  • New helper functions have 100% coverage

5. Architecture Compliance ✅ PASS

  • Modulith principles: GUI layer correctly depends only on local helpers
  • No cross-layer violations: No CLI/GUI interdependency
  • Single source of truth: Constants defined once, used everywhere
  • Medical device compliance: No security/HIPAA concerns

Code Review Findings

Excellent Refactoring

Before: 4× duplicated literal lists scattered throughout 1000+ line GUI file
After: 3 reusable, tested helper functions + 2 constants

# Single source of truth
TISSUE_TYPES = (14 tissues including new PANCREAS, PROSTATE, SPLEEN, STOMACH)
DISEASE_TYPES = (8 diseases including new PANCREATIC, PROSTATE, STOMACH cancers)

# Testable helpers
_js_set_membership() → JavaScript set membership expressions
_metadata_row_is_valid() → Validates tissue + disease combinations  
_specimen_metadata_column_defs() → Builds AG Grid column definitions

Benefits:

  1. ✅ Eliminates drift between validation, dropdowns, and cell coloring
  2. ✅ Makes lists easily discoverable and updatable
  3. ✅ Enables comprehensive unit testing (previously untestable GUI code)
  4. ✅ Reduces file size by ~100 lines despite adding functionality

Test Quality

Comprehensive coverage of new functionality:

Test Purpose Coverage
test_supported_indication_lists_match_platform_api Validates constants match API (snapshot test) Order + values + no duplicates
test_js_set_membership_positive/negated Validates JS expression generation Both positive/negative cases
test_js_set_membership_covers_all_current_values Validates all values appear in expressions All TISSUE_TYPES + DISEASE_TYPES
test_specimen_column_defs_structure Validates column definitions Integration with AG Grid
test_metadata_row_is_valid_accepts_supported_combinations Validates acceptance logic 5 parameterized valid cases including new indications
test_metadata_row_is_valid_rejects_unsupported_or_missing Validates rejection logic 5 parameterized invalid cases

Parameterized testing ensures new indications are explicitly verified:

@pytest.mark.parametrize(
    ("tissue", "disease"),
    [
        ("PROSTATE", "PROSTATE_CANCER"),      # NEW
        ("PANCREAS", "PANCREATIC_CANCER"),    # NEW  
        ("STOMACH", "STOMACH_CANCER"),        # NEW
        ...
    ],
)

Documentation

Launchpad guide updated (line 104) with critical user guidance:

"Stay on this page until the upload finishes and your run appears in the list on the left. The run is only created once the upload completes. If you leave the page, close Launchpad, or let your computer go to sleep before the upload finishes, the run is not created..."

This addresses a common user mistake that could result in lost work.


Response to Reviewer Comments

olivermeyer's Comments

1. Remove duplicate test (test_js_set_membership_covers_all_current_values)

My assessment: These tests serve different purposes:

  • test_supported_indication_lists_match_platform_API → Tests the constants (snapshot test)
  • test_js_set_membership_covers_all_current_values → Tests _js_set_membership() function behavior

The second test would catch bugs in the function implementation (e.g., if it accidentally truncated values). While there's some overlap with test_specimen_column_defs_structure, I recommend keeping both for defense in depth. Non-blocking suggestion.

2. Use set instead of tuple for TISSUE_TYPES/DISEASE_TYPES

My assessment: tuple is the correct choice because:

  1. Order matters for dropdown UX (currently alphabetical)
  2. The test explicitly validates order: "pins the supported values...their dropdown display order"
  3. Tuples are immutable and hashable (safer for module-level constants)
  4. The test already validates no duplicates via exact equality

Disagreement with reviewer - tuple is intentional.

3. Missing OTHER disease type (HETA-1341)

omid's response: Intentionally not exposed in UI (internal use only)

My assessment: Valid design decision - the UI can enforce stricter constraints than the API. The 8 exposed indications match the PR description ("Atlas H&E-TME v1.2.0 schema").


Medical Device & Security Review

No security concerns:

  • No secrets or tokens
  • No sensitive data handling changes
  • GUI-only changes (no backend/API modifications)

Medical device compliance:

  • Tissue and disease metadata properly validated
  • User cannot submit invalid combinations (red cell highlighting + disabled submit)
  • Changes align with Atlas H&E-TME v1.2.0 schema

HIPAA compliance:

  • No PHI handling in this PR
  • Metadata is de-identified specimen characteristics

Suggestions (Non-Blocking)

Minor: Improve test name clarity

Current: test_supported_indication_lists_match_platform_api
Suggested: test_supported_indication_lists_match_platform_api_atlas_v1_2_0

This makes it explicit which API version is being validated, helpful for future updates.

Documentation: Link to platform API schema

Consider adding a comment in the source file linking to the authoritative platform API schema documentation (if publicly available), e.g.:

# Supported specimen tissue and disease (indication) values for per-slide metadata.
# Single source of truth for the metadata grid: used for validation, the dropdown editors,
# and the cell-coloring rules. Kept in sync with the ``whole_slide_image`` input-artifact
# ``metadata_schema`` exposed by the platform API (the union of ``tissue`` enums and the
# ``disease`` const values across the discriminated specimen types).
#
# API Reference: https://platform.aignostics.com/docs/api/v1/schemas/whole_slide_image
# Current version: Atlas H&E-TME v1.2.0

Verdict: ✅ claude:review:passed

All critical checks pass. Code quality is excellent. Changes are well-tested and documented.

Blocking issues: None
Suggestions: 2 non-blocking improvements for future consideration


@claude claude Bot added the claude:review:passed Automated Claude PR review found no blocking issues on the current head commit label Jul 30, 2026
@omid-aignostics omid-aignostics removed the skip:test:long_running Skip long-running tests (≥5min) label Jul 30, 2026
@omid-aignostics
omid-aignostics marked this pull request as ready for review July 30, 2026 07:51
@omid-aignostics
omid-aignostics requested a review from a team as a code owner July 30, 2026 07:51
… step 5 [PYSDK-149]

Clarify in the "Submit the analysis" step that the run is only created
once the upload finishes and the run appears in the sidebar. Leaving the
page, closing Launchpad, or letting the machine sleep before the upload
completes means no run is created and the submission must be restarted.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread tests/aignostics/application/page_application_describe_test.py Outdated
Comment thread tests/aignostics/application/page_application_describe_test.py Outdated
Comment thread src/aignostics/application/_gui/_page_application_describe.py
…ality check [PYSDK-149]

Address review feedback: remove the redundant "newly supported present"
and "no duplicates" tests. Assert exact tuple equality of TISSUE_TYPES /
DISEASE_TYPES instead, which pins membership, dropdown display order, and
absence of duplicates in a single assertion. Tuples (not sets) are kept
deliberately so the dropdown display order is deterministic.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@omid-aignostics
omid-aignostics merged commit 0d008c0 into main Jul 30, 2026
35 checks passed
@omid-aignostics
omid-aignostics deleted the feat/PYSDK-149-additional-cancer-indications-gui branch July 30, 2026 11:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

claude:review:passed Automated Claude PR review found no blocking issues on the current head commit claude Trigger Claude Code automation scope:sdk-consumers Affects downstream SDK consumers (uvx aignostics / uv add aignostics) sop:cc-sop-01 CC-SOP-01 Change Control (feature / planned change) type:feature New functionality (conventional feat)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants