first commit
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
# CogMind (web)
|
||||
|
||||
문제를 풀고 **확신도**를 함께 기록하면, AI가 "안다고 착각한 개념"을 짚어 주는 메타인지 학습 서비스입니다.
|
||||
|
||||
LLM은 Google Gen AI SDK(`@google/genai`, 기본 모델 `gemini-2.5-flash`)를 사용합니다.
|
||||
|
||||
## 실행
|
||||
|
||||
```bash
|
||||
bun install
|
||||
|
||||
cp .env.example .env # GEMINI_API_KEY 를 채웁니다
|
||||
bun run start # http://127.0.0.1:1234
|
||||
```
|
||||
|
||||
API 키는 [Google AI Studio](https://aistudio.google.com/apikey)에서 발급합니다.
|
||||
`.env` 는 `.gitignore` 에 포함되어 있으니 키를 코드에 직접 적지 마세요.
|
||||
|
||||
개발 중에는 `bun run dev` (파일 변경 시 자동 재시작), 타입 검사는 `bun run typecheck`.
|
||||
|
||||
## 화면 주소
|
||||
|
||||
History API 로 화면마다 주소를 갖습니다. 브라우저 뒤로/앞으로 가기가 그대로 동작하고,
|
||||
주소를 직접 열거나 새로고침해도 같은 화면이 뜹니다 (`server.ts` 의 SPA 폴백).
|
||||
|
||||
| 주소 | 화면 |
|
||||
| --- | --- |
|
||||
| `/` | 시작 화면 |
|
||||
| `/quiz/3` | 풀고 있는 시험의 3번 문제 (문항마다 뒤로가기 한 단계) |
|
||||
| `/tests/:id` | 시험 결과 리포트 — 새로고침·공유 가능 |
|
||||
| `/history` | 지난 기록 목록 |
|
||||
|
||||
진행 중인 시험은 메모리에만 있으므로, 새로고침한 뒤의 `/quiz/*` 는 시작 화면으로 보냅니다.
|
||||
|
||||
## 서버 API
|
||||
|
||||
| 엔드포인트 | 설명 |
|
||||
| --- | --- |
|
||||
| `GET /api/chapters` | `chapter.json` (학교 종류 → 과목 → 단원) |
|
||||
| `POST /api/questions` | `{ school, subject, chapter, difficulty, amount }` → 문항 생성 |
|
||||
| `POST /api/tests` | 시험 결과 저장 → 저장된 기록 전체 반환 |
|
||||
| `GET /api/tests` | 기록 목록 (요약) |
|
||||
| `GET /api/tests/:id` | 기록 상세 |
|
||||
| `POST /api/tests/:id/feedback` | 메타인지 평가·학습 추천 생성 후 기록에 저장 |
|
||||
| `POST /api/tests/:id/questions/:index/explain` | 해설 생성 후 해당 문항에 저장 |
|
||||
| `POST /api/tests/:id/questions/:index/twin` | 쌍둥이 문제 생성 후 해당 문항의 `children` 에 추가 |
|
||||
| `POST /api/tests/:id/questions/:index/ask` | 해설에 이어지는 후속 질문. 질문·답변을 `conversation` 에 추가 |
|
||||
|
||||
해설과 피드백은 한 번 만들어지면 그대로 재사용합니다(중복 호출 시 저장된 값 반환).
|
||||
실패 시 `4xx/502` 와 `{ error }` 를 돌려줍니다.
|
||||
|
||||
## 기록 저장 형식
|
||||
|
||||
기록은 `data/history.json` 한 파일에 배열로 쌓입니다 (`.gitignore` 대상).
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"id": "msmjphyx-xj7nbf",
|
||||
"createdAt": "2026-08-10T01:21:13.785Z",
|
||||
"student": "김민준",
|
||||
"school": "고등학교", "subject": "수학", "chapter": "도함수",
|
||||
"difficulty": "medium",
|
||||
"score": { "total": 3, "correct": 2, "percent": 67,
|
||||
"overconfident": 1, "lucky": 1, "solid": 1 },
|
||||
"feedback": { "summary": "...", "detail": "...", "recommendation": "..." },
|
||||
"questions": [
|
||||
{
|
||||
"question": "...", "correct_answer": "...", "incorrect_answers": ["..."],
|
||||
"user_answer": "...", "confidence": "sure", "is_correct": false,
|
||||
"explanation": "AI 해설 (key/value)",
|
||||
"conversation": [ // 해설에 이어서 주고받은 질문·답변
|
||||
{ "role": "user", "content": "왜 그런가요?", "createdAt": "..." },
|
||||
{ "role": "assistant", "content": "...", "createdAt": "..." }
|
||||
],
|
||||
"children": [ // 쌍둥이 문제
|
||||
{ "question": "...", "correct_answer": "...",
|
||||
"incorrect_answers": ["..."], "createdAt": "..." }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 구조
|
||||
|
||||
```
|
||||
server.ts express 서버 + Gemini 호출
|
||||
store.ts data/history.json 기반 기록 저장소
|
||||
chapter.json 학교 종류 → 과목 → 단원
|
||||
public/index.html 앱 셸
|
||||
public/images/ logo-light.png (밝은 테마) · logo-dark.png (어두운 테마)
|
||||
public/main.css 디자인 토큰과 스타일 (라이트/다크 자동)
|
||||
public/main.js 상태, 서버 통신, 화면 전환
|
||||
public/report.js 리포트 렌더러 (결과 화면과 기록 상세가 공용)
|
||||
public/optionPage.js 시작 화면 (<option-page>)
|
||||
public/testPage.js 퀴즈 화면 (<test-page>)
|
||||
public/historyPage.js 지난 기록 목록 (<history-page>)
|
||||
```
|
||||
Reference in New Issue
Block a user