@things-factory/integration-label-studio 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 (152) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/EXTERNAL_DATA_SOURCING.md +484 -0
  3. package/IMPLEMENTATION_GUIDE.md +469 -0
  4. package/INTEGRATION.md +279 -0
  5. package/README.md +1014 -0
  6. package/SETUP_GUIDE.md +577 -0
  7. package/TEST_GUIDE.md +387 -0
  8. package/UI_CUSTOMIZATION.md +395 -0
  9. package/USER_SYNC_GUIDE.md +514 -0
  10. package/client/bootstrap.ts +1 -0
  11. package/client/index.ts +1 -0
  12. package/client/label-studio-label-page.ts +52 -0
  13. package/client/label-studio-project-create.ts +216 -0
  14. package/client/label-studio-project-list.ts +214 -0
  15. package/client/label-studio-wrapper.ts +294 -0
  16. package/client/route.ts +15 -0
  17. package/client/tsconfig.json +13 -0
  18. package/config/config.development.js +124 -0
  19. package/config/config.production.js +182 -0
  20. package/dist-client/bootstrap.d.ts +1 -0
  21. package/dist-client/bootstrap.js +2 -0
  22. package/dist-client/bootstrap.js.map +1 -0
  23. package/dist-client/index.d.ts +1 -0
  24. package/dist-client/index.js +2 -0
  25. package/dist-client/index.js.map +1 -0
  26. package/dist-client/label-studio-label-page.d.ts +8 -0
  27. package/dist-client/label-studio-label-page.js +54 -0
  28. package/dist-client/label-studio-label-page.js.map +1 -0
  29. package/dist-client/label-studio-project-create.d.ts +16 -0
  30. package/dist-client/label-studio-project-create.js +235 -0
  31. package/dist-client/label-studio-project-create.js.map +1 -0
  32. package/dist-client/label-studio-project-list.d.ts +16 -0
  33. package/dist-client/label-studio-project-list.js +222 -0
  34. package/dist-client/label-studio-project-list.js.map +1 -0
  35. package/dist-client/label-studio-wrapper.d.ts +57 -0
  36. package/dist-client/label-studio-wrapper.js +304 -0
  37. package/dist-client/label-studio-wrapper.js.map +1 -0
  38. package/dist-client/route.d.ts +1 -0
  39. package/dist-client/route.js +14 -0
  40. package/dist-client/route.js.map +1 -0
  41. package/dist-client/tsconfig.tsbuildinfo +1 -0
  42. package/dist-server/controller/label-studio-role-mapper.d.ts +35 -0
  43. package/dist-server/controller/label-studio-role-mapper.js +65 -0
  44. package/dist-server/controller/label-studio-role-mapper.js.map +1 -0
  45. package/dist-server/controller/user-provisioning-service.d.ts +66 -0
  46. package/dist-server/controller/user-provisioning-service.js +264 -0
  47. package/dist-server/controller/user-provisioning-service.js.map +1 -0
  48. package/dist-server/index.d.ts +7 -0
  49. package/dist-server/index.js +19 -0
  50. package/dist-server/index.js.map +1 -0
  51. package/dist-server/route/label-studio-sso.d.ts +2 -0
  52. package/dist-server/route/label-studio-sso.js +156 -0
  53. package/dist-server/route/label-studio-sso.js.map +1 -0
  54. package/dist-server/route/webhook.d.ts +65 -0
  55. package/dist-server/route/webhook.js +248 -0
  56. package/dist-server/route/webhook.js.map +1 -0
  57. package/dist-server/route.d.ts +1 -0
  58. package/dist-server/route.js +21 -0
  59. package/dist-server/route.js.map +1 -0
  60. package/dist-server/service/ai-prediction-service.d.ts +27 -0
  61. package/dist-server/service/ai-prediction-service.js +222 -0
  62. package/dist-server/service/ai-prediction-service.js.map +1 -0
  63. package/dist-server/service/dataset-labeling-integration.d.ts +44 -0
  64. package/dist-server/service/dataset-labeling-integration.js +512 -0
  65. package/dist-server/service/dataset-labeling-integration.js.map +1 -0
  66. package/dist-server/service/external-data-source-service.d.ts +78 -0
  67. package/dist-server/service/external-data-source-service.js +415 -0
  68. package/dist-server/service/external-data-source-service.js.map +1 -0
  69. package/dist-server/service/index.d.ts +12 -0
  70. package/dist-server/service/index.js +27 -0
  71. package/dist-server/service/index.js.map +1 -0
  72. package/dist-server/service/label-studio-sso-service.d.ts +38 -0
  73. package/dist-server/service/label-studio-sso-service.js +98 -0
  74. package/dist-server/service/label-studio-sso-service.js.map +1 -0
  75. package/dist-server/service/ml/ml-backend-service.d.ts +23 -0
  76. package/dist-server/service/ml/ml-backend-service.js +153 -0
  77. package/dist-server/service/ml/ml-backend-service.js.map +1 -0
  78. package/dist-server/service/prediction/prediction-management.d.ts +32 -0
  79. package/dist-server/service/prediction/prediction-management.js +299 -0
  80. package/dist-server/service/prediction/prediction-management.js.map +1 -0
  81. package/dist-server/service/project/project-management.d.ts +36 -0
  82. package/dist-server/service/project/project-management.js +309 -0
  83. package/dist-server/service/project/project-management.js.map +1 -0
  84. package/dist-server/service/task/task-management.d.ts +42 -0
  85. package/dist-server/service/task/task-management.js +372 -0
  86. package/dist-server/service/task/task-management.js.map +1 -0
  87. package/dist-server/service/user-provisioning/user-sync-mutation.d.ts +28 -0
  88. package/dist-server/service/user-provisioning/user-sync-mutation.js +111 -0
  89. package/dist-server/service/user-provisioning/user-sync-mutation.js.map +1 -0
  90. package/dist-server/service/webhook/webhook-management.d.ts +21 -0
  91. package/dist-server/service/webhook/webhook-management.js +134 -0
  92. package/dist-server/service/webhook/webhook-management.js.map +1 -0
  93. package/dist-server/tsconfig.tsbuildinfo +1 -0
  94. package/dist-server/types/dataset-labeling-types.d.ts +71 -0
  95. package/dist-server/types/dataset-labeling-types.js +259 -0
  96. package/dist-server/types/dataset-labeling-types.js.map +1 -0
  97. package/dist-server/types/label-studio-types.d.ts +128 -0
  98. package/dist-server/types/label-studio-types.js +494 -0
  99. package/dist-server/types/label-studio-types.js.map +1 -0
  100. package/dist-server/types/prediction-types.d.ts +39 -0
  101. package/dist-server/types/prediction-types.js +121 -0
  102. package/dist-server/types/prediction-types.js.map +1 -0
  103. package/dist-server/utils/annotation-exporter.d.ts +104 -0
  104. package/dist-server/utils/annotation-exporter.js +261 -0
  105. package/dist-server/utils/annotation-exporter.js.map +1 -0
  106. package/dist-server/utils/label-config-builder.d.ts +117 -0
  107. package/dist-server/utils/label-config-builder.js +286 -0
  108. package/dist-server/utils/label-config-builder.js.map +1 -0
  109. package/dist-server/utils/label-studio-api-client.d.ts +180 -0
  110. package/dist-server/utils/label-studio-api-client.js +401 -0
  111. package/dist-server/utils/label-studio-api-client.js.map +1 -0
  112. package/dist-server/utils/media-url-extractor.d.ts +45 -0
  113. package/dist-server/utils/media-url-extractor.js +152 -0
  114. package/dist-server/utils/media-url-extractor.js.map +1 -0
  115. package/dist-server/utils/task-transformer.d.ts +108 -0
  116. package/dist-server/utils/task-transformer.js +260 -0
  117. package/dist-server/utils/task-transformer.js.map +1 -0
  118. package/package.json +47 -0
  119. package/server/SERVER_STRUCTURE.md +351 -0
  120. package/server/controller/label-studio-role-mapper.ts +76 -0
  121. package/server/controller/user-provisioning-service.ts +340 -0
  122. package/server/index.ts +19 -0
  123. package/server/route/label-studio-sso.ts +194 -0
  124. package/server/route/webhook.ts +304 -0
  125. package/server/route.ts +35 -0
  126. package/server/service/ai-prediction-service.ts +239 -0
  127. package/server/service/dataset-labeling-integration.ts +590 -0
  128. package/server/service/external-data-source-service.ts +438 -0
  129. package/server/service/index.ts +24 -0
  130. package/server/service/label-studio-sso-service.ts +108 -0
  131. package/server/service/labeling-scenario-service.ts.deprecated +566 -0
  132. package/server/service/ml/ml-backend-service.ts +127 -0
  133. package/server/service/prediction/prediction-management.ts +281 -0
  134. package/server/service/project/project-management.ts +284 -0
  135. package/server/service/task/task-management.ts +363 -0
  136. package/server/service/user-provisioning/user-sync-mutation.ts +80 -0
  137. package/server/service/webhook/webhook-management.ts +109 -0
  138. package/server/tsconfig.json +11 -0
  139. package/server/types/dataset-labeling-types.ts +181 -0
  140. package/server/types/global.d.ts +23 -0
  141. package/server/types/label-studio-types.ts +346 -0
  142. package/server/types/prediction-types.ts +86 -0
  143. package/server/types/scenario-types.ts.deprecated +362 -0
  144. package/server/utils/annotation-exporter.ts +340 -0
  145. package/server/utils/label-config-builder.ts +340 -0
  146. package/server/utils/label-studio-api-client.ts +487 -0
  147. package/server/utils/media-url-extractor.ts +193 -0
  148. package/server/utils/task-transformer.ts +342 -0
  149. package/test-ai-prediction.js +268 -0
  150. package/test-dataset-integration.js +449 -0
  151. package/test-simple.js +89 -0
  152. package/things-factory.config.js +12 -0
@@ -0,0 +1,395 @@
1
+ # Label Studio UI 커스터마이징 가이드
2
+
3
+ Things-Factory iframe에서 Label Studio UI를 커스터마이징하는 방법입니다.
4
+
5
+ > **기본 동작**: Things-Factory에서는 **항상 컨텐츠 전용 모드**로 Label Studio를 표시합니다.
6
+ > 헤더와 사이드바는 기본적으로 숨겨지며, 라벨링 영역만 표시됩니다.
7
+
8
+ ---
9
+
10
+ ## 🎨 UI 요소 제어
11
+
12
+ Label Studio는 `interfaces` 쿼리 파라미터를 통해 표시할 UI 요소를 제어할 수 있습니다.
13
+
14
+ ### interfaces 파라미터
15
+
16
+ URL에 `?interfaces=panel,controls,annotations:menu` 형식으로 추가하면 해당 UI 요소만 표시됩니다.
17
+
18
+ ---
19
+
20
+ ## 📋 사용 가능한 Interface 옵션
21
+
22
+ ### 기본 컨트롤
23
+
24
+ | Interface | 설명 | 권장 |
25
+ | ---------- | ----------------------------------- | ------- |
26
+ | `panel` | 네비게이션 패널 (undo, redo, reset) | ✅ 필수 |
27
+ | `controls` | 제출/업데이트/스킵 버튼 | ✅ 필수 |
28
+ | `update` | 업데이트 버튼 | ⚠️ 선택 |
29
+ | `submit` | 제출 버튼 | ⚠️ 선택 |
30
+ | `skip` | 스킵 버튼 | ⚠️ 선택 |
31
+
32
+ ### 상단바 요소
33
+
34
+ | Interface | 설명 | 권장 |
35
+ | ------------- | ------------------ | -------------------- |
36
+ | `topbar` | 상단 메뉴바 전체 | ❌ iframe에서 불필요 |
37
+ | `infobar` | 정보 표시줄 | ⚠️ 선택 |
38
+ | `instruction` | 작업 지시사항 버튼 | ⚠️ 선택 |
39
+
40
+ ### 사이드바 요소
41
+
42
+ | Interface | 설명 | 권장 |
43
+ | ---------------------- | ----------------------- | -------------------- |
44
+ | `side-column` | 좌측/우측 사이드바 | ❌ iframe에서 불필요 |
45
+ | `annotations:tabs` | Annotation 탭 | ⚠️ 선택 |
46
+ | `annotations:menu` | Annotation 메뉴 | ✅ 권장 |
47
+ | `annotations:current` | 현재 annotation 정보 | ⚠️ 선택 |
48
+ | `annotations:add-new` | 새 annotation 추가 버튼 | ⚠️ 선택 |
49
+ | `annotations:delete` | Annotation 삭제 버튼 | ⚠️ 선택 |
50
+ | `annotations:view-all` | 모든 annotation 보기 | ⚠️ 선택 |
51
+ | `annotations:history` | Annotation 히스토리 | ⚠️ 선택 |
52
+
53
+ ### Prediction 관련
54
+
55
+ | Interface | 설명 | 권장 |
56
+ | ------------------ | --------------- | ------- |
57
+ | `predictions:tabs` | Prediction 탭 | ⚠️ 선택 |
58
+ | `predictions:menu` | Prediction 메뉴 | ⚠️ 선택 |
59
+ | `auto-annotation` | 자동 annotation | ⚠️ 선택 |
60
+
61
+ ---
62
+
63
+ ## 🎯 추천 설정
64
+
65
+ ### 1. 최소 인터페이스 (iframe 임베딩 권장)
66
+
67
+ 컨텐츠에 집중하고 Things-Factory 내에서 사용하기에 최적:
68
+
69
+ ```javascript
70
+ const interfaces = [
71
+ 'panel', // 네비게이션 (undo, redo, reset)
72
+ 'controls', // 제출/업데이트/스킵
73
+ 'annotations:menu' // Annotation 메뉴
74
+ ]
75
+
76
+ // URL 예시:
77
+ // https://label-studio.com/projects/1/data?token=xxx&interfaces=panel,controls,annotations:menu
78
+ ```
79
+
80
+ **결과**: 헤더, 사이드바 없이 **순수 라벨링 영역만** 표시
81
+
82
+ ### 2. 표준 인터페이스
83
+
84
+ 일반적인 라벨링 작업에 적합:
85
+
86
+ ```javascript
87
+ const interfaces = [
88
+ 'panel',
89
+ 'controls',
90
+ 'infobar',
91
+ 'instruction',
92
+ 'annotations:menu',
93
+ 'annotations:add-new',
94
+ 'annotations:delete',
95
+ 'predictions:menu'
96
+ ]
97
+ ```
98
+
99
+ **결과**: 라벨링에 필요한 기본 기능 모두 포함
100
+
101
+ ### 3. 전체 인터페이스
102
+
103
+ Label Studio의 모든 기능 사용:
104
+
105
+ ```javascript
106
+ // interfaces 파라미터 없음 또는 빈 값
107
+ // URL 예시: https://label-studio.com/projects/1/data?token=xxx
108
+ ```
109
+
110
+ **결과**: Label Studio 전체 UI (헤더, 사이드바 포함)
111
+
112
+ ---
113
+
114
+ ## 💻 구현 방법
115
+
116
+ ### label-studio-wrapper.ts에서 설정
117
+
118
+ 현재 구현 (`client/label-studio-wrapper.ts`):
119
+
120
+ ```typescript
121
+ async buildIframeUrl() {
122
+ let url = this.config.serverUrl
123
+
124
+ // 프로토콜 확인
125
+ if (!url.startsWith('http://') && !url.startsWith('https://')) {
126
+ url = `https://${url}`
127
+ }
128
+
129
+ // 트레일링 슬래시 제거
130
+ url = url.replace(/\/$/, '')
131
+
132
+ const params = new URLSearchParams()
133
+
134
+ // SSO 토큰 추가
135
+ const token = await this.getAccessToken()
136
+ if (token) {
137
+ const param = this.config.ssoTokenParam || 'token'
138
+ params.set(param, token)
139
+ }
140
+
141
+ // UI 요소 제어 (항상 최소 인터페이스)
142
+ const interfaces = [
143
+ 'panel', // 네비게이션 (undo, redo, reset)
144
+ 'controls', // 제출, 업데이트, 스킵 버튼
145
+ 'annotations:menu' // Annotation 메뉴
146
+ ]
147
+ params.set('interfaces', interfaces.join(','))
148
+
149
+ this.iframeUrl = `${url}?${params.toString()}`
150
+ }
151
+
152
+ async getAccessToken(): Promise<string | null> {
153
+ try {
154
+ // localStorage에서 JWT 토큰 가져오기
155
+ const token = (window as any).auth?.token || localStorage.getItem('access-token')
156
+ return token
157
+ } catch (err) {
158
+ console.error('Failed to get access token:', err)
159
+ return null
160
+ }
161
+ }
162
+ ```
163
+
164
+ ### Things-Factory 기본 설정
165
+
166
+ Things-Factory는 **항상 최소 인터페이스 모드**를 사용합니다:
167
+
168
+ ```typescript
169
+ // 고정 설정
170
+ const interfaces = [
171
+ 'panel', // 네비게이션
172
+ 'controls', // 제출 버튼
173
+ 'annotations:menu' // Annotation 메뉴
174
+ ]
175
+ ```
176
+
177
+ 사용자가 전체 Label Studio UI를 사용하려면 별도로 Label Studio에 직접 접속해야 합니다.
178
+
179
+ ---
180
+
181
+ ## 🔧 커스터마이징 예시
182
+
183
+ ### 예시 1: 읽기 전용 모드
184
+
185
+ Annotation을 보기만 하고 수정 불가:
186
+
187
+ ```javascript
188
+ const interfaces = ['panel', 'annotations:menu', 'annotations:view-all']
189
+ // controls 없음 = 제출/수정 불가
190
+ ```
191
+
192
+ ### 예시 2: 리뷰어 모드
193
+
194
+ 기존 annotation을 검토하고 승인:
195
+
196
+ ```javascript
197
+ const interfaces = ['panel', 'controls', 'annotations:tabs', 'annotations:menu', 'annotations:history']
198
+ ```
199
+
200
+ ### 예시 3: 어노테이터 모드
201
+
202
+ 새로운 annotation 작성에 집중:
203
+
204
+ ```javascript
205
+ const interfaces = ['panel', 'controls', 'instruction', 'annotations:menu', 'annotations:add-new']
206
+ ```
207
+
208
+ ---
209
+
210
+ ## 🎨 CSS 커스터마이징 (고급)
211
+
212
+ Label Studio의 UI 요소를 CSS로 더 세밀하게 제어할 수 있습니다.
213
+
214
+ ### iframe 내부 스타일 적용
215
+
216
+ ⚠️ **주의**: Cross-origin iframe에서는 보안상 제약이 있습니다.
217
+
218
+ **방법 1**: Label Studio 테마 커스터마이징
219
+
220
+ Label Studio `settings.py`에서:
221
+
222
+ ```python
223
+ # Label Studio settings.py
224
+ LABEL_STUDIO_CUSTOM_CSS = """
225
+ /* 상단바 숨기기 */
226
+ .dm-header {
227
+ display: none !important;
228
+ }
229
+
230
+ /* 사이드바 숨기기 */
231
+ .dm-sidebar {
232
+ display: none !important;
233
+ }
234
+
235
+ /* 컨텐츠 영역 전체 활용 */
236
+ .dm-content {
237
+ margin: 0 !important;
238
+ padding: 0 !important;
239
+ }
240
+ """
241
+ ```
242
+
243
+ **방법 2**: 프로젝트별 스타일 (설정 가능 시)
244
+
245
+ Label Studio UI에서 Project Settings → Appearance에서 CSS 추가
246
+
247
+ ---
248
+
249
+ ## 📊 특정 페이지 직접 접근
250
+
251
+ ### 프로젝트 데이터 페이지
252
+
253
+ ```
254
+ https://label-studio.com/projects/{project_id}/data?token=xxx&interfaces=panel,controls
255
+ ```
256
+
257
+ ### 특정 태스크 라벨링 페이지
258
+
259
+ ```
260
+ https://label-studio.com/projects/{project_id}/data?task={task_id}&token=xxx&interfaces=panel,controls,annotations:menu
261
+ ```
262
+
263
+ ### 대시보드 (통계)
264
+
265
+ ```
266
+ https://label-studio.com/projects/{project_id}?token=xxx&interfaces=topbar,infobar
267
+ ```
268
+
269
+ ---
270
+
271
+ ## 🔄 커스텀 인터페이스 설정 (선택사항)
272
+
273
+ Things-Factory 설정 파일에서 인터페이스를 커스터마이징할 수 있습니다:
274
+
275
+ **config/label-studio.config.js**:
276
+ ```javascript
277
+ module.exports = {
278
+ labelStudio: {
279
+ serverUrl: process.env.LABEL_STUDIO_URL || 'http://localhost:8080',
280
+ apiToken: process.env.LABEL_STUDIO_API_TOKEN || '',
281
+ // 표시할 UI 요소 커스터마이징
282
+ interfaces: 'panel,controls,annotations:menu,annotations:add-new,predictions:menu'
283
+ }
284
+ }
285
+ ```
286
+
287
+ **사용 가능한 interfaces 옵션**:
288
+ - `panel`: 네비게이션 패널 (undo, redo, reset)
289
+ - `controls`: 제출/업데이트/스킵 버튼
290
+ - `annotations:menu`: Annotation 메뉴
291
+ - `annotations:add-new`: 새 annotation 추가 버튼
292
+ - `annotations:delete`: Annotation 삭제 버튼
293
+ - `predictions:menu`: Prediction 메뉴
294
+ - `infobar`: 정보 표시줄
295
+ - `instruction`: 작업 지시사항 버튼
296
+
297
+ **주의**: `topbar`, `side-column` 등의 옵션은 iframe 통합에서 권장하지 않습니다.
298
+
299
+ ---
300
+
301
+ ## ⚠️ 제한사항
302
+
303
+ ### 1. Label Studio 버전 호환성
304
+
305
+ - `interfaces` 파라미터는 Label Studio 1.5.0+ 지원
306
+ - 일부 interface 옵션은 최신 버전에서만 작동
307
+
308
+ ### 2. Cross-origin 제약
309
+
310
+ - iframe 내부 DOM에 직접 접근 불가 (same-origin policy)
311
+ - CSS 주입은 Label Studio 서버 측에서 설정 필요
312
+
313
+ ### 3. URL 길이 제한
314
+
315
+ - 너무 많은 파라미터는 URL 길이 제한에 걸릴 수 있음
316
+ - 일반적으로 2048자 이내 권장
317
+
318
+ ---
319
+
320
+ ## 🧪 테스트 방법
321
+
322
+ ### 1. 브라우저 개발자 도구에서 직접 테스트
323
+
324
+ ```javascript
325
+ // 콘솔에서 실행
326
+ const baseUrl = 'https://label-studio.example.com/projects/1/data'
327
+ const token = 'your-jwt-token'
328
+ const interfaces = 'panel,controls,annotations:menu'
329
+
330
+ window.open(`${baseUrl}?token=${token}&interfaces=${interfaces}`)
331
+ ```
332
+
333
+ ### 2. iframe src 확인
334
+
335
+ Things-Factory에서 iframe 로드 후:
336
+
337
+ ```javascript
338
+ // 브라우저 콘솔
339
+ document.querySelector('iframe').src
340
+ ```
341
+
342
+ **예상 출력**:
343
+
344
+ ```
345
+ https://label-studio.example.com/projects/1/data?token=eyJhbGc...&interfaces=panel,controls,annotations:menu
346
+ ```
347
+
348
+ ### 3. 다양한 조합 테스트
349
+
350
+ ```bash
351
+ # 최소 인터페이스
352
+ ?interfaces=panel,controls
353
+
354
+ # 표준 인터페이스
355
+ ?interfaces=panel,controls,annotations:menu,annotations:add-new
356
+
357
+ # 전체 인터페이스
358
+ (interfaces 파라미터 없음)
359
+ ```
360
+
361
+ ---
362
+
363
+ ## 📚 참고 자료
364
+
365
+ - [Label Studio Frontend Documentation](https://labelstud.io/guide/frontend.html)
366
+ - [Label Studio Frontend Library Reference](https://labelstud.io/guide/frontend_reference)
367
+ - [Label Studio Frontend GitHub](https://github.com/HumanSignal/label-studio-frontend)
368
+
369
+ ---
370
+
371
+ ## 💡 권장 설정 요약
372
+
373
+ **Things-Factory iframe 임베딩 권장 설정**:
374
+
375
+ ```typescript
376
+ // label-studio-wrapper.ts
377
+ const interfaces = [
378
+ 'panel', // ✅ 네비게이션 필수
379
+ 'controls', // ✅ 제출 버튼 필수
380
+ 'annotations:menu' // ✅ Annotation 메뉴 필수
381
+ ]
382
+ ```
383
+
384
+ **결과**:
385
+
386
+ - ✅ 헤더 숨김
387
+ - ✅ 사이드바 숨김
388
+ - ✅ 순수 라벨링 컨텐츠만 표시
389
+ - ✅ Things-Factory UI와 자연스럽게 통합
390
+
391
+ ---
392
+
393
+ **문서 버전**: 1.0
394
+ **작성일**: 2025-10-02
395
+ **Label Studio 호환**: 1.5.0+