Self Checks
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:
- Some generated routes live under a different top-level segment, especially
workspaces.current.*.
- Some custom contracts intentionally provide stable frontend names instead of generated path-shaped names.
- Some custom contracts combine multiple generated segments into one frontend segment.
- Some callers rely on query keys produced by the current custom segment names.
- Some frontend models are narrower or more ergonomic than generated API response types.
The intended migration strategy is:
- Pick one segment at a time.
- Build a route mapping from current custom aliases to generated routes.
- Confirm generated request and response schemas are accurate. Fix backend OpenAPI/schema definitions first when generated types are too weak.
- Move call sites to generated
consoleClient / consoleQuery paths, or keep a small typed service normalization boundary when the UI needs stable domain models.
- Update query keys, invalidation logic, optimistic updates, and targeted tests in the same change.
- Add or update
web/service/console-router-loader.spec.ts coverage to prove the migrated segment now loads through the generated fallback.
- 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
Self Checks
Description
web/service/console-router-loader.tsstill has acustomConsoleContractLoadersmap. It is not just a duplicate of@dify/contracts/api/console/orpc.gen.The console client uses
DynamicLinkand loads the contract by the first path segment, such asconsoleClient.snippets.*orconsoleQuery.explore.*. The loader currently checks custom loaders first, then falls back to generatedcontractLoaders. This means a segment with a custom loader will never use the generated fallback until the custom entry is removed.Current custom loader entries:
enterprise@dify/contracts/enterprise/orpc.gen. This is a separate generated namespace, not a handwritten console duplicate.exploreexploreroutes with frontend-friendly aliases and stronger domain types. It also groups routes that actually belong to generatedinstalledAppsand generated enterprisewebAppAuthaccess-mode endpoints./explore/*callers to generatedexplore, move installed app callers to generatedinstalledApps, move access-mode callers to generatedenterprise.webAppAuth, and keep a service-level normalization boundary where frontend domain models differ from generated response types.modelProviders/workspaces/current/model-providers/*. The generated routes exist underworkspaces.current.modelProviders, not as a top-levelmodelProviderssegment.consoleQuery.modelProviders.*andconsoleClient.modelProviders.*callers toworkspaces.current.modelProviders.*, or introduce a typed service wrapper. Update query keys, cache invalidation, and model provider tests together.pluginscheckInstalledandlatestVersions. Generated equivalents exist underworkspaces.current.plugin.workspaces.current.pluginroutes, verify response schemas are strong enough for plugin UI types, then update hooks/tests and remove the local aliases.rbacAccessConfigworkspaces.current.rbacwith generated path-based naming and snake_case params.ResourceOpenScopeand current access policy response models.snippetsworkspaces.current.customizedSnippets, and workflow/run routes under generatedsnippets.bySnippetId. It also exposes frontend-friendly names likelist,detail,draftWorkflow, andpublishWorkflow.workspaces.current.customizedSnippets. Then move workflow operations to generatedsnippets.bySnippetId.*. Update param names, query keys, and optimistic/cache behavior. Keep normalization where generated models are wider or weaker than current frontend domain models.triggersworkspaces.current.triggerProvider.workspaces.current.triggerProviderroutes. Migrate hooks one operation group at a time and update mutation keys, invalidation keys, and trigger UI tests.trialAppsinfo,datasets,parameters,workflows) and maps responses to existing frontend domain models. Generated routes exist undertrialApps.byAppId.*.TryAppInfo,TryAppFlowPreview,ChatConfig, orDataSetListResponse.This issue tracks reducing those remaining custom loaders without breaking existing
consoleClient/consoleQuerycall 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
customConsoleContractLoadersdirectly would be unsafe because several entries are not drop-in replacements for generated contracts:workspaces.current.*.The intended migration strategy is:
consoleClient/consoleQuerypaths, or keep a small typed service normalization boundary when the UI needs stable domain models.web/service/console-router-loader.spec.tscoverage to prove the migrated segment now loads through the generated fallback.web/contract/router.tsentry, and the correspondingcustomConsoleContractLoadersentry only after type-check and targeted tests pass.Migration PRs
pluginsworkspaces.current.pluginroutes.modelProvidersworkspaces.current.modelProvidersroutes.trialAppstrialApps.byAppIdroutes and backend response schemas where generated types were inaccurate.triggersworkspaces.current.triggerProviderroutes.rbacAccessConfigworkspaces.current.rbacroutes.snippetsenterpriseAll migration PR branches include
origin/mainatc1d03a888fcd8fd393a0e5dd456db3a79d6a2a6das of 2026-07-01.Additional Context
Related cleanup already merged in #38231 for generated-ready segments:
agent,apps,notification,tags, andworkspaces.Current files to audit:
web/service/console-router-loader.tsweb/service/console-link.tsweb/contract/router.tsweb/contract/console/explore.tsweb/contract/console/model-providers.tsweb/contract/console/plugins.tsweb/contract/console/access-control.tsweb/contract/console/snippets.tsweb/contract/console/trigger.tsweb/contract/console/try-app.tspackages/contracts/generated/api/console/orpc.gen.tspackages/contracts/generated/api/console/workspaces/orpc.gen.tspackages/contracts/generated/api/console/installed-apps/orpc.gen.tspackages/contracts/generated/api/console/snippets/orpc.gen.tspackages/contracts/generated/api/console/trial-apps/orpc.gen.tspackages/contracts/generated/enterprise/orpc.gen.tsSuggested validation for each migrated segment:
pnpm --dir web type-checkpnpm --dir web test service/console-router-loader.spec.ts