Skip to content

feat(visualization): add protein viewer - #31

Merged
dsk-dev-ai merged 2 commits into
mainfrom
feat/visualization-protein-viewer
Aug 13, 2026
Merged

feat(visualization): add protein viewer#31
dsk-dev-ai merged 2 commits into
mainfrom
feat/visualization-protein-viewer

Conversation

@dsk-dev-ai

@dsk-dev-ai dsk-dev-ai commented Aug 13, 2026

Copy link
Copy Markdown
Owner

Summary

Implements Phase 6.5 — Protein Viewer of the GenomeAI Visualization Platform.

This PR adds a reusable protein sequence and annotation visualization layer on top of the existing GenomeAI visualization architecture.

The implementation builds on the existing Genome Browser, Gene/Transcript Viewer, Variant Viewer, visualization utilities, and API boundaries.

Features

Protein Viewer

  • Protein sequence visualization
  • Amino-acid residue positioning
  • Residue numbering
  • Protein length display
  • Protein feature/annotation rendering
  • Feature selection
  • Hover interaction
  • Viewport navigation
  • Long-sequence handling
  • Feature clipping at viewport boundaries
  • Loading state
  • Empty state
  • Error state
  • Accessible interaction

Protein Data Model

Introduces strongly typed models for:

  • proteins
  • residues
  • protein features
  • feature types
  • protein viewport/state

The viewer uses a consistent biological coordinate convention and keeps coordinate/geometry logic separate from UI rendering.

Visualization Architecture

The implementation follows the existing GenomeAI visualization architecture:

Visualization
    │
    ├── Genome Browser
    ├── Gene / Transcript Viewer
    ├── Variant Viewer
    └── Protein Viewer

Reusable sequence, feature, viewport, geometry, and API utilities are separated from the React components.

API Boundary

The Protein Viewer uses the GenomeAI API/data abstraction rather than making direct browser requests to external scientific databases.

No direct client-side integration with:

  • UniProt
  • RCSB PDB
  • AlphaFold DB
  • InterPro
  • Pfam

is introduced by this PR.

External scientific data ingestion and synchronization remain outside the scope of Phase 6.5.

Rendering Scope

This phase intentionally focuses on:

  • protein sequences
  • residues
  • annotations
  • domains/features
  • interactive navigation

It does not implement 3D molecular structure rendering.

No C++, WebAssembly, WebGPU, or new 3D rendering dependency is introduced.

Testing

Added/updated tests covering:

  • protein sequence handling
  • residue coordinates
  • viewport calculations
  • feature coordinates
  • feature clipping
  • feature selection
  • empty sequences
  • long sequences
  • API response handling
  • loading/error states
  • component rendering
  • accessibility
  • visualization integration

Existing GenomeAI tests remain unchanged and must continue to pass.

Verification

Run:

make setup
make lint
make typecheck
make test
pnpm turbo build

Also manually verify the visualization application and existing visualization routes.

Compatibility

  • No breaking API changes
  • Existing Genome Browser preserved
  • Existing Gene/Transcript Viewer preserved
  • Existing Variant Viewer preserved
  • Existing visualization architecture preserved
  • No unnecessary external dependencies

Roadmap Progress

Phase 6 — Visualization Platform

  • ✅ 6.1 Visualization Foundation
  • ✅ 6.2 Genome Browser
  • ✅ 6.3 Gene / Transcript Viewer
  • ✅ 6.4 Variant Viewer
  • ✅ 6.5 Protein Viewer

Next

Phase 6.6 — Biological Network Viewer

Planned capabilities include:

  • Gene networks
  • Protein interaction networks
  • Disease networks
  • Drug/target networks
  • Interactive node selection
  • Graph filtering
  • Network layout
  • API-backed biological relationships

Scope Boundary

This PR does not implement:

  • 3D molecular structures
  • RCSB PDB integration
  • AlphaFold structure integration
  • external database ingestion
  • external database synchronization
  • WebGPU
  • WebAssembly
  • C++

Those capabilities will be implemented only in their designated future phases.

Summary by Sourcery

Add a new Phase 6.5 protein sequence and annotation viewer to the GenomeAI visualization platform, including its React component, typed protein data/viewport/geometry utilities shared with existing genome viewers, API adapters, fixtures, and tests, while updating roadmap and visualization docs and demos to integrate the new module and generalizing common geometry, viewport, and row layout helpers.

New Features:

  • Introduce a Protein Viewer React component and demo that render protein sequences, residue windows, annotation features, and interactive selection using the shared visualization container.
  • Add a typed protein domain model, viewport/navigation logic, sequence utilities, geometry/feature helpers, and a useProteinViewer hook that reuse and extend existing visualization infrastructure.
  • Implement a protein API adapter over existing GenomeAI protein endpoints plus development fixtures to provide normalized protein data and features for the viewer.

Enhancements:

  • Generalize genome geometry, viewport pan/zoom (via an IntervalWindow abstraction), and row-packing utilities so genomic and protein visualizations share consistent interval and layout logic.
  • Refactor shared API type guards (asString, asNumber, idOf) into the genome API module for reuse across gene/transcript and protein adapters.

Documentation:

  • Document Phase 6.5 Protein Viewer scope, data flow, API boundaries, a11y, tests, and files, and update visualization README and roadmap to reflect the new milestone and module.

Tests:

  • Add focused unit tests for protein sequence handling, viewport navigation/parsing, geometry and feature layout/presentation, API adapters, the useProteinViewer hook, and the Protein Viewer component states and interactions, while keeping existing genome visualization tests passing.

@qodo-code-review

Copy link
Copy Markdown

ⓘ Qodo reviews are paused because your trial has ended. Ask your workspace admin to add credits to resume reviews. Manage billing

@sourcery-ai

sourcery-ai Bot commented Aug 13, 2026

Copy link
Copy Markdown

Reviewer's Guide

Implements a reusable Protein Viewer atop the existing GenomeAI visualization stack, including typed protein models, pure sequence/viewport/geometry utilities, a React SVG viewer, shared pan/zoom/row-packing helpers, and documentation/tests, while keeping navigation and geometry consistent with the genome viewers and maintaining API boundaries.

Sequence diagram for Protein Viewer zoom/pan navigation reuse

sequenceDiagram
  actor User
  participant ProteinViewer
  participant useProteinViewer
  participant protein_viewport as zoomProteinViewport
  participant genome_viewport as zoomViewport

  User->>ProteinViewer: Click Zoom in
  ProteinViewer->>useProteinViewer: zoomIn()
  useProteinViewer->>protein_viewport: zoomProteinViewport(viewport, 1 / ZOOM_FACTOR)
  protein_viewport->>genome_viewport: zoomViewport(viewport, factor)
  genome_viewport-->>protein_viewport: updated IntervalWindow
  protein_viewport-->>useProteinViewer: updated ProteinViewport
  useProteinViewer-->>ProteinViewer: result.viewport

  User->>ProteinViewer: Click Scroll right
  ProteinViewer->>useProteinViewer: panRight()
  useProteinViewer->>protein_viewport: panProteinViewport(viewport, panFraction(viewport, 1))
  protein_viewport->>genome_viewport: panViewport(viewport, delta)
  genome_viewport-->>protein_viewport: updated IntervalWindow
  protein_viewport-->>useProteinViewer: updated ProteinViewport
  useProteinViewer-->>ProteinViewer: result.viewport
Loading

File-Level Changes

Change Details Files
Introduce a fully typed protein data model, sequence utilities, viewport math, geometry helpers, feature presentation, and a dedicated view-model hook for the Protein Viewer.
  • Add Protein, residue, feature, feature-type, viewport, and viewer-state TypeScript types with explicit 1-based inclusive coordinate semantics.
  • Implement pure sequence helpers for residue indexing, validation, slicing, and window extraction.
  • Implement protein-specific viewport helpers (initial/whole window, pan/zoom/navigate, region parsing) built on shared IntervalWindow math.
  • Implement geometry helpers for mapping residues/features to pixels, computing axis ticks, layout of feature rows, and sizing the viewer.
  • Implement feature helpers for type normalization, validation, deduplication/sorting, colors, labels, accessible labels, and detail panel lines.
  • Implement useProteinViewer hook composing the shared visualization data lifecycle with protein viewport state and feature selection.
apps/web/src/lib/protein/types.ts
apps/web/src/lib/protein/sequence.ts
apps/web/src/lib/protein/viewport.ts
apps/web/src/lib/protein/geometry.ts
apps/web/src/lib/protein/features.ts
apps/web/src/lib/protein/useProteinViewer.ts
Add a thin typed protein API adapter and development fixtures, plus tests covering adapters, geometry, sequence, viewport, features, and the viewer hook/component.
  • Implement typed adapters over existing GenomeAI protein endpoints, including normalization of raw records to Protein/ProteinFeature and validation helpers.
  • Add injectable featureSource handling to enrich proteins with features until the backend exposes annotations, and build dev fixtures for TP53 and a long synthetic sequence.
  • Add unit tests for api, sequence, viewport, geometry, features, fixtures, and useProteinViewer to validate behavior and edge cases.
  • Add component tests for ProteinViewer covering loading/empty/error states, rendering, accessibility, navigation controls, selection, and region input.
apps/web/src/lib/protein/api.ts
apps/web/src/lib/protein/api.test.ts
apps/web/src/lib/protein/protein.fixtures.ts
apps/web/src/lib/protein/sequence.test.ts
apps/web/src/lib/protein/viewport.test.ts
apps/web/src/lib/protein/geometry.test.ts
apps/web/src/lib/protein/features.test.ts
apps/web/src/lib/protein/useProteinViewer.test.tsx
apps/web/src/components/protein/ProteinViewer.test.tsx
Implement the ProteinViewer React SVG component and integrate a ProteinDemo into the visualization page, wired to the new hook and dev fixture.
  • Add ProteinViewer component that renders the protein header, status, keyboard-accessible navigation controls, SVG residue axis, feature bars, sequence lane, and selected-feature detail panel using the new geometry/feature helpers.
  • Wire ProteinViewer to ProteinViewerResult from useProteinViewer, using VisualizationContainer for lifecycle (loading/empty/error/retry).
  • Add ProteinDemo client component that calls useProteinViewer with the TP53 dev fixture loader and renders ProteinViewer.
  • Update the visualization landing page to include ProteinDemo and expand the metadata/description to mention Phase 6.5 Protein Viewer.
apps/web/src/components/protein/ProteinViewer.tsx
apps/web/src/components/protein/ProteinViewer.test.tsx
apps/web/src/app/visualization/ProteinDemo.tsx
apps/web/src/app/visualization/page.tsx
Generalize existing genome visualization utilities (viewport, geometry, row packing, API guards) so they can be reused by the protein viewer without changing existing behavior.
  • Move intervalToPixels and PixelSpan/RenderedSpan types from geneTranscriptGeometry into the shared genome geometry module and re-export them from geneTranscriptGeometry for backward compatibility.
  • Introduce a structural IntervalWindow type in genome geometry/viewport and make viewportBaseCount, viewportEndBound, zoomViewport, and panViewport generic over IntervalWindow, updating tests accordingly.
  • Generalize layoutRows in genome tracks to use a RowFeature interface and a generic FeatureRow type so it can pack both genomic and protein features.
  • Refactor geneTranscript to import shared asString/asNumber/idOf helpers from genome api instead of duplicating them.
apps/web/src/lib/genome/geneTranscriptGeometry.ts
apps/web/src/lib/genome/geometry.ts
apps/web/src/lib/genome/viewport.ts
apps/web/src/lib/genome/viewport.test.ts
apps/web/src/lib/genome/tracks.ts
apps/web/src/lib/genome/api.ts
apps/web/src/lib/genome/geneTranscript.ts
Update visualization documentation and roadmap to reflect Phase 6.5 Protein Viewer, its capabilities, constraints, and technology choices.
  • Update roadmap docs to mark 6.5 Protein Viewer as the current milestone, list delivered artifacts, constraints, and adjust later phase descriptions and numbering.
  • Extend visualization README with a summary of what Phase 6.5 provides, including the new viewer, shared utilities, feature data boundary, and add a link to the Protein Viewer doc.
  • Adjust technology notes to clarify that Three.js is deferred to a future 3D molecular structure milestone rather than Phase 6.5.
  • Add a dedicated Protein Viewer documentation page describing scope, coordinate conventions, architecture, rendering, feature boundary, accessibility, tests, files, and validation commands.
docs/visualization/roadmap.md
docs/visualization/README.md
docs/visualization/protein-viewer.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@dsk-dev-ai, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 47 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d5eb392d-86a0-4292-9d35-0bee5aa1bb0d

📥 Commits

Reviewing files that changed from the base of the PR and between e064e6e and 4e19ac0.

📒 Files selected for processing (30)
  • apps/web/src/app/visualization/ProteinDemo.tsx
  • apps/web/src/app/visualization/page.tsx
  • apps/web/src/components/protein/ProteinViewer.test.tsx
  • apps/web/src/components/protein/ProteinViewer.tsx
  • apps/web/src/lib/genome/api.ts
  • apps/web/src/lib/genome/geneTranscript.ts
  • apps/web/src/lib/genome/geneTranscriptGeometry.ts
  • apps/web/src/lib/genome/geometry.ts
  • apps/web/src/lib/genome/tracks.ts
  • apps/web/src/lib/genome/types.ts
  • apps/web/src/lib/genome/viewport.test.ts
  • apps/web/src/lib/genome/viewport.ts
  • apps/web/src/lib/protein/api.test.ts
  • apps/web/src/lib/protein/api.ts
  • apps/web/src/lib/protein/features.test.ts
  • apps/web/src/lib/protein/features.ts
  • apps/web/src/lib/protein/geometry.test.ts
  • apps/web/src/lib/protein/geometry.ts
  • apps/web/src/lib/protein/protein.fixtures.ts
  • apps/web/src/lib/protein/sequence.test.ts
  • apps/web/src/lib/protein/sequence.ts
  • apps/web/src/lib/protein/types.ts
  • apps/web/src/lib/protein/useProteinViewer.test.tsx
  • apps/web/src/lib/protein/useProteinViewer.ts
  • apps/web/src/lib/protein/viewport.test.ts
  • apps/web/src/lib/protein/viewport.ts
  • apps/web/src/lib/visualization/visualizationModules.ts
  • docs/visualization/README.md
  • docs/visualization/protein-viewer.md
  • docs/visualization/roadmap.md

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues, and left some high level feedback:

  • There are now two IntervalWindow types (in genome/viewport.ts and genome/geometry.ts) with slightly different shapes; consider consolidating to a single shared definition to avoid semantic drift between window math and interval clipping.
  • The interactive feature selection rect in ProteinViewer uses a very small minimum hit-target width (FEATURE_HIT_MIN_PX = 6); increasing this to a more accessible size (e.g., ~24px or using a larger overlay) would improve keyboard and pointer usability on densely packed features.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- There are now two `IntervalWindow` types (in `genome/viewport.ts` and `genome/geometry.ts`) with slightly different shapes; consider consolidating to a single shared definition to avoid semantic drift between window math and interval clipping.
- The interactive feature selection rect in `ProteinViewer` uses a very small minimum hit-target width (`FEATURE_HIT_MIN_PX = 6`); increasing this to a more accessible size (e.g., ~24px or using a larger overlay) would improve keyboard and pointer usability on densely packed features.

## Individual Comments

### Comment 1
<location path="apps/web/src/lib/protein/api.ts" line_range="193-195" />
<code_context>
+    .filter((value): value is RawProteinRecord => typeof value === 'object' && value !== null)
+    .map((record) => toProtein(record))
+    .filter(isValidProtein)
+    .map((protein) => ({
+      ...protein,
+      features:
+        protein.features.length > 0 ? protein.features : prepareFeatures(featureSource(protein)),
+    }))
</code_context>
<issue_to_address>
**issue (bug_risk):** Pass protein length into `prepareFeatures` so out-of-range feature spans are rejected consistently.

Because `prepareFeatures` is called without the protein length, `isValidFeature` never runs the upper-bound check, so features with `end` beyond the sequence length are still accepted. In `fetchProteins`, please call `prepareFeatures(featureSource(protein), protein.length)` so all synthetic or API-provided features are consistently validated and cannot render outside the protein window.
</issue_to_address>

### Comment 2
<location path="docs/visualization/roadmap.md" line_range="23-24" />
<code_context>
+  navigation
+- Pure geometry (`lib/protein/geometry.ts`) — residue/feature pixel mapping and
+  axis-critical ticks via the shared genome scale, stable row packing
+- Feature presentation helpers (`lib/protein/features.ts`) — type
+  normalization, colors, labels, accessible labels, detail rows
+- Thin typed adapter (`lib/protein/api.ts`) over the existing protein endpoint
+  (`GET /proteins/{id}`, no backend changes) with injectable feature source
</code_context>
<issue_to_address>
**nitpick (typo):** Consider aligning spelling of "colors/colours" across related documentation sections.

This roadmap entry uses "colors" for the feature presentation helpers, while `protein-viewer.md` uses "colours" for the same concept. Please standardize on one spelling (US or UK) across the visualization docs for consistency.

Suggested implementation:

```
- Feature presentation helpers (`lib/protein/features.ts`) — type
  normalization, colours, labels, accessible labels, detail rows

```

To fully implement the suggestion, you should also:
1. Verify other visualization-related docs (e.g. `docs/visualization/protein-viewer.md` and any related files) for mixed "color/colour" usage and standardize them on "colours".
2. Optionally add a short style note to your documentation guidelines indicating that UK spelling ("colour/colours") is preferred for visualization terminology, to prevent future inconsistency.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread apps/web/src/lib/protein/api.ts
Comment thread docs/visualization/roadmap.md Outdated
Address the Sourcery review on #31:

- Pass the protein length into prepareFeatures so feature spans that
  extend past the sequence end are rejected (bug fix + regression test)
- Consolidate the duplicate IntervalWindow shapes into the shared genome
  types; viewport math and interval clipping now import one definition
- Enlarge the feature selection hit target from 6px to 24px for
  keyboard/pointer accessibility
- Standardize "colors" -> "colours" wording in the roadmap doc
@dsk-dev-ai
dsk-dev-ai merged commit ac1991b into main Aug 13, 2026
5 checks passed
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