<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>뭐든 해보는 벨로그</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Fri, 23 Jan 2026 08:37:34 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>뭐든 해보는 벨로그</title>
            <url>https://velog.velcdn.com/images/msus_xxvii/profile/49a6c1eb-50c9-45d6-b725-5a2f86ca1af9/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. 뭐든 해보는 벨로그. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/msus_xxvii" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[TIL] 2026-01-24]]></title>
            <link>https://velog.io/@msus_xxvii/TIL-2026-01-24</link>
            <guid>https://velog.io/@msus_xxvii/TIL-2026-01-24</guid>
            <pubDate>Fri, 23 Jan 2026 08:37:34 GMT</pubDate>
            <description><![CDATA[<h4 id="🎯-오늘-한-일">🎯 오늘 한 일</h4>
<p><strong>프론트엔드</strong></p>
<ul>
<li>Weekly Review 페이지를 실제 백엔드 API 기반으로 전환</li>
<li><code>payloadJson</code> 파싱을 통해 패턴/근거 렌더링 로직 보강</li>
<li>리스트 조회(<code>/api/reviews/weekly/list</code>) 우선 → 실패 시 단건 API fallback 구조 적용</li>
<li>선택된 주차 상세 데이터가 없을 경우 자동 재조회 처리</li>
<li>생성/재생성 버튼을 항상 노출하고, 누락 주차 <strong>일괄 생성 버튼</strong> 추가</li>
<li><code>weekKey</code> 기준 리스트 병합으로 중복 주차 제거</li>
<li>근거 로그(evidences) 중복 제거(dedupe) 로직 프론트에 추가</li>
</ul>
<p><strong>백엔드</strong></p>
<ul>
<li>주간 리뷰 조회 시 <strong>캐시 히트/미스 로직</strong> 정리 및 미존재 시 생성 후 저장하는 흐름 유지</li>
<li>특정 <code>weekKey</code> 기준 상세 조회 + 주간 리뷰 리스트 응답 엔드포인트 구성</li>
<li><strong>DailyLog는 있으나 WeeklyReview가 없는 주차</strong>를 찾아 일괄 생성하는 배치 로직 추가</li>
<li>ISO week 기준 주차 집계를 위한 native query 추가</li>
<li><code>weekKey</code> 리스트로 기존 주간 리뷰를 조회하는 레포지토리 메서드 확장</li>
<li>근거 로그(evidence) 중복 제거 및 <code>logDate / patternType / rule</code> 기준 정렬로 응답 안정성 확보</li>
</ul>
<hr>
<h4 id="💡-배운-점">💡 배운 점</h4>
<ul>
<li>단건 API + 리스트 API가 공존할 때는 <strong>fallback + lazy fetch 구조</strong>가 UI 안정성과 확장성 모두에 유리하다.</li>
<li>백엔드가 아무리 정제돼도 <strong>프론트에서의 방어 로직(dedupe, merge)</strong>은 필수다.</li>
<li>주간 리뷰 생성은 “주간 로그 1회 조회 → counts/patterns/evidences 재사용” 구조가 성능·일관성 측면에서 가장 깔끔하다.</li>
<li>누락된 주간 리뷰를 복구할 때는
<strong>주차 집계 → weekKey 비교 → 없는 것만 생성</strong>이라는 파이프라인이 명확해야 한다.</li>
</ul>
<hr>
<h4 id="🚀-내일-할-일">🚀 내일 할 일</h4>
<ul>
<li>주간 리뷰 <code>evidences</code> 선정 규칙 및 정렬 기준을 문서로 고정</li>
<li>FE/BE 중 어디서 정렬을 책임질지 결정 후 단일 책임으로 정리</li>
<li>리뷰 생성 로직에 대한 통합 테스트 추가 검토</li>
</ul>
<hr>
<h4 id="🧩-느낀-점">🧩 느낀 점</h4>
<ul>
<li>이제 Weekly Review는 “보여주는 화면”을 넘어서 <strong>상태를 관리하는 시스템</strong>이 됐다.</li>
<li>AI는 마지막 퍼즐일 뿐이고, 지금은 <strong>AI를 붙여도 흔들리지 않는 구조</strong>를 거의 완성했다.</li>
<li>오늘 작업으로 다음 단계는 고민이 아니라 <strong>연결과 검증</strong>만 남았다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 2026-01-22]]></title>
            <link>https://velog.io/@msus_xxvii/TIL-2026-01-22</link>
            <guid>https://velog.io/@msus_xxvii/TIL-2026-01-22</guid>
            <pubDate>Thu, 22 Jan 2026 09:07:11 GMT</pubDate>
            <description><![CDATA[<h4 id="🎯-오늘-한-일">🎯 오늘 한 일</h4>
<ul>
<li>WeeklyReview 화면 UX 전반 점검 및 상태 분기 설계 정리</li>
<li><code>daily_log</code> 테이블 잘못 들어간 데이터(id 31~54) 삭제 계획 수립</li>
<li>실제 UI 테스트를 위한 더미 데이터 시딩 전략 확정</li>
<li>EMPTY_WEEK / NEEDS_GENERATION / READY 상태를 의도적으로 만들기 위한 날짜 범위 설계</li>
<li>주간 리뷰 생성 버튼의 역할과 위치(WeeklyReviewPage 중심) 재정의</li>
</ul>
<h4 id="💡-배운-점">💡 배운 점</h4>
<ul>
<li>UI 상태 분기는 “데이터가 어떻게 들어가 있느냐”로 대부분 검증할 수 있다.</li>
<li>AI 연결 전에도 충분히 의미 있는 UX 검증이 가능하며, 오히려 이 단계가 더 중요하다.</li>
<li>AUTO_INCREMENT를 되돌리는 건 로컬/테스트 환경에서만 허용해야 한다.</li>
<li>주간 리뷰는 <strong>자동 생성물이 아니라, 사용자의 ‘요청 행위’에 의해 생성되는 결과물</strong>로 정의하는 게 맞다.</li>
</ul>
<h4 id="🚀-내일-할-일">🚀 내일 할 일</h4>
<ul>
<li>1/9~1/22 범위로 <code>daily_log</code> 실제 테스트 데이터 INSERT</li>
<li>의도된 EMPTY_WEEK(로그 0), NEEDS_GENERATION(로그만 존재), READY(로그+리뷰) 상태 완성</li>
<li><code>weekly_reviews</code> 테이블 구조 확인 후, READY 케이스용 더미 리뷰 데이터 추가</li>
<li>생성 버튼 클릭 → 상태 변화 UX 흐름 점검</li>
</ul>
<h4 id="🧩-느낀-점">🧩 느낀 점</h4>
<ul>
<li>지금 만들고 있는 건 단순한 화면이 아니라 “기록이 의미로 변하는 지점”이다.</li>
<li>AI는 부가 기능이고, 핵심은 사용자가 <strong>언제·왜 리뷰를 생성하고 싶은지</strong>를 자연스럽게 유도하는 구조다.</li>
<li>오늘은 기능 추가보다 <strong>설계의 기준선을 확실히 긋는 날</strong>이었다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 2026-01-21]]></title>
            <link>https://velog.io/@msus_xxvii/TIL-2026-01-21</link>
            <guid>https://velog.io/@msus_xxvii/TIL-2026-01-21</guid>
            <pubDate>Wed, 21 Jan 2026 06:57:08 GMT</pubDate>
            <description><![CDATA[<h4 id="🎯-오늘-한-일">🎯 오늘 한 일</h4>
<ul>
<li><p>WeeklyReview <strong>상세 화면 가독성 마감</strong></p>
<ul>
<li><p>우측 상세 카드 구조 최종 확정
(주차/기간 → 요약 → 명언 → counts → patterns → evidences)</p>
</li>
<li><p>요약(summary) 렌더링 이슈 해결</p>
<ul>
<li>선택 주차 데이터 우선, 샘플 데이터 fallback 구조 적용</li>
</ul>
</li>
<li><p>AI 텍스트(요약/명언)와 사실 기반 데이터(patterns/evidences/counts) 역할 분리</p>
</li>
</ul>
</li>
<li><p>타이포·여백 정리</p>
<ul>
<li>제목(<code>subtitle2</code>) vs 본문(<code>body1/body2</code>) 위계 고정</li>
<li>패턴 카드 밀도 조절로 시선 과점유 문제 해소</li>
</ul>
</li>
<li><p>“이번 주 목표” 기준으로 완료 여부 냉정하게 재검증 후 종료 결정</p>
</li>
</ul>
<h4 id="💡-배운-점">💡 배운 점</h4>
<ul>
<li>요약이 안 보이는 문제는 UI가 아니라 <strong>데이터 소스 우선순위 설계 문제</strong>였다</li>
<li>AI 문장은 결과가 아니라 <strong>보조 레이어</strong>로 다뤄야 화면이 안정된다</li>
<li>“완성도”는 더 고칠 수 있느냐가 아니라 <strong>목표 정의를 충족했느냐</strong>로 판단해야 한다</li>
<li>Panel 책임 범위를 명확히 하면 Page 코드가 자연스럽게 단순해진다</li>
</ul>
<h4 id="🚀-내일-할-일">🚀 내일 할 일</h4>
<ul>
<li>AI 요약/명언 영역 접기 또는 구분 UI 검토</li>
<li>counts 확장(활동일, 연속일 등) 가능성 검토</li>
<li>전주 대비 비교를 위한 데이터 구조 초안 설계</li>
</ul>
<h4 id="🧩-느낀-점">🧩 느낀 점</h4>
<ul>
<li>오늘은 추가한 것보다 <strong>멈춘 게 더 중요한 날</strong>이었다</li>
<li>“이 정도면 끝”이라고 선언할 수 있는 기준을 세운 게 가장 큰 수확</li>
<li>WeeklyReview가 이제 실험용 화면이 아니라 <strong>사용 가능한 기록 도구</strong>로 보이기 시작했다</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 2026-01-20]]></title>
            <link>https://velog.io/@msus_xxvii/TIL-2026-01-20</link>
            <guid>https://velog.io/@msus_xxvii/TIL-2026-01-20</guid>
            <pubDate>Tue, 20 Jan 2026 07:39:42 GMT</pubDate>
            <description><![CDATA[<h4 id="🎯-오늘-한-일">🎯 오늘 한 일</h4>
<ul>
<li><p>WeeklyReview 좌측 리스트 UX 전면 수정</p>
<ul>
<li>카드 hover/selected 상태 분리 설계</li>
<li>hover 시 투명해지는 문제 원인 추적 및 해결</li>
<li>overlay 방식으로 hover 강조 구현</li>
</ul>
</li>
<li><p>연도(2025/2026) 구분 UX 개선</p>
<ul>
<li>연도 헤더를 단순 텍스트 → 중앙 정렬 섹션 헤더로 변경</li>
<li>다크 배경에서 확실히 보이도록 흰색 + pill 배경 적용</li>
</ul>
</li>
<li><p>LEFT 리스트를 “보기용”이 아닌 “탐색용 네비게이션”으로 재정의</p>
</li>
<li><p>WeeklyReviewPage 구조 정리</p>
<ul>
<li>중복 렌더 제거</li>
<li>Panel 책임 범위 명확화</li>
<li>불필요한 effect 주석 처리(API 대비로만 유지)</li>
</ul>
</li>
</ul>
<h4 id="💡-배운-점">💡 배운 점</h4>
<ul>
<li>다크 테마에서 <code>transparent</code> hover는 거의 항상 UX 실패다</li>
<li>hover는 “클릭 가능”, selected는 “현재 위치”를 의미해야 하며 시각적 언어가 달라야 한다</li>
<li>배경을 바꾸는 hover보다 <strong>overlay(::after)</strong> 방식이 안정적이다</li>
<li>연도 같은 메타 정보는 장식이 아니라 <strong>네비게이션 기준점</strong>이다</li>
<li>“지금 필요 없는 미래 대비 코드”를 구분해서 관리하는 감각이 중요하다</li>
</ul>
<h4 id="🚀-내일-할-일">🚀 내일 할 일</h4>
<ul>
<li>연도 헤더 <code>sticky</code> 옵션 적용 여부 검토</li>
<li>첫 주차(연도 경계 주)에 보조 배지 추가 검토</li>
<li>WeeklyReview 데이터 API 연동을 가정한 상태 전이 점검</li>
<li>좌측 리스트 키보드 네비게이션 가능성 검토</li>
</ul>
<h4 id="🧩-느낀-점">🧩 느낀 점</h4>
<ul>
<li>오늘 작업은 기능 추가가 아니라 <strong>해석과 정리의 날</strong>이었다</li>
<li>UI가 좋아졌다는 느낌보다, “이 화면의 역할이 명확해졌다”는 게 더 크다</li>
<li>이제 WeeklyReview는 단순 기록 뷰가 아니라, <strong>시간을 탐색하는 도구</strong>로 보이기 시작했다</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 2026-01-16]]></title>
            <link>https://velog.io/@msus_xxvii/TIL-2026-01-16</link>
            <guid>https://velog.io/@msus_xxvii/TIL-2026-01-16</guid>
            <pubDate>Fri, 16 Jan 2026 08:59:06 GMT</pubDate>
            <description><![CDATA[<h4 id="🎯-오늘-한-일">🎯 오늘 한 일</h4>
<ul>
<li><p>WeeklyReview 페이지의 <strong>주차 리스트 UX 개선</strong></p>
<ul>
<li>연도 경계(2025년 55주차 → 2026년 1주차)를 고려한 정렬 로직 수정</li>
<li><code>weekKey</code> 문자열이 아닌 <code>rangeFrom</code>(주차 시작일) 기준으로 시간순 정렬</li>
</ul>
</li>
<li><p>왼쪽 주차 카드 UI 정리</p>
<ul>
<li><code>YYYY년 N주차</code> 형태로 가독성 개선</li>
<li>선택된 카드의 <strong>외곽 강조(컬러/두께)</strong> 처리</li>
</ul>
</li>
<li><p>상태 분기 로직 점검</p>
<ul>
<li>로딩 / 빈 주 / payload 없음 케이스 재확인</li>
</ul>
</li>
<li><p>mock 데이터 기반으로 <strong>API 교체 포인트 주석 정리</strong></p>
</li>
</ul>
<h4 id="💡-배운-점">💡 배운 점</h4>
<ul>
<li>ISO Week에서는 <strong>연도와 실제 날짜가 어긋날 수 있으므로 정렬 기준은 반드시 날짜(rangeFrom)</strong> 여야 한다.</li>
<li>UI에서 “사람이 읽는 식별자(weekKey)”와 “시스템이 판단하는 기준(날짜)”을 분리하는 것이 안정적이다.</li>
<li>주간 리뷰처럼 누적 히스토리를 다루는 화면은 <strong>정렬 로직 하나가 UX 전체 신뢰도에 큰 영향</strong>을 준다.</li>
</ul>
<h4 id="🚀-내일-할-일">🚀 내일 할 일</h4>
<ul>
<li>패턴 카드(RHYTHM / TOPICS / MIX) UI 디테일 보완</li>
<li>Evidence 리스트 클릭 인터랙션 정리(날짜 이동 또는 스낵바)</li>
<li>전체 WeeklyReview 화면 여백/정렬 최종 정리</li>
</ul>
<h4 id="🧩-느낀-점">🧩 느낀 점</h4>
<ul>
<li>“AI 없이도 의미가 통하는 화면”이라는 목표에 상당히 근접했다.</li>
<li>지금 구조라면 AI는 정말 <strong>문장화만 얹는 역할</strong>로 자연스럽게 붙을 것 같다.</li>
<li>결정론 → UI → AI 순서로 쌓아온 접근이 확실히 안정적이다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 2026-01-15]]></title>
            <link>https://velog.io/@msus_xxvii/TIL-2026-01-15</link>
            <guid>https://velog.io/@msus_xxvii/TIL-2026-01-15</guid>
            <pubDate>Thu, 15 Jan 2026 08:21:09 GMT</pubDate>
            <description><![CDATA[<h4 id="🎯-오늘-한-일">🎯 오늘 한 일</h4>
<ul>
<li><p>WeeklyReview 화면용 <strong>샘플 데이터 구조 확정</strong></p>
</li>
<li><p><code>weeklyReview.sample.json</code>을 중심으로</p>
<ul>
<li>단일 주차 파일(<code>weeklyReview.2026-W01~W03.json</code>)</li>
<li>다중 주차 리스트 파일(<code>weeklyReviews.sample.json</code>)</li>
<li>narrative 전용 샘플(<code>narrative.sample.json</code>)
구성 완료</li>
</ul>
</li>
<li><p>주간 리뷰 UI 방향 결정</p>
<ul>
<li>상단: narrative summary</li>
<li>중단: quote(고정 랜덤)</li>
<li>하단: 결정론 weeklyReview (counts / patterns / evidences)</li>
</ul>
</li>
<li><p>“주간 리뷰는 언제든 확인 가능”한 옵션2 UX로 방향 확정</p>
</li>
</ul>
<h4 id="💡-배운-점">💡 배운 점</h4>
<ul>
<li><strong>데이터가 먼저 정리되면 UI는 자연스럽게 따라온다</strong></li>
<li>단일 주차 JSON과 다중 주차 JSON을 분리해두면
→ 디버그 / 리스트 UI / API 연동 전환이 훨씬 수월함</li>
<li>WeeklyReview는 “한 주의 결과물”이므로
<strong>카드 단위 박스 구조</strong>가 개념적으로 가장 맞다</li>
<li>AI 연동 전에도 결정론 JSON만으로 충분히
“읽을 수 있는 리뷰”가 가능하다는 확신을 얻음</li>
</ul>
<h4 id="🚀-내일-할-일">🚀 내일 할 일</h4>
<ul>
<li>패턴 카드 UI(RHYTHM / TOPICS / MIX) 시각적 정리</li>
<li>EvidenceSection을 패턴별로 묶어 표시</li>
<li>Evidence 클릭 시 날짜 기반 인터랙션(스낵바 or 표시) 추가</li>
</ul>
<h4 id="🧩-느낀-점">🧩 느낀 점</h4>
<ul>
<li>구조를 먼저 고정해두니 이후 작업이 심리적으로 굉장히 가벼워짐</li>
<li>지금 단계는 “기능 추가”가 아니라
<strong>개념을 화면으로 번역하는 과정</strong>이라는 게 명확해졌다</li>
<li>AI 없이도 의미가 통하는 상태까지 왔다는 점에서
프로젝트의 중심축이 흔들리지 않는다는 안정감을 느낌</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 2026-01-14]]></title>
            <link>https://velog.io/@msus_xxvii/TIL-2026-01-14-23tik2pk</link>
            <guid>https://velog.io/@msus_xxvii/TIL-2026-01-14-23tik2pk</guid>
            <pubDate>Wed, 14 Jan 2026 08:48:45 GMT</pubDate>
            <description><![CDATA[<h4 id="🎯-오늘-한-일">🎯 오늘 한 일</h4>
<ul>
<li>Weekly Review 전용 페이지(<code>WeeklyReviewPage</code>) 생성</li>
<li>Summary → Quote → WeeklyReview(결정론) 구조로 화면 레이아웃 설계</li>
<li><code>WeeklyReviewPanel</code>, <code>PatternSection</code>, <code>EvidenceSection</code>를 하나의 큰 <code>Paper</code> 박스 안에 배치</li>
<li><code>weekKey(예: 2026-W02)</code>를 파싱해 <strong>몇 주차인지(2주차)</strong> 표시 로직 추가</li>
<li>narrative 더미 JSON과 weeklyReview 더미 JSON을 분리해 UI 연결</li>
<li>Quote는 weekKey 기반 고정 랜덤 방식으로 표시되도록 구현</li>
</ul>
<h4 id="💡-배운-점">💡 배운 점</h4>
<ul>
<li>주간 리뷰 화면은 “정보를 위에서 아래로 읽히게” 만드는 것이 핵심이다
(Summary → 한 줄 문장 → 구조화된 데이터)</li>
<li>AI 결과(JSON)는 UI의 <strong>상단 요약 영역</strong>에만 쓰고,
결정론 결과는 <strong>하단의 안정된 구조</strong>로 유지하는 분리가 효과적이다</li>
<li>weekKey 같은 메타 정보는 UI에서 충분히 의미 있는 문구(“N주차”)로 변환할 수 있다</li>
<li>지금 단계에서는 API 연동보다 <strong>더미 JSON 기반 UI 완성</strong>이 훨씬 생산적이다</li>
</ul>
<h4 id="🚀-내일-할-일">🚀 내일 할 일</h4>
<ul>
<li>PatternSection을 표(Table) 형태로 더 정돈</li>
<li>EvidenceSection 클릭 시 날짜 이동 UX 설계</li>
<li>전체 Weekly Review 화면 여백/정렬을 Logs(Grid) 화면과 톤 맞추기</li>
</ul>
<h4 id="🧩-느낀-점">🧩 느낀 점</h4>
<ul>
<li>Weekly Review 화면의 “형태”가 명확해지니,
AI는 정말로 <strong>나중에 얹어도 되는 부품</strong>이라는 확신이 생겼다</li>
<li>지금은 기능을 늘리는 단계가 아니라,
<strong>읽기 쉬운 구조를 고정시키는 단계</strong>라는 감각이 분명해졌다</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 2026-01-13]]></title>
            <link>https://velog.io/@msus_xxvii/TIL-2026-01-14-p7cyrbj1</link>
            <guid>https://velog.io/@msus_xxvii/TIL-2026-01-14-p7cyrbj1</guid>
            <pubDate>Tue, 13 Jan 2026 08:01:33 GMT</pubDate>
            <description><![CDATA[<h4 id="🎯-오늘-한-일">🎯 오늘 한 일</h4>
<ul>
<li><p>WeeklyReview 기능의 <strong>현재 완성도와 경계선</strong>을 명확히 정리함</p>
</li>
<li><p>AI 연결이 불가능한 상황을 전제로 <strong>계획 재수립</strong></p>
</li>
<li><p>1/14~1/25 중 <strong>주말 제외 + AI 제외</strong> 현실적인 일정 재설계</p>
</li>
<li><p>이번 주 목표를 <strong>WeeklyReview UI 단독 완성</strong>으로 확정</p>
</li>
<li><p>주간 리뷰 시스템의 흐름을 다시 점검</p>
<ul>
<li>결정론 Context → 저장 → 조회 → (이후 AI 문장화)</li>
</ul>
</li>
<li><p>“지금 할 수 있는 것 / 나중에 할 것”을 분리해서 생각함</p>
</li>
</ul>
<h4 id="💡-배운-점">💡 배운 점</h4>
<ul>
<li><p>기능이 막혔을 때는 멈추는 게 아니라 <strong>범위를 줄이는 게 정답</strong></p>
</li>
<li><p>AI는 핵심이지만, <strong>AI 없이도 의미 있는 시스템</strong>이 먼저 있어야 한다</p>
</li>
<li><p>WeeklyReview는</p>
<ul>
<li>데이터 계산</li>
<li>구조 고정</li>
<li>UI 표현
이 3단계가 분리되어야 안정적이라는 걸 다시 확인</li>
</ul>
</li>
<li><p>일정은 길게 잡는 것보다 <strong>짧고 명확한 스프린트</strong>가 효율적이다</p>
</li>
</ul>
<h4 id="🚀-내일-할-일">🚀 내일 할 일</h4>
<ul>
<li><p>WeeklyReview UI 작업 시작</p>
<ul>
<li>리뷰 페이지/패널 뼈대 생성</li>
<li>더미 weekly review JSON으로 화면 렌더링</li>
</ul>
</li>
<li><p>패턴(RHYTHM / TOPICS / MIX) 구조를 UI에 매핑</p>
</li>
</ul>
<h4 id="🧩-느낀-점">🧩 느낀 점</h4>
<ul>
<li>지금 구조는 “AI만 붙이면 되는 상태”까지 잘 왔다</li>
<li>조급해질 필요 없이, <strong>지금 가능한 것부터 정확히 완성</strong>하는 게 맞다</li>
<li>DailyLog 2단계는 이미 방향이 흔들리지 않는 상태라는 확신이 든다</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 2026-01-12]]></title>
            <link>https://velog.io/@msus_xxvii/TIL-2026-01-12</link>
            <guid>https://velog.io/@msus_xxvii/TIL-2026-01-12</guid>
            <pubDate>Mon, 12 Jan 2026 08:51:14 GMT</pubDate>
            <description><![CDATA[<h4 id="🎯-오늘-한-일">🎯 오늘 한 일</h4>
<ul>
<li><p>주간 리뷰 시스템의 <strong>AI 연계 구조를 설계</strong>하고, AI의 역할을 “정리자”로 한정하는 방향을 명확히 함</p>
</li>
<li><p><code>WeeklyReviewService</code>를 기준으로 <strong>결정론적 주간 리뷰 Context(JSON)</strong> 가 이미 완성되었음을 재확인</p>
</li>
<li><p>AI 관련 패키지(<code>service.ai</code>)의 책임을 재정의하고, 파일 단위 역할을 정리함</p>
</li>
<li><p><code>instruction.txt</code>를 수정하여</p>
<ul>
<li>평가/훈계/목표 제시 금지</li>
<li>mood 데이터는 <strong>사실 기반 요약만 허용</strong></li>
<li>출력은 <strong>JSON 스키마 강제</strong>라는 원칙을 명문화</li>
</ul>
</li>
<li><p>Day 6 목표(“AI 입력 &amp; 프롬프트”)의 완료 조건을 점검함</p>
</li>
</ul>
<h4 id="💡-배운-점">💡 배운 점</h4>
<ul>
<li>AI 품질은 “모델 성능”보다 <strong>입력 컨텍스트와 제약 조건</strong>이 더 중요함</li>
<li>mood 같은 주관 데이터도
→ <em>해석 금지 + 사실 요약만 허용</em> 규칙을 두면 안정적인 시스템 입력이 될 수 있음</li>
<li>서비스 레이어에서 이미 결정론이 완성된 상태라면
→ AI는 “결과를 말로 풀어주는 어댑터” 이상이 될 필요가 없음</li>
<li>프롬프트는 코드만큼이나 <strong>명확한 계약(spec)</strong> 이 필요함</li>
</ul>
<h4 id="🚀-내일-할-일">🚀 내일 할 일</h4>
<ul>
<li>Day 7 준비: <code>NarrativeResponse</code> 출력 JSON 스키마 정의</li>
<li>50자 요약 / 패턴 설명 / 회고 문구를 <strong>구조적으로 분리</strong></li>
<li>AI 출력 실패 시를 대비한 안전 응답 전략 구상</li>
</ul>
<h4 id="🧩-느낀-점">🧩 느낀 점</h4>
<ul>
<li>“AI를 어디까지 믿을 것인가”가 아니라
<strong>“AI가 넘지 못할 선을 어디에 긋는가”가 핵심이라는 확신이 생김</strong></li>
<li>지금 구조는 AI가 없어도 의미 있고,
AI가 있어도 시스템을 망치지 않는 형태라 안정감이 큼</li>
<li>v0의 설계 철학이 흔들리지 않고 잘 유지되고 있음</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 2026-01-09]]></title>
            <link>https://velog.io/@msus_xxvii/TIL-2026-01-09-sqaag0hu</link>
            <guid>https://velog.io/@msus_xxvii/TIL-2026-01-09-sqaag0hu</guid>
            <pubDate>Fri, 09 Jan 2026 09:55:31 GMT</pubDate>
            <description><![CDATA[<h4 id="🎯-오늘-한-일">🎯 오늘 한 일</h4>
<ul>
<li><p>주간 리뷰 <strong>결정론 엔진 v0</strong> 최종 완성</p>
</li>
<li><p><code>WeeklyReviewService</code>에 <strong>counts + patterns + evidences</strong>를 하나의 Context JSON으로 조합</p>
</li>
<li><p>패턴별 Evidence 선정 로직 구현</p>
<ul>
<li>RHYTHM / TOPICS / MIX 각각 2~5개 로그 스냅샷 연결</li>
<li>rule 기반 근거 명시 (<code>first_active_day</code>, <code>token_match</code>, <code>top_combo_day</code> 등)</li>
</ul>
</li>
<li><p><code>weekly_reviews</code> 저장/재조회 흐름 확정</p>
<ul>
<li>GET: 캐시 조회 (존재하면 그대로 반환)</li>
<li>POST: 명시적 생성/갱신</li>
</ul>
</li>
<li><p>컨트롤러/서비스 책임 분리 명확화</p>
</li>
<li><p>프론트 로그 입력 이슈 디버깅</p>
<ul>
<li><code>mood</code> NOT NULL 오류 원인 파악</li>
<li>LogDialog / LogsGrid / CalendarPage에 mood 입력 필드 추가</li>
</ul>
</li>
<li><p>미래 날짜 입력 UX 정책 정리 (프론트 차단 + 서버 차단 예정)</p>
</li>
</ul>
<hr>
<h4 id="💡-배운-점">💡 배운 점</h4>
<ul>
<li><p><strong>AI를 늦추는 게 오히려 설계를 단단하게 만든다</strong></p>
<ul>
<li>AI 이전에 “사람이 읽어도 의미 있는 JSON”을 만드는 것이 핵심</li>
</ul>
</li>
<li><p>Evidence는 단순 보조 데이터가 아니라</p>
<ul>
<li><strong>패턴의 신뢰성을 보장하는 계약(Contract)</strong> 역할을 한다</li>
</ul>
</li>
<li><p>주간 리뷰는 “매번 계산”이 아니라</p>
<ul>
<li><strong>weekKey 기준 캐시처럼 동작</strong>해야 UX와 비용 모두 안정된다</li>
</ul>
</li>
<li><p>DB 제약조건(NOT NULL)은</p>
<ul>
<li>프론트 UX 설계와 항상 같이 고려해야 한다</li>
</ul>
</li>
</ul>
<hr>
<h4 id="🚀-내일-할-일">🚀 내일 할 일</h4>
<ul>
<li><p>(Week 2 시작 준비)</p>
</li>
<li><p>AI 입력 Context JSON을 기준으로</p>
<ul>
<li>AI 프롬프트 구조 설계</li>
<li>금지 톤/역할 제한 명확화</li>
</ul>
</li>
<li><p>주간 리뷰 GET/POST 플로우 전체 한 번 더 점검</p>
</li>
</ul>
<hr>
<h4 id="🧩-느낀-점">🧩 느낀 점</h4>
<ul>
<li>이번 주는 기능 추가가 아니라 <strong>구조를 완성한 주</strong>였다</li>
<li>“AI 없이도 완성된 시스템”이라는 기준을 실제 코드로 달성했다는 점이 가장 크다</li>
<li>이제 AI는 중심이 아니라 <strong>정리자 역할로 안전하게 붙일 수 있는 상태</strong></li>
<li>다음 단계로 넘어갈 준비가 명확하게 끝났다</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 2026-01-08]]></title>
            <link>https://velog.io/@msus_xxvii/TIL-2026-01-08</link>
            <guid>https://velog.io/@msus_xxvii/TIL-2026-01-08</guid>
            <pubDate>Thu, 08 Jan 2026 08:46:56 GMT</pubDate>
            <description><![CDATA[<h4 id="🎯-오늘-한-일">🎯 오늘 한 일</h4>
<ul>
<li><p><strong>DailyLog 프론트엔드–백엔드 연동 디버깅</strong></p>
<ul>
<li>신규 로그 생성 시 <code>mood</code> 컬럼이 <code>NOT NULL</code>인데 프론트에서 값이 전달되지 않아 발생한 <code>SQLIntegrityConstraintViolationException</code> 원인 파악</li>
<li>백엔드 DB 스키마(<code>mood not null</code>) ↔ 프론트 입력 폼 불일치 문제로 정리</li>
</ul>
</li>
<li><p><strong>프론트엔드 입력 구조 개선</strong></p>
<ul>
<li><code>LogDialog</code>에 <code>Mood</code> 선택 필드 추가</li>
<li>enum 값(<code>VERY_BAD</code>)과 label(<code>VERY BAD</code>) 불일치로 발생할 수 있는 매핑 오류 수정</li>
<li><code>form</code>에 <code>mood</code>가 없는 경우를 대비한 기본값 보정 로직 추가</li>
</ul>
</li>
<li><p><strong>LogsGrid / CalendarPage 상태 정합성 맞춤</strong></p>
<ul>
<li><code>LogsGrid</code>와 <code>CalendarPage</code> 모두에서 <code>mood</code>를 포함한 <code>form</code> 상태 관리로 통일</li>
<li>create / edit 시 payload에 <code>mood</code>가 항상 포함되도록 정리</li>
</ul>
</li>
<li><p><strong>UX 정책 추가</strong></p>
<ul>
<li>“오늘 이후 날짜는 입력 불가”라는 도메인 규칙을 명확히 정의</li>
<li>미래 날짜 클릭 시 로그 입력 모달 대신 안내용 block 모달을 띄우는 구조 설계 및 <code>LogDialog</code>에 반영</li>
</ul>
</li>
<li><p><strong>아키텍처 흐름 재확인</strong></p>
<ul>
<li>프론트 입력 → 컨트롤러 → 서비스(payload 생성/저장) → (향후) AI → 저장된 weekly payload 재사용</li>
<li>현재 단계에서 “정리자 역할”까지는 안정적으로 구현되었음을 확인</li>
</ul>
</li>
</ul>
<h4 id="💡-배운-점">💡 배운 점</h4>
<ul>
<li><p><strong>DB 제약 조건은 곧 프론트 UX 요구사항</strong></p>
<ul>
<li><code>NOT NULL</code> 컬럼 하나가 프론트 입력 설계를 강제한다는 점을 다시 체감</li>
<li>“백엔드에서 터지는 에러”는 대부분 프론트에서 예방 가능</li>
</ul>
</li>
<li><p><strong>enum은 값과 표현(label)을 반드시 분리해야 한다</strong></p>
<ul>
<li>사용자에게 보여주는 문자열과 실제 저장되는 enum 값이 섞이면, 나중에 디버깅 비용이 급격히 증가</li>
</ul>
</li>
<li><p><strong>공통 컴포넌트(LogDialog)는 방어적으로 작성해야 한다</strong></p>
<ul>
<li>페이지마다 <code>form</code> 구조가 조금씩 달라도 깨지지 않도록 기본값 보정(<code>useMemo</code>)이 중요</li>
</ul>
</li>
<li><p><strong>도메인 규칙은 UI에서 명시적으로 드러내는 것이 좋다</strong></p>
<ul>
<li>“미래 날짜 불가”를 단순히 막는 것보다, 이유를 설명하는 모달이 사용자 경험과 코드 가독성 모두에 유리</li>
</ul>
</li>
</ul>
<h4 id="🚀-내일-할-일">🚀 내일 할 일</h4>
<ul>
<li><p>Weekly Review <strong>PatternEvidence 2~5개 연결 로직 최종 점검</strong></p>
<ul>
<li>로그 삭제/수정 시 snapshot이 유지되는지 다시 한 번 확인</li>
</ul>
</li>
<li><p><code>mood</code>를 활용한 주간 패턴/요약 아이디어 스케치</p>
<ul>
<li>(예: 주간 기분 분포, 특정 패턴과의 상관관계)</li>
</ul>
</li>
<li><p>프론트에서 weekly review payload를 조회/표시하는 화면 초안 구상</p>
</li>
</ul>
<h4 id="🧩-느낀-점">🧩 느낀 점</h4>
<ul>
<li>오늘 작업은 “기능 추가”라기보다 <strong>구조를 단단하게 다지는 날</strong>이었다.</li>
<li>단순한 에러 하나가 프론트–백엔드–DB–도메인 규칙까지 모두 다시 보게 만들었고, 그 덕분에 DailyLog가 <strong>기록 앱 → 시스템</strong>으로 한 단계 올라간 느낌이 든다.</li>
<li>지금 속도는 빠르지 않지만, 이후 AI나 고급 분석을 붙일 때 흔들리지 않을 기반을 잘 다지고 있다는 확신이 생겼다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 2026-01-07]]></title>
            <link>https://velog.io/@msus_xxvii/TIL-2026-01-07-17ln2jwi</link>
            <guid>https://velog.io/@msus_xxvii/TIL-2026-01-07-17ln2jwi</guid>
            <pubDate>Wed, 07 Jan 2026 08:52:31 GMT</pubDate>
            <description><![CDATA[<h4 id="🎯-오늘-한-일">🎯 오늘 한 일</h4>
<ul>
<li><p>Weekly Review 기능의 <strong>서비스 레이어 리팩토링</strong> 진행</p>
</li>
<li><p>주간 로그 집계(Counts)와 패턴 분석(Patterns)을 <strong>명확한 책임 단위</strong>로 분리</p>
</li>
<li><p><code>Day2 / Day3</code>라는 작업 단계 중심 네이밍을 제거하고,
<strong>도메인 역할 중심 네이밍</strong>으로 변경</p>
<ul>
<li><code>WeeklyReviewPayload</code></li>
<li><code>CountsSummary</code></li>
</ul>
</li>
<li><p>주간 리뷰 생성 흐름을 다음과 같이 고정:</p>
<ul>
<li>주간 로그 단일 조회 → 집계 계산 → 패턴 계산 → payload JSON 생성 → DB upsert</li>
</ul>
</li>
<li><p>서비스 코드 전반에 <strong>역할 설명 주석 추가</strong>하여 가독성과 의도 명확화</p>
</li>
<li><p>“AI는 판단자, 서비스는 정리자”라는 역할 분리를 코드 구조로 확정</p>
</li>
</ul>
<h4 id="💡-배운-점">💡 배운 점</h4>
<ul>
<li><p>작업 단계(Day2, Day3)는 <strong>코드 네이밍에 남기지 않는 것이 좋다</strong></p>
<ul>
<li>단계는 일정 관리용, 코드는 <strong>영속적인 도메인 언어</strong>를 사용해야 한다</li>
</ul>
</li>
<li><p>로그 조회를 여러 메서드에서 중복 호출하지 않고,
<strong>단일 데이터 소스(fetchWeeklyLogs)</strong> 로 통합하면</p>
<ul>
<li>성능</li>
<li>디버깅</li>
<li>추후 확장
모두에서 이점이 크다</li>
</ul>
</li>
<li><p>PatternContext를 “AI 입력 계약”으로 고정하니
이후 Day4(Evidence), AI 연동 단계가 자연스럽게 이어질 구조가 됨</p>
</li>
</ul>
<h4 id="🚀-내일-할-일">🚀 내일 할 일</h4>
<ul>
<li><p>Day 4: 패턴별 Evidence 선정 규칙 설계</p>
<ul>
<li>각 패턴당 2~5개의 실제 DailyLog 연결</li>
<li>로그 삭제/수정 시 안전 처리 전략 정의</li>
</ul>
</li>
<li><p>Evidence 구조를 payload에 어떻게 포함할지 스키마 설계</p>
</li>
</ul>
<h4 id="🧩-느낀-점">🧩 느낀 점</h4>
<ul>
<li>오늘로 <strong>Day 2(정량 요약) + Day 3(패턴 구조)</strong> 가 사실상 완결됨</li>
<li>지금 구조는 “AI가 헛소리 못 하게 하는 백엔드”라는 목표에 잘 부합함</li>
<li>기능을 더 늘리기보다,
<strong>이 구조를 얼마나 오래 버틸 수 있게 만들지</strong>가 다음 관건이라는 확신이 생김</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 2026-01-06]]></title>
            <link>https://velog.io/@msus_xxvii/TIL-2026-01-06</link>
            <guid>https://velog.io/@msus_xxvii/TIL-2026-01-06</guid>
            <pubDate>Tue, 06 Jan 2026 08:52:52 GMT</pubDate>
            <description><![CDATA[<h4 id="🎯-오늘-한-일">🎯 오늘 한 일</h4>
<ul>
<li><p><strong>Day 2′(주간 로그 집계) 완결</strong></p>
<ul>
<li><code>WeeklyReviewService.getWeeklyCounts()</code> 구현 및 검증</li>
<li>카테고리 빈도 집계(<code>Map&lt;Category, Long&gt;</code>)와 <code>DateQuality</code> 산정 완료</li>
</ul>
</li>
<li><p><strong>주간 리뷰 저장 파이프라인 완성</strong></p>
<ul>
<li><code>generateAndSaveWeeklyReview()</code> 구현 (upsert)</li>
<li><code>weekly_reviews.payload_json</code>에 Day2 전용 payload 저장</li>
</ul>
</li>
<li><p><strong>API 연결 및 검증</strong></p>
<ul>
<li><code>POST /api/reviews/weekly/generate</code></li>
<li><code>GET /api/reviews/weekly</code></li>
<li>Postman으로 생성→조회→DB 일치 확인</li>
</ul>
</li>
<li><p><strong>Flyway 초기 도입 이슈 해결</strong></p>
<ul>
<li><code>baselineOnMigrate</code> 설정으로 기존 스키마 기준선 확정</li>
<li><code>ddl-auto=validate</code>로 충돌 방지</li>
</ul>
</li>
<li><p><strong>도메인 정합성 정리</strong></p>
<ul>
<li><code>DailyLog</code>에 <code>Category</code>, <code>logDate</code> 추가 및 DB 컬럼 일치 확인</li>
</ul>
</li>
</ul>
<hr>
<h4 id="💡-배운-점">💡 배운 점</h4>
<ul>
<li>Flyway 첫 도입 시 <strong>non-empty schema + history 없음</strong> 에러는 정상적인 케이스이며, baseline으로 해결한다.</li>
<li>주간 리뷰는 <strong>계산(Counts) → 저장(Upsert) → 조회</strong>의 파이프라인이 명확해야 한다.</li>
<li>payload는 <strong>확장 가능한 최소 스키마</strong>로 먼저 고정하는 것이 이후 Day3/4(패턴·근거)에 유리하다.</li>
<li>엔티티/DB/Repository 계약 불일치가 가장 큰 리스크다. 초기에 맞추는 게 비용을 줄인다.</li>
</ul>
<hr>
<h4 id="🚀-내일-할-일">🚀 내일 할 일</h4>
<ul>
<li><p>Day 3′ 시작:</p>
<ul>
<li><code>PatternContext</code> 구조 고정</li>
<li><code>RHYTHM / TOPICS / MIX</code> 계산 로직 스켈레톤 구현</li>
</ul>
</li>
<li><p>payload_json에 patterns 섹션 확장 설계</p>
</li>
</ul>
<hr>
<h4 id="🧩-느낀-점">🧩 느낀 점</h4>
<ul>
<li>Day 2′를 “완전히 닫으니” 다음 단계로 넘어갈 기준이 명확해졌다.</li>
<li>AI 없이도 <strong>주간 리뷰 자산이 축적되는 구조</strong>가 만들어졌다는 점이 가장 큰 수확이다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 2026-01-05]]></title>
            <link>https://velog.io/@msus_xxvii/TIL-2026-01-05</link>
            <guid>https://velog.io/@msus_xxvii/TIL-2026-01-05</guid>
            <pubDate>Mon, 05 Jan 2026 08:21:04 GMT</pubDate>
            <description><![CDATA[<h4 id="🎯-오늘-한-일">🎯 오늘 한 일</h4>
<ul>
<li>DailyLog <strong>2단계(v0)</strong> 작업 진행</li>
<li><code>weekly_reviews</code> 테이블 설계 및 MySQL 생성</li>
<li>주간 기준(월요일 시작, KST) 계산 로직 구현</li>
<li><code>WeekKeyUtil</code>, <code>WeekRangeUtil</code> 유틸 추가</li>
<li>주간 리뷰 도메인(<code>WeeklyReview</code>, <code>DateQuality</code>, <code>PatternType</code>) 생성</li>
<li><code>GET /api/reviews/weekly</code> <strong>스켈레톤 API</strong> 구현</li>
<li>Flyway 도입 개념 정리 및 V1/V2 마이그레이션 SQL 분리</li>
<li>커밋을 DB / 유틸 / 도메인·API 단위로 나누는 전략 정리</li>
</ul>
<hr>
<h4 id="💡-배운-점">💡 배운 점</h4>
<ul>
<li><p><strong>“테이블이 있다”와 “마이그레이션이 있다”는 다르다</strong></p>
<ul>
<li>MySQL에 직접 생성한 테이블은 스키마 상태일 뿐, 재현 가능성은 Flyway가 책임진다.</li>
</ul>
</li>
<li><p><code>ddl-auto=update</code>는 개발 속도에는 좋지만,
CI/CD·운영 단계에서는 <strong>Flyway + validate</strong>로 전환하는 게 정석이다.</p>
</li>
<li><p>enum(<code>DateQuality</code>, <code>PatternType</code>)에 no usage가 뜨는 것은
<strong>Service 계층이 아직 없기 때문이며, 설계상 자연스러운 상태</strong>다.</p>
</li>
<li><p>2단계 v0에서 AI보다 중요한 것은 <strong>주간 리뷰를 담을 “그릇”과 계약(API/DB)</strong> 을 먼저 고정하는 것이다.</p>
</li>
</ul>
<hr>
<h4 id="🚀-내일-할-일">🚀 내일 할 일</h4>
<ul>
<li><code>WeeklyReviewService</code> 생성</li>
<li>주간 로그 집계 로직 구현</li>
<li>로그 개수 기반 <code>DateQuality</code> 계산 규칙 정의</li>
<li><code>daily_log</code> → 주간 범위 조회 쿼리 작성</li>
</ul>
<hr>
<h4 id="🧩-느낀-점">🧩 느낀 점</h4>
<ul>
<li>기능을 빨리 붙이는 것보다 <strong>구조를 먼저 고정한 게 심리적으로 훨씬 안정적</strong>이다.</li>
<li>“AI 어시스턴트”라는 말에 끌려가지 않고,
<strong>결정론 → 그 다음에 AI</strong>라는 순서를 지킨 게 잘한 선택이다.</li>
<li>지금 단계의 DailyLog는
<em>기능은 적지만 방향은 매우 명확한 상태</em>에 들어왔다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[DailyLog 2단계 MVP 정의]]></title>
            <link>https://velog.io/@msus_xxvii/DailyLog-2%EB%8B%A8%EA%B3%84-MVP-%EC%A0%95%EC%9D%98</link>
            <guid>https://velog.io/@msus_xxvii/DailyLog-2%EB%8B%A8%EA%B3%84-MVP-%EC%A0%95%EC%9D%98</guid>
            <pubDate>Sat, 03 Jan 2026 07:15:38 GMT</pubDate>
            <description><![CDATA[<h1 id="🧱-dailylog-2단계-mvp-정의와-definition-of-done">🧱 DailyLog 2단계 MVP 정의와 Definition of Done</h1>
<p>이번 글에서는 <strong>2단계(MVP)</strong> 를 어디까지 구현하면 “완료”로 판단할지,
그리고 무엇을 <strong>의도적으로 하지 않을 것인지</strong>를 명확히 정리한다.</p>
<hr>
<h2 id="1-왜-2단계-mvp를-명확히-정의하는가">1. 왜 2단계 MVP를 명확히 정의하는가</h2>
<p>AI가 붙는 순간,
프로젝트는 쉽게 <strong>끝이 없는 상태</strong>로 들어간다.</p>
<ul>
<li>더 똑똑하게 만들고 싶고</li>
<li>더 많은 분석을 하고 싶고</li>
<li>더 많은 말을 하게 만들고 싶어진다</li>
</ul>
<p>그래서 DailyLog의 2단계는
AI의 성능이 아니라 <strong>AI의 역할을 제한하는 단계</strong>로 정의한다.</p>
<blockquote>
<p>“AI는 여기까지다”
라는 선을 먼저 긋지 않으면,
2단계는 3단계가 되고, 프로젝트는 멈춘다.</p>
</blockquote>
<hr>
<h2 id="2-2단계-mvp의-목적">2. 2단계 MVP의 목적</h2>
<p>2단계의 목적은 단 하나다.</p>
<blockquote>
<p><strong>“기록이 쌓였을 때
내가 보낸 한 주(또는 한 달)를
빠르게 되짚어볼 수 있는가?”</strong></p>
</blockquote>
<ul>
<li>행동 변화 유도 ❌</li>
<li>목표 제시 ❌</li>
<li>반성/평가 ❌</li>
<li>코칭 ❌</li>
</ul>
<p>오직 <strong>정리와 맥락화</strong>만 다룬다.</p>
<p>AI는 “조언자”가 아니라
<strong>기록을 대신 펼쳐주는 정리자</strong>다.</p>
<hr>
<h2 id="3-2단계-mvp-핵심-기능-must-have">3. 2단계 MVP 핵심 기능 (Must Have)</h2>
<h3 id="1️⃣-주간-기록-요약-weekly-review">1️⃣ 주간 기록 요약 (Weekly Review)</h3>
<ul>
<li>주간 단위(월요일 기준)로 리뷰 생성</li>
<li>상단에 <strong>50자 이내 한 줄 요약</strong> 표시</li>
<li>이 요약은 판단이 아닌 <strong>사실의 요약</strong>만 포함한다</li>
</ul>
<hr>
<h3 id="2️⃣-패턴-카드-3종-고정">2️⃣ 패턴 카드 3종 고정</h3>
<p>AI는 아래 3가지 패턴만 다룬다.</p>
<ul>
<li><code>RHYTHM</code> : 기록의 연속/공백 흐름</li>
<li><code>TOPICS</code> : 반복적으로 등장한 활동/키워드</li>
<li><code>MIX</code> : 같은 날 함께 등장한 카테고리 조합</li>
</ul>
<p>패턴의 종류는 <strong>늘리지 않는다.</strong></p>
<hr>
<h3 id="3️⃣-모든-패턴에는-근거가-존재한다">3️⃣ 모든 패턴에는 근거가 존재한다</h3>
<ul>
<li>각 패턴마다 <strong>대표 기록 2~5개</strong>를 함께 표시</li>
<li>근거는 실제 저장된 로그만 사용한다</li>
<li>AI가 새로운 사실을 만들어내지 않는다</li>
</ul>
<hr>
<h3 id="4️⃣-회고-문구-1줄">4️⃣ 회고 문구 1줄</h3>
<ul>
<li>매주 리뷰 상단에 <strong>회고에 어울리는 문구 1줄</strong> 제공</li>
<li>명언 인용이 아닌, <strong>중립적인 회고 문구</strong>를 기본으로 한다</li>
<li>문구는 방향을 제시하지 않는다</li>
</ul>
<hr>
<h3 id="5️⃣-ai는-설명만-한다">5️⃣ AI는 “설명”만 한다</h3>
<p>AI가 하는 일:</p>
<ul>
<li>패턴을 문장으로 풀어 설명</li>
<li>기록 흐름을 자연어로 정리</li>
</ul>
<p>AI가 하지 않는 일:</p>
<ul>
<li>평가</li>
<li>훈계</li>
<li>목표 제안</li>
<li>행동 지시</li>
</ul>
<hr>
<h2 id="4-2단계에서-하지-않는-것-wont-have">4. 2단계에서 하지 않는 것 (Won’t Have)</h2>
<p>의도적으로 제외한 기능들이다.</p>
<ul>
<li>자유 질의형 AI 챗</li>
<li>행동 추천 / 코칭</li>
<li>목표 관리 / 회고 질문</li>
<li>감정 분석</li>
<li>알림 / 자동 리마인드</li>
<li>기록 자동 생성</li>
<li>외부 데이터 연동</li>
</ul>
<p>이 기능들은 <strong>2단계의 범위를 벗어난다.</strong></p>
<hr>
<h2 id="5-definition-of-done-완료-기준">5. Definition of Done (완료 기준)</h2>
<p>아래 조건을 모두 만족하면 <strong>2단계는 완료</strong>로 판단한다.</p>
<ol>
<li>주간 리뷰가 안정적으로 생성·저장·재조회된다</li>
<li>요약은 항상 <strong>50자 이내</strong>로 유지된다</li>
<li>패턴은 항상 동일한 3종 구조로 표시된다</li>
<li>모든 패턴에 실제 기록 근거가 연결된다</li>
<li>AI가 평가/훈계/목표 톤을 사용하지 않는다</li>
<li>2~3주 사용 후, 매주 한 번 이상 리뷰를 열어본다</li>
</ol>
<hr>
<h2 id="6-2단계-이후를-분리하는-이유">6. 2단계 이후를 분리하는 이유</h2>
<p>2단계는 <strong>나만 쓰는 도구</strong>다.</p>
<ul>
<li>정교함보다 안정성</li>
<li>똑똑함보다 신뢰</li>
<li>확장보다 경계 설정</li>
</ul>
<p>이 단계가 명확해야,
2.5단계(CI/CD &amp; 클라우드 안정화),
3단계(Web/App 확장)가 <strong>자연스럽게 분리</strong>된다.</p>
<hr>
<h2 id="7-정리">7. 정리</h2>
<p>DailyLog의 2단계는
AI를 붙이는 단계가 아니라,</p>
<blockquote>
<p><strong>AI를 ‘통제된 역할’로 고정하는 단계</strong>다.</p>
</blockquote>
<p>AI가 말을 많이 하지 않아도,
기록이 잘 정리되어 있다면
2단계는 성공이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[DailyLog 1단계 회고록]]></title>
            <link>https://velog.io/@msus_xxvii/DailyLog-1%EB%8B%A8%EA%B3%84-%ED%9A%8C%EA%B3%A0%EB%A1%9D</link>
            <guid>https://velog.io/@msus_xxvii/DailyLog-1%EB%8B%A8%EA%B3%84-%ED%9A%8C%EA%B3%A0%EB%A1%9D</guid>
            <pubDate>Fri, 02 Jan 2026 07:45:16 GMT</pubDate>
            <description><![CDATA[<h1 id="dailylog-1단계-mvp-정의--definition-of-done-검증">DailyLog 1단계 MVP 정의 &amp; Definition of Done 검증</h1>
<p>이번 글에서는<br><strong>내가 처음에 정의했던 1단계(MVP)의 기준에 실제로 도달했는지</strong>를 점검하고,<br>그 기준을 충족했기 때문에 <strong>2단계로 넘어갈 수 있는지</strong>를 스스로 판단한다.</p>
<p>이 글은 “회고”이자 동시에<br><strong>다음 단계를 허용해도 되는지에 대한 검증 문서</strong>다.</p>
<hr>
<h2 id="1-왜-1단계-mvp를-명확히-정의했는가">1. 왜 1단계 MVP를 명확히 정의했는가</h2>
<p>사이드 프로젝트에서 가장 흔한 실패는 이것이다.</p>
<ul>
<li>기능을 계속 추가한다</li>
<li>끝이 없다</li>
<li>결국 안 쓴다</li>
<li>목표점이 확실하지 않다</li>
</ul>
<p>그래서 DailyLog는 처음부터 이렇게 정했다.</p>
<blockquote>
<p>“기능을 늘리는 프로젝트”가 아니라<br><strong>완료 기준점이 먼저 존재하는 프로젝트</strong></p>
</blockquote>
<p>즉, ** 1차적인 기준점을 먼저 만들고, 거기에 도달하면 멈춘다.**</p>
<hr>
<h2 id="2-1단계-mvp의-목적-다시-확인">2. 1단계 MVP의 목적 (다시 확인)</h2>
<p>1단계의 목적은 단 하나였다.</p>
<blockquote>
<p>“캘린더를 열었을 때<br>내가 어떤 하루들을 보내고 있는지<br>직관적으로 인식할 수 있는가?”</p>
</blockquote>
<p>의도적으로 제외한 것들:</p>
<ul>
<li>생산성 향상 ❌  </li>
<li>목표 달성 ❌  </li>
<li>습관 강제 ❌  </li>
</ul>
<p><strong>오직 ‘인식’과 ‘기록’만 다룬다.</strong></p>
<hr>
<h2 id="3-1단계-mvp-핵심-기능--실제-구현-여부">3. 1단계 MVP 핵심 기능 — 실제 구현 여부</h2>
<p><img src="https://velog.velcdn.com/images/msus_xxvii/post/9b4f8ffd-6639-4517-94c8-8b9163d65820/image.png" alt=""></p>
<h3 id="1️⃣-캘린더-중심-ui">1️⃣ 캘린더 중심 UI</h3>
<ul>
<li>첫 화면 = 월간 캘린더 ✅</li>
<li>날짜별 기록이 카테고리 색 블록으로 표시 ✅</li>
<li>한 달의 흐름을 스크롤 없이 인식 가능 ✅</li>
</ul>
<p>→ <strong>캘린더는 단순한 뷰가 아니라 ‘진입점’ 및 &#39;대시보드&#39; 역할을 한다.</strong></p>
<hr>
<p><img src="https://velog.velcdn.com/images/msus_xxvii/post/0311d2fc-12c2-4127-bc34-b9b42a44165f/image.png" alt=""></p>
<h3 id="2️⃣-기본-기록-crud">2️⃣ 기본 기록 CRUD</h3>
<ul>
<li>생성(Create) ✅</li>
<li>조회(Read) — 월 단위 기준 ✅</li>
<li>수정(Update) ✅</li>
<li>삭제(Delete) ✅</li>
</ul>
<p>→ 캘린더 / 그리드 어디서든 동일한 모달 UX 사용</p>
<hr>
<h3 id="3️⃣-카테고리--색상-고정">3️⃣ 카테고리 + 색상 고정</h3>
<ul>
<li>카테고리 enum 고정 (EXERCISE / STUDY / MEETING) ✅</li>
<li>카테고리별 색상 통일 ✅</li>
<li>사용자 커스터마이징 없음 ✅</li>
</ul>
<p>→ <strong>시각적 의미를 줄이기 위해 선택지를 줄였다.</strong></p>
<hr>
<p><img src="https://velog.velcdn.com/images/msus_xxvii/post/a81292ae-f81e-4092-b897-1e2950e92721/image.png" alt=""></p>
<h3 id="4️⃣-최소-입력-ux">4️⃣ 최소 입력 UX</h3>
<ul>
<li>필수 입력:<ul>
<li>날짜(logDate)</li>
<li>카테고리</li>
<li>제목(title)</li>
</ul>
</li>
<li>메모(content)는 선택이지만 권장</li>
<li>“작성”이 아니라 <strong>“확인 후 저장”에 가까운 흐름</strong> ✅</li>
</ul>
<hr>
<h3 id="5️⃣-최근-7일-복사-입력">5️⃣ 최근 7일 복사 입력</h3>
<ul>
<li>최근 1주일 기록 계산 ✅</li>
<li>클릭 1번으로 자동 채움 ✅</li>
<li>저장까지 2~3번의 액션으로 완료 ✅</li>
<li>EXERCISE 우선 추천 로직 적용 ✅</li>
</ul>
<p>→ <strong>반복 기록의 ‘귀찮음’을 제거하는 데 실제로 효과가 있었다.</strong>
(하지만 이를 카테고리 별로 줄일지 더 고민해야하는 문제임)</p>
<hr>
<h2 id="4-1단계에서-하지-않기로-한-것--지켰는가">4. 1단계에서 하지 않기로 한 것 — 지켰는가?</h2>
<p>의도적으로 제외한 기능들:</p>
<ul>
<li>알림 / 리마인드 ❌</li>
<li>차트 / 통계 ❌</li>
<li>AI 요약 ❌</li>
<li>커스텀 이미지 / 도트 트래커 ❌</li>
<li>세부 운동 구조화 ❌</li>
<li>로그인 / 계정 / 공유 ❌</li>
<li>모바일 앱 ❌</li>
</ul>
<p>👉 <strong>단 하나도 넣지 않았다.</strong></p>
<p>이 점이 오히려 이번 단계의 완성도를 높였다.</p>
<hr>
<h2 id="5-기준점-최종-점검">5. 기준점 최종 점검</h2>
<p>아래 조건을 모두 만족하면<br><strong>1단계는 ‘완료’로 판단하기로 했다.</strong></p>
<ul>
<li>캘린더에 월 단위 기록이 정상 표시된다 ✅</li>
<li>날짜 클릭 → 추가/수정/삭제가 안정적이다 ✅</li>
<li>색 블록만 봐도 하루의 활동이 인식된다 ✅</li>
<li>최근 7일 복사 입력으로 빠르게 기록 가능하다 ✅</li>
<li>실제로 며칠 이상 사용해도 거부감이 없다 ✅</li>
</ul>
<p>👉 <strong>모두 충족했다.</strong></p>
<p>따라서<br><strong>1단계는 완료되었다고 판단한다.</strong></p>
<hr>
<h1 id="⚠️-중간에-겪은-실패-websquare-연동-시도">⚠️ 중간에 겪은 실패: WebSquare 연동 시도</h1>
<p>처음에는 프론트엔드를<br><strong>WebSquare 기반으로 구성하려는 시도</strong>를 했다.</p>
<p>SI회사 특성상 웹스퀘어, 넥사크로, 엑스프레임 같은 것을 많이 써서 선행 학습 및 적응용으로 쓰기 위해 시도했다.</p>
<p>결과는 실패였다.</p>
<h3 id="실패-이유">실패 이유</h3>
<ul>
<li>유효한 라이선스 없이는 정상적인 개발이 어려움</li>
<li>SPA 구조에 맞지 않음</li>
<li>Git 협업 / 컴포넌트 분리에 치명적인 제약</li>
<li>개인 프로젝트의 속도와 목적에 부적합</li>
</ul>
<h3 id="중요한-교훈">중요한 교훈</h3>
<p>이 실패는 시간 낭비가 아니었다.</p>
<ul>
<li>“기술적으로 가능한가?”보다</li>
<li><strong>“이 프로젝트의 목적과 맞는가?”</strong>가 더 중요하다는 걸 깨달았다.</li>
</ul>
<p>그래서 과감히:</p>
<ul>
<li>WebSquare 제거</li>
<li>React SPA로 전면 전환</li>
<li>Backend는 순수 API 서버로 역할 고정</li>
</ul>
<p>👉 이 결정이 없었다면<br>지금의 1단계 완성도는 불가능했다.</p>
<blockquote>
<p>Related Posts:
<a href="https://velog.io/@msus_xxvii/WebSquare-Spring-Boot-%EC%97%B0%EB%8F%99-%EC%8B%9C%EC%BC%9C%EB%B3%B4%EA%B8%B0-1">연동시키기 1편</a>
<a href="https://velog.io/@msus_xxvii/WebSquare-Spring-Boot-%EC%97%B0%EB%8F%99-%EC%8B%9C%EC%BC%9C%EB%B3%B4%EA%B8%B0-2-%EC%98%A4%EB%A5%98-%EC%A0%95%EB%A6%AC">연동시키기 2편</a>
<a href="https://velog.io/@msus_xxvii/WebSquare-IntelliJ-%EC%97%B0%EB%8F%99-%EC%8B%9C%EC%BC%9C%EB%B3%B4%EA%B8%B0-3-%EA%B3%84%ED%9A%8D-%EB%B3%80%EA%B2%BD">연동시키기 3편</a></p>
</blockquote>
<hr>
<h1 id="🤖-2단계로의-전환--ai-어시스턴트">🤖 2단계로의 전환 — AI 어시스턴트</h1>
<p>1단계가 끝났기 때문에<br><strong>이제서야 2단계를 이야기할 수 있다.</strong></p>
<h3 id="2단계의-역할-정의">2단계의 역할 정의</h3>
<blockquote>
<p>AI는 코치도, 평가자도 아니다.<br><strong>“정리자” 역할만 수행한다.</strong></p>
</blockquote>
<h3 id="2단계에서-할-것">2단계에서 할 것</h3>
<ul>
<li>주간 / 월간 기록 요약</li>
<li>패턴 인식</li>
<li>맥락 정리 (무슨 날이 많았는지, 흐름이 어땠는지)</li>
</ul>
<h3 id="하지-않을-것">하지 않을 것</h3>
<ul>
<li>평가 ❌</li>
<li>훈계 ❌</li>
<li>목표 설정 ❌</li>
<li>행동 교정 ❌</li>
</ul>
<p>👉 <strong>판단은 여전히 사용자의 몫</strong></p>
<p>AI는 해석을 도와줄 뿐이다.</p>
<p>(이에 관련한 프롬프트 작성 및 수치적으로 어떻게 평가할 건지에 대해서 공부해야한다..)</p>
<hr>
<h2 id="7-정리">7. 정리</h2>
<p>DailyLog 1단계는:</p>
<ul>
<li>작다</li>
<li>단순하다</li>
<li>하지만 방향이 명확하다</li>
</ul>
<p>기능을 많이 만드는 대신<br><strong>사용 흐름이 깨지지 않는 것</strong>을 목표로 했다.</p>
<p>Vite도 활용해보고 프론트와 백 모두 다룰 수 있어서 좋았다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 2026-01-01]]></title>
            <link>https://velog.io/@msus_xxvii/TIL-2026-01-01</link>
            <guid>https://velog.io/@msus_xxvii/TIL-2026-01-01</guid>
            <pubDate>Thu, 01 Jan 2026 08:34:29 GMT</pubDate>
            <description><![CDATA[<h4 id="🎯-오늘-한-일">🎯 오늘 한 일</h4>
<ul>
<li><p><strong>캘린더 UI 안정화 마무리</strong></p>
<ul>
<li><code>CalendarView</code>에서 이벤트 title overflow 처리 (ellipsis + tooltip)</li>
<li><code>dayMaxEvents={3}</code> 적용으로 일정 과다 시 UI 깨짐 방지</li>
<li><code>fixedWeekCount={false}</code>로 월별 높이 자연스럽게 조정</li>
</ul>
</li>
<li><p><strong>이벤트 데이터 방어 로직 강화</strong></p>
<ul>
<li><code>logDate</code> 유효성 체크 후 이벤트 생성 (<code>YYYY-MM-DD</code> 길이 기준)</li>
<li>잘못된 데이터가 FullCalendar로 들어가지 않도록 <code>map → filter(Boolean)</code> 패턴 적용</li>
</ul>
</li>
<li><p><strong>삭제/수정 흐름 최종 점검</strong></p>
<ul>
<li>캘린더에서 삭제 버튼 동작 확인</li>
<li>삭제 후 캘린더/모달 상태 정상 동기화 확인</li>
</ul>
</li>
<li><p><strong>목요일 UI 미세 조정 과제 완료 판단</strong></p>
<ul>
<li>캘린더 이벤트 표시 안정성 확보</li>
<li>사용 중 “왜 이래?” 나오는 구간 제거</li>
</ul>
</li>
</ul>
<h4 id="💡-배운-점">💡 배운 점</h4>
<ul>
<li>FullCalendar는 <code>start</code> 값이 애매하면 경고 없이도 UI 이상이 생길 수 있어 <strong>사전 필터링이 중요</strong>함</li>
<li><code>map</code> 단계에서 유효하지 않은 데이터는 아예 <code>null</code>로 만들고 <code>filter(Boolean)</code>로 제거하는 방식이 가장 읽기 좋고 안전함</li>
<li>UI 미세 조정은 “기능 추가”보다 <strong>예외/엣지 케이스 제거</strong>가 체감 품질을 훨씬 크게 올림</li>
</ul>
<h4 id="🚀-내일-할-일">🚀 내일 할 일</h4>
<ul>
<li><p>DataGrid 쪽 UI 최종 정리</p>
<ul>
<li>컬럼 폭/행 밀도 재확인</li>
<li>캘린더와 동일한 UX 톤 유지</li>
</ul>
</li>
<li><p>전체 플로우 10~15분 실제 사용 테스트</p>
</li>
<li><p>1단계(MVP) 종료 기준 정리 및 브랜치 마무리</p>
</li>
</ul>
<h4 id="🧩-느낀-점">🧩 느낀 점</h4>
<ul>
<li>기능 구현보다 <strong>안정화와 방어 코드가 프로젝트 완성도를 결정</strong>한다는 걸 체감함</li>
<li>오늘 작업으로 “사이드 프로젝트 티”가 많이 빠졌고, 실제 서비스처럼 쓸 수 있는 상태에 가까워짐</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 2025-12-30]]></title>
            <link>https://velog.io/@msus_xxvii/TIL-2025-12-30</link>
            <guid>https://velog.io/@msus_xxvii/TIL-2025-12-30</guid>
            <pubDate>Tue, 30 Dec 2025 08:40:08 GMT</pubDate>
            <description><![CDATA[<h4 id="🎯-오늘-한-일">🎯 오늘 한 일</h4>
<ul>
<li><p>Calendar / DataGrid <strong>공통 LogDialog 재사용 구조 완성</strong></p>
</li>
<li><p><code>useLogsApi</code> 도입으로 <strong>프론트엔드 데이터 계층 단일화</strong></p>
<ul>
<li>CalendarPage / LogsGrid에서 axios 직접 호출 제거</li>
<li><code>list / create / update / remove</code> API 접근을 한 곳으로 통합</li>
</ul>
</li>
<li><p>Grid 화면 UI 개선</p>
<ul>
<li>DataGrid width/height 조정으로 컬럼 잘림 문제 해결</li>
</ul>
</li>
<li><p>상단 네비게이션 개선</p>
<ul>
<li><code>NavLink</code> 기반으로 <strong>현재 페이지(Calendar / DataGrid)만 active 컬러 표시</strong></li>
</ul>
</li>
<li><p>전체 플로우 점검</p>
<ul>
<li>캘린더 ↔ 그리드 동일한 CRUD UX 유지 확인</li>
</ul>
</li>
</ul>
<h4 id="💡-배운-점">💡 배운 점</h4>
<ul>
<li><p><strong>UI 컴포넌트 재사용보다 더 중요한 건 데이터 흐름의 일관성</strong></p>
</li>
<li><p>axios 호출을 흩어두면 “작동은 되지만 유지보수는 망가진다”</p>
</li>
<li><p><code>useLogsApi</code> 같은 얇은 추상화 레이어만 있어도</p>
<ul>
<li>API 변경 비용이 급격히 줄어든다</li>
</ul>
</li>
<li><p><code>NavLink + isActive</code> 패턴은 탭 UI에서 거의 정답에 가깝다</p>
</li>
</ul>
<h4 id="🚀-내일-할-일">🚀 내일 할 일</h4>
<ul>
<li><p>공통 데이터 계층(<code>useLogsApi</code>) 기준으로 코드 정리 마무리</p>
</li>
<li><p>UI 디테일 정리</p>
<ul>
<li>버튼 간격 / 컬럼 가독성</li>
</ul>
</li>
<li><p>1단계 마무리 기준 점검</p>
<ul>
<li>“설명 없이 써도 되는가?”</li>
<li>“다음 주에 다시 열고 싶을까?”</li>
</ul>
</li>
</ul>
<h4 id="🧩-느낀-점">🧩 느낀 점</h4>
<ul>
<li>기능 추가보다 <strong>구조를 정리한 날</strong></li>
<li>이 시점에서 느끼는 안정감은 “코드가 통제되고 있다”는 감각에서 온다</li>
<li>지금 상태면 <strong>MVP 1단계는 명확히 끝났다</strong></li>
<li>다음 단계는 기능이 아니라 <em>밀도</em>를 높이는 작업이 될 것</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 2025-12-29]]></title>
            <link>https://velog.io/@msus_xxvii/TIL-2025-12-29-1izjet5h</link>
            <guid>https://velog.io/@msus_xxvii/TIL-2025-12-29-1izjet5h</guid>
            <pubDate>Mon, 29 Dec 2025 08:26:44 GMT</pubDate>
            <description><![CDATA[<h4 id="🎯-오늘-한-일">🎯 오늘 한 일</h4>
<ul>
<li><p><strong>Logs(Grid) 화면 분리 완료</strong></p>
<ul>
<li>Calendar와 분리된 <code>LogsGrid</code> 페이지 구성</li>
<li><code>/api/logs</code>를 공용 데이터 소스로 유지</li>
</ul>
</li>
<li><p><strong>LogDialog 공용 컴포넌트 적용</strong></p>
<ul>
<li>Calendar / Grid 모두 동일한 Dialog 사용</li>
<li><code>mode(create/edit)</code>, <code>form</code>, <code>onSave/onDelete</code> 인터페이스 통합</li>
</ul>
</li>
<li><p><strong>CRUD 흐름 통합</strong></p>
<ul>
<li>생성/수정/삭제 로직을 동일한 패턴으로 정리</li>
<li>optimistic update 방식으로 UI 즉시 반영</li>
</ul>
</li>
<li><p><strong>DataGrid UI 문제 해결</strong></p>
<ul>
<li>가로 잘림 이슈 해결 (<code>width: 100%</code>, <code>flex</code>, <code>minWidth</code> 조정)</li>
<li>스크롤/페이지네이션 정상 동작 확인</li>
</ul>
</li>
</ul>
<h4 id="💡-배운-점">💡 배운 점</h4>
<ul>
<li>화면이 달라도 <strong>Dialog·Form·CRUD 흐름은 하나의 규약</strong>으로 묶는 게 유지보수에 압도적으로 유리하다.</li>
<li>데이터가 적을 때 “잘 돌아가는 것처럼 보이는 코드”와
<strong>구조적으로 안전한 코드</strong>는 전혀 다르다.</li>
<li>기능 추가보다 먼저 <strong>화면/컴포넌트 경계를 명확히 나누는 작업</strong>이 전체 개발 속도를 올린다.</li>
</ul>
<h4 id="🚀-내일-할-일">🚀 내일 할 일</h4>
<ul>
<li>Calendar / Grid 공용 로직 정리 여부 최종 점검</li>
<li>불필요한 상태(state) 중복 제거</li>
<li>1단계 마무리 기준 재확인 및 PR 정리</li>
</ul>
<h4 id="🧩-느낀-점">🧩 느낀 점</h4>
<ul>
<li>오늘은 “기능을 만든 날”이 아니라 <strong>구조를 완성한 날</strong>이다.</li>
<li>이 상태면 이후 작업은 쌓는 일이지, 고치는 일이 아니다.</li>
<li>여기서 더 욕심내면 오히려 망가질 수 있는 지점까지 왔다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[DailyLog DB Index 1차 최적화 기록]]></title>
            <link>https://velog.io/@msus_xxvii/DailyLog-DB-Index-1%EC%B0%A8-%EC%B5%9C%EC%A0%81%ED%99%94-%EA%B8%B0%EB%A1%9D</link>
            <guid>https://velog.io/@msus_xxvii/DailyLog-DB-Index-1%EC%B0%A8-%EC%B5%9C%EC%A0%81%ED%99%94-%EA%B8%B0%EB%A1%9D</guid>
            <pubDate>Mon, 29 Dec 2025 07:09:29 GMT</pubDate>
            <description><![CDATA[<p>DailyLog 프로젝트에서 <strong>캘린더 기반 조회, 최근 기록 조회</strong> 기능을 구현하면서
데이터가 늘어날 경우를 대비해 <strong>MySQL 인덱스 최적화 작업</strong>을 진행했다.</p>
<p>이번 글에서는</p>
<blockquote>
<p><em>왜 인덱스가 필요한지</em> → <em>어떤 인덱스를 추가했는지</em> → <em>실제로 인덱스를 타는지</em>
를 <code>EXPLAIN</code> 기준으로 정리한다.</p>
</blockquote>
<hr>
<h2 id="1️⃣-현재-문제-인식">1️⃣ 현재 문제 인식</h2>
<p>초기 상태의 <code>daily_log</code> 테이블은 다음과 같았다.</p>
<pre><code class="language-sql">SHOW INDEX FROM daily_log;</code></pre>
<h3 id="결과">결과</h3>
<ul>
<li><code>PRIMARY KEY (id)</code>만 존재</li>
<li><code>log_date</code>, <code>category</code> 관련 인덱스 없음</li>
</ul>
<p>즉,</p>
<ul>
<li>날짜 기반 조회</li>
<li>최근 7일 조회</li>
<li>월 단위 캘린더 조회</li>
<li>카테고리 필터</li>
</ul>
<p>모두 <strong>풀 테이블 스캔(Full Scan)</strong> 상태였다.</p>
<blockquote>
<p>데이터가 적을 때는 문제가 없어 보이지만,
데이터가 쌓이면 성능 저하가 바로 발생할 수 있는 구조였다.</p>
</blockquote>
<hr>
<h2 id="2️⃣-사용-패턴-분석">2️⃣ 사용 패턴 분석</h2>
<p>DailyLog에서 실제로 발생하는 조회 패턴은 다음과 같다.</p>
<ul>
<li>📅 월 단위 캘린더 조회 (<code>log_date BETWEEN</code>)</li>
<li>🕒 최근 7일 기록 조회</li>
<li>🏋️ 최근 7일 중 <code>EXERCISE</code> 우선 노출</li>
<li>📌 특정 날짜 클릭 조회</li>
</ul>
<p>→ <strong>모든 쿼리의 중심은 <code>log_date</code></strong></p>
<hr>
<h2 id="3️⃣-인덱스-설계-전략">3️⃣ 인덱스 설계 전략</h2>
<h3 id="✅-필수-인덱스-log_date">✅ 필수 인덱스: <code>log_date</code></h3>
<pre><code class="language-sql">ALTER TABLE daily_log
ADD INDEX idx_daily_log_log_date (log_date);</code></pre>
<ul>
<li>날짜 범위 조회 최적화</li>
<li>캘린더/최근 기록/날짜 클릭 전부 커버</li>
</ul>
<hr>
<h3 id="✅-복합-인덱스-log_date-category">✅ 복합 인덱스: <code>(log_date, category)</code></h3>
<pre><code class="language-sql">ALTER TABLE daily_log
ADD INDEX idx_daily_log_log_date_category (log_date, category);</code></pre>
<ul>
<li>최근 7일 + 카테고리 필터</li>
<li>향후 통계/집계 대비</li>
</ul>
<blockquote>
<p>복합 인덱스는 <strong>왼쪽 컬럼부터 사용</strong>되므로
<code>log_date → category</code> 순서가 중요하다.</p>
</blockquote>
<hr>
<h2 id="4️⃣-인덱스-적용-결과">4️⃣ 인덱스 적용 결과</h2>
<pre><code class="language-sql">SHOW INDEX FROM daily_log;</code></pre>
<h3 id="결과-요약">결과 요약</h3>
<table>
<thead>
<tr>
<th>Index Name</th>
<th>Columns</th>
</tr>
</thead>
<tbody><tr>
<td>PRIMARY</td>
<td>id</td>
</tr>
<tr>
<td>idx_daily_log_log_date</td>
<td>log_date</td>
</tr>
<tr>
<td>idx_daily_log_log_date_category</td>
<td>log_date, category</td>
</tr>
</tbody></table>
<p>👉 의도한 인덱스가 정확히 적용됨.</p>
<hr>
<h2 id="5️⃣-인덱스가-실제로-사용되는지-확인-explain">5️⃣ 인덱스가 실제로 사용되는지 확인 (<code>EXPLAIN</code>)</h2>
<h3 id="①-월-단위-조회-캘린더">① 월 단위 조회 (캘린더)</h3>
<pre><code class="language-sql">EXPLAIN
SELECT *
FROM daily_log
WHERE log_date &gt;= &#39;2025-12-01&#39;
  AND log_date &lt;  &#39;2026-01-01&#39;
ORDER BY log_date DESC, created_at DESC;</code></pre>
<p><strong>기대 결과</strong></p>
<ul>
<li><code>type = range</code></li>
<li><code>key = idx_daily_log_log_date</code> 또는 복합 인덱스</li>
</ul>
<p><strong>결과값</strong> <img src="https://velog.velcdn.com/images/msus_xxvii/post/5ee78ec7-7cf8-4133-af6f-16069a2a7dda/image.png" alt=""></p>
<hr>
<h3 id="②-최근-7일-조회">② 최근 7일 조회</h3>
<pre><code class="language-sql">EXPLAIN
SELECT id, title, category, log_date
FROM daily_log
WHERE log_date &gt;= CURDATE() - INTERVAL 6 DAY
  AND log_date &lt;= CURDATE()
ORDER BY log_date DESC;</code></pre>
<p><strong>결과값</strong>
<img src="https://velog.velcdn.com/images/msus_xxvii/post/4ad95e0c-03e4-40b3-b2e5-d45dd5816920/image.png" alt=""></p>
<hr>
<h3 id="③-최근-7일--카테고리-필터">③ 최근 7일 + 카테고리 필터</h3>
<pre><code class="language-sql">EXPLAIN
SELECT id, title, category, log_date
FROM daily_log
WHERE log_date &gt;= CURDATE() - INTERVAL 6 DAY
  AND log_date &lt;= CURDATE()
  AND category = &#39;EXERCISE&#39;
ORDER BY log_date DESC;</code></pre>
<p><strong>기대 결과</strong></p>
<ul>
<li><code>key = idx_daily_log_log_date_category</code></li>
<li><code>type = range</code> 또는 <code>ref</code></li>
</ul>
<p><strong>결과값</strong>
<img src="https://velog.velcdn.com/images/msus_xxvii/post/ee1a54a8-672b-45a2-8a4f-a5e1521b5014/image.png" alt=""></p>
<hr>
<h3 id="④-특정-날짜-클릭-조회">④ 특정 날짜 클릭 조회</h3>
<pre><code class="language-sql">EXPLAIN
SELECT id, title, category, log_date
FROM daily_log
WHERE log_date = &#39;2025-12-12&#39;
ORDER BY created_at DESC;</code></pre>
<p><strong>결과값</strong>
<img src="https://velog.velcdn.com/images/msus_xxvii/post/2b134786-3aca-468f-937b-4081e289d06a/image.png" alt=""></p>
<hr>
<h2 id="6️⃣-인덱스-사용-여부-체크-포인트">6️⃣ 인덱스 사용 여부 체크 포인트</h2>
<p><code>EXPLAIN</code> 결과에서 아래만 보면 된다.</p>
<table>
<thead>
<tr>
<th>컬럼</th>
<th>의미</th>
</tr>
</thead>
<tbody><tr>
<td><code>type</code></td>
<td><code>ALL</code>이면 풀스캔, <code>range/ref</code>면 정상</td>
</tr>
<tr>
<td><code>key</code></td>
<td>실제 사용된 인덱스</td>
</tr>
<tr>
<td><code>rows</code></td>
<td>예상 스캔 row 수</td>
</tr>
<tr>
<td><code>Extra</code></td>
<td><code>Using where</code>, <code>Using filesort</code> 여부</td>
</tr>
</tbody></table>
<p>⚠️ 특히 아래 형태는 <strong>인덱스를 못 탄다</strong>:</p>
<pre><code class="language-sql">WHERE DATE(log_date) = &#39;2025-12-12&#39;</code></pre>
<p>반드시 이렇게 써야 한다:</p>
<pre><code class="language-sql">WHERE log_date = &#39;2025-12-12&#39;</code></pre>
<hr>
<h2 id="7️⃣-결론">7️⃣ 결론</h2>
<ul>
<li>테이블 구조 변경 ❌</li>
<li>데이터 삭제 ❌</li>
<li><strong>인덱스 추가만으로 구조 안정화 완료 ✅</strong></li>
</ul>
<blockquote>
<p><strong>“구조는 이미 맞았고, DB가 그 구조를 제대로 받쳐줄 차례였다.”</strong></p>
</blockquote>
<p>이번 작업으로 DailyLog는
<strong>데이터가 늘어나도 프론트 구조를 바꾸지 않아도 되는 상태</strong>가 되었다.</p>
]]></description>
        </item>
    </channel>
</rss>