Defer UI codegen upgrade: @7nohe/openapi-react-query-codegen v1→v2 (+ ts-morph 28) needs a full data-layer rewrite
- Dominant language
- Python
- Stars
- 46.9k
- Forks
- 17.8k
- Avg merge
- 2d 9h
- Merged PRs (30d)
- 472
Description
### Background
The grouped edge-UI dependency bump in #70777 split out one item as follow-up work:
> `@7nohe/openapi-react-query-codegen 1 → 2 (+ ts-morph 28)`
This issue documents why that upgrade is **deferred** and captures the measured cost, so it isn't re-attempted as a routine version bump.
### Why v2 is a breaking change (not a bump)
`@7nohe/openapi-react-query-codegen` v2 delegates generation to `@hey-api/openapi-ts` and emits a fundamentally different client:
- **Call arguments are restructured**: flat camelCase → nested snake_case `{ path, query, body }`.
```ts
// v1
mutate({ dagId, requestBody: {…} })
useX({ limit, orderBy })
// v2
mutate({ path: { dag_id: dagId }, body: {…} })
useX({ query: { limit, order_by } })
```
- Function SDK instead of service classes (`AssetService.getAssets(...)` → `getAssets(...)`).
- Result shape becomes `{ data, error }`; `body` replaces `requestBody`.
- Mutation option placement (`onSuccess`/`onError`) changes.
- The hand-rolled `ApiError` / `OpenAPI` runtime is replaced by the `@hey-api/client-*` runtime.
### Measured migration cost
Prototyped locally: regenerated `openapi-gen/` with v2 + `@hey-api/client-axios`, then applied the mechanical symbol renames (hooks lose the `Service` infix, response types are re-cased, e.g. `useAssetServiceGetAssets`→`useGetAssets`, `DAGRunResponse`→`DagRunResponse`) — ~684 identifiers, verified against the generated exports.
After the renames, **~827 `tsc` errors remain across ~216 files**, now dominated by call-site argument restructuring:
- `TS2353` (unknown property in `Options<…>`): ~249
- `TS2345` (argument type): ~117
- `TS2322` (type mismatch): ~269
There are ~513 flat-argument call-site lines (48 files use `requestBody`). This part is **not scriptable** — each operation's `path`/`query`/`body` split and key-casing differ, and path params are typed `unknown`, so a wrong split is a runtime bug `tsc` won't catch. It is also **all-or-nothing**: the UI does not compile until every call site is migrated, so it cannot land incrementally.
### ts-morph 28 is coupled to v2
`ts-morph` is used only by the code generator (no direct imports in `airflow-core/src/airflow/ui/src`). v1 declares `ts-morph 22.x` as a peer and already runs on 27; it also runs cleanly on **28** (verified: deterministic output, `tsc` 0 errors, no consumer changes — only generated optional types gain an explicit `| undefined`/`| null`). But bumping ts-morph to 28 on v1 delivers **no functional benefit** — 28 is required only by v2. The two should therefore move together.
### Work required to complete (acceptance criteria)
- [ ] Regenerate `openapi-gen/` with `@7nohe` v2 + a `@hey-api/client-*` runtime; update the `codegen` script.
- [ ] Re-wire client config: base URL via `client.setConfig({ baseURL })`, path-param encoding, and the request/response interceptors onto `client.instance` (preserving the current 401/403 redirect + 403-URL-blocking behavior). The hand-rolled `fetch`/axios callers (`useGridTiSummaries`, `useHITLReviewTabs`) must keep working via `client.getConfig().baseURL`.
- [ ] Migrate all ~513 call sites to structured snake_case `{ path, query, body }` args, `.data` result handling, new mutation-option placement, and the v2 error type.
- [ ] Bump `ts-morph` to 28 as part of the same change.
- [ ] Green `tsc`, ESLint, Vitest, `vite build`, and a Playwright smoke pass.
### Notes for whoever picks this up
The client re-wire and the mechanical symbol-rename map are straightforward and were prototyped; the bulk of the effort is the per-call-site argument restructuring, which needs manual attention and review site by site.
Related: #70777
Contributor guide
Research direction
Start by reviewing the generated openapi-gen/ client, the codegen script, and consumers under airflow-core/src/airflow/ui/src; run tsc to establish the current baseline. Migrate the generated client, configuration and all listed call sites, then verify green tsc, ESLint, Vitest, vite build, and a Playwright smoke pass while preserving the stated redirect and URL-blocking behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- openapi, typescript
- Domain
- api, frontend
- Issue type
- Refactor
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 28/100