lightweight-sdk/spec/conventions.md
Nicolas e2d7207237
Some checks failed
CI / build-lint-test (push) Failing after 1m53s
CI / build-lint-test (pull_request) Successful in 1m58s
Bootstrap monorepo pnpm + migration de web-component
- Outillage complet : pnpm workspaces (catalog), Biome, TypeScript
  (project references, CommonJS/Node10), Vitest, TypeDoc (validation
  bloquante en CI), Changesets.
- Organisation des packages en catégories client/common/server.
- Migration de @lightweight-sdk/web-component (packages/client/) depuis
  l'ancien repo lightweight-sdk-web-component : code source copié à
  l'identique, aucune modification. package.json/tsconfig.json/README.md
  adaptés autour. Exclu de la validation TypeDoc stricte et de quelques
  règles Biome (formatage, noShadowRestrictedNames) puisque le code ne
  peut pas être édité pour s'y conformer - détails dans spec/packages.md.
- Workflows Forgejo Actions (.forgejo/workflows/) : ci.yml (lint, build,
  test, docs:check) et release.yml (publication sur le registre npm
  privé via Changesets).
- Script pnpm create-package <client|common|server> <nom> pour scaffolder
  les futurs packages.
- Documentation dans /spec (architecture, conventions, ci-cd, packages).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-18 07:10:13 +02:00

50 lines
3.1 KiB
Markdown

# Conventions
## Traçabilité des règles CLAUDE.md
| Règle CLAUDE.md | Mécanisme dans ce repo |
|---|---|
| Modificateurs d'accès explicites | Biome `useConsistentMemberAccessibility: "explicit"` (partiellement auto-fixable via `pnpm lint:fix`) ✅ |
| TSDoc sur chaque fonction/type/interface/classe/membre/méthode | TypeDoc en mode validation (`pnpm docs:check`, bloquant en CI). Biome n'a pas de règle équivalente ✅ (sauf `@lightweight-sdk/web-component`, exclu — voir `packages.md`) |
| `.catch()` obligatoire sur toute Promise non-awaited | Biome `noFloatingPromises` / `noMisusedPromises` / `useAwaitThenable` ✅ |
| `try/catch` obligatoire autour de chaque `await` individuel | **Aucun linter JS/TS courant ne vérifie ça** (ni Biome ni ESLint). Convention à appliquer soi-même à chaque nouveau package ❌ mécanisme automatique |
| Indentation "2 tabulations" | `biome.json` (`indentStyle: "tab"`, `indentWidth: 2`) + `.editorconfig` ⚠️ deux exceptions : les fichiers YAML n'acceptent pas les tabulations (interdit par la spec YAML) → 2 espaces ; le Markdown n'est pas formaté par Biome → 2 espaces par convention manuelle |
| Logging exhaustif | Convention à appliquer dans chaque nouveau package (pas de mécanisme automatique — à illustrer dans le code) |
| Séparation `.ts`/`.html`/`.scss` (Frontend) | S'applique aux futurs packages `client/` qui rendent des composants concrets avec leur propre template. Ne s'applique pas à `web-component`, qui est une bibliothèque d'abstraction sans template propre (et de toute façon non modifiée, voir `packages.md`) |
| Services modulaires autonomes (Backend) | Chaque package `server/` doit exposer sa propre API, indépendante des autres |
`pnpm lint` (= `biome check .`) tourne **sans** `--error-on-warnings` : les diagnostics de sévérité "warn" restent visibles mais ne font pas échouer la CI. Seules les erreurs bloquent.
## Imports
Sous `module: CommonJS` + `moduleResolution: Node10` (voir `architecture.md`), les imports relatifs **n'ont pas besoin** d'extension (`from "./foo"`, pas `from "./foo.js"`).
## Nommage
- Dossiers de package et noms npm : kebab-case (`@lightweight-sdk/my-package`).
- Classes : PascalCase. Fonctions/variables : camelCase.
## Tests
- Colocalisés : `src/foo.ts` + `src/foo.test.ts`.
- Environnement Vitest par défaut : `"node"`. Pour un test qui a besoin du DOM, utiliser le pragma en première ligne du fichier : `// @vitest-environment happy-dom` (ajouter `happy-dom` en devDependency le jour où c'est nécessaire).
## Exemple : convention async/erreurs/logging attendue dans un nouveau package
```ts
import { logger } from './logger';
/** Fetches and parses the remote config, throwing on failure. */
export async function loadConfig(url: string): Promise<Config> {
try {
const response = await fetch(url);
return await response.json();
} catch (error) {
logger.error('loadConfig failed', { url, error });
throw error;
}
}
// Appel fire-and-forget : .catch() obligatoire (pas d'await)
void loadConfig(configUrl).catch((error) => logger.error('background config load failed', { error }));
```