@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.
Files changed (55) hide show
  1. package/CHANGELOG.md +87 -0
  2. package/ENTITY_IMPLEMENTATION.md +351 -0
  3. package/INTEGRATION_COMPLETE.md +531 -0
  4. package/MIGRATION_GUIDE.md +310 -0
  5. package/README.md +551 -0
  6. package/REFACTORING_SUMMARY.md +212 -0
  7. package/UI_DOCUMENTATION.md +552 -0
  8. package/dist-client/index.d.ts +3 -0
  9. package/dist-client/index.js +9 -0
  10. package/dist-client/index.js.map +1 -0
  11. package/dist-client/pages/labeling-workflow-builder.d.ts +26 -0
  12. package/dist-client/pages/labeling-workflow-builder.js +636 -0
  13. package/dist-client/pages/labeling-workflow-builder.js.map +1 -0
  14. package/dist-client/pages/labeling-workflow-list.d.ts +24 -0
  15. package/dist-client/pages/labeling-workflow-list.js +495 -0
  16. package/dist-client/pages/labeling-workflow-list.js.map +1 -0
  17. package/dist-client/route.d.ts +1 -0
  18. package/dist-client/route.js +47 -0
  19. package/dist-client/route.js.map +1 -0
  20. package/dist-client/tsconfig.tsbuildinfo +1 -0
  21. package/dist-server/entities/index.d.ts +5 -0
  22. package/dist-server/entities/index.js +11 -0
  23. package/dist-server/entities/index.js.map +1 -0
  24. package/dist-server/index.d.ts +3 -0
  25. package/dist-server/index.js +7 -0
  26. package/dist-server/index.js.map +1 -0
  27. package/dist-server/route.d.ts +2 -0
  28. package/dist-server/route.js +6 -0
  29. package/dist-server/route.js.map +1 -0
  30. package/dist-server/service/index.d.ts +8 -0
  31. package/dist-server/service/index.js +21 -0
  32. package/dist-server/service/index.js.map +1 -0
  33. package/dist-server/service/labeling-workflow-service.d.ts +69 -0
  34. package/dist-server/service/labeling-workflow-service.js +521 -0
  35. package/dist-server/service/labeling-workflow-service.js.map +1 -0
  36. package/dist-server/service/labeling-workflow.d.ts +30 -0
  37. package/dist-server/service/labeling-workflow.js +119 -0
  38. package/dist-server/service/labeling-workflow.js.map +1 -0
  39. package/dist-server/service/workflow-execution-step.d.ts +28 -0
  40. package/dist-server/service/workflow-execution-step.js +115 -0
  41. package/dist-server/service/workflow-execution-step.js.map +1 -0
  42. package/dist-server/service/workflow-execution.d.ts +27 -0
  43. package/dist-server/service/workflow-execution.js +110 -0
  44. package/dist-server/service/workflow-execution.js.map +1 -0
  45. package/dist-server/tsconfig.tsbuildinfo +1 -0
  46. package/dist-server/types/workflow-types.d.ts +141 -0
  47. package/dist-server/types/workflow-types.js +488 -0
  48. package/dist-server/types/workflow-types.js.map +1 -0
  49. package/package.json +51 -0
  50. package/things-factory.config.js +11 -0
  51. package/translations/en.json +6 -0
  52. package/translations/ja.json +6 -0
  53. package/translations/ko.json +6 -0
  54. package/translations/ms.json +6 -0
  55. package/translations/zh.json +6 -0
@@ -0,0 +1,552 @@
1
+ # Labeling Workflow UI Documentation
2
+
3
+ ## Overview
4
+
5
+ `@things-factory/labeling` 패키지는 레이블링 워크플로우를 시각적으로 생성, 편집, 관리할 수 있는 범용 UI 컴포넌트를 제공합니다.
6
+
7
+ ## Components
8
+
9
+ ### 1. Workflow List Page (`workflow-list.ts`)
10
+
11
+ 워크플로우 목록을 카드 형태로 표시하고 CRUD 작업을 수행하는 페이지입니다.
12
+
13
+ #### Features
14
+
15
+ - **Grid Layout**: 반응형 그리드로 워크플로우 카드 표시
16
+ - **Status Indicators**: 색상별 상태 표시
17
+ - Green (Active): 활성 워크플로우
18
+ - Gray (Draft): 초안 상태
19
+ - Orange (Paused): 일시정지
20
+ - Blue (Completed): 완료
21
+ - Red (Failed): 실패
22
+ - **Filtering**: 상태 및 프로젝트 ID로 필터링
23
+ - **Actions**:
24
+ - Create: 새 워크플로우 생성
25
+ - Edit: 워크플로우 편집
26
+ - Execute: 워크플로우 실행
27
+ - Pause/Resume: 실행 제어
28
+ - Delete: 워크플로우 삭제
29
+
30
+ #### Usage
31
+
32
+ ```typescript
33
+ import '@things-factory/labeling/dist-client/pages/workflow-list'
34
+
35
+ // HTML에서 사용
36
+ <workflow-list-page></workflow-list-page>
37
+ ```
38
+
39
+ #### GraphQL Queries Used
40
+
41
+ ```graphql
42
+ # 워크플로우 목록 조회
43
+ query GetWorkflows($projectId: Int) {
44
+ labelingWorkflows(projectId: $projectId) {
45
+ items {
46
+ id
47
+ name
48
+ description
49
+ projectId
50
+ status
51
+ triggerType
52
+ steps { name type }
53
+ createdAt
54
+ lastExecutedAt
55
+ }
56
+ }
57
+ }
58
+
59
+ # 워크플로우 실행
60
+ mutation ExecuteWorkflow($workflowId: String!) {
61
+ executeLabelingWorkflow(input: { workflowId: $workflowId }) {
62
+ executionId
63
+ status
64
+ summary
65
+ }
66
+ }
67
+
68
+ # 워크플로우 일시정지
69
+ mutation PauseWorkflow($workflowId: String!) {
70
+ pauseLabelingWorkflow(workflowId: $workflowId) {
71
+ id
72
+ status
73
+ }
74
+ }
75
+
76
+ # 워크플로우 재개
77
+ mutation ResumeWorkflow($workflowId: String!) {
78
+ resumeLabelingWorkflow(workflowId: $workflowId) {
79
+ id
80
+ status
81
+ }
82
+ }
83
+
84
+ # 워크플로우 삭제
85
+ mutation DeleteWorkflow($workflowId: String!) {
86
+ deleteLabelingWorkflow(workflowId: $workflowId)
87
+ }
88
+ ```
89
+
90
+ ### 2. Workflow Builder Page (`workflow-builder.ts`)
91
+
92
+ 워크플로우를 생성하거나 편집하는 인터랙티브 빌더 페이지입니다.
93
+
94
+ #### Features
95
+
96
+ **Layout**:
97
+ - **Sidebar (Left)**: 워크플로우 기본 정보 및 스텝 목록
98
+ - **Main Area (Right)**: 선택된 스텝의 상세 설정
99
+
100
+ **Workflow Settings (Sidebar)**:
101
+ - Name: 워크플로우 이름 (필수)
102
+ - Description: 설명
103
+ - Project ID: Label Studio 프로젝트 ID (필수)
104
+ - Trigger Type: Manual/Scheduled/Event-based
105
+ - Auto Start: 생성 후 자동 시작 여부
106
+
107
+ **Step Management**:
108
+ - Add Step: 새 스텝 추가
109
+ - Reorder: 스텝 순서 변경 (↑↓ 버튼)
110
+ - Delete: 스텝 삭제 (× 버튼)
111
+ - Select: 스텝 클릭으로 편집
112
+
113
+ **Step Editor (Main Area)**:
114
+ - Step Name: 스텝 이름
115
+ - Step Type: 스텝 유형 선택
116
+ - `import_data`: 데이터 가져오기
117
+ - `generate_predictions`: AI 예측 생성
118
+ - `wait_for_annotations`: 수동 레이블링 대기
119
+ - `sync_annotations`: 레이블 동기화
120
+ - `validate_quality`: 품질 검증
121
+ - `export_results`: 결과 내보내기
122
+ - `notification`: 알림 전송
123
+ - Configuration: JSON 형식의 스텝 설정
124
+ - Continue on Error: 에러 발생 시 계속 진행 여부
125
+
126
+ #### Usage
127
+
128
+ **Creating New Workflow**:
129
+ ```typescript
130
+ import '@things-factory/labeling/dist-client/pages/workflow-builder'
131
+
132
+ // 새 워크플로우 생성
133
+ <workflow-builder-page></workflow-builder-page>
134
+ ```
135
+
136
+ **Editing Existing Workflow**:
137
+ ```typescript
138
+ // 기존 워크플로우 편집
139
+ <workflow-builder-page workflowId="workflow-uuid"></workflow-builder-page>
140
+ ```
141
+
142
+ #### GraphQL Mutations Used
143
+
144
+ ```graphql
145
+ # 워크플로우 생성
146
+ mutation CreateWorkflow($input: CreateWorkflowRequest!) {
147
+ createLabelingWorkflow(input: $input) {
148
+ id
149
+ name
150
+ }
151
+ }
152
+
153
+ # 워크플로우 업데이트
154
+ mutation UpdateWorkflow($workflowId: String!, $input: UpdateWorkflowRequest!) {
155
+ updateLabelingWorkflow(workflowId: $workflowId, input: $input) {
156
+ id
157
+ name
158
+ }
159
+ }
160
+
161
+ # 워크플로우 상세 조회 (편집 모드)
162
+ query GetWorkflow($workflowId: String!) {
163
+ labelingWorkflow(workflowId: $workflowId) {
164
+ id
165
+ name
166
+ description
167
+ projectId
168
+ triggerType
169
+ triggerConfig
170
+ steps {
171
+ name
172
+ type
173
+ order
174
+ config
175
+ continueOnError
176
+ }
177
+ status
178
+ autoStart
179
+ }
180
+ }
181
+ ```
182
+
183
+ ## Route Configuration
184
+
185
+ ```typescript
186
+ // packages/labeling/client/route.ts
187
+ export default function route(page: string) {
188
+ switch (page) {
189
+ case 'workflows':
190
+ import('./pages/workflow-list')
191
+ return page
192
+
193
+ case 'workflow-builder':
194
+ import('./pages/workflow-builder')
195
+ return page
196
+ }
197
+ }
198
+ ```
199
+
200
+ ### URL Patterns
201
+
202
+ - `/workflows` - 워크플로우 목록
203
+ - `/workflow-builder` - 새 워크플로우 생성
204
+ - `/workflow-builder/{workflowId}` - 기존 워크플로우 편집
205
+
206
+ ## Menu Configuration
207
+
208
+ ```typescript
209
+ // packages/labeling/client/menu.ts
210
+ import i18next from 'i18next'
211
+
212
+ export function getMenuTemplate(owner: boolean = false) {
213
+ return [
214
+ {
215
+ name: 'LABELING WORKFLOWS',
216
+ type: 'group'
217
+ },
218
+ {
219
+ name: i18next.t('title.workflows'),
220
+ icon: 'account_tree',
221
+ path: 'workflows',
222
+ description: 'Manage labeling workflows'
223
+ },
224
+ owner && {
225
+ name: i18next.t('title.create workflow'),
226
+ icon: 'add_circle',
227
+ path: 'workflow-builder',
228
+ description: 'Create new labeling workflow'
229
+ }
230
+ ].filter(Boolean)
231
+ }
232
+ ```
233
+
234
+ ## Step Type Configuration Examples
235
+
236
+ ### Import Data Step
237
+
238
+ ```json
239
+ {
240
+ "sourceType": "dataset",
241
+ "dataSetId": "my-dataset-uuid",
242
+ "imageField": "image",
243
+ "limit": 1000
244
+ }
245
+ ```
246
+
247
+ ### Generate Predictions Step
248
+
249
+ ```json
250
+ {
251
+ "modelId": "resnet50-v2",
252
+ "confidenceThreshold": 0.7,
253
+ "forceRegenerate": false
254
+ }
255
+ ```
256
+
257
+ ### Wait for Annotations Step
258
+
259
+ ```json
260
+ {
261
+ "minCompletionRate": 0.9,
262
+ "autoProceed": false
263
+ }
264
+ ```
265
+
266
+ ### Sync Annotations Step
267
+
268
+ ```json
269
+ {
270
+ "completedOnly": true,
271
+ "targetDataSet": "my-dataset-uuid"
272
+ }
273
+ ```
274
+
275
+ ### Validate Quality Step
276
+
277
+ ```json
278
+ {
279
+ "minQualityScore": 0.8,
280
+ "validationRules": ["consistency", "completeness"]
281
+ }
282
+ ```
283
+
284
+ ### Export Results Step
285
+
286
+ ```json
287
+ {
288
+ "format": "coco",
289
+ "destination": "s3://my-bucket/exports/"
290
+ }
291
+ ```
292
+
293
+ ### Notification Step
294
+
295
+ ```json
296
+ {
297
+ "channels": ["email", "slack"],
298
+ "recipients": ["admin@example.com"],
299
+ "message": "Workflow completed successfully"
300
+ }
301
+ ```
302
+
303
+ ## Styling and Theming
304
+
305
+ UI 컴포넌트는 Material Design 3 테마 변수를 사용합니다:
306
+
307
+ ```css
308
+ /* Primary colors */
309
+ --md-sys-color-primary
310
+ --md-sys-color-on-primary
311
+ --md-sys-color-primary-container
312
+ --md-sys-color-on-primary-container
313
+
314
+ /* Surface colors */
315
+ --md-sys-color-surface
316
+ --md-sys-color-on-surface
317
+ --md-sys-color-surface-variant
318
+ --md-sys-color-on-surface-variant
319
+
320
+ /* Outline */
321
+ --md-sys-color-outline
322
+
323
+ /* Secondary */
324
+ --md-sys-color-secondary
325
+ --md-sys-color-on-secondary
326
+ ```
327
+
328
+ 테마를 커스터마이징하려면 CSS 변수를 오버라이드하세요:
329
+
330
+ ```css
331
+ :root {
332
+ --md-sys-color-primary: #6750a4;
333
+ --md-sys-color-on-primary: #ffffff;
334
+ }
335
+ ```
336
+
337
+ ## Integration with Other Packages
338
+
339
+ ### Option 1: Direct Usage
340
+
341
+ 다른 패키지에서 직접 사용:
342
+
343
+ ```typescript
344
+ import '@things-factory/labeling/dist-client/pages/workflow-list'
345
+ import '@things-factory/labeling/dist-client/pages/workflow-builder'
346
+ ```
347
+
348
+ ### Option 2: Re-export with Customization
349
+
350
+ 다른 패키지에서 래퍼 컴포넌트 생성:
351
+
352
+ ```typescript
353
+ // packages/operato-dataset/client/pages/dataset-workflow-builder.ts
354
+ import { html } from 'lit'
355
+ import { customElement } from 'lit/decorators.js'
356
+ import '@things-factory/labeling/dist-client/pages/workflow-builder'
357
+
358
+ @customElement('dataset-workflow-builder')
359
+ export class DatasetWorkflowBuilder extends LitElement {
360
+ render() {
361
+ return html`
362
+ <workflow-builder-page
363
+ .presetConfig=${{
364
+ triggerType: 'event',
365
+ steps: [
366
+ // DataSet-specific preset steps
367
+ ]
368
+ }}
369
+ ></workflow-builder-page>
370
+ `
371
+ }
372
+ }
373
+ ```
374
+
375
+ ### Option 3: Menu Integration
376
+
377
+ 다른 패키지의 메뉴에 통합:
378
+
379
+ ```typescript
380
+ // packages/operato-dataset/client/menu.ts
381
+ import { getMenuTemplate as getLabelingMenu } from '@things-factory/labeling'
382
+
383
+ export function getMenuTemplate(owner: boolean, dataSets: any[]) {
384
+ return [
385
+ // ... other menu items
386
+ ...getLabelingMenu(owner),
387
+ // ... more menu items
388
+ ]
389
+ }
390
+ ```
391
+
392
+ ## Best Practices
393
+
394
+ ### 1. Validation
395
+
396
+ 워크플로우 저장 전 검증:
397
+
398
+ ```typescript
399
+ validateWorkflow(workflow: any): string[] {
400
+ const errors: string[] = []
401
+
402
+ if (!workflow.name) errors.push('Workflow name is required')
403
+ if (!workflow.projectId) errors.push('Project ID is required')
404
+ if (workflow.steps.length === 0) errors.push('At least one step is required')
405
+
406
+ workflow.steps.forEach((step: any, index: number) => {
407
+ if (!step.name) errors.push(`Step ${index + 1}: Name is required`)
408
+ if (!step.type) errors.push(`Step ${index + 1}: Type is required`)
409
+
410
+ try {
411
+ JSON.parse(step.config)
412
+ } catch (e) {
413
+ errors.push(`Step ${index + 1}: Invalid JSON configuration`)
414
+ }
415
+ })
416
+
417
+ return errors
418
+ }
419
+ ```
420
+
421
+ ### 2. Error Handling
422
+
423
+ 사용자에게 명확한 에러 메시지 표시:
424
+
425
+ ```typescript
426
+ async saveWorkflow() {
427
+ try {
428
+ const errors = this.validateWorkflow(this.workflow)
429
+ if (errors.length > 0) {
430
+ this.error = errors.join('\n')
431
+ return
432
+ }
433
+
434
+ await client.mutate({ mutation, variables })
435
+ alert('Workflow saved successfully!')
436
+ } catch (error) {
437
+ console.error('Failed to save workflow:', error)
438
+ this.error = 'Failed to save workflow. Please check your inputs.'
439
+ }
440
+ }
441
+ ```
442
+
443
+ ### 3. Loading States
444
+
445
+ 긴 작업 중 로딩 상태 표시:
446
+
447
+ ```typescript
448
+ async loadWorkflows() {
449
+ this.loading = true
450
+ try {
451
+ const response = await client.query({ query })
452
+ this.workflows = response.data.labelingWorkflows.items
453
+ } finally {
454
+ this.loading = false
455
+ }
456
+ }
457
+ ```
458
+
459
+ ### 4. Navigation
460
+
461
+ 페이지 간 이동:
462
+
463
+ ```typescript
464
+ import { navigate } from '@operato/shell'
465
+
466
+ // 워크플로우 목록으로
467
+ navigate('workflows')
468
+
469
+ // 워크플로우 편집
470
+ navigate(`workflow-builder/${workflowId}`)
471
+
472
+ // 이전 페이지로
473
+ history.back()
474
+ ```
475
+
476
+ ## Accessibility
477
+
478
+ ### Keyboard Navigation
479
+
480
+ - Tab: 폼 필드 간 이동
481
+ - Enter: 버튼 클릭, 폼 제출
482
+ - Escape: 다이얼로그 닫기
483
+ - Arrow keys: 스텝 목록 탐색
484
+
485
+ ### Screen Readers
486
+
487
+ 모든 인터랙티브 요소에 적절한 ARIA 레이블 제공:
488
+
489
+ ```html
490
+ <button aria-label="Add new step">+ Add Step</button>
491
+ <input aria-label="Workflow name" placeholder="Enter workflow name" />
492
+ ```
493
+
494
+ ## Performance Optimization
495
+
496
+ ### Lazy Loading
497
+
498
+ 페이지 컴포넌트는 동적으로 임포트됩니다:
499
+
500
+ ```typescript
501
+ // route.ts
502
+ case 'workflows':
503
+ import('./pages/workflow-list') // Lazy loaded
504
+ return page
505
+ ```
506
+
507
+ ### Virtual Scrolling
508
+
509
+ 많은 워크플로우를 표시할 때는 가상 스크롤링 고려:
510
+
511
+ ```typescript
512
+ // 큰 리스트에 적용 (향후 개선 사항)
513
+ import { virtualScroll } from '@lit-labs/virtualizer'
514
+ ```
515
+
516
+ ## Troubleshooting
517
+
518
+ ### Common Issues
519
+
520
+ **Issue 1: GraphQL Query Fails**
521
+ - **Solution**: GraphQL 서버 연결 확인, 쿼리 구문 검증
522
+
523
+ **Issue 2: Workflow Not Saving**
524
+ - **Solution**: JSON 설정 형식 확인, 필수 필드 입력 확인
525
+
526
+ **Issue 3: Step Configuration Error**
527
+ - **Solution**: config 필드가 유효한 JSON 문자열인지 확인
528
+
529
+ **Issue 4: Navigation Not Working**
530
+ - **Solution**: route.ts가 올바르게 설정되었는지, shell 패키지 임포트 확인
531
+
532
+ ## Future Enhancements
533
+
534
+ ### Planned Features
535
+
536
+ - [ ] Drag & Drop 스텝 재정렬
537
+ - [ ] 비주얼 워크플로우 다이어그램
538
+ - [ ] 스텝 템플릿 라이브러리
539
+ - [ ] 실시간 워크플로우 실행 모니터링
540
+ - [ ] 워크플로우 복제 기능
541
+ - [ ] 워크플로우 비교 도구
542
+ - [ ] 스텝별 설정 검증기
543
+ - [ ] 다국어 지원 확장
544
+ - [ ] 워크플로우 시뮬레이션 모드
545
+ - [ ] 조건부 분기 지원
546
+
547
+ ## References
548
+
549
+ - [Lit Documentation](https://lit.dev/)
550
+ - [Material Design 3](https://m3.material.io/)
551
+ - [GraphQL Best Practices](https://graphql.org/learn/best-practices/)
552
+ - [Things-Factory Architecture](../../../docs/architecture.md)
@@ -0,0 +1,3 @@
1
+ export * from './pages/labeling-workflow-list.js';
2
+ export * from './pages/labeling-workflow-builder.js';
3
+ export { default as route } from './route.js';
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.route = void 0;
4
+ const tslib_1 = require("tslib");
5
+ tslib_1.__exportStar(require("./pages/labeling-workflow-list.js"), exports);
6
+ tslib_1.__exportStar(require("./pages/labeling-workflow-builder.js"), exports);
7
+ var route_js_1 = require("./route.js");
8
+ Object.defineProperty(exports, "route", { enumerable: true, get: function () { return tslib_1.__importDefault(route_js_1).default; } });
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../client/index.ts"],"names":[],"mappings":";;;;AAAA,4EAAiD;AACjD,+EAAoD;AAEpD,uCAA6C;AAApC,0HAAA,OAAO,OAAS","sourcesContent":["export * from './pages/labeling-workflow-list.js'\nexport * from './pages/labeling-workflow-builder.js'\n\nexport { default as route } from './route.js'\n"]}
@@ -0,0 +1,26 @@
1
+ import { PageView } from '@operato/shell';
2
+ /**
3
+ * Workflow Builder Page
4
+ *
5
+ * Generic workflow builder UI for creating and editing labeling workflows
6
+ */
7
+ export declare class LabelingWorkflowBuilderPage extends PageView {
8
+ static styles: import("lit").CSSResult[];
9
+ workflowId?: string;
10
+ workflow: any;
11
+ selectedStepIndex: number;
12
+ loading: boolean;
13
+ error: string;
14
+ firstUpdated(): Promise<void>;
15
+ loadWorkflow(): Promise<void>;
16
+ saveWorkflow(): Promise<void>;
17
+ addStep(): void;
18
+ removeStep(index: number): void;
19
+ moveStepUp(index: number): void;
20
+ moveStepDown(index: number): void;
21
+ selectStep(index: number): void;
22
+ updateStep(index: number, field: string, value: any): void;
23
+ updateWorkflow(field: string, value: any): void;
24
+ renderStepEditor(): import("lit-html").TemplateResult<1>;
25
+ render(): import("lit-html").TemplateResult<1>;
26
+ }