chore: build

This commit is contained in:
2026-06-14 17:50:35 +02:00
parent 3c92a0371f
commit 3a0f725159
93 changed files with 5311 additions and 4224 deletions
-219
View File
@@ -3,7 +3,6 @@ package db
import (
"encoding/json"
"fmt"
"gestion/models"
"log"
"time"
)
@@ -183,221 +182,3 @@ func (d *Database) InvalidateSession(clientID int) error {
log.Printf("✅ [SESSION] Session invalidée pour client %d", clientID)
return nil
}
// ============================================
// PANIER EN CACHE REDIS
// ============================================
// BasketItemCache représente un item du panier en cache
type BasketItemCache struct {
ID int `json:"id"`
ProductID int `json:"product_id"`
ProductName string `json:"product_name"`
Quantity int `json:"quantity"`
Price float64 `json:"price"`
Category string `json:"category"`
AddedAt int64 `json:"added_at"`
}
// GetSessionBasket récupère le panier en cache Redis
// Retourne les items du panier avec total
func (d *Database) GetSessionBasket(clientID int) ([]BasketItemCache, float64, error) {
basketKey := fmt.Sprintf("session:basket:%d", clientID)
// Récupérer tous les items du panier
items, err := Redis.HGetAll(RedisCtx, basketKey).Result()
if err != nil {
log.Printf("⚠️ [BASKET] Pas de panier en cache pour client %d", clientID)
return []BasketItemCache{}, 0, nil
}
var basketItems []BasketItemCache
var totalPrice float64
for _, itemJSON := range items {
var item BasketItemCache
if err := json.Unmarshal([]byte(itemJSON), &item); err != nil {
log.Printf("⚠️ [BASKET] Erreur parsing item: %v", err)
continue
}
basketItems = append(basketItems, item)
totalPrice += item.Price * float64(item.Quantity)
}
return basketItems, totalPrice, nil
}
// UpdateSessionBasket met à jour le panier en cache Redis
// Appelé après ajout/modification d'un produit au panier
func (d *Database) UpdateSessionBasket(clientID int, basketItems []BasketItemCache) error {
basketKey := fmt.Sprintf("session:basket:%d", clientID)
// Vider le panier existant
Redis.Del(RedisCtx, basketKey)
// Ajouter tous les items
for _, item := range basketItems {
itemJSON, _ := json.Marshal(item)
if err := Redis.HSet(RedisCtx, basketKey, item.ProductID, itemJSON).Err(); err != nil {
log.Printf("⚠️ [BASKET] Erreur ajout item: %v", err)
}
}
// TTL: 24 heures
if err := Redis.Expire(RedisCtx, basketKey, 24*time.Hour).Err(); err != nil {
log.Printf("⚠️ [BASKET] Erreur TTL: %v", err)
}
return nil
}
// ClearSessionBasket vide le panier en cache Redis
// Appelé après validation de commande (checkout)
func (d *Database) ClearSessionBasket(clientID int) error {
basketKey := fmt.Sprintf("session:basket:%d", clientID)
if err := Redis.Del(RedisCtx, basketKey).Err(); err != nil {
log.Printf("⚠️ [BASKET] Erreur clear: %v", err)
return nil
}
log.Printf("✅ [BASKET] Panier vidé pour client %d", clientID)
return nil
}
// ============================================
// UTILITAIRES SESSION
// ============================================
// GetAllActiveSessions récupère toutes les sessions actives
// Utile pour admin/stats
func (d *Database) GetAllActiveSessions() ([]SessionData, error) {
clientIDs, err := Redis.SMembers(RedisCtx, "session:active:clients").Result()
if err != nil {
return nil, fmt.Errorf("erreur récupération sessions: %w", err)
}
var sessions []SessionData
for _, clientIDStr := range clientIDs {
var clientID int
if _, err := fmt.Sscanf(clientIDStr, "%d", &clientID); err != nil {
continue
}
if session, err := d.GetClientSession(clientID); err == nil {
sessions = append(sessions, *session)
}
}
return sessions, nil
}
// GetSessionCount retourne le nombre de sessions actives
func (d *Database) GetSessionCount() (int64, error) {
count, err := Redis.SCard(RedisCtx, "session:active:clients").Result()
if err != nil {
return 0, fmt.Errorf("erreur comptage sessions: %w", err)
}
return count, nil
}
// ============================================
// CACHE PROFIL CLIENT
// ============================================
// CacheClientProfile met en cache les infos du client (pour 1h)
func (d *Database) CacheClientProfile(client interface{}) error {
// Récupérer le client depuis DB si c'est un username
var clientData *models.Client
// Si c'est un username string
if username, ok := client.(string); ok {
var err error
clientData, err = d.GetClientByUsername(username)
if err != nil {
return fmt.Errorf("client non trouvé: %w", err)
}
} else {
// Si c'est déjà un *models.Client
clientData = client.(*models.Client)
}
cacheKey := fmt.Sprintf("cache:client:profile:%d", clientData.ID)
// Sérialiser
profileJSON, err := json.Marshal(clientData)
if err != nil {
return fmt.Errorf("erreur sérialisation: %w", err)
}
// Sauvegarder avec TTL 1h
if err := Redis.Set(RedisCtx, cacheKey, profileJSON, 1*time.Hour).Err(); err != nil {
return fmt.Errorf("erreur cache: %w", err)
}
log.Printf("✅ [CACHE] Profil client %d mis en cache (1h)", clientData.ID)
return nil
}
// GetCachedClientProfile récupère le profil en cache
func (d *Database) GetCachedClientProfile(clientID int) (*models.Client, error) {
cacheKey := fmt.Sprintf("cache:client:profile:%d", clientID)
data, err := Redis.Get(RedisCtx, cacheKey).Result()
if err != nil {
return nil, fmt.Errorf("cache miss")
}
var client models.Client
if err := json.Unmarshal([]byte(data), &client); err != nil {
return nil, fmt.Errorf("erreur désérialisation: %w", err)
}
return &client, nil
}
// InvalidateClientCache invalide le cache du client
func (d *Database) InvalidateClientCache(clientID int) error {
cacheKey := fmt.Sprintf("cache:client:profile:%d", clientID)
if err := Redis.Del(RedisCtx, cacheKey).Err(); err != nil {
return fmt.Errorf("erreur invalidation: %w", err)
}
log.Printf("✅ [CACHE] Profil client %d invalidé", clientID)
return nil
}
// ============================================
// COMMANDES EN CACHE (POUR TRACKING)
// ============================================
// CacheCommandInfo met en cache les infos d'une commande
func (d *Database) CacheCommandInfo(commandID int, command map[string]interface{}) error {
cacheKey := fmt.Sprintf("cache:command:%d", commandID)
commandJSON, err := json.Marshal(command)
if err != nil {
return fmt.Errorf("erreur sérialisation: %w", err)
}
// TTL: 4 heures
if err := Redis.Set(RedisCtx, cacheKey, commandJSON, 4*time.Hour).Err(); err != nil {
return fmt.Errorf("erreur cache: %w", err)
}
return nil
}
// GetCachedCommand récupère une commande en cache
func (d *Database) GetCachedCommand(commandID int) (map[string]interface{}, error) {
cacheKey := fmt.Sprintf("cache:command:%d", commandID)
data, err := Redis.Get(RedisCtx, cacheKey).Result()
if err != nil {
return nil, fmt.Errorf("cache miss")
}
var command map[string]interface{}
if err := json.Unmarshal([]byte(data), &command); err != nil {
return nil, fmt.Errorf("erreur désérialisation: %w", err)
}
return command, nil
}