一键导入
data-integrity
Agent 채팅 데이터 무결성 관리 스킬. IndexedDB v3 스키마, Optimistic Updates, Eventual Consistency 패턴 구현 시 사용.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Agent 채팅 데이터 무결성 관리 스킬. IndexedDB v3 스키마, Optimistic Updates, Eventual Consistency 패턴 구현 시 사용.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
코드 품질 관리 스킬. Prettier/ESLint/TypeScript 컨벤션, Agent Skills 활용 패턴, 코드 리뷰 체크리스트.
Guide for the Map page feature (Kakao Maps integration, location search, store category filtering). Use when working on map components, search bar, bottom sheet, detail sheet, store/pickup filters, or Kakao Map API integration. Triggers on "map", "kakao map", "location search", "store category", "bottom sheet", "map marker", "nearby", "autocomplete", "suggest".
Agent 기능 트러블슈팅 스킬. 빌드 에러, 이미지 업로드 실패, SSE 연결 문제 등 실전 문제 해결 가이드.
Vercel 공식 React 성능 최적화 스킬. AI 에이전트를 위한 40+ 규칙 (waterfalls 제거, 번들 크기 최적화 등).
Agent 페이지 구현 스킬. SSE 토큰 스트리밍, 사이드바, 마크다운 렌더링, 메시지 액션을 포함한 AI 챗봇 인터페이스 구현 시 사용. React 19 + TypeScript + TailwindCSS 기반.
| name | data-integrity |
| description | Agent 채팅 데이터 무결성 관리 스킬. IndexedDB v3 스키마, Optimistic Updates, Eventual Consistency 패턴 구현 시 사용. |
Agent 채팅의 데이터 무결성과 일관성을 보장하는 아키텍처 패턴 가이드
Agent 채팅은 다층 데이터 아키텍처로 실시간 UX와 데이터 안정성을 모두 확보합니다:
┌─────────────────────────────────────────────────────────────┐
│ Frontend Data Layers │
├─────────────────────────────────────────────────────────────┤
│ │
│ Layer 1: React State (메모리) │
│ ├─ 목적: 실시간 UI 렌더링 │
│ ├─ 생명주기: 컴포넌트 마운트 ~ 언마운트 │
│ └─ 소실 조건: 새로고침, 탭 닫기 │
│ │
│ Layer 2: IndexedDB (브라우저) │
│ ├─ 목적: 새로고침 대비, 오프라인 캐시 │
│ ├─ 생명주기: 브라우저 저장소 유지 │
│ ├─ 격리: user_id + session_id │
│ └─ 정리: 30초 retention (committed) + 7일 TTL │
│ │
│ Layer 3: Backend DB (PostgreSQL) │
│ ├─ 목적: 영구 저장, Source of Truth │
│ ├─ 계층: users → conversations → messages │
│ └─ 정렬: created_at (timestamp) │
│ │
└─────────────────────────────────────────────────────────────┘
사용 시기: 메시지 전송 즉시
// 1. User 메시지 즉시 표시 (pending 상태)
const userMessage = createUserMessage(content);
userMessage.status = 'pending';
setMessages(prev => [...prev, userMessage]);
// 2. 서버 전송
const response = await sendMessage(chatId, { message: content });
// 3. SSE 완료 시 committed로 업데이트
onSSEComplete((result) => {
updateMessageStatus(userMessage.client_id, 'committed', result.server_id);
});
메시지 상태 전이:
pending → committed (성공)
pending → failed (실패)
계층 구조: Backend와 정확히 일치
// Backend
users_accounts.id → chat_conversations.id → chat_messages.id
// Frontend IndexedDB
user_id → session_id → client_id + created_at
주요 인덱스:
by-user-session-created: [user_id, session_id, created_at]by-synced: 동기화 여부 (0/1)30초 Retention Window: 서버 committed 메시지를 30초간 IndexedDB에 유지
// Reconcile 로직
const merged = reconcileMessages(localMessages, serverMessages, {
committedRetentionMs: 30000,
});
// 정책
// - pending 메시지: 항상 유지 (재시도 가능)
// - committed 메시지: 30초 후 삭제 (서버가 Source of Truth)
데이터 무결성 구현 시작
│
├─ IndexedDB 스키마 설계?
│ └─ references/indexeddb-schema.md 참조
│
├─ 메시지 순서 보장?
│ └─ references/message-ordering.md 참조
│
├─ Optimistic Updates 구현?
│ └─ references/optimistic-updates.md 참조
│
└─ Reconcile 정책 설정?
└─ references/optimistic-updates.md §4 참조
// db/messageDB.ts
const messageDB = new MessageDB();
await messageDB.init();
// v1 → v2 → v3 자동 마이그레이션
// 레거시 인덱스 정리 + 신규 인덱스 생성
await messageDB.saveMessages(
userId, // users_accounts.id
sessionId, // chat_conversations.id
messages, // AgentMessage[]
);
// 1. IndexedDB에서 로드 (즉시 표시)
const localMessages = await messageDB.getMessages(userId, sessionId);
setMessages(localMessages);
// 2. 서버 조회 (백그라운드)
const serverMessages = await getChatDetail(sessionId);
// 3. Reconcile (로컬 pending + 서버 committed)
const merged = reconcileMessages(localMessages, serverMessages, {
committedRetentionMs: 30000,
});
setMessages(merged);
❌ Redis Stream ID 사용 금지
created_at 필드 사용✅ created_at 기반 정렬
const messages = await db.getAllFromIndex(
'messages',
'by-user-session-created',
IDBKeyRange.bound([userId, sessionId, ''], [userId, sessionId, '\uffff'])
);
일관성 유지:
chat_id, conversation_id (동일한 값)session_id (명확한 계층 표현)// 30초 retention (committed + synced)
await messageDB.cleanup(userId, sessionId, {
committedRetentionMs: 30000,
});
// 7일 TTL (모든 메시지)
await messageDB.cleanup(userId, sessionId, {
ttlMs: 7 * 24 * 60 * 60 * 1000,
});
| 파일 | 내용 |
|---|---|
references/indexeddb-schema.md | v3 스키마 상세, 마이그레이션, ID 계층 구조 |
references/message-ordering.md | created_at vs stream_id, 순서 보장 검증 |
references/optimistic-updates.md | 상태 전이, Reconcile 로직, Retention 정책 |
구현 시 아래 순서대로 진행:
[ ] 1. IndexedDB v3 스키마 구현 (user_id + session_id)
[ ] 2. Optimistic Update 패턴 (pending → committed)
[ ] 3. SSE 완료 시 상태 업데이트 로직
[ ] 4. IndexedDB 자동 저장 (throttled, 500ms)
[ ] 5. Reconcile 로직 (로컬 + 서버 병합)
[ ] 6. Cleanup 정책 (30초 retention + 7일 TTL)
[ ] 7. User isolation 검증 (multi-user 시나리오)
[ ] 8. 메시지 순서 검증 (created_at 기반)
문제 발생 시 ../troubleshooting/SKILL.md 참조: