# Repository Guidelines ## Project Structure & Module Organization Formbricks runs as a pnpm/turbo monorepo. `apps/web` is the Next.js product surface, with feature modules under `app/` and `modules/`, assets in `public/` and `images/`, and Playwright specs in `apps/web/playwright/`. `apps/storybook` renders reusable UI pieces for review. Shared logic lives in `packages/*`: `database` (Prisma schemas/migrations), `surveys`, `js-core`, `types`, plus linting and TypeScript presets (`config-*`). Deployment collateral is kept in `docs/`, `docker/`, and `helm-chart/`. Unit tests sit next to their source as `*.test.ts` or inside `__tests__`. ## Build, Test & Development Commands - `pnpm install` — install workspace dependencies pinned by `pnpm-lock.yaml`. - `pnpm db:up` / `pnpm db:down` — start/stop the Docker services backing the app. - `pnpm dev` — run all app and worker dev servers in parallel via Turborepo. - `pnpm build` — generate production builds for every package and app. - `pnpm lint` — apply the shared ESLint rules across the workspace. - `pnpm test` / `pnpm test:coverage` — execute Vitest suites with optional coverage. - `pnpm test:e2e` — launch the Playwright browser regression suite. - `pnpm db:migrate:dev` — apply Prisma migrations against the dev database. ## Coding Style & Naming Conventions TypeScript, React, and Prisma are the primary languages. Use the shared ESLint presets (`@formbricks/eslint-config`) and Prettier preset (110-char width, semicolons, double quotes, sorted import groups). Two-space indentation is standard; prefer `PascalCase` for React components and folders under `modules/`, `camelCase` for functions/variables, and `SCREAMING_SNAKE_CASE` only for constants. When adding mocks, place them inside `__mocks__` so import ordering stays stable. We are using SonarQube to identify code smells and security hotspots. ## Architecture & Patterns - Next.js app router lives in `apps/web/app` with route groups like `(app)` and `(auth)`. Services live in `apps/web/lib`, feature modules in `apps/web/modules`. - Server actions wrap service calls and return `{ data }` or `{ error }` consistently. - Context providers should guard against missing provider usage and use cleanup patterns that snapshot refs inside `useEffect` to avoid React hooks warnings ## Caching - Use React `cache()` for request-level dedupe and `cache.withCache()` or explicit Redis for expensive data. - Do not use Next.js `unstable_cache()`. - Always use `createCacheKey.*` utilities for cache keys. ## i18n (Internationalization) - All user-facing text must use the `t()` function from `react-i18next`. - Key naming: use lowercase with dots for nesting (e.g., `common.welcome`). - Translations are in `apps/web/locales/`. Default is `en-US.json`. - Lingo.dev is automatically translating strings from en-US into other languages on commit. Run `pnpm i18n` to generate missing translations and validate keys. ## Database & Prisma Performance - Multi-tenancy: All data must be scoped by Organization or Environment. - Soft Deletion: Check for `isActive` or `deletedAt` fields; use proper filtering. - Never use `skip`/`offset` with `prisma.response.count()`; only use `where`. - Separate count and data queries and run in parallel (`Promise.all`). - Prefer cursor pagination for large datasets. - When filtering by `createdAt`, include indexed fields (e.g., `surveyId` + `createdAt`). ## Testing Guidelines Prefer Vitest with Testing Library for logic in `.ts` files, keeping specs colocated with the code they exercise (`utility.test.ts`). Do not write tests for `.tsx` files—React components are covered by Playwright E2E tests instead. Mock network and storage boundaries through helpers from `@formbricks/*`. Run `pnpm test` before opening a PR and `pnpm test:coverage` when touching critical flows; keep coverage from regressing. End-to-end scenarios belong in `apps/web/playwright`, using descriptive filenames (`billing.spec.ts`) and tagging slow suites with `@slow` when necessary. ## Documentation (apps/docs) - Add frontmatter with `title`, `description`, and `icon` at the top of the MDX file. - Do not start with an H1; use Camel Case headings (only capitalize the feature name). - Use Mintlify components for steps and callouts. - If Enterprise-only, add the Enterprise note block described in docs. ## Storybook - Stories live in `stories.tsx` in the component folder and import from `"./index"`. - Use `@storybook/react-vite` and organize argTypes into `Behavior`, `Appearance`, `Content`. - Include Default, Disabled (if supported), WithIcon (if supported), all variants, and edge cases. ## GitHub Actions - Always set minimal `permissions` for `GITHUB_TOKEN`. - On `ubuntu-latest`, add `step-security/harden-runner` as the first step. ## Quality Checklist - Keep code DRY and small; remove dead code and unused imports. - Follow React hooks rules, keep effects focused, and avoid unnecessary `useMemo`/`useCallback`. - Prefer type inference, avoid `any`, and use shared types from `@formbricks/types`. - Keep components focused, avoid deep nesting, and ensure basic accessibility. ## Commit & Pull Request Guidelines Commits follow a lightweight Conventional Commit format (`fix:`, `chore:`, `feat:`) and usually append the PR number, e.g. `fix: update OpenAPI schema (#6617)`. Keep commits scoped and lint-clean. Pull requests should outline the problem, summarize the solution, and link to issues or product specs. Attach screenshots or gifs for UI-facing work, list any migrations or env changes, and paste the output of relevant commands (`pnpm test`, `pnpm lint`, `pnpm db:migrate:dev`) so reviewers can verify readiness.