웹 세션 리플레이 · AI 컨텍스트 로깅 서비스 개발 계획 계획웹 MVP
마지막 업데이트 2026-08-04
이 문서는 이렇게 읽으면 됩니다
웹 세션 리플레이 · AI 컨텍스트 로깅 서비스 개발 계획의 MVP 경계와 설계 결정을 먼저 확인한 뒤, 이벤트 계약·저장 모델·분석 파이프라인·단계별 완료 기준을 순서대로 적용합니다.
핵심 흐름 펼쳐 보기
- 목표와 비범위로 LogRocket 대체의 첫 배포 범위를 확정합니다.
- 아키텍처와 이벤트 계약으로 데이터의 수집·저장·분석 경로를 구현합니다.
- 개발 단계와 운영 정책으로 배포 후 품질·비용·개인정보 위험을 점검합니다.
외부 LogRocket을 대체해 PPI 웹 내부에서 사용자 화면 흐름과 서비스 이벤트를 함께 기록하고, 세션 종료 후 AI가 이슈를 구조적으로 분석하는 운영 플랫폼 설계안이다.
문서 범위
1. 목표와 비범위
핵심 원칙은 화면 녹화가 아니라 단일 시간축의 구조화된 증거를 남기는 것이다. 운영자는 리플레이로 상황을 확인하고, AI는 같은 이벤트로 원인 후보와 영향도를 제시한다.
이번 서비스가 제공할 것
- 브라우저 DOM 재구성, 클릭·스크롤·URL·오류의 세션 리플레이
- STT, LLM, TTS, API, WebRTC 상태를 동일 타임라인에 통합
- 아동·수업 단위 세션 조회 및 AI 이슈 요약
- HIGH 이슈의 중복 억제 Slack 알림
이번 계획에서 제외할 것
- Unity 클라이언트 이벤트, 프레임 캡처, 동영상
- 기본값으로 음성 원본을 보관하는 기능
- LogRocket의 모든 분석·협업 기능 복제
- 자유 텍스트 검색용 OpenSearch 도입
2. 권장 아키텍처
버퍼/마스킹
| 구성 요소 | 책임 | 초기 구현 선택 |
|---|---|---|
| Client Logging SDK | 세션 식별, DOM/의미 이벤트 수집, 마스킹, IndexedDB 오프라인 큐, 배치 전송 | 웹 패키지로 제공; rrweb 기반 DOM 이벤트 + PPI 고유 이벤트 |
| Ingestion API | 세션 권한 검증, 이벤트 스키마 검증, 이벤트 ID 멱등성, S3 적재 요청 | 기존 PPI Web API route 또는 전용 Lambda/API Gateway |
| 원본 저장소 | 압축 이벤트 청크·DOM 스냅샷·분석 입력/원본 결과 보관 | S3, JSON Lines gzip; 객체는 immutable |
| 운영 메타데이터 | 세션·아동별 목록·이슈·분석 상태·알림 상태 조회 | DynamoDB 단일 테이블 + 최소 GSI |
| 분석 파이프라인 | 정규화, 규칙 탐지, LLM 호출, 결과 검증·저장 | SQS + Lambda부터 시작; 장시간/대용량은 ECS worker로 분리 |
세션 수명주기
- 서버가
sessionId를 발급하고 아동·회기·앱 버전·기기 익명 식별자와 연결한다. - SDK는 증가하는
sequence를 부여해 이벤트를 5초 또는 100건 단위로 압축 전송한다. - 네트워크 실패 시 IndexedDB에 보관하고 지수 백오프로 순서대로 재전송한다.
- 종료 시 manifest를 확정하고 세션 메타데이터를
UPLOADED로 전환한 뒤 분석 큐에 한 번만 발행한다. - 분석 결과와 이슈를 저장하고 정책을 통과한 항목만 Slack 전송 큐에 넣는다.
3. 이벤트 계약과 웹 SDK
원본 DOM 이벤트와 업무 의미 이벤트를 분리하되, 공통 envelope로 합친다. 이 구조는 리플레이·검색·AI 분석에서 같은 기준 시각과 증거 ID를 사용하게 한다.
{
"schemaVersion": "1.0",
"eventId": "evt_01HXYZ",
"sessionId": "sr_01HXYZ",
"childId": "child_123",
"lessonSessionId": "lesson_session_456",
"timestamp": "2026-08-04T07:30:15.421Z",
"sequence": 142,
"source": "ppi-web",
"eventType": "stt.completed",
"payload": { "text": "[masked if needed]", "confidence": 0.82, "latencyMs": 630 }
}
| 그룹 | 필수 이벤트 | AI/운영 가치 |
|---|---|---|
| 세션·화면 | session.started|ended|abandoned, screen.entered, route.changed, replay.full_snapshot | 재생 시작점, 이탈과 화면 전환 재구성 |
| 사용자 행동 | ui.clicked, ui.input_changed, ui.scrolled, ui.blocked | 반복 클릭·정체 구간·UI 실패 판단 |
| 음성 AI | stt.*, llm.*, tts.* | 단계별 지연, 실패, 프롬프트/모델 버전과 대화 문맥 |
| 통신·API | api.completed|failed, livekit.*, webrtc.stats | 재연결, 5xx, RTT·packet loss와 사용자 영향 연결 |
| 오류·수업 | client.error, lesson.step_entered|completed, lesson.ended | 예외 시점, 단계 진행 실패 및 회기 완료 여부 |
4. 저장·조회 모델
S3: 변경 불가 원본과 분석 산출물
s3://ppi-session-replay-{env}/
tenant/{tenantId}/child/{childId}/date=2026-08-04/session/{sessionId}/
manifest.json
replay/events-0001.ndjson.gz
replay/rrweb-0001.ndjson.gz
metrics/webrtc-summary.json.gz
analysis/context-v1.json
analysis/result-v1.json
manifest에는 파일 키, 시간 범위, 이벤트 수, SHA-256, 스키마 버전을 기록한다. 업로드 재시도는 동일한 eventId를 허용하고, server-side dedupe 후 manifest에 확정된 청크만 포함한다.
DynamoDB: 조회용 메타데이터
| 엔터티 | 키 | 주요 속성 | 조회 목적 |
|---|---|---|---|
| SESSION | PK=CHILD#{childId}SK=SESSION#{startedAt}#{sessionId} | lessonSessionId, 상태, duration, appVersion, issueCount, highestSeverity, manifestKey | 아동별 회기 시간순 목록 |
| SESSION lookup | GSI1PK=SESSION#{sessionId}GSI1SK=META | 동일 세션 레코드 투영 | 세션 상세 직접 진입 |
| ISSUE | PK=SESSION#{sessionId}SK=ISSUE#{startedAt}#{issueId} | type, severity, confidence, evidenceEventIds, status | 타임라인·이슈 패널 |
| 운영 GSI | GSI2PK=SEVERITY#{severity}GSI3PK=ANALYSIS#{status} | createdAt, appVersion, issueType | 운영 큐·실패 재처리 |
| 아동 집계 | PK=CHILD#{childId}SK=AGGREGATE#LATEST | 최근 N회기 지표·반복 이슈 카운트 | 장기 추세 카드 |
기간·앱 버전·복수 태그의 자유 조합 검색은 초기 DynamoDB 범위에 넣지 않는다. 우선 화면에서 필요한 단일 필터와 사전 집계만 지원하고, 실제 조회 패턴이 확인된 뒤 OpenSearch 도입 여부를 결정한다.
5. AI 이슈 분석 파이프라인
- 정규화: 시간 정렬, 중복 제거, 클록 보정, 민감정보 제거, sequence gap 표시.
- 규칙 사전 탐지: 명확하고 비용이 낮은 이상을 먼저 증거와 함께 계산.
- 컨텍스트 축약: 오류 전후 구간, 수업 단계별 전환, 음성 turn, 네트워크 요약만 AI에 전달.
- 구조화된 LLM 분석: JSON schema로 요약·이슈·심각도·증거·권장 조치를 생성.
- 검증과 저장: 시간 범위와 evidenceEventId가 실제 이벤트에 존재하는지 확인한 뒤 저장; 실패는 DLQ와 재시도 정책으로 처리.
| 규칙 | 초기 임계값 | 생성 이슈 |
|---|---|---|
| STT/LLM/TTS 단계 지연 | 각각 2초 / 5초 / 3초 초과 | LATENCY_DEGRADED |
| LiveKit 재연결 | 세션 중 3회 이상 | NETWORK_UNSTABLE |
| HTTP 서버 오류 | API 5xx 또는 핵심 API 연속 실패 | API_FAILURE |
| 사용자 진행 정체 | 동일 CTA 5회, 또는 30초 무진행 | USER_BLOCKED |
| 비정상 종료 | ended 없이 heartbeat timeout | SESSION_INCOMPLETE |
{
"sessionId": "sr_01HXYZ",
"summary": "STT 지연 이후 화면 진행이 정체된 세션입니다.",
"severity": "HIGH",
"issues": [{
"type": "STT_MISRECOGNITION",
"severity": "HIGH",
"startMs": 732000,
"endMs": 738000,
"confidence": 0.91,
"evidenceEventIds": ["evt_101", "evt_102"],
"possibleCause": "낮은 STT 신뢰도와 재연결 구간이 겹침",
"recommendedAction": "해당 구간의 마스킹된 전사와 네트워크 지표를 검토"
}],
"modelVersion": "analysis-prompt-v1"
}
6. PPI 웹 대시보드와 Slack
세션 목록
아동, 수업, 시작 시각, 길이, 앱 버전, 분석 상태, 이슈 수, 최고 심각도, 태그를 표시한다. MVP 필터는 기간·아동·분석 상태·심각도·앱 버전으로 제한한다.
세션 상세
좌측 DOM 리플레이, 우측 AI 요약·이슈, 하단 통합 타임라인과 원본 로그 링크로 구성한다. 이슈나 타임라인 항목을 선택하면 플레이어를 해당 시점으로 seek한다.
통합 타임라인 레인
UI · STT · LLM · TTS · Network · API/Error · AI Issue. 이벤트 밀집 구간은 집계 표시하고, AI 이슈는 심각도 색상과 evidence count를 함께 보인다.
Slack 알림 정책
- HIGH 이상, 세션 비정상 종료, 수업 미완료, STT/TTS 전체 실패, LiveKit 연결 실패만 즉시 전송
- MEDIUM은 30분 단위로 앱 버전·이슈 유형별 요약
dedupeKey = issueType + appVersion + normalizedCause로 일정 시간 중복 억제- 메시지에는 가명화된 아동 식별자, 지표, 권장 조치, 권한이 필요한 PPI 세션 링크만 포함
7. 단계별 개발 계획
Phase 1 — 이벤트 로깅과 저장 MVP 핵심
공통 스키마, 세션 발급, 웹 SDK 버퍼/재전송/마스킹, Ingestion API, S3 청크, DynamoDB 세션 메타데이터를 구현한다.
완료 기준: 테스트 세션이 순서대로 저장되고, 네트워크 단절 뒤에도 중복 없이 복구되며, 아동 ID로 목록을 조회한다.
Phase 2 — 웹 리플레이와 통합 타임라인 MVP 핵심
DOM 스냅샷/증분 이벤트를 재생하고 PPI 고유 이벤트를 타임라인에 합친다.
완료 기준: URL·클릭·오류·화면 흐름을 재생하고, 타임라인 선택이 해당 시간으로 이동한다.
Phase 3 — 음성·네트워크 컨텍스트
STT/LLM/TTS의 request correlation ID, 지연, 결과 상태, prompt/model version과 LiveKit/WebRTC 요약을 연결한다.
완료 기준: 한 세션에서 음성 파이프라인의 각 단계와 실패 지점을 확인한다.
Phase 4 — 자동 분석과 이슈 워크플로
규칙 엔진, 분석 컨텍스트 생성, JSON schema 검증, 이슈/태그 저장, HIGH Slack 알림을 추가한다.
완료 기준: 세션 종료 뒤 1분 안에 분석 결과가 생성되고, 이슈가 근거 이벤트와 연결된다.
Phase 5 — 운영 확대 후속
아동별 장기 집계, 반복 이슈 탐지, 앱 버전 회귀 지표, 보존 정책 자동화, 운영 피드백 기반 오탐 개선을 진행한다.
8. 보안·보존·장애 대응
| 영역 | 결정 |
|---|---|
| 접근 제어 | 개발자는 익명화 이벤트와 분석 결과만, 승인 운영자는 사유·감사 로그를 남겨 제한된 민감 원본에 접근한다. |
| 암호화 | 전송 TLS, S3 SSE-KMS, DynamoDB 암호화, presigned URL 최소 만료 시간을 적용한다. |
| 보존 | 성공 세션의 원본은 짧게, 오류 세션은 정책상 더 길게 보관한다. S3 lifecycle과 DynamoDB TTL을 이용하고 삭제 요청을 manifest·메타데이터·파생 분석 결과에 전파한다. |
| 업로드 실패 | IndexedDB 로컬 큐, 지수 백오프, eventId 멱등성, sequence gap 표시로 복구 가능성을 보장한다. |
| 종료 누락 | heartbeat timeout 뒤 INCOMPLETE로 전환한다. 불완전 세션도 분석 대상이며 자동 종료 사유를 남긴다. |
| 분석/알림 실패 | 상태 전이와 retry count를 DynamoDB에 기록하고, 제한 초과 메시지는 DLQ로 보낸다. Slack은 message id/dedupe key로 중복 전송을 막는다. |
9. 측정 지표와 착수 체크리스트
서비스 SLO
- 이벤트 업로드 성공률 ≥ 99.9%
- 리플레이 이벤트 누락률 ≤ 0.1%
- 세션 상세 조회 p95 ≤ 2초
- 분석 시작: 종료 후 ≤ 1분
- Slack 중복 알림률 ≤ 5%
착수 전 확정할 항목
- 아동/운영자 동의와 실제 데이터 보존 기간
- 기존 PPI 인증에서 세션 조회 권한을 판정하는 기준
- 실제 트래픽을 기준으로 한 청크 크기·샘플링·비용 한도
- STT/LLM/TTS 상관관계 ID의 현재 공급 위치