@winwinmbs/portal-api 1.0.0
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/README.md +29 -0
- package/dist/_tsup-dts-rollup.d.mts +4113 -0
- package/dist/_tsup-dts-rollup.d.ts +4113 -0
- package/dist/index.d.mts +120 -0
- package/dist/index.d.ts +120 -0
- package/dist/index.js +2144 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2085 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +40 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,2085 @@
|
|
|
1
|
+
// src/portal-api-client.ts
|
|
2
|
+
import axios from "axios";
|
|
3
|
+
|
|
4
|
+
// src/api/health.api.ts
|
|
5
|
+
var HealthAPI = class {
|
|
6
|
+
constructor(axios2) {
|
|
7
|
+
this.axios = axios2;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Check API health
|
|
11
|
+
*/
|
|
12
|
+
async check() {
|
|
13
|
+
const response = await this.axios.get("/health");
|
|
14
|
+
return response.data;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Validate if API key is still active
|
|
18
|
+
*/
|
|
19
|
+
async validateApiKey() {
|
|
20
|
+
try {
|
|
21
|
+
await this.check();
|
|
22
|
+
return true;
|
|
23
|
+
} catch (error) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// src/utils/logger.ts
|
|
30
|
+
var Logger = class {
|
|
31
|
+
constructor() {
|
|
32
|
+
this.config = {
|
|
33
|
+
enabled: true,
|
|
34
|
+
logLevel: typeof process !== "undefined" && process.env?.NODE_ENV === "production" ? "warn" : "debug"
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
shouldLog(level) {
|
|
38
|
+
if (!this.config.enabled) return false;
|
|
39
|
+
const levels = ["debug", "info", "warn", "error"];
|
|
40
|
+
const currentLevelIndex = levels.indexOf(this.config.logLevel);
|
|
41
|
+
const messageLevelIndex = levels.indexOf(level);
|
|
42
|
+
return messageLevelIndex >= currentLevelIndex;
|
|
43
|
+
}
|
|
44
|
+
debug(...args) {
|
|
45
|
+
if (this.shouldLog("debug")) {
|
|
46
|
+
console.log("[AuthClient]", ...args);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
info(...args) {
|
|
50
|
+
if (this.shouldLog("info")) {
|
|
51
|
+
console.log("[AuthClient]", ...args);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
warn(...args) {
|
|
55
|
+
if (this.shouldLog("warn")) {
|
|
56
|
+
console.warn("[AuthClient]", ...args);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
error(...args) {
|
|
60
|
+
if (this.shouldLog("error")) {
|
|
61
|
+
console.error("[AuthClient]", ...args);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* อัพเดท logging config
|
|
66
|
+
*
|
|
67
|
+
* @param config - Partial config เพื่อ merge กับ config ปัจจุบัน
|
|
68
|
+
*/
|
|
69
|
+
setConfig(config) {
|
|
70
|
+
this.config = { ...this.config, ...config };
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* ตรวจสอบว่า logging เปิดอยู่หรือไม่
|
|
74
|
+
*/
|
|
75
|
+
isEnabled() {
|
|
76
|
+
return this.config.enabled;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* ดู log level ปัจจุบัน
|
|
80
|
+
*/
|
|
81
|
+
getLogLevel() {
|
|
82
|
+
return this.config.logLevel;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
var logger = new Logger();
|
|
86
|
+
|
|
87
|
+
// src/api/system-config.api.ts
|
|
88
|
+
var SystemConfigAPI = class {
|
|
89
|
+
constructor(axios2) {
|
|
90
|
+
this.axios = axios2;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* GET /system-configs/categories/:category
|
|
94
|
+
* ดึง configs ตาม category - ส่ง object ที่รวมทุก key เป็น { key1: value1, key2: value2 }
|
|
95
|
+
*/
|
|
96
|
+
async getByCategory(category) {
|
|
97
|
+
const response = await this.axios.get(
|
|
98
|
+
`/system-configs/categories/${category}`
|
|
99
|
+
);
|
|
100
|
+
logger.debug("SystemConfigAPI getByCategory response:", response.data.data);
|
|
101
|
+
return response.data.data;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* GET /system-configs/categories/:category/:key
|
|
105
|
+
* ดึง config value ตรงๆ (API returns config.value directly, NOT the full SystemConfig row)
|
|
106
|
+
*/
|
|
107
|
+
async getByCategoryAndKey(category, key) {
|
|
108
|
+
const response = await this.axios.get(`/system-configs/categories/${category}/${key}`);
|
|
109
|
+
logger.debug("SystemConfigAPI getByCategoryAndKey response:", response.data.data);
|
|
110
|
+
return response.data.data;
|
|
111
|
+
}
|
|
112
|
+
async get(category, key) {
|
|
113
|
+
if (key) {
|
|
114
|
+
return await this.getByCategoryAndKey(category, key);
|
|
115
|
+
}
|
|
116
|
+
return await this.getByCategory(category);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* GET /system-configs/categories/security/session_management
|
|
120
|
+
* ดึง Session Management configuration (convenience method)
|
|
121
|
+
*/
|
|
122
|
+
async getSessionManagement() {
|
|
123
|
+
return this.get("security", "session_management");
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* GET /system-configs/categories/security/jwt
|
|
127
|
+
* ดึง Security JWT configuration (convenience method)
|
|
128
|
+
*/
|
|
129
|
+
async getSecurityJwt() {
|
|
130
|
+
return this.get("security", "jwt");
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
// src/api/files.api.ts
|
|
135
|
+
var FilesAPI = class {
|
|
136
|
+
constructor(axios2) {
|
|
137
|
+
this.axios = axios2;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* POST /files - อัปโหลดไฟล์ใหม่
|
|
141
|
+
* Supports both authenticated and anonymous uploads
|
|
142
|
+
*/
|
|
143
|
+
async upload(formData) {
|
|
144
|
+
const response = await this.axios.post("/files", formData, {
|
|
145
|
+
headers: {
|
|
146
|
+
"Content-Type": "multipart/form-data"
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
return response.data.data;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* GET /files/:id - ดูข้อมูลไฟล์
|
|
153
|
+
* Public access (supports both authenticated and anonymous)
|
|
154
|
+
*/
|
|
155
|
+
async getById(id) {
|
|
156
|
+
const response = await this.axios.get(`/files/${id}`);
|
|
157
|
+
return response.data.data;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* GET /files/:id/content - ดึง file content (รูปภาพ, เอกสาร)
|
|
161
|
+
* Returns the actual file content or redirects to cloud storage URL
|
|
162
|
+
* Public access based on file.is_public flag
|
|
163
|
+
*/
|
|
164
|
+
getContentUrl(id) {
|
|
165
|
+
const baseURL = this.axios.defaults.baseURL || "";
|
|
166
|
+
return `${baseURL}/files/${id}/content`;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* PUT /files/:id - อัปเดตข้อมูลไฟล์
|
|
170
|
+
* Requires authentication
|
|
171
|
+
*/
|
|
172
|
+
async update(id, updateData) {
|
|
173
|
+
const response = await this.axios.put(`/files/${id}`, updateData);
|
|
174
|
+
return response.data.data;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* DELETE /files/:id - ลบไฟล์
|
|
178
|
+
* Requires authentication
|
|
179
|
+
*/
|
|
180
|
+
async delete(id) {
|
|
181
|
+
const response = await this.axios.delete(`/files/${id}`);
|
|
182
|
+
return response.data.data;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* POST /files/search - ค้นหาไฟล์แบบ advanced
|
|
186
|
+
* Public access (supports both authenticated and anonymous)
|
|
187
|
+
*/
|
|
188
|
+
async search(searchParams) {
|
|
189
|
+
const response = await this.axios.post("/files/search", searchParams || {});
|
|
190
|
+
return response.data.data;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* DELETE /files/bulk - ลบไฟล์หลายไฟล์
|
|
194
|
+
* Requires authentication
|
|
195
|
+
*/
|
|
196
|
+
async bulkDelete(ids) {
|
|
197
|
+
const response = await this.axios.delete("/files/bulk", {
|
|
198
|
+
data: { ids }
|
|
199
|
+
});
|
|
200
|
+
return response.data.data;
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
// src/api/event-log.api.ts
|
|
205
|
+
var EventLogApi = class {
|
|
206
|
+
constructor(axios2) {
|
|
207
|
+
this.axios = axios2;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Log event to centralized event log system
|
|
211
|
+
*/
|
|
212
|
+
async logEvent(eventData) {
|
|
213
|
+
const response = await this.axios.post("/event-logs", eventData);
|
|
214
|
+
return response.data.data;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Batch log multiple events (for performance)
|
|
218
|
+
*/
|
|
219
|
+
async logEvents(events) {
|
|
220
|
+
const response = await this.axios.post("/event-logs/batch", {
|
|
221
|
+
events
|
|
222
|
+
});
|
|
223
|
+
return response.data.data;
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
// src/api/line.api.ts
|
|
228
|
+
var LineAPI = class {
|
|
229
|
+
constructor(axios2) {
|
|
230
|
+
this.axios = axios2;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* ส่งข้อความ text ไปยัง user
|
|
234
|
+
*
|
|
235
|
+
* @example
|
|
236
|
+
* ```typescript
|
|
237
|
+
* const result = await authClient.line.sendTextMessage({
|
|
238
|
+
* userId: 'user-123',
|
|
239
|
+
* message: 'สวัสดีครับ! ยินดีต้อนรับ'
|
|
240
|
+
* });
|
|
241
|
+
* ```
|
|
242
|
+
*/
|
|
243
|
+
async sendTextMessage(request) {
|
|
244
|
+
const response = await this.axios.post("/line/send-text", request);
|
|
245
|
+
return response.data;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* ส่ง sticker ไปยัง user
|
|
249
|
+
*
|
|
250
|
+
* @example
|
|
251
|
+
* ```typescript
|
|
252
|
+
* const result = await authClient.line.sendSticker({
|
|
253
|
+
* userId: 'user-123',
|
|
254
|
+
* packageId: '11537',
|
|
255
|
+
* stickerId: '52002734'
|
|
256
|
+
* });
|
|
257
|
+
* ```
|
|
258
|
+
*/
|
|
259
|
+
async sendSticker(request) {
|
|
260
|
+
const response = await this.axios.post("/line/send-sticker", request);
|
|
261
|
+
return response.data;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* ส่งรูปภาพไปยัง user
|
|
265
|
+
*
|
|
266
|
+
* @example
|
|
267
|
+
* ```typescript
|
|
268
|
+
* const result = await authClient.line.sendImage({
|
|
269
|
+
* userId: 'user-123',
|
|
270
|
+
* originalContentUrl: 'https://example.com/image.jpg',
|
|
271
|
+
* previewImageUrl: 'https://example.com/preview.jpg'
|
|
272
|
+
* });
|
|
273
|
+
* ```
|
|
274
|
+
*/
|
|
275
|
+
async sendImage(request) {
|
|
276
|
+
const response = await this.axios.post("/line/send-image", request);
|
|
277
|
+
return response.data;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* ส่งหลายข้อความพร้อมกัน (สูงสุด 5 ข้อความ)
|
|
281
|
+
*
|
|
282
|
+
* @example
|
|
283
|
+
* ```typescript
|
|
284
|
+
* const result = await authClient.line.sendMessages({
|
|
285
|
+
* userId: 'user-123',
|
|
286
|
+
* messages: [
|
|
287
|
+
* { type: 'text', text: 'ข้อความแรก' },
|
|
288
|
+
* { type: 'sticker', packageId: '11537', stickerId: '52002734' },
|
|
289
|
+
* { type: 'text', text: 'ข้อความสุดท้าย' }
|
|
290
|
+
* ]
|
|
291
|
+
* });
|
|
292
|
+
* ```
|
|
293
|
+
*/
|
|
294
|
+
async sendMessages(request) {
|
|
295
|
+
const response = await this.axios.post("/line/send-messages", request);
|
|
296
|
+
return response.data;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* ส่ง notification แบบ high-level (มี title, icon และ action URL)
|
|
300
|
+
*
|
|
301
|
+
* @example
|
|
302
|
+
* ```typescript
|
|
303
|
+
* const result = await authClient.line.sendNotification({
|
|
304
|
+
* userId: 'user-123',
|
|
305
|
+
* title: 'งานใหม่ได้รับมอบหมาย',
|
|
306
|
+
* message: 'คุณได้รับมอบหมายงาน: ทำรายงานประจำเดือน',
|
|
307
|
+
* type: 'info',
|
|
308
|
+
* action_url: 'https://app.example.com/tasks/123',
|
|
309
|
+
* priority: 'high'
|
|
310
|
+
* });
|
|
311
|
+
* ```
|
|
312
|
+
*/
|
|
313
|
+
async sendNotification(request) {
|
|
314
|
+
const response = await this.axios.post("/line/send-notification", request);
|
|
315
|
+
return response.data;
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* ตรวจสอบว่า user สามารถรับข้อความ LINE ได้หรือไม่
|
|
319
|
+
*
|
|
320
|
+
* @example
|
|
321
|
+
* ```typescript
|
|
322
|
+
* const result = await authClient.line.checkMessagingAvailability('user-123');
|
|
323
|
+
* if (result.data?.canReceiveMessages) {
|
|
324
|
+
* console.log('User can receive LINE messages');
|
|
325
|
+
* }
|
|
326
|
+
* ```
|
|
327
|
+
*/
|
|
328
|
+
async checkMessagingAvailability(userId) {
|
|
329
|
+
const response = await this.axios.get(`/line/messaging-availability/${userId}`);
|
|
330
|
+
return response.data;
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
// src/api/todo.api.ts
|
|
335
|
+
var TodoAPI = class {
|
|
336
|
+
constructor(axios2) {
|
|
337
|
+
this.axios = axios2;
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Create a new todo
|
|
341
|
+
*
|
|
342
|
+
* @example
|
|
343
|
+
* ```typescript
|
|
344
|
+
* const todo = await authClient.todo.create({
|
|
345
|
+
* title: "ซื้อของใช้ในบ้าน",
|
|
346
|
+
* priority: TodoPriority.NORMAL,
|
|
347
|
+
* user_id: "user123e4567-e89b-12d3-a456-426614174000",
|
|
348
|
+
* description: "ซื้อน้ำยาล้างจาน, กระดาษทิชชู่, แชมพู",
|
|
349
|
+
* due_date: new Date("2024-01-20T17:00:00Z"),
|
|
350
|
+
* category: "shopping",
|
|
351
|
+
* labels: ["บ้าน", "จำเป็น"],
|
|
352
|
+
* is_send_notification: true
|
|
353
|
+
* });
|
|
354
|
+
* ```
|
|
355
|
+
*/
|
|
356
|
+
async create(todoData) {
|
|
357
|
+
const response = await this.axios.post("/todos", todoData);
|
|
358
|
+
return response.data.data;
|
|
359
|
+
}
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
// src/api/user.api.ts
|
|
363
|
+
var UserAPI = class {
|
|
364
|
+
constructor(axios2) {
|
|
365
|
+
this.axios = axios2;
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Search users with pagination and filters
|
|
369
|
+
*
|
|
370
|
+
* @example
|
|
371
|
+
* ```typescript
|
|
372
|
+
* const result = await authClient.user.search({
|
|
373
|
+
* search: "สมชาย",
|
|
374
|
+
* page: 1,
|
|
375
|
+
* limit: 20,
|
|
376
|
+
* sort_by: "created_at",
|
|
377
|
+
* sort_order: "desc",
|
|
378
|
+
* advanced: {
|
|
379
|
+
* status: "active",
|
|
380
|
+
* department_id: "dept-123"
|
|
381
|
+
* }
|
|
382
|
+
* });
|
|
383
|
+
*
|
|
384
|
+
* // Access paginated data
|
|
385
|
+
* console.log(result.data); // User[]
|
|
386
|
+
* console.log(result.pagination.total); // Total count
|
|
387
|
+
* console.log(result.pagination.has_next); // Has next page
|
|
388
|
+
* ```
|
|
389
|
+
*/
|
|
390
|
+
async search(params) {
|
|
391
|
+
const response = await this.axios.post("/users/search", params || {});
|
|
392
|
+
return response.data;
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Get user by ID
|
|
396
|
+
*
|
|
397
|
+
* @example
|
|
398
|
+
* ```typescript
|
|
399
|
+
* const user = await authClient.user.get("user-123");
|
|
400
|
+
* ```
|
|
401
|
+
*/
|
|
402
|
+
async get(userId) {
|
|
403
|
+
const response = await this.axios.get(`/users/${userId}`);
|
|
404
|
+
return response.data.data;
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Create a new user
|
|
408
|
+
*
|
|
409
|
+
* @description ถ้าไม่ระบุ password ระบบจะ auto generate และส่ง reset password link ไปทางอีเมล
|
|
410
|
+
* ถ้าระบุ password ระบบจะใช้ password ที่ส่งมาและส่ง welcome email พร้อม login link
|
|
411
|
+
*
|
|
412
|
+
* @example
|
|
413
|
+
* ```typescript
|
|
414
|
+
* // กรณีที่มี password - ระบบจะส่ง welcome email พร้อม login link
|
|
415
|
+
* const newUser = await authClient.user.create({
|
|
416
|
+
* email: "user@example.com",
|
|
417
|
+
* first_name: "สมชาย",
|
|
418
|
+
* last_name: "ใจดี",
|
|
419
|
+
* password: "SecurePassword123!",
|
|
420
|
+
* code: "USR-2024-001",
|
|
421
|
+
* role_ids: ["role-123", "role-456"] // Optional: assign roles immediately
|
|
422
|
+
* });
|
|
423
|
+
* ```
|
|
424
|
+
*
|
|
425
|
+
* @example
|
|
426
|
+
* ```typescript
|
|
427
|
+
* // กรณีที่ไม่มี password - ระบบจะ auto generate และส่ง welcome email พร้อม reset password link
|
|
428
|
+
* const newUser = await authClient.user.create({
|
|
429
|
+
* email: "user@example.com",
|
|
430
|
+
* first_name: "สมชาย",
|
|
431
|
+
* last_name: "ใจดี",
|
|
432
|
+
* code: "USR-2024-002"
|
|
433
|
+
* });
|
|
434
|
+
* ```
|
|
435
|
+
*/
|
|
436
|
+
async create(userData) {
|
|
437
|
+
const response = await this.axios.post("/users", userData);
|
|
438
|
+
return response.data.data;
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Update user
|
|
442
|
+
*
|
|
443
|
+
* @example
|
|
444
|
+
* ```typescript
|
|
445
|
+
* const updatedUser = await authClient.user.update("user-123", {
|
|
446
|
+
* first_name: "สมชาย",
|
|
447
|
+
* last_name: "ใจดีมาก",
|
|
448
|
+
* phone_number: "+66812345678",
|
|
449
|
+
* role_ids: ["role-123", "role-456"] // Optional: replace all roles
|
|
450
|
+
* });
|
|
451
|
+
* ```
|
|
452
|
+
*/
|
|
453
|
+
async update(userId, userData) {
|
|
454
|
+
const response = await this.axios.put(`/users/${userId}`, userData);
|
|
455
|
+
return response.data.data;
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* Delete user
|
|
459
|
+
*
|
|
460
|
+
* @example
|
|
461
|
+
* ```typescript
|
|
462
|
+
* await authClient.user.delete("user-123");
|
|
463
|
+
* ```
|
|
464
|
+
*/
|
|
465
|
+
async delete(userId) {
|
|
466
|
+
await this.axios.delete(`/users/${userId}`);
|
|
467
|
+
}
|
|
468
|
+
// ==========================================================================
|
|
469
|
+
// Position Assignment
|
|
470
|
+
// ==========================================================================
|
|
471
|
+
/**
|
|
472
|
+
* Get user positions
|
|
473
|
+
*
|
|
474
|
+
* @description ดึงรายการตำแหน่งทั้งหมดของผู้ใช้
|
|
475
|
+
*
|
|
476
|
+
* @example
|
|
477
|
+
* ```typescript
|
|
478
|
+
* const positions = await authClient.user.getPositions("user-123");
|
|
479
|
+
* const primaryPosition = positions.find(p => p.is_primary);
|
|
480
|
+
* ```
|
|
481
|
+
*/
|
|
482
|
+
async getPositions(userId) {
|
|
483
|
+
const response = await this.axios.get(`/users/${userId}/positions`);
|
|
484
|
+
return response.data.data || [];
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Assign positions to user
|
|
488
|
+
*
|
|
489
|
+
* @description มอบหมายตำแหน่งให้ผู้ใช้ รองรับการมอบหมายหลายตำแหน่งพร้อมกัน
|
|
490
|
+
*
|
|
491
|
+
* @example
|
|
492
|
+
* ```typescript
|
|
493
|
+
* // Replace mode (default) - ทับตำแหน่งเดิมทั้งหมด
|
|
494
|
+
* const result = await authClient.user.assignPositions("user-123", {
|
|
495
|
+
* positions: [
|
|
496
|
+
* { position_id: "pos-001", is_primary: true },
|
|
497
|
+
* { position_id: "pos-002", is_primary: false }
|
|
498
|
+
* ],
|
|
499
|
+
* mode: "replace"
|
|
500
|
+
* });
|
|
501
|
+
*
|
|
502
|
+
* // Add mode - เพิ่มตำแหน่งใหม่โดยไม่ลบของเดิม
|
|
503
|
+
* const result = await authClient.user.assignPositions("user-123", {
|
|
504
|
+
* positions: [
|
|
505
|
+
* { position_id: "pos-003", is_primary: false }
|
|
506
|
+
* ],
|
|
507
|
+
* mode: "add"
|
|
508
|
+
* });
|
|
509
|
+
* ```
|
|
510
|
+
*/
|
|
511
|
+
async assignPositions(userId, data) {
|
|
512
|
+
const response = await this.axios.post(`/users/${userId}/positions`, data);
|
|
513
|
+
return response.data.data;
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Unassign positions from user
|
|
517
|
+
*
|
|
518
|
+
* @description ยกเลิกตำแหน่งจากผู้ใช้
|
|
519
|
+
*
|
|
520
|
+
* @example
|
|
521
|
+
* ```typescript
|
|
522
|
+
* const result = await authClient.user.unassignPositions("user-123", ["pos-001", "pos-002"]);
|
|
523
|
+
* ```
|
|
524
|
+
*/
|
|
525
|
+
async unassignPositions(userId, positionIds) {
|
|
526
|
+
const response = await this.axios.delete(`/users/${userId}/positions`, {
|
|
527
|
+
data: { ids: positionIds }
|
|
528
|
+
});
|
|
529
|
+
return response.data.data;
|
|
530
|
+
}
|
|
531
|
+
// ==========================================================================
|
|
532
|
+
// Role Assignment
|
|
533
|
+
// ==========================================================================
|
|
534
|
+
/**
|
|
535
|
+
* Get user roles
|
|
536
|
+
*
|
|
537
|
+
* @description ดึงรายการบทบาททั้งหมดของผู้ใช้
|
|
538
|
+
*
|
|
539
|
+
* @example
|
|
540
|
+
* ```typescript
|
|
541
|
+
* const roles = await authClient.user.getRoles("user-123");
|
|
542
|
+
* console.log(roles.map(r => r.name)); // ["Admin", "Manager"]
|
|
543
|
+
* ```
|
|
544
|
+
*/
|
|
545
|
+
async getRoles(userId) {
|
|
546
|
+
const response = await this.axios.get(`/users/${userId}/roles`);
|
|
547
|
+
return response.data.data || [];
|
|
548
|
+
}
|
|
549
|
+
/**
|
|
550
|
+
* Assign roles to user
|
|
551
|
+
*
|
|
552
|
+
* @description มอบหมายบทบาทให้ผู้ใช้ (แทนที่บทบาทเดิมทั้งหมด)
|
|
553
|
+
*
|
|
554
|
+
* @example
|
|
555
|
+
* ```typescript
|
|
556
|
+
* const result = await authClient.user.assignRoles("user-123", ["role-001", "role-002"]);
|
|
557
|
+
* ```
|
|
558
|
+
*/
|
|
559
|
+
async assignRoles(userId, roleIds) {
|
|
560
|
+
const response = await this.axios.post(`/users/${userId}/roles`, {
|
|
561
|
+
ids: roleIds
|
|
562
|
+
});
|
|
563
|
+
return response.data.data;
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* Unassign roles from user
|
|
567
|
+
*
|
|
568
|
+
* @description ยกเลิกบทบาทจากผู้ใช้
|
|
569
|
+
*
|
|
570
|
+
* @example
|
|
571
|
+
* ```typescript
|
|
572
|
+
* const result = await authClient.user.unassignRoles("user-123", ["role-001"]);
|
|
573
|
+
* ```
|
|
574
|
+
*/
|
|
575
|
+
async unassignRoles(userId, roleIds) {
|
|
576
|
+
const response = await this.axios.delete(`/users/${userId}/roles`, {
|
|
577
|
+
data: { ids: roleIds }
|
|
578
|
+
});
|
|
579
|
+
return response.data.data;
|
|
580
|
+
}
|
|
581
|
+
// ==========================================================================
|
|
582
|
+
// Sync Operations
|
|
583
|
+
// ==========================================================================
|
|
584
|
+
/**
|
|
585
|
+
* Sync users for external applications
|
|
586
|
+
*
|
|
587
|
+
* @description ดึงข้อมูลผู้ใช้แบบ paginated สำหรับ sync operations
|
|
588
|
+
* ใช้สำหรับ external applications ที่ต้องการ sync user data
|
|
589
|
+
* ต้องใช้ API Key authentication
|
|
590
|
+
*
|
|
591
|
+
* @example
|
|
592
|
+
* ```typescript
|
|
593
|
+
* // Sync all users (first page)
|
|
594
|
+
* const result = await authClient.user.sync({
|
|
595
|
+
* page: 1,
|
|
596
|
+
* page_size: 100
|
|
597
|
+
* });
|
|
598
|
+
*
|
|
599
|
+
* // Sync users updated after specific date
|
|
600
|
+
* const updatedUsers = await authClient.user.sync({
|
|
601
|
+
* page: 1,
|
|
602
|
+
* page_size: 100,
|
|
603
|
+
* updated_after: new Date('2024-01-01')
|
|
604
|
+
* });
|
|
605
|
+
*
|
|
606
|
+
* // Access paginated data
|
|
607
|
+
* console.log(result.data); // UserSyncResponse[]
|
|
608
|
+
* console.log(result.pagination.total); // Total count
|
|
609
|
+
* console.log(result.pagination.has_next); // Has next page
|
|
610
|
+
* ```
|
|
611
|
+
*/
|
|
612
|
+
async sync(params) {
|
|
613
|
+
const queryParams = {};
|
|
614
|
+
if (params?.page !== void 0) {
|
|
615
|
+
queryParams.page = params.page.toString();
|
|
616
|
+
}
|
|
617
|
+
if (params?.page_size !== void 0) {
|
|
618
|
+
queryParams.page_size = params.page_size.toString();
|
|
619
|
+
}
|
|
620
|
+
if (params?.updated_after) {
|
|
621
|
+
const updatedAfter = params.updated_after instanceof Date ? params.updated_after.toISOString() : params.updated_after;
|
|
622
|
+
queryParams.updated_after = updatedAfter;
|
|
623
|
+
}
|
|
624
|
+
const queryString = new URLSearchParams(queryParams).toString();
|
|
625
|
+
const url = `/users/sync${queryString ? `?${queryString}` : ""}`;
|
|
626
|
+
const response = await this.axios.get(url);
|
|
627
|
+
return response.data;
|
|
628
|
+
}
|
|
629
|
+
};
|
|
630
|
+
|
|
631
|
+
// src/api/otp.api.ts
|
|
632
|
+
var OtpAPI = class {
|
|
633
|
+
constructor(axios2) {
|
|
634
|
+
this.axios = axios2;
|
|
635
|
+
}
|
|
636
|
+
/**
|
|
637
|
+
* Send OTP to recipient (SMS or Email)
|
|
638
|
+
*
|
|
639
|
+
* @example
|
|
640
|
+
* ```typescript
|
|
641
|
+
* // Send SMS OTP
|
|
642
|
+
* const result = await authClient.otp.sendOTP({
|
|
643
|
+
* method: 'sms',
|
|
644
|
+
* recipient: '0812345678',
|
|
645
|
+
* context: 'login'
|
|
646
|
+
* });
|
|
647
|
+
*
|
|
648
|
+
* console.log('OTP ID:', result.otp_id); // UUID
|
|
649
|
+
* console.log('Ref Code:', result.ref_code); // OTP-XXXXXX (for tracking)
|
|
650
|
+
* console.log('Expires at:', result.expires_at);
|
|
651
|
+
*
|
|
652
|
+
* // Send Email OTP
|
|
653
|
+
* const result = await authClient.otp.sendOTP({
|
|
654
|
+
* method: 'email',
|
|
655
|
+
* recipient: 'user@example.com',
|
|
656
|
+
* context: 'verification'
|
|
657
|
+
* });
|
|
658
|
+
* ```
|
|
659
|
+
*/
|
|
660
|
+
async sendOTP(request) {
|
|
661
|
+
const response = await this.axios.post("/otp/send", request);
|
|
662
|
+
return response.data.data;
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* Verify OTP code
|
|
666
|
+
*
|
|
667
|
+
* @example
|
|
668
|
+
* ```typescript
|
|
669
|
+
* const result = await authClient.otp.verifyOTP({
|
|
670
|
+
* otp_id: '123e4567-e89b-12d3-a456-426614174000',
|
|
671
|
+
* code: '123456'
|
|
672
|
+
* });
|
|
673
|
+
*
|
|
674
|
+
* if (result.verified) {
|
|
675
|
+
* console.log('OTP verified successfully');
|
|
676
|
+
* }
|
|
677
|
+
* ```
|
|
678
|
+
*/
|
|
679
|
+
async verifyOTP(request) {
|
|
680
|
+
const response = await this.axios.post("/otp/verify", request);
|
|
681
|
+
return response.data.data;
|
|
682
|
+
}
|
|
683
|
+
};
|
|
684
|
+
|
|
685
|
+
// src/api/email.api.ts
|
|
686
|
+
var EmailAPI = class {
|
|
687
|
+
constructor(axios2) {
|
|
688
|
+
this.axios = axios2;
|
|
689
|
+
}
|
|
690
|
+
/**
|
|
691
|
+
* Send email (auto-detect Template Mode or Raw HTML Mode)
|
|
692
|
+
*
|
|
693
|
+
* @param request - SendEmailRequest
|
|
694
|
+
* @returns SendEmailResponse
|
|
695
|
+
*
|
|
696
|
+
* @example
|
|
697
|
+
* ```typescript
|
|
698
|
+
* // Template Mode
|
|
699
|
+
* const result = await authClient.email.sendEmail({
|
|
700
|
+
* template_code: 'welcome_email',
|
|
701
|
+
* template_data: { userName: 'John' },
|
|
702
|
+
* recipient_email: 'user@example.com'
|
|
703
|
+
* });
|
|
704
|
+
*
|
|
705
|
+
* // Raw HTML Mode
|
|
706
|
+
* const result = await authClient.email.sendEmail({
|
|
707
|
+
* html_body: '<h1>Hello</h1>',
|
|
708
|
+
* subject: 'Welcome',
|
|
709
|
+
* recipient_email: 'user@example.com'
|
|
710
|
+
* });
|
|
711
|
+
* ```
|
|
712
|
+
*/
|
|
713
|
+
async sendEmail(request) {
|
|
714
|
+
const response = await this.axios.post("/send", request);
|
|
715
|
+
return response.data.data;
|
|
716
|
+
}
|
|
717
|
+
/**
|
|
718
|
+
* Send email with template (Template Mode - convenience method)
|
|
719
|
+
*
|
|
720
|
+
* @param templateCode - Template code from database
|
|
721
|
+
* @param templateData - Template data for rendering
|
|
722
|
+
* @param recipient - Email address or user ID
|
|
723
|
+
* @param options - Additional options (cc, bcc, attachments, etc.)
|
|
724
|
+
* @returns SendEmailResponse
|
|
725
|
+
*
|
|
726
|
+
* @example
|
|
727
|
+
* ```typescript
|
|
728
|
+
* const result = await authClient.email.sendEmailWithTemplate(
|
|
729
|
+
* 'welcome_email',
|
|
730
|
+
* {
|
|
731
|
+
* userName: 'สมชาย ใจดี',
|
|
732
|
+
* activationLink: 'https://app.com/activate?token=xxx'
|
|
733
|
+
* },
|
|
734
|
+
* 'user@example.com',
|
|
735
|
+
* {
|
|
736
|
+
* recipient_name: 'สมชาย ใจดี',
|
|
737
|
+
* language: 'th',
|
|
738
|
+
* cc: ['manager@example.com'],
|
|
739
|
+
* attachments: [
|
|
740
|
+
* {
|
|
741
|
+
* filename: 'welcome.pdf',
|
|
742
|
+
* href: 'https://storage.azure.com/container/welcome.pdf' // URL จาก cloud storage
|
|
743
|
+
* }
|
|
744
|
+
* ]
|
|
745
|
+
* }
|
|
746
|
+
* );
|
|
747
|
+
* ```
|
|
748
|
+
*/
|
|
749
|
+
async sendEmailWithTemplate(templateCode, templateData, recipient, options) {
|
|
750
|
+
const request = {
|
|
751
|
+
template_code: templateCode,
|
|
752
|
+
template_data: templateData,
|
|
753
|
+
...options?.language && { language: options.language },
|
|
754
|
+
...options?.subject && { subject: options.subject },
|
|
755
|
+
...recipient.includes("@") ? { recipient_email: recipient } : { recipient_id: recipient },
|
|
756
|
+
...options?.recipient_name && { recipient_name: options.recipient_name },
|
|
757
|
+
...options?.cc && { cc: options.cc },
|
|
758
|
+
...options?.bcc && { bcc: options.bcc },
|
|
759
|
+
...options?.attachments && { attachments: options.attachments },
|
|
760
|
+
...options?.priority && { priority: options.priority },
|
|
761
|
+
...options?.scheduled_at && { scheduled_at: options.scheduled_at },
|
|
762
|
+
...options?.source && { source: options.source },
|
|
763
|
+
...options?.related_entity_id && { related_entity_id: options.related_entity_id },
|
|
764
|
+
...options?.related_entity_type && { related_entity_type: options.related_entity_type }
|
|
765
|
+
};
|
|
766
|
+
return this.sendEmail(request);
|
|
767
|
+
}
|
|
768
|
+
/**
|
|
769
|
+
* Send email with raw HTML (Raw HTML Mode - convenience method)
|
|
770
|
+
*
|
|
771
|
+
* @param htmlBody - HTML content
|
|
772
|
+
* @param subject - Email subject
|
|
773
|
+
* @param recipient - Email address or user ID
|
|
774
|
+
* @param options - Additional options (text_body, cc, bcc, attachments, etc.)
|
|
775
|
+
* @returns SendEmailResponse
|
|
776
|
+
*
|
|
777
|
+
* @example
|
|
778
|
+
* ```typescript
|
|
779
|
+
* const result = await authClient.email.sendRawEmail(
|
|
780
|
+
* '<h1>ยินดีต้อนรับ</h1><p>ขอบคุณที่สมัครสมาชิก</p>',
|
|
781
|
+
* 'ยินดีต้อนรับสู่ระบบ',
|
|
782
|
+
* 'user@example.com',
|
|
783
|
+
* {
|
|
784
|
+
* recipient_name: 'สมชาย ใจดี',
|
|
785
|
+
* text_body: 'ยินดีต้อนรับ ขอบคุณที่สมัครสมาชิก',
|
|
786
|
+
* cc: ['manager@example.com'],
|
|
787
|
+
* bcc: ['archive@example.com'],
|
|
788
|
+
* attachments: [
|
|
789
|
+
* {
|
|
790
|
+
* filename: 'document.pdf',
|
|
791
|
+
* href: 'https://api.example.com/files/123e4567-e89b-12d3-a456-426614174000/content' // URL จาก File API
|
|
792
|
+
* }
|
|
793
|
+
* ]
|
|
794
|
+
* }
|
|
795
|
+
* );
|
|
796
|
+
* ```
|
|
797
|
+
*/
|
|
798
|
+
async sendRawEmail(htmlBody, subject, recipient, options) {
|
|
799
|
+
const request = {
|
|
800
|
+
html_body: htmlBody,
|
|
801
|
+
subject,
|
|
802
|
+
...recipient.includes("@") ? { recipient_email: recipient } : { recipient_id: recipient },
|
|
803
|
+
...options?.recipient_name && { recipient_name: options.recipient_name },
|
|
804
|
+
...options?.text_body && { text_body: options.text_body },
|
|
805
|
+
...options?.cc && { cc: options.cc },
|
|
806
|
+
...options?.bcc && { bcc: options.bcc },
|
|
807
|
+
...options?.attachments && { attachments: options.attachments },
|
|
808
|
+
...options?.priority && { priority: options.priority },
|
|
809
|
+
...options?.scheduled_at && { scheduled_at: options.scheduled_at },
|
|
810
|
+
...options?.source && { source: options.source },
|
|
811
|
+
...options?.related_entity_id && { related_entity_id: options.related_entity_id },
|
|
812
|
+
...options?.related_entity_type && { related_entity_type: options.related_entity_type }
|
|
813
|
+
};
|
|
814
|
+
return this.sendEmail(request);
|
|
815
|
+
}
|
|
816
|
+
};
|
|
817
|
+
|
|
818
|
+
// src/api/workflow.api.ts
|
|
819
|
+
var WorkflowAPI = class {
|
|
820
|
+
constructor(axios2) {
|
|
821
|
+
this.axios = axios2;
|
|
822
|
+
}
|
|
823
|
+
/**
|
|
824
|
+
* Get workflow instance by ID
|
|
825
|
+
*
|
|
826
|
+
* @example
|
|
827
|
+
* ```typescript
|
|
828
|
+
* const instance = await authClient.workflow.getInstance("wf-inst-123");
|
|
829
|
+
* ```
|
|
830
|
+
*/
|
|
831
|
+
async getInstance(instanceId) {
|
|
832
|
+
const response = await this.axios.get(`/workflow-instances/${instanceId}`);
|
|
833
|
+
return response.data.data;
|
|
834
|
+
}
|
|
835
|
+
/**
|
|
836
|
+
* Create a new workflow instance
|
|
837
|
+
*
|
|
838
|
+
* @example
|
|
839
|
+
* ```typescript
|
|
840
|
+
* const instance = await authClient.workflow.createInstance({
|
|
841
|
+
* workflow_definition_id: "wf-def-123",
|
|
842
|
+
* document_id: "doc-123",
|
|
843
|
+
* document_type: "purchase_request",
|
|
844
|
+
* document_title: "ขอซื้อคอมพิวเตอร์",
|
|
845
|
+
* priority: "high",
|
|
846
|
+
* position_id: "pos-123",
|
|
847
|
+
* form_data: {
|
|
848
|
+
* amount: 150000,
|
|
849
|
+
* items: ["Laptop", "Monitor"]
|
|
850
|
+
* },
|
|
851
|
+
* user_id: "user-123"
|
|
852
|
+
* });
|
|
853
|
+
* ```
|
|
854
|
+
*/
|
|
855
|
+
async createInstance(instanceData) {
|
|
856
|
+
const response = await this.axios.post("/workflow-instances", instanceData);
|
|
857
|
+
return response.data.data;
|
|
858
|
+
}
|
|
859
|
+
/**
|
|
860
|
+
* Update workflow instance
|
|
861
|
+
*
|
|
862
|
+
* @example
|
|
863
|
+
* ```typescript
|
|
864
|
+
* const updatedInstance = await authClient.workflow.updateInstance("wf-inst-123", {
|
|
865
|
+
* document_title: "ขอซื้อคอมพิวเตอร์ (แก้ไข)",
|
|
866
|
+
* priority: "urgent"
|
|
867
|
+
* });
|
|
868
|
+
* ```
|
|
869
|
+
*/
|
|
870
|
+
async updateInstance(instanceId, instanceData) {
|
|
871
|
+
const response = await this.axios.put(
|
|
872
|
+
`/workflow-instances/${instanceId}`,
|
|
873
|
+
instanceData
|
|
874
|
+
);
|
|
875
|
+
return response.data.data;
|
|
876
|
+
}
|
|
877
|
+
/**
|
|
878
|
+
* Search workflow instances with pagination and filters
|
|
879
|
+
*
|
|
880
|
+
* @example
|
|
881
|
+
* ```typescript
|
|
882
|
+
* const result = await authClient.workflow.searchInstances({
|
|
883
|
+
* search: "ขอซื้อ",
|
|
884
|
+
* page: 1,
|
|
885
|
+
* limit: 20,
|
|
886
|
+
* sort_by: "created_at",
|
|
887
|
+
* sort_order: "desc",
|
|
888
|
+
* filters: {
|
|
889
|
+
* status: ["running", "pending"],
|
|
890
|
+
* priority: ["high", "urgent"]
|
|
891
|
+
* }
|
|
892
|
+
* });
|
|
893
|
+
*
|
|
894
|
+
* // Access paginated data
|
|
895
|
+
* console.log(result.data); // WorkflowInstance[]
|
|
896
|
+
* console.log(result.pagination.total); // Total count
|
|
897
|
+
* console.log(result.pagination.has_next); // Has next page
|
|
898
|
+
* ```
|
|
899
|
+
*/
|
|
900
|
+
async searchInstances(params) {
|
|
901
|
+
const response = await this.axios.post(
|
|
902
|
+
"/workflow-instances/search",
|
|
903
|
+
params || {}
|
|
904
|
+
);
|
|
905
|
+
return response.data;
|
|
906
|
+
}
|
|
907
|
+
/**
|
|
908
|
+
* Get workflow task by ID
|
|
909
|
+
*
|
|
910
|
+
* @example
|
|
911
|
+
* ```typescript
|
|
912
|
+
* const task = await authClient.workflow.getTask("task-123");
|
|
913
|
+
* ```
|
|
914
|
+
*/
|
|
915
|
+
async getTask(taskId) {
|
|
916
|
+
const response = await this.axios.get(`/workflow-tasks/${taskId}`);
|
|
917
|
+
return response.data.data;
|
|
918
|
+
}
|
|
919
|
+
/**
|
|
920
|
+
* Get user tasks with pagination and filters
|
|
921
|
+
*
|
|
922
|
+
* @example
|
|
923
|
+
* ```typescript
|
|
924
|
+
* const result = await authClient.workflow.getUserTasks({
|
|
925
|
+
* status: ["assigned", "in_progress"],
|
|
926
|
+
* priority: ["high"],
|
|
927
|
+
* page: 1,
|
|
928
|
+
* limit: 20
|
|
929
|
+
* });
|
|
930
|
+
*
|
|
931
|
+
* // Access paginated data
|
|
932
|
+
* console.log(result.data); // WorkflowTask[]
|
|
933
|
+
* console.log(result.pagination.total); // Total count
|
|
934
|
+
* ```
|
|
935
|
+
*/
|
|
936
|
+
async getUserTasks(params) {
|
|
937
|
+
const queryParams = {};
|
|
938
|
+
if (params?.status) {
|
|
939
|
+
queryParams.status = params.status.join(",");
|
|
940
|
+
}
|
|
941
|
+
if (params?.priority) {
|
|
942
|
+
queryParams.priority = params.priority.join(",");
|
|
943
|
+
}
|
|
944
|
+
if (params?.workflow_instance_id) {
|
|
945
|
+
queryParams.workflow_instance_id = params.workflow_instance_id;
|
|
946
|
+
}
|
|
947
|
+
if (params?.assigned_to) {
|
|
948
|
+
queryParams.assigned_to = params.assigned_to;
|
|
949
|
+
}
|
|
950
|
+
if (params?.page !== void 0) {
|
|
951
|
+
queryParams.page = params.page.toString();
|
|
952
|
+
}
|
|
953
|
+
if (params?.limit !== void 0) {
|
|
954
|
+
queryParams.limit = params.limit.toString();
|
|
955
|
+
}
|
|
956
|
+
if (params?.sort_by) {
|
|
957
|
+
queryParams.sort_by = params.sort_by;
|
|
958
|
+
}
|
|
959
|
+
if (params?.sort_order) {
|
|
960
|
+
queryParams.sort_order = params.sort_order;
|
|
961
|
+
}
|
|
962
|
+
const queryString = new URLSearchParams(queryParams).toString();
|
|
963
|
+
const url = `/workflow-tasks${queryString ? `?${queryString}` : ""}`;
|
|
964
|
+
const response = await this.axios.get(url);
|
|
965
|
+
return response.data;
|
|
966
|
+
}
|
|
967
|
+
/**
|
|
968
|
+
* Perform action on workflow task (approve, reject, delegate, escalate, etc.)
|
|
969
|
+
*
|
|
970
|
+
* @example
|
|
971
|
+
* ```typescript
|
|
972
|
+
* // Approve task
|
|
973
|
+
* const result = await authClient.workflow.performTaskAction("task-123", {
|
|
974
|
+
* action_key: "approve",
|
|
975
|
+
* comments: "อนุมัติตามขั้นตอน"
|
|
976
|
+
* });
|
|
977
|
+
*
|
|
978
|
+
* // Reject task
|
|
979
|
+
* const result = await authClient.workflow.performTaskAction("task-123", {
|
|
980
|
+
* action_key: "reject",
|
|
981
|
+
* comments: "ไม่ผ่านตามเงื่อนไข",
|
|
982
|
+
* reason: "งบประมาณไม่เพียงพอ"
|
|
983
|
+
* });
|
|
984
|
+
*
|
|
985
|
+
* // Delegate task
|
|
986
|
+
* const result = await authClient.workflow.performTaskAction("task-123", {
|
|
987
|
+
* action_key: "delegate",
|
|
988
|
+
* delegate_to_user_id: "user-456",
|
|
989
|
+
* comments: "มอบหมายให้ผู้จัดการพิจารณา"
|
|
990
|
+
* });
|
|
991
|
+
* ```
|
|
992
|
+
*/
|
|
993
|
+
async performTaskAction(taskId, actionData) {
|
|
994
|
+
const response = await this.axios.post(`/workflow-tasks/${taskId}/actions`, actionData);
|
|
995
|
+
return response.data.data;
|
|
996
|
+
}
|
|
997
|
+
/**
|
|
998
|
+
* Get workflow definition by ID
|
|
999
|
+
*
|
|
1000
|
+
* @example
|
|
1001
|
+
* ```typescript
|
|
1002
|
+
* const definition = await authClient.workflow.getDefinition("wf-def-123");
|
|
1003
|
+
* ```
|
|
1004
|
+
*/
|
|
1005
|
+
async getDefinition(definitionId) {
|
|
1006
|
+
const response = await this.axios.get(`/workflow-definitions/${definitionId}`);
|
|
1007
|
+
return response.data.data;
|
|
1008
|
+
}
|
|
1009
|
+
/**
|
|
1010
|
+
* Search workflow definitions with pagination and filters
|
|
1011
|
+
*
|
|
1012
|
+
* @example
|
|
1013
|
+
* ```typescript
|
|
1014
|
+
* const result = await authClient.workflow.searchDefinitions({
|
|
1015
|
+
* search: "อนุมัติ",
|
|
1016
|
+
* page: 1,
|
|
1017
|
+
* limit: 20,
|
|
1018
|
+
* filters: {
|
|
1019
|
+
* status: ["active"]
|
|
1020
|
+
* }
|
|
1021
|
+
* });
|
|
1022
|
+
*
|
|
1023
|
+
* // Access paginated data
|
|
1024
|
+
* console.log(result.data); // WorkflowDefinition[]
|
|
1025
|
+
* console.log(result.pagination.total); // Total count
|
|
1026
|
+
* ```
|
|
1027
|
+
*/
|
|
1028
|
+
async searchDefinitions(params) {
|
|
1029
|
+
const response = await this.axios.post(
|
|
1030
|
+
"/workflow-definitions/search",
|
|
1031
|
+
params || {}
|
|
1032
|
+
);
|
|
1033
|
+
return response.data;
|
|
1034
|
+
}
|
|
1035
|
+
};
|
|
1036
|
+
|
|
1037
|
+
// src/api/organization.api.ts
|
|
1038
|
+
var OrganizationAPI = class {
|
|
1039
|
+
constructor(axios2) {
|
|
1040
|
+
this.axios = axios2;
|
|
1041
|
+
}
|
|
1042
|
+
/**
|
|
1043
|
+
* Search organizations with pagination and filters
|
|
1044
|
+
*/
|
|
1045
|
+
async search(params) {
|
|
1046
|
+
const response = await this.axios.post("/organizations/search", params || {});
|
|
1047
|
+
return response.data;
|
|
1048
|
+
}
|
|
1049
|
+
/**
|
|
1050
|
+
* Get organization by ID
|
|
1051
|
+
*/
|
|
1052
|
+
async get(id) {
|
|
1053
|
+
const response = await this.axios.get(`/organizations/${id}`);
|
|
1054
|
+
return response.data.data;
|
|
1055
|
+
}
|
|
1056
|
+
/**
|
|
1057
|
+
* Find organization by code
|
|
1058
|
+
*
|
|
1059
|
+
* @description ค้นหาองค์กรด้วย code ที่ unique
|
|
1060
|
+
*
|
|
1061
|
+
* @example
|
|
1062
|
+
* ```typescript
|
|
1063
|
+
* const org = await authClient.organization.findByCode("WIN-CORP");
|
|
1064
|
+
* if (org) {
|
|
1065
|
+
* console.log(org.name); // "บริษัท วิน คอร์ปอเรชั่น จำกัด"
|
|
1066
|
+
* }
|
|
1067
|
+
* ```
|
|
1068
|
+
*/
|
|
1069
|
+
async findByCode(code) {
|
|
1070
|
+
const response = await this.axios.get(`/organizations/code/${code}`);
|
|
1071
|
+
return response.data.data || null;
|
|
1072
|
+
}
|
|
1073
|
+
/**
|
|
1074
|
+
* Create a new organization
|
|
1075
|
+
*/
|
|
1076
|
+
async create(data) {
|
|
1077
|
+
const response = await this.axios.post("/organizations", data);
|
|
1078
|
+
return response.data.data;
|
|
1079
|
+
}
|
|
1080
|
+
/**
|
|
1081
|
+
* Bulk create organizations (เร็วกว่า loop create ทีละรายการ)
|
|
1082
|
+
*
|
|
1083
|
+
* @description สร้างองค์กรหลายรายการในครั้งเดียว ต้องเรียง parent ก่อน child
|
|
1084
|
+
* หรือระบุ id ให้ parent เพื่อให้ child อ้างอิง parent_id ได้
|
|
1085
|
+
*
|
|
1086
|
+
* @example
|
|
1087
|
+
* ```typescript
|
|
1088
|
+
* const result = await authClient.organization.bulkCreate({
|
|
1089
|
+
* organizations: [
|
|
1090
|
+
* { name: "Group A", code: "GRP-A", type: "group", id: "uuid-1" },
|
|
1091
|
+
* { name: "Company 1", code: "CO-1", type: "company", parent_id: "uuid-1", id: "uuid-2" },
|
|
1092
|
+
* { name: "Dept IT", code: "IT", type: "department", parent_id: "uuid-2" },
|
|
1093
|
+
* ],
|
|
1094
|
+
* });
|
|
1095
|
+
* console.log(result.created); // 3
|
|
1096
|
+
* ```
|
|
1097
|
+
*/
|
|
1098
|
+
async bulkCreate(data) {
|
|
1099
|
+
const response = await this.axios.post(
|
|
1100
|
+
"/organizations/bulk-create",
|
|
1101
|
+
data
|
|
1102
|
+
);
|
|
1103
|
+
return response.data.data;
|
|
1104
|
+
}
|
|
1105
|
+
/**
|
|
1106
|
+
* Update organization
|
|
1107
|
+
*/
|
|
1108
|
+
async update(id, data) {
|
|
1109
|
+
const response = await this.axios.put(`/organizations/${id}`, data);
|
|
1110
|
+
return response.data.data;
|
|
1111
|
+
}
|
|
1112
|
+
/**
|
|
1113
|
+
* Delete organization
|
|
1114
|
+
*/
|
|
1115
|
+
async delete(id) {
|
|
1116
|
+
const response = await this.axios.delete(`/organizations/${id}`);
|
|
1117
|
+
return !!response.data.success;
|
|
1118
|
+
}
|
|
1119
|
+
/**
|
|
1120
|
+
* Get organization users
|
|
1121
|
+
* @param includeDescendants If true, returns users from all descendant organizations recursively
|
|
1122
|
+
*/
|
|
1123
|
+
async getUsers(id, includeDescendants = false) {
|
|
1124
|
+
const params = includeDescendants ? { includeDescendants: "true" } : {};
|
|
1125
|
+
const response = await this.axios.get(`/organizations/${id}/users`, { params });
|
|
1126
|
+
return response.data.data || [];
|
|
1127
|
+
}
|
|
1128
|
+
/**
|
|
1129
|
+
* Get ancestors (parent organizations at all levels)
|
|
1130
|
+
*/
|
|
1131
|
+
async getAncestors(id, includeRoot = true) {
|
|
1132
|
+
const params = { includeRoot: String(includeRoot) };
|
|
1133
|
+
const response = await this.axios.get(`/organizations/${id}/ancestors`, { params });
|
|
1134
|
+
return response.data.data || [];
|
|
1135
|
+
}
|
|
1136
|
+
/**
|
|
1137
|
+
* Get immediate supervisor/parent organization
|
|
1138
|
+
*/
|
|
1139
|
+
async getDirectSupervisor(id) {
|
|
1140
|
+
const response = await this.axios.get(`/organizations/${id}/supervisor`);
|
|
1141
|
+
return response.data.data || null;
|
|
1142
|
+
}
|
|
1143
|
+
/**
|
|
1144
|
+
* Get full path from root to organization
|
|
1145
|
+
*/
|
|
1146
|
+
async getPath(id) {
|
|
1147
|
+
const response = await this.axios.get(`/organizations/${id}/path`);
|
|
1148
|
+
return response.data.data || [];
|
|
1149
|
+
}
|
|
1150
|
+
/**
|
|
1151
|
+
* Get reporting line (hierarchical and functional)
|
|
1152
|
+
*/
|
|
1153
|
+
async getReportingLine(id) {
|
|
1154
|
+
const response = await this.axios.get(`/organizations/${id}/reporting-line`);
|
|
1155
|
+
return response.data.data;
|
|
1156
|
+
}
|
|
1157
|
+
/**
|
|
1158
|
+
* Get sibling organizations (same parent)
|
|
1159
|
+
*/
|
|
1160
|
+
async getSiblings(id, includeSelf = false) {
|
|
1161
|
+
const params = { includeSelf: String(includeSelf) };
|
|
1162
|
+
const response = await this.axios.get(`/organizations/${id}/siblings`, { params });
|
|
1163
|
+
return response.data.data || [];
|
|
1164
|
+
}
|
|
1165
|
+
/**
|
|
1166
|
+
* Get organization level
|
|
1167
|
+
*/
|
|
1168
|
+
async getLevel(id) {
|
|
1169
|
+
const response = await this.axios.get(`/organizations/${id}/level`);
|
|
1170
|
+
return response.data.data;
|
|
1171
|
+
}
|
|
1172
|
+
/**
|
|
1173
|
+
* Get lowest common ancestor of two organizations
|
|
1174
|
+
*/
|
|
1175
|
+
async getCommonAncestor(orgA, orgB) {
|
|
1176
|
+
const params = { orgA, orgB };
|
|
1177
|
+
const response = await this.axios.get("/organizations/common-ancestor", {
|
|
1178
|
+
params
|
|
1179
|
+
});
|
|
1180
|
+
return response.data.data || null;
|
|
1181
|
+
}
|
|
1182
|
+
/**
|
|
1183
|
+
* Check if an organization is an ancestor of another
|
|
1184
|
+
*/
|
|
1185
|
+
async isAncestorOf(ancestorId, descendantId) {
|
|
1186
|
+
const params = { ancestorId, descendantId };
|
|
1187
|
+
const response = await this.axios.get("/organizations/check-ancestor", { params });
|
|
1188
|
+
return !!response.data.data;
|
|
1189
|
+
}
|
|
1190
|
+
// ==========================================================================
|
|
1191
|
+
// Hierarchy Tree
|
|
1192
|
+
// ==========================================================================
|
|
1193
|
+
/**
|
|
1194
|
+
* Get organization hierarchy
|
|
1195
|
+
*
|
|
1196
|
+
* @description ดึง hierarchy tree ขององค์กรทั้งหมด หรือเริ่มจาก root ที่ระบุ
|
|
1197
|
+
*
|
|
1198
|
+
* @param rootId - Optional root organization ID. ถ้าไม่ระบุจะดึง hierarchy ทั้งหมด
|
|
1199
|
+
*
|
|
1200
|
+
* @example
|
|
1201
|
+
* ```typescript
|
|
1202
|
+
* // ดึง hierarchy ทั้งหมด
|
|
1203
|
+
* const hierarchy = await authClient.organization.getHierarchy();
|
|
1204
|
+
*
|
|
1205
|
+
* // ดึง hierarchy จาก root ที่ระบุ
|
|
1206
|
+
* const hierarchy = await authClient.organization.getHierarchy("org-root-123");
|
|
1207
|
+
* ```
|
|
1208
|
+
*/
|
|
1209
|
+
async getHierarchy(rootId) {
|
|
1210
|
+
const params = rootId ? { rootId } : {};
|
|
1211
|
+
const response = await this.axios.get("/organizations/hierarchy", { params });
|
|
1212
|
+
return response.data.data || [];
|
|
1213
|
+
}
|
|
1214
|
+
/**
|
|
1215
|
+
* Get organization tree (with departments and positions)
|
|
1216
|
+
*
|
|
1217
|
+
* @description ดึงโครงสร้าง tree ขององค์กร รวม departments, positions และ user assignments
|
|
1218
|
+
*
|
|
1219
|
+
* @example
|
|
1220
|
+
* ```typescript
|
|
1221
|
+
* const tree = await authClient.organization.getTree("org-123");
|
|
1222
|
+
* console.log(tree.children); // departments & positions
|
|
1223
|
+
* console.log(tree.total_users); // จำนวนผู้ใช้ทั้งหมด
|
|
1224
|
+
* ```
|
|
1225
|
+
*/
|
|
1226
|
+
async getTree(id) {
|
|
1227
|
+
const response = await this.axios.get(`/organizations/${id}/tree`);
|
|
1228
|
+
return response.data.data;
|
|
1229
|
+
}
|
|
1230
|
+
/**
|
|
1231
|
+
* Get direct children of organization
|
|
1232
|
+
*
|
|
1233
|
+
* @description ดึงองค์กรลูกตรง (direct children) ขององค์กรที่ระบุ
|
|
1234
|
+
*
|
|
1235
|
+
* @example
|
|
1236
|
+
* ```typescript
|
|
1237
|
+
* const children = await authClient.organization.getChildren("org-123");
|
|
1238
|
+
* ```
|
|
1239
|
+
*/
|
|
1240
|
+
async getChildren(id) {
|
|
1241
|
+
const response = await this.axios.get(`/organizations/${id}/children`);
|
|
1242
|
+
return response.data.data || [];
|
|
1243
|
+
}
|
|
1244
|
+
/**
|
|
1245
|
+
* Get sub-organizations
|
|
1246
|
+
*
|
|
1247
|
+
* @description ดึง sub-organizations ขององค์กรที่ระบุ
|
|
1248
|
+
*
|
|
1249
|
+
* @example
|
|
1250
|
+
* ```typescript
|
|
1251
|
+
* const subOrgs = await authClient.organization.getSubOrganizations("org-123");
|
|
1252
|
+
* ```
|
|
1253
|
+
*/
|
|
1254
|
+
async getSubOrganizations(id) {
|
|
1255
|
+
const response = await this.axios.get(`/organizations/${id}/sub-organizations`);
|
|
1256
|
+
return response.data.data || [];
|
|
1257
|
+
}
|
|
1258
|
+
/**
|
|
1259
|
+
* Get positions under organization
|
|
1260
|
+
*
|
|
1261
|
+
* @description ดึงรายการตำแหน่ง (position nodes) ทั้งหมดภายใต้องค์กรที่ระบุ
|
|
1262
|
+
*
|
|
1263
|
+
* @example
|
|
1264
|
+
* ```typescript
|
|
1265
|
+
* const positions = await authClient.organization.getPositions("org-123");
|
|
1266
|
+
* console.log(positions.map(p => p.name)); // ["Senior Developer", "Team Lead", ...]
|
|
1267
|
+
* ```
|
|
1268
|
+
*/
|
|
1269
|
+
async getPositions(id) {
|
|
1270
|
+
const response = await this.axios.get(`/organizations/${id}/positions`);
|
|
1271
|
+
return response.data.data || [];
|
|
1272
|
+
}
|
|
1273
|
+
// ==========================================================================
|
|
1274
|
+
// Status Management
|
|
1275
|
+
// ==========================================================================
|
|
1276
|
+
/**
|
|
1277
|
+
* Activate organization
|
|
1278
|
+
*
|
|
1279
|
+
* @description เปิดใช้งานองค์กร
|
|
1280
|
+
*
|
|
1281
|
+
* @example
|
|
1282
|
+
* ```typescript
|
|
1283
|
+
* await authClient.organization.activate("org-123");
|
|
1284
|
+
* ```
|
|
1285
|
+
*/
|
|
1286
|
+
async activate(id) {
|
|
1287
|
+
const response = await this.axios.patch(`/organizations/${id}/activate`);
|
|
1288
|
+
return !!response.data.data;
|
|
1289
|
+
}
|
|
1290
|
+
/**
|
|
1291
|
+
* Deactivate organization
|
|
1292
|
+
*
|
|
1293
|
+
* @description ปิดใช้งานองค์กร
|
|
1294
|
+
*
|
|
1295
|
+
* @example
|
|
1296
|
+
* ```typescript
|
|
1297
|
+
* await authClient.organization.deactivate("org-123");
|
|
1298
|
+
* ```
|
|
1299
|
+
*/
|
|
1300
|
+
async deactivate(id) {
|
|
1301
|
+
const response = await this.axios.patch(`/organizations/${id}/deactivate`);
|
|
1302
|
+
return !!response.data.data;
|
|
1303
|
+
}
|
|
1304
|
+
// ==========================================================================
|
|
1305
|
+
// Bulk Operations
|
|
1306
|
+
// ==========================================================================
|
|
1307
|
+
/**
|
|
1308
|
+
* Bulk activate organizations
|
|
1309
|
+
*
|
|
1310
|
+
* @description เปิดใช้งานหลายองค์กรพร้อมกัน
|
|
1311
|
+
*
|
|
1312
|
+
* @example
|
|
1313
|
+
* ```typescript
|
|
1314
|
+
* const result = await authClient.organization.bulkActivate(["org-1", "org-2", "org-3"]);
|
|
1315
|
+
* console.log(result.success_count); // 3
|
|
1316
|
+
* ```
|
|
1317
|
+
*/
|
|
1318
|
+
async bulkActivate(ids) {
|
|
1319
|
+
const response = await this.axios.post("/organizations/bulk-activate", {
|
|
1320
|
+
ids
|
|
1321
|
+
});
|
|
1322
|
+
return response.data.data;
|
|
1323
|
+
}
|
|
1324
|
+
/**
|
|
1325
|
+
* Bulk deactivate organizations
|
|
1326
|
+
*
|
|
1327
|
+
* @description ปิดใช้งานหลายองค์กรพร้อมกัน
|
|
1328
|
+
*
|
|
1329
|
+
* @example
|
|
1330
|
+
* ```typescript
|
|
1331
|
+
* const result = await authClient.organization.bulkDeactivate(["org-1", "org-2"]);
|
|
1332
|
+
* console.log(result.success_count); // 2
|
|
1333
|
+
* ```
|
|
1334
|
+
*/
|
|
1335
|
+
async bulkDeactivate(ids) {
|
|
1336
|
+
const response = await this.axios.post("/organizations/bulk-deactivate", {
|
|
1337
|
+
ids
|
|
1338
|
+
});
|
|
1339
|
+
return response.data.data;
|
|
1340
|
+
}
|
|
1341
|
+
/**
|
|
1342
|
+
* Bulk delete organizations
|
|
1343
|
+
*
|
|
1344
|
+
* @description ลบหลายองค์กรพร้อมกัน
|
|
1345
|
+
*
|
|
1346
|
+
* @example
|
|
1347
|
+
* ```typescript
|
|
1348
|
+
* const result = await authClient.organization.bulkDelete(["org-1", "org-2"]);
|
|
1349
|
+
* console.log(result.success_count); // 2
|
|
1350
|
+
* ```
|
|
1351
|
+
*/
|
|
1352
|
+
async bulkDelete(ids) {
|
|
1353
|
+
const response = await this.axios.post("/organizations/bulk-delete", {
|
|
1354
|
+
ids
|
|
1355
|
+
});
|
|
1356
|
+
return response.data.data;
|
|
1357
|
+
}
|
|
1358
|
+
/**
|
|
1359
|
+
* Clear all organization data
|
|
1360
|
+
*
|
|
1361
|
+
* @description ลบข้อมูลองค์กรทั้งหมด รวมถึง:
|
|
1362
|
+
* - user_position_assignment (เอาข้อมูล position ออกจาก user)
|
|
1363
|
+
* - organization_closure
|
|
1364
|
+
* - organization (company, department, position)
|
|
1365
|
+
* - Nullify organization/position references ใน workflow และ document tables
|
|
1366
|
+
*
|
|
1367
|
+
* รองรับทั้ง JWT และ API Key authentication (สำหรับเรียกจากระบบอื่น)
|
|
1368
|
+
*
|
|
1369
|
+
* @example
|
|
1370
|
+
* ```typescript
|
|
1371
|
+
* const result = await authClient.organization.clearAll();
|
|
1372
|
+
* console.log(result.organizations_deleted); // จำนวนองค์กรที่ลบ
|
|
1373
|
+
* console.log(result.user_position_assignments_deleted); // จำนวน position assignment ที่ลบ
|
|
1374
|
+
* ```
|
|
1375
|
+
*/
|
|
1376
|
+
async clearAll() {
|
|
1377
|
+
const response = await this.axios.post("/organizations/clear-all");
|
|
1378
|
+
return response.data.data;
|
|
1379
|
+
}
|
|
1380
|
+
/**
|
|
1381
|
+
* Rebuild all organization data (รวมทุก fix ในครั้งเดียว)
|
|
1382
|
+
*
|
|
1383
|
+
* @description ใช้หลัง clear-all + create เพื่อให้ข้อมูลครบถ้วน:
|
|
1384
|
+
* 1. fix organization_id ตาม hierarchy
|
|
1385
|
+
* 2. reload organization_closure สำหรับทุก company
|
|
1386
|
+
* 3. reload report_to_position
|
|
1387
|
+
*
|
|
1388
|
+
* @example
|
|
1389
|
+
* ```typescript
|
|
1390
|
+
* await authClient.organization.clearAll();
|
|
1391
|
+
* // ... create organizations ...
|
|
1392
|
+
* const result = await authClient.organization.rebuildAll();
|
|
1393
|
+
* console.log(result.organization_ids_fixed, result.closure_companies_processed);
|
|
1394
|
+
* ```
|
|
1395
|
+
*/
|
|
1396
|
+
async rebuildAll() {
|
|
1397
|
+
const response = await this.axios.post("/organizations/rebuild-all");
|
|
1398
|
+
return response.data.data;
|
|
1399
|
+
}
|
|
1400
|
+
// ==========================================================================
|
|
1401
|
+
// Hierarchy Operations
|
|
1402
|
+
// ==========================================================================
|
|
1403
|
+
/**
|
|
1404
|
+
* Duplicate organization (copy)
|
|
1405
|
+
*
|
|
1406
|
+
* @description คัดลอกองค์กรและ children ทั้งหมด สร้าง organization ใหม่พร้อม hierarchy fields และ closure records
|
|
1407
|
+
*
|
|
1408
|
+
* @example
|
|
1409
|
+
* ```typescript
|
|
1410
|
+
* const duplicated = await authClient.organization.duplicate("org-123");
|
|
1411
|
+
* console.log(duplicated.id); // new organization ID
|
|
1412
|
+
* ```
|
|
1413
|
+
*/
|
|
1414
|
+
async duplicate(id) {
|
|
1415
|
+
const response = await this.axios.post(`/organizations/${id}/duplicate`);
|
|
1416
|
+
return response.data.data;
|
|
1417
|
+
}
|
|
1418
|
+
/**
|
|
1419
|
+
* Move organization to new parent
|
|
1420
|
+
*
|
|
1421
|
+
* @description ย้ายองค์กรไปอยู่ภายใต้ parent ใหม่ อัพเดท hierarchy fields และ closure table อัตโนมัติ
|
|
1422
|
+
* ส่ง `null` เพื่อย้ายไปเป็น root level
|
|
1423
|
+
*
|
|
1424
|
+
* @example
|
|
1425
|
+
* ```typescript
|
|
1426
|
+
* // ย้ายไปอยู่ภายใต้ parent ใหม่
|
|
1427
|
+
* await authClient.organization.move("org-123", { new_parent_id: "org-456" });
|
|
1428
|
+
*
|
|
1429
|
+
* // ย้ายไปเป็น root level
|
|
1430
|
+
* await authClient.organization.move("org-123", { new_parent_id: null });
|
|
1431
|
+
* ```
|
|
1432
|
+
*/
|
|
1433
|
+
async move(id, data) {
|
|
1434
|
+
const response = await this.axios.patch(`/organizations/${id}/move`, data);
|
|
1435
|
+
return !!response.data.success;
|
|
1436
|
+
}
|
|
1437
|
+
};
|
|
1438
|
+
|
|
1439
|
+
// src/api/role.api.ts
|
|
1440
|
+
var RoleAPI = class {
|
|
1441
|
+
constructor(axios2) {
|
|
1442
|
+
this.axios = axios2;
|
|
1443
|
+
}
|
|
1444
|
+
// ==========================================================================
|
|
1445
|
+
// CRUD Operations
|
|
1446
|
+
// ==========================================================================
|
|
1447
|
+
/**
|
|
1448
|
+
* Search roles with pagination and filters
|
|
1449
|
+
*
|
|
1450
|
+
* @example
|
|
1451
|
+
* ```typescript
|
|
1452
|
+
* const result = await authClient.role.search({
|
|
1453
|
+
* search: "Admin",
|
|
1454
|
+
* page: 1,
|
|
1455
|
+
* limit: 20,
|
|
1456
|
+
* sort_by: "created_at",
|
|
1457
|
+
* sort_order: "desc"
|
|
1458
|
+
* });
|
|
1459
|
+
* ```
|
|
1460
|
+
*/
|
|
1461
|
+
async search(params) {
|
|
1462
|
+
const response = await this.axios.post("/roles/search", params || {});
|
|
1463
|
+
return response.data;
|
|
1464
|
+
}
|
|
1465
|
+
/**
|
|
1466
|
+
* Get role by ID
|
|
1467
|
+
*
|
|
1468
|
+
* @example
|
|
1469
|
+
* ```typescript
|
|
1470
|
+
* const role = await authClient.role.get("role-123");
|
|
1471
|
+
* ```
|
|
1472
|
+
*/
|
|
1473
|
+
async get(roleId) {
|
|
1474
|
+
const response = await this.axios.get(`/roles/${roleId}`);
|
|
1475
|
+
return response.data.data;
|
|
1476
|
+
}
|
|
1477
|
+
/**
|
|
1478
|
+
* Create a new role
|
|
1479
|
+
*
|
|
1480
|
+
* @example
|
|
1481
|
+
* ```typescript
|
|
1482
|
+
* const newRole = await authClient.role.create({
|
|
1483
|
+
* name: "ผู้ดูแลระบบ",
|
|
1484
|
+
* code: "ADMIN",
|
|
1485
|
+
* description: "บทบาทสำหรับผู้ดูแลระบบ"
|
|
1486
|
+
* });
|
|
1487
|
+
* ```
|
|
1488
|
+
*/
|
|
1489
|
+
async create(data) {
|
|
1490
|
+
const response = await this.axios.post("/roles", data);
|
|
1491
|
+
return response.data.data;
|
|
1492
|
+
}
|
|
1493
|
+
/**
|
|
1494
|
+
* Update role
|
|
1495
|
+
*
|
|
1496
|
+
* @example
|
|
1497
|
+
* ```typescript
|
|
1498
|
+
* const updatedRole = await authClient.role.update("role-123", {
|
|
1499
|
+
* name: "ผู้ดูแลระบบหลัก",
|
|
1500
|
+
* description: "บทบาทสำหรับผู้ดูแลระบบหลัก"
|
|
1501
|
+
* });
|
|
1502
|
+
* ```
|
|
1503
|
+
*/
|
|
1504
|
+
async update(roleId, data) {
|
|
1505
|
+
const response = await this.axios.put(`/roles/${roleId}`, data);
|
|
1506
|
+
return response.data.data;
|
|
1507
|
+
}
|
|
1508
|
+
/**
|
|
1509
|
+
* Clear all roles for current application (hard delete)
|
|
1510
|
+
*
|
|
1511
|
+
* @description ลบบทบาททั้งหมดตาม application_id จาก RequestContext (API key/context)
|
|
1512
|
+
* ใช้สำหรับ migrate - ไม่ใช้ DTO, ดึง application_id จาก context อัตโนมัติ
|
|
1513
|
+
*
|
|
1514
|
+
* @example
|
|
1515
|
+
* ```typescript
|
|
1516
|
+
* const result = await authClient.role.clear();
|
|
1517
|
+
* console.log(result.roles_deleted, result.role_permissions_deleted);
|
|
1518
|
+
* ```
|
|
1519
|
+
*/
|
|
1520
|
+
async clear() {
|
|
1521
|
+
const response = await this.axios.post("/roles/clear");
|
|
1522
|
+
return response.data.data;
|
|
1523
|
+
}
|
|
1524
|
+
/**
|
|
1525
|
+
* Delete role
|
|
1526
|
+
*
|
|
1527
|
+
* @example
|
|
1528
|
+
* ```typescript
|
|
1529
|
+
* await authClient.role.delete("role-123");
|
|
1530
|
+
* ```
|
|
1531
|
+
*/
|
|
1532
|
+
async delete(roleId) {
|
|
1533
|
+
const response = await this.axios.delete(`/roles/${roleId}`);
|
|
1534
|
+
return !!response.data.success;
|
|
1535
|
+
}
|
|
1536
|
+
// ==========================================================================
|
|
1537
|
+
// Status Management
|
|
1538
|
+
// ==========================================================================
|
|
1539
|
+
/**
|
|
1540
|
+
* Activate role
|
|
1541
|
+
*
|
|
1542
|
+
* @example
|
|
1543
|
+
* ```typescript
|
|
1544
|
+
* await authClient.role.activate("role-123");
|
|
1545
|
+
* ```
|
|
1546
|
+
*/
|
|
1547
|
+
async activate(roleId) {
|
|
1548
|
+
const response = await this.axios.patch(`/roles/${roleId}/activate`);
|
|
1549
|
+
return !!response.data.data;
|
|
1550
|
+
}
|
|
1551
|
+
/**
|
|
1552
|
+
* Deactivate role
|
|
1553
|
+
*
|
|
1554
|
+
* @example
|
|
1555
|
+
* ```typescript
|
|
1556
|
+
* await authClient.role.deactivate("role-123");
|
|
1557
|
+
* ```
|
|
1558
|
+
*/
|
|
1559
|
+
async deactivate(roleId) {
|
|
1560
|
+
const response = await this.axios.patch(`/roles/${roleId}/deactivate`);
|
|
1561
|
+
return !!response.data.data;
|
|
1562
|
+
}
|
|
1563
|
+
// ==========================================================================
|
|
1564
|
+
// User Assignment
|
|
1565
|
+
// ==========================================================================
|
|
1566
|
+
/**
|
|
1567
|
+
* Get role users
|
|
1568
|
+
*
|
|
1569
|
+
* @description ดึงรายการผู้ใช้ทั้งหมดที่มีบทบาทนี้
|
|
1570
|
+
*
|
|
1571
|
+
* @example
|
|
1572
|
+
* ```typescript
|
|
1573
|
+
* const users = await authClient.role.getUsers("role-123");
|
|
1574
|
+
* console.log(users.map(u => u.email));
|
|
1575
|
+
* ```
|
|
1576
|
+
*/
|
|
1577
|
+
async getUsers(roleId) {
|
|
1578
|
+
const response = await this.axios.get(`/roles/${roleId}/users`);
|
|
1579
|
+
return response.data.data || [];
|
|
1580
|
+
}
|
|
1581
|
+
/**
|
|
1582
|
+
* Assign users to role
|
|
1583
|
+
*
|
|
1584
|
+
* @description มอบหมายผู้ใช้ให้บทบาท (เพิ่มเข้าไป ไม่ลบของเดิม)
|
|
1585
|
+
*
|
|
1586
|
+
* @example
|
|
1587
|
+
* ```typescript
|
|
1588
|
+
* await authClient.role.assignUsers("role-123", ["user-001", "user-002"]);
|
|
1589
|
+
* ```
|
|
1590
|
+
*/
|
|
1591
|
+
async assignUsers(roleId, userIds) {
|
|
1592
|
+
const response = await this.axios.post(`/roles/${roleId}/users`, {
|
|
1593
|
+
ids: userIds
|
|
1594
|
+
});
|
|
1595
|
+
return !!response.data.success;
|
|
1596
|
+
}
|
|
1597
|
+
/**
|
|
1598
|
+
* Unassign users from role
|
|
1599
|
+
*
|
|
1600
|
+
* @description ยกเลิกผู้ใช้จากบทบาท
|
|
1601
|
+
*
|
|
1602
|
+
* @example
|
|
1603
|
+
* ```typescript
|
|
1604
|
+
* await authClient.role.unassignUsers("role-123", ["user-001"]);
|
|
1605
|
+
* ```
|
|
1606
|
+
*/
|
|
1607
|
+
async unassignUsers(roleId, userIds) {
|
|
1608
|
+
const response = await this.axios.delete(`/roles/${roleId}/users`, {
|
|
1609
|
+
data: { ids: userIds }
|
|
1610
|
+
});
|
|
1611
|
+
return !!response.data.success;
|
|
1612
|
+
}
|
|
1613
|
+
// ==========================================================================
|
|
1614
|
+
// Permission Assignment
|
|
1615
|
+
// ==========================================================================
|
|
1616
|
+
/**
|
|
1617
|
+
* Get role permissions
|
|
1618
|
+
*
|
|
1619
|
+
* @description ดึงรายการสิทธิ์ทั้งหมดของบทบาท
|
|
1620
|
+
*
|
|
1621
|
+
* @example
|
|
1622
|
+
* ```typescript
|
|
1623
|
+
* const permissions = await authClient.role.getPermissions("role-123");
|
|
1624
|
+
* ```
|
|
1625
|
+
*/
|
|
1626
|
+
async getPermissions(roleId) {
|
|
1627
|
+
const response = await this.axios.get(`/roles/${roleId}/permissions`);
|
|
1628
|
+
return response.data.data || [];
|
|
1629
|
+
}
|
|
1630
|
+
/**
|
|
1631
|
+
* Assign permissions to role
|
|
1632
|
+
*
|
|
1633
|
+
* @description มอบหมายสิทธิ์ให้บทบาท
|
|
1634
|
+
*
|
|
1635
|
+
* @example
|
|
1636
|
+
* ```typescript
|
|
1637
|
+
* await authClient.role.assignPermissions("role-123", ["perm-001", "perm-002"]);
|
|
1638
|
+
* ```
|
|
1639
|
+
*/
|
|
1640
|
+
async assignPermissions(roleId, permissionIds) {
|
|
1641
|
+
const response = await this.axios.post(`/roles/${roleId}/permissions`, {
|
|
1642
|
+
ids: permissionIds
|
|
1643
|
+
});
|
|
1644
|
+
return !!response.data.success;
|
|
1645
|
+
}
|
|
1646
|
+
/**
|
|
1647
|
+
* Unassign permissions from role
|
|
1648
|
+
*
|
|
1649
|
+
* @description ยกเลิกสิทธิ์จากบทบาท
|
|
1650
|
+
*
|
|
1651
|
+
* @example
|
|
1652
|
+
* ```typescript
|
|
1653
|
+
* await authClient.role.unassignPermissions("role-123", ["perm-001"]);
|
|
1654
|
+
* ```
|
|
1655
|
+
*/
|
|
1656
|
+
async unassignPermissions(roleId, permissionIds) {
|
|
1657
|
+
const response = await this.axios.delete(`/roles/${roleId}/permissions`, {
|
|
1658
|
+
data: { ids: permissionIds }
|
|
1659
|
+
});
|
|
1660
|
+
return !!response.data.success;
|
|
1661
|
+
}
|
|
1662
|
+
};
|
|
1663
|
+
|
|
1664
|
+
// src/api/permission.api.ts
|
|
1665
|
+
var PermissionAPI = class {
|
|
1666
|
+
constructor(axios2) {
|
|
1667
|
+
this.axios = axios2;
|
|
1668
|
+
}
|
|
1669
|
+
/**
|
|
1670
|
+
* Clear all permissions for current application (hard delete)
|
|
1671
|
+
*
|
|
1672
|
+
* @description ลบสิทธิ์ทั้งหมดตาม application_id จาก RequestContext (API key/context)
|
|
1673
|
+
* ใช้สำหรับ migrate - ไม่ใช้ DTO, ดึง application_id จาก context อัตโนมัติ
|
|
1674
|
+
*
|
|
1675
|
+
* @example
|
|
1676
|
+
* ```typescript
|
|
1677
|
+
* const result = await authClient.permission.clear();
|
|
1678
|
+
* console.log(result.permissions_deleted, result.role_permissions_deleted);
|
|
1679
|
+
* ```
|
|
1680
|
+
*/
|
|
1681
|
+
async clear() {
|
|
1682
|
+
const response = await this.axios.post("/permissions/clear");
|
|
1683
|
+
return response.data.data;
|
|
1684
|
+
}
|
|
1685
|
+
/**
|
|
1686
|
+
* Search permissions with pagination and filters
|
|
1687
|
+
*/
|
|
1688
|
+
async search(params) {
|
|
1689
|
+
const response = await this.axios.post("/permissions/search", params || {});
|
|
1690
|
+
return response.data;
|
|
1691
|
+
}
|
|
1692
|
+
/**
|
|
1693
|
+
* Get permission by ID
|
|
1694
|
+
*/
|
|
1695
|
+
async get(id) {
|
|
1696
|
+
const response = await this.axios.get(`/permissions/${id}`);
|
|
1697
|
+
return response.data.data ?? null;
|
|
1698
|
+
}
|
|
1699
|
+
/**
|
|
1700
|
+
* Create a new permission
|
|
1701
|
+
*/
|
|
1702
|
+
async create(data) {
|
|
1703
|
+
const response = await this.axios.post("/permissions", data);
|
|
1704
|
+
return response.data.data;
|
|
1705
|
+
}
|
|
1706
|
+
/**
|
|
1707
|
+
* Bulk create permissions ในครั้งเดียว
|
|
1708
|
+
*
|
|
1709
|
+
* @description สร้างสิทธิ์หลายรายการในครั้งเดียว ทุก permission ต้องมี category_id ที่มีอยู่แล้วในระบบ
|
|
1710
|
+
*
|
|
1711
|
+
* @example
|
|
1712
|
+
* ```typescript
|
|
1713
|
+
* const result = await authClient.permission.bulkCreate({
|
|
1714
|
+
* permissions: [
|
|
1715
|
+
* { category_id: "cat-uuid", name: "Create", key: "create", description: "..." },
|
|
1716
|
+
* { category_id: "cat-uuid", name: "Read", key: "read", description: "..." },
|
|
1717
|
+
* ],
|
|
1718
|
+
* });
|
|
1719
|
+
* console.log(result.created); // 2
|
|
1720
|
+
* ```
|
|
1721
|
+
*/
|
|
1722
|
+
async bulkCreate(data) {
|
|
1723
|
+
const response = await this.axios.post("/permissions/bulk-create", data);
|
|
1724
|
+
return response.data.data;
|
|
1725
|
+
}
|
|
1726
|
+
/**
|
|
1727
|
+
* Update permission
|
|
1728
|
+
*/
|
|
1729
|
+
async update(id, data) {
|
|
1730
|
+
const response = await this.axios.put(`/permissions/${id}`, data);
|
|
1731
|
+
return response.data.data;
|
|
1732
|
+
}
|
|
1733
|
+
/**
|
|
1734
|
+
* Delete permission
|
|
1735
|
+
*/
|
|
1736
|
+
async delete(id) {
|
|
1737
|
+
const response = await this.axios.delete(`/permissions/${id}`);
|
|
1738
|
+
return !!response.data.success;
|
|
1739
|
+
}
|
|
1740
|
+
/**
|
|
1741
|
+
* Activate permission
|
|
1742
|
+
*/
|
|
1743
|
+
async activate(id) {
|
|
1744
|
+
const response = await this.axios.patch(`/permissions/${id}/activate`);
|
|
1745
|
+
return !!response.data.data;
|
|
1746
|
+
}
|
|
1747
|
+
/**
|
|
1748
|
+
* Deactivate permission
|
|
1749
|
+
*/
|
|
1750
|
+
async deactivate(id) {
|
|
1751
|
+
const response = await this.axios.patch(`/permissions/${id}/deactivate`);
|
|
1752
|
+
return !!response.data.data;
|
|
1753
|
+
}
|
|
1754
|
+
};
|
|
1755
|
+
|
|
1756
|
+
// src/api/permission-category.api.ts
|
|
1757
|
+
var PermissionCategoryAPI = class {
|
|
1758
|
+
constructor(axios2) {
|
|
1759
|
+
this.axios = axios2;
|
|
1760
|
+
}
|
|
1761
|
+
/**
|
|
1762
|
+
* Clear all permission categories for current application (hard delete)
|
|
1763
|
+
*
|
|
1764
|
+
* @description ลบหมวดหมู่สิทธิ์ทั้งหมดตาม application_id จาก RequestContext (API key/context)
|
|
1765
|
+
* ใช้สำหรับ migrate - ไม่ใช้ DTO, ดึง application_id จาก context อัตโนมัติ
|
|
1766
|
+
*
|
|
1767
|
+
* @example
|
|
1768
|
+
* ```typescript
|
|
1769
|
+
* const result = await authClient.permissionCategory.clear();
|
|
1770
|
+
* console.log(result.permission_categories_deleted, result.permissions_deleted);
|
|
1771
|
+
* ```
|
|
1772
|
+
*/
|
|
1773
|
+
async clear() {
|
|
1774
|
+
const response = await this.axios.post(
|
|
1775
|
+
"/permission-categories/clear"
|
|
1776
|
+
);
|
|
1777
|
+
return response.data.data;
|
|
1778
|
+
}
|
|
1779
|
+
/**
|
|
1780
|
+
* Search permission categories with pagination and filters
|
|
1781
|
+
*/
|
|
1782
|
+
async search(params) {
|
|
1783
|
+
const response = await this.axios.post(
|
|
1784
|
+
"/permission-categories/search",
|
|
1785
|
+
params || {}
|
|
1786
|
+
);
|
|
1787
|
+
return response.data;
|
|
1788
|
+
}
|
|
1789
|
+
/**
|
|
1790
|
+
* Get permission category by ID
|
|
1791
|
+
*/
|
|
1792
|
+
async get(id) {
|
|
1793
|
+
const response = await this.axios.get(`/permission-categories/${id}`);
|
|
1794
|
+
return response.data.data;
|
|
1795
|
+
}
|
|
1796
|
+
/**
|
|
1797
|
+
* Create a new permission category (พร้อม permissions ได้)
|
|
1798
|
+
*
|
|
1799
|
+
* @note application_id ไม่ต้องส่งเมื่อเรียกจาก app context - API จะ inject อัตโนมัติ
|
|
1800
|
+
*/
|
|
1801
|
+
async create(data) {
|
|
1802
|
+
const response = await this.axios.post("/permission-categories", data);
|
|
1803
|
+
return response.data.data;
|
|
1804
|
+
}
|
|
1805
|
+
/**
|
|
1806
|
+
* Bulk create permission categories พร้อม permissions ในครั้งเดียว
|
|
1807
|
+
*
|
|
1808
|
+
* @description สร้างหมวดหมู่สิทธิ์หลายรายการพร้อม permissions ในครั้งเดียว
|
|
1809
|
+
* ต้องเรียง parent ก่อน child หรือระบุ id ให้ parent เพื่อให้ child อ้างอิง parent_id ได้
|
|
1810
|
+
*
|
|
1811
|
+
* @note application_id ไม่ต้องส่ง - API จะ inject อัตโนมัติจาก API key หรือ RequestContextService
|
|
1812
|
+
*
|
|
1813
|
+
* @example
|
|
1814
|
+
* ```typescript
|
|
1815
|
+
* // เรียกจาก app context (API key) - application_id จะถูก inject อัตโนมัติ
|
|
1816
|
+
* const result = await authClient.permissionCategory.bulkCreate({
|
|
1817
|
+
* permission_categories: [
|
|
1818
|
+
* {
|
|
1819
|
+
* id: "cat-users",
|
|
1820
|
+
* key: "users",
|
|
1821
|
+
* name: "User Management",
|
|
1822
|
+
* resource: "users",
|
|
1823
|
+
* permissions: [
|
|
1824
|
+
* { name: "Create User", key: "create", description: "..." },
|
|
1825
|
+
* { name: "Read User", key: "read", description: "..." },
|
|
1826
|
+
* ],
|
|
1827
|
+
* },
|
|
1828
|
+
* {
|
|
1829
|
+
* key: "user_profile",
|
|
1830
|
+
* name: "User Profile",
|
|
1831
|
+
* parent_id: "cat-users",
|
|
1832
|
+
* permissions: [{ name: "Edit Profile", key: "edit", description: "..." }],
|
|
1833
|
+
* },
|
|
1834
|
+
* ],
|
|
1835
|
+
* });
|
|
1836
|
+
* console.log(result.created); // 2
|
|
1837
|
+
* ```
|
|
1838
|
+
*/
|
|
1839
|
+
async bulkCreate(data) {
|
|
1840
|
+
const response = await this.axios.post(
|
|
1841
|
+
"/permission-categories/bulk-create",
|
|
1842
|
+
data
|
|
1843
|
+
);
|
|
1844
|
+
return response.data.data;
|
|
1845
|
+
}
|
|
1846
|
+
/**
|
|
1847
|
+
* Update permission category
|
|
1848
|
+
*/
|
|
1849
|
+
async update(id, data) {
|
|
1850
|
+
const response = await this.axios.put(`/permission-categories/${id}`, data);
|
|
1851
|
+
return response.data.data;
|
|
1852
|
+
}
|
|
1853
|
+
/**
|
|
1854
|
+
* Delete permission category
|
|
1855
|
+
*/
|
|
1856
|
+
async delete(id) {
|
|
1857
|
+
const response = await this.axios.delete(`/permission-categories/${id}`);
|
|
1858
|
+
return !!response.data.success;
|
|
1859
|
+
}
|
|
1860
|
+
};
|
|
1861
|
+
|
|
1862
|
+
// src/api/webhook.api.ts
|
|
1863
|
+
var WebhookAPI = class {
|
|
1864
|
+
constructor(axios2) {
|
|
1865
|
+
this.axios = axios2;
|
|
1866
|
+
}
|
|
1867
|
+
/**
|
|
1868
|
+
* ส่ง webhook request ผ่าน proxy endpoint
|
|
1869
|
+
*
|
|
1870
|
+
* @description
|
|
1871
|
+
* - ส่ง webhook request ไปยัง external URL ผ่านระบบ proxy
|
|
1872
|
+
* - ระบบจะสร้าง webhook_log และยิง webhook ออกไปให้
|
|
1873
|
+
* - รองรับ retry mechanism อัตโนมัติ
|
|
1874
|
+
* - ส่ง async: true เพื่อยิงทันทีและรับ result (http_status, response_body) ใน response
|
|
1875
|
+
*
|
|
1876
|
+
* @example
|
|
1877
|
+
* ```typescript
|
|
1878
|
+
* // ส่ง webhook request (โหมดปกติ - ได้ webhook_log_id กลับมา แล้วค่อย getStatus ตรวจสอบ)
|
|
1879
|
+
* const result = await authClient.webhook.proxy({
|
|
1880
|
+
* webhook_url: 'https://api.example.com/webhooks/users',
|
|
1881
|
+
* event_type: 'user.created',
|
|
1882
|
+
* payload: {
|
|
1883
|
+
* data: { id: 'user-123', email: 'user@example.com' },
|
|
1884
|
+
* object: 'event',
|
|
1885
|
+
* type: 'user.created'
|
|
1886
|
+
* },
|
|
1887
|
+
* headers: { 'Authorization': 'Bearer token' },
|
|
1888
|
+
* secret: 'webhook-secret',
|
|
1889
|
+
* timeout_ms: 30000,
|
|
1890
|
+
* max_retries: 3
|
|
1891
|
+
* });
|
|
1892
|
+
* console.log('Webhook Log ID:', result.webhook_log_id);
|
|
1893
|
+
*
|
|
1894
|
+
* // โหมด async: true - ยิงทันทีและได้ result กลับใน response (ไม่ต้อง getStatus)
|
|
1895
|
+
* const resultAsync = await authClient.webhook.proxy({
|
|
1896
|
+
* webhook_url: 'https://api.example.com/webhooks/users',
|
|
1897
|
+
* event_type: 'user.created',
|
|
1898
|
+
* payload: { data: { id: 'user-123' }, object: 'event', type: 'user.created' },
|
|
1899
|
+
* async: true
|
|
1900
|
+
* });
|
|
1901
|
+
* if (resultAsync.status === 'success') {
|
|
1902
|
+
* console.log('HTTP Status:', resultAsync.http_status);
|
|
1903
|
+
* console.log('Response Body:', resultAsync.response_body);
|
|
1904
|
+
* console.log('Execution Time:', resultAsync.execution_time_ms, 'ms');
|
|
1905
|
+
* } else {
|
|
1906
|
+
* console.error('Failed:', resultAsync.error_message);
|
|
1907
|
+
* }
|
|
1908
|
+
* ```
|
|
1909
|
+
*/
|
|
1910
|
+
async proxy(request) {
|
|
1911
|
+
const response = await this.axios.post("/webhook-proxy", request);
|
|
1912
|
+
return response.data.data;
|
|
1913
|
+
}
|
|
1914
|
+
/**
|
|
1915
|
+
* ดึง webhook log detail ตาม ID
|
|
1916
|
+
*
|
|
1917
|
+
* @description
|
|
1918
|
+
* - ดึงข้อมูล webhook log ตาม ID ที่ส่งกลับมาจาก proxy()
|
|
1919
|
+
* - แสดง status, response, error message, และข้อมูลอื่นๆ
|
|
1920
|
+
* - สามารถดึงได้เฉพาะ webhook logs ของ application ที่ authenticate อยู่เท่านั้น
|
|
1921
|
+
*
|
|
1922
|
+
* @example
|
|
1923
|
+
* ```typescript
|
|
1924
|
+
* // ดึง webhook log detail
|
|
1925
|
+
* const log = await authClient.webhook.getStatus('log-123e4567-e89b-12d3-a456-426614174000');
|
|
1926
|
+
*
|
|
1927
|
+
* console.log('Status:', log.status); // 'success', 'failed', 'pending', 'retrying'
|
|
1928
|
+
* console.log('HTTP Status:', log.http_status); // 200, 404, 500, etc.
|
|
1929
|
+
* console.log('Response Body:', log.response_body);
|
|
1930
|
+
* console.log('Error:', log.error_message);
|
|
1931
|
+
* console.log('Execution Time:', log.execution_time_ms, 'ms');
|
|
1932
|
+
* console.log('Retry Count:', log.retry_count);
|
|
1933
|
+
*
|
|
1934
|
+
* // ตรวจสอบว่า webhook สำเร็จหรือไม่
|
|
1935
|
+
* if (log.status === 'success') {
|
|
1936
|
+
* console.log('Webhook delivered successfully!');
|
|
1937
|
+
* } else if (log.status === 'failed') {
|
|
1938
|
+
* console.error('Webhook failed:', log.error_message);
|
|
1939
|
+
* }
|
|
1940
|
+
* ```
|
|
1941
|
+
*/
|
|
1942
|
+
async getStatus(webhookLogId) {
|
|
1943
|
+
const response = await this.axios.get(`/webhook-proxy/${webhookLogId}`);
|
|
1944
|
+
return response.data.data;
|
|
1945
|
+
}
|
|
1946
|
+
};
|
|
1947
|
+
|
|
1948
|
+
// src/portal-api-client.ts
|
|
1949
|
+
var PortalApiClient = class {
|
|
1950
|
+
constructor(config) {
|
|
1951
|
+
this.axios = axios.create({
|
|
1952
|
+
baseURL: config.apiUrl,
|
|
1953
|
+
timeout: config.timeout ?? 3e4,
|
|
1954
|
+
withCredentials: true
|
|
1955
|
+
});
|
|
1956
|
+
this.axios.interceptors.request.use((cfg) => {
|
|
1957
|
+
const token = config.getToken();
|
|
1958
|
+
if (token) cfg.headers.Authorization = `Bearer ${token}`;
|
|
1959
|
+
if (config.apiKey) cfg.headers["X-API-Key"] = config.apiKey;
|
|
1960
|
+
return cfg;
|
|
1961
|
+
});
|
|
1962
|
+
this.email = new EmailAPI(this.axios);
|
|
1963
|
+
this.eventLog = new EventLogApi(this.axios);
|
|
1964
|
+
this.files = new FilesAPI(this.axios);
|
|
1965
|
+
this.health = new HealthAPI(this.axios);
|
|
1966
|
+
this.line = new LineAPI(this.axios);
|
|
1967
|
+
this.organization = new OrganizationAPI(this.axios);
|
|
1968
|
+
this.otp = new OtpAPI(this.axios);
|
|
1969
|
+
this.permission = new PermissionAPI(this.axios);
|
|
1970
|
+
this.permissionCategory = new PermissionCategoryAPI(this.axios);
|
|
1971
|
+
this.role = new RoleAPI(this.axios);
|
|
1972
|
+
this.systemConfig = new SystemConfigAPI(this.axios);
|
|
1973
|
+
this.todo = new TodoAPI(this.axios);
|
|
1974
|
+
this.user = new UserAPI(this.axios);
|
|
1975
|
+
this.webhook = new WebhookAPI(this.axios);
|
|
1976
|
+
this.workflow = new WorkflowAPI(this.axios);
|
|
1977
|
+
}
|
|
1978
|
+
get(url, config) {
|
|
1979
|
+
return this.axios.get(url, config);
|
|
1980
|
+
}
|
|
1981
|
+
post(url, data, config) {
|
|
1982
|
+
return this.axios.post(url, data, config);
|
|
1983
|
+
}
|
|
1984
|
+
put(url, data, config) {
|
|
1985
|
+
return this.axios.put(url, data, config);
|
|
1986
|
+
}
|
|
1987
|
+
patch(url, data, config) {
|
|
1988
|
+
return this.axios.patch(url, data, config);
|
|
1989
|
+
}
|
|
1990
|
+
delete(url, config) {
|
|
1991
|
+
return this.axios.delete(url, config);
|
|
1992
|
+
}
|
|
1993
|
+
};
|
|
1994
|
+
|
|
1995
|
+
// ../../shared/src/enums/common.enums.ts
|
|
1996
|
+
var OrganizationType = /* @__PURE__ */ ((OrganizationType2) => {
|
|
1997
|
+
OrganizationType2["GROUP"] = "group";
|
|
1998
|
+
OrganizationType2["COMPANY"] = "company";
|
|
1999
|
+
OrganizationType2["BRANCH"] = "branch";
|
|
2000
|
+
OrganizationType2["DIVISION"] = "division";
|
|
2001
|
+
OrganizationType2["DEPARTMENT"] = "department";
|
|
2002
|
+
OrganizationType2["SECTION"] = "section";
|
|
2003
|
+
OrganizationType2["TEAM"] = "team";
|
|
2004
|
+
OrganizationType2["POSITION"] = "position";
|
|
2005
|
+
return OrganizationType2;
|
|
2006
|
+
})(OrganizationType || {});
|
|
2007
|
+
|
|
2008
|
+
// ../../shared/src/enums/event-log.enums.ts
|
|
2009
|
+
var EventSeverity = /* @__PURE__ */ ((EventSeverity2) => {
|
|
2010
|
+
EventSeverity2["DEBUG"] = "debug";
|
|
2011
|
+
EventSeverity2["INFO"] = "info";
|
|
2012
|
+
EventSeverity2["WARNING"] = "warning";
|
|
2013
|
+
EventSeverity2["ERROR"] = "error";
|
|
2014
|
+
EventSeverity2["CRITICAL"] = "critical";
|
|
2015
|
+
return EventSeverity2;
|
|
2016
|
+
})(EventSeverity || {});
|
|
2017
|
+
var EventOutcome = /* @__PURE__ */ ((EventOutcome2) => {
|
|
2018
|
+
EventOutcome2["SUCCESS"] = "success";
|
|
2019
|
+
EventOutcome2["FAILURE"] = "failure";
|
|
2020
|
+
EventOutcome2["PARTIAL"] = "partial";
|
|
2021
|
+
EventOutcome2["UNKNOWN"] = "unknown";
|
|
2022
|
+
return EventOutcome2;
|
|
2023
|
+
})(EventOutcome || {});
|
|
2024
|
+
var EventCategory = /* @__PURE__ */ ((EventCategory2) => {
|
|
2025
|
+
EventCategory2["AUTHENTICATION"] = "authentication";
|
|
2026
|
+
EventCategory2["AUTHORIZATION"] = "authorization";
|
|
2027
|
+
EventCategory2["DATA_ACCESS"] = "data_access";
|
|
2028
|
+
EventCategory2["SECURITY"] = "security";
|
|
2029
|
+
EventCategory2["BUSINESS"] = "business";
|
|
2030
|
+
EventCategory2["TECHNICAL"] = "technical";
|
|
2031
|
+
EventCategory2["COMPLIANCE"] = "compliance";
|
|
2032
|
+
EventCategory2["ISO27001_AUDIT"] = "iso27001_audit";
|
|
2033
|
+
return EventCategory2;
|
|
2034
|
+
})(EventCategory || {});
|
|
2035
|
+
var EventRiskLevel = /* @__PURE__ */ ((EventRiskLevel2) => {
|
|
2036
|
+
EventRiskLevel2["NONE"] = "none";
|
|
2037
|
+
EventRiskLevel2["LOW"] = "low";
|
|
2038
|
+
EventRiskLevel2["MEDIUM"] = "medium";
|
|
2039
|
+
EventRiskLevel2["HIGH"] = "high";
|
|
2040
|
+
EventRiskLevel2["CRITICAL"] = "critical";
|
|
2041
|
+
return EventRiskLevel2;
|
|
2042
|
+
})(EventRiskLevel || {});
|
|
2043
|
+
var ActorType = /* @__PURE__ */ ((ActorType2) => {
|
|
2044
|
+
ActorType2["USER"] = "user";
|
|
2045
|
+
ActorType2["SYSTEM"] = "system";
|
|
2046
|
+
ActorType2["SERVICE"] = "service";
|
|
2047
|
+
ActorType2["API_CLIENT"] = "api_client";
|
|
2048
|
+
ActorType2["SCHEDULER"] = "scheduler";
|
|
2049
|
+
ActorType2["WEBHOOK"] = "webhook";
|
|
2050
|
+
return ActorType2;
|
|
2051
|
+
})(ActorType || {});
|
|
2052
|
+
|
|
2053
|
+
// ../../shared/src/enums/todo.enums.ts
|
|
2054
|
+
var TodoPriority = /* @__PURE__ */ ((TodoPriority2) => {
|
|
2055
|
+
TodoPriority2["LOW"] = "low";
|
|
2056
|
+
TodoPriority2["NORMAL"] = "normal";
|
|
2057
|
+
TodoPriority2["HIGH"] = "high";
|
|
2058
|
+
return TodoPriority2;
|
|
2059
|
+
})(TodoPriority || {});
|
|
2060
|
+
export {
|
|
2061
|
+
ActorType,
|
|
2062
|
+
EmailAPI,
|
|
2063
|
+
EventCategory,
|
|
2064
|
+
EventLogApi,
|
|
2065
|
+
EventOutcome,
|
|
2066
|
+
EventRiskLevel,
|
|
2067
|
+
EventSeverity,
|
|
2068
|
+
FilesAPI,
|
|
2069
|
+
HealthAPI,
|
|
2070
|
+
LineAPI,
|
|
2071
|
+
OrganizationAPI,
|
|
2072
|
+
OrganizationType,
|
|
2073
|
+
OtpAPI,
|
|
2074
|
+
PermissionAPI,
|
|
2075
|
+
PermissionCategoryAPI,
|
|
2076
|
+
PortalApiClient,
|
|
2077
|
+
RoleAPI,
|
|
2078
|
+
SystemConfigAPI,
|
|
2079
|
+
TodoAPI,
|
|
2080
|
+
TodoPriority,
|
|
2081
|
+
UserAPI,
|
|
2082
|
+
WebhookAPI,
|
|
2083
|
+
WorkflowAPI
|
|
2084
|
+
};
|
|
2085
|
+
//# sourceMappingURL=index.mjs.map
|