@readerseye2/cr_type 1.0.135 → 1.0.137
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/dist/book/child-reading-progress.type.d.ts +96 -40
- package/dist/book/child-reading-progress.type.js +1 -1
- package/dist/socket/reading-section.types.d.ts +1 -1
- package/dist/socket/socket-serverToClientEvents.type.d.ts +12 -12
- package/dist/socket/unified-session.types.d.ts +19 -22
- package/dist/socket/unified-session.types.js +1 -1
- package/dist/socket/viewer-events.types.d.ts +5 -0
- package/package.json +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { EyeTrackerType } from '../gaze/eye-tracker.types';
|
|
1
2
|
/** 읽은 구간 (globalIndex 범위, inclusive) */
|
|
2
3
|
export interface ReadRange {
|
|
3
4
|
from: number;
|
|
@@ -8,6 +9,8 @@ export type CalibrationType = "quick" | "full";
|
|
|
8
9
|
/** 섹션 읽기 중 발생한 캘리브레이션 기간 */
|
|
9
10
|
export interface CalibrationPeriod {
|
|
10
11
|
type: CalibrationType;
|
|
12
|
+
/** 사용한 시선추적 트래커 */
|
|
13
|
+
trackerType: EyeTrackerType;
|
|
11
14
|
/** 사용한 포인트 수 (quick: 3, full: 5) */
|
|
12
15
|
points: number;
|
|
13
16
|
startedAt: string;
|
|
@@ -15,6 +18,14 @@ export interface CalibrationPeriod {
|
|
|
15
18
|
durationMs: number;
|
|
16
19
|
/** 캘리브레이션 결과 품질 (0~1, 기기 제공) */
|
|
17
20
|
quality?: number;
|
|
21
|
+
/** 화면 가로 해상도 (px) */
|
|
22
|
+
screenWidth?: number;
|
|
23
|
+
/** 화면 세로 해상도 (px) */
|
|
24
|
+
screenHeight?: number;
|
|
25
|
+
/** 평균 오차 (px) */
|
|
26
|
+
accuracyPx?: number;
|
|
27
|
+
/** 평균 오차 (degree) */
|
|
28
|
+
accuracyDeg?: number;
|
|
18
29
|
}
|
|
19
30
|
/** 퀴즈 시도 결과 (개별 퀴즈, 서버 저장용) */
|
|
20
31
|
export interface QuizAttemptResult {
|
|
@@ -78,9 +89,9 @@ export interface ReadingProgressReport {
|
|
|
78
89
|
/** 섹션 전체 GI 수 (ViewerSnapshot.totalItems) */
|
|
79
90
|
sectionGIMax: number;
|
|
80
91
|
/** 이 구간에서 뷰포트에 표시된 GI 범위의 최소값 */
|
|
81
|
-
|
|
92
|
+
exposedFrom: number;
|
|
82
93
|
/** 이 구간에서 뷰포트에 표시된 GI 범위의 최대값 */
|
|
83
|
-
|
|
94
|
+
exposedTo: number;
|
|
84
95
|
/**
|
|
85
96
|
* GI별 시선 dwell time (ms)
|
|
86
97
|
* - 키: globalIndex (string), 값: 해당 5초 윈도우 내 누적 dwell ms
|
|
@@ -120,24 +131,24 @@ export interface ChildSectionProgress {
|
|
|
120
131
|
sectionGIMax: number;
|
|
121
132
|
/** 섹션 단어 수 (SectionSummary.word_count, WPM 계산용) */
|
|
122
133
|
sectionWordCount: number;
|
|
123
|
-
|
|
134
|
+
exposedRanges: ReadRange[];
|
|
124
135
|
/** unique GI 수 (mergeReadRanges 후) */
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
/** 모든 flush의 (
|
|
132
|
-
|
|
136
|
+
exposedCount: number;
|
|
137
|
+
/** exposedCount / sectionGIMax */
|
|
138
|
+
exposedCoverage: number;
|
|
139
|
+
eyeReadRanges: ReadRange[];
|
|
140
|
+
eyeReadCount: number;
|
|
141
|
+
eyeReadCoverage: number;
|
|
142
|
+
/** 모든 flush의 (exposedTo - exposedFrom + 1) 합산 */
|
|
143
|
+
totalRawExposedGIs: number;
|
|
133
144
|
/** 모든 flush의 gaze dwell ≥ threshold GI 수 합산 */
|
|
134
|
-
|
|
145
|
+
totalRawEyeReadGIs: number;
|
|
135
146
|
totalReadMs: number;
|
|
136
147
|
lastGlobalIndex: number;
|
|
137
148
|
lastReadAt: string;
|
|
138
|
-
/** 검증된 읽기속도:
|
|
149
|
+
/** 검증된 읽기속도: eyeReadCount / (totalReadMs / 60000) — WPM 근사 (GI ≈ word) */
|
|
139
150
|
readingSpeedWPM: number | null;
|
|
140
|
-
/** 미검증 읽기속도:
|
|
151
|
+
/** 미검증 읽기속도: exposedCount / (totalReadMs / 60000) */
|
|
141
152
|
unverifiedReadingSpeedWPM: number | null;
|
|
142
153
|
/** 누적: 시선이 텍스트 위에 있었던 시간 (ms) */
|
|
143
154
|
totalGazeOnTextMs: number;
|
|
@@ -172,10 +183,10 @@ export interface ChildBookBookmark {
|
|
|
172
183
|
lastReadSectionId: string;
|
|
173
184
|
lastGlobalIndex: number;
|
|
174
185
|
totalGIMax: number;
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
186
|
+
totalExposedCount: number;
|
|
187
|
+
totalExposedCoverage: number;
|
|
188
|
+
totalEyeReadCount: number;
|
|
189
|
+
totalEyeReadCoverage: number;
|
|
179
190
|
totalReadingScore: number;
|
|
180
191
|
/** 책 전체 평균 WPM (검증된 속도) */
|
|
181
192
|
avgReadingSpeedWPM: number | null;
|
|
@@ -190,8 +201,8 @@ export interface ChildReadingLog {
|
|
|
190
201
|
childIdx: number;
|
|
191
202
|
bookIdx: number;
|
|
192
203
|
sectionId: string;
|
|
193
|
-
|
|
194
|
-
|
|
204
|
+
exposedFrom: number;
|
|
205
|
+
exposedTo: number;
|
|
195
206
|
/** 전체 dwell map 그대로 보존 */
|
|
196
207
|
gazeDwellMap: Record<string, number>;
|
|
197
208
|
blinkCount: number;
|
|
@@ -209,17 +220,27 @@ export interface ChildReadingLog {
|
|
|
209
220
|
}
|
|
210
221
|
export interface ChildCalibrationLog {
|
|
211
222
|
childIdx: number;
|
|
212
|
-
/** 읽기 세션 중 발생 시 세션 ID */
|
|
213
|
-
|
|
223
|
+
/** 읽기 세션 중 발생 시 읽기 세션 ID */
|
|
224
|
+
readingSessionId?: string;
|
|
214
225
|
/** 읽기 중이었던 섹션 */
|
|
215
226
|
sectionId?: string;
|
|
216
227
|
type: CalibrationType;
|
|
228
|
+
/** 사용한 시선추적 트래커 */
|
|
229
|
+
trackerType: EyeTrackerType;
|
|
217
230
|
/** 사용한 포인트 수 */
|
|
218
231
|
points: number;
|
|
219
232
|
startedAt: string;
|
|
220
233
|
endedAt: string;
|
|
221
234
|
durationMs: number;
|
|
222
235
|
quality?: number;
|
|
236
|
+
/** 화면 가로 해상도 (px) */
|
|
237
|
+
screenWidth?: number;
|
|
238
|
+
/** 화면 세로 해상도 (px) */
|
|
239
|
+
screenHeight?: number;
|
|
240
|
+
/** 평균 오차 (px) */
|
|
241
|
+
accuracyPx?: number;
|
|
242
|
+
/** 평균 오차 (degree) */
|
|
243
|
+
accuracyDeg?: number;
|
|
223
244
|
createdAt: string;
|
|
224
245
|
}
|
|
225
246
|
export interface SegmentReadingSummary {
|
|
@@ -230,17 +251,17 @@ export interface SegmentReadingSummary {
|
|
|
230
251
|
startedAt: string;
|
|
231
252
|
endedAt: string;
|
|
232
253
|
durationMs: number;
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
/**
|
|
254
|
+
exposedFrom: number;
|
|
255
|
+
exposedTo: number;
|
|
256
|
+
exposedGICount: number;
|
|
257
|
+
eyeReadGICount: number;
|
|
258
|
+
rawExposedGICount: number;
|
|
259
|
+
rawEyeReadGICount: number;
|
|
260
|
+
/** eyeReadGICount / (durationMs / 60000) — WPM 근사 */
|
|
240
261
|
readingSpeedWPM: number | null;
|
|
241
|
-
/**
|
|
262
|
+
/** exposedGICount / (durationMs / 60000) */
|
|
242
263
|
unverifiedReadingSpeedWPM: number;
|
|
243
|
-
/**
|
|
264
|
+
/** eyeReadGICount / exposedGICount (시선 없으면 null) */
|
|
244
265
|
focusRatio: number | null;
|
|
245
266
|
/** 평균 dwell time (ms per GI) */
|
|
246
267
|
avgDwellMs: number | null;
|
|
@@ -259,13 +280,13 @@ export interface SegmentReadingSummary {
|
|
|
259
280
|
}
|
|
260
281
|
export interface ChildReadingSessionSummary {
|
|
261
282
|
childIdx: number;
|
|
262
|
-
|
|
283
|
+
readingSessionId: string;
|
|
263
284
|
startedAt: string;
|
|
264
285
|
endedAt: string;
|
|
265
286
|
totalDurationMs: number;
|
|
266
287
|
segments: SegmentReadingSummary[];
|
|
267
|
-
|
|
268
|
-
|
|
288
|
+
totalExposedGICount: number;
|
|
289
|
+
totalEyeReadGICount: number;
|
|
269
290
|
overallFocusRatio: number | null;
|
|
270
291
|
avgReadingSpeedWPM: number | null;
|
|
271
292
|
avgUnverifiedReadingSpeedWPM: number;
|
|
@@ -287,9 +308,9 @@ export interface ChildReadingSessionSummary {
|
|
|
287
308
|
*/
|
|
288
309
|
export interface ReadingScoreInput {
|
|
289
310
|
/** 진도 (중첩비허용 coverage, 0~1) */
|
|
290
|
-
|
|
291
|
-
/** 검증된 진도 (
|
|
292
|
-
|
|
311
|
+
exposedCoverage: number;
|
|
312
|
+
/** 검증된 진도 (eyeRead coverage, 0~1) */
|
|
313
|
+
eyeReadCoverage: number;
|
|
293
314
|
/** 집중도 (%, 0~100) */
|
|
294
315
|
concentrationPercent: number | null;
|
|
295
316
|
/** 시선일치도 (0~1) */
|
|
@@ -312,9 +333,9 @@ export interface ReadingAccumulatedState {
|
|
|
312
333
|
sectionId: string;
|
|
313
334
|
sectionGIMax: number;
|
|
314
335
|
sectionWordCount: number;
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
336
|
+
exposedRanges: ReadRange[];
|
|
337
|
+
exposedCoverage: number;
|
|
338
|
+
totalRawExposedGIs: number;
|
|
318
339
|
totalReadMs: number;
|
|
319
340
|
lastGlobalIndex: number;
|
|
320
341
|
totalGazeOnTextMs: number;
|
|
@@ -329,6 +350,41 @@ export interface ReadingAccumulatedState {
|
|
|
329
350
|
quizMaxScore: number;
|
|
330
351
|
estimatedReadingScore: number;
|
|
331
352
|
}
|
|
353
|
+
export interface ChildDailySummary {
|
|
354
|
+
childIdx: number;
|
|
355
|
+
/** KST 기준 날짜 "YYYY-MM-DD" */
|
|
356
|
+
date: string;
|
|
357
|
+
totalReadMs: number;
|
|
358
|
+
sessionCount: number;
|
|
359
|
+
/** 오늘 읽은 bookIdx 목록 (unique) */
|
|
360
|
+
booksRead: number[];
|
|
361
|
+
/** 오늘 노출 GI 합 (세션별 누적) */
|
|
362
|
+
totalExposedGICount: number;
|
|
363
|
+
/** 오늘 시선 확인 GI 합 (세션별 누적) */
|
|
364
|
+
totalEyeReadGICount: number;
|
|
365
|
+
avgConcentrationPercent: number | null;
|
|
366
|
+
avgFocusRatio: number | null;
|
|
367
|
+
avgReadingSpeedWPM: number | null;
|
|
368
|
+
totalQuizScore: number;
|
|
369
|
+
totalQuizMaxScore: number;
|
|
370
|
+
totalBlinks: number;
|
|
371
|
+
totalLookedUpWords: number;
|
|
372
|
+
/** 집중도 가중합 (concentrationPercent × durationMs 누적) */
|
|
373
|
+
_weightedConcentrationMs: number;
|
|
374
|
+
/** 집중도 분모 (concentration 데이터가 있는 세션의 durationMs 누적) */
|
|
375
|
+
_concentrationDurationMs: number;
|
|
376
|
+
/** 속도 가중합 (speedWPM × durationMs 누적) */
|
|
377
|
+
_weightedSpeedMs: number;
|
|
378
|
+
/** 속도 분모 (speed 데이터가 있는 세션의 durationMs 누적) */
|
|
379
|
+
_speedDurationMs: number;
|
|
380
|
+
/** focusRatio 가중합 */
|
|
381
|
+
_weightedFocusRatioMs: number;
|
|
382
|
+
/** focusRatio 분모 */
|
|
383
|
+
_focusRatioDurationMs: number;
|
|
384
|
+
lastReadingSessionId: string;
|
|
385
|
+
createdAt: string;
|
|
386
|
+
updatedAt: string;
|
|
387
|
+
}
|
|
332
388
|
/** GET /api/reading-progress/:bookIdx */
|
|
333
389
|
export interface ChildBookProgressResponse {
|
|
334
390
|
bookmark: ChildBookBookmark | null;
|
|
@@ -8,5 +8,5 @@
|
|
|
8
8
|
// 시선일치도(gazeAlignment, 오디오재생+시선추적시)
|
|
9
9
|
// 집중도(concentration, gazeOnText/total %)
|
|
10
10
|
// 찾아본단어(lookedUpWords) 퀴즈점수/정답률
|
|
11
|
-
// 미검증 읽은양/속도(
|
|
11
|
+
// 미검증 읽은양/속도(exposedOnly) 종합 읽기점수(readingScore, 누적)
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -21,34 +21,34 @@ export interface ServerToClientEvents {
|
|
|
21
21
|
}) => void;
|
|
22
22
|
/** 세션 종료됨 (서버 확인) */
|
|
23
23
|
'session:ended': (payload: {
|
|
24
|
-
|
|
24
|
+
readingSessionId: string;
|
|
25
25
|
durationMs?: number;
|
|
26
26
|
}) => void;
|
|
27
27
|
/** 구독 성공 (Parent가 자녀 세션 구독 시) */
|
|
28
28
|
'session:subscribed': (payload: {
|
|
29
|
-
|
|
29
|
+
readingSessionId: string;
|
|
30
30
|
snapshot: ViewerSnapshot | null;
|
|
31
31
|
}) => void;
|
|
32
32
|
/** 구독 중인 세션의 진행 상황 */
|
|
33
33
|
'session:progress': (payload: {
|
|
34
|
-
|
|
34
|
+
readingSessionId: string;
|
|
35
35
|
snapshot: ViewerSnapshot;
|
|
36
36
|
}) => void;
|
|
37
37
|
/** 구독 중인 세션의 이벤트 */
|
|
38
38
|
'session:events': (payload: {
|
|
39
|
-
|
|
39
|
+
readingSessionId: string;
|
|
40
40
|
events: ViewerEvent[];
|
|
41
41
|
}) => void;
|
|
42
42
|
/** 구독 중인 세션의 실시간 시선 데이터 (~1초 간격) */
|
|
43
43
|
'session:gaze': (payload: {
|
|
44
|
-
|
|
44
|
+
readingSessionId: string;
|
|
45
45
|
gazeData: GazeDataPayload;
|
|
46
46
|
}) => void;
|
|
47
47
|
/** 구독 중인 세션의 세그먼트 변경 (섹션 변경) */
|
|
48
48
|
'session:segment-changed': (payload: SessionSegmentChangedPayload) => void;
|
|
49
49
|
/** 구독 중인 세션의 청크 (10초 간격) */
|
|
50
50
|
'session:chunk': (payload: {
|
|
51
|
-
|
|
51
|
+
readingSessionId: string;
|
|
52
52
|
segmentIndex: number;
|
|
53
53
|
chunk: UnifiedChunkFile;
|
|
54
54
|
}) => void;
|
|
@@ -72,34 +72,34 @@ export interface SessionServerToClientEvents {
|
|
|
72
72
|
}) => void;
|
|
73
73
|
/** 세션 종료됨 */
|
|
74
74
|
'session:ended': (payload: {
|
|
75
|
-
|
|
75
|
+
readingSessionId: string;
|
|
76
76
|
durationMs?: number;
|
|
77
77
|
}) => void;
|
|
78
78
|
/** 구독 성공 */
|
|
79
79
|
'session:subscribed': (payload: {
|
|
80
|
-
|
|
80
|
+
readingSessionId: string;
|
|
81
81
|
snapshot: ViewerSnapshot | null;
|
|
82
82
|
}) => void;
|
|
83
83
|
/** 구독 중인 세션 진행 상황 */
|
|
84
84
|
'session:progress': (payload: {
|
|
85
|
-
|
|
85
|
+
readingSessionId: string;
|
|
86
86
|
snapshot: ViewerSnapshot;
|
|
87
87
|
}) => void;
|
|
88
88
|
/** 구독 중인 세션 이벤트 */
|
|
89
89
|
'session:events': (payload: {
|
|
90
|
-
|
|
90
|
+
readingSessionId: string;
|
|
91
91
|
events: ViewerEvent[];
|
|
92
92
|
}) => void;
|
|
93
93
|
/** 구독 중인 세션 실시간 시선 데이터 (~1초 간격) */
|
|
94
94
|
'session:gaze': (payload: {
|
|
95
|
-
|
|
95
|
+
readingSessionId: string;
|
|
96
96
|
gazeData: GazeDataPayload;
|
|
97
97
|
}) => void;
|
|
98
98
|
/** 세그먼트 변경 (섹션 변경) */
|
|
99
99
|
'session:segment-changed': (payload: SessionSegmentChangedPayload) => void;
|
|
100
100
|
/** 실시간 청크 (10초 간격, 구독자에게) */
|
|
101
101
|
'session:chunk': (payload: {
|
|
102
|
-
|
|
102
|
+
readingSessionId: string;
|
|
103
103
|
segmentIndex: number;
|
|
104
104
|
chunk: UnifiedChunkFile;
|
|
105
105
|
}) => void;
|
|
@@ -96,15 +96,14 @@ export interface UnifiedSegmentSummary {
|
|
|
96
96
|
* - 기존 ReadingSessionRecord + RecordingManifest 대체
|
|
97
97
|
*/
|
|
98
98
|
export interface UnifiedSessionManifest {
|
|
99
|
-
/** 세션 ID (UUID) */
|
|
100
|
-
|
|
99
|
+
/** 읽기 세션 ID (UUID) */
|
|
100
|
+
readingSessionId: string;
|
|
101
101
|
/** 상태 */
|
|
102
102
|
status: UnifiedSessionStatus;
|
|
103
103
|
/** 스키마 버전 (구 포맷과 구분용, 항상 2) */
|
|
104
104
|
version: 2;
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
userName: string;
|
|
105
|
+
childIdx: number;
|
|
106
|
+
childName: string;
|
|
108
107
|
familyId: number;
|
|
109
108
|
/** 세션 시작 시간 (뷰어 열림, ms) */
|
|
110
109
|
startedAt: number;
|
|
@@ -162,10 +161,9 @@ export interface GazeDataPayload {
|
|
|
162
161
|
* - 현재 세그먼트 정보 포함
|
|
163
162
|
*/
|
|
164
163
|
export interface UnifiedSessionInfo {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
userName?: string;
|
|
164
|
+
readingSessionId: string;
|
|
165
|
+
childIdx: number;
|
|
166
|
+
childName?: string;
|
|
169
167
|
familyId: number;
|
|
170
168
|
startedAt: string;
|
|
171
169
|
snapshot: ViewerSnapshot;
|
|
@@ -184,7 +182,7 @@ export interface UnifiedSessionInfo {
|
|
|
184
182
|
}
|
|
185
183
|
/** 세그먼트 변경 알림 (섹션 변경 시) */
|
|
186
184
|
export interface SessionSegmentChangedPayload {
|
|
187
|
-
|
|
185
|
+
readingSessionId: string;
|
|
188
186
|
/** 종료된 세그먼트 인덱스 */
|
|
189
187
|
oldSegmentIndex: number;
|
|
190
188
|
/** 새로 시작된 세그먼트 */
|
|
@@ -200,24 +198,24 @@ export interface SessionSegmentChangedPayload {
|
|
|
200
198
|
/** 세션 이력 목록 조회 요청 */
|
|
201
199
|
export interface SessionHistoryListPayload {
|
|
202
200
|
familyId?: number;
|
|
203
|
-
|
|
201
|
+
childIdx?: number;
|
|
204
202
|
date?: string;
|
|
205
203
|
limit?: number;
|
|
206
204
|
offset?: number;
|
|
207
205
|
}
|
|
208
206
|
/** 세션 이력 상세 조회 요청 */
|
|
209
207
|
export interface SessionHistoryGetPayload {
|
|
210
|
-
|
|
208
|
+
readingSessionId: string;
|
|
211
209
|
s3Key?: string;
|
|
212
210
|
}
|
|
213
211
|
/** 세션 이력 삭제 요청 */
|
|
214
212
|
export interface SessionHistoryDeletePayload {
|
|
215
|
-
|
|
213
|
+
readingSessionId: string;
|
|
216
214
|
s3Key?: string;
|
|
217
215
|
}
|
|
218
216
|
/** 통합 청크 조회 요청 (seek/재생용) */
|
|
219
217
|
export interface UnifiedChunksGetPayload {
|
|
220
|
-
|
|
218
|
+
readingSessionId: string;
|
|
221
219
|
segmentIndex: number;
|
|
222
220
|
/** 시작 timestamp (이 시점부터 청크 조회) */
|
|
223
221
|
fromTimestamp?: number;
|
|
@@ -226,7 +224,7 @@ export interface UnifiedChunksGetPayload {
|
|
|
226
224
|
}
|
|
227
225
|
/** 통합 세그먼트 상세 조회 요청 */
|
|
228
226
|
export interface UnifiedSegmentGetPayload {
|
|
229
|
-
|
|
227
|
+
readingSessionId: string;
|
|
230
228
|
segmentIndex: number;
|
|
231
229
|
}
|
|
232
230
|
/** 세션 이력 목록 결과 */
|
|
@@ -245,7 +243,7 @@ export interface SessionHistoryGetResult {
|
|
|
245
243
|
}
|
|
246
244
|
/** 청크 조회 결과 */
|
|
247
245
|
export interface UnifiedChunksResult {
|
|
248
|
-
|
|
246
|
+
readingSessionId: string;
|
|
249
247
|
segmentIndex: number;
|
|
250
248
|
chunks: UnifiedChunkFile[];
|
|
251
249
|
/** Seek 시 가장 가까운 스냅샷 (초기 상태 복원용) */
|
|
@@ -253,12 +251,12 @@ export interface UnifiedChunksResult {
|
|
|
253
251
|
}
|
|
254
252
|
/** 세그먼트 상세 결과 */
|
|
255
253
|
export interface UnifiedSegmentResult {
|
|
256
|
-
|
|
254
|
+
readingSessionId: string;
|
|
257
255
|
segment: UnifiedSegmentMeta;
|
|
258
256
|
}
|
|
259
257
|
/** 세션 삭제 결과 */
|
|
260
258
|
export interface SessionHistoryDeleteResult {
|
|
261
|
-
|
|
259
|
+
readingSessionId: string;
|
|
262
260
|
success: boolean;
|
|
263
261
|
}
|
|
264
262
|
/**
|
|
@@ -266,11 +264,10 @@ export interface SessionHistoryDeleteResult {
|
|
|
266
264
|
* - 기존 ActiveRecording + SessionChunkState 대체
|
|
267
265
|
*/
|
|
268
266
|
export interface ActiveUnifiedSession {
|
|
269
|
-
|
|
267
|
+
readingSessionId: string;
|
|
270
268
|
s3Prefix: string;
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
userName: string;
|
|
269
|
+
childIdx: number;
|
|
270
|
+
childName: string;
|
|
274
271
|
familyId: number;
|
|
275
272
|
viewerSocketId: string;
|
|
276
273
|
startedAt: number;
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// - Parent + Admin 동일한 subscribe 체계
|
|
12
12
|
//
|
|
13
13
|
// S3 경로:
|
|
14
|
-
// reading-sessions/{familyId}/{
|
|
14
|
+
// reading-sessions/{familyId}/{childIdx}/{YYYY-MM-DD}/{readingSessionId}/
|
|
15
15
|
// ├── manifest.json (UnifiedSessionManifest)
|
|
16
16
|
// └── segments/
|
|
17
17
|
// ├── 0/
|
|
@@ -130,9 +130,14 @@ export type CalibrationStartEvent = ViewerEventBase<'calibration_start', {
|
|
|
130
130
|
}>;
|
|
131
131
|
export type CalibrationEndEvent = ViewerEventBase<'calibration_end', {
|
|
132
132
|
type: 'quick' | 'full';
|
|
133
|
+
trackerType: import('../gaze/eye-tracker.types').EyeTrackerType;
|
|
133
134
|
points: number;
|
|
134
135
|
durationMs: number;
|
|
135
136
|
quality?: number;
|
|
137
|
+
screenWidth?: number;
|
|
138
|
+
screenHeight?: number;
|
|
139
|
+
accuracyPx?: number;
|
|
140
|
+
accuracyDeg?: number;
|
|
136
141
|
}>;
|
|
137
142
|
export type ShowGazeChangeEvent = ViewerEventBase<'show_gaze_change', {
|
|
138
143
|
showGaze: boolean;
|