Initial commit

This commit is contained in:
2026-06-10 12:49:53 +09:00
commit b159597559
707 changed files with 551154 additions and 0 deletions
@@ -0,0 +1,198 @@
# SQLite + FastAPI + Vue CRUD 구현 계획
> **에이전트 작업자용:** 각 작업은 체크박스(`- [ ]`)로 추적합니다.
**목표:** SQLite의 `messages` 테이블 데이터를 FastAPI CRUD API로 조작하고 Vue 화면에서 생성, 조회, 수정, 삭제할 수 있게 만든다.
**아키텍처:** 백엔드는 `sqlite3`와 FastAPI로 단순 CRUD 엔드포인트를 제공하고, 프론트엔드는 브라우저용 Vue ESM 번들로 목록형 CRUD UI를 구현한다. 구현은 기존 파일 구조를 유지하면서 최소한의 상태만 추가하고, 마지막에 API와 화면 흐름을 직접 검증한다.
**기술 스택:** Python 3, FastAPI, sqlite3, Vue 3 ESM, 정적 HTML
---
- [ ] **작업 1: DB 초기화 스크립트 유지 여부 점검**
- **대상 파일:** `/Users/woozooni/Documents/trae_projects/skillDesk/backend/init_db.py` (수정)
- **할 일:** `messages` 테이블 구조가 CRUD 요구사항에 충분한지 확인하고, 초기 데이터 `hello world` 1건을 유지하는 방식으로 정리한다.
- **최소 구현 예시:**
```python
cursor.execute(
"CREATE TABLE IF NOT EXISTS messages (id INTEGER PRIMARY KEY AUTOINCREMENT, content TEXT NOT NULL)"
)
cursor.execute("DELETE FROM messages")
cursor.execute("INSERT INTO messages (content) VALUES (?)", ("hello world",))
```
- **검증 명령:** `python3 backend/init_db.py`
- **기대 결과:** `backend/app.db`가 다시 생성되거나 갱신되고, `messages` 테이블에 `hello world` 1건이 들어간다.
- [ ] **작업 2: FastAPI용 요청 모델과 DB 헬퍼 추가**
- **대상 파일:** `/Users/woozooni/Documents/trae_projects/skillDesk/backend/main.py` (수정)
- **할 일:** SQLite 연결 헬퍼, 메시지 직렬화 헬퍼, 입력 검증용 Pydantic 모델을 추가한다.
- **최소 구현 예시:**
```python
class MessagePayload(BaseModel):
content: str
@field_validator("content")
@classmethod
def validate_content(cls, value: str) -> str:
stripped_value = value.strip()
if not stripped_value:
raise ValueError("Content must not be empty")
return stripped_value
```
- **검증 명령:** `python3 -m py_compile backend/main.py`
- **기대 결과:** API 함수들이 공통 검증 로직과 연결 헬퍼를 재사용할 준비가 된다.
- [ ] **작업 3: 메시지 목록 조회 API 구현**
- **대상 파일:** `/Users/woozooni/Documents/trae_projects/skillDesk/backend/main.py` (수정)
- **할 일:** `GET /api/messages` 엔드포인트를 추가해 전체 메시지 목록을 `id` 오름차순으로 반환한다.
- **최소 구현 예시:**
```python
@app.get("/api/messages")
def list_messages() -> list[dict[str, object]]:
with get_connection() as connection:
rows = connection.execute(
"SELECT id, content FROM messages ORDER BY id ASC"
).fetchall()
return [serialize_message(row) for row in rows]
```
- **검증 명령:** `python3 -c "from backend.main import list_messages; print(list_messages())"`
- **기대 결과:** `hello world`가 포함된 리스트가 출력된다.
- [ ] **작업 4: 메시지 생성 API 구현**
- **대상 파일:** `/Users/woozooni/Documents/trae_projects/skillDesk/backend/main.py` (수정)
- **할 일:** `POST /api/messages` 엔드포인트를 추가해 메시지를 저장하고 생성된 `id`와 `content`를 반환한다.
- **최소 구현 예시:**
```python
@app.post("/api/messages", status_code=201)
def create_message(payload: MessagePayload) -> dict[str, object]:
with get_connection() as connection:
cursor = connection.execute(
"INSERT INTO messages (content) VALUES (?)",
(payload.content,),
)
connection.commit()
return {"id": cursor.lastrowid, "content": payload.content}
```
- **검증 명령:** `python3 - <<'PY'\nfrom backend.main import create_message, MessagePayload\nprint(create_message(MessagePayload(content='created from plan')))\nPY`
- **기대 결과:** 새 `id`와 저장된 `content`가 출력된다.
- [ ] **작업 5: 메시지 수정 API 구현**
- **대상 파일:** `/Users/woozooni/Documents/trae_projects/skillDesk/backend/main.py` (수정)
- **할 일:** `PUT /api/messages/{id}` 엔드포인트를 추가해 해당 메시지를 수정하고, 없는 `id`는 404를 반환한다.
- **최소 구현 예시:**
```python
@app.put("/api/messages/{message_id}")
def update_message(message_id: int, payload: MessagePayload) -> dict[str, object]:
with get_connection() as connection:
cursor = connection.execute(
"UPDATE messages SET content = ? WHERE id = ?",
(payload.content, message_id),
)
connection.commit()
if cursor.rowcount == 0:
raise HTTPException(status_code=404, detail="Message not found")
return {"id": message_id, "content": payload.content}
```
- **검증 명령:** `python3 - <<'PY'\nfrom backend.main import update_message, MessagePayload\nprint(update_message(1, MessagePayload(content='updated hello world')))\nPY`
- **기대 결과:** 수정된 메시지 객체가 출력된다.
- [ ] **작업 6: 메시지 삭제 API 구현**
- **대상 파일:** `/Users/woozooni/Documents/trae_projects/skillDesk/backend/main.py` (수정)
- **할 일:** `DELETE /api/messages/{id}` 엔드포인트를 추가해 해당 메시지를 삭제하고 성공 여부를 반환한다.
- **최소 구현 예시:**
```python
@app.delete("/api/messages/{message_id}")
def delete_message(message_id: int) -> dict[str, bool]:
with get_connection() as connection:
cursor = connection.execute(
"DELETE FROM messages WHERE id = ?",
(message_id,),
)
connection.commit()
if cursor.rowcount == 0:
raise HTTPException(status_code=404, detail="Message not found")
return {"success": True}
```
- **검증 명령:** `python3 - <<'PY'\nfrom backend.main import delete_message\nprint(delete_message(1))\nPY`
- **기대 결과:** `{'success': True}`가 출력된다.
- [ ] **작업 7: Vue 상태를 목록형 CRUD 구조로 변경**
- **대상 파일:** `/Users/woozooni/Documents/trae_projects/skillDesk/frontend/src/main.js` (수정)
- **할 일:** 단일 `message` 상태를 `messages`, `newContent`, `editingId`, `editingContent` 상태로 교체하고 목록 조회 함수를 만든다.
- **최소 구현 예시:**
```javascript
const messages = ref([])
const newContent = ref('')
const editingId = ref(null)
const editingContent = ref('')
```
- **검증 명령:** `python3 -m py_compile backend/main.py`
- **기대 결과:** 프론트 로직이 CRUD API 구조와 맞는 상태 이름으로 정리된다.
- [ ] **작업 8: Vue 생성/수정/삭제 액션 구현**
- **대상 파일:** `/Users/woozooni/Documents/trae_projects/skillDesk/frontend/src/main.js` (수정)
- **할 일:** `fetch`를 사용해 생성, 수정, 삭제 요청을 보내고 성공 후 목록을 다시 불러오거나 상태를 갱신한다.
- **최소 구현 예시:**
```javascript
const createMessage = async () => {
await fetch(`${API_BASE_URL}/messages`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ content: newContent.value.trim() }),
})
await loadMessages()
}
```
- **검증 명령:** `python3 backend/init_db.py`
- **기대 결과:** 프론트에서 각 버튼이 API 호출 함수와 연결된다.
- [ ] **작업 9: Vue 템플릿을 목록형 CRUD UI로 교체**
- **대상 파일:** `/Users/woozooni/Documents/trae_projects/skillDesk/frontend/src/main.js` (수정)
- **할 일:** 입력 폼, 목록, 인라인 편집, 빈 상태, 에러 상태를 모두 표시하는 템플릿으로 교체한다.
- **최소 구현 예시:**
```html
<form @submit.prevent="createMessage">
<input v-model="newContent" />
<button type="submit">추가</button>
</form>
<li v-for="message in messages" :key="message.id">
<span>{{ message.content }}</span>
</li>
```
- **검증 명령:** `python3 -m http.server 5173 -d frontend`
- **기대 결과:** 브라우저에서 목록형 CRUD 화면이 렌더링된다.
- [ ] **작업 10: README 실행/검증 문구를 CRUD 기준으로 갱신**
- **대상 파일:** `/Users/woozooni/Documents/trae_projects/skillDesk/README.md` (수정)
- **할 일:** 단일 조회 설명을 목록형 CRUD 예제 설명으로 바꾸고, 확인 포인트를 CRUD 흐름에 맞게 수정한다.
- **최소 구현 예시:**
```markdown
- 백엔드 API: `http://127.0.0.1:8000/api/messages`
- 프론트엔드 화면: `http://127.0.0.1:5173`
- 정상 동작 시 메시지 추가, 수정, 삭제가 모두 가능하다.
```
- **검증 명령:** `python3 -m py_compile backend/init_db.py backend/main.py`
- **기대 결과:** README만 읽어도 CRUD 예제 실행과 확인 방법을 이해할 수 있다.
- [ ] **작업 11: 백엔드 문법과 API 흐름 검증**
- **대상 파일:** `/Users/woozooni/Documents/trae_projects/skillDesk/backend/init_db.py` (검증), `/Users/woozooni/Documents/trae_projects/skillDesk/backend/main.py` (검증)
- **할 일:** DB를 초기화하고, Python에서 API 함수를 직접 호출해 생성, 조회, 수정, 삭제 흐름이 모두 동작하는지 확인한다.
- **실행 명령:**
```bash
python3 backend/init_db.py
python3 - <<'PY'
from backend.main import MessagePayload, create_message, delete_message, list_messages, update_message
print("LIST-1", list_messages())
created = create_message(MessagePayload(content="plan create"))
print("CREATED", created)
print("LIST-2", list_messages())
updated = update_message(created["id"], MessagePayload(content="plan update"))
print("UPDATED", updated)
print("LIST-3", list_messages())
print("DELETED", delete_message(created["id"]))
print("LIST-4", list_messages())
PY
```
- **기대 결과:** 각 단계 출력에 따라 CRUD가 순서대로 성공한다.
- [ ] **작업 12: 진단 점검 및 인라인 실행 정리**
- **대상 파일:** `/Users/woozooni/Documents/trae_projects/skillDesk/backend/main.py` (진단), `/Users/woozooni/Documents/trae_projects/skillDesk/frontend/src/main.js` (진단), `/Users/woozooni/Documents/trae_projects/skillDesk/README.md` (진단)
- **할 일:** 진단 도구로 오류를 확인하고 바로 수정한 뒤, 변경 파일과 실행 방법을 사용자에게 인계한다.
- **검증 도구:** IDE 진단 확인
- **기대 결과:** 새 오류 없이 CRUD 예제를 실행할 수 있는 상태로 마무리된다.