ToolJet/.github/instructions/appbuilder-review.instructions.md
Nakul Nagargade 433e1bd4c4
Enhance TypeScript support in frontend configuration (#15576)
* test: verify pre-commit hook

* fix: clean up code formatting and improve readability across multiple components

* chore: update subproject commit reference in frontend/ee

* chore: update eslint to version 9.26.0 and remove unused dependencies from package.json

fix: update submodule reference in server/ee

* chore: refactor ESLint configuration and add quiet linting script; update components to disable specific ESLint rules

* chore: add GitHub Copilot review instructions for App Builder team

Covers backward compatibility rules, styling conventions, state management,
resolution system, widget definitions, and common review flags.

* chore: add review instructions for App Builder, Data Migrations, Server Widget Config, Widget Components, and Widget Config

* Enhance TypeScript support in frontend configuration

- Added TypeScript parser and linting rules to ESLint configuration.
- Updated Babel configuration to include TypeScript preset.
- Modified package.json and package-lock.json to include TypeScript and related dependencies.
- Introduced tsconfig.json for TypeScript compiler options.
- Updated Webpack configuration to support .ts and .tsx file extensions.
- Adjusted linting and formatting scripts to include TypeScript files.

* chore: update TypeScript ESLint packages and subproject commits

---------

Co-authored-by: kavinvenkatachalam <kavin.saratha@gmail.com>
Co-authored-by: Johnson Cherian <johnsonc.dev@gmail.com>
2026-03-19 12:41:32 +05:30

2.8 KiB

applyTo excludeAgent
frontend/src/AppBuilder/**/* coding-agent

App Builder — Code Review Rules

Backward Compatibility (CRITICAL)

No change should break existing saved applications. When reviewing, always ask: "Would an app saved before this PR still load and behave correctly after it?"

Resolution System ({{}})

  • Flow: unresolved value → extractAndReplaceReferencesFromStringresolveDynamicValuesresolveCode (via new Function()) → resolved value stored in resolvedSlice.
  • {{...}} references MUST be registered in the dependency graph via addReferencesForDependencyGraph. Missing this causes stale renders.
  • After setExposedValue, updateDependencyValues MUST be called to propagate changes.
  • Inside ListView/Kanban, customResolvables provide row-scoped context (listItem / cardData).

Rendering Pipeline

AppCanvas → Container → WidgetWrapper → RenderWidget → Widget

  • Widgets receive resolved props from RenderWidget. They must NOT directly access store state.
  • setExposedVariable and fireEvent are passed as callbacks — widgets use these to communicate outward.

Subcontainer Architecture

  • SubcontainerContext carries contextPath array: [{ containerId, index }, ...].
  • Row-scoped resolution uses prototype overlay (prepareRowScope/updateRowScope).
  • Child-to-parent: setExposedValuesPerRow_deriveListviewChain (no callback chains).
  • ListView nesting limited to 2 levels. Only row 0 is editable; others are read-only mirrors.
  • findNearestSubcontainerAncestor is critical for dependency resolution — verify it's used when walking the component tree.
  • Keywords: listItem (ListView), cardData (Kanban). Don't mix them up.

Event & Query Systems

  • Events: fireEvent → handleEvent → executeActionsForEventId → executeAction. Events support runOnlyIf and debounce.
  • Queries: runQuery → resolve options → API call → update exposedValues.queries[name] → trigger dependency updates.
  • Event definitions live in eventsSlice, not in component definitions.

Bundle & Performance

  • Viewer (/applications/*) and editor are separate lazy bundles via RootRouter.jsx. Do not import editor-only code into viewer paths.
  • Avoid JSON.parse(JSON.stringify(...)) or _.cloneDeep in render/hot paths. Use Immer.
  • Flag O(N) loops inside already-O(N) resolution paths (eager resolution for ListView children).

State Management

  • Global stores (appDataStore, currentStateStore, dataQueriesStore, resolverStore) should NOT be used in AppBuilder code unless absolutely critical. Prefer the AppBuilder store. Flag any new usage.
  • AppBuilder store: AppBuilder/_stores/store.js (30+ slices). All slices are namespaced by moduleId (default: 'canvas').

Security

  • resolveCode uses new Function() — be cautious about evaluated expressions.