user-engine/src/user_engine/projections.py

50 lines
1.5 KiB
Python
Raw Normal View History

2026-05-22 21:33:38 +02:00
"""Projection helpers that do not make user-engine a token issuer."""
from __future__ import annotations
from dataclasses import dataclass, field
from user_engine.domain import Actor, ProjectionType
from user_engine.service import Projection, UserEngineService
@dataclass
class ClaimsEnrichmentProjectionCache:
"""Cache claims-enrichment projections for external token adapters.
The adapter caches profile material only. A caller that issues tokens must
still own token minting, signing, lifetimes, and issuer-specific policy.
"""
_cache: dict[tuple[str, str, str, str], Projection] = field(default_factory=dict)
def get(
self,
service: UserEngineService,
actor: Actor,
*,
user_id: str,
tenant: str,
application_id: str,
correlation_id: str,
) -> Projection:
key = (tenant, application_id, user_id, actor.subject)
cached = self._cache.get(key)
if cached is not None:
return cached
projection = service.projection(
actor,
user_id,
ProjectionType.CLAIMS_ENRICHMENT,
tenant=tenant,
application_id=application_id,
correlation_id=correlation_id,
)
self._cache[key] = projection
return projection
def invalidate_user(self, user_id: str) -> None:
for key in tuple(self._cache):
if key[2] == user_id:
del self._cache[key]