@things-factory/labeling 10.1.247 → 10.1.248

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.
Files changed (42) hide show
  1. package/package.json +4 -4
  2. package/dist-client/index.d.ts +0 -3
  3. package/dist-client/index.js +0 -9
  4. package/dist-client/index.js.map +0 -1
  5. package/dist-client/pages/labeling-workflow-builder.d.ts +0 -26
  6. package/dist-client/pages/labeling-workflow-builder.js +0 -636
  7. package/dist-client/pages/labeling-workflow-builder.js.map +0 -1
  8. package/dist-client/pages/labeling-workflow-list.d.ts +0 -24
  9. package/dist-client/pages/labeling-workflow-list.js +0 -495
  10. package/dist-client/pages/labeling-workflow-list.js.map +0 -1
  11. package/dist-client/route.d.ts +0 -1
  12. package/dist-client/route.js +0 -47
  13. package/dist-client/route.js.map +0 -1
  14. package/dist-client/tsconfig.tsbuildinfo +0 -1
  15. package/dist-server/entities/index.d.ts +0 -5
  16. package/dist-server/entities/index.js +0 -11
  17. package/dist-server/entities/index.js.map +0 -1
  18. package/dist-server/index.d.ts +0 -3
  19. package/dist-server/index.js +0 -7
  20. package/dist-server/index.js.map +0 -1
  21. package/dist-server/route.d.ts +0 -2
  22. package/dist-server/route.js +0 -6
  23. package/dist-server/route.js.map +0 -1
  24. package/dist-server/service/index.d.ts +0 -8
  25. package/dist-server/service/index.js +0 -21
  26. package/dist-server/service/index.js.map +0 -1
  27. package/dist-server/service/labeling-workflow-service.d.ts +0 -69
  28. package/dist-server/service/labeling-workflow-service.js +0 -531
  29. package/dist-server/service/labeling-workflow-service.js.map +0 -1
  30. package/dist-server/service/labeling-workflow.d.ts +0 -30
  31. package/dist-server/service/labeling-workflow.js +0 -119
  32. package/dist-server/service/labeling-workflow.js.map +0 -1
  33. package/dist-server/service/workflow-execution-step.d.ts +0 -28
  34. package/dist-server/service/workflow-execution-step.js +0 -115
  35. package/dist-server/service/workflow-execution-step.js.map +0 -1
  36. package/dist-server/service/workflow-execution.d.ts +0 -27
  37. package/dist-server/service/workflow-execution.js +0 -110
  38. package/dist-server/service/workflow-execution.js.map +0 -1
  39. package/dist-server/tsconfig.tsbuildinfo +0 -1
  40. package/dist-server/types/workflow-types.d.ts +0 -141
  41. package/dist-server/types/workflow-types.js +0 -488
  42. package/dist-server/types/workflow-types.js.map +0 -1
@@ -1,531 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.LabelingWorkflowService = void 0;
4
- const tslib_1 = require("tslib");
5
- const type_graphql_1 = require("type-graphql");
6
- const typeorm_1 = require("typeorm");
7
- const shell_1 = require("@things-factory/shell");
8
- const workflow_types_js_1 = require("../types/workflow-types.js");
9
- const labeling_workflow_js_1 = require("./labeling-workflow.js");
10
- const workflow_execution_js_1 = require("./workflow-execution.js");
11
- const workflow_execution_step_js_1 = require("./workflow-execution-step.js");
12
- const dataset_labeling_integration_js_1 = require("@things-factory/integration-label-studio/dist-server/service/dataset-labeling-integration.js");
13
- const external_data_source_service_js_1 = require("@things-factory/integration-label-studio/dist-server/service/external-data-source-service.js");
14
- const ai_prediction_service_js_1 = require("@things-factory/integration-label-studio/dist-server/service/ai-prediction-service.js");
15
- /**
16
- * Labeling Workflow Service
17
- *
18
- * Orchestrates end-to-end labeling workflows with multiple steps
19
- *
20
- * Features:
21
- * - Define multi-step labeling workflows
22
- * - Auto-execute workflows based on triggers
23
- * - Track execution progress
24
- * - Error handling and retry logic
25
- * - Conditional execution
26
- * - Database persistence with TypeORM
27
- */
28
- let LabelingWorkflowService = class LabelingWorkflowService {
29
- constructor() {
30
- // Service dependencies (lazy initialization)
31
- this.datasetIntegration = null;
32
- this.externalDataSource = null;
33
- this.aiPredictionService = null;
34
- }
35
- getDatasetIntegration() {
36
- if (!this.datasetIntegration) {
37
- this.datasetIntegration = new dataset_labeling_integration_js_1.DatasetLabelingIntegration();
38
- }
39
- return this.datasetIntegration;
40
- }
41
- getExternalDataSource() {
42
- if (!this.externalDataSource) {
43
- this.externalDataSource = new external_data_source_service_js_1.ExternalDataSourceService();
44
- }
45
- return this.externalDataSource;
46
- }
47
- getAIPredictionService() {
48
- if (!this.aiPredictionService) {
49
- this.aiPredictionService = new ai_prediction_service_js_1.LabelStudioAIPredictionService();
50
- }
51
- return this.aiPredictionService;
52
- }
53
- /**
54
- * Convert Entity to GraphQL Type
55
- */
56
- toWorkflowType(entity) {
57
- return {
58
- ...entity,
59
- steps: JSON.parse(entity.steps)
60
- };
61
- }
62
- toExecutionType(entity) {
63
- return entity;
64
- }
65
- /**
66
- * Create a new labeling workflow
67
- */
68
- async createLabelingWorkflow(input, context) {
69
- console.log(`[Workflow] Creating workflow: ${input.name}`);
70
- const workflowRepo = (0, shell_1.getRepository)(labeling_workflow_js_1.LabelingWorkflow, context.state.tx);
71
- const workflow = workflowRepo.create({
72
- domain: context.state.domain,
73
- creator: context.state.user,
74
- name: input.name,
75
- description: input.description,
76
- projectId: input.projectId,
77
- triggerType: input.triggerType,
78
- triggerConfig: input.triggerConfig,
79
- steps: JSON.stringify(input.steps.map((step, index) => ({
80
- name: step.name,
81
- type: step.type,
82
- config: step.config,
83
- condition: step.condition,
84
- continueOnError: step.continueOnError !== undefined ? step.continueOnError : true,
85
- maxRetries: step.maxRetries,
86
- order: index + 1
87
- }))),
88
- status: input.autoStart ? workflow_types_js_1.WorkflowStatus.Active : workflow_types_js_1.WorkflowStatus.Draft
89
- });
90
- await workflowRepo.save(workflow);
91
- console.log(`[Workflow] Created workflow ${workflow.id} with ${input.steps.length} steps`);
92
- return this.toWorkflowType(workflow);
93
- }
94
- /**
95
- * Execute a workflow
96
- */
97
- async executeLabelingWorkflow(input, context) {
98
- const workflowRepo = (0, typeorm_1.getRepository)(labeling_workflow_js_1.LabelingWorkflow);
99
- const workflow = await workflowRepo.findOne({
100
- where: { id: input.workflowId, domain: context.state.domain, deletedAt: (0, typeorm_1.IsNull)() }
101
- });
102
- if (!workflow) {
103
- throw new Error(`Workflow not found: ${input.workflowId}`);
104
- }
105
- console.log(`[Workflow] Executing workflow: ${workflow.name} (${workflow.id})`);
106
- const steps = JSON.parse(workflow.steps);
107
- const executionRepo = (0, typeorm_1.getRepository)(workflow_execution_js_1.WorkflowExecution);
108
- const execution = executionRepo.create({
109
- domain: context.state.domain,
110
- workflow,
111
- workflowId: workflow.id,
112
- workflowName: workflow.name,
113
- status: 'running',
114
- startedAt: new Date()
115
- });
116
- await executionRepo.save(execution);
117
- // Create execution steps
118
- const stepRepo = (0, typeorm_1.getRepository)(workflow_execution_step_js_1.WorkflowExecutionStep);
119
- await Promise.all(steps.map((step, index) => stepRepo.save(stepRepo.create({
120
- domain: context.state.domain,
121
- execution,
122
- executionId: execution.id,
123
- stepName: step.name,
124
- stepType: step.type,
125
- order: index + 1,
126
- status: 'pending'
127
- }))));
128
- // Execute asynchronously
129
- this.executeWorkflowAsync(execution.id, workflow.id, steps, context, input.parameters).catch(error => {
130
- console.error(`[Workflow] Execution failed:`, error);
131
- });
132
- return {
133
- executionId: execution.id,
134
- status: 'running',
135
- summary: `Started execution of ${steps.length} steps`
136
- };
137
- }
138
- /**
139
- * Get workflow details
140
- */
141
- async labelingWorkflow(workflowId, context) {
142
- const workflowRepo = (0, typeorm_1.getRepository)(labeling_workflow_js_1.LabelingWorkflow);
143
- const workflow = await workflowRepo.findOne({
144
- where: { id: workflowId, domain: context.state.domain, deletedAt: (0, typeorm_1.IsNull)() }
145
- });
146
- if (!workflow) {
147
- throw new Error(`Workflow not found: ${workflowId}`);
148
- }
149
- return this.toWorkflowType(workflow);
150
- }
151
- /**
152
- * List all workflows
153
- */
154
- async labelingWorkflows(projectId, context) {
155
- const workflowRepo = (0, typeorm_1.getRepository)(labeling_workflow_js_1.LabelingWorkflow);
156
- const queryBuilder = workflowRepo
157
- .createQueryBuilder('workflow')
158
- .where('workflow.domain = :domain', { domain: context.state.domain.id })
159
- .andWhere('workflow.deletedAt IS NULL');
160
- if (projectId) {
161
- queryBuilder.andWhere('workflow.projectId = :projectId', { projectId });
162
- }
163
- const [entities, total] = await queryBuilder.orderBy('workflow.createdAt', 'DESC').getManyAndCount();
164
- const items = entities.map(e => this.toWorkflowType(e));
165
- return { items, total };
166
- }
167
- /**
168
- * Get execution status
169
- */
170
- async workflowExecution(executionId, context) {
171
- const executionRepo = (0, typeorm_1.getRepository)(workflow_execution_js_1.WorkflowExecution);
172
- const execution = await executionRepo.findOne({
173
- where: { id: executionId, domain: context.state.domain, deletedAt: (0, typeorm_1.IsNull)() },
174
- relations: ['steps']
175
- });
176
- if (!execution) {
177
- throw new Error(`Execution not found: ${executionId}`);
178
- }
179
- return this.toExecutionType(execution);
180
- }
181
- /**
182
- * List executions for a workflow
183
- */
184
- async workflowExecutions(workflowId, context) {
185
- const executionRepo = (0, typeorm_1.getRepository)(workflow_execution_js_1.WorkflowExecution);
186
- const [entities, total] = await executionRepo.findAndCount({
187
- where: { workflowId, domain: context.state.domain, deletedAt: (0, typeorm_1.IsNull)() },
188
- order: { startedAt: 'DESC' }
189
- });
190
- const items = entities.map(e => this.toExecutionType(e));
191
- return { items, total };
192
- }
193
- /**
194
- * Pause a workflow
195
- */
196
- async pauseLabelingWorkflow(workflowId, context) {
197
- const workflowRepo = (0, shell_1.getRepository)(labeling_workflow_js_1.LabelingWorkflow, context.state.tx);
198
- const workflow = await workflowRepo.findOne({
199
- where: { id: workflowId, domain: context.state.domain, deletedAt: (0, typeorm_1.IsNull)() }
200
- });
201
- if (!workflow) {
202
- throw new Error(`Workflow not found: ${workflowId}`);
203
- }
204
- workflow.status = workflow_types_js_1.WorkflowStatus.Paused;
205
- await workflowRepo.save(workflow);
206
- console.log(`[Workflow] Paused workflow: ${workflow.name}`);
207
- return this.toWorkflowType(workflow);
208
- }
209
- /**
210
- * Resume a workflow
211
- */
212
- async resumeLabelingWorkflow(workflowId, context) {
213
- const workflowRepo = (0, shell_1.getRepository)(labeling_workflow_js_1.LabelingWorkflow, context.state.tx);
214
- const workflow = await workflowRepo.findOne({
215
- where: { id: workflowId, domain: context.state.domain, deletedAt: (0, typeorm_1.IsNull)() }
216
- });
217
- if (!workflow) {
218
- throw new Error(`Workflow not found: ${workflowId}`);
219
- }
220
- workflow.status = workflow_types_js_1.WorkflowStatus.Active;
221
- await workflowRepo.save(workflow);
222
- console.log(`[Workflow] Resumed workflow: ${workflow.name}`);
223
- return this.toWorkflowType(workflow);
224
- }
225
- // ============================================================================
226
- // Private Methods - Workflow Execution Engine
227
- // ============================================================================
228
- async executeWorkflowAsync(executionId, workflowId, steps, context, parametersJson) {
229
- const startTime = Date.now();
230
- const parameters = parametersJson ? JSON.parse(parametersJson) : {};
231
- console.log(`[Workflow] Starting execution ${executionId}`);
232
- const executionRepo = (0, typeorm_1.getRepository)(workflow_execution_js_1.WorkflowExecution);
233
- const stepRepo = (0, typeorm_1.getRepository)(workflow_execution_step_js_1.WorkflowExecutionStep);
234
- const workflowRepo = (0, typeorm_1.getRepository)(labeling_workflow_js_1.LabelingWorkflow);
235
- const execution = await executionRepo.findOne({
236
- where: { id: executionId },
237
- relations: ['steps', 'workflow']
238
- });
239
- if (!execution) {
240
- throw new Error(`Execution not found: ${executionId}`);
241
- }
242
- try {
243
- for (const [index, workflowStep] of steps.entries()) {
244
- const executionStep = execution.steps[index];
245
- executionStep.status = 'running';
246
- executionStep.startedAt = new Date();
247
- await stepRepo.save(executionStep);
248
- console.log(`[Workflow] Executing step ${index + 1}/${steps.length}: ${workflowStep.name}`);
249
- try {
250
- // Check condition if specified
251
- if (workflowStep.condition) {
252
- const conditionMet = this.evaluateCondition(workflowStep.condition, parameters);
253
- if (!conditionMet) {
254
- console.log(`[Workflow] Step ${workflowStep.name} condition not met, skipping`);
255
- executionStep.status = 'skipped';
256
- executionStep.completedAt = new Date();
257
- await stepRepo.save(executionStep);
258
- continue;
259
- }
260
- }
261
- // Execute step
262
- const stepConfig = JSON.parse(workflowStep.config);
263
- const stepResult = await this.executeStep(workflowStep.type, stepConfig, execution.workflow.projectId, context, parameters);
264
- executionStep.status = 'completed';
265
- executionStep.output = JSON.stringify(stepResult);
266
- executionStep.completedAt = new Date();
267
- executionStep.durationMs = executionStep.completedAt.getTime() - executionStep.startedAt.getTime();
268
- await stepRepo.save(executionStep);
269
- console.log(`[Workflow] Step ${workflowStep.name} completed in ${executionStep.durationMs}ms`);
270
- // Store step result in parameters for next steps
271
- parameters[`step_${index}_result`] = stepResult;
272
- }
273
- catch (stepError) {
274
- console.error(`[Workflow] Step ${workflowStep.name} failed:`, stepError);
275
- executionStep.status = 'failed';
276
- executionStep.error = stepError.message;
277
- executionStep.completedAt = new Date();
278
- executionStep.durationMs = executionStep.completedAt.getTime() - executionStep.startedAt.getTime();
279
- await stepRepo.save(executionStep);
280
- // Check if we should continue on error
281
- if (!workflowStep.continueOnError) {
282
- throw new Error(`Step ${workflowStep.name} failed: ${stepError.message}`);
283
- }
284
- console.log(`[Workflow] Continuing despite error (continueOnError=true)`);
285
- }
286
- }
287
- // All steps completed
288
- execution.status = 'completed';
289
- execution.summary = this.generateExecutionSummary(execution.steps);
290
- execution.completedAt = new Date();
291
- execution.totalDurationMs = Date.now() - startTime;
292
- await executionRepo.save(execution);
293
- console.log(`[Workflow] Execution completed in ${execution.totalDurationMs}ms`);
294
- // Update workflow status
295
- const workflow = await workflowRepo.findOne({ where: { id: workflowId } });
296
- if (workflow) {
297
- workflow.lastExecutedAt = new Date();
298
- if (workflow.triggerType === workflow_types_js_1.TriggerType.Schedule) {
299
- // Calculate next execution time (simplified, needs proper cron parser)
300
- // workflow.nextExecutionAt = ...
301
- }
302
- await workflowRepo.save(workflow);
303
- }
304
- }
305
- catch (error) {
306
- console.error(`[Workflow] Execution failed:`, error);
307
- execution.status = 'failed';
308
- execution.error = error.message;
309
- execution.summary = `Failed: ${error.message}`;
310
- execution.completedAt = new Date();
311
- execution.totalDurationMs = Date.now() - startTime;
312
- await executionRepo.save(execution);
313
- }
314
- }
315
- async executeStep(stepType, config, projectId, context, parameters) {
316
- switch (stepType) {
317
- case workflow_types_js_1.WorkflowStepType.ImportData:
318
- return await this.executeImportDataStep(config, projectId, context, parameters);
319
- case workflow_types_js_1.WorkflowStepType.GeneratePredictions:
320
- return await this.executeGeneratePredictionsStep(config, projectId, context, parameters);
321
- case workflow_types_js_1.WorkflowStepType.WaitForAnnotations:
322
- return await this.executeWaitForAnnotationsStep(config, projectId, context);
323
- case workflow_types_js_1.WorkflowStepType.SyncAnnotations:
324
- return await this.executeSyncAnnotationsStep(config, projectId, context, parameters);
325
- case workflow_types_js_1.WorkflowStepType.ValidateQuality:
326
- return await this.executeValidateQualityStep(config, projectId, context, parameters);
327
- case workflow_types_js_1.WorkflowStepType.Notification:
328
- return await this.executeNotificationStep(config, parameters);
329
- default:
330
- throw new Error(`Unknown step type: ${stepType}`);
331
- }
332
- }
333
- async executeImportDataStep(config, projectId, context, parameters) {
334
- if (config.sourceType === 'dataset') {
335
- return await this.getDatasetIntegration().createLabelingTasksFromDataset({
336
- projectId,
337
- dataSetId: config.dataSetId,
338
- imageField: config.imageField,
339
- autoGeneratePredictions: config.autoGeneratePredictions || false,
340
- limit: config.limit
341
- }, context);
342
- }
343
- else {
344
- return await this.getExternalDataSource().importFromExternalSource({
345
- projectId,
346
- source: {
347
- sourceType: config.sourceType,
348
- sourceUrl: config.sourceUrl,
349
- authHeader: config.authHeader,
350
- dataPath: config.dataPath
351
- },
352
- imageField: config.imageField,
353
- limit: config.limit
354
- }, context);
355
- }
356
- }
357
- async executeGeneratePredictionsStep(config, projectId, context, parameters) {
358
- const dataSetId = parameters.dataSetId || config.dataSetId;
359
- if (!dataSetId) {
360
- throw new Error('dataSetId required for GeneratePredictions step');
361
- }
362
- return await this.getDatasetIntegration().generatePredictionsForDataset({
363
- dataSetId,
364
- projectId,
365
- modelId: config.modelId,
366
- confidenceThreshold: config.confidenceThreshold,
367
- forceRegenerate: config.forceRegenerate || false
368
- }, context);
369
- }
370
- async executeWaitForAnnotationsStep(config, projectId, context) {
371
- // This is a simplified implementation
372
- // In production, this should poll or use webhooks
373
- console.log(`[Workflow] WaitForAnnotations step - checking criteria`);
374
- // TODO: Implement actual waiting/polling logic
375
- return {
376
- status: 'waiting',
377
- message: 'WaitForAnnotations step - manual check required'
378
- };
379
- }
380
- async executeSyncAnnotationsStep(config, projectId, context, parameters) {
381
- const dataSetId = parameters.dataSetId || config.dataSetId;
382
- if (!dataSetId) {
383
- throw new Error('dataSetId required for SyncAnnotations step');
384
- }
385
- return await this.getDatasetIntegration().syncAnnotationsToDataset({
386
- projectId,
387
- dataSetId,
388
- completedOnly: config.completedOnly !== false,
389
- sinceDate: config.sinceDate
390
- }, context);
391
- }
392
- async executeValidateQualityStep(config, projectId, context, parameters) {
393
- console.log(`[Workflow] ValidateQuality step`);
394
- // TODO: Implement quality validation logic
395
- return {
396
- status: 'validated',
397
- message: 'Quality validation - not yet implemented'
398
- };
399
- }
400
- async executeNotificationStep(config, parameters) {
401
- console.log(`[Workflow] Notification step: ${config.message}`);
402
- // TODO: Implement actual notification (email, webhook, etc.)
403
- return {
404
- status: 'sent',
405
- message: config.message,
406
- recipients: config.recipients
407
- };
408
- }
409
- evaluateCondition(condition, parameters) {
410
- // Simple condition evaluation
411
- // In production, use a proper expression evaluator
412
- try {
413
- const conditionObj = JSON.parse(condition);
414
- // Example: { "step_0_result.tasksCreated": { "$gt": 0 } }
415
- // For now, always return true
416
- return true;
417
- }
418
- catch (error) {
419
- console.warn(`[Workflow] Failed to evaluate condition: ${condition}`);
420
- return true;
421
- }
422
- }
423
- generateExecutionSummary(steps) {
424
- const completed = steps.filter(s => s.status === 'completed').length;
425
- const failed = steps.filter(s => s.status === 'failed').length;
426
- const skipped = steps.filter(s => s.status === 'skipped').length;
427
- return `Completed ${completed}/${steps.length} steps (${failed} failed, ${skipped} skipped)`;
428
- }
429
- };
430
- exports.LabelingWorkflowService = LabelingWorkflowService;
431
- tslib_1.__decorate([
432
- (0, type_graphql_1.Directive)('@transaction'),
433
- (0, type_graphql_1.Mutation)(returns => workflow_types_js_1.LabelingWorkflow, {
434
- description: 'Create a new labeling workflow'
435
- }),
436
- (0, type_graphql_1.Directive)('@privilege(category: "labeling", privilege: "mutation")'),
437
- tslib_1.__param(0, (0, type_graphql_1.Arg)('input')),
438
- tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
439
- tslib_1.__metadata("design:type", Function),
440
- tslib_1.__metadata("design:paramtypes", [workflow_types_js_1.CreateWorkflowRequest, Object]),
441
- tslib_1.__metadata("design:returntype", Promise)
442
- ], LabelingWorkflowService.prototype, "createLabelingWorkflow", null);
443
- tslib_1.__decorate([
444
- (0, type_graphql_1.Mutation)(returns => workflow_types_js_1.WorkflowExecutionResult, {
445
- description: 'Execute a labeling workflow'
446
- })
447
- /*
448
- * No `@transaction`: the steps run after this request has answered (`executeWorkflowAsync`) and reach Label
449
- * Studio and the model server. A request transaction would end before them; on SQLite it would hold the one
450
- * shared connection while they write.
451
- */
452
- ,
453
- (0, type_graphql_1.Directive)('@privilege(category: "labeling", privilege: "mutation")'),
454
- tslib_1.__param(0, (0, type_graphql_1.Arg)('input')),
455
- tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
456
- tslib_1.__metadata("design:type", Function),
457
- tslib_1.__metadata("design:paramtypes", [workflow_types_js_1.ExecuteWorkflowRequest, Object]),
458
- tslib_1.__metadata("design:returntype", Promise)
459
- ], LabelingWorkflowService.prototype, "executeLabelingWorkflow", null);
460
- tslib_1.__decorate([
461
- (0, type_graphql_1.Query)(returns => workflow_types_js_1.LabelingWorkflow, {
462
- description: 'Get labeling workflow details'
463
- }),
464
- (0, type_graphql_1.Directive)('@privilege(category: "labeling", privilege: "query")'),
465
- tslib_1.__param(0, (0, type_graphql_1.Arg)('workflowId')),
466
- tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
467
- tslib_1.__metadata("design:type", Function),
468
- tslib_1.__metadata("design:paramtypes", [String, Object]),
469
- tslib_1.__metadata("design:returntype", Promise)
470
- ], LabelingWorkflowService.prototype, "labelingWorkflow", null);
471
- tslib_1.__decorate([
472
- (0, type_graphql_1.Query)(returns => workflow_types_js_1.LabelingWorkflowList, {
473
- description: 'List all labeling workflows'
474
- }),
475
- (0, type_graphql_1.Directive)('@privilege(category: "labeling", privilege: "query")'),
476
- tslib_1.__param(0, (0, type_graphql_1.Arg)('projectId', type => type_graphql_1.Int, { nullable: true })),
477
- tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
478
- tslib_1.__metadata("design:type", Function),
479
- tslib_1.__metadata("design:paramtypes", [Number, Object]),
480
- tslib_1.__metadata("design:returntype", Promise)
481
- ], LabelingWorkflowService.prototype, "labelingWorkflows", null);
482
- tslib_1.__decorate([
483
- (0, type_graphql_1.Query)(returns => workflow_types_js_1.WorkflowExecution, {
484
- description: 'Get workflow execution status'
485
- }),
486
- (0, type_graphql_1.Directive)('@privilege(category: "labeling", privilege: "query")'),
487
- tslib_1.__param(0, (0, type_graphql_1.Arg)('executionId')),
488
- tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
489
- tslib_1.__metadata("design:type", Function),
490
- tslib_1.__metadata("design:paramtypes", [String, Object]),
491
- tslib_1.__metadata("design:returntype", Promise)
492
- ], LabelingWorkflowService.prototype, "workflowExecution", null);
493
- tslib_1.__decorate([
494
- (0, type_graphql_1.Query)(returns => workflow_types_js_1.WorkflowExecutionList, {
495
- description: 'List executions for a workflow'
496
- }),
497
- (0, type_graphql_1.Directive)('@privilege(category: "labeling", privilege: "query")'),
498
- tslib_1.__param(0, (0, type_graphql_1.Arg)('workflowId')),
499
- tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
500
- tslib_1.__metadata("design:type", Function),
501
- tslib_1.__metadata("design:paramtypes", [String, Object]),
502
- tslib_1.__metadata("design:returntype", Promise)
503
- ], LabelingWorkflowService.prototype, "workflowExecutions", null);
504
- tslib_1.__decorate([
505
- (0, type_graphql_1.Directive)('@transaction'),
506
- (0, type_graphql_1.Mutation)(returns => workflow_types_js_1.LabelingWorkflow, {
507
- description: 'Pause a workflow'
508
- }),
509
- (0, type_graphql_1.Directive)('@privilege(category: "labeling", privilege: "mutation")'),
510
- tslib_1.__param(0, (0, type_graphql_1.Arg)('workflowId')),
511
- tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
512
- tslib_1.__metadata("design:type", Function),
513
- tslib_1.__metadata("design:paramtypes", [String, Object]),
514
- tslib_1.__metadata("design:returntype", Promise)
515
- ], LabelingWorkflowService.prototype, "pauseLabelingWorkflow", null);
516
- tslib_1.__decorate([
517
- (0, type_graphql_1.Directive)('@transaction'),
518
- (0, type_graphql_1.Mutation)(returns => workflow_types_js_1.LabelingWorkflow, {
519
- description: 'Resume a paused workflow'
520
- }),
521
- (0, type_graphql_1.Directive)('@privilege(category: "labeling", privilege: "mutation")'),
522
- tslib_1.__param(0, (0, type_graphql_1.Arg)('workflowId')),
523
- tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
524
- tslib_1.__metadata("design:type", Function),
525
- tslib_1.__metadata("design:paramtypes", [String, Object]),
526
- tslib_1.__metadata("design:returntype", Promise)
527
- ], LabelingWorkflowService.prototype, "resumeLabelingWorkflow", null);
528
- exports.LabelingWorkflowService = LabelingWorkflowService = tslib_1.__decorate([
529
- (0, type_graphql_1.Resolver)()
530
- ], LabelingWorkflowService);
531
- //# sourceMappingURL=labeling-workflow-service.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"labeling-workflow-service.js","sourceRoot":"","sources":["../../server/service/labeling-workflow-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Resolver, Query, Mutation, Arg, Ctx, Int, Directive } from 'type-graphql'\nimport { getRepository, IsNull } from 'typeorm'\n\nimport { getRepository as getRequestRepository } from '@things-factory/shell'\nimport {\n CreateWorkflowRequest,\n ExecuteWorkflowRequest,\n WorkflowExecutionResult,\n LabelingWorkflow as LabelingWorkflowType,\n WorkflowExecution as WorkflowExecutionType,\n LabelingWorkflowList,\n WorkflowExecutionList,\n WorkflowStatus,\n WorkflowStepType,\n TriggerType,\n WorkflowStep\n} from '../types/workflow-types.js'\nimport { LabelingWorkflow as LabelingWorkflowEntity } from './labeling-workflow.js'\nimport { WorkflowExecution as WorkflowExecutionEntity } from './workflow-execution.js'\nimport { WorkflowExecutionStep as WorkflowExecutionStepEntity } from './workflow-execution-step.js'\nimport { DatasetLabelingIntegration } from '@things-factory/integration-label-studio/dist-server/service/dataset-labeling-integration.js'\nimport { ExternalDataSourceService } from '@things-factory/integration-label-studio/dist-server/service/external-data-source-service.js'\nimport { LabelStudioAIPredictionService } from '@things-factory/integration-label-studio/dist-server/service/ai-prediction-service.js'\n\n/**\n * Labeling Workflow Service\n *\n * Orchestrates end-to-end labeling workflows with multiple steps\n *\n * Features:\n * - Define multi-step labeling workflows\n * - Auto-execute workflows based on triggers\n * - Track execution progress\n * - Error handling and retry logic\n * - Conditional execution\n * - Database persistence with TypeORM\n */\n@Resolver()\nexport class LabelingWorkflowService {\n // Service dependencies (lazy initialization)\n private datasetIntegration: DatasetLabelingIntegration | null = null\n private externalDataSource: ExternalDataSourceService | null = null\n private aiPredictionService: LabelStudioAIPredictionService | null = null\n\n private getDatasetIntegration(): DatasetLabelingIntegration {\n if (!this.datasetIntegration) {\n this.datasetIntegration = new DatasetLabelingIntegration()\n }\n return this.datasetIntegration\n }\n\n private getExternalDataSource(): ExternalDataSourceService {\n if (!this.externalDataSource) {\n this.externalDataSource = new ExternalDataSourceService()\n }\n return this.externalDataSource\n }\n\n private getAIPredictionService(): LabelStudioAIPredictionService {\n if (!this.aiPredictionService) {\n this.aiPredictionService = new LabelStudioAIPredictionService()\n }\n return this.aiPredictionService\n }\n\n /**\n * Convert Entity to GraphQL Type\n */\n private toWorkflowType(entity: LabelingWorkflowEntity): LabelingWorkflowType {\n return {\n ...entity,\n steps: JSON.parse(entity.steps)\n } as LabelingWorkflowType\n }\n\n private toExecutionType(entity: WorkflowExecutionEntity): WorkflowExecutionType {\n return entity as any as WorkflowExecutionType\n }\n\n /**\n * Create a new labeling workflow\n */\n @Directive('@transaction')\n @Mutation(returns => LabelingWorkflowType, {\n description: 'Create a new labeling workflow'\n })\n @Directive('@privilege(category: \"labeling\", privilege: \"mutation\")')\n async createLabelingWorkflow(\n @Arg('input') input: CreateWorkflowRequest,\n @Ctx() context: ResolverContext\n ): Promise<LabelingWorkflowType> {\n console.log(`[Workflow] Creating workflow: ${input.name}`)\n\n const workflowRepo = getRequestRepository(LabelingWorkflowEntity, context.state.tx)\n\n const workflow = workflowRepo.create({\n domain: context.state.domain,\n creator: context.state.user,\n name: input.name,\n description: input.description,\n projectId: input.projectId,\n triggerType: input.triggerType,\n triggerConfig: input.triggerConfig,\n steps: JSON.stringify(\n input.steps.map((step, index) => ({\n name: step.name,\n type: step.type,\n config: step.config,\n condition: step.condition,\n continueOnError: step.continueOnError !== undefined ? step.continueOnError : true,\n maxRetries: step.maxRetries,\n order: index + 1\n }))\n ),\n status: input.autoStart ? WorkflowStatus.Active : WorkflowStatus.Draft\n })\n\n await workflowRepo.save(workflow)\n\n console.log(`[Workflow] Created workflow ${workflow.id} with ${input.steps.length} steps`)\n\n return this.toWorkflowType(workflow)\n }\n\n /**\n * Execute a workflow\n */\n @Mutation(returns => WorkflowExecutionResult, {\n description: 'Execute a labeling workflow'\n })\n /*\n * No `@transaction`: the steps run after this request has answered (`executeWorkflowAsync`) and reach Label\n * Studio and the model server. A request transaction would end before them; on SQLite it would hold the one\n * shared connection while they write.\n */\n @Directive('@privilege(category: \"labeling\", privilege: \"mutation\")')\n async executeLabelingWorkflow(\n @Arg('input') input: ExecuteWorkflowRequest,\n @Ctx() context: ResolverContext\n ): Promise<WorkflowExecutionResult> {\n const workflowRepo = getRepository(LabelingWorkflowEntity)\n const workflow = await workflowRepo.findOne({\n where: { id: input.workflowId, domain: context.state.domain, deletedAt: IsNull() }\n })\n\n if (!workflow) {\n throw new Error(`Workflow not found: ${input.workflowId}`)\n }\n\n console.log(`[Workflow] Executing workflow: ${workflow.name} (${workflow.id})`)\n\n const steps = JSON.parse(workflow.steps) as WorkflowStep[]\n\n const executionRepo = getRepository(WorkflowExecutionEntity)\n const execution = executionRepo.create({\n domain: context.state.domain,\n workflow,\n workflowId: workflow.id,\n workflowName: workflow.name,\n status: 'running',\n startedAt: new Date()\n })\n\n await executionRepo.save(execution)\n\n // Create execution steps\n const stepRepo = getRepository(WorkflowExecutionStepEntity)\n await Promise.all(\n steps.map((step, index) =>\n stepRepo.save(\n stepRepo.create({\n domain: context.state.domain,\n execution,\n executionId: execution.id,\n stepName: step.name,\n stepType: step.type,\n order: index + 1,\n status: 'pending'\n })\n )\n )\n )\n\n // Execute asynchronously\n this.executeWorkflowAsync(execution.id, workflow.id, steps, context, input.parameters).catch(error => {\n console.error(`[Workflow] Execution failed:`, error)\n })\n\n return {\n executionId: execution.id,\n status: 'running',\n summary: `Started execution of ${steps.length} steps`\n }\n }\n\n /**\n * Get workflow details\n */\n @Query(returns => LabelingWorkflowType, {\n description: 'Get labeling workflow details'\n })\n @Directive('@privilege(category: \"labeling\", privilege: \"query\")')\n async labelingWorkflow(\n @Arg('workflowId') workflowId: string,\n @Ctx() context: ResolverContext\n ): Promise<LabelingWorkflowType> {\n const workflowRepo = getRepository(LabelingWorkflowEntity)\n const workflow = await workflowRepo.findOne({\n where: { id: workflowId, domain: context.state.domain, deletedAt: IsNull() }\n })\n\n if (!workflow) {\n throw new Error(`Workflow not found: ${workflowId}`)\n }\n\n return this.toWorkflowType(workflow)\n }\n\n /**\n * List all workflows\n */\n @Query(returns => LabelingWorkflowList, {\n description: 'List all labeling workflows'\n })\n @Directive('@privilege(category: \"labeling\", privilege: \"query\")')\n async labelingWorkflows(\n @Arg('projectId', type => Int, { nullable: true }) projectId: number,\n @Ctx() context: ResolverContext\n ): Promise<LabelingWorkflowList> {\n const workflowRepo = getRepository(LabelingWorkflowEntity)\n const queryBuilder = workflowRepo\n .createQueryBuilder('workflow')\n .where('workflow.domain = :domain', { domain: context.state.domain.id })\n .andWhere('workflow.deletedAt IS NULL')\n\n if (projectId) {\n queryBuilder.andWhere('workflow.projectId = :projectId', { projectId })\n }\n\n const [entities, total] = await queryBuilder.orderBy('workflow.createdAt', 'DESC').getManyAndCount()\n const items = entities.map(e => this.toWorkflowType(e))\n\n return { items, total }\n }\n\n /**\n * Get execution status\n */\n @Query(returns => WorkflowExecutionType, {\n description: 'Get workflow execution status'\n })\n @Directive('@privilege(category: \"labeling\", privilege: \"query\")')\n async workflowExecution(\n @Arg('executionId') executionId: string,\n @Ctx() context: ResolverContext\n ): Promise<WorkflowExecutionType> {\n const executionRepo = getRepository(WorkflowExecutionEntity)\n const execution = await executionRepo.findOne({\n where: { id: executionId, domain: context.state.domain, deletedAt: IsNull() },\n relations: ['steps']\n })\n\n if (!execution) {\n throw new Error(`Execution not found: ${executionId}`)\n }\n\n return this.toExecutionType(execution)\n }\n\n /**\n * List executions for a workflow\n */\n @Query(returns => WorkflowExecutionList, {\n description: 'List executions for a workflow'\n })\n @Directive('@privilege(category: \"labeling\", privilege: \"query\")')\n async workflowExecutions(\n @Arg('workflowId') workflowId: string,\n @Ctx() context: ResolverContext\n ): Promise<WorkflowExecutionList> {\n const executionRepo = getRepository(WorkflowExecutionEntity)\n const [entities, total] = await executionRepo.findAndCount({\n where: { workflowId, domain: context.state.domain, deletedAt: IsNull() },\n order: { startedAt: 'DESC' }\n })\n\n const items = entities.map(e => this.toExecutionType(e))\n return { items, total }\n }\n\n /**\n * Pause a workflow\n */\n @Directive('@transaction')\n @Mutation(returns => LabelingWorkflowType, {\n description: 'Pause a workflow'\n })\n @Directive('@privilege(category: \"labeling\", privilege: \"mutation\")')\n async pauseLabelingWorkflow(\n @Arg('workflowId') workflowId: string,\n @Ctx() context: ResolverContext\n ): Promise<LabelingWorkflowType> {\n const workflowRepo = getRequestRepository(LabelingWorkflowEntity, context.state.tx)\n const workflow = await workflowRepo.findOne({\n where: { id: workflowId, domain: context.state.domain, deletedAt: IsNull() }\n })\n\n if (!workflow) {\n throw new Error(`Workflow not found: ${workflowId}`)\n }\n\n workflow.status = WorkflowStatus.Paused\n await workflowRepo.save(workflow)\n\n console.log(`[Workflow] Paused workflow: ${workflow.name}`)\n\n return this.toWorkflowType(workflow)\n }\n\n /**\n * Resume a workflow\n */\n @Directive('@transaction')\n @Mutation(returns => LabelingWorkflowType, {\n description: 'Resume a paused workflow'\n })\n @Directive('@privilege(category: \"labeling\", privilege: \"mutation\")')\n async resumeLabelingWorkflow(\n @Arg('workflowId') workflowId: string,\n @Ctx() context: ResolverContext\n ): Promise<LabelingWorkflowType> {\n const workflowRepo = getRequestRepository(LabelingWorkflowEntity, context.state.tx)\n const workflow = await workflowRepo.findOne({\n where: { id: workflowId, domain: context.state.domain, deletedAt: IsNull() }\n })\n\n if (!workflow) {\n throw new Error(`Workflow not found: ${workflowId}`)\n }\n\n workflow.status = WorkflowStatus.Active\n await workflowRepo.save(workflow)\n\n console.log(`[Workflow] Resumed workflow: ${workflow.name}`)\n\n return this.toWorkflowType(workflow)\n }\n\n // ============================================================================\n // Private Methods - Workflow Execution Engine\n // ============================================================================\n\n private async executeWorkflowAsync(\n executionId: string,\n workflowId: string,\n steps: WorkflowStep[],\n context: ResolverContext,\n parametersJson?: string\n ): Promise<void> {\n const startTime = Date.now()\n const parameters = parametersJson ? JSON.parse(parametersJson) : {}\n\n console.log(`[Workflow] Starting execution ${executionId}`)\n\n const executionRepo = getRepository(WorkflowExecutionEntity)\n const stepRepo = getRepository(WorkflowExecutionStepEntity)\n const workflowRepo = getRepository(LabelingWorkflowEntity)\n\n const execution = await executionRepo.findOne({\n where: { id: executionId },\n relations: ['steps', 'workflow']\n })\n\n if (!execution) {\n throw new Error(`Execution not found: ${executionId}`)\n }\n\n try {\n for (const [index, workflowStep] of steps.entries()) {\n const executionStep = execution.steps[index]\n executionStep.status = 'running'\n executionStep.startedAt = new Date()\n await stepRepo.save(executionStep)\n\n console.log(`[Workflow] Executing step ${index + 1}/${steps.length}: ${workflowStep.name}`)\n\n try {\n // Check condition if specified\n if (workflowStep.condition) {\n const conditionMet = this.evaluateCondition(workflowStep.condition, parameters)\n if (!conditionMet) {\n console.log(`[Workflow] Step ${workflowStep.name} condition not met, skipping`)\n executionStep.status = 'skipped'\n executionStep.completedAt = new Date()\n await stepRepo.save(executionStep)\n continue\n }\n }\n\n // Execute step\n const stepConfig = JSON.parse(workflowStep.config)\n const stepResult = await this.executeStep(\n workflowStep.type,\n stepConfig,\n execution.workflow.projectId,\n context,\n parameters\n )\n\n executionStep.status = 'completed'\n executionStep.output = JSON.stringify(stepResult)\n executionStep.completedAt = new Date()\n executionStep.durationMs = executionStep.completedAt.getTime() - executionStep.startedAt.getTime()\n await stepRepo.save(executionStep)\n\n console.log(`[Workflow] Step ${workflowStep.name} completed in ${executionStep.durationMs}ms`)\n\n // Store step result in parameters for next steps\n parameters[`step_${index}_result`] = stepResult\n } catch (stepError) {\n console.error(`[Workflow] Step ${workflowStep.name} failed:`, stepError)\n\n executionStep.status = 'failed'\n executionStep.error = stepError.message\n executionStep.completedAt = new Date()\n executionStep.durationMs = executionStep.completedAt.getTime() - executionStep.startedAt.getTime()\n await stepRepo.save(executionStep)\n\n // Check if we should continue on error\n if (!workflowStep.continueOnError) {\n throw new Error(`Step ${workflowStep.name} failed: ${stepError.message}`)\n }\n\n console.log(`[Workflow] Continuing despite error (continueOnError=true)`)\n }\n }\n\n // All steps completed\n execution.status = 'completed'\n execution.summary = this.generateExecutionSummary(execution.steps)\n execution.completedAt = new Date()\n execution.totalDurationMs = Date.now() - startTime\n await executionRepo.save(execution)\n\n console.log(`[Workflow] Execution completed in ${execution.totalDurationMs}ms`)\n\n // Update workflow status\n const workflow = await workflowRepo.findOne({ where: { id: workflowId } })\n if (workflow) {\n workflow.lastExecutedAt = new Date()\n if (workflow.triggerType === TriggerType.Schedule) {\n // Calculate next execution time (simplified, needs proper cron parser)\n // workflow.nextExecutionAt = ...\n }\n await workflowRepo.save(workflow)\n }\n } catch (error) {\n console.error(`[Workflow] Execution failed:`, error)\n\n execution.status = 'failed'\n execution.error = error.message\n execution.summary = `Failed: ${error.message}`\n execution.completedAt = new Date()\n execution.totalDurationMs = Date.now() - startTime\n await executionRepo.save(execution)\n }\n }\n\n private async executeStep(\n stepType: WorkflowStepType,\n config: any,\n projectId: number,\n context: ResolverContext,\n parameters: any\n ): Promise<any> {\n switch (stepType) {\n case WorkflowStepType.ImportData:\n return await this.executeImportDataStep(config, projectId, context, parameters)\n\n case WorkflowStepType.GeneratePredictions:\n return await this.executeGeneratePredictionsStep(config, projectId, context, parameters)\n\n case WorkflowStepType.WaitForAnnotations:\n return await this.executeWaitForAnnotationsStep(config, projectId, context)\n\n case WorkflowStepType.SyncAnnotations:\n return await this.executeSyncAnnotationsStep(config, projectId, context, parameters)\n\n case WorkflowStepType.ValidateQuality:\n return await this.executeValidateQualityStep(config, projectId, context, parameters)\n\n case WorkflowStepType.Notification:\n return await this.executeNotificationStep(config, parameters)\n\n default:\n throw new Error(`Unknown step type: ${stepType}`)\n }\n }\n\n private async executeImportDataStep(\n config: any,\n projectId: number,\n context: ResolverContext,\n parameters: any\n ): Promise<any> {\n if (config.sourceType === 'dataset') {\n return await this.getDatasetIntegration().createLabelingTasksFromDataset(\n {\n projectId,\n dataSetId: config.dataSetId,\n imageField: config.imageField,\n autoGeneratePredictions: config.autoGeneratePredictions || false,\n limit: config.limit\n },\n context\n )\n } else {\n return await this.getExternalDataSource().importFromExternalSource(\n {\n projectId,\n source: {\n sourceType: config.sourceType,\n sourceUrl: config.sourceUrl,\n authHeader: config.authHeader,\n dataPath: config.dataPath\n },\n imageField: config.imageField,\n limit: config.limit\n },\n context\n )\n }\n }\n\n private async executeGeneratePredictionsStep(\n config: any,\n projectId: number,\n context: ResolverContext,\n parameters: any\n ): Promise<any> {\n const dataSetId = parameters.dataSetId || config.dataSetId\n\n if (!dataSetId) {\n throw new Error('dataSetId required for GeneratePredictions step')\n }\n\n return await this.getDatasetIntegration().generatePredictionsForDataset(\n {\n dataSetId,\n projectId,\n modelId: config.modelId,\n confidenceThreshold: config.confidenceThreshold,\n forceRegenerate: config.forceRegenerate || false\n },\n context\n )\n }\n\n private async executeWaitForAnnotationsStep(config: any, projectId: number, context: ResolverContext): Promise<any> {\n // This is a simplified implementation\n // In production, this should poll or use webhooks\n console.log(`[Workflow] WaitForAnnotations step - checking criteria`)\n\n // TODO: Implement actual waiting/polling logic\n return {\n status: 'waiting',\n message: 'WaitForAnnotations step - manual check required'\n }\n }\n\n private async executeSyncAnnotationsStep(\n config: any,\n projectId: number,\n context: ResolverContext,\n parameters: any\n ): Promise<any> {\n const dataSetId = parameters.dataSetId || config.dataSetId\n\n if (!dataSetId) {\n throw new Error('dataSetId required for SyncAnnotations step')\n }\n\n return await this.getDatasetIntegration().syncAnnotationsToDataset(\n {\n projectId,\n dataSetId,\n completedOnly: config.completedOnly !== false,\n sinceDate: config.sinceDate\n },\n context\n )\n }\n\n private async executeValidateQualityStep(\n config: any,\n projectId: number,\n context: ResolverContext,\n parameters: any\n ): Promise<any> {\n console.log(`[Workflow] ValidateQuality step`)\n\n // TODO: Implement quality validation logic\n return {\n status: 'validated',\n message: 'Quality validation - not yet implemented'\n }\n }\n\n private async executeNotificationStep(config: any, parameters: any): Promise<any> {\n console.log(`[Workflow] Notification step: ${config.message}`)\n\n // TODO: Implement actual notification (email, webhook, etc.)\n return {\n status: 'sent',\n message: config.message,\n recipients: config.recipients\n }\n }\n\n private evaluateCondition(condition: string, parameters: any): boolean {\n // Simple condition evaluation\n // In production, use a proper expression evaluator\n try {\n const conditionObj = JSON.parse(condition)\n // Example: { \"step_0_result.tasksCreated\": { \"$gt\": 0 } }\n // For now, always return true\n return true\n } catch (error) {\n console.warn(`[Workflow] Failed to evaluate condition: ${condition}`)\n return true\n }\n }\n\n private generateExecutionSummary(steps: WorkflowExecutionStepEntity[]): string {\n const completed = steps.filter(s => s.status === 'completed').length\n const failed = steps.filter(s => s.status === 'failed').length\n const skipped = steps.filter(s => s.status === 'skipped').length\n\n return `Completed ${completed}/${steps.length} steps (${failed} failed, ${skipped} skipped)`\n }\n}\n"]}
@@ -1,30 +0,0 @@
1
- import { Domain } from '@things-factory/shell';
2
- import { User } from '@things-factory/auth-base';
3
- import { WorkflowExecution } from './workflow-execution.js';
4
- import { WorkflowStatus, TriggerType } from '../types/workflow-types.js';
5
- /**
6
- * LabelingWorkflow Entity
7
- *
8
- * Represents a labeling workflow definition with multiple steps.
9
- * Stores workflow configuration, steps, and trigger settings.
10
- */
11
- export declare class LabelingWorkflow {
12
- id: string;
13
- domain?: Domain;
14
- domainId?: string;
15
- creator?: User;
16
- creatorId?: string;
17
- name: string;
18
- description?: string;
19
- projectId: number;
20
- triggerType: TriggerType;
21
- triggerConfig?: string;
22
- steps: string;
23
- status: WorkflowStatus;
24
- lastExecutedAt?: Date;
25
- nextExecutionAt?: Date;
26
- executions?: WorkflowExecution[];
27
- createdAt: Date;
28
- updatedAt: Date;
29
- deletedAt?: Date;
30
- }