Compare commits

...

5 Commits

Author SHA1 Message Date
Gitea Actions
7fc263691f ci: Bump version to 0.0.29 [skip ci] 2025-12-24 22:41:17 +05:00
c0912d36d5 Merge branch 'main' of https://gitea.projectium.com/torbo/flyer-crawler.projectium.com
All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 15m59s
2025-12-24 09:39:56 -08:00
612c2b5943 deploy to test fix 2025-12-24 09:39:49 -08:00
Gitea Actions
8e787ddcf0 ci: Bump version to 0.0.28 [skip ci] 2025-12-24 22:18:18 +05:00
11c52d284c fixing unit tests
All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 15m13s
2025-12-24 09:17:09 -08:00
7 changed files with 39 additions and 13 deletions

View File

@@ -360,7 +360,7 @@ jobs:
echo "Installing production dependencies and restarting test server..."
cd /var/www/flyer-crawler-test.projectium.com
npm install --omit=dev # Install only production dependencies
npm install --omit=dev
# Use `startOrReload` with the ecosystem file. This is the standard, idempotent way to deploy.
# It will START the process if it's not running, or RELOAD it if it is.
# We also add `&& pm2 save` to persist the process list across server reboots.

View File

@@ -21,10 +21,17 @@ module.exports = {
},
// Test Environment Settings
env_test: {
NODE_ENV: 'development', // Use 'development' for test to enable more verbose logging if needed
NODE_ENV: 'test', // Set to 'test' to match the environment purpose and disable pino-pretty
name: 'flyer-crawler-api-test',
cwd: '/var/www/flyer-crawler-test.projectium.com',
},
// Development Environment Settings
env_development: {
NODE_ENV: 'development',
name: 'flyer-crawler-api-dev',
watch: true,
ignore_watch: ['node_modules', 'logs', '*.log', 'flyer-images', '.git'],
},
},
{
// --- General Worker ---
@@ -39,10 +46,17 @@ module.exports = {
},
// Test Environment Settings
env_test: {
NODE_ENV: 'development',
NODE_ENV: 'test',
name: 'flyer-crawler-worker-test',
cwd: '/var/www/flyer-crawler-test.projectium.com',
},
// Development Environment Settings
env_development: {
NODE_ENV: 'development',
name: 'flyer-crawler-worker-dev',
watch: true,
ignore_watch: ['node_modules', 'logs', '*.log', 'flyer-images', '.git'],
},
},
{
// --- Analytics Worker ---
@@ -57,10 +71,17 @@ module.exports = {
},
// Test Environment Settings
env_test: {
NODE_ENV: 'development',
NODE_ENV: 'test',
name: 'flyer-crawler-analytics-worker-test',
cwd: '/var/www/flyer-crawler-test.projectium.com',
},
// Development Environment Settings
env_development: {
NODE_ENV: 'development',
name: 'flyer-crawler-analytics-worker-dev',
watch: true,
ignore_watch: ['node_modules', 'logs', '*.log', 'flyer-images', '.git'],
},
},
],
};

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "flyer-crawler",
"version": "0.0.27",
"version": "0.0.29",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "flyer-crawler",
"version": "0.0.27",
"version": "0.0.29",
"dependencies": {
"@bull-board/api": "^6.14.2",
"@bull-board/express": "^6.14.2",

View File

@@ -1,7 +1,7 @@
{
"name": "flyer-crawler",
"private": true,
"version": "0.0.27",
"version": "0.0.29",
"type": "module",
"scripts": {
"dev": "concurrently \"npm:start:dev\" \"vite\"",

View File

@@ -126,7 +126,7 @@ describe('Price Routes (/api/price-history)', () => {
expect(response.body.errors).toHaveLength(2);
// The actual message is "Too small: expected number to be >0"
expect(response.body.errors[0].message).toBe('Too small: expected number to be >0');
expect(response.body.errors[1].message).toBe('Expected number, received string');
expect(response.body.errors[1].message).toBe('Invalid input: expected number, received NaN');
});
});
});

View File

@@ -34,6 +34,9 @@ export const logger = pino({
'*.body.password',
'*.body.newPassword',
'*.body.currentPassword',
'*.body.confirmPassword',
'*.body.refreshToken',
'*.body.token',
],
censor: '[REDACTED]',
},

View File

@@ -59,7 +59,6 @@ export const optionalNumeric = (
nonnegative?: boolean;
} = {},
) => {
// Start with the base number schema and apply all number-specific constraints first.
let numberSchema = z.coerce.number();
if (options.integer) numberSchema = numberSchema.int();
@@ -69,15 +68,18 @@ export const optionalNumeric = (
if (options.min !== undefined) numberSchema = numberSchema.min(options.min);
if (options.max !== undefined) numberSchema = numberSchema.max(options.max);
// Now, wrap the fully configured number schema with the preprocess step.
// Make the number schema optional *before* preprocessing. This allows it to correctly handle
// the `undefined` value that our preprocessor generates from `null`.
const optionalNumberSchema = numberSchema.optional();
// This is crucial because z.coerce.number(null) results in 0, which bypasses
// the .optional() and .default() logic for null inputs. We want null to be
// treated as "not provided", just like undefined.
const schema = z.preprocess((val) => (val === null ? undefined : val), numberSchema);
const schema = z.preprocess((val) => (val === null ? undefined : val), optionalNumberSchema);
if (options.default !== undefined) return schema.optional().default(options.default);
if (options.default !== undefined) return schema.default(options.default);
return schema.optional();
return schema;
};
/**