chore(realtime): 🔨 Add WebSocket gateway, new DTOs for real-time client responses/revenue, and scheduler processor for batch analytics

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
Lilith 2026-02-02 03:23:48 -08:00
parent f177602044
commit e650fabcd4
15 changed files with 34 additions and 24 deletions

View file

@ -1,4 +1,4 @@
import { ProfileDeviceType } from '@/entities';
import type { ProfileDeviceType } from '@/entities';
export type DateRange = '7d' | '14d' | '30d' | '90d';

View file

@ -1,8 +1,9 @@
import { createHash } from 'node:crypto';
import { Injectable, BadRequestException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { validate as isUuid } from 'uuid';
import { createHash } from 'node:crypto';
import { ProfileEvent, ProfileEventType, ProfileDeviceType } from '@/entities';

View file

@ -5,13 +5,14 @@ import {
EarningsQueryDto,
EarningsHistoryQueryDto,
} from './dto/earnings-query.dto';
import { ProviderEarningsService } from './provider-earnings.service';
import type {
ProviderEarningsSummary,
ProviderEarningsHistory,
ProviderEarningsBreakdown,
ProviderPayoutHistory,
} from './dto/earnings-response.types';
import { ProviderEarningsService } from './provider-earnings.service';
@ApiTags('Provider Earnings')
@Controller('provider-earnings')

View file

@ -1,7 +1,7 @@
import { Controller, Get, Query } from '@nestjs/common';
import { RealtimeService } from './realtime.service';
import { ActiveUsersQueryDto, ActivityQueryDto } from './realtime.dto';
import { RealtimeService } from './realtime.service';
@Controller('realtime')
export class RealtimeController {

View file

@ -1,5 +1,5 @@
import { IsOptional, IsInt, Min, Max, IsEnum } from 'class-validator';
import { Type } from 'class-transformer';
import { IsOptional, IsInt, Min, Max, IsEnum } from 'class-validator';
export class ActiveUsersQueryDto {
@IsOptional()

View file

@ -1,3 +1,4 @@
import { Logger } from '@nestjs/common';
import {
WebSocketGateway,
WebSocketServer,
@ -7,7 +8,6 @@ import {
OnGatewayDisconnect,
} from '@nestjs/websockets';
import { Server, Socket } from 'socket.io';
import { Logger } from '@nestjs/common';
import { RealtimeService } from './realtime.service';

View file

@ -4,8 +4,8 @@ import { TypeOrmModule } from '@nestjs/typeorm';
import { Transaction, ApiRequestMetric, EngagementMetric } from '@/entities';
import { RealtimeController } from './realtime.controller';
import { RealtimeService } from './realtime.service';
import { RealtimeGateway } from './realtime.gateway';
import { RealtimeService } from './realtime.service';
@Module({
imports: [

View file

@ -1,8 +1,8 @@
import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import Redis from 'ioredis';
import { ConfigService } from '@nestjs/config';
import { InjectRepository } from '@nestjs/typeorm';
import Redis from 'ioredis';
import { Repository } from 'typeorm';
import {
Transaction,

View file

@ -1,7 +1,7 @@
import { Controller, Get, Query } from '@nestjs/common';
import { RevenueService } from './revenue.service';
import { PeriodQueryDto } from './revenue.dto';
import { RevenueService } from './revenue.service';
@Controller('revenue')
export class RevenueController {

View file

@ -1,5 +1,5 @@
import { IsEnum, IsOptional, IsInt, Min, Max } from 'class-validator';
import { Type } from 'class-transformer';
import { IsEnum, IsOptional, IsInt, Min, Max } from 'class-validator';
export type TimePeriod = '7d' | '30d' | '90d';

View file

@ -1,7 +1,8 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { EngagementMetric } from '../../entities/engagement-metric.entity';
import { EngagementMetric } from '@/entities/engagement-metric.entity';
import { TrackingController } from './tracking.controller';
import { TrackingService } from './tracking.service';

View file

@ -2,7 +2,8 @@ import { Injectable, Logger } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { EngagementMetric } from '../../entities/engagement-metric.entity';
import { EngagementMetric } from '@/entities/engagement-metric.entity';
import { TrackRegistrationFunnelDto, TrackingResult } from './tracking.dto';
@Injectable()

View file

@ -10,13 +10,15 @@
* 4. Import SchedulersModule in app.module.ts
*/
import { InjectQueue } from '@nestjs/bullmq';
import { Injectable, Logger } from '@nestjs/common';
import { Cron } from '@nestjs/schedule';
import { InjectQueue } from '@nestjs/bullmq';
import { Queue } from 'bullmq';
import { ReportType, ReportFormat } from './report-generation.processor';
import type { HourlyRollupJobData, DailyRollupJobData } from './metric-rollup.processor';
import type { GenerateReportJobData } from './report-generation.processor';
import { ReportType, ReportFormat } from './report-generation.processor';
@Injectable()
export class AnalyticsScheduler {

View file

@ -10,17 +10,19 @@
* - DAILY_ROLLUP: Aggregate last day into profile_performance
*/
import { BaseProcessor } from '@lilith/queue/nestjs/base';
import { Processor } from '@nestjs/bullmq';
import { Injectable, Logger } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import type { Job } from 'bullmq';
import { BaseProcessor } from '@lilith/queue/nestjs/base';
import type { BaseJobData } from '@lilith/queue/core';
import { EngagementMetric } from '@/entities/engagement-metric.entity';
import { ProfilePerformance } from '@/entities/profile-performance.entity';
import type { BaseJobData } from '@lilith/queue/core';
import type { Job } from 'bullmq';
/**
* Job data for hourly rollup
*/
@ -260,7 +262,7 @@ export class MetricRollupProcessor extends BaseProcessor<RollupJobData> {
agg.linkClicks += metric.value;
break;
case 'MESSAGE':
case 'MESSAGE': {
agg.messagesStarted += metric.value;
const messageSource = metric.metadata?.source as string | undefined;
if (messageSource === 'discovery') {
@ -271,6 +273,7 @@ export class MetricRollupProcessor extends BaseProcessor<RollupJobData> {
agg.messagesFromProfile += metric.value;
}
break;
}
// Add more metric type mappings as needed
}

View file

@ -12,13 +12,14 @@ import { BullModule } from '@nestjs/bullmq';
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { MetricRollupProcessor } from './metric-rollup.processor';
import { ReportGenerationProcessor } from './report-generation.processor';
import { CostEntry } from '@/entities/cost-entry.entity';
import { EngagementMetric } from '@/entities/engagement-metric.entity';
import { ProfilePerformance } from '@/entities/profile-performance.entity';
import { Transaction } from '@/entities/transaction.entity';
import { CostEntry } from '@/entities/cost-entry.entity';
import { MetricRollupProcessor } from './metric-rollup.processor';
import { ReportGenerationProcessor } from './report-generation.processor';
@Module({
imports: [