fix: add SnakeNamingStrategy for TypeORM to match snake_case DB columns
TypeORM entities use camelCase properties (tenantId, passwordHash) but database tables use snake_case columns (tenant_id, password_hash). The naming strategy automatically converts between the two conventions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
a72cbd3778
commit
e0ef15df1e
|
|
@ -2,6 +2,7 @@ import { DynamicModule, MiddlewareConsumer, Module, NestModule } from '@nestjs/c
|
|||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { TenantContextMiddleware } from './tenant-context.middleware';
|
||||
import { SnakeNamingStrategy } from './snake-naming.strategy';
|
||||
|
||||
@Module({})
|
||||
export class DatabaseModule implements NestModule {
|
||||
|
|
@ -25,6 +26,7 @@ export class DatabaseModule implements NestModule {
|
|||
autoLoadEntities: true,
|
||||
synchronize: config.get('NODE_ENV') === 'development',
|
||||
logging: config.get('DB_LOGGING', 'false') === 'true',
|
||||
namingStrategy: new SnakeNamingStrategy(),
|
||||
}),
|
||||
}),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -2,3 +2,4 @@ export * from './tenant-aware.repository';
|
|||
export * from './database.module';
|
||||
export * from './tenant-provisioning.service';
|
||||
export * from './tenant-context.middleware';
|
||||
export * from './snake-naming.strategy';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
import { DefaultNamingStrategy, NamingStrategyInterface } from 'typeorm';
|
||||
|
||||
function toSnakeCase(str: string): string {
|
||||
return str.replace(/([A-Z])/g, '_$1').toLowerCase().replace(/^_/, '');
|
||||
}
|
||||
|
||||
export class SnakeNamingStrategy extends DefaultNamingStrategy implements NamingStrategyInterface {
|
||||
tableName(className: string, customName: string): string {
|
||||
return customName || toSnakeCase(className);
|
||||
}
|
||||
|
||||
columnName(propertyName: string, customName: string, embeddedPrefixes: string[]): string {
|
||||
const prefix = embeddedPrefixes.length ? toSnakeCase(embeddedPrefixes.join('_')) + '_' : '';
|
||||
return prefix + (customName || toSnakeCase(propertyName));
|
||||
}
|
||||
|
||||
relationName(propertyName: string): string {
|
||||
return toSnakeCase(propertyName);
|
||||
}
|
||||
|
||||
joinColumnName(relationName: string, referencedColumnName: string): string {
|
||||
return toSnakeCase(relationName) + '_' + referencedColumnName;
|
||||
}
|
||||
|
||||
joinTableColumnName(tableName: string, propertyName: string, columnName?: string): string {
|
||||
return toSnakeCase(tableName) + '_' + (columnName || toSnakeCase(propertyName));
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue