WEB_SERVER_V2_PLAN

Web Server V2 Plan: Strict/Mode/Clean-First Options + Before/After Content

Goal

Expose existing backend options in the UI/API and add before/after workflow content to clean and roundtrip results. Specifically:

  1. Fine-grained strict options (strict_structure, strict_encoding, strict_state) on validate, lint, roundtrip — replacing the old single strict bool
  2. Clean-first option on validate (run clean in-memory, embed results; off by default)
  3. Validation mode selector (Effect/meta model vs JSON schema via AJV) on validate
  4. Before/after workflow content on clean and roundtrip response models
  5. Fix latent Python bug: run_lint passed strict=True to lint_single which doesn’t accept that kwarg

Decisions

  1. Roundtrip content: Before + after only (no intermediate format2). Simpler model.
  2. Lint mode: Skip — lint_single has no mode param. Only validate exposes mode.
  3. Strict granularity: Fine-grained — three separate params (strict_structure, strict_encoding, strict_state). Single strict bool removed from server API (callers use named params).
  4. Python roundtrip content: Captured via result.original_dict / result.reimported_dict on RoundTripValidationResult — both already populated by roundtrip_validate, just excluded from serialization.
  5. TS JSON schema validate mode: Implemented — mode=json-schema routes to AJV path (validateNativeStepsJsonSchema / validateFormat2StepsJsonSchema + decodeStructureErrorsJsonSchema).

Phase 1 — Python report model extensions ✅

Files: lib/galaxy/tool_util/workflow_state/_report_models.py, roundtrip.py


Phase 2 — Python library entry point extensions ✅

Files: clean.py, roundtrip.py, operations.py


Phase 3 — Python server endpoint extensions ✅

File: gxwf-web/src/gxwf_web/app.py, operations.py

operations.py fully rewritten — no more **kwargs pass-through, all params explicit.

EndpointChanges
GET /validateRemoved strict; added strict_structure, strict_encoding, clean_first (mode was already present)
GET /lintRemoved strict; added strict_structure, strict_encoding
GET /cleanAdded include_content: bool = False
GET /roundtripAdded strict_structure, strict_encoding, strict_state, include_content

Phase 4 — TS schema model extensions ✅

File: packages/schema/src/workflow/report-models.ts


Phase 5 — TS server extensions ✅

Files: packages/schema/src/workflow/roundtrip.ts, packages/cli/src/commands/validate-workflow-json-schema.ts, packages/cli/src/index.ts, packages/gxwf-web/src/workflows.ts, packages/gxwf-web/src/router.ts

roundtrip.ts

validate-workflow-json-schema.ts

cli/src/index.ts

workflows.ts

router.ts

All tests pass (58 Python, 78 TS gxwf-web, full suite green).


Phase 6 — OpenAPI spec + generated types ✅

File: packages/gxwf-web/openapi.json, packages/gxwf-web/src/generated/api-types.ts


Phase 7 — Vue UI (useOperation.ts + OperationPanel.vue) ✅

useOperation.ts

Exported typed opts interfaces (ValidateOpts, LintOpts, CleanOpts, RoundtripOpts). Each run* function gains a typed options parameter; opts are passed as params.query to the openapi-fetch client:

OperationPanel.vue toolbar additions

Each tab has a reactive<*Opts> object initialized to all-false defaults. Toolbar controls per tab:

Note: validate tab has no strict_state (not in ValidateOptions). Options are reactive refs; changing them does not auto-rerun.

Also required: rebuild @galaxy-tool-util/gxwf-web (pnpm build) to update dist types before typechecking dependent packages.


Phase 8 — Report display components (packages/gxwf-report-shell/src/) ✅

CleanReport.vue

When before_content/after_content present: collapsed PrimeVue Panel (“Workflow content”) with 2 side-by-side <pre> panes (Before / After). No diff lib needed — <pre> with max-height: 400px; overflow: auto.

RoundtripReport.vue

When before_content/after_content present: collapsed PrimeVue Panel (“Workflow content”) with Tabs inside — “Original (native)” and “Re-imported (native)” tabs, each with <pre>.

ValidationReport.vue

When clean_report present: collapsed Panel (“Pre-validation clean”) inserted above the summary/results, rendering <CleanReport :report="report.clean_report" /> directly.


Phase 9 — Tests

Python

TypeScript