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
2 changes: 1 addition & 1 deletion src/ai-integration/ai-integration.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@ import { QueueConsumerService } from './services/queue-consumer.service';
},
],
})
export class AiIntegrationModule { }
export class AiIntegrationModule {}
17 changes: 8 additions & 9 deletions src/ai-integration/services/queue-consumer.service.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Processor, WorkerHost } from "@nestjs/bullmq";
import { RedisQueues, Services } from "src/utils/constants";
import { AiSummarizationService } from "./summarization.service";
import { Processor, WorkerHost } from '@nestjs/bullmq';
import { RedisQueues, Services } from 'src/utils/constants';
import { AiSummarizationService } from './summarization.service';
import { Job } from 'bullmq';
import { SummarizeJob } from "src/common/interfaces/summarizeJob.interface";
import { Inject } from "@nestjs/common";
import { PrismaService } from "src/prisma/prisma.service";
import { SummarizeJob } from 'src/common/interfaces/summarizeJob.interface';
import { Inject } from '@nestjs/common';
import { PrismaService } from 'src/prisma/prisma.service';

@Processor(RedisQueues.postQueue.name)
export class QueueConsumerService extends WorkerHost {
Expand All @@ -30,11 +30,10 @@ export class QueueConsumerService extends WorkerHost {
private async handleSummarizePostContent(job: Job<SummarizeJob>) {
const { postContent, postId } = job.data;
const summary = await this.aiSummarizationService.summarizePost(postContent);

await this.prismaService.post.update({
where: { id: postId },
data: { summary },
});
}

}
}
11 changes: 5 additions & 6 deletions src/ai-integration/services/summarization.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,20 @@ export class AiSummarizationService {

// GPT-4.1 / GPT-4o / GPT-o-mini etc.
const response = await this.openai.responses.create({
model: "gpt-4o-mini", // similar price/perf to gemini flash
model: 'gpt-4o-mini', // similar price/perf to gemini flash
input: prompt,
});

const summary =
response.output_text;
const summary = response.output_text;

if (!summary || summary.trim().length === 0) {
return "Summary unavailable.";
return 'Summary unavailable.';
}

return summary;
} catch (error) {
console.error("Error summarizing post:", error);
return "Summary unavailable.";
console.error('Error summarizing post:', error);
return 'Summary unavailable.';
}
}
}
2 changes: 2 additions & 0 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { MessagesModule } from './messages/messages.module';
import { ConversationsModule } from './conversations/conversations.module';
import { PrismaModule } from './prisma/prisma.module';
import { AiIntegrationModule } from './ai-integration/ai-integration.module';
import { GatewayModule } from './gateway/gateway.module';
import envSchema from './config/validate-config';
import { BullModule } from '@nestjs/bullmq';
import redisConfig from './config/redis.config';
Expand Down Expand Up @@ -83,6 +84,7 @@ const envFilePath = '.env';
ConversationsModule,
PrismaModule,
AiIntegrationModule,
GatewayModule,
NotificationsModule,
],
controllers: [],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { OptionalJwtAuthGuard } from './optional-jwt-auth.guard';
describe('OptionalJwtAuthGuard', () => {
it('should be defined', () => {
expect(new OptionalJwtAuthGuard()).toBeDefined();
});
});
import { OptionalJwtAuthGuard } from './optional-jwt-auth.guard';

describe('OptionalJwtAuthGuard', () => {
it('should be defined', () => {
expect(new OptionalJwtAuthGuard()).toBeDefined();
});
});
68 changes: 34 additions & 34 deletions src/auth/services/otp/otp.service.spec.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
import { Test, TestingModule } from '@nestjs/testing';
import { OtpService } from './otp.service';
import { Services } from 'src/utils/constants';
describe('OtpService', () => {
let service: OtpService;
const mockRedisService = {
get: jest.fn(),
set: jest.fn(),
del: jest.fn(),
};
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
{
provide: Services.OTP,
useClass: OtpService,
},
{
provide: Services.REDIS,
useValue: mockRedisService,
},
],
}).compile();
service = module.get<OtpService>(Services.OTP);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});
import { Test, TestingModule } from '@nestjs/testing';
import { OtpService } from './otp.service';
import { Services } from 'src/utils/constants';

describe('OtpService', () => {
let service: OtpService;

const mockRedisService = {
get: jest.fn(),
set: jest.fn(),
del: jest.fn(),
};

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
{
provide: Services.OTP,
useClass: OtpService,
},
{
provide: Services.REDIS,
useValue: mockRedisService,
},
],
}).compile();

service = module.get<OtpService>(Services.OTP);
});

it('should be defined', () => {
expect(service).toBeDefined();
});
});
6 changes: 3 additions & 3 deletions src/common/config/mailer.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export default registerAs('mailer', () => ({
// Use AWS SES first, fallback to Resend if it fails
// Set to 'false' to use Resend only (skip AWS SES entirely)
useAwsFirst: process.env.EMAIL_USE_AWS_FIRST !== 'false', // Default to true

awsSes: {
smtpHost: process.env.AWS_SES_SMTP_HOST || 'email-smtp.us-east-1.amazonaws.com',
smtpPort: Number.parseInt(process.env.AWS_SES_SMTP_PORT || '587', 10),
Expand All @@ -13,12 +13,12 @@ export default registerAs('mailer', () => ({
fromEmail: process.env.AWS_SES_FROM_EMAIL || 'noreply@hankers.tech',
region: process.env.AWS_SES_REGION || 'us-east-1',
},

resend: {
apiKey: process.env.RESEND_API_KEY,
fromEmail: process.env.RESEND_FROM_EMAIL || 'noreply@hankers.tech',
},

azure: {
connectionString: process.env.AZURE_EMAIL_CONNECTION_STRING,
fromEmail: process.env.AZURE_EMAIL_FROM,
Expand Down
6 changes: 3 additions & 3 deletions src/common/interfaces/summarizeJob.interface.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export interface SummarizeJob {
postId: number;
postContent: string;
}
postId: number;
postContent: string;
}
4 changes: 2 additions & 2 deletions src/config/configs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ import * as process from 'process';
dotenv.config();

export default {
openAiApiKey: process.env.OPENAI_API_KEY,
}
openAiApiKey: process.env.OPENAI_API_KEY,
};
2 changes: 1 addition & 1 deletion src/config/validate-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ const envSchema = Joi.object({
OPENAI_API_KEY: Joi.string().required(),
}).strict();

export default envSchema;
export default envSchema;
60 changes: 30 additions & 30 deletions src/email/email.controller.spec.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
import { Test, TestingModule } from '@nestjs/testing';
import { EmailController } from './email.controller';
import { EmailService } from './email.service';
import { Services } from 'src/utils/constants';
describe('EmailController', () => {
let controller: EmailController;
const mockEmailService = {
sendEmail: jest.fn(),
};
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [EmailController],
providers: [
{
provide: Services.EMAIL,
useValue: mockEmailService,
},
],
}).compile();
controller = module.get<EmailController>(EmailController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});
import { Test, TestingModule } from '@nestjs/testing';
import { EmailController } from './email.controller';
import { EmailService } from './email.service';
import { Services } from 'src/utils/constants';

describe('EmailController', () => {
let controller: EmailController;

const mockEmailService = {
sendEmail: jest.fn(),
};

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [EmailController],
providers: [
{
provide: Services.EMAIL,
useValue: mockEmailService,
},
],
}).compile();

controller = module.get<EmailController>(EmailController);
});

it('should be defined', () => {
expect(controller).toBeDefined();
});
});
16 changes: 8 additions & 8 deletions src/email/email.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,7 @@ import { SendEmailDto } from './dto/send-email.dto';
import { readFileSync } from 'fs';
import { join } from 'path';
import { Resend } from 'resend';
import {
EmailClient,
EmailMessage,
KnownEmailSendStatus,
} from '@azure/communication-email';
import { EmailClient, EmailMessage, KnownEmailSendStatus } from '@azure/communication-email';
import * as nodemailer from 'nodemailer';
import type { Transporter } from 'nodemailer';

Expand Down Expand Up @@ -131,7 +127,9 @@ export class EmailService {
});

try {
this.logger.log(`📧 [AWS SES] Sending email from: ${this.mailerConfiguration.awsSes.fromEmail}`);
this.logger.log(
`📧 [AWS SES] Sending email from: ${this.mailerConfiguration.awsSes.fromEmail}`,
);
this.logger.log(`📧 [AWS SES] Recipients: ${toRecipients.join(', ')}`);

const info = await this.awsSesTransporter.sendMail({
Expand Down Expand Up @@ -172,7 +170,9 @@ export class EmailService {
});

try {
this.logger.log(`📧 [RESEND] Sending email from: ${this.mailerConfiguration.resend.fromEmail}`);
this.logger.log(
`📧 [RESEND] Sending email from: ${this.mailerConfiguration.resend.fromEmail}`,
);
this.logger.log(`📧 [RESEND] Recipients: ${toRecipients.join(', ')}`);

const response = await this.resendClient.emails.send({
Expand Down Expand Up @@ -233,7 +233,7 @@ export class EmailService {

try {
this.logger.log(`📧 [AZURE] Sending email from: ${this.mailerConfiguration.azure.fromEmail}`);
const recipientEmails = recipients.map(r => typeof r === 'string' ? r : r.email);
const recipientEmails = recipients.map((r) => (typeof r === 'string' ? r : r.email));
this.logger.log(`📧 [AZURE] Recipients: ${recipientEmails.join(', ')}`);

const poller = await this.azureClient.beginSend(message);
Expand Down
11 changes: 11 additions & 0 deletions src/gateway/gateway.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Module } from '@nestjs/common';
import { SocketGateway } from './socket.gateway';
import { SocketService } from './socket.service';
import { MessagesModule } from 'src/messages/messages.module';

@Module({
imports: [MessagesModule],
providers: [SocketGateway, SocketService],
exports: [SocketService, SocketGateway],
})
export class GatewayModule {}
Loading
Loading