Files
ContentGen_BE/src/app.module.ts
Harun CAN adc6e34fca
Some checks failed
Backend Deploy 🚀 / build-and-deploy (push) Has been cancelled
main
2026-03-31 13:04:45 +03:00

243 lines
6.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { APP_FILTER, APP_GUARD, APP_INTERCEPTOR } from '@nestjs/core';
import { ThrottlerModule, ThrottlerGuard } from '@nestjs/throttler';
import { BullModule } from '@nestjs/bullmq';
import { CacheModule } from '@nestjs/cache-manager';
import { redisStore } from 'cache-manager-redis-yet';
import { LoggerModule } from 'nestjs-pino';
import {
I18nModule,
AcceptLanguageResolver,
HeaderResolver,
QueryResolver,
} from 'nestjs-i18n';
import * as path from 'path';
// Config
import {
appConfig,
databaseConfig,
jwtConfig,
redisConfig,
i18nConfig,
featuresConfig,
throttleConfig,
} from './config/configuration';
import { geminiConfig } from './modules/gemini/gemini.config';
import { validateEnv } from './config/env.validation';
// Common
import { GlobalExceptionFilter } from './common/filters/global-exception.filter';
import { ResponseInterceptor } from './common/interceptors/response.interceptor';
// Database
import { DatabaseModule } from './database/database.module';
// Modules
import { AuthModule } from './modules/auth/auth.module';
import { UsersModule } from './modules/users/users.module';
import { AdminModule } from './modules/admin/admin.module';
import { HealthModule } from './modules/health/health.module';
import { GeminiModule } from './modules/gemini/gemini.module';
// Video SaaS Modules
import { ProjectsModule } from './modules/projects/projects.module';
import { VideoQueueModule } from './modules/video-queue/video-queue.module';
import { VideoAiModule } from './modules/video-ai/video-ai.module';
import { StorageModule } from './modules/storage/storage.module';
import { BillingModule } from './modules/billing/billing.module';
import { XTwitterModule } from './modules/x-twitter/x-twitter.module';
import { EventsModule } from './modules/events/events.module';
import { RenderCallbackModule } from './modules/render-callback/render-callback.module';
import { DashboardModule } from './modules/dashboard/dashboard.module';
import { NotificationsModule } from './modules/notifications/notifications.module';
// Guards
import {
JwtAuthGuard,
RolesGuard,
PermissionsGuard,
} from './modules/auth/guards';
@Module({
imports: [
// Configuration
ConfigModule.forRoot({
isGlobal: true,
validate: validateEnv,
load: [
appConfig,
databaseConfig,
jwtConfig,
redisConfig,
i18nConfig,
featuresConfig,
throttleConfig,
geminiConfig,
],
}),
// BullMQ — Redis tabanlı job kuyruğu (Video üretim pipeline)
BullModule.forRootAsync({
imports: [ConfigModule],
useFactory: (configService: ConfigService) => ({
connection: {
host: configService.get<string>('redis.host', 'localhost'),
port: configService.get<number>('redis.port', 6379),
password: configService.get<string>('redis.password') || undefined,
},
}),
inject: [ConfigService],
}),
// Logger (Structured Logging with Pino)
LoggerModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: async (configService: ConfigService) => {
return {
pinoHttp: {
level: configService.get('app.isDevelopment') ? 'debug' : 'info',
transport: configService.get('app.isDevelopment')
? {
target: 'pino-pretty',
options: {
singleLine: true,
},
}
: undefined,
},
};
},
}),
// i18n
I18nModule.forRootAsync({
useFactory: (configService: ConfigService) => ({
fallbackLanguage: configService.get('i18n.fallbackLanguage', 'en'),
loaderOptions: {
path: path.join(__dirname, '..', 'i18n'),
watch: configService.get('app.isDevelopment', true),
},
}),
resolvers: [
new HeaderResolver(['x-lang', 'accept-language']),
new QueryResolver(['lang']),
AcceptLanguageResolver,
],
inject: [ConfigService],
}),
// Throttling
ThrottlerModule.forRootAsync({
inject: [ConfigService],
useFactory: (configService: ConfigService) => [
{
ttl: configService.get('throttle.ttl', 60000),
limit: configService.get('throttle.limit', 100),
},
],
}),
// Caching (Redis with in-memory fallback)
CacheModule.registerAsync({
isGlobal: true,
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => {
const useRedis = configService.get('REDIS_ENABLED', 'false') === 'true';
if (useRedis) {
try {
const store = await redisStore({
socket: {
host: configService.get('redis.host', 'localhost'),
port: configService.get('redis.port', 6379),
},
ttl: 60 * 1000, // 1 minute default
});
console.log('✅ Redis cache connected');
return {
store: store as unknown as any,
ttl: 60 * 1000,
};
} catch {
console.warn('⚠️ Redis connection failed, using in-memory cache');
}
}
// Fallback to in-memory cache
console.log('📦 Using in-memory cache');
return {
ttl: 60 * 1000,
};
},
inject: [ConfigService],
}),
// Database
DatabaseModule,
// Core Modules
AuthModule,
UsersModule,
AdminModule,
// Optional Modules (controlled by env variables)
GeminiModule,
HealthModule,
// Video SaaS Modules
ProjectsModule,
VideoQueueModule,
VideoAiModule,
StorageModule,
BillingModule,
XTwitterModule,
// Real-time & Callback Modules
EventsModule,
RenderCallbackModule,
DashboardModule,
NotificationsModule,
],
providers: [
// Global Exception Filter
{
provide: APP_FILTER,
useClass: GlobalExceptionFilter,
},
// Global Response Interceptor
{
provide: APP_INTERCEPTOR,
useClass: ResponseInterceptor,
},
// Global Rate Limiting
{
provide: APP_GUARD,
useClass: ThrottlerGuard,
},
// Global JWT Auth Guard
{
provide: APP_GUARD,
useClass: JwtAuthGuard,
},
// Global Roles Guard
{
provide: APP_GUARD,
useClass: RolesGuard,
},
// Global Permissions Guard
{
provide: APP_GUARD,
useClass: PermissionsGuard,
},
],
})
export class AppModule {}