Aller au contenu

Guide de contribution - ProbatioVault Backend

Merci de contribuer au projet ProbatioVault Backend ! Ce guide vous aidera à respecter les standards de qualité et les conventions du projet.


Table des matières

  1. Code de conduite
  2. Workflow de développement
  3. Standards de code
  4. Conventions de nommage
  5. Tests
  6. Commits et branches
  7. Revue de code
  8. Documentation

Code de conduite

  • Respectez les autres contributeurs
  • Soyez constructif dans vos feedbacks
  • Privilégiez la collaboration
  • Suivez les guidelines techniques

Workflow de développement

1. Créer une branche

# Format: type/PD-XX-description-courte
git checkout -b feature/PD-25-implement-srp-auth
git checkout -b fix/PD-42-fix-merkle-proof
git checkout -b refactor/PD-50-optimize-hash-service

Types de branches : - feature/ : Nouvelle fonctionnalité - fix/ : Correction de bug - refactor/ : Refactoring sans changement fonctionnel - docs/ : Documentation uniquement - test/ : Ajout/modification de tests - chore/ : Maintenance (dépendances, config, etc.)

2. Développer la fonctionnalité

# Installer les dépendances
npm install

# Lancer le mode développement
npm run start:dev

# Exécuter les tests en parallèle
npm run test:watch

3. Vérifier la qualité

# Linter + formatage
npm run lint
npm run format

# Type checking
npm run type-check

# Tests complets avec couverture
npm run test:cov

4. Commiter les changements

Voir section Commits et branches

5. Créer une Merge Request

  • Pusher la branche sur GitLab
  • Créer une MR vers dev
  • Remplir le template de MR
  • Assigner 2 reviewers minimum
  • Lier la PD correspondante

Standards de code

TypeScript strict mode

À faire :

// Types explicites
function calculateHash(data: Buffer): string {
  return sha3_256(data);
}

// Interfaces pour les objets
interface DocumentMetadata {
  name: string;
  size: number;
  mimeType: string;
}

// Nullish coalescing
const port = config.get<number>('PORT') ?? 3000;

À éviter :

// Any interdit (sauf cas exceptionnels documentés)
function process(data: any) { ... }

// Types implicites
function calculate(x, y) { ... }

// Assertions non vérifiées
const user = data as User;

ESLint

Le projet utilise des règles strictes :

// Complexité maximale
'complexity': ['warn', 15]
'max-lines-per-function': ['warn', 150]

// Sécurité
'security/detect-object-injection': 'error'
'security/detect-unsafe-regex': 'error'

// Imports organisés
'import/order': ['error', {
  'groups': ['builtin', 'external', 'internal'],
  'newlines-between': 'always',
  'alphabetize': { order: 'asc' }
}]

NestJS Best Practices

// Injection de dépendances
@Injectable()
export class DocumentsService {
  constructor(
    @InjectRepository(Document)
    private readonly documentsRepo: Repository<Document>,
    private readonly cryptoService: CryptoService,
  ) {}
}

// DTOs avec validation
export class CreateDocumentDto {
  @IsString()
  @IsNotEmpty()
  name!: string;

  @IsNumber()
  @Min(1)
  size!: number;
}

// Gestion d'erreurs explicite
if (!document) {
  throw new NotFoundException(`Document ${id} not found`);
}

Conventions de nommage

Fichiers

auth.module.ts          # Modules
auth.service.ts         # Services
auth.controller.ts      # Controllers
auth.service.spec.ts    # Tests unitaires
auth.e2e-spec.ts        # Tests E2E
login.dto.ts            # DTOs
user.entity.ts          # Entities TypeORM
jwt-auth.guard.ts       # Guards
logging.interceptor.ts  # Interceptors

Code

// Classes : PascalCase
class AuthService {}
class JwtStrategy {}

// Variables/fonctions : camelCase
const userToken = generateToken();
function validateUser() {}

// Constantes : UPPER_SNAKE_CASE
const MAX_FILE_SIZE = 10 * 1024 * 1024;
const DEFAULT_TIMEOUT = 5000;

// Interfaces : PascalCase avec I préfixe (optionnel)
interface DocumentMetadata {}
interface IUserRepository {}

// Types : PascalCase
type UserId = string;
type DocumentStatus = 'pending' | 'active' | 'archived';

// Enums : PascalCase
enum UserRole {
  Admin = 'admin',
  User = 'user',
  Guest = 'guest',
}

Tests

Couverture minimale

  • Branches : 80%
  • Functions : 85%
  • Lines : 85%
  • Statements : 85%

Structure des tests

describe('HashService', () => {
  let service: HashService;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [HashService],
    }).compile();

    service = module.get<HashService>(HashService);
  });

  describe('hash', () => {
    it('should hash data with SHA3-256', () => {
      const data = 'test';
      const hash = service.hash(data);

      expect(hash).toBeDefined();
      expect(hash.length).toBe(64);
    });

    it('should produce consistent hashes', () => {
      const hash1 = service.hash('test');
      const hash2 = service.hash('test');

      expect(hash1).toBe(hash2);
    });
  });
});

Tests obligatoires

Pour chaque service/controller : - Au moins 1 test par méthode publique - Test des cas nominaux - Test des cas d'erreur - Test des edge cases


Commits et branches

Format des commits (Conventional Commits)

<type>(<scope>): <description>

[body optionnel]

[footer optionnel]

Types : - feat: Nouvelle fonctionnalité - fix: Correction de bug - refactor: Refactoring - test: Ajout/modification de tests - docs: Documentation - style: Formatage (sans changement de code) - perf: Amélioration de performance - chore: Maintenance (dépendances, config)

Exemples :

feat(auth): implement SRP-6a authentication protocol

fix(crypto): correct AES-GCM decryption padding issue

refactor(documents): extract upload logic to separate service

test(merkle): add comprehensive Merkle tree test suite

docs(readme): update installation instructions

Branches

# Format
<type>/PD-<numero>-<description-kebab-case>

# Exemples
feature/PD-25-implement-srp-authentication
fix/PD-42-fix-merkle-proof-generation
refactor/PD-50-optimize-hash-performance

Revue de code

Checklist du développeur (avant MR)

  • Code respecte les standards ESLint/Prettier
  • TypeScript compile sans erreur ni warning
  • Tous les tests passent (couverture >= 85%)
  • Documentation à jour (JSDoc, README)
  • Pas de console.log / code de debug
  • Pas de secrets/credentials en dur
  • Pas de dépendances inutiles ajoutées
  • Commits bien formatés (Conventional Commits)

Checklist du reviewer

  • Code respecte l'architecture du projet
  • Logique métier correcte
  • Gestion d'erreurs appropriée
  • Pas de vulnérabilités de sécurité
  • Performance acceptable
  • Tests pertinents et suffisants
  • Documentation claire

Process de review

  1. 2 approbations minimum requises
  2. Pipeline CI/CD doit être verte
  3. Commentaires résolus avant merge
  4. Squash commits lors du merge (optionnel)

Documentation

JSDoc obligatoire

/**
 * Hash une donnée avec SHA3-256
 *
 * @param data - Données à hasher (string ou Buffer)
 * @returns Hash SHA3-256 en hexadécimal (64 caractères)
 * @throws {Error} Si les données sont invalides
 *
 * @example
 * const hash = hashService.hash('my data');
 * console.log(hash); // "a7b3c4d5..."
 */
hash(data: string | Buffer): string {
  // Implementation
}

Documentation à mettre à jour

Lors de changements significatifs : - [ ] README.md - [ ] Swagger/OpenAPI (via decorators NestJS) - [ ] Architecture Decision Records (ADR) - [ ] Diagrammes (si architecture modifiée)


Sécurité

Principes de sécurité

  1. Validation des entrées : Toujours valider avec class-validator
  2. Pas de secrets en dur : Utiliser les variables d'environnement
  3. Sanitization : Échapper les données utilisateur
  4. Least privilege : Permissions minimales
  5. Audit trail : Logger les actions sensibles

Rapport de vulnérabilité

Si vous découvrez une vulnérabilité : 1. NE PAS créer d'issue publique 2. Contacter l'équipe sécurité : security@probatiovault.com 3. Fournir un POC si possible


Contact

Questions ou problèmes ? Contactez l'équipe : - Slack : #probatiovault-backend - Email : dev@probatiovault.com - GitLab Issues : Pour les bugs/features