Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Frontend code review guidance from the Dify LLM application development platform repository.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/data-query-contracts.md
1# Data, Query, And Contract Rules23Use these rules for generated contracts, TanStack Query, mutations, auth/SSR boundaries, URL state, and client persistence.45## Generated Contracts67Flag:89- New legacy service/helper wrappers around generated `queryOptions()` or `mutationOptions()`.10- Continuing to use deprecated contract operations when a ready generated contract exists.11- Assuming a generated file means an operation is ready without checking deprecated markers, schema shape, and the actual UI consumer.12- Re-declaring API DTOs in components.13- Adding compatibility layers instead of migrating the pointed line and deleting the old layer.1415Use `web/contract/*` as the API shape source of truth. Follow existing `{ params, query?, body? }` input shape.1617## Queries1819Flag:2021- `enabled` used to hide missing required input instead of `input: skipToken`.22- Fake fallback IDs or placeholder inputs used to force a query to run.23- Query results copied into local state for rendering.24- Shared query behavior such as invalidation, stale defaults, or retry rules reimplemented at call sites.25- `prefetchQuery` treated as a hard gate or as returning data/errors to the caller.2627Use `useQuery(consoleQuery.xxx.queryOptions(...))` or `useQuery(marketplaceQuery.xxx.queryOptions(...))` directly unless a feature hook performs real orchestration.2829## Mutations3031Flag:3233- Deprecated `useInvalid` or `useReset`.34- `mutateAsync` used without a need for Promise semantics.35- Awaited mutations without `try/catch`.36- Components owning shared cache invalidation that belongs in query defaults.37- Optimistic updates that do not match current list/detail ownership.3839Use generated `mutationOptions()` directly when possible. Put shared cache behavior in `createTanstackQueryUtils(...experimental_defaults...)`.4041## SSR, Auth, And Route Boundaries4243Flag:4445- Request-time auth, setup, workspace role, or tenant decisions moved into static `next.config redirects()`.46- Dynamic role gates depending on `workspaces.current` implemented as static path redirects.47- Authorization logic depending on soft `prefetchQuery`.48- Removing a client fallback before server API unavailable behavior is defined.49- Global placeholder query contracts introduced to solve a route-local Suspense issue.50- Branding-sensitive UI reading placeholder defaults without checking pending/placeholder state.5152Separate hard gates from soft prefetches. `fetchQuery` can be a server decision boundary; `prefetchQuery` is cache warmup.5354## Workspace And Tenant5556Flag:5758- Treating workspace switch as ordinary CRUD invalidation when the current app flow performs server switch plus full reload.59- Query keys that omit workspace/tenant identity when the query truly varies by workspace and no full reload boundary applies.60- Mixing `workspace_id` and `tenant_id` without tracing the current backend/API contract.6162Current Dify workspace switch should be reviewed as a tenant cache boundary first.6364## URL State And Local Storage6566Flag:6768- Shareable filters, tabs, pagination, selected panels, or search state hidden only in component state.69- One-shot navigation signals modeled as subscribed persistent state.70- Live app state stored in localStorage.71- Direct `window.localStorage`, `globalThis.localStorage`, or raw storage calls in app code.72- High-frequency interaction state persisted on every change instead of on commit/settle.7374Use URL state for shareable UI state, feature/Jotai/store state for live UI state, and `@/hooks/use-local-storage` only for low-frequency client-only preferences, dismissed notices, and UI defaults.75