diff --git a/.claude/skills/react/SKILL.md b/.claude/skills/react/SKILL.md new file mode 100644 index 000000000..5ea927eca --- /dev/null +++ b/.claude/skills/react/SKILL.md @@ -0,0 +1,154 @@ +--- +name: react +description: > + Use when creating or editing frontend React code in react-ui or ui-components packages. + Triggers on any frontend component, hook, or UI work. +--- + +# React & Frontend Development Skill + +When working on frontend code in `packages/react-ui` or `packages/ui-components`, follow these guidelines strictly. + +--- + +## 1. Modular Components + +- Break the design into independent files. Avoid large, single-file outputs. +- Each component should have one clear responsibility. +- Reusable, pure components live in `packages/ui-components` and **must** have Storybook stories in `packages/ui-components/src/stories/`. +- Application-specific components live in `packages/react-ui`. +- Do not make breaking changes to existing component interfaces (props, names) without discussion. + +--- + +## 2. Logic Isolation + +- Move event handlers and business logic into **custom hooks** (`use-*.ts`). +- Follow existing convention: hooks go in `hooks/` directories alongside features (e.g., `features/campaigns/hooks/use-campaign-charts.ts`). +- Keep component files focused on rendering; delegate logic to hooks. +- Extract complex derived state into hooks or utility functions. + +--- + +## 3. Data Fetching — react-query v5 + +- Use `QueryKeys` from `@/app/constants/query-keys.ts` — **never hardcode query key strings**. +- Use `useQuery` for reads, `useMutation` for writes. +- Invalidate related queries after mutations using `queryClient.invalidateQueries`. +- Use the `enabled` option for conditional queries. +- Keep query functions in dedicated API modules (e.g., `campaigns-api.ts`). + +**Example — existing pattern:** + +```tsx +import { QueryKeys } from '@/app/constants/query-keys'; +import { useQuery } from '@tanstack/react-query'; +import { campaignsApi } from '../campaigns-api'; + +export function useCampaignCharts(campaignId: string) { + const { data: chartData } = useQuery({ + queryKey: [QueryKeys.campaignCharts, campaignId], + queryFn: () => campaignsApi.getCharts(campaignId), + }); + + const weekData = useMemo(() => /* derive from chartData */, [chartData]); + + return { chartData, weekData }; +} +``` + +--- + +## 4. React Hooks & Performance + +- **Prefer extracted event handlers** at component scope when they are passed to memoized children, reused across multiple elements, used in dependency arrays, or contain non-trivial logic. +- **Inline JSX callbacks are acceptable** for simple, local interactions when they keep the code clearer and are not causing avoidable re-renders in hot paths. +- **Use `useMemo`** for expensive computations or derived state. +- **Use `useCallback`** selectively for handlers where referential stability matters (for example, props to memoized children or values used in hook dependency arrays). +- Place hooks and any memoized values/functions near the top of the component, after state declarations, following existing file conventions. + +**Prefer extraction when logic is non-trivial or stability matters**: + +```tsx +// ✅ Simple inline callback — fine when the handler is trivial and local +; + +// ✅ Extracted handler — preferred when logic is non-trivial or passed to memoized children +const handleSubmit = useCallback( + (values: FormValues) => { + const sanitized = sanitizeInput(values); + onSubmit?.(sanitized); + }, + [onSubmit], +); + +return
; +``` + +--- + +## 5. Anti-Patterns Checklist + +❌ **Inline arrow functions in JSX for non-trivial logic or props to memoized children** (can cause avoidable re-renders) +❌ **Inline object/array literals in JSX props** (breaks reference equality) +❌ **Complex logic inside render** (hard to test, poor separation of concerns) +❌ **Missing dependency arrays** in `useEffect`/`useCallback`/`useMemo` +❌ **Unnecessary state** (derive from props when possible) +❌ **Hardcoded query key strings** (use `QueryKeys` constants) + +✅ **Extract and memoize** callbacks with `useCallback` when referential stability matters +✅ **Extract complex JSX logic** into separate memoized functions or sub-components +✅ **Derive state** with `useMemo` instead of storing duplicated state +✅ **Keep component functions focused** — one clear responsibility per function +✅ **Move business logic into custom hooks** + +--- + +## 6. Styling + +- Use shadcn components as the foundation. +- Use `cn` utility to group Tailwind classnames: + +```tsx +
+ {t('Sample output data')} +
+``` + +--- + +## 7. Code Quality Constraints + +- **SOLID, DRY, Clean Code** — small functions, clear names, no dead code. +- **Pattern consistency** — read existing code in the target area before writing new code. +- Run build, test, lint, type-check iteratively: + +```bash +npx nx test react-ui +npx nx test ui-components +npx nx lint react-ui +npx nx lint ui-components +``` + +--- + +## 8. Project-Specific Context + +- **React 18** with functional components +- **Zustand** for state management +- **react-query v5** (`@tanstack/react-query`) for data fetching +- **shadcn** for UI components +- **Axios** via existing wrapper in `api.ts`; use `qs` package for query strings +- Tests go in `tests/` folders alongside code (Jest) +- Perform browser testing with the available project tooling before finalizing UI changes diff --git a/AGENTS.md b/AGENTS.md index 26cd6745d..960579339 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -7,15 +7,25 @@ - Update documentation for user-facing changes - Do not introduce new dependencies without discussion - ## Structure The repository is using nx, with the source code under the "packages" directory. -Use nx to run tests (e.g. npx nx test server-shared). -Run "npx nx lint" before committing. +Notable packages (nx projects) include: + +- **packages/server/api** - Main Fastify-based API server (port 3000) +- **packages/server/shared** - Shared server utilities (logging, caching, encryption) +- **packages/engine** - Workflow execution engine (runs as separate service or AWS Lambda) +- **packages/react-ui** - React frontend application (Vite + TailwindCSS) +- **packages/shared** - Shared types and utilities across frontend/backend +- **packages/blocks/** - 50+ integration blocks (AWS, Azure, GCP, Slack, etc.) +- **packages/blocks/framework** - Base framework for creating blocks/actions/triggers +- **packages/ui-components** - Reusable UI component library (documented in Storybook) +- **packages/ui-kit** - UI kit with frontend tools, socket context, and API utilities ## Code Style +Run "npx nx lint" to verify code style before committing. + ### Formatting - **Indentation:** 2 spaces (TypeScript/JavaScript, shell scripts) @@ -81,45 +91,24 @@ export function getUserProfile(userId: string): UserProfile { ### Best Practices -- Follow best practices for React hooks -- Prefer small, composable components -- Extract helper functions where possible -- Do not make breaking changes to existing code interfaces (component props, names) without discussion -- Ensure compliance with strict linter setups (including Sonar) -- Use `cn` utility to group Tailwind classnames: - -```tsx -
- {t('Sample output data')} -
-``` +**Always use the `react` skill** when creating or editing frontend code in `react-ui` or `ui-components`. The skill covers component organization, hooks/performance, data fetching, styling, TDD, and anti-patterns. ## Testing +- **TDD** — red-green-refactor. No production code without a failing test first. - Use Jest for testing - Place unit tests in a `tests` folder alongside the code - Run tests using Nx commands: ```bash -nx test react-ui -nx test ui-components -nx test-unit server-api -nx test engine -nx lint react-ui +npx nx test react-ui +npx nx test ui-components +npx nx test-unit server-api +npx nx test engine +npx nx lint react-ui ``` -## Git Workflow +## Git and Pull Request Guidelines ### Commits @@ -127,17 +116,6 @@ nx lint react-ui - Keep commits small and focused on a single change - Write descriptive commit messages that explain what and why, not how -**Commit message format:** - -``` -Short summary in imperative mood (under 50 chars) - -More detailed explanation if necessary. Wrap at around 72 -characters. Explain what and why, not how (the code shows that). - -Fixes #issue_number -``` - ### Pull Requests #### Size and Scope @@ -156,7 +134,8 @@ Fixes #issue_number All PRs must reference a linear issue in their body. -Examples: +Examples: + - Fixes OPS-100. - Resolves OPS-101. - Part of CI-102. diff --git a/CLAUDE.md b/CLAUDE.md index 2c4ec8c0f..5f1995137 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -11,6 +11,7 @@ The repository is using nx, with the source code under the "packages" directory. Notable packages (nx projects) include: + - **packages/server/api** - Main Fastify-based API server (port 3000) - **packages/server/shared** - Shared server utilities (logging, caching, encryption) - **packages/engine** - Workflow execution engine (runs as separate service or AWS Lambda) @@ -19,7 +20,7 @@ Notable packages (nx projects) include: - **packages/blocks/** - 50+ integration blocks (AWS, Azure, GCP, Slack, etc.) - **packages/blocks/framework** - Base framework for creating blocks/actions/triggers - **packages/ui-components** - Reusable UI component library (documented in Storybook) - +- **packages/ui-kit** - UI kit with frontend tools, socket context, and API utilities ## Code Style @@ -90,36 +91,17 @@ export function getUserProfile(userId: string): UserProfile { ### Best Practices -- Follow best practices for React hooks -- Prefer small, composable components -- Extract helper functions where possible -- Do not make breaking changes to existing code interfaces (component props, names) without discussion -- Ensure compliance with strict linter setups (including Sonar) -- Use `cn` utility to group Tailwind classnames: - -```tsx -
- {t('Sample output data')} -
-``` +**Always use the `react` skill** when creating or editing frontend code in `react-ui` or `ui-components`. The skill covers component organization, hooks/performance, data fetching, styling, TDD, and anti-patterns. ## Testing +- **TDD** — red-green-refactor. No production code without a failing test first. - Use Jest for testing - Place unit tests in a `tests` folder alongside the code - Run tests using Nx commands: +Examples: + ```bash npx nx test react-ui npx nx test ui-components @@ -136,7 +118,6 @@ npx nx lint react-ui - Keep commits small and focused on a single change - Write descriptive commit messages that explain what and why, not how - ### Pull Requests #### Size and Scope @@ -155,7 +136,8 @@ npx nx lint react-ui All PRs must reference a linear issue in their body. -Examples: +Examples: + - Fixes OPS-100. - Resolves OPS-101. - Part of CI-102.