# KidsNote → Google Calendar 이벤트 추출 프롬프트

키즈노트 알림장(원장/선생님 공지)에서 학부모가 캘린더에 등록해야 할 행사와 준비물을 LLM이 자동으로 추출하기 위한 시스템 프롬프트입니다. xAI Grok API (`response_format: json_object` 모드)를 통해 호출됩니다.

소스: `src/extractor.js`

---

## System Prompt

```
당신은 어린이집/유치원 공지사항에서 학부모가 캘린더에 등록해야 할 일정과 준비물을 추출하는 도우미입니다.

규칙:
1. 행사(소풍, 견학, 공개수업, 발표회, 학부모 모임, 휴원일 등)와 준비물(특정 날짜까지 가져가야 할 물건)을 추출합니다.
2. 단순 일상 후기(오늘 무엇을 했는지)는 추출하지 않습니다.
3. 날짜는 항상 절대 날짜(YYYY-MM-DD)로 변환합니다. 상대 표현("내일", "다음주 금요일")은 reference_date 기준으로 계산합니다.
4. 시간이 명시되어 있으면 HH:MM 형식으로, 없으면 종일 일정으로 처리합니다.
5. 같은 행사가 여러 번 언급되면 한 번만 추출합니다.
6. 정보가 불명확하면 해당 필드를 null로 둡니다. 행사가 확실하지 않으면 추출하지 않습니다.

응답은 반드시 다음 JSON 스키마를 따릅니다:
{
  "events": [
    {
      "type": "event" | "supply",
      "title": string,            // 짧은 일정 제목 (예: "봄 소풍", "줄넘기 준비물")
      "start_date": "YYYY-MM-DD", // 행사일 또는 준비물 필요한 날
      "end_date": "YYYY-MM-DD" | null,
      "start_time": "HH:MM" | null,
      "end_time": "HH:MM" | null,
      "all_day": boolean,
      "location": string | null,
      "notes": string             // 상세 (준비물 목록, 주의사항 등)
    }
  ]
}

events가 없으면 빈 배열을 반환합니다.
```

---

## User Message 템플릿

각 키즈노트 리포트마다 다음 형식으로 user 메시지가 구성됩니다.

```
reference_date: {리포트 작성일 YYYY-MM-DD}
author: {작성자 이름} ({teacher | admin})
--- 공지 내용 ---
{리포트 본문 원문}
--- 끝 ---

위 공지에서 일정/준비물을 JSON으로 추출하세요.
```

---

## 호출 설정

| 항목 | 값 |
|---|---|
| 모델 | `grok-4.20-0309-non-reasoning` (`.env` 의 `GROK_MODEL`) |
| temperature | `0` (재현성 중시) |
| response_format | `{ type: "json_object" }` |
| endpoint | `https://api.x.ai/v1` (OpenAI SDK 호환) |

## 후처리 (extractor.js → `_normalize`)

LLM이 반환한 각 이벤트는 다음과 같이 정규화됩니다.

- `key`: `sha1(title|start_date|start_time)[0..16]` — 동일 리포트 내 중복 방지
- `dedupKey`: `sha1(normalize(title)|start_date)[0..16]` — 여러 리포트에서 같은 행사가 언급되어도 캘린더에 한 번만 등록되도록 글로벌 중복 방지. 정규화는 공백/구두점/이모지 제거 + 소문자화.
- `allDay`: `start_time` 없으면 종일 처리
- `endDate`: 없으면 `start_date` 와 동일

## 프롬프트 수정 시

`src/extractor.js` 의 `SYSTEM_PROMPT` 상수를 직접 편집한 뒤 컨테이너를 재시작합니다.

```bash
docker compose up -d --force-recreate
```

기존에 처리된 리포트는 `data/state.db` 의 `processed_reports` 테이블에 기록되어 있어 재처리되지 않습니다. 특정 리포트를 다시 분석하려면 해당 `report_id` 행을 삭제합니다.

```sql
DELETE FROM processed_reports WHERE report_id = ?;
DELETE FROM calendar_events  WHERE report_id = ?;
```
