Table of Contents

Namespace KadicAuth.Infrastructure.Services

Classes

CachedUserSessionValidator

Decorator over UserSessionValidator that caches positive and negative session-active results for a short TTL (30 s) to avoid hitting the database on every authenticated request.

CatalogDependencyService

Responde "que se rompe si desactivo esto" para los tres niveles del catalogo de Auth.

Antes de esto no existia ninguna comprobacion: desactivar un modulo no miraba sus submodulos ni los tenants que lo tenian contratado, y los dejaba activos colgando de algo inactivo.

Se usa en dos sitios y por eso devuelve el detalle en vez de un booleano: las guardas de los handlers (que construyen el 409) y los endpoints GET .../dependencies, que permiten a la UI avisar antes de que el usuario pulse.

Importante: todas las consultas ignoran los filtros globales de tenant. `AuthDbContext` aplica un filtro por `TenantId` a toda entidad que tenga esa propiedad, lo que incluye TenantModules, TenantSubModules y TenantRoles. Sin `IgnoreQueryFilters()` un PlatformAdmin solo veria las dependencias de SU tenant y la guarda diria "sin dependencias" en falso, que es justo el fallo que viene a evitar.

JwtTokenGenerator
NotificationsAuthHandler

Agrega Authorization: Bearer {token} si NotificationsAuthToken está configurado.

NotificationsClient
PasswordHasher
PlatformAdminAwarePermissionService

Decorator over the base KadicErp.Core.Abstractions.Authorization.IPermissionService implementation (KadicErp.Core.Authentication.Services.PermissionService) that short circuits for active platform admins and tenant super admins.

Why a decorator instead of modifying the base class: KadicErp.Core.Authentication would have to reference KadicAuth.Application to see IPlatformAdminService, which creates a dependency cycle (KadicAuth.Application → KadicErp.Core.Authentication → KadicAuth.Application). This lives in KadicAuth.Infrastructure which already references both projects, so we get the behavior we need without touching the core auth services layer.

Wire-up: register this as the KadicErp.Core.Abstractions.Authorization.IPermissionService implementation in every API host (KadicAuth.Api, KadicErp.WebApi, KadicErp.Notifications.Api), AND also register the base KadicErp.Core.Authentication.Services.PermissionService (or RedisPermissionService when Redis is enabled) as a concrete type so the decorator has something to delegate to. There is no shared DI helper method for this — each host wires it up inline via builder.Services.AddScoped<IPermissionService>(sp => new PlatformAdminAwarePermissionService(...)) in its own Program.cs.

PlatformAdminService
PlatformAdminVerifierAdapter

Thin adapter so modules that only depend on KadicErp.Core.Abstractions (RentACar, Purchase, etc. — never KadicAuth.Application) can still get a live-verified platform-admin check without taking on a hard reference to the Auth module's application layer. There is exactly one source of truth for platform-admin membership: IPlatformAdminService.

RedisPermissionService

GAP-16: Redis-backed IPermissionService for horizontally-scaled deployments. Uses IDistributedCache so the same permission set is shared across all API instances within the configured TTL — eliminates per-instance cache divergence.

Falls back gracefully to fetching from DB when the cache is unavailable (Redis down), never blocking authentication in case of cache failure.

Registration: swap PermissionService for this class in DI when RedisSettings.Enabled = true.

TenantModuleService

IMemoryCache-backed implementation of KadicErp.Core.Abstractions.Tenancy.ITenantModuleService. Caches the full active-module-key set per tenant for 5 minutes, with a per-tenant lock to avoid thundering-herd on first read.

TenantSuperAdminService
UiMenuTenantProvisioningService

Keeps the UI_MENU module (and all its submodules) assigned to a tenant whenever ANY business module gets assigned to it.

UserSessionValidator