# 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 ... ```