Skip to content

[AIBE3/5팀/임창기] TODO APP 만들기 완료#34

Open
gregoryc103 wants to merge 10 commits intosik2:mainfrom
gregoryc103:feature/dev
Open

[AIBE3/5팀/임창기] TODO APP 만들기 완료#34
gregoryc103 wants to merge 10 commits intosik2:mainfrom
gregoryc103:feature/dev

Conversation

@gregoryc103
Copy link

WTL 2주차 프로젝트: TodoAgent 개발 완료 정리

프로젝트 개요

프로젝트명

TodoAgent - GPT 기반 팀 할일 관리 시스템

main

개발 목표

  • 기존 Todo 애플리케이션에 GPT 채팅 기능 통합
  • 환경변수 기반 API 키 관리 시스템 구축
  • 팀 협업을 위한 멤버 관리 기능 개발
  • Context API를 활용한 전역 상태 관리 구현

주요 특징

  • AI 어시스턴트: GPT-3.5-turbo 기반 할일 관리 도우미
  • 팀 협업: 멤버별 할일 배정 및 진행률 추적
  • 보안 강화: 환경변수를 통한 API 키 관리
  • 실시간 동기화: localStorage 기반 데이터 영속성

기술 스택 및 아키텍처

핵심 기술

  • Frontend: React 19.1.0 + Vite 7.0.0
  • 스타일링: Tailwind CSS (CDN) + Custom CSS
  • 상태관리: React Context API + useReducer
  • AI 연동: OpenAI GPT-3.5-turbo API
  • 보안: 환경변수 기반 API 키 관리

Tailwind CSS 설정 (PostCSS 문제로 CDN 사용)

PostCSS 설정 이슈로 인해 Tailwind CSS를 CDN 방식으로 구성:

<!-- index.html -->
<script src="https://cdn.tailwindcss.com"></script>

설정 변경 사항:

  • 로컬 Tailwind 패키지 제거
  • PostCSS, Autoprefixer 의존성 제거
  • CDN 기반 Tailwind 사용으로 빌드 복잡성 감소

패키지 구성

{
  "dependencies": {
    "crypto-js": "^4.2.0",
    "react": "^19.1.0",
    "react-dom": "^19.1.0"
  },
  "devDependencies": {
    "@types/crypto-js": "^4.2.2",
    "vite": "^7.0.0"
  }
}

프로젝트 구조

src/
├── App.jsx                 # 메인 애플리케이션 컴포넌트
├── main.jsx               # 애플리케이션 진입점 (Provider 래핑)
├── TodoContext.jsx        # Todo 전역 상태 관리
├── ChatContext.jsx        # AI 채팅 상태 관리
├── components/            # 재사용 가능한 컴포넌트들
│   ├── TodoItem.jsx       # 개별 Todo 아이템
│   ├── TodoListSection.jsx # Todo 목록 섹션
│   ├── TodoWriteForm.jsx  # Todo 작성 폼
│   └── ChatSidebar.jsx    # AI 채팅 사이드바
├── hooks/
│   └── useTodos.js        # Todo 관련 비즈니스 로직
└── index.css              # Custom CSS (Tailwind CDN 사용)

핵심 구현 내용

1. 전역 상태 관리 (Context API)

TodoContext.jsx - 메인 상태 관리

// 전역으로 관리하는 주요 상태들
const [todos, setTodos] = useState([])
const [teamMembers, setTeamMembers] = useState([])
const [inputText, setInputText] = useState('')
const [checkedIds, setCheckedIds] = useState([])
const [selectedAssignee, setSelectedAssignee] = useState('')
const [selectedPriority, setSelectedPriority] = useState('medium')
const [filterAssignee, setFilterAssignee] = useState('all')
const [filterStatus, setFilterStatus] = useState('all')

// localStorage 자동 동기화
useEffect(() => {
  if (isLoaded && todos.length > 0) {
    localStorage.setItem('todoagent_todos', JSON.stringify(todos))
  }
}, [todos, isLoaded])

주요 기능:

  • 할일 목록 및 팀 멤버 전역 관리
  • localStorage 자동 동기화
  • 필터링 상태 관리
  • ID 자동 증가 관리

ChatContext.jsx - 채팅 관리

// 환경변수에서 API 키 가져오기
const apiKey = import.meta.env.VITE_OPENAI_API_KEY

const sendMessage = async (userMessage, todoContext = null) => {
  // 시스템 메시지 구성
  let systemMessage = `당신은 팀 할일 관리를 도와주는 AI 어시스턴트입니다.`
  
  // Todo 컨텍스트 정보 추가
  if (todoContext) {
    systemMessage += `\n\n현재 할일 현황:
- 전체 할일: ${todoContext.todos?.length || 0}
- 완료된 할일: ${todoContext.todos?.filter(todo => todo.completed).length || 0}
- 진행률: ${todoContext.progress || 0}%`
  }

  const response = await fetch('https://api.openai.com/v1/chat/completions', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${apiKey}`,
    },
    body: JSON.stringify({
      model: 'gpt-3.5-turbo',
      messages: [
        { role: 'system', content: systemMessage },
        ...messages.slice(-10), // 최근 10개 메시지만 포함
        { role: 'user', content: userMessage },
      ],
      max_tokens: 500,
      temperature: 0.7,
    }),
  })
}

2. 컴포넌트별 주요 기능

App.jsx - 메인 레이아웃

main2

chat

// 3분할 레이아웃 구현
return (
  <div className="flex h-screen border-4 border-wood-brown box-border">
    {/* 왼쪽: 팀 멤버 관리 */}
    <div className="w-80 bg-white border-r-4 border-wood-brown">
      {/* 팀 멤버 추가/삭제/통계 */}
    </div>

    {/* 중앙: 메인 Todo 관리 */}
    <div className="flex-1 mr-96 p-5 font-mono bg-cream flex flex-col">
      {/* 진행률, Todo 폼, 필터, 목록 */}
    </div>

    {/* 오른쪽: 채팅 사이드바 */}
    <ChatSidebar teamMembers={teamMembers} />
  </div>
)

ChatSidebar.jsx - 채팅 인터페이스

chat

const handleSendMessage = async () => {
  // Todo 컨텍스트 정보 준비
  const todoContext = {
    todos,
    progress: getOverallProgress ? getOverallProgress() : 0,
    teamMembers: [],
  }

  await sendMessage(inputMessage, todoContext)
  setInputMessage('')
}

채팅 기능:

  • 실시간 메시지 교환
  • Todo 현황 기반 AI 조언
  • 메시지 히스토리 localStorage 저장
  • 로딩 상태 표시

3. 환경변수 기반 API 키 관리

.env 파일 설정

VITE_OPENAI_API_KEY= api key 입력

.gitignore 보안 설정

# Environment variables
.env
.env.local
.env.development.local
.env.test.local
.env.production.local

보안 특징:

  • API 키 환경변수 관리
  • Git 버전 관리에서 제외
  • 개발/프로덕션 환경 분리

UI/UX 디자인

디자인 콘셉트

  • 테마: 클래식 닌텐도 분위기 디자인
  • 레이아웃: 3분할 고정 레이아웃 (팀관리-메인-채팅)

CSS 구조 (Tailwind CDN + Custom CSS)

/* Tailwind 기본 유틸리티 사용 */

.flex, .h-screen, .border-4, .w-80 /* CDN에서 로드 */

데이터 플로우 및 상태 관리

상태 관리 아키텍처

App.jsx (진입점)
    ↓
TodoProvider + ChatProvider (Context Providers)
    ↓
┌─────────────────┬─────────────────┬─────────────────┐
│   TeamManagement │    TodoManager   │   ChatSidebar   │
│                 │                 │                 │
│ - 멤버 추가/삭제  │ - Todo CRUD     │ - AI 메시지    │
│ - 진행률 표시    │ - 필터링/정렬    │ - 컨텍스트 인식 │
│ - 색상 관리      │ - 일괄 처리     │ - 히스토리 관리 │
└─────────────────┴─────────────────┴─────────────────┘
    ↓                ↓                ↓
localStorage      localStorage     localStorage
(team_members)     (todos)         (chat_messages)

주요 상태 변화 시나리오

1. Todo 추가 플로우

1. 사용자 입력  TodoWriteForm
2. handleSubmit() 호출  useTodos
3. Context 상태 업데이트  TodoContext
4. localStorage 자동 저장
5. UI 리렌더링  TodoListSection

2. AI 채팅 플로우

1. 사용자 메시지 입력  ChatSidebar
2. Todo 컨텍스트 수집  App.jsx
3. OpenAI API 호출  ChatContext
4. AI 응답 받기  표시
5. 메시지 히스토리 저장  localStorage

보안 및 검증

보안 측면

1. API 키 관리

  • 환경변수를 통한 API 키 보호
  • .gitignore를 통한 소스코드 노출 방지
  • 프론트엔드 한계 인지 (향후 백엔드 프록시 계획)

2. 데이터 검증

// 입력값 검증
if (!inputText.trim()) {
  alert('할 일을 입력해주세요.')
  return
}

// 팀 멤버 중복 검사
if (teamMembers.some((member) => member.name === memberName.trim())) {
  alert('이미 존재하는 팀원 이름입니다.')
  return
}

주요 기능 코드

1. 팀 멤버 추가 기능

const handleAddMember = () => {
  if (!memberName.trim()) {
    alert('팀원 이름을 입력해주세요.')
    return
  }

  const newMember = {
    id: nextMemberId.current,
    name: memberName.trim(),
    color: colorPalette[(nextMemberId.current - 1) % colorPalette.length],
  }

  setTeamMembers([...teamMembers, newMember])
  
  if (teamMembers.length === 0) {
    setSelectedAssignee(newMember.name)
  }

  nextMemberId.current += 1
}

2. 일괄 완료 처리 기능

const handleBulkComplete = () => {
  const selectedTodos = todos.filter((todo) => checkedIds.includes(todo.id))
  const completedCount = selectedTodos.filter((todo) => todo.completed).length
  
  let shouldComplete = true
  if (completedCount === selectedTodos.length) {
    shouldComplete = false // 모두 완료됨 → 미완료로 변경
  }

  const confirmComplete = window.confirm(
    `선택된 ${checkedIds.length}개의 항목을 ${shouldComplete ? '완료' : '미완료'}로 변경하시겠습니까?`
  )
  
  if (confirmComplete) {
    setTodos(todos.map((todo) =>
      checkedIds.includes(todo.id) ? { ...todo, completed: shouldComplete } : todo
    ))
    setCheckedIds([])
  }
}

3. 진행률 계산 기능

const getOverallProgress = () => {
  const totalTodos = todos.length
  const completedTodos = todos.filter((todo) => todo.completed).length
  return totalTodos > 0 ? Math.round((completedTodos / totalTodos) * 100) : 0
}

const getTeamStats = () => {
  const stats = {}
  teamMembers.forEach((member) => {
    const memberTodos = todos.filter((todo) => todo.assignee === member.name)
    const completedTodos = memberTodos.filter((todo) => todo.completed)
    stats[member.name] = {
      total: memberTodos.length,
      completed: completedTodos.length,
      percentage: memberTodos.length > 0 
        ? Math.round((completedTodos.length / memberTodos.length) * 100) 
        : 0,
    }
  })
  return stats
}

향후 개선 계획

1. 보안 강화 방안

  • 백엔드 프록시 서버 구축: API 키 완전 은닉
  • 사용자 인증 시스템: JWT 기반 로그인
  • 데이터 암호화: 민감 정보 암호화 저장

2. 기능 확장 계획

  • AI 기능 고도화:
    • 할일 자동 생성 및 분류
    • 우선순위 자동 추천
    • 업무 패턴 분석 및 조언
  • 실시간 협업: WebSocket 기반 실시간 동기화

문제 해결 과정

  1. API 키 관리: Local Storage → 환경변수 → (향후) 백엔드 프록시
  2. 상태 관리: useState → Context API로 복잡성 해결
  3. 스타일링 이슈: PostCSS 문제로 Tailwind CDN 방식 채택

결론

향후 백엔드 프록시 서버 구축과 실시간 협업 기능 추가를 통해 엔터프라이즈급 애플리케이션으로 발전시킬 계획입니다.


개발자: [임창기]
기술 스택: React 19 + Vite + Tailwind CSS (CDN) + OpenAI API

gregoryc103 and others added 10 commits July 10, 2025 01:40
- 프로젝트 구조, 기술 스택, 기능 요약 등을 README.md에 문서화
- 이후 팀원/사용자들이 전체 개요를 빠르게 이해할 수 있도록 목적 정의
- Tailwind CSS CDN 방식 연결 완료
- index.html 타이틀 수정 ("React Todo App with Chat")
- 기본 폴더 구조 생성: components/, hooks/, contexts/
- index.css에 기본 스타일 설정
- TodoContext.jsx: todo 상태 관리 구현 (추가, 삭제, 완료 토글 등)
- ChatContext.jsx: 채팅 메시지 상태 및 사이드바 열림/닫힘 상태 관리
- useReducer 기반 전역 상태 관리 구조 도입
- 각각의 context에 대한 커스텀 훅(useTodoContext, useChatContext) 제공
- 로컬 스토리지 연동: todos 자동 저장 및 초기 로드 처리
- todo 생성, 수정, 삭제, 완료 토글 기능 구현
- 완료/미완료 필터링 및 총 개수 계산 유틸리티 포함
- Context API와 연계하여 전역 상태 관리 대응
- TodoItem.jsx: 개별 아이템 표시, 완료 토글, 인라인 수정 및 삭제
- TodoWriteForm.jsx: 새 Todo 입력 및 추가 기능 구현
- TodoListSection.jsx: 목록 렌더링, 필터링, 통계 출력, 일괄 작업 처리
- Context + useTodos 훅 기반 상태 연동
- ChatSidebar.jsx: 실시간 채팅 UI 구현, 자동 응답 및 애니메이션 효과
  적용
  - App.jsx: 전체 앱 통합, Context Provider 적용 및 레이아웃 구성
  - 전체 기능 통합 완료:
    • Todo 관리 (추가/수정/삭제/완료)
    • 필터링 (전체, 진행중, 완료)
    • 로컬 스토리지 저장
    • 채팅 사이드바 기능
    • Tailwind CSS 기반 반응형 디자인 적용
- 레이아웃 및 스타일 수정 (반응형/색상/마진 등)
- Chat & Todo UI 요소 세부 조정
- 마운트 시 오류, 상태 누락 등 통합 테스트 중 발견된 버그 수정
- 전체 기능 정상 작동 확인
@1J-Choi
Copy link

1J-Choi commented Jul 10, 2025

채팅 기능 및 프로그레스 바 구현 등의 다양하게 확장된 기능이 인상적이였습니다.
또한 생소할 수 있는 기능의 문서 정리가 잘 되어있어 파악하기 쉬웠습니다!

@weare0gimbab
Copy link

todo list에 ai활용 채팅기능이라니 완전 신박한것 같아요!🙌 함수 네이밍도 직관적이네요! 혹시 API키가 환경변수에 잘 적용된것 같은데 호출에 실패한 원인은 뭘까요?

@Park-seungg
Copy link

채팅 기능에 AI를 활용한 점과 생소한 문법을 체험할 수 있었던 점이 인상 깊었습니다.
또한, 코드 설명 덕분에 흐름 파악이 훨씬 쉬웠습니다.

@gregoryc103
Copy link
Author

gregoryc103 commented Jul 10, 2025

todo list에 ai활용 채팅기능이라니 완전 신박한것 같아요!🙌 함수 네이밍도 직관적이네요! 혹시 API키가 환경변수에 잘 적용된것 같은데 호출에 실패한 원인은 뭘까요?

@weare0gimbab 안녕하세요 연서님, 문의주신 내용 답변 드립니다.
실패 원인은 .env 파일에 api key를 입력하지 않아 실패 문구를 반환받은 것입니다.
아래 사진은 실제 api key를 입력 후 실행 했을 때 동작 사진 입니다. 감사합니다.

image

@ehgk4245
Copy link

AI 채팅 기능과 Todo 현황 기반 AI 조언 기능을 추가한 아이디어가 매우 참신하며, 기존 Todo 앱의 기능과도 훌륭하게 조화를 이루고 있는 것 같습니다!
UI의 톤, 배치, 그리고 컨셉 또한 완성도가 매우 높아 보여 사용자 경험에 큰 긍정적 영향을 줄 것으로 기대됩니다🤩

@jookyworld
Copy link

학습 내용을 넘은 많은 내용이 포함되어 있었지만
기능과 코드에 대한 상세한 설명이 잘 정리되어 있어 이해하기 수월했습니다!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants