WEB_INTERFACE_PASS_3_PLAN

Web Interface Pass 3: Mutating Operations + UI Conversions

Goal: Flip workflow operations from read-only to write-by-default. Add dry_run for the old read-only behavior. Add export/convert UI for format conversions. Sync everything across Python, TypeScript, and the Vue SPA.

Terminology

Current State

OperationPython endpointTS endpointWrites to disk?UI tab?
cleanGET /workflows/{path}/cleanGET ...NoYes
to-format2GET /workflows/{path}/to-format2GET ...NoNo
to-nativeGET /workflows/{path}/to-nativeGET ...NoNo
validateGET /workflows/{path}/validateGET ...NoYes
lintGET /workflows/{path}/lintGET ...NoYes
roundtripGET /workflows/{path}/roundtripGET ...NoYes

Target State

OperationMethodEndpointDefaultdry_run=true
cleanPOST/workflows/{path}/cleanOverwrites file with cleaned contentReturns report + content, no write
exportPOST/workflows/{path}/exportWrites converted file alongside originalReturns report + content, no write
convertPOST/workflows/{path}/convertWrites converted file, removes originalReturns report + content, no write
validatePOST/workflows/{path}/validateNo change (read-only, reports only)N/A
lintPOST/workflows/{path}/lintNo change (read-only, reports only)N/A
roundtripPOST/workflows/{path}/roundtripNo change (read-only, reports only)N/A

All six endpoints switch from GET to POST. Validate, lint, and roundtrip remain read-only regardless (no dry_run needed). Clean, export, and convert gain a dry_run query param (default false).


Step 1: Python API Changes (gxwf-web)

Target: /Users/jxc755/projects/repositories/gxwf-web/

1a. Update operations.py - Add write-back logic

Note: export_single returns ExportSingleResult with format2_dict (a dict). Serialize with YAML. convert_to_native_stateful returns ToNativeResult with native_dict. Serialize with json.dumps(d, indent=4).

1b. Update app.py - Change routes

1c. Update models.py - Add response models

1d. Update tests (tests/test_api.py)

1e. Regenerate OpenAPI spec

cd /Users/jxc755/projects/repositories/gxwf-web
make docs-openapi

This writes to docs/_static/openapi.json.


Step 2: TypeScript Server Changes (gxwf-web package)

Target: /Users/jxc755/projects/worktrees/galaxy-tool-util/branch/report_models/packages/gxwf-web/

2a. Sync OpenAPI spec

Copy the regenerated openapi.json from Python’s docs/_static/openapi.json to TS’s packages/gxwf-web/openapi.json. Then regenerate types:

cd /Users/jxc755/projects/worktrees/galaxy-tool-util/branch/report_models
pnpm --filter @galaxy-tool-util/gxwf-web codegen

2b. Update workflows.ts - Add write-back logic

Mirror the Python changes:

2c. Update router.ts - Change route matching

2d. Update models.ts and exports

2e. Update tests


Step 3: Schema Package Updates

Target: /Users/jxc755/projects/worktrees/galaxy-tool-util/branch/report_models/packages/gxwf-schema/ (or wherever report model types live)


Step 4: Report Shell - New Components

Target: /Users/jxc755/projects/worktrees/galaxy-tool-util/branch/report_models/packages/gxwf-report-shell/

4a. Add ExportReport.vue

Display for export/convert results:

4b. Update ReportShell.vue

Add routing for new report types: "export", "convert".

4c. Update exports in index.ts

Export ExportReport component.


Step 5: UI Changes (gxwf-ui)

Target: /Users/jxc755/projects/worktrees/galaxy-tool-util/branch/report_models/packages/gxwf-ui/

5a. Update useOperation.ts composable

5b. Update OperationPanel.vue - Add export/convert tabs

Add two new tabs after “Roundtrip”:

Export tab:

Convert tab:

5c. Update clean tab

5d. Wire up workflow list refresh

After any mutating operation (non-dry-run clean/export/convert), the UI should:

  1. Clear the operation cache for the affected workflow path(s)
  2. Refresh the workflow list (POST /workflows/refresh)
  3. For convert: navigate back to dashboard (original workflow gone) or to the new workflow path

Step 6: OpenAPI Sync and Codegen

Final sync pass after all changes are stable:

  1. Python: cd /Users/jxc755/projects/repositories/gxwf-web && make docs-openapi
  2. Copy: cp docs/_static/openapi.json /Users/jxc755/projects/worktrees/galaxy-tool-util/branch/report_models/packages/gxwf-web/openapi.json
  3. Codegen: cd /Users/jxc755/projects/worktrees/galaxy-tool-util/branch/report_models && pnpm --filter @galaxy-tool-util/gxwf-web codegen
  4. Build: pnpm --filter @galaxy-tool-util/gxwf-web build
  5. Verify: types compile cleanly, UI builds, tests pass

Implementation Order

Step 1  (Python API)
  |
  v
Step 1e (generate openapi.json)
  |
  v
Step 2a (sync openapi to TS, codegen types)
  |
  +---> Step 2b-2e (TS server implementation)  --+
  |                                               |
  +---> Step 3 (schema types)                  --+
  |                                               |
  +---> Step 4 (report-shell components)       --+
                                                  |
                                                  v
                                            Step 5 (UI)
                                                  |
                                                  v
                                            Step 6 (final sync)

Steps 2-4 can proceed in parallel after Step 1e. Step 5 depends on all of 2-4. Step 6 is a final verification pass.


Testing Strategy

Python (gxwf-web)

TypeScript (gxwf-web)

UI (gxwf-ui)


File Inventory

Files to modify

Python (gxwf-web):

TypeScript (gxwf-web):

Report Shell:

UI (gxwf-ui):


Unresolved Questions

  1. Output path collision: If wf.gxwf.yml already exists when exporting wf.ga, overwrite silently or error? Leaning toward overwrite with a warning in the report.
  2. Clean serialization format: Clean currently returns JSON (json.dumps). For format2 workflows, should clean write back as YAML instead of JSON? The Python clean_single always returns JSON via after_content - this might need a format-aware serialization path.
  3. Subworkflow handling: Export/convert on workflows with external subworkflow references - should it also export/convert the subworkflows? Probably not in this pass, but worth noting.
  4. Checkpoint before mutate: Should clean/export/convert auto-create a checkpoint before writing? The Contents API has checkpoint support. Could be a nice safety net.
  5. Confirm dialog: Should convert (which deletes the original) require explicit confirmation in the UI? A simple “Are you sure?” dialog before the POST would prevent accidents.
  6. Export report model unification: The Python side has SingleExportReport (for to-format2) and ToNativeResult (for to-native) as separate types. The new ExportResult/ConvertResult wraps either. Should we unify the inner report into a single shape, or keep the union?