@autofleet/sadot 0.13.0-beta.11 → 0.13.0-beta.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -80,8 +80,9 @@ router.get('/', async (req, res) => {
80
80
  */
81
81
  router.get('/:validatorId', async (req, res) => {
82
82
  try {
83
- const { validatorId } = req.params;
84
- const validators = await ValidatorRepo.findAll({ id: validatorId });
83
+ const { validatorId, modelName } = req.params;
84
+ // Include disabled validators when fetching by ID
85
+ const validators = await ValidatorRepo.findAll({ id: validatorId, modelType: modelName }, { withDisabled: true });
85
86
  if (!validators.length) {
86
87
  throw new errors_1.ResourceNotFoundError('Validator not found');
87
88
  }
@@ -103,6 +104,11 @@ router.patch('/:validatorId', async (req, res) => {
103
104
  if (validatedPayload.schema) {
104
105
  (0, validator_schema_1.validateValidatorSchema)(validatedPayload.schema);
105
106
  }
107
+ // First verify the validator exists, including disabled ones
108
+ const existingValidators = await ValidatorRepo.findAll({ id: validatorId }, { withDisabled: true });
109
+ if (!existingValidators.length) {
110
+ throw new errors_1.ResourceNotFoundError('Validator not found');
111
+ }
106
112
  const [count, validators] = await ValidatorRepo.update(validatorId, validatedPayload);
107
113
  if (!count) {
108
114
  throw new errors_1.ResourceNotFoundError('Validator not found');
@@ -119,9 +125,14 @@ router.patch('/:validatorId', async (req, res) => {
119
125
  router.delete('/:validatorId', async (req, res) => {
120
126
  try {
121
127
  const { validatorId } = req.params;
128
+ // First verify the validator exists, including disabled ones
129
+ const existingValidators = await ValidatorRepo.findAll({ id: validatorId }, { withDisabled: true });
130
+ if (!existingValidators.length) {
131
+ throw new errors_1.ResourceNotFoundError('Validator not found');
132
+ }
122
133
  const [count] = await ValidatorRepo.disable(validatorId);
123
134
  if (!count) {
124
- throw new errors_1.ResourceNotFoundError('Validator not found');
135
+ throw new errors_1.ResourceNotFoundError('Validator failed to be disabled');
125
136
  }
126
137
  return res.status(http_status_codes_1.StatusCodes.NO_CONTENT).send();
127
138
  }
@@ -23,6 +23,7 @@ const validationSchemas = {
23
23
  }),
24
24
  update: joi_1.default.object({
25
25
  entityId: joi_1.default.string().uuid(),
26
+ entityType: joi_1.default.string(),
26
27
  schema: joi_1.default.object({
27
28
  type: joi_1.default.string().valid('object'),
28
29
  properties: joi_1.default.object({
@@ -44,6 +44,60 @@ const ajv = new ajv_1.default({
44
44
  $data: true, // Enable $data references
45
45
  });
46
46
  (0, ajv_formats_1.default)(ajv);
47
+ /**
48
+ * Helper function to manually copy object properties
49
+ * This is more efficient for large objects and avoids excessive object creation
50
+ */
51
+ const manualObjectCopy = (sourceObj, additionalProps) => {
52
+ const resultObj = Object.create(null);
53
+ // Copy properties from source object
54
+ if (sourceObj) {
55
+ Object.keys(sourceObj).forEach((key) => {
56
+ resultObj[key] = sourceObj[key];
57
+ });
58
+ }
59
+ // Add additional properties if provided
60
+ if (additionalProps) {
61
+ Object.keys(additionalProps).forEach((key) => {
62
+ resultObj[key] = additionalProps[key];
63
+ });
64
+ }
65
+ return resultObj;
66
+ };
67
+ /**
68
+ * Fetches complete custom fields for an instance by merging DB values with update values
69
+ * This is needed for partial updates to ensure all related fields are available for validation
70
+ */
71
+ const getCompleteCustomFields = async (instance, options) => {
72
+ // If we don't have an instance id or no custom fields being updated, return original fields
73
+ if (!instance.id || !instance.customFields || Object.keys(instance.customFields).length === 0) {
74
+ return instance.customFields || {};
75
+ }
76
+ try {
77
+ const ModelClass = instance.constructor;
78
+ // Only select the customFields column to minimize data transfer
79
+ const currentCustomFields = await ModelClass.findOne({
80
+ where: { id: instance.id },
81
+ attributes: ['customFields'],
82
+ transaction: options.transaction,
83
+ raw: true, // Get plain object instead of model instance for better performance
84
+ });
85
+ if (currentCustomFields?.customFields) {
86
+ // Merge existing fields with update fields using our helper function
87
+ const completeFields = manualObjectCopy(currentCustomFields.customFields, instance.customFields);
88
+ logger_1.default.debug('sadot - fetched complete custom fields for validation', {
89
+ fieldsCount: Object.keys(completeFields).length,
90
+ updateFieldsCount: Object.keys(instance.customFields).length,
91
+ });
92
+ return completeFields;
93
+ }
94
+ }
95
+ catch (error) {
96
+ logger_1.default.error('sadot - error fetching complete model for validation', { error });
97
+ // Continue with partial data if we can't fetch the complete model
98
+ }
99
+ return instance.customFields || {};
100
+ };
47
101
  /**
48
102
  * Validates the model using custom validators
49
103
  */
@@ -71,21 +125,26 @@ const validateModel = async (instance, options, scopeAttributes, isCreate = fals
71
125
  return;
72
126
  }
73
127
  // For updates, get the previous values
74
- const originalValues = isCreate
75
- ? null
76
- : {
77
- ...instance.previous(),
78
- customFields: instance.previous('customFields') || {},
79
- };
128
+ let originalValues = null;
129
+ if (!isCreate) {
130
+ // Create originalValues with our helper function
131
+ originalValues = manualObjectCopy(instance.previous());
132
+ // Add customFields separately
133
+ originalValues.customFields = instance.previous('customFields') || {};
134
+ }
135
+ // Get complete custom fields by merging DB values with update values
136
+ // This is especially important for partial updates to ensure all related fields are available
137
+ const completeCustomFields = !isCreate
138
+ ? await getCompleteCustomFields(instance, options)
139
+ : instance.customFields || {};
80
140
  // For debugging in case of update
81
141
  if (!isCreate) {
142
+ // Create after object for logging
143
+ const logAfterObj = manualObjectCopy(instance.dataValues, { customFields: completeCustomFields });
82
144
  logger_1.default.debug('sadot - validate with values', {
83
145
  before: originalValues,
84
- after: {
85
- ...instance.dataValues,
86
- ...instance.customFields,
87
- },
88
- schema: JSON.stringify(validators[0].schema),
146
+ after: logAfterObj,
147
+ schema: validators[0].schema,
89
148
  });
90
149
  }
91
150
  // eslint-disable-next-line no-restricted-syntax
@@ -93,7 +152,7 @@ const validateModel = async (instance, options, scopeAttributes, isCreate = fals
93
152
  const { schema } = validator;
94
153
  const typedSchema = schema;
95
154
  logger_1.default.debug('sadot - validating with schema', {
96
- schema: JSON.stringify(schema),
155
+ schema,
97
156
  hasAfterProps: !!typedSchema.properties?.after,
98
157
  hasBeforeProps: !!typedSchema.properties?.before,
99
158
  });
@@ -110,7 +169,7 @@ const validateModel = async (instance, options, scopeAttributes, isCreate = fals
110
169
  const isValid = validateSchema(JSON.parse(JSON.stringify({
111
170
  after: {
112
171
  ...instance.dataValues,
113
- customFields: instance.customFields,
172
+ customFields: completeCustomFields,
114
173
  },
115
174
  })));
116
175
  if (!isValid) {
@@ -122,21 +181,22 @@ const validateModel = async (instance, options, scopeAttributes, isCreate = fals
122
181
  else {
123
182
  // For update operations, we need both before and after
124
183
  const validateSchema = ajv.compile(typedSchema);
125
- const isValid = validateSchema(JSON.parse(JSON.stringify({
184
+ // Create after object with our helper function
185
+ const afterObj = manualObjectCopy(instance.dataValues);
186
+ // Add complete custom fields
187
+ afterObj.customFields = completeCustomFields;
188
+ // Create validation payload
189
+ const payload = {
126
190
  before: originalValues,
127
- after: {
128
- ...instance.dataValues,
129
- customFields: instance.customFields,
130
- },
131
- })));
191
+ after: afterObj,
192
+ };
193
+ // Validate
194
+ const isValid = validateSchema(JSON.parse(JSON.stringify(payload)));
132
195
  logger_1.default.info('sadot - validation result', {
133
196
  isValid,
134
197
  test: {
135
198
  before: originalValues,
136
- after: {
137
- ...instance.dataValues,
138
- ...instance.customFields,
139
- },
199
+ after: afterObj,
140
200
  },
141
201
  });
142
202
  if (!isValid) {
package/dist/index.d.ts CHANGED
@@ -4,9 +4,6 @@ import type { CustomFieldOptions, ModelFetcher, Models } from './types';
4
4
  export * from './utils/validations/schema/custom-fields';
5
5
  export * from './utils/constants';
6
6
  export * from './utils/helpers';
7
- export * as DefinitionRepo from './repository/definition';
8
- export * as ValueRepo from './repository/value';
9
- export * as ValidatorRepo from './repository/validator';
10
7
  /**
11
8
  * Adding custom fields enrichment to the models inside the MODELS_FILE_NAME json file
12
9
  * @see {@link 'custom-fields/config'} for configurations
package/dist/index.js CHANGED
@@ -29,7 +29,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
29
29
  return (mod && mod.__esModule) ? mod : { "default": mod };
30
30
  };
31
31
  Object.defineProperty(exports, "__esModule", { value: true });
32
- exports.disableCustomFields = exports.ValidatorRepo = exports.ValueRepo = exports.DefinitionRepo = void 0;
32
+ exports.disableCustomFields = void 0;
33
33
  const models_1 = require("./models");
34
34
  const api_1 = __importDefault(require("./api"));
35
35
  const db_1 = __importDefault(require("./utils/db"));
@@ -38,10 +38,6 @@ const init_1 = require("./utils/init");
38
38
  __exportStar(require("./utils/validations/schema/custom-fields"), exports);
39
39
  __exportStar(require("./utils/constants"), exports);
40
40
  __exportStar(require("./utils/helpers"), exports);
41
- // Export repositories
42
- exports.DefinitionRepo = __importStar(require("./repository/definition"));
43
- exports.ValueRepo = __importStar(require("./repository/value"));
44
- exports.ValidatorRepo = __importStar(require("./repository/validator"));
45
41
  /**
46
42
  * Adding custom fields enrichment to the models inside the MODELS_FILE_NAME json file
47
43
  * @see {@link 'custom-fields/config'} for configurations
@@ -90,6 +90,7 @@ __decorate([
90
90
  __metadata("design:returntype", void 0)
91
91
  ], CustomValidator, "afterSaveHandler", null);
92
92
  CustomValidator = __decorate([
93
+ (0, sequelize_typescript_1.DefaultScope)(() => ({ where: { disabled: false } })),
93
94
  (0, sequelize_typescript_1.Table)({
94
95
  timestamps: true,
95
96
  })
@@ -58,6 +58,21 @@ const initTables = async (sequelize, getUser, { schemaPrefix, schemaVersion, use
58
58
  },
59
59
  };
60
60
  });
61
+ CustomValidator_1.default.addScope('userScope', () => {
62
+ const user = getUser();
63
+ if (!user?.permissions) {
64
+ return {};
65
+ }
66
+ return {
67
+ where: {
68
+ entityId: [
69
+ ...Object.keys(user.permissions.fleets),
70
+ ...Object.keys(user.permissions.businessModels),
71
+ ...Object.keys(user.permissions.demandSources),
72
+ ],
73
+ },
74
+ };
75
+ });
61
76
  logger_1.default.info('custom-fields: models added');
62
77
  const SequelizeMeta = sequelize.define('SequelizeMeta', {
63
78
  name: {
@@ -7,7 +7,7 @@ export interface ValidatorAttributes {
7
7
  entityId: string;
8
8
  entityType: string;
9
9
  modelType: string;
10
- schema: Record<string, unknown>;
10
+ schema: CustomValidator['schema'];
11
11
  disabled?: boolean;
12
12
  [key: string]: unknown;
13
13
  }
@@ -16,13 +16,23 @@ exports.create = create;
16
16
  const findAll = async (where = {}, options = { withDisabled: false }) => {
17
17
  logger_1.default.debug('custom-validator - find all validators');
18
18
  const { transaction, withDisabled } = options;
19
- const fullWhere = withDisabled
20
- ? where
21
- : { ...where, disabled: false };
22
- const validators = await models_1.CustomValidator.findAll({
23
- where: fullWhere,
24
- transaction,
25
- });
19
+ let validators;
20
+ if (withDisabled) {
21
+ // If withDisabled is true, use unscoped to ignore the default scope that filters disabled items
22
+ // Apply the userScope separately to maintain permission filtering
23
+ validators = await models_1.CustomValidator.unscoped().scope('userScope').findAll({
24
+ where,
25
+ transaction,
26
+ });
27
+ }
28
+ else {
29
+ // Use defaultScope and userScope to filter both disabled and by permissions
30
+ // The defaultScope keeps only non-disabled validators
31
+ validators = await models_1.CustomValidator.scope(['defaultScope', 'userScope']).findAll({
32
+ where,
33
+ transaction,
34
+ });
35
+ }
26
36
  return validators;
27
37
  };
28
38
  exports.findAll = findAll;
@@ -4,7 +4,7 @@ exports.default = {
4
4
  test: {
5
5
  username: process.env.DB_USERNAME || '',
6
6
  password: process.env.DB_PASSWORD || null,
7
- database: process.env.DB_NAME || 'sadot_package_test',
7
+ database: process.env.DB_NAME || 'postgres',
8
8
  host: process.env.DB_HOST || '127.0.0.1',
9
9
  port: process.env.DB_PORT || 5432,
10
10
  dialect: process.env.DB_TYPE || 'postgres',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autofleet/sadot",
3
- "version": "0.13.0-beta.11",
3
+ "version": "0.13.0-beta.12",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -66,8 +66,9 @@ router.get<
66
66
  */
67
67
  router.get<{ modelName: string; validatorId: string }, CustomValidator>('/:validatorId', async (req, res) => {
68
68
  try {
69
- const { validatorId } = req.params;
70
- const validators = await ValidatorRepo.findAll({ id: validatorId });
69
+ const { validatorId, modelName } = req.params;
70
+ // Include disabled validators when fetching by ID
71
+ const validators = await ValidatorRepo.findAll({ id: validatorId, modelType: modelName }, { withDisabled: true });
71
72
 
72
73
  if (!validators.length) {
73
74
  throw new ResourceNotFoundError('Validator not found');
@@ -94,6 +95,12 @@ router.patch<{ modelName: string; validatorId: string }, CustomValidator>('/:val
94
95
  validateValidatorSchema(validatedPayload.schema);
95
96
  }
96
97
 
98
+ // First verify the validator exists, including disabled ones
99
+ const existingValidators = await ValidatorRepo.findAll({ id: validatorId }, { withDisabled: true });
100
+ if (!existingValidators.length) {
101
+ throw new ResourceNotFoundError('Validator not found');
102
+ }
103
+
97
104
  const [count, validators] = await ValidatorRepo.update(validatorId, validatedPayload);
98
105
 
99
106
  if (!count) {
@@ -112,10 +119,17 @@ router.patch<{ modelName: string; validatorId: string }, CustomValidator>('/:val
112
119
  router.delete<{ modelName: string; validatorId: string }>('/:validatorId', async (req, res) => {
113
120
  try {
114
121
  const { validatorId } = req.params;
122
+
123
+ // First verify the validator exists, including disabled ones
124
+ const existingValidators = await ValidatorRepo.findAll({ id: validatorId }, { withDisabled: true });
125
+ if (!existingValidators.length) {
126
+ throw new ResourceNotFoundError('Validator not found');
127
+ }
128
+
115
129
  const [count] = await ValidatorRepo.disable(validatorId);
116
130
 
117
131
  if (!count) {
118
- throw new ResourceNotFoundError('Validator not found');
132
+ throw new ResourceNotFoundError('Validator failed to be disabled');
119
133
  }
120
134
 
121
135
  return res.status(StatusCodes.NO_CONTENT).send();
@@ -21,6 +21,7 @@ const validationSchemas = {
21
21
 
22
22
  update: Joi.object({
23
23
  entityId: Joi.string().uuid(),
24
+ entityType: Joi.string(),
24
25
  schema: Joi.object({
25
26
  type: Joi.string().valid('object'),
26
27
  properties: Joi.object({
@@ -20,6 +20,72 @@ const ajv = new Ajv({
20
20
 
21
21
  addFormats(ajv);
22
22
 
23
+ /**
24
+ * Helper function to manually copy object properties
25
+ * This is more efficient for large objects and avoids excessive object creation
26
+ */
27
+ const manualObjectCopy = (sourceObj: Record<string, any>, additionalProps?: Record<string, any>): Record<string, any> => {
28
+ const resultObj = Object.create(null);
29
+
30
+ // Copy properties from source object
31
+ if (sourceObj) {
32
+ Object.keys(sourceObj).forEach((key) => {
33
+ resultObj[key] = sourceObj[key];
34
+ });
35
+ }
36
+
37
+ // Add additional properties if provided
38
+ if (additionalProps) {
39
+ Object.keys(additionalProps).forEach((key) => {
40
+ resultObj[key] = additionalProps[key];
41
+ });
42
+ }
43
+
44
+ return resultObj;
45
+ };
46
+
47
+ /**
48
+ * Fetches complete custom fields for an instance by merging DB values with update values
49
+ * This is needed for partial updates to ensure all related fields are available for validation
50
+ */
51
+ const getCompleteCustomFields = async (instance, options): Promise<Record<string, any>> => {
52
+ // If we don't have an instance id or no custom fields being updated, return original fields
53
+ if (!instance.id || !instance.customFields || Object.keys(instance.customFields).length === 0) {
54
+ return instance.customFields || {};
55
+ }
56
+
57
+ try {
58
+ const ModelClass = instance.constructor;
59
+ // Only select the customFields column to minimize data transfer
60
+ const currentCustomFields = await ModelClass.findOne({
61
+ where: { id: instance.id },
62
+ attributes: ['customFields'],
63
+ transaction: options.transaction,
64
+ raw: true, // Get plain object instead of model instance for better performance
65
+ });
66
+
67
+ if (currentCustomFields?.customFields) {
68
+ // Merge existing fields with update fields using our helper function
69
+ const completeFields = manualObjectCopy(
70
+ currentCustomFields.customFields,
71
+ instance.customFields,
72
+ );
73
+
74
+ logger.debug('sadot - fetched complete custom fields for validation', {
75
+ fieldsCount: Object.keys(completeFields).length,
76
+ updateFieldsCount: Object.keys(instance.customFields).length,
77
+ });
78
+
79
+ return completeFields;
80
+ }
81
+ } catch (error) {
82
+ logger.error('sadot - error fetching complete model for validation', { error });
83
+ // Continue with partial data if we can't fetch the complete model
84
+ }
85
+
86
+ return instance.customFields || {};
87
+ };
88
+
23
89
  /**
24
90
  * Validates the model using custom validators
25
91
  */
@@ -66,22 +132,30 @@ const validateModel = async (
66
132
  }
67
133
 
68
134
  // For updates, get the previous values
69
- const originalValues = isCreate
70
- ? null
71
- : {
72
- ...instance.previous(),
73
- customFields: instance.previous('customFields') || {},
74
- };
135
+ let originalValues = null;
136
+ if (!isCreate) {
137
+ // Create originalValues with our helper function
138
+ originalValues = manualObjectCopy(instance.previous());
139
+
140
+ // Add customFields separately
141
+ originalValues.customFields = instance.previous('customFields') || {};
142
+ }
143
+
144
+ // Get complete custom fields by merging DB values with update values
145
+ // This is especially important for partial updates to ensure all related fields are available
146
+ const completeCustomFields = !isCreate
147
+ ? await getCompleteCustomFields(instance, options)
148
+ : instance.customFields || {};
75
149
 
76
150
  // For debugging in case of update
77
151
  if (!isCreate) {
152
+ // Create after object for logging
153
+ const logAfterObj = manualObjectCopy(instance.dataValues, { customFields: completeCustomFields });
154
+
78
155
  logger.debug('sadot - validate with values', {
79
156
  before: originalValues,
80
- after: {
81
- ...instance.dataValues,
82
- ...instance.customFields,
83
- },
84
- schema: JSON.stringify(validators[0].schema),
157
+ after: logAfterObj,
158
+ schema: validators[0].schema,
85
159
  });
86
160
  }
87
161
 
@@ -91,7 +165,7 @@ const validateModel = async (
91
165
  const typedSchema = schema as Record<string, any>;
92
166
 
93
167
  logger.debug('sadot - validating with schema', {
94
- schema: JSON.stringify(schema),
168
+ schema,
95
169
  hasAfterProps: !!typedSchema.properties?.after,
96
170
  hasBeforeProps: !!typedSchema.properties?.before,
97
171
  });
@@ -110,7 +184,7 @@ const validateModel = async (
110
184
  const isValid = validateSchema(JSON.parse(JSON.stringify({
111
185
  after: {
112
186
  ...instance.dataValues,
113
- customFields: instance.customFields,
187
+ customFields: completeCustomFields,
114
188
  },
115
189
  })));
116
190
 
@@ -125,22 +199,26 @@ const validateModel = async (
125
199
  // For update operations, we need both before and after
126
200
  const validateSchema = ajv.compile(typedSchema);
127
201
 
128
- const isValid = validateSchema(JSON.parse(JSON.stringify({
202
+ // Create after object with our helper function
203
+ const afterObj = manualObjectCopy(instance.dataValues);
204
+
205
+ // Add complete custom fields
206
+ afterObj.customFields = completeCustomFields;
207
+
208
+ // Create validation payload
209
+ const payload = {
129
210
  before: originalValues,
130
- after: {
131
- ...instance.dataValues,
132
- customFields: instance.customFields,
133
- },
134
- })));
211
+ after: afterObj,
212
+ };
213
+
214
+ // Validate
215
+ const isValid = validateSchema(JSON.parse(JSON.stringify(payload)));
135
216
 
136
217
  logger.info('sadot - validation result', {
137
218
  isValid,
138
219
  test: {
139
220
  before: originalValues,
140
- after: {
141
- ...instance.dataValues,
142
- ...instance.customFields,
143
- },
221
+ after: afterObj,
144
222
  },
145
223
  });
146
224
 
package/src/index.ts CHANGED
@@ -17,11 +17,6 @@ export * from './utils/constants';
17
17
 
18
18
  export * from './utils/helpers';
19
19
 
20
- // Export repositories
21
- export * as DefinitionRepo from './repository/definition';
22
- export * as ValueRepo from './repository/value';
23
- export * as ValidatorRepo from './repository/validator';
24
-
25
20
  /**
26
21
  * Adding custom fields enrichment to the models inside the MODELS_FILE_NAME json file
27
22
  * @see {@link 'custom-fields/config'} for configurations
@@ -6,10 +6,12 @@ import {
6
6
  DataType,
7
7
  Default,
8
8
  AfterUpsert,
9
+ DefaultScope,
9
10
  } from 'sequelize-typescript';
10
11
  import { randomUUID } from 'node:crypto';
11
12
  import { sendDimEvent } from '../events';
12
13
 
14
+ @DefaultScope(() => ({ where: { disabled: false } }))
13
15
  @Table({
14
16
  timestamps: true,
15
17
  })
@@ -68,6 +68,22 @@ const initTables = async (
68
68
  };
69
69
  });
70
70
 
71
+ CustomValidator.addScope('userScope', () => {
72
+ const user = getUser();
73
+ if (!user?.permissions) {
74
+ return {};
75
+ }
76
+ return {
77
+ where: {
78
+ entityId: [
79
+ ...Object.keys(user.permissions.fleets),
80
+ ...Object.keys(user.permissions.businessModels),
81
+ ...Object.keys(user.permissions.demandSources),
82
+ ],
83
+ },
84
+ };
85
+ });
86
+
71
87
  logger.info('custom-fields: models added');
72
88
 
73
89
  const SequelizeMeta = sequelize.define(
@@ -11,7 +11,7 @@ export interface ValidatorAttributes {
11
11
  entityId: string;
12
12
  entityType: string;
13
13
  modelType: string;
14
- schema: Record<string, unknown>;
14
+ schema: CustomValidator['schema'];
15
15
  disabled?: boolean;
16
16
  [key: string]: unknown; // Add index signature for Sequelize compatibility
17
17
  }
@@ -36,14 +36,22 @@ export const findAll = async (
36
36
 
37
37
  const { transaction, withDisabled } = options;
38
38
 
39
- const fullWhere = withDisabled
40
- ? where
41
- : { ...where, disabled: false };
42
-
43
- const validators = await CustomValidator.findAll({
44
- where: fullWhere,
45
- transaction,
46
- });
39
+ let validators;
40
+ if (withDisabled) {
41
+ // If withDisabled is true, use unscoped to ignore the default scope that filters disabled items
42
+ // Apply the userScope separately to maintain permission filtering
43
+ validators = await CustomValidator.unscoped().scope('userScope').findAll({
44
+ where,
45
+ transaction,
46
+ });
47
+ } else {
48
+ // Use defaultScope and userScope to filter both disabled and by permissions
49
+ // The defaultScope keeps only non-disabled validators
50
+ validators = await CustomValidator.scope(['defaultScope', 'userScope']).findAll({
51
+ where,
52
+ transaction,
53
+ });
54
+ }
47
55
 
48
56
  return validators;
49
57
  };
@@ -2,7 +2,7 @@ export default {
2
2
  test: {
3
3
  username: process.env.DB_USERNAME || '',
4
4
  password: process.env.DB_PASSWORD || null,
5
- database: process.env.DB_NAME || 'sadot_package_test',
5
+ database: process.env.DB_NAME || 'postgres',
6
6
  host: process.env.DB_HOST || '127.0.0.1',
7
7
  port: process.env.DB_PORT || 5432,
8
8
  dialect: process.env.DB_TYPE || 'postgres',