Skip to content

Latest commit

 

History

History
73 lines (49 loc) · 9.53 KB

File metadata and controls

73 lines (49 loc) · 9.53 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Dockstore UI2 is the Angular front end for Dockstore, a registry of bioinformatics tools, workflows, services, notebooks and apptools. It talks to the backend in the separate dockstore/dockstore repo; the CLI (dockstore/cli) and user-facing documentation (dockstore/dockstore-documentation) are also separate repos, and the project has a discussion forum at https://discuss.dockstore.org/. Issues are tracked in the dockstore/dockstore repo, not here.

Dependency conventions

Favor Angular's own recommended libraries/patterns (and Angular Material/CDK) for things it has an opinion on over ad hoc alternatives. Beyond that, prefer, in order: (1) built-in TypeScript/browser/Angular features, (2) a third-party library already in package.json, (3) a new third-party dependency — only reach for a new one when neither of the above covers the need (and see the PR checklist items on npm audit and CVE due diligence).

Branching

Hubflow (gitflow) conventions: develop is the main integration branch and the default PR target, with work on feature/* branches branched from and merged back into develop, hotfix/* for urgent fixes, and release/* cut for releases.

Pull requests

  • Always create PRs in draft mode. A human developer must be the one to mark a PR ready for review — don't do it yourself.
  • Always check with the user before pushing to GitHub, even to a branch/PR already being worked on in the conversation — a push can kick off a long CI build or interrupt one already running.
  • When a GitHub MCP server or gh is available, diff the work against develop (or the PR's target branch) and minimize stylistic or otherwise-minor changes that inflate the diff, unless they fix something a Codacy finding or other code-quality check actually flagged.
  • Keep the freeform "Description" and "Review Instructions" sections of .github/PULL_REQUEST_TEMPLATE.md brief — one paragraph each, or two for a genuinely complicated fix.
  • The template's checklist must be copied into PR descriptions verbatim — never reword, reformat, condense, or append explanatory text to a checklist item. Only toggle [ ] to [x], and only after actually confirming that item was done/verified for this PR; leave it unchecked otherwise.

Using CI and review feedback to guide work

When diagnosing a failing build or iterating on an open PR, pull in whatever signal is actually available rather than guessing:

  • If gh or a GitHub MCP server is available, use GitHub Actions results (check runs, job logs — this repo has CodeQL, npm audit, accessibility and license workflows in .github/workflows/) to guide diagnosis and fixes.
  • If a CircleCI MCP server is available, use its results (workflow/job status, test failures, logs) — lint, unit tests, Cypress and the build run on CircleCI (.circleci/config.yml).
  • Codacy findings aren't reliably fetchable through available tooling. If Codacy results seem significant to the task, ask the user to copy-paste them rather than guessing at what Codacy flagged.
  • Code review comments from human developers are high-priority direction — investigate each one and propose concrete solutions, even without an explicit instruction to do so. Bot-authored comments (Codacy, Copilot Autofix, etc.) are useful but secondary.

JIRA

When adding comments to JIRA tickets, clearly indicate that the comment was written by Claude (e.g. lead with a line like "This comment was generated by Claude (Claude Code).").

Commands

Node version is pinned in .nvmrc; install with npm ci (don't set CI=true, or the Husky pre-commit hook won't install). Java 21+ and wget are needed because the build generates the API client.

  • npm run build / npm run build.prod — runs prebuild first (writes git version info and regenerates the OpenAPI client, see below), then ng build.
  • npm run start — dev server on :4200, proxying /api, /swagger.json, /openapi.yaml to a webservice on localhost:8080 (proxy.conf.json). Requires the OpenAPI client to have been generated at least once.
  • npm run lint — ng lint (ESLint).
  • npm test — Karma/Jasmine unit tests in Chrome (watch mode). CI runs: npx ng test --progress=false --watch=false --code-coverage --browsers ChromeHeadless --source-map=false.
  • Single spec file: npx ng test --watch=false --browsers ChromeHeadless --include src/app/path/to/foo.component.spec.ts (--include also accepts a directory or glob).
  • Cypress e2e: Cypress is not in package.json (see .circleci/config.yml for the version). npx cypress run --spec "cypress/e2e/group1/**/*". Needs Postgres, the UI served on :4200, and a running webservice jar — npm run webservice (scripts/run-webservice-script.sh) downloads the jar, loads test/${DB_DUMP:-db_dump.sql} and runs migrations.
  • Smoke tests against a local stack: npm run test-local-no-auth; other test-<qa|staging|prod>-* scripts target deployed environments.
  • After dependency changes: npm run license to regenerate THIRD-PARTY-LICENSES.csv, then manually review/revert entries that become "unknown".

Prettier (single quotes, printWidth 140) and eslint --fix run on staged files via Husky + lint-staged.

Generated OpenAPI client

src/app/shared/openapi/ is generated and gitignored — never edit it by hand. scripts/generate-openapi-script.sh (run by prebuild) uses openapi-generator typescript-angular against the webservice's openapi.yaml, chosen by package.json config:

  • use_snapshot: false → fetches openapi.yaml from the dockstore/dockstore GitHub repo at tag webservice_version.
  • use_snapshot: true → downloads dockstore-webservice-${webservice_version_prefix}-SNAPSHOT from OICR Artifactory via Maven (the prefix can include a branch name with / replaced by -).
  • Override without editing the file: npm pkg set config.webservice_version=....

API services (WorkflowsService, ContainersService, UsersService, MetadataService, …) and models are imported from app/shared/openapi (or shared/openapi). If a backend field/endpoint is missing, the fix is usually bumping the webservice version and regenerating, not hand-writing types. Loose dockstore-webservice-*.openapi.yaml files in the repo root are download byproducts of snapshot builds.

Architecture

  • Bootstrap/config: app.module.ts wires everything; at startup ConfigurationService.load() fetches /config from the webservice (MetadataService.getConfig()) and copies values into static fields on the Dockstore class (shared/dockstore.model.ts) — OAuth client IDs, launch-with platform URLs, feature settings. Code reads Dockstore.X statics rather than injecting config. FeatureService handles URL-param feature flags.
  • Auth: a vendored, modified copy of ng2-ui-auth lives in src/app/ng2-ui-auth/; the token is stored in localStorage as ng2-ui-auth_token. shared/auth.guard.ts protects logged-in routes; HTTP interceptors are in src/app/interceptors/.
  • Routing: app.routing.ts lazy-loads feature areas (containers/tools, workflows, services, apptools, notebooks, my-*, organizations, search, docs, users, aliases). Services, apptools and notebooks are variants of workflows (BioWorkflow/Service/AppTool/Notebook share the workflow code in src/app/workflow/ and src/app/workflows/); tools/containers live in src/app/container/ and src/app/containers/. Public entry pages and "my-*" management pages reuse the same entry components. Before adding per-entry-type logic, look for the shared code (src/app/shared/entry/, entry.ts, my-entry.ts, shared/state/) — new entry-type behavior is usually an extension of it, not a new parallel code path.
  • State: Akita stores. The common pattern is a trio per concern — foo.store.ts (state), foo.query.ts (selectors/observables), foo.service.ts (actions that call the API and update the store). Global ones are in src/app/shared/state/ (e.g. WorkflowService/WorkflowQuery for the currently viewed workflow, ExtendedWorkflow*, MyEntries*, Token*); feature areas like search/, organizations/, container/ have their own state/ folders.
  • Search (src/app/search/) builds Elasticsearch queries with bodybuilder and sends them through the webservice's ES proxy.
  • Components are standalone (Angular 22); Angular Material + @ngbracket/ngx-layout for layout, Bootstrap 3 CSS still present. Ace editor, Cytoscape (DAGs), Chart.js, marked/KaTeX are loaded as noted in angular.json scripts.
  • Unit test helpers: src/app/test/ holds shared stubs (service-stubs.ts, router-stubs.ts) and fixture objects (mocked-objects.ts, openapi-mocked-objects.ts) — reuse them in specs instead of building new mocks.

Cypress tests and DB dumps

  • cypress/e2e/group1..3 run against a webservice loaded with test/db_dump.sql (or other dumps in test/ selected via DB_DUMP); immutableDatabaseTests must not mutate data; smokeTests/sharedTests run against any environment (the package.json smoke scripts also reference qaOnly/stagingOnly/prodOnly specs that don't currently exist in the repo).
  • When a smoke test fails in CI it's either a UI change (fix the test) or missing data in test/smoke_test_db.sql (update the dump). To log in locally as a test user, set localStorage ng2-ui-auth_token to fake-admin-token, fake-curator-token or fake-basic-1-token. Never link real accounts when regenerating dumps — the dumps are public; check the token table before committing.