wiki: Topic_Blog 신규 문서 일괄 추가 + ASTRA 성장 자산 동기화
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
---
|
||||
id: pattern-catalog-index
|
||||
title: "패턴 카탈로그 인덱스"
|
||||
category: "Index"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["pattern catalog", "패턴 카탈로그", "design pattern index", "패턴 라이브러리"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.9
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["index", "pattern", "catalog", "navigation"]
|
||||
raw_sources: ["Pattern_Catalog 전체"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[패턴 카탈로그 인덱스]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
플랫폼이 달라도 개발은 *같은 문제(상태·비동기·데이터·캐싱·오류·분리)* 를 반복한다 — 이 카탈로그는 재사용 가능한 패턴 27종을 (언제·조건·장점·단점·대안·실패사례) 형식으로 정리해 작은 모델이 상황에 맞는 패턴을 고르게 한다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
각 패턴 카드 = 문제/조건/장단점/대안/실패. AstraAI 사례가 있으면 적용 예로 연결, 없으면 일반 지식.
|
||||
|
||||
## 📖 세부 내용 (Details · 패턴 목록)
|
||||
|
||||
### Cross-cutting (모든 플랫폼 공통 — 최우선 학습)
|
||||
- [[State Management Pattern]] · [[Async Concurrency Pattern]] · [[Data Flow Pattern]] · [[Caching Pattern]] · [[Error Handling Pattern]] · [[Architecture Separation Pattern]]
|
||||
|
||||
### AI
|
||||
- [[RAG Pattern]] · [[Memory Pattern]] · [[Agent Orchestration Pattern]] · [[Reflection Pattern]] · [[Critic Pattern]] · [[Tool Calling Pattern]]
|
||||
|
||||
### Web
|
||||
- [[JWT Authentication Pattern]] · [[Repository Pattern]] · [[API Client Pattern]] · [[React State Pattern]] · [[Infinite Scroll Pattern]] (캐싱은 [[Caching Pattern]])
|
||||
|
||||
### Mobile
|
||||
- [[Offline Sync Pattern]] · [[Local Storage Pattern]] · [[Background Task Pattern]] · [[Push Notification Pattern]] · [[Navigation Pattern]]
|
||||
|
||||
### Desktop
|
||||
- [[IPC Pattern]] · [[Plugin Architecture Pattern]] · [[Command Pattern]] · [[Event Bus Pattern]] · [[Background Worker Pattern]]
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
패턴은 *기본값* 이지 의무가 아니다. 적용 전 [[소프트웨어 실패 라이브러리]] 로 "이 패턴이 어떻게 깨지는가" 를 함께 확인하라.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
RAG/Memory/Agent Orchestration/Critic/Event Bus/Repository/Caching/API Client/IPC/Command/Plugin/Background Worker 는 AstraAI 에 실제 구현되어 있어 코드 근거가 있다.
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[Topic Programming 인덱스]]
|
||||
- **관련 개념:** [[소프트웨어 실패 라이브러리]] · [[플랫폼 개발 가이드 인덱스]] · [[프로젝트 독립 설계 원칙]]
|
||||
- **참조 맥락:** 작은 모델이 구현 시 "어떤 패턴을 쓸까" 를 고를 때의 카탈로그.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] Pattern_Catalog 전체 + 일반 소프트웨어 공학 지식 + AstraAI 적용 예
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: 패턴 카탈로그 인덱스 생성.
|
||||
@@ -0,0 +1,71 @@
|
||||
---
|
||||
id: pattern-agent-orchestration
|
||||
title: "Agent Orchestration Pattern"
|
||||
category: "Pattern_AI"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["Agent Orchestration", "에이전트 오케스트레이션 패턴", "multi-agent", "pipeline"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.88
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["pattern", "ai", "agent", "orchestration", "platform-independent"]
|
||||
raw_sources: ["일반 소프트웨어 공학 지식", "AstraAI/src/agents/*, src/features/company/dispatcher.ts (적용 예)"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[Agent Orchestration Pattern]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
에이전트 오케스트레이션은 "큰 작업을 단계/역할로 쪼개 LLM 을 여러 번 호출·조율" 하는 패턴이며, *에이전트 수를 늘리는 것 자체가 목적이 되면 실패* 한다 — 정보 손실과 자원을 먼저 따져라.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
1. **분해:** 작업 → 단계(outline/draft/polish) 또는 역할(planner/specialist/reporter).
|
||||
2. **조율:** 흐름 골격이 호출 순서·데이터 전달을 관리.
|
||||
3. **상태 전달:** 앞 단계 출력을 다음에 전달(peer-context), 단 손실 주의.
|
||||
4. **자원 모델:** 병렬 vs 순차는 하드웨어가 결정.
|
||||
|
||||
## 📖 세부 내용 (Details · 패턴 명세)
|
||||
- **Problem (언제 쓰나):** 단일 호출로는 품질/길이/전문성이 부족한 복합 작업.
|
||||
- **사용 조건:** 단계 분해가 명확; 단계 간 인터페이스 정의 가능; 자원이 선택한 동시성 모델을 감당.
|
||||
- **장점:** 단계별 최적화, 긴 산출물, 역할 전문화, 검증 단계 삽입 용이.
|
||||
- **단점:** 지연·비용 증가, hop 마다 컨텍스트 누적/원본 손실, 디버깅 복잡.
|
||||
- **대안:** 단일 프롬프트(짧은 작업), 단일 작성자 다중 역할(자원 제약), 도구 호출.
|
||||
- **실패 사례:** 에이전트 남발로 "방법론만 생성"; 병렬 다중 모델 상주 OOM; orchestrator 재비대.
|
||||
|
||||
## 💻 코드 패턴 (Code patterns)
|
||||
```text
|
||||
# 자원 제약: 순차 + 한 모델 상주
|
||||
plan = planner(prompt)
|
||||
peer = ""
|
||||
for task in plan.tasks:
|
||||
out = specialist(task, peer); persist(out); peer += truncate(out)
|
||||
report = synthesizer(prompt, peer)
|
||||
|
||||
# 단일 작성자 다중 역할 (작은 모델 친화)
|
||||
outline = M("outline", prompt); body = [M("section", o, source) for o in outline]; M("polish", body)
|
||||
```
|
||||
적용 예: [[Agent 오케스트레이터 분해]], [[AITRAIN 에이전트 오케스트레이션]], 결정 [[ADR-0003 단일작성자 다중역할 멀티에이전트]]·[[ADR-0004 순차 디스패치 채택]].
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
"멀티에이전트가 항상 낫다" 는 자원 제약 하에서 거짓 — 잘 만든 단일 작성자가 어설픈 병렬 파이프라인을 이긴다.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
AstraAI company dispatcher(순차), ChunkedWriter(단일 다중역할).
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[패턴 카탈로그 인덱스]]
|
||||
- **관련 개념:** [[Reflection Pattern]], [[Critic Pattern]], [[Tool Calling Pattern]], [[Background Worker Pattern]]
|
||||
- **참조 맥락:** 작은 모델이 복합 작업을 단계화할 때 과설계 회피와 함께 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] 일반 멀티에이전트 지식
|
||||
- [S2] AstraAI/src/agents/*, features/company/dispatcher.ts — 적용 예
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
|
||||
@@ -0,0 +1,63 @@
|
||||
---
|
||||
id: pattern-critic
|
||||
title: "Critic Pattern"
|
||||
category: "Pattern_AI"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["Critic", "LLM judge", "검수자 패턴", "verifier"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.88
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["pattern", "ai", "critic", "verification", "platform-independent"]
|
||||
raw_sources: ["일반 소프트웨어 공학 지식", "AstraAI/src/intelligence/criticAgent.ts (적용 예)"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[Critic Pattern]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
Critic 패턴은 "별도의 검수자(보통 LLM)가 산출물을 비판적으로 평가" 하는 것으로, 생성자와 검수자를 분리하면 환각·누락을 잡지만 *검수 출력도 결국 LLM 이라 강건 파싱·근거 강제가 필수* 다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
1. 생성자와 검수자 역할 분리. 2. 검수 기준 명시(요구 충족·근거·미결 구분·지어냄 금지). 3. 구조화 출력(JSON) + 강건 파싱. 4. 검수 결과를 보완 카드/재작성 입력으로.
|
||||
|
||||
## 📖 세부 내용 (Details · 패턴 명세)
|
||||
- **Problem (언제 쓰나):** 산출물의 사실성/완결성이 중요하고, 생성자 자체 점검만으론 부족할 때.
|
||||
- **사용 조건:** 검수 기준을 명문화 가능; 검수 호출 비용 감당; 출력 파싱 방어.
|
||||
- **장점:** 독립 시각으로 오류 포착, 근거 없는 단정 차단, 보완 제안.
|
||||
- **단점:** 추가 LLM 비용, 검수자도 환각 가능, JSON 형식 위반.
|
||||
- **대안:** 결정론 규칙 검증, 다수결(여러 검수자), 사람 검수.
|
||||
- **실패 사례:** 검수자가 원문에 없는 내용을 "보완" 으로 지어냄; JSON.parse 직접 호출로 파싱 실패; 무조건 검수로 비용 폭증.
|
||||
|
||||
## 💻 코드 패턴 (Code patterns)
|
||||
```text
|
||||
critique = LLM_critic(system="검수자. 근거 없는 단정/지어냄은 major. JSON만 출력", user=task+draft)
|
||||
result = parseBalancedJson(critique) or heuristicFallback() # 잡설 내성
|
||||
if not result.pass: attach(footer(result.issues, result.supplement))
|
||||
# 규칙: supplement 도 원문 근거 한정, 없으면 "(확인 필요)"
|
||||
```
|
||||
적용 예: [[Intelligence 검증 레이어]] 의 criticAgent(조건부 1-pass + 균형 괄호 파서), 결정 [[ADR-0009 결정론 항상 LLM검증 조건부]].
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
검수자가 생성자보다 똑똑하지 않으면 효과가 제한적 — 작은 모델끼리는 *결정론 신호 + 근거 강제* 가 LLM-judge 보다 안정적일 수 있다.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
AstraAI Critic(조건부), regression LLM-judge.
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[패턴 카탈로그 인덱스]]
|
||||
- **관련 개념:** [[Reflection Pattern]], [[프롬프트 엔지니어링 패턴]], [[소프트웨어 실패 라이브러리]]
|
||||
- **참조 맥락:** 작은 모델이 산출물 품질 게이트를 둘 때 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] 일반 LLM critic/judge 지식
|
||||
- [S2] AstraAI/src/intelligence/criticAgent.ts — 적용 예
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
|
||||
@@ -0,0 +1,63 @@
|
||||
---
|
||||
id: pattern-memory
|
||||
title: "Memory Pattern"
|
||||
category: "Pattern_AI"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["Memory Pattern", "에이전트 메모리 패턴", "agent memory"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.89
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["pattern", "ai", "memory", "agent", "platform-independent"]
|
||||
raw_sources: ["일반 소프트웨어 공학 지식", "AstraAI/src/memory/* (적용 예)"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[Memory Pattern]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
에이전트 메모리 패턴은 "대화/세션을 넘어 지식을 보존·회수" 하며, 단일 버퍼가 아니라 *수명·용도별 계층* 으로 나누고 관련도로 선별 주입할 때 작은 모델의 일관성이 크게 오른다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
1. **단기:** 현재 대화(FIFO). 2. **장기:** 안정적 사실/선호(만료 가능). 3. **작업/프로젝트:** 작업 종속 지식. 4. **절차:** 반복 작업 방법. 5. **일화:** 과거 세션 요약. 회수 시 관련도순 선별.
|
||||
|
||||
## 📖 세부 내용 (Details · 패턴 명세)
|
||||
- **Problem (언제 쓰나):** 에이전트가 세션을 넘어 사용자/프로젝트를 기억해야 할 때, 컨텍스트 한도가 빠듯할 때.
|
||||
- **사용 조건:** 영속 저장 가능; 관련도 점수화 가능; 무엇을 어느 계층에 넣을지 분류 규칙 존재.
|
||||
- **장점:** 일관성·개인화, 컨텍스트 정밀 선별, 시한부/영구 공존, 자동 정리(증류).
|
||||
- **단점:** 분류 결정 비용, 저장/검색 인프라, 잘못된 회수 시 노이즈.
|
||||
- **대안:** 무상태(매번 새로), 전체 이력 투입(짧을 때), 외부 RAG 로만 대체.
|
||||
- **실패 사례:** 만료 없는 영구 저장으로 옛 사실 재현; 관련도 오선별로 핵심 누락; 계층 경계 모호로 중복.
|
||||
|
||||
## 💻 코드 패턴 (Code patterns)
|
||||
```text
|
||||
buildContext(query):
|
||||
layers = [shortTerm, longTerm(query), project(query), procedural(query), episodic(query)]
|
||||
return sort_by_relevance(layers).join() # 빈 계층 제외
|
||||
onSessionEnd(): extract -> persist -> distill(stale -> longterm digest)
|
||||
```
|
||||
적용 예: [[5계층 메모리 시스템]], [[AITRAIN 메모리 시스템]], 결정 [[ADR-0002 5계층 메모리 분리]].
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
계층이 많을수록 표현력↑ 결정 비용↑ — 명확한 분류 규칙이 없으면 단순 3계층(작업/세션/영구)이 낫다.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
AstraAI MemoryManager.
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[패턴 카탈로그 인덱스]]
|
||||
- **관련 개념:** [[RAG Pattern]], [[Local Storage Pattern]], [[Offline Sync Pattern]]
|
||||
- **참조 맥락:** 작은 모델이 기억하는 에이전트를 만들 때 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] 일반 에이전트 메모리 지식
|
||||
- [S2] AstraAI/src/memory/* — 적용 예
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
|
||||
@@ -0,0 +1,66 @@
|
||||
---
|
||||
id: pattern-rag
|
||||
title: "RAG Pattern"
|
||||
category: "Pattern_AI"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["RAG", "Retrieval-Augmented Generation", "검색 증강 생성 패턴"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.9
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["pattern", "ai", "rag", "retrieval", "platform-independent"]
|
||||
raw_sources: ["일반 소프트웨어 공학 지식", "AstraAI/src/retrieval/* (적용 예)"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[RAG Pattern]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
RAG 는 "모델이 답하기 전에 외부 지식에서 관련 조각을 검색해 프롬프트에 주입" 하는 패턴으로, 모델의 학습되지 않은/최신/사적 지식을 *재학습 없이* 활용하고 환각을 줄인다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
1. **인덱싱:** 문서를 청크로 나눠 검색 인덱스(키워드/임베딩)에 저장.
|
||||
2. **검색:** 질의로 top-k 관련 청크 회수(sparse/dense/하이브리드).
|
||||
3. **증강:** 회수 청크를 컨텍스트로 프롬프트에 삽입(토큰 예산 내).
|
||||
4. **생성:** 모델이 근거를 보고 답하고 출처를 인용.
|
||||
|
||||
## 📖 세부 내용 (Details · 패턴 명세)
|
||||
- **Problem (언제 쓰나):** 모델이 모르는 사적/최신/대용량 지식이 필요하고, 파인튜닝은 비싸거나 자주 바뀔 때. 출처 인용·환각 감소가 필요할 때.
|
||||
- **사용 조건:** 검색 가능한 지식 베이스 존재; 청킹/인덱싱 가능; 컨텍스트 한도 내 주입 가능.
|
||||
- **장점:** 재학습 불필요, 지식 즉시 갱신, 출처 추적, 환각↓, 작은 모델도 강화.
|
||||
- **단점:** 검색 품질에 답이 좌우(garbage in), 인덱싱/저장 비용, 컨텍스트 토큰 소비, 청킹 경계 손실.
|
||||
- **대안:** 파인튜닝(지식이 안정적·대규모일 때), 긴 컨텍스트에 전체 투입(소량일 때), 도구 호출로 실시간 조회.
|
||||
- **실패 사례:** 청크가 너무 커 정밀도↓; 부분 정규화로 하이브리드 편향; 동의어 미확장으로 recall↓; stale 인덱스; 운영 로그를 지식으로 오염.
|
||||
|
||||
## 💻 코드 패턴 (Code patterns)
|
||||
```text
|
||||
index = chunk(docs) -> tokenize/embed -> store
|
||||
query -> expand(synonyms) -> score(sparse + α·dense) -> normalize -> rerank
|
||||
context = selectWithinTokenBudget(top_chunks)
|
||||
answer = LLM(system + context + question) # "근거 없으면 모른다고"
|
||||
```
|
||||
적용 예: AstraAI 의 [[RAG 검색 파이프라인]]·[[TF-IDF 이중언어 스코어링]] (하이브리드+섹션 청킹+토큰 예산).
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
"임베딩만 쓰면 된다" 는 가용성·설명가능성을 잃는다 — 결정론(키워드) 바닥선 + 임베딩 가산이 견고([[ADR-0007 하이브리드 검색 결정론 우선]]).
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
AstraAI 전체 검색이 이 패턴. → [[AITRAIN RAG 검색]].
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[패턴 카탈로그 인덱스]]
|
||||
- **관련 개념:** [[Memory Pattern]], [[Caching Pattern]], [[Tool Calling Pattern]], [[소프트웨어 실패 라이브러리]]
|
||||
- **참조 맥락:** 작은 모델이 지식 기반 응답 시스템을 만들 때 1순위 패턴.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] 일반 RAG 공학 지식
|
||||
- [S2] AstraAI/src/retrieval/* — 적용 예
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
id: pattern-reflection
|
||||
title: "Reflection Pattern"
|
||||
category: "Pattern_AI"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["Reflection", "자기성찰 패턴", "self-reflection", "self-critique"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.88
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["pattern", "ai", "reflection", "self-improvement", "platform-independent"]
|
||||
raw_sources: ["일반 소프트웨어 공학 지식", "AstraAI/src/intelligence/*, src/features/selfReflector/* (적용 예)"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[Reflection Pattern]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
Reflection 은 "모델이 자기 출력을 다시 점검·수정" 하는 패턴으로, 작은 모델의 1-pass 오류를 줄이지만 *호출이 늘어 비용/지연이 증가* 하므로 조건부로 써야 한다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
1. **생성 → 점검 → (필요시) 재생성** 루프. 2. 점검은 *결정론 신호* 또는 *LLM 자기비판*. 3. 자기검토 지시를 시스템 프롬프트에 주입. 4. 무한 루프 방지(최대 라운드).
|
||||
|
||||
## 📖 세부 내용 (Details · 패턴 명세)
|
||||
- **Problem (언제 쓰나):** 1-pass 정확도가 부족하고, 오류 비용이 재검토 비용보다 클 때.
|
||||
- **사용 조건:** 점검 신호(규칙/요구사항/근거) 정의 가능; 추가 호출 latency 감당.
|
||||
- **장점:** 정확도·완결성↑, 누락/모순 발견, 불확실성 표면화.
|
||||
- **단점:** 지연·비용↑, 과도하면 헤지 남발, 무한 루프 위험.
|
||||
- **대안:** 결정론 검증만(무LLM), 외부 검증기, 더 큰 모델 1-pass.
|
||||
- **실패 사례:** 매 턴 무조건 reflect 로 latency 폭증; 자기비판이 오히려 정답을 망침; 종료 조건 없어 루프.
|
||||
|
||||
## 💻 코드 패턴 (Code patterns)
|
||||
```text
|
||||
draft = LLM(task)
|
||||
signals = deterministicChecks(draft) # 커버리지/근거/확신도 — 항상(저비용)
|
||||
if signals.risky: # 조건부로만 LLM 점검
|
||||
issues = LLM_critique(task, draft)
|
||||
if issues: draft = revise(draft, issues) # 최대 N라운드
|
||||
emit(draft + confidence_footer)
|
||||
```
|
||||
적용 예: [[Intelligence 검증 레이어]] (사전 자기검토 블록 + 조건부 critic), 결정 [[ADR-0009 결정론 항상 LLM검증 조건부]].
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
"항상 성찰하면 좋다" 는 비용을 무시한 통념 — *위험 신호가 있을 때만* 깊은 성찰이 비용 대비 효과적.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
AstraAI selfReflector + 조건부 Critic.
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[패턴 카탈로그 인덱스]]
|
||||
- **관련 개념:** [[Critic Pattern]], [[Agent Orchestration Pattern]], [[프롬프트 엔지니어링 패턴]]
|
||||
- **참조 맥락:** 작은 모델의 자기개선 루프 설계 시 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] 일반 reflection/self-critique 지식
|
||||
- [S2] AstraAI/src/intelligence/*, features/selfReflector/* — 적용 예
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
id: pattern-tool-calling
|
||||
title: "Tool Calling Pattern"
|
||||
category: "Pattern_AI"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["Tool Calling", "function calling", "도구 호출 패턴", "action tag"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.88
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["pattern", "ai", "tool-calling", "function-calling", "platform-independent"]
|
||||
raw_sources: ["일반 소프트웨어 공학 지식", "AstraAI/src/agent/actions/* (적용 예)"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[Tool Calling Pattern]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
Tool Calling 은 "모델이 자연어 대신 구조화된 호출(함수/태그)로 외부 도구를 실행" 하게 해 실제 행동(파일 생성·명령 실행·검색)을 가능케 하며, *모델 출력을 신뢰 경계로 보고 검증·승인* 하는 것이 안전의 핵심이다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
1. 도구 스키마 정의(이름·인자). 2. 모델이 호출 의도를 구조화 출력(JSON function call 또는 `<action>` 태그). 3. 실행기가 파싱→검증→실행→결과 반환. 4. 위험 동작은 승인 게이트.
|
||||
|
||||
## 📖 세부 내용 (Details · 패턴 명세)
|
||||
- **Problem (언제 쓰나):** 모델이 텍스트를 넘어 *행동* 해야 할 때(파일/명령/API/검색).
|
||||
- **사용 조건:** 도구 인터페이스 명확; 출력 파싱 가능; 권한/검증 체계.
|
||||
- **장점:** 실제 작업 자동화, 결정론 도구로 환각 보완, 확장성(도구 추가).
|
||||
- **단점:** 보안 위험(임의 명령), 파싱 실패, 잘못된 인자, 무한 호출.
|
||||
- **대안:** 사람이 실행, 고정 워크플로(모델 미개입), 제한된 화이트리스트 액션.
|
||||
- **실패 사례:** 모델 출력을 검증 없이 실행(주입 공격); 경로 미검증으로 임의 파일 접근; 승인 없는 파괴적 명령.
|
||||
|
||||
## 💻 코드 패턴 (Code patterns)
|
||||
```text
|
||||
output = LLM(system + tools_schema + task)
|
||||
for call in parseToolCalls(output): # <create_file>, <run_command> ...
|
||||
if !validate(call): skip/log
|
||||
if dangerous(call): await approval() # 승인 게이트
|
||||
result = execute(call) # 실행기로 라우팅
|
||||
feed(result -> next turn)
|
||||
```
|
||||
적용 예: AstraAI 의 action tag 실행기(src/agent/actions/*) + 승인 큐(approval) + 경로 검증(security.validatePath). 라우팅은 [[Agent 오케스트레이터 분해]] 참조.
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
"모델이 시키는 대로 실행" 은 위험 — 모델 출력은 *신뢰되지 않은 입력* 으로 다뤄 검증·샌드박스·승인을 거쳐야 한다.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
AstraAI action tags + approval gate + validatePath/sanitizeCommand.
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[패턴 카탈로그 인덱스]]
|
||||
- **관련 개념:** [[Agent Orchestration Pattern]], [[API Client Pattern]], [[Command Pattern]], [[소프트웨어 실패 라이브러리]]
|
||||
- **참조 맥락:** 작은 모델이 행동하는 에이전트를 만들 때 안전 경계와 함께 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] 일반 function/tool calling 지식
|
||||
- [S2] AstraAI/src/agent/actions/*, security.ts — 적용 예
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
---
|
||||
id: pattern-architecture-separation
|
||||
title: "Architecture Separation Pattern"
|
||||
category: "Pattern_CrossCutting"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["layering", "아키텍처 분리", "관심사 분리", "separation of concerns", "layered architecture", "ports and adapters"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.88
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["pattern", "cross-cutting", "architecture", "layering", "platform-independent"]
|
||||
raw_sources: ["일반 소프트웨어 공학 지식", "AstraAI/src 구조 (적용 예)"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[Architecture Separation Pattern]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
아키텍처 분리는 "**관심사를 계층/모듈로 나누고, 의존은 한 방향(안정적인 쪽으로)으로만 흐르게**" 하는 것으로, 플랫폼이 달라도 UI/도메인/인프라를 섞지 않는 것이 유지보수의 토대다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
1. **계층:** 인프라(core) → 역량(lib/도메인 서비스) → 기능(features) → 조립(entry). 위가 아래에 의존.
|
||||
2. **관심사 분리:** UI / 도메인 로직 / I/O 를 섞지 않는다.
|
||||
3. **의존성 역전:** 도메인이 인프라 *인터페이스* 에 의존, 구현은 주입.
|
||||
4. **경계(ports & adapters):** 외부(DB/API/UI)는 어댑터로, 핵심은 순수.
|
||||
5. **단일 책임:** 한 모듈은 한 가지 변경 이유.
|
||||
|
||||
## 📖 세부 내용 (Details · 패턴 명세)
|
||||
- **Problem (언제 쓰나):** 코드가 커지며 UI/로직/I/O 가 엉켜 변경이 두려울 때.
|
||||
- **사용 조건:** 책임 경계를 식별 가능; 인터페이스로 추상화 가능.
|
||||
- **장점:** 변경 격리, 테스트성(핵심 순수), 교체 용이(어댑터), 병렬 작업.
|
||||
- **단점:** 초기 보일러플레이트, 과한 계층은 오버헤드("얇은 래퍼 지옥").
|
||||
- **대안:** 모놀리식 단순 구조(소규모), 수직 슬라이스(기능별 풀스택), 모듈러 모놀리스.
|
||||
- **실패 사례:** UI 에 비즈니스 로직 혼입; 도메인이 DB/프레임워크에 직접 의존(교체 불가); 순환 의존; 계층 우회(아래가 위 호출).
|
||||
|
||||
## 💻 코드 패턴 (Code patterns)
|
||||
```text
|
||||
features/ -> lib/도메인서비스 -> core/인프라 # 단방향 의존
|
||||
domain depends on interface (IRepo, IAIService) # 의존성 역전
|
||||
adapter implements interface (FileRepo, AIService)
|
||||
entrypoint wires them (composition root) # 조립은 한 곳
|
||||
```
|
||||
적용 예: AstraAI 계층(core/lib/memory/retrieval/intelligence/features) + 인터페이스 서비스([[AstraAI 아키텍처 개요]], [[의존성 주입과 서비스 인터페이스]], [[모듈 시스템과 프로젝트 구성]]).
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
계층이 많을수록 격리는 좋아지나 단순 변경도 여러 파일을 거친다 — 규모에 맞춰라. 흐름 가독성을 위해 *골격은 한 곳에* 남기는 절충도 유효([[ADR-0010 오케스트레이터 골격 모듈추출]]).
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
AstraAI 전체 폴더 계층 + DI.
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[패턴 카탈로그 인덱스]]
|
||||
- **관련 개념:** [[Repository Pattern]], [[Plugin Architecture Pattern]], [[Data Flow Pattern]], [[프로젝트 독립 설계 원칙]]
|
||||
- **참조 맥락:** 작은 모델이 새 프로젝트의 폴더/계층 구조를 잡을 때 1차 원리.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] 일반 계층화/관심사 분리 지식(Clean/Hexagonal)
|
||||
- [S2] AstraAI/src 구조 — 적용 예
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
|
||||
@@ -0,0 +1,69 @@
|
||||
---
|
||||
id: pattern-async-concurrency
|
||||
title: "Async Concurrency Pattern"
|
||||
category: "Pattern_CrossCutting"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["async pattern", "비동기 패턴", "concurrency", "cancellation", "debounce", "throttle"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.89
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["pattern", "cross-cutting", "async", "concurrency", "platform-independent"]
|
||||
raw_sources: ["일반 소프트웨어 공학 지식", "AstraAI/src/core/* (적용 예)"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[Async Concurrency Pattern]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
비동기 처리는 모든 플랫폼이 공유하는 핵심이며, 안전의 3축은 "**취소 가능(cancellation) · 자원 폭주 방지(제한) · 경쟁 상태 제어(직렬화)**" 다 — UI 멈춤·메모리 폭주·갱신 손실이 여기서 갈린다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
1. **취소:** AbortSignal/토큰으로 진행 중 작업 중단(타임아웃+사용자 취소 결합).
|
||||
2. **동시성 제한:** 큐/세마포어로 동시 실행 수 상한.
|
||||
3. **직렬화:** 공유 자원은 락/뮤텍스로 한 번에 하나.
|
||||
4. **debounce/throttle:** 빈번 이벤트(입력/스크롤)를 솎아냄.
|
||||
5. **병렬 vs 순차:** 독립이면 병렬(all), 의존이면 순차, 부분실패 허용이면 allSettled.
|
||||
|
||||
## 📖 세부 내용 (Details · 패턴 명세)
|
||||
- **Problem (언제 쓰나):** I/O·네트워크·장시간 작업이 UI/자원에 영향 줄 때.
|
||||
- **사용 조건:** 취소 신호 전파 가능; 작업 단위 분리 가능.
|
||||
- **장점:** 반응성 유지, 자원 안정, 데이터 일관.
|
||||
- **단점:** 복잡도↑, 콜백/Promise 추론 어려움, 취소 누락 시 좀비 작업.
|
||||
- **대안:** 동기(작은 작업), 워커/스레드(CPU 바운드), 큐 시스템(분산).
|
||||
- **실패 사례:** 취소 미전파로 좀비 fetch; Promise.all 부분 실패로 전체 손실; 무한 병렬 OOM; 락 미해제 데드락; forEach+async 로 미대기.
|
||||
|
||||
## 💻 코드 패턴 (Code patterns)
|
||||
```text
|
||||
signal = combine(userAbort, timeout(ms)) # 취소 = 사용자 OR 타임아웃
|
||||
await fetch(url, { signal })
|
||||
await queue.enqueue(task) # 동시성 상한
|
||||
release = await lock.acquire(id); try{...} finally{ release() } # 직렬화
|
||||
onInput = debounce(handler, 200) # 이벤트 솎기
|
||||
results = await Promise.allSettled(tasks) # 부분 실패 허용
|
||||
```
|
||||
적용 예: [[비동기 프로그래밍 Promise async await]], [[동시성 제어 Lock Queue Transaction]], [[AITRAIN 동시성 제어]].
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
"병렬이 빠르다" 는 자원 한도 내에서만 참 — 한도를 넘으면 스왑/OOM 으로 더 느려진다([[ADR-0004 순차 디스패치 채택]]).
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
AstraAI services(AbortSignal), lock/queue.
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[패턴 카탈로그 인덱스]]
|
||||
- **관련 개념:** [[Background Worker Pattern]], [[Background Task Pattern]], [[Error Handling Pattern]]
|
||||
- **참조 맥락:** 작은 모델이 어떤 플랫폼이든 비동기 코드를 쓸 때 1차 원리.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] 일반 비동기/동시성 지식
|
||||
- [S2] AstraAI/src/core/services.ts, lock.ts, queue.ts — 적용 예
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
|
||||
@@ -0,0 +1,69 @@
|
||||
---
|
||||
id: pattern-caching
|
||||
title: "Caching Pattern"
|
||||
category: "Pattern_CrossCutting"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["caching", "캐싱", "memoization", "TTL", "invalidation", "mtime cache"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.88
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["pattern", "cross-cutting", "caching", "performance", "platform-independent"]
|
||||
raw_sources: ["일반 소프트웨어 공학 지식", "AstraAI/src/retrieval/scoring.ts, src/lib/mtimeFileCache.ts (적용 예)"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[Caching Pattern]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
캐싱은 "비싼 계산/조회 결과를 저장해 재사용" 하는 보편 최적화이며, 어려운 것은 캐싱 자체가 아니라 "**언제 무효화(invalidation)하느냐**" 다 — stale 데이터는 성능보다 더 큰 버그를 만든다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
1. **memoization:** 같은 입력→같은 출력을 키로 저장.
|
||||
2. **무효화 전략:** TTL(시간), 버전/해시, 변경 감지(mtime), 수동.
|
||||
3. **캐시 키 설계:** 입력을 정확히 식별(누락 시 잘못된 hit).
|
||||
4. **용량 제한:** LRU/상한으로 무한 증가 방지.
|
||||
5. **계층:** 메모리→디스크→원격, 가까울수록 빠름.
|
||||
|
||||
## 📖 세부 내용 (Details · 패턴 명세)
|
||||
- **Problem (언제 쓰나):** 동일 계산/조회가 반복되고 비용이 클 때, 결과가 자주 안 바뀔 때.
|
||||
- **사용 조건:** 결정적 입력→출력; 무효화 신호 존재; 메모리/디스크 여유.
|
||||
- **장점:** 지연·비용 대폭↓, 부하 완화.
|
||||
- **단점:** stale 위험, 메모리 사용, 무효화 복잡, 캐시 키 버그.
|
||||
- **대안:** 매번 계산(정확성 우선), 사전 계산(배치), 증분 갱신.
|
||||
- **실패 사례:** 무효화 누락으로 옛 데이터 제공; 키 충돌로 잘못된 hit; 무한 증가 OOM; 변경 감지 누락(mtime 미갱신).
|
||||
|
||||
## 💻 코드 패턴 (Code patterns)
|
||||
```text
|
||||
# memoization + 용량 제한
|
||||
if cache.has(key): return cache.get(key)
|
||||
val = expensive(input); if cache.size >= LIMIT: cache.clear(); cache.set(key, val)
|
||||
|
||||
# 변경 감지 무효화 (파일)
|
||||
if file.mtime != cached.mtime: cached = reindex(file) # 변경된 파일만 재계산
|
||||
```
|
||||
적용 예: AstraAI 의 TOKEN_CACHE(토크나이저 memoization, 상한 시 clear) + mtime 키 brain 인덱스(변경 없는 파일 재토큰화 회피) [S2]. RAG 의 dense/sparse 인덱스도 캐시.
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
"캐시하면 빠르다" 의 이면은 "무효화를 틀리면 조용히 틀린 답" — Phil Karlton 의 "캐시 무효화는 컴퓨터 과학의 2대 난제". 변경 감지(mtime/해시)가 TTL 보다 정확할 때가 많다.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
AstraAI 토큰 캐시 + mtime 인덱스([[TF-IDF 이중언어 스코어링]], [[RAG 검색 파이프라인]]).
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[패턴 카탈로그 인덱스]]
|
||||
- **관련 개념:** [[Local Storage Pattern]], [[API Client Pattern]], [[RAG Pattern]], [[소프트웨어 실패 라이브러리]]
|
||||
- **참조 맥락:** 작은 모델이 성능 최적화를 할 때 무효화 전략과 함께 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] 일반 캐싱 공학 지식
|
||||
- [S2] AstraAI/src/retrieval/scoring.ts(TOKEN_CACHE), brainIndex/mtimeFileCache — 적용 예
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
|
||||
@@ -0,0 +1,66 @@
|
||||
---
|
||||
id: pattern-data-flow
|
||||
title: "Data Flow Pattern"
|
||||
category: "Pattern_CrossCutting"
|
||||
status: "draft"
|
||||
verification_status: "conceptual"
|
||||
canonical_id: ""
|
||||
aliases: ["data flow", "데이터 흐름", "pipeline", "transform", "boundary normalization"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.86
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["pattern", "cross-cutting", "data-flow", "pipeline", "platform-independent"]
|
||||
raw_sources: ["일반 소프트웨어 공학 지식", "AstraAI/src/retrieval/*, src/features/providers/* (적용 예)"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[Data Flow Pattern]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
데이터 흐름 설계의 핵심은 "**경계에서 정규화하고(입력 검증·형식 통일), 내부는 단일 형태로 다루며, 변환을 작은 순수 단계의 파이프라인으로**" 만드는 것이다 — 그러면 어디서 무엇이 변하는지 추적된다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
1. **경계 정규화:** 외부 입력(API/파일/사용자)을 들어오자마자 내부 표준 형태로 변환·검증.
|
||||
2. **단일 내부 모델:** 내부는 하나의 형태만 — 분기/특수처리를 가장자리로.
|
||||
3. **파이프라인:** 변환을 작은 순수 단계로 연결(test 가능).
|
||||
4. **출력 정규화:** 다양한 백엔드를 같은 출력 형식으로(예: SSE).
|
||||
5. **불변 전달:** 단계 간 데이터를 변형 대신 새 값 생성.
|
||||
|
||||
## 📖 세부 내용 (Details · 패턴 명세)
|
||||
- **Problem (언제 쓰나):** 이질적 소스/싱크가 많고 변환 단계가 여러 개일 때.
|
||||
- **사용 조건:** 표준 내부 모델 정의 가능; 단계 분해 가능.
|
||||
- **장점:** 추적성, 테스트성(순수 단계), 소스/싱크 추가 용이, 버그 격리.
|
||||
- **단점:** 변환 레이어 비용, 과한 추상화는 오버헤드.
|
||||
- **대안:** 직접 결합(소규모), 스트림 처리(대용량), 이벤트 버스(느슨 결합).
|
||||
- **실패 사례:** 경계 검증 누락으로 내부에 오염 전파; 내부에 외부 형식 누수(공급자별 분기 산재); 가변 전달로 단계 간 부작용.
|
||||
|
||||
## 💻 코드 패턴 (Code patterns)
|
||||
```text
|
||||
internal = normalizeAtBoundary(externalInput) # 들어올 때 1회 정규화 + 검증
|
||||
result = stage3(stage2(stage1(internal))) # 작은 순수 단계 파이프라인
|
||||
output = toStandardFormat(result) # 나갈 때 형식 통일 (예: SSE)
|
||||
```
|
||||
적용 예: [[LLM 프로바이더 추상화]](공급자별 입력 정규화→공통 SSE 출력), [[RAG 검색 파이프라인]](tokenize→score→fuse→budget).
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
경계 정규화는 비용이지만, 생략하면 특수처리가 코드 전체로 번진다 — "차이는 가장자리에서 흡수" 원칙([[AITRAIN 프로바이더 추상화]]).
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
AstraAI provider 어댑터, retrieval 파이프라인.
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[패턴 카탈로그 인덱스]]
|
||||
- **관련 개념:** [[State Management Pattern]], [[Repository Pattern]], [[API Client Pattern]], [[Architecture Separation Pattern]]
|
||||
- **참조 맥락:** 작은 모델이 입출력 변환이 많은 코드를 설계할 때 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] 일반 데이터 흐름/파이프라인 지식
|
||||
- [S2] AstraAI/src/retrieval/*, features/providers/* — 적용 예
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
|
||||
@@ -0,0 +1,68 @@
|
||||
---
|
||||
id: pattern-error-handling
|
||||
title: "Error Handling Pattern"
|
||||
category: "Pattern_CrossCutting"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["error handling", "오류 처리 패턴", "graceful degradation", "result type", "retry", "fallback"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.89
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["pattern", "cross-cutting", "error-handling", "resilience", "platform-independent"]
|
||||
raw_sources: ["일반 소프트웨어 공학 지식", "AstraAI/src/core/* (적용 예)"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[Error Handling Pattern]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
견고한 오류 처리는 "**실패를 분류하고(복구 가능/불가), 흔한 실패는 결과값으로·예외는 진짜 예외에, 부가 작업 실패는 본류를 막지 않게, 사용자에겐 행동 지침으로 번역**" 하는 것이다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
1. **분류:** 복구 가능(재시도/폴백) vs 불가(즉시 실패) vs 부가(무시).
|
||||
2. **결과 타입 vs 예외:** 흔한 실패는 `{ok,error}` 유니온, 계약 위반은 throw.
|
||||
3. **재시도/폴백:** 일시 오류는 backoff 재시도, 대안 경로 폴백.
|
||||
4. **graceful degradation:** 핵심은 살리고 부가만 끈다(이유 주석 필수).
|
||||
5. **사용자 번역:** 기술 에러→무엇을 하면 되는지.
|
||||
|
||||
## 📖 세부 내용 (Details · 패턴 명세)
|
||||
- **Problem (언제 쓰나):** I/O·네트워크·외부 의존이 있는 모든 코드.
|
||||
- **사용 조건:** 실패 유형을 구분 가능; 복구/대안 전략 존재.
|
||||
- **장점:** 복원력, 디버깅 용이, UX 개선, 부분 장애 격리.
|
||||
- **단점:** 코드량↑, 잘못된 삼킴은 버그 은폐.
|
||||
- **대안:** 크래시-온리(빠른 실패+재시작), 서킷 브레이커(연속 실패 차단).
|
||||
- **실패 사례:** 무음 빈 catch 로 실패 은폐; `||` 로 0/'' 삼킴; 무한 재시도; 사용자에게 raw 스택 노출; 부가 실패가 본류 중단.
|
||||
|
||||
## 💻 코드 패턴 (Code patterns)
|
||||
```text
|
||||
result = op() -> { ok:true, val } | { ok:false, error } # 흔한 실패는 유니온
|
||||
for engine in engines: try { return call(engine) } catch { last=e } # 폴백
|
||||
try { sideEffect() } catch { /* 부가 — 본류 안 막음(이유 주석) */ }
|
||||
showUser(translate(error)) # 행동 지침으로 번역
|
||||
catch (e) { err = e instanceof Error ? e : new Error(String(e)) } # 정규화
|
||||
```
|
||||
적용 예: [[에러 처리와 커스텀 에러]](G1Error 계층, ErrorTranslator, 보상 트랜잭션), [[LLM 프로바이더 추상화]](엔진 폴백).
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
"모든 에러를 잡아라" 와 "빠르게 실패하라" 의 균형 — 복구 불가·계약 위반은 던지고, 일시·부가만 흡수. 빈 catch 는 *부가 작업 + 이유 주석* 일 때만.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
AstraAI errors/errorHandler/transaction/services.
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[패턴 카탈로그 인덱스]]
|
||||
- **관련 개념:** [[Async Concurrency Pattern]], [[API Client Pattern]], [[소프트웨어 실패 라이브러리]], [[안티패턴 카탈로그]]
|
||||
- **참조 맥락:** 작은 모델이 어떤 플랫폼이든 실패 경로를 작성할 때 1차 원리.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] 일반 오류 처리/복원력 지식
|
||||
- [S2] AstraAI/src/core/errors.ts, errorHandler.ts, transaction.ts, services.ts — 적용 예
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
|
||||
@@ -0,0 +1,67 @@
|
||||
---
|
||||
id: pattern-state-management
|
||||
title: "State Management Pattern"
|
||||
category: "Pattern_CrossCutting"
|
||||
status: "draft"
|
||||
verification_status: "conceptual"
|
||||
canonical_id: ""
|
||||
aliases: ["state management", "상태 관리", "single source of truth", "unidirectional data flow"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.88
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["pattern", "cross-cutting", "state", "platform-independent"]
|
||||
raw_sources: ["일반 소프트웨어 공학 지식", "AstraAI/src/sidebar/managers/* (적용 예)"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[State Management Pattern]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
상태 관리의 본질은 플랫폼(웹/모바일/데스크탑)을 막론하고 "**단일 진실 원천(Single Source of Truth) + 단방향 데이터 흐름 + 명시적 변경**" 으로, 상태가 흩어지고 양방향으로 얽힐수록 버그가 기하급수로 는다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
1. **Single Source of Truth:** 같은 데이터를 한 곳에만 둔다(중복 상태 = 동기화 버그).
|
||||
2. **단방향 흐름:** 상태→뷰 렌더, 이벤트→상태 변경(역류 금지).
|
||||
3. **파생 상태 vs 원천 상태:** 계산 가능한 건 저장하지 말고 derive.
|
||||
4. **로컬 vs 전역:** 한 컴포넌트만 쓰면 로컬, 여러 곳이 공유하면 전역(끌어올림).
|
||||
5. **불변 업데이트:** 상태를 *교체* 로 갱신해 변경 추적/되돌리기 용이.
|
||||
|
||||
## 📖 세부 내용 (Details · 패턴 명세)
|
||||
- **Problem (언제 쓰나):** UI/세션/도메인 상태가 여러 곳에서 읽고 쓰일 때.
|
||||
- **사용 조건:** 상태 소유자를 정할 수 있을 때; 변경 경로를 한정할 수 있을 때.
|
||||
- **장점:** 예측 가능, 디버깅 용이(변경 추적), 동기화 버그↓, 테스트 용이.
|
||||
- **단점:** 보일러플레이트, 과한 전역화는 결합↑, 작은 앱엔 과설계.
|
||||
- **대안:** 로컬 상태만(소규모), 서버 상태를 진실로(react-query류), 이벤트 소싱(이력 필요 시).
|
||||
- **실패 사례:** 같은 데이터를 두 곳에 저장→불일치; 파생값을 저장→stale; 컴포넌트가 부모 상태 직접 변경(역류); 전역 store 에 모든 걸 넣어 결합 폭증.
|
||||
|
||||
## 💻 코드 패턴 (Code patterns)
|
||||
```text
|
||||
state = SingleStore(initial)
|
||||
view = render(state) # 상태 → 뷰
|
||||
onEvent(e): state = reducer(state, e) # 이벤트 → 새 상태(불변 교체) → 재렌더
|
||||
derived = useMemo(() => compute(state))# 파생은 저장 말고 계산
|
||||
```
|
||||
적용 예: AstraAI 의 sessionStateStore/chatSessionStore 등 manager 가 상태 소유, webview 는 메시지로만 변경 요청([[VSCode 확장 구조와 생명주기]]).
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
전역 상태 라이브러리(Redux 등)가 항상 답은 아니다 — 서버 상태는 캐시 라이브러리에, UI 지역 상태는 로컬에, 진짜 공유 도메인 상태만 전역에.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
AstraAI sidebar managers(상태 소유 + 메시지 변경).
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[패턴 카탈로그 인덱스]]
|
||||
- **관련 개념:** [[Data Flow Pattern]], [[React State Pattern]], [[Caching Pattern]], [[프로젝트 독립 설계 원칙]]
|
||||
- **참조 맥락:** 작은 모델이 어떤 플랫폼이든 UI/앱 상태를 설계할 때 1차 원리.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] 일반 상태 관리 공학 지식
|
||||
- [S2] AstraAI/src/sidebar/managers/* — 적용 예
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
|
||||
@@ -0,0 +1,68 @@
|
||||
---
|
||||
id: pattern-background-worker
|
||||
title: "Background Worker Pattern"
|
||||
category: "Pattern_Desktop"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["background worker", "백그라운드 워커", "worker thread", "job queue", "concurrency limit"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.86
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["pattern", "desktop", "worker", "queue", "concurrency", "platform-independent"]
|
||||
raw_sources: ["일반 소프트웨어 공학 지식", "AstraAI/src/core/queue.ts (적용 예)"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[Background Worker Pattern]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
Background Worker 는 "무거운/장시간 작업을 메인(UI) 흐름 밖에서, *동시성 상한이 있는 큐* 로 처리" 해 UI 멈춤과 자원 폭주를 동시에 막는 패턴이다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
1. **작업 큐:** 작업을 enqueue, 워커가 꺼내 실행.
|
||||
2. **동시성 상한:** 동시에 N개만(CPU/메모리 보호).
|
||||
3. **UI 분리:** CPU 바운드는 워커 스레드, I/O 는 비동기.
|
||||
4. **결과 반환:** 작업별 Promise/콜백으로 결과 전달.
|
||||
5. **백프레셔:** 큐가 넘치면 거부/지연.
|
||||
|
||||
## 📖 세부 내용 (Details · 패턴 명세)
|
||||
- **언제 쓰나:** 대량/무거운 작업이 UI 반응성·자원을 위협할 때.
|
||||
- **사용 조건:** 작업 단위 분리; 동시성 정책; 결과 전달 경로.
|
||||
- **장점:** UI 반응성, 자원 안정(상한), 처리량 제어.
|
||||
- **단점:** 복잡도, 결과 동기화, 스레드 통신 비용(CPU 바운드 시).
|
||||
- **대안:** 동기 처리(소규모), 외부 잡 시스템(분산), OS 스케줄러.
|
||||
- **실패 사례:** 무한 병렬 OOM; 큐 무한 증가(백프레셔 없음); 워커 예외 미처리로 멈춤; UI 스레드에서 무거운 작업.
|
||||
|
||||
## 💻 코드 패턴 (Code patterns)
|
||||
```text
|
||||
class Queue {
|
||||
enqueue(task): Promise = new Promise((res,rej)=>{ this.q.push(()=>task().then(res,rej)); this.next() })
|
||||
next(): if (active < limit && q.length) { active++; run(q.shift()).finally(()=>{active--; next()}) }
|
||||
}
|
||||
limit = max(2, cpus-1) # UI 코어 여유
|
||||
```
|
||||
적용 예: AstraAI 의 ActionQueueManager(동시성 `max(2,cpus-1)`, micro-delay 로 숨통) [S2]. 무거운 LLM 작업은 큐 대신 missionId 락으로 직렬화([[동시성 제어 Lock Queue Transaction]]).
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
동시성은 처리량을 올리지만 자원을 넘으면 역효과 — 상한은 *하드웨어 기준*([[ADR-0004 순차 디스패치 채택]]). 메모리 큰 작업(모델)은 병렬보다 순차가 안전.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
AstraAI actionQueue + 워처.
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[패턴 카탈로그 인덱스]]
|
||||
- **관련 개념:** [[Async Concurrency Pattern]], [[Background Task Pattern]], [[AITRAIN 동시성 제어]], [[데스크탑 앱 개발 가이드]]
|
||||
- **참조 맥락:** 작은 모델이 무거운 작업을 백그라운드로 뺄 때 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] 일반 워커/잡 큐 지식
|
||||
- [S2] AstraAI/src/core/queue.ts — ActionQueueManager
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
|
||||
@@ -0,0 +1,67 @@
|
||||
---
|
||||
id: pattern-command
|
||||
title: "Command Pattern"
|
||||
category: "Pattern_Desktop"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["command pattern", "커맨드 패턴", "command registry", "undo redo", "action"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.86
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["pattern", "desktop", "command", "behavioral", "platform-independent"]
|
||||
raw_sources: ["일반 소프트웨어 공학 지식", "AstraAI/src/extension.ts(registerCommand), src/agent/actions/* (적용 예)"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[Command Pattern]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
Command 패턴은 "요청(동작)을 객체/등록 항목으로 캡슐화" 해 실행을 호출자와 분리하고, 등록·취소(undo)·큐잉·로깅·단축키 매핑을 일관되게 만든다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
1. **명령 캡슐화:** 동작을 id+핸들러로 등록.
|
||||
2. **레지스트리:** id→핸들러 매핑(중앙 디스패치).
|
||||
3. **undo/redo:** 명령에 역연산 정의(선택).
|
||||
4. **메타데이터:** 단축키·메뉴·가시성 조건.
|
||||
5. **분리:** UI(버튼/메뉴)는 명령 id 만 알면 됨.
|
||||
|
||||
## 📖 세부 내용 (Details · 패턴 명세)
|
||||
- **언제 쓰나:** 여러 진입점(메뉴/단축키/팔레트)이 같은 동작을 부를 때, undo/매크로/큐가 필요할 때.
|
||||
- **사용 조건:** 동작을 id 로 표현; 핸들러 등록 메커니즘.
|
||||
- **장점:** 호출자-실행자 분리, 재사용, undo/큐/로깅 일관, 확장 용이.
|
||||
- **단점:** 명령 폭증, 단순 동작엔 과설계, 상태 전달 설계 필요.
|
||||
- **대안:** 직접 함수 호출(소규모), 이벤트(반응형).
|
||||
- **실패 사례:** 명령에 무거운 상태 결합; undo 불완전(부분 복원); id 충돌; 등록 해제 누락.
|
||||
|
||||
## 💻 코드 패턴 (Code patterns)
|
||||
```text
|
||||
registry.register('app.save', () => save()) # 명령 = id + 핸들러
|
||||
ui.button(onClick = () => exec('app.save')) # UI 는 id 만
|
||||
shortcut('Ctrl+S' -> 'app.save') # 매핑 일관
|
||||
# undo 지원 시: command = { do(), undo() }; history.push(command)
|
||||
```
|
||||
적용 예: AstraAI 의 `vscode.commands.registerCommand('g1nation.openChat', ...)` (명령 레지스트리)와 action tag 실행기(`<create_file>` 등을 명령처럼 라우팅) [S2]. → [[Tool Calling Pattern]].
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
진입점이 하나면 함수 호출이 단순 — 다중 진입점/undo/큐가 필요할 때 Command 가 값을 한다.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
AstraAI VS Code 명령 등록 + action 실행기.
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[패턴 카탈로그 인덱스]]
|
||||
- **관련 개념:** [[Event Bus Pattern]], [[Tool Calling Pattern]], [[Plugin Architecture Pattern]], [[데스크탑 앱 개발 가이드]]
|
||||
- **참조 맥락:** 작은 모델이 다중 진입점/undo 동작을 설계할 때 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] 일반 Command 패턴(GoF) 지식
|
||||
- [S2] AstraAI/src/extension.ts(registerCommand), agent/actions/* — 적용 예
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
|
||||
@@ -0,0 +1,67 @@
|
||||
---
|
||||
id: pattern-event-bus
|
||||
title: "Event Bus Pattern"
|
||||
category: "Pattern_Desktop"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["event bus", "이벤트 버스", "observer", "pub-sub", "EventEmitter", "발행 구독"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.88
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["pattern", "desktop", "event-bus", "pub-sub", "decoupling", "platform-independent"]
|
||||
raw_sources: ["일반 소프트웨어 공학 지식", "AstraAI/src/core/events.ts (적용 예)"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[Event Bus Pattern]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
Event Bus(발행-구독)는 "발신자와 수신자가 서로를 모른 채 이벤트로 소통" 해 모듈 결합을 낮추는 패턴 — 단, 흐름이 *암묵적* 이 되어 추적이 어려워지므로 이벤트 종류와 계약을 명시해야 한다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
1. **발행/구독:** emit(event) / on(event, handler).
|
||||
2. **느슨한 결합:** 발신자는 누가 듣는지 모름.
|
||||
3. **이벤트 타입 명시:** enum/상수로 이벤트 카탈로그.
|
||||
4. **리스너 수명:** 등록 해제(누수 방지), 최대 리스너 한도.
|
||||
5. **동기 vs 비동기:** 핸들러 예외가 발신자에 새지 않게.
|
||||
|
||||
## 📖 세부 내용 (Details · 패턴 명세)
|
||||
- **언제 쓰나:** 한 사건에 여러 관심사가 반응(로깅·UI·기록), 모듈을 직접 의존시키고 싶지 않을 때.
|
||||
- **사용 조건:** 이벤트 카탈로그 정의; 리스너 수명 관리.
|
||||
- **장점:** 결합도↓, 확장 용이(구독 추가), 관심사 분리.
|
||||
- **단점:** 흐름 암묵적(추적 난해), 디버깅 어려움, 이벤트 폭발, 순서 보장 약함.
|
||||
- **대안:** 직접 호출(흐름 명확, 결합↑), 콜백 주입, 상태 구독(reactive).
|
||||
- **실패 사례:** 리스너 해제 누락→누수·중복 실행; 이벤트 이름 오타(문자열); 핸들러 예외가 발신자 중단; "누가 이 이벤트를 듣나" 추적 불가; 이벤트 순환.
|
||||
|
||||
## 💻 코드 패턴 (Code patterns)
|
||||
```text
|
||||
enum E { TASK_STARTED='task:started', ERROR='error:occurred' } # 카탈로그
|
||||
bus.emit(E.TASK_STARTED, payload) # 발신자: 누가 듣는지 모름
|
||||
bus.on(E.TASK_STARTED, h); // ... bus.off(E.TASK_STARTED, h) # 해제로 누수 방지
|
||||
bus.setMaxListeners(20) # 폭발 방지
|
||||
```
|
||||
적용 예: AstraAI 의 `agentEvents`(싱글톤 EventEmitter)와 `AgentEventTypes` enum — 트랜잭션 commit/rollback, task 시작/완료 등을 발행해 모듈 결합을 낮춤 [S2].
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
이벤트 버스는 결합을 낮추지만 *흐름을 숨긴다* — 핵심 제어 흐름은 명시 호출이 낫고, 부가/횡단 반응(로깅·기록)에 이벤트가 적합.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
AstraAI agentEvents(Observer 허브).
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[패턴 카탈로그 인덱스]]
|
||||
- **관련 개념:** [[Command Pattern]], [[IPC Pattern]], [[Architecture Separation Pattern]], [[데스크탑 앱 개발 가이드]]
|
||||
- **참조 맥락:** 작은 모델이 모듈 간 느슨한 통신을 설계할 때 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] 일반 pub-sub/observer 지식
|
||||
- [S2] AstraAI/src/core/events.ts — agentEvents/AgentEventTypes
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
|
||||
@@ -0,0 +1,69 @@
|
||||
---
|
||||
id: pattern-ipc
|
||||
title: "IPC Pattern"
|
||||
category: "Pattern_Desktop"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["IPC", "프로세스 간 통신", "inter-process communication", "message passing", "bridge"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.86
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["pattern", "desktop", "ipc", "messaging", "platform-independent"]
|
||||
raw_sources: ["일반 데스크탑 공학 지식", "AstraAI/src/bridge.ts, sidebarProvider.ts (적용 예)"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[IPC Pattern]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
IPC 는 "서로 다른 프로세스(메인↔렌더러, 앱↔외부 도구)가 메시지로 소통" 하는 패턴으로, *직렬화 가능한 메시지 계약 + 신뢰 경계 검증* 이 핵심 — 다른 프로세스의 입력은 신뢰되지 않은 입력이다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
1. **메시지 패싱:** 객체 직접 공유 불가 → 직렬화(JSON)해 전달.
|
||||
2. **채널/타입:** 메시지에 type 을 두고 핸들러로 라우팅.
|
||||
3. **요청-응답 vs 단방향:** 명령은 응답, 알림은 단방향.
|
||||
4. **신뢰 경계:** 상대 프로세스 입력을 검증(특히 외부 도구).
|
||||
5. **전송 매체:** Electron ipcMain/Renderer, 웹뷰 postMessage, 로컬 HTTP/소켓.
|
||||
|
||||
## 📖 세부 내용 (Details · 패턴 명세)
|
||||
- **언제 쓰나:** UI 프로세스↔백그라운드, 앱↔외부 프로그램 통신.
|
||||
- **사용 조건:** 직렬화 가능 메시지; 채널 정의; 보안 검증.
|
||||
- **장점:** 프로세스 격리(크래시 격리·보안), 언어/도구 무관 연동.
|
||||
- **단점:** 직렬화 비용, 객체 공유 불가, 비동기 복잡, 보안 표면.
|
||||
- **대안:** 단일 프로세스(스레드/공유 메모리), 파일 교환, 메시지 큐.
|
||||
- **실패 사례:** 외부 입력 미검증→임의 명령 실행; 함수/순환 객체 직렬화 실패; 채널 타입 오타; 응답 누락으로 행; 포트 충돌.
|
||||
|
||||
## 💻 코드 패턴 (Code patterns)
|
||||
```text
|
||||
# 웹뷰(렌더러) ↔ 확장(메인): postMessage 프로토콜
|
||||
webview.postMessage({ type:'streamChunk', value }) # 확장 → UI
|
||||
onMessage(msg): route(msg.type, validate(msg)) # UI → 확장
|
||||
|
||||
# 앱 ↔ 외부 도구: 로컬 HTTP 브리지
|
||||
http.createServer((req,res) => { body=validate(parse(req)); res.end(handle(body)) })
|
||||
```
|
||||
적용 예: AstraAI 의 BridgeServer(로컬 HTTP 포트 4825 로 외부 도구↔확장 연결, 서비스 레이어로 로직 분리) + 웹뷰 postMessage 프로토콜([[VSCode 확장 구조와 생명주기]], [[Agent 오케스트레이터 분해]]) [S2].
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
프로세스 분리는 격리·보안 이득이 있으나 직렬화·복잡도 비용 — 같은 신뢰 영역의 작은 작업이면 단일 프로세스가 단순. 외부 IPC 는 *항상* 입력 검증.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
AstraAI BridgeServer + 웹뷰 메시지.
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[패턴 카탈로그 인덱스]]
|
||||
- **관련 개념:** [[Event Bus Pattern]], [[Tool Calling Pattern]], [[API Client Pattern]], [[데스크탑 앱 개발 가이드]]
|
||||
- **참조 맥락:** 작은 모델이 데스크탑(Electron/확장) 프로세스 통신을 설계할 때 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] 일반 IPC 지식(Electron, message passing)
|
||||
- [S2] AstraAI/src/bridge.ts, sidebarProvider.ts — 적용 예
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
|
||||
@@ -0,0 +1,70 @@
|
||||
---
|
||||
id: pattern-plugin-architecture
|
||||
title: "Plugin Architecture Pattern"
|
||||
category: "Pattern_Desktop"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["plugin architecture", "플러그인 아키텍처", "extension point", "self-registration", "skill loader"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.85
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["pattern", "desktop", "plugin", "extensibility", "platform-independent"]
|
||||
raw_sources: ["일반 소프트웨어 공학 지식", "AstraAI/src/skills/externalSkillLoader.ts, src/features/*/handlers.ts (적용 예)"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[Plugin Architecture Pattern]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
플러그인 아키텍처는 "코어를 안정적으로 두고 기능을 *확장 지점(extension point)* 으로 끼워 넣게" 해 코어 수정 없이 능력을 늘리는 패턴 — 핵심은 *안정된 계약(인터페이스)* 과 *자기 등록* 이다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
1. **확장 지점:** 코어가 정의한 인터페이스/훅.
|
||||
2. **자기 등록:** 플러그인 로드 시 레지스트리에 자기를 등록(side-effect import).
|
||||
3. **발견(discovery):** 디렉터리/매니페스트 스캔으로 동적 로드.
|
||||
4. **격리/검증:** 플러그인 실패가 코어를 죽이지 않게.
|
||||
5. **버전 계약:** 코어 API 버전 호환.
|
||||
|
||||
## 📖 세부 내용 (Details · 패턴 명세)
|
||||
- **언제 쓰나:** 서드파티/도메인 기능을 코어 변경 없이 추가, 기능 on/off, 생태계 구축.
|
||||
- **사용 조건:** 안정된 확장 인터페이스; 로딩/등록 메커니즘; 격리.
|
||||
- **장점:** 확장성, 코어 안정, 병렬 개발, 선택적 기능.
|
||||
- **단점:** 인터페이스 설계 어려움, 버전 호환 부담, 플러그인 품질/보안 위험.
|
||||
- **대안:** 모놀리식(소규모), 설정 플래그, 마이크로서비스.
|
||||
- **실패 사례:** 플러그인 예외가 코어 크래시(격리 부재); 안정 안 된 API 로 잦은 호환 깨짐; 등록 순서 의존; 신뢰 안 된 플러그인 권한 과다.
|
||||
|
||||
## 💻 코드 패턴 (Code patterns)
|
||||
```text
|
||||
# 자기 등록 (side-effect import)
|
||||
import './features/system/handlers' # 로드되며 registry.register(...) 실행
|
||||
registry.register('cmd:foo', handler)
|
||||
|
||||
# 동적 발견
|
||||
for file in scan(pluginsDir): plugin = load(file); if validate(plugin): register(plugin)
|
||||
try { plugin.run() } catch { /* 격리 — 코어 보호 */ logError() }
|
||||
```
|
||||
적용 예: AstraAI 의 핸들러 자기등록(`import './features/.../handlers'` 가 slashRouter 에 등록)과 externalSkillLoader(외부 스킬 동적 로드) [S2]. → [[모듈 시스템과 프로젝트 구성]].
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
플러그인은 유연하나 *안정된 계약* 없이는 버전 지옥. 확장 지점을 최소·신중히 설계하고, 신뢰 안 된 플러그인은 샌드박스/권한 제한.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
AstraAI 핸들러 자기등록 + 스킬 로더.
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[패턴 카탈로그 인덱스]]
|
||||
- **관련 개념:** [[Command Pattern]], [[Event Bus Pattern]], [[Architecture Separation Pattern]], [[데스크탑 앱 개발 가이드]]
|
||||
- **참조 맥락:** 작은 모델이 확장 가능한 앱(에디터/IDE/툴)을 설계할 때 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] 일반 플러그인/확장 아키텍처 지식
|
||||
- [S2] AstraAI/src/skills/externalSkillLoader.ts, features/*/handlers.ts — 적용 예
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
|
||||
@@ -0,0 +1,68 @@
|
||||
---
|
||||
id: pattern-background-task
|
||||
title: "Background Task Pattern"
|
||||
category: "Pattern_Mobile"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["background task", "백그라운드 작업", "scheduled job", "watcher", "cron", "WorkManager"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.86
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["pattern", "mobile", "background", "scheduling", "platform-independent"]
|
||||
raw_sources: ["일반 모바일/클라이언트 공학 지식", "AstraAI/src/features/*/watcher, src/extension.ts (적용 예)"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[Background Task Pattern]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
백그라운드 작업은 "사용자 상호작용 밖에서 주기적/지연 작업을 실행" 하는 패턴으로, OS 제약(배터리/킬)과 *재진입·중복 실행 방지*를 고려하지 않으면 자원을 낭비하거나 데이터를 손상시킨다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
1. **스케줄링:** interval/cron/조건(충전 중·Wi-Fi) 트리거.
|
||||
2. **수명관리:** 등록한 작업은 dispose 가능해야(누수 방지).
|
||||
3. **재진입 방지:** 이전 실행이 안 끝났으면 skip/큐.
|
||||
4. **멱등성:** 중복 실행에도 안전.
|
||||
5. **OS 제약:** 모바일은 OS 가 백그라운드를 제한(WorkManager/BGTask).
|
||||
|
||||
## 📖 세부 내용 (Details · 패턴 명세)
|
||||
- **Problem (언제 쓰나):** 동기화/정리/알림/사전계산을 사용자 흐름 밖에서.
|
||||
- **사용 조건:** 스케줄러; 작업을 작게 분할; 취소/정리 가능.
|
||||
- **장점:** 응답성(무거운 일을 뒤로), 자동화, 유휴 활용.
|
||||
- **단점:** 디버깅 난해, OS 킬/제약, 중복/경쟁 위험.
|
||||
- **대안:** 포그라운드 처리, 서버측 작업(클라 부담↓), 푸시 트리거.
|
||||
- **실패 사례:** dispose 누락으로 타이머 누수; 재진입으로 중복 실행; 무거운 작업을 메인 스레드; OS 제약 무시로 실행 안 됨; 실패 무한 재시도.
|
||||
|
||||
## 💻 코드 패턴 (Code patterns)
|
||||
```text
|
||||
const handle = scheduleInterval(ms, async () => {
|
||||
if (running) return; running = true # 재진입 방지
|
||||
try { await doWork() /*멱등, 작게*/ } finally { running = false }
|
||||
})
|
||||
register(handle) # dispose 가능하게 등록 → 종료 시 정리
|
||||
```
|
||||
적용 예: AstraAI 의 stocksWatcher/dailyBriefing/growthCycle/sleepDigest 워처가 interval 로 돌고 disposable 을 `context.subscriptions` 에 등록해 종료 시 정리([[VSCode 확장 구조와 생명주기]]).
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
모바일에선 OS 가 백그라운드를 강하게 제한 — "정확한 시각 보장" 을 가정하면 깨진다. 중요 작업은 서버 푸시로 트리거하는 것이 안전.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
AstraAI 워처들(KST 스케줄, dispose 등록).
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[패턴 카탈로그 인덱스]]
|
||||
- **관련 개념:** [[Background Worker Pattern]], [[Async Concurrency Pattern]], [[Push Notification Pattern]], [[모바일 개발 가이드]]
|
||||
- **참조 맥락:** 작은 모델이 주기/지연 작업을 설계할 때 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] 일반 백그라운드 작업 지식(WorkManager/BGTaskScheduler)
|
||||
- [S2] AstraAI/src/features/*/watcher, extension.ts — 적용 예
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
|
||||
@@ -0,0 +1,68 @@
|
||||
---
|
||||
id: pattern-local-storage
|
||||
title: "Local Storage Pattern"
|
||||
category: "Pattern_Mobile"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["local storage", "로컬 저장 패턴", "key-value", "sqlite", "secure storage"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.86
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["pattern", "mobile", "storage", "persistence", "platform-independent"]
|
||||
raw_sources: ["일반 모바일/클라이언트 공학 지식", "AstraAI/src/core/services.ts, eventSourcedStore.ts (적용 예)"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[Local Storage Pattern]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
로컬 저장은 "데이터 성격에 맞는 매체를 고르는 것" 이 핵심 — 소량 설정은 key-value, 구조화 데이터는 SQLite, 민감정보는 보안 저장소, 대용량 파일은 파일시스템. 한 매체에 다 넣으면 성능·보안이 무너진다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
1. **key-value(prefs):** 작은 설정/플래그.
|
||||
2. **임베디드 DB(SQLite/Realm):** 구조화/쿼리 데이터.
|
||||
3. **보안 저장소(Keychain/Keystore):** 토큰/비밀.
|
||||
4. **파일시스템:** 이미지/대용량/캐시.
|
||||
5. **마이그레이션:** 스키마 버전 관리.
|
||||
|
||||
## 📖 세부 내용 (Details · 패턴 명세)
|
||||
- **Problem (언제 쓰나):** 앱이 디바이스에 데이터를 보존해야 할 때.
|
||||
- **사용 조건:** 데이터 성격 분류; 용량/보안 요구 파악.
|
||||
- **장점:** 오프라인, 빠른 접근, 네트워크 절약.
|
||||
- **단점:** 디바이스 한정, 백업/동기화 별도, 보안 책임.
|
||||
- **대안:** 서버 저장(동기화 필요), 캐시만(휘발).
|
||||
- **실패 사례:** 토큰을 평문 prefs 에(보안 사고); 대용량을 key-value 에(성능); 마이그레이션 없어 업데이트 시 크래시; 캐시와 영구 데이터 혼동.
|
||||
|
||||
## 💻 코드 패턴 (Code patterns)
|
||||
```text
|
||||
prefs.set('theme', v) # 소량 설정
|
||||
secureStore.set('token', t) # 민감정보 (Keychain/Keystore)
|
||||
db.exec('INSERT ...') # 구조화 데이터
|
||||
fs.write(path, blob) # 대용량
|
||||
onUpgrade(old, new): migrate(old→new) # 스키마 버전
|
||||
```
|
||||
적용 예: AstraAI 는 설정=VS Code config/secrets, 지식=Markdown 파일, 이벤트=JSONL — *데이터 성격별 매체 분리* 원칙을 그대로([[ADR-0005 파일 기반 저장 채택]]).
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
"전부 SQLite" 나 "전부 key-value" 는 안티패턴 — 성격별 분리가 원칙. 민감정보는 *반드시* 보안 저장소.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
AstraAI secrets(토큰) + 파일(지식) + JSONL(이벤트).
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[패턴 카탈로그 인덱스]]
|
||||
- **관련 개념:** [[Offline Sync Pattern]], [[Caching Pattern]], [[이벤트 소싱 스토어 패턴]], [[모바일 개발 가이드]]
|
||||
- **참조 맥락:** 작은 모델이 클라이언트 저장을 설계할 때 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] 일반 모바일 저장 지식
|
||||
- [S2] AstraAI/src/core/services.ts, extension.ts(secrets), eventSourcedStore.ts — 적용 예
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
id: pattern-navigation
|
||||
title: "Navigation Pattern"
|
||||
category: "Pattern_Mobile"
|
||||
status: "draft"
|
||||
verification_status: "conceptual"
|
||||
canonical_id: ""
|
||||
aliases: ["navigation", "내비게이션 패턴", "routing", "deep link", "navigation stack"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.83
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["pattern", "mobile", "navigation", "routing", "platform-independent"]
|
||||
raw_sources: ["일반 모바일/프런트엔드 공학 지식"]
|
||||
applied_in: []
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[Navigation Pattern]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
내비게이션은 "화면 간 이동과 스택/상태를 관리" 하는 패턴으로, *경로를 선언적·직렬화 가능*하게 두고 딥링크/뒤로가기/상태 복원을 1급으로 다뤄야 한다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
1. **선언적 라우트:** URL/route 로 화면을 표현(직렬화 가능).
|
||||
2. **스택/탭/드로어:** 내비 구조 유형.
|
||||
3. **딥링크:** 외부에서 특정 화면 직접 진입.
|
||||
4. **파라미터 전달:** 라우트 인자 + 타입 안전.
|
||||
5. **상태 복원:** 프로세스 죽어도 내비 상태 복구.
|
||||
|
||||
## 📖 세부 내용 (Details · 패턴 명세)
|
||||
- **Problem (언제 쓰나):** 다화면 앱의 이동/히스토리/딥링크 관리.
|
||||
- **사용 조건:** 라우트 정의; 화면 식별자; 인자 직렬화.
|
||||
- **장점:** 일관된 이동, 딥링크, 뒤로가기, 테스트성.
|
||||
- **단점:** 설정 복잡, 깊은 스택 메모리, 타입 안전 관리.
|
||||
- **대안:** 단일 화면(소규모), 조건부 렌더(상태 기반), 코디네이터 패턴.
|
||||
- **실패 사례:** 객체를 라우트 인자로 직접(직렬화 불가/딥링크 깨짐); 스택 누수(화면 안 떼어냄); 뒤로가기 상태 불일치; 딥링크 시 부모 스택 없어 길 잃음.
|
||||
|
||||
## 💻 코드 패턴 (Code patterns)
|
||||
```text
|
||||
routes = { '/home': Home, '/item/:id': ItemDetail } # 선언적 + 직렬화 가능 인자
|
||||
navigate('/item/42') # id 만 전달(객체 X)
|
||||
deepLink('myapp://item/42') -> rebuild stack [Home, ItemDetail]
|
||||
restore(savedNavState) # 프로세스 복원
|
||||
```
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
"상태로 화면 전환" vs "라우터" — 작은 앱은 상태 조건부가 단순하나, 딥링크/히스토리가 필요하면 선언적 라우터가 필수.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
일반 모바일/SPA. (AstraAI 는 패널 기반이라 직접 사례 없음 — 화면 식별/복원 원리는 동일.)
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[패턴 카탈로그 인덱스]]
|
||||
- **관련 개념:** [[State Management Pattern]], [[React State Pattern]], [[모바일 개발 가이드]]
|
||||
- **참조 맥락:** 작은 모델이 다화면 앱의 이동을 설계할 때 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] 일반 내비게이션/라우팅 지식
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
|
||||
@@ -0,0 +1,66 @@
|
||||
---
|
||||
id: pattern-offline-sync
|
||||
title: "Offline Sync Pattern"
|
||||
category: "Pattern_Mobile"
|
||||
status: "draft"
|
||||
verification_status: "conceptual"
|
||||
canonical_id: ""
|
||||
aliases: ["offline sync", "오프라인 동기화", "optimistic update", "conflict resolution", "outbox"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.85
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["pattern", "mobile", "offline", "sync", "platform-independent"]
|
||||
raw_sources: ["일반 모바일 공학 지식", "AstraAI/src/features/_shared/eventSourcedStore.ts (개념 유사)"]
|
||||
applied_in: []
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[Offline Sync Pattern]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
오프라인 동기화는 "네트워크 없이도 로컬에서 동작하고, 연결되면 변경을 *큐로 모아 동기화*하며 충돌을 해소" 하는 패턴으로, 핵심 난제는 동기화 자체가 아니라 **충돌 해소(conflict resolution)** 다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
1. **로컬 우선 저장:** 모든 쓰기를 먼저 로컬에.
|
||||
2. **outbox(변경 큐):** 미동기 변경을 append-only 로 쌓아 연결 시 전송.
|
||||
3. **낙관적 업데이트:** UI 는 즉시 반영, 실패 시 롤백.
|
||||
4. **충돌 해소:** last-write-wins / 버전 벡터 / 병합 / 사용자 선택.
|
||||
5. **멱등성:** 재전송에도 안전하도록 변경에 고유 id.
|
||||
|
||||
## 📖 세부 내용 (Details · 패턴 명세)
|
||||
- **Problem (언제 쓰나):** 불안정/없는 네트워크에서도 앱이 동작해야 할 때.
|
||||
- **사용 조건:** 로컬 저장소; 변경을 식별/순서화 가능; 서버 동기 API.
|
||||
- **장점:** 오프라인 사용성, 빠른 반응(낙관적), 복원력.
|
||||
- **단점:** 충돌 해소 복잡, 데이터 일관성 약화, 디버깅 난해.
|
||||
- **대안:** 온라인 전용(단순), CRDT(자동 병합, 복잡), 서버 권위(충돌 시 서버 우선).
|
||||
- **실패 사례:** 멱등 키 없어 중복 적용; LWW 로 사용자 데이터 유실; outbox 순서 꼬임; 낙관적 업데이트 롤백 누락으로 유령 데이터.
|
||||
|
||||
## 💻 코드 패턴 (Code patterns)
|
||||
```text
|
||||
write(op): localDB.apply(op); outbox.append({id:uuid, op, ts}) # 로컬 우선 + 큐
|
||||
onOnline: for op in outbox: try{ server.apply(op) /*멱등*/; outbox.remove(op) } catch{ retry }
|
||||
onPull: merge(serverChanges, local, resolve=versionVector|userChoice)
|
||||
```
|
||||
개념 유사: AstraAI 의 append-only 이벤트([[이벤트 소싱 스토어 패턴]])가 outbox 와 같은 구조 — 변경을 줄로 쌓고 재생/전송.
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
LWW 는 간단하지만 데이터 손실 위험 — 협업/중요 데이터엔 버전 벡터/CRDT 또는 사용자 충돌 해소가 안전.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
일반 모바일 앱(노트/메신저). AstraAI 는 단일 로컬이라 동기화는 불필요하나 outbox 구조는 동일.
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[패턴 카탈로그 인덱스]]
|
||||
- **관련 개념:** [[Local Storage Pattern]], [[Background Task Pattern]], [[이벤트 소싱 스토어 패턴]], [[모바일 개발 가이드]]
|
||||
- **참조 맥락:** 작은 모델이 오프라인 가능 앱을 설계할 때 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] 일반 오프라인 동기화 지식(outbox, CRDT)
|
||||
- [S2] AstraAI/src/features/_shared/eventSourcedStore.ts — 구조 유사
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
|
||||
@@ -0,0 +1,67 @@
|
||||
---
|
||||
id: pattern-push-notification
|
||||
title: "Push Notification Pattern"
|
||||
category: "Pattern_Mobile"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["push notification", "푸시 알림", "FCM", "APNs", "notification"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.84
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["pattern", "mobile", "push", "notification", "platform-independent"]
|
||||
raw_sources: ["일반 모바일 공학 지식", "AstraAI/src/integrations/telegram/*, src/features/briefing/* (유사 예)"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[Push Notification Pattern]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
푸시 알림은 "서버가 디바이스로 비동기 메시지를 밀어 넣는" 패턴으로, 토큰 수명 관리·전달 보장 없음·사용자 동의·과알림 피로를 다루지 못하면 오히려 이탈을 부른다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
1. **디바이스 토큰:** 앱이 FCM/APNs 토큰 등록, 서버 저장(만료/갱신).
|
||||
2. **전송:** 서버→게이트웨이(FCM/APNs)→디바이스.
|
||||
3. **전달 비보장:** best-effort — 중요 데이터는 알림 본문 말고 동기화로.
|
||||
4. **동의/채널:** 권한 요청, 카테고리별 on/off.
|
||||
5. **딥링크:** 탭 시 해당 화면으로.
|
||||
|
||||
## 📖 세부 내용 (Details · 패턴 명세)
|
||||
- **Problem (언제 쓰나):** 서버 이벤트를 사용자에게 즉시 알릴 때.
|
||||
- **사용 조건:** 게이트웨이 연동; 토큰 저장; 사용자 동의.
|
||||
- **장점:** 재참여, 실시간 알림, 백그라운드 트리거.
|
||||
- **단점:** 전달 비보장, 토큰 만료, 권한 거부 시 무력, 과알림 피로.
|
||||
- **대안:** 인앱 알림, 폴링(배터리↑), 이메일/SMS.
|
||||
- **실패 사례:** 만료 토큰으로 전송 실패; 알림 본문에만 중요 데이터(미수신 시 유실); 과알림으로 권한 철회; 딥링크 없어 탭 후 길 잃음.
|
||||
|
||||
## 💻 코드 패턴 (Code patterns)
|
||||
```text
|
||||
onAppStart: token = registerForPush(); server.saveToken(userId, token)
|
||||
server.onEvent: send(FCM/APNs, token, { title, body, data:{deeplink} }) # best-effort
|
||||
onReceive: showNotification ; onTap: navigate(data.deeplink)
|
||||
onTokenRefresh: server.updateToken(...)
|
||||
```
|
||||
유사 예: AstraAI 의 Telegram 리포트/daily briefing 이 "서버측 이벤트→사용자 채널 푸시" 구조([[Background Task Pattern]] 워처가 트리거). 전달 비보장 가정도 동일.
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
알림을 "전달된다" 고 가정하면 안 된다 — 중요 상태는 서버에 두고 알림은 *유도* 만. 과알림은 가장 흔한 이탈 원인.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
AstraAI Telegram 알림(리포트/브리핑).
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[패턴 카탈로그 인덱스]]
|
||||
- **관련 개념:** [[Background Task Pattern]], [[API Client Pattern]], [[모바일 개발 가이드]]
|
||||
- **참조 맥락:** 작은 모델이 알림 기능을 설계할 때 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] 일반 푸시(FCM/APNs) 지식
|
||||
- [S2] AstraAI/src/integrations/telegram/*, features/briefing/* — 유사 예
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
|
||||
@@ -0,0 +1,72 @@
|
||||
---
|
||||
id: pattern-api-client
|
||||
title: "API Client Pattern"
|
||||
category: "Pattern_Web"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["API client", "HTTP client", "API 클라이언트 패턴", "adapter", "SDK wrapper"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.88
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["pattern", "web", "api", "http", "platform-independent"]
|
||||
raw_sources: ["일반 소프트웨어 공학 지식", "AstraAI/src/features/providers/*, src/integrations/telegram/telegramClient.ts (적용 예)"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[API Client Pattern]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
API Client 패턴은 "외부 HTTP/SDK 호출을 한 모듈로 캡슐화" 해 인증·재시도·타임아웃·에러 정규화·취소를 한 곳에서 관리하고, 호출부는 깨끗한 메서드만 보게 한다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
1. **단일 클라이언트:** baseURL/헤더/인증을 한 곳에.
|
||||
2. **횡단 관심사:** 재시도·타임아웃·취소(AbortSignal)·로깅·에러 변환을 내장.
|
||||
3. **응답 정규화:** 다양한 응답을 내부 표준 형태로.
|
||||
4. **인증 주입:** 토큰을 getter 로(갱신 반영).
|
||||
5. **에러 passthrough/translate:** 실패를 호출부가 쓸 수 있는 형태로.
|
||||
|
||||
## 📖 세부 내용 (Details · 패턴 명세)
|
||||
- **Problem (언제 쓰나):** 외부 API/SDK 를 여러 곳에서 호출, 인증·재시도·에러 처리가 반복될 때.
|
||||
- **사용 조건:** 호출 인터페이스 정의 가능; 인증/설정 중앙화 가능.
|
||||
- **장점:** 중복 제거, 일관된 에러/재시도/취소, 교체·모킹 용이, 테스트성.
|
||||
- **단점:** 추상화 비용, 만능 클라이언트화 위험.
|
||||
- **대안:** fetch 직접(소규모), 생성된 SDK, GraphQL 클라이언트.
|
||||
- **실패 사례:** 타임아웃/취소 누락으로 멈춤; 토큰 하드코딩(갱신 안 됨); 에러 삼킴; 재시도에 backoff 없어 폭주; 응답 형식 호출부 산재.
|
||||
|
||||
## 💻 코드 패턴 (Code patterns)
|
||||
```text
|
||||
class Client {
|
||||
constructor({ getToken, baseUrl }) # 인증은 getter 주입
|
||||
async call(path, body, { signal }) {
|
||||
const s = combine(signal, timeout(ms)) # 취소+타임아웃
|
||||
res = await fetch(baseUrl+path, { headers:{Authorization:getToken()}, signal:s })
|
||||
if (!res.ok) return normalizeError(res) # 에러 정규화/passthrough
|
||||
return parse(res) # 응답 정규화
|
||||
}
|
||||
}
|
||||
```
|
||||
적용 예: AstraAI 의 provider 어댑터(공급자별 차이 흡수→공통 SSE)와 TelegramHttpClient(getToken 게터). → [[LLM 프로바이더 추상화]], [[AITRAIN 프로바이더 추상화]].
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
얇은 호출이면 fetch 직접이 낫다 — 인증/재시도/에러가 반복될 때만 클라이언트 추상화가 이득.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
AstraAI providers + telegramClient.
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[패턴 카탈로그 인덱스]]
|
||||
- **관련 개념:** [[Async Concurrency Pattern]], [[Error Handling Pattern]], [[Caching Pattern]], [[Tool Calling Pattern]]
|
||||
- **참조 맥락:** 작은 모델이 외부 API 통합 코드를 작성할 때 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] 일반 API 클라이언트 지식
|
||||
- [S2] AstraAI/src/features/providers/*, integrations/telegram/telegramClient.ts — 적용 예
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
|
||||
@@ -0,0 +1,66 @@
|
||||
---
|
||||
id: pattern-infinite-scroll
|
||||
title: "Infinite Scroll Pattern"
|
||||
category: "Pattern_Web"
|
||||
status: "draft"
|
||||
verification_status: "conceptual"
|
||||
canonical_id: ""
|
||||
aliases: ["infinite scroll", "무한 스크롤", "pagination", "cursor pagination", "virtualization"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.85
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["pattern", "web", "frontend", "pagination", "platform-independent"]
|
||||
raw_sources: ["일반 프런트엔드 공학 지식"]
|
||||
applied_in: []
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[Infinite Scroll Pattern]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
무한 스크롤은 "사용자가 끝에 도달하면 다음 페이지를 자동 로드" 하는 패턴으로, *커서 기반 페이징 + DOM 가상화 + 중복/경쟁 요청 방지* 가 없으면 성능과 정확성이 무너진다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
1. **트리거:** IntersectionObserver 로 sentinel 가시화 감지.
|
||||
2. **커서 페이징:** offset 대신 cursor(마지막 항목 키) — 삽입/삭제에 안정.
|
||||
3. **가상화:** 화면 밖 항목은 DOM 에서 제거(react-window 등).
|
||||
4. **중복/경쟁 방지:** 진행 중 로드 잠금, 이전 요청 취소.
|
||||
5. **상태:** 로딩/끝(hasMore)/에러 표시.
|
||||
|
||||
## 📖 세부 내용 (Details · 패턴 명세)
|
||||
- **Problem (언제 쓰나):** 큰 목록(피드/검색결과)을 점진 로드해 초기 부하를 줄일 때.
|
||||
- **사용 조건:** 페이징 API(가급적 커서); 항목 높이 처리.
|
||||
- **장점:** 빠른 초기 로드, 자연스러운 UX, 대용량 처리.
|
||||
- **단점:** 푸터 도달 불가, 딥링크/뒤로가기 어려움, 접근성/SEO 약함, 구현 복잡.
|
||||
- **대안:** 일반 페이지네이션(점프/SEO 좋음), "더 보기" 버튼(제어 명확).
|
||||
- **실패 사례:** offset 페이징 중 삽입→항목 중복/누락; 가상화 없이 DOM 폭증 렉; 중복 트리거로 같은 페이지 N번; 경쟁 요청 순서 꼬임; hasMore 미처리로 무한 호출.
|
||||
|
||||
## 💻 코드 패턴 (Code patterns)
|
||||
```text
|
||||
observer.observe(sentinel)
|
||||
onIntersect: if (!loading && hasMore) { loading=true; signal=abortPrev()
|
||||
page = await api.list({ cursor, signal }); items.push(...page.items)
|
||||
cursor = page.nextCursor; hasMore = !!cursor; loading=false }
|
||||
render: virtualize(items) # 화면 밖 제거
|
||||
```
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
무한 스크롤이 항상 옳지 않다 — 작업형 목록(테이블/검색)엔 페이지네이션이 제어·딥링크 면에서 낫다. 피드형에만 적합.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
일반 웹/모바일 피드. (AstraAI 직접 사례 없음.)
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[패턴 카탈로그 인덱스]]
|
||||
- **관련 개념:** [[React State Pattern]], [[Async Concurrency Pattern]], [[Caching Pattern]], [[웹 개발 가이드]]
|
||||
- **참조 맥락:** 작은 모델이 큰 목록 UI 를 구현할 때 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] 일반 프런트엔드 페이징/가상화 지식
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
id: pattern-jwt-authentication
|
||||
title: "JWT Authentication Pattern"
|
||||
category: "Pattern_Web"
|
||||
status: "draft"
|
||||
verification_status: "conceptual"
|
||||
canonical_id: ""
|
||||
aliases: ["JWT", "토큰 인증", "access token", "refresh token", "stateless auth"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.86
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["pattern", "web", "auth", "jwt", "security", "platform-independent"]
|
||||
raw_sources: ["일반 웹 보안 공학 지식"]
|
||||
applied_in: []
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[JWT Authentication Pattern]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
JWT 인증은 "서명된 토큰에 사용자 정보를 담아 *서버 세션 없이* 상태 무관(stateless) 인증" 을 하는 패턴으로, 확장성은 좋지만 *토큰을 즉시 무효화하기 어렵다* 는 본질적 약점이 있다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
1. **access token(짧은 수명) + refresh token(긴 수명):** 짧은 access 로 노출 위험↓, refresh 로 재발급.
|
||||
2. **서명 검증:** 서버 비밀키로 서명, 변조 시 검증 실패(저장 불필요).
|
||||
3. **claims:** sub/exp/role 등 페이로드(민감정보 금지 — base64 는 암호화 아님).
|
||||
4. **저장 위치:** httpOnly 쿠키(XSS 안전) vs localStorage(XSS 취약).
|
||||
5. **무효화:** 블랙리스트/짧은 만료/회전으로 보완.
|
||||
|
||||
## 📖 세부 내용 (Details · 패턴 명세)
|
||||
- **Problem (언제 쓰나):** 분산/무상태 API, 여러 서비스가 같은 토큰 검증(SSO), 모바일+웹 공용.
|
||||
- **사용 조건:** 비밀키 안전 보관; HTTPS; 토큰 수명 정책.
|
||||
- **장점:** 무상태(수평 확장), 서비스 간 공유, DB 조회 없이 검증.
|
||||
- **단점:** 즉시 무효화 어려움(로그아웃/탈취), 페이로드 노출, 토큰 비대.
|
||||
- **대안:** 서버 세션(즉시 무효화 쉬움, 상태 필요), OAuth/OIDC(위임), API key(머신).
|
||||
- **실패 사례:** localStorage 저장→XSS 탈취; refresh 회전 없이 탈취 지속; 민감정보를 claims 에; 만료 너무 길어 탈취 피해 확대; 서명 알고리즘 `none` 허용.
|
||||
|
||||
## 💻 코드 패턴 (Code patterns)
|
||||
```text
|
||||
login: verify(creds) -> access=sign({sub,exp:15m}), refresh=sign({sub,exp:7d}); setHttpOnlyCookie
|
||||
request: verifySignature(access) && !expired -> allow ; else 401
|
||||
refresh: verify(refresh) && !revoked -> rotate(new access+refresh), invalidate old
|
||||
logout: revoke(refresh) # 블랙리스트/회전
|
||||
```
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
"JWT 가 세션보다 낫다" 는 과장 — 즉시 무효화·서버측 제어가 중요하면 세션이 낫다. JWT 는 *무상태 확장* 이 목적일 때.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
일반 웹/모바일 API 인증. (AstraAI 는 로컬 도구라 직접 사례 없음 — provider API key 는 [[API Client Pattern]] 참조.)
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[패턴 카탈로그 인덱스]]
|
||||
- **관련 개념:** [[API Client Pattern]], [[웹 개발 가이드]], [[소프트웨어 실패 라이브러리]]
|
||||
- **참조 맥락:** 작은 모델이 웹/모바일 인증을 구현할 때 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] 일반 웹 보안/JWT 지식(RFC 7519, OWASP)
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
id: pattern-react-state
|
||||
title: "React State Pattern"
|
||||
category: "Pattern_Web"
|
||||
status: "draft"
|
||||
verification_status: "conceptual"
|
||||
canonical_id: ""
|
||||
aliases: ["React state", "리액트 상태 패턴", "hooks", "lifting state up", "server state"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.85
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["pattern", "web", "react", "frontend", "state", "platform-independent"]
|
||||
raw_sources: ["일반 프런트엔드 공학 지식"]
|
||||
applied_in: []
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[React State Pattern]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
React(및 유사 선언형 UI) 상태의 핵심 규칙은 "**상태를 필요한 가장 낮은 곳에 두되, 공유되면 끌어올리고, 서버 데이터는 UI 상태와 분리**" 하는 것 — 이는 [[State Management Pattern]] 의 프런트엔드 구체화다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
1. **로컬 상태(useState):** 한 컴포넌트만 쓰는 상태.
|
||||
2. **lifting state up:** 두 형제가 공유하면 공통 부모로.
|
||||
3. **전역 상태(Context/Zustand/Redux):** 앱 전반 공유(과용 금지).
|
||||
4. **서버 상태(react-query/SWR):** 원격 데이터는 캐시·동기화 라이브러리로 분리.
|
||||
5. **파생 상태:** useMemo 로 계산, 저장하지 않음.
|
||||
|
||||
## 📖 세부 내용 (Details · 패턴 명세)
|
||||
- **Problem (언제 쓰나):** 컴포넌트 트리에서 상태 위치·공유 범위를 정할 때.
|
||||
- **사용 조건:** 선언형 UI; 단방향 데이터.
|
||||
- **장점:** 예측 가능 렌더, 재사용, 테스트성.
|
||||
- **단점:** prop drilling(전역 미사용 시), 과한 전역화는 리렌더·결합, 서버/클라 상태 혼동.
|
||||
- **대안:** 전역 store(공유 많을 때), 서버 상태 라이브러리, URL 상태(공유 가능 상태).
|
||||
- **실패 사례:** 서버 데이터를 useState 에 복사→stale·동기화 버그; 모든 걸 전역 store 에→불필요 리렌더·결합; 파생값 저장; 깊은 prop drilling.
|
||||
|
||||
## 💻 코드 패턴 (Code patterns)
|
||||
```text
|
||||
const [v, setV] = useState(init) # 로컬
|
||||
// 공유되면 부모로 올리고 props/context 로 전달
|
||||
const data = useQuery('key', fetcher) # 서버 상태는 분리(캐시/리페치)
|
||||
const total = useMemo(() => sum(items), [items]) # 파생은 계산
|
||||
```
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
"Redux 가 정석" 은 옛말 — 서버 상태는 react-query, 지역은 useState, 진짜 전역만 가벼운 store. 도구보다 *상태의 출처/수명* 으로 위치를 정하라.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
일반 React 앱. (AstraAI 웹뷰는 메시지 기반 — 원리는 [[State Management Pattern]] 와 동일.)
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[패턴 카탈로그 인덱스]]
|
||||
- **관련 개념:** [[State Management Pattern]], [[Data Flow Pattern]], [[Infinite Scroll Pattern]], [[웹 개발 가이드]]
|
||||
- **참조 맥락:** 작은 모델이 프런트엔드 상태를 설계할 때 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] 일반 React/프런트엔드 상태 지식
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
|
||||
@@ -0,0 +1,66 @@
|
||||
---
|
||||
id: pattern-repository
|
||||
title: "Repository Pattern"
|
||||
category: "Pattern_Web"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["Repository", "리포지토리 패턴", "data access layer", "DAO"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.88
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["pattern", "web", "backend", "data-access", "platform-independent"]
|
||||
raw_sources: ["일반 소프트웨어 공학 지식", "AstraAI/src/features/_shared/eventSourcedStore.ts (적용 예)"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[Repository Pattern]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
Repository 는 "도메인 코드와 데이터 저장 방식 사이에 *컬렉션처럼 보이는* 인터페이스를 두어, 비즈니스 로직이 DB/파일/API 의 세부를 모르게" 하는 패턴이다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
1. **인터페이스로 저장 추상화:** `find/save/delete` 같은 도메인 언어 메서드.
|
||||
2. **구현 교체:** 같은 인터페이스로 메모리/파일/SQL/원격 구현.
|
||||
3. **도메인 모델 반환:** raw 행이 아니라 도메인 객체.
|
||||
4. **쿼리 캡슐화:** 복잡 쿼리를 repository 안에.
|
||||
|
||||
## 📖 세부 내용 (Details · 패턴 명세)
|
||||
- **Problem (언제 쓰나):** 도메인 로직을 저장 기술과 분리하고 테스트(가짜 repo)하고 싶을 때.
|
||||
- **사용 조건:** 도메인 모델 정의; 저장 연산을 인터페이스로 표현 가능.
|
||||
- **장점:** 저장 교체 용이, 테스트성(in-memory repo), 도메인 순수, 쿼리 한 곳.
|
||||
- **단점:** 추상화 비용, 단순 CRUD 엔 과설계, leaky abstraction 위험.
|
||||
- **대안:** ORM 직접 사용(소규모), Active Record, 쿼리 빌더 직접.
|
||||
- **실패 사례:** repository 가 DB 세부를 누수(IQueryable 노출); 만능 repository(God repo); 도메인이 SQL 을 알게 됨.
|
||||
|
||||
## 💻 코드 패턴 (Code patterns)
|
||||
```text
|
||||
interface UserRepo { findById(id): User?; save(u: User): Result; list(): User[] }
|
||||
class FileUserRepo implements UserRepo { ... } # 교체 가능 구현
|
||||
class SqlUserRepo implements UserRepo { ... }
|
||||
service(repo: UserRepo) # 도메인은 인터페이스만 의존(주입)
|
||||
```
|
||||
적용 예: AstraAI 의 `createEventStore<E>` 가 read/append/count 로 저장을 추상화하고 도메인은 인터페이스만 사용([[이벤트 소싱 스토어 패턴]], [[AITRAIN 이벤트소싱 저장]]).
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
ORM 이 이미 repository 유사 추상을 주므로, 그 위에 또 repository 를 얹으면 중복일 수 있다 — 교체/테스트 필요가 명확할 때만.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
AstraAI eventSourcedStore(도메인별 store 인스턴스화).
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[패턴 카탈로그 인덱스]]
|
||||
- **관련 개념:** [[의존성 주입과 서비스 인터페이스]], [[Architecture Separation Pattern]], [[Local Storage Pattern]], [[백엔드 API 개발 가이드]]
|
||||
- **참조 맥락:** 작은 모델이 데이터 접근 계층을 설계할 때 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] 일반 DDD/Repository 지식
|
||||
- [S2] AstraAI/src/features/_shared/eventSourcedStore.ts — 적용 예
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
|
||||
Reference in New Issue
Block a user