Skip to content

Commit d040204

Browse files
chore:refactor services/integrations change every class to Singelton pattern
1 parent 98b48d1 commit d040204

File tree

11 files changed

+69
-24
lines changed

11 files changed

+69
-24
lines changed

src/app/api/asp-ai/evaluate-answer/route.ts

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,12 @@ import { evaluateAnswer } from "@/app/server/services/ai/evaluateAnswer";
88
import { validateEvaluateAnswerAPIFormData } from "@/app/server/validators/asp-ai.validators";
99
import { getAuthenticatedUser } from "@/app/server/utils/getAuthUserDetails";
1010
import { User } from "@prisma/client";
11-
import { Duration, Ratelimit } from "@upstash/ratelimit";
12-
import { Redis } from "@upstash/redis";
1311
import { ErrorCodes } from "@/app/lib/constants";
12+
import RatelimitService from "@/app/server/services/integrations/rateLimitig.service";
1413

15-
const redis = new Redis({
16-
url: process.env.UPSTASH_REDIS_URL,
17-
token: process.env.UPSTASH_REDIS_TOKEN,
18-
});
19-
const ratelimit = new Ratelimit({
20-
redis: redis,
21-
limiter: Ratelimit.fixedWindow(
22-
parseInt(process.env.DEFAULT_API_TOKENS!),
23-
process.env.DEFAULT_API_TOKEN_FILLED_AFTER! as Duration,
24-
),
25-
});
26-
const s3 = new S3Service(process.env.AWS_S3_BUCKET_NAME!);
27-
const textExtract = new TextractService(process.env.AWS_S3_BUCKET_NAME!);
14+
const s3 = S3Service.getInstance(process.env.AWS_S3_BUCKET_NAME!);
15+
const textExtract =TextractService.getInstance(process.env.AWS_S3_BUCKET_NAME!);
16+
const rl = RatelimitService.getInstance().getRatelimit()
2817

2918
export const maxDuration = 60;
3019

@@ -41,7 +30,7 @@ export async function POST(req: Request) {
4130

4231
// Rate limiting
4332
//apiPath:keyPerfix:key
44-
const rateLimitCheck = await ratelimit.limit(
33+
const rateLimitCheck = await rl.limit(
4534
`/asp-ai/evaluate-answer:userId:${user.id}`,
4635
);
4736

src/app/server/services/answers.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { prisma } from "../db/prisma";
1+
import { prisma } from "../utils/prisma";
22

33
export async function createAnswer({
44
id,
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { Duration, Ratelimit } from "@upstash/ratelimit";
2+
import { Redis } from "@upstash/redis";
3+
4+
class RatelimitService {
5+
private static instance: RatelimitService;
6+
private ratelimitInstance: Ratelimit;
7+
8+
// Private constructor to prevent direct instantiation
9+
private constructor() {
10+
const redisClient = new Redis({
11+
url: process.env.UPSTASH_REDIS_URL!,
12+
token: process.env.UPSTASH_REDIS_TOKEN!,
13+
});
14+
15+
this.ratelimitInstance = new Ratelimit({
16+
redis: redisClient,
17+
limiter: Ratelimit.fixedWindow(
18+
parseInt(process.env.DEFAULT_API_TOKENS!),
19+
process.env.DEFAULT_API_TOKEN_FILLED_AFTER! as Duration,
20+
),
21+
});
22+
}
23+
24+
// Static method to get the singleton instance
25+
public static getInstance(): RatelimitService {
26+
if (!RatelimitService.instance) {
27+
RatelimitService.instance = new RatelimitService();
28+
}
29+
return RatelimitService.instance;
30+
}
31+
32+
// Expose the Ratelimit instance
33+
public getRatelimit(): Ratelimit {
34+
return this.ratelimitInstance;
35+
}
36+
}
37+
38+
export default RatelimitService;

src/app/server/services/integrations/s3.service.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3";
22
import { Upload } from "@aws-sdk/lib-storage";
33
import { Readable } from "stream";
44

5-
// TODO: Singleton pattern
65
export class S3Service {
6+
private static instance: S3Service;
77
private s3Client: S3Client;
88
private bucketName: string;
99

10-
constructor(bucketName: string) {
10+
private constructor(bucketName: string) {
1111
this.bucketName = bucketName;
1212
this.s3Client = new S3Client({
1313
region: process.env.AWS_REGION,
@@ -18,6 +18,13 @@ export class S3Service {
1818
});
1919
}
2020

21+
static getInstance(bucketName: string): S3Service {
22+
if (!S3Service.instance) {
23+
S3Service.instance = new S3Service(bucketName);
24+
}
25+
return S3Service.instance;
26+
}
27+
2128
async uploadFile(
2229
key: string,
2330
body: Buffer | Readable,

src/app/server/services/integrations/texextract.service.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ import {
77
export const maxDuration = 60;
88

99
export class TextractService {
10+
private static instance: TextractService;
1011
private textractClient: TextractClient;
1112
private bucketName: string;
1213

13-
constructor(bucketName: string) {
14+
// Private constructor to prevent direct instantiation
15+
private constructor(bucketName: string) {
1416
this.bucketName = bucketName;
1517
this.textractClient = new TextractClient({
1618
region: process.env.AWS_REGION,
@@ -21,6 +23,14 @@ export class TextractService {
2123
});
2224
}
2325

26+
// Static method to get the singleton instance
27+
public static getInstance(bucketName: string): TextractService {
28+
if (!TextractService.instance) {
29+
TextractService.instance = new TextractService(bucketName);
30+
}
31+
return TextractService.instance;
32+
}
33+
2434
public async extractTextFromS3PDF(objectKey: string): Promise<string> {
2535
try {
2636
// Start the Textract document text detection

src/app/server/services/questions.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
Papers,
55
QuestionsWithEverything,
66
} from "@/app/lib/types/feed.types";
7-
import { prisma } from "../db/prisma";
7+
import { prisma } from "../utils/prisma";
88

99
const DEFAULT_ANSWER_LIMIT = 5;
1010
const DEFAULT_QUESTIONS_OFFSET = 0;

src/app/server/services/topics.services.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { prisma } from "../db/prisma";
1+
import { prisma } from "../utils/prisma";
22

33
export const getAllTopics = () => {
44
return prisma.topics.findMany();

src/app/server/services/user.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { prisma } from "../db/prisma";
1+
import { prisma } from "../utils/prisma";
22

33
export async function getUserByEmail(email: string) {
44
const user = await prisma.user.findUnique({
File renamed without changes.

src/app/server/validators/asp-ai.validators.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { ErrorCodes } from "@/app/lib/constants";
22
import { NextResponse } from "next/server";
33

4+
// TODO: Replace this with zod schema.
45
export async function validateEvaluateAnswerAPIFormData(
56
answerPDF: FormDataEntryValue | null,
67
question?: string,

0 commit comments

Comments
 (0)