Trovella Wiki

Quality Gates Overview

How linting, formatting, type checking, and pre-commit hooks enforce code quality before code reaches CI.

Quality gates are automated checks that run at two points in the development workflow: locally before each commit (via pre-commit hooks) and in CI before merge. Together they enforce formatting consistency, type safety, lint rules, and SDK boundary compliance across the monorepo.

The Four Gates

GateToolRuns locallyRuns in CIBlocks merge
FormattingPrettierOn staged files (pre-commit)pnpm format:checkYes
LintingESLint (flat config)On staged .ts/.tsx files (pre-commit)pnpm turbo lint --affectedYes
Type checkingTypeScript 5.9 strictManual (pnpm typecheck)pnpm turbo typecheck --affectedYes
SDK boundariesESLint no-restricted-importsSame as lintingSame as lintingYes

Two additional static analysis tools -- dependency-cruiser (dependency graph validation) and Knip (dead code detection) -- also run in CI but are covered under Delivery -- Architecture Enforcement.

Execution Order

Pre-commit (local)

The pre-commit hook runs via Husky and lint-staged. It targets only staged files, keeping the feedback loop under a few seconds:

  1. ESLint with --fix on staged .ts/.tsx files (grouped by package for correct tsconfig.json resolution)
  2. Prettier with --write on all staged files matching supported extensions

CI (pnpm ci:check)

The ci:check script runs every gate in a fixed sequence. If any step fails, the remaining steps do not run:

  1. pnpm format:check -- Prettier (check mode, no writes)
  2. pnpm lint -- ESLint via Turborepo (respects --affected in CI)
  3. pnpm dep-cruise -- dependency-cruiser graph validation
  4. pnpm lint:dead-code -- Knip dead code detection
  5. pnpm lint:duplication -- jscpd copy-paste detection
  6. pnpm typecheck -- TypeScript via Turborepo
  7. pnpm test -- Vitest via Turborepo
  8. pnpm docs:update-detection -- flags stale user-facing docs

Steps 3--5 and 8 are architecture enforcement and documentation quality checks. See Delivery -- Architecture Enforcement and Delivery -- Pipeline for those topics.

Shared Configuration Packages

Quality gate configuration is centralized in two internal packages:

@repo/eslint-config

Provides three ESLint flat config presets and an SDK boundary restriction function:

ExportUsed byDescription
./baseAll presetsCore TypeScript rules, naming conventions, complexity limits, import sorting
./librarypackages/*Extends base (identical today, reserved for library-specific rules)
./nextapps/webExtends base + Next.js rules
./restrictionsAll packagesrestrictedImports(packageName) function for SDK boundaries

@repo/typescript-config

Provides three tsconfig.json presets:

ExportUsed byDescription
./base.jsonAll presetsStrict mode, noUncheckedIndexedAccess, verbatimModuleSyntax, ES2022 target
./library.jsonpackages/*Extends base, sets outDir/rootDir for library builds
./nextjs.jsonapps/webExtends base, adds JSX/DOM support and the Next.js compiler plugin

Pages in This Topic

ESLint Configuration

The full rule set: TypeScript strict rules, naming conventions, complexity limits, import sorting, SonarJS code smells, SDK boundary enforcement via no-restricted-imports, and per-package customization.

TypeScript Strictness

The tsconfig.json presets, what each strict flag does, how packages extend the base config, and why verbatimModuleSyntax is enabled.

Prettier Formatting

Prettier configuration, file type coverage, the Tailwind CSS plugin, and the .prettierignore exclusions.

Pre-commit Hooks

The Husky + lint-staged pipeline: how files are grouped by package, the custom ESLint wrapper script, and what happens on each commit.

On this page