diff --git a/Screenshot 2024-10-15 180911.png b/Screenshot 2024-10-15 180911.png
new file mode 100644
index 0000000..e28ba8f
Binary files /dev/null and b/Screenshot 2024-10-15 180911.png differ
diff --git a/frontend/app/config.ts b/frontend/app/config.ts
index 3a2a8ac..684bf12 100644
--- a/frontend/app/config.ts
+++ b/frontend/app/config.ts
@@ -1,2 +1,2 @@
export const BACKEND_URL="http://localhost:3000"
-export const HOOKS_URL="https://localhost:3002"
\ No newline at end of file
+export const HOOKS_URL="http://localhost:3002"
\ No newline at end of file
diff --git a/frontend/app/login/page.tsx b/frontend/app/login/page.tsx
index 11abe3b..aaf3a54 100644
--- a/frontend/app/login/page.tsx
+++ b/frontend/app/login/page.tsx
@@ -12,11 +12,6 @@ export default function Page() {
const [email,setEmail]=useState("");
const [password,setPassword]=useState("");
const router=useRouter();
- useEffect(()=>{
- if(localStorage.getItem("token")){
- router.push("/dashboard")
- }
- },[])
return (
diff --git a/hooks/package.json b/hooks/package.json
index 205856a..d869d8f 100644
--- a/hooks/package.json
+++ b/hooks/package.json
@@ -3,7 +3,7 @@
"version": "1.0.0",
"main": "index.js",
"scripts": {
- "start": "tsc -b && node dist/index.js"
+ "dev": "tsc -b && node dist/index.js"
},
"keywords": [],
"author": "",
diff --git a/primaryBackend/package.json b/primaryBackend/package.json
index 21c6981..44ad0b3 100644
--- a/primaryBackend/package.json
+++ b/primaryBackend/package.json
@@ -3,7 +3,7 @@
"version": "1.0.0",
"main": "index.js",
"scripts": {
- "start": "tsc -b && node dist/index.js"
+ "dev": "tsc -b && node dist/index.js"
},
"keywords": [],
"author": "",
diff --git a/processor/dist/index.js b/processor/dist/index.js
index 5321812..56e70e2 100644
--- a/processor/dist/index.js
+++ b/processor/dist/index.js
@@ -31,7 +31,7 @@ function main() {
topic: TOPIC_NAME,
messages: pendingRows.map(r => {
return {
- value: r.zapRunId
+ value: JSON.stringify({ zapRunId: r.zapRunId, stage: 0 })
};
})
});
diff --git a/processor/package.json b/processor/package.json
index dafa3e3..713820b 100644
--- a/processor/package.json
+++ b/processor/package.json
@@ -3,7 +3,7 @@
"version": "1.0.0",
"main": "index.js",
"scripts": {
- "start": "tsc -b && node dist/index.js"
+ "dev": "tsc -b && node dist/index.js"
},
"keywords": [],
"author": "",
diff --git a/worker/.gitignore b/worker/.gitignore
new file mode 100644
index 0000000..11ddd8d
--- /dev/null
+++ b/worker/.gitignore
@@ -0,0 +1,3 @@
+node_modules
+# Keep environment variables out of version control
+.env
diff --git a/worker/dist/index.js b/worker/dist/index.js
index 578575c..15a120a 100644
--- a/worker/dist/index.js
+++ b/worker/dist/index.js
@@ -10,6 +10,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
};
Object.defineProperty(exports, "__esModule", { value: true });
const kafkajs_1 = require("kafkajs");
+const client_1 = require("@prisma/client");
+const prismaClient = new client_1.PrismaClient();
const TOPIC_NAME = "zap-events";
const kafka = new kafkajs_1.Kafka({
clientId: "outbox-processor",
@@ -21,18 +23,68 @@ function main() {
groupId: "main-worker",
});
yield consumer.connect();
+ const producer = kafka.producer();
+ yield producer.connect();
yield consumer.subscribe({ topic: TOPIC_NAME, fromBeginning: true });
yield consumer.run({
autoCommit: false,
eachMessage: (_a) => __awaiter(this, [_a], void 0, function* ({ topic, partition, message }) {
- var _b;
+ var _b, _c, _d, _e, _f;
console.log({
partition,
offset: message.offset,
value: (_b = message.value) === null || _b === void 0 ? void 0 : _b.toString(),
});
- //
+ if (!((_c = message.value) === null || _c === void 0 ? void 0 : _c.toString())) {
+ return;
+ }
+ const parsedValue = JSON.parse((_d = message.value) === null || _d === void 0 ? void 0 : _d.toString());
+ const zapRunId = parsedValue.zapRunId;
+ const stage = parsedValue.stage;
+ const zapRunDetails = yield prismaClient.zapRun.findFirst({
+ where: {
+ id: zapRunId
+ },
+ include: {
+ zap: {
+ include: {
+ actions: {
+ include: {
+ type: true
+ }
+ }
+ }
+ }
+ }
+ });
+ const currentAction = zapRunDetails === null || zapRunDetails === void 0 ? void 0 : zapRunDetails.zap.actions.find(x => x.sortingOrder === stage);
+ if (!currentAction) {
+ console.log('Current action not found');
+ return;
+ }
+ console.log(currentAction);
+ if (currentAction.type.id === 'email') {
+ console.log('Sending out an email');
+ //parse out the email to send
+ }
+ if (currentAction.type.id === 'send-sol') {
+ console.log('Sending out solana');
+ //parse out the address and the amount to send
+ }
yield new Promise((r) => setTimeout(r, 500));
+ const zapId = (_e = message === null || message === void 0 ? void 0 : message.value) === null || _e === void 0 ? void 0 : _e.toString();
+ const lastStage = (((_f = zapRunDetails === null || zapRunDetails === void 0 ? void 0 : zapRunDetails.zap.actions) === null || _f === void 0 ? void 0 : _f.length) || 1) - 1;
+ if (lastStage !== stage) {
+ yield producer.send({
+ topic: TOPIC_NAME,
+ messages: [{
+ value: JSON.stringify({
+ stage: stage + 1,
+ zapRunId
+ })
+ }]
+ });
+ }
console.log('processing done');
//you can do your action operation here!
//
diff --git a/worker/node_modules/.package-lock.json b/worker/node_modules/.package-lock.json
index 7c73dd3..a98f2dd 100644
--- a/worker/node_modules/.package-lock.json
+++ b/worker/node_modules/.package-lock.json
@@ -4,6 +4,74 @@
"lockfileVersion": 3,
"requires": true,
"packages": {
+ "node_modules/@prisma/client": {
+ "version": "5.20.0",
+ "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.20.0.tgz",
+ "integrity": "sha512-CLv55ZuMuUawMsxoqxGtLT3bEZoa2W8L3Qnp6rDIFWy+ZBrUcOFKdoeGPSnbBqxc3SkdxJrF+D1veN/WNynZYA==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=16.13"
+ },
+ "peerDependencies": {
+ "prisma": "*"
+ },
+ "peerDependenciesMeta": {
+ "prisma": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@prisma/debug": {
+ "version": "5.20.0",
+ "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.20.0.tgz",
+ "integrity": "sha512-oCx79MJ4HSujokA8S1g0xgZUGybD4SyIOydoHMngFYiwEwYDQ5tBQkK5XoEHuwOYDKUOKRn/J0MEymckc4IgsQ==",
+ "devOptional": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/@prisma/engines": {
+ "version": "5.20.0",
+ "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.20.0.tgz",
+ "integrity": "sha512-DtqkP+hcZvPEbj8t8dK5df2b7d3B8GNauKqaddRRqQBBlgkbdhJkxhoJTrOowlS3vaRt2iMCkU0+CSNn0KhqAQ==",
+ "devOptional": true,
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@prisma/debug": "5.20.0",
+ "@prisma/engines-version": "5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284",
+ "@prisma/fetch-engine": "5.20.0",
+ "@prisma/get-platform": "5.20.0"
+ }
+ },
+ "node_modules/@prisma/engines-version": {
+ "version": "5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284",
+ "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284.tgz",
+ "integrity": "sha512-Lg8AS5lpi0auZe2Mn4gjuCg081UZf88k3cn0RCwHgR+6cyHHpttPZBElJTHf83ZGsRNAmVCZCfUGA57WB4u4JA==",
+ "devOptional": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/@prisma/fetch-engine": {
+ "version": "5.20.0",
+ "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.20.0.tgz",
+ "integrity": "sha512-JVcaPXC940wOGpCOwuqQRTz6I9SaBK0c1BAyC1pcz9xBi+dzFgUu3G/p9GV1FhFs9OKpfSpIhQfUJE9y00zhqw==",
+ "devOptional": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@prisma/debug": "5.20.0",
+ "@prisma/engines-version": "5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284",
+ "@prisma/get-platform": "5.20.0"
+ }
+ },
+ "node_modules/@prisma/get-platform": {
+ "version": "5.20.0",
+ "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.20.0.tgz",
+ "integrity": "sha512-8/+CehTZZNzJlvuryRgc77hZCWrUDYd/PmlZ7p2yNXtmf2Una4BWnTbak3us6WVdqoz5wmptk6IhsXdG2v5fmA==",
+ "devOptional": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@prisma/debug": "5.20.0"
+ }
+ },
"node_modules/kafkajs": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/kafkajs/-/kafkajs-2.2.4.tgz",
@@ -11,6 +79,26 @@
"engines": {
"node": ">=14.0.0"
}
+ },
+ "node_modules/prisma": {
+ "version": "5.20.0",
+ "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.20.0.tgz",
+ "integrity": "sha512-6obb3ucKgAnsGS9x9gLOe8qa51XxvJ3vLQtmyf52CTey1Qcez3A6W6ROH5HIz5Q5bW+0VpmZb8WBohieMFGpig==",
+ "devOptional": true,
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@prisma/engines": "5.20.0"
+ },
+ "bin": {
+ "prisma": "build/index.js"
+ },
+ "engines": {
+ "node": ">=16.13"
+ },
+ "optionalDependencies": {
+ "fsevents": "2.3.3"
+ }
}
}
}
diff --git a/worker/package-lock.json b/worker/package-lock.json
index 1e6a544..c5bb88a 100644
--- a/worker/package-lock.json
+++ b/worker/package-lock.json
@@ -9,7 +9,94 @@
"version": "1.0.0",
"license": "ISC",
"dependencies": {
+ "@prisma/client": "^5.20.0",
"kafkajs": "^2.2.4"
+ },
+ "devDependencies": {
+ "prisma": "^5.20.0"
+ }
+ },
+ "node_modules/@prisma/client": {
+ "version": "5.20.0",
+ "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.20.0.tgz",
+ "integrity": "sha512-CLv55ZuMuUawMsxoqxGtLT3bEZoa2W8L3Qnp6rDIFWy+ZBrUcOFKdoeGPSnbBqxc3SkdxJrF+D1veN/WNynZYA==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=16.13"
+ },
+ "peerDependencies": {
+ "prisma": "*"
+ },
+ "peerDependenciesMeta": {
+ "prisma": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@prisma/debug": {
+ "version": "5.20.0",
+ "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.20.0.tgz",
+ "integrity": "sha512-oCx79MJ4HSujokA8S1g0xgZUGybD4SyIOydoHMngFYiwEwYDQ5tBQkK5XoEHuwOYDKUOKRn/J0MEymckc4IgsQ==",
+ "devOptional": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/@prisma/engines": {
+ "version": "5.20.0",
+ "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.20.0.tgz",
+ "integrity": "sha512-DtqkP+hcZvPEbj8t8dK5df2b7d3B8GNauKqaddRRqQBBlgkbdhJkxhoJTrOowlS3vaRt2iMCkU0+CSNn0KhqAQ==",
+ "devOptional": true,
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@prisma/debug": "5.20.0",
+ "@prisma/engines-version": "5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284",
+ "@prisma/fetch-engine": "5.20.0",
+ "@prisma/get-platform": "5.20.0"
+ }
+ },
+ "node_modules/@prisma/engines-version": {
+ "version": "5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284",
+ "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284.tgz",
+ "integrity": "sha512-Lg8AS5lpi0auZe2Mn4gjuCg081UZf88k3cn0RCwHgR+6cyHHpttPZBElJTHf83ZGsRNAmVCZCfUGA57WB4u4JA==",
+ "devOptional": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/@prisma/fetch-engine": {
+ "version": "5.20.0",
+ "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.20.0.tgz",
+ "integrity": "sha512-JVcaPXC940wOGpCOwuqQRTz6I9SaBK0c1BAyC1pcz9xBi+dzFgUu3G/p9GV1FhFs9OKpfSpIhQfUJE9y00zhqw==",
+ "devOptional": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@prisma/debug": "5.20.0",
+ "@prisma/engines-version": "5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284",
+ "@prisma/get-platform": "5.20.0"
+ }
+ },
+ "node_modules/@prisma/get-platform": {
+ "version": "5.20.0",
+ "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.20.0.tgz",
+ "integrity": "sha512-8/+CehTZZNzJlvuryRgc77hZCWrUDYd/PmlZ7p2yNXtmf2Una4BWnTbak3us6WVdqoz5wmptk6IhsXdG2v5fmA==",
+ "devOptional": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@prisma/debug": "5.20.0"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/kafkajs": {
@@ -19,6 +106,26 @@
"engines": {
"node": ">=14.0.0"
}
+ },
+ "node_modules/prisma": {
+ "version": "5.20.0",
+ "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.20.0.tgz",
+ "integrity": "sha512-6obb3ucKgAnsGS9x9gLOe8qa51XxvJ3vLQtmyf52CTey1Qcez3A6W6ROH5HIz5Q5bW+0VpmZb8WBohieMFGpig==",
+ "devOptional": true,
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@prisma/engines": "5.20.0"
+ },
+ "bin": {
+ "prisma": "build/index.js"
+ },
+ "engines": {
+ "node": ">=16.13"
+ },
+ "optionalDependencies": {
+ "fsevents": "2.3.3"
+ }
}
}
}
diff --git a/worker/package.json b/worker/package.json
index 6698f0a..03489d8 100644
--- a/worker/package.json
+++ b/worker/package.json
@@ -3,13 +3,17 @@
"version": "1.0.0",
"main": "index.js",
"scripts": {
- "start": "tsc -b && node dist/index.js"
+ "dev": "tsc -b && node dist/index.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
+ "@prisma/client": "^5.20.0",
"kafkajs": "^2.2.4"
+ },
+ "devDependencies": {
+ "prisma": "^5.20.0"
}
}
diff --git a/worker/prisma/schema.prisma b/worker/prisma/schema.prisma
new file mode 100644
index 0000000..5b129ea
--- /dev/null
+++ b/worker/prisma/schema.prisma
@@ -0,0 +1,79 @@
+// This is your Prisma schema file,
+// learn more about it in the docs: https://pris.ly/d/prisma-schema
+
+// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
+// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
+
+generator client {
+ provider = "prisma-client-js"
+}
+
+datasource db {
+ provider = "postgresql"
+ url = env("DATABASE_URL")
+}
+
+model User {
+ id Int @id @default(autoincrement())
+ name String
+ email String @unique
+ password String
+ zaps Zap[]
+}
+
+model Zap {
+ id String @id @default(uuid())
+ triggerId String?
+ userId Int
+ trigger Trigger?
+ actions Action[]
+ zapRuns ZapRun[]
+ user User @relation(fields: [userId], references: [id])
+}
+
+model Trigger {
+ id String @id @default(uuid())
+ zapId String @unique
+ zap Zap @relation(fields: [zapId], references: [id])
+ availableTriggerId String
+ metadata Json @default("{}")
+ type AvailableTrigger @relation(fields: [availableTriggerId], references: [id])
+}
+
+model Action {
+ id String @id @default(uuid())
+ zapId String
+ zap Zap @relation(fields: [zapId], references: [id])
+ actionId String
+ metadata Json @default("{}")
+ type AvailableAction @relation(fields: [actionId], references: [id])
+ sortingOrder Int @default(0)
+}
+
+model AvailableAction {
+ id String @id @default(uuid())
+ name String
+ image String
+ actions Action[]
+}
+
+model AvailableTrigger {
+ id String @id @default(uuid())
+ name String
+ image String
+ triggers Trigger[]
+}
+
+model ZapRun {
+ id String @id @default(uuid())
+ zapId String
+ metadata Json
+ zap Zap @relation(fields: [zapId], references: [id])
+ zapRunOutBox ZapRunOutbox?
+}
+
+model ZapRunOutbox {
+ id String @id @default(uuid())
+ zapRunId String @unique
+ zapRun ZapRun @relation(fields: [zapRunId], references: [id])
+}
diff --git a/worker/src/index.ts b/worker/src/index.ts
index fbf3667..dd53f76 100644
--- a/worker/src/index.ts
+++ b/worker/src/index.ts
@@ -1,4 +1,8 @@
import { Kafka } from "kafkajs";
+import { PrismaClient } from "@prisma/client";
+import { JsonObject } from "@prisma/client/runtime/library";
+
+const prismaClient=new PrismaClient();
const TOPIC_NAME = "zap-events";
@@ -11,7 +15,13 @@ async function main() {
const consumer = kafka.consumer({
groupId: "main-worker",
});
+
await consumer.connect();
+
+ const producer = kafka.producer();
+
+ await producer.connect();
+
await consumer.subscribe({ topic: TOPIC_NAME, fromBeginning: true });
await consumer.run({
autoCommit: false,
@@ -25,8 +35,62 @@ async function main() {
return;
}
const parsedValue=JSON.parse(message.value?.toString());
- //
+ const zapRunId= parsedValue.zapRunId;
+ const stage=parsedValue.stage;
+ const zapRunDetails=await prismaClient.zapRun.findFirst({
+ where:{
+ id:zapRunId
+ },
+ include:{
+ zap:{
+ include:{
+ actions:{
+ include:{
+ type:true
+ }
+ }
+ }
+ }
+ }
+ })
+ const currentAction=zapRunDetails?.zap.actions.find(x=>x.sortingOrder === stage)
+
+ if(!currentAction){
+ console.log('Current action not found')
+ return;
+ }
+
+ if(currentAction.type.id==='email'){
+ console.log('Sending out an email')
+ const body=(currentAction.metadata as JsonObject)?.body;
+ const to=(currentAction.metadata as JsonObject)?.email;
+ const zapRunMetadata=zapRunDetails?.metadata;
+
+ }
+
+ if(currentAction.type.id==='send-sol'){
+ console.log('Sending out solana')
+ //parse out the address and the amount to send
+ }
+
await new Promise((r) => setTimeout(r, 500));
+
+ const zapId= message?.value?.toString();
+
+ const lastStage= (zapRunDetails?.zap.actions?.length || 1) - 1;
+
+ if(lastStage!==stage){
+ await producer.send({
+ topic: TOPIC_NAME,
+ messages:[{
+ value: JSON.stringify({
+ stage : stage + 1,
+ zapRunId
+ })
+ }]
+ })
+ }
+
console.log('processing done')
//you can do your action operation here!
diff --git a/worker/src/parser.ts b/worker/src/parser.ts
new file mode 100644
index 0000000..b6e2d17
--- /dev/null
+++ b/worker/src/parser.ts
@@ -0,0 +1,30 @@
+export function parse(text:string, values:any , startDelimeter:"{", endDelimeter:"}"){
+ //you received {comment.amount} money from {comment.link}
+ let startIndex=0;
+ let endIndex=1;
+
+ while(endIndex!=text.length){
+ if(text[startIndex]===startDelimeter){
+ let endPoint=startIndex+2;
+ while(text[endPoint] !=endDelimeter){
+ endPoint++;
+ }
+ let stringHoldingValue = text.slice(startIndex+1, endPoint-1);
+ const keys= stringHoldingValue.split(".")
+ let localValues={
+ ...values
+ }
+ for(let i=0;i