diff --git a/.cursor/README.md b/.cursor/README.md
index 4cedaba667..deabe8cf24 100644
--- a/.cursor/README.md
+++ b/.cursor/README.md
@@ -1,6 +1,39 @@
-# Cursor Rules
+# Appsmith Cursor Configuration
-This directory contains configuration for cursor-specific rules and behaviors.
+This directory contains configuration for Cursor AI tools, rules, and guidelines for the Appsmith project.
+
+## Directory Structure
+
+```
+.cursor/
+├── settings.json # Main configuration file
+├── docs/ # Documentation
+│ ├── guides/ # In-depth guides
+│ ├── references/ # Quick references
+│ └── practices/ # Best practices
+├── rules/ # Rule definitions
+│ ├── commit/ # Commit-related rules
+│ ├── quality/ # Code quality rules
+│ ├── testing/ # Testing rules
+│ └── verification/ # Verification rules
+└── hooks/ # Git hooks and scripts
+```
+
+## Key Features
+
+- **Commit Message Rules**: Guidelines for structured, informative commit messages
+- **Code Quality Checks**: Automated validation of code quality standards
+- **Testing Requirements**: Rules for test coverage and quality
+- **Performance Guidelines**: Best practices for maintaining high performance
+- **Documentation**: Comprehensive guides and references for the codebase
+
+## Usage
+
+- Use the rules in this directory to ensure consistent quality across the project
+- Reference the documentation for best practices and technical details
+- Hooks automate common tasks and enforce quality standards
+
+For more information, see the specific README files in each subdirectory.
## Commit Message Rules
diff --git a/.cursor/docs/README.md b/.cursor/docs/README.md
new file mode 100644
index 0000000000..01f6958d6e
--- /dev/null
+++ b/.cursor/docs/README.md
@@ -0,0 +1,27 @@
+# Appsmith Documentation
+
+This directory contains comprehensive documentation for the Appsmith project, organized by type and purpose.
+
+## Structure
+
+- **guides/**: Detailed, in-depth guides on specific topics
+ - `performance.md`: Performance optimization best practices
+ - `testing.md`: Comprehensive guide to testing in Appsmith
+ - `verification.md`: Workflow for verifying changes
+
+- **references/**: Quick reference documents for daily use
+ - `codebase-map.md`: Overview of the codebase structure
+ - `testing-reference.md`: Quick testing reference
+ - `technical-details.md`: Technical specifications and architecture
+
+- **practices/**: Best practices for development
+ - `react-hooks.md`: Best practices for using React hooks
+
+## Using This Documentation
+
+- **New developers**: Start with the codebase map and technical details
+- **Feature development**: Reference the testing guide and feature verification workflows
+- **Bug fixing**: Consult the verification workflow and bug fix verification guidelines
+- **Performance optimization**: Follow the performance optimization guide
+
+The documentation is designed to be comprehensive but approachable. If you need more specific information, check the individual files in each directory.
\ No newline at end of file
diff --git a/.cursor/docs/guides/performance.md b/.cursor/docs/guides/performance.md
new file mode 100644
index 0000000000..c21f0ef6e7
--- /dev/null
+++ b/.cursor/docs/guides/performance.md
@@ -0,0 +1,353 @@
+# Appsmith Performance Optimization Guide
+
+This guide outlines approaches for identifying, analyzing, and resolving performance issues in the Appsmith codebase.
+
+## Identifying Performance Issues
+
+### Frontend Performance Metrics
+
+1. **Page Load Time**
+ - Initial page load
+ - Time to first paint
+ - Time to interactive
+
+2. **Rendering Performance**
+ - Component render times
+ - React render cycles
+ - Frame rate (FPS)
+
+3. **Network Performance**
+ - API request latency
+ - Payload sizes
+ - Number of requests
+
+4. **Memory Usage**
+ - Heap snapshots
+ - Memory leaks
+ - DOM node count
+
+### Backend Performance Metrics
+
+1. **Response Times**
+ - API endpoint latency
+ - Database query performance
+ - Worker thread utilization
+
+2. **Resource Utilization**
+ - CPU usage
+ - Memory consumption
+ - I/O operations
+
+3. **Database Performance**
+ - Query execution time
+ - Index utilization
+ - Connection pool efficiency
+
+4. **Concurrency**
+ - Request throughput
+ - Thread pool utilization
+ - Blocking operations
+
+## Performance Analysis Tools
+
+### Frontend Tools
+
+1. **Browser DevTools**
+ - Performance tab
+ - Network tab
+ - Memory tab
+
+2. **React DevTools**
+ - Component profiler
+ - Highlight updates
+
+3. **Lighthouse**
+ - Performance audits
+ - Optimization suggestions
+
+4. **Custom Timing**
+ ```javascript
+ // Performance measurement
+ performance.mark('start');
+ // ...code to measure...
+ performance.mark('end');
+ performance.measure('operation', 'start', 'end');
+ console.log(performance.getEntriesByName('operation')[0].duration);
+ ```
+
+### Backend Tools
+
+1. **Profilers**
+ - JProfiler
+ - VisualVM
+ - YourKit
+
+2. **Logging and Metrics**
+ - Log execution times
+ - Prometheus metrics
+ - Grafana dashboards
+
+3. **Load Testing**
+ - JMeter
+ - K6
+ - Artillery
+
+## Common Performance Issues and Solutions
+
+### Frontend Performance Issues
+
+1. **Unnecessary Re-renders**
+
+ Issue:
+ ```jsx
+ function Component() {
+ // This creates a new object on every render
+ const options = { value: 'example' };
+ return ;
+ }
+ ```
+
+ Solution:
+ ```jsx
+ function Component() {
+ // Memoize object
+ const options = useMemo(() => ({ value: 'example' }), []);
+ return ;
+ }
+ ```
+
+2. **Unoptimized List Rendering**
+
+ Issue:
+ ```jsx
+ function ItemList({ items }) {
+ return (
+
+ {items.map(item => (
+
+ ))}
+
+ );
+ }
+ ```
+
+ Solution:
+ ```jsx
+ function ItemList({ items }) {
+ return (
+
+ {items.map(item => (
+
+ ))}
+
+ );
+ }
+
+ // Memoize the Item component
+ const Item = React.memo(function Item({ data }) {
+ return {data.name}
;
+ });
+ ```
+
+3. **Large Bundle Size**
+
+ Issue:
+ - Importing entire libraries
+ - Not code-splitting
+
+ Solution:
+ ```javascript
+ // Before
+ import { map, filter, reduce } from 'lodash';
+
+ // After
+ import map from 'lodash/map';
+ import filter from 'lodash/filter';
+ import reduce from 'lodash/reduce';
+
+ // Code splitting with React.lazy
+ const HeavyComponent = React.lazy(() => import('./HeavyComponent'));
+ ```
+
+4. **Memory Leaks**
+
+ Issue:
+ ```jsx
+ function Component() {
+ useEffect(() => {
+ const interval = setInterval(() => {
+ // Do something
+ }, 1000);
+ // No cleanup
+ }, []);
+
+ return Component
;
+ }
+ ```
+
+ Solution:
+ ```jsx
+ function Component() {
+ useEffect(() => {
+ const interval = setInterval(() => {
+ // Do something
+ }, 1000);
+
+ // Cleanup
+ return () => clearInterval(interval);
+ }, []);
+
+ return Component
;
+ }
+ ```
+
+### Backend Performance Issues
+
+1. **N+1 Query Problem**
+
+ Issue:
+ ```java
+ List workspaces = workspaceRepository.findAll().collectList().block();
+ for (Workspace workspace : workspaces) {
+ List apps = applicationRepository.findByWorkspaceId(workspace.getId()).collectList().block();
+ workspace.setApplications(apps);
+ }
+ ```
+
+ Solution:
+ ```java
+ // Use join query or batch loading
+ List workspaces = workspaceRepository.findAllWithApplications().collectList().block();
+ ```
+
+2. **Missing Database Indexes**
+
+ Issue:
+ ```java
+ // Query without proper index
+ Mono findByEmail(String email);
+ ```
+
+ Solution:
+ ```java
+ // Add index to database
+ @Document(collection = "users")
+ public class User {
+ @Indexed(unique = true)
+ private String email;
+ // ...
+ }
+ ```
+
+3. **Blocking Operations in Reactive Streams**
+
+ Issue:
+ ```java
+ return Mono.fromCallable(() -> {
+ // Blocking file I/O operation
+ return Files.readAllBytes(Paths.get("path/to/file"));
+ });
+ ```
+
+ Solution:
+ ```java
+ return Mono.fromCallable(() -> {
+ // Blocking file I/O operation
+ return Files.readAllBytes(Paths.get("path/to/file"));
+ }).subscribeOn(Schedulers.boundedElastic());
+ ```
+
+4. **Inefficient Data Processing**
+
+ Issue:
+ ```java
+ // Processing large amounts of data in memory
+ return repository.findAll()
+ .collectList()
+ .map(items -> {
+ // Process all items at once
+ return items.stream().map(this::transform).collect(Collectors.toList());
+ });
+ ```
+
+ Solution:
+ ```java
+ // Stream processing with backpressure
+ return repository.findAll()
+ .map(this::transform)
+ .collectList();
+ ```
+
+## Performance Optimization Workflow
+
+### Step 1: Establish Baselines
+
+1. Identify key metrics to track
+2. Measure current performance
+3. Set performance goals
+
+### Step 2: Identify Bottlenecks
+
+1. Use profiling tools
+2. Analyze critical user paths
+3. Focus on high-impact areas
+
+### Step 3: Optimize
+
+1. Make one change at a time
+2. Measure impact of each change
+3. Document optimizations
+
+### Step 4: Verify
+
+1. Compare to baseline metrics
+2. Run performance tests
+3. Check for regressions
+
+### Step 5: Monitor
+
+1. Set up continuous performance monitoring
+2. Track trends over time
+3. Set up alerts for degradations
+
+## Performance Testing Best Practices
+
+1. **Test with realistic data volumes**
+2. **Simulate actual user behavior**
+3. **Test on hardware similar to production**
+4. **Include performance tests in CI/CD pipeline**
+5. **Test in isolation and under load**
+6. **Focus on critical user journeys**
+7. **Set clear performance budgets**
+8. **Compare results to previous baselines**
+
+## Performance Optimization Checklist
+
+### Frontend Checklist
+
+- [ ] Use React.memo for expensive components
+- [ ] Implement proper keys for list items
+- [ ] Memoize callbacks with useCallback
+- [ ] Memoize computed values with useMemo
+- [ ] Code-split large bundles
+- [ ] Lazy load components and routes
+- [ ] Optimize images and assets
+- [ ] Minimize CSS and JS bundle sizes
+- [ ] Use virtualization for large lists
+- [ ] Implement proper cleanup in useEffect
+- [ ] Avoid prop drilling with Context API
+- [ ] Optimize Redux selectors
+
+### Backend Checklist
+
+- [ ] Add appropriate database indexes
+- [ ] Use pagination for large result sets
+- [ ] Optimize database queries
+- [ ] Avoid N+1 query problem
+- [ ] Use reactive programming correctly
+- [ ] Handle blocking operations properly
+- [ ] Implement caching where appropriate
+- [ ] Optimize serialization/deserialization
+- [ ] Use connection pooling
+- [ ] Configure thread pools appropriately
+- [ ] Monitor and optimize GC behavior
\ No newline at end of file
diff --git a/.cursor/docs/guides/testing.md b/.cursor/docs/guides/testing.md
new file mode 100644
index 0000000000..6bad530576
--- /dev/null
+++ b/.cursor/docs/guides/testing.md
@@ -0,0 +1,513 @@
+# Appsmith Testing Guide
+
+This guide outlines best practices for writing tests for the Appsmith codebase.
+
+## Frontend Testing
+
+### Unit Tests with Jest
+
+Appsmith uses Jest for frontend unit tests. Unit tests should be written for individual components, utility functions, and Redux slices.
+
+#### Test File Structure
+
+Create test files with the `.test.ts` or `.test.tsx` extension in the same directory as the source file:
+
+```
+src/
+ components/
+ Button/
+ Button.tsx
+ Button.test.tsx
+ utils/
+ helpers.ts
+ helpers.test.ts
+```
+
+#### Writing React Component Tests
+
+```typescript
+import React from "react";
+import { render, screen, fireEvent } from "@testing-library/react";
+import Button from "./Button";
+
+describe("Button component", () => {
+ it("renders correctly with default props", () => {
+ render();
+ expect(screen.getByText("Click me")).toBeInTheDocument();
+ });
+
+ it("calls onClick handler when clicked", () => {
+ const handleClick = jest.fn();
+ render();
+
+ fireEvent.click(screen.getByText("Click me"));
+ expect(handleClick).toHaveBeenCalledTimes(1);
+ });
+});
+```
+
+#### Redux Testing
+
+```typescript
+import { configureStore } from "@reduxjs/toolkit";
+import reducer, {
+ setUserInfo,
+ fetchUserInfo
+} from "./userSlice";
+
+describe("User reducer", () => {
+ it("should handle initial state", () => {
+ expect(reducer(undefined, { type: "unknown" })).toEqual({
+ userInfo: null,
+ isLoading: false,
+ error: null
+ });
+ });
+
+ it("should handle setUserInfo", () => {
+ const userInfo = { name: "Test User", email: "test@example.com" };
+ expect(
+ reducer(
+ { userInfo: null, isLoading: false, error: null },
+ setUserInfo(userInfo)
+ )
+ ).toEqual({
+ userInfo,
+ isLoading: false,
+ error: null
+ });
+ });
+});
+```
+
+### Testing Redux/React Safety Patterns
+
+Safety when accessing deeply nested properties in Redux state is critical for application reliability. Here are patterns for testing these safety mechanisms:
+
+#### Testing Redux Selectors with Incomplete State
+
+```typescript
+import { configureStore } from '@reduxjs/toolkit';
+import reducer, { selectNestedData } from './dataSlice';
+import { renderHook } from '@testing-library/react-hooks';
+import { Provider } from 'react-redux';
+import { useSelector } from 'react-redux';
+
+describe("selectNestedData", () => {
+ it("returns default value when state is incomplete", () => {
+ // Set up store with incomplete state
+ const store = configureStore({
+ reducer: {
+ data: reducer,
+ },
+ preloadedState: {
+ data: {
+ // Missing expected nested properties
+ },
+ },
+ });
+
+ // Wrap the hook with the Redux provider
+ const wrapper = ({ children }) => (
+ {children}
+ );
+
+ // Render the hook with the selector
+ const { result } = renderHook(() => useSelector(selectNestedData), { wrapper });
+
+ // Verify the selector returns the fallback/default value
+ expect(result.current).toEqual(/* expected default value */);
+ });
+
+ it("returns actual data when state is complete", () => {
+ // Set up store with complete state
+ const expectedData = { value: "test" };
+ const store = configureStore({
+ reducer: {
+ data: reducer,
+ },
+ preloadedState: {
+ data: {
+ entities: {
+ items: {
+ 123: {
+ details: expectedData,
+ },
+ },
+ },
+ },
+ },
+ });
+
+ const wrapper = ({ children }) => (
+ {children}
+ );
+
+ const { result } = renderHook(() => useSelector(state =>
+ selectNestedData(state, '123')
+ ), { wrapper });
+
+ // Verify the selector returns the actual data
+ expect(result.current).toEqual(expectedData);
+ });
+});
+```
+
+#### Testing Components with Error Boundaries
+
+```typescript
+import React from 'react';
+import { render, screen } from '@testing-library/react';
+import { ErrorBoundary } from 'react-error-boundary';
+import ComponentWithDeepAccess from './ComponentWithDeepAccess';
+
+describe('ComponentWithDeepAccess with error boundary', () => {
+ it('renders fallback UI when data is invalid', () => {
+ // Define invalid data that would cause property access errors
+ const invalidData = {
+ // Missing required nested structure
+ };
+
+ const FallbackComponent = () => Error occurred
;
+
+ render(
+
+
+
+ );
+
+ // Verify the fallback component is rendered
+ expect(screen.getByText('Error occurred')).toBeInTheDocument();
+ });
+
+ it('renders normally with valid data', () => {
+ // Define valid data with complete structure
+ const validData = {
+ user: {
+ profile: {
+ name: 'Test User'
+ }
+ }
+ };
+
+ const FallbackComponent = () => Error occurred
;
+
+ render(
+
+
+
+ );
+
+ // Verify the component renders normally
+ expect(screen.getByText('Test User')).toBeInTheDocument();
+ });
+});
+```
+
+#### Testing Safe Property Access Utilities
+
+```typescript
+import { safeGet } from './propertyAccessUtils';
+
+describe('safeGet utility', () => {
+ it('returns the value when the path exists', () => {
+ const obj = {
+ a: {
+ b: {
+ c: 'value'
+ }
+ }
+ };
+
+ expect(safeGet(obj, 'a.b.c')).toBe('value');
+ });
+
+ it('returns default value when path does not exist', () => {
+ const obj = {
+ a: {}
+ };
+
+ expect(safeGet(obj, 'a.b.c', 'default')).toBe('default');
+ });
+
+ it('handles array indices in path', () => {
+ const obj = {
+ users: [
+ { id: 1, name: 'User 1' },
+ { id: 2, name: 'User 2' }
+ ]
+ };
+
+ expect(safeGet(obj, 'users.1.name')).toBe('User 2');
+ });
+
+ it('handles null and undefined input', () => {
+ expect(safeGet(null, 'a.b.c', 'default')).toBe('default');
+ expect(safeGet(undefined, 'a.b.c', 'default')).toBe('default');
+ });
+});
+```
+
+### Integration Tests with Cypress
+
+Cypress is used for integration and end-to-end testing. These tests should verify the functionality of the application from a user's perspective.
+
+#### Test File Structure
+
+```
+cypress/
+ integration/
+ Editor/
+ Canvas.spec.ts
+ PropertyPane.spec.ts
+ Workspace/
+ Applications.spec.ts
+```
+
+#### Writing Cypress Tests
+
+```typescript
+describe("Application Canvas", () => {
+ before(() => {
+ cy.visit("/applications/my-app/pages/page-1/edit");
+ });
+
+ it("should allow adding a widget to the canvas", () => {
+ cy.get("[data-cy=entity-explorer]").should("be.visible");
+ cy.get("[data-cy=widget-button]").drag("[data-cy=canvas-drop-zone]");
+ cy.get("[data-cy=widget-card-button]").should("exist");
+ });
+
+ it("should open property pane when widget is selected", () => {
+ cy.get("[data-cy=widget-card-button]").click();
+ cy.get("[data-cy=property-pane]").should("be.visible");
+ cy.get("[data-cy=property-pane-title]").should("contain", "Button");
+ });
+});
+```
+
+## Backend Testing
+
+### Unit Tests with JUnit
+
+Backend unit tests should validate individual components and services.
+
+#### Test File Structure
+
+```
+src/test/java/com/appsmith/server/
+ services/
+ ApplicationServiceTest.java
+ UserServiceTest.java
+ controllers/
+ ApplicationControllerTest.java
+```
+
+#### Writing Java Unit Tests
+
+```java
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class ApplicationServiceTest {
+
+ @Autowired
+ private ApplicationService applicationService;
+
+ @MockBean
+ private WorkspaceService workspaceService;
+
+ @Test
+ public void testCreateApplication() {
+ // Arrange
+ Application application = new Application();
+ application.setName("Test Application");
+
+ Workspace workspace = new Workspace();
+ workspace.setId("workspace-id");
+
+ Mono workspaceMono = Mono.just(workspace);
+ when(workspaceService.findById(any())).thenReturn(workspaceMono);
+
+ // Act
+ Mono result = applicationService.createApplication(application, "workspace-id");
+
+ // Assert
+ StepVerifier.create(result)
+ .assertNext(app -> {
+ assertThat(app.getId()).isNotNull();
+ assertThat(app.getName()).isEqualTo("Test Application");
+ assertThat(app.getWorkspaceId()).isEqualTo("workspace-id");
+ })
+ .verifyComplete();
+ }
+}
+```
+
+### Integration Tests
+
+Backend integration tests should verify interactions between different components of the system.
+
+```java
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+public class ApplicationControllerIntegrationTest {
+
+ @Autowired
+ private WebTestClient webTestClient;
+
+ @Autowired
+ private ApplicationRepository applicationRepository;
+
+ @Before
+ public void setUp() {
+ applicationRepository.deleteAll().block();
+ }
+
+ @Test
+ public void testGetAllApplications() {
+ // Test implementation
+ }
+}
+```
+
+## Best Practices
+
+### General Test Guidelines
+
+1. **Test Isolation**: Each test should be independent of others.
+2. **Test Coverage**: Aim for 80%+ coverage for critical code paths.
+3. **Avoid Implementation Details**: Test behavior, not implementation.
+4. **Concise Tests**: Keep tests focused on one behavior or functionality.
+5. **Descriptive Names**: Use clear test names that describe what is being tested.
+
+### Redux/React Safety Best Practices
+
+1. **Always Check Property Existence**: Test edge cases where properties might not exist.
+2. **Use Defensive Programming**: Design components and selectors to handle incomplete data gracefully.
+3. **Test Error Boundaries**: Verify that error boundaries correctly catch and handle errors from property access.
+4. **Test Default Values**: Ensure selectors return appropriate defaults when data is missing.
+5. **Test Different State Permutations**: Create tests with various combinations of missing or incomplete state to ensure robustness.
+
+### Performance Considerations
+
+1. **Mock Heavy Dependencies**: Use mocks for API calls, databases, etc.
+2. **Optimize Test Speed**: Keep tests fast to encourage frequent testing.
+3. **Use Focused Tests**: Test only what needs to be tested.
+
+## Troubleshooting Tests
+
+### Common Issues
+
+1. **Flaky Tests**: Tests that sometimes pass and sometimes fail.
+ - Solution: Make tests more deterministic, avoid race conditions.
+
+2. **Memory Leaks**: Tests that consume increasing memory.
+ - Solution: Clean up resources, avoid global state.
+
+3. **Slow Tests**: Tests that take too long to run.
+ - Solution: Mock heavy dependencies, parallelize when possible.
+
+### React-Specific Issues
+
+1. **Component State Issues**: Components not updating as expected.
+ - Solution: Use `act()` for state updates, wait for async operations.
+
+2. **Redux State Access Errors**: Errors when accessing nested properties.
+ - Solution: Use optional chaining, lodash/get, or default values in selectors.
+
+3. **Rendering Errors**: Components not rendering as expected.
+ - Solution: Verify props, check for conditionals that might prevent rendering.
+
+## Advanced Testing Techniques
+
+### Property-Based Testing
+
+Test with a wide range of automatically generated inputs to find edge cases.
+
+### Snapshot Testing
+
+Useful for detecting unintended changes in UI components.
+
+### Visual Regression Testing
+
+Compare screenshots of components to detect visual changes.
+
+### Load and Performance Testing
+
+Test system behavior under high load or stress conditions.
+
+### A/B Testing
+
+Compare different implementations to determine which performs better.
+
+## Test Data Best Practices
+
+### Creating Test Fixtures
+
+- Create reusable fixtures for common test data
+- Use descriptive names for test fixtures
+- Keep test data minimal but sufficient
+
+### Mocking External Services
+
+- Mock external API calls and dependencies
+- Use realistic mock responses
+- Consider edge cases and error conditions
+
+## Testing Standards
+
+### Frontend Testing Standards
+
+1. Aim for 80%+ test coverage for utility functions
+2. Test all Redux slices thoroughly
+3. Focus on critical user journeys in integration tests
+4. Test responsive behavior for key components
+5. Include accessibility tests for UI components
+
+### Backend Testing Standards
+
+1. Test all public service methods
+2. Test both successful and error cases
+3. Test database interactions with real repositories
+4. Test API endpoints with WebTestClient
+5. Mock external services to isolate tests
+
+## Running Tests
+
+### Frontend Tests
+
+```bash
+# Run all Jest tests
+cd app/client
+yarn run test:unit
+
+# Run a specific test file
+yarn jest src/path/to/test.ts
+
+# Run Cypress tests
+npx cypress run
+```
+
+### Backend Tests
+
+```bash
+# Run all backend tests
+cd app/server
+./mvnw test
+
+# Run a specific test class
+./mvnw test -Dtest=ApplicationServiceTest
+```
+
+## Best Practices for Test-Driven Development
+
+1. Write failing tests first
+2. Start with simple test cases
+3. Refactor after tests pass
+4. Use descriptive test names
+5. Keep tests independent
+6. Avoid test interdependence
+7. Test edge cases and error conditions
+8. Keep tests fast
+9. Avoid testing implementation details
+10. Review and update tests when requirements change
\ No newline at end of file
diff --git a/.cursor/docs/guides/verification.md b/.cursor/docs/guides/verification.md
new file mode 100644
index 0000000000..f339a04afd
--- /dev/null
+++ b/.cursor/docs/guides/verification.md
@@ -0,0 +1,180 @@
+# Appsmith Verification Workflow
+
+This document outlines the process that Cursor should follow when verifying changes to the Appsmith codebase.
+
+## Bug Fix Verification
+
+When fixing a bug, follow these steps:
+
+1. **Reproduce the issue**
+ - Understand the reported bug and its root cause
+ - Create a minimal reproduction of the issue
+ - Identify the components affected
+
+2. **Write test(s) for the bug**
+ - Create failing tests that demonstrate the bug's existence
+ - For frontend bugs: write Jest unit tests and/or Cypress integration tests
+ - For backend bugs: write JUnit tests
+
+3. **Implement the fix**
+ - Make minimal, targeted changes to address the root cause
+ - Ensure the tests now pass
+ - Check for any unintended side effects
+
+4. **Verify the fix**
+ - Confirm the original issue is resolved
+ - Run the full test suite to ensure no regressions
+ - Check both development and production builds
+
+5. **Quality checks**
+ - Run type checking: `yarn run check-types`
+ - Run linting: `yarn run lint`
+ - Check for cyclic dependencies in client code
+ - For backend: run Spotless checks
+ - Verify Redux/React safety guidelines:
+ - Use optional chaining (`?.`) or lodash/get for deep property access
+ - Check for null/undefined before accessing nested properties
+ - Avoid direct deep property chains (e.g., `obj.prop1.prop2.prop3`)
+ - Handle potential nulls in Redux state access
+
+6. **Performance verification**
+ - Ensure the fix doesn't negatively impact performance
+ - Check for memory leaks or increased resource usage
+ - Verify response times aren't degraded
+
+7. **CI/CD verification**
+ - Ensure all GitHub workflow checks would pass with the changes
+ - Verify both client and server builds
+
+## Feature Implementation Verification
+
+When implementing a new feature, follow these steps:
+
+1. **Understand requirements**
+ - Clearly define the feature's acceptance criteria
+ - Identify all components that need to be modified
+
+2. **Design test approach**
+ - Plan unit, integration, and end-to-end tests before implementation
+ - Create test scenarios that cover the feature's functionality
+ - Consider edge cases and error handling
+
+3. **Implement test cases**
+ - Write tests for new functionality
+ - Include positive and negative test cases
+ - Cover edge cases and error conditions
+
+4. **Implement the feature**
+ - Develop the feature to pass the tests
+ - Follow code style and patterns established in the project
+ - Document the new functionality as needed
+
+5. **Verify against acceptance criteria**
+ - Confirm the feature meets all acceptance criteria
+ - Perform manual testing for user experience
+ - Get stakeholder sign-off if applicable
+
+6. **Quality checks**
+ - Same checks as for bug fixes
+ - Additional check for documentation updates if needed
+ - Verify UI/UX consistency
+
+7. **Performance testing**
+ - Check performance implications of the new feature
+ - Ensure the feature is optimized for efficiency
+ - Test under different load conditions if applicable
+
+8. **CI/CD verification**
+ - Same checks as for bug fixes
+ - Additional check for new assets or dependencies
+
+## Incrementally Learning From Changes
+
+For each code change, Cursor should:
+
+1. Analyze patterns in successful implementations
+2. Record common pitfalls and how they were resolved
+3. Update its understanding of the codebase structure
+4. Note the relationships between components
+5. Learn from test cases how different modules should interact
+6. Understand the project's coding standards and conventions
+7. Track performance considerations for different features
+8. Maintain a knowledge graph of the codebase to provide better context
+
+## Pre-commit Verification Checklist
+
+Before considering a change complete, verify:
+
+- [ ] All tests pass locally
+- [ ] No linting issues reported
+- [ ] Type checking passes
+- [ ] No performance degradation
+- [ ] Code follows project conventions
+- [ ] Documentation is updated if needed
+- [ ] No sensitive data is included
+- [ ] The change satisfies the original requirements
+- [ ] GitHub workflows would pass if the changes were committed
+- [ ] React/Redux code follows safety best practices
+ - [ ] Uses optional chaining or lodash/get for nested properties
+ - [ ] Handles potential null values in state access
+ - [ ] No direct deep object chaining without safety checks
+ - [ ] Redux selectors properly handle state structure changes
+
+## React/Redux Safety Guidelines
+
+When working with React and Redux code, follow these guidelines:
+
+### Safe Property Access
+
+- **Avoid direct deep property access**:
+ ```jsx
+ // Unsafe
+ const value = state.entities.users[userId].profile.preferences;
+
+ // Safe - using optional chaining
+ const value = state.entities?.users?.[userId]?.profile?.preferences;
+
+ // Safe - using lodash/get with default value
+ const value = get(state, `entities.users.${userId}.profile.preferences`, defaultValue);
+ ```
+
+### Redux State Access
+
+- **Use selectors for all state access**:
+ ```jsx
+ // Define selector
+ const getUserPreferences = (state, userId) =>
+ get(state, ['entities', 'users', userId, 'profile', 'preferences'], {});
+
+ // Use selector
+ const preferences = useSelector(state => getUserPreferences(state, userId));
+ ```
+
+### Error Boundary Usage
+
+- **Wrap components that access complex data structures**:
+ ```jsx
+ }>
+
+
+ ```
+
+### Data Validation
+
+- **Validate data structure before usage**:
+ ```jsx
+ const isValidUserData = (userData) =>
+ userData &&
+ typeof userData === 'object' &&
+ userData.profile !== undefined;
+
+ // Use validation before accessing
+ if (isValidUserData(userData)) {
+ // Now safe to use userData.profile
+ }
+ ```
+
+Following these guidelines will help prevent common issues like:
+- Runtime errors from accessing properties of undefined
+- Unexpected application crashes due to null property access
+- Hard-to-debug errors in deeply nested state structures
\ No newline at end of file
diff --git a/.cursor/docs/practices/react-hooks.md b/.cursor/docs/practices/react-hooks.md
new file mode 100644
index 0000000000..c4a2a0dd64
--- /dev/null
+++ b/.cursor/docs/practices/react-hooks.md
@@ -0,0 +1,202 @@
+# Lessons from Fixing Circular Dependencies in React Hooks
+
+## Background
+
+While working on the Appsmith codebase, we encountered a critical issue in the `useSyncParamsToPath` React hook that caused infinite re-renders and circular dependency problems. This hook was responsible for synchronizing URL paths and query parameters bidirectionally in the API panel. When a user changed the URL, parameters would get extracted and populated in the form, and when parameters were changed, the URL would get updated.
+
+## The Problem
+
+The initial implementation of the hook had several issues:
+
+1. **Improper property access**: The hook was directly accessing nested properties like `values.actionConfiguration.path` without properly handling the case where these nested paths might not exist.
+
+2. **Missing flexible configuration**: The hook couldn't be reused with different property paths since it had hardcoded property paths.
+
+3. **Circular updates**: When the hook updated the path, it would trigger a re-render which would then trigger the hook again, causing an infinite loop.
+
+4. **Missing safeguards**: The hook didn't have proper tracking of previous values or early exits to prevent unnecessary updates.
+
+## The Solution
+
+We implemented several patterns to fix these issues:
+
+### 1. Safe nested property access using lodash/get
+
+Instead of directly accessing nested properties:
+
+```jsx
+// Before
+const path = values.actionConfiguration?.path;
+const queryParameters = values.actionConfiguration?.queryParameters;
+```
+
+We used lodash's `get` function with default values:
+
+```jsx
+// After
+import get from 'lodash/get';
+
+const path = get(values, `${configProperty}.path`, "");
+const queryParameters = get(values, `${configProperty}.params`, []);
+```
+
+This approach provides several benefits:
+- Safely handles undefined or null intermediate values
+- Provides sensible default values
+- Makes the property path configurable using the `configProperty` parameter
+
+### 2. Tracking previous values with useRef
+
+We implemented a pattern to track previous values and prevent unnecessary updates:
+
+```jsx
+// Refs to track the last values to prevent infinite loops
+const lastPathRef = useRef("");
+const lastParamsRef = useRef([]);
+
+useEffect(
+ function syncParamsEffect() {
+ // Early return if nothing has changed
+ if (path === lastPathRef.current && isEqual(queryParameters, lastParamsRef.current)) {
+ return;
+ }
+
+ // Update refs to current values
+ lastPathRef.current = path;
+ lastParamsRef.current = [...queryParameters];
+
+ // Rest of the effect logic
+ },
+ [formValues, dispatch, formName, configProperty],
+);
+```
+
+### 3. Directional updates
+
+To prevent circular updates, we implemented a pattern where the hook would only process one update direction per effect execution:
+
+```jsx
+// Only one sync direction per effect execution to prevent loops
+// Path changed - update params from path if needed
+if (pathChanged) {
+ // Logic to update params from path
+ // Exit early after updating
+ return;
+}
+
+// Params changed - update path from params if needed
+if (paramsChanged) {
+ // Logic to update path from params
+}
+```
+
+### 4. Deep comparisons for complex objects
+
+For comparing arrays of parameters, we implemented custom comparison logic that compares the actual values rather than just checking references:
+
+```jsx
+// Helper function to check if two arrays of params are functionally equivalent
+const areParamsEquivalent = (params1: Property[], params2: Property[]): boolean => {
+ if (params1.length !== params2.length) return false;
+
+ // Create a map of key-value pairs for easier comparison
+ const paramsMap1 = params1.reduce((map, param) => {
+ if (param.key) map[param.key] = param.value;
+ return map;
+ }, {} as Record);
+
+ const paramsMap2 = params2.reduce((map, param) => {
+ if (param.key) map[param.key] = param.value;
+ return map;
+ }, {} as Record);
+
+ return isEqual(paramsMap1, paramsMap2);
+};
+```
+
+## Key Takeaways for React Hook Development
+
+1. **Always use safe property access**:
+ - For deep nested properties, use lodash's `get` with default values
+ - Alternatively, use optional chaining (`?.`) but remember it doesn't provide default values
+
+2. **Track previous values to prevent infinite loops**:
+ - Use `useRef` to store previous values between renders
+ - Compare new values against previous values before making updates
+
+3. **Implement early exits**:
+ - If nothing has changed, return early from your hook
+ - Use deep equality checks for objects and arrays (e.g., `isEqual` from lodash)
+
+4. **Make effects unidirectional in a single execution**:
+ - In bidirectional sync, handle only one direction per effect execution
+ - Exit early after making updates in one direction
+
+5. **Make hooks flexible and reusable**:
+ - Use parameters for configuration (e.g., `configProperty`)
+ - Don't hardcode property paths or selectors
+
+6. **Test bidirectional hooks thoroughly**:
+ - Write tests for both directions of data flow
+ - Test edge cases (undefined values, empty arrays, etc.)
+ - Verify the hook prevents infinite loops with nearly identical input
+
+## Implementation Example
+
+The `useSyncParamsToPath` hook provides a real-world example of these patterns in action:
+
+```tsx
+// Hook to sync query parameters with URL path in both directions
+export const useSyncParamsToPath = (formName: string, configProperty: string) => {
+ const dispatch = useDispatch();
+ const formValues = useSelector((state) => getFormData(state, formName));
+ // Refs to track the last values to prevent infinite loops
+ const lastPathRef = useRef("");
+ const lastParamsRef = useRef([]);
+
+ useEffect(
+ function syncParamsEffect() {
+ if (!formValues || !formValues.values) return;
+
+ const values = formValues.values;
+ const actionId = values.id;
+
+ if (!actionId) return;
+
+ // Correctly access nested properties using lodash's get
+ const path = get(values, `${configProperty}.path`, "");
+ const queryParameters = get(values, `${configProperty}.params`, []);
+
+ // Early return if nothing has changed
+ if (path === lastPathRef.current && isEqual(queryParameters, lastParamsRef.current)) {
+ return;
+ }
+
+ // Check if params have changed but path hasn't - indicating params tab update
+ const paramsChanged = !isEqual(queryParameters, lastParamsRef.current);
+ const pathChanged = path !== lastPathRef.current;
+
+ // Update refs to current values
+ lastPathRef.current = path;
+ lastParamsRef.current = [...queryParameters];
+
+ // Only one sync direction per effect execution to prevent loops
+
+ // Path changed - update params from path if needed
+ if (pathChanged) {
+ // Logic to update params from path
+ // Exit early to prevent circular updates
+ return;
+ }
+
+ // Params changed - update path from params if needed
+ if (paramsChanged) {
+ // Logic to update path from params
+ }
+ },
+ [formValues, dispatch, formName, configProperty],
+ );
+};
+```
+
+By implementing these patterns, we fixed the circular dependency and infinite loop issues while making the hook more reusable and robust.
\ No newline at end of file
diff --git a/.cursor/docs/references/codebase-map.md b/.cursor/docs/references/codebase-map.md
new file mode 100644
index 0000000000..e4e7e6f152
--- /dev/null
+++ b/.cursor/docs/references/codebase-map.md
@@ -0,0 +1,226 @@
+# Appsmith Codebase Map
+
+This document provides a comprehensive overview of the Appsmith codebase structure to help Cursor AI better understand the organization and relationships between different components.
+
+## Project Overview
+
+Appsmith is a low-code platform that allows developers to build internal tools and dashboards by connecting to databases, APIs, and other data sources. The application consists of:
+
+1. A React-based frontend (client)
+2. A Java Spring Boot backend (server)
+3. Various plugins for connecting to external data sources
+4. A self-contained deployment architecture
+
+## Directory Structure
+
+The codebase is organized into the following main directories:
+
+- `app/` - Contains the main application code
+ - `client/` - Frontend application (React)
+ - `server/` - Backend application (Java Spring Boot)
+ - `util/` - Shared utilities
+ - `monitoring/` - Monitoring and metrics
+
+## Frontend Architecture (app/client)
+
+The frontend is built with React, Redux, and TypeScript. Key directories include:
+
+### Core Structure (app/client/src)
+- `actions/` - Redux actions
+- `reducers/` - Redux reducers
+- `sagas/` - Redux sagas for side effects and async operations
+- `selectors/` - Redux selectors
+- `store.ts` - Redux store configuration
+
+### UI Components
+- `components/` - Reusable UI components
+- `pages/` - Page-level components
+- `widgets/` - Draggable widgets for the page builder
+- `theme/` - Styling and theme definitions
+- `icons/` - SVG icons and icon components
+
+### Data and APIs
+- `api/` - API client and service functions
+- `constants/` - Application constants and configuration
+- `utils/` - Utility functions
+- `entities/` - Data models and entity definitions
+
+### Edition-specific Code
+- `ee/` - Enterprise Edition specific code
+- `ce/` - Community Edition specific code
+
+### Testing
+- `test/` - Test utilities and mocks
+- `cypress/` - End-to-end testing with Cypress
+
+## Backend Architecture (app/server)
+
+The backend is built with Java Spring Boot and MongoDB. Key packages include:
+
+### Core Structure (app/server/appsmith-server/src/main/java/com/appsmith/server)
+- `ServerApplication.java` - Main application entry point
+
+### API Layer
+- `controllers/` - REST API controllers
+- `dtos/` - Data Transfer Objects
+- `exceptions/` - Custom exception classes
+
+### Business Logic
+- `services/` - Business logic and service implementations
+- `helpers/` - Helper classes and utilities
+- `domains/` - Domain models
+
+### Data Access
+- `repositories/` - Data access repositories
+- `configurations/` - Database and application configuration
+
+### Features
+- `applications/` - Application management
+- `pages/` - Page management
+- `actions/` - Action management (API, DB queries)
+- `plugins/` - Plugin system for external integrations
+- `datasources/` - Data source management
+- `authentication/` - Authentication and authorization
+- `organization/` - Organization management
+
+### Extensions
+- `appsmith-plugins/` - Plugin implementations
+- `appsmith-git/` - Git integration features
+- `appsmith-interfaces/` - Core interfaces
+- `appsmith-ai/` - AI features implementation
+
+## Key Concepts
+
+### Frontend Concepts
+
+1. **Widgets**: Draggable UI components that users can place on their pages
+2. **Actions**: API calls, DB queries, or JS code that widgets can trigger
+3. **Datasources**: Connections to external data sources like databases or APIs
+4. **Pages**: Containers for widgets representing different views in an application
+5. **Theme**: Visual styling applied to the entire application
+
+### Backend Concepts
+
+1. **Applications**: Container for pages and other resources
+2. **Organizations**: Groups of users and applications
+3. **Plugins**: Connectors to external services
+4. **Actions**: Executable code blocks (API calls, DB queries)
+5. **Datasources**: Connection configurations for external data systems
+
+## Code Patterns
+
+### Frontend Patterns
+
+1. **Redux for State Management**:
+ - Actions define state changes
+ - Reducers implement state updates
+ - Sagas handle side effects
+ - Selectors extract state
+
+2. **Component Structure**:
+ - Functional components with hooks
+ - Container/Presentation separation
+ - Styled-components for styling
+ - Typescript interfaces for type safety
+
+3. **API Communication**:
+ - Axios-based API clients
+ - Redux sagas for async operations
+ - Error handling middleware
+
+### Backend Patterns
+
+1. **Spring Boot Architecture**:
+ - Controller -> Service -> Repository pattern
+ - DTO pattern for API requests/responses
+ - Reactive programming with Reactor
+
+2. **Security**:
+ - JWT-based authentication
+ - RBAC (Role-Based Access Control)
+ - Permission checks with Spring Security
+
+3. **Database**:
+ - MongoDB as primary datastore
+ - Reactive repositories
+
+## Common Workflows
+
+### Frontend Development Workflow
+
+1. Define Redux actions in `actions/`
+2. Implement reducers in `reducers/`
+3. Create sagas for async operations in `sagas/`
+4. Build UI components in `components/` or `pages/`
+5. Connect components to Redux using selectors
+
+### Backend Development Workflow
+
+1. Define DTOs in `dtos/`
+2. Create domain models in `domains/`
+3. Implement repositories in `repositories/`
+4. Add business logic in `services/`
+5. Expose APIs in `controllers/`
+
+## Testing Approach
+
+### Frontend Testing
+- Unit tests with Jest and React Testing Library
+- End-to-end tests with Cypress
+- Visual regression tests
+
+### Backend Testing
+- Unit tests with JUnit
+- Integration tests with Spring Boot Test
+- API tests with RestAssured
+
+## Performance Considerations
+
+### Frontend Performance
+- Memoization of heavy computations
+- Code splitting for page loads
+- Virtualization for large lists
+- Optimized rendering with React.memo
+
+### Backend Performance
+- Query optimization in MongoDB
+- Caching strategies
+- Reactive programming for non-blocking operations
+
+## Security Model
+
+1. **Authentication**: JWT-based auth with refresh tokens
+2. **Authorization**: RBAC with granular permissions
+3. **Data Isolation**: Multi-tenancy support
+
+## Enterprise vs Community Edition
+
+The codebase is separated into:
+- `ee/` - Enterprise features
+- `ce/` - Community features
+
+Key differences:
+1. Enterprise: SSO, audit logs, role-based access
+2. Community: Basic features, self-hosted option
+
+## Important Files
+
+### Frontend
+- `client/src/index.tsx` - Application entry point
+- `client/src/store.ts` - Redux store configuration
+- `client/src/App.tsx` - Main application component
+
+### Backend
+- `server/appsmith-server/src/main/java/com/appsmith/server/ServerApplication.java` - Main entry point
+- `server/appsmith-server/src/main/resources/application.yml` - Application configuration
+
+## Development Guidelines
+
+1. Follow the established patterns in the existing codebase
+2. Use TypeScript interfaces for type safety in frontend
+3. Add appropriate tests for all new features
+4. Document complex logic with comments
+5. Use reactive programming patterns in backend
+6. Follow established file naming conventions
+
+This map should help Cursor better understand the Appsmith codebase structure and provide more contextual assistance when working with the code.
\ No newline at end of file
diff --git a/.cursor/docs/references/technical-details.md b/.cursor/docs/references/technical-details.md
new file mode 100644
index 0000000000..270cc194a9
--- /dev/null
+++ b/.cursor/docs/references/technical-details.md
@@ -0,0 +1,699 @@
+# Appsmith Technical Details
+
+This document provides in-depth technical information about the Appsmith codebase, focusing on implementation details, design patterns, and technologies used. This information will help Cursor AI better understand the code at a deeper level.
+
+## Technology Stack
+
+### Frontend
+- **Framework**: React 17+
+- **State Management**: Redux with Redux-Saga
+- **Language**: TypeScript 4+
+- **Styling**: Styled Components with Tailwind CSS
+- **Build Tool**: Webpack
+- **Testing**: Jest, React Testing Library, Cypress
+- **Form Management**: Formik
+- **API Client**: Axios
+- **UI Components**: Custom component library
+
+### Backend
+- **Framework**: Spring Boot 2.x
+- **Language**: Java 11+
+- **Database**: MongoDB
+- **Reactive Programming**: Project Reactor
+- **Security**: Spring Security
+- **API Documentation**: Swagger/OpenAPI
+- **Caching**: Redis
+
+## Key Frontend Implementation Details
+
+### State Management
+
+The application uses Redux with a sophisticated structure:
+
+```typescript
+// Example action
+export const fetchDatasources = (applicationId: string) => ({
+ type: ReduxActionTypes.FETCH_DATASOURCES,
+ payload: { applicationId },
+});
+
+// Example reducer
+const datasourceReducer = (state = initialState, action: ReduxAction) => {
+ switch (action.type) {
+ case ReduxActionTypes.FETCH_DATASOURCES_SUCCESS:
+ return { ...state, list: action.payload };
+ // ...
+ }
+};
+
+// Example saga
+function* fetchDatasourcesSaga(action: ReduxAction<{ applicationId: string }>) {
+ try {
+ const response = yield call(DatasourcesApi.fetchDatasources, action.payload.applicationId);
+ yield put({
+ type: ReduxActionTypes.FETCH_DATASOURCES_SUCCESS,
+ payload: response.data,
+ });
+ } catch (error) {
+ yield put({
+ type: ReduxActionTypes.FETCH_DATASOURCES_ERROR,
+ payload: { error },
+ });
+ }
+}
+```
+
+### Widget System
+
+Widgets are the building blocks of the application UI. They follow a standard structure:
+
+```typescript
+export type WidgetProps = {
+ widgetId: string;
+ type: string;
+ widgetName: string;
+ parentId?: string;
+ renderMode: RenderMode;
+ version: number;
+ // ...other properties
+};
+
+export default class ButtonWidget extends BaseWidget {
+ static getPropertyPaneConfig() {
+ return [
+ {
+ sectionName: "General",
+ children: [
+ {
+ propertyName: "text",
+ label: "Label",
+ controlType: "INPUT_TEXT",
+ // ...
+ },
+ // ...other properties
+ ],
+ },
+ // ...other sections
+ ];
+ }
+
+ getPageView() {
+ return (
+
+ );
+ }
+
+ handleClick = () => {
+ if (this.props.onClick) {
+ super.executeAction({
+ triggerPropertyName: "onClick",
+ dynamicString: this.props.onClick,
+ event: {
+ type: EventType.ON_CLICK,
+ // ...
+ },
+ });
+ }
+ };
+}
+```
+
+### Property Pane System
+
+The property pane is dynamically generated based on the widget configuration:
+
+```typescript
+export const PropertyPaneView = (props: PropertyPaneViewProps) => {
+ const { config, panel } = props;
+
+ // Render property sections
+ return (
+
+ {config.map((section) => (
+
+ {section.children.map((property) => (
+
+ ))}
+
+ ))}
+
+ );
+};
+```
+
+### Data Binding
+
+The app uses a JS evaluation engine to bind data to widgets:
+
+```typescript
+export function evaluateDynamicValue(
+ dynamicValue: string,
+ data: Record,
+): any {
+ // Set up execution environment
+ const scriptToEvaluate = `
+ function evaluation() {
+ const $ = ${JSON.stringify(data)};
+ try {
+ return ${dynamicValue};
+ } catch (e) {
+ return undefined;
+ }
+ }
+ evaluation();
+ `;
+
+ try {
+ return eval(scriptToEvaluate);
+ } catch (e) {
+ return undefined;
+ }
+}
+```
+
+### API Integration
+
+The API client is set up with Axios and handles authentication:
+
+```typescript
+const axiosInstance = axios.create({
+ baseURL: "/api/v1",
+ headers: {
+ "Content-Type": "application/json",
+ },
+});
+
+// Request interceptor for adding auth token
+axiosInstance.interceptors.request.use((config) => {
+ const token = localStorage.getItem("AUTH_TOKEN");
+ if (token) {
+ // Basic validation - check if token is a valid JWT format
+ if (token.split('.').length === 3) {
+ config.headers.Authorization = `Bearer ${token}`;
+ } else {
+ // Handle invalid token - could log user out or refresh token
+ store.dispatch(refreshToken());
+ }
+ }
+ return config;
+});
+
+// Response interceptor for handling errors
+axiosInstance.interceptors.response.use(
+ (response) => response,
+ (error) => {
+ if (error.response && error.response.status === 401) {
+ // Handle unauthorized
+ store.dispatch(logoutUser());
+ }
+ return Promise.reject(error);
+ }
+);
+```
+
+## Key Backend Implementation Details
+
+### Repository Pattern
+
+Mongo repositories use reactive programming:
+
+```java
+@Repository
+public interface DatasourceRepository extends ReactiveMongoRepository {
+ Mono findByNameAndOrganizationId(String name, String organizationId);
+ Flux findAllByOrganizationId(String organizationId);
+ Mono countByNameAndOrganizationId(String name, String organizationId);
+}
+```
+
+### Service Layer
+
+Services handle business logic:
+
+```java
+@Service
+@RequiredArgsConstructor
+public class DatasourceServiceImpl implements DatasourceService {
+ private final DatasourceRepository repository;
+ private final PluginService pluginService;
+
+ @Override
+ public Mono create(Datasource datasource) {
+ return repository.save(datasource)
+ .flatMap(saved -> pluginService.getById(datasource.getPluginId())
+ .map(plugin -> {
+ saved.setPlugin(plugin);
+ return saved;
+ }));
+ }
+
+ // Other methods...
+}
+```
+
+### Controller Layer
+
+Controllers expose REST APIs:
+
+```java
+@RestController
+@RequestMapping("/api/v1/datasources")
+@RequiredArgsConstructor
+public class DatasourceController {
+ private final DatasourceService service;
+
+ @PostMapping
+ public Mono> create(@RequestBody DatasourceDTO dto) {
+ Datasource datasource = new Datasource();
+ BeanUtils.copyProperties(dto, datasource);
+
+ return service.create(datasource)
+ .map(created -> new ResponseDTO<>(HttpStatus.CREATED.value(), created, null));
+ }
+
+ // Other endpoints...
+}
+```
+
+### Security Configuration
+
+Spring Security setup:
+
+```java
+@Configuration
+@EnableWebFluxSecurity
+@EnableReactiveMethodSecurity
+public class SecurityConfig {
+
+ @Bean
+ public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
+ return http
+ .csrf().disable()
+ .formLogin().disable()
+ .httpBasic().disable()
+ .authorizeExchange()
+ .pathMatchers("/api/v1/public/**").permitAll()
+ .pathMatchers("/api/v1/auth/**").permitAll()
+ .anyExchange().authenticated()
+ .and()
+ .addFilterAt(jwtAuthenticationFilter, SecurityWebFiltersOrder.AUTHENTICATION)
+ .build();
+ }
+
+ // Other beans...
+}
+```
+
+### Query Execution
+
+Action execution is handled in a structured way:
+
+```java
+@Service
+@RequiredArgsConstructor
+public class ActionExecutionServiceImpl implements ActionExecutionService {
+ private final ActionExecutorFactory executorFactory;
+
+ @Override
+ public Mono executeAction(ActionDTO action) {
+ ActionExecutor executor = executorFactory.getExecutor(action.getPluginType());
+
+ if (executor == null) {
+ return Mono.error(new AppsmithException(AppsmithError.UNSUPPORTED_PLUGIN_ACTION));
+ }
+
+ return executor.execute(action);
+ }
+}
+```
+
+## Advanced Patterns
+
+### Code Splitting
+
+```typescript
+// Lazy loading of components
+const ApplicationPage = React.lazy(() => import("pages/Applications"));
+const EditorPage = React.lazy(() => import("pages/Editor"));
+
+// Router setup
+const routes = [
+ {
+ path: "/applications",
+ component: ApplicationPage,
+ },
+ {
+ path: "/app/editor/:applicationId/:pageId",
+ component: EditorPage,
+ },
+ // ...
+];
+```
+
+### Plugin System
+
+The plugin system allows extensibility:
+
+```java
+public interface PluginExecutor {
+ Mono execute(T connection, U datasourceConfiguration, Object executeActionDTO);
+ Mono datasourceCreate(U datasourceConfiguration);
+ void datasourceDestroy(T connection);
+ Set getHintMessages(U datasourceConfiguration);
+ // ...
+}
+```
+
+### Reactive Caching
+
+```java
+@Service
+public class CacheableRepositoryHelper {
+ private final Map> cacheMap = new ConcurrentHashMap<>();
+
+ public Mono fetchFromCache(String cacheName, String key, Supplier> fetchFunction) {
+ Cache cache = cacheMap.computeIfAbsent(cacheName, k ->
+ Caffeine.newBuilder().expireAfterWrite(30, TimeUnit.MINUTES).build());
+
+ Object cachedValue = cache.getIfPresent(key);
+ if (cachedValue != null) {
+ return Mono.just((T) cachedValue);
+ }
+
+ return fetchFunction.get()
+ .doOnNext(value -> cache.put(key, value));
+ }
+}
+```
+
+### Action Collection System
+
+Actions are grouped into collections for better organization:
+
+```java
+@Document
+public class ActionCollection {
+ @Id
+ private String id;
+ private String name;
+ private String applicationId;
+ private String organizationId;
+ private String pageId;
+ private List actions;
+ private List actionIds;
+ private String body;
+ // ...
+}
+```
+
+## Common Code Patterns
+
+### Error Handling
+
+Frontend error handling:
+
+```typescript
+// Global error boundary
+export class AppErrorBoundary extends React.Component<{}, { hasError: boolean }> {
+ constructor(props: {}) {
+ super(props);
+ this.state = { hasError: false };
+ }
+
+ static getDerivedStateFromError() {
+ return { hasError: true };
+ }
+
+ componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
+ logError(error, errorInfo);
+ }
+
+ render() {
+ if (this.state.hasError) {
+ return ;
+ }
+ return this.props.children;
+ }
+}
+```
+
+Backend error handling:
+
+```java
+@ExceptionHandler(AppsmithException.class)
+public Mono>> handleAppsmithException(AppsmithException exception) {
+ log.error("Application error: {}", exception.getMessage(), exception);
+
+ ResponseDTO