Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/auth/guards/jwt-auth.guard.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { AUTH_STRATEGY } from '../../common/constants/auth.constants';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}
export class JwtAuthGuard extends AuthGuard(AUTH_STRATEGY.JWT) {}
3 changes: 2 additions & 1 deletion src/backup/backup.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { TypeOrmModule } from '@nestjs/typeorm';
import { BullModule } from '@nestjs/bull';
import { ConfigModule } from '@nestjs/config';
import { ScheduleModule } from '@nestjs/schedule';
import { QUEUE_NAMES } from '../common/constants/queue.constants';

// Entities
import { BackupRecord } from './entities/backup-record.entity';
Expand Down Expand Up @@ -31,7 +32,7 @@ import { MonitoringModule } from '../monitoring/monitoring.module';
ScheduleModule.forRoot(),
TypeOrmModule.forFeature([BackupRecord, RecoveryTest]),
BullModule.registerQueue({
name: 'backup-processing',
name: QUEUE_NAMES.BACKUP_PROCESSING,
}),
MediaModule, // For FileStorageService
MonitoringModule, // For AlertingService and MetricsCollectionService
Expand Down
7 changes: 4 additions & 3 deletions src/backup/backup.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { InjectRepository } from '@nestjs/typeorm';
import { Repository, LessThan } from 'typeorm';
import { InjectQueue } from '@nestjs/bull';
import { Queue } from 'bull';
import { QUEUE_NAMES, JOB_NAMES } from './../../common/constants/queue.constants';
import { ConfigService } from '@nestjs/config';
import { Cron } from '@nestjs/schedule';
import { BackupRecord } from './entities/backup-record.entity';
Expand All @@ -29,7 +30,7 @@ export class BackupService {
constructor(
@InjectRepository(BackupRecord)
private readonly backupRepository: Repository<BackupRecord>,
@InjectQueue('backup-processing')
@InjectQueue(QUEUE_NAMES.BACKUP_PROCESSING)
private readonly backupQueue: Queue,
private readonly configService: ConfigService,
private readonly alertingService: AlertingService,
Expand Down Expand Up @@ -103,7 +104,7 @@ export class BackupService {

// Queue backup job
await this.backupQueue.add(
'create-backup',
JOB_NAMES.CREATE_BACKUP,
{
backupRecordId: backupRecord.id,
backupType: BackupType.FULL,
Expand Down Expand Up @@ -157,7 +158,7 @@ export class BackupService {

for (const backup of expiredBackups) {
await this.backupQueue.add(
'delete-backup',
JOB_NAMES.DELETE_BACKUP,
{ backupRecordId: backup.id },
{
attempts: 3,
Expand Down
13 changes: 7 additions & 6 deletions src/backup/processing/backup-queue.processor.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Process, Processor } from '@nestjs/bull';
import { Logger } from '@nestjs/common';
import { Job } from 'bull';
import { QUEUE_NAMES, JOB_NAMES } from '../../common/constants/queue.constants';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { ConfigService } from '@nestjs/config';
Expand All @@ -24,7 +25,7 @@ import { S3Client, CopyObjectCommand, DeleteObjectCommand } from '@aws-sdk/clien
const execAsync = promisify(exec);
const MAX_RETRIES = 3;

@Processor('backup-processing')
@Processor(QUEUE_NAMES.BACKUP_PROCESSING)
export class BackupQueueProcessor {
private readonly logger = new Logger(BackupQueueProcessor.name);
private readonly kmsClient: KMSClient;
Expand Down Expand Up @@ -57,7 +58,7 @@ export class BackupQueueProcessor {
});
}

@Process('create-backup')
@Process(JOB_NAMES.CREATE_BACKUP)
async handleCreateBackup(job: Job<BackupJobData>) {
const { backupRecordId, databaseName } = job.data;
this.logger.log(`Processing backup creation for: ${backupRecordId}`);
Expand Down Expand Up @@ -136,7 +137,7 @@ export class BackupQueueProcessor {

// Queue verification job
await (job.queue as any).add(
'verify-backup',
JOB_NAMES.VERIFY_BACKUP,
{ backupRecordId, storageKey: encryptedKey },
{
attempts: 3,
Expand All @@ -151,7 +152,7 @@ export class BackupQueueProcessor {
}
}

@Process('verify-backup')
@Process(JOB_NAMES.VERIFY_BACKUP)
async handleVerifyBackup(job: Job<VerificationJobData>) {
const { backupRecordId } = job.data;
this.logger.log(`Verifying backup integrity: ${backupRecordId}`);
Expand All @@ -177,13 +178,13 @@ export class BackupQueueProcessor {
}
}

@Process('recovery-test')
@Process(JOB_NAMES.RECOVERY_TEST)
async handleRecoveryTest(_job: Job<RecoveryTestJobData>) {
this.logger.log(`Recovery test processing handled by RecoveryTestingService`);
// Delegated to RecoveryTestingService.executeRecoveryTest()
}

@Process('delete-backup')
@Process(JOB_NAMES.DELETE_BACKUP)
async handleDeleteBackup(job: Job<{ backupRecordId: string }>) {
const { backupRecordId } = job.data;
this.logger.log(`Deleting expired backup: ${backupRecordId}`);
Expand Down
5 changes: 3 additions & 2 deletions src/backup/testing/recovery-testing.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { InjectQueue } from '@nestjs/bull';
import { Queue } from 'bull';
import { QUEUE_NAMES, JOB_NAMES } from '../../common/constants/queue.constants';
import { ConfigService } from '@nestjs/config';
import { RecoveryTest } from '../entities/recovery-test.entity';
import { RecoveryTestStatus } from '../enums/recovery-test-status.enum';
Expand All @@ -27,7 +28,7 @@ export class RecoveryTestingService {
constructor(
@InjectRepository(RecoveryTest)
private readonly recoveryTestRepository: Repository<RecoveryTest>,
@InjectQueue('backup-processing')
@InjectQueue(QUEUE_NAMES.BACKUP_PROCESSING)
private readonly backupQueue: Queue,
private readonly backupService: BackupService,
private readonly fileStorageService: FileStorageService,
Expand Down Expand Up @@ -59,7 +60,7 @@ export class RecoveryTestingService {

// Queue recovery test job
await this.backupQueue.add(
'recovery-test',
JOB_NAMES.RECOVERY_TEST,
{
recoveryTestId: recoveryTest.id,
backupRecordId: backupId,
Expand Down
5 changes: 2 additions & 3 deletions src/caching/cache-management.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,13 @@ import { CacheInvalidationService } from './invalidation/invalidation.service';
import { CacheWarmingService } from './warming/cache-warming.service';
import { CacheStrategiesService } from './strategies/cache-strategies.service';
import { RolesGuard } from '../common/guards/roles.guard';
import { Roles } from '../common/decorators/roles.decorator';
// import { Role } from '../common/decorators/roles.decorator';
import { Roles, Role } from '../common/decorators/roles.decorator';

@ApiTags('Cache Management')
@ApiBearerAuth()
@Controller('cache')
@UseGuards(RolesGuard)
@Roles('admin')
@Roles(Role.ADMIN)
export class CacheManagementController {
constructor(
private readonly cachingService: CachingService,
Expand Down
4 changes: 4 additions & 0 deletions src/caching/caching.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ export const CACHE_PREFIXES = {
POPULAR: 'cache:popular',
ENROLLMENT: 'cache:enrollment',
FEATURED: 'cache:featured',
SYSTEM_CONFIG: 'cache:system:config',
USERS_LIST: 'cache:users:list',
} as const;

export const CACHE_EVENTS = {
Expand All @@ -30,4 +32,6 @@ export const CACHE_EVENTS = {
ENROLLMENT_CREATED: 'cache.enrollment.created',
ENROLLMENT_UPDATED: 'cache.enrollment.updated',
SEARCH_INDEX_UPDATED: 'cache.search.updated',
CACHE_INVALIDATED: 'cache.invalidated',
CACHE_PURGED: 'cache.purged',
} as const;
2 changes: 1 addition & 1 deletion src/caching/warming/cache-warming.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ export class CacheWarmingService implements OnModuleInit, OnModuleDestroy {
private async warmSystemConfig(): Promise<void> {
this.logger.debug('Warming system configuration...');

const configKey = 'cache:system:config';
const configKey = CACHE_PREFIXES.SYSTEM_CONFIG;

const configData = {
version: this.configService.get<string>('npm_package_version') || '1.0.0',
Expand Down
25 changes: 25 additions & 0 deletions src/collaboration/constants/collaboration-events.constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export const COLLABORATION_EVENTS = {
// Inbound WebSocket messages
JOIN_SESSION: 'join-session',
COLLABORATIVE_OPERATION: 'collaborative-operation',
REQUEST_SYNC: 'request-sync',
RESOLVE_CONFLICT: 'resolve-conflict',

// Outbound WebSocket messages
USER_JOINED: 'user-joined',
SESSION_STATE: 'session-state',
OPERATION_APPLIED: 'operation-applied',
FULL_SYNC: 'full-sync',
CONFLICT_RESOLVED: 'conflict-resolved',
} as const;

export const NOTIFICATION_GATEWAY_EVENTS = {
SUBSCRIBE: 'subscribe',
NOTIFICATION: 'notification',
BROADCAST_NOTIFICATION: 'broadcast_notification',
SUBSCRIBE_NOTIFICATIONS: 'subscribe_notifications',
} as const;

export const MESSAGING_GATEWAY_EVENTS = {
SEND_MESSAGE: 'send_message',
} as const;
19 changes: 10 additions & 9 deletions src/collaboration/gateway/collaboration.gateway.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
MessageBody,
ConnectedSocket,
} from '@nestjs/websockets';
import { COLLABORATION_EVENTS } from '../constants/collaboration-events.constants';
import { Server, Socket } from 'socket.io';
import { Logger, UseGuards } from '@nestjs/common';
import { CollaborationService } from '../collaboration.service';
Expand Down Expand Up @@ -75,7 +76,7 @@ export class CollaborationGateway
// Remove client from any active sessions
}

@SubscribeMessage('join-session')
@SubscribeMessage(COLLABORATION_EVENTS.JOIN_SESSION)
async handleJoinSession(
@MessageBody() data: { sessionId: string; userId: string; resourceType: string },
@ConnectedSocket() client: Socket,
Expand Down Expand Up @@ -122,10 +123,10 @@ export class CollaborationGateway
}

// Notify other users in the session
client.to(sessionId).emit('user-joined', { userId, sessionId });
client.to(sessionId).emit(COLLABORATION_EVENTS.USER_JOINED, { userId, sessionId });

// Send current resource state to the joining user
client.emit('session-state', {
client.emit(COLLABORATION_EVENTS.SESSION_STATE, {
sessionId,
resourceType,
resource,
Expand All @@ -139,7 +140,7 @@ export class CollaborationGateway
}
}

@SubscribeMessage('collaborative-operation')
@SubscribeMessage(COLLABORATION_EVENTS.COLLABORATIVE_OPERATION)
async handleCollaborativeOperation(
@MessageBody() operation: CollaborativeOperation,
@ConnectedSocket() client: Socket,
Expand Down Expand Up @@ -175,7 +176,7 @@ export class CollaborationGateway
});

// Broadcast the operation to all other clients in the session
client.to(sessionId).emit('operation-applied', {
client.to(sessionId).emit(COLLABORATION_EVENTS.OPERATION_APPLIED, {
operation: opData,
userId,
timestamp: Date.now(),
Expand All @@ -189,7 +190,7 @@ export class CollaborationGateway
}
}

@SubscribeMessage('request-sync')
@SubscribeMessage(COLLABORATION_EVENTS.REQUEST_SYNC)
async handleSyncRequest(
@MessageBody() data: { sessionId: string; userId: string },
@ConnectedSocket() client: Socket,
Expand All @@ -207,7 +208,7 @@ export class CollaborationGateway
const document = await this.sharedDocumentService.getDocument(sessionId);
const whiteboard = await this.whiteboardService.getWhiteboard(sessionId);

client.emit('full-sync', {
client.emit(COLLABORATION_EVENTS.FULL_SYNC, {
sessionId,
document: document || null,
whiteboard: whiteboard || null,
Expand All @@ -218,7 +219,7 @@ export class CollaborationGateway
}
}

@SubscribeMessage('resolve-conflict')
@SubscribeMessage(COLLABORATION_EVENTS.RESOLVE_CONFLICT)
async handleConflictResolution(
@MessageBody()
data: { sessionId: string; userId: string; resourceType: string; operations: any[] },
Expand Down Expand Up @@ -246,7 +247,7 @@ export class CollaborationGateway
}

// Broadcast resolved state to all clients
this.server.to(sessionId).emit('conflict-resolved', {
this.server.to(sessionId).emit(COLLABORATION_EVENTS.CONFLICT_RESOLVED, {
sessionId,
resourceType,
resolvedState: result,
Expand Down
3 changes: 3 additions & 0 deletions src/common/constants/auth.constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const AUTH_STRATEGY = {
JWT: 'jwt',
} as const;
31 changes: 31 additions & 0 deletions src/common/constants/event.constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
export const APP_EVENTS = {
// Data sync events
DATA_UPDATED: 'data.updated',

// Cache events
CACHE_INVALIDATED: 'cache.invalidated',
CACHE_PURGED: 'cache.purged',

// Data integrity events
DATA_CONSISTENCY_SCHEDULED: 'data.consistency.scheduled',
DATA_INTEGRITY_VIOLATION: 'data.integrity.violation',

// User events
USER_SIGNUP: 'user.signup',
USER_ADD_TAG: 'user.addTag',
USER_REMOVE_TAG: 'user.removeTag',

// Course events
COURSE_ENROLLED: 'course.enrolled',
COURSE_COMPLETED: 'course.completed',

// Payment events
PAYMENT_COMPLETED: 'payment.completed',

// Segment events
SEGMENT_ADD_USER: 'segment.addUser',

// Notification events
NOTIFICATION_SEND: 'notification.send',
NOTIFICATION_TEMPLATE_SEND: 'notification.template.send',
} as const;
42 changes: 42 additions & 0 deletions src/common/constants/queue.constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
export const QUEUE_NAMES = {
EMAIL: 'email',
EMAIL_MARKETING: 'email-marketing',
SYNC_TASKS: 'sync-tasks',
BACKUP_PROCESSING: 'backup-processing',
MESSAGE_QUEUE: 'message-queue',
MEDIA_PROCESSING: 'media-processing',
DEFAULT: 'default',
USER_DATA_EXPORT: 'user-data-export',
SUBSCRIPTIONS: 'subscriptions',
WEBHOOKS: 'webhooks',
} as const;

export const JOB_NAMES = {
// Email queue
SEND_EMAIL: 'send-email',

// Email marketing queue
SEND_CAMPAIGN: 'send-campaign',
PROCESS_CAMPAIGN: 'process-campaign',
RESUME_CAMPAIGN: 'resume-campaign',
SEND_AUTOMATION_EMAIL: 'send-automation-email',
CONTINUE_AUTOMATION: 'continue-automation',
CALL_WEBHOOK: 'call-webhook',

// Sync tasks queue
CONSISTENCY_CHECK: 'consistency-check',
REPLICATE_DATA: 'replicate-data',

// Backup processing queue
CREATE_BACKUP: 'create-backup',
VERIFY_BACKUP: 'verify-backup',
RECOVERY_TEST: 'recovery-test',
DELETE_BACKUP: 'delete-backup',

// Media processing queue
TRANSCODE_VIDEO: 'transcode-video',

// Payments queues
PROCESS_SUBSCRIPTION: 'process_subscription',
PROCESS_WEBHOOK: 'process-webhook',
} as const;
Loading
Loading