@vibexnpm/talkx 8.11.0 → 8.13.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibexnpm/talkx",
3
- "version": "8.11.0",
3
+ "version": "8.13.0",
4
4
  "type": "module",
5
5
  "description": "TalkFlow SDK - Chat & WebRTC unified client",
6
6
  "main": "dist/talkflow-sdk.umd.js",
@@ -1439,14 +1439,53 @@ class ChatClient extends EventEmitter {
1439
1439
  *
1440
1440
  * @param {Object} [params]
1441
1441
  * @param {string} [params.roomId] - 방 하나로 거르기. 생략하면 참여 중인 방 전부. 참여하지 않은 방이면 403
1442
+ * @param {'IMAGE'|'VIDEO'|'AUDIO'|'DOCUMENT'|'FILE'} [params.type] - 종류로 거르기 — 응답 category 와 같은 값
1443
+ * ({@code FILE} = 기타). 생략하면 전부, 그 밖의 값이면 400. 방·종류를 바꾸면 커서 없이 처음부터 부른다
1442
1444
  * @param {number} [params.size=50] - 페이지 크기 (1-100, 파일 수)
1443
1445
  * @param {string} [params.lastId] - 직전 응답의 lastId 를 그대로 — 불투명 값이라 만들어 쓰지 않는다
1444
1446
  * @param {number} [params.lastSortValue] - 직전 응답의 lastSortValue 를 그대로
1445
1447
  * @returns {Promise<Object>}
1446
1448
  */
1447
1449
  async getFiles(params = {}) {
1448
- const { roomId, size = 50, lastId, lastSortValue } = params;
1449
- return this.apiClient.get('/api/v1/files', { roomId, size, lastId, lastSortValue });
1450
+ const { roomId, type, size = 50, lastId, lastSortValue } = params;
1451
+ return this.apiClient.get('/api/v1/files', { roomId, type, size, lastId, lastSortValue });
1452
+ }
1453
+
1454
+ /**
1455
+ * PM 보고서 목록 — 내가 지금 참여 중인 방들에 PM 이 올린 작업 결과(지금은 자료조사)를 최신순 커서 페이지로.
1456
+ *
1457
+ * <p>한 줄이 결과 하나다 — 제목(위임 요지)·미리보기(결과 앞 200자)·방·시킨 사람·PM·올라온 시각. 본문은
1458
+ * {@link ChatClient#getPmReport} 로 연다. 보이는 범위는 파일함과 같다 — 참여 중인 방만, 재입장 이전·보관 기간 밖·
1459
+ * 나만 삭제한 결과는 오지 않는다. 실패 안내·단순 답변은 보고서가 아니다.</p>
1460
+ *
1461
+ * <p>{@link ChatClient#getFiles} 처럼 서버 응답 래퍼째 돌려준다 — 페이지는 {@code result.data}. 끝은 {@code hasNext}
1462
+ * 로만 판단한다 — 드물게 짧거나 빈 페이지가 {@code hasNext: true} 와 함께 온다(게시 뒤 결과가 지워진 줄은 빠진다).</p>
1463
+ *
1464
+ * @param {Object} [params]
1465
+ * @param {'RESEARCH'} [params.kind] - 보고서 종류 — 지금은 {@code RESEARCH}(자료조사) 하나, 생략하면 자료조사.
1466
+ * 그 밖의 값이면 400. 종류·방을 바꾸면 커서 없이 처음부터 부른다
1467
+ * @param {string} [params.roomId] - 방 하나로 거르기. 생략하면 참여 중인 방 전부. 참여하지 않은 방이면 403
1468
+ * @param {number} [params.size=50] - 페이지 크기 (1-100)
1469
+ * @param {string} [params.lastId] - 직전 응답의 lastId 를 그대로
1470
+ * @param {number} [params.lastSortValue] - 직전 응답의 lastSortValue 를 그대로
1471
+ * @returns {Promise<Object>}
1472
+ */
1473
+ async getPmReports(params = {}) {
1474
+ const { kind, roomId, size = 50, lastId, lastSortValue } = params;
1475
+ return this.apiClient.get('/api/v1/pm-reports', { kind, roomId, size, lastId, lastSortValue });
1476
+ }
1477
+
1478
+ /**
1479
+ * PM 보고서 상세 — 목록 한 줄과 같은 칸 + 본문({@code content}, 마크다운 · 출처 절 포함).
1480
+ *
1481
+ * <p>채팅에서 결과에 붙었던 안내도 같은 문구로 붙는다 — 대화 변경 고지(본문 위)·이미지 분석 범위 안내(본문 끝).
1482
+ * 없거나 볼 수 없으면(나만 삭제·방에서 나감 등) 404 하나로 답한다. 반환은 래퍼째({@code result.data}).</p>
1483
+ *
1484
+ * @param {string} reportId - 목록 한 줄의 {@code id}
1485
+ * @returns {Promise<Object>}
1486
+ */
1487
+ async getPmReport(reportId) {
1488
+ return this.apiClient.get(`/api/v1/pm-reports/${encodeURIComponent(reportId)}`);
1450
1489
  }
1451
1490
 
1452
1491
  /**
@@ -22,6 +22,9 @@ const CHAT_DELEGATE_METHODS = [
22
22
  'getMessages',
23
23
  // 파일함 — 참여 중인 방들의 파일 목록(방 하나로 거르기 가능).
24
24
  'getFiles',
25
+ // PM 보고서 — 참여 중인 방들에 PM 이 올린 작업 결과(지금은 자료조사) 목록·상세.
26
+ 'getPmReports',
27
+ 'getPmReport',
25
28
  'fetchLinkPreview',
26
29
  'sendMessage',
27
30
  'sendMessageOptimistic',
@@ -2,20 +2,20 @@
2
2
  * 파일함 타입 — docs/chat.md «파일함» 예제가 <b>실제로 컴파일되는지</b>.
3
3
  *
4
4
  * <p>jest 는 `.d.ts` 를 보지 않는다. 문서가 약속한 모양(반환은 envelope 째 · 한 줄 = 파일 하나 · 커서 두 칸은 직전 응답
5
- * 그대로 · 이름·방 이름은 비어 있을 수 있음 · 종류는 다섯 값)이 선언과 맞는지 여기서 tsc 로 고정한다.</p>
5
+ * 그대로 · 이름·방 이름은 비어 있을 수 있음 · 종류는 다섯 값이고 거를 때도 같은 값)이 선언과 맞는지 여기서 tsc 로 고정한다.</p>
6
6
  *
7
7
  * <p>실행: {@code npm run typecheck}</p>
8
8
  */
9
9
  import TalkFlowClient from '../index';
10
- import type { ChatFile, ChatFileListParams } from '../index';
10
+ import type { ChatFile, ChatFileCategory, ChatFileListParams } from '../index';
11
11
 
12
12
  declare const talkflow: TalkFlowClient;
13
13
  declare const roomId: string;
14
14
 
15
- // 1) 처음부터 끝까지 — 다음 페이지는 응답의 커서 두 칸을 그대로 넘긴다.
16
- async function loadAll(filterRoomId?: string): Promise<ChatFile[]> {
15
+ // 1) 처음부터 끝까지 — 다음 페이지는 응답의 커서 두 칸을 그대로 넘긴다. 종류 탭이면 type 을 함께 싣는다.
16
+ async function loadAll(filterRoomId?: string, tab?: ChatFileCategory): Promise<ChatFile[]> {
17
17
  const rows: ChatFile[] = [];
18
- let params: ChatFileListParams = { roomId: filterRoomId, size: 50 };
18
+ let params: ChatFileListParams = { roomId: filterRoomId, type: tab, size: 50 };
19
19
  for (;;) {
20
20
  const result = await talkflow.getFiles(params);
21
21
  rows.push(...result.data.content);
@@ -43,11 +43,12 @@ function describe(row: ChatFile): string {
43
43
  return `${who} · ${room} · ${row.file.fileName ?? link}`;
44
44
  }
45
45
 
46
- // 3) 방 목록 필터는 파일함에 없다 — 방 하나는 roomId 로 고른다.
47
- async function wrongFilter(): Promise<void> {
48
- // @ts-expect-error — type 은 방 목록(getRooms) 파라미터다.
46
+ // 3) 종류는 파일 종류 다섯 값뿐 — 방 종류(GROUP 등)는 파일함 type 이 아니다. 응답 category 를 그대로 다시 넣을 수 있다.
47
+ async function wrongFilter(row: ChatFile): Promise<void> {
48
+ // @ts-expect-error — GROUP 은 방 종류다(방 목록 getRooms 의 type).
49
49
  await talkflow.getFiles({ type: 'GROUP' });
50
- await talkflow.getFiles({ roomId });
50
+ await talkflow.getFiles({ roomId, type: 'FILE' });
51
+ await talkflow.getFiles({ type: row.category });
51
52
  }
52
53
 
53
54
  void [loadAll, describe, wrongFilter];
@@ -0,0 +1,55 @@
1
+ /**
2
+ * PM 보고서 타입 — docs/chat.md «PM 보고서» 예제가 <b>실제로 컴파일되는지</b>.
3
+ *
4
+ * <p>jest 는 `.d.ts` 를 보지 않는다. 문서가 약속한 모양(반환은 envelope 째 · 커서 두 칸은 직전 응답 그대로 · 이름·제목은
5
+ * 비어 있을 수 있음 · 종류는 지금 RESEARCH 하나 · 상세는 목록 한 줄 + 본문)이 선언과 맞는지 여기서 tsc 로 고정한다.</p>
6
+ *
7
+ * <p>실행: {@code npm run typecheck}</p>
8
+ */
9
+ import TalkFlowClient from '../index';
10
+ import type { PmReport, PmReportDetail, PmReportListParams } from '../index';
11
+
12
+ declare const talkflow: TalkFlowClient;
13
+ declare const roomId: string;
14
+
15
+ // 1) 처음부터 끝까지 — 다음 페이지는 응답의 커서 두 칸을 그대로 넘긴다.
16
+ async function loadAll(filterRoomId?: string): Promise<PmReport[]> {
17
+ const rows: PmReport[] = [];
18
+ let params: PmReportListParams = { roomId: filterRoomId, size: 50 };
19
+ for (;;) {
20
+ const result = await talkflow.getPmReports(params);
21
+ rows.push(...result.data.content);
22
+ if (!result.data.hasNext) {
23
+ return rows;
24
+ }
25
+ params = {
26
+ ...params,
27
+ lastId: result.data.lastId ?? undefined,
28
+ lastSortValue: result.data.lastSortValue ?? undefined,
29
+ };
30
+ }
31
+ }
32
+
33
+ // 2) 한 줄 그리기 → 열기 — 상세는 같은 칸 + 본문.
34
+ async function open(row: PmReport): Promise<string> {
35
+ const title: string = row.title ?? row.preview;
36
+ const who: string = row.requesterName ?? '알 수 없음';
37
+ const pm: string = row.pmName ?? 'PM';
38
+ const room: string = row.roomName ?? '';
39
+ const publishedAt: number = row.publishedAt;
40
+ const changed: boolean = row.contextChanged;
41
+ void [who, pm, room, publishedAt, changed];
42
+ const detail: PmReportDetail = (await talkflow.getPmReport(row.id)).data;
43
+ const length: number = detail.contentLength;
44
+ void length;
45
+ return `${title}\n\n${detail.content}`;
46
+ }
47
+
48
+ // 3) 종류는 지금 RESEARCH 하나 — 다른 이름은 컴파일에서 막힌다.
49
+ async function wrongKind(): Promise<void> {
50
+ // @ts-expect-error — 기획은 아직 보고서 종류로 열지 않았다.
51
+ await talkflow.getPmReports({ kind: 'PLANNING' });
52
+ await talkflow.getPmReports({ kind: 'RESEARCH', roomId });
53
+ }
54
+
55
+ void [loadAll, open, wrongKind];
package/types/index.d.ts CHANGED
@@ -1290,10 +1290,18 @@ export interface ApiEnvelope<T> {
1290
1290
  message?: string;
1291
1291
  }
1292
1292
 
1293
+ /**
1294
+ * 파일 종류 — {@link ChatFile.category} 와 {@link ChatFileListParams.type} 이 같은 값을 쓴다.
1295
+ * {@code FILE} 은 «기타» — 이미지·동영상·음성·문서가 아닌 파일(zip 등).
1296
+ */
1297
+ export type ChatFileCategory = 'IMAGE' | 'VIDEO' | 'AUDIO' | 'DOCUMENT' | 'FILE';
1298
+
1293
1299
  /** {@link ChatClient.getFiles} 파라미터 — 파일함 한 페이지. */
1294
1300
  export interface ChatFileListParams {
1295
1301
  /** 방 하나로 거르기. 생략하면 내가 지금 참여 중인 방 전부. 참여하지 않은 방이면 403. */
1296
1302
  roomId?: string;
1303
+ /** 종류로 거르기 — 생략하면 전부. 방·종류를 바꾸면 커서({@code lastId}·{@code lastSortValue}) 없이 처음부터 부른다. */
1304
+ type?: ChatFileCategory;
1297
1305
  /** 페이지 크기(파일 수). 기본 50, max 100. */
1298
1306
  size?: number;
1299
1307
  /** 직전 응답의 {@code lastId} 그대로 — 불투명 값이라 만들어 쓰지 않는다. */
@@ -1326,11 +1334,71 @@ export interface ChatFile {
1326
1334
  /** 올린 시각(epoch millis). */
1327
1335
  uploadedAt: number;
1328
1336
  /** 종류 — 파일 MIME 기준, 채팅 첨부 분류와 같다. */
1329
- category: 'IMAGE' | 'VIDEO' | 'AUDIO' | 'DOCUMENT' | 'FILE';
1337
+ category: ChatFileCategory;
1330
1338
  /** 파일명({@code fileName})·다운로드 링크({@code fileUrl})·MIME({@code fileType})·크기·썸네일 — 채팅 메시지 첨부와 같은 모양. */
1331
1339
  file: FileMetaData;
1332
1340
  }
1333
1341
 
1342
+ /** PM 보고서 종류 — 지금은 자료조사({@code RESEARCH}) 하나. {@link PmReport.kind} 와 {@link PmReportListParams.kind} 가 같은 값. */
1343
+ export type PmReportKind = 'RESEARCH';
1344
+
1345
+ /** {@link ChatClient.getPmReports} 파라미터 — 보고서 한 페이지. */
1346
+ export interface PmReportListParams {
1347
+ /** 보고서 종류 — 생략하면 {@code RESEARCH}. 종류·방을 바꾸면 커서 없이 처음부터 부른다. */
1348
+ kind?: PmReportKind;
1349
+ /** 방 하나로 거르기. 생략하면 내가 지금 참여 중인 방 전부. 참여하지 않은 방이면 403. */
1350
+ roomId?: string;
1351
+ /** 페이지 크기. 기본 50, max 100. */
1352
+ size?: number;
1353
+ /** 직전 응답의 {@code lastId} 그대로. */
1354
+ lastId?: string;
1355
+ /** 직전 응답의 {@code lastSortValue} 그대로(epoch millis). */
1356
+ lastSortValue?: number | string;
1357
+ }
1358
+
1359
+ /**
1360
+ * PM 보고서 목록 한 줄 — 방에 PM 이 올린 작업 결과 하나.
1361
+ *
1362
+ * <p>보이는 범위는 파일함과 같다 — 참여 중인 방만, 재입장 이전·보관 기간 밖·나만 삭제한 결과는 오지 않는다.</p>
1363
+ */
1364
+ export interface PmReport {
1365
+ /** 보고서 id — 상세({@link ChatClient.getPmReport})에 넘기는 값. 목록 key 로 쓴다. */
1366
+ id: string;
1367
+ /** 결과 메시지 — {@link ChatMessage.messageId} 와 같은 값. 채팅에서 그 메시지로 이동할 때 쓴다. */
1368
+ messageId: string;
1369
+ kind: PmReportKind;
1370
+ /** 제목 — PM 이 작업을 맡긴 요지(120자). 비어 있으면 null. */
1371
+ title: string | null;
1372
+ /** 결과 앞 200자 — 마크다운 원문 그대로. */
1373
+ preview: string;
1374
+ /** 채팅에서 «작업 중 참고한 대화 일부가 수정/삭제되어…» 고지가 붙은 결과인가 — 상세 본문 위에 같은 문구가 붙는다. */
1375
+ contextChanged: boolean;
1376
+ roomId: string;
1377
+ /** 방 이름 — 1:1 은 상대 이름. 찾지 못하면 null. */
1378
+ roomName: string | null;
1379
+ roomType: ChatRoomTypeValue | null;
1380
+ /** 작업을 시킨 사람. */
1381
+ requesterId: string | null;
1382
+ /** 그 사람 닉네임 — 찾지 못하면(탈퇴 등) null. */
1383
+ requesterName: string | null;
1384
+ requesterProfileUrl: string | null;
1385
+ /** 결과를 올린 PM 페르소나 이름 — 찾지 못하면 null. */
1386
+ pmName: string | null;
1387
+ /** 결과가 방에 올라온 시각(epoch millis). */
1388
+ publishedAt: number;
1389
+ }
1390
+
1391
+ /** PM 보고서 상세 — 목록 한 줄({@link PmReport})과 같은 칸 + 본문. */
1392
+ export interface PmReportDetail extends PmReport {
1393
+ /**
1394
+ * 본문(마크다운) — 결과 전문(출처 절 포함). 채팅에서 결과에 붙었던 안내도 같은 문구로 붙는다: 대화 변경 고지(본문 위,
1395
+ * {@code contextChanged} 일 때)·이미지 분석 범위 안내(본문 끝).
1396
+ */
1397
+ content: string;
1398
+ /** 본문 글자 수(코드포인트). */
1399
+ contentLength: number;
1400
+ }
1401
+
1334
1402
  // ============================================================================
1335
1403
  // Event payloads
1336
1404
  // ============================================================================
@@ -2447,6 +2515,17 @@ export class ChatClient implements SdkEventEmitter<ChatClientEvents> {
2447
2515
  * 다음 페이지는 응답의 {@code lastId}·{@code lastSortValue} 를 그대로 넘긴다.
2448
2516
  */
2449
2517
  getFiles(params?: ChatFileListParams): Promise<ApiEnvelope<CursorPageResponse<ChatFile>>>;
2518
+
2519
+ /**
2520
+ * PM 보고서 목록 — 내가 지금 참여 중인 방들에 PM 이 올린 작업 결과(지금은 자료조사), 최신순 커서 페이징. 반환은
2521
+ * envelope 째({@code result.data.content}). 보이는 범위는 파일함과 같다. 다음 페이지는 응답의 {@code lastId}·
2522
+ * {@code lastSortValue} 를 그대로 넘긴다. 끝은 {@code hasNext} 로만 판단한다 — 드물게 짧거나 빈 페이지가
2523
+ * {@code hasNext: true} 와 함께 온다.
2524
+ */
2525
+ getPmReports(params?: PmReportListParams): Promise<ApiEnvelope<CursorPageResponse<PmReport>>>;
2526
+
2527
+ /** PM 보고서 상세 — 목록 한 줄 + 본문({@code content}). 없거나 볼 수 없으면 404. 반환은 envelope 째. */
2528
+ getPmReport(reportId: string): Promise<ApiEnvelope<PmReportDetail>>;
2450
2529
  fetchLinkPreview(url: string): Promise<FetchLinkPreviewResponse | null>;
2451
2530
  sendMessage(roomId: string, data: SendMessageData): Promise<SendMessageResult>;
2452
2531
  /** Optimistic UI 버전 — 응답 전 base/예측 messageIds 동기 반환. */
@@ -2940,6 +3019,17 @@ export default class TalkFlowClient implements SdkEventEmitter<TalkFlowClientEve
2940
3019
  * 다음 페이지는 응답의 {@code lastId}·{@code lastSortValue} 를 그대로 넘긴다.
2941
3020
  */
2942
3021
  getFiles(params?: ChatFileListParams): Promise<ApiEnvelope<CursorPageResponse<ChatFile>>>;
3022
+
3023
+ /**
3024
+ * PM 보고서 목록 — 내가 지금 참여 중인 방들에 PM 이 올린 작업 결과(지금은 자료조사), 최신순 커서 페이징. 반환은
3025
+ * envelope 째({@code result.data.content}). 보이는 범위는 파일함과 같다. 다음 페이지는 응답의 {@code lastId}·
3026
+ * {@code lastSortValue} 를 그대로 넘긴다. 끝은 {@code hasNext} 로만 판단한다 — 드물게 짧거나 빈 페이지가
3027
+ * {@code hasNext: true} 와 함께 온다.
3028
+ */
3029
+ getPmReports(params?: PmReportListParams): Promise<ApiEnvelope<CursorPageResponse<PmReport>>>;
3030
+
3031
+ /** PM 보고서 상세 — 목록 한 줄 + 본문({@code content}). 없거나 볼 수 없으면 404. 반환은 envelope 째. */
3032
+ getPmReport(reportId: string): Promise<ApiEnvelope<PmReportDetail>>;
2943
3033
  fetchLinkPreview(url: string): Promise<FetchLinkPreviewResponse | null>;
2944
3034
  sendMessage(roomId: string, data: SendMessageData): Promise<SendMessageResult>;
2945
3035
  /** Optimistic UI 버전 — 응답 전 base/예측 messageIds 동기 반환. */