Severity: Medium
Type: Performance
Scope: users/guards/admin.guard.ts, Admin, Users
Labels: refactoring, help wanted
Description
AdminGuard.canActivate (src/users/guards/admin.guard.ts, lines ~10–26) loads the user via prisma.user.findUnique({ where: { walletAddress } }) for every admin-protected request, before comparing role !== 'ADMIN'. Under load, every admin dashboard, key-revocation, suspension, and KYC update adds one round trip to Postgres purely to verify a property already known at JWT issuance.
The query also runs after JwtAuthGuard, which has already authenticated the user, so the work is strictly redundant in the common case.
Recommendation
- Embed
role in the JWT payload at issuance (and include in the JwtStrategy.validate return value).
- Have
AdminGuard read request.user.role directly, with a RolesGuard (already present) enforcing it.
- Optionally fall back to a Redis-cached role check (TTL ≈ 60s) to survive role changes within a short window.
Severity: Medium
Type: Performance
Scope: users/guards/admin.guard.ts, Admin, Users
Labels:
refactoring,help wantedDescription
AdminGuard.canActivate(src/users/guards/admin.guard.ts, lines ~10–26) loads the user viaprisma.user.findUnique({ where: { walletAddress } })for every admin-protected request, before comparingrole !== 'ADMIN'. Under load, every admin dashboard, key-revocation, suspension, and KYC update adds one round trip to Postgres purely to verify a property already known at JWT issuance.The query also runs after
JwtAuthGuard, which has already authenticated the user, so the work is strictly redundant in the common case.Recommendation
rolein the JWT payload at issuance (and include in theJwtStrategy.validatereturn value).AdminGuardreadrequest.user.roledirectly, with aRolesGuard(already present) enforcing it.