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
87 changes: 43 additions & 44 deletions apps/hooks/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,56 +1,55 @@

import { prismaClient } from "@repo/db/client";
import express from "express";

import express from "express";
const app = express();
app.use(express.json());

app.post("/hooks/catch/:userId/:workflowId", async (req, res) => {
console.log("REcieved Here in the initla error")

const userId = req.params.userId;
const Data = req.body
try {
const result = await prismaClient.$transaction(
async (tx) => {
console.log("REcieved Here")
const workflow = await tx.workflow.create({
data: {
userId,
name: "Sample Workflow",
description: "Auto-generated workflow",
status: "Start",
config: {},
},
});
console.log("REcieved Here 2222")

const workflowExecution = await tx.workflowExecution.create({
data: {
workflowId: workflow.id,
status: "Start",
metadata: Data
},
});
console.log("REcieved Here 22222")

// Assuming that workflowExecutionTable requires a valid workflowExecution connection
const datInWork = await tx.workflowExecutionTable.create({
data : {
workflowExecution : {
connect : {id : workflowExecution.id}
}
}
});
return { workflow, workflowExecution , datInWork };
const { userId, workflowId } = req.params;
const { triggerData } = req.body;

const result = await prismaClient.$transaction(async (tx) => {
console.log("Request Recieved to hooks backed with", userId, workflowId);
Copy link

Copilot AI Jan 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spelling error: "Recieved" should be "Received".

Suggested change
console.log("Request Recieved to hooks backed with", userId, workflowId);
console.log("Request Received to hooks backed with", userId, workflowId);

Copilot uses AI. Check for mistakes.

const workflow = await tx.workflow.findFirst({
where: { id: workflowId, userId },
include: { nodes: { orderBy: { position: "asc" } } },
});
if (!workflow) {
throw new Error("Workflow not found or access denied");
}
);

res.status(200).json({ success: true, data: result });
} catch (err) {
console.error(err);
res.status(500).json({ success: false, error: "Internal Server Error" });
const workflowExecution = await tx.workflowExecution.create({
data: {
workflowId: workflow.id,
// next time you see this line validate the trigger data thinnnnnnnnnn
Copy link

Copilot AI Jan 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment indicates incomplete implementation. The trigger data validation should be added before merging to production to prevent invalid data from being stored in the workflow execution metadata.

Copilot uses AI. Check for mistakes.
status: "Pending",
metadata: triggerData,
},
});

const outBox = await tx.workflowExecutionTable.create({
Copy link

Copilot AI Jan 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The unused variable outBox is created but never used. Either remove this variable if it's not needed, or use the result appropriately.

Suggested change
const outBox = await tx.workflowExecutionTable.create({
await tx.workflowExecutionTable.create({

Copilot uses AI. Check for mistakes.
data: {
workflowExecutionId: workflowExecution.id,
},
});
return { workflowExecution };
});
return res.status(200).json({
success: true,
workflowExecutionId: result.workflowExecution.id,
});
} catch (error: any) {
console.log(error);
res.status(500).json({
success: false,
error: "Failed to process webhook"
});
}
});

app.listen(3002, () => console.log("Server listening on port 3002"));

app.listen(3003, () => {
console.log("Server running on 3003");
});
2 changes: 1 addition & 1 deletion apps/http-backend/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { googleAuth } from "./routes/google_callback.js";

const app = express()

const allowedOrigins = ['http://localhost:3000' , 'http://localhost:300/' ];
const allowedOrigins = ['http://localhost:3000', 'http://localhost:3001'];
app.use(cors({
origin: allowedOrigins,
credentials: true,
Expand Down
7 changes: 4 additions & 3 deletions apps/http-backend/src/routes/userRoutes/userRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,20 +280,21 @@ router.post("/create/workflow",
// ------------------------------------ FETCHING WORKFLOWS -----------------------------------

router.get("/workflows",
userMiddleware,
userMiddleware ,
Copy link

Copilot AI Jan 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spacing inconsistency: there's an extra space after userMiddleware. Remove the trailing space for consistent formatting.

Suggested change
userMiddleware ,
userMiddleware,

Copilot uses AI. Check for mistakes.
async (req: AuthRequest, res: Response) => {
try {
if (!req.user)
return res
.status(statusCodes.UNAUTHORIZED)
.json({ message: "User is not logged in /not authorized" });
const userId = req.user.id;
const userId = req.user.id ;
Copy link

Copilot AI Jan 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spacing inconsistency: there's an extra space after req.user.id. Remove the trailing space for consistent formatting.

Suggested change
const userId = req.user.id ;
const userId = req.user.id;

Copilot uses AI. Check for mistakes.

const workflows = await prismaClient.workflow.findMany({
where: {
userId: userId,
userId
},
});
console.log(workflows)
Copy link

Copilot AI Jan 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This console.log statement should be removed before merging. Debug logging should either be removed or replaced with a proper logging framework for production code.

Suggested change
console.log(workflows)

Copilot uses AI. Check for mistakes.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Remove debug console.log statement.

This debug statement should be removed before merging to avoid cluttering production logs.

🔎 Proposed fix
-      console.log(workflows)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
console.log(workflows)
🤖 Prompt for AI Agents
In apps/http-backend/src/routes/userRoutes/userRoutes.ts around line 297 there
is a leftover debug console.log(workflows); remove this debug statement before
merging — either delete the console.log call or replace it with a proper logger
call at an appropriate level (e.g., debug) if the information must be retained,
ensuring no direct console.log remains in production code.

return res
.status(statusCodes.OK)
.json({ message: "Workflows fetched succesfullu", Data: workflows });
Copy link

Copilot AI Jan 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spelling error in the response message: "succesfullu" should be "successfully".

Suggested change
.json({ message: "Workflows fetched succesfullu", Data: workflows });
.json({ message: "Workflows fetched successfully", Data: workflows });

Copilot uses AI. Check for mistakes.
Expand Down
2 changes: 1 addition & 1 deletion apps/http-backend/tsconfig.tsbuildinfo
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"root":["./src/index.ts","./src/routes/google_callback.ts","./src/routes/nodes.routes.ts","./src/routes/userRoutes/userMiddleware.ts","./src/routes/userRoutes/userRoutes.ts"],"version":"5.7.3"}
{"root":["./src/index.ts","./src/routes/google_callback.ts","./src/routes/nodes.routes.ts","./src/routes/userRoutes/userMiddleware.ts","./src/routes/userRoutes/userRoutes.ts"],"version":"5.7.3"}
12 changes: 12 additions & 0 deletions apps/processor/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Ignore build artifacts and dependency folders for production
node_modules/
dist/
build/
*.log
*.tsbuildinfo
.env
.DS_Store
coverage/
.tmp/
.idea/
.vscode/
64 changes: 39 additions & 25 deletions apps/processor/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,51 @@
import {prismaClient} from "@repo/db/client"
import { prismaClient } from "@repo/db/client";

import { Kafka } from "kafkajs";
import { retryLogic } from "./lib/retry.js";

const kafka = new Kafka({
clientId: 'Processing App',
brokers: ['localhost:9092']
})
const TOPIC_NAME = "First-Client";

const TOPIC_NAME = "First-Client"
async function main () {
const producer = kafka.producer();
await producer.connect();

const kafka = new Kafka({
brokers: ["localhost:9092"],
clientId: "Processing App",
});
async function main() {
const producer = kafka.producer();

await retryLogic(async () => {
await producer.connect();
console.log("Producer connected to kafka successfully");
}, 3);

while (1) {
const pedningRows = await prismaClient.workflowExecutionTable.findMany({
where : {},
take : 10
})
while (true) {
try {
const pendingRows = await prismaClient.workflowExecutionTable.findMany({
// take: 10,
Copy link

Copilot AI Jan 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The commented-out code for the take parameter should either be uncommented with a proper value or removed entirely. Leaving commented code in production reduces maintainability.

Suggested change
// take: 10,

Copilot uses AI. Check for mistakes.
where : {sent : false}
});
if (pendingRows.length > 0) {
await producer.send({
topic: TOPIC_NAME,
messages: pedningRows.map(r => ({ value: String(r.workflowExecutionId) }))
topic: TOPIC_NAME,

messages: pendingRows.map((r) => ({
value: r.workflowExecutionId,
})),
});

await prismaClient.workflowExecutionTable.deleteMany({
where : {
id : {
in : pedningRows.map(r => r.id)
}
}
})
await prismaClient.workflowExecutionTable.updateMany({
where: { id: { in: pendingRows.map((r) => r.id) } },
data : {sent : true}
});
console.log(`Published to kafka with ${pendingRows.length} to kafka `);
Copy link

Copilot AI Jan 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in console.log message: there's a duplicate word "to kafka" at the end. The message should read "Published X messages to kafka" without the redundant "to kafka" at the end.

Suggested change
console.log(`Published to kafka with ${pendingRows.length} to kafka `);
console.log(`Published ${pendingRows.length} messages to kafka`);

Copilot uses AI. Check for mistakes.
}

await new Promise((resolve) => setTimeout(resolve, 1000));
} catch (error) {
console.log("Processing Error", error);
// Continue loop even if there's an error
}
}
}
main()

console.log("Hello world");
main();
19 changes: 19 additions & 0 deletions apps/processor/src/lib/retry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export async function retryLogic<T>(
fn: () => Promise<T>,
maxRetries = 3
): Promise<T> {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
const result = await fn();
return result;
} catch (error) {
if (attempt === maxRetries - 1)
Copy link

Copilot AI Jan 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition attempt === maxRetries - 1 is incorrect. With maxRetries = 3, the loop runs from attempt 0 to 3 (inclusive), so this condition will throw an error at attempt 2, allowing one more retry at attempt 3. The condition should be attempt === maxRetries to throw after all retries are exhausted.

Suggested change
if (attempt === maxRetries - 1)
if (attempt === maxRetries)

Copilot uses AI. Check for mistakes.
throw Error("Max Retries Reached. Try again after some time");

const delay = Math.pow(2, attempt) * 1000;
console.log(`Retrying again with attempt ${attempt} after ${delay} ms`);
await new Promise((res) => setTimeout(res, delay));
}
}
Comment on lines +5 to +17
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Off-by-one error in retry logic.

The loop condition and throw check are inconsistent:

  • Loop runs attempt from 0 to maxRetries inclusive (4 iterations when maxRetries=3)
  • Error is thrown when attempt === maxRetries - 1 (i.e., on the 3rd iteration, attempt=2)
  • This means the function throws before the final retry attempt (attempt=3) is ever tried
🔎 Proposed fix
 export async function retryLogic<T>(
   fn: () => Promise<T>,
   maxRetries = 3
 ): Promise<T> {
-  for (let attempt = 0; attempt <= maxRetries; attempt++) {
+  for (let attempt = 0; attempt < maxRetries; attempt++) {
     try {
       const result = await fn();
       return result;
     } catch (error) {
-      if (attempt === maxRetries - 1)
+      if (attempt === maxRetries - 1) {
         throw Error("Max Retries Reached. Try again after some time");
+      }
 
       const delay = Math.pow(2, attempt) * 1000;
       console.log(`Retrying again with attempt ${attempt} after ${delay} ms`);
       await new Promise((res) => setTimeout(res, delay));
     }
   }
-  throw Error("Max Retries Reached. Try again after some time Technically this won't get executed but putting for the sake of making typescript happy ");
+  // Unreachable due to throw in catch block on final attempt
+  throw Error("Max Retries Reached");
 }

With this fix, for maxRetries=3:

  • attempt=0: 1st try
  • attempt=1: 2nd try (1st retry)
  • attempt=2: 3rd try (2nd retry) → throws on failure since attempt === maxRetries - 1

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In apps/processor/src/lib/retry.ts around lines 5 to 17, the retry loop runs
off-by-one: change the loop condition from "attempt = 0; attempt <= maxRetries;
attempt++" to "attempt = 0; attempt < maxRetries; attempt++" so attempts iterate
0..maxRetries-1 and the existing throw check (attempt === maxRetries - 1)
correctly throws after the final allowed attempt; keep the delay/logging and
await logic unchanged.

throw Error("Max Retries Reached. Try again after some time Technically this won't get executed but putting for the sake of making typescript happy ");
Comment on lines +5 to +18
Copy link

Copilot AI Jan 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This error is unreachable code. The loop guarantees that either a successful result is returned or an error is thrown at maxRetries, making this line impossible to execute. Consider removing it or restructuring the function to avoid TypeScript complaints without adding unreachable code.

Suggested change
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
const result = await fn();
return result;
} catch (error) {
if (attempt === maxRetries - 1)
throw Error("Max Retries Reached. Try again after some time");
const delay = Math.pow(2, attempt) * 1000;
console.log(`Retrying again with attempt ${attempt} after ${delay} ms`);
await new Promise((res) => setTimeout(res, delay));
}
}
throw Error("Max Retries Reached. Try again after some time Technically this won't get executed but putting for the sake of making typescript happy ");
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const result = await fn();
return result;
} catch (error) {
if (attempt === maxRetries - 1) {
break;
}
const delay = Math.pow(2, attempt) * 1000;
console.log(`Retrying again with attempt ${attempt} after ${delay} ms`);
await new Promise((res) => setTimeout(res, delay));
}
}
throw Error("Max Retries Reached. Try again after some time");

Copilot uses AI. Check for mistakes.
}
4 changes: 3 additions & 1 deletion apps/processor/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@
"compilerOptions" : {
"rootDir" : "./src",
"outDir" : "./dist"
}
},
"include": ["src"]

}
2 changes: 1 addition & 1 deletion apps/processor/tsconfig.tsbuildinfo
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"root":["./src/index.ts"],"version":"5.7.3"}
{"root":["./src/index.ts","./src/lib/retry.ts"],"version":"5.7.3"}
1 change: 1 addition & 0 deletions packages/db/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ model WorkflowExecutionTable {
id String @id @default(uuid())
workflowExecutionId String @unique
workflowExecution WorkflowExecution @relation(fields: [workflowExecutionId], references: [id])
sent Boolean @default(false)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# List migration files in the prisma migrations directory
ls -la packages/db/prisma/migrations 2>/dev/null | tail -20

# Check if migrations directory exists and list files
fd -t f . packages/db/prisma/migrations 2>/dev/null | head -30

Repository: Dev-Pross/BuildFlow

Length of output: 289


🏁 Script executed:

# Get the full context of WorkflowExecutionTable in the schema
rg -A 20 "model WorkflowExecutionTable" packages/db/prisma/schema.prisma

Repository: Dev-Pross/BuildFlow

Length of output: 441


🏁 Script executed:

# Search for any index definitions related to the sent field
rg "@@index.*sent|sent.*@@index" packages/db/prisma/schema.prisma

Repository: Dev-Pross/BuildFlow

Length of output: 45


🏁 Script executed:

# Check if there are any queries using the sent field
rg -i "sent\s*=" --type ts --type js packages/db -A 2 | head -40

Repository: Dev-Pross/BuildFlow

Length of output: 295


A Prisma migration file must be generated and applied for the sent field.

The sent field has been added to the schema but there is no corresponding migration file in packages/db/prisma/migrations/. Generate this migration with:

npx prisma migrate dev --name add_sent_field_to_workflow_execution_table

Additionally, consider adding an index on the sent field to improve query performance if the processor frequently queries for unsent records (WHERE sent = false):

model WorkflowExecutionTable {
  id                  String            @id @default(uuid())
  workflowExecutionId String            @unique
  workflowExecution   WorkflowExecution @relation(fields: [workflowExecutionId], references: [id])
  sent                Boolean           @default(false)
  
  @@index([sent])
}

Then generate and apply the migration to update the index.

🤖 Prompt for AI Agents
In packages/db/prisma/schema.prisma at line 121 the new "sent" Boolean field was
added but no Prisma migration exists; generate and apply a migration (e.g., run
npx prisma migrate dev --name add_sent_field_to_workflow_execution_table) so the
database is updated, and if queries will frequently filter WHERE sent = false
add an @@index([sent]) to the WorkflowExecutionTable model in the same schema
before generating the migration so the index is created together with the
column.

}

enum WorkflowStatus {
Expand Down