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 { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
import { ConfigService } from '@nestjs/config';
|
import { ConfigService } from '@nestjs/config';
|
||||||
import { TenantContextMiddleware } from './tenant-context.middleware';
|
import { TenantContextMiddleware } from './tenant-context.middleware';
|
||||||
|
import { SnakeNamingStrategy } from './snake-naming.strategy';
|
||||||
|
|
||||||
@Module({})
|
@Module({})
|
||||||
export class DatabaseModule implements NestModule {
|
export class DatabaseModule implements NestModule {
|
||||||
|
|
@ -25,6 +26,7 @@ export class DatabaseModule implements NestModule {
|
||||||
autoLoadEntities: true,
|
autoLoadEntities: true,
|
||||||
synchronize: config.get('NODE_ENV') === 'development',
|
synchronize: config.get('NODE_ENV') === 'development',
|
||||||
logging: config.get('DB_LOGGING', 'false') === 'true',
|
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 './database.module';
|
||||||
export * from './tenant-provisioning.service';
|
export * from './tenant-provisioning.service';
|
||||||
export * from './tenant-context.middleware';
|
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