• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

statuscompliance / status-backend / 20269538425

16 Dec 2025 01:26PM UTC coverage: 90.985% (-0.4%) from 91.375%
20269538425

push

github

alvarobernal2412
chore(linker): make datasourceConfigs required field

1470 of 1698 branches covered (86.57%)

Branch coverage included in aggregate %.

40 of 51 new or added lines in 4 files covered. (78.43%)

1 existing line in 1 file now uncovered.

2769 of 2961 relevant lines covered (93.52%)

28.31 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

73.08
/src/models/linker.model.js
1
import { DataTypes, UUIDV4 } from 'sequelize';
2

3
export default (sequelize) => sequelize.define('Linker', {
78✔
4
  id: {
5
    type: DataTypes.UUID,
6
    defaultValue: UUIDV4,
7
    primaryKey: true,
8
    allowNull: false,
9
  },
10
  name: {
11
    type: DataTypes.STRING(100),
12
    allowNull: true,
13
    comment: 'Human-readable name for the linker'
14
  },
15
  defaultMethodName: {
16
    type: DataTypes.STRING(100),
17
    allowNull: false,
18
    defaultValue: 'default',
19
    comment: 'Default method name to use when fetching from datasources'
20
  },
21
  datasourceIds: {
22
    type: DataTypes.JSON,
23
    allowNull: false,
24
    comment: 'Array of datasource IDs referenced by this linker',
25
    validate: {
26
      isValidArray(value) {
27
        if (!Array.isArray(value)) {
8✔
28
          throw new TypeError('datasourceIds must be an array');
1✔
29
        }
30
        if (value.length === 0) {
7✔
31
          throw new Error('datasourceIds must contain at least one datasource ID');
1✔
32
        }
33
      }
34
    }
35
  },
36
  datasourceConfigs: {
37
    type: DataTypes.JSON,
38
    allowNull: false,
39
    comment: 'Configuration map for each datasource including method configs and property mappings (REQUIRED)',
40
    validate: {
41
      isValidConfig(value) {
42
        if (typeof value !== 'object' || Array.isArray(value)) {
5!
NEW
43
          throw new Error('datasourceConfigs must be an object');
×
44
        }
45
        // Ensure each datasource config has methodConfig with methodName
46
        for (const [dsId, config] of Object.entries(value)) {
5✔
47
          if (!config.methodConfig) {
5!
NEW
48
            throw new Error(`methodConfig is required for datasource '${dsId}'`);
×
49
          }
50
          if (!config.methodConfig.methodName) {
5!
NEW
51
            throw new Error(`methodConfig.methodName is required for datasource '${dsId}'`);
×
52
          }
53
        }
54
      }
55
    }
56
  },
57
  description: {
58
    type: DataTypes.TEXT,
59
    allowNull: true,
60
    comment: 'Optional description of what this linker does'
61
  },
62
  environment: {
63
    type: DataTypes.STRING(20),
64
    allowNull: false,
65
    defaultValue: 'production',
66
    comment: 'Environment where this linker is used (production, staging, dev)'
67
  },
68
  isActive: {
69
    type: DataTypes.BOOLEAN,
70
    allowNull: false,
71
    defaultValue: true,
72
    comment: 'Whether this linker is active and can be used'
73
  },
74
  createdBy: {
75
    type: DataTypes.STRING(100),
76
    allowNull: false,
77
    comment: 'Username of the creator'
78
  },
79
  version: {
80
    type: DataTypes.INTEGER,
81
    allowNull: false,
82
    defaultValue: 1,
83
    comment: 'Version number, incremented on config changes'
84
  },
85
  lastExecutedAt: {
86
    type: DataTypes.DATE,
87
    allowNull: true,
88
    comment: 'Last time this linker was executed'
89
  },
90
  executionStatus: {
91
    type: import.meta.env?.VITEST ? DataTypes.STRING(50) : DataTypes.ENUM('success', 'failure', 'pending', 'not_executed'),
78!
92
    allowNull: false,
93
    defaultValue: 'not_executed'
94
  },
95
  createdAt: {
96
    type: DataTypes.DATE,
97
    allowNull: false,
98
    defaultValue: DataTypes.NOW
99
  },
100
  updatedAt: {
101
    type: DataTypes.DATE,
102
    allowNull: false,
103
    defaultValue: DataTypes.NOW
104
  },
105
  ownerId: {
106
    type: DataTypes.INTEGER,
107
    allowNull: false,
108
    references: {
109
      model: 'users',
110
      key: 'id'
111
    },
112
    onDelete: 'CASCADE',
113
    comment: 'User ID of the owner'
114
  }
115
}, {
116
  tableName: 'linkers',
117
  timestamps: true,
118
  indexes: [
119
    {
120
      unique: true,
121
      fields: ['name', 'ownerId'],
122
      name: 'linkers_name_owner_unique'
123
    },
124
    {
125
      fields: ['environment']
126
    },
127
    {
128
      fields: ['isActive']
129
    },
130
    {
131
      fields: ['ownerId']
132
    }
133
  ]
134
});
135

136
/**
137
 * @swagger
138
 * components:
139
 *   schemas:
140
 *     Linker:
141
 *       type: object
142
 *       properties:
143
 *         id:
144
 *           type: string
145
 *           format: uuid
146
 *           description: Unique identifier for the linker
147
 *         name:
148
 *           type: string
149
 *           description: Human-readable name for the linker
150
 *         defaultMethodName:
151
 *           type: string
152
 *           default: default
153
 *           description: Default method name to use when fetching from datasources
154
 *         datasourceIds:
155
 *           type: array
156
 *           items:
157
 *             type: string
158
 *             format: uuid
159
 *           description: Array of datasource IDs referenced by this linker
160
 *         datasourceConfigs:
161
 *           type: object
162
 *           required: true
163
 *           description: |
164
 *             Configuration map for each datasource (REQUIRED). 
165
 *             Each datasource MUST have a methodConfig with a methodName specified.
166
 *           additionalProperties:
167
 *             type: object
168
 *             required:
169
 *               - methodConfig
170
 *             properties:
171
 *               id:
172
 *                 type: string
173
 *                 format: uuid
174
 *               methodConfig:
175
 *                 type: object
176
 *                 required:
177
 *                   - methodName
178
 *                 properties:
179
 *                   methodName:
180
 *                     type: string
181
 *                     description: Name of the method to invoke (REQUIRED)
182
 *                   options:
183
 *                     type: object
184
 *                     description: Method-specific options
185
 *               propertyMapping:
186
 *                 type: object
187
 *                 additionalProperties:
188
 *                   type: string
189
 *         description:
190
 *           type: string
191
 *           description: Optional description of what this linker does
192
 *         environment:
193
 *           type: string
194
 *           enum: [production, staging, dev]
195
 *           default: production
196
 *           description: Environment where this linker is used
197
 *         isActive:
198
 *           type: boolean
199
 *           default: true
200
 *           description: Whether this linker is active and can be used
201
 *         createdBy:
202
 *           type: string
203
 *           description: Username of the creator
204
 *         version:
205
 *           type: integer
206
 *           description: Version number, incremented on config changes
207
 *         lastExecutedAt:
208
 *           type: string
209
 *           format: date-time
210
 *           description: Last time this linker was executed
211
 *         executionStatus:
212
 *           type: string
213
 *           enum: [success, failure, pending, not_executed]
214
 *           default: not_executed
215
 *           description: Status of the last execution
216
 *         createdAt:
217
 *           type: string
218
 *           format: date-time
219
 *         updatedAt:
220
 *           type: string
221
 *           format: date-time
222
 *         ownerId:
223
 *           type: integer
224
 *           description: User ID of the owner
225
 *       required:
226
 *         - datasourceIds
227
 *         - datasourceConfigs
228
 *         - createdBy
229
 *         - ownerId
230
 */
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc