@things-factory/labeling 9.1.19
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.
- package/CHANGELOG.md +87 -0
- package/ENTITY_IMPLEMENTATION.md +351 -0
- package/INTEGRATION_COMPLETE.md +531 -0
- package/MIGRATION_GUIDE.md +310 -0
- package/README.md +551 -0
- package/REFACTORING_SUMMARY.md +212 -0
- package/UI_DOCUMENTATION.md +552 -0
- package/dist-client/index.d.ts +3 -0
- package/dist-client/index.js +9 -0
- package/dist-client/index.js.map +1 -0
- package/dist-client/pages/labeling-workflow-builder.d.ts +26 -0
- package/dist-client/pages/labeling-workflow-builder.js +636 -0
- package/dist-client/pages/labeling-workflow-builder.js.map +1 -0
- package/dist-client/pages/labeling-workflow-list.d.ts +24 -0
- package/dist-client/pages/labeling-workflow-list.js +495 -0
- package/dist-client/pages/labeling-workflow-list.js.map +1 -0
- package/dist-client/route.d.ts +1 -0
- package/dist-client/route.js +47 -0
- package/dist-client/route.js.map +1 -0
- package/dist-client/tsconfig.tsbuildinfo +1 -0
- package/dist-server/entities/index.d.ts +5 -0
- package/dist-server/entities/index.js +11 -0
- package/dist-server/entities/index.js.map +1 -0
- package/dist-server/index.d.ts +3 -0
- package/dist-server/index.js +7 -0
- package/dist-server/index.js.map +1 -0
- package/dist-server/route.d.ts +2 -0
- package/dist-server/route.js +6 -0
- package/dist-server/route.js.map +1 -0
- package/dist-server/service/index.d.ts +8 -0
- package/dist-server/service/index.js +21 -0
- package/dist-server/service/index.js.map +1 -0
- package/dist-server/service/labeling-workflow-service.d.ts +69 -0
- package/dist-server/service/labeling-workflow-service.js +521 -0
- package/dist-server/service/labeling-workflow-service.js.map +1 -0
- package/dist-server/service/labeling-workflow.d.ts +30 -0
- package/dist-server/service/labeling-workflow.js +119 -0
- package/dist-server/service/labeling-workflow.js.map +1 -0
- package/dist-server/service/workflow-execution-step.d.ts +28 -0
- package/dist-server/service/workflow-execution-step.js +115 -0
- package/dist-server/service/workflow-execution-step.js.map +1 -0
- package/dist-server/service/workflow-execution.d.ts +27 -0
- package/dist-server/service/workflow-execution.js +110 -0
- package/dist-server/service/workflow-execution.js.map +1 -0
- package/dist-server/tsconfig.tsbuildinfo +1 -0
- package/dist-server/types/workflow-types.d.ts +141 -0
- package/dist-server/types/workflow-types.js +488 -0
- package/dist-server/types/workflow-types.js.map +1 -0
- package/package.json +51 -0
- package/things-factory.config.js +11 -0
- package/translations/en.json +6 -0
- package/translations/ja.json +6 -0
- package/translations/ko.json +6 -0
- package/translations/ms.json +6 -0
- package/translations/zh.json +6 -0
package/README.md
ADDED
|
@@ -0,0 +1,551 @@
|
|
|
1
|
+
# @things-factory/labeling
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@things-factory/labeling)
|
|
4
|
+
[](https://github.com/hatiolab/things-factory/blob/master/LICENSE)
|
|
5
|
+
|
|
6
|
+
Labeling workflow orchestration module for Things-Factory platform.
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
This module provides comprehensive workflow orchestration capabilities for data labeling processes, including both **backend services** (GraphQL API, database persistence) and **frontend UI components** (workflow builder, list view).
|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
### Backend (Server) ✅
|
|
15
|
+
|
|
16
|
+
- **Workflow Management**: Create, execute, pause, resume, and delete labeling workflows
|
|
17
|
+
- **TypeORM Entities**: Persistent storage with PostgreSQL/SQLite support
|
|
18
|
+
- **GraphQL API**: Full-featured GraphQL resolvers with type safety
|
|
19
|
+
- **Multi-tenancy**: Domain-based data isolation
|
|
20
|
+
- **Execution Tracking**: Monitor workflow and step-level execution status
|
|
21
|
+
- **Error Handling**: Configurable retry logic and continue-on-error behavior
|
|
22
|
+
- **Step Types**:
|
|
23
|
+
- `import_data` - Import data from datasets or external sources
|
|
24
|
+
- `generate_predictions` - Generate AI predictions for pre-labeling
|
|
25
|
+
- `wait_for_annotations` - Wait for human annotations with completion tracking
|
|
26
|
+
- `sync_annotations` - Sync labels back to dataset
|
|
27
|
+
- `validate_quality` - Quality validation checks
|
|
28
|
+
- `export_results` - Export annotations to external systems
|
|
29
|
+
- `notification` - Send alerts and notifications
|
|
30
|
+
|
|
31
|
+
### Frontend (Client) ✅
|
|
32
|
+
|
|
33
|
+
- **Workflow List Page**: View and manage all workflows with filtering
|
|
34
|
+
- **Workflow Builder**: Visual workflow creation and editing interface
|
|
35
|
+
- **Step Editor**: Configure individual workflow steps with JSON config
|
|
36
|
+
- **Status Indicators**: Color-coded workflow status (Active, Draft, Paused, Failed)
|
|
37
|
+
- **CRUD Operations**: Complete workflow lifecycle management
|
|
38
|
+
- **Responsive Design**: Material Design 3 themed UI components
|
|
39
|
+
|
|
40
|
+
## Terminology
|
|
41
|
+
|
|
42
|
+
This module uses **"workflow"** terminology to distinguish from the existing `scenario` entity in Things-Factory:
|
|
43
|
+
|
|
44
|
+
- `LabelingWorkflow` - A workflow definition
|
|
45
|
+
- `WorkflowExecution` - A workflow execution instance
|
|
46
|
+
- `WorkflowStep` - Individual step in a workflow
|
|
47
|
+
- `WorkflowStatus` - Workflow state (Draft, Active, Paused, Completed, Failed)
|
|
48
|
+
|
|
49
|
+
## Installation
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npm install @things-factory/labeling
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Dependencies
|
|
56
|
+
|
|
57
|
+
### Server
|
|
58
|
+
- `@things-factory/integration-label-studio` - Label Studio API integration
|
|
59
|
+
- `@things-factory/dataset` - Dataset management
|
|
60
|
+
- `@things-factory/ai-inference` - AI model inference
|
|
61
|
+
- `@things-factory/auth-base` - Authentication
|
|
62
|
+
- `@things-factory/shell` - Core framework
|
|
63
|
+
- `typeorm` - Database ORM
|
|
64
|
+
|
|
65
|
+
### Client
|
|
66
|
+
- `@operato/shell` - Shell components and navigation
|
|
67
|
+
- `@operato/graphql` - GraphQL client
|
|
68
|
+
- `lit` - Web components framework
|
|
69
|
+
- `graphql-tag` - GraphQL query parsing
|
|
70
|
+
- `i18next` - Internationalization
|
|
71
|
+
|
|
72
|
+
## Usage
|
|
73
|
+
|
|
74
|
+
### Backend
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
import { LabelingWorkflowService } from '@things-factory/labeling'
|
|
78
|
+
|
|
79
|
+
// Create workflow service
|
|
80
|
+
const service = new LabelingWorkflowService()
|
|
81
|
+
|
|
82
|
+
// Create workflow
|
|
83
|
+
const workflow = await service.createLabelingWorkflow({
|
|
84
|
+
name: 'Image Classification Workflow',
|
|
85
|
+
description: 'Automated image classification with AI',
|
|
86
|
+
projectId: 123,
|
|
87
|
+
triggerType: 'manual',
|
|
88
|
+
steps: [
|
|
89
|
+
{
|
|
90
|
+
name: 'Import Images',
|
|
91
|
+
type: 'import_data',
|
|
92
|
+
config: JSON.stringify({
|
|
93
|
+
sourceType: 'dataset',
|
|
94
|
+
dataSetId: 'my-dataset',
|
|
95
|
+
limit: 1000
|
|
96
|
+
}),
|
|
97
|
+
continueOnError: false
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
name: 'Generate Predictions',
|
|
101
|
+
type: 'generate_predictions',
|
|
102
|
+
config: JSON.stringify({
|
|
103
|
+
modelId: 'resnet50-v2',
|
|
104
|
+
confidenceThreshold: 0.7
|
|
105
|
+
}),
|
|
106
|
+
continueOnError: true
|
|
107
|
+
}
|
|
108
|
+
],
|
|
109
|
+
autoStart: false
|
|
110
|
+
}, context)
|
|
111
|
+
|
|
112
|
+
// Execute workflow
|
|
113
|
+
const execution = await service.executeLabelingWorkflow({
|
|
114
|
+
workflowId: workflow.id
|
|
115
|
+
}, context)
|
|
116
|
+
|
|
117
|
+
// Monitor execution
|
|
118
|
+
const status = await service.workflowExecution(execution.executionId, context)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Frontend
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
// Import UI components
|
|
125
|
+
import '@things-factory/labeling/dist-client/pages/workflow-list'
|
|
126
|
+
import '@things-factory/labeling/dist-client/pages/workflow-builder'
|
|
127
|
+
|
|
128
|
+
// Use in HTML
|
|
129
|
+
<workflow-list-page></workflow-list-page>
|
|
130
|
+
<workflow-builder-page></workflow-builder-page>
|
|
131
|
+
|
|
132
|
+
// Edit existing workflow
|
|
133
|
+
<workflow-builder-page workflowId="workflow-uuid"></workflow-builder-page>
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Menu Integration
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
import { getMenuTemplate } from '@things-factory/labeling'
|
|
140
|
+
|
|
141
|
+
// Get menu items (owner = true for admin features)
|
|
142
|
+
const menuItems = getMenuTemplate(true)
|
|
143
|
+
|
|
144
|
+
// Integrate into your app's menu
|
|
145
|
+
export function getAppMenu(owner: boolean) {
|
|
146
|
+
return [
|
|
147
|
+
...yourMenuItems,
|
|
148
|
+
...getMenuTemplate(owner)
|
|
149
|
+
]
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Route Configuration
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
import route from '@things-factory/labeling/dist-client/route'
|
|
157
|
+
|
|
158
|
+
// Available routes:
|
|
159
|
+
// - /workflows → Workflow list page
|
|
160
|
+
// - /workflow-builder → Create new workflow
|
|
161
|
+
// - /workflow-builder/{id} → Edit existing workflow
|
|
162
|
+
|
|
163
|
+
// In your app's route.ts:
|
|
164
|
+
export default function appRoute(page: string) {
|
|
165
|
+
// Try labeling routes first
|
|
166
|
+
const labelingRoute = route(page)
|
|
167
|
+
if (labelingRoute) return labelingRoute
|
|
168
|
+
|
|
169
|
+
// Your other routes
|
|
170
|
+
switch (page) {
|
|
171
|
+
// ...
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## GraphQL API
|
|
177
|
+
|
|
178
|
+
### Mutations
|
|
179
|
+
|
|
180
|
+
```graphql
|
|
181
|
+
# Create workflow
|
|
182
|
+
mutation CreateWorkflow($input: CreateWorkflowRequest!) {
|
|
183
|
+
createLabelingWorkflow(input: $input) {
|
|
184
|
+
id
|
|
185
|
+
name
|
|
186
|
+
status
|
|
187
|
+
steps {
|
|
188
|
+
name
|
|
189
|
+
type
|
|
190
|
+
order
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
# Update workflow
|
|
196
|
+
mutation UpdateWorkflow($workflowId: String!, $input: UpdateWorkflowRequest!) {
|
|
197
|
+
updateLabelingWorkflow(workflowId: $workflowId, input: $input) {
|
|
198
|
+
id
|
|
199
|
+
name
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
# Execute workflow
|
|
204
|
+
mutation ExecuteWorkflow($input: ExecuteWorkflowRequest!) {
|
|
205
|
+
executeLabelingWorkflow(input: $input) {
|
|
206
|
+
executionId
|
|
207
|
+
status
|
|
208
|
+
summary
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
# Pause workflow
|
|
213
|
+
mutation PauseWorkflow($workflowId: String!) {
|
|
214
|
+
pauseLabelingWorkflow(workflowId: $workflowId) {
|
|
215
|
+
id
|
|
216
|
+
status
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
# Resume workflow
|
|
221
|
+
mutation ResumeWorkflow($workflowId: String!) {
|
|
222
|
+
resumeLabelingWorkflow(workflowId: $workflowId) {
|
|
223
|
+
id
|
|
224
|
+
status
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
# Delete workflow
|
|
229
|
+
mutation DeleteWorkflow($workflowId: String!) {
|
|
230
|
+
deleteLabelingWorkflow(workflowId: $workflowId)
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Queries
|
|
235
|
+
|
|
236
|
+
```graphql
|
|
237
|
+
# List workflows
|
|
238
|
+
query GetWorkflows($projectId: Int) {
|
|
239
|
+
labelingWorkflows(projectId: $projectId) {
|
|
240
|
+
items {
|
|
241
|
+
id
|
|
242
|
+
name
|
|
243
|
+
description
|
|
244
|
+
status
|
|
245
|
+
projectId
|
|
246
|
+
triggerType
|
|
247
|
+
steps {
|
|
248
|
+
name
|
|
249
|
+
type
|
|
250
|
+
config
|
|
251
|
+
}
|
|
252
|
+
createdAt
|
|
253
|
+
lastExecutedAt
|
|
254
|
+
}
|
|
255
|
+
total
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
# Get workflow details
|
|
260
|
+
query GetWorkflow($workflowId: String!) {
|
|
261
|
+
labelingWorkflow(workflowId: $workflowId) {
|
|
262
|
+
id
|
|
263
|
+
name
|
|
264
|
+
description
|
|
265
|
+
projectId
|
|
266
|
+
steps {
|
|
267
|
+
name
|
|
268
|
+
type
|
|
269
|
+
order
|
|
270
|
+
config
|
|
271
|
+
continueOnError
|
|
272
|
+
}
|
|
273
|
+
status
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
# Get execution status
|
|
278
|
+
query GetExecution($executionId: String!) {
|
|
279
|
+
workflowExecution(executionId: $executionId) {
|
|
280
|
+
id
|
|
281
|
+
workflowName
|
|
282
|
+
status
|
|
283
|
+
steps {
|
|
284
|
+
stepName
|
|
285
|
+
stepType
|
|
286
|
+
status
|
|
287
|
+
order
|
|
288
|
+
startedAt
|
|
289
|
+
completedAt
|
|
290
|
+
durationMs
|
|
291
|
+
output
|
|
292
|
+
error
|
|
293
|
+
}
|
|
294
|
+
startedAt
|
|
295
|
+
completedAt
|
|
296
|
+
totalDurationMs
|
|
297
|
+
summary
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
## Database Schema
|
|
303
|
+
|
|
304
|
+
### Tables
|
|
305
|
+
|
|
306
|
+
**labeling_workflows**
|
|
307
|
+
- `id` (UUID) - Primary key
|
|
308
|
+
- `domain_id` - Multi-tenancy
|
|
309
|
+
- `creator_id` - User who created workflow
|
|
310
|
+
- `name`, `description` - Workflow metadata
|
|
311
|
+
- `project_id` - Label Studio project ID
|
|
312
|
+
- `trigger_type` - Manual/Scheduled/Event
|
|
313
|
+
- `trigger_config` - Trigger configuration (JSON)
|
|
314
|
+
- `steps` (JSONB) - Workflow step definitions
|
|
315
|
+
- `status` - Draft/Active/Paused/Completed/Failed
|
|
316
|
+
- `last_executed_at`, `next_execution_at` - Scheduling
|
|
317
|
+
- `created_at`, `updated_at`, `deleted_at` - Timestamps
|
|
318
|
+
|
|
319
|
+
**workflow_executions**
|
|
320
|
+
- `id` (UUID) - Execution instance ID
|
|
321
|
+
- `workflow_id` - Reference to workflow
|
|
322
|
+
- `status` - running/completed/failed
|
|
323
|
+
- `started_at`, `completed_at`, `total_duration_ms` - Timing
|
|
324
|
+
- `summary`, `error` - Results
|
|
325
|
+
|
|
326
|
+
**workflow_execution_steps**
|
|
327
|
+
- `id` (UUID) - Step instance ID
|
|
328
|
+
- `execution_id` - Reference to execution
|
|
329
|
+
- `step_name`, `step_type` - Step info
|
|
330
|
+
- `order` - Execution sequence
|
|
331
|
+
- `status` - pending/running/completed/failed/skipped
|
|
332
|
+
- `started_at`, `completed_at`, `duration_ms` - Timing
|
|
333
|
+
- `output`, `error` - Results
|
|
334
|
+
|
|
335
|
+
### Indexes
|
|
336
|
+
|
|
337
|
+
- `ix_labeling_workflow_0` - (domain, projectId, status)
|
|
338
|
+
- `ix_labeling_workflow_1` - (domain, name)
|
|
339
|
+
- `ix_workflow_execution_0` - (domain, workflow, status)
|
|
340
|
+
- `ix_workflow_execution_1` - (domain, startedAt)
|
|
341
|
+
- `ix_workflow_execution_step_0` - (domain, execution, status)
|
|
342
|
+
- `ix_workflow_execution_step_1` - (domain, execution, order)
|
|
343
|
+
|
|
344
|
+
## Step Configuration Examples
|
|
345
|
+
|
|
346
|
+
### Import Data Step
|
|
347
|
+
```json
|
|
348
|
+
{
|
|
349
|
+
"sourceType": "dataset",
|
|
350
|
+
"dataSetId": "dataset-uuid",
|
|
351
|
+
"imageField": "image",
|
|
352
|
+
"limit": 1000
|
|
353
|
+
}
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
### Generate Predictions Step
|
|
357
|
+
```json
|
|
358
|
+
{
|
|
359
|
+
"modelId": "resnet50-v2",
|
|
360
|
+
"confidenceThreshold": 0.7,
|
|
361
|
+
"forceRegenerate": false
|
|
362
|
+
}
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### Wait for Annotations Step
|
|
366
|
+
```json
|
|
367
|
+
{
|
|
368
|
+
"minCompletionRate": 0.9,
|
|
369
|
+
"autoProceed": false
|
|
370
|
+
}
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### Sync Annotations Step
|
|
374
|
+
```json
|
|
375
|
+
{
|
|
376
|
+
"completedOnly": true,
|
|
377
|
+
"targetDataSet": "dataset-uuid"
|
|
378
|
+
}
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### Validate Quality Step
|
|
382
|
+
```json
|
|
383
|
+
{
|
|
384
|
+
"minQualityScore": 0.8,
|
|
385
|
+
"validationRules": ["consistency", "completeness"]
|
|
386
|
+
}
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
## Architecture
|
|
390
|
+
|
|
391
|
+
```
|
|
392
|
+
@things-factory/labeling
|
|
393
|
+
├── server/ # Backend
|
|
394
|
+
│ ├── entities/ # TypeORM entities
|
|
395
|
+
│ │ ├── labeling-workflow.ts
|
|
396
|
+
│ │ ├── workflow-execution.ts
|
|
397
|
+
│ │ └── workflow-execution-step.ts
|
|
398
|
+
│ ├── service/ # Business logic
|
|
399
|
+
│ │ └── labeling-workflow-service.ts
|
|
400
|
+
│ ├── types/ # GraphQL types
|
|
401
|
+
│ │ └── workflow-types.ts
|
|
402
|
+
│ └── index.ts # Exports
|
|
403
|
+
│
|
|
404
|
+
└── client/ # Frontend
|
|
405
|
+
├── pages/ # Page components
|
|
406
|
+
│ ├── workflow-list.ts
|
|
407
|
+
│ └── workflow-builder.ts
|
|
408
|
+
├── route.ts # Route configuration
|
|
409
|
+
├── menu.ts # Menu configuration
|
|
410
|
+
└── index.ts # Exports
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
## Integration Examples
|
|
414
|
+
|
|
415
|
+
### With operato-dataset
|
|
416
|
+
|
|
417
|
+
```typescript
|
|
418
|
+
// Extend with dataset-specific functionality
|
|
419
|
+
import { LabelingWorkflowService } from '@things-factory/labeling'
|
|
420
|
+
|
|
421
|
+
@Resolver()
|
|
422
|
+
export class DatasetLabelingWorkflow {
|
|
423
|
+
private workflowService = new LabelingWorkflowService()
|
|
424
|
+
|
|
425
|
+
@Mutation()
|
|
426
|
+
async createDatasetLabelingWorkflow(
|
|
427
|
+
@Arg('dataSetId') dataSetId: string,
|
|
428
|
+
@Arg('projectId', type => Int) projectId: number
|
|
429
|
+
) {
|
|
430
|
+
return await this.workflowService.createLabelingWorkflow({
|
|
431
|
+
name: `Auto-label ${dataSetId}`,
|
|
432
|
+
projectId,
|
|
433
|
+
steps: [
|
|
434
|
+
// Dataset-specific preset steps
|
|
435
|
+
]
|
|
436
|
+
}, context)
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
### Custom UI Wrapper
|
|
442
|
+
|
|
443
|
+
```typescript
|
|
444
|
+
// Create custom workflow builder with presets
|
|
445
|
+
@customElement('custom-workflow-builder')
|
|
446
|
+
export class CustomWorkflowBuilder extends LitElement {
|
|
447
|
+
render() {
|
|
448
|
+
return html`
|
|
449
|
+
<workflow-builder-page
|
|
450
|
+
.defaultConfig=${{
|
|
451
|
+
triggerType: 'event',
|
|
452
|
+
steps: [/* preset steps */]
|
|
453
|
+
}}
|
|
454
|
+
></workflow-builder-page>
|
|
455
|
+
`
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
## Documentation
|
|
461
|
+
|
|
462
|
+
- **[UI Documentation](./UI_DOCUMENTATION.md)** - Complete UI component reference
|
|
463
|
+
- **[Entity Implementation](./ENTITY_IMPLEMENTATION.md)** - Database schema details
|
|
464
|
+
- **[Integration Guide](../operato-dataset/LABELING_INTEGRATION.md)** - Integration examples
|
|
465
|
+
|
|
466
|
+
## Development
|
|
467
|
+
|
|
468
|
+
```bash
|
|
469
|
+
# Install dependencies
|
|
470
|
+
npm install
|
|
471
|
+
|
|
472
|
+
# Build both server and client
|
|
473
|
+
npm run build
|
|
474
|
+
|
|
475
|
+
# Build server only
|
|
476
|
+
npm run build:server
|
|
477
|
+
|
|
478
|
+
# Build client only
|
|
479
|
+
npm run build:client
|
|
480
|
+
|
|
481
|
+
# Clean build artifacts
|
|
482
|
+
npm run clean
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
## Best Practices
|
|
486
|
+
|
|
487
|
+
1. **Validate JSON configurations** before saving workflows
|
|
488
|
+
2. **Use continue-on-error judiciously** for non-critical steps
|
|
489
|
+
3. **Monitor execution status** for long-running workflows
|
|
490
|
+
4. **Set appropriate limits** in import_data steps
|
|
491
|
+
5. **Use descriptive step names** for clarity
|
|
492
|
+
|
|
493
|
+
## Troubleshooting
|
|
494
|
+
|
|
495
|
+
**Issue**: Workflow not saving
|
|
496
|
+
- **Solution**: Check JSON configuration syntax, ensure required fields are filled
|
|
497
|
+
|
|
498
|
+
**Issue**: Execution stuck
|
|
499
|
+
- **Solution**: Check workflow_execution_steps table for failed steps, review error messages
|
|
500
|
+
|
|
501
|
+
**Issue**: UI components not loading
|
|
502
|
+
- **Solution**: Verify route configuration, check browser console for import errors
|
|
503
|
+
|
|
504
|
+
## Future Enhancements
|
|
505
|
+
|
|
506
|
+
- [x] Database persistence with TypeORM
|
|
507
|
+
- [x] Visual workflow builder UI
|
|
508
|
+
- [x] GraphQL API
|
|
509
|
+
- [ ] Schedule-based triggers (cron support)
|
|
510
|
+
- [ ] Event-based triggers (webhook integration)
|
|
511
|
+
- [ ] Drag & drop workflow builder
|
|
512
|
+
- [ ] Real-time execution monitoring
|
|
513
|
+
- [ ] Workflow templates library
|
|
514
|
+
- [ ] Conditional branching
|
|
515
|
+
- [ ] Parallel step execution
|
|
516
|
+
- [ ] Workflow versioning
|
|
517
|
+
|
|
518
|
+
## License
|
|
519
|
+
|
|
520
|
+
MIT
|
|
521
|
+
|
|
522
|
+
## Contributing
|
|
523
|
+
|
|
524
|
+
Contributions are welcome! Please follow the Things-Factory contribution guidelines.
|
|
525
|
+
|
|
526
|
+
## Support
|
|
527
|
+
|
|
528
|
+
For issues and questions, please open an issue on GitHub or contact the Things-Factory team.
|
|
529
|
+
|
|
530
|
+
## Changelog
|
|
531
|
+
|
|
532
|
+
### 9.1.0 (2024-10-14)
|
|
533
|
+
|
|
534
|
+
**Added**:
|
|
535
|
+
- ✅ Complete backend with TypeORM entities
|
|
536
|
+
- ✅ GraphQL API for workflow management
|
|
537
|
+
- ✅ Workflow list page UI component
|
|
538
|
+
- ✅ Workflow builder page UI component
|
|
539
|
+
- ✅ Step editor with JSON configuration
|
|
540
|
+
- ✅ Route and menu integration
|
|
541
|
+
- ✅ Multi-tenancy support
|
|
542
|
+
- ✅ PostgreSQL and SQLite compatibility
|
|
543
|
+
- ✅ Comprehensive documentation
|
|
544
|
+
|
|
545
|
+
**Changed**:
|
|
546
|
+
- Renamed from "scenario" to "workflow" terminology
|
|
547
|
+
- Separated from integration-label-studio package
|
|
548
|
+
|
|
549
|
+
**Fixed**:
|
|
550
|
+
- Parameter order issues in GraphQL resolvers
|
|
551
|
+
- Type conflicts between entities and GraphQL types
|