mirror of
https://github.com/R0m1k3/LogiFlow.git
synced 2026-10-11 17:27:31 +02:00
Merge pull request #332 from R0m1k3/1.1
Update file upload handling to use Busboy for improved efficiency
This commit is contained in:
5 files changed
+284
-121
No files matched your search
@@ -37,4 +37,4 @@ args = "npm run dev"
|
||||
waitForPort = 5000
|
||||
|
||||
[agent]
|
||||
integrations = ["javascript_log_in_with_replit==1.0.0", "javascript_object_storage==1.0.0", "javascript_database==1.0.0"]
|
||||
integrations = ["javascript_object_storage==1.0.0", "javascript_database==1.0.0", "javascript_log_in_with_replit==1.0.0"]
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
Actions
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
✅ Using DatabaseStorage (production PostgreSQL)
|
||||
|
||||
⏰ Automatic backup scheduled for daily 2:00 AM+ (native timer)
|
||||
|
||||
file:///app/dist/index.js:11
|
||||
|
||||
throw Error('Dynamic require of "' + x2 + '" is not supported');
|
||||
|
||||
|
||||
|
||||
^
|
||||
|
||||
Error: Dynamic require of "path" is not supported
|
||||
|
||||
at file:///app/dist/index.js:11:9
|
||||
|
||||
at node_modules/mime-types/index.js (file:///app/dist/index.js:13971:19)
|
||||
|
||||
at __require2 (file:///app/dist/index.js:17:50)
|
||||
|
||||
at node_modules/type-is/index.js (file:///app/dist/index.js:14061:16)
|
||||
|
||||
at __require2 (file:///app/dist/index.js:17:50)
|
||||
|
||||
at node_modules/multer/lib/make-middleware.js (file:///app/dist/index.js:18269:15)
|
||||
|
||||
at __require2 (file:///app/dist/index.js:17:50)
|
||||
|
||||
at node_modules/multer/index.js (file:///app/dist/index.js:22048:26)
|
||||
|
||||
at __require2 (file:///app/dist/index.js:17:50)
|
||||
|
||||
at file:///app/dist/index.js:29500:29
|
||||
|
||||
Node.js v20.19.4
|
||||
|
||||
Applying DLC migration...
|
||||
|
||||
NOTICE: column "stock_epuise" of relation "dlc_products" already exists, skipping
|
||||
|
||||
NOTICE: column "stock_epuise_by" of relation "dlc_products" already exists, skipping
|
||||
|
||||
NOTICE: column "stock_epuise_at" of relation "dlc_products" already exists, skipping
|
||||
|
||||
NOTICE: relation "idx_dlc_products_stock_epuise" already exists, skipping
|
||||
|
||||
ALTER TABLE
|
||||
|
||||
␍CREATE INDEX
|
||||
|
||||
🔗 Database initialization: {
|
||||
|
||||
NODE_ENV: 'production',
|
||||
|
||||
isProduction: true,
|
||||
|
||||
hasDbUrl: true,
|
||||
|
||||
dbHost: 'logiflow-db'
|
||||
|
||||
}
|
||||
|
||||
🐳 PRODUCTION: Using standard PostgreSQL
|
||||
|
||||
✅ PostgreSQL connection test successful
|
||||
|
||||
🔗 Database initialization: {
|
||||
|
||||
NODE_ENV: 'production',
|
||||
|
||||
isProduction: true,
|
||||
|
||||
hasDbUrl: true,
|
||||
|
||||
dbHost: 'logiflow-db:5432'
|
||||
|
||||
}
|
||||
|
||||
✅ Using DatabaseStorage (production PostgreSQL)
|
||||
|
||||
⏰ Automatic backup scheduled for daily 2:00 AM+ (native timer)
|
||||
|
||||
file:///app/dist/index.js:11
|
||||
|
||||
throw Error('Dynamic require of "' + x2 + '" is not supported');
|
||||
|
||||
|
||||
|
||||
^
|
||||
|
||||
Error: Dynamic require of "path" is not supported
|
||||
|
||||
at file:///app/dist/index.js:11:9
|
||||
|
||||
at node_modules/mime-types/index.js (file:///app/dist/index.js:13971:19)
|
||||
|
||||
at __require2 (file:///app/dist/index.js:17:50)
|
||||
|
||||
at node_modules/type-is/index.js (file:///app/dist/index.js:14061:16)
|
||||
|
||||
at __require2 (file:///app/dist/index.js:17:50)
|
||||
|
||||
at node_modules/multer/lib/make-middleware.js (file:///app/dist/index.js:18269:15)
|
||||
|
||||
at __require2 (file:///app/dist/index.js:17:50)
|
||||
|
||||
at node_modules/multer/index.js (file:///app/dist/index.js:22048:26)
|
||||
|
||||
at __require2 (file:///app/dist/index.js:17:50)
|
||||
|
||||
at file:///app/dist/index.js:29500:29
|
||||
|
||||
Node.js v20.19.4
|
||||
|
||||
Applying DLC migration...
|
||||
|
||||
NOTICE: column "stock_epuise" of relation "dlc_products" already exists, skipping
|
||||
|
||||
NOTICE: column "stock_epuise_by" of relation "dlc_products" already exists, skipping
|
||||
|
||||
NOTICE: column "stock_epuise_at" of relation "dlc_products" already exists, skipping
|
||||
|
||||
NOTICE: relation "idx_dlc_products_stock_epuise" already exists, skipping
|
||||
|
||||
ALTER TABLE
|
||||
|
||||
␍CREATE INDEX
|
||||
|
||||
🔗 Database initialization: {
|
||||
|
||||
NODE_ENV: 'production',
|
||||
|
||||
isProduction: true,
|
||||
|
||||
hasDbUrl: true,
|
||||
|
||||
dbHost: 'logiflow-db'
|
||||
|
||||
}
|
||||
|
||||
🐳 PRODUCTION: Using standard PostgreSQL
|
||||
|
||||
✅ PostgreSQL connection test successful
|
||||
|
||||
🔗 Database initialization: {
|
||||
|
||||
NODE_ENV: 'production',
|
||||
|
||||
isProduction: true,
|
||||
|
||||
hasDbUrl: true,
|
||||
|
||||
dbHost: 'logiflow-db:5432'
|
||||
|
||||
}
|
||||
|
||||
✅ Using DatabaseStorage (production PostgreSQL)
|
||||
|
||||
⏰ Automatic backup scheduled for daily 2:00 AM+ (native timer)
|
||||
|
||||
file:///app/dist/index.js:11
|
||||
|
||||
throw Error('Dynamic require of "' + x2 + '" is not supported');
|
||||
|
||||
|
||||
|
||||
^
|
||||
|
||||
Error: Dynamic require of "path" is not supported
|
||||
|
||||
at file:///app/dist/index.js:11:9
|
||||
|
||||
at node_modules/mime-types/index.js (file:///app/dist/index.js:13971:19)
|
||||
|
||||
at __require2 (file:///app/dist/index.js:17:50)
|
||||
|
||||
at node_modules/type-is/index.js (file:///app/dist/index.js:14061:16)
|
||||
|
||||
at __require2 (file:///app/dist/index.js:17:50)
|
||||
|
||||
at node_modules/multer/lib/make-middleware.js (file:///app/dist/index.js:18269:15)
|
||||
|
||||
at __require2 (file:///app/dist/index.js:17:50)
|
||||
|
||||
at node_modules/multer/index.js (file:///app/dist/index.js:22048:26)
|
||||
|
||||
at __require2 (file:///app/dist/index.js:17:50)
|
||||
|
||||
at file:///app/dist/index.js:29500:29
|
||||
|
||||
Node.js v20.19.4
|
||||
|
||||
Generated
+22
-100
@@ -41,12 +41,13 @@
|
||||
"@radix-ui/react-tooltip": "^1.2.0",
|
||||
"@tanstack/react-query": "^5.60.5",
|
||||
"@types/bcrypt": "^6.0.0",
|
||||
"@types/busboy": "^1.5.4",
|
||||
"@types/form-data": "^2.2.1",
|
||||
"@types/memoizee": "^0.4.12",
|
||||
"@types/multer": "^2.0.0",
|
||||
"@types/node-fetch": "^2.6.13",
|
||||
"@types/pg": "^8.15.4",
|
||||
"bcrypt": "^6.0.0",
|
||||
"busboy": "^1.6.0",
|
||||
"caniuse-lite": "^1.0.30001727",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
@@ -68,7 +69,6 @@
|
||||
"lucide-react": "^0.453.0",
|
||||
"memoizee": "^0.4.17",
|
||||
"memorystore": "^1.6.7",
|
||||
"multer": "^2.0.2",
|
||||
"nanoid": "^5.1.5",
|
||||
"next-themes": "^0.4.6",
|
||||
"node-cron": "^4.2.1",
|
||||
@@ -3618,16 +3618,27 @@
|
||||
"version": "1.19.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz",
|
||||
"integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/connect": "*",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/busboy": {
|
||||
"version": "1.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/busboy/-/busboy-1.5.4.tgz",
|
||||
"integrity": "sha512-kG7WrUuAKK0NoyxfQHsVE6j1m01s6kMma64E+OZenQABMQyTJop1DumUWcLwAQ2JzpefU7PDYoRDKl8uZosFjw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/connect": {
|
||||
"version": "3.4.38",
|
||||
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
|
||||
"integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
@@ -3719,6 +3730,7 @@
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz",
|
||||
"integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/body-parser": "*",
|
||||
@@ -3731,6 +3743,7 @@
|
||||
"version": "4.19.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz",
|
||||
"integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*",
|
||||
@@ -3762,6 +3775,7 @@
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz",
|
||||
"integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/memoizee": {
|
||||
@@ -3774,17 +3788,9 @@
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
|
||||
"integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/multer": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/multer/-/multer-2.0.0.tgz",
|
||||
"integrity": "sha512-C3Z9v9Evij2yST3RSBktxP9STm6OdMc5uR1xF1SGr98uv8dUlAL2hqwrZ3GVB3uyMyiegnscEK6PGtYvNrjTjw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/express": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.16.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.11.tgz",
|
||||
@@ -3859,12 +3865,14 @@
|
||||
"version": "6.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz",
|
||||
"integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/range-parser": {
|
||||
"version": "1.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
|
||||
"integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/react": {
|
||||
@@ -3892,6 +3900,7 @@
|
||||
"version": "0.17.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz",
|
||||
"integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/mime": "^1",
|
||||
@@ -3902,6 +3911,7 @@
|
||||
"version": "1.15.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz",
|
||||
"integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/http-errors": "*",
|
||||
@@ -3996,12 +4006,6 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/append-field": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz",
|
||||
"integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/arg": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
|
||||
@@ -4211,6 +4215,7 @@
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/bufferutil": {
|
||||
@@ -4427,21 +4432,6 @@
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/concat-stream": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz",
|
||||
"integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==",
|
||||
"engines": [
|
||||
"node >= 6.0"
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"inherits": "^2.0.3",
|
||||
"readable-stream": "^3.0.2",
|
||||
"typedarray": "^0.0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/connect-pg-simple": {
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmjs.org/connect-pg-simple/-/connect-pg-simple-10.0.0.tgz",
|
||||
@@ -6957,15 +6947,6 @@
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/minimist": {
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
|
||||
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/minipass": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
|
||||
@@ -7038,36 +7019,6 @@
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/multer": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/multer/-/multer-2.0.2.tgz",
|
||||
"integrity": "sha512-u7f2xaZ/UG8oLXHvtF/oWTRvT44p9ecwBBqTwgJVq0+4BW1g8OW01TyMEGWBHbyMOYVHXslaut7qEQ1meATXgw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"append-field": "^1.0.0",
|
||||
"busboy": "^1.6.0",
|
||||
"concat-stream": "^2.0.0",
|
||||
"mkdirp": "^0.5.6",
|
||||
"object-assign": "^4.1.1",
|
||||
"type-is": "^1.6.18",
|
||||
"xtend": "^4.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.16.0"
|
||||
}
|
||||
},
|
||||
"node_modules/multer/node_modules/mkdirp": {
|
||||
"version": "0.5.6",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
|
||||
"integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"minimist": "^1.2.6"
|
||||
},
|
||||
"bin": {
|
||||
"mkdirp": "bin/cmd.js"
|
||||
}
|
||||
},
|
||||
"node_modules/mz": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
|
||||
@@ -8063,20 +8014,6 @@
|
||||
"pify": "^2.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/readable-stream": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/readdirp": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
||||
@@ -8521,15 +8458,6 @@
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/string_decoder": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"safe-buffer": "~5.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/string-width": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
|
||||
@@ -8897,12 +8825,6 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/typedarray": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
||||
"integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.6.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz",
|
||||
|
||||
+2
-2
@@ -43,12 +43,13 @@
|
||||
"@radix-ui/react-tooltip": "^1.2.0",
|
||||
"@tanstack/react-query": "^5.60.5",
|
||||
"@types/bcrypt": "^6.0.0",
|
||||
"@types/busboy": "^1.5.4",
|
||||
"@types/form-data": "^2.2.1",
|
||||
"@types/memoizee": "^0.4.12",
|
||||
"@types/multer": "^2.0.0",
|
||||
"@types/node-fetch": "^2.6.13",
|
||||
"@types/pg": "^8.15.4",
|
||||
"bcrypt": "^6.0.0",
|
||||
"busboy": "^1.6.0",
|
||||
"caniuse-lite": "^1.0.30001727",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
@@ -70,7 +71,6 @@
|
||||
"lucide-react": "^0.453.0",
|
||||
"memoizee": "^0.4.17",
|
||||
"memorystore": "^1.6.7",
|
||||
"multer": "^2.0.2",
|
||||
"nanoid": "^5.1.5",
|
||||
"next-themes": "^0.4.6",
|
||||
"node-cron": "^4.2.1",
|
||||
|
||||
+60
-18
@@ -49,11 +49,9 @@ import { eq, desc, or, isNull } from "drizzle-orm";
|
||||
import { invoiceVerificationService } from "./invoiceVerification";
|
||||
import { backupService } from "./backupService";
|
||||
import { weatherService } from "./weatherService.js";
|
||||
import multer from "multer";
|
||||
import Busboy from 'busboy';
|
||||
import fetch from "node-fetch";
|
||||
|
||||
const upload = multer({ storage: multer.memoryStorage() });
|
||||
|
||||
export async function registerRoutes(app: Express): Promise<Server> {
|
||||
// Detect environment
|
||||
const environment = process.env.NODE_ENV || 'development';
|
||||
@@ -72,16 +70,66 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
await setupAuth(app);
|
||||
|
||||
// Route BAP pour envoi webhook n8n
|
||||
app.post('/api/bap/send-webhook', isAuthenticated, upload.single('pdf'), async (req: any, res) => {
|
||||
app.post('/api/bap/send-webhook', isAuthenticated, async (req: any, res) => {
|
||||
try {
|
||||
const { recipient } = req.body;
|
||||
const file = req.file;
|
||||
// Vérifier que l'utilisateur est admin
|
||||
const user = await storage.getUser(req.user.claims ? req.user.claims.sub : req.user.id);
|
||||
if (!user || user.role !== 'admin') {
|
||||
return res.status(403).json({ error: 'Accès refusé - Admin uniquement' });
|
||||
}
|
||||
|
||||
if (!file) {
|
||||
// Parser le multipart/form-data avec busboy
|
||||
const busboy = Busboy({ headers: req.headers });
|
||||
let fileBuffer: Buffer | null = null;
|
||||
let fileName = '';
|
||||
let recipient = '';
|
||||
let mimeType = '';
|
||||
|
||||
const parsePromise = new Promise<void>((resolve, reject) => {
|
||||
busboy.on('file', (fieldname, file, info) => {
|
||||
const { filename, mimeType: fileMimeType } = info;
|
||||
|
||||
if (fieldname === 'pdf') {
|
||||
fileName = filename;
|
||||
mimeType = fileMimeType;
|
||||
|
||||
const chunks: Buffer[] = [];
|
||||
file.on('data', (chunk) => {
|
||||
chunks.push(chunk);
|
||||
});
|
||||
|
||||
file.on('end', () => {
|
||||
fileBuffer = Buffer.concat(chunks);
|
||||
});
|
||||
} else {
|
||||
file.resume(); // Ignorer les autres fichiers
|
||||
}
|
||||
});
|
||||
|
||||
busboy.on('field', (fieldname, val) => {
|
||||
if (fieldname === 'recipient') {
|
||||
recipient = val;
|
||||
}
|
||||
});
|
||||
|
||||
busboy.on('finish', () => {
|
||||
resolve();
|
||||
});
|
||||
|
||||
busboy.on('error', (err) => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
|
||||
req.pipe(busboy);
|
||||
await parsePromise;
|
||||
|
||||
// Valider les données
|
||||
if (!fileBuffer) {
|
||||
return res.status(400).json({ error: 'Aucun fichier PDF fourni' });
|
||||
}
|
||||
|
||||
if (file.mimetype !== 'application/pdf') {
|
||||
if (mimeType !== 'application/pdf') {
|
||||
return res.status(400).json({ error: 'Le fichier doit être un PDF' });
|
||||
}
|
||||
|
||||
@@ -89,24 +137,18 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
return res.status(400).json({ error: 'Destinataire invalide' });
|
||||
}
|
||||
|
||||
// Vérifier que l'utilisateur est admin
|
||||
const user = await storage.getUser(req.user.claims ? req.user.claims.sub : req.user.id);
|
||||
if (!user || user.role !== 'admin') {
|
||||
return res.status(403).json({ error: 'Accès refusé - Admin uniquement' });
|
||||
}
|
||||
|
||||
console.log('📤 BAP: Envoi webhook n8n', {
|
||||
recipient,
|
||||
fileName: file.originalname,
|
||||
fileSize: file.size,
|
||||
fileName,
|
||||
fileSize: fileBuffer?.length || 0,
|
||||
userId: user.id
|
||||
});
|
||||
|
||||
// Créer FormData pour l'envoi vers n8n
|
||||
const FormData = (await import('form-data')).default;
|
||||
const formData = new FormData();
|
||||
formData.append('pdf', file.buffer, {
|
||||
filename: file.originalname,
|
||||
formData.append('pdf', fileBuffer, {
|
||||
filename: fileName,
|
||||
contentType: 'application/pdf'
|
||||
});
|
||||
formData.append('recipient', recipient);
|
||||
|
||||
Reference in new issue
Block a user