Skip to content

Lint: no non-null assertions in the GSA form (52 → 0) - #896

Merged
adamjohnwright merged 5 commits into
mainfrom
lint/non-null-1
Nov 11, 2026
Merged

adamjohnwright merged 5 commits into
mainfrom
lint/non-null-1

Conversation

@adamjohnwright

Copy link
Copy Markdown
Contributor

Lint ratchet: @typescript-eslint/no-non-null-assertion, first area. This removes all 52 non-null assertions from the GSA form library (projects/reactome-gsa-form).

What changed

A dataset in the store fills in as it loads: first its summary, then its annotations, then its statistical design. Each reader now states what it needs, instead of asserting that the data is there.

  • Reducer.
    • A change to a design goes through updateDesign, and a change made from a summary goes through fromSummary. Before the dataset has a design or summary, both leave the state as it is. The entity helper already does the same for a dataset that does not exist.
    • Annotation columns are made only for datasets that have annotations.
  • Selectors. Each reads the design once, and treats a missing design as "not complete". Before, loadingStatus!.status threw when the status was absent.
  • Submitting. The request's design is built by submittedDesign, which is exported and tested.
    • A design missing its comparison groups, or naming a covariate that has no column, is refused through the same path a refused request takes (loadFailure, with the reason shown). Before, it was sent without them for the service to refuse.
    • The form requires a complete design before it submits, so this path is not expected to fire.
    • Request.Dataset and Request.DataInformation are exported so the function can be typed.
  • Loading. A finished load with no dataset id now fails the same way as a summary that could not be fetched. Before, it requested /summary/undefined.
  • Dataset sources. The source selector compares type only when it exists. The ! on id was unnecessary, because id is required.

Counts

Before After
Lint 1,129 1,077
no-non-null-assertion 203 151
Dead code 104 104

Tested

  • Unit: the new submittedDesign spec covers a complete design, a design missing its groups, and a covariate with no column. I removed the comparison-group check and it failed.
  • End-to-end: analysis.spec.ts and analysis-results.spec.ts, which include the GSA form: 33 passed.
  • Preflight: passed in full on push.

Note for review

This branch was cut before #895 merged. Both PRs touch lint-baseline.json, so whichever merges second needs its baseline regenerated; I'll rebase this one once #895 is in.

🤖 Generated with Claude Code

adamjohnwright and others added 4 commits November 7, 2026 22:01
A dataset in the store fills in as it loads (its summary, annotations,
statistical design), so each reader now says what it needs:

- The reducer changes a design through updateDesign and a summary
  through fromSummary, which leave the state as it is before the
  dataset has one, as the entity helper already does for a dataset
  there is not. Annotation columns are made for the datasets that have
  annotations.
- The selectors read the design once, and say "not complete" where it
  is missing rather than throwing.
- The submitted design is built by submittedDesign, tested: a design
  without its groups or a covariate's column is refused through the
  path a refused request takes (loadFailure, its reason shown), not
  sent without them for the service to refuse.
- A finished load with no dataset id fails as a summary that could not
  be had.

Lint 1,129 -> 1,077 (no-non-null-assertion 203 -> 151).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From #896's review. The default analysis group comes from the service, not
from the annotation header, so the form can show a design complete whose
group names a column the samples lack; submitting it said only that the
design was not complete. It now names the column, as it does for a chosen
covariate with no column.

The refusal is made by refusal(), tested as a 400 with its reason in
detail: a 503 would be retried every minute as the service being busy.
Both tests were seen failing (a 503; the message removed).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@adamjohnwright

Copy link
Copy Markdown
Contributor Author

Independent review, with main merged in: no regression that matters; the state shape is unchanged.

Acted on (5388605, both tests seen failing under mutation):

  • A design whose analysis group or chosen covariate names a column the samples lack now says which column, instead of only "not complete". The default analysis group comes from the service, not the annotation header, so the form can show such a design as complete.
  • The client-side refusal is built by refusal() and tested as a 400 with its reason in detail. A 503 would be retried every minute as the service being busy.

Left as they are, all on paths the form's steps do not reach in normal use:

  • A load with no dataset id now goes straight to getSummaryError without the 10 s snackbar. Nothing reads that action's error today.
  • The reducer's new no-op paths (updateDesign, fromSummary, initAnnotationColumns) replace code that fabricated partial state or threw, and have no tests of their own.

The lint baseline is regenerated after the merge: 931 → 879 warnings.

🤖 Generated with Claude Code

@adamjohnwright
adamjohnwright merged commit 0fe3abb into main Nov 11, 2026
17 of 22 checks passed
@adamjohnwright
adamjohnwright deleted the lint/non-null-1 branch November 11, 2026 21:36
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.

1 participant