Add ResilientLdapGroupRoleMappingService — a singleton decorator that wraps the hot-path GetByGroupsAsync call in a Polly pipeline (timeout 2s → retry 3× jittered → fallback to in-memory sealed snapshot) so a transient Config DB outage at Admin sign-in falls back to the last-known-good mapping set rather than denying every login. The static LdapOptions.GroupToRole bootstrap dictionary in AdminRoleGrantResolver remains the lock-out-proof floor regardless of DB state. DI wiring uses keyed services: LdapGroupRoleMappingService (EF, scoped) is registered under key "LdapGroupRoleMappingService.Inner"; the resilient singleton decorator is the primary ILdapGroupRoleMappingService binding. The singleton avoids the captive-dependency anti-pattern by using IServiceScopeFactory to open a short-lived scope for each DB call. Write methods (CreateAsync, DeleteAsync, ListAllAsync) pass through unchanged — resilience is read-path only per Phase 6.1 design decision. 15 new unit tests cover: DB success/failure/retry paths, snapshot sealing and per-group-set isolation, order-independent cache key normalisation, cancellation propagation, and pass-through method routing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
11 KiB
11 KiB