Skip to content

[Refactor/Chore] Migrate remaining custom console contract loaders #38232

Description

@hyoban

Self Checks

  • I have read the Contributing Guide and Language Policy.
  • This is only for refactors or chores; if you would like to ask a question, please head to Discussions.
  • I have searched for existing issues search for existing issues, including closed ones.
  • I confirm that I am using English to submit this report, otherwise it will be closed.
  • 【中文用户 & Non English User】请使用英语提交,否则会被关闭 :)
  • Please do not modify this template :) and fill in all the required fields.

Description

web/service/console-router-loader.ts still has a customConsoleContractLoaders map. It is not just a duplicate of @dify/contracts/api/console/orpc.gen.

The console client uses DynamicLink and loads the contract by the first path segment, such as consoleClient.snippets.* or consoleQuery.explore.*. The loader currently checks custom loaders first, then falls back to generated contractLoaders. This means a segment with a custom loader will never use the generated fallback until the custom entry is removed.

Current custom loader entries:

Segment Current role Migration path
enterprise Loads the generated enterprise contract from @dify/contracts/enterprise/orpc.gen. This is a separate generated namespace, not a handwritten console duplicate. Keep it unless enterprise contracts are merged into the generated console loader architecture. If we want a unified loader, compose enterprise generated loaders explicitly instead of treating this as a local contract cleanup.
explore Extends and overrides generated explore routes with frontend-friendly aliases and stronger domain types. It also groups routes that actually belong to generated installedApps and generated enterprise webAppAuth access-mode endpoints. Split migration by route group: move /explore/* callers to generated explore, move installed app callers to generated installedApps, move access-mode callers to generated enterprise.webAppAuth, and keep a service-level normalization boundary where frontend domain models differ from generated response types.
modelProviders Provides a compact top-level alias for /workspaces/current/model-providers/*. The generated routes exist under workspaces.current.modelProviders, not as a top-level modelProviders segment. Migrate consoleQuery.modelProviders.* and consoleClient.modelProviders.* callers to workspaces.current.modelProviders.*, or introduce a typed service wrapper. Update query keys, cache invalidation, and model provider tests together.
plugins Provides top-level aliases such as checkInstalled and latestVersions. Generated equivalents exist under workspaces.current.plugin. Map each alias to generated workspaces.current.plugin routes, verify response schemas are strong enough for plugin UI types, then update hooks/tests and remove the local aliases.
rbacAccessConfig Provides stable frontend names for app and dataset access-control operations. Generated equivalents are nested under workspaces.current.rbac with generated path-based naming and snake_case params. Create a route-by-route mapping for app/dataset access policy, user access policies, member binding removal, and whitelist updates. Update service hooks, query keys, and cache invalidation after confirming generated schemas match ResourceOpenScope and current access policy response models.
snippets Combines two generated areas behind one top-level segment: customized snippet CRUD/import/export/use-count routes under workspaces.current.customizedSnippets, and workflow/run routes under generated snippets.bySnippetId. It also exposes frontend-friendly names like list, detail, draftWorkflow, and publishWorkflow. Migrate in phases. First move customized snippet CRUD/import/export/use-count callers to workspaces.current.customizedSnippets. Then move workflow operations to generated snippets.bySnippetId.*. Update param names, query keys, and optimistic/cache behavior. Keep normalization where generated models are wider or weaker than current frontend domain models.
triggers Provides top-level aliases for trigger provider info, subscriptions, builders, verification, logs, OAuth config, and OAuth actions. Generated routes exist under workspaces.current.triggerProvider. Map each custom trigger alias to generated workspaces.current.triggerProvider routes. Migrate hooks one operation group at a time and update mutation keys, invalidation keys, and trigger UI tests.
trialApps Provides top-level aliases (info, datasets, parameters, workflows) and maps responses to existing frontend domain models. Generated routes exist under trialApps.byAppId.*. Migrate callers to generated nested trial app routes, or add a small normalization layer if the generated workflow/parameter/dataset shapes do not directly match TryAppInfo, TryAppFlowPreview, ChatConfig, or DataSetListResponse.

This issue tracks reducing those remaining custom loaders without breaking existing consoleClient / consoleQuery call sites, cache keys, or frontend domain model expectations.

Motivation

The frontend direction is to prefer generated contracts when their request and response schemas are accurate enough. Keeping custom console contracts forever increases maintenance cost and can hide backend OpenAPI/schema drift.

However, deleting customConsoleContractLoaders directly would be unsafe because several entries are not drop-in replacements for generated contracts:

  1. Some generated routes live under a different top-level segment, especially workspaces.current.*.
  2. Some custom contracts intentionally provide stable frontend names instead of generated path-shaped names.
  3. Some custom contracts combine multiple generated segments into one frontend segment.
  4. Some callers rely on query keys produced by the current custom segment names.
  5. Some frontend models are narrower or more ergonomic than generated API response types.

The intended migration strategy is:

  1. Pick one segment at a time.
  2. Build a route mapping from current custom aliases to generated routes.
  3. Confirm generated request and response schemas are accurate. Fix backend OpenAPI/schema definitions first when generated types are too weak.
  4. Move call sites to generated consoleClient / consoleQuery paths, or keep a small typed service normalization boundary when the UI needs stable domain models.
  5. Update query keys, invalidation logic, optimistic updates, and targeted tests in the same change.
  6. Add or update web/service/console-router-loader.spec.ts coverage to prove the migrated segment now loads through the generated fallback.
  7. Remove the local contract file, the web/contract/router.ts entry, and the corresponding customConsoleContractLoaders entry only after type-check and targeted tests pass.

Migration PRs

Segment PR Scope
plugins #38252 Migrate plugin console contract callers to generated workspaces.current.plugin routes.
modelProviders #38253 Migrate model provider callers to generated workspaces.current.modelProviders routes.
trialApps #38254 Migrate trial app callers to generated trialApps.byAppId routes and backend response schemas where generated types were inaccurate.
triggers #38255 Migrate trigger provider/subscription/OAuth hooks to generated workspaces.current.triggerProvider routes.
rbacAccessConfig #38256 Migrate access-control callers to generated workspaces.current.rbac routes.
snippets #38258 Migrate snippet CRUD/workflow callers to generated customized snippet and snippet workflow routes.
enterprise Not in scope Enterprise interfaces are intentionally left unchanged for this migration pass.

All migration PR branches include origin/main at c1d03a888fcd8fd393a0e5dd456db3a79d6a2a6d as of 2026-07-01.

Additional Context

Related cleanup already merged in #38231 for generated-ready segments: agent, apps, notification, tags, and workspaces.

Current files to audit:

  • web/service/console-router-loader.ts
  • web/service/console-link.ts
  • web/contract/router.ts
  • web/contract/console/explore.ts
  • web/contract/console/model-providers.ts
  • web/contract/console/plugins.ts
  • web/contract/console/access-control.ts
  • web/contract/console/snippets.ts
  • web/contract/console/trigger.ts
  • web/contract/console/try-app.ts
  • packages/contracts/generated/api/console/orpc.gen.ts
  • packages/contracts/generated/api/console/workspaces/orpc.gen.ts
  • packages/contracts/generated/api/console/installed-apps/orpc.gen.ts
  • packages/contracts/generated/api/console/snippets/orpc.gen.ts
  • packages/contracts/generated/api/console/trial-apps/orpc.gen.ts
  • packages/contracts/generated/enterprise/orpc.gen.ts

Suggested validation for each migrated segment:

  • pnpm --dir web type-check
  • targeted tests for changed services/hooks/components
  • pnpm --dir web test service/console-router-loader.spec.ts
  • search for stale custom aliases before deleting the local contract file

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions