Files
CODE_ASSISTANT/specs/001-snippet-palette/contracts/snippet-data-interface.md
T
2026-09-16 17:22:14 +09:00

2.2 KiB

Contract: 프론트 데이터 인터페이스 (snippets.api.ts)

feature의 유일한 데이터 진입점. 화면·hook은 이 인터페이스만 알고, 뒤가 브릿지(SQLite)인지 나중에 백엔드인지는 모른다. (spec FR-022 / plan 편차1: HTTP 클라이언트 미경유)

import type { Snippet, SnippetInput } from "../types"

export interface SnippetsApi {
  list(): Promise<Snippet[]>                       // usage 병합, 정렬은 프론트가
  create(input: SnippetInput): Promise<Snippet>    // 중복 name → reject(Error)
  update(input: SnippetInput): Promise<Snippet>    // name=키
  remove(name: string): Promise<void>
  recordUse(name: string): Promise<{ name: string; usageCount: number; lastUsed: number }>  // 붙여넣기 성공 후, 갱신된 usage 반환(caller는 무시 가능)
}
  • v1 구현체 snippetBridge(브릿지 왕복). 나중에 백엔드 전환 시 이 인터페이스 뒤 구현만 교체.
  • 반환 타입은 순수 데이터(브릿지/HTTP 세부 노출 안 함). 실패는 Error reject.

react-query 계약 (hooks/useSnippets.ts) — memos 패턴 준용

export const SNIPPETS_KEY = "snippets"

useSnippets()            // useQuery([SNIPPETS_KEY]) → Snippet[]
useCreateSnippet()       // mutation → invalidate([SNIPPETS_KEY]) + sonner "스니펫 생성됨"
useUpdateSnippet()       // → invalidate + "저장됨"
useDeleteSnippet()       // → invalidate + "삭제됨"
useRecordUse()           // → invalidate([SNIPPETS_KEY]) (랭킹 갱신). 토스트 없음(조용히)
  • 에러: 브릿지 실패는 ApiError(HTTP 전용)가 아니라 rejected promise의 순수 Error임 → err instanceof Error ? err.message : "<한글 폴백>" 형태(memos 톤은 같되 타입만 Error).
  • useSnippets가 준 목록에 core/search+core/ranking을 화면에서 적용(서버 정렬 아님 — 로컬 계산).

붙여넣기 (기존 재사용, 신규 아님)

import { pasteToApp } from "@/lib/bridge/webviewBridge"
// Enter / Alt+숫자 →
pasteToApp(snippet.body)   // 기존 paste.code — C# PasteService가 앞 창에 Ctrl+V + 창 숨김
await recordUse(snippet.name)