diff --git a/backend/.gitignore b/backend/.gitignore
index 13dfa36..fb4895f 100644
--- a/backend/.gitignore
+++ b/backend/.gitignore
@@ -1,2 +1,3 @@
.env
-node_modules/
\ No newline at end of file
+node_modules/
+/generated/prisma
diff --git a/backend/package-lock.json b/backend/package-lock.json
index e727a5c..d8d0326 100644
--- a/backend/package-lock.json
+++ b/backend/package-lock.json
@@ -5,14 +5,110 @@
"packages": {
"": {
"dependencies": {
+ "@prisma/client": "^6.16.0",
"cors": "^2.8.5",
"dotenv": "^17.2.2",
"express": "^5.1.0",
"pinata": "^2.5.0",
"twilio": "^5.9.0",
"unirest": "^0.6.0"
+ },
+ "devDependencies": {
+ "prisma": "^6.16.0"
+ }
+ },
+ "node_modules/@prisma/client": {
+ "version": "6.16.0",
+ "resolved": "https://registry.npmjs.org/@prisma/client/-/client-6.16.0.tgz",
+ "integrity": "sha512-FYkFJtgwpwJRMxtmrB26y7gtpR372kyChw6lWng5TMmvn5V+uisy0OyllO5EJD1s8lX78V8X3XjhiXOoMLnu3w==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18"
+ },
+ "peerDependencies": {
+ "prisma": "*",
+ "typescript": ">=5.1.0"
+ },
+ "peerDependenciesMeta": {
+ "prisma": {
+ "optional": true
+ },
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@prisma/config": {
+ "version": "6.16.0",
+ "resolved": "https://registry.npmjs.org/@prisma/config/-/config-6.16.0.tgz",
+ "integrity": "sha512-Q9TgfnllVehvQziY9lJwRJLGmziX0OimZUEQ/MhCUBoJMSScj2VivCjw/Of2vlO1FfyaHXxrvjZAr7ASl7DVcw==",
+ "devOptional": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "c12": "3.1.0",
+ "deepmerge-ts": "7.1.5",
+ "effect": "3.16.12",
+ "empathic": "2.0.0"
+ }
+ },
+ "node_modules/@prisma/debug": {
+ "version": "6.16.0",
+ "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.16.0.tgz",
+ "integrity": "sha512-bxzro5vbVqAPkWyDs2A6GpQtRZunD8tyrLmSAchx9u0b+gWCDY6eV+oh5A0YtYT9245dIxQBswckayHuJG4u3w==",
+ "devOptional": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/@prisma/engines": {
+ "version": "6.16.0",
+ "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.16.0.tgz",
+ "integrity": "sha512-RHJGCH/zi017W4CWYWqg0Sv1pquGGFVo8T3auJ9sodDNaiRzbeNldydjaQzszVS8nscdtcvLuJzy7e65C3puqQ==",
+ "devOptional": true,
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@prisma/debug": "6.16.0",
+ "@prisma/engines-version": "6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43",
+ "@prisma/fetch-engine": "6.16.0",
+ "@prisma/get-platform": "6.16.0"
+ }
+ },
+ "node_modules/@prisma/engines-version": {
+ "version": "6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43",
+ "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43.tgz",
+ "integrity": "sha512-ThvlDaKIVrnrv97ujNFDYiQbeMQpLa0O86HFA2mNoip4mtFqM7U5GSz2ie1i2xByZtvPztJlNRgPsXGeM/kqAA==",
+ "devOptional": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/@prisma/fetch-engine": {
+ "version": "6.16.0",
+ "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.16.0.tgz",
+ "integrity": "sha512-Mx5rml0XRIDizhB9eZxSP8c0nMoXYVITTiJJwxlWn9rNCel8mG8NAqIw+vJlN3gPR+kt3IBkP1SQVsplPPpYrA==",
+ "devOptional": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@prisma/debug": "6.16.0",
+ "@prisma/engines-version": "6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43",
+ "@prisma/get-platform": "6.16.0"
+ }
+ },
+ "node_modules/@prisma/get-platform": {
+ "version": "6.16.0",
+ "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.16.0.tgz",
+ "integrity": "sha512-eaJOOvAoGslSUTjiQrtE9E0hoBdfL43j8SymOGD6LbdrKRNtIoiy6qiBaEr2fNYD+R/Qns7QOwPhl7SVHJayKA==",
+ "devOptional": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@prisma/debug": "6.16.0"
}
},
+ "node_modules/@standard-schema/spec": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz",
+ "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==",
+ "devOptional": true,
+ "license": "MIT"
+ },
"node_modules/accepts": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
@@ -175,6 +271,48 @@
"node": ">= 0.8"
}
},
+ "node_modules/c12": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/c12/-/c12-3.1.0.tgz",
+ "integrity": "sha512-uWoS8OU1MEIsOv8p/5a82c3H31LsWVR5qiyXVfBNOzfffjUWtPnhAb4BYI2uG2HfGmZmFjCtui5XNWaps+iFuw==",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "chokidar": "^4.0.3",
+ "confbox": "^0.2.2",
+ "defu": "^6.1.4",
+ "dotenv": "^16.6.1",
+ "exsolve": "^1.0.7",
+ "giget": "^2.0.0",
+ "jiti": "^2.4.2",
+ "ohash": "^2.0.11",
+ "pathe": "^2.0.3",
+ "perfect-debounce": "^1.0.0",
+ "pkg-types": "^2.2.0",
+ "rc9": "^2.1.2"
+ },
+ "peerDependencies": {
+ "magicast": "^0.3.5"
+ },
+ "peerDependenciesMeta": {
+ "magicast": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/c12/node_modules/dotenv": {
+ "version": "16.6.1",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz",
+ "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==",
+ "devOptional": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
+ }
+ },
"node_modules/call-bind-apply-helpers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
@@ -210,6 +348,32 @@
"integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==",
"license": "Apache-2.0"
},
+ "node_modules/chokidar": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
+ "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "readdirp": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 14.16.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/citty": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/citty/-/citty-0.1.6.tgz",
+ "integrity": "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "consola": "^3.2.3"
+ }
+ },
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -222,6 +386,23 @@
"node": ">= 0.8"
}
},
+ "node_modules/confbox": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz",
+ "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==",
+ "devOptional": true,
+ "license": "MIT"
+ },
+ "node_modules/consola": {
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz",
+ "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==",
+ "devOptional": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^14.18.0 || >=16.10.0"
+ }
+ },
"node_modules/content-disposition": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz",
@@ -315,6 +496,23 @@
}
}
},
+ "node_modules/deepmerge-ts": {
+ "version": "7.1.5",
+ "resolved": "https://registry.npmjs.org/deepmerge-ts/-/deepmerge-ts-7.1.5.tgz",
+ "integrity": "sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw==",
+ "devOptional": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/defu": {
+ "version": "6.1.4",
+ "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz",
+ "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==",
+ "devOptional": true,
+ "license": "MIT"
+ },
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
@@ -333,6 +531,13 @@
"node": ">= 0.8"
}
},
+ "node_modules/destr": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.5.tgz",
+ "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==",
+ "devOptional": true,
+ "license": "MIT"
+ },
"node_modules/dotenv": {
"version": "17.2.2",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.2.tgz",
@@ -384,6 +589,27 @@
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
"license": "MIT"
},
+ "node_modules/effect": {
+ "version": "3.16.12",
+ "resolved": "https://registry.npmjs.org/effect/-/effect-3.16.12.tgz",
+ "integrity": "sha512-N39iBk0K71F9nb442TLbTkjl24FLUzuvx2i1I2RsEAQsdAdUTuUoW0vlfUXgkMTUOnYqKnWcFfqw4hK4Pw27hg==",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "@standard-schema/spec": "^1.0.0",
+ "fast-check": "^3.23.1"
+ }
+ },
+ "node_modules/empathic": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/empathic/-/empathic-2.0.0.tgz",
+ "integrity": "sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==",
+ "devOptional": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ }
+ },
"node_modules/encodeurl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
@@ -516,6 +742,13 @@
"node": ">= 0.6"
}
},
+ "node_modules/exsolve": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.7.tgz",
+ "integrity": "sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==",
+ "devOptional": true,
+ "license": "MIT"
+ },
"node_modules/extend": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
@@ -531,6 +764,29 @@
],
"license": "MIT"
},
+ "node_modules/fast-check": {
+ "version": "3.23.2",
+ "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.23.2.tgz",
+ "integrity": "sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==",
+ "devOptional": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/dubzzz"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fast-check"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "pure-rand": "^6.1.0"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -678,6 +934,24 @@
"assert-plus": "^1.0.0"
}
},
+ "node_modules/giget": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/giget/-/giget-2.0.0.tgz",
+ "integrity": "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "citty": "^0.1.6",
+ "consola": "^3.4.0",
+ "defu": "^6.1.4",
+ "node-fetch-native": "^1.6.6",
+ "nypm": "^0.6.0",
+ "pathe": "^2.0.3"
+ },
+ "bin": {
+ "giget": "dist/cli.mjs"
+ }
+ },
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
@@ -850,6 +1124,16 @@
"integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==",
"license": "MIT"
},
+ "node_modules/jiti": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.5.1.tgz",
+ "integrity": "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==",
+ "devOptional": true,
+ "license": "MIT",
+ "bin": {
+ "jiti": "lib/jiti-cli.mjs"
+ }
+ },
"node_modules/jsbn": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
@@ -1052,6 +1336,33 @@
"node": ">= 0.6"
}
},
+ "node_modules/node-fetch-native": {
+ "version": "1.6.7",
+ "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.7.tgz",
+ "integrity": "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==",
+ "devOptional": true,
+ "license": "MIT"
+ },
+ "node_modules/nypm": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.6.1.tgz",
+ "integrity": "sha512-hlacBiRiv1k9hZFiphPUkfSQ/ZfQzZDzC+8z0wL3lvDAOUu/2NnChkKuMoMjNur/9OpKuz2QsIeiPVN0xM5Q0w==",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "citty": "^0.1.6",
+ "consola": "^3.4.2",
+ "pathe": "^2.0.3",
+ "pkg-types": "^2.2.0",
+ "tinyexec": "^1.0.1"
+ },
+ "bin": {
+ "nypm": "dist/cli.mjs"
+ },
+ "engines": {
+ "node": "^14.16.0 || >=16.10.0"
+ }
+ },
"node_modules/oauth-sign": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
@@ -1082,6 +1393,13 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/ohash": {
+ "version": "2.0.11",
+ "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz",
+ "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==",
+ "devOptional": true,
+ "license": "MIT"
+ },
"node_modules/on-finished": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
@@ -1122,6 +1440,20 @@
"url": "https://opencollective.com/express"
}
},
+ "node_modules/pathe": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
+ "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
+ "devOptional": true,
+ "license": "MIT"
+ },
+ "node_modules/perfect-debounce": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz",
+ "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==",
+ "devOptional": true,
+ "license": "MIT"
+ },
"node_modules/performance-now": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
@@ -1149,6 +1481,44 @@
}
}
},
+ "node_modules/pkg-types": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.0.tgz",
+ "integrity": "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "confbox": "^0.2.2",
+ "exsolve": "^1.0.7",
+ "pathe": "^2.0.3"
+ }
+ },
+ "node_modules/prisma": {
+ "version": "6.16.0",
+ "resolved": "https://registry.npmjs.org/prisma/-/prisma-6.16.0.tgz",
+ "integrity": "sha512-TTh+H1Kw8N68KN9cDzdAyMroqMOvdCO/Z+kS2wKEVYR1nuR21qH5Q/Db/bZHsAgw7l/TPHtM/veG5VABcdwPDw==",
+ "devOptional": true,
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@prisma/config": "6.16.0",
+ "@prisma/engines": "6.16.0"
+ },
+ "bin": {
+ "prisma": "build/index.js"
+ },
+ "engines": {
+ "node": ">=18.18"
+ },
+ "peerDependencies": {
+ "typescript": ">=5.1.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
"node_modules/proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@@ -1189,6 +1559,23 @@
"node": ">=6"
}
},
+ "node_modules/pure-rand": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz",
+ "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==",
+ "devOptional": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/dubzzz"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fast-check"
+ }
+ ],
+ "license": "MIT"
+ },
"node_modules/qs": {
"version": "6.14.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
@@ -1244,6 +1631,31 @@
"url": "https://opencollective.com/express"
}
},
+ "node_modules/rc9": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/rc9/-/rc9-2.1.2.tgz",
+ "integrity": "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "defu": "^6.1.4",
+ "destr": "^2.0.3"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
+ "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
+ "devOptional": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14.18.0"
+ },
+ "funding": {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
"node_modules/request": {
"version": "2.88.2",
"resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
@@ -1529,6 +1941,13 @@
"node": ">= 0.8"
}
},
+ "node_modules/tinyexec": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.1.tgz",
+ "integrity": "sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==",
+ "devOptional": true,
+ "license": "MIT"
+ },
"node_modules/toidentifier": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
diff --git a/backend/package.json b/backend/package.json
index 936ad66..729b34f 100644
--- a/backend/package.json
+++ b/backend/package.json
@@ -1,10 +1,14 @@
{
"dependencies": {
+ "@prisma/client": "^6.16.0",
"cors": "^2.8.5",
"dotenv": "^17.2.2",
"express": "^5.1.0",
"pinata": "^2.5.0",
"twilio": "^5.9.0",
"unirest": "^0.6.0"
+ },
+ "devDependencies": {
+ "prisma": "^6.16.0"
}
}
diff --git a/backend/prisma/schema.prisma b/backend/prisma/schema.prisma
new file mode 100644
index 0000000..ee4810b
--- /dev/null
+++ b/backend/prisma/schema.prisma
@@ -0,0 +1,37 @@
+// 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"
+ output = "../generated/prisma"
+}
+
+datasource db {
+ provider = "postgresql"
+ url = env("DATABASE_URL")
+}
+
+model Farmer{
+ id Int @id @default(autoincrement())
+ phone_number Int @unique
+ transactions Transaction[]
+}
+
+model Farm{
+ f_id Int @id @default(autoincrement())
+ f_name String
+ f_size Float
+ f_location String
+ crop_type String
+}
+
+model Transaction {
+ id Int @id @default(autoincrement())
+ hash String @unique
+ farmer Farmer @relation(fields: [farmerId], references: [id])
+ farmerId Int // foreign key to Farmer
+}
+
diff --git a/backend/server.js b/backend/server.js
index dde041e..6e7b8e2 100644
--- a/backend/server.js
+++ b/backend/server.js
@@ -4,16 +4,20 @@ import cors from "cors";
import bodyParser from "body-parser";
import twilio from "twilio";
import { PinataSDK } from "pinata";
+import { PrismaClient } from "@prisma/client";
+import dotenv from dotenv;
+dotenv.config()
+accountSid=process.env.ACCOUNT_SID;
+authToken=process.env.AUTH_TOKEN;
+verifySid=process.env.VERIFY_SID;
+const prisma = new PrismaClient();
const app = express();
app.use(cors());
app.use(bodyParser.json());
-// Twilio credentials
-const accountSid = "ACbe77ad3c5aad3f1ddd78f98031f63fe7";
-const authToken = "86ac375878f88be6bcfc7100787038e8";
-const verifySid = "VAf37f20c6f2744ba98556b1338fa21f57"; // Your Verify Service SID
+
const client = twilio(accountSid, authToken);
@@ -72,4 +76,64 @@ app.get("/presigned_url", async (req, res) => {
}
});
+app.post("/farmdetails", async (req, res) => {
+ try {
+ const { f_name, f_size, f_location, crop_type } = req.body;
+
+ // basic validation
+ if (!f_name || !f_size || !f_location || !crop_type) {
+ return res.status(400).json({ error: "All fields are required" });
+ }
+
+ const farm = await prisma.farm.create({
+ data: {
+ f_name,
+ f_size: parseFloat(f_size), // ensure number
+ f_location,
+ crop_type,
+ },
+ });
+
+ res.status(201).json({
+ message: "Farm details saved successfully",
+ farm,
+ });
+ } catch (error) {
+ console.error("Error saving farm details:", error);
+ res.status(500).json({ error: "Internal Server Error" });
+ }
+});
+
+app.post("/number", async (req, res) => {
+ try {
+ const { phone_number } = req.body;
+
+ // basic validation
+ if (!phone_number) {
+ return res.status(400).json({ error: "Phone number is required" });
+ }
+
+ // store farmer in db
+ const farmer = await prisma.farmer.create({
+ data: {
+ phone_number: parseInt(phone_number), // ensure number type
+ },
+ });
+
+ res.status(201).json({
+ message: "Farmer phone number stored successfully",
+ farmer,
+ });
+ } catch (error) {
+ console.error("Error saving farmer:", error);
+
+ if (error.code === "P2002") {
+ // Prisma unique constraint error
+ return res.status(409).json({ error: "Phone number already exists" });
+ }
+
+ res.status(500).json({ error: "Internal Server Error" });
+ }
+});
+
app.listen(5000, () => console.log("🚀 Server running on http://localhost:5000"));
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 4c609ff..8d5e57a 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -1696,17 +1696,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/@types/node": {
- "version": "24.3.1",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-24.3.1.tgz",
- "integrity": "sha512-3vXmQDXy+woz+gnrTvuvNrPzekOi+Ds0ReMxw0LzBiK3a+1k0kQn9f2NWk+lgD4rJehFUmYy2gMhJ2ZI+7YP9g==",
- "license": "MIT",
- "optional": true,
- "peer": true,
- "dependencies": {
- "undici-types": "~7.10.0"
- }
- },
"node_modules/@types/react": {
"version": "19.1.12",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.12.tgz",
@@ -5285,14 +5274,6 @@
"node": ">= 0.4"
}
},
- "node_modules/undici-types": {
- "version": "7.10.0",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz",
- "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==",
- "license": "MIT",
- "optional": true,
- "peer": true
- },
"node_modules/update-browserslist-db": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx
index 61fd0d1..8c828dc 100644
--- a/frontend/src/App.jsx
+++ b/frontend/src/App.jsx
@@ -33,7 +33,7 @@ function App() {