7bec20620a
아키텍처 감사 결과 HIGH 2건 + MED 2건 + LOW 1건 — 7 라운드 정리 시리즈.
기능 변경 없음, 순수 구조 정리.
**slashRouter.ts: 4,174 → 201줄 (–3,973, –95%)**
**agent.ts: 1,617 → 1,551줄 (–66, –4%)**
v2.2.195: eventSourcedStore + SystemPromptBlock registry
- createEventStore<E>(opts) — 4 store (customers/hire/runway/feedback) I/O 240줄 중복 제거
- _turnCtx 5 named string field → 1 Map<string, string> (새 verification block 추가 25곳→1곳)
- buildAstraModeSystemPrompt: 5 ternary gate + 5 위치 → 1 for-loop join
v2.2.196: trackers cluster split
- src/features/teamops/handlers/_shared.ts (fmtKrw/parseAmount/daysUntil/parseTaskOwner/stageEmoji/STAGE_ORDER/TERMINAL_STAGES)
- src/features/teamops/handlers/trackers.ts (runway/customers/hire)
- src/features/teamops/handlers/index.ts (barrel)
- extension.ts 에 side-effect import (순환 import 회피)
v2.2.197: mtimeFileCache + PostAnswerHook registry
- src/lib/mtimeFileCache.ts — createMtimeFileCache<T>(name, parse) (terminologyBlock + termValidator 2-cache invariant 자동화)
- src/agent/postAnswerHooks/{types,index}.ts — Devil/SelfCheck/TermValidator 3 _maybeX method → 1 runPostAnswerHooks(ctx) loop
- agent.ts –66줄
v2.2.198: dashboards cluster split
- src/features/teamops/handlers/dashboards.ts (morning/evening/cohort/weekly)
v2.2.199: coordination + communication clusters split
- src/features/teamops/handlers/coordination.ts (task/decisions/onesie/blocked/standup)
- src/features/teamops/handlers/communication.ts (draft/feedback)
- callLmSynthesis export 노출 (communication 이 사용)
- 옛 parseTaskOwner local 정의 삭제 (_shared.ts 사용)
v2.2.200: system cluster split
- src/features/system/handlers.ts (memory/glossary/help)
v2.2.201: datacollect cluster split + LLM 인프라 추출
- src/features/datacollect/handlers.ts (research/benchmark/youtube/blog/wikify/meet)
- src/features/datacollect/llm.ts (callLmSynthesis + repairKoreanGlitches + bridgeErrorRemedy)
- slashRouter import 4개로 축소: vscode/logInfo/getBridgeBaseUrl/bridgeErrorRemedy
**최종 slashRouter (201줄):**
- REGISTRY Map + registerSlashCommand/listSlashCommands/isSlashCommand
- handleSlashCommand (dispatcher + 에러 처리)
- Webview interface + chunk helper
- getRecentSlashCommands ring buffer (actionability scoring 용)
**미래 부담 감소 metrics:**
- 새 슬래시 명령: god-file 끝에 함수 + register → 1 파일 + 1 register call
- 새 verification block: 5곳 편집 → 1 set call
- 새 event store: 60줄 boilerplate → createEventStore 한 줄
- 새 post-answer hook: 3 step → 1 push
- 새 mtime cache: Map + invariant 관리 → createMtimeFileCache 한 줄
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
45 lines
1.8 KiB
TypeScript
45 lines
1.8 KiB
TypeScript
/**
|
|
* 고객 피드백 누적 저장소.
|
|
*
|
|
* 단일 운영자(대표) 모드에서 슬랙·이메일·CS 채널에 흩어진 고객 피드백을
|
|
* `/feedback <텍스트>` 한 줄로 모아 둔다. 패턴 분석은 `/feedback summary` 로
|
|
* LLM 이 누적 데이터를 보고 카테고리 분포 + 반복 주제를 추출.
|
|
*
|
|
* 저장 형식: JSON Lines (.jsonl) — 한 줄 = 한 entry. 누적·append-only, 사람이
|
|
* 직접 편집 가능, grep / 백업 친화. 위치: `<workspace>/.astra/customer-feedback.jsonl`.
|
|
*
|
|
* 워크스페이스 폴더가 없으면 저장 불가 (null 반환). 사용자가 `/feedback path` 로
|
|
* 위치 확인 가능. 민감 정보 포함 가능성 있으므로 외부로 안 보냄 — 로컬 only.
|
|
*/
|
|
|
|
import { createEventStore } from '../_shared/eventSourcedStore';
|
|
|
|
const STORE_REL_PATH = '.astra/customer-feedback.jsonl';
|
|
|
|
export interface FeedbackEntry {
|
|
/** unique id — timestamp 기반 (정렬·dedup 용도). */
|
|
id: string;
|
|
/** ISO timestamp of when this entry was captured. */
|
|
timestamp: string;
|
|
/** 사용자가 입력한 원본 텍스트 (그대로 보존). */
|
|
text: string;
|
|
/** 선택적 출처 — 'slack' / 'email' / 'cs' / 'review' 등. */
|
|
source?: string;
|
|
/** LLM 이 부여한 카테고리 (1~3개). */
|
|
categories?: string[];
|
|
/** LLM 판정 — 'positive' / 'neutral' / 'negative'. */
|
|
sentiment?: 'positive' | 'neutral' | 'negative';
|
|
}
|
|
|
|
const _store = createEventStore<FeedbackEntry>({
|
|
relPath: STORE_REL_PATH,
|
|
validate: (e): e is FeedbackEntry => !!e
|
|
&& typeof (e as any).id === 'string'
|
|
&& typeof (e as any).text === 'string',
|
|
});
|
|
|
|
export const getFeedbackFilePath = _store.getFilePath;
|
|
export const readFeedback = _store.read;
|
|
export const appendFeedback = _store.append;
|
|
export const countFeedback = _store.count;
|