CAITSGet started

Change the rules and the tools

This page shows how a project changes its architecture rules, and the settings of its tools: ESLint, Vite and Vitest, Playwright, Stryker and TypeScript. CAITS gives the defaults; your files have the last word.

The two kinds of files

FilesOwnerWhat they hold
quality/caits/*CAITSThe defaults of CAITS. npx caits update writes them again: do not change them.
quality/*, tsconfig.jsonThe projectThe configuration of the project. Each file imports the defaults of CAITS, then changes them. CAITS never changes these files.

Your file has the last word: what it removes, replaces or adds is what the tool uses.

The architecture rules

caits architecture checks the rules that quality/architecture.mjs exports. Each rule is an object with a name, a description, the kind of thing that it reads (on), and a check.

Remove a rule:

quality/architecture.mjs

import { rules } from "./caits/architecture.mjs";

export default rules.filter(rule => rule.name !== "routes-folders");

Add a rule:

quality/architecture.mjs

import { rules } from "./caits/architecture.mjs";

const noLodashInDomain = {
  name: "no-lodash-in-domain",
  description: "The domain does not import lodash.",
  on: "import",
  check: ({ from, specifier }) => from.layer === "domain" && specifier.startsWith("lodash") && "the domain does not import lodash"
};

export default [...rules, noLodashInDomain];

To replace a rule, remove it, then add your own rule with the same name.

A check gives false or undefined when the rule holds. Otherwise, it gives the message, or a list of messages. on tells what the check reads:

onThe check reads
"import"Each import of the production code: { file, from, to, specifier, internal, target }.
"file"Each file, and the project. With production: true, the check reads only the production code: the test files stay out.
"project"The project, once. The check gives a list of { file, message }.

@ingenioz-it/caits/quality/architecture gives what the rules of CAITS use: locate, isCore, portOf, adapterOf, resolveImport… Read quality/caits/architecture.mjs for examples.

To test your rules, write quality/*.test.mjs with checkArchitecture(root, sources, rules) of the same module. npm test runs these tests.

ESLint

quality/eslint.config.js is a list. ESLint applies the entries in their order, so your entries win over those of CAITS:

quality/eslint.config.js

import caits from "./caits/eslint.js";

export default [
  ...caits,
  { files: ["src/**/*.ts"], rules: { "no-console": "error" } }
];

Vite and Vitest

quality/vite.config.ts is the configuration of the build, of the development server and of the unit tests. mergeConfig adds your settings to those of CAITS:

quality/vite.config.ts

import { mergeConfig } from "vitest/config";
import caits from "./caits/vite.ts";

export default mergeConfig(caits, {
  test: { coverage: { thresholds: { branches: 90 } } }
});

mergeConfig adds to the lists (for example plugins and test.include). To replace a list, change it after the merge.

Playwright and Stryker

Your values replace those of CAITS. To change one value of an object, copy the others:

quality/playwright.config.ts

import { defineConfig } from "@playwright/test";
import caits from "./caits/playwright.ts";

export default defineConfig({
  ...caits,
  use: { ...caits.use, locale: "fr-FR" }
});

caits e2e reads webServer from quality/playwright.config.ts: if you change the port or the command of the server, the command uses your values.

Stryker asks for 100% of the mutants killed. To run it on fewer processes, for example on a small machine:

quality/stryker.config.mjs

import caits from "./caits/stryker.mjs";

export default {
  ...caits,
  concurrency: 4
};

To keep one mutant out, with its reason, see A mutant survived. Lower the thresholds only with your team: a test that checks nothing then has a place to hide.

TypeScript

tsconfig.json extends quality/caits/tsconfig.json. Add your options next to extends: they replace those of CAITS.

tsconfig.json

{
  "extends": "./quality/caits/tsconfig.json",
  "compilerOptions": { "noUnusedParameters": true }
}
Next pageWrite the styles The CSS of all the pages, of one page, or of one component, in SCSS.