@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.
- package/CHANGELOG.md +85 -0
- package/EXTERNAL_DATA_SOURCING.md +484 -0
- package/IMPLEMENTATION_GUIDE.md +469 -0
- package/INTEGRATION.md +279 -0
- package/README.md +1014 -0
- package/SETUP_GUIDE.md +577 -0
- package/TEST_GUIDE.md +387 -0
- package/UI_CUSTOMIZATION.md +395 -0
- package/USER_SYNC_GUIDE.md +514 -0
- package/client/bootstrap.ts +1 -0
- package/client/index.ts +1 -0
- package/client/label-studio-label-page.ts +52 -0
- package/client/label-studio-project-create.ts +216 -0
- package/client/label-studio-project-list.ts +214 -0
- package/client/label-studio-wrapper.ts +294 -0
- package/client/route.ts +15 -0
- package/client/tsconfig.json +13 -0
- package/config/config.development.js +124 -0
- package/config/config.production.js +182 -0
- package/dist-client/bootstrap.d.ts +1 -0
- package/dist-client/bootstrap.js +2 -0
- package/dist-client/bootstrap.js.map +1 -0
- package/dist-client/index.d.ts +1 -0
- package/dist-client/index.js +2 -0
- package/dist-client/index.js.map +1 -0
- package/dist-client/label-studio-label-page.d.ts +8 -0
- package/dist-client/label-studio-label-page.js +54 -0
- package/dist-client/label-studio-label-page.js.map +1 -0
- package/dist-client/label-studio-project-create.d.ts +16 -0
- package/dist-client/label-studio-project-create.js +235 -0
- package/dist-client/label-studio-project-create.js.map +1 -0
- package/dist-client/label-studio-project-list.d.ts +16 -0
- package/dist-client/label-studio-project-list.js +222 -0
- package/dist-client/label-studio-project-list.js.map +1 -0
- package/dist-client/label-studio-wrapper.d.ts +57 -0
- package/dist-client/label-studio-wrapper.js +304 -0
- package/dist-client/label-studio-wrapper.js.map +1 -0
- package/dist-client/route.d.ts +1 -0
- package/dist-client/route.js +14 -0
- package/dist-client/route.js.map +1 -0
- package/dist-client/tsconfig.tsbuildinfo +1 -0
- package/dist-server/controller/label-studio-role-mapper.d.ts +35 -0
- package/dist-server/controller/label-studio-role-mapper.js +65 -0
- package/dist-server/controller/label-studio-role-mapper.js.map +1 -0
- package/dist-server/controller/user-provisioning-service.d.ts +66 -0
- package/dist-server/controller/user-provisioning-service.js +264 -0
- package/dist-server/controller/user-provisioning-service.js.map +1 -0
- package/dist-server/index.d.ts +7 -0
- package/dist-server/index.js +19 -0
- package/dist-server/index.js.map +1 -0
- package/dist-server/route/label-studio-sso.d.ts +2 -0
- package/dist-server/route/label-studio-sso.js +156 -0
- package/dist-server/route/label-studio-sso.js.map +1 -0
- package/dist-server/route/webhook.d.ts +65 -0
- package/dist-server/route/webhook.js +248 -0
- package/dist-server/route/webhook.js.map +1 -0
- package/dist-server/route.d.ts +1 -0
- package/dist-server/route.js +21 -0
- package/dist-server/route.js.map +1 -0
- package/dist-server/service/ai-prediction-service.d.ts +27 -0
- package/dist-server/service/ai-prediction-service.js +222 -0
- package/dist-server/service/ai-prediction-service.js.map +1 -0
- package/dist-server/service/dataset-labeling-integration.d.ts +44 -0
- package/dist-server/service/dataset-labeling-integration.js +512 -0
- package/dist-server/service/dataset-labeling-integration.js.map +1 -0
- package/dist-server/service/external-data-source-service.d.ts +78 -0
- package/dist-server/service/external-data-source-service.js +415 -0
- package/dist-server/service/external-data-source-service.js.map +1 -0
- package/dist-server/service/index.d.ts +12 -0
- package/dist-server/service/index.js +27 -0
- package/dist-server/service/index.js.map +1 -0
- package/dist-server/service/label-studio-sso-service.d.ts +38 -0
- package/dist-server/service/label-studio-sso-service.js +98 -0
- package/dist-server/service/label-studio-sso-service.js.map +1 -0
- package/dist-server/service/ml/ml-backend-service.d.ts +23 -0
- package/dist-server/service/ml/ml-backend-service.js +153 -0
- package/dist-server/service/ml/ml-backend-service.js.map +1 -0
- package/dist-server/service/prediction/prediction-management.d.ts +32 -0
- package/dist-server/service/prediction/prediction-management.js +299 -0
- package/dist-server/service/prediction/prediction-management.js.map +1 -0
- package/dist-server/service/project/project-management.d.ts +36 -0
- package/dist-server/service/project/project-management.js +309 -0
- package/dist-server/service/project/project-management.js.map +1 -0
- package/dist-server/service/task/task-management.d.ts +42 -0
- package/dist-server/service/task/task-management.js +372 -0
- package/dist-server/service/task/task-management.js.map +1 -0
- package/dist-server/service/user-provisioning/user-sync-mutation.d.ts +28 -0
- package/dist-server/service/user-provisioning/user-sync-mutation.js +111 -0
- package/dist-server/service/user-provisioning/user-sync-mutation.js.map +1 -0
- package/dist-server/service/webhook/webhook-management.d.ts +21 -0
- package/dist-server/service/webhook/webhook-management.js +134 -0
- package/dist-server/service/webhook/webhook-management.js.map +1 -0
- package/dist-server/tsconfig.tsbuildinfo +1 -0
- package/dist-server/types/dataset-labeling-types.d.ts +71 -0
- package/dist-server/types/dataset-labeling-types.js +259 -0
- package/dist-server/types/dataset-labeling-types.js.map +1 -0
- package/dist-server/types/label-studio-types.d.ts +128 -0
- package/dist-server/types/label-studio-types.js +494 -0
- package/dist-server/types/label-studio-types.js.map +1 -0
- package/dist-server/types/prediction-types.d.ts +39 -0
- package/dist-server/types/prediction-types.js +121 -0
- package/dist-server/types/prediction-types.js.map +1 -0
- package/dist-server/utils/annotation-exporter.d.ts +104 -0
- package/dist-server/utils/annotation-exporter.js +261 -0
- package/dist-server/utils/annotation-exporter.js.map +1 -0
- package/dist-server/utils/label-config-builder.d.ts +117 -0
- package/dist-server/utils/label-config-builder.js +286 -0
- package/dist-server/utils/label-config-builder.js.map +1 -0
- package/dist-server/utils/label-studio-api-client.d.ts +180 -0
- package/dist-server/utils/label-studio-api-client.js +401 -0
- package/dist-server/utils/label-studio-api-client.js.map +1 -0
- package/dist-server/utils/media-url-extractor.d.ts +45 -0
- package/dist-server/utils/media-url-extractor.js +152 -0
- package/dist-server/utils/media-url-extractor.js.map +1 -0
- package/dist-server/utils/task-transformer.d.ts +108 -0
- package/dist-server/utils/task-transformer.js +260 -0
- package/dist-server/utils/task-transformer.js.map +1 -0
- package/package.json +47 -0
- package/server/SERVER_STRUCTURE.md +351 -0
- package/server/controller/label-studio-role-mapper.ts +76 -0
- package/server/controller/user-provisioning-service.ts +340 -0
- package/server/index.ts +19 -0
- package/server/route/label-studio-sso.ts +194 -0
- package/server/route/webhook.ts +304 -0
- package/server/route.ts +35 -0
- package/server/service/ai-prediction-service.ts +239 -0
- package/server/service/dataset-labeling-integration.ts +590 -0
- package/server/service/external-data-source-service.ts +438 -0
- package/server/service/index.ts +24 -0
- package/server/service/label-studio-sso-service.ts +108 -0
- package/server/service/labeling-scenario-service.ts.deprecated +566 -0
- package/server/service/ml/ml-backend-service.ts +127 -0
- package/server/service/prediction/prediction-management.ts +281 -0
- package/server/service/project/project-management.ts +284 -0
- package/server/service/task/task-management.ts +363 -0
- package/server/service/user-provisioning/user-sync-mutation.ts +80 -0
- package/server/service/webhook/webhook-management.ts +109 -0
- package/server/tsconfig.json +11 -0
- package/server/types/dataset-labeling-types.ts +181 -0
- package/server/types/global.d.ts +23 -0
- package/server/types/label-studio-types.ts +346 -0
- package/server/types/prediction-types.ts +86 -0
- package/server/types/scenario-types.ts.deprecated +362 -0
- package/server/utils/annotation-exporter.ts +340 -0
- package/server/utils/label-config-builder.ts +340 -0
- package/server/utils/label-studio-api-client.ts +487 -0
- package/server/utils/media-url-extractor.ts +193 -0
- package/server/utils/task-transformer.ts +342 -0
- package/test-ai-prediction.js +268 -0
- package/test-dataset-integration.js +449 -0
- package/test-simple.js +89 -0
- package/things-factory.config.js +12 -0
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
# Label Studio Integration - Server 모듈 구조
|
|
2
|
+
|
|
3
|
+
Things-Factory Label Studio 통합 서버 모듈의 최종 정리된 구조입니다.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 📁 디렉토리 구조
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
server/
|
|
11
|
+
├── controller/ # 비즈니스 로직
|
|
12
|
+
│ └── label-studio-role-mapper.ts # 권한 매핑 로직
|
|
13
|
+
├── service/ # GraphQL 서비스
|
|
14
|
+
│ ├── user-provisioning/
|
|
15
|
+
│ │ ├── user-provisioning-service.ts # 사용자 동기화 서비스
|
|
16
|
+
│ │ ├── user-sync-mutation.ts # GraphQL Mutation
|
|
17
|
+
│ │ └── index.ts
|
|
18
|
+
│ └── index.ts # 서비스 통합
|
|
19
|
+
├── index.ts # 서버 모듈 진입점
|
|
20
|
+
└── route.ts # 메뉴 등록
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 📋 파일별 역할
|
|
26
|
+
|
|
27
|
+
### 1. **controller/label-studio-role-mapper.ts**
|
|
28
|
+
|
|
29
|
+
Things-Factory 사용자 권한을 Label Studio 권한으로 매핑
|
|
30
|
+
|
|
31
|
+
**주요 기능**:
|
|
32
|
+
|
|
33
|
+
- `mapUserPermissions(domain, user)`: 권한 매핑
|
|
34
|
+
- `getPermissionsDescription(permissions)`: 권한 설명
|
|
35
|
+
|
|
36
|
+
**매핑 규칙**:
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
// 1. label-studio 카테고리 권한 있음 → Staff
|
|
40
|
+
// 2. user.owner === true → Admin
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**반환값**:
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
interface LabelStudioPermissions {
|
|
47
|
+
is_superuser: boolean // Admin 여부
|
|
48
|
+
is_staff: boolean // Django admin 접근
|
|
49
|
+
is_active: boolean // 활성화 여부
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
### 2. **service/user-provisioning/user-provisioning-service.ts**
|
|
56
|
+
|
|
57
|
+
Label Studio API를 통한 사용자 동기화 서비스
|
|
58
|
+
|
|
59
|
+
**주요 메서드**:
|
|
60
|
+
|
|
61
|
+
#### `syncUser(domain, user): Promise<SyncResult>`
|
|
62
|
+
|
|
63
|
+
개별 사용자를 Label Studio에 동기화
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
// 1. 권한 확인
|
|
67
|
+
const hasLSPrivilege = await User.hasPrivilege('label-studio', ...)
|
|
68
|
+
|
|
69
|
+
// 2. 권한 매핑
|
|
70
|
+
const lsPermissions = await LabelStudioRoleMapper.mapUserPermissions(domain, user)
|
|
71
|
+
|
|
72
|
+
// 3. Label Studio API 호출
|
|
73
|
+
const result = await createOrUpdateLabelStudioUser(...)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
#### `syncAllUsers(domain): Promise<SyncSummary>`
|
|
77
|
+
|
|
78
|
+
도메인의 모든 사용자를 일괄 동기화
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
const users = await getDomainUsers(domain)
|
|
82
|
+
for (const user of users) {
|
|
83
|
+
await syncUser(domain, user)
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
#### `getDomainUsers(domain): Promise<User[]>`
|
|
88
|
+
|
|
89
|
+
도메인의 모든 사용자 조회 (users_domains 테이블 조인)
|
|
90
|
+
|
|
91
|
+
**Helper 메서드**:
|
|
92
|
+
|
|
93
|
+
- `createOrUpdateLabelStudioUser()`: 사용자 생성/수정
|
|
94
|
+
- `deactivateUser()`: 사용자 비활성화
|
|
95
|
+
- `buildApiUrl()`: API URL 생성
|
|
96
|
+
- `generateRandomPassword()`: 랜덤 패스워드 생성
|
|
97
|
+
- `sleep()`: Rate Limiting 방지
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
### 3. **service/user-provisioning/user-sync-mutation.ts**
|
|
102
|
+
|
|
103
|
+
GraphQL Mutation 정의
|
|
104
|
+
|
|
105
|
+
**Mutations**:
|
|
106
|
+
|
|
107
|
+
#### `syncMyUserToLabelStudio`
|
|
108
|
+
|
|
109
|
+
```graphql
|
|
110
|
+
mutation {
|
|
111
|
+
syncMyUserToLabelStudio {
|
|
112
|
+
success
|
|
113
|
+
email
|
|
114
|
+
action
|
|
115
|
+
lsPermissions
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**권한**: `@privilege(category: "label-studio", privilege: "staff")`
|
|
121
|
+
|
|
122
|
+
#### `syncAllUsersToLabelStudio`
|
|
123
|
+
|
|
124
|
+
```graphql
|
|
125
|
+
mutation {
|
|
126
|
+
syncAllUsersToLabelStudio {
|
|
127
|
+
total
|
|
128
|
+
created
|
|
129
|
+
updated
|
|
130
|
+
deactivated
|
|
131
|
+
skipped
|
|
132
|
+
errors
|
|
133
|
+
results {
|
|
134
|
+
email
|
|
135
|
+
action
|
|
136
|
+
lsPermissions
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**권한**: `@privilege(category: "label-studio", privilege: "admin")`
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
### 4. **service/index.ts**
|
|
147
|
+
|
|
148
|
+
GraphQL 리졸버 통합
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
export const resolvers = [UserSyncMutation]
|
|
152
|
+
export * from './user-provisioning/index.js'
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
### 5. **index.ts**
|
|
158
|
+
|
|
159
|
+
서버 모듈 진입점
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
export * from './service/index.js'
|
|
163
|
+
import './route.js'
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## 🔄 데이터 흐름
|
|
169
|
+
|
|
170
|
+
### 사용자 동기화 플로우
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
1. GraphQL Mutation 호출
|
|
174
|
+
↓
|
|
175
|
+
2. user-sync-mutation.ts
|
|
176
|
+
- 설정 검증 (apiToken 확인)
|
|
177
|
+
↓
|
|
178
|
+
3. user-provisioning-service.ts
|
|
179
|
+
- 권한 확인 (User.hasPrivilege)
|
|
180
|
+
↓
|
|
181
|
+
4. label-studio-role-mapper.ts
|
|
182
|
+
- 권한 매핑 (label-studio 카테고리 → Staff/Admin)
|
|
183
|
+
↓
|
|
184
|
+
5. Label Studio API 호출
|
|
185
|
+
- POST/PATCH /api/users
|
|
186
|
+
- is_superuser, is_staff, is_active 설정
|
|
187
|
+
↓
|
|
188
|
+
6. 결과 반환
|
|
189
|
+
- SyncResult / SyncSummary
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## 🔧 설정
|
|
195
|
+
|
|
196
|
+
### config/config.development.js
|
|
197
|
+
|
|
198
|
+
```javascript
|
|
199
|
+
labelStudio: {
|
|
200
|
+
serverUrl: 'http://localhost:8080',
|
|
201
|
+
apiToken: '', // Label Studio API Token
|
|
202
|
+
interfaces: 'panel,controls,annotations:menu'
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### 설정 사용
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
import { config } from '@things-factory/env'
|
|
210
|
+
|
|
211
|
+
const labelStudioConfig = config.get('labelStudio', {
|
|
212
|
+
serverUrl: '',
|
|
213
|
+
apiToken: '',
|
|
214
|
+
interfaces: 'panel,controls,annotations:menu'
|
|
215
|
+
})
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## 🗑️ 제거된 항목
|
|
221
|
+
|
|
222
|
+
### 1. **LabelStudioConfig Entity**
|
|
223
|
+
|
|
224
|
+
- 엔티티 DB 저장 제거
|
|
225
|
+
- config 파일로 대체
|
|
226
|
+
|
|
227
|
+
### 2. **label-studio-config 폴더**
|
|
228
|
+
|
|
229
|
+
- `label-studio-config.ts` (Entity)
|
|
230
|
+
- `label-studio-config-query.ts` (Query)
|
|
231
|
+
- `label-studio-config-mutation.ts` (Mutation)
|
|
232
|
+
|
|
233
|
+
### 3. **role-mapping 폴더**
|
|
234
|
+
|
|
235
|
+
- `label-studio-role-mapper.ts` → controller로 이동
|
|
236
|
+
|
|
237
|
+
### 4. **불필요한 메서드**
|
|
238
|
+
|
|
239
|
+
- `getOrganizationId()` - Community Edition 미사용
|
|
240
|
+
- `createOrganizationMembership()` - Community Edition 미사용
|
|
241
|
+
- `updateOrganizationMembership()` - Community Edition 미사용
|
|
242
|
+
|
|
243
|
+
### 5. **entities 배열**
|
|
244
|
+
|
|
245
|
+
- `service/index.ts`의 빈 entities 배열 제거
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## 📊 권한 체계
|
|
250
|
+
|
|
251
|
+
### Things-Factory 권한
|
|
252
|
+
|
|
253
|
+
| Privilege Category | 설명 |
|
|
254
|
+
| ----------------------- | ---------------------- |
|
|
255
|
+
| `label-studio:query` | Label Studio 조회 권한 |
|
|
256
|
+
| `label-studio:mutation` | Label Studio 수정 권한 |
|
|
257
|
+
| `label-studio:staff` | Staff 전용 mutation |
|
|
258
|
+
| `label-studio:admin` | Admin 전용 mutation |
|
|
259
|
+
|
|
260
|
+
### Label Studio 권한 (Community Edition)
|
|
261
|
+
|
|
262
|
+
| 플래그 | 설명 |
|
|
263
|
+
| --------------------- | ----------------- |
|
|
264
|
+
| `is_superuser: true` | Admin (모든 권한) |
|
|
265
|
+
| `is_superuser: false` | Staff (라벨링만) |
|
|
266
|
+
| `is_active: false` | 비활성화 |
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## 🧪 테스트
|
|
271
|
+
|
|
272
|
+
### 1. 개인 동기화
|
|
273
|
+
|
|
274
|
+
```graphql
|
|
275
|
+
mutation {
|
|
276
|
+
syncMyUserToLabelStudio {
|
|
277
|
+
success
|
|
278
|
+
email
|
|
279
|
+
action
|
|
280
|
+
lsPermissions
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### 2. 전체 동기화
|
|
286
|
+
|
|
287
|
+
```graphql
|
|
288
|
+
mutation {
|
|
289
|
+
syncAllUsersToLabelStudio {
|
|
290
|
+
total
|
|
291
|
+
created
|
|
292
|
+
updated
|
|
293
|
+
results {
|
|
294
|
+
email
|
|
295
|
+
lsPermissions
|
|
296
|
+
error
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## 📝 코드 규칙
|
|
305
|
+
|
|
306
|
+
### 1. 권한 확인
|
|
307
|
+
|
|
308
|
+
```typescript
|
|
309
|
+
// User.hasPrivilege 사용
|
|
310
|
+
const hasPrivilege = await User.hasPrivilege('label-studio', 'query', domain, user)
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### 2. 설정 가져오기
|
|
314
|
+
|
|
315
|
+
```typescript
|
|
316
|
+
// config.get 사용
|
|
317
|
+
const config = config.get('labelStudio', {
|
|
318
|
+
serverUrl: '',
|
|
319
|
+
apiToken: '',
|
|
320
|
+
interfaces: 'panel,controls,annotations:menu'
|
|
321
|
+
})
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### 3. API 호출
|
|
325
|
+
|
|
326
|
+
```typescript
|
|
327
|
+
// axios 사용
|
|
328
|
+
await axios.patch(`${apiUrl}/users/${id}/`, data, {
|
|
329
|
+
headers: {
|
|
330
|
+
Authorization: `Token ${config.apiToken}`,
|
|
331
|
+
'Content-Type': 'application/json'
|
|
332
|
+
}
|
|
333
|
+
})
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## 🚀 향후 확장
|
|
339
|
+
|
|
340
|
+
### 가능한 개선사항
|
|
341
|
+
|
|
342
|
+
1. **Batch API 지원**: 여러 사용자 한 번에 동기화
|
|
343
|
+
2. **Webhook 연동**: Label Studio → Things-Factory 이벤트
|
|
344
|
+
3. **동기화 스케줄러**: 주기적 자동 동기화
|
|
345
|
+
4. **에러 재시도 로직**: 실패 시 재시도
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
**문서 버전**: 1.0
|
|
350
|
+
**작성일**: 2025-10-03
|
|
351
|
+
**정리 완료**: ✅
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Domain } from '@things-factory/shell'
|
|
2
|
+
import { User } from '@things-factory/auth-base'
|
|
3
|
+
/**
|
|
4
|
+
* Label Studio Community Edition 권한
|
|
5
|
+
* Community Edition은 Django의 is_superuser 플래그만 사용
|
|
6
|
+
*/
|
|
7
|
+
export interface LabelStudioPermissions {
|
|
8
|
+
is_superuser: boolean // true: 관리자, false: 일반 사용자
|
|
9
|
+
is_staff: boolean // Django admin 페이지 접근 (일반적으로 is_superuser와 동일)
|
|
10
|
+
is_active: boolean // 활성화 여부
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Things-Factory Role → Label Studio Permissions 매핑
|
|
15
|
+
* Community Edition용 (2단계 권한)
|
|
16
|
+
*/
|
|
17
|
+
export class LabelStudioRoleMapper {
|
|
18
|
+
/**
|
|
19
|
+
* Things-Factory 사용자의 권한을 분석하여 Label Studio 권한 결정
|
|
20
|
+
*
|
|
21
|
+
* 매핑 규칙:
|
|
22
|
+
* 1. privilege category에 'label-studio'가 포함되어 있으면 → Staff 권한
|
|
23
|
+
* 2. user.admin === true 이면 → Admin 권한
|
|
24
|
+
*
|
|
25
|
+
* @param user Things-Factory 사용자
|
|
26
|
+
* @returns Label Studio 권한 (is_superuser, is_staff, is_active)
|
|
27
|
+
*/
|
|
28
|
+
static async mapUserPermissions(domain: Domain, user: User): Promise<LabelStudioPermissions> {
|
|
29
|
+
// 사용자의 권한 조회
|
|
30
|
+
// 1. Label Studio 관련 권한이 있는지 확인 (category에 'label-studio' 포함)
|
|
31
|
+
const hasLabelStudioPrivilege =
|
|
32
|
+
(await User.hasPrivilege('label-studio', 'query', domain, user)) ||
|
|
33
|
+
(await User.hasPrivilege('label-studio', 'mutation', domain, user))
|
|
34
|
+
|
|
35
|
+
// Label Studio 권한이 없으면 비활성화
|
|
36
|
+
if (!hasLabelStudioPrivilege) {
|
|
37
|
+
return {
|
|
38
|
+
is_superuser: false,
|
|
39
|
+
is_staff: false,
|
|
40
|
+
is_active: false
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// 2. user.owner 플래그 확인
|
|
45
|
+
if (user.owner === true) {
|
|
46
|
+
return {
|
|
47
|
+
is_superuser: true,
|
|
48
|
+
is_staff: true,
|
|
49
|
+
is_active: true
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// 3. Label Studio 권한은 있지만 owner가 아닌 경우 → Staff
|
|
54
|
+
return {
|
|
55
|
+
is_superuser: false,
|
|
56
|
+
is_staff: false,
|
|
57
|
+
is_active: true
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Label Studio 권한 설명 반환 (디버깅/로깅용)
|
|
63
|
+
*
|
|
64
|
+
* @param permissions Label Studio 권한
|
|
65
|
+
* @returns 권한 설명
|
|
66
|
+
*/
|
|
67
|
+
static getPermissionsDescription(permissions: LabelStudioPermissions): string {
|
|
68
|
+
if (!permissions.is_active) {
|
|
69
|
+
return 'Inactive (No Label Studio access)'
|
|
70
|
+
}
|
|
71
|
+
if (permissions.is_superuser) {
|
|
72
|
+
return 'Admin (Full access)'
|
|
73
|
+
}
|
|
74
|
+
return 'Staff (Labeling only)'
|
|
75
|
+
}
|
|
76
|
+
}
|