본문 바로가기
하루하루/일상

클로드3.5, 챗지피티4o 도움 받아 생애 첫 앱(습관 트래커) 개발 성공

by 오송인 2024. 6. 26.
반응형

개발을 하고 싶었던 이유, 파이썬 공부 지속의 어려움, 공부 재시작

옵시디언 쓰면서 제가 가진 자료를 체계화하는 데 도움을 주는 많은 플러그인을 사용해 왔습니다. 많을 때는 70~80개까지 쓴 것 같아요. 특히 안피곤님이 만든 티스토리 플러그인이 있어서 티스토리 블로그에 옵시디언 글을 수월하게 업로드할 수 있었습니다.(아쉽지만 티스토리 정책 변경으로 지금은 사용 못 합니다.)

개발은 매우 직접적이고 가시적인 방식으로 사람의 일상을 편리하게 만드는 것 같습니다. 십수년 동안 임상/상담심리학을 공부해 온 저로서는 개발의 이런 점이 너무 매력적으로 느껴집니다. 마음은 기본적으로 보이지 않는 것이잖아요. 손 재주가 있다면 목공이라도 배웠을 테지만 손이 닿으면 물건이 망가지는 마이너스 손에게 개발은 심리학을 배울 때와는 질적으로 다른 즐거움을 선물하는 듯했습니다.

이에 작년 10월 중순 무렵부터 본격적으로 파이썬을 공부하기 시작했습니다. 하지만 2월 무렵까지 하다가 손을 놓았습니다. Udemy 코스를 따라가는 중이었는데, 간단한 예제 문제 푸는 데 한 시간 이상 걸리니 점점 하기 싫어지더군요. 챗지피티의 도움을 받을 수 있었지만, 그렇게 배우면 왠지 발전이 없을 것 같아서 구글링해서 많은 시행착오를 겪으며 예제를 하나씩 풀었습니다. 세 달 동안 Udemy 코스는 들어가 보지도 않게 된 게 그 결과입니다.

그러다가 이번에 클로드3.5의 Artifacts 기능을 보면서 다시 재도전해 봐야겠다는 생각이 들었습니다. 예제는 챗지피티나 클로드가 풀게 하고 그저 주마간산으로 한 번 훑어보며 Udemy 코스를 완주하는 데 주안점을 두기로 했습니다.

클로드3.5로 천군만마를 얻었으니 앱을 개발해 보자

코스를 달리는 동시에 제가 만들어 보고 싶은 앱을 개발해 보는 것도 좋겠다 싶어서 어제 오늘 꼬박 네 시간 투자하여 습관 트래커를 만들었습니다. 일상의 습관을 기록하는 앱입니다. 매일 각 습관을 특정 기준에 따라 1점, 2점, 3점으로 평정하여 주간 그래프와 연간 그래프를 볼 수 있게 했습니다. Firebase를 사용하여 로그인 기능과 데이터 저장 기능까지 추가했습니다. 아래 그 과정을 복기한 내용입니다.

완성된 앱은 다음과 같습니다. React App

초기 형태

처음에는 아래와 같은 형태였습니다.

이미지가 보이지 않으면 새로고침을 눌러주세요.

그런데 Monthly Score가 합산이 제대로 안 돼 수정하게 했을 때 클로드가 React란 것을 사용하여 구현하더군요. 디폴트 점수가 0이어야 하는데 1로 돼 있다거나 개별 습관 점수 4점에 Monthly Score가 1점씩 올라가는 사소한 오류들을 해결하는 데 시간을 약간 썼습니다. 제 요구사항이 잘 반영된 코드는 아래와 같습니다.

import React, { useState } from 'react';

const habits = [
  { name: 'Read (chapters)' },
  { name: 'Exercise (minutes)' },
  { name: 'Meditate (minutes)' },
];

const HabitTracker = () => {
  const [habitData, setHabitData] = useState(
    habits.map(habit => ({ ...habit, days: Array(7).fill(0) }))
  );

  const handleScoreChange = (habitIndex, dayIndex, score) => {
    const newHabitData = [...habitData];
    newHabitData[habitIndex].days[dayIndex] = score;
    setHabitData(newHabitData);
  };

  const calculateMonthlyScore = (habit) => {
    return habit.days.reduce((total, score) => total + score, 0);
  };

  return (
    <div className="container mx-auto p-4">
      <h1 className="text-2xl font-bold mb-4">Advanced Habit Tracker</h1>
      <table className="w-full border-collapse">
        <thead>
          <tr>
            <th className="border p-2">Habit</th>
            {[...Array(7)].map((_, i) => (
              <th key={i} className="border p-2">{new Date(2024, 5, 19 + i).getDate()}</th>
            ))}
            <th className="border p-2">Monthly Score</th>
          </tr>
        </thead>
        <tbody>
          {habitData.map((habit, habitIndex) => (
            <tr key={habitIndex}>
              <td className="border p-2">{habit.name}</td>
              {habit.days.map((score, dayIndex) => (
                <td key={dayIndex} className="border p-2">
                  <select
                    value={score}
                    onChange={(e) => handleScoreChange(habitIndex, dayIndex, parseInt(e.target.value))}
                    className="w-16 p-1 border rounded"
                  >
                    <option value={0}>0</option>
                    <option value={1}>1</option>
                    <option value={2}>2</option>
                    <option value={3}>3</option>
                  </select>
                </td>
              ))}
              <td className="border p-2 font-bold">{calculateMonthlyScore(habit)}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
};

export default HabitTracker;

그 다음에 주차별 각 습관의 추이를 그래프로 보고 싶다고 주문하니 아래와 같이 만들었습니다. 이후 월을 선택할 수 있게 수정했습니다.

웹 앱 배포를 성공해 보자

클로드 유료 사용자가 아닌지라 limit에 걸려서 다음 날 챗지피티로 넘어와 다시 시작했습니다. 웹 앱을 배포하는 데까지 성공하고 싶었습니다. 이 때부터 터미널에서 많은 시행착오를 거쳤습니다.

  1. Create React App 설치 및 프로젝트 생성
  2. npm 버전 업데이트
  3. 데이터 시각화 라이브러리인 recharts 설치

여기까지 성공한 다음에 로그인 기능과 데이터베이스까지 갖추고 싶어서

  1. Firebase 설치 및 프로젝트 설정
  2. Firebase 인증 설정
  3. Firestore 데이터베이스 설정
  4. React 애플리케이션에 Firebase 인증 및 Firestore 통합
  5. Vercel 로그인 후 프로젝트 배포 등을 거쳤습니다.

내 컴퓨터 안에 있던 앱이 Vercel을 통해 웹에 잘 배포가 되었습니다. 그런데 login과 signup 버튼을 눌러도 아무 반응이 없어서 꽤 많은 시간 이 문제를 해결하고자 시행착오를 거쳤습니다.

몇 번을 코드 수정 후 재배포해도 동일한 증상이 나타납니다. 챗지피티에게 물어보니 "브라우저의 콘솔에서 발생하는 오류를 확인하고 추가적인 디버깅을 진행하세요."라고 하는데 브라우저 콘솔이 어디 붙어 있는 거고 또 디버깅은 어떻게 하는건지 몰라서 챗지피티에게 물어보니 아래와 같이 답합니다.

### 1. 브라우저 콘솔 열기

1. **Google Chrome 열기**: Google Chrome 브라우저를 엽니다.
2. **개발자 도구 열기**:
    - 키보드 단축키: `F12` 키를 누르거나 `Ctrl + Shift + I` (Windows/Linux) 또는 `Cmd + Option + I` (Mac)를 누릅니다.
    - 메뉴 사용: Chrome 브라우저의 오른쪽 상단에 있는 세 개의 점 아이콘을 클릭한 다음 `More tools` -> `Developer tools`를 선택합니다.

### 2. 콘솔 탭으로 이동

개발자 도구 창이 열리면 상단의 탭 중에서 `Console` 탭을 클릭합니다. 여기에서 애플리케이션 실행 중 발생하는 오류 메시지 및 경고를 확인할 수 있습니다.

### 3. 애플리케이션에서 액션 수행

애플리케이션에서 로그인 또는 회원가입 버튼을 클릭합니다. 이때 콘솔에서 발생하는 오류 메시지를 확인합니다.

### 4. 오류 메시지 확인 및 디버깅

콘솔에 표시되는 오류 메시지를 확인하고, 문제가 발생하는 부분을 수정합니다. 예를 들어, 로그인 버튼을 클릭했을 때 오류 메시지가 나타난다면 해당 메시지를 바탕으로 원인을 파악할 수 있습니다.

하라는 대로 해보니 아래와 같은 오류가 떴고 대응 방안을 살폈습니다.

"Failed to load resource: the server responded with a status of 401 ()" 오류는 브라우저가 리소스에 접근하려 했지만 유효한 인증 자격 증명을 제공하지 못했기 때문에 서버에서 접근을 거부했음을 의미합니다. 이 문제를 해결하기 위해 다음 단계를 따라 문제의 원인을 파악하고 해결해 보겠습니다. 1. Firebase 인증 설정 확인...(중략) 4. Firestore 보안 규칙 확인 (후략)

1번 확인을 위해 firebase.js를 열어보면 아래처럼 ID, Key 등을 넣는 데가 있습니다. 이걸 안 넣은 게 문제임을 확인했습니다. 하지만 구글 firebase 콘솔 어디에 ID와 apiKey가 있는지 찾는 데 꽤 걸렸습니다.

const firebaseConfig = {
  apiKey: "YOUR_API_KEY",
  authDomain: "YOUR_AUTH_DOMAIN",
  projectId: "YOUR_PROJECT_ID",
  storageBucket: "YOUR_STORAGE_BUCKET",
  messagingSenderId: "YOUR_MESSAGING_SENDER_ID",
  appId: "YOUR_APP_ID"
};

const app = initializeApp(firebaseConfig);

export const auth = getAuth(app);
export const db = getFirestore(app);

아래 사진에서처럼 자기가 만든 앱을 클릭해서 들어가면면

아래화면처럼 나오고요, 자기가 만든 앱 이름을 다시 한 번 클릭하면 톱니바퀴 모양이 나옵니다. 톱니바퀴 클릭해서 들어가면

아래처럼 프로젝트 셋팅이 뜹니다. General 탭을 스크롤 하셔서 하단으로 내려가시면 apiKey, authDomain 등 필요한 정보가 나옵니다. 스크롤을 꼭 내리셔야 저처럼 시간낭비 안 합니다.

4번도 안 했더군요. Firestore Database에서 Rules로 이동하여 아래 코드 넣으라고 하는데 Rules가 어디 붙어 있는지 약간 헤맸습니다.

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth != null;
    }
  }
}

이후에도 입력한 습관 데이터 저장이 되지 않는 문제가 반복돼 스트레스 받다가 잠시 포기하고 점심 먹으러 갔습니다. 그런데 점심 먹고 돌아와서 다시 해보니 되더군요. 역시 잘 안 될 때는 맥락을 바꿨다가 다시 도전하는 게 좋다는 것을 배웁니다.

챗지피티에만 의존하면 뭐가 문제였고 뭐가 해결책이었는지 정확히 알기 어려운 부분이 있기 때문에, 개발을 기초부터 잘 배워야 하겠다는 생각을 합니다. 이하 챗지피티가 전체 개발 과정을 요약하고 인싸이트 도출한 내용입니다.

챗지피티가 배움의 과정을 요약하고 인싸이트 도출

1. 시행착오 과정을 통해 최종 Habit Tracker를 완성한 이야기

처음에 나는 습관을 기록할 수 있는 간단한 웹페이지를 만들기 시작했어. 이 페이지는 상단에 날짜가 있고 좌측 1열에는 각각의 습관이 있는 형태로, 각 날짜와 각 습관이 만나는 지점에 체크 표시를 할 수 있도록 구성했지. 그리고 가장 우측 열에는 그 습관을 몇 번 했는지 빈도수를 표시하려고 했어. 이 기본적인 구상에서 시작해서 여러 문제를 해결하며 점점 더 기능을 확장해 나갔어.

처음에는 HTML과 JavaScript를 이용해 간단한 테이블 형태의 페이지를 구성했어. 날짜와 습관 이름을 동적으로 추가하고, 각 셀에 체크박스를 배치해서 사용자가 습관을 기록할 수 있도록 했지. 체크박스를 클릭할 때마다 빈도수가 자동으로 계산되어 우측 열에 표시되도록 했어.

그러나 점점 더 많은 기능을 추가하면서, React와 같은 라이브러리를 사용하여 상태 관리를 더 효율적으로 해야겠다는 생각이 들었어. 그래서 Habit Tracker를 React로 구현하기로 결정했지. 이를 통해 상태 관리가 더 쉬워졌고, 컴포넌트를 재사용할 수 있었어.

그 후, Firebase를 이용해 사용자의 습관 데이터를 저장하고 불러오는 기능을 추가했어. 이를 통해 사용자가 로그인하고 자신의 데이터를 안전하게 저장하고, 나중에 불러올 수 있게 되었지. 이 과정에서 Firestore 보안 규칙 설정과 관련된 문제를 해결하며 데이터 접근 권한을 관리했어.

마지막으로, 연간 트렌드 그래프와 주차별 트렌드 그래프를 추가해서 사용자가 자신의 습관 변화를 시각적으로 쉽게 확인할 수 있도록 했어. 이를 통해 단순한 기록에서 벗어나 시각적인 피드백을 제공할 수 있게 되었지.

2. 어떤 문제에 봉착했고 어떻게 해결했나

문제 1: 초기 상태 관리

  • 봉착한 문제: 초기 상태를 어떻게 관리할지, 체크박스를 어떻게 동적으로 생성할지 고민이 많았어.
  • 질문: "초기 상태를 어떻게 설정해야 할까?", "체크박스를 동적으로 생성하는 가장 좋은 방법은 무엇일까?"
  • 해결 방법: React를 도입하여 상태 관리를 효율적으로 하고, 컴포넌트 기반으로 체크박스를 동적으로 생성.

문제 2: 데이터 저장 및 불러오기

  • 봉착한 문제: 사용자 데이터를 안전하게 저장하고 불러오기 위한 방법이 필요했어.
  • 질문: "사용자 데이터를 어떻게 저장하고 불러올 수 있을까?", "데이터베이스 보안 규칙은 어떻게 설정해야 할까?"
  • 해결 방법: Firebase와 Firestore를 도입하여 사용자 데이터를 안전하게 관리하고, 보안 규칙을 설정하여 데이터 접근 권한을 관리.

문제 3: 상태 동기화 및 캐시 문제

  • 봉착한 문제: 여러 개의 탭에서 같은 데이터를 동시에 사용하려고 할 때 문제가 생겼어. 예를 들어, 컴퓨터에서 인터넷 창을 두 개 열고 같은 습관 기록 앱을 사용하려고 하면, 데이터가 제대로 동기화되지 않아서 혼란스러울 수 있었어. 또, 데이터가 컴퓨터에 임시로 저장되는 방식(IndexedDB)에서 오류가 발생했어.
  • 질문: "여러 개의 인터넷 창에서 같은 데이터를 사용할 때 문제가 없도록 하려면 어떻게 해야 할까?", "임시 저장되는 데이터 오류를 어떻게 해결할 수 있을까?"
  • 해결 방법: Firestore라는 도구에서 제공하는 설정을 사용해서 여러 개의 창이 동시에 열려 있을 때도 데이터를 잘 동기화할 수 있도록 만들었어. 그리고 IndexedDB 캐시 문제를 해결하기 위해 필요한 설정을 추가했어. 이 설정들은 데이터를 안전하게 저장하고, 여러 창에서 사용하더라도 문제가 생기지 않게 도와줬어.

문제 4: 시각화 및 데이터 입력

  • 봉착한 문제: 사용자가 입력한 데이터를 기반으로 주차별 및 연간 트렌드를 시각화하고, 데이터 입력을 쉽게 할 수 있는 방법이 필요했어.
  • 질문: "주차별 및 연간 데이터를 어떻게 시각화할 수 있을까?", "데이터 입력을 더 직관적으로 만들 수 있을까?"
  • 해결 방법: Recharts 라이브러리를 사용하여 주차별 및 연간 데이터를 시각화하고, 드롭다운 메뉴를 통해 데이터를 입력하도록 수정.

3. 인사이트 및 추후 활용 방안

인사이트

  1. 효율적인 상태 관리: React와 같은 프레임워크를 사용하여 상태 관리를 효율적으로 할 수 있으며, 이는 특히 복잡한 UI에서 큰 도움이 됨을 배웠어.
  2. 데이터베이스 보안 및 관리: Firebase와 Firestore를 사용하여 사용자 데이터를 안전하게 관리할 수 있으며, 적절한 보안 규칙 설정의 중요성을 깨달았어.
  3. 사용자 경험 향상: 시각적인 피드백을 제공하는 것이 사용자 경험을 크게 향상시킬 수 있음을 알게 되었어. 특히, 데이터 시각화는 사용자가 자신의 진행 상황을 쉽게 이해하고 동기부여를 높이는 데 매우 효과적이었어.
  4. 실시간 데이터 처리: 실시간 데이터 동기화와 캐시 문제를 해결하는 것이 얼마나 중요한지, 그리고 이를 위한 다양한 도구와 방법이 있다는 것을 배웠어.

추후 활용 방안

  1. 프로젝트 확장: 이 인사이트를 바탕으로 더 복잡한 프로젝트를 확장하거나 새로운 기능을 추가할 때 적용할 수 있어.
  2. 다른 도메인 적용: 데이터 시각화와 실시간 상태 관리를 다른 도메인이나 프로젝트에 적용하여 사용자 경험을 향상시킬 수 있어.
  3. 보안 강화: 보안 규칙 설정과 데이터베이스 관리를 통해 안전한 웹 애플리케이션을 개발하는 데 도움이 될 수 있어.
  4. 개발 효율성 향상: 효율적인 상태 관리와 컴포넌트 기반 개발 방식을 통해 개발 효율성을 높일 수 있어.

이 과정을 통해 얻은 경험과 인사이트는 앞으로 더 나은 웹 애플리케이션을 개발하는 데 큰 도움이 될 거야. 추가적인 질문이나 도움이 필요하면 언제든지 말해줘!

반응형

댓글