fix: close four auth/schema gaps (PrismaModule import, typed mappers, UserStatus enum, session filter) - #860
Open
Zinai10 wants to merge 1 commit into
Conversation
…status enum, session filter) Issue 1 – PrismaModule missing from AuthModule @module imports - Added PrismaModule to AuthModule's imports array; it was imported at the top of the file but omitted from @module({ imports }), silently relying on a global side-effect registration. Without this, PrismaService cannot be injected into RefreshTokenService at runtime. - Fixed key-management.module.ts: added missing EventEmitterModule import and KeyValidationCacheService import + provider declaration. - Fixed jest moduleNameMapper: added mapping for the bare 'generated/prisma' import path used by refresh-token.service.ts (previously only the '/client' suffix was mapped). - Rewrote auth.module.spec.ts as a fast, hermetic Reflect.getMetadata check that fails immediately if PrismaModule is ever removed from imports again. - Updated Prisma client mock to inline all enum values, eliminating the circular-import problem that blocked the test suite. Issue 2 – mapPrismaXxx mappers typed as (prisma: any) - wallets.service.ts: mapPrismaWalletToDomain now accepts PrismaWallet (generated Wallet row type) instead of any. - users/idempotent-user.service.ts: mapPrismaUserToDomain and validateUserState now accept PrismaUser instead of any. - api-keys/api-key.service.ts: mapPrismaApiKeyToDomain now accepts PrismaApiKey instead of any. - Schema drift (accessing a renamed/removed column) now causes a TypeScript compile error rather than a silent runtime bug. Issue 3 – User.status stored as free-form String - Added UserStatus enum to prisma/schema.prisma with the five lifecycle states already defined in user.entity.ts: PROVISIONING, ACTIVE, RECOVERY_PENDING, SUSPENDED, DISABLED. - Changed User.status column from String @default("ACTIVE") to UserStatus @default(ACTIVE). - Added migration 20260831000001_add_user_status_enum with a safe, fail-closed upgrade path: normalises legacy 'INACTIVE' rows to 'DISABLED', guards against unknown values, then ALTERs the column with an explicit USING cast. - Regenerated Prisma client; the generated UserStatus enum matches the entity's UserStatus exactly (same string values), so no application-layer casting changes are needed. Issue 4 – Session filter enum aligned with UserStatus - AuthSessionFilterDto already uses UserStatus from user.entity.ts, so the DTO validation and the controller's @apiquery decorator both reflect the authoritative five-state enum. No behaviour change — this was verified correct and documented explicitly. Test coverage - auth.module.spec.ts: 5 regression guards via Reflect.getMetadata; will fail if PrismaModule is removed from imports or providers/exports change. - Typed mappers: TypeScript compile-time enforcement (tsc --noEmit) catches schema drift; no new runtime tests needed for a pure type-narrowing change. - Migration: fail-fast DO 15439 block aborts if unrecognised status values exist before the ALTER TABLE executes. No secrets logged. No fail-open auth paths introduced.
|
@Zinai10 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes four correctness gaps that could cause silent runtime failures in production:
Issue 1 – PrismaModule missing from AuthModule
@ModuleimportsPrismaModulewas imported at the top ofauth.module.tsbut omitted from@Module({ imports }), silently relying on a global side-effect. Without this,PrismaServicecannot be injected intoRefreshTokenServiceat runtime — auth token issuance would fail at startup in any module that doesn't happen to importPrismaModuleelsewhere in its own graph.Changes:
PrismaModuletoAuthModule'simportsarray.key-management.module.ts: added missingEventEmitterModuleimport andKeyValidationCacheServiceprovider declaration.moduleNameMapper: added mapping for the baregenerated/prismaimport path (only the/clientsuffix was mapped previously, causing test-suite compilation failures).auth.module.spec.tsas a fastReflect.getMetadataregression guard — fails immediately ifPrismaModuleis ever removed fromimportsagain.Issue 2 –
mapPrismaXxxmappers typed as(prisma: any)Three private mapper functions accepted
any, hiding schema drift until runtime.Changes:
wallets.service.ts:mapPrismaWalletToDomain→PrismaWallet(generatedWalletrow type).users/idempotent-user.service.ts:mapPrismaUserToDomainandvalidateUserState→PrismaUser.api-keys/api-key.service.ts:mapPrismaApiKeyToDomain→PrismaApiKey.Accessing a renamed or removed column now produces a TypeScript compile error (
tsc --noEmit) rather than a silentundefinedat runtime.Issue 3 –
User.statusstored as free-formStringUser.statuswas aStringcolumn with no DB-level constraint, meaning any arbitrary string could be written and the application would silently misinterpret it.Changes:
UserStatusenum toprisma/schema.prismawith the five lifecycle states already authoritative inuser.entity.ts:PROVISIONING,ACTIVE,RECOVERY_PENDING,SUSPENDED,DISABLED.User.statusfromString @default("ACTIVE")→UserStatus @default(ACTIVE).20260831000001_add_user_status_enumwith a safe upgrade path: normalises legacyINACTIVErows toDISABLED, guards with a fail-fastDO 15858block, thenALTER TABLE ... USINGcast.UserStatusmatches the entity enum exactly (same string values) — no application-layer casting changes required.Issue 4 – Session filter enum alignment
AuthSessionFilterDtoalready usesUserStatusfromuser.entity.tsfor its@IsEnumvalidator and Swagger@ApiProperty({ enum: UserStatus }). The controller's@ApiQuerydecorator also documents the correct five states. No code changes needed — verified correct and explicitly documented.Test coverage
Reflect.getMetadataassertions inauth.module.spec.ts(all pass)tsc --noEmit— compile-time enforcement; schema drift is now a build errorALTER TABLENo regressions introduced
pnpm testsuite unaffected for all files not touched by this PR.closes #773
closes #774
closes #775
closes #776