============================ Cache Tenant-Aware ============================ Le module de cache isole automatiquement les clés par tenant pour prévenir les fuites de données cross-tenant. Module : ``src.share_kernel.infrastructure.cache`` Fonctions ========= .. module:: src.share_kernel.infrastructure.cache :synopsis: Abstraction de cache isolée par tenant .. function:: tenant_cache_key_func(key: str, key_prefix: str, version: int) -> str Fonction de préfixage de clés pour le paramètre ``KEY_FUNCTION`` de Django. Préfixe toutes les clés avec ``t::`` ou ``shared:``. **Configuration dans settings.py :** .. code-block:: python CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.redis.RedisCache', 'LOCATION': 'redis://localhost:6379/0', 'KEY_FUNCTION': 'src.share_kernel.infrastructure.cache.tenant_cache_key_func', } } .. function:: tenant_cache_key(key: str) -> str Construit une clé scopée au tenant pour les opérations manuelles. :param key: La clé de base :returns: ``t::`` ou ``shared:`` .. code-block:: python from src.share_kernel.infrastructure.cache import tenant_cache_key key = tenant_cache_key("user_count") # → "t:550e8400-e29b-41d4-a716-446655440000:user_count" .. function:: cache_get(key: str, default: Any = None) -> Any Récupère une valeur du cache scopé au tenant. .. code-block:: python from src.share_kernel.infrastructure.cache import cache_get, cache_set count = cache_get("user_count") if count is None: count = User.objects.count() cache_set("user_count", count, timeout=300) .. function:: cache_set(key: str, value: Any, timeout: int | None = None) -> None Stocke une valeur dans le cache scopé au tenant. :param key: Clé de cache :param value: Valeur à stocker :param timeout: TTL en secondes (optionnel) .. function:: cache_delete(key: str) -> None Supprime une valeur du cache scopé au tenant. .. function:: cache_delete_pattern(pattern: str) -> None Supprime toutes les clés correspondant à un pattern. Fonctionne uniquement avec les backends supportant ``delete_pattern`` (ex: ``django-redis``). Silencieux pour les autres backends. .. code-block:: python from src.share_kernel.infrastructure.cache import cache_delete_pattern # Supprime tout le cache utilisateur du tenant courant cache_delete_pattern("user_*") Isolation des clés ================== .. code-block:: text Tenant A (id: aaa-...) Tenant B (id: bbb-...) ┌──────────────────────┐ ┌──────────────────────┐ │ t:aaa:user_count = 5 │ │ t:bbb:user_count = 3 │ │ t:aaa:product_list │ │ t:bbb:product_list │ └──────────────────────┘ └──────────────────────┘ Routes publiques (pas de tenant) ┌──────────────────────┐ │ shared:config = ... │ └──────────────────────┘