Files
skillDesk/docs/superpowers/plans/2026-06-09-sqlite-fastapi-vue-crud.md
2026-06-10 12:49:53 +09:00

11 KiB

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건을 유지하는 방식으로 정리한다.
    • 최소 구현 예시:
      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 모델을 추가한다.
    • 최소 구현 예시:
      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 오름차순으로 반환한다.
    • 최소 구현 예시:
      @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 엔드포인트를 추가해 메시지를 저장하고 생성된 idcontent를 반환한다.
    • 최소 구현 예시:
      @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를 반환한다.
    • 최소 구현 예시:
      @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} 엔드포인트를 추가해 해당 메시지를 삭제하고 성공 여부를 반환한다.
    • 최소 구현 예시:
      @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 상태로 교체하고 목록 조회 함수를 만든다.
    • 최소 구현 예시:
      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를 사용해 생성, 수정, 삭제 요청을 보내고 성공 후 목록을 다시 불러오거나 상태를 갱신한다.
    • 최소 구현 예시:
      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 (수정)
    • 할 일: 입력 폼, 목록, 인라인 편집, 빈 상태, 에러 상태를 모두 표시하는 템플릿으로 교체한다.
    • 최소 구현 예시:
      <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 흐름에 맞게 수정한다.
    • 최소 구현 예시:
      - 백엔드 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 함수를 직접 호출해 생성, 조회, 수정, 삭제 흐름이 모두 동작하는지 확인한다.
    • 실행 명령:
      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 예제를 실행할 수 있는 상태로 마무리된다.