veza/veza-backend-api/internal/config/config.go

1445 lines
53 KiB
Go
Raw Normal View History

2025-12-03 19:29:37 +00:00
package config
import (
"context"
"errors"
"fmt"
2026-01-07 18:39:21 +00:00
"net/http"
2025-12-03 19:29:37 +00:00
"os"
"strconv"
"strings"
"time"
"veza-backend-api/internal/database"
P0: stabilisation backend/chat/stream + nouvelle base migrations v1 Backend Go: - Remplacement complet des anciennes migrations par la base V1 alignée sur ORIGIN. - Durcissement global du parsing JSON (BindAndValidateJSON + RespondWithAppError). - Sécurisation de config.go, CORS, statuts de santé et monitoring. - Implémentation des transactions P0 (RBAC, duplication de playlists, social toggles). - Ajout d’un job worker structuré (emails, analytics, thumbnails) + tests associés. - Nouvelle doc backend : AUDIT_CONFIG, BACKEND_CONFIG, AUTH_PASSWORD_RESET, JOB_WORKER_*. Chat server (Rust): - Refonte du pipeline JWT + sécurité, audit et rate limiting avancé. - Implémentation complète du cycle de message (read receipts, delivered, edit/delete, typing). - Nettoyage des panics, gestion d’erreurs robuste, logs structurés. - Migrations chat alignées sur le schéma UUID et nouvelles features. Stream server (Rust): - Refonte du moteur de streaming (encoding pipeline + HLS) et des modules core. - Transactions P0 pour les jobs et segments, garanties d’atomicité. - Documentation détaillée de la pipeline (AUDIT_STREAM_*, DESIGN_STREAM_PIPELINE, TRANSACTIONS_P0_IMPLEMENTATION). Documentation & audits: - TRIAGE.md et AUDIT_STABILITY.md à jour avec l’état réel des 3 services. - Cartographie complète des migrations et des transactions (DB_MIGRATIONS_*, DB_TRANSACTION_PLAN, AUDIT_DB_TRANSACTIONS, TRANSACTION_TESTS_PHASE3). - Scripts de reset et de cleanup pour la lab DB et la V1. Ce commit fige l’ensemble du travail de stabilisation P0 (UUID, backend, chat et stream) avant les phases suivantes (Coherence Guardian, WS hardening, etc.).
2025-12-06 10:14:38 +00:00
"veza-backend-api/internal/email"
2025-12-03 19:29:37 +00:00
"veza-backend-api/internal/eventbus" // Import the eventbus package
"veza-backend-api/internal/logging"
2025-12-03 19:29:37 +00:00
"veza-backend-api/internal/metrics"
"veza-backend-api/internal/middleware"
2025-12-13 02:34:34 +00:00
"veza-backend-api/internal/repositories"
2025-12-03 19:29:37 +00:00
"veza-backend-api/internal/services"
P0: stabilisation backend/chat/stream + nouvelle base migrations v1 Backend Go: - Remplacement complet des anciennes migrations par la base V1 alignée sur ORIGIN. - Durcissement global du parsing JSON (BindAndValidateJSON + RespondWithAppError). - Sécurisation de config.go, CORS, statuts de santé et monitoring. - Implémentation des transactions P0 (RBAC, duplication de playlists, social toggles). - Ajout d’un job worker structuré (emails, analytics, thumbnails) + tests associés. - Nouvelle doc backend : AUDIT_CONFIG, BACKEND_CONFIG, AUTH_PASSWORD_RESET, JOB_WORKER_*. Chat server (Rust): - Refonte du pipeline JWT + sécurité, audit et rate limiting avancé. - Implémentation complète du cycle de message (read receipts, delivered, edit/delete, typing). - Nettoyage des panics, gestion d’erreurs robuste, logs structurés. - Migrations chat alignées sur le schéma UUID et nouvelles features. Stream server (Rust): - Refonte du moteur de streaming (encoding pipeline + HLS) et des modules core. - Transactions P0 pour les jobs et segments, garanties d’atomicité. - Documentation détaillée de la pipeline (AUDIT_STREAM_*, DESIGN_STREAM_PIPELINE, TRANSACTIONS_P0_IMPLEMENTATION). Documentation & audits: - TRIAGE.md et AUDIT_STABILITY.md à jour avec l’état réel des 3 services. - Cartographie complète des migrations et des transactions (DB_MIGRATIONS_*, DB_TRANSACTION_PLAN, AUDIT_DB_TRANSACTIONS, TRANSACTION_TESTS_PHASE3). - Scripts de reset et de cleanup pour la lab DB et la V1. Ce commit fige l’ensemble du travail de stabilisation P0 (UUID, backend, chat et stream) avant les phases suivantes (Coherence Guardian, WS hardening, etc.).
2025-12-06 10:14:38 +00:00
"veza-backend-api/internal/workers"
2025-12-03 19:29:37 +00:00
"github.com/gin-gonic/gin"
"github.com/redis/go-redis/v9"
"go.uber.org/zap"
)
// Config contient toute la configuration de l'application
type Config struct {
// Base de données
Database *database.Database
// Redis
RedisClient *redis.Client
// Services
SessionService *services.SessionService
AuditService *services.AuditService
TOTPService *services.TOTPService
UploadValidator *services.UploadValidator
CacheService *services.CacheService
PlaylistService *services.PlaylistService
2025-12-03 19:29:37 +00:00
PermissionService *services.PermissionService
2025-12-13 02:34:34 +00:00
JWTService *services.JWTService
UserService *services.UserService
S3StorageService *services.S3StorageService // BE-SVC-005: S3 storage service
2025-12-03 19:29:37 +00:00
// Middlewares
RateLimiter *middleware.RateLimiter
SimpleRateLimiter *middleware.SimpleRateLimiter // Rate limiter simple (T0015)
EndpointLimiter *middleware.EndpointLimiter
UserRateLimiter *middleware.UserRateLimiter // BE-SVC-002: Per-user rate limiting
2025-12-03 19:29:37 +00:00
AuthMiddleware *middleware.AuthMiddleware
// Logger
Logger *zap.Logger
// Metrics (T0020)
ErrorMetrics *metrics.ErrorMetrics
// Secrets Provider (T0037)
SecretsProvider SecretsProvider
// Config Watcher (T0040)
ConfigWatcher *ConfigWatcher
// Configuration
Env string // Environnement: development, test, production (P0-SECURITY)
AppPort int // Port pour le serveur HTTP (T0031)
AppDomain string // Domaine applicatif (APP_DOMAIN) — single source of truth pour URLs & CORS
JWTSecret string
JWTIssuer string // T0204: Issuer claim validation (P1-SECURITY)
JWTAudience string // T0204: Audience claim validation (P1-SECURITY)
ChatJWTSecret string // Secret pour les tokens WebSocket Chat
RedisURL string
RedisEnable bool // Enable/Disable Redis
DatabaseURL string
UploadDir string // Répertoire d'upload
StreamServerURL string // URL du serveur de streaming
StreamServerInternalAPIKey string // API key for /internal/jobs/transcode (P1.1.2 - same as stream server INTERNAL_API_KEY)
ChatServerURL string // URL du serveur de chat
CORSOrigins []string // Liste des origines CORS autorisées
// S3 Storage Configuration (BE-SVC-005)
S3Bucket string // Nom du bucket S3
S3Region string // Région AWS
S3Endpoint string // Endpoint personnalisé (pour MinIO, etc.)
S3AccessKey string // Access key AWS (optionnel, utilise les credentials par défaut si vide)
S3SecretKey string // Secret key AWS (optionnel, utilise les credentials par défaut si vide)
S3Enabled bool // Activer le stockage S3
P0: stabilisation backend/chat/stream + nouvelle base migrations v1 Backend Go: - Remplacement complet des anciennes migrations par la base V1 alignée sur ORIGIN. - Durcissement global du parsing JSON (BindAndValidateJSON + RespondWithAppError). - Sécurisation de config.go, CORS, statuts de santé et monitoring. - Implémentation des transactions P0 (RBAC, duplication de playlists, social toggles). - Ajout d’un job worker structuré (emails, analytics, thumbnails) + tests associés. - Nouvelle doc backend : AUDIT_CONFIG, BACKEND_CONFIG, AUTH_PASSWORD_RESET, JOB_WORKER_*. Chat server (Rust): - Refonte du pipeline JWT + sécurité, audit et rate limiting avancé. - Implémentation complète du cycle de message (read receipts, delivered, edit/delete, typing). - Nettoyage des panics, gestion d’erreurs robuste, logs structurés. - Migrations chat alignées sur le schéma UUID et nouvelles features. Stream server (Rust): - Refonte du moteur de streaming (encoding pipeline + HLS) et des modules core. - Transactions P0 pour les jobs et segments, garanties d’atomicité. - Documentation détaillée de la pipeline (AUDIT_STREAM_*, DESIGN_STREAM_PIPELINE, TRANSACTIONS_P0_IMPLEMENTATION). Documentation & audits: - TRIAGE.md et AUDIT_STABILITY.md à jour avec l’état réel des 3 services. - Cartographie complète des migrations et des transactions (DB_MIGRATIONS_*, DB_TRANSACTION_PLAN, AUDIT_DB_TRANSACTIONS, TRANSACTION_TESTS_PHASE3). - Scripts de reset et de cleanup pour la lab DB et la V1. Ce commit fige l’ensemble du travail de stabilisation P0 (UUID, backend, chat et stream) avant les phases suivantes (Coherence Guardian, WS hardening, etc.).
2025-12-06 10:14:38 +00:00
// Sentry configuration
2025-12-13 02:34:34 +00:00
SentryDsn string // DSN Sentry pour error tracking
SentryEnvironment string // Environnement Sentry (dev, staging, prod)
SentrySampleRateErrors float64 // Sample rate pour les erreurs (0.0-1.0)
SentrySampleRateTransactions float64 // Sample rate pour les transactions (0.0-1.0)
RateLimitLimit int // Limite de requêtes pour le rate limiter simple
RateLimitWindow int // Fenêtre de temps en secondes pour le rate limiter simple
AuthRateLimitLoginAttempts int // Max login attempts (PR-3)
AuthRateLimitLoginWindow int // Login rate limit window in minutes (PR-3)
2026-02-07 19:36:48 +00:00
AccountLockoutExemptEmails []string // BE-SEC-007: Emails exempt from lockout (e.g. testuser@example.com)
2025-12-13 02:34:34 +00:00
HandlerTimeout time.Duration // Global handler timeout (PR-6)
LogLevel string // Niveau de log (T0027)
DBMaxRetries int
DBRetryInterval time.Duration
2025-12-16 18:34:08 +00:00
MaxConcurrentUploads int // MOD-P2-005: Limite uploads simultanés (backpressure)
2025-12-03 19:29:37 +00:00
// Log Aggregation (BE-SVC-015)
LogAggregationEnabled bool // Activer l'agrégation de logs
LogAggregationEndpoint string // URL du service d'agrégation (ex: "http://loki:3100/loki/api/v1/push")
LogAggregationBatchSize int // Nombre de logs à accumuler avant envoi
LogAggregationFlushInterval time.Duration // Intervalle de flush automatique
LogAggregationTimeout time.Duration // Timeout pour les requêtes HTTP
LogAggregationLabels map[string]string // Labels statiques pour les logs
// Log Files Configuration
LogDir string // Répertoire pour les fichiers de logs (ex: "/var/log/veza")
2025-12-03 19:29:37 +00:00
// RabbitMQ
RabbitMQEventBus *eventbus.RabbitMQEventBus // Ajout de l'instance de l'EventBus
RabbitMQURL string
RabbitMQMaxRetries int
RabbitMQRetryInterval time.Duration
RabbitMQEnable bool
P0: stabilisation backend/chat/stream + nouvelle base migrations v1 Backend Go: - Remplacement complet des anciennes migrations par la base V1 alignée sur ORIGIN. - Durcissement global du parsing JSON (BindAndValidateJSON + RespondWithAppError). - Sécurisation de config.go, CORS, statuts de santé et monitoring. - Implémentation des transactions P0 (RBAC, duplication de playlists, social toggles). - Ajout d’un job worker structuré (emails, analytics, thumbnails) + tests associés. - Nouvelle doc backend : AUDIT_CONFIG, BACKEND_CONFIG, AUTH_PASSWORD_RESET, JOB_WORKER_*. Chat server (Rust): - Refonte du pipeline JWT + sécurité, audit et rate limiting avancé. - Implémentation complète du cycle de message (read receipts, delivered, edit/delete, typing). - Nettoyage des panics, gestion d’erreurs robuste, logs structurés. - Migrations chat alignées sur le schéma UUID et nouvelles features. Stream server (Rust): - Refonte du moteur de streaming (encoding pipeline + HLS) et des modules core. - Transactions P0 pour les jobs et segments, garanties d’atomicité. - Documentation détaillée de la pipeline (AUDIT_STREAM_*, DESIGN_STREAM_PIPELINE, TRANSACTIONS_P0_IMPLEMENTATION). Documentation & audits: - TRIAGE.md et AUDIT_STABILITY.md à jour avec l’état réel des 3 services. - Cartographie complète des migrations et des transactions (DB_MIGRATIONS_*, DB_TRANSACTION_PLAN, AUDIT_DB_TRANSACTIONS, TRANSACTION_TESTS_PHASE3). - Scripts de reset et de cleanup pour la lab DB et la V1. Ce commit fige l’ensemble du travail de stabilisation P0 (UUID, backend, chat et stream) avant les phases suivantes (Coherence Guardian, WS hardening, etc.).
2025-12-06 10:14:38 +00:00
2026-01-07 18:39:21 +00:00
// Cookie Security Settings
CookieSecure bool // Secure flag (true en production, false en dev)
CookieSameSite string // SameSite policy: strict, lax, none
CookieDomain string // Cookie domain (vide pour domaine actuel)
CookieHttpOnly bool // HttpOnly flag (toujours true pour refresh_token)
CookiePath string // Cookie path (généralement "/")
// Hyperswitch Payment (Phase 2)
HyperswitchEnabled bool // Enable Hyperswitch payments (default false in dev)
HyperswitchURL string // Hyperswitch router URL (e.g. http://hyperswitch:8080)
HyperswitchAPIKey string // API key for Hyperswitch
HyperswitchWebhookSecret string // Webhook signature verification secret
CheckoutSuccessURL string // URL to redirect after successful payment (e.g. /checkout/success)
P0: stabilisation backend/chat/stream + nouvelle base migrations v1 Backend Go: - Remplacement complet des anciennes migrations par la base V1 alignée sur ORIGIN. - Durcissement global du parsing JSON (BindAndValidateJSON + RespondWithAppError). - Sécurisation de config.go, CORS, statuts de santé et monitoring. - Implémentation des transactions P0 (RBAC, duplication de playlists, social toggles). - Ajout d’un job worker structuré (emails, analytics, thumbnails) + tests associés. - Nouvelle doc backend : AUDIT_CONFIG, BACKEND_CONFIG, AUTH_PASSWORD_RESET, JOB_WORKER_*. Chat server (Rust): - Refonte du pipeline JWT + sécurité, audit et rate limiting avancé. - Implémentation complète du cycle de message (read receipts, delivered, edit/delete, typing). - Nettoyage des panics, gestion d’erreurs robuste, logs structurés. - Migrations chat alignées sur le schéma UUID et nouvelles features. Stream server (Rust): - Refonte du moteur de streaming (encoding pipeline + HLS) et des modules core. - Transactions P0 pour les jobs et segments, garanties d’atomicité. - Documentation détaillée de la pipeline (AUDIT_STREAM_*, DESIGN_STREAM_PIPELINE, TRANSACTIONS_P0_IMPLEMENTATION). Documentation & audits: - TRIAGE.md et AUDIT_STABILITY.md à jour avec l’état réel des 3 services. - Cartographie complète des migrations et des transactions (DB_MIGRATIONS_*, DB_TRANSACTION_PLAN, AUDIT_DB_TRANSACTIONS, TRANSACTION_TESTS_PHASE3). - Scripts de reset et de cleanup pour la lab DB et la V1. Ce commit fige l’ensemble du travail de stabilisation P0 (UUID, backend, chat et stream) avant les phases suivantes (Coherence Guardian, WS hardening, etc.).
2025-12-06 10:14:38 +00:00
// Email & Jobs
EmailSender *email.SMTPEmailSender
JobWorker *workers.JobWorker
SMTPConfig email.SMTPConfig
2025-12-03 19:29:37 +00:00
}
// INT-019: ValidateRequiredEnvironmentVariables valide toutes les variables d'environnement requises
// Cette fonction vérifie que toutes les variables critiques sont définies avant le chargement de la configuration
func ValidateRequiredEnvironmentVariables(env string) error {
var missingVars []string
var errors []string
// Variables requises dans tous les environnements
requiredVars := []string{
"JWT_SECRET",
"DATABASE_URL",
}
// Vérifier les variables requises
for _, varName := range requiredVars {
value := os.Getenv(varName)
if value == "" {
missingVars = append(missingVars, varName)
}
}
// Validation spécifique selon l'environnement
if env == EnvProduction {
// En production, CORS_ALLOWED_ORIGINS est requis
corsOrigins := os.Getenv("CORS_ALLOWED_ORIGINS")
if corsOrigins == "" {
missingVars = append(missingVars, "CORS_ALLOWED_ORIGINS")
} else {
// Vérifier qu'il n'y a pas de wildcard en production
if strings.Contains(corsOrigins, "*") {
errors = append(errors, "CORS_ALLOWED_ORIGINS cannot contain wildcard '*' in production environment")
}
}
// En production, vérifier que RabbitMQ URL est défini si RabbitMQ est activé
rabbitMQEnable := os.Getenv("RABBITMQ_ENABLE")
if rabbitMQEnable != "false" {
rabbitMQURL := os.Getenv("RABBITMQ_URL")
if rabbitMQURL == "" {
errors = append(errors, "RABBITMQ_URL is required in production when RabbitMQ is enabled")
}
}
// En production, LOG_LEVEL ne doit pas être DEBUG
logLevel := os.Getenv("LOG_LEVEL")
if logLevel == "DEBUG" {
errors = append(errors, "LOG_LEVEL=DEBUG is not allowed in production environment for security reasons")
}
}
// Construire le message d'erreur
if len(missingVars) > 0 {
errors = append(errors, fmt.Sprintf("required environment variables are missing: %v", missingVars))
}
if len(errors) > 0 {
return fmt.Errorf("environment variable validation failed: %s", strings.Join(errors, "; "))
}
return nil
}
2025-12-03 19:29:37 +00:00
// NewConfig crée une nouvelle configuration
func NewConfig() (*Config, error) {
// Déterminer l'environnement avec détection automatique améliorée (T0032, T0039)
env := DetectEnvironment()
// INT-019: Valider les variables d'environnement requises avant de charger la configuration
if err := ValidateRequiredEnvironmentVariables(env); err != nil {
return nil, fmt.Errorf("environment validation failed: %w", err)
}
2025-12-03 19:29:37 +00:00
// Charger les fichiers .env selon l'environnement (T0032)
// Charge dans l'ordre: .env.{env}, .env
// Les variables d'environnement système ont priorité
if err := LoadEnvFiles(env); err != nil {
// En cas d'erreur, continuer quand même (peut-être que les fichiers .env n'existent pas)
// Les variables d'environnement système seront utilisées
}
// FIX #2: Charger LOG_LEVEL AVANT d'initialiser le logger
// Charger le niveau de log depuis les variables d'environnement (T0027)
// Valeurs possibles: DEBUG, INFO, WARN, ERROR
// Par défaut: INFO
logLevel := getEnv("LOG_LEVEL", "INFO")
2025-12-03 19:29:37 +00:00
// Charger le domaine applicatif (single source of truth pour URLs, CORS, etc.)
appDomain := getEnv("APP_DOMAIN", "veza.fr")
P0: stabilisation backend/chat/stream + nouvelle base migrations v1 Backend Go: - Remplacement complet des anciennes migrations par la base V1 alignée sur ORIGIN. - Durcissement global du parsing JSON (BindAndValidateJSON + RespondWithAppError). - Sécurisation de config.go, CORS, statuts de santé et monitoring. - Implémentation des transactions P0 (RBAC, duplication de playlists, social toggles). - Ajout d’un job worker structuré (emails, analytics, thumbnails) + tests associés. - Nouvelle doc backend : AUDIT_CONFIG, BACKEND_CONFIG, AUTH_PASSWORD_RESET, JOB_WORKER_*. Chat server (Rust): - Refonte du pipeline JWT + sécurité, audit et rate limiting avancé. - Implémentation complète du cycle de message (read receipts, delivered, edit/delete, typing). - Nettoyage des panics, gestion d’erreurs robuste, logs structurés. - Migrations chat alignées sur le schéma UUID et nouvelles features. Stream server (Rust): - Refonte du moteur de streaming (encoding pipeline + HLS) et des modules core. - Transactions P0 pour les jobs et segments, garanties d’atomicité. - Documentation détaillée de la pipeline (AUDIT_STREAM_*, DESIGN_STREAM_PIPELINE, TRANSACTIONS_P0_IMPLEMENTATION). Documentation & audits: - TRIAGE.md et AUDIT_STABILITY.md à jour avec l’état réel des 3 services. - Cartographie complète des migrations et des transactions (DB_MIGRATIONS_*, DB_TRANSACTION_PLAN, AUDIT_DB_TRANSACTIONS, TRANSACTION_TESTS_PHASE3). - Scripts de reset et de cleanup pour la lab DB et la V1. Ce commit fige l’ensemble du travail de stabilisation P0 (UUID, backend, chat et stream) avant les phases suivantes (Coherence Guardian, WS hardening, etc.).
2025-12-06 10:14:38 +00:00
// SECURITY: Charger les origines CORS avec defaults sécurisés selon l'environnement (P0-SECURITY)
corsOrigins := getCORSOrigins(env, appDomain)
2025-12-03 19:29:37 +00:00
// Charger la configuration du rate limiter simple (A04: toujours actif, limites assouplies en dev)
rateLimitLimit := getEnvInt("RATE_LIMIT_LIMIT", getDefaultRateLimitLimit(env))
2025-12-03 19:29:37 +00:00
rateLimitWindow := getEnvInt("RATE_LIMIT_WINDOW", 60) // 60 secondes (1 minute) par défaut
// Charger le port depuis les variables d'environnement (T0031)
appPort := getEnvInt("APP_PORT", 8080)
2025-12-16 18:34:08 +00:00
// MOD-P2-005: Charger la limite d'uploads simultanés (backpressure)
maxConcurrentUploads := getEnvInt("MAX_CONCURRENT_UPLOADS", 10) // 10 par défaut
2025-12-03 19:29:37 +00:00
// Configuration depuis les variables d'environnement
P0: stabilisation backend/chat/stream + nouvelle base migrations v1 Backend Go: - Remplacement complet des anciennes migrations par la base V1 alignée sur ORIGIN. - Durcissement global du parsing JSON (BindAndValidateJSON + RespondWithAppError). - Sécurisation de config.go, CORS, statuts de santé et monitoring. - Implémentation des transactions P0 (RBAC, duplication de playlists, social toggles). - Ajout d’un job worker structuré (emails, analytics, thumbnails) + tests associés. - Nouvelle doc backend : AUDIT_CONFIG, BACKEND_CONFIG, AUTH_PASSWORD_RESET, JOB_WORKER_*. Chat server (Rust): - Refonte du pipeline JWT + sécurité, audit et rate limiting avancé. - Implémentation complète du cycle de message (read receipts, delivered, edit/delete, typing). - Nettoyage des panics, gestion d’erreurs robuste, logs structurés. - Migrations chat alignées sur le schéma UUID et nouvelles features. Stream server (Rust): - Refonte du moteur de streaming (encoding pipeline + HLS) et des modules core. - Transactions P0 pour les jobs et segments, garanties d’atomicité. - Documentation détaillée de la pipeline (AUDIT_STREAM_*, DESIGN_STREAM_PIPELINE, TRANSACTIONS_P0_IMPLEMENTATION). Documentation & audits: - TRIAGE.md et AUDIT_STABILITY.md à jour avec l’état réel des 3 services. - Cartographie complète des migrations et des transactions (DB_MIGRATIONS_*, DB_TRANSACTION_PLAN, AUDIT_DB_TRANSACTIONS, TRANSACTION_TESTS_PHASE3). - Scripts de reset et de cleanup pour la lab DB et la V1. Ce commit fige l’ensemble du travail de stabilisation P0 (UUID, backend, chat et stream) avant les phases suivantes (Coherence Guardian, WS hardening, etc.).
2025-12-06 10:14:38 +00:00
// SECURITY: JWT_SECRET est REQUIS - pas de valeur par défaut pour éviter les failles de sécurité
2025-12-13 02:34:34 +00:00
jwtSecret, err := getEnvRequired("JWT_SECRET")
if err != nil {
return nil, err
}
databaseURL, err := getEnvRequired("DATABASE_URL")
if err != nil {
return nil, err
}
// BE-SEC-014: Get RabbitMQ URL with environment-aware defaults
rabbitMQURL := getRabbitMQURL(env, appDomain)
2025-12-03 19:29:37 +00:00
config := &Config{
Env: env, // Store environment for validation (P0-SECURITY)
AppPort: appPort,
AppDomain: appDomain,
JWTSecret: jwtSecret,
2025-12-13 02:34:34 +00:00
JWTIssuer: getEnv("JWT_ISSUER", "veza-api"),
JWTAudience: getEnv("JWT_AUDIENCE", "veza-app"),
ChatJWTSecret: getEnv("CHAT_JWT_SECRET", jwtSecret), // Fallback to main JWT secret if not set
RedisURL: getEnv("REDIS_URL", "redis://"+appDomain+":6379"),
2025-12-13 02:34:34 +00:00
RedisEnable: getEnvBool("REDIS_ENABLE", true),
P0: stabilisation backend/chat/stream + nouvelle base migrations v1 Backend Go: - Remplacement complet des anciennes migrations par la base V1 alignée sur ORIGIN. - Durcissement global du parsing JSON (BindAndValidateJSON + RespondWithAppError). - Sécurisation de config.go, CORS, statuts de santé et monitoring. - Implémentation des transactions P0 (RBAC, duplication de playlists, social toggles). - Ajout d’un job worker structuré (emails, analytics, thumbnails) + tests associés. - Nouvelle doc backend : AUDIT_CONFIG, BACKEND_CONFIG, AUTH_PASSWORD_RESET, JOB_WORKER_*. Chat server (Rust): - Refonte du pipeline JWT + sécurité, audit et rate limiting avancé. - Implémentation complète du cycle de message (read receipts, delivered, edit/delete, typing). - Nettoyage des panics, gestion d’erreurs robuste, logs structurés. - Migrations chat alignées sur le schéma UUID et nouvelles features. Stream server (Rust): - Refonte du moteur de streaming (encoding pipeline + HLS) et des modules core. - Transactions P0 pour les jobs et segments, garanties d’atomicité. - Documentation détaillée de la pipeline (AUDIT_STREAM_*, DESIGN_STREAM_PIPELINE, TRANSACTIONS_P0_IMPLEMENTATION). Documentation & audits: - TRIAGE.md et AUDIT_STABILITY.md à jour avec l’état réel des 3 services. - Cartographie complète des migrations et des transactions (DB_MIGRATIONS_*, DB_TRANSACTION_PLAN, AUDIT_DB_TRANSACTIONS, TRANSACTION_TESTS_PHASE3). - Scripts de reset et de cleanup pour la lab DB et la V1. Ce commit fige l’ensemble du travail de stabilisation P0 (UUID, backend, chat et stream) avant les phases suivantes (Coherence Guardian, WS hardening, etc.).
2025-12-06 10:14:38 +00:00
// SECURITY: DATABASE_URL est REQUIS - contient des credentials sensibles
DatabaseURL: databaseURL,
UploadDir: getEnv("UPLOAD_DIR", "uploads"),
StreamServerURL: getEnv("STREAM_SERVER_URL", "http://"+appDomain+":8082"),
StreamServerInternalAPIKey: getEnv("STREAM_SERVER_INTERNAL_API_KEY", ""),
ChatServerURL: getEnv("CHAT_SERVER_URL", "http://"+appDomain+":8081"),
CORSOrigins: corsOrigins,
// S3 Storage Configuration (BE-SVC-005)
S3Bucket: getEnv("AWS_S3_BUCKET", ""),
S3Region: getEnv("AWS_REGION", "us-east-1"),
S3Endpoint: getEnv("AWS_S3_ENDPOINT", ""), // Optionnel, pour MinIO
S3AccessKey: getEnv("AWS_ACCESS_KEY_ID", ""),
S3SecretKey: getEnv("AWS_SECRET_ACCESS_KEY", ""),
S3Enabled: getEnvBool("AWS_S3_ENABLED", false), // Désactivé par défaut
P0: stabilisation backend/chat/stream + nouvelle base migrations v1 Backend Go: - Remplacement complet des anciennes migrations par la base V1 alignée sur ORIGIN. - Durcissement global du parsing JSON (BindAndValidateJSON + RespondWithAppError). - Sécurisation de config.go, CORS, statuts de santé et monitoring. - Implémentation des transactions P0 (RBAC, duplication de playlists, social toggles). - Ajout d’un job worker structuré (emails, analytics, thumbnails) + tests associés. - Nouvelle doc backend : AUDIT_CONFIG, BACKEND_CONFIG, AUTH_PASSWORD_RESET, JOB_WORKER_*. Chat server (Rust): - Refonte du pipeline JWT + sécurité, audit et rate limiting avancé. - Implémentation complète du cycle de message (read receipts, delivered, edit/delete, typing). - Nettoyage des panics, gestion d’erreurs robuste, logs structurés. - Migrations chat alignées sur le schéma UUID et nouvelles features. Stream server (Rust): - Refonte du moteur de streaming (encoding pipeline + HLS) et des modules core. - Transactions P0 pour les jobs et segments, garanties d’atomicité. - Documentation détaillée de la pipeline (AUDIT_STREAM_*, DESIGN_STREAM_PIPELINE, TRANSACTIONS_P0_IMPLEMENTATION). Documentation & audits: - TRIAGE.md et AUDIT_STABILITY.md à jour avec l’état réel des 3 services. - Cartographie complète des migrations et des transactions (DB_MIGRATIONS_*, DB_TRANSACTION_PLAN, AUDIT_DB_TRANSACTIONS, TRANSACTION_TESTS_PHASE3). - Scripts de reset et de cleanup pour la lab DB et la V1. Ce commit fige l’ensemble du travail de stabilisation P0 (UUID, backend, chat et stream) avant les phases suivantes (Coherence Guardian, WS hardening, etc.).
2025-12-06 10:14:38 +00:00
// Sentry configuration
SentryDsn: getEnv("SENTRY_DSN", ""),
SentryEnvironment: env, // Utiliser l'environnement détecté
SentrySampleRateErrors: getEnvFloat64("SENTRY_SAMPLE_RATE_ERRORS", 1.0),
P0: stabilisation backend/chat/stream + nouvelle base migrations v1 Backend Go: - Remplacement complet des anciennes migrations par la base V1 alignée sur ORIGIN. - Durcissement global du parsing JSON (BindAndValidateJSON + RespondWithAppError). - Sécurisation de config.go, CORS, statuts de santé et monitoring. - Implémentation des transactions P0 (RBAC, duplication de playlists, social toggles). - Ajout d’un job worker structuré (emails, analytics, thumbnails) + tests associés. - Nouvelle doc backend : AUDIT_CONFIG, BACKEND_CONFIG, AUTH_PASSWORD_RESET, JOB_WORKER_*. Chat server (Rust): - Refonte du pipeline JWT + sécurité, audit et rate limiting avancé. - Implémentation complète du cycle de message (read receipts, delivered, edit/delete, typing). - Nettoyage des panics, gestion d’erreurs robuste, logs structurés. - Migrations chat alignées sur le schéma UUID et nouvelles features. Stream server (Rust): - Refonte du moteur de streaming (encoding pipeline + HLS) et des modules core. - Transactions P0 pour les jobs et segments, garanties d’atomicité. - Documentation détaillée de la pipeline (AUDIT_STREAM_*, DESIGN_STREAM_PIPELINE, TRANSACTIONS_P0_IMPLEMENTATION). Documentation & audits: - TRIAGE.md et AUDIT_STABILITY.md à jour avec l’état réel des 3 services. - Cartographie complète des migrations et des transactions (DB_MIGRATIONS_*, DB_TRANSACTION_PLAN, AUDIT_DB_TRANSACTIONS, TRANSACTION_TESTS_PHASE3). - Scripts de reset et de cleanup pour la lab DB et la V1. Ce commit fige l’ensemble du travail de stabilisation P0 (UUID, backend, chat et stream) avant les phases suivantes (Coherence Guardian, WS hardening, etc.).
2025-12-06 10:14:38 +00:00
SentrySampleRateTransactions: getEnvFloat64("SENTRY_SAMPLE_RATE_TRANSACTIONS", 0.1),
RateLimitLimit: rateLimitLimit,
RateLimitWindow: rateLimitWindow,
// Augmenter les limites pour l'environnement de test/E2E
AuthRateLimitLoginAttempts: getAuthRateLimitLoginAttempts(env),
AuthRateLimitLoginWindow: getAuthRateLimitLoginWindow(env),
2026-02-07 19:36:48 +00:00
AccountLockoutExemptEmails: getEnvStringSlice("ACCOUNT_LOCKOUT_EXEMPT_EMAILS", nil),
HandlerTimeout: getEnvDuration("HANDLER_TIMEOUT", 30*time.Second), // Default: 30 seconds
LogLevel: logLevel,
Logger: nil, // Sera initialisé après selon LOG_LEVEL et agrégation
DBMaxRetries: getEnvInt("DB_MAX_RETRIES", 5), // 5 tentatives par défaut
DBRetryInterval: getEnvDuration("DB_RETRY_INTERVAL", 5*time.Second), // 5 secondes par défaut
MaxConcurrentUploads: maxConcurrentUploads, // MOD-P2-005: Limite uploads simultanés
2025-12-03 19:29:37 +00:00
// Log Aggregation Configuration (BE-SVC-015)
// FIX #26: Activer l'agrégation par défaut en production si l'endpoint est configuré
LogAggregationEndpoint: getEnv("LOG_AGGREGATION_ENDPOINT", ""), // Ex: "http://loki:3100/loki/api/v1/push"
LogAggregationBatchSize: getEnvInt("LOG_AGGREGATION_BATCH_SIZE", 100), // 100 logs par batch
LogAggregationFlushInterval: getEnvDuration("LOG_AGGREGATION_FLUSH_INTERVAL", 5*time.Second), // Flush toutes les 5 secondes
LogAggregationTimeout: getEnvDuration("LOG_AGGREGATION_TIMEOUT", 10*time.Second), // Timeout de 10 secondes
LogAggregationLabels: parseLogAggregationLabels(getEnv("LOG_AGGREGATION_LABELS", "")), // Labels au format "key1=value1,key2=value2"
2025-12-03 19:29:37 +00:00
// Configuration RabbitMQ
// BE-SEC-014: In production, require RABBITMQ_URL to be set (no default with credentials)
RabbitMQURL: rabbitMQURL,
2025-12-03 19:29:37 +00:00
RabbitMQMaxRetries: getEnvInt("RABBITMQ_MAX_RETRIES", 3), // 3 tentatives par défaut
RabbitMQRetryInterval: getEnvDuration("RABBITMQ_RETRY_INTERVAL", 2*time.Second), // 2 secondes par défaut
RabbitMQEnable: getEnvBool("RABBITMQ_ENABLE", true), // Activé par défaut
2026-01-07 18:39:21 +00:00
// Cookie Security Configuration
CookieSecure: getCookieSecure(env),
CookieSameSite: getCookieSameSite(env),
CookieDomain: getEnv("COOKIE_DOMAIN", ""),
CookieHttpOnly: getEnvBool("COOKIE_HTTP_ONLY", true),
CookiePath: getEnv("COOKIE_PATH", "/"),
// Hyperswitch Payment Configuration
HyperswitchEnabled: getEnvBool("HYPERSWITCH_ENABLED", false),
HyperswitchURL: getEnv("HYPERSWITCH_URL", "http://localhost:18081"),
HyperswitchAPIKey: getEnv("HYPERSWITCH_API_KEY", ""),
HyperswitchWebhookSecret: getEnv("HYPERSWITCH_WEBHOOK_SECRET", ""),
CheckoutSuccessURL: getEnv("CHECKOUT_SUCCESS_URL", ""),
// Log Files Configuration
// En développement, utiliser ./logs si /var/log n'est pas accessible
LogDir: func() string {
logDir := getEnv("LOG_DIR", "/var/log/veza")
// En développement, préférer un répertoire local si /var/log n'est pas accessible
if env == EnvDevelopment || env == "dev" {
if logDir == "/var/log/veza" {
// Essayer de créer le répertoire pour vérifier les permissions
if err := os.MkdirAll("/var/log/veza", 0755); err != nil {
// Si échec, utiliser ./logs
return "./logs"
}
// Vérifier qu'on peut écrire dedans en créant un fichier test
testFile := "/var/log/veza/.test_write"
if f, err := os.Create(testFile); err != nil {
// Ne peut pas écrire, utiliser ./logs
return "./logs"
} else {
f.Close()
os.Remove(testFile)
}
}
}
return logDir
}(),
2025-12-03 19:29:37 +00:00
}
// Initialiser le SecretsProvider (T0037)
secretKeys := DefaultSecretKeys()
config.SecretsProvider = NewEnvSecretsProvider(secretKeys)
// FIX #26: Activer l'agrégation par défaut en production si l'endpoint est configuré
// Si LOG_AGGREGATION_ENABLED est explicitement défini, l'utiliser
// Sinon, activer automatiquement en production si l'endpoint est configuré
logAggregationEndpoint := config.LogAggregationEndpoint
explicitlyEnabled := os.Getenv("LOG_AGGREGATION_ENABLED") != ""
var logAggregationEnabled bool
if explicitlyEnabled {
// Si explicitement défini, respecter la valeur
logAggregationEnabled = getEnvBool("LOG_AGGREGATION_ENABLED", false)
} else {
// Sinon, activer par défaut en production si l'endpoint est configuré
logAggregationEnabled = (env == EnvProduction || env == EnvStaging) && logAggregationEndpoint != ""
}
config.LogAggregationEnabled = logAggregationEnabled
// FIX #2: Initialiser le logger avec le bon niveau (LOG_LEVEL respecté)
// BE-SVC-015: Utiliser logger avec agrégation si activée, sinon logger standard
var logger *zap.Logger
if config.LogAggregationEnabled && config.LogAggregationEndpoint != "" {
aggConfig := &logging.AggregationConfig{
EndpointURL: config.LogAggregationEndpoint,
Enabled: true,
BatchSize: config.LogAggregationBatchSize,
FlushInterval: config.LogAggregationFlushInterval,
Timeout: config.LogAggregationTimeout,
Labels: config.LogAggregationLabels,
}
// Ajouter des labels par défaut si non définis
if aggConfig.Labels == nil {
aggConfig.Labels = make(map[string]string)
}
if _, exists := aggConfig.Labels["service"]; !exists {
aggConfig.Labels["service"] = "veza-api"
}
if _, exists := aggConfig.Labels["env"]; !exists {
aggConfig.Labels["env"] = env
}
aggLogger, err := logging.NewLoggerWithAggregation(env, logLevel, aggConfig)
if err != nil {
// FIX #27: Fallback vers logger optimisé (asynchrone) si agrégation échoue
// En production/staging, utiliser logger optimisé pour performance
var stdLogger *logging.Logger
var err2 error
if env == EnvProduction || env == EnvStaging {
stdLogger, err2 = logging.NewOptimizedLogger(env, logLevel)
if err2 != nil {
return nil, fmt.Errorf("failed to initialize optimized logger: %w", err2)
}
} else {
stdLogger, err2 = logging.NewLogger(env, logLevel)
if err2 != nil {
return nil, fmt.Errorf("failed to initialize logger: %w", err2)
}
}
logger = stdLogger.GetZapLogger()
logger.Warn("Failed to initialize logger with aggregation, using optimized logger",
zap.Error(err),
zap.String("endpoint", config.LogAggregationEndpoint),
)
} else {
logger = aggLogger.GetZapLogger()
logger.Info("Logger with aggregation initialized",
zap.String("endpoint", config.LogAggregationEndpoint),
zap.Int("batch_size", config.LogAggregationBatchSize),
zap.String("log_level", logLevel),
)
}
} else {
// Utiliser logger avec fichiers de rotation vers /var/log/veza/
// Crée deux fichiers : backend-api.log (tous les logs) et backend-api-error.log (erreurs uniquement)
stdLogger, err := logging.NewLoggerWithFileRotation(config.LogDir, "backend-api", env, logLevel)
if err != nil {
return nil, fmt.Errorf("failed to initialize logger with file rotation: %w", err)
}
logger = stdLogger.GetZapLogger()
// Log initialization message - ignore any broken pipe errors silently
// This is the first log message after logger initialization and may trigger broken pipe
// if systemd journald is not ready or stdout/stderr is redirected incorrectly
func() {
defer func() {
if r := recover(); r != nil {
// Silently ignore panics from logger (shouldn't happen, but be safe)
_ = r
}
}()
logger.Info("Logger initialized with file rotation",
zap.String("log_level", logLevel),
zap.String("env", env),
zap.String("log_dir", config.LogDir),
zap.String("all_logs_file", fmt.Sprintf("%s/backend-api.log", config.LogDir)),
zap.String("error_logs_file", fmt.Sprintf("%s/backend-api-error.log", config.LogDir)),
)
}()
}
// FIX #30: Appliquer le filtre de secrets au logger
logger = logging.WrapLoggerWithSecretFilter(logger)
// Assigner le logger à la config
config.Logger = logger
P0: stabilisation backend/chat/stream + nouvelle base migrations v1 Backend Go: - Remplacement complet des anciennes migrations par la base V1 alignée sur ORIGIN. - Durcissement global du parsing JSON (BindAndValidateJSON + RespondWithAppError). - Sécurisation de config.go, CORS, statuts de santé et monitoring. - Implémentation des transactions P0 (RBAC, duplication de playlists, social toggles). - Ajout d’un job worker structuré (emails, analytics, thumbnails) + tests associés. - Nouvelle doc backend : AUDIT_CONFIG, BACKEND_CONFIG, AUTH_PASSWORD_RESET, JOB_WORKER_*. Chat server (Rust): - Refonte du pipeline JWT + sécurité, audit et rate limiting avancé. - Implémentation complète du cycle de message (read receipts, delivered, edit/delete, typing). - Nettoyage des panics, gestion d’erreurs robuste, logs structurés. - Migrations chat alignées sur le schéma UUID et nouvelles features. Stream server (Rust): - Refonte du moteur de streaming (encoding pipeline + HLS) et des modules core. - Transactions P0 pour les jobs et segments, garanties d’atomicité. - Documentation détaillée de la pipeline (AUDIT_STREAM_*, DESIGN_STREAM_PIPELINE, TRANSACTIONS_P0_IMPLEMENTATION). Documentation & audits: - TRIAGE.md et AUDIT_STABILITY.md à jour avec l’état réel des 3 services. - Cartographie complète des migrations et des transactions (DB_MIGRATIONS_*, DB_TRANSACTION_PLAN, AUDIT_DB_TRANSACTIONS, TRANSACTION_TESTS_PHASE3). - Scripts de reset et de cleanup pour la lab DB et la V1. Ce commit fige l’ensemble du travail de stabilisation P0 (UUID, backend, chat et stream) avant les phases suivantes (Coherence Guardian, WS hardening, etc.).
2025-12-06 10:14:38 +00:00
// SECURITY: Valider la configuration selon l'environnement (P0-SECURITY)
if err := config.ValidateForEnvironment(); err != nil {
// CRITICAL: Protect logger calls from broken pipe errors
func() {
defer func() {
if r := recover(); r != nil {
_ = r
}
}()
logger.Error("Configuration validation failed", zap.Error(err), zap.String("env", env))
}()
2025-12-03 19:29:37 +00:00
return nil, fmt.Errorf("invalid configuration: %w", err)
}
2025-12-13 02:34:34 +00:00
// Warn if CORS is strict/empty in production (MOD-P0-002)
if env == EnvProduction && len(config.CORSOrigins) == 0 {
// CRITICAL: Protect logger calls from broken pipe errors
func() {
defer func() {
if r := recover(); r != nil {
_ = r
}
}()
logger.Warn("CORS_ALLOWED_ORIGINS is empty in production. Strict mode enabled: ALL CORS requests will be rejected.")
}()
2025-12-13 02:34:34 +00:00
}
// Créer des loggers séparés pour chaque module
redisLoggerWrapper, err := logging.NewLoggerWithFileRotation(config.LogDir, "redis", env, logLevel)
var redisLoggerZap *zap.Logger
if err != nil {
// CRITICAL: Protect logger calls from broken pipe errors
func() {
defer func() {
if r := recover(); r != nil {
_ = r
}
}()
logger.Warn("Failed to create Redis logger, using main logger", zap.Error(err))
}()
redisLoggerZap = logger
} else {
redisLoggerZap = logging.WrapLoggerWithSecretFilter(redisLoggerWrapper.GetZapLogger())
}
dbLoggerWrapper, err := logging.NewLoggerWithFileRotation(config.LogDir, "db", env, logLevel)
var dbLoggerZap *zap.Logger
if err != nil {
// CRITICAL: Protect logger calls from broken pipe errors
func() {
defer func() {
if r := recover(); r != nil {
_ = r
}
}()
logger.Warn("Failed to create DB logger, using main logger", zap.Error(err))
}()
dbLoggerZap = logger
} else {
dbLoggerZap = logging.WrapLoggerWithSecretFilter(dbLoggerWrapper.GetZapLogger())
}
rabbitmqLoggerWrapper, err := logging.NewLoggerWithFileRotation(config.LogDir, "rabbitmq", env, logLevel)
var rabbitmqLoggerZap *zap.Logger
if err != nil {
// CRITICAL: Protect logger calls from broken pipe errors
func() {
defer func() {
if r := recover(); r != nil {
_ = r
}
}()
logger.Warn("Failed to create RabbitMQ logger, using main logger", zap.Error(err))
}()
rabbitmqLoggerZap = logger
} else {
rabbitmqLoggerZap = logging.WrapLoggerWithSecretFilter(rabbitmqLoggerWrapper.GetZapLogger())
}
2025-12-03 19:29:37 +00:00
// Initialiser Redis
2025-12-13 02:34:34 +00:00
if config.RedisEnable {
config.RedisClient, err = initRedis(config.RedisURL, redisLoggerZap)
2025-12-13 02:34:34 +00:00
if err != nil {
// CRITICAL: Protect logger calls from broken pipe errors
func() {
defer func() {
if r := recover(); r != nil {
_ = r
}
}()
logger.Error("Failed to initialize Redis", zap.Error(err))
}()
2025-12-13 02:34:34 +00:00
return nil, err
}
} else {
// CRITICAL: Protect logger calls from broken pipe errors
func() {
defer func() {
if r := recover(); r != nil {
_ = r
}
}()
logger.Warn("Redis désactivé par configuration (REDIS_ENABLE=false)")
}()
2025-12-03 19:29:37 +00:00
}
// Initialiser la base de données avec retry
config.Database, err = initDatabaseWithRetry(config.DatabaseURL, config.DBMaxRetries, config.DBRetryInterval, dbLoggerZap)
2025-12-03 19:29:37 +00:00
if err != nil {
// CRITICAL: Protect logger calls from broken pipe errors
func() {
defer func() {
if r := recover(); r != nil {
_ = r
}
}()
logger.Error("Failed to initialize database", zap.Error(err))
}()
return nil, fmt.Errorf("failed to initialize database: %w", err)
2025-12-03 19:29:37 +00:00
}
// Initialiser RabbitMQ avec retry
config.RabbitMQEventBus, err = eventbus.NewRabbitMQEventBusWithRetry(&eventbus.RabbitMQConfig{
URL: config.RabbitMQURL,
MaxRetries: config.RabbitMQMaxRetries,
RetryInterval: config.RabbitMQRetryInterval,
Enable: config.RabbitMQEnable,
}, rabbitmqLoggerZap)
2025-12-03 19:29:37 +00:00
if err != nil {
// En mode dégradé, l'erreur n'est pas fatale au démarrage du service
if _, ok := err.(*eventbus.EventBusUnavailableError); ok && !config.RabbitMQEnable {
logger.Warn("RabbitMQ EventBus est indisponible mais le service démarre en mode dégradé.", zap.Error(err))
} else if _, ok := err.(*eventbus.EventBusUnavailableError); ok {
// Si le service est censé être enabled et qu'il est injoignable après retries
logger.Fatal("Impossible de se connecter à RabbitMQ après plusieurs tentatives. Le service ne peut pas démarrer.", zap.Error(err))
return nil, err // Retourner l'erreur fatale
} else {
logger.Error("Failed to initialize RabbitMQ EventBus", zap.Error(err))
return nil, err
}
}
// BE-SVC-005: Initialiser le service S3 si activé
if config.S3Enabled && config.S3Bucket != "" {
s3Service, err := services.NewS3StorageService(services.S3Config{
Bucket: config.S3Bucket,
Region: config.S3Region,
Endpoint: config.S3Endpoint,
AccessKey: config.S3AccessKey,
SecretKey: config.S3SecretKey,
Logger: logger,
})
if err != nil {
logger.Warn("Failed to initialize S3 storage service, falling back to local storage",
zap.Error(err),
zap.String("bucket", config.S3Bucket),
)
config.S3Enabled = false
} else {
config.S3StorageService = s3Service
logger.Info("S3 storage service initialized successfully",
zap.String("bucket", config.S3Bucket),
zap.String("region", config.S3Region),
)
}
}
2025-12-03 19:29:37 +00:00
// Initialiser les services
err = config.initServices()
if err != nil {
logger.Error("Failed to initialize services", zap.Error(err))
return nil, err
}
// Initialiser les middlewares
err = config.initMiddlewares()
if err != nil {
logger.Error("Failed to initialize middlewares", zap.Error(err))
return nil, err
}
// Initialiser les métriques d'erreurs (T0020)
config.ErrorMetrics = metrics.NewErrorMetrics()
P0: stabilisation backend/chat/stream + nouvelle base migrations v1 Backend Go: - Remplacement complet des anciennes migrations par la base V1 alignée sur ORIGIN. - Durcissement global du parsing JSON (BindAndValidateJSON + RespondWithAppError). - Sécurisation de config.go, CORS, statuts de santé et monitoring. - Implémentation des transactions P0 (RBAC, duplication de playlists, social toggles). - Ajout d’un job worker structuré (emails, analytics, thumbnails) + tests associés. - Nouvelle doc backend : AUDIT_CONFIG, BACKEND_CONFIG, AUTH_PASSWORD_RESET, JOB_WORKER_*. Chat server (Rust): - Refonte du pipeline JWT + sécurité, audit et rate limiting avancé. - Implémentation complète du cycle de message (read receipts, delivered, edit/delete, typing). - Nettoyage des panics, gestion d’erreurs robuste, logs structurés. - Migrations chat alignées sur le schéma UUID et nouvelles features. Stream server (Rust): - Refonte du moteur de streaming (encoding pipeline + HLS) et des modules core. - Transactions P0 pour les jobs et segments, garanties d’atomicité. - Documentation détaillée de la pipeline (AUDIT_STREAM_*, DESIGN_STREAM_PIPELINE, TRANSACTIONS_P0_IMPLEMENTATION). Documentation & audits: - TRIAGE.md et AUDIT_STABILITY.md à jour avec l’état réel des 3 services. - Cartographie complète des migrations et des transactions (DB_MIGRATIONS_*, DB_TRANSACTION_PLAN, AUDIT_DB_TRANSACTIONS, TRANSACTION_TESTS_PHASE3). - Scripts de reset et de cleanup pour la lab DB et la V1. Ce commit fige l’ensemble du travail de stabilisation P0 (UUID, backend, chat et stream) avant les phases suivantes (Coherence Guardian, WS hardening, etc.).
2025-12-06 10:14:38 +00:00
// Initialiser la configuration SMTP
config.SMTPConfig = email.LoadSMTPConfigFromEnv()
config.EmailSender = email.NewSMTPEmailSender(config.SMTPConfig, logger)
// Initialiser le JobService
jobService := services.NewJobService(logger)
// Initialiser le JobWorker
config.JobWorker = workers.NewJobWorker(
config.Database.GormDB,
jobService,
logger,
100, // queueSize
3, // workers
3, // maxRetries
P0: stabilisation backend/chat/stream + nouvelle base migrations v1 Backend Go: - Remplacement complet des anciennes migrations par la base V1 alignée sur ORIGIN. - Durcissement global du parsing JSON (BindAndValidateJSON + RespondWithAppError). - Sécurisation de config.go, CORS, statuts de santé et monitoring. - Implémentation des transactions P0 (RBAC, duplication de playlists, social toggles). - Ajout d’un job worker structuré (emails, analytics, thumbnails) + tests associés. - Nouvelle doc backend : AUDIT_CONFIG, BACKEND_CONFIG, AUTH_PASSWORD_RESET, JOB_WORKER_*. Chat server (Rust): - Refonte du pipeline JWT + sécurité, audit et rate limiting avancé. - Implémentation complète du cycle de message (read receipts, delivered, edit/delete, typing). - Nettoyage des panics, gestion d’erreurs robuste, logs structurés. - Migrations chat alignées sur le schéma UUID et nouvelles features. Stream server (Rust): - Refonte du moteur de streaming (encoding pipeline + HLS) et des modules core. - Transactions P0 pour les jobs et segments, garanties d’atomicité. - Documentation détaillée de la pipeline (AUDIT_STREAM_*, DESIGN_STREAM_PIPELINE, TRANSACTIONS_P0_IMPLEMENTATION). Documentation & audits: - TRIAGE.md et AUDIT_STABILITY.md à jour avec l’état réel des 3 services. - Cartographie complète des migrations et des transactions (DB_MIGRATIONS_*, DB_TRANSACTION_PLAN, AUDIT_DB_TRANSACTIONS, TRANSACTION_TESTS_PHASE3). - Scripts de reset et de cleanup pour la lab DB et la V1. Ce commit fige l’ensemble du travail de stabilisation P0 (UUID, backend, chat et stream) avant les phases suivantes (Coherence Guardian, WS hardening, etc.).
2025-12-06 10:14:38 +00:00
config.EmailSender, // emailSender
)
// BE-SVC-003: Connect JobService to JobWorker
jobService.SetJobEnqueuer(config.JobWorker)
2025-12-03 19:29:37 +00:00
// Logger la configuration avec masquage des secrets (T0037)
config.logConfigInitialized(logger)
// Initialiser le ConfigWatcher si activé (T0040)
// Le watcher peut être activé via une variable d'environnement CONFIG_WATCH=true
if getEnv("CONFIG_WATCH", "false") == "true" {
reloader := config.GetConfigReloader()
watcher, err := NewConfigWatcher(reloader, logger)
if err != nil {
logger.Warn("Failed to create config watcher", zap.Error(err))
} else {
config.ConfigWatcher = watcher
// Surveiller les fichiers .env
envFiles := []string{".env", ".env." + env}
if err := watcher.Watch(envFiles); err != nil {
logger.Warn("Failed to start watching config files", zap.Error(err))
} else {
logger.Info("Config watcher started", zap.Strings("files", watcher.GetWatchedFiles()))
}
}
}
return config, nil
}
// GetConfigReloader retourne le ConfigReloader pour cette configuration (T0034)
func (c *Config) GetConfigReloader() *ConfigReloader {
return NewConfigReloader(c, c.Logger)
}
// initServices initialise tous les services
func (c *Config) initServices() error {
// Service de session
c.SessionService = services.NewSessionService(c.Database, c.Logger)
// Service d'audit
c.AuditService = services.NewAuditService(c.Database, c.Logger)
// Service TOTP
c.TOTPService = services.NewTOTPService(c.Database, c.Logger)
// Validateur d'upload
uploadConfig := services.DefaultUploadConfig()
// Lire ENABLE_CLAMAV depuis l'environnement (défaut: true pour sécurité en production)
// En développement, peut être désactivé si ClamAV n'est pas disponible
clamAVEnabled := getEnvBool("ENABLE_CLAMAV", true)
uploadConfig.ClamAVEnabled = clamAVEnabled
if !clamAVEnabled {
c.Logger.Warn("ENABLE_CLAMAV=false - ClamAV virus scanning is disabled. This should only be used in development environments.")
}
2025-12-16 18:34:08 +00:00
// MOD-P1-002: Lire CLAMAV_REQUIRED depuis l'environnement (défaut: true pour sécurité)
clamAVRequired := getEnvBool("CLAMAV_REQUIRED", true)
uploadConfig.ClamAVRequired = clamAVRequired
if !clamAVRequired {
c.Logger.Warn("CLAMAV_REQUIRED=false - Uploads will be accepted even if ClamAV is unavailable (degraded mode). This should only be used in development or with alternative security measures.")
}
// Chemin vers clamdscan (exec) - remplace go-clamd abandonné
if p := getEnv("CLAMAV_CLAMD_PATH", ""); p != "" {
uploadConfig.ClamAVClamdPath = p
}
2025-12-03 19:29:37 +00:00
var err error
c.UploadValidator, err = services.NewUploadValidator(uploadConfig, c.Logger)
if err != nil {
return err
}
// Service de cache
c.CacheService = services.NewCacheService(c.RedisClient, c.Logger)
// Service de playlist
c.PlaylistService = services.NewPlaylistServiceWithDB(c.Database.GormDB, c.Logger)
// Service de permissions
c.PermissionService = services.NewPermissionService(c.Database.GormDB)
2025-12-13 02:34:34 +00:00
// JWT Service
c.JWTService, err = services.NewJWTService(c.JWTSecret, c.JWTIssuer, c.JWTAudience)
if err != nil {
return err
}
// User Service
userRepo := repositories.NewGormUserRepository(c.Database.GormDB)
c.UserService = services.NewUserServiceWithDB(userRepo, c.Database.GormDB)
// BE-SVC-001: Set cache service for UserService
if c.CacheService != nil {
c.UserService.SetCacheService(c.CacheService)
}
// BE-SVC-001: Set cache service for PlaylistService
if c.CacheService != nil && c.PlaylistService != nil {
c.PlaylistService.SetCacheService(c.CacheService)
}
2025-12-13 02:34:34 +00:00
2025-12-03 19:29:37 +00:00
return nil
}
// initMiddlewares initialise tous les middlewares
func (c *Config) initMiddlewares() error {
// Rate limiter global (avec Redis)
// En développement, augmenter les limites pour éviter les erreurs lors des tests
// Utiliser getEnvInt au lieu de getEnvAsInt (qui n'existe peut-être pas)
ipLimit := getEnvInt("RATE_LIMIT_IP_PER_MINUTE", 200) // Augmenté de 100 à 200 en dev
ipBurst := getEnvInt("RATE_LIMIT_IP_BURST", 20) // Augmenté de 10 à 20 en dev
userLimit := getEnvInt("RATE_LIMIT_USER_PER_MINUTE", 1000)
userBurst := getEnvInt("RATE_LIMIT_USER_BURST", 100)
2025-12-03 19:29:37 +00:00
rateLimiterConfig := &middleware.RateLimiterConfig{
IPRequestsPerMinute: ipLimit,
IPBurst: ipBurst,
UserRequestsPerMinute: userLimit,
UserBurst: userBurst,
2025-12-03 19:29:37 +00:00
RedisClient: c.RedisClient,
KeyPrefix: "veza:rate_limit",
}
c.RateLimiter = middleware.NewRateLimiter(rateLimiterConfig)
// Simple rate limiter (T0015) - sans dépendance Redis
window := time.Duration(c.RateLimitWindow) * time.Second
c.SimpleRateLimiter = middleware.NewSimpleRateLimiter(c.RateLimitLimit, window)
// Rate limiter par endpoint
endpointLimiterConfig := &middleware.EndpointLimiterConfig{
RedisClient: c.RedisClient,
KeyPrefix: "veza:endpoint_limit",
}
endpointLimits := middleware.DefaultEndpointLimits()
2025-12-13 02:34:34 +00:00
// Override defaults with config (PR-3)
endpointLimits.LoginAttempts = c.AuthRateLimitLoginAttempts
endpointLimits.LoginWindow = time.Duration(c.AuthRateLimitLoginWindow) * time.Minute
// A04: Limites register assouplies en dev (20/heure au lieu de 3/heure)
endpointLimits.RegisterAttempts = getDefaultRegisterAttempts(c.Env)
endpointLimits.RegisterWindow = time.Hour
2025-12-13 02:34:34 +00:00
2025-12-03 19:29:37 +00:00
c.EndpointLimiter = middleware.NewEndpointLimiter(endpointLimiterConfig, endpointLimits)
// BE-SVC-002: Initialize per-user rate limiter
userRateLimiterConfig := &middleware.UserRateLimiterConfig{
RequestsPerMinute: getEnvAsInt("USER_RATE_LIMIT_PER_MINUTE", 1000), // Default: 1000 requests per minute per user
Burst: getEnvAsInt("USER_RATE_LIMIT_BURST", 100), // Default: 100 burst
Window: time.Minute,
RedisClient: c.RedisClient,
KeyPrefix: "user_rate_limit",
Logger: c.Logger,
}
c.UserRateLimiter = middleware.NewUserRateLimiter(userRateLimiterConfig)
2025-12-03 19:29:37 +00:00
// Middleware d'authentification
c.AuthMiddleware = middleware.NewAuthMiddleware(
c.SessionService,
c.AuditService,
c.PermissionService,
2025-12-13 02:34:34 +00:00
c.JWTService,
c.UserService,
2025-12-03 19:29:37 +00:00
c.Logger,
)
return nil
}
// NOTE: Les handlers ne sont plus initialisés dans Config pour éviter les imports cycliques.
// Les handlers doivent être créés dans main.go ou dans les routes selon les besoins.
//
// SetupRoutes a été supprimé pour casser le cycle d'import config <-> api.
// Utiliser directement api.SetupRoutes() dans cmd/modern-server/main.go
// SetupMiddleware configure les middlewares globaux
// DÉPRÉCIÉ : Cette méthode est conservée pour compatibilité mais ne fait plus rien
// Les middlewares globaux sont maintenant configurés dans internal/api/router.go via APIRouter.Setup()
// TODO: Améliorer la configuration CORS dans api/router.go pour utiliser c.CORSOrigins depuis la config
func (c *Config) SetupMiddleware(router *gin.Engine) {
// No-op : Les middlewares sont configurés dans api/router.go
// Cette méthode existe uniquement pour compatibilité avec cmd/main.go (legacy)
// qui sera désactivé dans le Chantier 1 - Étape 2
}
// initRedis initialise la connexion Redis
func initRedis(redisURL string, logger *zap.Logger) (*redis.Client, error) {
2025-12-03 19:29:37 +00:00
opts, err := redis.ParseURL(redisURL)
if err != nil {
return nil, err
}
// Configurer un logger filtré pour Redis pour éviter les warnings "maint_notifications"
redis.SetLogger(&filteredRedisLogger{logger: logger})
2025-12-03 19:29:37 +00:00
client := redis.NewClient(opts)
// Test de connexion
ctx := context.Background()
_, err = client.Ping(ctx).Result()
if err != nil {
return nil, err
}
return client, nil
}
// filteredRedisLogger est un wrapper pour filtrer les logs de Redis
type filteredRedisLogger struct {
logger *zap.Logger
}
func (l *filteredRedisLogger) Printf(ctx context.Context, format string, v ...interface{}) {
msg := fmt.Sprintf(format, v...)
if strings.Contains(msg, "maint_notifications") {
return // Ignorer ce warning spécifique en mode auto-discovery
}
l.logger.Debug("Redis internal", zap.String("message", msg))
}
2025-12-03 19:29:37 +00:00
// initDatabaseWithRetry initialise la connexion à la base de données avec des tentatives de retry
func initDatabaseWithRetry(databaseURL string, maxRetries int, retryInterval time.Duration, logger *zap.Logger) (*database.Database, error) {
dbConfig := &database.Config{
URL: databaseURL,
// BE-DB-015: Optimized connection pool settings for production
// MaxOpenConns: Recommended formula: (2 * CPU cores) + effective_spindle_count
// Default: 25 for small-medium apps, 50-100 for high-traffic apps
MaxOpenConns: getEnvAsInt("DB_MAX_OPEN_CONNS", 50),
// MaxIdleConns: Should be ~25% of MaxOpenConns to maintain warm connections
MaxIdleConns: getEnvAsInt("DB_MAX_IDLE_CONNS", 12),
// MaxLifetime: 5-15 minutes recommended to avoid connection timeouts
// PostgreSQL default idle_in_transaction_session_timeout is 0 (unlimited)
MaxLifetime: getEnvAsDuration("DB_MAX_LIFETIME", 10*time.Minute),
// MaxIdleTime: 5-10 minutes to close idle connections and free resources
MaxIdleTime: getEnvAsDuration("DB_MAX_IDLE_TIME", 5*time.Minute),
2025-12-03 19:29:37 +00:00
MaxRetries: maxRetries,
RetryInterval: retryInterval,
}
// Utiliser la fonction de connexion avec retry du package database
return database.NewDatabaseWithRetry(dbConfig, logger)
}
// EnvConfig représente la configuration de base chargée depuis les variables d'environnement
// Cette struct est utilisée par la fonction Load() pour charger la configuration de base
type EnvConfig struct {
AppEnv string
AppPort int
DBHost string
DBPort int
DBUser string
DBPassword string
DBName string
JWTSecret string
RedisURL string
CORSOrigins []string // Liste des origines CORS autorisées
}
// Load charge et valide les variables d'environnement avec valeurs par défaut
func Load() (*EnvConfig, error) {
// Déterminer l'environnement (T0032)
env := getEnv("APP_ENV", "development")
// Charger les fichiers .env selon l'environnement (T0032)
// Charge dans l'ordre: .env.{env}, .env
// Les variables d'environnement système ont priorité
if err := LoadEnvFiles(env); err != nil {
return nil, fmt.Errorf("failed to load environment files: %w", err)
}
// Charger les origines CORS depuis les variables d'environnement
corsOrigins := getEnvStringSlice("CORS_ALLOWED_ORIGINS", []string{"*"})
2025-12-13 02:34:34 +00:00
// Database, JWTSecret are required
dbPassword, err := getEnvRequired("DB_PASSWORD")
if err != nil {
return nil, err
}
jwtSecret, err := getEnvRequired("JWT_SECRET")
if err != nil {
return nil, err
}
envDomain := getEnv("APP_DOMAIN", "veza.fr")
2025-12-03 19:29:37 +00:00
config := &EnvConfig{
AppEnv: getEnv("APP_ENV", "development"),
AppPort: getEnvInt("APP_PORT", 8080),
DBHost: getEnv("DB_HOST", envDomain),
2025-12-03 19:29:37 +00:00
DBPort: getEnvInt("DB_PORT", 5432),
DBUser: getEnv("DB_USER", "veza"),
2025-12-13 02:34:34 +00:00
DBPassword: dbPassword,
2025-12-03 19:29:37 +00:00
DBName: getEnv("DB_NAME", "veza_db"),
2025-12-13 02:34:34 +00:00
JWTSecret: jwtSecret,
RedisURL: getEnv("REDIS_URL", "redis://"+envDomain+":6379"),
2025-12-03 19:29:37 +00:00
CORSOrigins: corsOrigins,
}
return config, nil
}
// getEnv récupère une variable d'environnement avec une valeur par défaut
P0: stabilisation backend/chat/stream + nouvelle base migrations v1 Backend Go: - Remplacement complet des anciennes migrations par la base V1 alignée sur ORIGIN. - Durcissement global du parsing JSON (BindAndValidateJSON + RespondWithAppError). - Sécurisation de config.go, CORS, statuts de santé et monitoring. - Implémentation des transactions P0 (RBAC, duplication de playlists, social toggles). - Ajout d’un job worker structuré (emails, analytics, thumbnails) + tests associés. - Nouvelle doc backend : AUDIT_CONFIG, BACKEND_CONFIG, AUTH_PASSWORD_RESET, JOB_WORKER_*. Chat server (Rust): - Refonte du pipeline JWT + sécurité, audit et rate limiting avancé. - Implémentation complète du cycle de message (read receipts, delivered, edit/delete, typing). - Nettoyage des panics, gestion d’erreurs robuste, logs structurés. - Migrations chat alignées sur le schéma UUID et nouvelles features. Stream server (Rust): - Refonte du moteur de streaming (encoding pipeline + HLS) et des modules core. - Transactions P0 pour les jobs et segments, garanties d’atomicité. - Documentation détaillée de la pipeline (AUDIT_STREAM_*, DESIGN_STREAM_PIPELINE, TRANSACTIONS_P0_IMPLEMENTATION). Documentation & audits: - TRIAGE.md et AUDIT_STABILITY.md à jour avec l’état réel des 3 services. - Cartographie complète des migrations et des transactions (DB_MIGRATIONS_*, DB_TRANSACTION_PLAN, AUDIT_DB_TRANSACTIONS, TRANSACTION_TESTS_PHASE3). - Scripts de reset et de cleanup pour la lab DB et la V1. Ce commit fige l’ensemble du travail de stabilisation P0 (UUID, backend, chat et stream) avant les phases suivantes (Coherence Guardian, WS hardening, etc.).
2025-12-06 10:14:38 +00:00
// SECURITY: Removed debug fmt.Printf to avoid leaking config info in production (P0-SECURITY)
2025-12-03 19:29:37 +00:00
func getEnv(key, defaultValue string) string {
if value := os.Getenv(key); value != "" {
return strings.TrimSpace(value)
}
return defaultValue
}
// getEnvAsInt retrieves an environment variable as an integer
// BE-DB-015: Helper for connection pool configuration
func getEnvAsInt(key string, defaultValue int) int {
value := os.Getenv(key)
if value == "" {
return defaultValue
}
intValue, err := strconv.Atoi(strings.TrimSpace(value))
if err != nil {
return defaultValue
}
return intValue
}
// getEnvAsDuration retrieves an environment variable as a time.Duration
// BE-DB-015: Helper for connection pool configuration
func getEnvAsDuration(key string, defaultValue time.Duration) time.Duration {
value := os.Getenv(key)
if value == "" {
return defaultValue
}
duration, err := time.ParseDuration(strings.TrimSpace(value))
if err != nil {
return defaultValue
}
return duration
}
2025-12-13 02:34:34 +00:00
// getEnvRequired récupère une variable d'environnement requise (retourne erreur si absente)
func getEnvRequired(key string) (string, error) {
2025-12-03 19:29:37 +00:00
value := os.Getenv(key)
if value == "" {
2025-12-13 02:34:34 +00:00
return "", fmt.Errorf("required environment variable %s is not set", key)
2025-12-03 19:29:37 +00:00
}
2025-12-13 02:34:34 +00:00
return value, nil
2025-12-03 19:29:37 +00:00
}
// BE-SEC-014: getRabbitMQURL récupère l'URL RabbitMQ avec validation selon l'environnement
// En production, RABBITMQ_URL doit être explicitement défini (pas de valeur par défaut avec credentials)
func getRabbitMQURL(env string, appDomain string) string {
rabbitMQURL := os.Getenv("RABBITMQ_URL")
if rabbitMQURL != "" {
return rabbitMQURL
}
// En production, ne pas utiliser de valeur par défaut avec credentials
if env == EnvProduction {
return "" // Will be validated in ValidateForEnvironment
}
// En développement: par défaut veza:password sur port 15672 (aligné docker-compose)
// Port 15672 = host mapping, 5672 = port interne container
port := getEnv("RABBITMQ_PORT", "15672")
user := getEnv("RABBITMQ_USER", "veza")
pass := getEnv("RABBITMQ_PASS", "password")
return fmt.Sprintf("amqp://%s:%s@%s:%s/", user, pass, appDomain, port)
}
2025-12-03 19:29:37 +00:00
// getEnvInt récupère une variable d'environnement entière avec une valeur par défaut
func getEnvInt(key string, defaultValue int) int {
if value := os.Getenv(key); value != "" {
if intValue, err := strconv.Atoi(value); err == nil {
return intValue
}
}
return defaultValue
}
// getEnvBool récupère une variable d'environnement booléenne avec une valeur par défaut
func getEnvBool(key string, defaultValue bool) bool {
if value := os.Getenv(key); value != "" {
if boolValue, err := strconv.ParseBool(value); err == nil {
return boolValue
}
}
return defaultValue
}
// getEnvDuration récupère une variable d'environnement durée avec une valeur par défaut
func getEnvDuration(key string, defaultValue time.Duration) time.Duration {
if value := os.Getenv(key); value != "" {
if duration, err := time.ParseDuration(value); err == nil {
return duration
}
}
return defaultValue
}
P0: stabilisation backend/chat/stream + nouvelle base migrations v1 Backend Go: - Remplacement complet des anciennes migrations par la base V1 alignée sur ORIGIN. - Durcissement global du parsing JSON (BindAndValidateJSON + RespondWithAppError). - Sécurisation de config.go, CORS, statuts de santé et monitoring. - Implémentation des transactions P0 (RBAC, duplication de playlists, social toggles). - Ajout d’un job worker structuré (emails, analytics, thumbnails) + tests associés. - Nouvelle doc backend : AUDIT_CONFIG, BACKEND_CONFIG, AUTH_PASSWORD_RESET, JOB_WORKER_*. Chat server (Rust): - Refonte du pipeline JWT + sécurité, audit et rate limiting avancé. - Implémentation complète du cycle de message (read receipts, delivered, edit/delete, typing). - Nettoyage des panics, gestion d’erreurs robuste, logs structurés. - Migrations chat alignées sur le schéma UUID et nouvelles features. Stream server (Rust): - Refonte du moteur de streaming (encoding pipeline + HLS) et des modules core. - Transactions P0 pour les jobs et segments, garanties d’atomicité. - Documentation détaillée de la pipeline (AUDIT_STREAM_*, DESIGN_STREAM_PIPELINE, TRANSACTIONS_P0_IMPLEMENTATION). Documentation & audits: - TRIAGE.md et AUDIT_STABILITY.md à jour avec l’état réel des 3 services. - Cartographie complète des migrations et des transactions (DB_MIGRATIONS_*, DB_TRANSACTION_PLAN, AUDIT_DB_TRANSACTIONS, TRANSACTION_TESTS_PHASE3). - Scripts de reset et de cleanup pour la lab DB et la V1. Ce commit fige l’ensemble du travail de stabilisation P0 (UUID, backend, chat et stream) avant les phases suivantes (Coherence Guardian, WS hardening, etc.).
2025-12-06 10:14:38 +00:00
// getEnvFloat64 récupère une variable d'environnement float64 avec une valeur par défaut
func getEnvFloat64(key string, defaultValue float64) float64 {
if value := os.Getenv(key); value != "" {
if floatValue, err := strconv.ParseFloat(value, 64); err == nil {
return floatValue
}
}
return defaultValue
}
// getDefaultRateLimitLimit retourne la limite globale par défaut selon l'environnement (A04)
func getDefaultRateLimitLimit(env string) int {
if env == EnvDevelopment || env == EnvTest {
return 1000 // Très permissif pour dev/tests
}
return 200 // Staging/prod
}
// getDefaultRegisterAttempts retourne le nombre d'inscriptions autorisées par heure (A04)
func getDefaultRegisterAttempts(env string) int {
if env == EnvDevelopment || env == EnvTest {
return 20 // Assoupli pour dev/tests
}
return 3 // Staging/prod
}
// getAuthRateLimitLoginAttempts retourne le nombre de tentatives de login autorisées
// Augmente les limites pour l'environnement de test/E2E
func getAuthRateLimitLoginAttempts(env string) int {
// Vérifier si on est en mode test/E2E
if env == "test" || env == "e2e" ||
os.Getenv("GO_ENV") == "test" ||
os.Getenv("GO_ENV") == "e2e" ||
os.Getenv("E2E_TEST") == "true" {
// Limite élevée pour les tests (100 tentatives)
return getEnvInt("AUTH_RATE_LIMIT_LOGIN_ATTEMPTS", 100)
}
// Limite normale en production (5 tentatives)
return getEnvInt("AUTH_RATE_LIMIT_LOGIN_ATTEMPTS", 5)
}
// getAuthRateLimitLoginWindow retourne la fenêtre de temps pour les tentatives de login
func getAuthRateLimitLoginWindow(env string) int {
// En mode test, utiliser 1 minute (comme en production)
// La fenêtre reste la même, seule la limite de tentatives change
return getEnvInt("AUTH_RATE_LIMIT_LOGIN_WINDOW", 1)
}
2025-12-03 19:29:37 +00:00
// getEnvStringSlice récupère une variable d'environnement comme une slice de strings
// Format attendu: "value1,value2,value3" (séparées par des virgules)
func getEnvStringSlice(key string, defaultValue []string) []string {
if value := os.Getenv(key); value != "" {
// Séparer par virgule et nettoyer les espaces
parts := strings.Split(value, ",")
result := make([]string, 0, len(parts))
for _, part := range parts {
trimmed := strings.TrimSpace(part)
if trimmed != "" {
result = append(result, trimmed)
}
}
if len(result) > 0 {
return result
}
}
return defaultValue
}
// parseLogAggregationLabels parse les labels d'agrégation de logs depuis une chaîne
// Format attendu: "key1=value1,key2=value2" (séparés par des virgules, key=value par paire)
func parseLogAggregationLabels(value string) map[string]string {
labels := make(map[string]string)
if value == "" {
return labels
}
// Séparer par virgule
pairs := strings.Split(value, ",")
for _, pair := range pairs {
pair = strings.TrimSpace(pair)
if pair == "" {
continue
}
// Séparer key=value
parts := strings.SplitN(pair, "=", 2)
if len(parts) == 2 {
key := strings.TrimSpace(parts[0])
val := strings.TrimSpace(parts[1])
if key != "" && val != "" {
labels[key] = val
}
}
}
return labels
}
2026-01-07 18:39:21 +00:00
// getCookieSecure détermine si les cookies doivent être Secure
// Auto-detect: secure en production, insecure en développement
// Peut être forcé via COOKIE_SECURE=true/false
func getCookieSecure(env string) bool {
cookieSecureEnv := getEnv("COOKIE_SECURE", "")
if cookieSecureEnv != "" {
return getEnvBool("COOKIE_SECURE", false)
}
// Auto-detect: secure en production, insecure en développement
return (env == EnvProduction)
}
// getCookieSameSite détermine la politique SameSite pour les cookies
// strict par défaut pour sécurité maximale, lax en développement local
func getCookieSameSite(env string) string {
cookieSameSite := getEnv("COOKIE_SAME_SITE", "strict")
if env == EnvDevelopment && cookieSameSite == "strict" {
// En dev local, utiliser "lax" pour permettre le domaine local (APP_DOMAIN)
2026-01-07 18:39:21 +00:00
return "lax"
}
return cookieSameSite
}
// GetCookieSameSite retourne la valeur http.SameSite correspondante
func (c *Config) GetCookieSameSite() http.SameSite {
switch c.CookieSameSite {
case "lax":
return http.SameSiteLaxMode
case "none":
return http.SameSiteNoneMode
default:
return http.SameSiteStrictMode
}
}
// ShouldUseSecureCookies détermine si les cookies doivent être Secure
// Prend en compte la configuration explicite et l'environnement
func (c *Config) ShouldUseSecureCookies() bool {
return c.CookieSecure
}
// devDefaultCORSOrigins returns origins always allowed in development/staging.
// Generated from APP_DOMAIN so that changing the domain propagates everywhere.
func devDefaultCORSOrigins(appDomain string) []string {
2026-02-07 19:36:48 +00:00
return []string{
"http://" + appDomain,
"http://" + appDomain + ":3000",
"http://" + appDomain + ":5173",
"http://" + appDomain + ":8080",
2026-02-07 19:36:48 +00:00
}
}
// mergeCORSOrigins merges custom with base and deduplicates (order: base then custom).
func mergeCORSOrigins(base, custom []string) []string {
seen := make(map[string]bool)
out := make([]string, 0, len(base)+len(custom))
for _, o := range base {
if !seen[o] {
seen[o] = true
out = append(out, o)
}
}
for _, o := range custom {
if !seen[o] {
seen[o] = true
out = append(out, o)
P0: stabilisation backend/chat/stream + nouvelle base migrations v1 Backend Go: - Remplacement complet des anciennes migrations par la base V1 alignée sur ORIGIN. - Durcissement global du parsing JSON (BindAndValidateJSON + RespondWithAppError). - Sécurisation de config.go, CORS, statuts de santé et monitoring. - Implémentation des transactions P0 (RBAC, duplication de playlists, social toggles). - Ajout d’un job worker structuré (emails, analytics, thumbnails) + tests associés. - Nouvelle doc backend : AUDIT_CONFIG, BACKEND_CONFIG, AUTH_PASSWORD_RESET, JOB_WORKER_*. Chat server (Rust): - Refonte du pipeline JWT + sécurité, audit et rate limiting avancé. - Implémentation complète du cycle de message (read receipts, delivered, edit/delete, typing). - Nettoyage des panics, gestion d’erreurs robuste, logs structurés. - Migrations chat alignées sur le schéma UUID et nouvelles features. Stream server (Rust): - Refonte du moteur de streaming (encoding pipeline + HLS) et des modules core. - Transactions P0 pour les jobs et segments, garanties d’atomicité. - Documentation détaillée de la pipeline (AUDIT_STREAM_*, DESIGN_STREAM_PIPELINE, TRANSACTIONS_P0_IMPLEMENTATION). Documentation & audits: - TRIAGE.md et AUDIT_STABILITY.md à jour avec l’état réel des 3 services. - Cartographie complète des migrations et des transactions (DB_MIGRATIONS_*, DB_TRANSACTION_PLAN, AUDIT_DB_TRANSACTIONS, TRANSACTION_TESTS_PHASE3). - Scripts de reset et de cleanup pour la lab DB et la V1. Ce commit fige l’ensemble du travail de stabilisation P0 (UUID, backend, chat et stream) avant les phases suivantes (Coherence Guardian, WS hardening, etc.).
2025-12-06 10:14:38 +00:00
}
}
2026-02-07 19:36:48 +00:00
return out
}
// getCORSOrigins charge les origines CORS avec defaults sécurisés selon l'environnement (P0-SECURITY)
// - development/staging: si CORS_ALLOWED_ORIGINS est défini, on le fusionne avec les defaults (APP_DOMAIN)
// pour que $APP_DOMAIN:5173 reste autorisé même avec une config partielle
2026-02-07 19:36:48 +00:00
// - production: CORS_ALLOWED_ORIGINS obligatoire, pas de merge
// - test: liste vide par défaut
func getCORSOrigins(env string, appDomain string) []string {
2026-02-07 19:36:48 +00:00
custom := getEnvStringSlice("CORS_ALLOWED_ORIGINS", nil)
P0: stabilisation backend/chat/stream + nouvelle base migrations v1 Backend Go: - Remplacement complet des anciennes migrations par la base V1 alignée sur ORIGIN. - Durcissement global du parsing JSON (BindAndValidateJSON + RespondWithAppError). - Sécurisation de config.go, CORS, statuts de santé et monitoring. - Implémentation des transactions P0 (RBAC, duplication de playlists, social toggles). - Ajout d’un job worker structuré (emails, analytics, thumbnails) + tests associés. - Nouvelle doc backend : AUDIT_CONFIG, BACKEND_CONFIG, AUTH_PASSWORD_RESET, JOB_WORKER_*. Chat server (Rust): - Refonte du pipeline JWT + sécurité, audit et rate limiting avancé. - Implémentation complète du cycle de message (read receipts, delivered, edit/delete, typing). - Nettoyage des panics, gestion d’erreurs robuste, logs structurés. - Migrations chat alignées sur le schéma UUID et nouvelles features. Stream server (Rust): - Refonte du moteur de streaming (encoding pipeline + HLS) et des modules core. - Transactions P0 pour les jobs et segments, garanties d’atomicité. - Documentation détaillée de la pipeline (AUDIT_STREAM_*, DESIGN_STREAM_PIPELINE, TRANSACTIONS_P0_IMPLEMENTATION). Documentation & audits: - TRIAGE.md et AUDIT_STABILITY.md à jour avec l’état réel des 3 services. - Cartographie complète des migrations et des transactions (DB_MIGRATIONS_*, DB_TRANSACTION_PLAN, AUDIT_DB_TRANSACTIONS, TRANSACTION_TESTS_PHASE3). - Scripts de reset et de cleanup pour la lab DB et la V1. Ce commit fige l’ensemble du travail de stabilisation P0 (UUID, backend, chat et stream) avant les phases suivantes (Coherence Guardian, WS hardening, etc.).
2025-12-06 10:14:38 +00:00
switch env {
case EnvProduction:
2026-02-07 19:36:48 +00:00
if len(custom) > 0 {
return custom
}
P0: stabilisation backend/chat/stream + nouvelle base migrations v1 Backend Go: - Remplacement complet des anciennes migrations par la base V1 alignée sur ORIGIN. - Durcissement global du parsing JSON (BindAndValidateJSON + RespondWithAppError). - Sécurisation de config.go, CORS, statuts de santé et monitoring. - Implémentation des transactions P0 (RBAC, duplication de playlists, social toggles). - Ajout d’un job worker structuré (emails, analytics, thumbnails) + tests associés. - Nouvelle doc backend : AUDIT_CONFIG, BACKEND_CONFIG, AUTH_PASSWORD_RESET, JOB_WORKER_*. Chat server (Rust): - Refonte du pipeline JWT + sécurité, audit et rate limiting avancé. - Implémentation complète du cycle de message (read receipts, delivered, edit/delete, typing). - Nettoyage des panics, gestion d’erreurs robuste, logs structurés. - Migrations chat alignées sur le schéma UUID et nouvelles features. Stream server (Rust): - Refonte du moteur de streaming (encoding pipeline + HLS) et des modules core. - Transactions P0 pour les jobs et segments, garanties d’atomicité. - Documentation détaillée de la pipeline (AUDIT_STREAM_*, DESIGN_STREAM_PIPELINE, TRANSACTIONS_P0_IMPLEMENTATION). Documentation & audits: - TRIAGE.md et AUDIT_STABILITY.md à jour avec l’état réel des 3 services. - Cartographie complète des migrations et des transactions (DB_MIGRATIONS_*, DB_TRANSACTION_PLAN, AUDIT_DB_TRANSACTIONS, TRANSACTION_TESTS_PHASE3). - Scripts de reset et de cleanup pour la lab DB et la V1. Ce commit fige l’ensemble du travail de stabilisation P0 (UUID, backend, chat et stream) avant les phases suivantes (Coherence Guardian, WS hardening, etc.).
2025-12-06 10:14:38 +00:00
return []string{}
case EnvTest:
2026-02-07 19:36:48 +00:00
if len(custom) > 0 {
return custom
}
P0: stabilisation backend/chat/stream + nouvelle base migrations v1 Backend Go: - Remplacement complet des anciennes migrations par la base V1 alignée sur ORIGIN. - Durcissement global du parsing JSON (BindAndValidateJSON + RespondWithAppError). - Sécurisation de config.go, CORS, statuts de santé et monitoring. - Implémentation des transactions P0 (RBAC, duplication de playlists, social toggles). - Ajout d’un job worker structuré (emails, analytics, thumbnails) + tests associés. - Nouvelle doc backend : AUDIT_CONFIG, BACKEND_CONFIG, AUTH_PASSWORD_RESET, JOB_WORKER_*. Chat server (Rust): - Refonte du pipeline JWT + sécurité, audit et rate limiting avancé. - Implémentation complète du cycle de message (read receipts, delivered, edit/delete, typing). - Nettoyage des panics, gestion d’erreurs robuste, logs structurés. - Migrations chat alignées sur le schéma UUID et nouvelles features. Stream server (Rust): - Refonte du moteur de streaming (encoding pipeline + HLS) et des modules core. - Transactions P0 pour les jobs et segments, garanties d’atomicité. - Documentation détaillée de la pipeline (AUDIT_STREAM_*, DESIGN_STREAM_PIPELINE, TRANSACTIONS_P0_IMPLEMENTATION). Documentation & audits: - TRIAGE.md et AUDIT_STABILITY.md à jour avec l’état réel des 3 services. - Cartographie complète des migrations et des transactions (DB_MIGRATIONS_*, DB_TRANSACTION_PLAN, AUDIT_DB_TRANSACTIONS, TRANSACTION_TESTS_PHASE3). - Scripts de reset et de cleanup pour la lab DB et la V1. Ce commit fige l’ensemble du travail de stabilisation P0 (UUID, backend, chat et stream) avant les phases suivantes (Coherence Guardian, WS hardening, etc.).
2025-12-06 10:14:38 +00:00
return []string{}
case EnvDevelopment, EnvStaging:
base := devDefaultCORSOrigins(appDomain)
2026-02-07 19:36:48 +00:00
if len(custom) > 0 {
return mergeCORSOrigins(base, custom)
}
return base
P0: stabilisation backend/chat/stream + nouvelle base migrations v1 Backend Go: - Remplacement complet des anciennes migrations par la base V1 alignée sur ORIGIN. - Durcissement global du parsing JSON (BindAndValidateJSON + RespondWithAppError). - Sécurisation de config.go, CORS, statuts de santé et monitoring. - Implémentation des transactions P0 (RBAC, duplication de playlists, social toggles). - Ajout d’un job worker structuré (emails, analytics, thumbnails) + tests associés. - Nouvelle doc backend : AUDIT_CONFIG, BACKEND_CONFIG, AUTH_PASSWORD_RESET, JOB_WORKER_*. Chat server (Rust): - Refonte du pipeline JWT + sécurité, audit et rate limiting avancé. - Implémentation complète du cycle de message (read receipts, delivered, edit/delete, typing). - Nettoyage des panics, gestion d’erreurs robuste, logs structurés. - Migrations chat alignées sur le schéma UUID et nouvelles features. Stream server (Rust): - Refonte du moteur de streaming (encoding pipeline + HLS) et des modules core. - Transactions P0 pour les jobs et segments, garanties d’atomicité. - Documentation détaillée de la pipeline (AUDIT_STREAM_*, DESIGN_STREAM_PIPELINE, TRANSACTIONS_P0_IMPLEMENTATION). Documentation & audits: - TRIAGE.md et AUDIT_STABILITY.md à jour avec l’état réel des 3 services. - Cartographie complète des migrations et des transactions (DB_MIGRATIONS_*, DB_TRANSACTION_PLAN, AUDIT_DB_TRANSACTIONS, TRANSACTION_TESTS_PHASE3). - Scripts de reset et de cleanup pour la lab DB et la V1. Ce commit fige l’ensemble du travail de stabilisation P0 (UUID, backend, chat et stream) avant les phases suivantes (Coherence Guardian, WS hardening, etc.).
2025-12-06 10:14:38 +00:00
default:
return []string{"http://" + appDomain + ":3000", "http://" + appDomain + ":5173"}
P0: stabilisation backend/chat/stream + nouvelle base migrations v1 Backend Go: - Remplacement complet des anciennes migrations par la base V1 alignée sur ORIGIN. - Durcissement global du parsing JSON (BindAndValidateJSON + RespondWithAppError). - Sécurisation de config.go, CORS, statuts de santé et monitoring. - Implémentation des transactions P0 (RBAC, duplication de playlists, social toggles). - Ajout d’un job worker structuré (emails, analytics, thumbnails) + tests associés. - Nouvelle doc backend : AUDIT_CONFIG, BACKEND_CONFIG, AUTH_PASSWORD_RESET, JOB_WORKER_*. Chat server (Rust): - Refonte du pipeline JWT + sécurité, audit et rate limiting avancé. - Implémentation complète du cycle de message (read receipts, delivered, edit/delete, typing). - Nettoyage des panics, gestion d’erreurs robuste, logs structurés. - Migrations chat alignées sur le schéma UUID et nouvelles features. Stream server (Rust): - Refonte du moteur de streaming (encoding pipeline + HLS) et des modules core. - Transactions P0 pour les jobs et segments, garanties d’atomicité. - Documentation détaillée de la pipeline (AUDIT_STREAM_*, DESIGN_STREAM_PIPELINE, TRANSACTIONS_P0_IMPLEMENTATION). Documentation & audits: - TRIAGE.md et AUDIT_STABILITY.md à jour avec l’état réel des 3 services. - Cartographie complète des migrations et des transactions (DB_MIGRATIONS_*, DB_TRANSACTION_PLAN, AUDIT_DB_TRANSACTIONS, TRANSACTION_TESTS_PHASE3). - Scripts de reset et de cleanup pour la lab DB et la V1. Ce commit fige l’ensemble du travail de stabilisation P0 (UUID, backend, chat et stream) avant les phases suivantes (Coherence Guardian, WS hardening, etc.).
2025-12-06 10:14:38 +00:00
}
}
// ValidateForEnvironment valide la configuration selon l'environnement (P0-SECURITY)
// En production: validation stricte (CORS requis, pas de wildcard, etc.)
// En development: validation permissive avec warnings
func (c *Config) ValidateForEnvironment() error {
// D'abord, validation de base (port, secrets, URLs, etc.)
if err := c.Validate(); err != nil {
return err
}
// Validations spécifiques selon l'environnement
switch c.Env {
case EnvProduction:
// PRODUCTION: Validation stricte
2025-12-13 02:34:34 +00:00
// 1. MOD-P0-001: CORS_ALLOWED_ORIGINS MUST be configured in production (fail-fast)
// Empty CORS origins means strict mode (reject all), which makes the service inaccessible from frontend
P0: stabilisation backend/chat/stream + nouvelle base migrations v1 Backend Go: - Remplacement complet des anciennes migrations par la base V1 alignée sur ORIGIN. - Durcissement global du parsing JSON (BindAndValidateJSON + RespondWithAppError). - Sécurisation de config.go, CORS, statuts de santé et monitoring. - Implémentation des transactions P0 (RBAC, duplication de playlists, social toggles). - Ajout d’un job worker structuré (emails, analytics, thumbnails) + tests associés. - Nouvelle doc backend : AUDIT_CONFIG, BACKEND_CONFIG, AUTH_PASSWORD_RESET, JOB_WORKER_*. Chat server (Rust): - Refonte du pipeline JWT + sécurité, audit et rate limiting avancé. - Implémentation complète du cycle de message (read receipts, delivered, edit/delete, typing). - Nettoyage des panics, gestion d’erreurs robuste, logs structurés. - Migrations chat alignées sur le schéma UUID et nouvelles features. Stream server (Rust): - Refonte du moteur de streaming (encoding pipeline + HLS) et des modules core. - Transactions P0 pour les jobs et segments, garanties d’atomicité. - Documentation détaillée de la pipeline (AUDIT_STREAM_*, DESIGN_STREAM_PIPELINE, TRANSACTIONS_P0_IMPLEMENTATION). Documentation & audits: - TRIAGE.md et AUDIT_STABILITY.md à jour avec l’état réel des 3 services. - Cartographie complète des migrations et des transactions (DB_MIGRATIONS_*, DB_TRANSACTION_PLAN, AUDIT_DB_TRANSACTIONS, TRANSACTION_TESTS_PHASE3). - Scripts de reset et de cleanup pour la lab DB et la V1. Ce commit fige l’ensemble du travail de stabilisation P0 (UUID, backend, chat et stream) avant les phases suivantes (Coherence Guardian, WS hardening, etc.).
2025-12-06 10:14:38 +00:00
if len(c.CORSOrigins) == 0 {
2025-12-13 02:34:34 +00:00
return fmt.Errorf("CORS_ALLOWED_ORIGINS is required in production environment. Empty CORS origins will reject all CORS requests, making the service inaccessible from frontend. Please set CORS_ALLOWED_ORIGINS with explicit origins (e.g., CORS_ALLOWED_ORIGINS=https://app.veza.com,https://www.veza.com)")
P0: stabilisation backend/chat/stream + nouvelle base migrations v1 Backend Go: - Remplacement complet des anciennes migrations par la base V1 alignée sur ORIGIN. - Durcissement global du parsing JSON (BindAndValidateJSON + RespondWithAppError). - Sécurisation de config.go, CORS, statuts de santé et monitoring. - Implémentation des transactions P0 (RBAC, duplication de playlists, social toggles). - Ajout d’un job worker structuré (emails, analytics, thumbnails) + tests associés. - Nouvelle doc backend : AUDIT_CONFIG, BACKEND_CONFIG, AUTH_PASSWORD_RESET, JOB_WORKER_*. Chat server (Rust): - Refonte du pipeline JWT + sécurité, audit et rate limiting avancé. - Implémentation complète du cycle de message (read receipts, delivered, edit/delete, typing). - Nettoyage des panics, gestion d’erreurs robuste, logs structurés. - Migrations chat alignées sur le schéma UUID et nouvelles features. Stream server (Rust): - Refonte du moteur de streaming (encoding pipeline + HLS) et des modules core. - Transactions P0 pour les jobs et segments, garanties d’atomicité. - Documentation détaillée de la pipeline (AUDIT_STREAM_*, DESIGN_STREAM_PIPELINE, TRANSACTIONS_P0_IMPLEMENTATION). Documentation & audits: - TRIAGE.md et AUDIT_STABILITY.md à jour avec l’état réel des 3 services. - Cartographie complète des migrations et des transactions (DB_MIGRATIONS_*, DB_TRANSACTION_PLAN, AUDIT_DB_TRANSACTIONS, TRANSACTION_TESTS_PHASE3). - Scripts de reset et de cleanup pour la lab DB et la V1. Ce commit fige l’ensemble du travail de stabilisation P0 (UUID, backend, chat et stream) avant les phases suivantes (Coherence Guardian, WS hardening, etc.).
2025-12-06 10:14:38 +00:00
}
// 2. CORS_ALLOWED_ORIGINS ne doit PAS contenir "*" (wildcard interdit en prod)
for _, origin := range c.CORSOrigins {
if origin == "*" {
return fmt.Errorf("CORS wildcard '*' is not allowed in production environment. Please specify explicit origins in CORS_ALLOWED_ORIGINS")
}
}
// 3. LogLevel ne doit pas être DEBUG en production
if c.LogLevel == "DEBUG" {
return fmt.Errorf("LOG_LEVEL=DEBUG is not allowed in production environment for security reasons")
}
// 4. BE-SEC-014: RabbitMQ URL must be explicitly set in production (no default with credentials)
if c.RabbitMQEnable && c.RabbitMQURL == "" {
return fmt.Errorf("RABBITMQ_URL is required in production when RabbitMQ is enabled. Do not use default credentials in production")
P0: stabilisation backend/chat/stream + nouvelle base migrations v1 Backend Go: - Remplacement complet des anciennes migrations par la base V1 alignée sur ORIGIN. - Durcissement global du parsing JSON (BindAndValidateJSON + RespondWithAppError). - Sécurisation de config.go, CORS, statuts de santé et monitoring. - Implémentation des transactions P0 (RBAC, duplication de playlists, social toggles). - Ajout d’un job worker structuré (emails, analytics, thumbnails) + tests associés. - Nouvelle doc backend : AUDIT_CONFIG, BACKEND_CONFIG, AUTH_PASSWORD_RESET, JOB_WORKER_*. Chat server (Rust): - Refonte du pipeline JWT + sécurité, audit et rate limiting avancé. - Implémentation complète du cycle de message (read receipts, delivered, edit/delete, typing). - Nettoyage des panics, gestion d’erreurs robuste, logs structurés. - Migrations chat alignées sur le schéma UUID et nouvelles features. Stream server (Rust): - Refonte du moteur de streaming (encoding pipeline + HLS) et des modules core. - Transactions P0 pour les jobs et segments, garanties d’atomicité. - Documentation détaillée de la pipeline (AUDIT_STREAM_*, DESIGN_STREAM_PIPELINE, TRANSACTIONS_P0_IMPLEMENTATION). Documentation & audits: - TRIAGE.md et AUDIT_STABILITY.md à jour avec l’état réel des 3 services. - Cartographie complète des migrations et des transactions (DB_MIGRATIONS_*, DB_TRANSACTION_PLAN, AUDIT_DB_TRANSACTIONS, TRANSACTION_TESTS_PHASE3). - Scripts de reset et de cleanup pour la lab DB et la V1. Ce commit fige l’ensemble du travail de stabilisation P0 (UUID, backend, chat et stream) avant les phases suivantes (Coherence Guardian, WS hardening, etc.).
2025-12-06 10:14:38 +00:00
}
case EnvTest:
// TEST: Validation adaptée aux tests
// CORS peut être vide ou configuré explicitement
// Pas de validation stricte sur les secrets (peuvent être des valeurs de test)
case EnvDevelopment, EnvStaging:
// DEVELOPMENT/STAGING: Validation permissive avec warnings
// Si CORS contient "*", logger un warning mais ne pas bloquer
for _, origin := range c.CORSOrigins {
if origin == "*" {
c.Logger.Warn("CORS wildcard '*' detected in development environment. This is acceptable for dev but should never be used in production")
break
}
}
}
return nil
}
2025-12-03 19:29:37 +00:00
// Validate valide la configuration (T0031, T0036)
// Vérifie que toutes les valeurs de configuration sont valides avant le démarrage de l'application
// Utilise ConfigValidator pour une validation stricte selon les règles de schéma (T0036)
func (c *Config) Validate() error {
validator := NewConfigValidator()
// Valider le port (1-65535) avec ConfigValidator (T0036)
if err := validator.ValidatePort(c.AppPort); err != nil {
return fmt.Errorf("APP_PORT validation failed: %w", err)
}
// Valider JWT secret (minimum 32 caractères pour sécurité) avec ConfigValidator (T0036)
if err := validator.ValidateSecretLength(c.JWTSecret, 32); err != nil {
return fmt.Errorf("JWT_SECRET validation failed: %w", err)
}
// Valider DatabaseURL (requis) avec ConfigValidator (T0036)
if c.DatabaseURL == "" {
return errors.New("DATABASE_URL is required")
}
// Valider le format de DatabaseURL avec ConfigValidator (T0036)
// Support postgres, postgresql, et sqlite
if err := validator.ValidateURL(c.DatabaseURL, "postgres"); err != nil {
if err2 := validator.ValidateURL(c.DatabaseURL, "postgresql"); err2 != nil {
if err3 := validator.ValidateURL(c.DatabaseURL, "sqlite"); err3 != nil {
return fmt.Errorf("DATABASE_URL validation failed: must start with postgres://, postgresql://, or sqlite://")
}
}
}
// Valider RedisURL (requis) avec ConfigValidator (T0036)
if c.RedisURL == "" {
return errors.New("REDIS_URL is required")
}
// Valider le format de RedisURL avec ConfigValidator (T0036)
// Support redis et rediss (Redis avec SSL)
if err := validator.ValidateURL(c.RedisURL, "redis"); err != nil {
if err2 := validator.ValidateURL(c.RedisURL, "rediss"); err2 != nil {
return fmt.Errorf("REDIS_URL validation failed: must start with redis:// or rediss://")
}
}
// Valider LogLevel avec ValidateEnum (T0036)
if c.LogLevel != "" {
allowedLevels := []string{"DEBUG", "INFO", "WARN", "ERROR"}
if err := validator.ValidateEnum(c.LogLevel, allowedLevels); err != nil {
return fmt.Errorf("LOG_LEVEL validation failed: %w", err)
}
}
// Valider RateLimitLimit et RateLimitWindow avec ValidatePositiveInt (T0036)
if err := validator.ValidatePositiveInt(c.RateLimitLimit, "RATE_LIMIT_LIMIT"); err != nil {
return fmt.Errorf("RATE_LIMIT_LIMIT validation failed: %w", err)
}
if err := validator.ValidatePositiveInt(c.RateLimitWindow, "RATE_LIMIT_WINDOW"); err != nil {
return fmt.Errorf("RATE_LIMIT_WINDOW validation failed: %w", err)
}
return nil
}
// logConfigInitialized log la configuration initialisée avec masquage des secrets (T0037)
2025-12-13 02:34:34 +00:00
// MOD-P0-002: Always mask secrets in logs, even in DEBUG mode
2025-12-03 19:29:37 +00:00
func (c *Config) logConfigInitialized(logger *zap.Logger) {
logger.Info("Configuration initialized successfully",
zap.Int("app_port", c.AppPort),
zap.String("jwt_secret", MaskConfigValue("JWT_SECRET", c.JWTSecret, c.SecretsProvider)),
2025-12-13 02:34:34 +00:00
zap.String("jwt_issuer", c.JWTIssuer),
zap.String("jwt_audience", c.JWTAudience),
zap.String("chat_jwt_secret", MaskConfigValue("CHAT_JWT_SECRET", c.ChatJWTSecret, c.SecretsProvider)),
2025-12-03 19:29:37 +00:00
zap.String("database_url", MaskConfigValue("DATABASE_URL", c.DatabaseURL, c.SecretsProvider)),
zap.String("redis_url", MaskConfigValue("REDIS_URL", c.RedisURL, c.SecretsProvider)),
2025-12-13 02:34:34 +00:00
zap.String("rabbitmq_url", MaskConfigValue("RABBITMQ_URL", c.RabbitMQURL, c.SecretsProvider)),
2025-12-03 19:29:37 +00:00
zap.Strings("cors_origins", c.CORSOrigins),
zap.Int("rate_limit_limit", c.RateLimitLimit),
zap.Int("rate_limit_window", c.RateLimitWindow),
2025-12-13 02:34:34 +00:00
zap.Int("auth_rate_limit_login_attempts", c.AuthRateLimitLoginAttempts),
zap.Int("auth_rate_limit_login_window", c.AuthRateLimitLoginWindow),
zap.Duration("handler_timeout", c.HandlerTimeout),
2025-12-03 19:29:37 +00:00
zap.String("log_level", c.LogLevel),
2025-12-13 02:34:34 +00:00
zap.String("sentry_dsn", MaskConfigValue("SENTRY_DSN", c.SentryDsn, c.SecretsProvider)),
2025-12-03 19:29:37 +00:00
)
}
// Close ferme toutes les connexions (T0040)
func (c *Config) Close() error {
var err error
// Arrêter le ConfigWatcher si actif (T0040)
if c.ConfigWatcher != nil {
if closeErr := c.ConfigWatcher.Stop(); closeErr != nil {
err = closeErr
}
}
if c.RedisClient != nil {
if closeErr := c.RedisClient.Close(); closeErr != nil {
err = closeErr
}
}
if c.Database != nil {
if closeErr := c.Database.Close(); closeErr != nil {
err = closeErr
}
}
if c.RabbitMQEventBus != nil {
if closeErr := c.RabbitMQEventBus.Close(); closeErr != nil {
err = closeErr
}
}
// FIX #4: Logger.Sync() est géré par le ShutdownManager dans main.go
// Ne pas appeler Sync() ici pour éviter le double flush
// Le ShutdownManager garantit le flush avec timeout et gestion d'erreur
2025-12-03 19:29:37 +00:00
if c.Logger != nil {
// Le logger sera sync'd par le ShutdownManager enregistré dans main.go
// Pas besoin de Sync() ici car cela pourrait causer un double flush
// et l'erreur serait ignorée de toute façon
2025-12-03 19:29:37 +00:00
}
return err
}