feat(portal-bff): redis client foundation per ADR-0010 #109
Reference in New Issue
Block a user
Delete Branch "feat/portal-bff/session-redis-client"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
First step toward Redis-backed sessions (ADR-0010). Adds the shared
ioredisconnection that every downstream consumer (session storage, OBO token cache, …) injects via the newREDIS_CLIENTDI token. No session logic in this PR — that's the next one.What lands
ioredis@^5.10.1as a direct dependency. Chosen by ADR-0010 for its mature Sentinel support — single-instance URL today, Sentinel-HA configuration lands with the prod infrastructure ADR..env.examplepromotesREDIS_URLfrom its future-vars comment to an active variable, defaulting to the local Compose stack's address. The Sentinel-style keys (REDIS_SENTINEL_HOSTS,REDIS_SENTINEL_NAME,REDIS_TLS) stay in the future-vars comment until the prod deploy.check-redis-config.ts— boot-time guard mirroring the existing four:redis(s):/// passwordless / placeholder URLs.RedisConfigwith parsedhost+portfor downstream observability.redis.token.ts—REDIS_CLIENTstring token +Redistype alias. Same shape as the existingENTRA_CONFIG/MSAL_CLIENT.redis.module.ts—RedisModulefactory provider:maxRetriesPerRequest: 3so an unreachable Redis surfaces a clear command-time error rather than an infinite reconnect storm.connect/ready/error/close/reconnectingevents into the Pino stream under therediscontext — easy log isolation.main.tscallsassertRedisConfig()alongside the other three validators;AppModuleimportsRedisModule.Decisions worth flagging
maxRetriesPerRequest: 3rather than the ioredis default of 20. With the default, a Redis outage masquerades as request-level timeouts spread over minutes. Capping low surfaces the outage in the first command failure — the BFF can then return 503 and recover quickly when Redis comes back.redis.duplicate()per ioredis convention. Connect/disconnect is one socket per BFF instance.OnApplicationShutdown+redis.quit().Verification
nx run-many -t lint test build --projects=portal-bff— green.check-redis-configcovers happy path + 6 failure modes;redis.modulecovers DI resolution against an unreachable URL plus the missing-env failure).rediscontext showsredis.connect→redis.readyon startup; killing the Redis container producesredis.close/redis.reconnectinglines.What this PR explicitly does NOT do
express-session+connect-redismiddleware. The next PR wires the session cookie (__Host-portal_session), the encrypted payload, and the lookup middleware that attachesuserto every request..env.examplefor when the prod deploy lands.