docs: add standardized comments to all services (Python, Go, Bash)
- Add docs/commenting-standard.md defining per-language comment standards (Go godoc, Python PEP-257, C Doxygen, Bash header blocks, SQL banners) - services/dashboard: 100% docstring coverage (100/100 functions) - All FastAPI route handlers, helpers, classes, and models documented - Language: French (project convention) - services/bot-detector: 100% docstring coverage (53/53 symbols) - bot_detector.py: 14 functions + module docstring - anubis/fetch_rules.py: 9 functions - shared/python/ja4_common: full docstrings on ClickHouseClient (7 methods) and ClickHouseSettings class - services/correlator: 24 godoc comments added across 6 Go files - correlation_service.go: 10 private helpers - unixsocket/source.go: 6 parsing/socket helpers - correlated_log.go: 4 field extraction helpers - orchestrator.go, logger.go, main.go: 4 comments - services/correlator/scripts/audit-architecture.sh: standardized header block Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
210
docs/commenting-standard.md
Normal file
210
docs/commenting-standard.md
Normal file
@ -0,0 +1,210 @@
|
||||
# Standard de commentaires — ja4-platform
|
||||
|
||||
Ce document définit les conventions de commentaires pour tous les projets du monorepo.
|
||||
Toutes les nouvelles contributions doivent respecter ce standard.
|
||||
Les commentaires de **code fonctionnel** sont en **français** ; les identifiants, types, et
|
||||
noms de variables restent en anglais (convention Go / Python).
|
||||
|
||||
---
|
||||
|
||||
## Go
|
||||
|
||||
### Règles
|
||||
- Tout package public : `// Package foo fournit...`
|
||||
- Toute fonction/méthode **exportée** : commentaire godoc commençant par le nom de la fonction
|
||||
- Toute fonction/méthode **privée non triviale** (>5 lignes) : une ligne `// nomFonction fait X`
|
||||
- Structures exportées : un commentaire par champ si la sémantique n'est pas évidente
|
||||
- Pas de commentaires pour les getters/setters triviaux ni les stubs
|
||||
|
||||
### Exemple
|
||||
|
||||
```go
|
||||
// Package capture gère la capture de paquets réseau bruts via libpcap.
|
||||
package capture
|
||||
|
||||
// RawPacket représente un paquet TCP/IP brut capturé sur l'interface réseau.
|
||||
type RawPacket struct {
|
||||
Data []byte // Contenu brut du paquet (à partir de la couche Ethernet)
|
||||
Timestamp time.Time // Horodatage de capture (précision nanoseconde)
|
||||
SrcIP net.IP // Adresse IP source
|
||||
DstIP net.IP // Adresse IP destination
|
||||
}
|
||||
|
||||
// Capture définit l'interface pour la capture de paquets bruts.
|
||||
// Les implémentations doivent écouter sur une interface réseau configurée,
|
||||
// appliquer des filtres BPF et émettre des RawPacket vers un canal.
|
||||
// Close doit être appelé pour libérer le handle pcap.
|
||||
type Capture interface {
|
||||
Start(ctx context.Context) (<-chan RawPacket, error)
|
||||
Close() error
|
||||
}
|
||||
|
||||
// NewCapture crée une nouvelle instance de capture pcap sur l'interface donnée.
|
||||
// Retourne une erreur si l'interface n'existe pas ou si les droits NET_RAW sont absents.
|
||||
func NewCapture(iface string, ports []int) (Capture, error) { ... }
|
||||
|
||||
// buildBPFFilter construit le filtre BPF pour les ports et IPs locales spécifiés.
|
||||
// Format : "(tcp dst port 443) and (dst host 192.168.1.10)"
|
||||
func buildBPFFilter(ports []int, localIPs []net.IP) string { ... }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Python
|
||||
|
||||
### Règles
|
||||
- Tout module : docstring triple-guillemets en première ligne
|
||||
- Toute classe : docstring décrivant le rôle et les attributs principaux
|
||||
- Toute fonction/méthode publique : docstring une ou plusieurs lignes
|
||||
- Fonctions privées simples (`_helper`) : une ligne si non triviales
|
||||
- Routes FastAPI : docstring courte décrivant ce que renvoie l'endpoint (utilisée par Swagger/OpenAPI)
|
||||
- Langue : **français**
|
||||
|
||||
### Exemple
|
||||
|
||||
```python
|
||||
"""
|
||||
Module de détection de bots par machine learning.
|
||||
|
||||
Utilise un modèle IsolationForest entraîné sur les features comportementales
|
||||
extraites de ja4_processing.agg_host_ip_ja4_1h.
|
||||
"""
|
||||
|
||||
class BotDetector:
|
||||
"""
|
||||
Détecteur de bots basé sur IsolationForest.
|
||||
|
||||
Attributes:
|
||||
model: Modèle entraîné (None avant le premier entraînement).
|
||||
threshold: Seuil de score d'anomalie en dessous duquel un IP est flaggée.
|
||||
"""
|
||||
|
||||
def train(self, df: pd.DataFrame) -> None:
|
||||
"""
|
||||
Entraîne le modèle IsolationForest sur le DataFrame fourni.
|
||||
|
||||
Le DataFrame doit contenir les colonnes de features définies dans FEATURE_COLS.
|
||||
Le modèle précédent est remplacé à chaque appel.
|
||||
"""
|
||||
|
||||
def score_batch(self, ips: list[str]) -> dict[str, float]:
|
||||
"""Calcule le score d'anomalie pour une liste d'IPs. Retourne {ip: score}."""
|
||||
|
||||
|
||||
# --- Routes FastAPI ---
|
||||
|
||||
@router.get("/hourly")
|
||||
async def get_heatmap_hourly(db=Depends(get_db)):
|
||||
"""Retourne les hits agrégés par heure sur les 72 dernières heures."""
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## C
|
||||
|
||||
### Règles
|
||||
- Chaque fichier : bloc d'en-tête `/* filename.c — description */`
|
||||
- Chaque fonction : bloc `/** @brief description */` au-dessus de la déclaration
|
||||
- Macros complexes : commentaire inline expliquant le comportement
|
||||
- Section logique : bannière `/* ====== Nom de section ====== */`
|
||||
- Membres de struct : commentaire `/* description */` en fin de ligne si non évident
|
||||
|
||||
### Exemple
|
||||
|
||||
```c
|
||||
/*
|
||||
* mod_reqin_log.c — Module Apache HTTPD pour la journalisation JSON des requêtes HTTP.
|
||||
*
|
||||
* Ce module capture chaque requête entrante, sérialise ses métadonnées (headers,
|
||||
* IP, méthode, path) en JSON et les envoie vers une socket Unix pour le correlateur.
|
||||
*/
|
||||
|
||||
/* ====== Fonctions de buffer dynamique ====== */
|
||||
|
||||
/**
|
||||
* @brief Initialise un buffer dynamique avec une capacité initiale.
|
||||
*
|
||||
* @param buf Pointeur vers le buffer à initialiser.
|
||||
* @param pool Pool APR utilisé pour les allocations.
|
||||
* @param init Capacité initiale en octets.
|
||||
*/
|
||||
static void dynbuf_init(dynbuf_t *buf, apr_pool_t *pool, size_t init) { ... }
|
||||
|
||||
/**
|
||||
* @brief Ajoute une chaîne dans le buffer, réalloue si nécessaire.
|
||||
*
|
||||
* Croissance exponentielle (×2) pour amortir les allocations.
|
||||
* Retourne 0 en cas de succès, -1 si la taille maximale MAX_JSON_SIZE est dépassée.
|
||||
*/
|
||||
static int dynbuf_append(dynbuf_t *buf, const char *str, size_t len) { ... }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Bash
|
||||
|
||||
### Règles
|
||||
- Tout script : bloc d'en-tête standardisé avec description, Usage, et variables d'environnement
|
||||
- Toute fonction : commentaire `# nomFonction — description` sur la ligne précédente
|
||||
- Variables globales non évidentes : commentaire `# description` en fin de ligne
|
||||
|
||||
### Exemple
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
# =============================================================================
|
||||
# script.sh — Description courte du script
|
||||
#
|
||||
# Description longue si nécessaire.
|
||||
#
|
||||
# Usage:
|
||||
# ./script.sh [OPTIONS]
|
||||
#
|
||||
# Options:
|
||||
# --dry-run Simuler sans modifier
|
||||
# --verbose Afficher les détails
|
||||
#
|
||||
# Variables d'environnement:
|
||||
# CLICKHOUSE_HOST — Hôte ClickHouse (défaut: localhost)
|
||||
# CLICKHOUSE_PORT — Port natif ClickHouse (défaut: 9000)
|
||||
# =============================================================================
|
||||
set -euo pipefail
|
||||
|
||||
# log — Affiche un message horodaté sur stderr
|
||||
log() { echo "[$(date +%H:%M:%S)] $*" >&2; }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## SQL (ClickHouse)
|
||||
|
||||
### Règles
|
||||
- Chaque fichier : bannière `-- ==== filename.sql — description ====`
|
||||
- Chaque table/vue/dictionnaire : section `-- --- Nom ---` + description du rôle
|
||||
- Colonnes groupées : commentaire de groupe `-- Groupe (ex: Réseau, TLS, Métadonnées IP)`
|
||||
- TODOs de sécurité : `-- TODO: ...` clairement identifiés
|
||||
|
||||
### Exemple
|
||||
|
||||
```sql
|
||||
-- =============================================================================
|
||||
-- 01_raw_tables.sql — Tables brutes (ingestion directe du correlateur)
|
||||
--
|
||||
-- Ces tables reçoivent les logs JSON bruts du correlateur via INSERT.
|
||||
-- Le TTL d'un jour évite l'accumulation de données non traitées.
|
||||
-- =============================================================================
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- http_logs_raw — Table d'ingestion brute
|
||||
-- Reçoit les entrées du correlateur ; la MV mv_http_logs parse et enrichit.
|
||||
-- TTL : 1 jour (données transformées conservées dans http_logs)
|
||||
-- -----------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS ja4_logs.http_logs_raw
|
||||
(
|
||||
-- Identifiant de flux
|
||||
conn_id String,
|
||||
-- Payload JSON brut
|
||||
raw_json String CODEC(ZSTD(3))
|
||||
)
|
||||
ENGINE = MergeTree ...
|
||||
```
|
||||
Reference in New Issue
Block a user