Initial Commit
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
# Data Model: 스니펫 팔레트 (Phase 1)
|
||||
|
||||
003 스키마를 그대로 따른다. 랭킹·검색은 프론트에서 계산하므로, 저장은 원자적 데이터만 담는다.
|
||||
|
||||
## 엔티티
|
||||
|
||||
### Snippet
|
||||
붙여넣을 코드 조각 한 개.
|
||||
|
||||
| 필드 | 타입 | 제약 | 설명 |
|
||||
|---|---|---|---|
|
||||
| `name` | string | **PK**, 정규화(대문자·공백→`_`), 유일 | 식별 키, 결과 행 제목 |
|
||||
| `desc` | string | 기본 `""` | 짧은 설명, 결과 부제 · 검색 대상 |
|
||||
| `body` | string | 비어있지 않음, 원문 보존 | 실제 붙여넣어지는 내용 |
|
||||
| `category` | string | 기본 `"코드"` | 분류 라벨 |
|
||||
|
||||
- 003의 `change_word1/2`는 **가져오지 않음**(안 쓰는 유물).
|
||||
- 저장 시 검증: `name` 정규화 후 비어있지 않음 + 유일(중복 거부), `body` 비어있지 않음. (spec FR-016)
|
||||
- `name`은 편집 불가(키). desc/body/category만 수정. (FR-017)
|
||||
|
||||
### Usage
|
||||
스니펫별 사용 통계. 별도 테이블(003과 동일).
|
||||
|
||||
| 필드 | 타입 | 제약 | 설명 |
|
||||
|---|---|---|---|
|
||||
| `name` | string | **PK**, Snippet.name 참조 | 어떤 스니펫 |
|
||||
| `count` | integer | 기본 0 | 붙여넣기 성공 누적 |
|
||||
| `last_used` | integer | unix 초 | 마지막 붙여넣기 시각 |
|
||||
|
||||
- 붙여넣기 성공 시 upsert: `count+1`, `last_used=now`. (FR-011)
|
||||
- Snippet에 대응 Usage가 없으면 `(0,0)`으로 취급.
|
||||
|
||||
## SQLite 스키마 (C# 호스트 소유)
|
||||
|
||||
```sql
|
||||
CREATE TABLE IF NOT EXISTS snippets (
|
||||
name TEXT PRIMARY KEY,
|
||||
desc TEXT NOT NULL DEFAULT '',
|
||||
body TEXT NOT NULL DEFAULT '',
|
||||
category TEXT NOT NULL DEFAULT '코드'
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS usage (
|
||||
name TEXT PRIMARY KEY,
|
||||
count INTEGER NOT NULL DEFAULT 0,
|
||||
last_used INTEGER NOT NULL DEFAULT 0
|
||||
);
|
||||
```
|
||||
|
||||
파일: `%LOCALAPPDATA%\CodeAssist\snippets.db`. 첫 실행 시 003의 `snippets.db`가 있으면 1회 복사(시드). (research R4·R5)
|
||||
|
||||
## 프론트 타입 (`features/snippets/types.ts`)
|
||||
|
||||
로컬 엔티티라 `types/api.ts`(서버 DTO 전용) 아님.
|
||||
|
||||
```ts
|
||||
export interface Snippet {
|
||||
name: string
|
||||
desc: string
|
||||
body: string
|
||||
category: string
|
||||
usageCount: number // usage.count (없으면 0)
|
||||
lastUsed: number // usage.last_used unix초 (없으면 0)
|
||||
}
|
||||
|
||||
export interface SnippetInput { // 생성/수정 입력
|
||||
name: string
|
||||
desc: string
|
||||
body: string
|
||||
category: string
|
||||
}
|
||||
```
|
||||
|
||||
- 브릿지 응답에서 snippets ⨝ usage 조인 결과를 `Snippet`(usageCount/lastUsed 병합)로 받는다. C#가 조인해 내려주거나, 두 테이블을 각각 내려 프론트에서 병합 — 구현 시 단순한 쪽(C# 조인 권장).
|
||||
|
||||
## 파생 규칙 (프론트 순수함수)
|
||||
|
||||
### 검색 (`core/search.ts`) — FR-005/006
|
||||
- 입력: 스니펫 목록, 쿼리 문자열, (선택)category.
|
||||
- category가 있으면 그 분류로 먼저 제한. `"전체"`면 전체.
|
||||
- 쿼리를 공백으로 split → 키워드들. 각 키워드(대문자화)가 **전부(AND)** `(name + " " + desc)`의 대문자화 문자열에 포함될 때만 통과. `body`는 검색 안 함. 퍼지 없음.
|
||||
- 빈 쿼리 → (category 제한된) 전체.
|
||||
|
||||
### 랭킹 (`core/ranking.ts`) — FR-007
|
||||
- 정렬 키: `count desc, lastUsed desc, name asc`.
|
||||
- 모든 결과 집합(검색·전체 공통)에 적용. 상위 9개에 `1~9` 번호(Alt+숫자 대응). (FR-008)
|
||||
|
||||
## 상태 전이
|
||||
|
||||
스니펫: (없음) → 생성 → (편집)* → 삭제.
|
||||
Usage: 붙여넣기 성공마다 count 증가 · last_used 갱신 → 랭킹 상단으로 부상.
|
||||
Reference in New Issue
Block a user