<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>minn__ij.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Wed, 23 Jul 2025 08:02:39 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. minn__ij.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/minn__ij" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[TIL] TanStack Query 세팅, 사용 방법 정리 (useQuery)]]></title>
            <link>https://velog.io/@minn__ij/TIL-TanStack-Query-%EC%84%B8%ED%8C%85-%EC%82%AC%EC%9A%A9-%EB%B0%A9%EB%B2%95-%EC%A0%95%EB%A6%AC-useQuery</link>
            <guid>https://velog.io/@minn__ij/TIL-TanStack-Query-%EC%84%B8%ED%8C%85-%EC%82%AC%EC%9A%A9-%EB%B0%A9%EB%B2%95-%EC%A0%95%EB%A6%AC-useQuery</guid>
            <pubDate>Wed, 23 Jul 2025 08:02:39 GMT</pubDate>
            <description><![CDATA[<h1 id="1-설치">1. 설치</h1>
<blockquote>
<p>yarn add @tanstack/react-query
또는
npm install @tanstack/react-query</p>
</blockquote>
<blockquote>
<p>yarn add axios
yarn add -D @types/axios
또는
npm install axios
npm install --save-dev @types/axios</p>
</blockquote>
<p>@types/axios = 타입스크립트에서 axios를 인식시키기 위한 타입 정의 파일</p>
<h1 id="2-queryclientprovider-설정-앱-전역에-적용">2. QueryClientProvider 설정 (앱 전역에 적용)</h1>
<pre><code>import { StrictMode } from &quot;react&quot;;
import { createRoot } from &quot;react-dom/client&quot;;
import App from &quot;./App.tsx&quot;;
import { QueryClient, QueryClientProvider } from &quot;@tanstack/react-query&quot;;

const queryClient = new QueryClient();

createRoot(document.getElementById(&quot;root&quot;)!).render(
  &lt;StrictMode&gt;
    &lt;QueryClientProvider client={queryClient}&gt;
      &lt;App /&gt;
    &lt;/QueryClientProvider&gt;
  &lt;/StrictMode&gt;
);</code></pre><h1 id="3-api-요청-함수-만들기">3. API 요청 함수 만들기</h1>
<pre><code>import axios from &quot;axios&quot;;

export const getResults = async () =&gt; {
  const res = await axios.get(
&gt;     &quot;https://api주소&quot;
  );
  return res.data;
};
</code></pre><h1 id="4-커스텀-훅으로-usequery-사용">4. 커스텀 훅으로 useQuery 사용</h1>
<pre><code>import { useQuery } from &quot;@tanstack/react-query&quot;;
import { fetchUsers } from &quot;../api/example&quot;;

export const useUsersQuery = () =&gt; {
  return useQuery({
    queryKey: [&quot;users&quot;],
    queryFn: fetchUsers,
  });
};</code></pre><h1 id="5-컴포넌트에서-사용">5. 컴포넌트에서 사용</h1>
<pre><code>import { useUsersQuery } from &quot;../hooks/useUsersQuery&quot;;

function Home() {
  const { data, isLoading, isError } = useUsersQuery();

  if (isLoading) return &lt;div&gt;로딩 중...&lt;/div&gt;;
  if (isError) return &lt;div&gt;에러 발생&lt;/div&gt;;

  return (
    &lt;div&gt;
      &lt;h1&gt;사용자 목록&lt;/h1&gt;
      &lt;ul&gt;
        {data.map((user: any) =&gt; (
          &lt;li key={user.id}&gt;{user.name}&lt;/li&gt;
        ))}
      &lt;/ul&gt;
    &lt;/div&gt;
  );
}

export default Home;</code></pre><h1 id="폴더-구조-example">폴더 구조 example</h1>
<p>1.</p>
<p>├── apis/
│   └── api/
│        └── results.ts
│   └── services/
│        └── useGetResults.ts
├── pages/
│   └── Home.tsx
├── types/
│   └── result.d.ts
└── main.tsx</p>
<p>2.</p>
<p>src/
├── api/
│   └── example.ts
├── hooks/
│   └── useUsersQuery.ts
├── pages/
│   └── Home.tsx
├── types/
│   └── user.d.ts
└── main.tsx</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 19주차 월요일. 파이널 프로젝트 회고 - 1]]></title>
            <link>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-19%EC%A3%BC%EC%B0%A8-%EC%9B%94%EC%9A%94%EC%9D%BC</link>
            <guid>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-19%EC%A3%BC%EC%B0%A8-%EC%9B%94%EC%9A%94%EC%9D%BC</guid>
            <pubDate>Mon, 19 Aug 2024 13:01:06 GMT</pubDate>
            <description><![CDATA[<h1 id="보고서에-들어갈-내용-작성">보고서에 들어갈 내용 작성</h1>
<h3 id="🌈-맡은-기능">🌈 맡은 기능</h3>
<p>1) 실시간 채팅 기능
2) 실시간 알림 기능 일부
3) home 페이지, 헤더, 탭메뉴, 기능 일부</p>
<h3 id="🌈-사용한-라이브러리와-이유">🌈 사용한 라이브러리와 이유</h3>
<ul>
<li>zustand 사용해 count 전역 상태 관리 : 코드가 복잡하지 않으며 사용이 편리하고 유지보수에 용이</li>
</ul>
<h3 id="🌈-기술적으로-강조할-부분">🌈 기술적으로 강조할 부분</h3>
<ul>
<li>supabase realtime 활용한 실시간 인터렉션</li>
<li>supabase SQL editor로 안 읽은 메시지 숫자를 반환해주는 함수를 작성해 사용</li>
<li>useTapScroll 등 재사용이 가능한 코드는 hooks, utils 파일 만들어 재사용</li>
</ul>
<h3 id="🌈-기술적-의사-결정-과정사유">🌈 기술적 의사 결정 과정/사유</h3>
<ul>
<li>안 읽은 메시지 개수 세는 SQL 작성: 대량 데이터 처리가 필요한데 DB에서 계산해주면 효율적이라고 생각했습니다. DB 변경은 없는데 실시간으로 소통할 수 있고 클라이언트 사이드에서 코드로 가져오는 것보다 간결하고 처리가 빠를 것이라고 판단했습니다.</li>
</ul>
<h3 id="🌈-트러블-슈팅과-해결-과정">🌈 트러블 슈팅과 해결 과정</h3>
<ul>
<li>채팅 목록(chat)과 채팅방(chat/[id] 페이지 데스크탑 구현. 모바일에서는 따로 분리되었던 두 페이지의 UI가 데스크탑에선 같이 보여져야 했던 문제.
채팅 목록에서 채팅을 누르면 목록은 그대로 남아있고 옆에 채팅방이 뜨도록 만들어야 했습니다. 이 부분이 막막해서 며칠을 인스타그램 등의 다른 유사 서비스를 살펴보며, 구글링도 해보며 고민하고 우선은 다른 기능부터 작업하다가, 문득 정말 간단한 방법이 있다는 걸 떠올릴 수 있었습니다. chat 폴더의 layout.tsx에 컴포넌트를 넣는 방법입니다. layout.tsx에 채팅 리스트 컴포넌트를 넣고, 1280px 이상일 경우에만 보이도록 설정해주어서 간단히 해결할 수 있었습니다.
처음 해본다고 어렵게 생각하거나 두려워하지 말고, 기초부터 생각해보면 쉽게 답이 나올 수도 있다는 것을 배웠습니다.</li>
</ul>
<h3 id="🌈-개선-과제">🌈 개선 과제</h3>
<ul>
<li>맡은 파트 전체적으로 리팩토링</li>
</ul>
<h3 id="🌈-팀에-대한-평가">🌈 팀에 대한 평가</h3>
<ul>
<li>10점 만점 중 9점</li>
<li>모두 맡으신 파트 잘 해주셨습니다. 특히 리더님과 부리더님이 맡은 파트 외의 개발적인 부분도, 개발 외적인 일들도 열정을 다해주시고 이끌어주신 덕분에 완성도 높은 프로젝트를 만들 수 있었습니다. 또한 디자이너님과 함께하는 첫 협업이라는 점에서도 어려움이 있을 수 있었지만, 서로 소통이 원만하게 이루어졌다고 느꼈습니다.</li>
</ul>
<h3 id="🌈-스스로에-대한-평가">🌈 스스로에 대한 평가</h3>
<ul>
<li>10점 만점 중 5점</li>
<li>채팅 구현은 예전부터 해보고 싶었던 기능이었는데 좋은 경험이 되었습니다. 실시간 기능 구현, 깃허브 활용, zustand 사용, SQL작성 등 처음 해보는 게 많았는데 도전해보길 잘 했다고 느끼고 있습니다. 하지만 처음 팀에서 지키자고 했던 컨벤션을 못 지키고 정돈되지 않은 코드를 작성하게 되었고, 맡은 파트 구현 자체도 100% 하지는 못 하고 팀원 분들의 도움을 받아 완성시킬 수 있었어서, 프로젝트는 잘 마무리 되었지만 개인적으로 아쉬움이 남습니다.</li>
</ul>
<h3 id="🌈-부트캠프를-마치며-하고-싶은-말">🌈 부트캠프를 마치며 하고 싶은 말</h3>
<ul>
<li>파이널 프로젝트에서 좋은 팀을 만나 많이 배우고 캠프를 잘 마무리 할 수 있었습니다! 고생 많으셨습니다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 18주차 월요일. UT 피드백 점검, 단체 코드리뷰 시간]]></title>
            <link>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-18%EC%A3%BC%EC%B0%A8-%EC%9B%94%EC%9A%94%EC%9D%BC</link>
            <guid>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-18%EC%A3%BC%EC%B0%A8-%EC%9B%94%EC%9A%94%EC%9D%BC</guid>
            <pubDate>Mon, 12 Aug 2024 23:30:09 GMT</pubDate>
            <description><![CDATA[<h2 id="ut-피드백-점검">UT 피드백 점검</h2>
<blockquote>
<h3 id="김민지-티켓-검토-결과">김민지 티켓 검토 결과</h3>
<ol start="24">
<li>[제안] 본인이 입력한 채팅을 마이페이지에서 확인 가능하도록</li>
</ol>
<p>-&gt; 채팅 탭이 별도로 존재하기 때문에 구현하지 않아도 될 것 같다.
-&gt; 지금은 참여한 여정의 상세페이지에서 &#39;참여하기&#39; 누르면 &#39;이미 참여한 여정입니다?&#39;라고 뜨는데 대신 &#39;채팅하기&#39; 버튼으로 바꾸는 방법?
33. [버그] 채팅 탭을 누르면 전 페이지로 돌아감
-&gt; trips 페이지에서 참여한 여정이 없는 상태에서 chat 페이지로 넘어가신 거로 추정.
-&gt; 채팅이 없으면 &quot;아직 참여한 여정이 없습니다! 트립 버디즈와 함께 즐거운 여행을 시작해 볼까요?&quot; 문구 뜨고 클릭하면 trips로 이동하는 로직으로 변경하는 건 어떤지. <em>- 12일까지</em>
47. [제안][공통] 랜덤 채팅방
-&gt; 구현하기 어려울 것 같습니다.
51. [제안] 채팅 메시지 읽음 기능, 메시지 삭제 기능
-&gt; 읽음 기능 추가 예정 <em>- 14일까지</em>
-&gt; 삭제 기능은 후순위로 (피그마에도 없음)
56. [제안] 여정 상세에서 글을 보다가 뒤로 가려면 불편함 -&gt; 여정 상세에서 헤더 고정
-&gt; 모바일에선 헤더를 탭메뉴와 마찬가지로 fixed로 상시 고정하는 방법 어떠신지 팀원분들 의견 구하기
58. [제안] 하단 탭 메뉴 스크롤을 살짝 해야 보여서 불편 -&gt; 고정
-&gt; home 페이지에서만 스크롤 해야 보이는 거로 확인. 수정해보겠습니다.
59. [미구현] 여정 리스트 모바일 헤더 notification 아이콘 미작동
-&gt; notification 리스트 페이지로 이동하도록 구현 완료. 알림 기능은 개발 중. <em>- 14일까지</em>
74. [제안] 홈 페이지 ‘전체보기’가 버튼인지 모르겠음 (와이어프레임과 상이하네요)
-&gt; 바로 수정하겠습니다 <em>- 12일까지</em>
78. [제안] 여정 출발 전 휴대폰 알림
-&gt; 후순위로 두기
99. [제안] 홈 헤더 “예정된 ~여정이 ~일 남았어요” 클릭 시 해당 여정 상세로 리다이렉트
-&gt; 이 부분 생각했던 건데 좋은 피드백입니다. 구현 하겠습니다. <em>- 12일까지</em></p>
</blockquote>
<h2 id="얻게-된-것">얻게 된 것</h2>
<ul>
<li>위의 내용 말고도 내 담당이 아닌 부분들까지 굉장히 많은 다양한 피드백을 받았는데, 아예 생각하지 못 한 부분들도 꽤 있어서 도움이 많이 되었다.</li>
<li>UT를 진행하고 받은 모든 피드백을 다 반영하지는 못 하니, 이렇게 정리해서 우리의 기획, 현재 상황, 그리고 앞으로의 일정과 계획에 따라 조정하는 작업을 잘 한 것 같다. 부팀장님이 피드백을 모두 정리해주시고 형식도 정해주셔서 따라가기만 했는데... 팀플 하면서 이렇게 계속 팀원 분들께 배우게 된다!</li>
<li>하나 메모하면 좋을 것: 어떤 기기에서 사용했는지도 설문에 받으면 좋을 것 같다. 운영 체제뿐만 아니라 모바일의 경우 어떤 모바일 디바이스인지..</li>
</ul>
<h2 id="코드리뷰">코드리뷰</h2>
<p>그동안 빠르게 approve, merge 하느라 PR마다 코드리뷰를 거의 안 달고 확인 댓글만 짧게 남겼었는데, 한 번 쭉 다같이 코드리뷰를 해보자는 팀장님&amp;부팀장님의 의견에 따라 코드리뷰를 해 보았다.</p>
<h2 id="얻게-된-것-1">얻게 된 것</h2>
<ul>
<li>코드를 전체적으로 검토해보면서(기술적인 부분은 거의 그냥 넘겼지만..) 내가 쓰지 않은 부분까지 프로젝트 전반적인 구조를 더 이해할 수 있게 되었다! 좋은 작업인 것 같다.</li>
<li>놓치고 있던 자잘한 컨벤션도 다시 짚고 넘어갈 수 있게 된 시간이었다. 프로젝트 극 초반에 써놓고 수정하지 않았던 코드를 다시 보니까 컨벤션이 안 지켜져 있다는 걸 확인할 수 있었다.</li>
<li>내 코드 리팩토링이 시급하다 (어렵다..)</li>
<li>기술적인 면에서 나보다 실력이 좋은 팀원 분들의 조언을 얻을 수 있어서 유익했다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 17주차 목요일. 안 읽은 메시지 숫자 표시하는 방법에 대해 고민]]></title>
            <link>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-17%EC%A3%BC%EC%B0%A8-%EB%AA%A9%EC%9A%94%EC%9D%BC</link>
            <guid>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-17%EC%A3%BC%EC%B0%A8-%EB%AA%A9%EC%9A%94%EC%9D%BC</guid>
            <pubDate>Thu, 08 Aug 2024 11:38:59 GMT</pubDate>
            <description><![CDATA[<h2 id="오늘-한-일">오늘 한 일</h2>
<ul>
<li>notifications 페이지 UI 작업</li>
<li>trips 페이지에서 Alarm 아이콘 누르면 notifications 페이지로 이동</li>
<li>탭메뉴 글씨 추가, 컬러 변경</li>
<li>채팅 목록에 안 읽은 메시지 숫자 표시하는 방법에 대해 고민</li>
</ul>
<h2 id="트러블-슈팅--기술적-의사-결정">트러블 슈팅 &amp; 기술적 의사 결정</h2>
<blockquote>
<p>안 읽은 메시지 숫자 표시하는 방법에 대해 고민. =&gt; contract 테이블에 &#39;마지막으로 읽은 메시지 아이디&#39; 컬럼 추가하는 방법으로 결정</p>
</blockquote>
<h3 id="의사-결정-사유">의사 결정 사유</h3>
<p>두 가지 방법을 생각했다. column을 새로 추가하는 방법과, 클라이언트 사이드에서 useState 변경을 주어서 realtime으로 메시지가 전송될 때마다 +1이 되는 방법. 최대한 table을 건드리지 않고 구현하는 쪽으로 생각해봤는데...
=&gt; 후자의 경우, 새로고침하면 데이터가 날라간다는 걸 생각
=&gt; 테이블에 column 추가하기로 결정.</p>
<h3 id="로직">로직</h3>
<ol>
<li>contract table에 contract_last_read_message_id (이하 lrm_id) column 추가</li>
<li>lrm_id의 message_created_at 값을 찾는다</li>
<li>그것보다 뒤에 올라온 메시지 수를 계산</li>
<li>(+n) 컴포넌트 분리해서 realtime으로 구현. 테이블에 insert 될 때마다 업데이트</li>
<li>채팅리스트아이템 클릭 시 lrm_id를 last_message_id로 업데이트</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 17주차 수요일. 남은 할 일 정리]]></title>
            <link>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-17%EC%A3%BC%EC%B0%A8-%EC%88%98%EC%9A%94%EC%9D%BC</link>
            <guid>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-17%EC%A3%BC%EC%B0%A8-%EC%88%98%EC%9A%94%EC%9D%BC</guid>
            <pubDate>Wed, 07 Aug 2024 16:17:12 GMT</pubDate>
            <description><![CDATA[<h2 id="내일부터-남은-할-일">내일부터 남은 할 일</h2>
<ul>
<li>채팅 목록 &amp; 채팅 페이지 pc 버전</li>
<li>전체적으로 리팩토링</li>
<li>tanstackquery 사용</li>
<li>컴포넌트 분리, atoms까지 분리!</li>
<li>messages 테이블에 unread column 추가하는 것 관련해서 의견 내기</li>
<li>알림 목록 페이지 만들기</li>
<li>알림 기능 구현</li>
<li>기술면접 공부</li>
<li>남은 2주 동안 github 기록 많이 남기기..</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 17주차 화요일. css 이미지 꽉 차게 하는 법]]></title>
            <link>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-17%EC%A3%BC%EC%B0%A8-%ED%99%94%EC%9A%94%EC%9D%BC</link>
            <guid>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-17%EC%A3%BC%EC%B0%A8-%ED%99%94%EC%9A%94%EC%9D%BC</guid>
            <pubDate>Wed, 07 Aug 2024 00:15:14 GMT</pubDate>
            <description><![CDATA[<h2 id="상위-요소에-꽉-차게-만드는-방법">상위 요소에 꽉 차게 만드는 방법</h2>
<pre><code>&lt;div className=&quot;w-[40px] h-[40px] rounded-full overflow-hidden flex justify-center&quot;&gt;
    &lt;Image src={message.buddy?.buddy_profile_pic}
    alt=&quot;Profile Image&quot;
    width={40}
    height={40}
    className=&quot;object-cover&quot;
    /&gt;
&lt;/div&gt;</code></pre><p>부모 요소 (레이아웃) : overflow-hidden, 하위 요소 센터로 배치
자식 요소 (이미지 자체) : object-cover</p>
<p>자주 필요한 이미지 설정인데 한번 기록해 놓아야 좋을 것 같아서 기록한다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 16주차 수요일. 팀 프로젝트 - 채팅 기능 supabase realtime 사용해 구현. 어제의 이슈 해결]]></title>
            <link>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-16%EC%A3%BC%EC%B0%A8-%EC%88%98%EC%9A%94%EC%9D%BC</link>
            <guid>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-16%EC%A3%BC%EC%B0%A8-%EC%88%98%EC%9A%94%EC%9D%BC</guid>
            <pubDate>Wed, 31 Jul 2024 17:50:39 GMT</pubDate>
            <description><![CDATA[<h1 id="이슈-1---실시간-프사-렌더링-오류">이슈 (1) - 실시간 프사 렌더링 오류</h1>
<h2 id="1-이슈-문제-파악">1. 이슈 문제 파악</h2>
<p>현재 supabase를 이용한 실시간 채팅 구현에서 메시지는 정상적으로 불러와지지만, 프로필 사진은 새로고침을 해야만 로드된다. 즉, 프로필 사진 데이터가 컴포넌트의 마운트 시점에만 로드된다. 실시간으로 추가된 메시지의 유저 프로필 사진은 로드되지 않고 있다.</p>
<h2 id="2-해결-시도---useeffect">2. 해결 시도 - useEffect</h2>
<ul>
<li>데이터 fetch 하는 useEffect()의 의존성 배열 값 = id (현재 채팅의 id)</li>
<li>이걸 지우면 해결되지 않을까 하는 생각
<img src="https://velog.velcdn.com/images/minn__ij/post/b8ff32d4-f05b-477c-a1de-474998bf2a77/image.jpg" alt="">
<img src="https://velog.velcdn.com/images/minn__ij/post/9e02561a-c25e-42eb-b13f-229d8d3a6a4a/image.jpg" alt="">
<img src="https://velog.velcdn.com/images/minn__ij/post/cc7226f4-f345-437c-89e7-88bab1a51b36/image.png" alt=""></li>
<li>실시간으로 띄워주는 건 성공했지만! 근본적인 해결책은 아니었다.</li>
</ul>
<h2 id="3-해결-방법---realtime의-chat-room-안에서-messages-테이블-buddies-테이블-모두-접근">3. 해결 방법 - realtime의 chat-room 안에서 messages 테이블, buddies 테이블 모두 접근</h2>
<ul>
<li>기존 코드
<img src="https://velog.velcdn.com/images/minn__ij/post/7ec45f74-a9cc-43bb-a8bb-aac256b8fb1c/image.png" alt=""></li>
<li>이젠 buddy 정보를 총 두번 불러온다. 처음 마운트 할 때 &amp; 실시간 변경이 일어날 때
<img src="https://velog.velcdn.com/images/minn__ij/post/2da2ddca-5720-4147-ad79-bb1d213f86ae/image.png" alt=""></li>
<li>과제: useEffect buddy 부분 컴포넌트 분리하기</li>
</ul>
<h1 id="이슈-2---채팅-리스트-데이터-호출">이슈 (2) - 채팅 리스트 데이터 호출</h1>
<h2 id="코딩-전에-로직-정리">코딩 전에 로직 정리</h2>
<p><strong>로직</strong></p>
<ul>
<li>buddy_id가 contract.contract_buddy_id와 일치하는</li>
<li>모든 contract_id를 찾고, isPending === false &amp;&amp; isValidate === true 인 contract_id와 그 contract_trip_id를 필터링</li>
<li>filtered contract_id마다 있는 모든 contract_buddy_id를 찾고</li>
<li>각 buddy_id마다 buddies.buddy_profile_pic를 객체 속 배열로 반환.</li>
<li>이런 느낌..data = [{ contract_id: &quot;&quot;, contract_trip_id: &quot;&quot;, contract_buddies_profile_pics: [&quot;&quot;, &quot;&quot;, &quot;&quot;] }, ]contract_trip_id와 foreign key로 연결된 trips.trip_id를 찾아</li>
<li>trips.trip_title 반환</li>
<li>trips.trip_id와 foreign key로 연결된 가장 최근 생성된 messages.message_trip_id 찾기</li>
<li>messages.message_content, messages.message_created_at 반환</li>
</ul>
<p><strong>사용 column</strong></p>
<ul>
<li>contract.contract_trip_id / contract.contract_buddy_id / contract.contract_isPending / contact.contract_isValidate</li>
<li>trips.trip_id / trips.trip_title</li>
<li>buddies.buddy_id / buddies.buddy_profile_pic</li>
<li>messages.message_content / messages.message_created_at / messages.message_trip_id</li>
</ul>
<p><strong>참고용: supabase 사용 정리 잘 되어 있는 블로그</strong>
<a href="https://ramincoding.tistory.com/entry/Supabase-Supabase-%EB%A1%9C-%EB%B0%B1%EC%97%94%EB%93%9C-%EC%97%86%EC%9D%B4-Database-%EA%B5%AC%EC%B6%95%ED%95%98%EA%B8%B0%EA%B8%B0%EB%B3%B8-%EC%82%AC%EC%9A%A9%EB%B2%95">https://ramincoding.tistory.com/entry/Supabase-Supabase-%EB%A1%9C-%EB%B0%B1%EC%97%94%EB%93%9C-%EC%97%86%EC%9D%B4-Database-%EA%B5%AC%EC%B6%95%ED%95%98%EA%B8%B0%EA%B8%B0%EB%B3%B8-%EC%82%AC%EC%9A%A9%EB%B2%95</a></p>
<h2 id="작업-과정에서-느낀-점">작업 과정에서 느낀 점</h2>
<ul>
<li>본격적인 작업 들어가기 전 로직 정리, 의사코드 작성의 중요성을 느꼈다!</li>
<li>어떤 데이터가 필요한지 모두 정리해 놓는 것도 좋다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 16주차 화요일. 팀 프로젝트 - 채팅 기능 supabase realtime 사용해 구현. 이슈 발생]]></title>
            <link>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-16%EC%A3%BC%EC%B0%A8-%ED%99%94%EC%9A%94%EC%9D%BC</link>
            <guid>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-16%EC%A3%BC%EC%B0%A8-%ED%99%94%EC%9A%94%EC%9D%BC</guid>
            <pubDate>Tue, 30 Jul 2024 19:15:15 GMT</pubDate>
            <description><![CDATA[<h2 id="realtime-사용하여-chat-room-생성">Realtime 사용하여 chat-room 생성</h2>
<pre><code class="language-ts">useEffect(() =&gt; {
        const channel = supabase
            .channel(&#39;chat-room&#39;)
            .on(
                &#39;postgres_changes&#39;,
                { event: &#39;INSERT&#39;, schema: &#39;public&#39;, table: &#39;messages&#39; },
                payload =&gt; {
                    const newMessage = payload.new as Message &amp; {
                        buddy: {
                            buddy_profile_pic: string;
                            buddy_nickname: string;
                        };
                    };
                    if (newMessage.message_trip_id === id) {
                        setMessages(prevMessages =&gt; [
                            ...prevMessages,
                            newMessage,
                        ]);
                    }
                },
            )
            .subscribe();

        return () =&gt; {
            channel.unsubscribe();
        };
    }, [id]);

    useEffect(() =&gt; {
        const fetchMessages = async () =&gt; {
            const { data, error } = await supabase
                .from(&#39;messages&#39;)
                .select(
                    `
                    *,
                    buddy:message_sender_id (
                        buddy_profile_pic,
                        buddy_nickname
                    )
                `,
                )
                .eq(&#39;message_trip_id&#39;, id)
                .order(&#39;message_created_at&#39;, { ascending: true });

            if (error) {
                console.error(&#39;Error fetching messages:&#39;, error);
            } else {
                setMessages(data);
            }
        };

        fetchMessages();
    }, [id]);</code></pre>
<h2 id="리얼타임-써본-후기">리얼타임 써본 후기</h2>
<p>어렵게 생각했는데 생각했던 것보다 간결하다!</p>
<h2 id="작업하면서">작업하면서..</h2>
<h3 id="이슈-1">이슈 (1)</h3>
<p><img src="https://velog.velcdn.com/images/minn__ij/post/cd7133ba-1d9e-494e-86d3-4f2a4d8a0b54/image.png" alt=""></p>
<p>현재 supabase를 이용한 실시간 채팅 구현에서 메시지는 정상적으로 불러와지지만, 프로필 사진은 새로고침을 해야만 로드된다. 즉, 프로필 사진 데이터가 컴포넌트의 마운트 시점에만 로드된다. 실시간으로 추가된 메시지의 유저 프로필 사진은 로드되지 않고 있다.</p>
<h3 id="이슈-2">이슈 (2)</h3>
<p>buddies, trips, contract, messages 4개의 테이블을 잘 엮어서 데이터를 가져와야 한다. 이 부분이 생각보다 오래 걸리고 있다.
그동안 나는 동시에 한 개의, 혹은 두 개의 테이블만 사용했었다. 내일은 여러 개의 테이블의 데이터를 잘 엮어서 사용하는 방법에 대해서 찾아보고 작업에 들어가는 게 좋을 것 같다! 의사코드도 먼저 작성해보고.
<img src="https://velog.velcdn.com/images/minn__ij/post/b8e3e786-4bd1-48f7-ae8c-cf71cf4f3a3f/image.png" alt=""></p>
<h3 id="이슈-해결-계획">이슈 해결 계획</h3>
<p>(1) 방법 구글링 (GPT의 도움은 받지 말아보자!)
(2) 로직 정리해보기 -&gt; 여러 테이블 엮어서 사용하는 법 서치 -&gt; 의사코드 작성 및 기록 -&gt; 실제 코딩 작업 </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 16주차 월요일. 팀 프로젝트 - 채팅 기능 구현 중 (supabase realtime)]]></title>
            <link>https://velog.io/@minn__ij/TIL-16%EC%A3%BC%EC%B0%A8-%EC%9B%94%EC%9A%94%EC%9D%BC</link>
            <guid>https://velog.io/@minn__ij/TIL-16%EC%A3%BC%EC%B0%A8-%EC%9B%94%EC%9A%94%EC%9D%BC</guid>
            <pubDate>Mon, 29 Jul 2024 17:25:07 GMT</pubDate>
            <description><![CDATA[<h2 id="supabase-realtime">Supabase Realtime</h2>
<h3 id="고민의-과정">고민의 과정</h3>
<p>어제 강의를 들어봤는데, 두려워 했던 것보다 어렵지 않아 보였다.
이번주에 MVP 발표까지 해야 하는 구현 사항을 마쳐야 하기 때문에... 우선 realtime으로 해 놓고 MVP 발표 이후 웹소켓 활용하여 리팩토링 작업해볼까 하는 새 계획이 생겼다.</p>
<h2 id="기술적-의사결정">기술적 의사결정</h2>
<h3 id="결정-사항">결정 사항</h3>
<p>본래 웹소켓을 도전 과제로 삼아 작업해볼 계획이었지만 우선 Supabase Realtime을 활용하도록 결정.</p>
<h3 id="supabase-realtime-사용-결정-이유">Supabase Realtime 사용 결정 이유</h3>
<ol>
<li>짧은 한정된 시간 내에 기능 구현을 완성해야 유저 테스트 진행도 가능해지는데, 현재로썬 어렵다고 판단.
따라서 MVP, 유저 테스트 전까지는 사용이 원활할 정도로 Supabase Realtime을 활용해 구현하기로 결정.</li>
<li>웹소켓을 사용하지 않고 Realtime 만으로도 충분히 MVP와 유저 테스트가 가능할 것 같다는 판단.</li>
<li>팀 전원이 Supabase를 사용하여 작업하고 있기 때문에 통일성을 고려한 이유도 있다. 웹소켓은 기술적 도전을 위한 스스로의 과제 사항.
또한 웹소켓은 현재 상황으로썬 무리지만, MVP 발표 이후 리팩토링 예정.</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 15주차 금요일. 팀 프로젝트 - 채팅 페이지 ui 작업 & 채팅 기능 구현 공부 중]]></title>
            <link>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-15%EC%A3%BC%EC%B0%A8-%EA%B8%88%EC%9A%94%EC%9D%BC</link>
            <guid>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-15%EC%A3%BC%EC%B0%A8-%EA%B8%88%EC%9A%94%EC%9D%BC</guid>
            <pubDate>Fri, 26 Jul 2024 12:00:10 GMT</pubDate>
            <description><![CDATA[<h2 id="타입-파일-분리--사용">타입 파일 분리 &amp; 사용</h2>
<h3 id="우리의-컨벤션">우리의 컨벤션</h3>
<p>초반 기획 단계 회의 시간에 한 번 supabase.ts 의 Database의 public의 Table의 message... 이런 식으로 안 쓰고 저렇게 Tables&lt;&#39;messages&#39;&gt;만 써도 된다고 리더님이 설명 해주셨었다. 좋은 정보.
types 폴더 안에 넣어 놓고 파일명은 어떻게 하자~ 이런 컨벤션도 정했었다.</p>
<h3 id="타입-import-시도">타입 import 시도</h3>
<p>기능 들어가기 전 UI만 그리다가... supabase의 Table의 type 불러오는 걸 이제 처음 해봄.
한 번 정리하면 좋을 것 같아서 사용한 파일 세 개 같이 스샷해서 올려 놓는다.
<img src="https://velog.velcdn.com/images/minn__ij/post/478110c8-b4d7-42f5-812a-475e87e8f31d/image.png" alt=""></p>
<h2 id="채팅-기능-공부-중">채팅 기능 공부 중</h2>
<h3 id="보고-있는-강의">보고 있는 강의</h3>
<p><a href="https://www.youtube.com/watch?v=-xXASlyU0Ck&amp;ab_channel=DailyWebCoding">https://www.youtube.com/watch?v=-xXASlyU0Ck&amp;ab_channel=DailyWebCoding</a></p>
<h3 id="주말-계획">주말 계획</h3>
<p>채팅 기능 어느 정도는 구현하기.
바로 응용하는 게 어려울 것 같으면 한 번 테스트용 새 프로젝트 만들어서 똑같이 따라해보고 감을 찾는 것도 방법!
이참에 하나 사이드 프로젝트로 만들어보자.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 15주차 목요일. 첫 모의 기술 면접. 팀 프로젝트 - 채팅 페이지 ui 작업 중.]]></title>
            <link>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-15%EC%A3%BC%EC%B0%A8-%EB%AA%A9%EC%9A%94%EC%9D%BC</link>
            <guid>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-15%EC%A3%BC%EC%B0%A8-%EB%AA%A9%EC%9A%94%EC%9D%BC</guid>
            <pubDate>Thu, 25 Jul 2024 14:54:14 GMT</pubDate>
            <description><![CDATA[<h2 id="🌊-오늘-한-일과-내일의-계획">🌊 오늘 한 일과 내일의 계획</h2>
<h3 id="1-오늘-한-일">1. 오늘 한 일</h3>
<ul>
<li>첫 모의 기술 면접</li>
<li>채팅 목록 페이지 모바일 ui 작업</li>
<li>채팅 페이지 모바일 ui 작업</li>
</ul>
<h3 id="2-내일-계획">2. 내일 계획</h3>
<ul>
<li>기술 면접 공부</li>
<li>채팅 페이지 ui 작업 초안 완성</li>
<li>채팅 목록, 채팅 페이지 데스크탑 작업</li>
<li>채팅 기능 조금이라도 시작</li>
</ul>
<h2 id="👼🏻-첫-모의-면접">👼🏻 첫 모의 면접</h2>
<h3 id="1-모의-면접-질문">1. 모의 면접 질문</h3>
<p>실제 기술 면접처럼 컬쳐핏, 협업, 기술 질문들로 구성.</p>
<pre><code>1. 자기소개
2. 프론트엔드 선택 이유
3. 개발 말고 다른 취미
4. 공부 방법
5. 장점 / 단점
6. 협업 과정에서 어려웠던 점, 어떻게 극복했는지
7. 좋은 협업 환경이란?
8. 프론트엔드도 디자인에 대해 알아야 한다고 생각하는지
9. Javascript 특징
10. 리액트 특징
11. 이벤트 위임
12. useEffect
13. useCallback, useMemo
14. 브라우저 렌더링
15. 크로스 브라우징
16. API 란 무엇인지</code></pre><h3 id="2-피드백-및-느낀-점">2. 피드백 및 느낀 점</h3>
<ul>
<li>컬쳐핏, 협업 질문은 잘 대답했는데, 기술 질문은 확실히 준비가 많이 필요할 것 같다.</li>
<li>장점과 단점, 협업 능력 등에 관한 질문들은 직무와 연결지어서 얘기하면 좋다. 예를 들면 내가 장점으로 꼼꼼함을 얘기했는데, 거기에 덧붙여서 그 꼼꼼한 성격으로 협업에서 어떤 까다로운 요구사항이 있어도 꼼꼼하게 해결할 수 있다는 것을 어필하면 좋다.</li>
<li>기술 질문이 시작될 때 첫 질문은 굉장히 중요하다. 첫 질문에 어떻게 답하냐느에 따라 뒤의 질문들의 수준이 달라진다. 어느 정도 내 기술적 역량을 판단하는 척도가 되는데, 이때 잘 답한다면 내 역량을 높게 평가하고 다음 질문을 낼 수 있다. 수준 높은 질문을 물어본다는 것은 내 역량을 어필할 수 있는 기회가 주어지는 것. 첫 질문의 중요성을 기억하고 최대한 잘 답해보자.</li>
<li>개인 면접의 경우 질문을 듣자마자 너무 급하게 답할 필요는 없다. 어느 정도 충분히 생각할 시간을 갖고 답해도 괜찮으니 조금 여유를 가지자.</li>
<li>내가 어필하려는 기술 스택의 특징들은 언제 물어보든 술술 말할 수 있어야 한다. 자바스크립트 특징 등.</li>
<li>오늘 받은 질문들은 사실상 기초의 기초. 익숙하게 사용하는 것들이지만 막상 말로 설명하니 계속 막히게 되는 것을 경험했다. 대충 아는 것이니 넘어가자~ 라고 하지 말고, 스스로의 언어로 정돈되게 그리고 가득찬 내용으로 대답할 수 있도록 연습이 꼭 필요하다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 15주차 수요일. 팀 프로젝트 - ui 작업 중]]></title>
            <link>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-15%EC%A3%BC%EC%B0%A8-%EC%88%98%EC%9A%94%EC%9D%BC</link>
            <guid>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-15%EC%A3%BC%EC%B0%A8-%EC%88%98%EC%9A%94%EC%9D%BC</guid>
            <pubDate>Wed, 24 Jul 2024 12:14:37 GMT</pubDate>
            <description><![CDATA[<h1 id="오늘-한-일">오늘 한 일</h1>
<ul>
<li>메인페이지, 탭메뉴 컴포넌트 보다 더 세분화, 재사용성 고려</li>
<li>헤더, 탭메뉴 ui 수정</li>
<li>이번 프로젝트 첫 PR, 첫 merge</li>
<li>chat 페이지 (채팅 목록) 스켈레톤 작성</li>
<li>chat 페이지 구현 시 레이아웃 구성 관련 고민, 레퍼런스 서치</li>
</ul>
<h1 id="과제">과제</h1>
<h2 id="chat-페이지-구성-구현">chat 페이지 구성 구현</h2>
<blockquote>
<p>모바일에서는 chat(목록)과 chat(id) 페이지가 분리되는데, 데스크탑에서는 화면을 둘로 나눠서 같이 띄워주는 작업이 필요. url이 다른데 어떻게 구현해야 좋을지.
<img src="https://velog.velcdn.com/images/minn__ij/post/d9a3e729-e8db-436e-82b2-362042b5dd5e/image.png" alt="">
<img src="https://velog.velcdn.com/images/minn__ij/post/d74cadcc-6eef-468b-9f4e-b544f88189cd/image.png" alt=""></p>
</blockquote>
<h2 id="레퍼런스-서치">레퍼런스 서치</h2>
<p>별 거 없지만, 인스타그램을 많이 참고했기에 인스타그램의 url을 한 번 봤다.
주소 구조는 모르겠지만 어쨌든, url이 바뀌면서 한쪽에만 띄워주는 건 가능하다는 것을 봄.</p>
<pre><code>인스타그램...
채팅 목록만 보이는 주소 : https://www.instagram.com/direct/inbox/
채팅 item 누르면 바뀌는 주소 : https://www.instagram.com/direct/t/[id]</code></pre><h2 id="고민">고민</h2>
<ul>
<li>모바일 width에서는 chat/[id]에 목록 컴포넌트를 hidden으로 처리할까?</li>
<li>다른 깔쌈한 방법이 있을 것 같은데, 이건 확실히 서치가 필요하다.</li>
</ul>
<h2 id="결론">결론</h2>
<p>은 아직 안 났다... 내일 해결해보고 남기도록...</p>
<h1 id="til">TIL</h1>
<p>url에 따라서? 동적으로 레이아웃 위치에 있는 헤더를 변경하는 기능에 대한 얘기를 나누다가 본 개념.
파라미터 사용... 공부가 필요할 것 같다.
<a href="https://nextjs.org/docs/app/api-reference/file-conventions/page">https://nextjs.org/docs/app/api-reference/file-conventions/page</a></p>
<h1 id="내일-계획">내일 계획</h1>
<ul>
<li>chat 페이지 레이아웃 구성 작업 (모바일과 데스크탑 모두 고려)</li>
<li>chat 페이지 리스트 컴포넌트 ui 작업</li>
<li>chat 상세 페이지 ui 작업 시작</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 15주차 화요일. Next.js 사용 중 -4094 에러 해결]]></title>
            <link>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-15%EC%A3%BC%EC%B0%A8-%ED%99%94%EC%9A%94%EC%9D%BC</link>
            <guid>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-15%EC%A3%BC%EC%B0%A8-%ED%99%94%EC%9A%94%EC%9D%BC</guid>
            <pubDate>Tue, 23 Jul 2024 13:02:42 GMT</pubDate>
            <description><![CDATA[<h1 id="트러블-슈팅">트러블 슈팅</h1>
<h2 id="🚨-문제">🚨 문제</h2>
<blockquote>
<p><strong><em>-4094 에러 (Internal Server Error)</em></strong>
<img src="https://velog.velcdn.com/images/minn__ij/post/4ab3acdc-216c-41c9-bc8e-e08cd6deea3c/image.png" alt=""></p>
</blockquote>
<p>Next.js 를 사용하기 시작하고 나를 계속 괴롭힌 에러.</p>
<p>간단한 CSS 수정을 하든 뭘 하든 뭘 안 하든 짧게는 몇십초 길게는 몇분 내에 꼭 저 에러가 뜨면서 랜더링이 멈추고, yarn dev를 다시 실행해야 했다.</p>
<h2 id="🏃🏻♀️-문제-해결-시도-과정">🏃🏻‍♀️ 문제 해결 시도 과정</h2>
<h3 id="1-next-node_modules-폴더-삭제-후-yarn-패키지-재설치"><strong>1. .next, node_modules 폴더 삭제 후 yarn 패키지 재설치</strong></h3>
<p>→ 해결 실패</p>
<h3 id="2-구글링"><strong>2. 구글링</strong></h3>
<p>→ 삭제 후 재설치 외에 &#39;운영체제 초기화&#39; 라는 해결책을 발견…</p>
<p>→ 다른 방법 찾아보기로 결정</p>
<h3 id="3-gpt에게-도움-요청"><strong>3. GPT에게 도움 요청</strong></h3>
<p>→ 권한 문제일 수도 있다는 답변!</p>
<blockquote>
<p><em>파일 시스템 권한 확인 권한 문제일 수도 있으므로, 프로젝트 폴더와 하위 파일/폴더에 대한 읽기/쓰기 권한을 확인합니다.</em></p>
</blockquote>
<pre><code># Windows에서는 관리자 권한으로 실행해야 할 수도 있습니다
icacls &quot;프로젝트경로&quot; /grant Everyone:(OI)(CI)F /T</code></pre><p><em>위 명령어는 프로젝트 폴더와 하위 파일/폴더에 대해 모든 사용자에게 읽기/쓰기 권한을 부여합니다.</em></p>
<p>→ 해결</p>
<p>→ 된 줄 알았지만… 몇 시간은 괜찮다가 작업을 계속하다 보니 다시 똑같은 에러 발생.</p>
<h2 id="🙆🏻♀️-문제-해결">🙆🏻‍♀️ 문제 해결</h2>
<h3 id="1-에러가-발생하는-시점이-언제인지-터미널을-다시-살펴보았다"><strong>1. 에러가 발생하는 시점이 언제인지 터미널을 다시 살펴보았다.</strong></h3>
<p>VSCode에서 저장됨 &gt; 자동으로 반영 &gt; 서버에 띄워줌 이런 식으로 작동되는데</p>
<p>이게 Compiling이 잘 되다가.. 잘 되다가… 갑자기 뜬금없이 에러가 생긴다.
<img src="https://velog.velcdn.com/images/minn__ij/post/f0e036ea-2b41-4584-85cb-87fa9755ba87/image.png" alt=""></p>
<h3 id="2-원인-추측">2. 원인 추측</h3>
<blockquote>
<p><strong><em>지금 글자 하나 하나 바뀔 때마다 자동으로 저장이 되는데, 렌더링은 그 속도를 못 따라가서 생기는 문제가 아닐까..???</em></strong></p>
</blockquote>
<h3 id="3-vs-code-설정을-변경해보자"><strong>3. VS Code 설정을 변경해보자..</strong></h3>
<p>원래 코드 변경이 있을 때마다 자동 저장 되도록 설정을 해 놨었음.
이게 문제 될 거라고는 생각해본 적이 없는데, 문득 그럴 수도 있겠다는 생각이 들음.
Auto Save: afterDelay로 되어 있던 걸 off로 변경해봄.
<img src="https://velog.velcdn.com/images/minn__ij/post/201b1088-821a-4819-ad4e-3ce2fa09920c/image.png" alt=""></p>
<h3 id="4-해결">4. 해결.</h3>
<p>이렇게 간단한 문제였다니… 상상도 못 했다.
그래도 혼자의 힘으로 간단하지만 <strong>엄청나게 중요한</strong> 문제를 해결해서 뿌듯한 경험이 됐다.
컴퓨터 속도 등 환경에 따라 다를 수도 있지만, 이런 방법도 있다는 점을 기록하고 싶다.</p>
<h2 id="👍🏻-결론">👍🏻 결론</h2>
<blockquote>
<p><strong>VS Code 설정에 자동저장이 켜져 있으면 꺼보세요!!</strong></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 15주차 월요일. 파이널 프로젝트 개발 시작!!!]]></title>
            <link>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-15%EC%A3%BC%EC%B0%A8-%EC%9B%94%EC%9A%94%EC%9D%BC</link>
            <guid>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-15%EC%A3%BC%EC%B0%A8-%EC%9B%94%EC%9A%94%EC%9D%BC</guid>
            <pubDate>Mon, 22 Jul 2024 12:35:46 GMT</pubDate>
            <description><![CDATA[<h2 id="오늘-한-일">오늘 한 일</h2>
<ul>
<li>프로젝트 세팅</li>
<li>디자이너 님과 미팅</li>
<li>맡은 파트의 항목 별 진행 및 마감일 계획 세우기</li>
<li>개발 시작</li>
<li>메인 페이지 컴포넌트 파일 분리 및 UI 구현 시작</li>
</ul>
<h2 id="til--eslintrdjs-파일">TIL : .eslintrd.js 파일?</h2>
<p>팀원 분들이 해결해주신 트러블 슈팅인데 나도 새롭게 배운 부분.
git clone 받은 다음 코딩 시작하기 전에 팀장님이 알려주신 세팅을 하는데 계속 모든 코드에 빨간 줄이 뜨는 문제가 발생했다.
prettier, eslintrc 설정에 문제가 있었는데, <strong><em>endOfLine: &#39;auto&#39;</em></strong> 를 추가해서 해결.</p>
<pre><code class="language-js">module.exports = {
    extends: [&#39;next/core-web-vitals&#39;, &#39;plugin:prettier/recommended&#39;],
    // plugins: [&#39;prettier&#39;, &#39;unused-imports&#39;],
    plugins: [&#39;prettier&#39;],
    rules: {
        // 선언되지 않은 변수 또는 임포트 구문 정리 규칙
        &#39;no-undef&#39;: &#39;error&#39;,
        // &#39;unused-imports/no-unused-imports&#39;: &#39;error&#39;,

        // 프리티어 설정
        &#39;prettier/prettier&#39;: [
            &#39;error&#39;,
            {
                singleQuote: true,
                semi: true,
                tabWidth: 4,
                trailingComma: &#39;all&#39;,
                printWidth: 80,
                bracketSpacing: true,
                arrowParens: &#39;avoid&#39;,
                endOfLine: &#39;auto&#39;,
            },
        ],
    },
};</code></pre>
<blockquote>
<p>참고 블로그 : <a href="https://guiyomi.tistory.com/134">https://guiyomi.tistory.com/134</a></p>
</blockquote>
<blockquote>
<p><em>이것은 개행시 crlf 를 쓸것인지 lf 를 쓸것인지의 문제에서 윈도우 사용자와 맥 사용자가 상이해서 생기는 문제라고 하네요</em> &lt;- 팀장님의 한 줄 요약!</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 14주차 금요일. 파이널 프로젝트 첫주를 마무리 하며]]></title>
            <link>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-14%EC%A3%BC%EC%B0%A8-%EA%B8%88%EC%9A%94%EC%9D%BC</link>
            <guid>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-14%EC%A3%BC%EC%B0%A8-%EA%B8%88%EC%9A%94%EC%9D%BC</guid>
            <pubDate>Fri, 19 Jul 2024 13:10:39 GMT</pubDate>
            <description><![CDATA[<h1 id="오늘-한-일-같이">오늘 한 일 (같이)</h1>
<ul>
<li>디자이너님과 회의</li>
<li>와이어프레임 피드백 및 플로우 정리</li>
<li>각자 의사코드 공유, 다같이 회의 거쳐서 수정</li>
<li>DB 완성</li>
</ul>
<h1 id="채팅-구현-플로우">채팅 구현 플로우</h1>
<h3 id="홈-의사코드">홈 의사코드</h3>
<p><strong>1. 배너</strong></p>
<p>trips 테이블에서 get</p>
<p>trips.trip_master || trips.trip_members 에 있는 id와 유저 id가 일치하는 trip만 필터링</p>
<p>start_data를 기준으로 저장</p>
<p>0번째 인덱스만 불러와서 배너에 노출</p>
<p>(새로 추가된 테이블 기준으로 수정)</p>
<p><strong>2. 추천 인기 버디즈</strong></p>
<p>온도 기준으로 정렬</p>
<p>buddies 테이블에서 get</p>
<p>메인페이지에선 몇개만 가져오기</p>
<p>전체보기 누르면 /buddies 페이지로 이동</p>
<p><strong>3. 인기 스토리</strong></p>
<p>(이 부분은 은님에게 컴퍼넌트 맡김)</p>
<p><strong>4. 지금 모집중인 여정</strong></p>
<p>trips 테이블에서 isValidated 만 필터링해서 get</p>
<p>메인페이지에선 몇개만 가져오기</p>
<p>전체보기 누르면 /trips 페이지로 이동</p>
<h3 id="chat-의사코드">chat 의사코드</h3>
<p><strong>1. 채팅 생성:</strong></p>
<p>trip 모집 생성 시 바로 contracts 테이블에 isLeader=true인 row 생성</p>
<p><strong>2. contract 추가 및 채팅방 입장:</strong></p>
<p>채팅하기 = isValidate=true 해당되어야만 채팅창 접근 가능</p>
<p>채팅하기 클릭 -&gt; master에게 요청 알림 -&gt; 거절or수락 창</p>
<p>거절 시 거절됐다는 알림</p>
<p>수락 시 수락됐다는 알림 (클릭하면 채팅으로 이동)</p>
<p>수락 시 participant 테이블에 row 생성</p>
<p>master의 경우: 수락하기 -&gt; 채팅방 이동</p>
<p><strong>3. 채팅 목록:</strong></p>
<p>contracts 테이블에서 user_id와 member_id? 비교 돌려서 해당되는 채팅만 가져옴</p>
<p>상태에 저장, 목록 렌더링</p>
<p>클릭하면 chat/[id]로 이동</p>
<p><strong>4. 메시지 전송:</strong></p>
<p>해당 chat과 연결된 messages 리스트를 상태에 저장</p>
<p>메시지 도착할 때마다 메시지 리스트 업데이트</p>
<p>input 창에 입력한 message_content와 message_sender_id 저장</p>
<p>전송 누르면 messages 테이블에 새로운 메시지 삽입</p>
<p>메시지 보내면 notification 테이블에 type=&quot;message&quot;로 새 row 추가</p>
<p><strong>5. 이미지 전송 로직</strong></p>
<ul>
<li>createObjectUrl이미지를 화면에서 볼 수 있도록 임시 url 생성</li>
<li>supabase storage에 저장 (webp로)</li>
<li>getPublicUrl 사용해서 Image 컴퍼넌트로 뿌리기</li>
</ul>
<h1 id="새로-배운-것들-메모">새로 배운 것들 메모</h1>
<h3 id="1-supabase-실시간-채팅-관련">1. supabase 실시간 채팅 관련</h3>
<ul>
<li>postgress를 사용하면 서버에 써지면 렌더링됨
바로바로 되려면 broadcast를 쓰면 됨</li>
<li>문제: 서버에 저장을 따로 해줘야 함. 화면에 그려지는 순간 업데이트 되지만 채팅 데이터는 따로 테이블에 저장을 해야 한다.</li>
</ul>
<h3 id="2-이미지-처리">2. 이미지 처리</h3>
<p><strong>1) createObjectUrl</strong> 사용해 이미지를 화면에서 볼 수 있도록 임시 url 생성
<strong>2) supabase storage에 저장</strong></p>
<pre><code>.from bucket
.upload</code></pre><p><strong>3) getPublicUrl</strong> 사용해 Image 컴퍼넌트로 뿌리기
***Optimistic 업데이트를 사용한다면 createObjectUrl</p>
<h3 id="3-퍼널funnel-패턴">3. 퍼널(Funnel) 패턴</h3>
<p>출처: <a href="https://dev.to/hxxtae/tossyi-peoneolfunnel-paeteon-jeogyonghaebogi-2n7c">https://dev.to/hxxtae/tossyi-peoneolfunnel-paeteon-jeogyonghaebogi-2n7c</a>
요즘 모바일 UX, 토스 이후로 신경쓰기 시작한 부분. 튜터님이 우리 진행 상황을 보시고 모바일 구현 시 다들 참고하면 좋다고 하신 기술이다!
<img src="https://velog.velcdn.com/images/minn__ij/post/cb79bdcf-a937-4b90-9b6d-a99b153a096b/image.png" alt="">
<img src="https://velog.velcdn.com/images/minn__ij/post/415b1635-2185-493a-a3f9-b29a899d8c5a/image.png" alt="">
이런 패턴을 적용할만한 부분이 있다면 적용해보자.
좋은 팁을 알게 됐다.</p>
<h1 id="파이널-프로젝트-첫주를-마무리-하며">파이널 프로젝트 첫주를 마무리 하며</h1>
<p>파이널 프로젝트를 시작한 주. 월요일에 첫 인사를 시작으로 화요일부터 이어진 본격적인 회의. 정말 9 to 9 의 회의 시간. 리더님 부리더님은 새벽까지 회의하신 것 같지만... 12시간 회의도 정말 심리적으로나 체력적으로나 쉽지 않은 4일이었다!
하지만 뿌듯하고, 좋은 팀, 좋은 팀원들을 만난 것 같아서 즐겁게 임할 수 있는 시간이었다. 리더 부리더 님들이 정말 배려를 많이 해주시고, 부족한 부분을 잘 이해해주시고 다같이 문제를 해결해나갈 수 있도록 열심히 도와주셔서... 너무 잘 만났다고 감사하다고 말하고 싶다! 우리가 사전에 계획했던 대부분의 일은 마친 것 같고. 이제 코딩 들어가면 더 바빠지겠지..?
매우 기대가 된다.
회의는 (즐거웠지만) 지쳐서 이제 잘 하든 못하든 코딩을 빨리 시작하고 싶다ㅋㅋㅋㅋ</p>
<p>주말 동안 채팅 구현 로직에 대해 더 공부하고 와야겠다.
기술 면접 준비도 잊지 말고! 알고리즘 문제 풀이도 내일부터는 매일 하나씩은 꼭 하는 거 잊지 말자.
기록은 생명. 5분 기록 보드와 TIL 반드시 12시 지나가기 전에 작성하기.</p>
<p>남은 기간 동안 성실하게 임해보자.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 14주차 목요일. 팀 프로젝트 회의 - 와이어프레임 초안 피드백, 기능 및 플로우 정리]]></title>
            <link>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-14%EC%A3%BC%EC%B0%A8-%EB%AA%A9%EC%9A%94%EC%9D%BC</link>
            <guid>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-14%EC%A3%BC%EC%B0%A8-%EB%AA%A9%EC%9A%94%EC%9D%BC</guid>
            <pubDate>Thu, 18 Jul 2024 13:40:23 GMT</pubDate>
            <description><![CDATA[<h2 id="오늘-한-일-다같이">오늘 한 일 (다같이)</h2>
<ul>
<li>와이어프레임 피드백</li>
<li>세부 기능, 로직, 플로우 정리</li>
<li>디자이너 미팅<h2 id="의사-코드-작성">의사 코드 작성..</h2>
채팅 생성:
chat 테이블에 컬럼 생성</li>
</ul>
<p>채팅 목록:
chat 테이블 데이터 가져옴
상태에 저장, 목록 렌더링
이름 클릭하면 chat/[id] 로 이동</p>
<p>메시지 전송:
해당 chat과 연결된 messages 리스트를 상태에 저장
메시지 도착할 때마다 메시지 리스트 업데이트
input 창에 입력한 메시지와 사용자id, 닉네임을 저장
전송 누르면 messages 테이블에 새로운 메시지 삽입</p>
<p>일단 플로우 조금 작성해봤는데 많은 수정이 필요할 것 같다.
오늘 밤에 채팅 구현하는 방법을 제대로 찾아보고 로직 작성해보자.
메인 페이지의 의사 코드도!</p>
<h2 id="느낀-점-소통-관련">느낀 점 (소통 관련)</h2>
<ul>
<li>말 끊고 들어갈 때 조심스럽게 하기! 기분 상하지 않도록</li>
<li>디테일한 부분을 놓치고 있다 싶으면 바로 얘기해보자</li>
<li>하지만 내가 말할 때는 정리한 상태로 말하기. 이해가 잘 되도록 생각하면서 얘기하기.</li>
<li>항상 집중! 놓치는 게 있다면 바로바로 짚고 넘어가자.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 14주차 수요일. 팀 프로젝트 회의 - 유저플로우, 컴포넌트 구조, DB 설계, API 명세서 작성]]></title>
            <link>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-14%EC%A3%BC%EC%B0%A8-%EC%88%98%EC%9A%94%EC%9D%BC</link>
            <guid>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-14%EC%A3%BC%EC%B0%A8-%EC%88%98%EC%9A%94%EC%9D%BC</guid>
            <pubDate>Wed, 17 Jul 2024 12:27:40 GMT</pubDate>
            <description><![CDATA[<h2 id="유저플로우">유저플로우</h2>
<p>우리는 Figma에서 작업하다가 좀 더 구조 그리기 편한 걸 써보자! 해서 Figjam으로 넘어가게 됐다. 진작 그럴 걸.
<img src="https://velog.velcdn.com/images/minn__ij/post/d20358fd-b692-4ab9-a720-6ca5edea45ec/image.png" alt=""></p>
<h2 id="컴포넌트-구조">컴포넌트 구조</h2>
<p>피그잼으로 오니까 이렇게 화살표 그리는 것도 간편하고, 스탬프를 활용해 누가 어떤 파트를 작업할지 나누어 놓는 것도 쉽게 가능해졌다.
컴포넌트 구조:</p>
<ul>
<li>우선 페이지가 들어가는 app 폴더 안에는 (provider) 폴더를 넣고, 그 안에 인증/인가에 따른 (authenticated), (conditional), (public) 세 가지로 나누었다.</li>
<li>components 폴더를 src 바로 하위 요소로 넣고, atomic 폴더 구조를 활용해보기로 결정했다.
atoms &lt; molecules &lt; organisms &lt; templates &lt; pages 이렇게 나누어지는데, 튜터님께 이 방법을 사용하는 게 나을지 다른 방법을 사용하는 게 나을지 자문을 구했다. 결론은 atomic 폴더 구조는 사용하는데 우선은 atoms, molecules, organisms까지만 사용하도록 결정. (어차피 pages도 따로 있으니!)
튜터님에게는 아토믹을 활용한다 하더라도 꼭 다 쓸 필요는 없고, 팀원들끼리 합의 하에 요소와 요소 각각의 기준을 정하고 우리만의 규칙으로 진행해도 된다는 피드백을 받았다.</li>
<li>hooks, store, providers, context 안에 들어가 있는 파일명도 컨벤션을 정해보았다. &quot;뭐뭐.store.ts&quot; &lt;- 이런 식으로.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/minn__ij/post/f4f20f96-0f38-4c65-bca8-22b305c61974/image.png" alt="">
(중간은 아직 완전 확정은 아니니까 생략하고...)
<img src="https://velog.velcdn.com/images/minn__ij/post/61ad6b9a-2e2a-4d6e-8b38-4ddf167a8567/image.png" alt=""></p>
<h2 id="db-설계-하는-중-일부만-예시로">DB 설계 하는 중 (일부만 예시로..)</h2>
<p><img src="https://velog.velcdn.com/images/minn__ij/post/2966cefd-62ba-4e6d-b08f-d3ecc4f2795f/image.png" alt=""></p>
<h2 id="마크다운-랭귀지-새로-배운-거">마크다운 랭귀지 새로 배운 거</h2>
<p><code>[링크제목](url주소)</code></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 13주차 수요일. 심화 프로젝트 - 트러블 슈팅]]></title>
            <link>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-13%EC%A3%BC%EC%B0%A8-%EC%88%98%EC%9A%94%EC%9D%BC</link>
            <guid>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-13%EC%A3%BC%EC%B0%A8-%EC%88%98%EC%9A%94%EC%9D%BC</guid>
            <pubDate>Thu, 11 Jul 2024 00:20:24 GMT</pubDate>
            <description><![CDATA[<h2 id="트러블">트러블</h2>
<p>홈 페이지에서 생성하기 누름 -&gt; 기본 정보 입력 모달 -&gt; 모달의 생성하기 누르면 지도 불러오는 페이지로 이동
위와 같은 과정에서, 지도 불러오는 페이지로 이동했는데 지도가 로드 되지 않는 문제가 발생했다.
새로고침을 하면 작동이 되는데, 페이지에서 페이지로 넘어갈 때 안 되는 문제.</p>
<h2 id="해결-과정">해결 과정</h2>
<p>다른 팀원 분이 발견하신 문제였는데 그 분이 해결 방법을 찾아보시고, 튜터님과 다른 수강생들한테 도움을 구하러 다니셨지만 해결하지 못 해서 골머리를 앓고 있는 중이었다.
팀 회의에서 보이는 코드를 다 하나씩 주석처리 해 가면서 문제가 어디서 발생하는지 찾아 보았고, 아무래도 다른 것보다 맵 가져오는 컴퍼넌트의 문제인 것 같다고 팀원들과 의견을 나누게 되었다.
그리고, 최후의 방법으로 gpt한테 도움을 구했고... 해결할 수 있었다.</p>
<h2 id="코드">코드</h2>
<p><strong>변경 전 코드</strong></p>
<pre><code class="language-typescript">&#39;use client&#39;;

import { IMGURLS } from &#39;@/constants/images.constant&#39;;
import useGeoLocation from &#39;@/lib/hooks/useGeolocation&#39;;
import Script from &#39;next/script&#39;;
import { Map, MapMarker } from &#39;react-kakao-maps-sdk&#39;;

const KAKAO_SDK_URL = //dapi.kakao.com/v2/maps/sdk.js?appkey=${process.env.NEXT_PUBLIC_KAKAO_API_KEY}&amp;libraries=services,clusterer&amp;autoload=false;
const imgUrl = IMGURLS.myLocationIconImgUrl;

const KakaoMap = () =&gt; {
  const myLocation = useGeoLocation();
  return (
    &lt;&gt;
      &lt;section className=&quot;h-lvh mr-1&quot;&gt;
        &lt;Script src={KAKAO_SDK_URL} strategy=&quot;beforeInteractive&quot; /&gt;
        &lt;Map
          center={
            myLocation ? { lat: myLocation.latitude, lng: myLocation.longitude } : { lat: 37.715133, lng: 126.734086 }
          }
          style={{ width: &#39;800px&#39;, height: &#39;100%&#39; }}
        &gt;
          {myLocation &amp;&amp; (
            &lt;MapMarker
              position={{ lat: myLocation.latitude, lng: myLocation.longitude }}
              image={{ src: imgUrl, size: { width: 70, height: 70 } }}
              title=&quot;현재 위치&quot;
            /&gt;
          )}
        &lt;/Map&gt;
      &lt;/section&gt;
    &lt;/&gt;
  );
};

export default KakaoMap;</code></pre>
<p><strong>변경 후 코드</strong></p>
<pre><code class="language-typescript">&#39;use client&#39;;

import { useEffect, useState } from &#39;react&#39;;
import { IMGURLS } from &#39;@/constants/images.constant&#39;;
import useGeoLocation from &#39;@/lib/hooks/useGeolocation&#39;;
import { Map, MapMarker } from &#39;react-kakao-maps-sdk&#39;;

const KAKAO_SDK_URL = `https://dapi.kakao.com/v2/maps/sdk.js?appkey=${process.env.NEXT_PUBLIC_KAKAO_API_KEY}&amp;libraries=services,clusterer&amp;autoload=false`;
const imgUrl = IMGURLS.myLocationIconImgUrl;
const KakaoMap = () =&gt; {
  const myLocation = useGeoLocation();
  const [isLoaded, setIsLoaded] = useState(false);
  useEffect(() =&gt; {
    const script = document.createElement(&#39;script&#39;);
    script.src = KAKAO_SDK_URL;
    script.onload = () =&gt; {
      kakao.maps.load(() =&gt; {
        setIsLoaded(true);
      });
    };
    document.head.appendChild(script);
    return () =&gt; {
      document.head.removeChild(script);
    };
  }, []);
  return (
    &lt;section className=&quot;h-lvh mr-1&quot;&gt;
      {isLoaded &amp;&amp; (
        &lt;Map
          center={
            myLocation ? { lat: myLocation.latitude, lng: myLocation.longitude } : { lat: 37.715133, lng: 126.734086 }
          }
          style={{ width: &#39;800px&#39;, height: &#39;100%&#39; }}
        &gt;
          {myLocation &amp;&amp; (
            &lt;MapMarker
              position={{ lat: myLocation.latitude, lng: myLocation.longitude }}
              image={{ src: imgUrl, size: { width: 70, height: 70 } }}
              title=&quot;현재 위치&quot;
            /&gt;
          )}
        &lt;/Map&gt;
      )}
    &lt;/section&gt;
  );
};
export default KakaoMap;</code></pre>
<h2 id="메모">메모</h2>
<p>코드를 항상 뜯어보고 이해하자...
지금은 시간이 부족해서 구현하기에만 급급하지만...
그리고 문제 해결에 적극적으로 나서자 시간 낭비를 줄이도록</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 13주차 화요일. 심화 프로젝트 - Next.js에서 카카오맵 api 사용하기]]></title>
            <link>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-13%EC%A3%BC%EC%B0%A8-%ED%99%94%EC%9A%94%EC%9D%BC</link>
            <guid>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-13%EC%A3%BC%EC%B0%A8-%ED%99%94%EC%9A%94%EC%9D%BC</guid>
            <pubDate>Thu, 11 Jul 2024 00:03:45 GMT</pubDate>
            <description><![CDATA[<h2 id="방법-정리">방법 정리..</h2>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 13주차 월요일. 심화 프로젝트 - 기획, UI 구성 및 프로젝트 세팅]]></title>
            <link>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-13%EC%A3%BC%EC%B0%A8-%EC%9B%94%EC%9A%94%EC%9D%BC</link>
            <guid>https://velog.io/@minn__ij/%EB%82%B4%EB%B0%B0%EC%BA%A0TIL-13%EC%A3%BC%EC%B0%A8-%EC%9B%94%EC%9A%94%EC%9D%BC</guid>
            <pubDate>Mon, 08 Jul 2024 13:49:53 GMT</pubDate>
            <description><![CDATA[<h2 id="✍🏻">✍🏻</h2>
<p><strong>하루종일 회의했던 날...</strong>
오늘은 하루 내내 새 팀 프로젝트의 기획과 디자인을 하는 날이었다.
낮밤이 바뀌어서 두 시간 정도 자고 왔는데, 몽롱한 상태로 하루종일 계속 소통하니까 예쁘고 부드럽게 말하는 걸 신경쓰지 못 한 것 같다...
내일부터는 다시 좋은 팀원이 되도록 노력해보자..!!</p>
<p><strong>내일의 계획</strong>
지금 맡은 파트 빨리 끝내기
빨리 끝내서 다른 분들 파트 나눠 할 거 있으면 해보기
알고리즘 문제 매일 풀기!
사이드 프로젝트 계획했던 거 빨리 빨리 해보자</p>
]]></description>
        </item>
    </channel>
</rss>