Files
formbricks/AGENTS.md

5.6 KiB

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.