Skip to content

feat: 카카오 로그인 기능 구현 - #50

Merged
evenif99 merged 19 commits into
devfrom
feature/common-component-jw
Jun 18, 2026
Merged

evenif99 merged 19 commits into
devfrom
feature/common-component-jw

Conversation

@evenif99

@evenif99 evenif99 commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator

1. 작업 내용

  • 카카오 OAuth 로그인 기능 구현 (버튼 signIn 연결)
  • @auth/prisma-adapter 설치 및 authOptions 적용
  • 최초 로그인 시 kakaoId, nickname, termsAgreedAt 자동 설정 (signIn 콜백)
  • 닉네임 자동 생성 유틸 추가 (~하는부엉이 + 랜덤 4자리, 20개 동사 pool)
  • 닉네임 유니크 제약(@unique) 추가 및 충돌 재시도 로직 구현 (최대 10회, fallback도 랜덤 8자리)
  • middleware.ts 추가: /login, /api/auth/* 외 비인증 접근 차단 (경계 패턴 보완)
  • SCSS import 절대경로(@/) 수정, .disclaimer에 text-caption mixin 적용
  • 캐릭터 이미지 Next/Image fill → img 태그 변경
  • 이용약관/개인정보처리방침 링크(/terms, /privacy) 및 스타일(underline, cursor:pointer) 적용

2. 담당 작업 영역

  • identity-access
  • room-ai-chat
  • invite-participation
  • statement
  • judgement-result
  • result-card-media
  • records-lifecycle
  • calendar-diary
  • statistics
  • gift-recommendation
  • profile-mypage
  • ops-common

3. 관련 Issue

  • close #

4. 관련 기능 요구사항

  • FR-AUTH-001
  • FR-AUTH-002
  • FR-AUTH-003

5. 관련 비기능 요구사항

  • NFR-

6. 변경 사항

파일 작업
src/app/(page)/login/page.tsx 로그인 UI, signIn 버튼 연결, 캐릭터 img 태그 변경, 약관 링크 추가
src/app/(page)/login/login.module.scss SCSS 절대경로, text-caption mixin 적용, character/disclaimerLink 클래스
src/lib/auth/index.ts PrismaAdapter, signIn 콜백, 닉네임 재시도 로직 (fallback 랜덤화)
src/lib/auth/nickname.ts 닉네임 자동 생성 + fallback 유틸
src/middleware.ts 라우트 인증 보호 (경계 패턴 보완)
prisma/schema.prisma nickname @unique 제약 추가
package.json / package-lock.json @auth/prisma-adapter 의존성 추가

7. 테스트 결과

  • 로컬 실행 확인
  • 기능 동작 확인
  • 에러 케이스 확인
  • 모바일 화면 확인
  • 빌드 확인
  • lint 확인
  • type-check 확인 (작업 파일 기준 오류 없음)

8. 작업 범위 확인

  • Issue에 정의된 작업 범위 안에서 수정함
  • 다른 팀원 담당 영역을 불필요하게 수정하지 않음
  • 공통 파일 변경 시 팀에 공유함 — middleware.ts 신규 추가로 전체 라우트에 인증 보호 적용됨. 팀 확인 필요
  • 관련 문서 수정 필요 여부를 확인함

9. 보안 / 개인정보 확인

  • 환경변수 노출 없음
  • API Key 노출 없음
  • Supabase Service Role Key 클라이언트 노출 없음
  • 권한 검증 적용
  • 개인정보/진술/감정일기 원문 로그 저장 없음
  • 공유 이미지에 민감정보 포함 없음

10. DB/API/Storage 변경 여부

  • DB 변경 없음
  • DB 변경 있음 → nickname 컬럼 @unique 제약 추가 (prisma db push 필요, DB 담당자 확인 요청)
  • API 변경 없음
  • API 변경 있음 → /api/auth/[...nextauth] PrismaAdapter 연동 (기존 엔드포인트 유지, 동작 변경)
  • Storage 변경 없음
  • Storage 변경 있음 → Supabase Storage 정책 확인

11. 스크린샷

필요 시 첨부

12. 추가 공유 사항

  • DB에 kakao_id, nickname(@unique), terms_agreed_at 컬럼 반영 필요. DB 담당자에게 prisma db push 반영 여부 확인 필요.
  • middleware.ts 신규 추가로 인증이 필요한 모든 페이지에 영향. 각 담당자 로컬 테스트 시 참고.
  • /terms, /privacy 페이지는 미구현 상태. 추후 페이지 구현 시 링크 자동 연결.

Summary by CodeRabbit

릴리스 노트

  • New Features
    • 카카오 로그인 연동 및 로그인 처리 경로를 정비
    • 로그인 페이지 UI 추가(로고/캐릭터, 이용약관 및 개인정보 처리방침 링크 포함)
    • 첫 로그인 시 자동 닉네임 생성 및 닉네임 중복 발생 시 재시도/대체 닉네임 적용
  • Chores
    • 인증 데이터 저장을 위한 Prisma 어댑터 연동

evenif99 and others added 16 commits June 16, 2026 16:04
- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)
- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거
…ea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 로그인 페이지 UI 및 카카오 signIn 버튼 연결
- @auth/prisma-adapter 설치 및 authOptions에 적용
- 최초 로그인 시 kakaoId, nickname, termsAgreedAt 자동 설정
- 닉네임 자동 생성 유틸 추가 (~하는부엉이 + 4자리 난수)
- middleware 추가: 비인증 사용자 /login 리다이렉트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
talky-owl Ready Ready Preview, Comment Jun 18, 2026 5:16am

@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

@auth/prisma-adapter 의존성을 추가하고, DB 스키마의 nickname 필드에 유니크 제약을 추가한다. authOptions에 PrismaAdapter·JWT 세션 전략·페이지 라우트·signIn 콜백(최초 로그인 시 kakaoId/닉네임/약관동의 시각 DB 기록, 닉네임 충돌 시 재시도)을 설정한다. Next.js 미들웨어로 인증이 필요한 라우트를 보호하고, 카카오 로그인 버튼이 포함된 로그인 페이지 UI를 새로 추가한다.

Changes

Kakao 로그인 전체 플로우

Layer / File(s) Summary
닉네임 생성 유틸 및 PrismaAdapter 의존성 추가
package.json, src/lib/auth/nickname.ts
@auth/prisma-adapter 패키지를 의존성에 등록하고, 동사와 4자리 숫자를 조합해 닉네임을 생성하는 generateNickname(), 재시도 한계 도달 시 사용할 generateFallbackNickname() 함수를 추가한다.
DB 스키마 업데이트: 닉네임 유니크 제약
prisma/schema.prisma
Prisma User 모델의 nickname 필드에 @unique 제약을 추가해 닉네임 중복을 방지한다.
authOptions 확장: PrismaAdapter·세션·signIn 콜백
src/lib/auth/index.ts
PrismaAdapter, session.strategy: jwt, /login 페이지 매핑을 authOptions에 추가한다. callbacks.signIn에서 최초 Kakao 로그인 시 kakaoId, 생성된 닉네임, termsAgreedAt을 DB에 기록하며, 닉네임 유니크 제약 위반 시 재시도 로직으로 대응한다.
Next.js 미들웨어 라우트 보호 설정
src/middleware.ts
next-auth/middleware를 재내보내고 config.matcher의 부정 전방탐색 패턴으로 /login, /api/auth, 정적 에셋 경로를 제외한 모든 경로에 인증 미들웨어를 적용한다.
로그인 페이지 UI 및 스타일
src/app/(page)/login/page.tsx, src/app/(page)/login/login.module.scss
로고·캐릭터 이미지와 카카오 로그인 버튼을 렌더링하는 LoginPage 클라이언트 컴포넌트와 KakaoIcon SVG를 추가한다. CSS Module로 플렉스 레이아웃, 버튼 상태별 스타일링, 면책 문구와 이용약관·개인정보처리방침 링크 타이포그래피를 정의한다.

Sequence Diagram(s)

sequenceDiagram
  participant 사용자
  participant LoginPage
  participant NextAuth
  participant signInCallback
  participant PrismaDB as Prisma DB

  rect rgba(99, 179, 237, 0.5)
    사용자->>LoginPage: 카카오 로그인 버튼 클릭
    LoginPage->>NextAuth: signIn('kakao', { callbackUrl: '/home' })
  end

  rect rgba(154, 230, 180, 0.5)
    NextAuth->>signInCallback: callbacks.signIn(user, account) 호출
    signInCallback->>PrismaDB: findUnique — kakaoId 존재 여부 조회
    alt 최초 로그인 (kakaoId 없음)
      signInCallback->>signInCallback: generateNickname() 실행
      signInCallback->>PrismaDB: update — kakaoId, nickname, termsAgreedAt 기록
      alt 닉네임 충돌 (P2002)
        signInCallback->>signInCallback: 새 닉네임으로 재시도 (최대 10회)
        signInCallback->>PrismaDB: update — 재시도
      end
      alt 재시도 한계 도달
        signInCallback->>signInCallback: generateFallbackNickname() 실행
        signInCallback->>PrismaDB: update — fallback 닉네임 기록
      end
      PrismaDB-->>signInCallback: 업데이트 완료
    end
    signInCallback-->>NextAuth: return true
  end

  NextAuth-->>사용자: /home으로 리다이렉트
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~28 minutes

Poem

🦉 달빛 아래 부엉이가 키보드를 두드리며,
카카오 버튼 하나로 문을 열었네.
처음 온 친구엔 이름을 선물하고,
DB에 발자국을 살짝 남겨 두었지.
이제 로그인 걱정은 훌훌~ 날려 버렸어! 🍀

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목이 변경 사항의 주요 내용(카카오 로그인 기능)을 명확하고 간결하게 설명하고 있습니다.
Description check ✅ Passed PR 설명이 리포지토리 템플릿의 대부분 섹션을 포함하며, 작업 내용, 담당 영역, 변경 사항, 테스트 결과, 보안 확인 등이 상세히 기술되어 있습니다.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/common-component-jw

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lib/auth/index.ts`:
- Around line 33-35: The current nickname generation at the `generateNickname()`
call in the user creation block does not guarantee uniqueness and lacks retry
logic for collision handling. Create a helper function (for example,
`generateUniqueNicknameWithRetry`) that accepts the prisma client and attempts
to generate a unique nickname by repeatedly calling `generateNickname()` and
checking if the nickname already exists in the database using `findFirst`,
retrying up to a specified maximum number of times before throwing an error.
Replace the direct `generateNickname()` call with this new helper function to
ensure the PR goal of creating unique nicknames is satisfied. Additionally,
ensure the nickname column has a unique constraint in the database schema.

In `@src/middleware.ts`:
- Line 5: The matcher pattern in the middleware config file uses a negative
lookahead that only matches path prefixes, allowing unintended paths like
`/login-help` or `/images-private` to bypass authentication. Update the pattern
to add word boundaries `(?:/|$)` after each excluded path name in the negative
lookahead (such as after login, api/auth, _next/static, _next/image,
favicon.ico, and images) to ensure only exact path matches or directory
boundaries are excluded, preventing partial prefix matches from creating
security vulnerabilities.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 9c3f39b7-8df9-4c80-a137-ec6f164f66a1

📥 Commits

Reviewing files that changed from the base of the PR and between e2384b2 and 29b612f.

⛔ Files ignored due to path filters (2)
  • package-lock.json is excluded by !**/package-lock.json
  • public/images/common/login_character.png is excluded by !**/*.png
📒 Files selected for processing (6)
  • package.json
  • src/app/(page)/login/login.module.scss
  • src/app/(page)/login/page.tsx
  • src/lib/auth/index.ts
  • src/lib/auth/nickname.ts
  • src/middleware.ts

Comment thread src/lib/auth/index.ts Outdated
Comment thread src/middleware.ts Outdated
@evenif99 evenif99 self-assigned this Jun 18, 2026
Comment thread src/app/(page)/login/login.module.scss Outdated
@@ -0,0 +1,65 @@
@use '../../../styles/abstracts/variables' as v;
@use '../../../styles/abstracts/functions' as fn;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

팀장님 이것도 절대경로로 수정 부탁드려요 ㅎㅎ

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오우 죄송함다

priority
/>
</div>
<Image

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이걸 이미지 처리했네요....?!?! 충분히 코드로 처리 가능할 것 같은뎁...

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 폰트를 쓰는곳이 로고밖에 없기때문에 이미지가 맞을거같아서 제가 미리 만들어둔거에요!
웹폰트로 처리하는게 더비용이 크지않을까요?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아 비용이 들어가는 폰트라면 그게 나을 것 같네요.

Comment thread src/app/(page)/login/page.tsx Outdated
카카오로 로그인 하기
</Button>
<p className={styles.disclaimer}>
로그인 시 이용약관 및 개인정보 처리방침에 동의한 것으로 간주합니다.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이용약관이랑 개인정보 처리방침은 text-decoration: underline 추가하고 cursor: point, 하고 두 개 각각 doc 링크로 연결되어야해용

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵 수정하겠슴다

- SCSS import 절대경로(@/) 수정
- 캐릭터 이미지 Next/Image fill → img 태그로 변경
- 이용약관/개인정보처리방침 링크(/terms, /privacy) 추가 및 스타일 적용
- 닉네임 유니크 제약(@unique) 추가 및 충돌 재시도 로직 구현 (최대 10회)
- middleware matcher 패턴 보완 (/login-help 등 우회 경로 차단)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lib/auth/index.ts`:
- Around line 9-30: The saveFirstLoginFields function lacks error handling when
all retry attempts are exhausted. After the for loop completes without returning
early (meaning all MAX_NICKNAME_RETRIES attempts failed with P2002 errors), the
function implicitly returns undefined instead of throwing an error, causing
silent failures where the user is created with incomplete data. Add a throw
statement after the for loop in saveFirstLoginFields to raise an error when all
nickname generation attempts fail, ensuring the signIn callback properly detects
and rejects failed user creation operations.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: c3cc1464-554a-4d31-8da7-6de5bdc3c512

📥 Commits

Reviewing files that changed from the base of the PR and between 29b612f and 1f30c28.

📒 Files selected for processing (5)
  • prisma/schema.prisma
  • src/app/(page)/login/login.module.scss
  • src/app/(page)/login/page.tsx
  • src/lib/auth/index.ts
  • src/middleware.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/middleware.ts
  • src/app/(page)/login/login.module.scss
  • src/app/(page)/login/page.tsx

Comment thread src/lib/auth/index.ts
Comment on lines +9 to +30
async function saveFirstLoginFields(userId: string, kakaoId: string): Promise<void> {
for (let attempt = 0; attempt < MAX_NICKNAME_RETRIES; attempt++) {
const isLastAttempt = attempt === MAX_NICKNAME_RETRIES - 1
const nickname = isLastAttempt
? `부엉이${Date.now()}`
: generateNickname()

try {
await prisma.user.update({
where: { id: userId },
data: { kakaoId, nickname, termsAgreedAt: new Date() },
})
return
} catch (e) {
const err = e as { code?: string; meta?: { target?: string[] } }
if (err.code === 'P2002' && err.meta?.target?.includes('nickname')) {
continue
}
throw e
}
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

모든 재시도 실패 시 오류가 발생하지 않습니다.

루프가 10회 모두 P2002 오류로 실패하면 함수가 정상 종료되어 signIn 콜백이 true를 반환합니다. 이 경우 사용자는 로그인되지만 kakaoId, nickname, termsAgreedAt 필드가 설정되지 않은 채로 남습니다.

🐛 재시도 실패 시 오류를 던지도록 수정
       throw e
     }
   }
+  throw new Error('고유 닉네임 생성 실패: 재시도 한도 초과')
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async function saveFirstLoginFields(userId: string, kakaoId: string): Promise<void> {
for (let attempt = 0; attempt < MAX_NICKNAME_RETRIES; attempt++) {
const isLastAttempt = attempt === MAX_NICKNAME_RETRIES - 1
const nickname = isLastAttempt
? `부엉이${Date.now()}`
: generateNickname()
try {
await prisma.user.update({
where: { id: userId },
data: { kakaoId, nickname, termsAgreedAt: new Date() },
})
return
} catch (e) {
const err = e as { code?: string; meta?: { target?: string[] } }
if (err.code === 'P2002' && err.meta?.target?.includes('nickname')) {
continue
}
throw e
}
}
}
async function saveFirstLoginFields(userId: string, kakaoId: string): Promise<void> {
for (let attempt = 0; attempt < MAX_NICKNAME_RETRIES; attempt++) {
const isLastAttempt = attempt === MAX_NICKNAME_RETRIES - 1
const nickname = isLastAttempt
? `부엉이${Date.now()}`
: generateNickname()
try {
await prisma.user.update({
where: { id: userId },
data: { kakaoId, nickname, termsAgreedAt: new Date() },
})
return
} catch (e) {
const err = e as { code?: string; meta?: { target?: string[] } }
if (err.code === 'P2002' && err.meta?.target?.includes('nickname')) {
continue
}
throw e
}
}
throw new Error('고유 닉네임 생성 실패: 재시도 한도 초과')
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/auth/index.ts` around lines 9 - 30, The saveFirstLoginFields function
lacks error handling when all retry attempts are exhausted. After the for loop
completes without returning early (meaning all MAX_NICKNAME_RETRIES attempts
failed with P2002 errors), the function implicitly returns undefined instead of
throwing an error, causing silent failures where the user is created with
incomplete data. Add a throw statement after the for loop in
saveFirstLoginFields to raise an error when all nickname generation attempts
fail, ensuring the signIn callback properly detects and rejects failed user
creation operations.

Comment thread src/app/(page)/login/login.module.scss Outdated
Comment on lines +55 to +59
font-size: v.$font-size-caption;
font-weight: v.$font-weight-regular;
color: v.$color-black-400;
text-align: center;
line-height: v.$line-height-caption;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mixin 사용 부탁드립니다

Comment on lines +57 to +71
<svg
width="18"
height="18"
viewBox="0 0 18 18"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M9 1.5C4.858 1.5 1.5 4.134 1.5 7.38c0 2.1 1.395 3.942 3.498 4.998L4.1 15.228a.188.188 0 0 0 .288.204l3.726-2.472A8.8 8.8 0 0 0 9 13.26c4.142 0 7.5-2.634 7.5-5.88S13.142 1.5 9 1.5Z"
fill="#000000"
/>
</svg>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아이콘이 깨져보이는데 확인부탁드려요

wjdalss21 added a commit that referenced this pull request Jun 18, 2026
변경 이유:
- src/app/page.tsx: 홈 화면 콘텐츠를 루트 경로(/)에서 서빙하도록 이동
  → Next.js App Router에서 루트 경로는 src/app/page.tsx가 담당하므로
    기존 (page)/home/page.tsx 대신 루트로 이동하는 것이 구조적으로 올바름
- src/app/page.module.scss: (page)/home/page.module.scss를 루트로 이동
  → page.tsx와 동일 위치에서 관리하도록 이동 (git rename으로 추적됨)
- src/app/(page)/home/page.tsx: redirect('/')로 교체
  → 기존 /home URL 접근 시 /로 리다이렉트하여 북마크/공유 링크 호환성 유지
- src/app/(page)/login/page.tsx: callbackUrl '/home' → '/'
  → 로그인 성공 후 이동 경로를 변경된 홈 경로(/)에 맞게 수정
- src/components/layout/BottomNavigation.tsx: href '/home' → '/'
  → 하단 탭 홈 버튼이 올바른 경로를 가리키도록 수정
  → pathname.startsWith('/') 는 모든 경로에서 true이므로
    홈 탭 활성 조건을 pathname === '/' 로 변경하여 활성 상태 오류 수정
- src/components/home/StatsCategorySection.module.scss: width 100%로 변경
  → 고정 픽셀(346px) 대신 width: 100%로 반응형 처리
- src/middleware.ts: 개발 환경 인증 bypass 추가
  → PR #50 카카오 로그인 병합 후 next-auth/middleware가 모든 경로를 차단하게 됨
  → 개발 편의를 위해 NODE_ENV === development 일 때 인증 없이 접근 허용
  → 배포 전 반드시 제거 필요 (TODO 주석 명시)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
evenif99 pushed a commit that referenced this pull request Jun 18, 2026
* feat: 홈 화면 기본 구조 생성 (헤더, 일기 박스)

- 헤더: 세션 유저명 + character-welcome.png 부엉이 이미지
- 일기 박스: 365x88, border black-700 2px, bg primary-100
- TODO: GangwonEduPower 폰트 추가 후 헤더 로고 텍스트 적용 필요

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Header variant 분리 (logo/title) 및 홈 화면 적용

- Header.tsx에 variant prop 추가 (logo | title)
  - logo: 좌측 상단 말해부엉 로고 표시 (66x19, h:56, padding: 16px 20px)
  - title: 기존 뒤로가기 + 페이지 제목 형태 유지
- Header.module.scss에 __logo 스타일 추가
- home/page.tsx에 Header variant='logo' 적용
  - 헤더를 컨테이너 padding 밖으로 분리하여 상단 여백 제거
- home/page.module.scss diaryBox에 align-self: center 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건기록 페이지 생성 및 로고 헤더 적용 (/records)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: diaryBox 고정 폭을 max-width + width 100%로 반응형 처리

- width: 365px → width: 100% + max-width: 365px
- 작은 화면에서 좌우 패딩과 결합 시 오버플로우 방지

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 감정일기 작성 버튼 /diary/new 네비게이션 연결

- 일기 박스 전체를 Link로 변경 (텍스트 + 버튼 모두 클릭 가능)
- diaryBox에 text-decoration: none, cursor: pointer 추가
- /diary/new 경로는 임시 지정 (담당자 확인 후 수정 예정)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면 캐릭터 이미지 교체 및 위치 조정

- character-welcome.png → character-home.png 교체 (169x138)
- 캐릭터 절대 위치 적용 (top: 41px, right: -20px)
- 캐릭터가 일기 박스 뒤에 위치하도록 z-index 조정 (character: 0, container: 1)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 홈 화면 코드래빗 피드백 반영

- 캐릭터 이미지 가로 스크롤 방지: .page에 overflow-x: hidden 추가
- 비로그인 사용자 분기 처리: 말해부엉 알아보기 박스 추가 (/login 이동)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: 홈 화면 typography 믹신 적용

- greetingText, diaryTitle, diarySubtitle에 typography 믹신 사용
- 개별 font 속성 직접 선언 → @include m.text-* 토큰으로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 비로그인 알아보기 박스 위치 수정

- 인사/일기 박스는 로그인 여부 무관하게 항상 표시
- 말해부엉 알아보기 박스를 진행중인 사건 위치(구분선 아래)로 이동
- 비로그인 인사: '안녕하세요' 표시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면에 통계 섹션 및 구분선 통합

- StatsCategorySection, useStatistics, QueryProvider 병합
- 고민 카테고리 TOP4 통계 섹션 추가
- 통계 섹션 하단 구분선 추가 (h:8px, black-100, gap:42px)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: 개발 편의용 로그인 상태 강제 설정 (배포 전 제거 필요)

- isLoggedIn = true 하드코딩으로 로그인 상태 유지
- TODO 주석으로 배포 전 제거 안내 표시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면 진행중인 사건 섹션 UI 구현

- ActiveCasesSection 컴포넌트 추가
  - 진행중인 사건 목록 표시 (waiting_opponent / opponent_joined / both_submitted)
  - CaseCard 공통 컴포넌트 재사용
  - 좌측 카테고리 컬러 accent bar
  - 카드 간격 12px
- useActiveCases 훅 추가 (mock 데이터, TODO: 실 API 연동)
- CaseCard에 participants prop 추가 (AvatarGroup 렌더링)
- CategoryIcon의 CATEGORY_COLOR_MAP export 추가
- 홈 페이지에 로그인 시 ActiveCasesSection 표시
- 구분선 ↔ 섹션 간격 20px 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 진행중인 사건 카드 수정 - CaseCard 원본 구조 유지, 좌측 컬러바 제거, Avatar 좌측 배치

- CaseCard 원본 구조 완전 원복 (participants prop 제거, div 래퍼 제거)
- CategoryIcon CATEGORY_COLOR_MAP export 원복
- 불필요한 좌측 카테고리 accent bar 제거
- Avatar absolute 오버레이 우측→좌측 하단 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard preview 텍스트 컬러 black-700으로 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 진행중인 사건 섹션 내 진행중 뱃지 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 진행중인 사건 카드 푸터 레이아웃 및 외곽선 black-700 2px inset 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 진행중인 사건 카드 preview-footer 간격 8px 조정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 코드래빗 리뷰 반영 - 린트, loading/error 상태 처리, onClick li로 이동

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: 홈 화면 캐릭터 이미지 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: 홈 페이지를 /home에서 / 루트 경로로 이동

변경 이유:
- src/app/page.tsx: 홈 화면 콘텐츠를 루트 경로(/)에서 서빙하도록 이동
  → Next.js App Router에서 루트 경로는 src/app/page.tsx가 담당하므로
    기존 (page)/home/page.tsx 대신 루트로 이동하는 것이 구조적으로 올바름
- src/app/page.module.scss: (page)/home/page.module.scss를 루트로 이동
  → page.tsx와 동일 위치에서 관리하도록 이동 (git rename으로 추적됨)
- src/app/(page)/home/page.tsx: redirect('/')로 교체
  → 기존 /home URL 접근 시 /로 리다이렉트하여 북마크/공유 링크 호환성 유지
- src/app/(page)/login/page.tsx: callbackUrl '/home' → '/'
  → 로그인 성공 후 이동 경로를 변경된 홈 경로(/)에 맞게 수정
- src/components/layout/BottomNavigation.tsx: href '/home' → '/'
  → 하단 탭 홈 버튼이 올바른 경로를 가리키도록 수정
  → pathname.startsWith('/') 는 모든 경로에서 true이므로
    홈 탭 활성 조건을 pathname === '/' 로 변경하여 활성 상태 오류 수정
- src/components/home/StatsCategorySection.module.scss: width 100%로 변경
  → 고정 픽셀(346px) 대신 width: 100%로 반응형 처리
- src/middleware.ts: 개발 환경 인증 bypass 추가
  → PR #50 카카오 로그인 병합 후 next-auth/middleware가 모든 경로를 차단하게 됨
  → 개발 편의를 위해 NODE_ENV === development 일 때 인증 없이 접근 허용
  → 배포 전 반드시 제거 필요 (TODO 주석 명시)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
evenif99 pushed a commit that referenced this pull request Jun 19, 2026
* feat: 홈 화면 기본 구조 생성 (헤더, 일기 박스)

- 헤더: 세션 유저명 + character-welcome.png 부엉이 이미지
- 일기 박스: 365x88, border black-700 2px, bg primary-100
- TODO: GangwonEduPower 폰트 추가 후 헤더 로고 텍스트 적용 필요

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Header variant 분리 (logo/title) 및 홈 화면 적용

- Header.tsx에 variant prop 추가 (logo | title)
  - logo: 좌측 상단 말해부엉 로고 표시 (66x19, h:56, padding: 16px 20px)
  - title: 기존 뒤로가기 + 페이지 제목 형태 유지
- Header.module.scss에 __logo 스타일 추가
- home/page.tsx에 Header variant='logo' 적용
  - 헤더를 컨테이너 padding 밖으로 분리하여 상단 여백 제거
- home/page.module.scss diaryBox에 align-self: center 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건기록 페이지 생성 및 로고 헤더 적용 (/records)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: diaryBox 고정 폭을 max-width + width 100%로 반응형 처리

- width: 365px → width: 100% + max-width: 365px
- 작은 화면에서 좌우 패딩과 결합 시 오버플로우 방지

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 감정일기 작성 버튼 /diary/new 네비게이션 연결

- 일기 박스 전체를 Link로 변경 (텍스트 + 버튼 모두 클릭 가능)
- diaryBox에 text-decoration: none, cursor: pointer 추가
- /diary/new 경로는 임시 지정 (담당자 확인 후 수정 예정)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면 캐릭터 이미지 교체 및 위치 조정

- character-welcome.png → character-home.png 교체 (169x138)
- 캐릭터 절대 위치 적용 (top: 41px, right: -20px)
- 캐릭터가 일기 박스 뒤에 위치하도록 z-index 조정 (character: 0, container: 1)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 홈 화면 코드래빗 피드백 반영

- 캐릭터 이미지 가로 스크롤 방지: .page에 overflow-x: hidden 추가
- 비로그인 사용자 분기 처리: 말해부엉 알아보기 박스 추가 (/login 이동)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: 홈 화면 typography 믹신 적용

- greetingText, diaryTitle, diarySubtitle에 typography 믹신 사용
- 개별 font 속성 직접 선언 → @include m.text-* 토큰으로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 비로그인 알아보기 박스 위치 수정

- 인사/일기 박스는 로그인 여부 무관하게 항상 표시
- 말해부엉 알아보기 박스를 진행중인 사건 위치(구분선 아래)로 이동
- 비로그인 인사: '안녕하세요' 표시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면에 통계 섹션 및 구분선 통합

- StatsCategorySection, useStatistics, QueryProvider 병합
- 고민 카테고리 TOP4 통계 섹션 추가
- 통계 섹션 하단 구분선 추가 (h:8px, black-100, gap:42px)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: 개발 편의용 로그인 상태 강제 설정 (배포 전 제거 필요)

- isLoggedIn = true 하드코딩으로 로그인 상태 유지
- TODO 주석으로 배포 전 제거 안내 표시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면 진행중인 사건 섹션 UI 구현

- ActiveCasesSection 컴포넌트 추가
  - 진행중인 사건 목록 표시 (waiting_opponent / opponent_joined / both_submitted)
  - CaseCard 공통 컴포넌트 재사용
  - 좌측 카테고리 컬러 accent bar
  - 카드 간격 12px
- useActiveCases 훅 추가 (mock 데이터, TODO: 실 API 연동)
- CaseCard에 participants prop 추가 (AvatarGroup 렌더링)
- CategoryIcon의 CATEGORY_COLOR_MAP export 추가
- 홈 페이지에 로그인 시 ActiveCasesSection 표시
- 구분선 ↔ 섹션 간격 20px 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 진행중인 사건 카드 수정 - CaseCard 원본 구조 유지, 좌측 컬러바 제거, Avatar 좌측 배치

- CaseCard 원본 구조 완전 원복 (participants prop 제거, div 래퍼 제거)
- CategoryIcon CATEGORY_COLOR_MAP export 원복
- 불필요한 좌측 카테고리 accent bar 제거
- Avatar absolute 오버레이 우측→좌측 하단 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard preview 텍스트 컬러 black-700으로 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 진행중인 사건 섹션 내 진행중 뱃지 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 진행중인 사건 카드 푸터 레이아웃 및 외곽선 black-700 2px inset 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 진행중인 사건 카드 preview-footer 간격 8px 조정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 코드래빗 리뷰 반영 - 린트, loading/error 상태 처리, onClick li로 이동

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: 홈 화면 캐릭터 이미지 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: 홈 페이지를 /home에서 / 루트 경로로 이동

변경 이유:
- src/app/page.tsx: 홈 화면 콘텐츠를 루트 경로(/)에서 서빙하도록 이동
  → Next.js App Router에서 루트 경로는 src/app/page.tsx가 담당하므로
    기존 (page)/home/page.tsx 대신 루트로 이동하는 것이 구조적으로 올바름
- src/app/page.module.scss: (page)/home/page.module.scss를 루트로 이동
  → page.tsx와 동일 위치에서 관리하도록 이동 (git rename으로 추적됨)
- src/app/(page)/home/page.tsx: redirect('/')로 교체
  → 기존 /home URL 접근 시 /로 리다이렉트하여 북마크/공유 링크 호환성 유지
- src/app/(page)/login/page.tsx: callbackUrl '/home' → '/'
  → 로그인 성공 후 이동 경로를 변경된 홈 경로(/)에 맞게 수정
- src/components/layout/BottomNavigation.tsx: href '/home' → '/'
  → 하단 탭 홈 버튼이 올바른 경로를 가리키도록 수정
  → pathname.startsWith('/') 는 모든 경로에서 true이므로
    홈 탭 활성 조건을 pathname === '/' 로 변경하여 활성 상태 오류 수정
- src/components/home/StatsCategorySection.module.scss: width 100%로 변경
  → 고정 픽셀(346px) 대신 width: 100%로 반응형 처리
- src/middleware.ts: 개발 환경 인증 bypass 추가
  → PR #50 카카오 로그인 병합 후 next-auth/middleware가 모든 경로를 차단하게 됨
  → 개발 편의를 위해 NODE_ENV === development 일 때 인증 없이 접근 허용
  → 배포 전 반드시 제거 필요 (TODO 주석 명시)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면 새 사건 버튼 및 서비스 정보 푸터 구현

- NewCaseButton: 홈 화면 우측 하단 고정 플로팅 버튼 추가
  (w115 h48, color/black-700, border-radius 100, text-title-s)
  새 사건 작성 페이지 생성 후 href 연결 필요 (TODO 주석)
- HomeServiceInfo: 서비스 정보 박스 구현
  (로고 w66 h19, 서비스 소개/개인정보처리방침/이용약관/고객문의 링크,
  Copyright 텍스트, 전체 너비 반응형, 탭바 뒤에 위치)
- BottomNavigation: 홈 페이지에 탭바 추가, z-index 100 유지
  (서비스 정보 박스보다 앞에 렌더링)
- page.tsx: NewCaseButton, HomeServiceInfo, BottomNavigation 렌더링 추가
- page.module.scss: container padding-bottom 60px, serviceInfoWrapper 스타일

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 새 사건 버튼 카테고리 선택 모달 구현

- 새 사건 + 버튼 클릭 시 카테고리 선택 모달 표시
- 모달 오버레이: color-black-700 40% 틴트 + bg-page 불투명 베이스
  (배경 콘텐츠가 비치지 않도록 레이어드 배경 처리)
- 카테고리 박스: w133 h176, 흰 배경, 4개 카테고리 항목 가운데 정렬
  (CategoryIcon 공통 컴포넌트 사용, 연인관계/직장관계/친구관계/가족관계)
  (텍스트: text-body-m, text/primary, 아이콘과 9px 간격)
- X 닫기 버튼: 48x48 흰 원형, CloseIcon 24x24
- 모달 오픈 시 body overflow hidden으로 스크롤 잠금
- 카테고리 href: '#' 임시 처리 (새 사건 작성 페이지 생성 후 교체 필요)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CodeRabbit 리뷰 반영 — isLoggedIn 하드코딩 제거, 서비스 링크 경로 교체, SCSS 빈 줄 정리

- isLoggedIn = true → !!session 으로 교체, 개발용 TODO 주석 제거
- HomeServiceInfo /privacy, /terms 실제 경로 연결
- page.module.scss 불필요 인라인 주석 제거
- HomeServiceInfo.module.scss .link/.copyright @include 뒤 빈 줄 추가
- NewCaseButton.module.scss @include 뒤 빈 줄, 주석/선언 그룹 간격 정리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
evenif99 pushed a commit that referenced this pull request Jun 19, 2026
* feat: 홈 화면 기본 구조 생성 (헤더, 일기 박스)

- 헤더: 세션 유저명 + character-welcome.png 부엉이 이미지
- 일기 박스: 365x88, border black-700 2px, bg primary-100
- TODO: GangwonEduPower 폰트 추가 후 헤더 로고 텍스트 적용 필요

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Header variant 분리 (logo/title) 및 홈 화면 적용

- Header.tsx에 variant prop 추가 (logo | title)
  - logo: 좌측 상단 말해부엉 로고 표시 (66x19, h:56, padding: 16px 20px)
  - title: 기존 뒤로가기 + 페이지 제목 형태 유지
- Header.module.scss에 __logo 스타일 추가
- home/page.tsx에 Header variant='logo' 적용
  - 헤더를 컨테이너 padding 밖으로 분리하여 상단 여백 제거
- home/page.module.scss diaryBox에 align-self: center 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건기록 페이지 생성 및 로고 헤더 적용 (/records)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: diaryBox 고정 폭을 max-width + width 100%로 반응형 처리

- width: 365px → width: 100% + max-width: 365px
- 작은 화면에서 좌우 패딩과 결합 시 오버플로우 방지

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 감정일기 작성 버튼 /diary/new 네비게이션 연결

- 일기 박스 전체를 Link로 변경 (텍스트 + 버튼 모두 클릭 가능)
- diaryBox에 text-decoration: none, cursor: pointer 추가
- /diary/new 경로는 임시 지정 (담당자 확인 후 수정 예정)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면 캐릭터 이미지 교체 및 위치 조정

- character-welcome.png → character-home.png 교체 (169x138)
- 캐릭터 절대 위치 적용 (top: 41px, right: -20px)
- 캐릭터가 일기 박스 뒤에 위치하도록 z-index 조정 (character: 0, container: 1)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 홈 화면 코드래빗 피드백 반영

- 캐릭터 이미지 가로 스크롤 방지: .page에 overflow-x: hidden 추가
- 비로그인 사용자 분기 처리: 말해부엉 알아보기 박스 추가 (/login 이동)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: 홈 화면 typography 믹신 적용

- greetingText, diaryTitle, diarySubtitle에 typography 믹신 사용
- 개별 font 속성 직접 선언 → @include m.text-* 토큰으로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 비로그인 알아보기 박스 위치 수정

- 인사/일기 박스는 로그인 여부 무관하게 항상 표시
- 말해부엉 알아보기 박스를 진행중인 사건 위치(구분선 아래)로 이동
- 비로그인 인사: '안녕하세요' 표시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면에 통계 섹션 및 구분선 통합

- StatsCategorySection, useStatistics, QueryProvider 병합
- 고민 카테고리 TOP4 통계 섹션 추가
- 통계 섹션 하단 구분선 추가 (h:8px, black-100, gap:42px)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: 개발 편의용 로그인 상태 강제 설정 (배포 전 제거 필요)

- isLoggedIn = true 하드코딩으로 로그인 상태 유지
- TODO 주석으로 배포 전 제거 안내 표시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면 진행중인 사건 섹션 UI 구현

- ActiveCasesSection 컴포넌트 추가
  - 진행중인 사건 목록 표시 (waiting_opponent / opponent_joined / both_submitted)
  - CaseCard 공통 컴포넌트 재사용
  - 좌측 카테고리 컬러 accent bar
  - 카드 간격 12px
- useActiveCases 훅 추가 (mock 데이터, TODO: 실 API 연동)
- CaseCard에 participants prop 추가 (AvatarGroup 렌더링)
- CategoryIcon의 CATEGORY_COLOR_MAP export 추가
- 홈 페이지에 로그인 시 ActiveCasesSection 표시
- 구분선 ↔ 섹션 간격 20px 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 진행중인 사건 카드 수정 - CaseCard 원본 구조 유지, 좌측 컬러바 제거, Avatar 좌측 배치

- CaseCard 원본 구조 완전 원복 (participants prop 제거, div 래퍼 제거)
- CategoryIcon CATEGORY_COLOR_MAP export 원복
- 불필요한 좌측 카테고리 accent bar 제거
- Avatar absolute 오버레이 우측→좌측 하단 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard preview 텍스트 컬러 black-700으로 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 진행중인 사건 섹션 내 진행중 뱃지 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 진행중인 사건 카드 푸터 레이아웃 및 외곽선 black-700 2px inset 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 진행중인 사건 카드 preview-footer 간격 8px 조정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 코드래빗 리뷰 반영 - 린트, loading/error 상태 처리, onClick li로 이동

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: 홈 화면 캐릭터 이미지 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: 홈 페이지를 /home에서 / 루트 경로로 이동

변경 이유:
- src/app/page.tsx: 홈 화면 콘텐츠를 루트 경로(/)에서 서빙하도록 이동
  → Next.js App Router에서 루트 경로는 src/app/page.tsx가 담당하므로
    기존 (page)/home/page.tsx 대신 루트로 이동하는 것이 구조적으로 올바름
- src/app/page.module.scss: (page)/home/page.module.scss를 루트로 이동
  → page.tsx와 동일 위치에서 관리하도록 이동 (git rename으로 추적됨)
- src/app/(page)/home/page.tsx: redirect('/')로 교체
  → 기존 /home URL 접근 시 /로 리다이렉트하여 북마크/공유 링크 호환성 유지
- src/app/(page)/login/page.tsx: callbackUrl '/home' → '/'
  → 로그인 성공 후 이동 경로를 변경된 홈 경로(/)에 맞게 수정
- src/components/layout/BottomNavigation.tsx: href '/home' → '/'
  → 하단 탭 홈 버튼이 올바른 경로를 가리키도록 수정
  → pathname.startsWith('/') 는 모든 경로에서 true이므로
    홈 탭 활성 조건을 pathname === '/' 로 변경하여 활성 상태 오류 수정
- src/components/home/StatsCategorySection.module.scss: width 100%로 변경
  → 고정 픽셀(346px) 대신 width: 100%로 반응형 처리
- src/middleware.ts: 개발 환경 인증 bypass 추가
  → PR #50 카카오 로그인 병합 후 next-auth/middleware가 모든 경로를 차단하게 됨
  → 개발 편의를 위해 NODE_ENV === development 일 때 인증 없이 접근 허용
  → 배포 전 반드시 제거 필요 (TODO 주석 명시)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면 새 사건 버튼 및 서비스 정보 푸터 구현

- NewCaseButton: 홈 화면 우측 하단 고정 플로팅 버튼 추가
  (w115 h48, color/black-700, border-radius 100, text-title-s)
  새 사건 작성 페이지 생성 후 href 연결 필요 (TODO 주석)
- HomeServiceInfo: 서비스 정보 박스 구현
  (로고 w66 h19, 서비스 소개/개인정보처리방침/이용약관/고객문의 링크,
  Copyright 텍스트, 전체 너비 반응형, 탭바 뒤에 위치)
- BottomNavigation: 홈 페이지에 탭바 추가, z-index 100 유지
  (서비스 정보 박스보다 앞에 렌더링)
- page.tsx: NewCaseButton, HomeServiceInfo, BottomNavigation 렌더링 추가
- page.module.scss: container padding-bottom 60px, serviceInfoWrapper 스타일

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 새 사건 버튼 카테고리 선택 모달 구현

- 새 사건 + 버튼 클릭 시 카테고리 선택 모달 표시
- 모달 오버레이: color-black-700 40% 틴트 + bg-page 불투명 베이스
  (배경 콘텐츠가 비치지 않도록 레이어드 배경 처리)
- 카테고리 박스: w133 h176, 흰 배경, 4개 카테고리 항목 가운데 정렬
  (CategoryIcon 공통 컴포넌트 사용, 연인관계/직장관계/친구관계/가족관계)
  (텍스트: text-body-m, text/primary, 아이콘과 9px 간격)
- X 닫기 버튼: 48x48 흰 원형, CloseIcon 24x24
- 모달 오픈 시 body overflow hidden으로 스크롤 잠금
- 카테고리 href: '#' 임시 처리 (새 사건 작성 페이지 생성 후 교체 필요)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CodeRabbit 리뷰 반영 — isLoggedIn 하드코딩 제거, 서비스 링크 경로 교체, SCSS 빈 줄 정리

- isLoggedIn = true → !!session 으로 교체, 개발용 TODO 주석 제거
- HomeServiceInfo /privacy, /terms 실제 경로 연결
- page.module.scss 불필요 인라인 주석 제거
- HomeServiceInfo.module.scss .link/.copyright @include 뒤 빈 줄 추가
- NewCaseButton.module.scss @include 뒤 빈 줄, 주석/선언 그룹 간격 정리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: HomeGreeting 컴포넌트 추가 및 DB 닉네임 기반 인사말 적용

- useUserMe 훅 추가 (/api/user/me 호출, TanStack Query)
- HomeGreeting 클라이언트 컴포넌트 추가 (DB 닉네임 기반 인사말)
- page.tsx에서 session.user.name 제거, HomeGreeting으로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 데이터 없을 때 목 데이터 fallback 추가 (UI 확인용)

실제 판결 데이터 쌓이면 자동으로 실제 데이터로 전환됨.
TODO: 실제 데이터 쌓이면 MOCK_ITEMS 및 fallback 로직 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: 진행중인 사건 목 데이터 제거

실 API 미연동 상태로 빈 배열 반환 처리.
API 연동 시 fetchActiveCases 주석 해제 후 교체 필요.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 새 사건 버튼 카테고리 클릭 시 진술 작성 페이지로 이동

선택한 카테고리를 ?category= 쿼리 파라미터로 전달.
/disputes/test/statement?category={category}로 임시 연결.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 서비스 소개·고객문의 링크 미연결 항목 span으로 교체

href 없는 항목은 a 태그 대신 span(aria-disabled)으로 렌더링.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: NewCaseButton SCSS declaration-empty-line-before 위반 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
evenif99 pushed a commit that referenced this pull request Jun 19, 2026
* feat: 홈 화면 기본 구조 생성 (헤더, 일기 박스)

- 헤더: 세션 유저명 + character-welcome.png 부엉이 이미지
- 일기 박스: 365x88, border black-700 2px, bg primary-100
- TODO: GangwonEduPower 폰트 추가 후 헤더 로고 텍스트 적용 필요

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Header variant 분리 (logo/title) 및 홈 화면 적용

- Header.tsx에 variant prop 추가 (logo | title)
  - logo: 좌측 상단 말해부엉 로고 표시 (66x19, h:56, padding: 16px 20px)
  - title: 기존 뒤로가기 + 페이지 제목 형태 유지
- Header.module.scss에 __logo 스타일 추가
- home/page.tsx에 Header variant='logo' 적용
  - 헤더를 컨테이너 padding 밖으로 분리하여 상단 여백 제거
- home/page.module.scss diaryBox에 align-self: center 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건기록 페이지 생성 및 로고 헤더 적용 (/records)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: diaryBox 고정 폭을 max-width + width 100%로 반응형 처리

- width: 365px → width: 100% + max-width: 365px
- 작은 화면에서 좌우 패딩과 결합 시 오버플로우 방지

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 감정일기 작성 버튼 /diary/new 네비게이션 연결

- 일기 박스 전체를 Link로 변경 (텍스트 + 버튼 모두 클릭 가능)
- diaryBox에 text-decoration: none, cursor: pointer 추가
- /diary/new 경로는 임시 지정 (담당자 확인 후 수정 예정)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면 캐릭터 이미지 교체 및 위치 조정

- character-welcome.png → character-home.png 교체 (169x138)
- 캐릭터 절대 위치 적용 (top: 41px, right: -20px)
- 캐릭터가 일기 박스 뒤에 위치하도록 z-index 조정 (character: 0, container: 1)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 홈 화면 코드래빗 피드백 반영

- 캐릭터 이미지 가로 스크롤 방지: .page에 overflow-x: hidden 추가
- 비로그인 사용자 분기 처리: 말해부엉 알아보기 박스 추가 (/login 이동)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: 홈 화면 typography 믹신 적용

- greetingText, diaryTitle, diarySubtitle에 typography 믹신 사용
- 개별 font 속성 직접 선언 → @include m.text-* 토큰으로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 비로그인 알아보기 박스 위치 수정

- 인사/일기 박스는 로그인 여부 무관하게 항상 표시
- 말해부엉 알아보기 박스를 진행중인 사건 위치(구분선 아래)로 이동
- 비로그인 인사: '안녕하세요' 표시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면에 통계 섹션 및 구분선 통합

- StatsCategorySection, useStatistics, QueryProvider 병합
- 고민 카테고리 TOP4 통계 섹션 추가
- 통계 섹션 하단 구분선 추가 (h:8px, black-100, gap:42px)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: 개발 편의용 로그인 상태 강제 설정 (배포 전 제거 필요)

- isLoggedIn = true 하드코딩으로 로그인 상태 유지
- TODO 주석으로 배포 전 제거 안내 표시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면 진행중인 사건 섹션 UI 구현

- ActiveCasesSection 컴포넌트 추가
  - 진행중인 사건 목록 표시 (waiting_opponent / opponent_joined / both_submitted)
  - CaseCard 공통 컴포넌트 재사용
  - 좌측 카테고리 컬러 accent bar
  - 카드 간격 12px
- useActiveCases 훅 추가 (mock 데이터, TODO: 실 API 연동)
- CaseCard에 participants prop 추가 (AvatarGroup 렌더링)
- CategoryIcon의 CATEGORY_COLOR_MAP export 추가
- 홈 페이지에 로그인 시 ActiveCasesSection 표시
- 구분선 ↔ 섹션 간격 20px 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 진행중인 사건 카드 수정 - CaseCard 원본 구조 유지, 좌측 컬러바 제거, Avatar 좌측 배치

- CaseCard 원본 구조 완전 원복 (participants prop 제거, div 래퍼 제거)
- CategoryIcon CATEGORY_COLOR_MAP export 원복
- 불필요한 좌측 카테고리 accent bar 제거
- Avatar absolute 오버레이 우측→좌측 하단 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard preview 텍스트 컬러 black-700으로 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 진행중인 사건 섹션 내 진행중 뱃지 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 진행중인 사건 카드 푸터 레이아웃 및 외곽선 black-700 2px inset 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 진행중인 사건 카드 preview-footer 간격 8px 조정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 코드래빗 리뷰 반영 - 린트, loading/error 상태 처리, onClick li로 이동

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: 홈 화면 캐릭터 이미지 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: 홈 페이지를 /home에서 / 루트 경로로 이동

변경 이유:
- src/app/page.tsx: 홈 화면 콘텐츠를 루트 경로(/)에서 서빙하도록 이동
  → Next.js App Router에서 루트 경로는 src/app/page.tsx가 담당하므로
    기존 (page)/home/page.tsx 대신 루트로 이동하는 것이 구조적으로 올바름
- src/app/page.module.scss: (page)/home/page.module.scss를 루트로 이동
  → page.tsx와 동일 위치에서 관리하도록 이동 (git rename으로 추적됨)
- src/app/(page)/home/page.tsx: redirect('/')로 교체
  → 기존 /home URL 접근 시 /로 리다이렉트하여 북마크/공유 링크 호환성 유지
- src/app/(page)/login/page.tsx: callbackUrl '/home' → '/'
  → 로그인 성공 후 이동 경로를 변경된 홈 경로(/)에 맞게 수정
- src/components/layout/BottomNavigation.tsx: href '/home' → '/'
  → 하단 탭 홈 버튼이 올바른 경로를 가리키도록 수정
  → pathname.startsWith('/') 는 모든 경로에서 true이므로
    홈 탭 활성 조건을 pathname === '/' 로 변경하여 활성 상태 오류 수정
- src/components/home/StatsCategorySection.module.scss: width 100%로 변경
  → 고정 픽셀(346px) 대신 width: 100%로 반응형 처리
- src/middleware.ts: 개발 환경 인증 bypass 추가
  → PR #50 카카오 로그인 병합 후 next-auth/middleware가 모든 경로를 차단하게 됨
  → 개발 편의를 위해 NODE_ENV === development 일 때 인증 없이 접근 허용
  → 배포 전 반드시 제거 필요 (TODO 주석 명시)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면 새 사건 버튼 및 서비스 정보 푸터 구현

- NewCaseButton: 홈 화면 우측 하단 고정 플로팅 버튼 추가
  (w115 h48, color/black-700, border-radius 100, text-title-s)
  새 사건 작성 페이지 생성 후 href 연결 필요 (TODO 주석)
- HomeServiceInfo: 서비스 정보 박스 구현
  (로고 w66 h19, 서비스 소개/개인정보처리방침/이용약관/고객문의 링크,
  Copyright 텍스트, 전체 너비 반응형, 탭바 뒤에 위치)
- BottomNavigation: 홈 페이지에 탭바 추가, z-index 100 유지
  (서비스 정보 박스보다 앞에 렌더링)
- page.tsx: NewCaseButton, HomeServiceInfo, BottomNavigation 렌더링 추가
- page.module.scss: container padding-bottom 60px, serviceInfoWrapper 스타일

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 새 사건 버튼 카테고리 선택 모달 구현

- 새 사건 + 버튼 클릭 시 카테고리 선택 모달 표시
- 모달 오버레이: color-black-700 40% 틴트 + bg-page 불투명 베이스
  (배경 콘텐츠가 비치지 않도록 레이어드 배경 처리)
- 카테고리 박스: w133 h176, 흰 배경, 4개 카테고리 항목 가운데 정렬
  (CategoryIcon 공통 컴포넌트 사용, 연인관계/직장관계/친구관계/가족관계)
  (텍스트: text-body-m, text/primary, 아이콘과 9px 간격)
- X 닫기 버튼: 48x48 흰 원형, CloseIcon 24x24
- 모달 오픈 시 body overflow hidden으로 스크롤 잠금
- 카테고리 href: '#' 임시 처리 (새 사건 작성 페이지 생성 후 교체 필요)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CodeRabbit 리뷰 반영 — isLoggedIn 하드코딩 제거, 서비스 링크 경로 교체, SCSS 빈 줄 정리

- isLoggedIn = true → !!session 으로 교체, 개발용 TODO 주석 제거
- HomeServiceInfo /privacy, /terms 실제 경로 연결
- page.module.scss 불필요 인라인 주석 제거
- HomeServiceInfo.module.scss .link/.copyright @include 뒤 빈 줄 추가
- NewCaseButton.module.scss @include 뒤 빈 줄, 주석/선언 그룹 간격 정리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: HomeGreeting 컴포넌트 추가 및 DB 닉네임 기반 인사말 적용

- useUserMe 훅 추가 (/api/user/me 호출, TanStack Query)
- HomeGreeting 클라이언트 컴포넌트 추가 (DB 닉네임 기반 인사말)
- page.tsx에서 session.user.name 제거, HomeGreeting으로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 데이터 없을 때 목 데이터 fallback 추가 (UI 확인용)

실제 판결 데이터 쌓이면 자동으로 실제 데이터로 전환됨.
TODO: 실제 데이터 쌓이면 MOCK_ITEMS 및 fallback 로직 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: 진행중인 사건 목 데이터 제거

실 API 미연동 상태로 빈 배열 반환 처리.
API 연동 시 fetchActiveCases 주석 해제 후 교체 필요.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 새 사건 버튼 카테고리 클릭 시 진술 작성 페이지로 이동

선택한 카테고리를 ?category= 쿼리 파라미터로 전달.
/disputes/test/statement?category={category}로 임시 연결.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 서비스 소개·고객문의 링크 미연결 항목 span으로 교체

href 없는 항목은 a 태그 대신 span(aria-disabled)으로 렌더링.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: NewCaseButton SCSS declaration-empty-line-before 위반 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 새 사건 버튼 카테고리 클릭 시 POST /api/rooms 호출 후 statement 이동

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 새 사건 버튼 — POST /api/rooms 후 roomId+category를 statement 페이지로 전달

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 새 사건 버튼 중복 클릭 방지 및 5초 타임아웃 추가

- isCreating 상태로 in-flight 중 재진입 차단 및 버튼 비활성화
- AbortController 5초 타임아웃으로 네트워크 지연 시 fallback 보장

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 진행중인 사건 없을 때 캐릭터 이미지 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 진행중인 사건 빈 상태 이미지 Next.js Image → img 태그로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: PR73 CodeRabbit 피드백 반영

- NewCaseButton: catch fallback 이동 제거 → 에러 메시지 표시로 교체
- NewCaseButton: 성공 시 URL /disputes/new/ → /disputes/[roomId]/ 수정
- ActiveCasesSection: <img> → Next.js <Image> priority 적용
- ActiveCasesSection: 장식용 이미지 alt='' 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
evenif99 added a commit that referenced this pull request Jun 22, 2026
* chore: initialize project folder structure (#1)

* chore: initialize project folder structure

- Add base directory layout for Next.js + domain-driven architecture
- Add .gitkeep to track empty directories in git
- Exclude MVP out-of-scope domains (shop, points, user-items)
- No implementation files included, structure only

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update README.md

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add CLAUDE.md with project rules and work guidelines (#2)

- Add project overview and MVP scope definition
- Add fixed product rules (categories, AI chat policy, judgement output)
- Add architecture, domain scope, and state transition rules
- Add auth/security, DB, frontend state, API, logging rules
- Add Git workflow, Claude work process, STOP conditions
- Add approval-required list and required reference documents

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: setup project config and install dependencies (#3)

- Add package.json with Next.js 15, React 19, TypeScript stack
- Add next.config.ts (minimal Next.js 15 config)
- Add tsconfig.json (strict mode, @/* path alias)
- Add eslint.config.mjs (next/core-web-vitals + next/typescript)
- Add .prettierrc and .prettierignore
- Add .gitignore (node_modules, .next, .env.local, etc.)
- Add .env.example (key names only, no real values)
- Add prisma/schema.prisma (generator + datasource only)
- Add data/mock/db.json (health check stub for json-server)
- Add docs/TECH_STACK.md (package list and selection rationale)
- Update README.md with run commands and env guide

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add base documentation structure (#4)

- Add PROJECT_DECISIONS.md (MVP scope, architecture, security principles)
- Add guides/CLAUDE_WORKFLOW.md (work process, STOP conditions, approval rules)
- Add guides/GIT_WORKFLOW.md (branch naming, commit convention, workflow)
- Add guides/PR_RULES.md (PR target, title rules, review criteria)
- Add guides/ENV_GUIDE.md (Vercel env pull, .env.example management)
- Add guides/CODING_CONVENTION.md (naming, state management, folder rules)
- Add db/STATUS_TRANSITION.md (room_mode, dispute_status transitions)
- Add db/PRISMA_MAPPING.md (snake_case/camelCase mapping rules)
- Add db/MASTER_DATA.md (categories, result types, DB master principles)
- Add domains/README.md (domain list, MVP scope, writing guidelines)
- Add domains/_DOMAIN_TEMPLATE.md (template for domain docs)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add domain document drafts for all MVP domains (#5)

- Add AUTH.md (kakao login, terms, session management)
- Add COMMON.md (error handling, logging, common response)
- Add ROOM.md (AI chat room, invite link, room_mode transitions)
- Add PERSONAL_ANALYSIS.md (AI-based personal conflict analysis)
- Add DISPUTE.md (1:1 mediation, roles, statements, dispute_status)
- Add JUDGEMENT.md (AI judgement, Gemini API, result card)
- Add GIFT.md (gift recommendation after judgement)
- Add USER.md (mypage, profile, bottom tab)
- Add CALENDAR.md (date-based record marking, monthly summary)
- Add DIARY.md (emotion diary, author-only access, content protection)
- Add STATISTICS.md (anonymous aggregation, summary components)
- Add SHOP_FUTURE.md (v2.0 planned, MVP excluded)
- Add POINTS_FUTURE.md (v2.0 planned, MVP excluded)
- Add USER_ITEMS_FUTURE.md (v2.0 planned, MVP excluded)

All documents are draft templates with TODO markers for assignees.
No implementation, no API routes, no schema changes.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: add Next.js App Router entry files and SCSS base structure (#6)

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Infra/init next setup (#7)

* infra: add Next.js App Router entry files and SCSS base structure

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: resolve ESLint and TypeScript config warnings

- eslint.config.mjs: ignore next-env.d.ts and .next/** (auto-generated by Next.js, triple-slash reference false positive)
- tsconfig.json: remove deprecated baseUrl option (TypeScript 5.x+, paths works without baseUrl)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update README.md (#8)

* docs(infra): confirm Supabase as project infrastructure (#9)

* chore(github): add collaboration templates and policy (#10)

* docs(env): document environment variable management (#11)

* docs(calendar): confirm MUI date picker usage (#12)

달력 UI 라이브러리로 MUI X Date Pickers + Day.js 사용을 확정하고
관련 문서(TECH_STACK, PROJECT_DECISIONS, CODING_CONVENTION, CALENDAR, DIARY, CLAUDE.md)에 반영한다.

* chore(deps): install MUI X Date Pickers and peer dependencies (#13)

달력 UI 구현을 위해 MUI X Date Pickers 및 필수 peer dependency를 설치한다.
@mui/material@9.1.1, @emotion/react@11.14.0, @emotion/styled@11.14.1,
@mui/x-date-pickers@9.5.0, dayjs@1.11.21

* Update README.md (#15)

* fix: resolve ESLint and TypeScript config warnings (#20)

* infra: add Next.js App Router entry files and SCSS base structure

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: resolve ESLint and TypeScript config warnings

- eslint.config.mjs: ignore next-env.d.ts and .next/** (auto-generated by Next.js, triple-slash reference false positive)
- tsconfig.json: remove deprecated baseUrl option (TypeScript 5.x+, paths works without baseUrl)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: add MVP Prisma schema with NextAuth and TALKY-OWL models (#21)

- datasource: add directUrl for Supabase connection pooler support
- enums: CategoryGroup, RoomMode, DisputeStatus, ParticipantRole, etc.
- NextAuth models: User (with TALKY-OWL fields), Account, Session, VerificationToken
- core models: DisputeRoom, RoomAiConversation, RoomAiMessage
- dispute models: Dispute, DisputeParticipant, DisputeStatement
- judgment models: AiJudgment, JudgmentResultCard
- gift models: GiftRecommendation, GiftRecommendationItem
- feature models: EmotionDiary, CalendarRecord
- master data: ConflictTypeGroup, ConflictTypeDetail (DB-based, no enum hardcoding)
- log models: AuditLog, ApiErrorLog, ModerationLog, RoomAccessLog, UserDeletionLog
- .env.example: add DIRECT_URL for Supabase directUrl
- v2.0 TODO: ShopItem, PointTransaction, UserItem, DisputeStatistic excluded

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: align project structure with guide v2 (#22)

folders added:
- src/components/{personal-analysis,room,dispute,judgement,calendar,diary,statistics,gift}
- src/app/api/auth/[...nextauth]
- src/app/api/v1/{users,personal-analyses,rooms,disputes,statements,calendar,diary,statistics,cron}

files added:
- prisma/seed.ts (placeholder for ConflictTypeGroup master data)

docs updated (minimal):
- docs/domains/COMMON.md: add log table list, judgement_logs TODO note
- docs/domains/JUDGEMENT.md: clarify Storage is MVP-excluded scaffolding
- docs/guides/ENV_GUIDE.md: clarify Supabase Storage vars are MVP-excluded

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: rename src/app/page to src/app/(page) for correct Next.js route group (#23)

src/app/page/ (괄호 없음)는 /page/* URL segment를 생성하므로,
Next.js App Router route group 문법인 src/app/(page)/로 변경한다.
URL은 /landing, /home 등으로 노출되어야 하며 /page/... 가 아니다.

관련 문서 내 경로 참조도 모두 업데이트 (CLAUDE.md, docs/domains/*, docs/guides/*).

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* [Style] 디자인 토큰 및 전역 스타일 설정 (#25)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 디자인 시스템 기반 설정 (#27)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: rem 스케일 토큰 추가 및 타이포그래피 변수 rem 참조로 전환

- Rem scale 섹션 추가 (0.25rem ~ 30rem)
- 폰트 토큰에서 누락된 0.875rem(14px), 1.125rem(18px) 추가
- font-size, line-height 변수를 rem 스케일 변수 참조로 전환
- rem 스케일을 typography 섹션보다 상단으로 이동 (선언 순서)
- 컴포넌트 width/height 대응을 위해 큰 단위(9rem~30rem) 포함

Co-Authored-By: Claude <noreply@anthropic.com>

* style: r() 함수 분리 및 타이포그래피 변수 함수 기반으로 전환

- _functions.scss 신규 추가 — px → rem 변환 함수 r() 단독 관리
- _variables.scss에서 rem 스케일 변수 제거, fn.r() 참조로 전환
- _mixins.scss에 functions @use 추가
- 순환 참조 없이 variables → functions → (없음) 단방향 의존성 구성

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Feature/common component jw (#28)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* fix: :root {} 시맨틱 토큰을 _global.scss로 분리 (#29)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: rem 스케일 토큰 추가 및 타이포그래피 변수 rem 참조로 전환

- Rem scale 섹션 추가 (0.25rem ~ 30rem)
- 폰트 토큰에서 누락된 0.875rem(14px), 1.125rem(18px) 추가
- font-size, line-height 변수를 rem 스케일 변수 참조로 전환
- rem 스케일을 typography 섹션보다 상단으로 이동 (선언 순서)
- 컴포넌트 width/height 대응을 위해 큰 단위(9rem~30rem) 포함

Co-Authored-By: Claude <noreply@anthropic.com>

* style: r() 함수 분리 및 타이포그래피 변수 함수 기반으로 전환

- _functions.scss 신규 추가 — px → rem 변환 함수 r() 단독 관리
- _variables.scss에서 rem 스케일 변수 제거, fn.r() 참조로 전환
- _mixins.scss에 functions @use 추가
- 순환 참조 없이 variables → functions → (없음) 단방향 의존성 구성

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: :root {} 시맨틱 토큰을 _global.scss로 분리

_variables.scss에 :root {}가 있으면 module.scss에서 @use 시
CSS Modules 'not pure' 에러 발생.
SCSS 변수는 _variables.scss, CSS 출력은 _global.scss로 분리.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): 공통 UI 컴포넌트 추가 및 MUI 정책 적용 (#30)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 목록 공통 UI 컴포넌트 추가 (Tab, StatusBadge) (#31)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 위치 수정 (#32)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 absolute 배치

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 공통 및 dispute·judgment DTO 타입 정의

- ApiResponse, ApiError, ApiFieldError, CategoryGroup (common.ts)
- DisputeDto, CreateDisputeRequest, DisputeListResponse 등 (dispute.ts)
- AiJudgmentDto, CreateAiJudgmentRequest 등 (judgment.ts)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: dispute 도메인 공유 상수·헬퍼·mapper 추가

- VALID_CATEGORY_GROUPS, IMMUTABLE_DISPUTE_STATUSES 상수 (constants/dispute.ts)
- getSessionUserId NextAuth 세션 헬퍼 (auth/session.ts)
- toAiJudgmentDto 공유 mapper (judgement/judgment.mapper.ts)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 목록 조회·생성·수정·삭제 API 구현

- GET /api/v1/disputes — 참여 사건 목록, categoryGroup 필터, 페이지네이션
- POST /api/v1/disputes — 사건 생성 + role_a 참여자 트랜잭션 등록
- GET /api/v1/disputes/:id — 사건 상세 조회
- PATCH /api/v1/disputes/:id — 사건 수정 (role_a 전용, 변경 불가 상태 차단)
- DELETE /api/v1/disputes/:id — 사건 소프트 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: AI 판결 요청·결과 조회 API 구현

- POST /api/v1/disputes/:id/judge — AI 판결 요청, JUDGING 상태 잠금으로 멱등성 보장
- GET /api/v1/disputes/:id/result — 판결 결과 조회 (참여자 전용)
- AI 모듈 미구현 구간은 TODO 주석으로 마킹, 완료 전까지 503 반환

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 공통 UI 컴포넌트 - StatusBadge, Tab, 진행 상태 (#33)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Prisma 클라이언트, NextAuth Kakao OAuth 설정 및 핸들러 추가

- src/lib/db/index.ts — Prisma 전역 싱글턴
- src/lib/auth/index.ts — NextAuth authOptions (Kakao OAuth, session user.id 매핑)
- src/app/api/auth/[...nextauth]/route.ts — NextAuth GET/POST 핸들러
- @mui/icons-material 패키지 설치 (빌드 에러 해결)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: 빌드 스크립트에 prisma generate 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: MVP 전체 API 명세서 작성 (API_SPEC.md) (#36)

* docs: MVP 전체 API 명세서 작성 (API_SPEC.md)

- 도메인 문서 및 기존 합의 기반 MVP API 명세 초안 작성
- 공통 응답 구조, 에러 코드 체계 정의
- Auth / User / Room / Dispute / Statement / Judgement / Diary / Calendar / Statistics / Gift / Cron 도메인 API 명세 포함
- 경로 충돌 항목 (withdraw, judge/result, diary 경로) 확정 필요 사항으로 명시
- 미확정 TODO 항목 섹션 7에 전체 정리
- MVP 제외 항목 (shop, points, 단독판결, 독립 통계 화면 등) 명시적으로 제거 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독 판결 MVP 포함 반영 및 라우트 주석 명확화

- 단독 판결(상대방 없는 AI 판결)을 MVP 포함 범위로 변경
- Personal Analysis 섹션에 단독 판결 API 초안 추가 (POST/GET /api/v1/personal-analyses)
- 라우트 트리 personal-analyses 디렉터리 구조 구체화
- /auth/withdraw route.ts 주석을 경로 충돌 상호 참조가 명확한 형태로 수정
  (경로 충돌 → /auth/withdraw vs DELETE /users/me)
- MVP 제외 목록에서 단독 판결 항목 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 카카오 로그인 시 약관 동의 자동 간주 정책 반영

- 카카오 OAuth 로그인 완료를 약관 동의로 간주
- 별도 약관 동의 페이지 이동 플로우 제거
- 확정 필요 항목에서 약관 동의 기준 항목 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 도메인 API 목록 중복 제거 및 회원탈퇴 경로 확정

- docs/domains/*.md 8개 파일의 API 목록 섹션을 docs/API_SPEC.md 참조로 교체
  (AUTH, USER, ROOM, DISPUTE, JUDGEMENT, DIARY, CALENDAR, STATISTICS)
- API_SPEC.md 단일 소스 체계 확립
- 회원탈퇴 경로 DELETE /api/v1/users/me 채택 확정
  - §3 요약표, §4.1·§4.2 상세, §5 라우트 트리, §6 충돌 목록, §7 체크리스트 반영
  - /auth/withdraw 라우트 제거, /users/me route.ts에 DELETE 추가
- CLAUDE_WORKFLOW.md PR 템플릿 준수 문구 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 날짜 포맷 및 Pagination 구조 확정 반영

- 날짜/시간 포맷 ISO 8601 (YYYY-MM-DDTHH:mm:ssZ) 확정
- Pagination 공통 구조 확정
  - data 필드: items 배열
  - page 필드: page / totalPages / sortBy / isNext
- 섹션 7 확정 필요 항목 두 개 체크 처리
- Room 목록, Diary 목록 섹션 Pagination 참조로 갱신

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: Pagination 구조에 size / sort / hasNext / hasPrevious 추가

- size: 한 번에 가져오는 항목 수
- sort: 정렬 방향 (asc | desc)
- isNext → hasNext로 변경 (다음 페이지 존재 여부)
- hasPrevious 추가 (이전 페이지 존재 여부)
- §7 체크리스트 항목 갱신

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 날짜 포맷 코드블록 언어 지정자 추가 (MD040)

코드래빗 지적 사항 반영 — 언어 미지정 펜스 코드블록에 text 지정자 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 통계 API 비로그인 공개 조회로 변경

홈 화면 진입 시 비로그인 회원도 통계 조회 가능하도록 수정
- GET /api/v1/statistics/summary: 🔒 → 공개
- GET /api/v1/statistics/top-types: 🔒 → 공개
- §3 요약표, §4.9 상세 명세 인증 표기 및 설명 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 목록 응답 예시에 page 객체 추가 (코드래빗 지적 반영)

- GET /api/v1/rooms 응답 예시에 page 객체 추가
- GET /api/v1/diary 응답 예시에 page 객체 추가
- GET /api/v1/statistics/top-types 응답 예시에 page 객체 추가
  (Top5 고정 목록 특성 반영: size=5, totalPages=1, hasNext=false)
- 코드래빗 제안의 구버전 필드(isNext) 대신 확정 구조(hasNext/hasPrevious/size/sort) 적용
- §7 Room Pagination 항목 체크 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Spinner, Avatar, AvatarGroup 공통 컴포넌트 추가 (#37)

* chore: 정적 이미지 에셋 추가 및 정리

주요 페이지용 캐릭터 이미지 추가 및 공통 에셋 정리.
gift, loading 캐릭터를 common에서 characters로 이동하여
캐릭터 이미지를 한 폴더로 통합.

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: Spinner 공통 컴포넌트 추가

캐릭터 로딩 이미지를 중앙에 배치한 88x88 스피너 컴포넌트 추가.
트랙(배경 원)과 애니메이션 링을 분리하여 각각 border-default, bg-brand 색상 적용.

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: Avatar, AvatarGroup 공통 컴포넌트 추가

MUI Avatar, AvatarGroup 래핑 컴포넌트 추가.
size prop으로 s/m/l 사이즈 조절, src prop으로 프로필 사진 지원.
global.scss에 --color-white, --color-black CSS 변수 추가.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: Avatar Context로 AvatarGroup size 전달 및 토큰 수정

AvatarGroup size prop이 자식 Avatar에 적용 안 되는 버그 수정.
Context를 통해 size를 내려주고 Avatar가 그룹 size를 우선 적용.
color 토큰 --color-white를 --text-inverse로 교체.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: Avatar src 없을 때 기본 썸네일 이미지로 fallback 처리

Co-Authored-By: Claude <noreply@anthropic.com>

* test: Spinner, Avatar, AvatarGroup 테스트 페이지 추가

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

* feat: 공통 UI 컴포넌트 - CategoryFilter, CategoryIcon, Tab, StatusBadge (#38)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 공통 컴포넌트 생성

- 전체/연애/직장/친구/가족 카테고리 필터 구현
- 아이콘 박스 44x44, border-radius 8, 아이콘 24x24
- 선택 상태: icon-primary bg / 미선택: bg-disabled
- MUI icons 사용 (GridViewRounded, Favorite, BusinessCenter, Diversity3, FamilyRestroom)
- Category 타입 export

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Tab 라벨 폰트 스타일 명시

- item.label을 span.label로 래핑
- Body-M 기준 font-size 16, line-height 28 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: @mui/icons-material 패키지 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 스타일 및 single 모드 적용

- 선택: bg-page + border-brand(1px) + icon-primary + 텍스트 bold
- 미선택: bg-page + border-default(1px) + icon-secondary + 텍스트 regular
- mode prop 추가 (filter 기본값 / single: 선택된 박스 하나만 표시)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 타입을 DB CategoryGroup 기준으로 통일

## 수정 배경

CategoryIcon, CategoryFilter가 한국어 문자열('연애', '직장' 등)을 타입으로 사용하고 있어
API/DB의 CategoryGroup('romance', 'work' 등)과 불일치가 발생.
페이지에서 연결 시 별도 변환 레이어가 필요해지는 문제를 사전 차단.

## 변경 파일별 수정 내용

### CategoryIcon.tsx
- CategoryWithoutAll 타입 제거 → @/types/common의 CategoryGroup 직접 사용
- 아이콘/레이블/컬러 맵 키를 한국어 → 영문 DB 값으로 변경
  (romance, work, friend, family)
- CATEGORY_LABEL_MAP export 추가 (CategoryFilter에서 레이블 참조용)

### CategoryFilter.tsx
- Category 타입을 'all' | CategoryGroup으로 변경 (기존: 한국어 문자열)
- CATEGORIES 배열에 label 필드 추가, CATEGORY_LABEL_MAP에서 참조
- 전체 키를 '전체' → 'all'로 변경 (API 필터 미적용 값과 일치)

### CaseCard.tsx (타팀원 파일 수정)
- 수정 이유: CATEGORY_EMOJI 맵 키가 대문자('ROMANCE')였으나
  API 응답은 소문자('romance')로 내려와 emoji가 항상 '📋' fallback만 표시되는 버그 존재
- 해결 방법: emoji 방식 전체 제거, CategoryIcon 컴포넌트로 교체
- categoryGroup prop 타입을 string → CategoryGroup으로 명시
- categoryGroup 미전달 시 아이콘 미표시 처리 (optional 유지)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update src/components/ui/CategoryIcon.tsx

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: CategoryIcon 중복 import 제거 및 CategoryFilter discriminated union 타입 에러 수정

- CategoryIcon: FamilyRestroomIcon, CategoryGroup 중복 import 제거
- CategoryFilter: discriminated union(CodeRabbit 피드백 반영) 유지하면서
  props 전체로 받아 props.mode로 narrowing 처리해 타입 에러 해결
  (mode='single'일 때 onChange가 CategoryGroup을 기대하는 문제)
- Tab.module.scss: height → min-height 변경 (유연한 높이 대응)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard 카테고리 아이콘을 제목 왼쪽 인라인으로 이동

- card__header 구조 변경: titleRow(아이콘+제목)와 badge를 좌우 배치
- card__titleRow 추가: flex row, align-items center, gap 6px
- 아이콘이 제목 위에 쌓이던 문제 수정 → 제목 왼쪽에 인라인 배치
- card__icon: font-size/line-height(이모지 잔재) → display:flex 로 변경
- card__title: margin-bottom 제거(card__header margin-bottom으로 대체)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 공통 컴포넌트 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard titleRow flex 축소 보완 (min-width: 0, flex: 1)

긴 제목에서 card__titleRow가 축소되지 않아 배지가 밀리는 문제 방지.
card__header가 space-between일 때 titleRow가 flex: 1로 가용 공간을 차지하고
min-width: 0으로 내부 콘텐츠가 넘치지 않도록 제약.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix(common): BottomNavigation 아이콘 MUI MD2 기본 스타일로 수정 (#39)

* fix(common): BottomNavigation 아이콘을 MUI MD2 기본 스타일로 수정

- HomeRounded → Home
- GavelRounded → MenuBook (사건기록 아이콘 자체 변경)
- CalendarMonthRounded → CalendarMonth
- PersonRounded → Person
디자인 시안 기준 MD2 filled 아이콘으로 통일

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: BottomNavigation 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): BottomNavigation 활성 탭 레이블 색상 black-700으로 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): BottomNavigation 테스트 스크린샷 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: wjdalss21 <jungxmin21@gmail.com>

* feat: 사건·방 도메인 타입 정의 및 API 구현 (#40)

* feat: room DTO 타입 정의

- RoomMode, RoomDto, CreateRoomRequest, RoomListResponse

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 방 목록 조회·생성·상세 조회·종료·삭제 API 구현

- GET  /api/v1/rooms — 내 방 목록 조회 (페이지네이션)
- POST /api/v1/rooms — AI 대화방 생성 (roomMode = ai_chat)
- GET  /api/v1/rooms/:id — 방 상세 조회
- POST /api/v1/rooms/:id/close — 방 종료 (closedAt + roomMode = closed)
- DELETE /api/v1/rooms/:id — 방 소프트 삭제 (deletedAt + roomMode = deleted)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 방 목록 페이지네이션 파라미터 NaN 방어 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: API 라우트 경로 v1 버전 세그먼트 제거 (#42)

* fix: API 라우트 경로에서 v1 버전 세그먼트 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 라우트 핸들러 주석 경로 v1 제거 (/api/v1/ -> /api/)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): 서비스 흐름 기반 문서 구조 수정 및 페이지 문서 생성 (#43)

* fix(docs): 서비스 흐름 기반 문서 구조 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): PAGES.md 코드 블록 언어 명시 추가 (MD040)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: personal-analyses 페이지 및 API 폴더 삭제 (#45)

* fix: personal-analyses 페이지 및 API 폴더 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): personal-analysis 도메인 참조 MD 문서 일괄 정리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 API 구현 (GET /api/statistics/categories) (#44)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 공통 컴포넌트 생성

- 전체/연애/직장/친구/가족 카테고리 필터 구현
- 아이콘 박스 44x44, border-radius 8, 아이콘 24x24
- 선택 상태: icon-primary bg / 미선택: bg-disabled
- MUI icons 사용 (GridViewRounded, Favorite, BusinessCenter, Diversity3, FamilyRestroom)
- Category 타입 export

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Tab 라벨 폰트 스타일 명시

- item.label을 span.label로 래핑
- Body-M 기준 font-size 16, line-height 28 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: @mui/icons-material 패키지 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 스타일 및 single 모드 적용

- 선택: bg-page + border-brand(1px) + icon-primary + 텍스트 bold
- 미선택: bg-page + border-default(1px) + icon-secondary + 텍스트 regular
- mode prop 추가 (filter 기본값 / single: 선택된 박스 하나만 표시)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 타입을 DB CategoryGroup 기준으로 통일

## 수정 배경

CategoryIcon, CategoryFilter가 한국어 문자열('연애', '직장' 등)을 타입으로 사용하고 있어
API/DB의 CategoryGroup('romance', 'work' 등)과 불일치가 발생.
페이지에서 연결 시 별도 변환 레이어가 필요해지는 문제를 사전 차단.

## 변경 파일별 수정 내용

### CategoryIcon.tsx
- CategoryWithoutAll 타입 제거 → @/types/common의 CategoryGroup 직접 사용
- 아이콘/레이블/컬러 맵 키를 한국어 → 영문 DB 값으로 변경
  (romance, work, friend, family)
- CATEGORY_LABEL_MAP export 추가 (CategoryFilter에서 레이블 참조용)

### CategoryFilter.tsx
- Category 타입을 'all' | CategoryGroup으로 변경 (기존: 한국어 문자열)
- CATEGORIES 배열에 label 필드 추가, CATEGORY_LABEL_MAP에서 참조
- 전체 키를 '전체' → 'all'로 변경 (API 필터 미적용 값과 일치)

### CaseCard.tsx (타팀원 파일 수정)
- 수정 이유: CATEGORY_EMOJI 맵 키가 대문자('ROMANCE')였으나
  API 응답은 소문자('romance')로 내려와 emoji가 항상 '📋' fallback만 표시되는 버그 존재
- 해결 방법: emoji 방식 전체 제거, CategoryIcon 컴포넌트로 교체
- categoryGroup prop 타입을 string → CategoryGroup으로 명시
- categoryGroup 미전달 시 아이콘 미표시 처리 (optional 유지)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update src/components/ui/CategoryIcon.tsx

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: CategoryIcon 중복 import 제거 및 CategoryFilter discriminated union 타입 에러 수정

- CategoryIcon: FamilyRestroomIcon, CategoryGroup 중복 import 제거
- CategoryFilter: discriminated union(CodeRabbit 피드백 반영) 유지하면서
  props 전체로 받아 props.mode로 narrowing 처리해 타입 에러 해결
  (mode='single'일 때 onChange가 CategoryGroup을 기대하는 문제)
- Tab.module.scss: height → min-height 변경 (유연한 높이 대응)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard 카테고리 아이콘을 제목 왼쪽 인라인으로 이동

- card__header 구조 변경: titleRow(아이콘+제목)와 badge를 좌우 배치
- card__titleRow 추가: flex row, align-items center, gap 6px
- 아이콘이 제목 위에 쌓이던 문제 수정 → 제목 왼쪽에 인라인 배치
- card__icon: font-size/line-height(이모지 잔재) → display:flex 로 변경
- card__title: margin-bottom 제거(card__header margin-bottom으로 대체)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 공통 컴포넌트 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard titleRow flex 축소 보완 (min-width: 0, flex: 1)

긴 제목에서 card__titleRow가 축소되지 않아 배지가 밀리는 문제 방지.
card__header가 space-between일 때 titleRow가 flex: 1로 가용 공간을 차지하고
min-width: 0으로 내부 콘텐츠가 넘치지 않도록 제약.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 도메인 서비스 레이어 생성 (statisticsService.ts)

## 생성 이유
통계 API의 DB 쿼리 로직을 Route Handler와 분리하기 위해
도메인 서비스 레이어를 별도 파일로 작성했다.

## 폴더 선택 이유
src/domains/statistics/
- CLAUDE.md §4 아키텍처 원칙에 따라 도메인별 비즈니스 로직은
  src/domains/{domain}/ 에 위치한다.
- statistics는 MVP 도메인 목록에 포함된 독립 도메인이다.
- Route Handler(src/app/api/)는 요청/응답 처리만 담당하고,
  실제 DB 쿼리 로직은 서비스 레이어에서 관리한다.

## 구현 내용

### getSummary()
- 서비스 전체 판결 완료 건수(totalJudgements) 집계
- dispute.status = JUDGED 조건 명시: ai_judgements는 판결 완료 시에만
  생성되지만 의도를 코드에 명시적으로 표현
- deletedAt / anonymizedAt IS NULL: 삭제·익명화된 사건 제외 (CLAUDE.md §7)

### getTopTypes(size = 5)
- ai_judgements.result_conflict_detail_id 기준 GROUP BY COUNT DESC
- 결과 유형 마스터(conflict_type_details)를 JOIN해 detailCode·displayName 반환
- isActive = true 필터: 비활성화된 유형은 통계에서 제외
- percentage 서버 계산: count / total * 100 (소수점 1자리)
  FE에서 별도 계산 없이 바로 사용할 수 있도록 서버에서 내려줌
- prisma.conflictTypeDetail 사용 (prisma.conflictDetail은 스키마에 존재하지 않음)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 API Route Handler 생성 (GET /api/v1/statistics/top-types)

## 생성 이유
statisticsService의 getTopTypes()를 HTTP 엔드포인트로 노출하기 위해
Next.js App Router 기반 Route Handler를 생성했다.

## 폴더 선택 이유
src/app/api/v1/statistics/top-types/
- CLAUDE.md §4 아키텍처 원칙에 따라 API Route는 src/app/api/v1/ 하위에 위치한다.
- API_SPEC.md §4.9 기준 엔드포인트 경로: GET /api/v1/statistics/top-types
- summary 엔드포인트는 현재 MVP 범위에서 불필요하여 top-types만 생성

## 구현 내용
- getServerSession으로 서버에서 직접 세션 검증
  (FE 리다이렉트만으로는 API 직접 호출을 막을 수 없으므로 서버 검증 필수 — CLAUDE.md §7)
- 인증 실패 시 401 UNAUTHORIZED 반환
- getTopTypes(5) 호출 → 판결 완료 기준 Top5 유형 + 비율 반환
- ApiResponse 타입 준수: data/error는 null 아닌 undefined(optional) 사용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: statistics top-types 인증 제거 (메인 페이지 공개 접근 허용)

메인 페이지에서도 통계 차트가 노출되는 익명 집계 데이터이므로
세션 없이 접근 가능하도록 수정.

- getServerSession 및 관련 import 제거
- 401 인증 체크 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: statistics top-types 에러 핸들링 보완

코드래빗 피드백 반영:
- catch {} -> catch (error): 에러 정보 유실 방지
- 타임아웃 감지 후 504 분기 처리
- console.error 로깅 추가 (CLAUDE.md 11 API 오류 로그 대상)
- 세션 체크는 이전 커밋에서 이미 제거됨 (공개 엔드포인트)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: 통계 API 카테고리 기준으로 재설계

- 결과 유형(top-types) → 작성 카테고리(ROMANCE/FAMILY/FRIEND/WORK) 기준으로 변경
- route.ts에 DB 쿼리 직접 작성, statisticsService.ts 제거
- 비율 계산은 프론트 훅(useStatistics)에서 담당
- revalidate = 86400 (하루 1회 재계산)
- src/hooks/ 폴더 신설 및 useStatistics.ts 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 통계 API 서버 측 세션 인증 추가

- GET /api/statistics/categories 진입 시 getServerSession으로 인증 검증
- 미인증 요청 401 UNAUTHORIZED 반환

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* feat: Header variant 분리 (logo/title) 및 홈 화면 적용 (#47)

* feat: 홈 화면 기본 구조 생성 (헤더, 일기 박스)

- 헤더: 세션 유저명 + character-welcome.png 부엉이 이미지
- 일기 박스: 365x88, border black-700 2px, bg primary-100
- TODO: GangwonEduPower 폰트 추가 후 헤더 로고 텍스트 적용 필요

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Header variant 분리 (logo/title) 및 홈 화면 적용

- Header.tsx에 variant prop 추가 (logo | title)
  - logo: 좌측 상단 말해부엉 로고 표시 (66x19, h:56, padding: 16px 20px)
  - title: 기존 뒤로가기 + 페이지 제목 형태 유지
- Header.module.scss에 __logo 스타일 추가
- home/page.tsx에 Header variant='logo' 적용
  - 헤더를 컨테이너 padding 밖으로 분리하여 상단 여백 제거
- home/page.module.scss diaryBox에 align-self: center 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건기록 페이지 생성 및 로고 헤더 적용 (/records)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: diaryBox 고정 폭을 max-width + width 100%로 반응형 처리

- width: 365px → width: 100% + max-width: 365px
- 작은 화면에서 좌우 패딩과 결합 시 오버플로우 방지

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 감정일기 작성 버튼 /diary/new 네비게이션 연결

- 일기 박스 전체를 Link로 변경 (텍스트 + 버튼 모두 클릭 가능)
- diaryBox에 text-decoration: none, cursor: pointer 추가
- /diary/new 경로는 임시 지정 (담당자 확인 후 수정 예정)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면 캐릭터 이미지 교체 및 위치 조정

- character-welcome.png → character-home.png 교체 (169x138)
- 캐릭터 절대 위치 적용 (top: 41px, right: -20px)
- 캐릭터가 일기 박스 뒤에 위치하도록 z-index 조정 (character: 0, container: 1)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 홈 화면 코드래빗 피드백 반영

- 캐릭터 이미지 가로 스크롤 방지: .page에 overflow-x: hidden 추가
- 비로그인 사용자 분기 처리: 말해부엉 알아보기 박스 추가 (/login 이동)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: 홈 화면 typography 믹신 적용

- greetingText, diaryTitle, diarySubtitle에 typography 믹신 사용
- 개별 font 속성 직접 선언 → @include m.text-* 토큰으로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 비로그인 알아보기 박스 위치 수정

- 인사/일기 박스는 로그인 여부 무관하게 항상 표시
- 말해부엉 알아보기 박스를 진행중인 사건 위치(구분선 아래)로 이동
- 비로그인 인사: '안녕하세요' 표시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면에 통계 섹션 및 구분선 통합

- StatsCategorySection, useStatistics, QueryProvider 병합
- 고민 카테고리 TOP4 통계 섹션 추가
- 통계 섹션 하단 구분선 추가 (h:8px, black-100, gap:42px)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: 개발 편의용 로그인 상태 강제 설정 (배포 전 제거 필요)

- isLoggedIn = true 하드코딩으로 로그인 상태 유지
- TODO 주석으로 배포 전 제거 안내 표시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건작성 페이지 구현 (disputes/[id]/statement) (#46)

* feat: 사건작성 페이지 구현 (disputes/[id]/statement)

- 사건 카테고리 선택 (연애/직장/친구/가족)
- MBTI 선택 드롭다운
- 진술 내용 입력 (최대 1000자)
- 진술저장 버튼 (내용 입력 시 활성화)
- TODO: 진술 저장 API 연결

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 사건작성 페이지 카테고리/간격/드롭다운 수정

- 카테고리를 searchParams에서 읽어 하나만 표시 (비상호작용)
- 카테고리 없을 시 모달 표시 후 이전 페이지로 이동
- Select/Textarea 사이 간격 8px (statementGroup)
- label/Select 사이 간격 16px 유지
- Textarea placeholder 줄바꿈 적용 (\n)
- content overflow-y 제거 → Select 드롭다운 아래 방향 열림 수정
- Select placeholder 색상 var(--text-secondary) 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 없음 모달에서 버튼 제거 — 페이지 블로킹만 유지

확인 버튼 클릭 시 이동하지 않고 Header 뒤로가기로만 탈출 가능

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 기본값 romance 적용, 모달 확인 버튼 복원

- searchParams에 카테고리 없을 시 임시로 romance 기본값 사용
- 모달 확인 버튼 클릭 시 router.back() 복원
- TODO: 이전 페이지 카테고리 데이터 연동 후 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 커스텀 드롭다운 교체 및 Textarea focus 스타일 제거

- Select: 네이티브 select → 커스텀 드롭다운 (항상 아래 방향 열림)
- Select: placeholder 색상 --text-secondary 적용 (option 색 영향 없음)
- Select: 아이콘 회전 애니메이션 추가
- Textarea: focus 시 border-color 변경 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: Button 좌우 패딩 16 → 12으로 조정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: SCSS import 상대경로 → 절대경로(@/) 변환 및 컨벤션 문서 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 접근성 및 스타일 개선

- ul 기본 margin 리셋
- hasValue를 options.find 기준으로 판단 (빈 문자열 오인 방지)
- aria-invalid / aria-describedby 연결로 보조기기 지원
- 키보드 내비게이션 추가 (ArrowUp/Down, Enter/Space, Escape)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: dispute 생성 조건을 active room 전체로 완화 (ONE_TO_ONE 제한 제거)

혼자서도 판결 가능한 흐름을 지원하기 위해
room.roomMode !== 'ONE_TO_ONE' 체크를 제거하고
CLOSED/EXPIRED 방만 차단하도록 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select id 안정화, 빈 options 가드, Tab 기본 포커스 이동 허용

- resolvedId를 label 문자열 대신 useId() 기반으로 고정
- option id를 value 대신 index 기반으로 변경
- Enter/Space 시 options 길이 가드 추가 (크래시 방지)
- Tab은 preventDefault 제거 — 닫기만 하고 포커스 이동은 브라우저에 위임

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독 판결 MVP 포함 및 관련 정책 업데이트 (#51)

- Section 1: 단독 판결 / 1:1 판결 흐름 분리 명시
- Section 2: 단독 판결을 MVP 포함으로 이동, MVP 제외에서 제거
- Section 3: AI 대화방 정책 수정 (ai_chat/invite_ready 상태 단독 판결 허용)
- Section 3: 단독 판결 vs 1:1 판결 제공 결과 비교 섹션 추가
- Section 14: 단독 판결 관련 STOP Condition 항목 제거

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Feature/verdict record display - 캘린더 페이지 ui 제작  (#41)

* feat : 다이어리 (감정일기 , 사건기록)탭분리

* feat : 달력 ui 커스텀 추가 및 감정일기 사건기록 분기처리

* refactor:  및 캘린더 페이지구조 개선 (리뷰 피드백 반영)

* feat : 감정일기카드 컴포넌트 구현

* fix: build 에러 ( 임시 페이지 )

* refactor: 감정일기 컴포넌트 SCSS 모듈 적용 및 믹스인 토큰 사용

* feat: 달력 페이지 UI 구현 및 스타일 정리

- MUI DateCalendar 커스텀
- 감정일기 / 사건기록 탭 전환 구조 구현
- EmotionDiaryList, RecordList 빈 상태 UI 추가
- DiaryCard mixin 적용 (text-title-s, text-body-s, text-label-s)
- 인라인 style 제거 → SCSS 모듈로 분리
- outsideCurrentMonth 감정 아이콘 노출 차단
- 새 일기 FAB 버튼 추가 (감정일기 탭 전용)
- 불필요한 파일 삭제 (DiaryMode, EmotionDiaryCard 등)

* style : EmotionDiaryList.moulde 스타일 수정

* feat: 달력 RecordList에 CaseCard 연동 및 스타일 개선

* Update model name from 'gpt-5.5' to 'gemini-2.5-flash'

seed.ts Ai modelName 수정

---------

Co-authored-by: 배근영 <bgy09270@naver.com>

* feat: 사건작성(진술서) 페이지 구현 및 욕설 감지 필터 연동 (#49)

* feat: 사건작성 페이지 구현 (disputes/[id]/statement)

- 사건 카테고리 선택 (연애/직장/친구/가족)
- MBTI 선택 드롭다운
- 진술 내용 입력 (최대 1000자)
- 진술저장 버튼 (내용 입력 시 활성화)
- TODO: 진술 저장 API 연결

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 사건작성 페이지 카테고리/간격/드롭다운 수정

- 카테고리를 searchParams에서 읽어 하나만 표시 (비상호작용)
- 카테고리 없을 시 모달 표시 후 이전 페이지로 이동
- Select/Textarea 사이 간격 8px (statementGroup)
- label/Select 사이 간격 16px 유지
- Textarea placeholder 줄바꿈 적용 (\n)
- content overflow-y 제거 → Select 드롭다운 아래 방향 열림 수정
- Select placeholder 색상 var(--text-secondary) 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 없음 모달에서 버튼 제거 — 페이지 블로킹만 유지

확인 버튼 클릭 시 이동하지 않고 Header 뒤로가기로만 탈출 가능

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 기본값 romance 적용, 모달 확인 버튼 복원

- searchParams에 카테고리 없을 시 임시로 romance 기본값 사용
- 모달 확인 버튼 클릭 시 router.back() 복원
- TODO: 이전 페이지 카테고리 데이터 연동 후 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 커스텀 드롭다운 교체 및 Textarea focus 스타일 제거

- Select: 네이티브 select → 커스텀 드롭다운 (항상 아래 방향 열림)
- Select: placeholder 색상 --text-secondary 적용 (option 색 영향 없음)
- Select: 아이콘 회전 애니메이션 추가
- Textarea: focus 시 border-color 변경 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: Button 좌우 패딩 16 → 12으로 조정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: SCSS import 상대경로 → 절대경로(@/) 변환 및 컨벤션 문서 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 접근성 및 스타일 개선

- ul 기본 margin 리셋
- hasValue를 options.find 기준으로 판단 (빈 문자열 오인 방지)
- aria-invalid / aria-describedby 연결로 보조기기 지원
- 키보드 내비게이션 추가 (ArrowUp/Down, Enter/Space, Escape)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: dispute 생성 조건을 active room 전체로 완화 (ONE_TO_ONE 제한 제거)

혼자서도 판결 가능한 흐름을 지원하기 위해
room.roomMode !== 'ONE_TO_ONE' 체크를 제거하고
CLOSED/EXPIRED 방만 차단하도록 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select id 안정화, 빈 options 가드, Tab 기본 포커스 이동 허용

- resolvedId를 label 문자열 대신 useId() 기반으로 고정
- option id를 value 대신 index 기반으로 변경
- Enter/Space 시 options 길이 가드 추가 (크래시 방지)
- Tab은 preventDefault 제거 — 닫기만 하고 포커스 이동은 브라우저에 위임

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Textarea 바이트 카운팅 및 filterMessage prop 추가

- 한글 2바이트/ASCII 1바이트 기준으로 글자 수 계산
- maxLength 초과 시 바이트 기준으로 자동 truncate
- filterMessage prop 추가 — 욕설 차단 메시지 동적 표시
- border 색상 변경은 error prop에만 적용 (filter는 border 유지)
- filter-warning 텍스트: Body-S + var(--text-danger)
- field gap 8 → 10px (Figma 기준)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 욕설 감지 필터 구현 (Gemini 2.5 Flash)

- moderation.ts: Gemini 2.5 Flash 기반 욕설/개인정보 감지
  - isBlocked: 욕설·혐오·위협 차단 (보수적 기준)
  - hasPersonalInfo: 개인정보 경고 (차단 없음)
  - fail-open: Gemini 실패 시 pending 상태로 저장
- statements/route.ts: 진술 저장 API
  - 모더레이션 통과 후 upsert + ModerationLog 트랜잭션
  - 차단 시 ModerationLog만 기록, 저장 없이 422 반환
  - dev bypass: 개발 환경에서 세션 없이 모더레이션 테스트 가능
- page.tsx: handleSave 연결, filterMessage 상태, 개인정보 경고 모달
- StatementPage.module.scss: 모달 스타일, Stylelint 공백 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: PR #49 코드리뷰 수정 — MBTI 연동, 파싱 에러, 인젝션, 타임아웃

- MBTI: GET /api/user/me 신규 생성, statement 페이지 마운트 시 user.mbti 초기화
- MBTI: handleSave body에 mbti 포함, statements route에서 user.mbti 업데이트 (트랜잭션)
- statement/page.tsx: res.json() 파싱 실패를 별도 try-catch로 분리
- Textarea.tsx: e.target.value 직접 변경 → Object.assign으로 새 이벤트 객체 전달
- moderation.ts: content 삽입 전 < > HTML 이스케이프 (프롬프트 인젝션 방지)
- moderation.ts: Promise.race() 기반 10초 타임아웃 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: user/me route catch 블록에 에러 로깅 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: judge route 1인 판결 허용 — isSolo 분기 및 rollback 상태 수정

- 2인: BOTH_SUBMITTED 상태 확인 유지
- 1인: 진술 제출 여부만 확인 (statements.length > 0)
- 롤백 대상을 하드코딩된 BOTH_SUBMITTED → previousStatus로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 카카오 로그인 기능 구현 (#50)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 absolute 배치

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 카카오 로그인 기능 구현

- 로그인 페이지 UI 및 카카오 signIn 버튼 연결
- @auth/prisma-adapter 설치 및 authOptions에 적용
- 최초 로그인 시 kakaoId, nickname, termsAgreedAt 자동 설정
- 닉네임 자동 생성 유틸 추가 (~하는부엉이 + 4자리 난수)
- middleware 추가: 비인증 사용자 /login 리다이렉트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 로그인 페이지 및 인증 로직 개선

- SCSS import 절대경로(@/) 수정
- 캐릭터 이미지 Next/Image fill → img 태그로 변경
- 이용약관/개인정보처리방침 링크(/terms, /privacy) 추가 및 스타일 적용
- 닉네임 유니크 제약(@unique) 추가 및 충돌 재시도 로직 구현 (최대 10회)
- middleware matcher 패턴 보완 (/login-help 등 우회 경로 차단)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: disclaimer mixin 적용, nickname 유실 복구 및 fallback 랜덤화

- .disclaimer에 @include m.text-caption mixin 적용
- 유실된 nickname.ts 복구
- fallback 닉네임 Date.now() → 랜덤 8자리 숫자로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독/1:1 판결 공통 진입 흐름 반영 및 관련 문서 일괄 수정 (#54)

- 단독 판결과 1:1 판결이 완전히 분리된 진입이 아니라
  AI 대화방 → 진술저장 → [분기] → disputes/[id]/statement 경로를 공통으로 거침
- CLAUDE.md: 핵심 서비스 흐름 분기 구조로 수정, 단독 판결 MVP 포함 반영,
  AI 대화방 정책 단독/1:1 병행 기술, dispute_status 단독 경로 추가
- PROJECT_DECISIONS.md: 흐름·MVP포함·MVP제외·dispute_status 동기화
- STATUS_TRANSITION.md: 단독 판결 경로(draft→judging→judged) 추가
- DISPUTE.md: 상태 전이 단독/1:1 경로 분리 기술, 주의사항 확정 내용 반영
- ROOM.md: 진술저장 후 분기 흐름 포함 기능에 명시

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Login 페이지 hydration removeChild 에러 수정 (#55)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- …
evenif99 added a commit that referenced this pull request Jun 22, 2026
* chore: initialize project folder structure (#1)

* chore: initialize project folder structure

- Add base directory layout for Next.js + domain-driven architecture
- Add .gitkeep to track empty directories in git
- Exclude MVP out-of-scope domains (shop, points, user-items)
- No implementation files included, structure only

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update README.md

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add CLAUDE.md with project rules and work guidelines (#2)

- Add project overview and MVP scope definition
- Add fixed product rules (categories, AI chat policy, judgement output)
- Add architecture, domain scope, and state transition rules
- Add auth/security, DB, frontend state, API, logging rules
- Add Git workflow, Claude work process, STOP conditions
- Add approval-required list and required reference documents

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: setup project config and install dependencies (#3)

- Add package.json with Next.js 15, React 19, TypeScript stack
- Add next.config.ts (minimal Next.js 15 config)
- Add tsconfig.json (strict mode, @/* path alias)
- Add eslint.config.mjs (next/core-web-vitals + next/typescript)
- Add .prettierrc and .prettierignore
- Add .gitignore (node_modules, .next, .env.local, etc.)
- Add .env.example (key names only, no real values)
- Add prisma/schema.prisma (generator + datasource only)
- Add data/mock/db.json (health check stub for json-server)
- Add docs/TECH_STACK.md (package list and selection rationale)
- Update README.md with run commands and env guide

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add base documentation structure (#4)

- Add PROJECT_DECISIONS.md (MVP scope, architecture, security principles)
- Add guides/CLAUDE_WORKFLOW.md (work process, STOP conditions, approval rules)
- Add guides/GIT_WORKFLOW.md (branch naming, commit convention, workflow)
- Add guides/PR_RULES.md (PR target, title rules, review criteria)
- Add guides/ENV_GUIDE.md (Vercel env pull, .env.example management)
- Add guides/CODING_CONVENTION.md (naming, state management, folder rules)
- Add db/STATUS_TRANSITION.md (room_mode, dispute_status transitions)
- Add db/PRISMA_MAPPING.md (snake_case/camelCase mapping rules)
- Add db/MASTER_DATA.md (categories, result types, DB master principles)
- Add domains/README.md (domain list, MVP scope, writing guidelines)
- Add domains/_DOMAIN_TEMPLATE.md (template for domain docs)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add domain document drafts for all MVP domains (#5)

- Add AUTH.md (kakao login, terms, session management)
- Add COMMON.md (error handling, logging, common response)
- Add ROOM.md (AI chat room, invite link, room_mode transitions)
- Add PERSONAL_ANALYSIS.md (AI-based personal conflict analysis)
- Add DISPUTE.md (1:1 mediation, roles, statements, dispute_status)
- Add JUDGEMENT.md (AI judgement, Gemini API, result card)
- Add GIFT.md (gift recommendation after judgement)
- Add USER.md (mypage, profile, bottom tab)
- Add CALENDAR.md (date-based record marking, monthly summary)
- Add DIARY.md (emotion diary, author-only access, content protection)
- Add STATISTICS.md (anonymous aggregation, summary components)
- Add SHOP_FUTURE.md (v2.0 planned, MVP excluded)
- Add POINTS_FUTURE.md (v2.0 planned, MVP excluded)
- Add USER_ITEMS_FUTURE.md (v2.0 planned, MVP excluded)

All documents are draft templates with TODO markers for assignees.
No implementation, no API routes, no schema changes.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: add Next.js App Router entry files and SCSS base structure (#6)

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Infra/init next setup (#7)

* infra: add Next.js App Router entry files and SCSS base structure

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: resolve ESLint and TypeScript config warnings

- eslint.config.mjs: ignore next-env.d.ts and .next/** (auto-generated by Next.js, triple-slash reference false positive)
- tsconfig.json: remove deprecated baseUrl option (TypeScript 5.x+, paths works without baseUrl)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update README.md (#8)

* docs(infra): confirm Supabase as project infrastructure (#9)

* chore(github): add collaboration templates and policy (#10)

* docs(env): document environment variable management (#11)

* docs(calendar): confirm MUI date picker usage (#12)

달력 UI 라이브러리로 MUI X Date Pickers + Day.js 사용을 확정하고
관련 문서(TECH_STACK, PROJECT_DECISIONS, CODING_CONVENTION, CALENDAR, DIARY, CLAUDE.md)에 반영한다.

* chore(deps): install MUI X Date Pickers and peer dependencies (#13)

달력 UI 구현을 위해 MUI X Date Pickers 및 필수 peer dependency를 설치한다.
@mui/material@9.1.1, @emotion/react@11.14.0, @emotion/styled@11.14.1,
@mui/x-date-pickers@9.5.0, dayjs@1.11.21

* Update README.md (#15)

* fix: resolve ESLint and TypeScript config warnings (#20)

* infra: add Next.js App Router entry files and SCSS base structure

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: resolve ESLint and TypeScript config warnings

- eslint.config.mjs: ignore next-env.d.ts and .next/** (auto-generated by Next.js, triple-slash reference false positive)
- tsconfig.json: remove deprecated baseUrl option (TypeScript 5.x+, paths works without baseUrl)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: add MVP Prisma schema with NextAuth and TALKY-OWL models (#21)

- datasource: add directUrl for Supabase connection pooler support
- enums: CategoryGroup, RoomMode, DisputeStatus, ParticipantRole, etc.
- NextAuth models: User (with TALKY-OWL fields), Account, Session, VerificationToken
- core models: DisputeRoom, RoomAiConversation, RoomAiMessage
- dispute models: Dispute, DisputeParticipant, DisputeStatement
- judgment models: AiJudgment, JudgmentResultCard
- gift models: GiftRecommendation, GiftRecommendationItem
- feature models: EmotionDiary, CalendarRecord
- master data: ConflictTypeGroup, ConflictTypeDetail (DB-based, no enum hardcoding)
- log models: AuditLog, ApiErrorLog, ModerationLog, RoomAccessLog, UserDeletionLog
- .env.example: add DIRECT_URL for Supabase directUrl
- v2.0 TODO: ShopItem, PointTransaction, UserItem, DisputeStatistic excluded

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: align project structure with guide v2 (#22)

folders added:
- src/components/{personal-analysis,room,dispute,judgement,calendar,diary,statistics,gift}
- src/app/api/auth/[...nextauth]
- src/app/api/v1/{users,personal-analyses,rooms,disputes,statements,calendar,diary,statistics,cron}

files added:
- prisma/seed.ts (placeholder for ConflictTypeGroup master data)

docs updated (minimal):
- docs/domains/COMMON.md: add log table list, judgement_logs TODO note
- docs/domains/JUDGEMENT.md: clarify Storage is MVP-excluded scaffolding
- docs/guides/ENV_GUIDE.md: clarify Supabase Storage vars are MVP-excluded

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: rename src/app/page to src/app/(page) for correct Next.js route group (#23)

src/app/page/ (괄호 없음)는 /page/* URL segment를 생성하므로,
Next.js App Router route group 문법인 src/app/(page)/로 변경한다.
URL은 /landing, /home 등으로 노출되어야 하며 /page/... 가 아니다.

관련 문서 내 경로 참조도 모두 업데이트 (CLAUDE.md, docs/domains/*, docs/guides/*).

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* [Style] 디자인 토큰 및 전역 스타일 설정 (#25)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 디자인 시스템 기반 설정 (#27)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: rem 스케일 토큰 추가 및 타이포그래피 변수 rem 참조로 전환

- Rem scale 섹션 추가 (0.25rem ~ 30rem)
- 폰트 토큰에서 누락된 0.875rem(14px), 1.125rem(18px) 추가
- font-size, line-height 변수를 rem 스케일 변수 참조로 전환
- rem 스케일을 typography 섹션보다 상단으로 이동 (선언 순서)
- 컴포넌트 width/height 대응을 위해 큰 단위(9rem~30rem) 포함

Co-Authored-By: Claude <noreply@anthropic.com>

* style: r() 함수 분리 및 타이포그래피 변수 함수 기반으로 전환

- _functions.scss 신규 추가 — px → rem 변환 함수 r() 단독 관리
- _variables.scss에서 rem 스케일 변수 제거, fn.r() 참조로 전환
- _mixins.scss에 functions @use 추가
- 순환 참조 없이 variables → functions → (없음) 단방향 의존성 구성

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Feature/common component jw (#28)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* fix: :root {} 시맨틱 토큰을 _global.scss로 분리 (#29)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: rem 스케일 토큰 추가 및 타이포그래피 변수 rem 참조로 전환

- Rem scale 섹션 추가 (0.25rem ~ 30rem)
- 폰트 토큰에서 누락된 0.875rem(14px), 1.125rem(18px) 추가
- font-size, line-height 변수를 rem 스케일 변수 참조로 전환
- rem 스케일을 typography 섹션보다 상단으로 이동 (선언 순서)
- 컴포넌트 width/height 대응을 위해 큰 단위(9rem~30rem) 포함

Co-Authored-By: Claude <noreply@anthropic.com>

* style: r() 함수 분리 및 타이포그래피 변수 함수 기반으로 전환

- _functions.scss 신규 추가 — px → rem 변환 함수 r() 단독 관리
- _variables.scss에서 rem 스케일 변수 제거, fn.r() 참조로 전환
- _mixins.scss에 functions @use 추가
- 순환 참조 없이 variables → functions → (없음) 단방향 의존성 구성

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: :root {} 시맨틱 토큰을 _global.scss로 분리

_variables.scss에 :root {}가 있으면 module.scss에서 @use 시
CSS Modules 'not pure' 에러 발생.
SCSS 변수는 _variables.scss, CSS 출력은 _global.scss로 분리.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): 공통 UI 컴포넌트 추가 및 MUI 정책 적용 (#30)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 목록 공통 UI 컴포넌트 추가 (Tab, StatusBadge) (#31)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 위치 수정 (#32)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 absolute 배치

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 공통 및 dispute·judgment DTO 타입 정의

- ApiResponse, ApiError, ApiFieldError, CategoryGroup (common.ts)
- DisputeDto, CreateDisputeRequest, DisputeListResponse 등 (dispute.ts)
- AiJudgmentDto, CreateAiJudgmentRequest 등 (judgment.ts)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: dispute 도메인 공유 상수·헬퍼·mapper 추가

- VALID_CATEGORY_GROUPS, IMMUTABLE_DISPUTE_STATUSES 상수 (constants/dispute.ts)
- getSessionUserId NextAuth 세션 헬퍼 (auth/session.ts)
- toAiJudgmentDto 공유 mapper (judgement/judgment.mapper.ts)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 목록 조회·생성·수정·삭제 API 구현

- GET /api/v1/disputes — 참여 사건 목록, categoryGroup 필터, 페이지네이션
- POST /api/v1/disputes — 사건 생성 + role_a 참여자 트랜잭션 등록
- GET /api/v1/disputes/:id — 사건 상세 조회
- PATCH /api/v1/disputes/:id — 사건 수정 (role_a 전용, 변경 불가 상태 차단)
- DELETE /api/v1/disputes/:id — 사건 소프트 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: AI 판결 요청·결과 조회 API 구현

- POST /api/v1/disputes/:id/judge — AI 판결 요청, JUDGING 상태 잠금으로 멱등성 보장
- GET /api/v1/disputes/:id/result — 판결 결과 조회 (참여자 전용)
- AI 모듈 미구현 구간은 TODO 주석으로 마킹, 완료 전까지 503 반환

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 공통 UI 컴포넌트 - StatusBadge, Tab, 진행 상태 (#33)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Prisma 클라이언트, NextAuth Kakao OAuth 설정 및 핸들러 추가

- src/lib/db/index.ts — Prisma 전역 싱글턴
- src/lib/auth/index.ts — NextAuth authOptions (Kakao OAuth, session user.id 매핑)
- src/app/api/auth/[...nextauth]/route.ts — NextAuth GET/POST 핸들러
- @mui/icons-material 패키지 설치 (빌드 에러 해결)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: 빌드 스크립트에 prisma generate 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: MVP 전체 API 명세서 작성 (API_SPEC.md) (#36)

* docs: MVP 전체 API 명세서 작성 (API_SPEC.md)

- 도메인 문서 및 기존 합의 기반 MVP API 명세 초안 작성
- 공통 응답 구조, 에러 코드 체계 정의
- Auth / User / Room / Dispute / Statement / Judgement / Diary / Calendar / Statistics / Gift / Cron 도메인 API 명세 포함
- 경로 충돌 항목 (withdraw, judge/result, diary 경로) 확정 필요 사항으로 명시
- 미확정 TODO 항목 섹션 7에 전체 정리
- MVP 제외 항목 (shop, points, 단독판결, 독립 통계 화면 등) 명시적으로 제거 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독 판결 MVP 포함 반영 및 라우트 주석 명확화

- 단독 판결(상대방 없는 AI 판결)을 MVP 포함 범위로 변경
- Personal Analysis 섹션에 단독 판결 API 초안 추가 (POST/GET /api/v1/personal-analyses)
- 라우트 트리 personal-analyses 디렉터리 구조 구체화
- /auth/withdraw route.ts 주석을 경로 충돌 상호 참조가 명확한 형태로 수정
  (경로 충돌 → /auth/withdraw vs DELETE /users/me)
- MVP 제외 목록에서 단독 판결 항목 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 카카오 로그인 시 약관 동의 자동 간주 정책 반영

- 카카오 OAuth 로그인 완료를 약관 동의로 간주
- 별도 약관 동의 페이지 이동 플로우 제거
- 확정 필요 항목에서 약관 동의 기준 항목 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 도메인 API 목록 중복 제거 및 회원탈퇴 경로 확정

- docs/domains/*.md 8개 파일의 API 목록 섹션을 docs/API_SPEC.md 참조로 교체
  (AUTH, USER, ROOM, DISPUTE, JUDGEMENT, DIARY, CALENDAR, STATISTICS)
- API_SPEC.md 단일 소스 체계 확립
- 회원탈퇴 경로 DELETE /api/v1/users/me 채택 확정
  - §3 요약표, §4.1·§4.2 상세, §5 라우트 트리, §6 충돌 목록, §7 체크리스트 반영
  - /auth/withdraw 라우트 제거, /users/me route.ts에 DELETE 추가
- CLAUDE_WORKFLOW.md PR 템플릿 준수 문구 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 날짜 포맷 및 Pagination 구조 확정 반영

- 날짜/시간 포맷 ISO 8601 (YYYY-MM-DDTHH:mm:ssZ) 확정
- Pagination 공통 구조 확정
  - data 필드: items 배열
  - page 필드: page / totalPages / sortBy / isNext
- 섹션 7 확정 필요 항목 두 개 체크 처리
- Room 목록, Diary 목록 섹션 Pagination 참조로 갱신

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: Pagination 구조에 size / sort / hasNext / hasPrevious 추가

- size: 한 번에 가져오는 항목 수
- sort: 정렬 방향 (asc | desc)
- isNext → hasNext로 변경 (다음 페이지 존재 여부)
- hasPrevious 추가 (이전 페이지 존재 여부)
- §7 체크리스트 항목 갱신

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 날짜 포맷 코드블록 언어 지정자 추가 (MD040)

코드래빗 지적 사항 반영 — 언어 미지정 펜스 코드블록에 text 지정자 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 통계 API 비로그인 공개 조회로 변경

홈 화면 진입 시 비로그인 회원도 통계 조회 가능하도록 수정
- GET /api/v1/statistics/summary: 🔒 → 공개
- GET /api/v1/statistics/top-types: 🔒 → 공개
- §3 요약표, §4.9 상세 명세 인증 표기 및 설명 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 목록 응답 예시에 page 객체 추가 (코드래빗 지적 반영)

- GET /api/v1/rooms 응답 예시에 page 객체 추가
- GET /api/v1/diary 응답 예시에 page 객체 추가
- GET /api/v1/statistics/top-types 응답 예시에 page 객체 추가
  (Top5 고정 목록 특성 반영: size=5, totalPages=1, hasNext=false)
- 코드래빗 제안의 구버전 필드(isNext) 대신 확정 구조(hasNext/hasPrevious/size/sort) 적용
- §7 Room Pagination 항목 체크 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Spinner, Avatar, AvatarGroup 공통 컴포넌트 추가 (#37)

* chore: 정적 이미지 에셋 추가 및 정리

주요 페이지용 캐릭터 이미지 추가 및 공통 에셋 정리.
gift, loading 캐릭터를 common에서 characters로 이동하여
캐릭터 이미지를 한 폴더로 통합.

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: Spinner 공통 컴포넌트 추가

캐릭터 로딩 이미지를 중앙에 배치한 88x88 스피너 컴포넌트 추가.
트랙(배경 원)과 애니메이션 링을 분리하여 각각 border-default, bg-brand 색상 적용.

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: Avatar, AvatarGroup 공통 컴포넌트 추가

MUI Avatar, AvatarGroup 래핑 컴포넌트 추가.
size prop으로 s/m/l 사이즈 조절, src prop으로 프로필 사진 지원.
global.scss에 --color-white, --color-black CSS 변수 추가.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: Avatar Context로 AvatarGroup size 전달 및 토큰 수정

AvatarGroup size prop이 자식 Avatar에 적용 안 되는 버그 수정.
Context를 통해 size를 내려주고 Avatar가 그룹 size를 우선 적용.
color 토큰 --color-white를 --text-inverse로 교체.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: Avatar src 없을 때 기본 썸네일 이미지로 fallback 처리

Co-Authored-By: Claude <noreply@anthropic.com>

* test: Spinner, Avatar, AvatarGroup 테스트 페이지 추가

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

* feat: 공통 UI 컴포넌트 - CategoryFilter, CategoryIcon, Tab, StatusBadge (#38)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 공통 컴포넌트 생성

- 전체/연애/직장/친구/가족 카테고리 필터 구현
- 아이콘 박스 44x44, border-radius 8, 아이콘 24x24
- 선택 상태: icon-primary bg / 미선택: bg-disabled
- MUI icons 사용 (GridViewRounded, Favorite, BusinessCenter, Diversity3, FamilyRestroom)
- Category 타입 export

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Tab 라벨 폰트 스타일 명시

- item.label을 span.label로 래핑
- Body-M 기준 font-size 16, line-height 28 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: @mui/icons-material 패키지 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 스타일 및 single 모드 적용

- 선택: bg-page + border-brand(1px) + icon-primary + 텍스트 bold
- 미선택: bg-page + border-default(1px) + icon-secondary + 텍스트 regular
- mode prop 추가 (filter 기본값 / single: 선택된 박스 하나만 표시)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 타입을 DB CategoryGroup 기준으로 통일

## 수정 배경

CategoryIcon, CategoryFilter가 한국어 문자열('연애', '직장' 등)을 타입으로 사용하고 있어
API/DB의 CategoryGroup('romance', 'work' 등)과 불일치가 발생.
페이지에서 연결 시 별도 변환 레이어가 필요해지는 문제를 사전 차단.

## 변경 파일별 수정 내용

### CategoryIcon.tsx
- CategoryWithoutAll 타입 제거 → @/types/common의 CategoryGroup 직접 사용
- 아이콘/레이블/컬러 맵 키를 한국어 → 영문 DB 값으로 변경
  (romance, work, friend, family)
- CATEGORY_LABEL_MAP export 추가 (CategoryFilter에서 레이블 참조용)

### CategoryFilter.tsx
- Category 타입을 'all' | CategoryGroup으로 변경 (기존: 한국어 문자열)
- CATEGORIES 배열에 label 필드 추가, CATEGORY_LABEL_MAP에서 참조
- 전체 키를 '전체' → 'all'로 변경 (API 필터 미적용 값과 일치)

### CaseCard.tsx (타팀원 파일 수정)
- 수정 이유: CATEGORY_EMOJI 맵 키가 대문자('ROMANCE')였으나
  API 응답은 소문자('romance')로 내려와 emoji가 항상 '📋' fallback만 표시되는 버그 존재
- 해결 방법: emoji 방식 전체 제거, CategoryIcon 컴포넌트로 교체
- categoryGroup prop 타입을 string → CategoryGroup으로 명시
- categoryGroup 미전달 시 아이콘 미표시 처리 (optional 유지)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update src/components/ui/CategoryIcon.tsx

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: CategoryIcon 중복 import 제거 및 CategoryFilter discriminated union 타입 에러 수정

- CategoryIcon: FamilyRestroomIcon, CategoryGroup 중복 import 제거
- CategoryFilter: discriminated union(CodeRabbit 피드백 반영) 유지하면서
  props 전체로 받아 props.mode로 narrowing 처리해 타입 에러 해결
  (mode='single'일 때 onChange가 CategoryGroup을 기대하는 문제)
- Tab.module.scss: height → min-height 변경 (유연한 높이 대응)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard 카테고리 아이콘을 제목 왼쪽 인라인으로 이동

- card__header 구조 변경: titleRow(아이콘+제목)와 badge를 좌우 배치
- card__titleRow 추가: flex row, align-items center, gap 6px
- 아이콘이 제목 위에 쌓이던 문제 수정 → 제목 왼쪽에 인라인 배치
- card__icon: font-size/line-height(이모지 잔재) → display:flex 로 변경
- card__title: margin-bottom 제거(card__header margin-bottom으로 대체)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 공통 컴포넌트 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard titleRow flex 축소 보완 (min-width: 0, flex: 1)

긴 제목에서 card__titleRow가 축소되지 않아 배지가 밀리는 문제 방지.
card__header가 space-between일 때 titleRow가 flex: 1로 가용 공간을 차지하고
min-width: 0으로 내부 콘텐츠가 넘치지 않도록 제약.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix(common): BottomNavigation 아이콘 MUI MD2 기본 스타일로 수정 (#39)

* fix(common): BottomNavigation 아이콘을 MUI MD2 기본 스타일로 수정

- HomeRounded → Home
- GavelRounded → MenuBook (사건기록 아이콘 자체 변경)
- CalendarMonthRounded → CalendarMonth
- PersonRounded → Person
디자인 시안 기준 MD2 filled 아이콘으로 통일

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: BottomNavigation 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): BottomNavigation 활성 탭 레이블 색상 black-700으로 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): BottomNavigation 테스트 스크린샷 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: wjdalss21 <jungxmin21@gmail.com>

* feat: 사건·방 도메인 타입 정의 및 API 구현 (#40)

* feat: room DTO 타입 정의

- RoomMode, RoomDto, CreateRoomRequest, RoomListResponse

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 방 목록 조회·생성·상세 조회·종료·삭제 API 구현

- GET  /api/v1/rooms — 내 방 목록 조회 (페이지네이션)
- POST /api/v1/rooms — AI 대화방 생성 (roomMode = ai_chat)
- GET  /api/v1/rooms/:id — 방 상세 조회
- POST /api/v1/rooms/:id/close — 방 종료 (closedAt + roomMode = closed)
- DELETE /api/v1/rooms/:id — 방 소프트 삭제 (deletedAt + roomMode = deleted)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 방 목록 페이지네이션 파라미터 NaN 방어 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: API 라우트 경로 v1 버전 세그먼트 제거 (#42)

* fix: API 라우트 경로에서 v1 버전 세그먼트 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 라우트 핸들러 주석 경로 v1 제거 (/api/v1/ -> /api/)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): 서비스 흐름 기반 문서 구조 수정 및 페이지 문서 생성 (#43)

* fix(docs): 서비스 흐름 기반 문서 구조 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): PAGES.md 코드 블록 언어 명시 추가 (MD040)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: personal-analyses 페이지 및 API 폴더 삭제 (#45)

* fix: personal-analyses 페이지 및 API 폴더 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): personal-analysis 도메인 참조 MD 문서 일괄 정리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 API 구현 (GET /api/statistics/categories) (#44)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 공통 컴포넌트 생성

- 전체/연애/직장/친구/가족 카테고리 필터 구현
- 아이콘 박스 44x44, border-radius 8, 아이콘 24x24
- 선택 상태: icon-primary bg / 미선택: bg-disabled
- MUI icons 사용 (GridViewRounded, Favorite, BusinessCenter, Diversity3, FamilyRestroom)
- Category 타입 export

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Tab 라벨 폰트 스타일 명시

- item.label을 span.label로 래핑
- Body-M 기준 font-size 16, line-height 28 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: @mui/icons-material 패키지 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 스타일 및 single 모드 적용

- 선택: bg-page + border-brand(1px) + icon-primary + 텍스트 bold
- 미선택: bg-page + border-default(1px) + icon-secondary + 텍스트 regular
- mode prop 추가 (filter 기본값 / single: 선택된 박스 하나만 표시)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 타입을 DB CategoryGroup 기준으로 통일

## 수정 배경

CategoryIcon, CategoryFilter가 한국어 문자열('연애', '직장' 등)을 타입으로 사용하고 있어
API/DB의 CategoryGroup('romance', 'work' 등)과 불일치가 발생.
페이지에서 연결 시 별도 변환 레이어가 필요해지는 문제를 사전 차단.

## 변경 파일별 수정 내용

### CategoryIcon.tsx
- CategoryWithoutAll 타입 제거 → @/types/common의 CategoryGroup 직접 사용
- 아이콘/레이블/컬러 맵 키를 한국어 → 영문 DB 값으로 변경
  (romance, work, friend, family)
- CATEGORY_LABEL_MAP export 추가 (CategoryFilter에서 레이블 참조용)

### CategoryFilter.tsx
- Category 타입을 'all' | CategoryGroup으로 변경 (기존: 한국어 문자열)
- CATEGORIES 배열에 label 필드 추가, CATEGORY_LABEL_MAP에서 참조
- 전체 키를 '전체' → 'all'로 변경 (API 필터 미적용 값과 일치)

### CaseCard.tsx (타팀원 파일 수정)
- 수정 이유: CATEGORY_EMOJI 맵 키가 대문자('ROMANCE')였으나
  API 응답은 소문자('romance')로 내려와 emoji가 항상 '📋' fallback만 표시되는 버그 존재
- 해결 방법: emoji 방식 전체 제거, CategoryIcon 컴포넌트로 교체
- categoryGroup prop 타입을 string → CategoryGroup으로 명시
- categoryGroup 미전달 시 아이콘 미표시 처리 (optional 유지)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update src/components/ui/CategoryIcon.tsx

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: CategoryIcon 중복 import 제거 및 CategoryFilter discriminated union 타입 에러 수정

- CategoryIcon: FamilyRestroomIcon, CategoryGroup 중복 import 제거
- CategoryFilter: discriminated union(CodeRabbit 피드백 반영) 유지하면서
  props 전체로 받아 props.mode로 narrowing 처리해 타입 에러 해결
  (mode='single'일 때 onChange가 CategoryGroup을 기대하는 문제)
- Tab.module.scss: height → min-height 변경 (유연한 높이 대응)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard 카테고리 아이콘을 제목 왼쪽 인라인으로 이동

- card__header 구조 변경: titleRow(아이콘+제목)와 badge를 좌우 배치
- card__titleRow 추가: flex row, align-items center, gap 6px
- 아이콘이 제목 위에 쌓이던 문제 수정 → 제목 왼쪽에 인라인 배치
- card__icon: font-size/line-height(이모지 잔재) → display:flex 로 변경
- card__title: margin-bottom 제거(card__header margin-bottom으로 대체)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 공통 컴포넌트 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard titleRow flex 축소 보완 (min-width: 0, flex: 1)

긴 제목에서 card__titleRow가 축소되지 않아 배지가 밀리는 문제 방지.
card__header가 space-between일 때 titleRow가 flex: 1로 가용 공간을 차지하고
min-width: 0으로 내부 콘텐츠가 넘치지 않도록 제약.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 도메인 서비스 레이어 생성 (statisticsService.ts)

## 생성 이유
통계 API의 DB 쿼리 로직을 Route Handler와 분리하기 위해
도메인 서비스 레이어를 별도 파일로 작성했다.

## 폴더 선택 이유
src/domains/statistics/
- CLAUDE.md §4 아키텍처 원칙에 따라 도메인별 비즈니스 로직은
  src/domains/{domain}/ 에 위치한다.
- statistics는 MVP 도메인 목록에 포함된 독립 도메인이다.
- Route Handler(src/app/api/)는 요청/응답 처리만 담당하고,
  실제 DB 쿼리 로직은 서비스 레이어에서 관리한다.

## 구현 내용

### getSummary()
- 서비스 전체 판결 완료 건수(totalJudgements) 집계
- dispute.status = JUDGED 조건 명시: ai_judgements는 판결 완료 시에만
  생성되지만 의도를 코드에 명시적으로 표현
- deletedAt / anonymizedAt IS NULL: 삭제·익명화된 사건 제외 (CLAUDE.md §7)

### getTopTypes(size = 5)
- ai_judgements.result_conflict_detail_id 기준 GROUP BY COUNT DESC
- 결과 유형 마스터(conflict_type_details)를 JOIN해 detailCode·displayName 반환
- isActive = true 필터: 비활성화된 유형은 통계에서 제외
- percentage 서버 계산: count / total * 100 (소수점 1자리)
  FE에서 별도 계산 없이 바로 사용할 수 있도록 서버에서 내려줌
- prisma.conflictTypeDetail 사용 (prisma.conflictDetail은 스키마에 존재하지 않음)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 API Route Handler 생성 (GET /api/v1/statistics/top-types)

## 생성 이유
statisticsService의 getTopTypes()를 HTTP 엔드포인트로 노출하기 위해
Next.js App Router 기반 Route Handler를 생성했다.

## 폴더 선택 이유
src/app/api/v1/statistics/top-types/
- CLAUDE.md §4 아키텍처 원칙에 따라 API Route는 src/app/api/v1/ 하위에 위치한다.
- API_SPEC.md §4.9 기준 엔드포인트 경로: GET /api/v1/statistics/top-types
- summary 엔드포인트는 현재 MVP 범위에서 불필요하여 top-types만 생성

## 구현 내용
- getServerSession으로 서버에서 직접 세션 검증
  (FE 리다이렉트만으로는 API 직접 호출을 막을 수 없으므로 서버 검증 필수 — CLAUDE.md §7)
- 인증 실패 시 401 UNAUTHORIZED 반환
- getTopTypes(5) 호출 → 판결 완료 기준 Top5 유형 + 비율 반환
- ApiResponse 타입 준수: data/error는 null 아닌 undefined(optional) 사용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: statistics top-types 인증 제거 (메인 페이지 공개 접근 허용)

메인 페이지에서도 통계 차트가 노출되는 익명 집계 데이터이므로
세션 없이 접근 가능하도록 수정.

- getServerSession 및 관련 import 제거
- 401 인증 체크 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: statistics top-types 에러 핸들링 보완

코드래빗 피드백 반영:
- catch {} -> catch (error): 에러 정보 유실 방지
- 타임아웃 감지 후 504 분기 처리
- console.error 로깅 추가 (CLAUDE.md 11 API 오류 로그 대상)
- 세션 체크는 이전 커밋에서 이미 제거됨 (공개 엔드포인트)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: 통계 API 카테고리 기준으로 재설계

- 결과 유형(top-types) → 작성 카테고리(ROMANCE/FAMILY/FRIEND/WORK) 기준으로 변경
- route.ts에 DB 쿼리 직접 작성, statisticsService.ts 제거
- 비율 계산은 프론트 훅(useStatistics)에서 담당
- revalidate = 86400 (하루 1회 재계산)
- src/hooks/ 폴더 신설 및 useStatistics.ts 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 통계 API 서버 측 세션 인증 추가

- GET /api/statistics/categories 진입 시 getServerSession으로 인증 검증
- 미인증 요청 401 UNAUTHORIZED 반환

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* feat: Header variant 분리 (logo/title) 및 홈 화면 적용 (#47)

* feat: 홈 화면 기본 구조 생성 (헤더, 일기 박스)

- 헤더: 세션 유저명 + character-welcome.png 부엉이 이미지
- 일기 박스: 365x88, border black-700 2px, bg primary-100
- TODO: GangwonEduPower 폰트 추가 후 헤더 로고 텍스트 적용 필요

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Header variant 분리 (logo/title) 및 홈 화면 적용

- Header.tsx에 variant prop 추가 (logo | title)
  - logo: 좌측 상단 말해부엉 로고 표시 (66x19, h:56, padding: 16px 20px)
  - title: 기존 뒤로가기 + 페이지 제목 형태 유지
- Header.module.scss에 __logo 스타일 추가
- home/page.tsx에 Header variant='logo' 적용
  - 헤더를 컨테이너 padding 밖으로 분리하여 상단 여백 제거
- home/page.module.scss diaryBox에 align-self: center 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건기록 페이지 생성 및 로고 헤더 적용 (/records)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: diaryBox 고정 폭을 max-width + width 100%로 반응형 처리

- width: 365px → width: 100% + max-width: 365px
- 작은 화면에서 좌우 패딩과 결합 시 오버플로우 방지

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 감정일기 작성 버튼 /diary/new 네비게이션 연결

- 일기 박스 전체를 Link로 변경 (텍스트 + 버튼 모두 클릭 가능)
- diaryBox에 text-decoration: none, cursor: pointer 추가
- /diary/new 경로는 임시 지정 (담당자 확인 후 수정 예정)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면 캐릭터 이미지 교체 및 위치 조정

- character-welcome.png → character-home.png 교체 (169x138)
- 캐릭터 절대 위치 적용 (top: 41px, right: -20px)
- 캐릭터가 일기 박스 뒤에 위치하도록 z-index 조정 (character: 0, container: 1)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 홈 화면 코드래빗 피드백 반영

- 캐릭터 이미지 가로 스크롤 방지: .page에 overflow-x: hidden 추가
- 비로그인 사용자 분기 처리: 말해부엉 알아보기 박스 추가 (/login 이동)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: 홈 화면 typography 믹신 적용

- greetingText, diaryTitle, diarySubtitle에 typography 믹신 사용
- 개별 font 속성 직접 선언 → @include m.text-* 토큰으로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 비로그인 알아보기 박스 위치 수정

- 인사/일기 박스는 로그인 여부 무관하게 항상 표시
- 말해부엉 알아보기 박스를 진행중인 사건 위치(구분선 아래)로 이동
- 비로그인 인사: '안녕하세요' 표시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면에 통계 섹션 및 구분선 통합

- StatsCategorySection, useStatistics, QueryProvider 병합
- 고민 카테고리 TOP4 통계 섹션 추가
- 통계 섹션 하단 구분선 추가 (h:8px, black-100, gap:42px)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: 개발 편의용 로그인 상태 강제 설정 (배포 전 제거 필요)

- isLoggedIn = true 하드코딩으로 로그인 상태 유지
- TODO 주석으로 배포 전 제거 안내 표시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건작성 페이지 구현 (disputes/[id]/statement) (#46)

* feat: 사건작성 페이지 구현 (disputes/[id]/statement)

- 사건 카테고리 선택 (연애/직장/친구/가족)
- MBTI 선택 드롭다운
- 진술 내용 입력 (최대 1000자)
- 진술저장 버튼 (내용 입력 시 활성화)
- TODO: 진술 저장 API 연결

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 사건작성 페이지 카테고리/간격/드롭다운 수정

- 카테고리를 searchParams에서 읽어 하나만 표시 (비상호작용)
- 카테고리 없을 시 모달 표시 후 이전 페이지로 이동
- Select/Textarea 사이 간격 8px (statementGroup)
- label/Select 사이 간격 16px 유지
- Textarea placeholder 줄바꿈 적용 (\n)
- content overflow-y 제거 → Select 드롭다운 아래 방향 열림 수정
- Select placeholder 색상 var(--text-secondary) 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 없음 모달에서 버튼 제거 — 페이지 블로킹만 유지

확인 버튼 클릭 시 이동하지 않고 Header 뒤로가기로만 탈출 가능

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 기본값 romance 적용, 모달 확인 버튼 복원

- searchParams에 카테고리 없을 시 임시로 romance 기본값 사용
- 모달 확인 버튼 클릭 시 router.back() 복원
- TODO: 이전 페이지 카테고리 데이터 연동 후 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 커스텀 드롭다운 교체 및 Textarea focus 스타일 제거

- Select: 네이티브 select → 커스텀 드롭다운 (항상 아래 방향 열림)
- Select: placeholder 색상 --text-secondary 적용 (option 색 영향 없음)
- Select: 아이콘 회전 애니메이션 추가
- Textarea: focus 시 border-color 변경 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: Button 좌우 패딩 16 → 12으로 조정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: SCSS import 상대경로 → 절대경로(@/) 변환 및 컨벤션 문서 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 접근성 및 스타일 개선

- ul 기본 margin 리셋
- hasValue를 options.find 기준으로 판단 (빈 문자열 오인 방지)
- aria-invalid / aria-describedby 연결로 보조기기 지원
- 키보드 내비게이션 추가 (ArrowUp/Down, Enter/Space, Escape)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: dispute 생성 조건을 active room 전체로 완화 (ONE_TO_ONE 제한 제거)

혼자서도 판결 가능한 흐름을 지원하기 위해
room.roomMode !== 'ONE_TO_ONE' 체크를 제거하고
CLOSED/EXPIRED 방만 차단하도록 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select id 안정화, 빈 options 가드, Tab 기본 포커스 이동 허용

- resolvedId를 label 문자열 대신 useId() 기반으로 고정
- option id를 value 대신 index 기반으로 변경
- Enter/Space 시 options 길이 가드 추가 (크래시 방지)
- Tab은 preventDefault 제거 — 닫기만 하고 포커스 이동은 브라우저에 위임

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독 판결 MVP 포함 및 관련 정책 업데이트 (#51)

- Section 1: 단독 판결 / 1:1 판결 흐름 분리 명시
- Section 2: 단독 판결을 MVP 포함으로 이동, MVP 제외에서 제거
- Section 3: AI 대화방 정책 수정 (ai_chat/invite_ready 상태 단독 판결 허용)
- Section 3: 단독 판결 vs 1:1 판결 제공 결과 비교 섹션 추가
- Section 14: 단독 판결 관련 STOP Condition 항목 제거

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Feature/verdict record display - 캘린더 페이지 ui 제작  (#41)

* feat : 다이어리 (감정일기 , 사건기록)탭분리

* feat : 달력 ui 커스텀 추가 및 감정일기 사건기록 분기처리

* refactor:  및 캘린더 페이지구조 개선 (리뷰 피드백 반영)

* feat : 감정일기카드 컴포넌트 구현

* fix: build 에러 ( 임시 페이지 )

* refactor: 감정일기 컴포넌트 SCSS 모듈 적용 및 믹스인 토큰 사용

* feat: 달력 페이지 UI 구현 및 스타일 정리

- MUI DateCalendar 커스텀
- 감정일기 / 사건기록 탭 전환 구조 구현
- EmotionDiaryList, RecordList 빈 상태 UI 추가
- DiaryCard mixin 적용 (text-title-s, text-body-s, text-label-s)
- 인라인 style 제거 → SCSS 모듈로 분리
- outsideCurrentMonth 감정 아이콘 노출 차단
- 새 일기 FAB 버튼 추가 (감정일기 탭 전용)
- 불필요한 파일 삭제 (DiaryMode, EmotionDiaryCard 등)

* style : EmotionDiaryList.moulde 스타일 수정

* feat: 달력 RecordList에 CaseCard 연동 및 스타일 개선

* Update model name from 'gpt-5.5' to 'gemini-2.5-flash'

seed.ts Ai modelName 수정

---------

Co-authored-by: 배근영 <bgy09270@naver.com>

* feat: 사건작성(진술서) 페이지 구현 및 욕설 감지 필터 연동 (#49)

* feat: 사건작성 페이지 구현 (disputes/[id]/statement)

- 사건 카테고리 선택 (연애/직장/친구/가족)
- MBTI 선택 드롭다운
- 진술 내용 입력 (최대 1000자)
- 진술저장 버튼 (내용 입력 시 활성화)
- TODO: 진술 저장 API 연결

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 사건작성 페이지 카테고리/간격/드롭다운 수정

- 카테고리를 searchParams에서 읽어 하나만 표시 (비상호작용)
- 카테고리 없을 시 모달 표시 후 이전 페이지로 이동
- Select/Textarea 사이 간격 8px (statementGroup)
- label/Select 사이 간격 16px 유지
- Textarea placeholder 줄바꿈 적용 (\n)
- content overflow-y 제거 → Select 드롭다운 아래 방향 열림 수정
- Select placeholder 색상 var(--text-secondary) 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 없음 모달에서 버튼 제거 — 페이지 블로킹만 유지

확인 버튼 클릭 시 이동하지 않고 Header 뒤로가기로만 탈출 가능

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 기본값 romance 적용, 모달 확인 버튼 복원

- searchParams에 카테고리 없을 시 임시로 romance 기본값 사용
- 모달 확인 버튼 클릭 시 router.back() 복원
- TODO: 이전 페이지 카테고리 데이터 연동 후 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 커스텀 드롭다운 교체 및 Textarea focus 스타일 제거

- Select: 네이티브 select → 커스텀 드롭다운 (항상 아래 방향 열림)
- Select: placeholder 색상 --text-secondary 적용 (option 색 영향 없음)
- Select: 아이콘 회전 애니메이션 추가
- Textarea: focus 시 border-color 변경 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: Button 좌우 패딩 16 → 12으로 조정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: SCSS import 상대경로 → 절대경로(@/) 변환 및 컨벤션 문서 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 접근성 및 스타일 개선

- ul 기본 margin 리셋
- hasValue를 options.find 기준으로 판단 (빈 문자열 오인 방지)
- aria-invalid / aria-describedby 연결로 보조기기 지원
- 키보드 내비게이션 추가 (ArrowUp/Down, Enter/Space, Escape)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: dispute 생성 조건을 active room 전체로 완화 (ONE_TO_ONE 제한 제거)

혼자서도 판결 가능한 흐름을 지원하기 위해
room.roomMode !== 'ONE_TO_ONE' 체크를 제거하고
CLOSED/EXPIRED 방만 차단하도록 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select id 안정화, 빈 options 가드, Tab 기본 포커스 이동 허용

- resolvedId를 label 문자열 대신 useId() 기반으로 고정
- option id를 value 대신 index 기반으로 변경
- Enter/Space 시 options 길이 가드 추가 (크래시 방지)
- Tab은 preventDefault 제거 — 닫기만 하고 포커스 이동은 브라우저에 위임

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Textarea 바이트 카운팅 및 filterMessage prop 추가

- 한글 2바이트/ASCII 1바이트 기준으로 글자 수 계산
- maxLength 초과 시 바이트 기준으로 자동 truncate
- filterMessage prop 추가 — 욕설 차단 메시지 동적 표시
- border 색상 변경은 error prop에만 적용 (filter는 border 유지)
- filter-warning 텍스트: Body-S + var(--text-danger)
- field gap 8 → 10px (Figma 기준)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 욕설 감지 필터 구현 (Gemini 2.5 Flash)

- moderation.ts: Gemini 2.5 Flash 기반 욕설/개인정보 감지
  - isBlocked: 욕설·혐오·위협 차단 (보수적 기준)
  - hasPersonalInfo: 개인정보 경고 (차단 없음)
  - fail-open: Gemini 실패 시 pending 상태로 저장
- statements/route.ts: 진술 저장 API
  - 모더레이션 통과 후 upsert + ModerationLog 트랜잭션
  - 차단 시 ModerationLog만 기록, 저장 없이 422 반환
  - dev bypass: 개발 환경에서 세션 없이 모더레이션 테스트 가능
- page.tsx: handleSave 연결, filterMessage 상태, 개인정보 경고 모달
- StatementPage.module.scss: 모달 스타일, Stylelint 공백 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: PR #49 코드리뷰 수정 — MBTI 연동, 파싱 에러, 인젝션, 타임아웃

- MBTI: GET /api/user/me 신규 생성, statement 페이지 마운트 시 user.mbti 초기화
- MBTI: handleSave body에 mbti 포함, statements route에서 user.mbti 업데이트 (트랜잭션)
- statement/page.tsx: res.json() 파싱 실패를 별도 try-catch로 분리
- Textarea.tsx: e.target.value 직접 변경 → Object.assign으로 새 이벤트 객체 전달
- moderation.ts: content 삽입 전 < > HTML 이스케이프 (프롬프트 인젝션 방지)
- moderation.ts: Promise.race() 기반 10초 타임아웃 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: user/me route catch 블록에 에러 로깅 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: judge route 1인 판결 허용 — isSolo 분기 및 rollback 상태 수정

- 2인: BOTH_SUBMITTED 상태 확인 유지
- 1인: 진술 제출 여부만 확인 (statements.length > 0)
- 롤백 대상을 하드코딩된 BOTH_SUBMITTED → previousStatus로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 카카오 로그인 기능 구현 (#50)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 absolute 배치

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 카카오 로그인 기능 구현

- 로그인 페이지 UI 및 카카오 signIn 버튼 연결
- @auth/prisma-adapter 설치 및 authOptions에 적용
- 최초 로그인 시 kakaoId, nickname, termsAgreedAt 자동 설정
- 닉네임 자동 생성 유틸 추가 (~하는부엉이 + 4자리 난수)
- middleware 추가: 비인증 사용자 /login 리다이렉트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 로그인 페이지 및 인증 로직 개선

- SCSS import 절대경로(@/) 수정
- 캐릭터 이미지 Next/Image fill → img 태그로 변경
- 이용약관/개인정보처리방침 링크(/terms, /privacy) 추가 및 스타일 적용
- 닉네임 유니크 제약(@unique) 추가 및 충돌 재시도 로직 구현 (최대 10회)
- middleware matcher 패턴 보완 (/login-help 등 우회 경로 차단)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: disclaimer mixin 적용, nickname 유실 복구 및 fallback 랜덤화

- .disclaimer에 @include m.text-caption mixin 적용
- 유실된 nickname.ts 복구
- fallback 닉네임 Date.now() → 랜덤 8자리 숫자로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독/1:1 판결 공통 진입 흐름 반영 및 관련 문서 일괄 수정 (#54)

- 단독 판결과 1:1 판결이 완전히 분리된 진입이 아니라
  AI 대화방 → 진술저장 → [분기] → disputes/[id]/statement 경로를 공통으로 거침
- CLAUDE.md: 핵심 서비스 흐름 분기 구조로 수정, 단독 판결 MVP 포함 반영,
  AI 대화방 정책 단독/1:1 병행 기술, dispute_status 단독 경로 추가
- PROJECT_DECISIONS.md: 흐름·MVP포함·MVP제외·dispute_status 동기화
- STATUS_TRANSITION.md: 단독 판결 경로(draft→judging→judged) 추가
- DISPUTE.md: 상태 전이 단독/1:1 경로 분리 기술, 주의사항 확정 내용 반영
- ROOM.md: 진술저장 후 분기 흐름 포함 기능에 명시

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Login 페이지 hydration removeChild 에러 수정 (#55)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-…
evenif99 added a commit that referenced this pull request Jun 23, 2026
* chore: initialize project folder structure (#1)

* chore: initialize project folder structure

- Add base directory layout for Next.js + domain-driven architecture
- Add .gitkeep to track empty directories in git
- Exclude MVP out-of-scope domains (shop, points, user-items)
- No implementation files included, structure only

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update README.md

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add CLAUDE.md with project rules and work guidelines (#2)

- Add project overview and MVP scope definition
- Add fixed product rules (categories, AI chat policy, judgement output)
- Add architecture, domain scope, and state transition rules
- Add auth/security, DB, frontend state, API, logging rules
- Add Git workflow, Claude work process, STOP conditions
- Add approval-required list and required reference documents

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: setup project config and install dependencies (#3)

- Add package.json with Next.js 15, React 19, TypeScript stack
- Add next.config.ts (minimal Next.js 15 config)
- Add tsconfig.json (strict mode, @/* path alias)
- Add eslint.config.mjs (next/core-web-vitals + next/typescript)
- Add .prettierrc and .prettierignore
- Add .gitignore (node_modules, .next, .env.local, etc.)
- Add .env.example (key names only, no real values)
- Add prisma/schema.prisma (generator + datasource only)
- Add data/mock/db.json (health check stub for json-server)
- Add docs/TECH_STACK.md (package list and selection rationale)
- Update README.md with run commands and env guide

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add base documentation structure (#4)

- Add PROJECT_DECISIONS.md (MVP scope, architecture, security principles)
- Add guides/CLAUDE_WORKFLOW.md (work process, STOP conditions, approval rules)
- Add guides/GIT_WORKFLOW.md (branch naming, commit convention, workflow)
- Add guides/PR_RULES.md (PR target, title rules, review criteria)
- Add guides/ENV_GUIDE.md (Vercel env pull, .env.example management)
- Add guides/CODING_CONVENTION.md (naming, state management, folder rules)
- Add db/STATUS_TRANSITION.md (room_mode, dispute_status transitions)
- Add db/PRISMA_MAPPING.md (snake_case/camelCase mapping rules)
- Add db/MASTER_DATA.md (categories, result types, DB master principles)
- Add domains/README.md (domain list, MVP scope, writing guidelines)
- Add domains/_DOMAIN_TEMPLATE.md (template for domain docs)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add domain document drafts for all MVP domains (#5)

- Add AUTH.md (kakao login, terms, session management)
- Add COMMON.md (error handling, logging, common response)
- Add ROOM.md (AI chat room, invite link, room_mode transitions)
- Add PERSONAL_ANALYSIS.md (AI-based personal conflict analysis)
- Add DISPUTE.md (1:1 mediation, roles, statements, dispute_status)
- Add JUDGEMENT.md (AI judgement, Gemini API, result card)
- Add GIFT.md (gift recommendation after judgement)
- Add USER.md (mypage, profile, bottom tab)
- Add CALENDAR.md (date-based record marking, monthly summary)
- Add DIARY.md (emotion diary, author-only access, content protection)
- Add STATISTICS.md (anonymous aggregation, summary components)
- Add SHOP_FUTURE.md (v2.0 planned, MVP excluded)
- Add POINTS_FUTURE.md (v2.0 planned, MVP excluded)
- Add USER_ITEMS_FUTURE.md (v2.0 planned, MVP excluded)

All documents are draft templates with TODO markers for assignees.
No implementation, no API routes, no schema changes.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: add Next.js App Router entry files and SCSS base structure (#6)

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Infra/init next setup (#7)

* infra: add Next.js App Router entry files and SCSS base structure

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: resolve ESLint and TypeScript config warnings

- eslint.config.mjs: ignore next-env.d.ts and .next/** (auto-generated by Next.js, triple-slash reference false positive)
- tsconfig.json: remove deprecated baseUrl option (TypeScript 5.x+, paths works without baseUrl)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update README.md (#8)

* docs(infra): confirm Supabase as project infrastructure (#9)

* chore(github): add collaboration templates and policy (#10)

* docs(env): document environment variable management (#11)

* docs(calendar): confirm MUI date picker usage (#12)

달력 UI 라이브러리로 MUI X Date Pickers + Day.js 사용을 확정하고
관련 문서(TECH_STACK, PROJECT_DECISIONS, CODING_CONVENTION, CALENDAR, DIARY, CLAUDE.md)에 반영한다.

* chore(deps): install MUI X Date Pickers and peer dependencies (#13)

달력 UI 구현을 위해 MUI X Date Pickers 및 필수 peer dependency를 설치한다.
@mui/material@9.1.1, @emotion/react@11.14.0, @emotion/styled@11.14.1,
@mui/x-date-pickers@9.5.0, dayjs@1.11.21

* Update README.md (#15)

* fix: resolve ESLint and TypeScript config warnings (#20)

* infra: add Next.js App Router entry files and SCSS base structure

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: resolve ESLint and TypeScript config warnings

- eslint.config.mjs: ignore next-env.d.ts and .next/** (auto-generated by Next.js, triple-slash reference false positive)
- tsconfig.json: remove deprecated baseUrl option (TypeScript 5.x+, paths works without baseUrl)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: add MVP Prisma schema with NextAuth and TALKY-OWL models (#21)

- datasource: add directUrl for Supabase connection pooler support
- enums: CategoryGroup, RoomMode, DisputeStatus, ParticipantRole, etc.
- NextAuth models: User (with TALKY-OWL fields), Account, Session, VerificationToken
- core models: DisputeRoom, RoomAiConversation, RoomAiMessage
- dispute models: Dispute, DisputeParticipant, DisputeStatement
- judgment models: AiJudgment, JudgmentResultCard
- gift models: GiftRecommendation, GiftRecommendationItem
- feature models: EmotionDiary, CalendarRecord
- master data: ConflictTypeGroup, ConflictTypeDetail (DB-based, no enum hardcoding)
- log models: AuditLog, ApiErrorLog, ModerationLog, RoomAccessLog, UserDeletionLog
- .env.example: add DIRECT_URL for Supabase directUrl
- v2.0 TODO: ShopItem, PointTransaction, UserItem, DisputeStatistic excluded

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: align project structure with guide v2 (#22)

folders added:
- src/components/{personal-analysis,room,dispute,judgement,calendar,diary,statistics,gift}
- src/app/api/auth/[...nextauth]
- src/app/api/v1/{users,personal-analyses,rooms,disputes,statements,calendar,diary,statistics,cron}

files added:
- prisma/seed.ts (placeholder for ConflictTypeGroup master data)

docs updated (minimal):
- docs/domains/COMMON.md: add log table list, judgement_logs TODO note
- docs/domains/JUDGEMENT.md: clarify Storage is MVP-excluded scaffolding
- docs/guides/ENV_GUIDE.md: clarify Supabase Storage vars are MVP-excluded

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: rename src/app/page to src/app/(page) for correct Next.js route group (#23)

src/app/page/ (괄호 없음)는 /page/* URL segment를 생성하므로,
Next.js App Router route group 문법인 src/app/(page)/로 변경한다.
URL은 /landing, /home 등으로 노출되어야 하며 /page/... 가 아니다.

관련 문서 내 경로 참조도 모두 업데이트 (CLAUDE.md, docs/domains/*, docs/guides/*).

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* [Style] 디자인 토큰 및 전역 스타일 설정 (#25)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 디자인 시스템 기반 설정 (#27)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: rem 스케일 토큰 추가 및 타이포그래피 변수 rem 참조로 전환

- Rem scale 섹션 추가 (0.25rem ~ 30rem)
- 폰트 토큰에서 누락된 0.875rem(14px), 1.125rem(18px) 추가
- font-size, line-height 변수를 rem 스케일 변수 참조로 전환
- rem 스케일을 typography 섹션보다 상단으로 이동 (선언 순서)
- 컴포넌트 width/height 대응을 위해 큰 단위(9rem~30rem) 포함

Co-Authored-By: Claude <noreply@anthropic.com>

* style: r() 함수 분리 및 타이포그래피 변수 함수 기반으로 전환

- _functions.scss 신규 추가 — px → rem 변환 함수 r() 단독 관리
- _variables.scss에서 rem 스케일 변수 제거, fn.r() 참조로 전환
- _mixins.scss에 functions @use 추가
- 순환 참조 없이 variables → functions → (없음) 단방향 의존성 구성

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Feature/common component jw (#28)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* fix: :root {} 시맨틱 토큰을 _global.scss로 분리 (#29)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: rem 스케일 토큰 추가 및 타이포그래피 변수 rem 참조로 전환

- Rem scale 섹션 추가 (0.25rem ~ 30rem)
- 폰트 토큰에서 누락된 0.875rem(14px), 1.125rem(18px) 추가
- font-size, line-height 변수를 rem 스케일 변수 참조로 전환
- rem 스케일을 typography 섹션보다 상단으로 이동 (선언 순서)
- 컴포넌트 width/height 대응을 위해 큰 단위(9rem~30rem) 포함

Co-Authored-By: Claude <noreply@anthropic.com>

* style: r() 함수 분리 및 타이포그래피 변수 함수 기반으로 전환

- _functions.scss 신규 추가 — px → rem 변환 함수 r() 단독 관리
- _variables.scss에서 rem 스케일 변수 제거, fn.r() 참조로 전환
- _mixins.scss에 functions @use 추가
- 순환 참조 없이 variables → functions → (없음) 단방향 의존성 구성

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: :root {} 시맨틱 토큰을 _global.scss로 분리

_variables.scss에 :root {}가 있으면 module.scss에서 @use 시
CSS Modules 'not pure' 에러 발생.
SCSS 변수는 _variables.scss, CSS 출력은 _global.scss로 분리.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): 공통 UI 컴포넌트 추가 및 MUI 정책 적용 (#30)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 목록 공통 UI 컴포넌트 추가 (Tab, StatusBadge) (#31)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 위치 수정 (#32)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 absolute 배치

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 공통 및 dispute·judgment DTO 타입 정의

- ApiResponse, ApiError, ApiFieldError, CategoryGroup (common.ts)
- DisputeDto, CreateDisputeRequest, DisputeListResponse 등 (dispute.ts)
- AiJudgmentDto, CreateAiJudgmentRequest 등 (judgment.ts)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: dispute 도메인 공유 상수·헬퍼·mapper 추가

- VALID_CATEGORY_GROUPS, IMMUTABLE_DISPUTE_STATUSES 상수 (constants/dispute.ts)
- getSessionUserId NextAuth 세션 헬퍼 (auth/session.ts)
- toAiJudgmentDto 공유 mapper (judgement/judgment.mapper.ts)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 목록 조회·생성·수정·삭제 API 구현

- GET /api/v1/disputes — 참여 사건 목록, categoryGroup 필터, 페이지네이션
- POST /api/v1/disputes — 사건 생성 + role_a 참여자 트랜잭션 등록
- GET /api/v1/disputes/:id — 사건 상세 조회
- PATCH /api/v1/disputes/:id — 사건 수정 (role_a 전용, 변경 불가 상태 차단)
- DELETE /api/v1/disputes/:id — 사건 소프트 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: AI 판결 요청·결과 조회 API 구현

- POST /api/v1/disputes/:id/judge — AI 판결 요청, JUDGING 상태 잠금으로 멱등성 보장
- GET /api/v1/disputes/:id/result — 판결 결과 조회 (참여자 전용)
- AI 모듈 미구현 구간은 TODO 주석으로 마킹, 완료 전까지 503 반환

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 공통 UI 컴포넌트 - StatusBadge, Tab, 진행 상태 (#33)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Prisma 클라이언트, NextAuth Kakao OAuth 설정 및 핸들러 추가

- src/lib/db/index.ts — Prisma 전역 싱글턴
- src/lib/auth/index.ts — NextAuth authOptions (Kakao OAuth, session user.id 매핑)
- src/app/api/auth/[...nextauth]/route.ts — NextAuth GET/POST 핸들러
- @mui/icons-material 패키지 설치 (빌드 에러 해결)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: 빌드 스크립트에 prisma generate 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: MVP 전체 API 명세서 작성 (API_SPEC.md) (#36)

* docs: MVP 전체 API 명세서 작성 (API_SPEC.md)

- 도메인 문서 및 기존 합의 기반 MVP API 명세 초안 작성
- 공통 응답 구조, 에러 코드 체계 정의
- Auth / User / Room / Dispute / Statement / Judgement / Diary / Calendar / Statistics / Gift / Cron 도메인 API 명세 포함
- 경로 충돌 항목 (withdraw, judge/result, diary 경로) 확정 필요 사항으로 명시
- 미확정 TODO 항목 섹션 7에 전체 정리
- MVP 제외 항목 (shop, points, 단독판결, 독립 통계 화면 등) 명시적으로 제거 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독 판결 MVP 포함 반영 및 라우트 주석 명확화

- 단독 판결(상대방 없는 AI 판결)을 MVP 포함 범위로 변경
- Personal Analysis 섹션에 단독 판결 API 초안 추가 (POST/GET /api/v1/personal-analyses)
- 라우트 트리 personal-analyses 디렉터리 구조 구체화
- /auth/withdraw route.ts 주석을 경로 충돌 상호 참조가 명확한 형태로 수정
  (경로 충돌 → /auth/withdraw vs DELETE /users/me)
- MVP 제외 목록에서 단독 판결 항목 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 카카오 로그인 시 약관 동의 자동 간주 정책 반영

- 카카오 OAuth 로그인 완료를 약관 동의로 간주
- 별도 약관 동의 페이지 이동 플로우 제거
- 확정 필요 항목에서 약관 동의 기준 항목 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 도메인 API 목록 중복 제거 및 회원탈퇴 경로 확정

- docs/domains/*.md 8개 파일의 API 목록 섹션을 docs/API_SPEC.md 참조로 교체
  (AUTH, USER, ROOM, DISPUTE, JUDGEMENT, DIARY, CALENDAR, STATISTICS)
- API_SPEC.md 단일 소스 체계 확립
- 회원탈퇴 경로 DELETE /api/v1/users/me 채택 확정
  - §3 요약표, §4.1·§4.2 상세, §5 라우트 트리, §6 충돌 목록, §7 체크리스트 반영
  - /auth/withdraw 라우트 제거, /users/me route.ts에 DELETE 추가
- CLAUDE_WORKFLOW.md PR 템플릿 준수 문구 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 날짜 포맷 및 Pagination 구조 확정 반영

- 날짜/시간 포맷 ISO 8601 (YYYY-MM-DDTHH:mm:ssZ) 확정
- Pagination 공통 구조 확정
  - data 필드: items 배열
  - page 필드: page / totalPages / sortBy / isNext
- 섹션 7 확정 필요 항목 두 개 체크 처리
- Room 목록, Diary 목록 섹션 Pagination 참조로 갱신

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: Pagination 구조에 size / sort / hasNext / hasPrevious 추가

- size: 한 번에 가져오는 항목 수
- sort: 정렬 방향 (asc | desc)
- isNext → hasNext로 변경 (다음 페이지 존재 여부)
- hasPrevious 추가 (이전 페이지 존재 여부)
- §7 체크리스트 항목 갱신

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 날짜 포맷 코드블록 언어 지정자 추가 (MD040)

코드래빗 지적 사항 반영 — 언어 미지정 펜스 코드블록에 text 지정자 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 통계 API 비로그인 공개 조회로 변경

홈 화면 진입 시 비로그인 회원도 통계 조회 가능하도록 수정
- GET /api/v1/statistics/summary: 🔒 → 공개
- GET /api/v1/statistics/top-types: 🔒 → 공개
- §3 요약표, §4.9 상세 명세 인증 표기 및 설명 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 목록 응답 예시에 page 객체 추가 (코드래빗 지적 반영)

- GET /api/v1/rooms 응답 예시에 page 객체 추가
- GET /api/v1/diary 응답 예시에 page 객체 추가
- GET /api/v1/statistics/top-types 응답 예시에 page 객체 추가
  (Top5 고정 목록 특성 반영: size=5, totalPages=1, hasNext=false)
- 코드래빗 제안의 구버전 필드(isNext) 대신 확정 구조(hasNext/hasPrevious/size/sort) 적용
- §7 Room Pagination 항목 체크 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Spinner, Avatar, AvatarGroup 공통 컴포넌트 추가 (#37)

* chore: 정적 이미지 에셋 추가 및 정리

주요 페이지용 캐릭터 이미지 추가 및 공통 에셋 정리.
gift, loading 캐릭터를 common에서 characters로 이동하여
캐릭터 이미지를 한 폴더로 통합.

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: Spinner 공통 컴포넌트 추가

캐릭터 로딩 이미지를 중앙에 배치한 88x88 스피너 컴포넌트 추가.
트랙(배경 원)과 애니메이션 링을 분리하여 각각 border-default, bg-brand 색상 적용.

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: Avatar, AvatarGroup 공통 컴포넌트 추가

MUI Avatar, AvatarGroup 래핑 컴포넌트 추가.
size prop으로 s/m/l 사이즈 조절, src prop으로 프로필 사진 지원.
global.scss에 --color-white, --color-black CSS 변수 추가.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: Avatar Context로 AvatarGroup size 전달 및 토큰 수정

AvatarGroup size prop이 자식 Avatar에 적용 안 되는 버그 수정.
Context를 통해 size를 내려주고 Avatar가 그룹 size를 우선 적용.
color 토큰 --color-white를 --text-inverse로 교체.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: Avatar src 없을 때 기본 썸네일 이미지로 fallback 처리

Co-Authored-By: Claude <noreply@anthropic.com>

* test: Spinner, Avatar, AvatarGroup 테스트 페이지 추가

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

* feat: 공통 UI 컴포넌트 - CategoryFilter, CategoryIcon, Tab, StatusBadge (#38)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 공통 컴포넌트 생성

- 전체/연애/직장/친구/가족 카테고리 필터 구현
- 아이콘 박스 44x44, border-radius 8, 아이콘 24x24
- 선택 상태: icon-primary bg / 미선택: bg-disabled
- MUI icons 사용 (GridViewRounded, Favorite, BusinessCenter, Diversity3, FamilyRestroom)
- Category 타입 export

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Tab 라벨 폰트 스타일 명시

- item.label을 span.label로 래핑
- Body-M 기준 font-size 16, line-height 28 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: @mui/icons-material 패키지 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 스타일 및 single 모드 적용

- 선택: bg-page + border-brand(1px) + icon-primary + 텍스트 bold
- 미선택: bg-page + border-default(1px) + icon-secondary + 텍스트 regular
- mode prop 추가 (filter 기본값 / single: 선택된 박스 하나만 표시)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 타입을 DB CategoryGroup 기준으로 통일

## 수정 배경

CategoryIcon, CategoryFilter가 한국어 문자열('연애', '직장' 등)을 타입으로 사용하고 있어
API/DB의 CategoryGroup('romance', 'work' 등)과 불일치가 발생.
페이지에서 연결 시 별도 변환 레이어가 필요해지는 문제를 사전 차단.

## 변경 파일별 수정 내용

### CategoryIcon.tsx
- CategoryWithoutAll 타입 제거 → @/types/common의 CategoryGroup 직접 사용
- 아이콘/레이블/컬러 맵 키를 한국어 → 영문 DB 값으로 변경
  (romance, work, friend, family)
- CATEGORY_LABEL_MAP export 추가 (CategoryFilter에서 레이블 참조용)

### CategoryFilter.tsx
- Category 타입을 'all' | CategoryGroup으로 변경 (기존: 한국어 문자열)
- CATEGORIES 배열에 label 필드 추가, CATEGORY_LABEL_MAP에서 참조
- 전체 키를 '전체' → 'all'로 변경 (API 필터 미적용 값과 일치)

### CaseCard.tsx (타팀원 파일 수정)
- 수정 이유: CATEGORY_EMOJI 맵 키가 대문자('ROMANCE')였으나
  API 응답은 소문자('romance')로 내려와 emoji가 항상 '📋' fallback만 표시되는 버그 존재
- 해결 방법: emoji 방식 전체 제거, CategoryIcon 컴포넌트로 교체
- categoryGroup prop 타입을 string → CategoryGroup으로 명시
- categoryGroup 미전달 시 아이콘 미표시 처리 (optional 유지)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update src/components/ui/CategoryIcon.tsx

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: CategoryIcon 중복 import 제거 및 CategoryFilter discriminated union 타입 에러 수정

- CategoryIcon: FamilyRestroomIcon, CategoryGroup 중복 import 제거
- CategoryFilter: discriminated union(CodeRabbit 피드백 반영) 유지하면서
  props 전체로 받아 props.mode로 narrowing 처리해 타입 에러 해결
  (mode='single'일 때 onChange가 CategoryGroup을 기대하는 문제)
- Tab.module.scss: height → min-height 변경 (유연한 높이 대응)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard 카테고리 아이콘을 제목 왼쪽 인라인으로 이동

- card__header 구조 변경: titleRow(아이콘+제목)와 badge를 좌우 배치
- card__titleRow 추가: flex row, align-items center, gap 6px
- 아이콘이 제목 위에 쌓이던 문제 수정 → 제목 왼쪽에 인라인 배치
- card__icon: font-size/line-height(이모지 잔재) → display:flex 로 변경
- card__title: margin-bottom 제거(card__header margin-bottom으로 대체)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 공통 컴포넌트 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard titleRow flex 축소 보완 (min-width: 0, flex: 1)

긴 제목에서 card__titleRow가 축소되지 않아 배지가 밀리는 문제 방지.
card__header가 space-between일 때 titleRow가 flex: 1로 가용 공간을 차지하고
min-width: 0으로 내부 콘텐츠가 넘치지 않도록 제약.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix(common): BottomNavigation 아이콘 MUI MD2 기본 스타일로 수정 (#39)

* fix(common): BottomNavigation 아이콘을 MUI MD2 기본 스타일로 수정

- HomeRounded → Home
- GavelRounded → MenuBook (사건기록 아이콘 자체 변경)
- CalendarMonthRounded → CalendarMonth
- PersonRounded → Person
디자인 시안 기준 MD2 filled 아이콘으로 통일

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: BottomNavigation 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): BottomNavigation 활성 탭 레이블 색상 black-700으로 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): BottomNavigation 테스트 스크린샷 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: wjdalss21 <jungxmin21@gmail.com>

* feat: 사건·방 도메인 타입 정의 및 API 구현 (#40)

* feat: room DTO 타입 정의

- RoomMode, RoomDto, CreateRoomRequest, RoomListResponse

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 방 목록 조회·생성·상세 조회·종료·삭제 API 구현

- GET  /api/v1/rooms — 내 방 목록 조회 (페이지네이션)
- POST /api/v1/rooms — AI 대화방 생성 (roomMode = ai_chat)
- GET  /api/v1/rooms/:id — 방 상세 조회
- POST /api/v1/rooms/:id/close — 방 종료 (closedAt + roomMode = closed)
- DELETE /api/v1/rooms/:id — 방 소프트 삭제 (deletedAt + roomMode = deleted)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 방 목록 페이지네이션 파라미터 NaN 방어 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: API 라우트 경로 v1 버전 세그먼트 제거 (#42)

* fix: API 라우트 경로에서 v1 버전 세그먼트 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 라우트 핸들러 주석 경로 v1 제거 (/api/v1/ -> /api/)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): 서비스 흐름 기반 문서 구조 수정 및 페이지 문서 생성 (#43)

* fix(docs): 서비스 흐름 기반 문서 구조 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): PAGES.md 코드 블록 언어 명시 추가 (MD040)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: personal-analyses 페이지 및 API 폴더 삭제 (#45)

* fix: personal-analyses 페이지 및 API 폴더 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): personal-analysis 도메인 참조 MD 문서 일괄 정리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 API 구현 (GET /api/statistics/categories) (#44)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 공통 컴포넌트 생성

- 전체/연애/직장/친구/가족 카테고리 필터 구현
- 아이콘 박스 44x44, border-radius 8, 아이콘 24x24
- 선택 상태: icon-primary bg / 미선택: bg-disabled
- MUI icons 사용 (GridViewRounded, Favorite, BusinessCenter, Diversity3, FamilyRestroom)
- Category 타입 export

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Tab 라벨 폰트 스타일 명시

- item.label을 span.label로 래핑
- Body-M 기준 font-size 16, line-height 28 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: @mui/icons-material 패키지 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 스타일 및 single 모드 적용

- 선택: bg-page + border-brand(1px) + icon-primary + 텍스트 bold
- 미선택: bg-page + border-default(1px) + icon-secondary + 텍스트 regular
- mode prop 추가 (filter 기본값 / single: 선택된 박스 하나만 표시)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 타입을 DB CategoryGroup 기준으로 통일

## 수정 배경

CategoryIcon, CategoryFilter가 한국어 문자열('연애', '직장' 등)을 타입으로 사용하고 있어
API/DB의 CategoryGroup('romance', 'work' 등)과 불일치가 발생.
페이지에서 연결 시 별도 변환 레이어가 필요해지는 문제를 사전 차단.

## 변경 파일별 수정 내용

### CategoryIcon.tsx
- CategoryWithoutAll 타입 제거 → @/types/common의 CategoryGroup 직접 사용
- 아이콘/레이블/컬러 맵 키를 한국어 → 영문 DB 값으로 변경
  (romance, work, friend, family)
- CATEGORY_LABEL_MAP export 추가 (CategoryFilter에서 레이블 참조용)

### CategoryFilter.tsx
- Category 타입을 'all' | CategoryGroup으로 변경 (기존: 한국어 문자열)
- CATEGORIES 배열에 label 필드 추가, CATEGORY_LABEL_MAP에서 참조
- 전체 키를 '전체' → 'all'로 변경 (API 필터 미적용 값과 일치)

### CaseCard.tsx (타팀원 파일 수정)
- 수정 이유: CATEGORY_EMOJI 맵 키가 대문자('ROMANCE')였으나
  API 응답은 소문자('romance')로 내려와 emoji가 항상 '📋' fallback만 표시되는 버그 존재
- 해결 방법: emoji 방식 전체 제거, CategoryIcon 컴포넌트로 교체
- categoryGroup prop 타입을 string → CategoryGroup으로 명시
- categoryGroup 미전달 시 아이콘 미표시 처리 (optional 유지)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update src/components/ui/CategoryIcon.tsx

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: CategoryIcon 중복 import 제거 및 CategoryFilter discriminated union 타입 에러 수정

- CategoryIcon: FamilyRestroomIcon, CategoryGroup 중복 import 제거
- CategoryFilter: discriminated union(CodeRabbit 피드백 반영) 유지하면서
  props 전체로 받아 props.mode로 narrowing 처리해 타입 에러 해결
  (mode='single'일 때 onChange가 CategoryGroup을 기대하는 문제)
- Tab.module.scss: height → min-height 변경 (유연한 높이 대응)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard 카테고리 아이콘을 제목 왼쪽 인라인으로 이동

- card__header 구조 변경: titleRow(아이콘+제목)와 badge를 좌우 배치
- card__titleRow 추가: flex row, align-items center, gap 6px
- 아이콘이 제목 위에 쌓이던 문제 수정 → 제목 왼쪽에 인라인 배치
- card__icon: font-size/line-height(이모지 잔재) → display:flex 로 변경
- card__title: margin-bottom 제거(card__header margin-bottom으로 대체)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 공통 컴포넌트 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard titleRow flex 축소 보완 (min-width: 0, flex: 1)

긴 제목에서 card__titleRow가 축소되지 않아 배지가 밀리는 문제 방지.
card__header가 space-between일 때 titleRow가 flex: 1로 가용 공간을 차지하고
min-width: 0으로 내부 콘텐츠가 넘치지 않도록 제약.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 도메인 서비스 레이어 생성 (statisticsService.ts)

## 생성 이유
통계 API의 DB 쿼리 로직을 Route Handler와 분리하기 위해
도메인 서비스 레이어를 별도 파일로 작성했다.

## 폴더 선택 이유
src/domains/statistics/
- CLAUDE.md §4 아키텍처 원칙에 따라 도메인별 비즈니스 로직은
  src/domains/{domain}/ 에 위치한다.
- statistics는 MVP 도메인 목록에 포함된 독립 도메인이다.
- Route Handler(src/app/api/)는 요청/응답 처리만 담당하고,
  실제 DB 쿼리 로직은 서비스 레이어에서 관리한다.

## 구현 내용

### getSummary()
- 서비스 전체 판결 완료 건수(totalJudgements) 집계
- dispute.status = JUDGED 조건 명시: ai_judgements는 판결 완료 시에만
  생성되지만 의도를 코드에 명시적으로 표현
- deletedAt / anonymizedAt IS NULL: 삭제·익명화된 사건 제외 (CLAUDE.md §7)

### getTopTypes(size = 5)
- ai_judgements.result_conflict_detail_id 기준 GROUP BY COUNT DESC
- 결과 유형 마스터(conflict_type_details)를 JOIN해 detailCode·displayName 반환
- isActive = true 필터: 비활성화된 유형은 통계에서 제외
- percentage 서버 계산: count / total * 100 (소수점 1자리)
  FE에서 별도 계산 없이 바로 사용할 수 있도록 서버에서 내려줌
- prisma.conflictTypeDetail 사용 (prisma.conflictDetail은 스키마에 존재하지 않음)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 API Route Handler 생성 (GET /api/v1/statistics/top-types)

## 생성 이유
statisticsService의 getTopTypes()를 HTTP 엔드포인트로 노출하기 위해
Next.js App Router 기반 Route Handler를 생성했다.

## 폴더 선택 이유
src/app/api/v1/statistics/top-types/
- CLAUDE.md §4 아키텍처 원칙에 따라 API Route는 src/app/api/v1/ 하위에 위치한다.
- API_SPEC.md §4.9 기준 엔드포인트 경로: GET /api/v1/statistics/top-types
- summary 엔드포인트는 현재 MVP 범위에서 불필요하여 top-types만 생성

## 구현 내용
- getServerSession으로 서버에서 직접 세션 검증
  (FE 리다이렉트만으로는 API 직접 호출을 막을 수 없으므로 서버 검증 필수 — CLAUDE.md §7)
- 인증 실패 시 401 UNAUTHORIZED 반환
- getTopTypes(5) 호출 → 판결 완료 기준 Top5 유형 + 비율 반환
- ApiResponse 타입 준수: data/error는 null 아닌 undefined(optional) 사용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: statistics top-types 인증 제거 (메인 페이지 공개 접근 허용)

메인 페이지에서도 통계 차트가 노출되는 익명 집계 데이터이므로
세션 없이 접근 가능하도록 수정.

- getServerSession 및 관련 import 제거
- 401 인증 체크 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: statistics top-types 에러 핸들링 보완

코드래빗 피드백 반영:
- catch {} -> catch (error): 에러 정보 유실 방지
- 타임아웃 감지 후 504 분기 처리
- console.error 로깅 추가 (CLAUDE.md 11 API 오류 로그 대상)
- 세션 체크는 이전 커밋에서 이미 제거됨 (공개 엔드포인트)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: 통계 API 카테고리 기준으로 재설계

- 결과 유형(top-types) → 작성 카테고리(ROMANCE/FAMILY/FRIEND/WORK) 기준으로 변경
- route.ts에 DB 쿼리 직접 작성, statisticsService.ts 제거
- 비율 계산은 프론트 훅(useStatistics)에서 담당
- revalidate = 86400 (하루 1회 재계산)
- src/hooks/ 폴더 신설 및 useStatistics.ts 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 통계 API 서버 측 세션 인증 추가

- GET /api/statistics/categories 진입 시 getServerSession으로 인증 검증
- 미인증 요청 401 UNAUTHORIZED 반환

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* feat: Header variant 분리 (logo/title) 및 홈 화면 적용 (#47)

* feat: 홈 화면 기본 구조 생성 (헤더, 일기 박스)

- 헤더: 세션 유저명 + character-welcome.png 부엉이 이미지
- 일기 박스: 365x88, border black-700 2px, bg primary-100
- TODO: GangwonEduPower 폰트 추가 후 헤더 로고 텍스트 적용 필요

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Header variant 분리 (logo/title) 및 홈 화면 적용

- Header.tsx에 variant prop 추가 (logo | title)
  - logo: 좌측 상단 말해부엉 로고 표시 (66x19, h:56, padding: 16px 20px)
  - title: 기존 뒤로가기 + 페이지 제목 형태 유지
- Header.module.scss에 __logo 스타일 추가
- home/page.tsx에 Header variant='logo' 적용
  - 헤더를 컨테이너 padding 밖으로 분리하여 상단 여백 제거
- home/page.module.scss diaryBox에 align-self: center 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건기록 페이지 생성 및 로고 헤더 적용 (/records)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: diaryBox 고정 폭을 max-width + width 100%로 반응형 처리

- width: 365px → width: 100% + max-width: 365px
- 작은 화면에서 좌우 패딩과 결합 시 오버플로우 방지

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 감정일기 작성 버튼 /diary/new 네비게이션 연결

- 일기 박스 전체를 Link로 변경 (텍스트 + 버튼 모두 클릭 가능)
- diaryBox에 text-decoration: none, cursor: pointer 추가
- /diary/new 경로는 임시 지정 (담당자 확인 후 수정 예정)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면 캐릭터 이미지 교체 및 위치 조정

- character-welcome.png → character-home.png 교체 (169x138)
- 캐릭터 절대 위치 적용 (top: 41px, right: -20px)
- 캐릭터가 일기 박스 뒤에 위치하도록 z-index 조정 (character: 0, container: 1)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 홈 화면 코드래빗 피드백 반영

- 캐릭터 이미지 가로 스크롤 방지: .page에 overflow-x: hidden 추가
- 비로그인 사용자 분기 처리: 말해부엉 알아보기 박스 추가 (/login 이동)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: 홈 화면 typography 믹신 적용

- greetingText, diaryTitle, diarySubtitle에 typography 믹신 사용
- 개별 font 속성 직접 선언 → @include m.text-* 토큰으로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 비로그인 알아보기 박스 위치 수정

- 인사/일기 박스는 로그인 여부 무관하게 항상 표시
- 말해부엉 알아보기 박스를 진행중인 사건 위치(구분선 아래)로 이동
- 비로그인 인사: '안녕하세요' 표시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면에 통계 섹션 및 구분선 통합

- StatsCategorySection, useStatistics, QueryProvider 병합
- 고민 카테고리 TOP4 통계 섹션 추가
- 통계 섹션 하단 구분선 추가 (h:8px, black-100, gap:42px)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: 개발 편의용 로그인 상태 강제 설정 (배포 전 제거 필요)

- isLoggedIn = true 하드코딩으로 로그인 상태 유지
- TODO 주석으로 배포 전 제거 안내 표시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건작성 페이지 구현 (disputes/[id]/statement) (#46)

* feat: 사건작성 페이지 구현 (disputes/[id]/statement)

- 사건 카테고리 선택 (연애/직장/친구/가족)
- MBTI 선택 드롭다운
- 진술 내용 입력 (최대 1000자)
- 진술저장 버튼 (내용 입력 시 활성화)
- TODO: 진술 저장 API 연결

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 사건작성 페이지 카테고리/간격/드롭다운 수정

- 카테고리를 searchParams에서 읽어 하나만 표시 (비상호작용)
- 카테고리 없을 시 모달 표시 후 이전 페이지로 이동
- Select/Textarea 사이 간격 8px (statementGroup)
- label/Select 사이 간격 16px 유지
- Textarea placeholder 줄바꿈 적용 (\n)
- content overflow-y 제거 → Select 드롭다운 아래 방향 열림 수정
- Select placeholder 색상 var(--text-secondary) 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 없음 모달에서 버튼 제거 — 페이지 블로킹만 유지

확인 버튼 클릭 시 이동하지 않고 Header 뒤로가기로만 탈출 가능

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 기본값 romance 적용, 모달 확인 버튼 복원

- searchParams에 카테고리 없을 시 임시로 romance 기본값 사용
- 모달 확인 버튼 클릭 시 router.back() 복원
- TODO: 이전 페이지 카테고리 데이터 연동 후 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 커스텀 드롭다운 교체 및 Textarea focus 스타일 제거

- Select: 네이티브 select → 커스텀 드롭다운 (항상 아래 방향 열림)
- Select: placeholder 색상 --text-secondary 적용 (option 색 영향 없음)
- Select: 아이콘 회전 애니메이션 추가
- Textarea: focus 시 border-color 변경 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: Button 좌우 패딩 16 → 12으로 조정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: SCSS import 상대경로 → 절대경로(@/) 변환 및 컨벤션 문서 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 접근성 및 스타일 개선

- ul 기본 margin 리셋
- hasValue를 options.find 기준으로 판단 (빈 문자열 오인 방지)
- aria-invalid / aria-describedby 연결로 보조기기 지원
- 키보드 내비게이션 추가 (ArrowUp/Down, Enter/Space, Escape)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: dispute 생성 조건을 active room 전체로 완화 (ONE_TO_ONE 제한 제거)

혼자서도 판결 가능한 흐름을 지원하기 위해
room.roomMode !== 'ONE_TO_ONE' 체크를 제거하고
CLOSED/EXPIRED 방만 차단하도록 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select id 안정화, 빈 options 가드, Tab 기본 포커스 이동 허용

- resolvedId를 label 문자열 대신 useId() 기반으로 고정
- option id를 value 대신 index 기반으로 변경
- Enter/Space 시 options 길이 가드 추가 (크래시 방지)
- Tab은 preventDefault 제거 — 닫기만 하고 포커스 이동은 브라우저에 위임

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독 판결 MVP 포함 및 관련 정책 업데이트 (#51)

- Section 1: 단독 판결 / 1:1 판결 흐름 분리 명시
- Section 2: 단독 판결을 MVP 포함으로 이동, MVP 제외에서 제거
- Section 3: AI 대화방 정책 수정 (ai_chat/invite_ready 상태 단독 판결 허용)
- Section 3: 단독 판결 vs 1:1 판결 제공 결과 비교 섹션 추가
- Section 14: 단독 판결 관련 STOP Condition 항목 제거

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Feature/verdict record display - 캘린더 페이지 ui 제작  (#41)

* feat : 다이어리 (감정일기 , 사건기록)탭분리

* feat : 달력 ui 커스텀 추가 및 감정일기 사건기록 분기처리

* refactor:  및 캘린더 페이지구조 개선 (리뷰 피드백 반영)

* feat : 감정일기카드 컴포넌트 구현

* fix: build 에러 ( 임시 페이지 )

* refactor: 감정일기 컴포넌트 SCSS 모듈 적용 및 믹스인 토큰 사용

* feat: 달력 페이지 UI 구현 및 스타일 정리

- MUI DateCalendar 커스텀
- 감정일기 / 사건기록 탭 전환 구조 구현
- EmotionDiaryList, RecordList 빈 상태 UI 추가
- DiaryCard mixin 적용 (text-title-s, text-body-s, text-label-s)
- 인라인 style 제거 → SCSS 모듈로 분리
- outsideCurrentMonth 감정 아이콘 노출 차단
- 새 일기 FAB 버튼 추가 (감정일기 탭 전용)
- 불필요한 파일 삭제 (DiaryMode, EmotionDiaryCard 등)

* style : EmotionDiaryList.moulde 스타일 수정

* feat: 달력 RecordList에 CaseCard 연동 및 스타일 개선

* Update model name from 'gpt-5.5' to 'gemini-2.5-flash'

seed.ts Ai modelName 수정

---------

Co-authored-by: 배근영 <bgy09270@naver.com>

* feat: 사건작성(진술서) 페이지 구현 및 욕설 감지 필터 연동 (#49)

* feat: 사건작성 페이지 구현 (disputes/[id]/statement)

- 사건 카테고리 선택 (연애/직장/친구/가족)
- MBTI 선택 드롭다운
- 진술 내용 입력 (최대 1000자)
- 진술저장 버튼 (내용 입력 시 활성화)
- TODO: 진술 저장 API 연결

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 사건작성 페이지 카테고리/간격/드롭다운 수정

- 카테고리를 searchParams에서 읽어 하나만 표시 (비상호작용)
- 카테고리 없을 시 모달 표시 후 이전 페이지로 이동
- Select/Textarea 사이 간격 8px (statementGroup)
- label/Select 사이 간격 16px 유지
- Textarea placeholder 줄바꿈 적용 (\n)
- content overflow-y 제거 → Select 드롭다운 아래 방향 열림 수정
- Select placeholder 색상 var(--text-secondary) 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 없음 모달에서 버튼 제거 — 페이지 블로킹만 유지

확인 버튼 클릭 시 이동하지 않고 Header 뒤로가기로만 탈출 가능

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 기본값 romance 적용, 모달 확인 버튼 복원

- searchParams에 카테고리 없을 시 임시로 romance 기본값 사용
- 모달 확인 버튼 클릭 시 router.back() 복원
- TODO: 이전 페이지 카테고리 데이터 연동 후 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 커스텀 드롭다운 교체 및 Textarea focus 스타일 제거

- Select: 네이티브 select → 커스텀 드롭다운 (항상 아래 방향 열림)
- Select: placeholder 색상 --text-secondary 적용 (option 색 영향 없음)
- Select: 아이콘 회전 애니메이션 추가
- Textarea: focus 시 border-color 변경 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: Button 좌우 패딩 16 → 12으로 조정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: SCSS import 상대경로 → 절대경로(@/) 변환 및 컨벤션 문서 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 접근성 및 스타일 개선

- ul 기본 margin 리셋
- hasValue를 options.find 기준으로 판단 (빈 문자열 오인 방지)
- aria-invalid / aria-describedby 연결로 보조기기 지원
- 키보드 내비게이션 추가 (ArrowUp/Down, Enter/Space, Escape)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: dispute 생성 조건을 active room 전체로 완화 (ONE_TO_ONE 제한 제거)

혼자서도 판결 가능한 흐름을 지원하기 위해
room.roomMode !== 'ONE_TO_ONE' 체크를 제거하고
CLOSED/EXPIRED 방만 차단하도록 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select id 안정화, 빈 options 가드, Tab 기본 포커스 이동 허용

- resolvedId를 label 문자열 대신 useId() 기반으로 고정
- option id를 value 대신 index 기반으로 변경
- Enter/Space 시 options 길이 가드 추가 (크래시 방지)
- Tab은 preventDefault 제거 — 닫기만 하고 포커스 이동은 브라우저에 위임

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Textarea 바이트 카운팅 및 filterMessage prop 추가

- 한글 2바이트/ASCII 1바이트 기준으로 글자 수 계산
- maxLength 초과 시 바이트 기준으로 자동 truncate
- filterMessage prop 추가 — 욕설 차단 메시지 동적 표시
- border 색상 변경은 error prop에만 적용 (filter는 border 유지)
- filter-warning 텍스트: Body-S + var(--text-danger)
- field gap 8 → 10px (Figma 기준)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 욕설 감지 필터 구현 (Gemini 2.5 Flash)

- moderation.ts: Gemini 2.5 Flash 기반 욕설/개인정보 감지
  - isBlocked: 욕설·혐오·위협 차단 (보수적 기준)
  - hasPersonalInfo: 개인정보 경고 (차단 없음)
  - fail-open: Gemini 실패 시 pending 상태로 저장
- statements/route.ts: 진술 저장 API
  - 모더레이션 통과 후 upsert + ModerationLog 트랜잭션
  - 차단 시 ModerationLog만 기록, 저장 없이 422 반환
  - dev bypass: 개발 환경에서 세션 없이 모더레이션 테스트 가능
- page.tsx: handleSave 연결, filterMessage 상태, 개인정보 경고 모달
- StatementPage.module.scss: 모달 스타일, Stylelint 공백 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: PR #49 코드리뷰 수정 — MBTI 연동, 파싱 에러, 인젝션, 타임아웃

- MBTI: GET /api/user/me 신규 생성, statement 페이지 마운트 시 user.mbti 초기화
- MBTI: handleSave body에 mbti 포함, statements route에서 user.mbti 업데이트 (트랜잭션)
- statement/page.tsx: res.json() 파싱 실패를 별도 try-catch로 분리
- Textarea.tsx: e.target.value 직접 변경 → Object.assign으로 새 이벤트 객체 전달
- moderation.ts: content 삽입 전 < > HTML 이스케이프 (프롬프트 인젝션 방지)
- moderation.ts: Promise.race() 기반 10초 타임아웃 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: user/me route catch 블록에 에러 로깅 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: judge route 1인 판결 허용 — isSolo 분기 및 rollback 상태 수정

- 2인: BOTH_SUBMITTED 상태 확인 유지
- 1인: 진술 제출 여부만 확인 (statements.length > 0)
- 롤백 대상을 하드코딩된 BOTH_SUBMITTED → previousStatus로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 카카오 로그인 기능 구현 (#50)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 absolute 배치

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 카카오 로그인 기능 구현

- 로그인 페이지 UI 및 카카오 signIn 버튼 연결
- @auth/prisma-adapter 설치 및 authOptions에 적용
- 최초 로그인 시 kakaoId, nickname, termsAgreedAt 자동 설정
- 닉네임 자동 생성 유틸 추가 (~하는부엉이 + 4자리 난수)
- middleware 추가: 비인증 사용자 /login 리다이렉트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 로그인 페이지 및 인증 로직 개선

- SCSS import 절대경로(@/) 수정
- 캐릭터 이미지 Next/Image fill → img 태그로 변경
- 이용약관/개인정보처리방침 링크(/terms, /privacy) 추가 및 스타일 적용
- 닉네임 유니크 제약(@unique) 추가 및 충돌 재시도 로직 구현 (최대 10회)
- middleware matcher 패턴 보완 (/login-help 등 우회 경로 차단)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: disclaimer mixin 적용, nickname 유실 복구 및 fallback 랜덤화

- .disclaimer에 @include m.text-caption mixin 적용
- 유실된 nickname.ts 복구
- fallback 닉네임 Date.now() → 랜덤 8자리 숫자로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독/1:1 판결 공통 진입 흐름 반영 및 관련 문서 일괄 수정 (#54)

- 단독 판결과 1:1 판결이 완전히 분리된 진입이 아니라
  AI 대화방 → 진술저장 → [분기] → disputes/[id]/statement 경로를 공통으로 거침
- CLAUDE.md: 핵심 서비스 흐름 분기 구조로 수정, 단독 판결 MVP 포함 반영,
  AI 대화방 정책 단독/1:1 병행 기술, dispute_status 단독 경로 추가
- PROJECT_DECISIONS.md: 흐름·MVP포함·MVP제외·dispute_status 동기화
- STATUS_TRANSITION.md: 단독 판결 경로(draft→judging→judged) 추가
- DISPUTE.md: 상태 전이 단독/1:1 경로 분리 기술, 주의사항 확정 내용 반영
- ROOM.md: 진술저장 후 분기 흐름 포함 기능에 명시

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Login 페이지 hydration removeChild 에러 수정 (#55)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘…
evenif99 added a commit that referenced this pull request Jun 23, 2026
* chore: initialize project folder structure (#1)

* chore: initialize project folder structure

- Add base directory layout for Next.js + domain-driven architecture
- Add .gitkeep to track empty directories in git
- Exclude MVP out-of-scope domains (shop, points, user-items)
- No implementation files included, structure only

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update README.md

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add CLAUDE.md with project rules and work guidelines (#2)

- Add project overview and MVP scope definition
- Add fixed product rules (categories, AI chat policy, judgement output)
- Add architecture, domain scope, and state transition rules
- Add auth/security, DB, frontend state, API, logging rules
- Add Git workflow, Claude work process, STOP conditions
- Add approval-required list and required reference documents

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: setup project config and install dependencies (#3)

- Add package.json with Next.js 15, React 19, TypeScript stack
- Add next.config.ts (minimal Next.js 15 config)
- Add tsconfig.json (strict mode, @/* path alias)
- Add eslint.config.mjs (next/core-web-vitals + next/typescript)
- Add .prettierrc and .prettierignore
- Add .gitignore (node_modules, .next, .env.local, etc.)
- Add .env.example (key names only, no real values)
- Add prisma/schema.prisma (generator + datasource only)
- Add data/mock/db.json (health check stub for json-server)
- Add docs/TECH_STACK.md (package list and selection rationale)
- Update README.md with run commands and env guide

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add base documentation structure (#4)

- Add PROJECT_DECISIONS.md (MVP scope, architecture, security principles)
- Add guides/CLAUDE_WORKFLOW.md (work process, STOP conditions, approval rules)
- Add guides/GIT_WORKFLOW.md (branch naming, commit convention, workflow)
- Add guides/PR_RULES.md (PR target, title rules, review criteria)
- Add guides/ENV_GUIDE.md (Vercel env pull, .env.example management)
- Add guides/CODING_CONVENTION.md (naming, state management, folder rules)
- Add db/STATUS_TRANSITION.md (room_mode, dispute_status transitions)
- Add db/PRISMA_MAPPING.md (snake_case/camelCase mapping rules)
- Add db/MASTER_DATA.md (categories, result types, DB master principles)
- Add domains/README.md (domain list, MVP scope, writing guidelines)
- Add domains/_DOMAIN_TEMPLATE.md (template for domain docs)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add domain document drafts for all MVP domains (#5)

- Add AUTH.md (kakao login, terms, session management)
- Add COMMON.md (error handling, logging, common response)
- Add ROOM.md (AI chat room, invite link, room_mode transitions)
- Add PERSONAL_ANALYSIS.md (AI-based personal conflict analysis)
- Add DISPUTE.md (1:1 mediation, roles, statements, dispute_status)
- Add JUDGEMENT.md (AI judgement, Gemini API, result card)
- Add GIFT.md (gift recommendation after judgement)
- Add USER.md (mypage, profile, bottom tab)
- Add CALENDAR.md (date-based record marking, monthly summary)
- Add DIARY.md (emotion diary, author-only access, content protection)
- Add STATISTICS.md (anonymous aggregation, summary components)
- Add SHOP_FUTURE.md (v2.0 planned, MVP excluded)
- Add POINTS_FUTURE.md (v2.0 planned, MVP excluded)
- Add USER_ITEMS_FUTURE.md (v2.0 planned, MVP excluded)

All documents are draft templates with TODO markers for assignees.
No implementation, no API routes, no schema changes.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: add Next.js App Router entry files and SCSS base structure (#6)

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Infra/init next setup (#7)

* infra: add Next.js App Router entry files and SCSS base structure

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: resolve ESLint and TypeScript config warnings

- eslint.config.mjs: ignore next-env.d.ts and .next/** (auto-generated by Next.js, triple-slash reference false positive)
- tsconfig.json: remove deprecated baseUrl option (TypeScript 5.x+, paths works without baseUrl)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update README.md (#8)

* docs(infra): confirm Supabase as project infrastructure (#9)

* chore(github): add collaboration templates and policy (#10)

* docs(env): document environment variable management (#11)

* docs(calendar): confirm MUI date picker usage (#12)

달력 UI 라이브러리로 MUI X Date Pickers + Day.js 사용을 확정하고
관련 문서(TECH_STACK, PROJECT_DECISIONS, CODING_CONVENTION, CALENDAR, DIARY, CLAUDE.md)에 반영한다.

* chore(deps): install MUI X Date Pickers and peer dependencies (#13)

달력 UI 구현을 위해 MUI X Date Pickers 및 필수 peer dependency를 설치한다.
@mui/material@9.1.1, @emotion/react@11.14.0, @emotion/styled@11.14.1,
@mui/x-date-pickers@9.5.0, dayjs@1.11.21

* Update README.md (#15)

* fix: resolve ESLint and TypeScript config warnings (#20)

* infra: add Next.js App Router entry files and SCSS base structure

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: resolve ESLint and TypeScript config warnings

- eslint.config.mjs: ignore next-env.d.ts and .next/** (auto-generated by Next.js, triple-slash reference false positive)
- tsconfig.json: remove deprecated baseUrl option (TypeScript 5.x+, paths works without baseUrl)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: add MVP Prisma schema with NextAuth and TALKY-OWL models (#21)

- datasource: add directUrl for Supabase connection pooler support
- enums: CategoryGroup, RoomMode, DisputeStatus, ParticipantRole, etc.
- NextAuth models: User (with TALKY-OWL fields), Account, Session, VerificationToken
- core models: DisputeRoom, RoomAiConversation, RoomAiMessage
- dispute models: Dispute, DisputeParticipant, DisputeStatement
- judgment models: AiJudgment, JudgmentResultCard
- gift models: GiftRecommendation, GiftRecommendationItem
- feature models: EmotionDiary, CalendarRecord
- master data: ConflictTypeGroup, ConflictTypeDetail (DB-based, no enum hardcoding)
- log models: AuditLog, ApiErrorLog, ModerationLog, RoomAccessLog, UserDeletionLog
- .env.example: add DIRECT_URL for Supabase directUrl
- v2.0 TODO: ShopItem, PointTransaction, UserItem, DisputeStatistic excluded

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: align project structure with guide v2 (#22)

folders added:
- src/components/{personal-analysis,room,dispute,judgement,calendar,diary,statistics,gift}
- src/app/api/auth/[...nextauth]
- src/app/api/v1/{users,personal-analyses,rooms,disputes,statements,calendar,diary,statistics,cron}

files added:
- prisma/seed.ts (placeholder for ConflictTypeGroup master data)

docs updated (minimal):
- docs/domains/COMMON.md: add log table list, judgement_logs TODO note
- docs/domains/JUDGEMENT.md: clarify Storage is MVP-excluded scaffolding
- docs/guides/ENV_GUIDE.md: clarify Supabase Storage vars are MVP-excluded

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: rename src/app/page to src/app/(page) for correct Next.js route group (#23)

src/app/page/ (괄호 없음)는 /page/* URL segment를 생성하므로,
Next.js App Router route group 문법인 src/app/(page)/로 변경한다.
URL은 /landing, /home 등으로 노출되어야 하며 /page/... 가 아니다.

관련 문서 내 경로 참조도 모두 업데이트 (CLAUDE.md, docs/domains/*, docs/guides/*).

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* [Style] 디자인 토큰 및 전역 스타일 설정 (#25)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 디자인 시스템 기반 설정 (#27)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: rem 스케일 토큰 추가 및 타이포그래피 변수 rem 참조로 전환

- Rem scale 섹션 추가 (0.25rem ~ 30rem)
- 폰트 토큰에서 누락된 0.875rem(14px), 1.125rem(18px) 추가
- font-size, line-height 변수를 rem 스케일 변수 참조로 전환
- rem 스케일을 typography 섹션보다 상단으로 이동 (선언 순서)
- 컴포넌트 width/height 대응을 위해 큰 단위(9rem~30rem) 포함

Co-Authored-By: Claude <noreply@anthropic.com>

* style: r() 함수 분리 및 타이포그래피 변수 함수 기반으로 전환

- _functions.scss 신규 추가 — px → rem 변환 함수 r() 단독 관리
- _variables.scss에서 rem 스케일 변수 제거, fn.r() 참조로 전환
- _mixins.scss에 functions @use 추가
- 순환 참조 없이 variables → functions → (없음) 단방향 의존성 구성

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Feature/common component jw (#28)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* fix: :root {} 시맨틱 토큰을 _global.scss로 분리 (#29)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: rem 스케일 토큰 추가 및 타이포그래피 변수 rem 참조로 전환

- Rem scale 섹션 추가 (0.25rem ~ 30rem)
- 폰트 토큰에서 누락된 0.875rem(14px), 1.125rem(18px) 추가
- font-size, line-height 변수를 rem 스케일 변수 참조로 전환
- rem 스케일을 typography 섹션보다 상단으로 이동 (선언 순서)
- 컴포넌트 width/height 대응을 위해 큰 단위(9rem~30rem) 포함

Co-Authored-By: Claude <noreply@anthropic.com>

* style: r() 함수 분리 및 타이포그래피 변수 함수 기반으로 전환

- _functions.scss 신규 추가 — px → rem 변환 함수 r() 단독 관리
- _variables.scss에서 rem 스케일 변수 제거, fn.r() 참조로 전환
- _mixins.scss에 functions @use 추가
- 순환 참조 없이 variables → functions → (없음) 단방향 의존성 구성

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: :root {} 시맨틱 토큰을 _global.scss로 분리

_variables.scss에 :root {}가 있으면 module.scss에서 @use 시
CSS Modules 'not pure' 에러 발생.
SCSS 변수는 _variables.scss, CSS 출력은 _global.scss로 분리.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): 공통 UI 컴포넌트 추가 및 MUI 정책 적용 (#30)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 목록 공통 UI 컴포넌트 추가 (Tab, StatusBadge) (#31)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 위치 수정 (#32)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 absolute 배치

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 공통 및 dispute·judgment DTO 타입 정의

- ApiResponse, ApiError, ApiFieldError, CategoryGroup (common.ts)
- DisputeDto, CreateDisputeRequest, DisputeListResponse 등 (dispute.ts)
- AiJudgmentDto, CreateAiJudgmentRequest 등 (judgment.ts)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: dispute 도메인 공유 상수·헬퍼·mapper 추가

- VALID_CATEGORY_GROUPS, IMMUTABLE_DISPUTE_STATUSES 상수 (constants/dispute.ts)
- getSessionUserId NextAuth 세션 헬퍼 (auth/session.ts)
- toAiJudgmentDto 공유 mapper (judgement/judgment.mapper.ts)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 목록 조회·생성·수정·삭제 API 구현

- GET /api/v1/disputes — 참여 사건 목록, categoryGroup 필터, 페이지네이션
- POST /api/v1/disputes — 사건 생성 + role_a 참여자 트랜잭션 등록
- GET /api/v1/disputes/:id — 사건 상세 조회
- PATCH /api/v1/disputes/:id — 사건 수정 (role_a 전용, 변경 불가 상태 차단)
- DELETE /api/v1/disputes/:id — 사건 소프트 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: AI 판결 요청·결과 조회 API 구현

- POST /api/v1/disputes/:id/judge — AI 판결 요청, JUDGING 상태 잠금으로 멱등성 보장
- GET /api/v1/disputes/:id/result — 판결 결과 조회 (참여자 전용)
- AI 모듈 미구현 구간은 TODO 주석으로 마킹, 완료 전까지 503 반환

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 공통 UI 컴포넌트 - StatusBadge, Tab, 진행 상태 (#33)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Prisma 클라이언트, NextAuth Kakao OAuth 설정 및 핸들러 추가

- src/lib/db/index.ts — Prisma 전역 싱글턴
- src/lib/auth/index.ts — NextAuth authOptions (Kakao OAuth, session user.id 매핑)
- src/app/api/auth/[...nextauth]/route.ts — NextAuth GET/POST 핸들러
- @mui/icons-material 패키지 설치 (빌드 에러 해결)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: 빌드 스크립트에 prisma generate 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: MVP 전체 API 명세서 작성 (API_SPEC.md) (#36)

* docs: MVP 전체 API 명세서 작성 (API_SPEC.md)

- 도메인 문서 및 기존 합의 기반 MVP API 명세 초안 작성
- 공통 응답 구조, 에러 코드 체계 정의
- Auth / User / Room / Dispute / Statement / Judgement / Diary / Calendar / Statistics / Gift / Cron 도메인 API 명세 포함
- 경로 충돌 항목 (withdraw, judge/result, diary 경로) 확정 필요 사항으로 명시
- 미확정 TODO 항목 섹션 7에 전체 정리
- MVP 제외 항목 (shop, points, 단독판결, 독립 통계 화면 등) 명시적으로 제거 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독 판결 MVP 포함 반영 및 라우트 주석 명확화

- 단독 판결(상대방 없는 AI 판결)을 MVP 포함 범위로 변경
- Personal Analysis 섹션에 단독 판결 API 초안 추가 (POST/GET /api/v1/personal-analyses)
- 라우트 트리 personal-analyses 디렉터리 구조 구체화
- /auth/withdraw route.ts 주석을 경로 충돌 상호 참조가 명확한 형태로 수정
  (경로 충돌 → /auth/withdraw vs DELETE /users/me)
- MVP 제외 목록에서 단독 판결 항목 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 카카오 로그인 시 약관 동의 자동 간주 정책 반영

- 카카오 OAuth 로그인 완료를 약관 동의로 간주
- 별도 약관 동의 페이지 이동 플로우 제거
- 확정 필요 항목에서 약관 동의 기준 항목 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 도메인 API 목록 중복 제거 및 회원탈퇴 경로 확정

- docs/domains/*.md 8개 파일의 API 목록 섹션을 docs/API_SPEC.md 참조로 교체
  (AUTH, USER, ROOM, DISPUTE, JUDGEMENT, DIARY, CALENDAR, STATISTICS)
- API_SPEC.md 단일 소스 체계 확립
- 회원탈퇴 경로 DELETE /api/v1/users/me 채택 확정
  - §3 요약표, §4.1·§4.2 상세, §5 라우트 트리, §6 충돌 목록, §7 체크리스트 반영
  - /auth/withdraw 라우트 제거, /users/me route.ts에 DELETE 추가
- CLAUDE_WORKFLOW.md PR 템플릿 준수 문구 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 날짜 포맷 및 Pagination 구조 확정 반영

- 날짜/시간 포맷 ISO 8601 (YYYY-MM-DDTHH:mm:ssZ) 확정
- Pagination 공통 구조 확정
  - data 필드: items 배열
  - page 필드: page / totalPages / sortBy / isNext
- 섹션 7 확정 필요 항목 두 개 체크 처리
- Room 목록, Diary 목록 섹션 Pagination 참조로 갱신

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: Pagination 구조에 size / sort / hasNext / hasPrevious 추가

- size: 한 번에 가져오는 항목 수
- sort: 정렬 방향 (asc | desc)
- isNext → hasNext로 변경 (다음 페이지 존재 여부)
- hasPrevious 추가 (이전 페이지 존재 여부)
- §7 체크리스트 항목 갱신

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 날짜 포맷 코드블록 언어 지정자 추가 (MD040)

코드래빗 지적 사항 반영 — 언어 미지정 펜스 코드블록에 text 지정자 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 통계 API 비로그인 공개 조회로 변경

홈 화면 진입 시 비로그인 회원도 통계 조회 가능하도록 수정
- GET /api/v1/statistics/summary: 🔒 → 공개
- GET /api/v1/statistics/top-types: 🔒 → 공개
- §3 요약표, §4.9 상세 명세 인증 표기 및 설명 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 목록 응답 예시에 page 객체 추가 (코드래빗 지적 반영)

- GET /api/v1/rooms 응답 예시에 page 객체 추가
- GET /api/v1/diary 응답 예시에 page 객체 추가
- GET /api/v1/statistics/top-types 응답 예시에 page 객체 추가
  (Top5 고정 목록 특성 반영: size=5, totalPages=1, hasNext=false)
- 코드래빗 제안의 구버전 필드(isNext) 대신 확정 구조(hasNext/hasPrevious/size/sort) 적용
- §7 Room Pagination 항목 체크 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Spinner, Avatar, AvatarGroup 공통 컴포넌트 추가 (#37)

* chore: 정적 이미지 에셋 추가 및 정리

주요 페이지용 캐릭터 이미지 추가 및 공통 에셋 정리.
gift, loading 캐릭터를 common에서 characters로 이동하여
캐릭터 이미지를 한 폴더로 통합.

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: Spinner 공통 컴포넌트 추가

캐릭터 로딩 이미지를 중앙에 배치한 88x88 스피너 컴포넌트 추가.
트랙(배경 원)과 애니메이션 링을 분리하여 각각 border-default, bg-brand 색상 적용.

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: Avatar, AvatarGroup 공통 컴포넌트 추가

MUI Avatar, AvatarGroup 래핑 컴포넌트 추가.
size prop으로 s/m/l 사이즈 조절, src prop으로 프로필 사진 지원.
global.scss에 --color-white, --color-black CSS 변수 추가.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: Avatar Context로 AvatarGroup size 전달 및 토큰 수정

AvatarGroup size prop이 자식 Avatar에 적용 안 되는 버그 수정.
Context를 통해 size를 내려주고 Avatar가 그룹 size를 우선 적용.
color 토큰 --color-white를 --text-inverse로 교체.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: Avatar src 없을 때 기본 썸네일 이미지로 fallback 처리

Co-Authored-By: Claude <noreply@anthropic.com>

* test: Spinner, Avatar, AvatarGroup 테스트 페이지 추가

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

* feat: 공통 UI 컴포넌트 - CategoryFilter, CategoryIcon, Tab, StatusBadge (#38)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 공통 컴포넌트 생성

- 전체/연애/직장/친구/가족 카테고리 필터 구현
- 아이콘 박스 44x44, border-radius 8, 아이콘 24x24
- 선택 상태: icon-primary bg / 미선택: bg-disabled
- MUI icons 사용 (GridViewRounded, Favorite, BusinessCenter, Diversity3, FamilyRestroom)
- Category 타입 export

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Tab 라벨 폰트 스타일 명시

- item.label을 span.label로 래핑
- Body-M 기준 font-size 16, line-height 28 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: @mui/icons-material 패키지 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 스타일 및 single 모드 적용

- 선택: bg-page + border-brand(1px) + icon-primary + 텍스트 bold
- 미선택: bg-page + border-default(1px) + icon-secondary + 텍스트 regular
- mode prop 추가 (filter 기본값 / single: 선택된 박스 하나만 표시)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 타입을 DB CategoryGroup 기준으로 통일

## 수정 배경

CategoryIcon, CategoryFilter가 한국어 문자열('연애', '직장' 등)을 타입으로 사용하고 있어
API/DB의 CategoryGroup('romance', 'work' 등)과 불일치가 발생.
페이지에서 연결 시 별도 변환 레이어가 필요해지는 문제를 사전 차단.

## 변경 파일별 수정 내용

### CategoryIcon.tsx
- CategoryWithoutAll 타입 제거 → @/types/common의 CategoryGroup 직접 사용
- 아이콘/레이블/컬러 맵 키를 한국어 → 영문 DB 값으로 변경
  (romance, work, friend, family)
- CATEGORY_LABEL_MAP export 추가 (CategoryFilter에서 레이블 참조용)

### CategoryFilter.tsx
- Category 타입을 'all' | CategoryGroup으로 변경 (기존: 한국어 문자열)
- CATEGORIES 배열에 label 필드 추가, CATEGORY_LABEL_MAP에서 참조
- 전체 키를 '전체' → 'all'로 변경 (API 필터 미적용 값과 일치)

### CaseCard.tsx (타팀원 파일 수정)
- 수정 이유: CATEGORY_EMOJI 맵 키가 대문자('ROMANCE')였으나
  API 응답은 소문자('romance')로 내려와 emoji가 항상 '📋' fallback만 표시되는 버그 존재
- 해결 방법: emoji 방식 전체 제거, CategoryIcon 컴포넌트로 교체
- categoryGroup prop 타입을 string → CategoryGroup으로 명시
- categoryGroup 미전달 시 아이콘 미표시 처리 (optional 유지)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update src/components/ui/CategoryIcon.tsx

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: CategoryIcon 중복 import 제거 및 CategoryFilter discriminated union 타입 에러 수정

- CategoryIcon: FamilyRestroomIcon, CategoryGroup 중복 import 제거
- CategoryFilter: discriminated union(CodeRabbit 피드백 반영) 유지하면서
  props 전체로 받아 props.mode로 narrowing 처리해 타입 에러 해결
  (mode='single'일 때 onChange가 CategoryGroup을 기대하는 문제)
- Tab.module.scss: height → min-height 변경 (유연한 높이 대응)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard 카테고리 아이콘을 제목 왼쪽 인라인으로 이동

- card__header 구조 변경: titleRow(아이콘+제목)와 badge를 좌우 배치
- card__titleRow 추가: flex row, align-items center, gap 6px
- 아이콘이 제목 위에 쌓이던 문제 수정 → 제목 왼쪽에 인라인 배치
- card__icon: font-size/line-height(이모지 잔재) → display:flex 로 변경
- card__title: margin-bottom 제거(card__header margin-bottom으로 대체)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 공통 컴포넌트 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard titleRow flex 축소 보완 (min-width: 0, flex: 1)

긴 제목에서 card__titleRow가 축소되지 않아 배지가 밀리는 문제 방지.
card__header가 space-between일 때 titleRow가 flex: 1로 가용 공간을 차지하고
min-width: 0으로 내부 콘텐츠가 넘치지 않도록 제약.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix(common): BottomNavigation 아이콘 MUI MD2 기본 스타일로 수정 (#39)

* fix(common): BottomNavigation 아이콘을 MUI MD2 기본 스타일로 수정

- HomeRounded → Home
- GavelRounded → MenuBook (사건기록 아이콘 자체 변경)
- CalendarMonthRounded → CalendarMonth
- PersonRounded → Person
디자인 시안 기준 MD2 filled 아이콘으로 통일

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: BottomNavigation 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): BottomNavigation 활성 탭 레이블 색상 black-700으로 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): BottomNavigation 테스트 스크린샷 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: wjdalss21 <jungxmin21@gmail.com>

* feat: 사건·방 도메인 타입 정의 및 API 구현 (#40)

* feat: room DTO 타입 정의

- RoomMode, RoomDto, CreateRoomRequest, RoomListResponse

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 방 목록 조회·생성·상세 조회·종료·삭제 API 구현

- GET  /api/v1/rooms — 내 방 목록 조회 (페이지네이션)
- POST /api/v1/rooms — AI 대화방 생성 (roomMode = ai_chat)
- GET  /api/v1/rooms/:id — 방 상세 조회
- POST /api/v1/rooms/:id/close — 방 종료 (closedAt + roomMode = closed)
- DELETE /api/v1/rooms/:id — 방 소프트 삭제 (deletedAt + roomMode = deleted)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 방 목록 페이지네이션 파라미터 NaN 방어 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: API 라우트 경로 v1 버전 세그먼트 제거 (#42)

* fix: API 라우트 경로에서 v1 버전 세그먼트 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 라우트 핸들러 주석 경로 v1 제거 (/api/v1/ -> /api/)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): 서비스 흐름 기반 문서 구조 수정 및 페이지 문서 생성 (#43)

* fix(docs): 서비스 흐름 기반 문서 구조 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): PAGES.md 코드 블록 언어 명시 추가 (MD040)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: personal-analyses 페이지 및 API 폴더 삭제 (#45)

* fix: personal-analyses 페이지 및 API 폴더 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): personal-analysis 도메인 참조 MD 문서 일괄 정리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 API 구현 (GET /api/statistics/categories) (#44)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 공통 컴포넌트 생성

- 전체/연애/직장/친구/가족 카테고리 필터 구현
- 아이콘 박스 44x44, border-radius 8, 아이콘 24x24
- 선택 상태: icon-primary bg / 미선택: bg-disabled
- MUI icons 사용 (GridViewRounded, Favorite, BusinessCenter, Diversity3, FamilyRestroom)
- Category 타입 export

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Tab 라벨 폰트 스타일 명시

- item.label을 span.label로 래핑
- Body-M 기준 font-size 16, line-height 28 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: @mui/icons-material 패키지 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 스타일 및 single 모드 적용

- 선택: bg-page + border-brand(1px) + icon-primary + 텍스트 bold
- 미선택: bg-page + border-default(1px) + icon-secondary + 텍스트 regular
- mode prop 추가 (filter 기본값 / single: 선택된 박스 하나만 표시)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 타입을 DB CategoryGroup 기준으로 통일

## 수정 배경

CategoryIcon, CategoryFilter가 한국어 문자열('연애', '직장' 등)을 타입으로 사용하고 있어
API/DB의 CategoryGroup('romance', 'work' 등)과 불일치가 발생.
페이지에서 연결 시 별도 변환 레이어가 필요해지는 문제를 사전 차단.

## 변경 파일별 수정 내용

### CategoryIcon.tsx
- CategoryWithoutAll 타입 제거 → @/types/common의 CategoryGroup 직접 사용
- 아이콘/레이블/컬러 맵 키를 한국어 → 영문 DB 값으로 변경
  (romance, work, friend, family)
- CATEGORY_LABEL_MAP export 추가 (CategoryFilter에서 레이블 참조용)

### CategoryFilter.tsx
- Category 타입을 'all' | CategoryGroup으로 변경 (기존: 한국어 문자열)
- CATEGORIES 배열에 label 필드 추가, CATEGORY_LABEL_MAP에서 참조
- 전체 키를 '전체' → 'all'로 변경 (API 필터 미적용 값과 일치)

### CaseCard.tsx (타팀원 파일 수정)
- 수정 이유: CATEGORY_EMOJI 맵 키가 대문자('ROMANCE')였으나
  API 응답은 소문자('romance')로 내려와 emoji가 항상 '📋' fallback만 표시되는 버그 존재
- 해결 방법: emoji 방식 전체 제거, CategoryIcon 컴포넌트로 교체
- categoryGroup prop 타입을 string → CategoryGroup으로 명시
- categoryGroup 미전달 시 아이콘 미표시 처리 (optional 유지)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update src/components/ui/CategoryIcon.tsx

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: CategoryIcon 중복 import 제거 및 CategoryFilter discriminated union 타입 에러 수정

- CategoryIcon: FamilyRestroomIcon, CategoryGroup 중복 import 제거
- CategoryFilter: discriminated union(CodeRabbit 피드백 반영) 유지하면서
  props 전체로 받아 props.mode로 narrowing 처리해 타입 에러 해결
  (mode='single'일 때 onChange가 CategoryGroup을 기대하는 문제)
- Tab.module.scss: height → min-height 변경 (유연한 높이 대응)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard 카테고리 아이콘을 제목 왼쪽 인라인으로 이동

- card__header 구조 변경: titleRow(아이콘+제목)와 badge를 좌우 배치
- card__titleRow 추가: flex row, align-items center, gap 6px
- 아이콘이 제목 위에 쌓이던 문제 수정 → 제목 왼쪽에 인라인 배치
- card__icon: font-size/line-height(이모지 잔재) → display:flex 로 변경
- card__title: margin-bottom 제거(card__header margin-bottom으로 대체)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 공통 컴포넌트 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard titleRow flex 축소 보완 (min-width: 0, flex: 1)

긴 제목에서 card__titleRow가 축소되지 않아 배지가 밀리는 문제 방지.
card__header가 space-between일 때 titleRow가 flex: 1로 가용 공간을 차지하고
min-width: 0으로 내부 콘텐츠가 넘치지 않도록 제약.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 도메인 서비스 레이어 생성 (statisticsService.ts)

## 생성 이유
통계 API의 DB 쿼리 로직을 Route Handler와 분리하기 위해
도메인 서비스 레이어를 별도 파일로 작성했다.

## 폴더 선택 이유
src/domains/statistics/
- CLAUDE.md §4 아키텍처 원칙에 따라 도메인별 비즈니스 로직은
  src/domains/{domain}/ 에 위치한다.
- statistics는 MVP 도메인 목록에 포함된 독립 도메인이다.
- Route Handler(src/app/api/)는 요청/응답 처리만 담당하고,
  실제 DB 쿼리 로직은 서비스 레이어에서 관리한다.

## 구현 내용

### getSummary()
- 서비스 전체 판결 완료 건수(totalJudgements) 집계
- dispute.status = JUDGED 조건 명시: ai_judgements는 판결 완료 시에만
  생성되지만 의도를 코드에 명시적으로 표현
- deletedAt / anonymizedAt IS NULL: 삭제·익명화된 사건 제외 (CLAUDE.md §7)

### getTopTypes(size = 5)
- ai_judgements.result_conflict_detail_id 기준 GROUP BY COUNT DESC
- 결과 유형 마스터(conflict_type_details)를 JOIN해 detailCode·displayName 반환
- isActive = true 필터: 비활성화된 유형은 통계에서 제외
- percentage 서버 계산: count / total * 100 (소수점 1자리)
  FE에서 별도 계산 없이 바로 사용할 수 있도록 서버에서 내려줌
- prisma.conflictTypeDetail 사용 (prisma.conflictDetail은 스키마에 존재하지 않음)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 API Route Handler 생성 (GET /api/v1/statistics/top-types)

## 생성 이유
statisticsService의 getTopTypes()를 HTTP 엔드포인트로 노출하기 위해
Next.js App Router 기반 Route Handler를 생성했다.

## 폴더 선택 이유
src/app/api/v1/statistics/top-types/
- CLAUDE.md §4 아키텍처 원칙에 따라 API Route는 src/app/api/v1/ 하위에 위치한다.
- API_SPEC.md §4.9 기준 엔드포인트 경로: GET /api/v1/statistics/top-types
- summary 엔드포인트는 현재 MVP 범위에서 불필요하여 top-types만 생성

## 구현 내용
- getServerSession으로 서버에서 직접 세션 검증
  (FE 리다이렉트만으로는 API 직접 호출을 막을 수 없으므로 서버 검증 필수 — CLAUDE.md §7)
- 인증 실패 시 401 UNAUTHORIZED 반환
- getTopTypes(5) 호출 → 판결 완료 기준 Top5 유형 + 비율 반환
- ApiResponse 타입 준수: data/error는 null 아닌 undefined(optional) 사용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: statistics top-types 인증 제거 (메인 페이지 공개 접근 허용)

메인 페이지에서도 통계 차트가 노출되는 익명 집계 데이터이므로
세션 없이 접근 가능하도록 수정.

- getServerSession 및 관련 import 제거
- 401 인증 체크 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: statistics top-types 에러 핸들링 보완

코드래빗 피드백 반영:
- catch {} -> catch (error): 에러 정보 유실 방지
- 타임아웃 감지 후 504 분기 처리
- console.error 로깅 추가 (CLAUDE.md 11 API 오류 로그 대상)
- 세션 체크는 이전 커밋에서 이미 제거됨 (공개 엔드포인트)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: 통계 API 카테고리 기준으로 재설계

- 결과 유형(top-types) → 작성 카테고리(ROMANCE/FAMILY/FRIEND/WORK) 기준으로 변경
- route.ts에 DB 쿼리 직접 작성, statisticsService.ts 제거
- 비율 계산은 프론트 훅(useStatistics)에서 담당
- revalidate = 86400 (하루 1회 재계산)
- src/hooks/ 폴더 신설 및 useStatistics.ts 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 통계 API 서버 측 세션 인증 추가

- GET /api/statistics/categories 진입 시 getServerSession으로 인증 검증
- 미인증 요청 401 UNAUTHORIZED 반환

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* feat: Header variant 분리 (logo/title) 및 홈 화면 적용 (#47)

* feat: 홈 화면 기본 구조 생성 (헤더, 일기 박스)

- 헤더: 세션 유저명 + character-welcome.png 부엉이 이미지
- 일기 박스: 365x88, border black-700 2px, bg primary-100
- TODO: GangwonEduPower 폰트 추가 후 헤더 로고 텍스트 적용 필요

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Header variant 분리 (logo/title) 및 홈 화면 적용

- Header.tsx에 variant prop 추가 (logo | title)
  - logo: 좌측 상단 말해부엉 로고 표시 (66x19, h:56, padding: 16px 20px)
  - title: 기존 뒤로가기 + 페이지 제목 형태 유지
- Header.module.scss에 __logo 스타일 추가
- home/page.tsx에 Header variant='logo' 적용
  - 헤더를 컨테이너 padding 밖으로 분리하여 상단 여백 제거
- home/page.module.scss diaryBox에 align-self: center 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건기록 페이지 생성 및 로고 헤더 적용 (/records)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: diaryBox 고정 폭을 max-width + width 100%로 반응형 처리

- width: 365px → width: 100% + max-width: 365px
- 작은 화면에서 좌우 패딩과 결합 시 오버플로우 방지

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 감정일기 작성 버튼 /diary/new 네비게이션 연결

- 일기 박스 전체를 Link로 변경 (텍스트 + 버튼 모두 클릭 가능)
- diaryBox에 text-decoration: none, cursor: pointer 추가
- /diary/new 경로는 임시 지정 (담당자 확인 후 수정 예정)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면 캐릭터 이미지 교체 및 위치 조정

- character-welcome.png → character-home.png 교체 (169x138)
- 캐릭터 절대 위치 적용 (top: 41px, right: -20px)
- 캐릭터가 일기 박스 뒤에 위치하도록 z-index 조정 (character: 0, container: 1)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 홈 화면 코드래빗 피드백 반영

- 캐릭터 이미지 가로 스크롤 방지: .page에 overflow-x: hidden 추가
- 비로그인 사용자 분기 처리: 말해부엉 알아보기 박스 추가 (/login 이동)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: 홈 화면 typography 믹신 적용

- greetingText, diaryTitle, diarySubtitle에 typography 믹신 사용
- 개별 font 속성 직접 선언 → @include m.text-* 토큰으로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 비로그인 알아보기 박스 위치 수정

- 인사/일기 박스는 로그인 여부 무관하게 항상 표시
- 말해부엉 알아보기 박스를 진행중인 사건 위치(구분선 아래)로 이동
- 비로그인 인사: '안녕하세요' 표시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면에 통계 섹션 및 구분선 통합

- StatsCategorySection, useStatistics, QueryProvider 병합
- 고민 카테고리 TOP4 통계 섹션 추가
- 통계 섹션 하단 구분선 추가 (h:8px, black-100, gap:42px)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: 개발 편의용 로그인 상태 강제 설정 (배포 전 제거 필요)

- isLoggedIn = true 하드코딩으로 로그인 상태 유지
- TODO 주석으로 배포 전 제거 안내 표시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건작성 페이지 구현 (disputes/[id]/statement) (#46)

* feat: 사건작성 페이지 구현 (disputes/[id]/statement)

- 사건 카테고리 선택 (연애/직장/친구/가족)
- MBTI 선택 드롭다운
- 진술 내용 입력 (최대 1000자)
- 진술저장 버튼 (내용 입력 시 활성화)
- TODO: 진술 저장 API 연결

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 사건작성 페이지 카테고리/간격/드롭다운 수정

- 카테고리를 searchParams에서 읽어 하나만 표시 (비상호작용)
- 카테고리 없을 시 모달 표시 후 이전 페이지로 이동
- Select/Textarea 사이 간격 8px (statementGroup)
- label/Select 사이 간격 16px 유지
- Textarea placeholder 줄바꿈 적용 (\n)
- content overflow-y 제거 → Select 드롭다운 아래 방향 열림 수정
- Select placeholder 색상 var(--text-secondary) 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 없음 모달에서 버튼 제거 — 페이지 블로킹만 유지

확인 버튼 클릭 시 이동하지 않고 Header 뒤로가기로만 탈출 가능

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 기본값 romance 적용, 모달 확인 버튼 복원

- searchParams에 카테고리 없을 시 임시로 romance 기본값 사용
- 모달 확인 버튼 클릭 시 router.back() 복원
- TODO: 이전 페이지 카테고리 데이터 연동 후 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 커스텀 드롭다운 교체 및 Textarea focus 스타일 제거

- Select: 네이티브 select → 커스텀 드롭다운 (항상 아래 방향 열림)
- Select: placeholder 색상 --text-secondary 적용 (option 색 영향 없음)
- Select: 아이콘 회전 애니메이션 추가
- Textarea: focus 시 border-color 변경 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: Button 좌우 패딩 16 → 12으로 조정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: SCSS import 상대경로 → 절대경로(@/) 변환 및 컨벤션 문서 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 접근성 및 스타일 개선

- ul 기본 margin 리셋
- hasValue를 options.find 기준으로 판단 (빈 문자열 오인 방지)
- aria-invalid / aria-describedby 연결로 보조기기 지원
- 키보드 내비게이션 추가 (ArrowUp/Down, Enter/Space, Escape)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: dispute 생성 조건을 active room 전체로 완화 (ONE_TO_ONE 제한 제거)

혼자서도 판결 가능한 흐름을 지원하기 위해
room.roomMode !== 'ONE_TO_ONE' 체크를 제거하고
CLOSED/EXPIRED 방만 차단하도록 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select id 안정화, 빈 options 가드, Tab 기본 포커스 이동 허용

- resolvedId를 label 문자열 대신 useId() 기반으로 고정
- option id를 value 대신 index 기반으로 변경
- Enter/Space 시 options 길이 가드 추가 (크래시 방지)
- Tab은 preventDefault 제거 — 닫기만 하고 포커스 이동은 브라우저에 위임

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독 판결 MVP 포함 및 관련 정책 업데이트 (#51)

- Section 1: 단독 판결 / 1:1 판결 흐름 분리 명시
- Section 2: 단독 판결을 MVP 포함으로 이동, MVP 제외에서 제거
- Section 3: AI 대화방 정책 수정 (ai_chat/invite_ready 상태 단독 판결 허용)
- Section 3: 단독 판결 vs 1:1 판결 제공 결과 비교 섹션 추가
- Section 14: 단독 판결 관련 STOP Condition 항목 제거

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Feature/verdict record display - 캘린더 페이지 ui 제작  (#41)

* feat : 다이어리 (감정일기 , 사건기록)탭분리

* feat : 달력 ui 커스텀 추가 및 감정일기 사건기록 분기처리

* refactor:  및 캘린더 페이지구조 개선 (리뷰 피드백 반영)

* feat : 감정일기카드 컴포넌트 구현

* fix: build 에러 ( 임시 페이지 )

* refactor: 감정일기 컴포넌트 SCSS 모듈 적용 및 믹스인 토큰 사용

* feat: 달력 페이지 UI 구현 및 스타일 정리

- MUI DateCalendar 커스텀
- 감정일기 / 사건기록 탭 전환 구조 구현
- EmotionDiaryList, RecordList 빈 상태 UI 추가
- DiaryCard mixin 적용 (text-title-s, text-body-s, text-label-s)
- 인라인 style 제거 → SCSS 모듈로 분리
- outsideCurrentMonth 감정 아이콘 노출 차단
- 새 일기 FAB 버튼 추가 (감정일기 탭 전용)
- 불필요한 파일 삭제 (DiaryMode, EmotionDiaryCard 등)

* style : EmotionDiaryList.moulde 스타일 수정

* feat: 달력 RecordList에 CaseCard 연동 및 스타일 개선

* Update model name from 'gpt-5.5' to 'gemini-2.5-flash'

seed.ts Ai modelName 수정

---------

Co-authored-by: 배근영 <bgy09270@naver.com>

* feat: 사건작성(진술서) 페이지 구현 및 욕설 감지 필터 연동 (#49)

* feat: 사건작성 페이지 구현 (disputes/[id]/statement)

- 사건 카테고리 선택 (연애/직장/친구/가족)
- MBTI 선택 드롭다운
- 진술 내용 입력 (최대 1000자)
- 진술저장 버튼 (내용 입력 시 활성화)
- TODO: 진술 저장 API 연결

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 사건작성 페이지 카테고리/간격/드롭다운 수정

- 카테고리를 searchParams에서 읽어 하나만 표시 (비상호작용)
- 카테고리 없을 시 모달 표시 후 이전 페이지로 이동
- Select/Textarea 사이 간격 8px (statementGroup)
- label/Select 사이 간격 16px 유지
- Textarea placeholder 줄바꿈 적용 (\n)
- content overflow-y 제거 → Select 드롭다운 아래 방향 열림 수정
- Select placeholder 색상 var(--text-secondary) 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 없음 모달에서 버튼 제거 — 페이지 블로킹만 유지

확인 버튼 클릭 시 이동하지 않고 Header 뒤로가기로만 탈출 가능

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 기본값 romance 적용, 모달 확인 버튼 복원

- searchParams에 카테고리 없을 시 임시로 romance 기본값 사용
- 모달 확인 버튼 클릭 시 router.back() 복원
- TODO: 이전 페이지 카테고리 데이터 연동 후 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 커스텀 드롭다운 교체 및 Textarea focus 스타일 제거

- Select: 네이티브 select → 커스텀 드롭다운 (항상 아래 방향 열림)
- Select: placeholder 색상 --text-secondary 적용 (option 색 영향 없음)
- Select: 아이콘 회전 애니메이션 추가
- Textarea: focus 시 border-color 변경 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: Button 좌우 패딩 16 → 12으로 조정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: SCSS import 상대경로 → 절대경로(@/) 변환 및 컨벤션 문서 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 접근성 및 스타일 개선

- ul 기본 margin 리셋
- hasValue를 options.find 기준으로 판단 (빈 문자열 오인 방지)
- aria-invalid / aria-describedby 연결로 보조기기 지원
- 키보드 내비게이션 추가 (ArrowUp/Down, Enter/Space, Escape)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: dispute 생성 조건을 active room 전체로 완화 (ONE_TO_ONE 제한 제거)

혼자서도 판결 가능한 흐름을 지원하기 위해
room.roomMode !== 'ONE_TO_ONE' 체크를 제거하고
CLOSED/EXPIRED 방만 차단하도록 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select id 안정화, 빈 options 가드, Tab 기본 포커스 이동 허용

- resolvedId를 label 문자열 대신 useId() 기반으로 고정
- option id를 value 대신 index 기반으로 변경
- Enter/Space 시 options 길이 가드 추가 (크래시 방지)
- Tab은 preventDefault 제거 — 닫기만 하고 포커스 이동은 브라우저에 위임

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Textarea 바이트 카운팅 및 filterMessage prop 추가

- 한글 2바이트/ASCII 1바이트 기준으로 글자 수 계산
- maxLength 초과 시 바이트 기준으로 자동 truncate
- filterMessage prop 추가 — 욕설 차단 메시지 동적 표시
- border 색상 변경은 error prop에만 적용 (filter는 border 유지)
- filter-warning 텍스트: Body-S + var(--text-danger)
- field gap 8 → 10px (Figma 기준)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 욕설 감지 필터 구현 (Gemini 2.5 Flash)

- moderation.ts: Gemini 2.5 Flash 기반 욕설/개인정보 감지
  - isBlocked: 욕설·혐오·위협 차단 (보수적 기준)
  - hasPersonalInfo: 개인정보 경고 (차단 없음)
  - fail-open: Gemini 실패 시 pending 상태로 저장
- statements/route.ts: 진술 저장 API
  - 모더레이션 통과 후 upsert + ModerationLog 트랜잭션
  - 차단 시 ModerationLog만 기록, 저장 없이 422 반환
  - dev bypass: 개발 환경에서 세션 없이 모더레이션 테스트 가능
- page.tsx: handleSave 연결, filterMessage 상태, 개인정보 경고 모달
- StatementPage.module.scss: 모달 스타일, Stylelint 공백 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: PR #49 코드리뷰 수정 — MBTI 연동, 파싱 에러, 인젝션, 타임아웃

- MBTI: GET /api/user/me 신규 생성, statement 페이지 마운트 시 user.mbti 초기화
- MBTI: handleSave body에 mbti 포함, statements route에서 user.mbti 업데이트 (트랜잭션)
- statement/page.tsx: res.json() 파싱 실패를 별도 try-catch로 분리
- Textarea.tsx: e.target.value 직접 변경 → Object.assign으로 새 이벤트 객체 전달
- moderation.ts: content 삽입 전 < > HTML 이스케이프 (프롬프트 인젝션 방지)
- moderation.ts: Promise.race() 기반 10초 타임아웃 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: user/me route catch 블록에 에러 로깅 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: judge route 1인 판결 허용 — isSolo 분기 및 rollback 상태 수정

- 2인: BOTH_SUBMITTED 상태 확인 유지
- 1인: 진술 제출 여부만 확인 (statements.length > 0)
- 롤백 대상을 하드코딩된 BOTH_SUBMITTED → previousStatus로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 카카오 로그인 기능 구현 (#50)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 absolute 배치

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 카카오 로그인 기능 구현

- 로그인 페이지 UI 및 카카오 signIn 버튼 연결
- @auth/prisma-adapter 설치 및 authOptions에 적용
- 최초 로그인 시 kakaoId, nickname, termsAgreedAt 자동 설정
- 닉네임 자동 생성 유틸 추가 (~하는부엉이 + 4자리 난수)
- middleware 추가: 비인증 사용자 /login 리다이렉트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 로그인 페이지 및 인증 로직 개선

- SCSS import 절대경로(@/) 수정
- 캐릭터 이미지 Next/Image fill → img 태그로 변경
- 이용약관/개인정보처리방침 링크(/terms, /privacy) 추가 및 스타일 적용
- 닉네임 유니크 제약(@unique) 추가 및 충돌 재시도 로직 구현 (최대 10회)
- middleware matcher 패턴 보완 (/login-help 등 우회 경로 차단)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: disclaimer mixin 적용, nickname 유실 복구 및 fallback 랜덤화

- .disclaimer에 @include m.text-caption mixin 적용
- 유실된 nickname.ts 복구
- fallback 닉네임 Date.now() → 랜덤 8자리 숫자로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독/1:1 판결 공통 진입 흐름 반영 및 관련 문서 일괄 수정 (#54)

- 단독 판결과 1:1 판결이 완전히 분리된 진입이 아니라
  AI 대화방 → 진술저장 → [분기] → disputes/[id]/statement 경로를 공통으로 거침
- CLAUDE.md: 핵심 서비스 흐름 분기 구조로 수정, 단독 판결 MVP 포함 반영,
  AI 대화방 정책 단독/1:1 병행 기술, dispute_status 단독 경로 추가
- PROJECT_DECISIONS.md: 흐름·MVP포함·MVP제외·dispute_status 동기화
- STATUS_TRANSITION.md: 단독 판결 경로(draft→judging→judged) 추가
- DISPUTE.md: 상태 전이 단독/1:1 경로 분리 기술, 주의사항 확정 내용 반영
- ROOM.md: 진술저장 후 분기 흐름 포함 기능에 명시

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Login 페이지 hydration removeChild 에러 수정 (#55)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지),…
evenif99 added a commit that referenced this pull request Jun 25, 2026
* chore: initialize project folder structure (#1)

* chore: initialize project folder structure

- Add base directory layout for Next.js + domain-driven architecture
- Add .gitkeep to track empty directories in git
- Exclude MVP out-of-scope domains (shop, points, user-items)
- No implementation files included, structure only

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update README.md

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add CLAUDE.md with project rules and work guidelines (#2)

- Add project overview and MVP scope definition
- Add fixed product rules (categories, AI chat policy, judgement output)
- Add architecture, domain scope, and state transition rules
- Add auth/security, DB, frontend state, API, logging rules
- Add Git workflow, Claude work process, STOP conditions
- Add approval-required list and required reference documents

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: setup project config and install dependencies (#3)

- Add package.json with Next.js 15, React 19, TypeScript stack
- Add next.config.ts (minimal Next.js 15 config)
- Add tsconfig.json (strict mode, @/* path alias)
- Add eslint.config.mjs (next/core-web-vitals + next/typescript)
- Add .prettierrc and .prettierignore
- Add .gitignore (node_modules, .next, .env.local, etc.)
- Add .env.example (key names only, no real values)
- Add prisma/schema.prisma (generator + datasource only)
- Add data/mock/db.json (health check stub for json-server)
- Add docs/TECH_STACK.md (package list and selection rationale)
- Update README.md with run commands and env guide

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add base documentation structure (#4)

- Add PROJECT_DECISIONS.md (MVP scope, architecture, security principles)
- Add guides/CLAUDE_WORKFLOW.md (work process, STOP conditions, approval rules)
- Add guides/GIT_WORKFLOW.md (branch naming, commit convention, workflow)
- Add guides/PR_RULES.md (PR target, title rules, review criteria)
- Add guides/ENV_GUIDE.md (Vercel env pull, .env.example management)
- Add guides/CODING_CONVENTION.md (naming, state management, folder rules)
- Add db/STATUS_TRANSITION.md (room_mode, dispute_status transitions)
- Add db/PRISMA_MAPPING.md (snake_case/camelCase mapping rules)
- Add db/MASTER_DATA.md (categories, result types, DB master principles)
- Add domains/README.md (domain list, MVP scope, writing guidelines)
- Add domains/_DOMAIN_TEMPLATE.md (template for domain docs)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add domain document drafts for all MVP domains (#5)

- Add AUTH.md (kakao login, terms, session management)
- Add COMMON.md (error handling, logging, common response)
- Add ROOM.md (AI chat room, invite link, room_mode transitions)
- Add PERSONAL_ANALYSIS.md (AI-based personal conflict analysis)
- Add DISPUTE.md (1:1 mediation, roles, statements, dispute_status)
- Add JUDGEMENT.md (AI judgement, Gemini API, result card)
- Add GIFT.md (gift recommendation after judgement)
- Add USER.md (mypage, profile, bottom tab)
- Add CALENDAR.md (date-based record marking, monthly summary)
- Add DIARY.md (emotion diary, author-only access, content protection)
- Add STATISTICS.md (anonymous aggregation, summary components)
- Add SHOP_FUTURE.md (v2.0 planned, MVP excluded)
- Add POINTS_FUTURE.md (v2.0 planned, MVP excluded)
- Add USER_ITEMS_FUTURE.md (v2.0 planned, MVP excluded)

All documents are draft templates with TODO markers for assignees.
No implementation, no API routes, no schema changes.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: add Next.js App Router entry files and SCSS base structure (#6)

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Infra/init next setup (#7)

* infra: add Next.js App Router entry files and SCSS base structure

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: resolve ESLint and TypeScript config warnings

- eslint.config.mjs: ignore next-env.d.ts and .next/** (auto-generated by Next.js, triple-slash reference false positive)
- tsconfig.json: remove deprecated baseUrl option (TypeScript 5.x+, paths works without baseUrl)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update README.md (#8)

* docs(infra): confirm Supabase as project infrastructure (#9)

* chore(github): add collaboration templates and policy (#10)

* docs(env): document environment variable management (#11)

* docs(calendar): confirm MUI date picker usage (#12)

달력 UI 라이브러리로 MUI X Date Pickers + Day.js 사용을 확정하고
관련 문서(TECH_STACK, PROJECT_DECISIONS, CODING_CONVENTION, CALENDAR, DIARY, CLAUDE.md)에 반영한다.

* chore(deps): install MUI X Date Pickers and peer dependencies (#13)

달력 UI 구현을 위해 MUI X Date Pickers 및 필수 peer dependency를 설치한다.
@mui/material@9.1.1, @emotion/react@11.14.0, @emotion/styled@11.14.1,
@mui/x-date-pickers@9.5.0, dayjs@1.11.21

* Update README.md (#15)

* fix: resolve ESLint and TypeScript config warnings (#20)

* infra: add Next.js App Router entry files and SCSS base structure

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: resolve ESLint and TypeScript config warnings

- eslint.config.mjs: ignore next-env.d.ts and .next/** (auto-generated by Next.js, triple-slash reference false positive)
- tsconfig.json: remove deprecated baseUrl option (TypeScript 5.x+, paths works without baseUrl)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: add MVP Prisma schema with NextAuth and TALKY-OWL models (#21)

- datasource: add directUrl for Supabase connection pooler support
- enums: CategoryGroup, RoomMode, DisputeStatus, ParticipantRole, etc.
- NextAuth models: User (with TALKY-OWL fields), Account, Session, VerificationToken
- core models: DisputeRoom, RoomAiConversation, RoomAiMessage
- dispute models: Dispute, DisputeParticipant, DisputeStatement
- judgment models: AiJudgment, JudgmentResultCard
- gift models: GiftRecommendation, GiftRecommendationItem
- feature models: EmotionDiary, CalendarRecord
- master data: ConflictTypeGroup, ConflictTypeDetail (DB-based, no enum hardcoding)
- log models: AuditLog, ApiErrorLog, ModerationLog, RoomAccessLog, UserDeletionLog
- .env.example: add DIRECT_URL for Supabase directUrl
- v2.0 TODO: ShopItem, PointTransaction, UserItem, DisputeStatistic excluded

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: align project structure with guide v2 (#22)

folders added:
- src/components/{personal-analysis,room,dispute,judgement,calendar,diary,statistics,gift}
- src/app/api/auth/[...nextauth]
- src/app/api/v1/{users,personal-analyses,rooms,disputes,statements,calendar,diary,statistics,cron}

files added:
- prisma/seed.ts (placeholder for ConflictTypeGroup master data)

docs updated (minimal):
- docs/domains/COMMON.md: add log table list, judgement_logs TODO note
- docs/domains/JUDGEMENT.md: clarify Storage is MVP-excluded scaffolding
- docs/guides/ENV_GUIDE.md: clarify Supabase Storage vars are MVP-excluded

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: rename src/app/page to src/app/(page) for correct Next.js route group (#23)

src/app/page/ (괄호 없음)는 /page/* URL segment를 생성하므로,
Next.js App Router route group 문법인 src/app/(page)/로 변경한다.
URL은 /landing, /home 등으로 노출되어야 하며 /page/... 가 아니다.

관련 문서 내 경로 참조도 모두 업데이트 (CLAUDE.md, docs/domains/*, docs/guides/*).

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* [Style] 디자인 토큰 및 전역 스타일 설정 (#25)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 디자인 시스템 기반 설정 (#27)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: rem 스케일 토큰 추가 및 타이포그래피 변수 rem 참조로 전환

- Rem scale 섹션 추가 (0.25rem ~ 30rem)
- 폰트 토큰에서 누락된 0.875rem(14px), 1.125rem(18px) 추가
- font-size, line-height 변수를 rem 스케일 변수 참조로 전환
- rem 스케일을 typography 섹션보다 상단으로 이동 (선언 순서)
- 컴포넌트 width/height 대응을 위해 큰 단위(9rem~30rem) 포함

Co-Authored-By: Claude <noreply@anthropic.com>

* style: r() 함수 분리 및 타이포그래피 변수 함수 기반으로 전환

- _functions.scss 신규 추가 — px → rem 변환 함수 r() 단독 관리
- _variables.scss에서 rem 스케일 변수 제거, fn.r() 참조로 전환
- _mixins.scss에 functions @use 추가
- 순환 참조 없이 variables → functions → (없음) 단방향 의존성 구성

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Feature/common component jw (#28)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* fix: :root {} 시맨틱 토큰을 _global.scss로 분리 (#29)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: rem 스케일 토큰 추가 및 타이포그래피 변수 rem 참조로 전환

- Rem scale 섹션 추가 (0.25rem ~ 30rem)
- 폰트 토큰에서 누락된 0.875rem(14px), 1.125rem(18px) 추가
- font-size, line-height 변수를 rem 스케일 변수 참조로 전환
- rem 스케일을 typography 섹션보다 상단으로 이동 (선언 순서)
- 컴포넌트 width/height 대응을 위해 큰 단위(9rem~30rem) 포함

Co-Authored-By: Claude <noreply@anthropic.com>

* style: r() 함수 분리 및 타이포그래피 변수 함수 기반으로 전환

- _functions.scss 신규 추가 — px → rem 변환 함수 r() 단독 관리
- _variables.scss에서 rem 스케일 변수 제거, fn.r() 참조로 전환
- _mixins.scss에 functions @use 추가
- 순환 참조 없이 variables → functions → (없음) 단방향 의존성 구성

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: :root {} 시맨틱 토큰을 _global.scss로 분리

_variables.scss에 :root {}가 있으면 module.scss에서 @use 시
CSS Modules 'not pure' 에러 발생.
SCSS 변수는 _variables.scss, CSS 출력은 _global.scss로 분리.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): 공통 UI 컴포넌트 추가 및 MUI 정책 적용 (#30)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 목록 공통 UI 컴포넌트 추가 (Tab, StatusBadge) (#31)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 위치 수정 (#32)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 absolute 배치

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 공통 및 dispute·judgment DTO 타입 정의

- ApiResponse, ApiError, ApiFieldError, CategoryGroup (common.ts)
- DisputeDto, CreateDisputeRequest, DisputeListResponse 등 (dispute.ts)
- AiJudgmentDto, CreateAiJudgmentRequest 등 (judgment.ts)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: dispute 도메인 공유 상수·헬퍼·mapper 추가

- VALID_CATEGORY_GROUPS, IMMUTABLE_DISPUTE_STATUSES 상수 (constants/dispute.ts)
- getSessionUserId NextAuth 세션 헬퍼 (auth/session.ts)
- toAiJudgmentDto 공유 mapper (judgement/judgment.mapper.ts)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 목록 조회·생성·수정·삭제 API 구현

- GET /api/v1/disputes — 참여 사건 목록, categoryGroup 필터, 페이지네이션
- POST /api/v1/disputes — 사건 생성 + role_a 참여자 트랜잭션 등록
- GET /api/v1/disputes/:id — 사건 상세 조회
- PATCH /api/v1/disputes/:id — 사건 수정 (role_a 전용, 변경 불가 상태 차단)
- DELETE /api/v1/disputes/:id — 사건 소프트 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: AI 판결 요청·결과 조회 API 구현

- POST /api/v1/disputes/:id/judge — AI 판결 요청, JUDGING 상태 잠금으로 멱등성 보장
- GET /api/v1/disputes/:id/result — 판결 결과 조회 (참여자 전용)
- AI 모듈 미구현 구간은 TODO 주석으로 마킹, 완료 전까지 503 반환

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 공통 UI 컴포넌트 - StatusBadge, Tab, 진행 상태 (#33)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Prisma 클라이언트, NextAuth Kakao OAuth 설정 및 핸들러 추가

- src/lib/db/index.ts — Prisma 전역 싱글턴
- src/lib/auth/index.ts — NextAuth authOptions (Kakao OAuth, session user.id 매핑)
- src/app/api/auth/[...nextauth]/route.ts — NextAuth GET/POST 핸들러
- @mui/icons-material 패키지 설치 (빌드 에러 해결)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: 빌드 스크립트에 prisma generate 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: MVP 전체 API 명세서 작성 (API_SPEC.md) (#36)

* docs: MVP 전체 API 명세서 작성 (API_SPEC.md)

- 도메인 문서 및 기존 합의 기반 MVP API 명세 초안 작성
- 공통 응답 구조, 에러 코드 체계 정의
- Auth / User / Room / Dispute / Statement / Judgement / Diary / Calendar / Statistics / Gift / Cron 도메인 API 명세 포함
- 경로 충돌 항목 (withdraw, judge/result, diary 경로) 확정 필요 사항으로 명시
- 미확정 TODO 항목 섹션 7에 전체 정리
- MVP 제외 항목 (shop, points, 단독판결, 독립 통계 화면 등) 명시적으로 제거 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독 판결 MVP 포함 반영 및 라우트 주석 명확화

- 단독 판결(상대방 없는 AI 판결)을 MVP 포함 범위로 변경
- Personal Analysis 섹션에 단독 판결 API 초안 추가 (POST/GET /api/v1/personal-analyses)
- 라우트 트리 personal-analyses 디렉터리 구조 구체화
- /auth/withdraw route.ts 주석을 경로 충돌 상호 참조가 명확한 형태로 수정
  (경로 충돌 → /auth/withdraw vs DELETE /users/me)
- MVP 제외 목록에서 단독 판결 항목 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 카카오 로그인 시 약관 동의 자동 간주 정책 반영

- 카카오 OAuth 로그인 완료를 약관 동의로 간주
- 별도 약관 동의 페이지 이동 플로우 제거
- 확정 필요 항목에서 약관 동의 기준 항목 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 도메인 API 목록 중복 제거 및 회원탈퇴 경로 확정

- docs/domains/*.md 8개 파일의 API 목록 섹션을 docs/API_SPEC.md 참조로 교체
  (AUTH, USER, ROOM, DISPUTE, JUDGEMENT, DIARY, CALENDAR, STATISTICS)
- API_SPEC.md 단일 소스 체계 확립
- 회원탈퇴 경로 DELETE /api/v1/users/me 채택 확정
  - §3 요약표, §4.1·§4.2 상세, §5 라우트 트리, §6 충돌 목록, §7 체크리스트 반영
  - /auth/withdraw 라우트 제거, /users/me route.ts에 DELETE 추가
- CLAUDE_WORKFLOW.md PR 템플릿 준수 문구 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 날짜 포맷 및 Pagination 구조 확정 반영

- 날짜/시간 포맷 ISO 8601 (YYYY-MM-DDTHH:mm:ssZ) 확정
- Pagination 공통 구조 확정
  - data 필드: items 배열
  - page 필드: page / totalPages / sortBy / isNext
- 섹션 7 확정 필요 항목 두 개 체크 처리
- Room 목록, Diary 목록 섹션 Pagination 참조로 갱신

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: Pagination 구조에 size / sort / hasNext / hasPrevious 추가

- size: 한 번에 가져오는 항목 수
- sort: 정렬 방향 (asc | desc)
- isNext → hasNext로 변경 (다음 페이지 존재 여부)
- hasPrevious 추가 (이전 페이지 존재 여부)
- §7 체크리스트 항목 갱신

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 날짜 포맷 코드블록 언어 지정자 추가 (MD040)

코드래빗 지적 사항 반영 — 언어 미지정 펜스 코드블록에 text 지정자 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 통계 API 비로그인 공개 조회로 변경

홈 화면 진입 시 비로그인 회원도 통계 조회 가능하도록 수정
- GET /api/v1/statistics/summary: 🔒 → 공개
- GET /api/v1/statistics/top-types: 🔒 → 공개
- §3 요약표, §4.9 상세 명세 인증 표기 및 설명 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 목록 응답 예시에 page 객체 추가 (코드래빗 지적 반영)

- GET /api/v1/rooms 응답 예시에 page 객체 추가
- GET /api/v1/diary 응답 예시에 page 객체 추가
- GET /api/v1/statistics/top-types 응답 예시에 page 객체 추가
  (Top5 고정 목록 특성 반영: size=5, totalPages=1, hasNext=false)
- 코드래빗 제안의 구버전 필드(isNext) 대신 확정 구조(hasNext/hasPrevious/size/sort) 적용
- §7 Room Pagination 항목 체크 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Spinner, Avatar, AvatarGroup 공통 컴포넌트 추가 (#37)

* chore: 정적 이미지 에셋 추가 및 정리

주요 페이지용 캐릭터 이미지 추가 및 공통 에셋 정리.
gift, loading 캐릭터를 common에서 characters로 이동하여
캐릭터 이미지를 한 폴더로 통합.

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: Spinner 공통 컴포넌트 추가

캐릭터 로딩 이미지를 중앙에 배치한 88x88 스피너 컴포넌트 추가.
트랙(배경 원)과 애니메이션 링을 분리하여 각각 border-default, bg-brand 색상 적용.

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: Avatar, AvatarGroup 공통 컴포넌트 추가

MUI Avatar, AvatarGroup 래핑 컴포넌트 추가.
size prop으로 s/m/l 사이즈 조절, src prop으로 프로필 사진 지원.
global.scss에 --color-white, --color-black CSS 변수 추가.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: Avatar Context로 AvatarGroup size 전달 및 토큰 수정

AvatarGroup size prop이 자식 Avatar에 적용 안 되는 버그 수정.
Context를 통해 size를 내려주고 Avatar가 그룹 size를 우선 적용.
color 토큰 --color-white를 --text-inverse로 교체.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: Avatar src 없을 때 기본 썸네일 이미지로 fallback 처리

Co-Authored-By: Claude <noreply@anthropic.com>

* test: Spinner, Avatar, AvatarGroup 테스트 페이지 추가

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

* feat: 공통 UI 컴포넌트 - CategoryFilter, CategoryIcon, Tab, StatusBadge (#38)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 공통 컴포넌트 생성

- 전체/연애/직장/친구/가족 카테고리 필터 구현
- 아이콘 박스 44x44, border-radius 8, 아이콘 24x24
- 선택 상태: icon-primary bg / 미선택: bg-disabled
- MUI icons 사용 (GridViewRounded, Favorite, BusinessCenter, Diversity3, FamilyRestroom)
- Category 타입 export

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Tab 라벨 폰트 스타일 명시

- item.label을 span.label로 래핑
- Body-M 기준 font-size 16, line-height 28 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: @mui/icons-material 패키지 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 스타일 및 single 모드 적용

- 선택: bg-page + border-brand(1px) + icon-primary + 텍스트 bold
- 미선택: bg-page + border-default(1px) + icon-secondary + 텍스트 regular
- mode prop 추가 (filter 기본값 / single: 선택된 박스 하나만 표시)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 타입을 DB CategoryGroup 기준으로 통일

## 수정 배경

CategoryIcon, CategoryFilter가 한국어 문자열('연애', '직장' 등)을 타입으로 사용하고 있어
API/DB의 CategoryGroup('romance', 'work' 등)과 불일치가 발생.
페이지에서 연결 시 별도 변환 레이어가 필요해지는 문제를 사전 차단.

## 변경 파일별 수정 내용

### CategoryIcon.tsx
- CategoryWithoutAll 타입 제거 → @/types/common의 CategoryGroup 직접 사용
- 아이콘/레이블/컬러 맵 키를 한국어 → 영문 DB 값으로 변경
  (romance, work, friend, family)
- CATEGORY_LABEL_MAP export 추가 (CategoryFilter에서 레이블 참조용)

### CategoryFilter.tsx
- Category 타입을 'all' | CategoryGroup으로 변경 (기존: 한국어 문자열)
- CATEGORIES 배열에 label 필드 추가, CATEGORY_LABEL_MAP에서 참조
- 전체 키를 '전체' → 'all'로 변경 (API 필터 미적용 값과 일치)

### CaseCard.tsx (타팀원 파일 수정)
- 수정 이유: CATEGORY_EMOJI 맵 키가 대문자('ROMANCE')였으나
  API 응답은 소문자('romance')로 내려와 emoji가 항상 '📋' fallback만 표시되는 버그 존재
- 해결 방법: emoji 방식 전체 제거, CategoryIcon 컴포넌트로 교체
- categoryGroup prop 타입을 string → CategoryGroup으로 명시
- categoryGroup 미전달 시 아이콘 미표시 처리 (optional 유지)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update src/components/ui/CategoryIcon.tsx

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: CategoryIcon 중복 import 제거 및 CategoryFilter discriminated union 타입 에러 수정

- CategoryIcon: FamilyRestroomIcon, CategoryGroup 중복 import 제거
- CategoryFilter: discriminated union(CodeRabbit 피드백 반영) 유지하면서
  props 전체로 받아 props.mode로 narrowing 처리해 타입 에러 해결
  (mode='single'일 때 onChange가 CategoryGroup을 기대하는 문제)
- Tab.module.scss: height → min-height 변경 (유연한 높이 대응)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard 카테고리 아이콘을 제목 왼쪽 인라인으로 이동

- card__header 구조 변경: titleRow(아이콘+제목)와 badge를 좌우 배치
- card__titleRow 추가: flex row, align-items center, gap 6px
- 아이콘이 제목 위에 쌓이던 문제 수정 → 제목 왼쪽에 인라인 배치
- card__icon: font-size/line-height(이모지 잔재) → display:flex 로 변경
- card__title: margin-bottom 제거(card__header margin-bottom으로 대체)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 공통 컴포넌트 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard titleRow flex 축소 보완 (min-width: 0, flex: 1)

긴 제목에서 card__titleRow가 축소되지 않아 배지가 밀리는 문제 방지.
card__header가 space-between일 때 titleRow가 flex: 1로 가용 공간을 차지하고
min-width: 0으로 내부 콘텐츠가 넘치지 않도록 제약.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix(common): BottomNavigation 아이콘 MUI MD2 기본 스타일로 수정 (#39)

* fix(common): BottomNavigation 아이콘을 MUI MD2 기본 스타일로 수정

- HomeRounded → Home
- GavelRounded → MenuBook (사건기록 아이콘 자체 변경)
- CalendarMonthRounded → CalendarMonth
- PersonRounded → Person
디자인 시안 기준 MD2 filled 아이콘으로 통일

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: BottomNavigation 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): BottomNavigation 활성 탭 레이블 색상 black-700으로 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): BottomNavigation 테스트 스크린샷 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: wjdalss21 <jungxmin21@gmail.com>

* feat: 사건·방 도메인 타입 정의 및 API 구현 (#40)

* feat: room DTO 타입 정의

- RoomMode, RoomDto, CreateRoomRequest, RoomListResponse

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 방 목록 조회·생성·상세 조회·종료·삭제 API 구현

- GET  /api/v1/rooms — 내 방 목록 조회 (페이지네이션)
- POST /api/v1/rooms — AI 대화방 생성 (roomMode = ai_chat)
- GET  /api/v1/rooms/:id — 방 상세 조회
- POST /api/v1/rooms/:id/close — 방 종료 (closedAt + roomMode = closed)
- DELETE /api/v1/rooms/:id — 방 소프트 삭제 (deletedAt + roomMode = deleted)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 방 목록 페이지네이션 파라미터 NaN 방어 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: API 라우트 경로 v1 버전 세그먼트 제거 (#42)

* fix: API 라우트 경로에서 v1 버전 세그먼트 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 라우트 핸들러 주석 경로 v1 제거 (/api/v1/ -> /api/)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): 서비스 흐름 기반 문서 구조 수정 및 페이지 문서 생성 (#43)

* fix(docs): 서비스 흐름 기반 문서 구조 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): PAGES.md 코드 블록 언어 명시 추가 (MD040)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: personal-analyses 페이지 및 API 폴더 삭제 (#45)

* fix: personal-analyses 페이지 및 API 폴더 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): personal-analysis 도메인 참조 MD 문서 일괄 정리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 API 구현 (GET /api/statistics/categories) (#44)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 공통 컴포넌트 생성

- 전체/연애/직장/친구/가족 카테고리 필터 구현
- 아이콘 박스 44x44, border-radius 8, 아이콘 24x24
- 선택 상태: icon-primary bg / 미선택: bg-disabled
- MUI icons 사용 (GridViewRounded, Favorite, BusinessCenter, Diversity3, FamilyRestroom)
- Category 타입 export

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Tab 라벨 폰트 스타일 명시

- item.label을 span.label로 래핑
- Body-M 기준 font-size 16, line-height 28 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: @mui/icons-material 패키지 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 스타일 및 single 모드 적용

- 선택: bg-page + border-brand(1px) + icon-primary + 텍스트 bold
- 미선택: bg-page + border-default(1px) + icon-secondary + 텍스트 regular
- mode prop 추가 (filter 기본값 / single: 선택된 박스 하나만 표시)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 타입을 DB CategoryGroup 기준으로 통일

## 수정 배경

CategoryIcon, CategoryFilter가 한국어 문자열('연애', '직장' 등)을 타입으로 사용하고 있어
API/DB의 CategoryGroup('romance', 'work' 등)과 불일치가 발생.
페이지에서 연결 시 별도 변환 레이어가 필요해지는 문제를 사전 차단.

## 변경 파일별 수정 내용

### CategoryIcon.tsx
- CategoryWithoutAll 타입 제거 → @/types/common의 CategoryGroup 직접 사용
- 아이콘/레이블/컬러 맵 키를 한국어 → 영문 DB 값으로 변경
  (romance, work, friend, family)
- CATEGORY_LABEL_MAP export 추가 (CategoryFilter에서 레이블 참조용)

### CategoryFilter.tsx
- Category 타입을 'all' | CategoryGroup으로 변경 (기존: 한국어 문자열)
- CATEGORIES 배열에 label 필드 추가, CATEGORY_LABEL_MAP에서 참조
- 전체 키를 '전체' → 'all'로 변경 (API 필터 미적용 값과 일치)

### CaseCard.tsx (타팀원 파일 수정)
- 수정 이유: CATEGORY_EMOJI 맵 키가 대문자('ROMANCE')였으나
  API 응답은 소문자('romance')로 내려와 emoji가 항상 '📋' fallback만 표시되는 버그 존재
- 해결 방법: emoji 방식 전체 제거, CategoryIcon 컴포넌트로 교체
- categoryGroup prop 타입을 string → CategoryGroup으로 명시
- categoryGroup 미전달 시 아이콘 미표시 처리 (optional 유지)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update src/components/ui/CategoryIcon.tsx

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: CategoryIcon 중복 import 제거 및 CategoryFilter discriminated union 타입 에러 수정

- CategoryIcon: FamilyRestroomIcon, CategoryGroup 중복 import 제거
- CategoryFilter: discriminated union(CodeRabbit 피드백 반영) 유지하면서
  props 전체로 받아 props.mode로 narrowing 처리해 타입 에러 해결
  (mode='single'일 때 onChange가 CategoryGroup을 기대하는 문제)
- Tab.module.scss: height → min-height 변경 (유연한 높이 대응)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard 카테고리 아이콘을 제목 왼쪽 인라인으로 이동

- card__header 구조 변경: titleRow(아이콘+제목)와 badge를 좌우 배치
- card__titleRow 추가: flex row, align-items center, gap 6px
- 아이콘이 제목 위에 쌓이던 문제 수정 → 제목 왼쪽에 인라인 배치
- card__icon: font-size/line-height(이모지 잔재) → display:flex 로 변경
- card__title: margin-bottom 제거(card__header margin-bottom으로 대체)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 공통 컴포넌트 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard titleRow flex 축소 보완 (min-width: 0, flex: 1)

긴 제목에서 card__titleRow가 축소되지 않아 배지가 밀리는 문제 방지.
card__header가 space-between일 때 titleRow가 flex: 1로 가용 공간을 차지하고
min-width: 0으로 내부 콘텐츠가 넘치지 않도록 제약.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 도메인 서비스 레이어 생성 (statisticsService.ts)

## 생성 이유
통계 API의 DB 쿼리 로직을 Route Handler와 분리하기 위해
도메인 서비스 레이어를 별도 파일로 작성했다.

## 폴더 선택 이유
src/domains/statistics/
- CLAUDE.md §4 아키텍처 원칙에 따라 도메인별 비즈니스 로직은
  src/domains/{domain}/ 에 위치한다.
- statistics는 MVP 도메인 목록에 포함된 독립 도메인이다.
- Route Handler(src/app/api/)는 요청/응답 처리만 담당하고,
  실제 DB 쿼리 로직은 서비스 레이어에서 관리한다.

## 구현 내용

### getSummary()
- 서비스 전체 판결 완료 건수(totalJudgements) 집계
- dispute.status = JUDGED 조건 명시: ai_judgements는 판결 완료 시에만
  생성되지만 의도를 코드에 명시적으로 표현
- deletedAt / anonymizedAt IS NULL: 삭제·익명화된 사건 제외 (CLAUDE.md §7)

### getTopTypes(size = 5)
- ai_judgements.result_conflict_detail_id 기준 GROUP BY COUNT DESC
- 결과 유형 마스터(conflict_type_details)를 JOIN해 detailCode·displayName 반환
- isActive = true 필터: 비활성화된 유형은 통계에서 제외
- percentage 서버 계산: count / total * 100 (소수점 1자리)
  FE에서 별도 계산 없이 바로 사용할 수 있도록 서버에서 내려줌
- prisma.conflictTypeDetail 사용 (prisma.conflictDetail은 스키마에 존재하지 않음)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 API Route Handler 생성 (GET /api/v1/statistics/top-types)

## 생성 이유
statisticsService의 getTopTypes()를 HTTP 엔드포인트로 노출하기 위해
Next.js App Router 기반 Route Handler를 생성했다.

## 폴더 선택 이유
src/app/api/v1/statistics/top-types/
- CLAUDE.md §4 아키텍처 원칙에 따라 API Route는 src/app/api/v1/ 하위에 위치한다.
- API_SPEC.md §4.9 기준 엔드포인트 경로: GET /api/v1/statistics/top-types
- summary 엔드포인트는 현재 MVP 범위에서 불필요하여 top-types만 생성

## 구현 내용
- getServerSession으로 서버에서 직접 세션 검증
  (FE 리다이렉트만으로는 API 직접 호출을 막을 수 없으므로 서버 검증 필수 — CLAUDE.md §7)
- 인증 실패 시 401 UNAUTHORIZED 반환
- getTopTypes(5) 호출 → 판결 완료 기준 Top5 유형 + 비율 반환
- ApiResponse 타입 준수: data/error는 null 아닌 undefined(optional) 사용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: statistics top-types 인증 제거 (메인 페이지 공개 접근 허용)

메인 페이지에서도 통계 차트가 노출되는 익명 집계 데이터이므로
세션 없이 접근 가능하도록 수정.

- getServerSession 및 관련 import 제거
- 401 인증 체크 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: statistics top-types 에러 핸들링 보완

코드래빗 피드백 반영:
- catch {} -> catch (error): 에러 정보 유실 방지
- 타임아웃 감지 후 504 분기 처리
- console.error 로깅 추가 (CLAUDE.md 11 API 오류 로그 대상)
- 세션 체크는 이전 커밋에서 이미 제거됨 (공개 엔드포인트)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: 통계 API 카테고리 기준으로 재설계

- 결과 유형(top-types) → 작성 카테고리(ROMANCE/FAMILY/FRIEND/WORK) 기준으로 변경
- route.ts에 DB 쿼리 직접 작성, statisticsService.ts 제거
- 비율 계산은 프론트 훅(useStatistics)에서 담당
- revalidate = 86400 (하루 1회 재계산)
- src/hooks/ 폴더 신설 및 useStatistics.ts 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 통계 API 서버 측 세션 인증 추가

- GET /api/statistics/categories 진입 시 getServerSession으로 인증 검증
- 미인증 요청 401 UNAUTHORIZED 반환

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* feat: Header variant 분리 (logo/title) 및 홈 화면 적용 (#47)

* feat: 홈 화면 기본 구조 생성 (헤더, 일기 박스)

- 헤더: 세션 유저명 + character-welcome.png 부엉이 이미지
- 일기 박스: 365x88, border black-700 2px, bg primary-100
- TODO: GangwonEduPower 폰트 추가 후 헤더 로고 텍스트 적용 필요

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Header variant 분리 (logo/title) 및 홈 화면 적용

- Header.tsx에 variant prop 추가 (logo | title)
  - logo: 좌측 상단 말해부엉 로고 표시 (66x19, h:56, padding: 16px 20px)
  - title: 기존 뒤로가기 + 페이지 제목 형태 유지
- Header.module.scss에 __logo 스타일 추가
- home/page.tsx에 Header variant='logo' 적용
  - 헤더를 컨테이너 padding 밖으로 분리하여 상단 여백 제거
- home/page.module.scss diaryBox에 align-self: center 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건기록 페이지 생성 및 로고 헤더 적용 (/records)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: diaryBox 고정 폭을 max-width + width 100%로 반응형 처리

- width: 365px → width: 100% + max-width: 365px
- 작은 화면에서 좌우 패딩과 결합 시 오버플로우 방지

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 감정일기 작성 버튼 /diary/new 네비게이션 연결

- 일기 박스 전체를 Link로 변경 (텍스트 + 버튼 모두 클릭 가능)
- diaryBox에 text-decoration: none, cursor: pointer 추가
- /diary/new 경로는 임시 지정 (담당자 확인 후 수정 예정)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면 캐릭터 이미지 교체 및 위치 조정

- character-welcome.png → character-home.png 교체 (169x138)
- 캐릭터 절대 위치 적용 (top: 41px, right: -20px)
- 캐릭터가 일기 박스 뒤에 위치하도록 z-index 조정 (character: 0, container: 1)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 홈 화면 코드래빗 피드백 반영

- 캐릭터 이미지 가로 스크롤 방지: .page에 overflow-x: hidden 추가
- 비로그인 사용자 분기 처리: 말해부엉 알아보기 박스 추가 (/login 이동)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: 홈 화면 typography 믹신 적용

- greetingText, diaryTitle, diarySubtitle에 typography 믹신 사용
- 개별 font 속성 직접 선언 → @include m.text-* 토큰으로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 비로그인 알아보기 박스 위치 수정

- 인사/일기 박스는 로그인 여부 무관하게 항상 표시
- 말해부엉 알아보기 박스를 진행중인 사건 위치(구분선 아래)로 이동
- 비로그인 인사: '안녕하세요' 표시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면에 통계 섹션 및 구분선 통합

- StatsCategorySection, useStatistics, QueryProvider 병합
- 고민 카테고리 TOP4 통계 섹션 추가
- 통계 섹션 하단 구분선 추가 (h:8px, black-100, gap:42px)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: 개발 편의용 로그인 상태 강제 설정 (배포 전 제거 필요)

- isLoggedIn = true 하드코딩으로 로그인 상태 유지
- TODO 주석으로 배포 전 제거 안내 표시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건작성 페이지 구현 (disputes/[id]/statement) (#46)

* feat: 사건작성 페이지 구현 (disputes/[id]/statement)

- 사건 카테고리 선택 (연애/직장/친구/가족)
- MBTI 선택 드롭다운
- 진술 내용 입력 (최대 1000자)
- 진술저장 버튼 (내용 입력 시 활성화)
- TODO: 진술 저장 API 연결

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 사건작성 페이지 카테고리/간격/드롭다운 수정

- 카테고리를 searchParams에서 읽어 하나만 표시 (비상호작용)
- 카테고리 없을 시 모달 표시 후 이전 페이지로 이동
- Select/Textarea 사이 간격 8px (statementGroup)
- label/Select 사이 간격 16px 유지
- Textarea placeholder 줄바꿈 적용 (\n)
- content overflow-y 제거 → Select 드롭다운 아래 방향 열림 수정
- Select placeholder 색상 var(--text-secondary) 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 없음 모달에서 버튼 제거 — 페이지 블로킹만 유지

확인 버튼 클릭 시 이동하지 않고 Header 뒤로가기로만 탈출 가능

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 기본값 romance 적용, 모달 확인 버튼 복원

- searchParams에 카테고리 없을 시 임시로 romance 기본값 사용
- 모달 확인 버튼 클릭 시 router.back() 복원
- TODO: 이전 페이지 카테고리 데이터 연동 후 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 커스텀 드롭다운 교체 및 Textarea focus 스타일 제거

- Select: 네이티브 select → 커스텀 드롭다운 (항상 아래 방향 열림)
- Select: placeholder 색상 --text-secondary 적용 (option 색 영향 없음)
- Select: 아이콘 회전 애니메이션 추가
- Textarea: focus 시 border-color 변경 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: Button 좌우 패딩 16 → 12으로 조정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: SCSS import 상대경로 → 절대경로(@/) 변환 및 컨벤션 문서 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 접근성 및 스타일 개선

- ul 기본 margin 리셋
- hasValue를 options.find 기준으로 판단 (빈 문자열 오인 방지)
- aria-invalid / aria-describedby 연결로 보조기기 지원
- 키보드 내비게이션 추가 (ArrowUp/Down, Enter/Space, Escape)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: dispute 생성 조건을 active room 전체로 완화 (ONE_TO_ONE 제한 제거)

혼자서도 판결 가능한 흐름을 지원하기 위해
room.roomMode !== 'ONE_TO_ONE' 체크를 제거하고
CLOSED/EXPIRED 방만 차단하도록 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select id 안정화, 빈 options 가드, Tab 기본 포커스 이동 허용

- resolvedId를 label 문자열 대신 useId() 기반으로 고정
- option id를 value 대신 index 기반으로 변경
- Enter/Space 시 options 길이 가드 추가 (크래시 방지)
- Tab은 preventDefault 제거 — 닫기만 하고 포커스 이동은 브라우저에 위임

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독 판결 MVP 포함 및 관련 정책 업데이트 (#51)

- Section 1: 단독 판결 / 1:1 판결 흐름 분리 명시
- Section 2: 단독 판결을 MVP 포함으로 이동, MVP 제외에서 제거
- Section 3: AI 대화방 정책 수정 (ai_chat/invite_ready 상태 단독 판결 허용)
- Section 3: 단독 판결 vs 1:1 판결 제공 결과 비교 섹션 추가
- Section 14: 단독 판결 관련 STOP Condition 항목 제거

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Feature/verdict record display - 캘린더 페이지 ui 제작  (#41)

* feat : 다이어리 (감정일기 , 사건기록)탭분리

* feat : 달력 ui 커스텀 추가 및 감정일기 사건기록 분기처리

* refactor:  및 캘린더 페이지구조 개선 (리뷰 피드백 반영)

* feat : 감정일기카드 컴포넌트 구현

* fix: build 에러 ( 임시 페이지 )

* refactor: 감정일기 컴포넌트 SCSS 모듈 적용 및 믹스인 토큰 사용

* feat: 달력 페이지 UI 구현 및 스타일 정리

- MUI DateCalendar 커스텀
- 감정일기 / 사건기록 탭 전환 구조 구현
- EmotionDiaryList, RecordList 빈 상태 UI 추가
- DiaryCard mixin 적용 (text-title-s, text-body-s, text-label-s)
- 인라인 style 제거 → SCSS 모듈로 분리
- outsideCurrentMonth 감정 아이콘 노출 차단
- 새 일기 FAB 버튼 추가 (감정일기 탭 전용)
- 불필요한 파일 삭제 (DiaryMode, EmotionDiaryCard 등)

* style : EmotionDiaryList.moulde 스타일 수정

* feat: 달력 RecordList에 CaseCard 연동 및 스타일 개선

* Update model name from 'gpt-5.5' to 'gemini-2.5-flash'

seed.ts Ai modelName 수정

---------

Co-authored-by: 배근영 <bgy09270@naver.com>

* feat: 사건작성(진술서) 페이지 구현 및 욕설 감지 필터 연동 (#49)

* feat: 사건작성 페이지 구현 (disputes/[id]/statement)

- 사건 카테고리 선택 (연애/직장/친구/가족)
- MBTI 선택 드롭다운
- 진술 내용 입력 (최대 1000자)
- 진술저장 버튼 (내용 입력 시 활성화)
- TODO: 진술 저장 API 연결

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 사건작성 페이지 카테고리/간격/드롭다운 수정

- 카테고리를 searchParams에서 읽어 하나만 표시 (비상호작용)
- 카테고리 없을 시 모달 표시 후 이전 페이지로 이동
- Select/Textarea 사이 간격 8px (statementGroup)
- label/Select 사이 간격 16px 유지
- Textarea placeholder 줄바꿈 적용 (\n)
- content overflow-y 제거 → Select 드롭다운 아래 방향 열림 수정
- Select placeholder 색상 var(--text-secondary) 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 없음 모달에서 버튼 제거 — 페이지 블로킹만 유지

확인 버튼 클릭 시 이동하지 않고 Header 뒤로가기로만 탈출 가능

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 기본값 romance 적용, 모달 확인 버튼 복원

- searchParams에 카테고리 없을 시 임시로 romance 기본값 사용
- 모달 확인 버튼 클릭 시 router.back() 복원
- TODO: 이전 페이지 카테고리 데이터 연동 후 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 커스텀 드롭다운 교체 및 Textarea focus 스타일 제거

- Select: 네이티브 select → 커스텀 드롭다운 (항상 아래 방향 열림)
- Select: placeholder 색상 --text-secondary 적용 (option 색 영향 없음)
- Select: 아이콘 회전 애니메이션 추가
- Textarea: focus 시 border-color 변경 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: Button 좌우 패딩 16 → 12으로 조정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: SCSS import 상대경로 → 절대경로(@/) 변환 및 컨벤션 문서 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 접근성 및 스타일 개선

- ul 기본 margin 리셋
- hasValue를 options.find 기준으로 판단 (빈 문자열 오인 방지)
- aria-invalid / aria-describedby 연결로 보조기기 지원
- 키보드 내비게이션 추가 (ArrowUp/Down, Enter/Space, Escape)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: dispute 생성 조건을 active room 전체로 완화 (ONE_TO_ONE 제한 제거)

혼자서도 판결 가능한 흐름을 지원하기 위해
room.roomMode !== 'ONE_TO_ONE' 체크를 제거하고
CLOSED/EXPIRED 방만 차단하도록 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select id 안정화, 빈 options 가드, Tab 기본 포커스 이동 허용

- resolvedId를 label 문자열 대신 useId() 기반으로 고정
- option id를 value 대신 index 기반으로 변경
- Enter/Space 시 options 길이 가드 추가 (크래시 방지)
- Tab은 preventDefault 제거 — 닫기만 하고 포커스 이동은 브라우저에 위임

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Textarea 바이트 카운팅 및 filterMessage prop 추가

- 한글 2바이트/ASCII 1바이트 기준으로 글자 수 계산
- maxLength 초과 시 바이트 기준으로 자동 truncate
- filterMessage prop 추가 — 욕설 차단 메시지 동적 표시
- border 색상 변경은 error prop에만 적용 (filter는 border 유지)
- filter-warning 텍스트: Body-S + var(--text-danger)
- field gap 8 → 10px (Figma 기준)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 욕설 감지 필터 구현 (Gemini 2.5 Flash)

- moderation.ts: Gemini 2.5 Flash 기반 욕설/개인정보 감지
  - isBlocked: 욕설·혐오·위협 차단 (보수적 기준)
  - hasPersonalInfo: 개인정보 경고 (차단 없음)
  - fail-open: Gemini 실패 시 pending 상태로 저장
- statements/route.ts: 진술 저장 API
  - 모더레이션 통과 후 upsert + ModerationLog 트랜잭션
  - 차단 시 ModerationLog만 기록, 저장 없이 422 반환
  - dev bypass: 개발 환경에서 세션 없이 모더레이션 테스트 가능
- page.tsx: handleSave 연결, filterMessage 상태, 개인정보 경고 모달
- StatementPage.module.scss: 모달 스타일, Stylelint 공백 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: PR #49 코드리뷰 수정 — MBTI 연동, 파싱 에러, 인젝션, 타임아웃

- MBTI: GET /api/user/me 신규 생성, statement 페이지 마운트 시 user.mbti 초기화
- MBTI: handleSave body에 mbti 포함, statements route에서 user.mbti 업데이트 (트랜잭션)
- statement/page.tsx: res.json() 파싱 실패를 별도 try-catch로 분리
- Textarea.tsx: e.target.value 직접 변경 → Object.assign으로 새 이벤트 객체 전달
- moderation.ts: content 삽입 전 < > HTML 이스케이프 (프롬프트 인젝션 방지)
- moderation.ts: Promise.race() 기반 10초 타임아웃 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: user/me route catch 블록에 에러 로깅 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: judge route 1인 판결 허용 — isSolo 분기 및 rollback 상태 수정

- 2인: BOTH_SUBMITTED 상태 확인 유지
- 1인: 진술 제출 여부만 확인 (statements.length > 0)
- 롤백 대상을 하드코딩된 BOTH_SUBMITTED → previousStatus로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 카카오 로그인 기능 구현 (#50)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 absolute 배치

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 카카오 로그인 기능 구현

- 로그인 페이지 UI 및 카카오 signIn 버튼 연결
- @auth/prisma-adapter 설치 및 authOptions에 적용
- 최초 로그인 시 kakaoId, nickname, termsAgreedAt 자동 설정
- 닉네임 자동 생성 유틸 추가 (~하는부엉이 + 4자리 난수)
- middleware 추가: 비인증 사용자 /login 리다이렉트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 로그인 페이지 및 인증 로직 개선

- SCSS import 절대경로(@/) 수정
- 캐릭터 이미지 Next/Image fill → img 태그로 변경
- 이용약관/개인정보처리방침 링크(/terms, /privacy) 추가 및 스타일 적용
- 닉네임 유니크 제약(@unique) 추가 및 충돌 재시도 로직 구현 (최대 10회)
- middleware matcher 패턴 보완 (/login-help 등 우회 경로 차단)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: disclaimer mixin 적용, nickname 유실 복구 및 fallback 랜덤화

- .disclaimer에 @include m.text-caption mixin 적용
- 유실된 nickname.ts 복구
- fallback 닉네임 Date.now() → 랜덤 8자리 숫자로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독/1:1 판결 공통 진입 흐름 반영 및 관련 문서 일괄 수정 (#54)

- 단독 판결과 1:1 판결이 완전히 분리된 진입이 아니라
  AI 대화방 → 진술저장 → [분기] → disputes/[id]/statement 경로를 공통으로 거침
- CLAUDE.md: 핵심 서비스 흐름 분기 구조로 수정, 단독 판결 MVP 포함 반영,
  AI 대화방 정책 단독/1:1 병행 기술, dispute_status 단독 경로 추가
- PROJECT_DECISIONS.md: 흐름·MVP포함·MVP제외·dispute_status 동기화
- STATUS_TRANSITION.md: 단독 판결 경로(draft→judging→judged) 추가
- DISPUTE.md: 상태 전이 단독/1:1 경로 분리 기술, 주의사항 확정 내용 반영
- ROOM.md: 진술저장 후 분기 흐름 포함 기능에 명시

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Login 페이지 hydration removeChild 에러 수정 (#55)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아…
evenif99 added a commit that referenced this pull request Jun 25, 2026
* chore: initialize project folder structure (#1)

* chore: initialize project folder structure

- Add base directory layout for Next.js + domain-driven architecture
- Add .gitkeep to track empty directories in git
- Exclude MVP out-of-scope domains (shop, points, user-items)
- No implementation files included, structure only

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update README.md

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add CLAUDE.md with project rules and work guidelines (#2)

- Add project overview and MVP scope definition
- Add fixed product rules (categories, AI chat policy, judgement output)
- Add architecture, domain scope, and state transition rules
- Add auth/security, DB, frontend state, API, logging rules
- Add Git workflow, Claude work process, STOP conditions
- Add approval-required list and required reference documents

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: setup project config and install dependencies (#3)

- Add package.json with Next.js 15, React 19, TypeScript stack
- Add next.config.ts (minimal Next.js 15 config)
- Add tsconfig.json (strict mode, @/* path alias)
- Add eslint.config.mjs (next/core-web-vitals + next/typescript)
- Add .prettierrc and .prettierignore
- Add .gitignore (node_modules, .next, .env.local, etc.)
- Add .env.example (key names only, no real values)
- Add prisma/schema.prisma (generator + datasource only)
- Add data/mock/db.json (health check stub for json-server)
- Add docs/TECH_STACK.md (package list and selection rationale)
- Update README.md with run commands and env guide

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add base documentation structure (#4)

- Add PROJECT_DECISIONS.md (MVP scope, architecture, security principles)
- Add guides/CLAUDE_WORKFLOW.md (work process, STOP conditions, approval rules)
- Add guides/GIT_WORKFLOW.md (branch naming, commit convention, workflow)
- Add guides/PR_RULES.md (PR target, title rules, review criteria)
- Add guides/ENV_GUIDE.md (Vercel env pull, .env.example management)
- Add guides/CODING_CONVENTION.md (naming, state management, folder rules)
- Add db/STATUS_TRANSITION.md (room_mode, dispute_status transitions)
- Add db/PRISMA_MAPPING.md (snake_case/camelCase mapping rules)
- Add db/MASTER_DATA.md (categories, result types, DB master principles)
- Add domains/README.md (domain list, MVP scope, writing guidelines)
- Add domains/_DOMAIN_TEMPLATE.md (template for domain docs)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add domain document drafts for all MVP domains (#5)

- Add AUTH.md (kakao login, terms, session management)
- Add COMMON.md (error handling, logging, common response)
- Add ROOM.md (AI chat room, invite link, room_mode transitions)
- Add PERSONAL_ANALYSIS.md (AI-based personal conflict analysis)
- Add DISPUTE.md (1:1 mediation, roles, statements, dispute_status)
- Add JUDGEMENT.md (AI judgement, Gemini API, result card)
- Add GIFT.md (gift recommendation after judgement)
- Add USER.md (mypage, profile, bottom tab)
- Add CALENDAR.md (date-based record marking, monthly summary)
- Add DIARY.md (emotion diary, author-only access, content protection)
- Add STATISTICS.md (anonymous aggregation, summary components)
- Add SHOP_FUTURE.md (v2.0 planned, MVP excluded)
- Add POINTS_FUTURE.md (v2.0 planned, MVP excluded)
- Add USER_ITEMS_FUTURE.md (v2.0 planned, MVP excluded)

All documents are draft templates with TODO markers for assignees.
No implementation, no API routes, no schema changes.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: add Next.js App Router entry files and SCSS base structure (#6)

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Infra/init next setup (#7)

* infra: add Next.js App Router entry files and SCSS base structure

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: resolve ESLint and TypeScript config warnings

- eslint.config.mjs: ignore next-env.d.ts and .next/** (auto-generated by Next.js, triple-slash reference false positive)
- tsconfig.json: remove deprecated baseUrl option (TypeScript 5.x+, paths works without baseUrl)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update README.md (#8)

* docs(infra): confirm Supabase as project infrastructure (#9)

* chore(github): add collaboration templates and policy (#10)

* docs(env): document environment variable management (#11)

* docs(calendar): confirm MUI date picker usage (#12)

달력 UI 라이브러리로 MUI X Date Pickers + Day.js 사용을 확정하고
관련 문서(TECH_STACK, PROJECT_DECISIONS, CODING_CONVENTION, CALENDAR, DIARY, CLAUDE.md)에 반영한다.

* chore(deps): install MUI X Date Pickers and peer dependencies (#13)

달력 UI 구현을 위해 MUI X Date Pickers 및 필수 peer dependency를 설치한다.
@mui/material@9.1.1, @emotion/react@11.14.0, @emotion/styled@11.14.1,
@mui/x-date-pickers@9.5.0, dayjs@1.11.21

* Update README.md (#15)

* fix: resolve ESLint and TypeScript config warnings (#20)

* infra: add Next.js App Router entry files and SCSS base structure

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: resolve ESLint and TypeScript config warnings

- eslint.config.mjs: ignore next-env.d.ts and .next/** (auto-generated by Next.js, triple-slash reference false positive)
- tsconfig.json: remove deprecated baseUrl option (TypeScript 5.x+, paths works without baseUrl)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: add MVP Prisma schema with NextAuth and TALKY-OWL models (#21)

- datasource: add directUrl for Supabase connection pooler support
- enums: CategoryGroup, RoomMode, DisputeStatus, ParticipantRole, etc.
- NextAuth models: User (with TALKY-OWL fields), Account, Session, VerificationToken
- core models: DisputeRoom, RoomAiConversation, RoomAiMessage
- dispute models: Dispute, DisputeParticipant, DisputeStatement
- judgment models: AiJudgment, JudgmentResultCard
- gift models: GiftRecommendation, GiftRecommendationItem
- feature models: EmotionDiary, CalendarRecord
- master data: ConflictTypeGroup, ConflictTypeDetail (DB-based, no enum hardcoding)
- log models: AuditLog, ApiErrorLog, ModerationLog, RoomAccessLog, UserDeletionLog
- .env.example: add DIRECT_URL for Supabase directUrl
- v2.0 TODO: ShopItem, PointTransaction, UserItem, DisputeStatistic excluded

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: align project structure with guide v2 (#22)

folders added:
- src/components/{personal-analysis,room,dispute,judgement,calendar,diary,statistics,gift}
- src/app/api/auth/[...nextauth]
- src/app/api/v1/{users,personal-analyses,rooms,disputes,statements,calendar,diary,statistics,cron}

files added:
- prisma/seed.ts (placeholder for ConflictTypeGroup master data)

docs updated (minimal):
- docs/domains/COMMON.md: add log table list, judgement_logs TODO note
- docs/domains/JUDGEMENT.md: clarify Storage is MVP-excluded scaffolding
- docs/guides/ENV_GUIDE.md: clarify Supabase Storage vars are MVP-excluded

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: rename src/app/page to src/app/(page) for correct Next.js route group (#23)

src/app/page/ (괄호 없음)는 /page/* URL segment를 생성하므로,
Next.js App Router route group 문법인 src/app/(page)/로 변경한다.
URL은 /landing, /home 등으로 노출되어야 하며 /page/... 가 아니다.

관련 문서 내 경로 참조도 모두 업데이트 (CLAUDE.md, docs/domains/*, docs/guides/*).

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* [Style] 디자인 토큰 및 전역 스타일 설정 (#25)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 디자인 시스템 기반 설정 (#27)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: rem 스케일 토큰 추가 및 타이포그래피 변수 rem 참조로 전환

- Rem scale 섹션 추가 (0.25rem ~ 30rem)
- 폰트 토큰에서 누락된 0.875rem(14px), 1.125rem(18px) 추가
- font-size, line-height 변수를 rem 스케일 변수 참조로 전환
- rem 스케일을 typography 섹션보다 상단으로 이동 (선언 순서)
- 컴포넌트 width/height 대응을 위해 큰 단위(9rem~30rem) 포함

Co-Authored-By: Claude <noreply@anthropic.com>

* style: r() 함수 분리 및 타이포그래피 변수 함수 기반으로 전환

- _functions.scss 신규 추가 — px → rem 변환 함수 r() 단독 관리
- _variables.scss에서 rem 스케일 변수 제거, fn.r() 참조로 전환
- _mixins.scss에 functions @use 추가
- 순환 참조 없이 variables → functions → (없음) 단방향 의존성 구성

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Feature/common component jw (#28)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* fix: :root {} 시맨틱 토큰을 _global.scss로 분리 (#29)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: rem 스케일 토큰 추가 및 타이포그래피 변수 rem 참조로 전환

- Rem scale 섹션 추가 (0.25rem ~ 30rem)
- 폰트 토큰에서 누락된 0.875rem(14px), 1.125rem(18px) 추가
- font-size, line-height 변수를 rem 스케일 변수 참조로 전환
- rem 스케일을 typography 섹션보다 상단으로 이동 (선언 순서)
- 컴포넌트 width/height 대응을 위해 큰 단위(9rem~30rem) 포함

Co-Authored-By: Claude <noreply@anthropic.com>

* style: r() 함수 분리 및 타이포그래피 변수 함수 기반으로 전환

- _functions.scss 신규 추가 — px → rem 변환 함수 r() 단독 관리
- _variables.scss에서 rem 스케일 변수 제거, fn.r() 참조로 전환
- _mixins.scss에 functions @use 추가
- 순환 참조 없이 variables → functions → (없음) 단방향 의존성 구성

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: :root {} 시맨틱 토큰을 _global.scss로 분리

_variables.scss에 :root {}가 있으면 module.scss에서 @use 시
CSS Modules 'not pure' 에러 발생.
SCSS 변수는 _variables.scss, CSS 출력은 _global.scss로 분리.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): 공통 UI 컴포넌트 추가 및 MUI 정책 적용 (#30)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 목록 공통 UI 컴포넌트 추가 (Tab, StatusBadge) (#31)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 위치 수정 (#32)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 absolute 배치

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 공통 및 dispute·judgment DTO 타입 정의

- ApiResponse, ApiError, ApiFieldError, CategoryGroup (common.ts)
- DisputeDto, CreateDisputeRequest, DisputeListResponse 등 (dispute.ts)
- AiJudgmentDto, CreateAiJudgmentRequest 등 (judgment.ts)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: dispute 도메인 공유 상수·헬퍼·mapper 추가

- VALID_CATEGORY_GROUPS, IMMUTABLE_DISPUTE_STATUSES 상수 (constants/dispute.ts)
- getSessionUserId NextAuth 세션 헬퍼 (auth/session.ts)
- toAiJudgmentDto 공유 mapper (judgement/judgment.mapper.ts)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 목록 조회·생성·수정·삭제 API 구현

- GET /api/v1/disputes — 참여 사건 목록, categoryGroup 필터, 페이지네이션
- POST /api/v1/disputes — 사건 생성 + role_a 참여자 트랜잭션 등록
- GET /api/v1/disputes/:id — 사건 상세 조회
- PATCH /api/v1/disputes/:id — 사건 수정 (role_a 전용, 변경 불가 상태 차단)
- DELETE /api/v1/disputes/:id — 사건 소프트 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: AI 판결 요청·결과 조회 API 구현

- POST /api/v1/disputes/:id/judge — AI 판결 요청, JUDGING 상태 잠금으로 멱등성 보장
- GET /api/v1/disputes/:id/result — 판결 결과 조회 (참여자 전용)
- AI 모듈 미구현 구간은 TODO 주석으로 마킹, 완료 전까지 503 반환

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 공통 UI 컴포넌트 - StatusBadge, Tab, 진행 상태 (#33)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Prisma 클라이언트, NextAuth Kakao OAuth 설정 및 핸들러 추가

- src/lib/db/index.ts — Prisma 전역 싱글턴
- src/lib/auth/index.ts — NextAuth authOptions (Kakao OAuth, session user.id 매핑)
- src/app/api/auth/[...nextauth]/route.ts — NextAuth GET/POST 핸들러
- @mui/icons-material 패키지 설치 (빌드 에러 해결)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: 빌드 스크립트에 prisma generate 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: MVP 전체 API 명세서 작성 (API_SPEC.md) (#36)

* docs: MVP 전체 API 명세서 작성 (API_SPEC.md)

- 도메인 문서 및 기존 합의 기반 MVP API 명세 초안 작성
- 공통 응답 구조, 에러 코드 체계 정의
- Auth / User / Room / Dispute / Statement / Judgement / Diary / Calendar / Statistics / Gift / Cron 도메인 API 명세 포함
- 경로 충돌 항목 (withdraw, judge/result, diary 경로) 확정 필요 사항으로 명시
- 미확정 TODO 항목 섹션 7에 전체 정리
- MVP 제외 항목 (shop, points, 단독판결, 독립 통계 화면 등) 명시적으로 제거 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독 판결 MVP 포함 반영 및 라우트 주석 명확화

- 단독 판결(상대방 없는 AI 판결)을 MVP 포함 범위로 변경
- Personal Analysis 섹션에 단독 판결 API 초안 추가 (POST/GET /api/v1/personal-analyses)
- 라우트 트리 personal-analyses 디렉터리 구조 구체화
- /auth/withdraw route.ts 주석을 경로 충돌 상호 참조가 명확한 형태로 수정
  (경로 충돌 → /auth/withdraw vs DELETE /users/me)
- MVP 제외 목록에서 단독 판결 항목 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 카카오 로그인 시 약관 동의 자동 간주 정책 반영

- 카카오 OAuth 로그인 완료를 약관 동의로 간주
- 별도 약관 동의 페이지 이동 플로우 제거
- 확정 필요 항목에서 약관 동의 기준 항목 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 도메인 API 목록 중복 제거 및 회원탈퇴 경로 확정

- docs/domains/*.md 8개 파일의 API 목록 섹션을 docs/API_SPEC.md 참조로 교체
  (AUTH, USER, ROOM, DISPUTE, JUDGEMENT, DIARY, CALENDAR, STATISTICS)
- API_SPEC.md 단일 소스 체계 확립
- 회원탈퇴 경로 DELETE /api/v1/users/me 채택 확정
  - §3 요약표, §4.1·§4.2 상세, §5 라우트 트리, §6 충돌 목록, §7 체크리스트 반영
  - /auth/withdraw 라우트 제거, /users/me route.ts에 DELETE 추가
- CLAUDE_WORKFLOW.md PR 템플릿 준수 문구 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 날짜 포맷 및 Pagination 구조 확정 반영

- 날짜/시간 포맷 ISO 8601 (YYYY-MM-DDTHH:mm:ssZ) 확정
- Pagination 공통 구조 확정
  - data 필드: items 배열
  - page 필드: page / totalPages / sortBy / isNext
- 섹션 7 확정 필요 항목 두 개 체크 처리
- Room 목록, Diary 목록 섹션 Pagination 참조로 갱신

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: Pagination 구조에 size / sort / hasNext / hasPrevious 추가

- size: 한 번에 가져오는 항목 수
- sort: 정렬 방향 (asc | desc)
- isNext → hasNext로 변경 (다음 페이지 존재 여부)
- hasPrevious 추가 (이전 페이지 존재 여부)
- §7 체크리스트 항목 갱신

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 날짜 포맷 코드블록 언어 지정자 추가 (MD040)

코드래빗 지적 사항 반영 — 언어 미지정 펜스 코드블록에 text 지정자 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 통계 API 비로그인 공개 조회로 변경

홈 화면 진입 시 비로그인 회원도 통계 조회 가능하도록 수정
- GET /api/v1/statistics/summary: 🔒 → 공개
- GET /api/v1/statistics/top-types: 🔒 → 공개
- §3 요약표, §4.9 상세 명세 인증 표기 및 설명 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 목록 응답 예시에 page 객체 추가 (코드래빗 지적 반영)

- GET /api/v1/rooms 응답 예시에 page 객체 추가
- GET /api/v1/diary 응답 예시에 page 객체 추가
- GET /api/v1/statistics/top-types 응답 예시에 page 객체 추가
  (Top5 고정 목록 특성 반영: size=5, totalPages=1, hasNext=false)
- 코드래빗 제안의 구버전 필드(isNext) 대신 확정 구조(hasNext/hasPrevious/size/sort) 적용
- §7 Room Pagination 항목 체크 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Spinner, Avatar, AvatarGroup 공통 컴포넌트 추가 (#37)

* chore: 정적 이미지 에셋 추가 및 정리

주요 페이지용 캐릭터 이미지 추가 및 공통 에셋 정리.
gift, loading 캐릭터를 common에서 characters로 이동하여
캐릭터 이미지를 한 폴더로 통합.

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: Spinner 공통 컴포넌트 추가

캐릭터 로딩 이미지를 중앙에 배치한 88x88 스피너 컴포넌트 추가.
트랙(배경 원)과 애니메이션 링을 분리하여 각각 border-default, bg-brand 색상 적용.

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: Avatar, AvatarGroup 공통 컴포넌트 추가

MUI Avatar, AvatarGroup 래핑 컴포넌트 추가.
size prop으로 s/m/l 사이즈 조절, src prop으로 프로필 사진 지원.
global.scss에 --color-white, --color-black CSS 변수 추가.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: Avatar Context로 AvatarGroup size 전달 및 토큰 수정

AvatarGroup size prop이 자식 Avatar에 적용 안 되는 버그 수정.
Context를 통해 size를 내려주고 Avatar가 그룹 size를 우선 적용.
color 토큰 --color-white를 --text-inverse로 교체.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: Avatar src 없을 때 기본 썸네일 이미지로 fallback 처리

Co-Authored-By: Claude <noreply@anthropic.com>

* test: Spinner, Avatar, AvatarGroup 테스트 페이지 추가

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

* feat: 공통 UI 컴포넌트 - CategoryFilter, CategoryIcon, Tab, StatusBadge (#38)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 공통 컴포넌트 생성

- 전체/연애/직장/친구/가족 카테고리 필터 구현
- 아이콘 박스 44x44, border-radius 8, 아이콘 24x24
- 선택 상태: icon-primary bg / 미선택: bg-disabled
- MUI icons 사용 (GridViewRounded, Favorite, BusinessCenter, Diversity3, FamilyRestroom)
- Category 타입 export

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Tab 라벨 폰트 스타일 명시

- item.label을 span.label로 래핑
- Body-M 기준 font-size 16, line-height 28 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: @mui/icons-material 패키지 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 스타일 및 single 모드 적용

- 선택: bg-page + border-brand(1px) + icon-primary + 텍스트 bold
- 미선택: bg-page + border-default(1px) + icon-secondary + 텍스트 regular
- mode prop 추가 (filter 기본값 / single: 선택된 박스 하나만 표시)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 타입을 DB CategoryGroup 기준으로 통일

## 수정 배경

CategoryIcon, CategoryFilter가 한국어 문자열('연애', '직장' 등)을 타입으로 사용하고 있어
API/DB의 CategoryGroup('romance', 'work' 등)과 불일치가 발생.
페이지에서 연결 시 별도 변환 레이어가 필요해지는 문제를 사전 차단.

## 변경 파일별 수정 내용

### CategoryIcon.tsx
- CategoryWithoutAll 타입 제거 → @/types/common의 CategoryGroup 직접 사용
- 아이콘/레이블/컬러 맵 키를 한국어 → 영문 DB 값으로 변경
  (romance, work, friend, family)
- CATEGORY_LABEL_MAP export 추가 (CategoryFilter에서 레이블 참조용)

### CategoryFilter.tsx
- Category 타입을 'all' | CategoryGroup으로 변경 (기존: 한국어 문자열)
- CATEGORIES 배열에 label 필드 추가, CATEGORY_LABEL_MAP에서 참조
- 전체 키를 '전체' → 'all'로 변경 (API 필터 미적용 값과 일치)

### CaseCard.tsx (타팀원 파일 수정)
- 수정 이유: CATEGORY_EMOJI 맵 키가 대문자('ROMANCE')였으나
  API 응답은 소문자('romance')로 내려와 emoji가 항상 '📋' fallback만 표시되는 버그 존재
- 해결 방법: emoji 방식 전체 제거, CategoryIcon 컴포넌트로 교체
- categoryGroup prop 타입을 string → CategoryGroup으로 명시
- categoryGroup 미전달 시 아이콘 미표시 처리 (optional 유지)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update src/components/ui/CategoryIcon.tsx

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: CategoryIcon 중복 import 제거 및 CategoryFilter discriminated union 타입 에러 수정

- CategoryIcon: FamilyRestroomIcon, CategoryGroup 중복 import 제거
- CategoryFilter: discriminated union(CodeRabbit 피드백 반영) 유지하면서
  props 전체로 받아 props.mode로 narrowing 처리해 타입 에러 해결
  (mode='single'일 때 onChange가 CategoryGroup을 기대하는 문제)
- Tab.module.scss: height → min-height 변경 (유연한 높이 대응)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard 카테고리 아이콘을 제목 왼쪽 인라인으로 이동

- card__header 구조 변경: titleRow(아이콘+제목)와 badge를 좌우 배치
- card__titleRow 추가: flex row, align-items center, gap 6px
- 아이콘이 제목 위에 쌓이던 문제 수정 → 제목 왼쪽에 인라인 배치
- card__icon: font-size/line-height(이모지 잔재) → display:flex 로 변경
- card__title: margin-bottom 제거(card__header margin-bottom으로 대체)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 공통 컴포넌트 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard titleRow flex 축소 보완 (min-width: 0, flex: 1)

긴 제목에서 card__titleRow가 축소되지 않아 배지가 밀리는 문제 방지.
card__header가 space-between일 때 titleRow가 flex: 1로 가용 공간을 차지하고
min-width: 0으로 내부 콘텐츠가 넘치지 않도록 제약.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix(common): BottomNavigation 아이콘 MUI MD2 기본 스타일로 수정 (#39)

* fix(common): BottomNavigation 아이콘을 MUI MD2 기본 스타일로 수정

- HomeRounded → Home
- GavelRounded → MenuBook (사건기록 아이콘 자체 변경)
- CalendarMonthRounded → CalendarMonth
- PersonRounded → Person
디자인 시안 기준 MD2 filled 아이콘으로 통일

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: BottomNavigation 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): BottomNavigation 활성 탭 레이블 색상 black-700으로 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): BottomNavigation 테스트 스크린샷 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: wjdalss21 <jungxmin21@gmail.com>

* feat: 사건·방 도메인 타입 정의 및 API 구현 (#40)

* feat: room DTO 타입 정의

- RoomMode, RoomDto, CreateRoomRequest, RoomListResponse

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 방 목록 조회·생성·상세 조회·종료·삭제 API 구현

- GET  /api/v1/rooms — 내 방 목록 조회 (페이지네이션)
- POST /api/v1/rooms — AI 대화방 생성 (roomMode = ai_chat)
- GET  /api/v1/rooms/:id — 방 상세 조회
- POST /api/v1/rooms/:id/close — 방 종료 (closedAt + roomMode = closed)
- DELETE /api/v1/rooms/:id — 방 소프트 삭제 (deletedAt + roomMode = deleted)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 방 목록 페이지네이션 파라미터 NaN 방어 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: API 라우트 경로 v1 버전 세그먼트 제거 (#42)

* fix: API 라우트 경로에서 v1 버전 세그먼트 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 라우트 핸들러 주석 경로 v1 제거 (/api/v1/ -> /api/)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): 서비스 흐름 기반 문서 구조 수정 및 페이지 문서 생성 (#43)

* fix(docs): 서비스 흐름 기반 문서 구조 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): PAGES.md 코드 블록 언어 명시 추가 (MD040)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: personal-analyses 페이지 및 API 폴더 삭제 (#45)

* fix: personal-analyses 페이지 및 API 폴더 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): personal-analysis 도메인 참조 MD 문서 일괄 정리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 API 구현 (GET /api/statistics/categories) (#44)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 공통 컴포넌트 생성

- 전체/연애/직장/친구/가족 카테고리 필터 구현
- 아이콘 박스 44x44, border-radius 8, 아이콘 24x24
- 선택 상태: icon-primary bg / 미선택: bg-disabled
- MUI icons 사용 (GridViewRounded, Favorite, BusinessCenter, Diversity3, FamilyRestroom)
- Category 타입 export

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Tab 라벨 폰트 스타일 명시

- item.label을 span.label로 래핑
- Body-M 기준 font-size 16, line-height 28 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: @mui/icons-material 패키지 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 스타일 및 single 모드 적용

- 선택: bg-page + border-brand(1px) + icon-primary + 텍스트 bold
- 미선택: bg-page + border-default(1px) + icon-secondary + 텍스트 regular
- mode prop 추가 (filter 기본값 / single: 선택된 박스 하나만 표시)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 타입을 DB CategoryGroup 기준으로 통일

## 수정 배경

CategoryIcon, CategoryFilter가 한국어 문자열('연애', '직장' 등)을 타입으로 사용하고 있어
API/DB의 CategoryGroup('romance', 'work' 등)과 불일치가 발생.
페이지에서 연결 시 별도 변환 레이어가 필요해지는 문제를 사전 차단.

## 변경 파일별 수정 내용

### CategoryIcon.tsx
- CategoryWithoutAll 타입 제거 → @/types/common의 CategoryGroup 직접 사용
- 아이콘/레이블/컬러 맵 키를 한국어 → 영문 DB 값으로 변경
  (romance, work, friend, family)
- CATEGORY_LABEL_MAP export 추가 (CategoryFilter에서 레이블 참조용)

### CategoryFilter.tsx
- Category 타입을 'all' | CategoryGroup으로 변경 (기존: 한국어 문자열)
- CATEGORIES 배열에 label 필드 추가, CATEGORY_LABEL_MAP에서 참조
- 전체 키를 '전체' → 'all'로 변경 (API 필터 미적용 값과 일치)

### CaseCard.tsx (타팀원 파일 수정)
- 수정 이유: CATEGORY_EMOJI 맵 키가 대문자('ROMANCE')였으나
  API 응답은 소문자('romance')로 내려와 emoji가 항상 '📋' fallback만 표시되는 버그 존재
- 해결 방법: emoji 방식 전체 제거, CategoryIcon 컴포넌트로 교체
- categoryGroup prop 타입을 string → CategoryGroup으로 명시
- categoryGroup 미전달 시 아이콘 미표시 처리 (optional 유지)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update src/components/ui/CategoryIcon.tsx

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: CategoryIcon 중복 import 제거 및 CategoryFilter discriminated union 타입 에러 수정

- CategoryIcon: FamilyRestroomIcon, CategoryGroup 중복 import 제거
- CategoryFilter: discriminated union(CodeRabbit 피드백 반영) 유지하면서
  props 전체로 받아 props.mode로 narrowing 처리해 타입 에러 해결
  (mode='single'일 때 onChange가 CategoryGroup을 기대하는 문제)
- Tab.module.scss: height → min-height 변경 (유연한 높이 대응)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard 카테고리 아이콘을 제목 왼쪽 인라인으로 이동

- card__header 구조 변경: titleRow(아이콘+제목)와 badge를 좌우 배치
- card__titleRow 추가: flex row, align-items center, gap 6px
- 아이콘이 제목 위에 쌓이던 문제 수정 → 제목 왼쪽에 인라인 배치
- card__icon: font-size/line-height(이모지 잔재) → display:flex 로 변경
- card__title: margin-bottom 제거(card__header margin-bottom으로 대체)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 공통 컴포넌트 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard titleRow flex 축소 보완 (min-width: 0, flex: 1)

긴 제목에서 card__titleRow가 축소되지 않아 배지가 밀리는 문제 방지.
card__header가 space-between일 때 titleRow가 flex: 1로 가용 공간을 차지하고
min-width: 0으로 내부 콘텐츠가 넘치지 않도록 제약.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 도메인 서비스 레이어 생성 (statisticsService.ts)

## 생성 이유
통계 API의 DB 쿼리 로직을 Route Handler와 분리하기 위해
도메인 서비스 레이어를 별도 파일로 작성했다.

## 폴더 선택 이유
src/domains/statistics/
- CLAUDE.md §4 아키텍처 원칙에 따라 도메인별 비즈니스 로직은
  src/domains/{domain}/ 에 위치한다.
- statistics는 MVP 도메인 목록에 포함된 독립 도메인이다.
- Route Handler(src/app/api/)는 요청/응답 처리만 담당하고,
  실제 DB 쿼리 로직은 서비스 레이어에서 관리한다.

## 구현 내용

### getSummary()
- 서비스 전체 판결 완료 건수(totalJudgements) 집계
- dispute.status = JUDGED 조건 명시: ai_judgements는 판결 완료 시에만
  생성되지만 의도를 코드에 명시적으로 표현
- deletedAt / anonymizedAt IS NULL: 삭제·익명화된 사건 제외 (CLAUDE.md §7)

### getTopTypes(size = 5)
- ai_judgements.result_conflict_detail_id 기준 GROUP BY COUNT DESC
- 결과 유형 마스터(conflict_type_details)를 JOIN해 detailCode·displayName 반환
- isActive = true 필터: 비활성화된 유형은 통계에서 제외
- percentage 서버 계산: count / total * 100 (소수점 1자리)
  FE에서 별도 계산 없이 바로 사용할 수 있도록 서버에서 내려줌
- prisma.conflictTypeDetail 사용 (prisma.conflictDetail은 스키마에 존재하지 않음)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 API Route Handler 생성 (GET /api/v1/statistics/top-types)

## 생성 이유
statisticsService의 getTopTypes()를 HTTP 엔드포인트로 노출하기 위해
Next.js App Router 기반 Route Handler를 생성했다.

## 폴더 선택 이유
src/app/api/v1/statistics/top-types/
- CLAUDE.md §4 아키텍처 원칙에 따라 API Route는 src/app/api/v1/ 하위에 위치한다.
- API_SPEC.md §4.9 기준 엔드포인트 경로: GET /api/v1/statistics/top-types
- summary 엔드포인트는 현재 MVP 범위에서 불필요하여 top-types만 생성

## 구현 내용
- getServerSession으로 서버에서 직접 세션 검증
  (FE 리다이렉트만으로는 API 직접 호출을 막을 수 없으므로 서버 검증 필수 — CLAUDE.md §7)
- 인증 실패 시 401 UNAUTHORIZED 반환
- getTopTypes(5) 호출 → 판결 완료 기준 Top5 유형 + 비율 반환
- ApiResponse 타입 준수: data/error는 null 아닌 undefined(optional) 사용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: statistics top-types 인증 제거 (메인 페이지 공개 접근 허용)

메인 페이지에서도 통계 차트가 노출되는 익명 집계 데이터이므로
세션 없이 접근 가능하도록 수정.

- getServerSession 및 관련 import 제거
- 401 인증 체크 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: statistics top-types 에러 핸들링 보완

코드래빗 피드백 반영:
- catch {} -> catch (error): 에러 정보 유실 방지
- 타임아웃 감지 후 504 분기 처리
- console.error 로깅 추가 (CLAUDE.md 11 API 오류 로그 대상)
- 세션 체크는 이전 커밋에서 이미 제거됨 (공개 엔드포인트)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: 통계 API 카테고리 기준으로 재설계

- 결과 유형(top-types) → 작성 카테고리(ROMANCE/FAMILY/FRIEND/WORK) 기준으로 변경
- route.ts에 DB 쿼리 직접 작성, statisticsService.ts 제거
- 비율 계산은 프론트 훅(useStatistics)에서 담당
- revalidate = 86400 (하루 1회 재계산)
- src/hooks/ 폴더 신설 및 useStatistics.ts 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 통계 API 서버 측 세션 인증 추가

- GET /api/statistics/categories 진입 시 getServerSession으로 인증 검증
- 미인증 요청 401 UNAUTHORIZED 반환

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* feat: Header variant 분리 (logo/title) 및 홈 화면 적용 (#47)

* feat: 홈 화면 기본 구조 생성 (헤더, 일기 박스)

- 헤더: 세션 유저명 + character-welcome.png 부엉이 이미지
- 일기 박스: 365x88, border black-700 2px, bg primary-100
- TODO: GangwonEduPower 폰트 추가 후 헤더 로고 텍스트 적용 필요

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Header variant 분리 (logo/title) 및 홈 화면 적용

- Header.tsx에 variant prop 추가 (logo | title)
  - logo: 좌측 상단 말해부엉 로고 표시 (66x19, h:56, padding: 16px 20px)
  - title: 기존 뒤로가기 + 페이지 제목 형태 유지
- Header.module.scss에 __logo 스타일 추가
- home/page.tsx에 Header variant='logo' 적용
  - 헤더를 컨테이너 padding 밖으로 분리하여 상단 여백 제거
- home/page.module.scss diaryBox에 align-self: center 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건기록 페이지 생성 및 로고 헤더 적용 (/records)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: diaryBox 고정 폭을 max-width + width 100%로 반응형 처리

- width: 365px → width: 100% + max-width: 365px
- 작은 화면에서 좌우 패딩과 결합 시 오버플로우 방지

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 감정일기 작성 버튼 /diary/new 네비게이션 연결

- 일기 박스 전체를 Link로 변경 (텍스트 + 버튼 모두 클릭 가능)
- diaryBox에 text-decoration: none, cursor: pointer 추가
- /diary/new 경로는 임시 지정 (담당자 확인 후 수정 예정)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면 캐릭터 이미지 교체 및 위치 조정

- character-welcome.png → character-home.png 교체 (169x138)
- 캐릭터 절대 위치 적용 (top: 41px, right: -20px)
- 캐릭터가 일기 박스 뒤에 위치하도록 z-index 조정 (character: 0, container: 1)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 홈 화면 코드래빗 피드백 반영

- 캐릭터 이미지 가로 스크롤 방지: .page에 overflow-x: hidden 추가
- 비로그인 사용자 분기 처리: 말해부엉 알아보기 박스 추가 (/login 이동)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: 홈 화면 typography 믹신 적용

- greetingText, diaryTitle, diarySubtitle에 typography 믹신 사용
- 개별 font 속성 직접 선언 → @include m.text-* 토큰으로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 비로그인 알아보기 박스 위치 수정

- 인사/일기 박스는 로그인 여부 무관하게 항상 표시
- 말해부엉 알아보기 박스를 진행중인 사건 위치(구분선 아래)로 이동
- 비로그인 인사: '안녕하세요' 표시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면에 통계 섹션 및 구분선 통합

- StatsCategorySection, useStatistics, QueryProvider 병합
- 고민 카테고리 TOP4 통계 섹션 추가
- 통계 섹션 하단 구분선 추가 (h:8px, black-100, gap:42px)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: 개발 편의용 로그인 상태 강제 설정 (배포 전 제거 필요)

- isLoggedIn = true 하드코딩으로 로그인 상태 유지
- TODO 주석으로 배포 전 제거 안내 표시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건작성 페이지 구현 (disputes/[id]/statement) (#46)

* feat: 사건작성 페이지 구현 (disputes/[id]/statement)

- 사건 카테고리 선택 (연애/직장/친구/가족)
- MBTI 선택 드롭다운
- 진술 내용 입력 (최대 1000자)
- 진술저장 버튼 (내용 입력 시 활성화)
- TODO: 진술 저장 API 연결

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 사건작성 페이지 카테고리/간격/드롭다운 수정

- 카테고리를 searchParams에서 읽어 하나만 표시 (비상호작용)
- 카테고리 없을 시 모달 표시 후 이전 페이지로 이동
- Select/Textarea 사이 간격 8px (statementGroup)
- label/Select 사이 간격 16px 유지
- Textarea placeholder 줄바꿈 적용 (\n)
- content overflow-y 제거 → Select 드롭다운 아래 방향 열림 수정
- Select placeholder 색상 var(--text-secondary) 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 없음 모달에서 버튼 제거 — 페이지 블로킹만 유지

확인 버튼 클릭 시 이동하지 않고 Header 뒤로가기로만 탈출 가능

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 기본값 romance 적용, 모달 확인 버튼 복원

- searchParams에 카테고리 없을 시 임시로 romance 기본값 사용
- 모달 확인 버튼 클릭 시 router.back() 복원
- TODO: 이전 페이지 카테고리 데이터 연동 후 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 커스텀 드롭다운 교체 및 Textarea focus 스타일 제거

- Select: 네이티브 select → 커스텀 드롭다운 (항상 아래 방향 열림)
- Select: placeholder 색상 --text-secondary 적용 (option 색 영향 없음)
- Select: 아이콘 회전 애니메이션 추가
- Textarea: focus 시 border-color 변경 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: Button 좌우 패딩 16 → 12으로 조정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: SCSS import 상대경로 → 절대경로(@/) 변환 및 컨벤션 문서 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 접근성 및 스타일 개선

- ul 기본 margin 리셋
- hasValue를 options.find 기준으로 판단 (빈 문자열 오인 방지)
- aria-invalid / aria-describedby 연결로 보조기기 지원
- 키보드 내비게이션 추가 (ArrowUp/Down, Enter/Space, Escape)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: dispute 생성 조건을 active room 전체로 완화 (ONE_TO_ONE 제한 제거)

혼자서도 판결 가능한 흐름을 지원하기 위해
room.roomMode !== 'ONE_TO_ONE' 체크를 제거하고
CLOSED/EXPIRED 방만 차단하도록 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select id 안정화, 빈 options 가드, Tab 기본 포커스 이동 허용

- resolvedId를 label 문자열 대신 useId() 기반으로 고정
- option id를 value 대신 index 기반으로 변경
- Enter/Space 시 options 길이 가드 추가 (크래시 방지)
- Tab은 preventDefault 제거 — 닫기만 하고 포커스 이동은 브라우저에 위임

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독 판결 MVP 포함 및 관련 정책 업데이트 (#51)

- Section 1: 단독 판결 / 1:1 판결 흐름 분리 명시
- Section 2: 단독 판결을 MVP 포함으로 이동, MVP 제외에서 제거
- Section 3: AI 대화방 정책 수정 (ai_chat/invite_ready 상태 단독 판결 허용)
- Section 3: 단독 판결 vs 1:1 판결 제공 결과 비교 섹션 추가
- Section 14: 단독 판결 관련 STOP Condition 항목 제거

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Feature/verdict record display - 캘린더 페이지 ui 제작  (#41)

* feat : 다이어리 (감정일기 , 사건기록)탭분리

* feat : 달력 ui 커스텀 추가 및 감정일기 사건기록 분기처리

* refactor:  및 캘린더 페이지구조 개선 (리뷰 피드백 반영)

* feat : 감정일기카드 컴포넌트 구현

* fix: build 에러 ( 임시 페이지 )

* refactor: 감정일기 컴포넌트 SCSS 모듈 적용 및 믹스인 토큰 사용

* feat: 달력 페이지 UI 구현 및 스타일 정리

- MUI DateCalendar 커스텀
- 감정일기 / 사건기록 탭 전환 구조 구현
- EmotionDiaryList, RecordList 빈 상태 UI 추가
- DiaryCard mixin 적용 (text-title-s, text-body-s, text-label-s)
- 인라인 style 제거 → SCSS 모듈로 분리
- outsideCurrentMonth 감정 아이콘 노출 차단
- 새 일기 FAB 버튼 추가 (감정일기 탭 전용)
- 불필요한 파일 삭제 (DiaryMode, EmotionDiaryCard 등)

* style : EmotionDiaryList.moulde 스타일 수정

* feat: 달력 RecordList에 CaseCard 연동 및 스타일 개선

* Update model name from 'gpt-5.5' to 'gemini-2.5-flash'

seed.ts Ai modelName 수정

---------

Co-authored-by: 배근영 <bgy09270@naver.com>

* feat: 사건작성(진술서) 페이지 구현 및 욕설 감지 필터 연동 (#49)

* feat: 사건작성 페이지 구현 (disputes/[id]/statement)

- 사건 카테고리 선택 (연애/직장/친구/가족)
- MBTI 선택 드롭다운
- 진술 내용 입력 (최대 1000자)
- 진술저장 버튼 (내용 입력 시 활성화)
- TODO: 진술 저장 API 연결

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 사건작성 페이지 카테고리/간격/드롭다운 수정

- 카테고리를 searchParams에서 읽어 하나만 표시 (비상호작용)
- 카테고리 없을 시 모달 표시 후 이전 페이지로 이동
- Select/Textarea 사이 간격 8px (statementGroup)
- label/Select 사이 간격 16px 유지
- Textarea placeholder 줄바꿈 적용 (\n)
- content overflow-y 제거 → Select 드롭다운 아래 방향 열림 수정
- Select placeholder 색상 var(--text-secondary) 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 없음 모달에서 버튼 제거 — 페이지 블로킹만 유지

확인 버튼 클릭 시 이동하지 않고 Header 뒤로가기로만 탈출 가능

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 기본값 romance 적용, 모달 확인 버튼 복원

- searchParams에 카테고리 없을 시 임시로 romance 기본값 사용
- 모달 확인 버튼 클릭 시 router.back() 복원
- TODO: 이전 페이지 카테고리 데이터 연동 후 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 커스텀 드롭다운 교체 및 Textarea focus 스타일 제거

- Select: 네이티브 select → 커스텀 드롭다운 (항상 아래 방향 열림)
- Select: placeholder 색상 --text-secondary 적용 (option 색 영향 없음)
- Select: 아이콘 회전 애니메이션 추가
- Textarea: focus 시 border-color 변경 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: Button 좌우 패딩 16 → 12으로 조정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: SCSS import 상대경로 → 절대경로(@/) 변환 및 컨벤션 문서 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 접근성 및 스타일 개선

- ul 기본 margin 리셋
- hasValue를 options.find 기준으로 판단 (빈 문자열 오인 방지)
- aria-invalid / aria-describedby 연결로 보조기기 지원
- 키보드 내비게이션 추가 (ArrowUp/Down, Enter/Space, Escape)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: dispute 생성 조건을 active room 전체로 완화 (ONE_TO_ONE 제한 제거)

혼자서도 판결 가능한 흐름을 지원하기 위해
room.roomMode !== 'ONE_TO_ONE' 체크를 제거하고
CLOSED/EXPIRED 방만 차단하도록 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select id 안정화, 빈 options 가드, Tab 기본 포커스 이동 허용

- resolvedId를 label 문자열 대신 useId() 기반으로 고정
- option id를 value 대신 index 기반으로 변경
- Enter/Space 시 options 길이 가드 추가 (크래시 방지)
- Tab은 preventDefault 제거 — 닫기만 하고 포커스 이동은 브라우저에 위임

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Textarea 바이트 카운팅 및 filterMessage prop 추가

- 한글 2바이트/ASCII 1바이트 기준으로 글자 수 계산
- maxLength 초과 시 바이트 기준으로 자동 truncate
- filterMessage prop 추가 — 욕설 차단 메시지 동적 표시
- border 색상 변경은 error prop에만 적용 (filter는 border 유지)
- filter-warning 텍스트: Body-S + var(--text-danger)
- field gap 8 → 10px (Figma 기준)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 욕설 감지 필터 구현 (Gemini 2.5 Flash)

- moderation.ts: Gemini 2.5 Flash 기반 욕설/개인정보 감지
  - isBlocked: 욕설·혐오·위협 차단 (보수적 기준)
  - hasPersonalInfo: 개인정보 경고 (차단 없음)
  - fail-open: Gemini 실패 시 pending 상태로 저장
- statements/route.ts: 진술 저장 API
  - 모더레이션 통과 후 upsert + ModerationLog 트랜잭션
  - 차단 시 ModerationLog만 기록, 저장 없이 422 반환
  - dev bypass: 개발 환경에서 세션 없이 모더레이션 테스트 가능
- page.tsx: handleSave 연결, filterMessage 상태, 개인정보 경고 모달
- StatementPage.module.scss: 모달 스타일, Stylelint 공백 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: PR #49 코드리뷰 수정 — MBTI 연동, 파싱 에러, 인젝션, 타임아웃

- MBTI: GET /api/user/me 신규 생성, statement 페이지 마운트 시 user.mbti 초기화
- MBTI: handleSave body에 mbti 포함, statements route에서 user.mbti 업데이트 (트랜잭션)
- statement/page.tsx: res.json() 파싱 실패를 별도 try-catch로 분리
- Textarea.tsx: e.target.value 직접 변경 → Object.assign으로 새 이벤트 객체 전달
- moderation.ts: content 삽입 전 < > HTML 이스케이프 (프롬프트 인젝션 방지)
- moderation.ts: Promise.race() 기반 10초 타임아웃 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: user/me route catch 블록에 에러 로깅 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: judge route 1인 판결 허용 — isSolo 분기 및 rollback 상태 수정

- 2인: BOTH_SUBMITTED 상태 확인 유지
- 1인: 진술 제출 여부만 확인 (statements.length > 0)
- 롤백 대상을 하드코딩된 BOTH_SUBMITTED → previousStatus로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 카카오 로그인 기능 구현 (#50)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 absolute 배치

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 카카오 로그인 기능 구현

- 로그인 페이지 UI 및 카카오 signIn 버튼 연결
- @auth/prisma-adapter 설치 및 authOptions에 적용
- 최초 로그인 시 kakaoId, nickname, termsAgreedAt 자동 설정
- 닉네임 자동 생성 유틸 추가 (~하는부엉이 + 4자리 난수)
- middleware 추가: 비인증 사용자 /login 리다이렉트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 로그인 페이지 및 인증 로직 개선

- SCSS import 절대경로(@/) 수정
- 캐릭터 이미지 Next/Image fill → img 태그로 변경
- 이용약관/개인정보처리방침 링크(/terms, /privacy) 추가 및 스타일 적용
- 닉네임 유니크 제약(@unique) 추가 및 충돌 재시도 로직 구현 (최대 10회)
- middleware matcher 패턴 보완 (/login-help 등 우회 경로 차단)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: disclaimer mixin 적용, nickname 유실 복구 및 fallback 랜덤화

- .disclaimer에 @include m.text-caption mixin 적용
- 유실된 nickname.ts 복구
- fallback 닉네임 Date.now() → 랜덤 8자리 숫자로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독/1:1 판결 공통 진입 흐름 반영 및 관련 문서 일괄 수정 (#54)

- 단독 판결과 1:1 판결이 완전히 분리된 진입이 아니라
  AI 대화방 → 진술저장 → [분기] → disputes/[id]/statement 경로를 공통으로 거침
- CLAUDE.md: 핵심 서비스 흐름 분기 구조로 수정, 단독 판결 MVP 포함 반영,
  AI 대화방 정책 단독/1:1 병행 기술, dispute_status 단독 경로 추가
- PROJECT_DECISIONS.md: 흐름·MVP포함·MVP제외·dispute_status 동기화
- STATUS_TRANSITION.md: 단독 판결 경로(draft→judging→judged) 추가
- DISPUTE.md: 상태 전이 단독/1:1 경로 분리 기술, 주의사항 확정 내용 반영
- ROOM.md: 진술저장 후 분기 흐름 포함 기능에 명시

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Login 페이지 hydration removeChild 에러 수정 (#55)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이…
evenif99 added a commit that referenced this pull request Jun 26, 2026
* chore: initialize project folder structure (#1)

* chore: initialize project folder structure

- Add base directory layout for Next.js + domain-driven architecture
- Add .gitkeep to track empty directories in git
- Exclude MVP out-of-scope domains (shop, points, user-items)
- No implementation files included, structure only

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update README.md

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add CLAUDE.md with project rules and work guidelines (#2)

- Add project overview and MVP scope definition
- Add fixed product rules (categories, AI chat policy, judgement output)
- Add architecture, domain scope, and state transition rules
- Add auth/security, DB, frontend state, API, logging rules
- Add Git workflow, Claude work process, STOP conditions
- Add approval-required list and required reference documents

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: setup project config and install dependencies (#3)

- Add package.json with Next.js 15, React 19, TypeScript stack
- Add next.config.ts (minimal Next.js 15 config)
- Add tsconfig.json (strict mode, @/* path alias)
- Add eslint.config.mjs (next/core-web-vitals + next/typescript)
- Add .prettierrc and .prettierignore
- Add .gitignore (node_modules, .next, .env.local, etc.)
- Add .env.example (key names only, no real values)
- Add prisma/schema.prisma (generator + datasource only)
- Add data/mock/db.json (health check stub for json-server)
- Add docs/TECH_STACK.md (package list and selection rationale)
- Update README.md with run commands and env guide

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add base documentation structure (#4)

- Add PROJECT_DECISIONS.md (MVP scope, architecture, security principles)
- Add guides/CLAUDE_WORKFLOW.md (work process, STOP conditions, approval rules)
- Add guides/GIT_WORKFLOW.md (branch naming, commit convention, workflow)
- Add guides/PR_RULES.md (PR target, title rules, review criteria)
- Add guides/ENV_GUIDE.md (Vercel env pull, .env.example management)
- Add guides/CODING_CONVENTION.md (naming, state management, folder rules)
- Add db/STATUS_TRANSITION.md (room_mode, dispute_status transitions)
- Add db/PRISMA_MAPPING.md (snake_case/camelCase mapping rules)
- Add db/MASTER_DATA.md (categories, result types, DB master principles)
- Add domains/README.md (domain list, MVP scope, writing guidelines)
- Add domains/_DOMAIN_TEMPLATE.md (template for domain docs)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add domain document drafts for all MVP domains (#5)

- Add AUTH.md (kakao login, terms, session management)
- Add COMMON.md (error handling, logging, common response)
- Add ROOM.md (AI chat room, invite link, room_mode transitions)
- Add PERSONAL_ANALYSIS.md (AI-based personal conflict analysis)
- Add DISPUTE.md (1:1 mediation, roles, statements, dispute_status)
- Add JUDGEMENT.md (AI judgement, Gemini API, result card)
- Add GIFT.md (gift recommendation after judgement)
- Add USER.md (mypage, profile, bottom tab)
- Add CALENDAR.md (date-based record marking, monthly summary)
- Add DIARY.md (emotion diary, author-only access, content protection)
- Add STATISTICS.md (anonymous aggregation, summary components)
- Add SHOP_FUTURE.md (v2.0 planned, MVP excluded)
- Add POINTS_FUTURE.md (v2.0 planned, MVP excluded)
- Add USER_ITEMS_FUTURE.md (v2.0 planned, MVP excluded)

All documents are draft templates with TODO markers for assignees.
No implementation, no API routes, no schema changes.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: add Next.js App Router entry files and SCSS base structure (#6)

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Infra/init next setup (#7)

* infra: add Next.js App Router entry files and SCSS base structure

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: resolve ESLint and TypeScript config warnings

- eslint.config.mjs: ignore next-env.d.ts and .next/** (auto-generated by Next.js, triple-slash reference false positive)
- tsconfig.json: remove deprecated baseUrl option (TypeScript 5.x+, paths works without baseUrl)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update README.md (#8)

* docs(infra): confirm Supabase as project infrastructure (#9)

* chore(github): add collaboration templates and policy (#10)

* docs(env): document environment variable management (#11)

* docs(calendar): confirm MUI date picker usage (#12)

달력 UI 라이브러리로 MUI X Date Pickers + Day.js 사용을 확정하고
관련 문서(TECH_STACK, PROJECT_DECISIONS, CODING_CONVENTION, CALENDAR, DIARY, CLAUDE.md)에 반영한다.

* chore(deps): install MUI X Date Pickers and peer dependencies (#13)

달력 UI 구현을 위해 MUI X Date Pickers 및 필수 peer dependency를 설치한다.
@mui/material@9.1.1, @emotion/react@11.14.0, @emotion/styled@11.14.1,
@mui/x-date-pickers@9.5.0, dayjs@1.11.21

* Update README.md (#15)

* fix: resolve ESLint and TypeScript config warnings (#20)

* infra: add Next.js App Router entry files and SCSS base structure

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: resolve ESLint and TypeScript config warnings

- eslint.config.mjs: ignore next-env.d.ts and .next/** (auto-generated by Next.js, triple-slash reference false positive)
- tsconfig.json: remove deprecated baseUrl option (TypeScript 5.x+, paths works without baseUrl)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: add MVP Prisma schema with NextAuth and TALKY-OWL models (#21)

- datasource: add directUrl for Supabase connection pooler support
- enums: CategoryGroup, RoomMode, DisputeStatus, ParticipantRole, etc.
- NextAuth models: User (with TALKY-OWL fields), Account, Session, VerificationToken
- core models: DisputeRoom, RoomAiConversation, RoomAiMessage
- dispute models: Dispute, DisputeParticipant, DisputeStatement
- judgment models: AiJudgment, JudgmentResultCard
- gift models: GiftRecommendation, GiftRecommendationItem
- feature models: EmotionDiary, CalendarRecord
- master data: ConflictTypeGroup, ConflictTypeDetail (DB-based, no enum hardcoding)
- log models: AuditLog, ApiErrorLog, ModerationLog, RoomAccessLog, UserDeletionLog
- .env.example: add DIRECT_URL for Supabase directUrl
- v2.0 TODO: ShopItem, PointTransaction, UserItem, DisputeStatistic excluded

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: align project structure with guide v2 (#22)

folders added:
- src/components/{personal-analysis,room,dispute,judgement,calendar,diary,statistics,gift}
- src/app/api/auth/[...nextauth]
- src/app/api/v1/{users,personal-analyses,rooms,disputes,statements,calendar,diary,statistics,cron}

files added:
- prisma/seed.ts (placeholder for ConflictTypeGroup master data)

docs updated (minimal):
- docs/domains/COMMON.md: add log table list, judgement_logs TODO note
- docs/domains/JUDGEMENT.md: clarify Storage is MVP-excluded scaffolding
- docs/guides/ENV_GUIDE.md: clarify Supabase Storage vars are MVP-excluded

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: rename src/app/page to src/app/(page) for correct Next.js route group (#23)

src/app/page/ (괄호 없음)는 /page/* URL segment를 생성하므로,
Next.js App Router route group 문법인 src/app/(page)/로 변경한다.
URL은 /landing, /home 등으로 노출되어야 하며 /page/... 가 아니다.

관련 문서 내 경로 참조도 모두 업데이트 (CLAUDE.md, docs/domains/*, docs/guides/*).

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* [Style] 디자인 토큰 및 전역 스타일 설정 (#25)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 디자인 시스템 기반 설정 (#27)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: rem 스케일 토큰 추가 및 타이포그래피 변수 rem 참조로 전환

- Rem scale 섹션 추가 (0.25rem ~ 30rem)
- 폰트 토큰에서 누락된 0.875rem(14px), 1.125rem(18px) 추가
- font-size, line-height 변수를 rem 스케일 변수 참조로 전환
- rem 스케일을 typography 섹션보다 상단으로 이동 (선언 순서)
- 컴포넌트 width/height 대응을 위해 큰 단위(9rem~30rem) 포함

Co-Authored-By: Claude <noreply@anthropic.com>

* style: r() 함수 분리 및 타이포그래피 변수 함수 기반으로 전환

- _functions.scss 신규 추가 — px → rem 변환 함수 r() 단독 관리
- _variables.scss에서 rem 스케일 변수 제거, fn.r() 참조로 전환
- _mixins.scss에 functions @use 추가
- 순환 참조 없이 variables → functions → (없음) 단방향 의존성 구성

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Feature/common component jw (#28)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* fix: :root {} 시맨틱 토큰을 _global.scss로 분리 (#29)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: rem 스케일 토큰 추가 및 타이포그래피 변수 rem 참조로 전환

- Rem scale 섹션 추가 (0.25rem ~ 30rem)
- 폰트 토큰에서 누락된 0.875rem(14px), 1.125rem(18px) 추가
- font-size, line-height 변수를 rem 스케일 변수 참조로 전환
- rem 스케일을 typography 섹션보다 상단으로 이동 (선언 순서)
- 컴포넌트 width/height 대응을 위해 큰 단위(9rem~30rem) 포함

Co-Authored-By: Claude <noreply@anthropic.com>

* style: r() 함수 분리 및 타이포그래피 변수 함수 기반으로 전환

- _functions.scss 신규 추가 — px → rem 변환 함수 r() 단독 관리
- _variables.scss에서 rem 스케일 변수 제거, fn.r() 참조로 전환
- _mixins.scss에 functions @use 추가
- 순환 참조 없이 variables → functions → (없음) 단방향 의존성 구성

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: :root {} 시맨틱 토큰을 _global.scss로 분리

_variables.scss에 :root {}가 있으면 module.scss에서 @use 시
CSS Modules 'not pure' 에러 발생.
SCSS 변수는 _variables.scss, CSS 출력은 _global.scss로 분리.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): 공통 UI 컴포넌트 추가 및 MUI 정책 적용 (#30)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 목록 공통 UI 컴포넌트 추가 (Tab, StatusBadge) (#31)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 위치 수정 (#32)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 absolute 배치

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 공통 및 dispute·judgment DTO 타입 정의

- ApiResponse, ApiError, ApiFieldError, CategoryGroup (common.ts)
- DisputeDto, CreateDisputeRequest, DisputeListResponse 등 (dispute.ts)
- AiJudgmentDto, CreateAiJudgmentRequest 등 (judgment.ts)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: dispute 도메인 공유 상수·헬퍼·mapper 추가

- VALID_CATEGORY_GROUPS, IMMUTABLE_DISPUTE_STATUSES 상수 (constants/dispute.ts)
- getSessionUserId NextAuth 세션 헬퍼 (auth/session.ts)
- toAiJudgmentDto 공유 mapper (judgement/judgment.mapper.ts)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 목록 조회·생성·수정·삭제 API 구현

- GET /api/v1/disputes — 참여 사건 목록, categoryGroup 필터, 페이지네이션
- POST /api/v1/disputes — 사건 생성 + role_a 참여자 트랜잭션 등록
- GET /api/v1/disputes/:id — 사건 상세 조회
- PATCH /api/v1/disputes/:id — 사건 수정 (role_a 전용, 변경 불가 상태 차단)
- DELETE /api/v1/disputes/:id — 사건 소프트 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: AI 판결 요청·결과 조회 API 구현

- POST /api/v1/disputes/:id/judge — AI 판결 요청, JUDGING 상태 잠금으로 멱등성 보장
- GET /api/v1/disputes/:id/result — 판결 결과 조회 (참여자 전용)
- AI 모듈 미구현 구간은 TODO 주석으로 마킹, 완료 전까지 503 반환

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 공통 UI 컴포넌트 - StatusBadge, Tab, 진행 상태 (#33)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Prisma 클라이언트, NextAuth Kakao OAuth 설정 및 핸들러 추가

- src/lib/db/index.ts — Prisma 전역 싱글턴
- src/lib/auth/index.ts — NextAuth authOptions (Kakao OAuth, session user.id 매핑)
- src/app/api/auth/[...nextauth]/route.ts — NextAuth GET/POST 핸들러
- @mui/icons-material 패키지 설치 (빌드 에러 해결)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: 빌드 스크립트에 prisma generate 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: MVP 전체 API 명세서 작성 (API_SPEC.md) (#36)

* docs: MVP 전체 API 명세서 작성 (API_SPEC.md)

- 도메인 문서 및 기존 합의 기반 MVP API 명세 초안 작성
- 공통 응답 구조, 에러 코드 체계 정의
- Auth / User / Room / Dispute / Statement / Judgement / Diary / Calendar / Statistics / Gift / Cron 도메인 API 명세 포함
- 경로 충돌 항목 (withdraw, judge/result, diary 경로) 확정 필요 사항으로 명시
- 미확정 TODO 항목 섹션 7에 전체 정리
- MVP 제외 항목 (shop, points, 단독판결, 독립 통계 화면 등) 명시적으로 제거 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독 판결 MVP 포함 반영 및 라우트 주석 명확화

- 단독 판결(상대방 없는 AI 판결)을 MVP 포함 범위로 변경
- Personal Analysis 섹션에 단독 판결 API 초안 추가 (POST/GET /api/v1/personal-analyses)
- 라우트 트리 personal-analyses 디렉터리 구조 구체화
- /auth/withdraw route.ts 주석을 경로 충돌 상호 참조가 명확한 형태로 수정
  (경로 충돌 → /auth/withdraw vs DELETE /users/me)
- MVP 제외 목록에서 단독 판결 항목 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 카카오 로그인 시 약관 동의 자동 간주 정책 반영

- 카카오 OAuth 로그인 완료를 약관 동의로 간주
- 별도 약관 동의 페이지 이동 플로우 제거
- 확정 필요 항목에서 약관 동의 기준 항목 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 도메인 API 목록 중복 제거 및 회원탈퇴 경로 확정

- docs/domains/*.md 8개 파일의 API 목록 섹션을 docs/API_SPEC.md 참조로 교체
  (AUTH, USER, ROOM, DISPUTE, JUDGEMENT, DIARY, CALENDAR, STATISTICS)
- API_SPEC.md 단일 소스 체계 확립
- 회원탈퇴 경로 DELETE /api/v1/users/me 채택 확정
  - §3 요약표, §4.1·§4.2 상세, §5 라우트 트리, §6 충돌 목록, §7 체크리스트 반영
  - /auth/withdraw 라우트 제거, /users/me route.ts에 DELETE 추가
- CLAUDE_WORKFLOW.md PR 템플릿 준수 문구 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 날짜 포맷 및 Pagination 구조 확정 반영

- 날짜/시간 포맷 ISO 8601 (YYYY-MM-DDTHH:mm:ssZ) 확정
- Pagination 공통 구조 확정
  - data 필드: items 배열
  - page 필드: page / totalPages / sortBy / isNext
- 섹션 7 확정 필요 항목 두 개 체크 처리
- Room 목록, Diary 목록 섹션 Pagination 참조로 갱신

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: Pagination 구조에 size / sort / hasNext / hasPrevious 추가

- size: 한 번에 가져오는 항목 수
- sort: 정렬 방향 (asc | desc)
- isNext → hasNext로 변경 (다음 페이지 존재 여부)
- hasPrevious 추가 (이전 페이지 존재 여부)
- §7 체크리스트 항목 갱신

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 날짜 포맷 코드블록 언어 지정자 추가 (MD040)

코드래빗 지적 사항 반영 — 언어 미지정 펜스 코드블록에 text 지정자 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 통계 API 비로그인 공개 조회로 변경

홈 화면 진입 시 비로그인 회원도 통계 조회 가능하도록 수정
- GET /api/v1/statistics/summary: 🔒 → 공개
- GET /api/v1/statistics/top-types: 🔒 → 공개
- §3 요약표, §4.9 상세 명세 인증 표기 및 설명 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 목록 응답 예시에 page 객체 추가 (코드래빗 지적 반영)

- GET /api/v1/rooms 응답 예시에 page 객체 추가
- GET /api/v1/diary 응답 예시에 page 객체 추가
- GET /api/v1/statistics/top-types 응답 예시에 page 객체 추가
  (Top5 고정 목록 특성 반영: size=5, totalPages=1, hasNext=false)
- 코드래빗 제안의 구버전 필드(isNext) 대신 확정 구조(hasNext/hasPrevious/size/sort) 적용
- §7 Room Pagination 항목 체크 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Spinner, Avatar, AvatarGroup 공통 컴포넌트 추가 (#37)

* chore: 정적 이미지 에셋 추가 및 정리

주요 페이지용 캐릭터 이미지 추가 및 공통 에셋 정리.
gift, loading 캐릭터를 common에서 characters로 이동하여
캐릭터 이미지를 한 폴더로 통합.

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: Spinner 공통 컴포넌트 추가

캐릭터 로딩 이미지를 중앙에 배치한 88x88 스피너 컴포넌트 추가.
트랙(배경 원)과 애니메이션 링을 분리하여 각각 border-default, bg-brand 색상 적용.

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: Avatar, AvatarGroup 공통 컴포넌트 추가

MUI Avatar, AvatarGroup 래핑 컴포넌트 추가.
size prop으로 s/m/l 사이즈 조절, src prop으로 프로필 사진 지원.
global.scss에 --color-white, --color-black CSS 변수 추가.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: Avatar Context로 AvatarGroup size 전달 및 토큰 수정

AvatarGroup size prop이 자식 Avatar에 적용 안 되는 버그 수정.
Context를 통해 size를 내려주고 Avatar가 그룹 size를 우선 적용.
color 토큰 --color-white를 --text-inverse로 교체.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: Avatar src 없을 때 기본 썸네일 이미지로 fallback 처리

Co-Authored-By: Claude <noreply@anthropic.com>

* test: Spinner, Avatar, AvatarGroup 테스트 페이지 추가

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

* feat: 공통 UI 컴포넌트 - CategoryFilter, CategoryIcon, Tab, StatusBadge (#38)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 공통 컴포넌트 생성

- 전체/연애/직장/친구/가족 카테고리 필터 구현
- 아이콘 박스 44x44, border-radius 8, 아이콘 24x24
- 선택 상태: icon-primary bg / 미선택: bg-disabled
- MUI icons 사용 (GridViewRounded, Favorite, BusinessCenter, Diversity3, FamilyRestroom)
- Category 타입 export

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Tab 라벨 폰트 스타일 명시

- item.label을 span.label로 래핑
- Body-M 기준 font-size 16, line-height 28 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: @mui/icons-material 패키지 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 스타일 및 single 모드 적용

- 선택: bg-page + border-brand(1px) + icon-primary + 텍스트 bold
- 미선택: bg-page + border-default(1px) + icon-secondary + 텍스트 regular
- mode prop 추가 (filter 기본값 / single: 선택된 박스 하나만 표시)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 타입을 DB CategoryGroup 기준으로 통일

## 수정 배경

CategoryIcon, CategoryFilter가 한국어 문자열('연애', '직장' 등)을 타입으로 사용하고 있어
API/DB의 CategoryGroup('romance', 'work' 등)과 불일치가 발생.
페이지에서 연결 시 별도 변환 레이어가 필요해지는 문제를 사전 차단.

## 변경 파일별 수정 내용

### CategoryIcon.tsx
- CategoryWithoutAll 타입 제거 → @/types/common의 CategoryGroup 직접 사용
- 아이콘/레이블/컬러 맵 키를 한국어 → 영문 DB 값으로 변경
  (romance, work, friend, family)
- CATEGORY_LABEL_MAP export 추가 (CategoryFilter에서 레이블 참조용)

### CategoryFilter.tsx
- Category 타입을 'all' | CategoryGroup으로 변경 (기존: 한국어 문자열)
- CATEGORIES 배열에 label 필드 추가, CATEGORY_LABEL_MAP에서 참조
- 전체 키를 '전체' → 'all'로 변경 (API 필터 미적용 값과 일치)

### CaseCard.tsx (타팀원 파일 수정)
- 수정 이유: CATEGORY_EMOJI 맵 키가 대문자('ROMANCE')였으나
  API 응답은 소문자('romance')로 내려와 emoji가 항상 '📋' fallback만 표시되는 버그 존재
- 해결 방법: emoji 방식 전체 제거, CategoryIcon 컴포넌트로 교체
- categoryGroup prop 타입을 string → CategoryGroup으로 명시
- categoryGroup 미전달 시 아이콘 미표시 처리 (optional 유지)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update src/components/ui/CategoryIcon.tsx

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: CategoryIcon 중복 import 제거 및 CategoryFilter discriminated union 타입 에러 수정

- CategoryIcon: FamilyRestroomIcon, CategoryGroup 중복 import 제거
- CategoryFilter: discriminated union(CodeRabbit 피드백 반영) 유지하면서
  props 전체로 받아 props.mode로 narrowing 처리해 타입 에러 해결
  (mode='single'일 때 onChange가 CategoryGroup을 기대하는 문제)
- Tab.module.scss: height → min-height 변경 (유연한 높이 대응)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard 카테고리 아이콘을 제목 왼쪽 인라인으로 이동

- card__header 구조 변경: titleRow(아이콘+제목)와 badge를 좌우 배치
- card__titleRow 추가: flex row, align-items center, gap 6px
- 아이콘이 제목 위에 쌓이던 문제 수정 → 제목 왼쪽에 인라인 배치
- card__icon: font-size/line-height(이모지 잔재) → display:flex 로 변경
- card__title: margin-bottom 제거(card__header margin-bottom으로 대체)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 공통 컴포넌트 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard titleRow flex 축소 보완 (min-width: 0, flex: 1)

긴 제목에서 card__titleRow가 축소되지 않아 배지가 밀리는 문제 방지.
card__header가 space-between일 때 titleRow가 flex: 1로 가용 공간을 차지하고
min-width: 0으로 내부 콘텐츠가 넘치지 않도록 제약.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix(common): BottomNavigation 아이콘 MUI MD2 기본 스타일로 수정 (#39)

* fix(common): BottomNavigation 아이콘을 MUI MD2 기본 스타일로 수정

- HomeRounded → Home
- GavelRounded → MenuBook (사건기록 아이콘 자체 변경)
- CalendarMonthRounded → CalendarMonth
- PersonRounded → Person
디자인 시안 기준 MD2 filled 아이콘으로 통일

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: BottomNavigation 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): BottomNavigation 활성 탭 레이블 색상 black-700으로 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): BottomNavigation 테스트 스크린샷 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: wjdalss21 <jungxmin21@gmail.com>

* feat: 사건·방 도메인 타입 정의 및 API 구현 (#40)

* feat: room DTO 타입 정의

- RoomMode, RoomDto, CreateRoomRequest, RoomListResponse

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 방 목록 조회·생성·상세 조회·종료·삭제 API 구현

- GET  /api/v1/rooms — 내 방 목록 조회 (페이지네이션)
- POST /api/v1/rooms — AI 대화방 생성 (roomMode = ai_chat)
- GET  /api/v1/rooms/:id — 방 상세 조회
- POST /api/v1/rooms/:id/close — 방 종료 (closedAt + roomMode = closed)
- DELETE /api/v1/rooms/:id — 방 소프트 삭제 (deletedAt + roomMode = deleted)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 방 목록 페이지네이션 파라미터 NaN 방어 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: API 라우트 경로 v1 버전 세그먼트 제거 (#42)

* fix: API 라우트 경로에서 v1 버전 세그먼트 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 라우트 핸들러 주석 경로 v1 제거 (/api/v1/ -> /api/)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): 서비스 흐름 기반 문서 구조 수정 및 페이지 문서 생성 (#43)

* fix(docs): 서비스 흐름 기반 문서 구조 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): PAGES.md 코드 블록 언어 명시 추가 (MD040)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: personal-analyses 페이지 및 API 폴더 삭제 (#45)

* fix: personal-analyses 페이지 및 API 폴더 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): personal-analysis 도메인 참조 MD 문서 일괄 정리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 API 구현 (GET /api/statistics/categories) (#44)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 공통 컴포넌트 생성

- 전체/연애/직장/친구/가족 카테고리 필터 구현
- 아이콘 박스 44x44, border-radius 8, 아이콘 24x24
- 선택 상태: icon-primary bg / 미선택: bg-disabled
- MUI icons 사용 (GridViewRounded, Favorite, BusinessCenter, Diversity3, FamilyRestroom)
- Category 타입 export

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Tab 라벨 폰트 스타일 명시

- item.label을 span.label로 래핑
- Body-M 기준 font-size 16, line-height 28 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: @mui/icons-material 패키지 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 스타일 및 single 모드 적용

- 선택: bg-page + border-brand(1px) + icon-primary + 텍스트 bold
- 미선택: bg-page + border-default(1px) + icon-secondary + 텍스트 regular
- mode prop 추가 (filter 기본값 / single: 선택된 박스 하나만 표시)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 타입을 DB CategoryGroup 기준으로 통일

## 수정 배경

CategoryIcon, CategoryFilter가 한국어 문자열('연애', '직장' 등)을 타입으로 사용하고 있어
API/DB의 CategoryGroup('romance', 'work' 등)과 불일치가 발생.
페이지에서 연결 시 별도 변환 레이어가 필요해지는 문제를 사전 차단.

## 변경 파일별 수정 내용

### CategoryIcon.tsx
- CategoryWithoutAll 타입 제거 → @/types/common의 CategoryGroup 직접 사용
- 아이콘/레이블/컬러 맵 키를 한국어 → 영문 DB 값으로 변경
  (romance, work, friend, family)
- CATEGORY_LABEL_MAP export 추가 (CategoryFilter에서 레이블 참조용)

### CategoryFilter.tsx
- Category 타입을 'all' | CategoryGroup으로 변경 (기존: 한국어 문자열)
- CATEGORIES 배열에 label 필드 추가, CATEGORY_LABEL_MAP에서 참조
- 전체 키를 '전체' → 'all'로 변경 (API 필터 미적용 값과 일치)

### CaseCard.tsx (타팀원 파일 수정)
- 수정 이유: CATEGORY_EMOJI 맵 키가 대문자('ROMANCE')였으나
  API 응답은 소문자('romance')로 내려와 emoji가 항상 '📋' fallback만 표시되는 버그 존재
- 해결 방법: emoji 방식 전체 제거, CategoryIcon 컴포넌트로 교체
- categoryGroup prop 타입을 string → CategoryGroup으로 명시
- categoryGroup 미전달 시 아이콘 미표시 처리 (optional 유지)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update src/components/ui/CategoryIcon.tsx

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: CategoryIcon 중복 import 제거 및 CategoryFilter discriminated union 타입 에러 수정

- CategoryIcon: FamilyRestroomIcon, CategoryGroup 중복 import 제거
- CategoryFilter: discriminated union(CodeRabbit 피드백 반영) 유지하면서
  props 전체로 받아 props.mode로 narrowing 처리해 타입 에러 해결
  (mode='single'일 때 onChange가 CategoryGroup을 기대하는 문제)
- Tab.module.scss: height → min-height 변경 (유연한 높이 대응)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard 카테고리 아이콘을 제목 왼쪽 인라인으로 이동

- card__header 구조 변경: titleRow(아이콘+제목)와 badge를 좌우 배치
- card__titleRow 추가: flex row, align-items center, gap 6px
- 아이콘이 제목 위에 쌓이던 문제 수정 → 제목 왼쪽에 인라인 배치
- card__icon: font-size/line-height(이모지 잔재) → display:flex 로 변경
- card__title: margin-bottom 제거(card__header margin-bottom으로 대체)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 공통 컴포넌트 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard titleRow flex 축소 보완 (min-width: 0, flex: 1)

긴 제목에서 card__titleRow가 축소되지 않아 배지가 밀리는 문제 방지.
card__header가 space-between일 때 titleRow가 flex: 1로 가용 공간을 차지하고
min-width: 0으로 내부 콘텐츠가 넘치지 않도록 제약.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 도메인 서비스 레이어 생성 (statisticsService.ts)

## 생성 이유
통계 API의 DB 쿼리 로직을 Route Handler와 분리하기 위해
도메인 서비스 레이어를 별도 파일로 작성했다.

## 폴더 선택 이유
src/domains/statistics/
- CLAUDE.md §4 아키텍처 원칙에 따라 도메인별 비즈니스 로직은
  src/domains/{domain}/ 에 위치한다.
- statistics는 MVP 도메인 목록에 포함된 독립 도메인이다.
- Route Handler(src/app/api/)는 요청/응답 처리만 담당하고,
  실제 DB 쿼리 로직은 서비스 레이어에서 관리한다.

## 구현 내용

### getSummary()
- 서비스 전체 판결 완료 건수(totalJudgements) 집계
- dispute.status = JUDGED 조건 명시: ai_judgements는 판결 완료 시에만
  생성되지만 의도를 코드에 명시적으로 표현
- deletedAt / anonymizedAt IS NULL: 삭제·익명화된 사건 제외 (CLAUDE.md §7)

### getTopTypes(size = 5)
- ai_judgements.result_conflict_detail_id 기준 GROUP BY COUNT DESC
- 결과 유형 마스터(conflict_type_details)를 JOIN해 detailCode·displayName 반환
- isActive = true 필터: 비활성화된 유형은 통계에서 제외
- percentage 서버 계산: count / total * 100 (소수점 1자리)
  FE에서 별도 계산 없이 바로 사용할 수 있도록 서버에서 내려줌
- prisma.conflictTypeDetail 사용 (prisma.conflictDetail은 스키마에 존재하지 않음)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 API Route Handler 생성 (GET /api/v1/statistics/top-types)

## 생성 이유
statisticsService의 getTopTypes()를 HTTP 엔드포인트로 노출하기 위해
Next.js App Router 기반 Route Handler를 생성했다.

## 폴더 선택 이유
src/app/api/v1/statistics/top-types/
- CLAUDE.md §4 아키텍처 원칙에 따라 API Route는 src/app/api/v1/ 하위에 위치한다.
- API_SPEC.md §4.9 기준 엔드포인트 경로: GET /api/v1/statistics/top-types
- summary 엔드포인트는 현재 MVP 범위에서 불필요하여 top-types만 생성

## 구현 내용
- getServerSession으로 서버에서 직접 세션 검증
  (FE 리다이렉트만으로는 API 직접 호출을 막을 수 없으므로 서버 검증 필수 — CLAUDE.md §7)
- 인증 실패 시 401 UNAUTHORIZED 반환
- getTopTypes(5) 호출 → 판결 완료 기준 Top5 유형 + 비율 반환
- ApiResponse 타입 준수: data/error는 null 아닌 undefined(optional) 사용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: statistics top-types 인증 제거 (메인 페이지 공개 접근 허용)

메인 페이지에서도 통계 차트가 노출되는 익명 집계 데이터이므로
세션 없이 접근 가능하도록 수정.

- getServerSession 및 관련 import 제거
- 401 인증 체크 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: statistics top-types 에러 핸들링 보완

코드래빗 피드백 반영:
- catch {} -> catch (error): 에러 정보 유실 방지
- 타임아웃 감지 후 504 분기 처리
- console.error 로깅 추가 (CLAUDE.md 11 API 오류 로그 대상)
- 세션 체크는 이전 커밋에서 이미 제거됨 (공개 엔드포인트)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: 통계 API 카테고리 기준으로 재설계

- 결과 유형(top-types) → 작성 카테고리(ROMANCE/FAMILY/FRIEND/WORK) 기준으로 변경
- route.ts에 DB 쿼리 직접 작성, statisticsService.ts 제거
- 비율 계산은 프론트 훅(useStatistics)에서 담당
- revalidate = 86400 (하루 1회 재계산)
- src/hooks/ 폴더 신설 및 useStatistics.ts 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 통계 API 서버 측 세션 인증 추가

- GET /api/statistics/categories 진입 시 getServerSession으로 인증 검증
- 미인증 요청 401 UNAUTHORIZED 반환

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* feat: Header variant 분리 (logo/title) 및 홈 화면 적용 (#47)

* feat: 홈 화면 기본 구조 생성 (헤더, 일기 박스)

- 헤더: 세션 유저명 + character-welcome.png 부엉이 이미지
- 일기 박스: 365x88, border black-700 2px, bg primary-100
- TODO: GangwonEduPower 폰트 추가 후 헤더 로고 텍스트 적용 필요

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Header variant 분리 (logo/title) 및 홈 화면 적용

- Header.tsx에 variant prop 추가 (logo | title)
  - logo: 좌측 상단 말해부엉 로고 표시 (66x19, h:56, padding: 16px 20px)
  - title: 기존 뒤로가기 + 페이지 제목 형태 유지
- Header.module.scss에 __logo 스타일 추가
- home/page.tsx에 Header variant='logo' 적용
  - 헤더를 컨테이너 padding 밖으로 분리하여 상단 여백 제거
- home/page.module.scss diaryBox에 align-self: center 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건기록 페이지 생성 및 로고 헤더 적용 (/records)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: diaryBox 고정 폭을 max-width + width 100%로 반응형 처리

- width: 365px → width: 100% + max-width: 365px
- 작은 화면에서 좌우 패딩과 결합 시 오버플로우 방지

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 감정일기 작성 버튼 /diary/new 네비게이션 연결

- 일기 박스 전체를 Link로 변경 (텍스트 + 버튼 모두 클릭 가능)
- diaryBox에 text-decoration: none, cursor: pointer 추가
- /diary/new 경로는 임시 지정 (담당자 확인 후 수정 예정)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면 캐릭터 이미지 교체 및 위치 조정

- character-welcome.png → character-home.png 교체 (169x138)
- 캐릭터 절대 위치 적용 (top: 41px, right: -20px)
- 캐릭터가 일기 박스 뒤에 위치하도록 z-index 조정 (character: 0, container: 1)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 홈 화면 코드래빗 피드백 반영

- 캐릭터 이미지 가로 스크롤 방지: .page에 overflow-x: hidden 추가
- 비로그인 사용자 분기 처리: 말해부엉 알아보기 박스 추가 (/login 이동)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: 홈 화면 typography 믹신 적용

- greetingText, diaryTitle, diarySubtitle에 typography 믹신 사용
- 개별 font 속성 직접 선언 → @include m.text-* 토큰으로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 비로그인 알아보기 박스 위치 수정

- 인사/일기 박스는 로그인 여부 무관하게 항상 표시
- 말해부엉 알아보기 박스를 진행중인 사건 위치(구분선 아래)로 이동
- 비로그인 인사: '안녕하세요' 표시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면에 통계 섹션 및 구분선 통합

- StatsCategorySection, useStatistics, QueryProvider 병합
- 고민 카테고리 TOP4 통계 섹션 추가
- 통계 섹션 하단 구분선 추가 (h:8px, black-100, gap:42px)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: 개발 편의용 로그인 상태 강제 설정 (배포 전 제거 필요)

- isLoggedIn = true 하드코딩으로 로그인 상태 유지
- TODO 주석으로 배포 전 제거 안내 표시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건작성 페이지 구현 (disputes/[id]/statement) (#46)

* feat: 사건작성 페이지 구현 (disputes/[id]/statement)

- 사건 카테고리 선택 (연애/직장/친구/가족)
- MBTI 선택 드롭다운
- 진술 내용 입력 (최대 1000자)
- 진술저장 버튼 (내용 입력 시 활성화)
- TODO: 진술 저장 API 연결

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 사건작성 페이지 카테고리/간격/드롭다운 수정

- 카테고리를 searchParams에서 읽어 하나만 표시 (비상호작용)
- 카테고리 없을 시 모달 표시 후 이전 페이지로 이동
- Select/Textarea 사이 간격 8px (statementGroup)
- label/Select 사이 간격 16px 유지
- Textarea placeholder 줄바꿈 적용 (\n)
- content overflow-y 제거 → Select 드롭다운 아래 방향 열림 수정
- Select placeholder 색상 var(--text-secondary) 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 없음 모달에서 버튼 제거 — 페이지 블로킹만 유지

확인 버튼 클릭 시 이동하지 않고 Header 뒤로가기로만 탈출 가능

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 기본값 romance 적용, 모달 확인 버튼 복원

- searchParams에 카테고리 없을 시 임시로 romance 기본값 사용
- 모달 확인 버튼 클릭 시 router.back() 복원
- TODO: 이전 페이지 카테고리 데이터 연동 후 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 커스텀 드롭다운 교체 및 Textarea focus 스타일 제거

- Select: 네이티브 select → 커스텀 드롭다운 (항상 아래 방향 열림)
- Select: placeholder 색상 --text-secondary 적용 (option 색 영향 없음)
- Select: 아이콘 회전 애니메이션 추가
- Textarea: focus 시 border-color 변경 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: Button 좌우 패딩 16 → 12으로 조정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: SCSS import 상대경로 → 절대경로(@/) 변환 및 컨벤션 문서 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 접근성 및 스타일 개선

- ul 기본 margin 리셋
- hasValue를 options.find 기준으로 판단 (빈 문자열 오인 방지)
- aria-invalid / aria-describedby 연결로 보조기기 지원
- 키보드 내비게이션 추가 (ArrowUp/Down, Enter/Space, Escape)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: dispute 생성 조건을 active room 전체로 완화 (ONE_TO_ONE 제한 제거)

혼자서도 판결 가능한 흐름을 지원하기 위해
room.roomMode !== 'ONE_TO_ONE' 체크를 제거하고
CLOSED/EXPIRED 방만 차단하도록 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select id 안정화, 빈 options 가드, Tab 기본 포커스 이동 허용

- resolvedId를 label 문자열 대신 useId() 기반으로 고정
- option id를 value 대신 index 기반으로 변경
- Enter/Space 시 options 길이 가드 추가 (크래시 방지)
- Tab은 preventDefault 제거 — 닫기만 하고 포커스 이동은 브라우저에 위임

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독 판결 MVP 포함 및 관련 정책 업데이트 (#51)

- Section 1: 단독 판결 / 1:1 판결 흐름 분리 명시
- Section 2: 단독 판결을 MVP 포함으로 이동, MVP 제외에서 제거
- Section 3: AI 대화방 정책 수정 (ai_chat/invite_ready 상태 단독 판결 허용)
- Section 3: 단독 판결 vs 1:1 판결 제공 결과 비교 섹션 추가
- Section 14: 단독 판결 관련 STOP Condition 항목 제거

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Feature/verdict record display - 캘린더 페이지 ui 제작  (#41)

* feat : 다이어리 (감정일기 , 사건기록)탭분리

* feat : 달력 ui 커스텀 추가 및 감정일기 사건기록 분기처리

* refactor:  및 캘린더 페이지구조 개선 (리뷰 피드백 반영)

* feat : 감정일기카드 컴포넌트 구현

* fix: build 에러 ( 임시 페이지 )

* refactor: 감정일기 컴포넌트 SCSS 모듈 적용 및 믹스인 토큰 사용

* feat: 달력 페이지 UI 구현 및 스타일 정리

- MUI DateCalendar 커스텀
- 감정일기 / 사건기록 탭 전환 구조 구현
- EmotionDiaryList, RecordList 빈 상태 UI 추가
- DiaryCard mixin 적용 (text-title-s, text-body-s, text-label-s)
- 인라인 style 제거 → SCSS 모듈로 분리
- outsideCurrentMonth 감정 아이콘 노출 차단
- 새 일기 FAB 버튼 추가 (감정일기 탭 전용)
- 불필요한 파일 삭제 (DiaryMode, EmotionDiaryCard 등)

* style : EmotionDiaryList.moulde 스타일 수정

* feat: 달력 RecordList에 CaseCard 연동 및 스타일 개선

* Update model name from 'gpt-5.5' to 'gemini-2.5-flash'

seed.ts Ai modelName 수정

---------

Co-authored-by: 배근영 <bgy09270@naver.com>

* feat: 사건작성(진술서) 페이지 구현 및 욕설 감지 필터 연동 (#49)

* feat: 사건작성 페이지 구현 (disputes/[id]/statement)

- 사건 카테고리 선택 (연애/직장/친구/가족)
- MBTI 선택 드롭다운
- 진술 내용 입력 (최대 1000자)
- 진술저장 버튼 (내용 입력 시 활성화)
- TODO: 진술 저장 API 연결

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 사건작성 페이지 카테고리/간격/드롭다운 수정

- 카테고리를 searchParams에서 읽어 하나만 표시 (비상호작용)
- 카테고리 없을 시 모달 표시 후 이전 페이지로 이동
- Select/Textarea 사이 간격 8px (statementGroup)
- label/Select 사이 간격 16px 유지
- Textarea placeholder 줄바꿈 적용 (\n)
- content overflow-y 제거 → Select 드롭다운 아래 방향 열림 수정
- Select placeholder 색상 var(--text-secondary) 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 없음 모달에서 버튼 제거 — 페이지 블로킹만 유지

확인 버튼 클릭 시 이동하지 않고 Header 뒤로가기로만 탈출 가능

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 기본값 romance 적용, 모달 확인 버튼 복원

- searchParams에 카테고리 없을 시 임시로 romance 기본값 사용
- 모달 확인 버튼 클릭 시 router.back() 복원
- TODO: 이전 페이지 카테고리 데이터 연동 후 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 커스텀 드롭다운 교체 및 Textarea focus 스타일 제거

- Select: 네이티브 select → 커스텀 드롭다운 (항상 아래 방향 열림)
- Select: placeholder 색상 --text-secondary 적용 (option 색 영향 없음)
- Select: 아이콘 회전 애니메이션 추가
- Textarea: focus 시 border-color 변경 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: Button 좌우 패딩 16 → 12으로 조정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: SCSS import 상대경로 → 절대경로(@/) 변환 및 컨벤션 문서 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 접근성 및 스타일 개선

- ul 기본 margin 리셋
- hasValue를 options.find 기준으로 판단 (빈 문자열 오인 방지)
- aria-invalid / aria-describedby 연결로 보조기기 지원
- 키보드 내비게이션 추가 (ArrowUp/Down, Enter/Space, Escape)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: dispute 생성 조건을 active room 전체로 완화 (ONE_TO_ONE 제한 제거)

혼자서도 판결 가능한 흐름을 지원하기 위해
room.roomMode !== 'ONE_TO_ONE' 체크를 제거하고
CLOSED/EXPIRED 방만 차단하도록 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select id 안정화, 빈 options 가드, Tab 기본 포커스 이동 허용

- resolvedId를 label 문자열 대신 useId() 기반으로 고정
- option id를 value 대신 index 기반으로 변경
- Enter/Space 시 options 길이 가드 추가 (크래시 방지)
- Tab은 preventDefault 제거 — 닫기만 하고 포커스 이동은 브라우저에 위임

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Textarea 바이트 카운팅 및 filterMessage prop 추가

- 한글 2바이트/ASCII 1바이트 기준으로 글자 수 계산
- maxLength 초과 시 바이트 기준으로 자동 truncate
- filterMessage prop 추가 — 욕설 차단 메시지 동적 표시
- border 색상 변경은 error prop에만 적용 (filter는 border 유지)
- filter-warning 텍스트: Body-S + var(--text-danger)
- field gap 8 → 10px (Figma 기준)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 욕설 감지 필터 구현 (Gemini 2.5 Flash)

- moderation.ts: Gemini 2.5 Flash 기반 욕설/개인정보 감지
  - isBlocked: 욕설·혐오·위협 차단 (보수적 기준)
  - hasPersonalInfo: 개인정보 경고 (차단 없음)
  - fail-open: Gemini 실패 시 pending 상태로 저장
- statements/route.ts: 진술 저장 API
  - 모더레이션 통과 후 upsert + ModerationLog 트랜잭션
  - 차단 시 ModerationLog만 기록, 저장 없이 422 반환
  - dev bypass: 개발 환경에서 세션 없이 모더레이션 테스트 가능
- page.tsx: handleSave 연결, filterMessage 상태, 개인정보 경고 모달
- StatementPage.module.scss: 모달 스타일, Stylelint 공백 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: PR #49 코드리뷰 수정 — MBTI 연동, 파싱 에러, 인젝션, 타임아웃

- MBTI: GET /api/user/me 신규 생성, statement 페이지 마운트 시 user.mbti 초기화
- MBTI: handleSave body에 mbti 포함, statements route에서 user.mbti 업데이트 (트랜잭션)
- statement/page.tsx: res.json() 파싱 실패를 별도 try-catch로 분리
- Textarea.tsx: e.target.value 직접 변경 → Object.assign으로 새 이벤트 객체 전달
- moderation.ts: content 삽입 전 < > HTML 이스케이프 (프롬프트 인젝션 방지)
- moderation.ts: Promise.race() 기반 10초 타임아웃 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: user/me route catch 블록에 에러 로깅 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: judge route 1인 판결 허용 — isSolo 분기 및 rollback 상태 수정

- 2인: BOTH_SUBMITTED 상태 확인 유지
- 1인: 진술 제출 여부만 확인 (statements.length > 0)
- 롤백 대상을 하드코딩된 BOTH_SUBMITTED → previousStatus로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 카카오 로그인 기능 구현 (#50)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 absolute 배치

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 카카오 로그인 기능 구현

- 로그인 페이지 UI 및 카카오 signIn 버튼 연결
- @auth/prisma-adapter 설치 및 authOptions에 적용
- 최초 로그인 시 kakaoId, nickname, termsAgreedAt 자동 설정
- 닉네임 자동 생성 유틸 추가 (~하는부엉이 + 4자리 난수)
- middleware 추가: 비인증 사용자 /login 리다이렉트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 로그인 페이지 및 인증 로직 개선

- SCSS import 절대경로(@/) 수정
- 캐릭터 이미지 Next/Image fill → img 태그로 변경
- 이용약관/개인정보처리방침 링크(/terms, /privacy) 추가 및 스타일 적용
- 닉네임 유니크 제약(@unique) 추가 및 충돌 재시도 로직 구현 (최대 10회)
- middleware matcher 패턴 보완 (/login-help 등 우회 경로 차단)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: disclaimer mixin 적용, nickname 유실 복구 및 fallback 랜덤화

- .disclaimer에 @include m.text-caption mixin 적용
- 유실된 nickname.ts 복구
- fallback 닉네임 Date.now() → 랜덤 8자리 숫자로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독/1:1 판결 공통 진입 흐름 반영 및 관련 문서 일괄 수정 (#54)

- 단독 판결과 1:1 판결이 완전히 분리된 진입이 아니라
  AI 대화방 → 진술저장 → [분기] → disputes/[id]/statement 경로를 공통으로 거침
- CLAUDE.md: 핵심 서비스 흐름 분기 구조로 수정, 단독 판결 MVP 포함 반영,
  AI 대화방 정책 단독/1:1 병행 기술, dispute_status 단독 경로 추가
- PROJECT_DECISIONS.md: 흐름·MVP포함·MVP제외·dispute_status 동기화
- STATUS_TRANSITION.md: 단독 판결 경로(draft→judging→judged) 추가
- DISPUTE.md: 상태 전이 단독/1:1 경로 분리 기술, 주의사항 확정 내용 반영
- ROOM.md: 진술저장 후 분기 흐름 포함 기능에 명시

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Login 페이지 hydration removeChild 에러 수정 (#55)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
…
evenif99 added a commit that referenced this pull request Jun 29, 2026
* chore: initialize project folder structure (#1)

* chore: initialize project folder structure

- Add base directory layout for Next.js + domain-driven architecture
- Add .gitkeep to track empty directories in git
- Exclude MVP out-of-scope domains (shop, points, user-items)
- No implementation files included, structure only

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update README.md

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add CLAUDE.md with project rules and work guidelines (#2)

- Add project overview and MVP scope definition
- Add fixed product rules (categories, AI chat policy, judgement output)
- Add architecture, domain scope, and state transition rules
- Add auth/security, DB, frontend state, API, logging rules
- Add Git workflow, Claude work process, STOP conditions
- Add approval-required list and required reference documents

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: setup project config and install dependencies (#3)

- Add package.json with Next.js 15, React 19, TypeScript stack
- Add next.config.ts (minimal Next.js 15 config)
- Add tsconfig.json (strict mode, @/* path alias)
- Add eslint.config.mjs (next/core-web-vitals + next/typescript)
- Add .prettierrc and .prettierignore
- Add .gitignore (node_modules, .next, .env.local, etc.)
- Add .env.example (key names only, no real values)
- Add prisma/schema.prisma (generator + datasource only)
- Add data/mock/db.json (health check stub for json-server)
- Add docs/TECH_STACK.md (package list and selection rationale)
- Update README.md with run commands and env guide

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add base documentation structure (#4)

- Add PROJECT_DECISIONS.md (MVP scope, architecture, security principles)
- Add guides/CLAUDE_WORKFLOW.md (work process, STOP conditions, approval rules)
- Add guides/GIT_WORKFLOW.md (branch naming, commit convention, workflow)
- Add guides/PR_RULES.md (PR target, title rules, review criteria)
- Add guides/ENV_GUIDE.md (Vercel env pull, .env.example management)
- Add guides/CODING_CONVENTION.md (naming, state management, folder rules)
- Add db/STATUS_TRANSITION.md (room_mode, dispute_status transitions)
- Add db/PRISMA_MAPPING.md (snake_case/camelCase mapping rules)
- Add db/MASTER_DATA.md (categories, result types, DB master principles)
- Add domains/README.md (domain list, MVP scope, writing guidelines)
- Add domains/_DOMAIN_TEMPLATE.md (template for domain docs)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add domain document drafts for all MVP domains (#5)

- Add AUTH.md (kakao login, terms, session management)
- Add COMMON.md (error handling, logging, common response)
- Add ROOM.md (AI chat room, invite link, room_mode transitions)
- Add PERSONAL_ANALYSIS.md (AI-based personal conflict analysis)
- Add DISPUTE.md (1:1 mediation, roles, statements, dispute_status)
- Add JUDGEMENT.md (AI judgement, Gemini API, result card)
- Add GIFT.md (gift recommendation after judgement)
- Add USER.md (mypage, profile, bottom tab)
- Add CALENDAR.md (date-based record marking, monthly summary)
- Add DIARY.md (emotion diary, author-only access, content protection)
- Add STATISTICS.md (anonymous aggregation, summary components)
- Add SHOP_FUTURE.md (v2.0 planned, MVP excluded)
- Add POINTS_FUTURE.md (v2.0 planned, MVP excluded)
- Add USER_ITEMS_FUTURE.md (v2.0 planned, MVP excluded)

All documents are draft templates with TODO markers for assignees.
No implementation, no API routes, no schema changes.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: add Next.js App Router entry files and SCSS base structure (#6)

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Infra/init next setup (#7)

* infra: add Next.js App Router entry files and SCSS base structure

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: resolve ESLint and TypeScript config warnings

- eslint.config.mjs: ignore next-env.d.ts and .next/** (auto-generated by Next.js, triple-slash reference false positive)
- tsconfig.json: remove deprecated baseUrl option (TypeScript 5.x+, paths works without baseUrl)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update README.md (#8)

* docs(infra): confirm Supabase as project infrastructure (#9)

* chore(github): add collaboration templates and policy (#10)

* docs(env): document environment variable management (#11)

* docs(calendar): confirm MUI date picker usage (#12)

달력 UI 라이브러리로 MUI X Date Pickers + Day.js 사용을 확정하고
관련 문서(TECH_STACK, PROJECT_DECISIONS, CODING_CONVENTION, CALENDAR, DIARY, CLAUDE.md)에 반영한다.

* chore(deps): install MUI X Date Pickers and peer dependencies (#13)

달력 UI 구현을 위해 MUI X Date Pickers 및 필수 peer dependency를 설치한다.
@mui/material@9.1.1, @emotion/react@11.14.0, @emotion/styled@11.14.1,
@mui/x-date-pickers@9.5.0, dayjs@1.11.21

* Update README.md (#15)

* fix: resolve ESLint and TypeScript config warnings (#20)

* infra: add Next.js App Router entry files and SCSS base structure

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: resolve ESLint and TypeScript config warnings

- eslint.config.mjs: ignore next-env.d.ts and .next/** (auto-generated by Next.js, triple-slash reference false positive)
- tsconfig.json: remove deprecated baseUrl option (TypeScript 5.x+, paths works without baseUrl)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: add MVP Prisma schema with NextAuth and TALKY-OWL models (#21)

- datasource: add directUrl for Supabase connection pooler support
- enums: CategoryGroup, RoomMode, DisputeStatus, ParticipantRole, etc.
- NextAuth models: User (with TALKY-OWL fields), Account, Session, VerificationToken
- core models: DisputeRoom, RoomAiConversation, RoomAiMessage
- dispute models: Dispute, DisputeParticipant, DisputeStatement
- judgment models: AiJudgment, JudgmentResultCard
- gift models: GiftRecommendation, GiftRecommendationItem
- feature models: EmotionDiary, CalendarRecord
- master data: ConflictTypeGroup, ConflictTypeDetail (DB-based, no enum hardcoding)
- log models: AuditLog, ApiErrorLog, ModerationLog, RoomAccessLog, UserDeletionLog
- .env.example: add DIRECT_URL for Supabase directUrl
- v2.0 TODO: ShopItem, PointTransaction, UserItem, DisputeStatistic excluded

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: align project structure with guide v2 (#22)

folders added:
- src/components/{personal-analysis,room,dispute,judgement,calendar,diary,statistics,gift}
- src/app/api/auth/[...nextauth]
- src/app/api/v1/{users,personal-analyses,rooms,disputes,statements,calendar,diary,statistics,cron}

files added:
- prisma/seed.ts (placeholder for ConflictTypeGroup master data)

docs updated (minimal):
- docs/domains/COMMON.md: add log table list, judgement_logs TODO note
- docs/domains/JUDGEMENT.md: clarify Storage is MVP-excluded scaffolding
- docs/guides/ENV_GUIDE.md: clarify Supabase Storage vars are MVP-excluded

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: rename src/app/page to src/app/(page) for correct Next.js route group (#23)

src/app/page/ (괄호 없음)는 /page/* URL segment를 생성하므로,
Next.js App Router route group 문법인 src/app/(page)/로 변경한다.
URL은 /landing, /home 등으로 노출되어야 하며 /page/... 가 아니다.

관련 문서 내 경로 참조도 모두 업데이트 (CLAUDE.md, docs/domains/*, docs/guides/*).

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* [Style] 디자인 토큰 및 전역 스타일 설정 (#25)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 디자인 시스템 기반 설정 (#27)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: rem 스케일 토큰 추가 및 타이포그래피 변수 rem 참조로 전환

- Rem scale 섹션 추가 (0.25rem ~ 30rem)
- 폰트 토큰에서 누락된 0.875rem(14px), 1.125rem(18px) 추가
- font-size, line-height 변수를 rem 스케일 변수 참조로 전환
- rem 스케일을 typography 섹션보다 상단으로 이동 (선언 순서)
- 컴포넌트 width/height 대응을 위해 큰 단위(9rem~30rem) 포함

Co-Authored-By: Claude <noreply@anthropic.com>

* style: r() 함수 분리 및 타이포그래피 변수 함수 기반으로 전환

- _functions.scss 신규 추가 — px → rem 변환 함수 r() 단독 관리
- _variables.scss에서 rem 스케일 변수 제거, fn.r() 참조로 전환
- _mixins.scss에 functions @use 추가
- 순환 참조 없이 variables → functions → (없음) 단방향 의존성 구성

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Feature/common component jw (#28)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* fix: :root {} 시맨틱 토큰을 _global.scss로 분리 (#29)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: rem 스케일 토큰 추가 및 타이포그래피 변수 rem 참조로 전환

- Rem scale 섹션 추가 (0.25rem ~ 30rem)
- 폰트 토큰에서 누락된 0.875rem(14px), 1.125rem(18px) 추가
- font-size, line-height 변수를 rem 스케일 변수 참조로 전환
- rem 스케일을 typography 섹션보다 상단으로 이동 (선언 순서)
- 컴포넌트 width/height 대응을 위해 큰 단위(9rem~30rem) 포함

Co-Authored-By: Claude <noreply@anthropic.com>

* style: r() 함수 분리 및 타이포그래피 변수 함수 기반으로 전환

- _functions.scss 신규 추가 — px → rem 변환 함수 r() 단독 관리
- _variables.scss에서 rem 스케일 변수 제거, fn.r() 참조로 전환
- _mixins.scss에 functions @use 추가
- 순환 참조 없이 variables → functions → (없음) 단방향 의존성 구성

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: :root {} 시맨틱 토큰을 _global.scss로 분리

_variables.scss에 :root {}가 있으면 module.scss에서 @use 시
CSS Modules 'not pure' 에러 발생.
SCSS 변수는 _variables.scss, CSS 출력은 _global.scss로 분리.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): 공통 UI 컴포넌트 추가 및 MUI 정책 적용 (#30)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 목록 공통 UI 컴포넌트 추가 (Tab, StatusBadge) (#31)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 위치 수정 (#32)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 absolute 배치

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 공통 및 dispute·judgment DTO 타입 정의

- ApiResponse, ApiError, ApiFieldError, CategoryGroup (common.ts)
- DisputeDto, CreateDisputeRequest, DisputeListResponse 등 (dispute.ts)
- AiJudgmentDto, CreateAiJudgmentRequest 등 (judgment.ts)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: dispute 도메인 공유 상수·헬퍼·mapper 추가

- VALID_CATEGORY_GROUPS, IMMUTABLE_DISPUTE_STATUSES 상수 (constants/dispute.ts)
- getSessionUserId NextAuth 세션 헬퍼 (auth/session.ts)
- toAiJudgmentDto 공유 mapper (judgement/judgment.mapper.ts)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 목록 조회·생성·수정·삭제 API 구현

- GET /api/v1/disputes — 참여 사건 목록, categoryGroup 필터, 페이지네이션
- POST /api/v1/disputes — 사건 생성 + role_a 참여자 트랜잭션 등록
- GET /api/v1/disputes/:id — 사건 상세 조회
- PATCH /api/v1/disputes/:id — 사건 수정 (role_a 전용, 변경 불가 상태 차단)
- DELETE /api/v1/disputes/:id — 사건 소프트 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: AI 판결 요청·결과 조회 API 구현

- POST /api/v1/disputes/:id/judge — AI 판결 요청, JUDGING 상태 잠금으로 멱등성 보장
- GET /api/v1/disputes/:id/result — 판결 결과 조회 (참여자 전용)
- AI 모듈 미구현 구간은 TODO 주석으로 마킹, 완료 전까지 503 반환

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 공통 UI 컴포넌트 - StatusBadge, Tab, 진행 상태 (#33)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Prisma 클라이언트, NextAuth Kakao OAuth 설정 및 핸들러 추가

- src/lib/db/index.ts — Prisma 전역 싱글턴
- src/lib/auth/index.ts — NextAuth authOptions (Kakao OAuth, session user.id 매핑)
- src/app/api/auth/[...nextauth]/route.ts — NextAuth GET/POST 핸들러
- @mui/icons-material 패키지 설치 (빌드 에러 해결)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: 빌드 스크립트에 prisma generate 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: MVP 전체 API 명세서 작성 (API_SPEC.md) (#36)

* docs: MVP 전체 API 명세서 작성 (API_SPEC.md)

- 도메인 문서 및 기존 합의 기반 MVP API 명세 초안 작성
- 공통 응답 구조, 에러 코드 체계 정의
- Auth / User / Room / Dispute / Statement / Judgement / Diary / Calendar / Statistics / Gift / Cron 도메인 API 명세 포함
- 경로 충돌 항목 (withdraw, judge/result, diary 경로) 확정 필요 사항으로 명시
- 미확정 TODO 항목 섹션 7에 전체 정리
- MVP 제외 항목 (shop, points, 단독판결, 독립 통계 화면 등) 명시적으로 제거 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독 판결 MVP 포함 반영 및 라우트 주석 명확화

- 단독 판결(상대방 없는 AI 판결)을 MVP 포함 범위로 변경
- Personal Analysis 섹션에 단독 판결 API 초안 추가 (POST/GET /api/v1/personal-analyses)
- 라우트 트리 personal-analyses 디렉터리 구조 구체화
- /auth/withdraw route.ts 주석을 경로 충돌 상호 참조가 명확한 형태로 수정
  (경로 충돌 → /auth/withdraw vs DELETE /users/me)
- MVP 제외 목록에서 단독 판결 항목 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 카카오 로그인 시 약관 동의 자동 간주 정책 반영

- 카카오 OAuth 로그인 완료를 약관 동의로 간주
- 별도 약관 동의 페이지 이동 플로우 제거
- 확정 필요 항목에서 약관 동의 기준 항목 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 도메인 API 목록 중복 제거 및 회원탈퇴 경로 확정

- docs/domains/*.md 8개 파일의 API 목록 섹션을 docs/API_SPEC.md 참조로 교체
  (AUTH, USER, ROOM, DISPUTE, JUDGEMENT, DIARY, CALENDAR, STATISTICS)
- API_SPEC.md 단일 소스 체계 확립
- 회원탈퇴 경로 DELETE /api/v1/users/me 채택 확정
  - §3 요약표, §4.1·§4.2 상세, §5 라우트 트리, §6 충돌 목록, §7 체크리스트 반영
  - /auth/withdraw 라우트 제거, /users/me route.ts에 DELETE 추가
- CLAUDE_WORKFLOW.md PR 템플릿 준수 문구 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 날짜 포맷 및 Pagination 구조 확정 반영

- 날짜/시간 포맷 ISO 8601 (YYYY-MM-DDTHH:mm:ssZ) 확정
- Pagination 공통 구조 확정
  - data 필드: items 배열
  - page 필드: page / totalPages / sortBy / isNext
- 섹션 7 확정 필요 항목 두 개 체크 처리
- Room 목록, Diary 목록 섹션 Pagination 참조로 갱신

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: Pagination 구조에 size / sort / hasNext / hasPrevious 추가

- size: 한 번에 가져오는 항목 수
- sort: 정렬 방향 (asc | desc)
- isNext → hasNext로 변경 (다음 페이지 존재 여부)
- hasPrevious 추가 (이전 페이지 존재 여부)
- §7 체크리스트 항목 갱신

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 날짜 포맷 코드블록 언어 지정자 추가 (MD040)

코드래빗 지적 사항 반영 — 언어 미지정 펜스 코드블록에 text 지정자 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 통계 API 비로그인 공개 조회로 변경

홈 화면 진입 시 비로그인 회원도 통계 조회 가능하도록 수정
- GET /api/v1/statistics/summary: 🔒 → 공개
- GET /api/v1/statistics/top-types: 🔒 → 공개
- §3 요약표, §4.9 상세 명세 인증 표기 및 설명 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 목록 응답 예시에 page 객체 추가 (코드래빗 지적 반영)

- GET /api/v1/rooms 응답 예시에 page 객체 추가
- GET /api/v1/diary 응답 예시에 page 객체 추가
- GET /api/v1/statistics/top-types 응답 예시에 page 객체 추가
  (Top5 고정 목록 특성 반영: size=5, totalPages=1, hasNext=false)
- 코드래빗 제안의 구버전 필드(isNext) 대신 확정 구조(hasNext/hasPrevious/size/sort) 적용
- §7 Room Pagination 항목 체크 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Spinner, Avatar, AvatarGroup 공통 컴포넌트 추가 (#37)

* chore: 정적 이미지 에셋 추가 및 정리

주요 페이지용 캐릭터 이미지 추가 및 공통 에셋 정리.
gift, loading 캐릭터를 common에서 characters로 이동하여
캐릭터 이미지를 한 폴더로 통합.

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: Spinner 공통 컴포넌트 추가

캐릭터 로딩 이미지를 중앙에 배치한 88x88 스피너 컴포넌트 추가.
트랙(배경 원)과 애니메이션 링을 분리하여 각각 border-default, bg-brand 색상 적용.

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: Avatar, AvatarGroup 공통 컴포넌트 추가

MUI Avatar, AvatarGroup 래핑 컴포넌트 추가.
size prop으로 s/m/l 사이즈 조절, src prop으로 프로필 사진 지원.
global.scss에 --color-white, --color-black CSS 변수 추가.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: Avatar Context로 AvatarGroup size 전달 및 토큰 수정

AvatarGroup size prop이 자식 Avatar에 적용 안 되는 버그 수정.
Context를 통해 size를 내려주고 Avatar가 그룹 size를 우선 적용.
color 토큰 --color-white를 --text-inverse로 교체.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: Avatar src 없을 때 기본 썸네일 이미지로 fallback 처리

Co-Authored-By: Claude <noreply@anthropic.com>

* test: Spinner, Avatar, AvatarGroup 테스트 페이지 추가

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

* feat: 공통 UI 컴포넌트 - CategoryFilter, CategoryIcon, Tab, StatusBadge (#38)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 공통 컴포넌트 생성

- 전체/연애/직장/친구/가족 카테고리 필터 구현
- 아이콘 박스 44x44, border-radius 8, 아이콘 24x24
- 선택 상태: icon-primary bg / 미선택: bg-disabled
- MUI icons 사용 (GridViewRounded, Favorite, BusinessCenter, Diversity3, FamilyRestroom)
- Category 타입 export

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Tab 라벨 폰트 스타일 명시

- item.label을 span.label로 래핑
- Body-M 기준 font-size 16, line-height 28 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: @mui/icons-material 패키지 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 스타일 및 single 모드 적용

- 선택: bg-page + border-brand(1px) + icon-primary + 텍스트 bold
- 미선택: bg-page + border-default(1px) + icon-secondary + 텍스트 regular
- mode prop 추가 (filter 기본값 / single: 선택된 박스 하나만 표시)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 타입을 DB CategoryGroup 기준으로 통일

## 수정 배경

CategoryIcon, CategoryFilter가 한국어 문자열('연애', '직장' 등)을 타입으로 사용하고 있어
API/DB의 CategoryGroup('romance', 'work' 등)과 불일치가 발생.
페이지에서 연결 시 별도 변환 레이어가 필요해지는 문제를 사전 차단.

## 변경 파일별 수정 내용

### CategoryIcon.tsx
- CategoryWithoutAll 타입 제거 → @/types/common의 CategoryGroup 직접 사용
- 아이콘/레이블/컬러 맵 키를 한국어 → 영문 DB 값으로 변경
  (romance, work, friend, family)
- CATEGORY_LABEL_MAP export 추가 (CategoryFilter에서 레이블 참조용)

### CategoryFilter.tsx
- Category 타입을 'all' | CategoryGroup으로 변경 (기존: 한국어 문자열)
- CATEGORIES 배열에 label 필드 추가, CATEGORY_LABEL_MAP에서 참조
- 전체 키를 '전체' → 'all'로 변경 (API 필터 미적용 값과 일치)

### CaseCard.tsx (타팀원 파일 수정)
- 수정 이유: CATEGORY_EMOJI 맵 키가 대문자('ROMANCE')였으나
  API 응답은 소문자('romance')로 내려와 emoji가 항상 '📋' fallback만 표시되는 버그 존재
- 해결 방법: emoji 방식 전체 제거, CategoryIcon 컴포넌트로 교체
- categoryGroup prop 타입을 string → CategoryGroup으로 명시
- categoryGroup 미전달 시 아이콘 미표시 처리 (optional 유지)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update src/components/ui/CategoryIcon.tsx

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: CategoryIcon 중복 import 제거 및 CategoryFilter discriminated union 타입 에러 수정

- CategoryIcon: FamilyRestroomIcon, CategoryGroup 중복 import 제거
- CategoryFilter: discriminated union(CodeRabbit 피드백 반영) 유지하면서
  props 전체로 받아 props.mode로 narrowing 처리해 타입 에러 해결
  (mode='single'일 때 onChange가 CategoryGroup을 기대하는 문제)
- Tab.module.scss: height → min-height 변경 (유연한 높이 대응)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard 카테고리 아이콘을 제목 왼쪽 인라인으로 이동

- card__header 구조 변경: titleRow(아이콘+제목)와 badge를 좌우 배치
- card__titleRow 추가: flex row, align-items center, gap 6px
- 아이콘이 제목 위에 쌓이던 문제 수정 → 제목 왼쪽에 인라인 배치
- card__icon: font-size/line-height(이모지 잔재) → display:flex 로 변경
- card__title: margin-bottom 제거(card__header margin-bottom으로 대체)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 공통 컴포넌트 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard titleRow flex 축소 보완 (min-width: 0, flex: 1)

긴 제목에서 card__titleRow가 축소되지 않아 배지가 밀리는 문제 방지.
card__header가 space-between일 때 titleRow가 flex: 1로 가용 공간을 차지하고
min-width: 0으로 내부 콘텐츠가 넘치지 않도록 제약.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix(common): BottomNavigation 아이콘 MUI MD2 기본 스타일로 수정 (#39)

* fix(common): BottomNavigation 아이콘을 MUI MD2 기본 스타일로 수정

- HomeRounded → Home
- GavelRounded → MenuBook (사건기록 아이콘 자체 변경)
- CalendarMonthRounded → CalendarMonth
- PersonRounded → Person
디자인 시안 기준 MD2 filled 아이콘으로 통일

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: BottomNavigation 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): BottomNavigation 활성 탭 레이블 색상 black-700으로 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): BottomNavigation 테스트 스크린샷 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: wjdalss21 <jungxmin21@gmail.com>

* feat: 사건·방 도메인 타입 정의 및 API 구현 (#40)

* feat: room DTO 타입 정의

- RoomMode, RoomDto, CreateRoomRequest, RoomListResponse

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 방 목록 조회·생성·상세 조회·종료·삭제 API 구현

- GET  /api/v1/rooms — 내 방 목록 조회 (페이지네이션)
- POST /api/v1/rooms — AI 대화방 생성 (roomMode = ai_chat)
- GET  /api/v1/rooms/:id — 방 상세 조회
- POST /api/v1/rooms/:id/close — 방 종료 (closedAt + roomMode = closed)
- DELETE /api/v1/rooms/:id — 방 소프트 삭제 (deletedAt + roomMode = deleted)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 방 목록 페이지네이션 파라미터 NaN 방어 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: API 라우트 경로 v1 버전 세그먼트 제거 (#42)

* fix: API 라우트 경로에서 v1 버전 세그먼트 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 라우트 핸들러 주석 경로 v1 제거 (/api/v1/ -> /api/)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): 서비스 흐름 기반 문서 구조 수정 및 페이지 문서 생성 (#43)

* fix(docs): 서비스 흐름 기반 문서 구조 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): PAGES.md 코드 블록 언어 명시 추가 (MD040)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: personal-analyses 페이지 및 API 폴더 삭제 (#45)

* fix: personal-analyses 페이지 및 API 폴더 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): personal-analysis 도메인 참조 MD 문서 일괄 정리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 API 구현 (GET /api/statistics/categories) (#44)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 공통 컴포넌트 생성

- 전체/연애/직장/친구/가족 카테고리 필터 구현
- 아이콘 박스 44x44, border-radius 8, 아이콘 24x24
- 선택 상태: icon-primary bg / 미선택: bg-disabled
- MUI icons 사용 (GridViewRounded, Favorite, BusinessCenter, Diversity3, FamilyRestroom)
- Category 타입 export

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Tab 라벨 폰트 스타일 명시

- item.label을 span.label로 래핑
- Body-M 기준 font-size 16, line-height 28 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: @mui/icons-material 패키지 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 스타일 및 single 모드 적용

- 선택: bg-page + border-brand(1px) + icon-primary + 텍스트 bold
- 미선택: bg-page + border-default(1px) + icon-secondary + 텍스트 regular
- mode prop 추가 (filter 기본값 / single: 선택된 박스 하나만 표시)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 타입을 DB CategoryGroup 기준으로 통일

## 수정 배경

CategoryIcon, CategoryFilter가 한국어 문자열('연애', '직장' 등)을 타입으로 사용하고 있어
API/DB의 CategoryGroup('romance', 'work' 등)과 불일치가 발생.
페이지에서 연결 시 별도 변환 레이어가 필요해지는 문제를 사전 차단.

## 변경 파일별 수정 내용

### CategoryIcon.tsx
- CategoryWithoutAll 타입 제거 → @/types/common의 CategoryGroup 직접 사용
- 아이콘/레이블/컬러 맵 키를 한국어 → 영문 DB 값으로 변경
  (romance, work, friend, family)
- CATEGORY_LABEL_MAP export 추가 (CategoryFilter에서 레이블 참조용)

### CategoryFilter.tsx
- Category 타입을 'all' | CategoryGroup으로 변경 (기존: 한국어 문자열)
- CATEGORIES 배열에 label 필드 추가, CATEGORY_LABEL_MAP에서 참조
- 전체 키를 '전체' → 'all'로 변경 (API 필터 미적용 값과 일치)

### CaseCard.tsx (타팀원 파일 수정)
- 수정 이유: CATEGORY_EMOJI 맵 키가 대문자('ROMANCE')였으나
  API 응답은 소문자('romance')로 내려와 emoji가 항상 '📋' fallback만 표시되는 버그 존재
- 해결 방법: emoji 방식 전체 제거, CategoryIcon 컴포넌트로 교체
- categoryGroup prop 타입을 string → CategoryGroup으로 명시
- categoryGroup 미전달 시 아이콘 미표시 처리 (optional 유지)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update src/components/ui/CategoryIcon.tsx

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: CategoryIcon 중복 import 제거 및 CategoryFilter discriminated union 타입 에러 수정

- CategoryIcon: FamilyRestroomIcon, CategoryGroup 중복 import 제거
- CategoryFilter: discriminated union(CodeRabbit 피드백 반영) 유지하면서
  props 전체로 받아 props.mode로 narrowing 처리해 타입 에러 해결
  (mode='single'일 때 onChange가 CategoryGroup을 기대하는 문제)
- Tab.module.scss: height → min-height 변경 (유연한 높이 대응)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard 카테고리 아이콘을 제목 왼쪽 인라인으로 이동

- card__header 구조 변경: titleRow(아이콘+제목)와 badge를 좌우 배치
- card__titleRow 추가: flex row, align-items center, gap 6px
- 아이콘이 제목 위에 쌓이던 문제 수정 → 제목 왼쪽에 인라인 배치
- card__icon: font-size/line-height(이모지 잔재) → display:flex 로 변경
- card__title: margin-bottom 제거(card__header margin-bottom으로 대체)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 공통 컴포넌트 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard titleRow flex 축소 보완 (min-width: 0, flex: 1)

긴 제목에서 card__titleRow가 축소되지 않아 배지가 밀리는 문제 방지.
card__header가 space-between일 때 titleRow가 flex: 1로 가용 공간을 차지하고
min-width: 0으로 내부 콘텐츠가 넘치지 않도록 제약.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 도메인 서비스 레이어 생성 (statisticsService.ts)

## 생성 이유
통계 API의 DB 쿼리 로직을 Route Handler와 분리하기 위해
도메인 서비스 레이어를 별도 파일로 작성했다.

## 폴더 선택 이유
src/domains/statistics/
- CLAUDE.md §4 아키텍처 원칙에 따라 도메인별 비즈니스 로직은
  src/domains/{domain}/ 에 위치한다.
- statistics는 MVP 도메인 목록에 포함된 독립 도메인이다.
- Route Handler(src/app/api/)는 요청/응답 처리만 담당하고,
  실제 DB 쿼리 로직은 서비스 레이어에서 관리한다.

## 구현 내용

### getSummary()
- 서비스 전체 판결 완료 건수(totalJudgements) 집계
- dispute.status = JUDGED 조건 명시: ai_judgements는 판결 완료 시에만
  생성되지만 의도를 코드에 명시적으로 표현
- deletedAt / anonymizedAt IS NULL: 삭제·익명화된 사건 제외 (CLAUDE.md §7)

### getTopTypes(size = 5)
- ai_judgements.result_conflict_detail_id 기준 GROUP BY COUNT DESC
- 결과 유형 마스터(conflict_type_details)를 JOIN해 detailCode·displayName 반환
- isActive = true 필터: 비활성화된 유형은 통계에서 제외
- percentage 서버 계산: count / total * 100 (소수점 1자리)
  FE에서 별도 계산 없이 바로 사용할 수 있도록 서버에서 내려줌
- prisma.conflictTypeDetail 사용 (prisma.conflictDetail은 스키마에 존재하지 않음)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 API Route Handler 생성 (GET /api/v1/statistics/top-types)

## 생성 이유
statisticsService의 getTopTypes()를 HTTP 엔드포인트로 노출하기 위해
Next.js App Router 기반 Route Handler를 생성했다.

## 폴더 선택 이유
src/app/api/v1/statistics/top-types/
- CLAUDE.md §4 아키텍처 원칙에 따라 API Route는 src/app/api/v1/ 하위에 위치한다.
- API_SPEC.md §4.9 기준 엔드포인트 경로: GET /api/v1/statistics/top-types
- summary 엔드포인트는 현재 MVP 범위에서 불필요하여 top-types만 생성

## 구현 내용
- getServerSession으로 서버에서 직접 세션 검증
  (FE 리다이렉트만으로는 API 직접 호출을 막을 수 없으므로 서버 검증 필수 — CLAUDE.md §7)
- 인증 실패 시 401 UNAUTHORIZED 반환
- getTopTypes(5) 호출 → 판결 완료 기준 Top5 유형 + 비율 반환
- ApiResponse 타입 준수: data/error는 null 아닌 undefined(optional) 사용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: statistics top-types 인증 제거 (메인 페이지 공개 접근 허용)

메인 페이지에서도 통계 차트가 노출되는 익명 집계 데이터이므로
세션 없이 접근 가능하도록 수정.

- getServerSession 및 관련 import 제거
- 401 인증 체크 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: statistics top-types 에러 핸들링 보완

코드래빗 피드백 반영:
- catch {} -> catch (error): 에러 정보 유실 방지
- 타임아웃 감지 후 504 분기 처리
- console.error 로깅 추가 (CLAUDE.md 11 API 오류 로그 대상)
- 세션 체크는 이전 커밋에서 이미 제거됨 (공개 엔드포인트)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: 통계 API 카테고리 기준으로 재설계

- 결과 유형(top-types) → 작성 카테고리(ROMANCE/FAMILY/FRIEND/WORK) 기준으로 변경
- route.ts에 DB 쿼리 직접 작성, statisticsService.ts 제거
- 비율 계산은 프론트 훅(useStatistics)에서 담당
- revalidate = 86400 (하루 1회 재계산)
- src/hooks/ 폴더 신설 및 useStatistics.ts 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 통계 API 서버 측 세션 인증 추가

- GET /api/statistics/categories 진입 시 getServerSession으로 인증 검증
- 미인증 요청 401 UNAUTHORIZED 반환

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* feat: Header variant 분리 (logo/title) 및 홈 화면 적용 (#47)

* feat: 홈 화면 기본 구조 생성 (헤더, 일기 박스)

- 헤더: 세션 유저명 + character-welcome.png 부엉이 이미지
- 일기 박스: 365x88, border black-700 2px, bg primary-100
- TODO: GangwonEduPower 폰트 추가 후 헤더 로고 텍스트 적용 필요

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Header variant 분리 (logo/title) 및 홈 화면 적용

- Header.tsx에 variant prop 추가 (logo | title)
  - logo: 좌측 상단 말해부엉 로고 표시 (66x19, h:56, padding: 16px 20px)
  - title: 기존 뒤로가기 + 페이지 제목 형태 유지
- Header.module.scss에 __logo 스타일 추가
- home/page.tsx에 Header variant='logo' 적용
  - 헤더를 컨테이너 padding 밖으로 분리하여 상단 여백 제거
- home/page.module.scss diaryBox에 align-self: center 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건기록 페이지 생성 및 로고 헤더 적용 (/records)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: diaryBox 고정 폭을 max-width + width 100%로 반응형 처리

- width: 365px → width: 100% + max-width: 365px
- 작은 화면에서 좌우 패딩과 결합 시 오버플로우 방지

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 감정일기 작성 버튼 /diary/new 네비게이션 연결

- 일기 박스 전체를 Link로 변경 (텍스트 + 버튼 모두 클릭 가능)
- diaryBox에 text-decoration: none, cursor: pointer 추가
- /diary/new 경로는 임시 지정 (담당자 확인 후 수정 예정)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면 캐릭터 이미지 교체 및 위치 조정

- character-welcome.png → character-home.png 교체 (169x138)
- 캐릭터 절대 위치 적용 (top: 41px, right: -20px)
- 캐릭터가 일기 박스 뒤에 위치하도록 z-index 조정 (character: 0, container: 1)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 홈 화면 코드래빗 피드백 반영

- 캐릭터 이미지 가로 스크롤 방지: .page에 overflow-x: hidden 추가
- 비로그인 사용자 분기 처리: 말해부엉 알아보기 박스 추가 (/login 이동)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: 홈 화면 typography 믹신 적용

- greetingText, diaryTitle, diarySubtitle에 typography 믹신 사용
- 개별 font 속성 직접 선언 → @include m.text-* 토큰으로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 비로그인 알아보기 박스 위치 수정

- 인사/일기 박스는 로그인 여부 무관하게 항상 표시
- 말해부엉 알아보기 박스를 진행중인 사건 위치(구분선 아래)로 이동
- 비로그인 인사: '안녕하세요' 표시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면에 통계 섹션 및 구분선 통합

- StatsCategorySection, useStatistics, QueryProvider 병합
- 고민 카테고리 TOP4 통계 섹션 추가
- 통계 섹션 하단 구분선 추가 (h:8px, black-100, gap:42px)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: 개발 편의용 로그인 상태 강제 설정 (배포 전 제거 필요)

- isLoggedIn = true 하드코딩으로 로그인 상태 유지
- TODO 주석으로 배포 전 제거 안내 표시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건작성 페이지 구현 (disputes/[id]/statement) (#46)

* feat: 사건작성 페이지 구현 (disputes/[id]/statement)

- 사건 카테고리 선택 (연애/직장/친구/가족)
- MBTI 선택 드롭다운
- 진술 내용 입력 (최대 1000자)
- 진술저장 버튼 (내용 입력 시 활성화)
- TODO: 진술 저장 API 연결

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 사건작성 페이지 카테고리/간격/드롭다운 수정

- 카테고리를 searchParams에서 읽어 하나만 표시 (비상호작용)
- 카테고리 없을 시 모달 표시 후 이전 페이지로 이동
- Select/Textarea 사이 간격 8px (statementGroup)
- label/Select 사이 간격 16px 유지
- Textarea placeholder 줄바꿈 적용 (\n)
- content overflow-y 제거 → Select 드롭다운 아래 방향 열림 수정
- Select placeholder 색상 var(--text-secondary) 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 없음 모달에서 버튼 제거 — 페이지 블로킹만 유지

확인 버튼 클릭 시 이동하지 않고 Header 뒤로가기로만 탈출 가능

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 기본값 romance 적용, 모달 확인 버튼 복원

- searchParams에 카테고리 없을 시 임시로 romance 기본값 사용
- 모달 확인 버튼 클릭 시 router.back() 복원
- TODO: 이전 페이지 카테고리 데이터 연동 후 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 커스텀 드롭다운 교체 및 Textarea focus 스타일 제거

- Select: 네이티브 select → 커스텀 드롭다운 (항상 아래 방향 열림)
- Select: placeholder 색상 --text-secondary 적용 (option 색 영향 없음)
- Select: 아이콘 회전 애니메이션 추가
- Textarea: focus 시 border-color 변경 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: Button 좌우 패딩 16 → 12으로 조정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: SCSS import 상대경로 → 절대경로(@/) 변환 및 컨벤션 문서 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 접근성 및 스타일 개선

- ul 기본 margin 리셋
- hasValue를 options.find 기준으로 판단 (빈 문자열 오인 방지)
- aria-invalid / aria-describedby 연결로 보조기기 지원
- 키보드 내비게이션 추가 (ArrowUp/Down, Enter/Space, Escape)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: dispute 생성 조건을 active room 전체로 완화 (ONE_TO_ONE 제한 제거)

혼자서도 판결 가능한 흐름을 지원하기 위해
room.roomMode !== 'ONE_TO_ONE' 체크를 제거하고
CLOSED/EXPIRED 방만 차단하도록 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select id 안정화, 빈 options 가드, Tab 기본 포커스 이동 허용

- resolvedId를 label 문자열 대신 useId() 기반으로 고정
- option id를 value 대신 index 기반으로 변경
- Enter/Space 시 options 길이 가드 추가 (크래시 방지)
- Tab은 preventDefault 제거 — 닫기만 하고 포커스 이동은 브라우저에 위임

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독 판결 MVP 포함 및 관련 정책 업데이트 (#51)

- Section 1: 단독 판결 / 1:1 판결 흐름 분리 명시
- Section 2: 단독 판결을 MVP 포함으로 이동, MVP 제외에서 제거
- Section 3: AI 대화방 정책 수정 (ai_chat/invite_ready 상태 단독 판결 허용)
- Section 3: 단독 판결 vs 1:1 판결 제공 결과 비교 섹션 추가
- Section 14: 단독 판결 관련 STOP Condition 항목 제거

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Feature/verdict record display - 캘린더 페이지 ui 제작  (#41)

* feat : 다이어리 (감정일기 , 사건기록)탭분리

* feat : 달력 ui 커스텀 추가 및 감정일기 사건기록 분기처리

* refactor:  및 캘린더 페이지구조 개선 (리뷰 피드백 반영)

* feat : 감정일기카드 컴포넌트 구현

* fix: build 에러 ( 임시 페이지 )

* refactor: 감정일기 컴포넌트 SCSS 모듈 적용 및 믹스인 토큰 사용

* feat: 달력 페이지 UI 구현 및 스타일 정리

- MUI DateCalendar 커스텀
- 감정일기 / 사건기록 탭 전환 구조 구현
- EmotionDiaryList, RecordList 빈 상태 UI 추가
- DiaryCard mixin 적용 (text-title-s, text-body-s, text-label-s)
- 인라인 style 제거 → SCSS 모듈로 분리
- outsideCurrentMonth 감정 아이콘 노출 차단
- 새 일기 FAB 버튼 추가 (감정일기 탭 전용)
- 불필요한 파일 삭제 (DiaryMode, EmotionDiaryCard 등)

* style : EmotionDiaryList.moulde 스타일 수정

* feat: 달력 RecordList에 CaseCard 연동 및 스타일 개선

* Update model name from 'gpt-5.5' to 'gemini-2.5-flash'

seed.ts Ai modelName 수정

---------

Co-authored-by: 배근영 <bgy09270@naver.com>

* feat: 사건작성(진술서) 페이지 구현 및 욕설 감지 필터 연동 (#49)

* feat: 사건작성 페이지 구현 (disputes/[id]/statement)

- 사건 카테고리 선택 (연애/직장/친구/가족)
- MBTI 선택 드롭다운
- 진술 내용 입력 (최대 1000자)
- 진술저장 버튼 (내용 입력 시 활성화)
- TODO: 진술 저장 API 연결

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 사건작성 페이지 카테고리/간격/드롭다운 수정

- 카테고리를 searchParams에서 읽어 하나만 표시 (비상호작용)
- 카테고리 없을 시 모달 표시 후 이전 페이지로 이동
- Select/Textarea 사이 간격 8px (statementGroup)
- label/Select 사이 간격 16px 유지
- Textarea placeholder 줄바꿈 적용 (\n)
- content overflow-y 제거 → Select 드롭다운 아래 방향 열림 수정
- Select placeholder 색상 var(--text-secondary) 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 없음 모달에서 버튼 제거 — 페이지 블로킹만 유지

확인 버튼 클릭 시 이동하지 않고 Header 뒤로가기로만 탈출 가능

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 기본값 romance 적용, 모달 확인 버튼 복원

- searchParams에 카테고리 없을 시 임시로 romance 기본값 사용
- 모달 확인 버튼 클릭 시 router.back() 복원
- TODO: 이전 페이지 카테고리 데이터 연동 후 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 커스텀 드롭다운 교체 및 Textarea focus 스타일 제거

- Select: 네이티브 select → 커스텀 드롭다운 (항상 아래 방향 열림)
- Select: placeholder 색상 --text-secondary 적용 (option 색 영향 없음)
- Select: 아이콘 회전 애니메이션 추가
- Textarea: focus 시 border-color 변경 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: Button 좌우 패딩 16 → 12으로 조정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: SCSS import 상대경로 → 절대경로(@/) 변환 및 컨벤션 문서 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 접근성 및 스타일 개선

- ul 기본 margin 리셋
- hasValue를 options.find 기준으로 판단 (빈 문자열 오인 방지)
- aria-invalid / aria-describedby 연결로 보조기기 지원
- 키보드 내비게이션 추가 (ArrowUp/Down, Enter/Space, Escape)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: dispute 생성 조건을 active room 전체로 완화 (ONE_TO_ONE 제한 제거)

혼자서도 판결 가능한 흐름을 지원하기 위해
room.roomMode !== 'ONE_TO_ONE' 체크를 제거하고
CLOSED/EXPIRED 방만 차단하도록 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select id 안정화, 빈 options 가드, Tab 기본 포커스 이동 허용

- resolvedId를 label 문자열 대신 useId() 기반으로 고정
- option id를 value 대신 index 기반으로 변경
- Enter/Space 시 options 길이 가드 추가 (크래시 방지)
- Tab은 preventDefault 제거 — 닫기만 하고 포커스 이동은 브라우저에 위임

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Textarea 바이트 카운팅 및 filterMessage prop 추가

- 한글 2바이트/ASCII 1바이트 기준으로 글자 수 계산
- maxLength 초과 시 바이트 기준으로 자동 truncate
- filterMessage prop 추가 — 욕설 차단 메시지 동적 표시
- border 색상 변경은 error prop에만 적용 (filter는 border 유지)
- filter-warning 텍스트: Body-S + var(--text-danger)
- field gap 8 → 10px (Figma 기준)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 욕설 감지 필터 구현 (Gemini 2.5 Flash)

- moderation.ts: Gemini 2.5 Flash 기반 욕설/개인정보 감지
  - isBlocked: 욕설·혐오·위협 차단 (보수적 기준)
  - hasPersonalInfo: 개인정보 경고 (차단 없음)
  - fail-open: Gemini 실패 시 pending 상태로 저장
- statements/route.ts: 진술 저장 API
  - 모더레이션 통과 후 upsert + ModerationLog 트랜잭션
  - 차단 시 ModerationLog만 기록, 저장 없이 422 반환
  - dev bypass: 개발 환경에서 세션 없이 모더레이션 테스트 가능
- page.tsx: handleSave 연결, filterMessage 상태, 개인정보 경고 모달
- StatementPage.module.scss: 모달 스타일, Stylelint 공백 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: PR #49 코드리뷰 수정 — MBTI 연동, 파싱 에러, 인젝션, 타임아웃

- MBTI: GET /api/user/me 신규 생성, statement 페이지 마운트 시 user.mbti 초기화
- MBTI: handleSave body에 mbti 포함, statements route에서 user.mbti 업데이트 (트랜잭션)
- statement/page.tsx: res.json() 파싱 실패를 별도 try-catch로 분리
- Textarea.tsx: e.target.value 직접 변경 → Object.assign으로 새 이벤트 객체 전달
- moderation.ts: content 삽입 전 < > HTML 이스케이프 (프롬프트 인젝션 방지)
- moderation.ts: Promise.race() 기반 10초 타임아웃 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: user/me route catch 블록에 에러 로깅 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: judge route 1인 판결 허용 — isSolo 분기 및 rollback 상태 수정

- 2인: BOTH_SUBMITTED 상태 확인 유지
- 1인: 진술 제출 여부만 확인 (statements.length > 0)
- 롤백 대상을 하드코딩된 BOTH_SUBMITTED → previousStatus로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 카카오 로그인 기능 구현 (#50)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 absolute 배치

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 카카오 로그인 기능 구현

- 로그인 페이지 UI 및 카카오 signIn 버튼 연결
- @auth/prisma-adapter 설치 및 authOptions에 적용
- 최초 로그인 시 kakaoId, nickname, termsAgreedAt 자동 설정
- 닉네임 자동 생성 유틸 추가 (~하는부엉이 + 4자리 난수)
- middleware 추가: 비인증 사용자 /login 리다이렉트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 로그인 페이지 및 인증 로직 개선

- SCSS import 절대경로(@/) 수정
- 캐릭터 이미지 Next/Image fill → img 태그로 변경
- 이용약관/개인정보처리방침 링크(/terms, /privacy) 추가 및 스타일 적용
- 닉네임 유니크 제약(@unique) 추가 및 충돌 재시도 로직 구현 (최대 10회)
- middleware matcher 패턴 보완 (/login-help 등 우회 경로 차단)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: disclaimer mixin 적용, nickname 유실 복구 및 fallback 랜덤화

- .disclaimer에 @include m.text-caption mixin 적용
- 유실된 nickname.ts 복구
- fallback 닉네임 Date.now() → 랜덤 8자리 숫자로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독/1:1 판결 공통 진입 흐름 반영 및 관련 문서 일괄 수정 (#54)

- 단독 판결과 1:1 판결이 완전히 분리된 진입이 아니라
  AI 대화방 → 진술저장 → [분기] → disputes/[id]/statement 경로를 공통으로 거침
- CLAUDE.md: 핵심 서비스 흐름 분기 구조로 수정, 단독 판결 MVP 포함 반영,
  AI 대화방 정책 단독/1:1 병행 기술, dispute_status 단독 경로 추가
- PROJECT_DECISIONS.md: 흐름·MVP포함·MVP제외·dispute_status 동기화
- STATUS_TRANSITION.md: 단독 판결 경로(draft→judging→judged) 추가
- DISPUTE.md: 상태 전이 단독/1:1 경로 분리 기술, 주의사항 확정 내용 반영
- ROOM.md: 진술저장 후 분기 흐름 포함 기능에 명시

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Login 페이지 hydration removeChild 에러 수정 (#55)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이…
evenif99 added a commit that referenced this pull request Jun 29, 2026
* chore: initialize project folder structure (#1)

* chore: initialize project folder structure

- Add base directory layout for Next.js + domain-driven architecture
- Add .gitkeep to track empty directories in git
- Exclude MVP out-of-scope domains (shop, points, user-items)
- No implementation files included, structure only

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update README.md

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add CLAUDE.md with project rules and work guidelines (#2)

- Add project overview and MVP scope definition
- Add fixed product rules (categories, AI chat policy, judgement output)
- Add architecture, domain scope, and state transition rules
- Add auth/security, DB, frontend state, API, logging rules
- Add Git workflow, Claude work process, STOP conditions
- Add approval-required list and required reference documents

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: setup project config and install dependencies (#3)

- Add package.json with Next.js 15, React 19, TypeScript stack
- Add next.config.ts (minimal Next.js 15 config)
- Add tsconfig.json (strict mode, @/* path alias)
- Add eslint.config.mjs (next/core-web-vitals + next/typescript)
- Add .prettierrc and .prettierignore
- Add .gitignore (node_modules, .next, .env.local, etc.)
- Add .env.example (key names only, no real values)
- Add prisma/schema.prisma (generator + datasource only)
- Add data/mock/db.json (health check stub for json-server)
- Add docs/TECH_STACK.md (package list and selection rationale)
- Update README.md with run commands and env guide

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add base documentation structure (#4)

- Add PROJECT_DECISIONS.md (MVP scope, architecture, security principles)
- Add guides/CLAUDE_WORKFLOW.md (work process, STOP conditions, approval rules)
- Add guides/GIT_WORKFLOW.md (branch naming, commit convention, workflow)
- Add guides/PR_RULES.md (PR target, title rules, review criteria)
- Add guides/ENV_GUIDE.md (Vercel env pull, .env.example management)
- Add guides/CODING_CONVENTION.md (naming, state management, folder rules)
- Add db/STATUS_TRANSITION.md (room_mode, dispute_status transitions)
- Add db/PRISMA_MAPPING.md (snake_case/camelCase mapping rules)
- Add db/MASTER_DATA.md (categories, result types, DB master principles)
- Add domains/README.md (domain list, MVP scope, writing guidelines)
- Add domains/_DOMAIN_TEMPLATE.md (template for domain docs)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add domain document drafts for all MVP domains (#5)

- Add AUTH.md (kakao login, terms, session management)
- Add COMMON.md (error handling, logging, common response)
- Add ROOM.md (AI chat room, invite link, room_mode transitions)
- Add PERSONAL_ANALYSIS.md (AI-based personal conflict analysis)
- Add DISPUTE.md (1:1 mediation, roles, statements, dispute_status)
- Add JUDGEMENT.md (AI judgement, Gemini API, result card)
- Add GIFT.md (gift recommendation after judgement)
- Add USER.md (mypage, profile, bottom tab)
- Add CALENDAR.md (date-based record marking, monthly summary)
- Add DIARY.md (emotion diary, author-only access, content protection)
- Add STATISTICS.md (anonymous aggregation, summary components)
- Add SHOP_FUTURE.md (v2.0 planned, MVP excluded)
- Add POINTS_FUTURE.md (v2.0 planned, MVP excluded)
- Add USER_ITEMS_FUTURE.md (v2.0 planned, MVP excluded)

All documents are draft templates with TODO markers for assignees.
No implementation, no API routes, no schema changes.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: add Next.js App Router entry files and SCSS base structure (#6)

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Infra/init next setup (#7)

* infra: add Next.js App Router entry files and SCSS base structure

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: resolve ESLint and TypeScript config warnings

- eslint.config.mjs: ignore next-env.d.ts and .next/** (auto-generated by Next.js, triple-slash reference false positive)
- tsconfig.json: remove deprecated baseUrl option (TypeScript 5.x+, paths works without baseUrl)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update README.md (#8)

* docs(infra): confirm Supabase as project infrastructure (#9)

* chore(github): add collaboration templates and policy (#10)

* docs(env): document environment variable management (#11)

* docs(calendar): confirm MUI date picker usage (#12)

달력 UI 라이브러리로 MUI X Date Pickers + Day.js 사용을 확정하고
관련 문서(TECH_STACK, PROJECT_DECISIONS, CODING_CONVENTION, CALENDAR, DIARY, CLAUDE.md)에 반영한다.

* chore(deps): install MUI X Date Pickers and peer dependencies (#13)

달력 UI 구현을 위해 MUI X Date Pickers 및 필수 peer dependency를 설치한다.
@mui/material@9.1.1, @emotion/react@11.14.0, @emotion/styled@11.14.1,
@mui/x-date-pickers@9.5.0, dayjs@1.11.21

* Update README.md (#15)

* fix: resolve ESLint and TypeScript config warnings (#20)

* infra: add Next.js App Router entry files and SCSS base structure

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: resolve ESLint and TypeScript config warnings

- eslint.config.mjs: ignore next-env.d.ts and .next/** (auto-generated by Next.js, triple-slash reference false positive)
- tsconfig.json: remove deprecated baseUrl option (TypeScript 5.x+, paths works without baseUrl)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: add MVP Prisma schema with NextAuth and TALKY-OWL models (#21)

- datasource: add directUrl for Supabase connection pooler support
- enums: CategoryGroup, RoomMode, DisputeStatus, ParticipantRole, etc.
- NextAuth models: User (with TALKY-OWL fields), Account, Session, VerificationToken
- core models: DisputeRoom, RoomAiConversation, RoomAiMessage
- dispute models: Dispute, DisputeParticipant, DisputeStatement
- judgment models: AiJudgment, JudgmentResultCard
- gift models: GiftRecommendation, GiftRecommendationItem
- feature models: EmotionDiary, CalendarRecord
- master data: ConflictTypeGroup, ConflictTypeDetail (DB-based, no enum hardcoding)
- log models: AuditLog, ApiErrorLog, ModerationLog, RoomAccessLog, UserDeletionLog
- .env.example: add DIRECT_URL for Supabase directUrl
- v2.0 TODO: ShopItem, PointTransaction, UserItem, DisputeStatistic excluded

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: align project structure with guide v2 (#22)

folders added:
- src/components/{personal-analysis,room,dispute,judgement,calendar,diary,statistics,gift}
- src/app/api/auth/[...nextauth]
- src/app/api/v1/{users,personal-analyses,rooms,disputes,statements,calendar,diary,statistics,cron}

files added:
- prisma/seed.ts (placeholder for ConflictTypeGroup master data)

docs updated (minimal):
- docs/domains/COMMON.md: add log table list, judgement_logs TODO note
- docs/domains/JUDGEMENT.md: clarify Storage is MVP-excluded scaffolding
- docs/guides/ENV_GUIDE.md: clarify Supabase Storage vars are MVP-excluded

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: rename src/app/page to src/app/(page) for correct Next.js route group (#23)

src/app/page/ (괄호 없음)는 /page/* URL segment를 생성하므로,
Next.js App Router route group 문법인 src/app/(page)/로 변경한다.
URL은 /landing, /home 등으로 노출되어야 하며 /page/... 가 아니다.

관련 문서 내 경로 참조도 모두 업데이트 (CLAUDE.md, docs/domains/*, docs/guides/*).

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* [Style] 디자인 토큰 및 전역 스타일 설정 (#25)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 디자인 시스템 기반 설정 (#27)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: rem 스케일 토큰 추가 및 타이포그래피 변수 rem 참조로 전환

- Rem scale 섹션 추가 (0.25rem ~ 30rem)
- 폰트 토큰에서 누락된 0.875rem(14px), 1.125rem(18px) 추가
- font-size, line-height 변수를 rem 스케일 변수 참조로 전환
- rem 스케일을 typography 섹션보다 상단으로 이동 (선언 순서)
- 컴포넌트 width/height 대응을 위해 큰 단위(9rem~30rem) 포함

Co-Authored-By: Claude <noreply@anthropic.com>

* style: r() 함수 분리 및 타이포그래피 변수 함수 기반으로 전환

- _functions.scss 신규 추가 — px → rem 변환 함수 r() 단독 관리
- _variables.scss에서 rem 스케일 변수 제거, fn.r() 참조로 전환
- _mixins.scss에 functions @use 추가
- 순환 참조 없이 variables → functions → (없음) 단방향 의존성 구성

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Feature/common component jw (#28)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* fix: :root {} 시맨틱 토큰을 _global.scss로 분리 (#29)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: rem 스케일 토큰 추가 및 타이포그래피 변수 rem 참조로 전환

- Rem scale 섹션 추가 (0.25rem ~ 30rem)
- 폰트 토큰에서 누락된 0.875rem(14px), 1.125rem(18px) 추가
- font-size, line-height 변수를 rem 스케일 변수 참조로 전환
- rem 스케일을 typography 섹션보다 상단으로 이동 (선언 순서)
- 컴포넌트 width/height 대응을 위해 큰 단위(9rem~30rem) 포함

Co-Authored-By: Claude <noreply@anthropic.com>

* style: r() 함수 분리 및 타이포그래피 변수 함수 기반으로 전환

- _functions.scss 신규 추가 — px → rem 변환 함수 r() 단독 관리
- _variables.scss에서 rem 스케일 변수 제거, fn.r() 참조로 전환
- _mixins.scss에 functions @use 추가
- 순환 참조 없이 variables → functions → (없음) 단방향 의존성 구성

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: :root {} 시맨틱 토큰을 _global.scss로 분리

_variables.scss에 :root {}가 있으면 module.scss에서 @use 시
CSS Modules 'not pure' 에러 발생.
SCSS 변수는 _variables.scss, CSS 출력은 _global.scss로 분리.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): 공통 UI 컴포넌트 추가 및 MUI 정책 적용 (#30)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 목록 공통 UI 컴포넌트 추가 (Tab, StatusBadge) (#31)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 위치 수정 (#32)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 absolute 배치

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 공통 및 dispute·judgment DTO 타입 정의

- ApiResponse, ApiError, ApiFieldError, CategoryGroup (common.ts)
- DisputeDto, CreateDisputeRequest, DisputeListResponse 등 (dispute.ts)
- AiJudgmentDto, CreateAiJudgmentRequest 등 (judgment.ts)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: dispute 도메인 공유 상수·헬퍼·mapper 추가

- VALID_CATEGORY_GROUPS, IMMUTABLE_DISPUTE_STATUSES 상수 (constants/dispute.ts)
- getSessionUserId NextAuth 세션 헬퍼 (auth/session.ts)
- toAiJudgmentDto 공유 mapper (judgement/judgment.mapper.ts)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 목록 조회·생성·수정·삭제 API 구현

- GET /api/v1/disputes — 참여 사건 목록, categoryGroup 필터, 페이지네이션
- POST /api/v1/disputes — 사건 생성 + role_a 참여자 트랜잭션 등록
- GET /api/v1/disputes/:id — 사건 상세 조회
- PATCH /api/v1/disputes/:id — 사건 수정 (role_a 전용, 변경 불가 상태 차단)
- DELETE /api/v1/disputes/:id — 사건 소프트 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: AI 판결 요청·결과 조회 API 구현

- POST /api/v1/disputes/:id/judge — AI 판결 요청, JUDGING 상태 잠금으로 멱등성 보장
- GET /api/v1/disputes/:id/result — 판결 결과 조회 (참여자 전용)
- AI 모듈 미구현 구간은 TODO 주석으로 마킹, 완료 전까지 503 반환

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 공통 UI 컴포넌트 - StatusBadge, Tab, 진행 상태 (#33)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Prisma 클라이언트, NextAuth Kakao OAuth 설정 및 핸들러 추가

- src/lib/db/index.ts — Prisma 전역 싱글턴
- src/lib/auth/index.ts — NextAuth authOptions (Kakao OAuth, session user.id 매핑)
- src/app/api/auth/[...nextauth]/route.ts — NextAuth GET/POST 핸들러
- @mui/icons-material 패키지 설치 (빌드 에러 해결)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: 빌드 스크립트에 prisma generate 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: MVP 전체 API 명세서 작성 (API_SPEC.md) (#36)

* docs: MVP 전체 API 명세서 작성 (API_SPEC.md)

- 도메인 문서 및 기존 합의 기반 MVP API 명세 초안 작성
- 공통 응답 구조, 에러 코드 체계 정의
- Auth / User / Room / Dispute / Statement / Judgement / Diary / Calendar / Statistics / Gift / Cron 도메인 API 명세 포함
- 경로 충돌 항목 (withdraw, judge/result, diary 경로) 확정 필요 사항으로 명시
- 미확정 TODO 항목 섹션 7에 전체 정리
- MVP 제외 항목 (shop, points, 단독판결, 독립 통계 화면 등) 명시적으로 제거 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독 판결 MVP 포함 반영 및 라우트 주석 명확화

- 단독 판결(상대방 없는 AI 판결)을 MVP 포함 범위로 변경
- Personal Analysis 섹션에 단독 판결 API 초안 추가 (POST/GET /api/v1/personal-analyses)
- 라우트 트리 personal-analyses 디렉터리 구조 구체화
- /auth/withdraw route.ts 주석을 경로 충돌 상호 참조가 명확한 형태로 수정
  (경로 충돌 → /auth/withdraw vs DELETE /users/me)
- MVP 제외 목록에서 단독 판결 항목 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 카카오 로그인 시 약관 동의 자동 간주 정책 반영

- 카카오 OAuth 로그인 완료를 약관 동의로 간주
- 별도 약관 동의 페이지 이동 플로우 제거
- 확정 필요 항목에서 약관 동의 기준 항목 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 도메인 API 목록 중복 제거 및 회원탈퇴 경로 확정

- docs/domains/*.md 8개 파일의 API 목록 섹션을 docs/API_SPEC.md 참조로 교체
  (AUTH, USER, ROOM, DISPUTE, JUDGEMENT, DIARY, CALENDAR, STATISTICS)
- API_SPEC.md 단일 소스 체계 확립
- 회원탈퇴 경로 DELETE /api/v1/users/me 채택 확정
  - §3 요약표, §4.1·§4.2 상세, §5 라우트 트리, §6 충돌 목록, §7 체크리스트 반영
  - /auth/withdraw 라우트 제거, /users/me route.ts에 DELETE 추가
- CLAUDE_WORKFLOW.md PR 템플릿 준수 문구 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 날짜 포맷 및 Pagination 구조 확정 반영

- 날짜/시간 포맷 ISO 8601 (YYYY-MM-DDTHH:mm:ssZ) 확정
- Pagination 공통 구조 확정
  - data 필드: items 배열
  - page 필드: page / totalPages / sortBy / isNext
- 섹션 7 확정 필요 항목 두 개 체크 처리
- Room 목록, Diary 목록 섹션 Pagination 참조로 갱신

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: Pagination 구조에 size / sort / hasNext / hasPrevious 추가

- size: 한 번에 가져오는 항목 수
- sort: 정렬 방향 (asc | desc)
- isNext → hasNext로 변경 (다음 페이지 존재 여부)
- hasPrevious 추가 (이전 페이지 존재 여부)
- §7 체크리스트 항목 갱신

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 날짜 포맷 코드블록 언어 지정자 추가 (MD040)

코드래빗 지적 사항 반영 — 언어 미지정 펜스 코드블록에 text 지정자 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 통계 API 비로그인 공개 조회로 변경

홈 화면 진입 시 비로그인 회원도 통계 조회 가능하도록 수정
- GET /api/v1/statistics/summary: 🔒 → 공개
- GET /api/v1/statistics/top-types: 🔒 → 공개
- §3 요약표, §4.9 상세 명세 인증 표기 및 설명 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 목록 응답 예시에 page 객체 추가 (코드래빗 지적 반영)

- GET /api/v1/rooms 응답 예시에 page 객체 추가
- GET /api/v1/diary 응답 예시에 page 객체 추가
- GET /api/v1/statistics/top-types 응답 예시에 page 객체 추가
  (Top5 고정 목록 특성 반영: size=5, totalPages=1, hasNext=false)
- 코드래빗 제안의 구버전 필드(isNext) 대신 확정 구조(hasNext/hasPrevious/size/sort) 적용
- §7 Room Pagination 항목 체크 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Spinner, Avatar, AvatarGroup 공통 컴포넌트 추가 (#37)

* chore: 정적 이미지 에셋 추가 및 정리

주요 페이지용 캐릭터 이미지 추가 및 공통 에셋 정리.
gift, loading 캐릭터를 common에서 characters로 이동하여
캐릭터 이미지를 한 폴더로 통합.

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: Spinner 공통 컴포넌트 추가

캐릭터 로딩 이미지를 중앙에 배치한 88x88 스피너 컴포넌트 추가.
트랙(배경 원)과 애니메이션 링을 분리하여 각각 border-default, bg-brand 색상 적용.

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: Avatar, AvatarGroup 공통 컴포넌트 추가

MUI Avatar, AvatarGroup 래핑 컴포넌트 추가.
size prop으로 s/m/l 사이즈 조절, src prop으로 프로필 사진 지원.
global.scss에 --color-white, --color-black CSS 변수 추가.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: Avatar Context로 AvatarGroup size 전달 및 토큰 수정

AvatarGroup size prop이 자식 Avatar에 적용 안 되는 버그 수정.
Context를 통해 size를 내려주고 Avatar가 그룹 size를 우선 적용.
color 토큰 --color-white를 --text-inverse로 교체.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: Avatar src 없을 때 기본 썸네일 이미지로 fallback 처리

Co-Authored-By: Claude <noreply@anthropic.com>

* test: Spinner, Avatar, AvatarGroup 테스트 페이지 추가

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

* feat: 공통 UI 컴포넌트 - CategoryFilter, CategoryIcon, Tab, StatusBadge (#38)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 공통 컴포넌트 생성

- 전체/연애/직장/친구/가족 카테고리 필터 구현
- 아이콘 박스 44x44, border-radius 8, 아이콘 24x24
- 선택 상태: icon-primary bg / 미선택: bg-disabled
- MUI icons 사용 (GridViewRounded, Favorite, BusinessCenter, Diversity3, FamilyRestroom)
- Category 타입 export

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Tab 라벨 폰트 스타일 명시

- item.label을 span.label로 래핑
- Body-M 기준 font-size 16, line-height 28 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: @mui/icons-material 패키지 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 스타일 및 single 모드 적용

- 선택: bg-page + border-brand(1px) + icon-primary + 텍스트 bold
- 미선택: bg-page + border-default(1px) + icon-secondary + 텍스트 regular
- mode prop 추가 (filter 기본값 / single: 선택된 박스 하나만 표시)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 타입을 DB CategoryGroup 기준으로 통일

## 수정 배경

CategoryIcon, CategoryFilter가 한국어 문자열('연애', '직장' 등)을 타입으로 사용하고 있어
API/DB의 CategoryGroup('romance', 'work' 등)과 불일치가 발생.
페이지에서 연결 시 별도 변환 레이어가 필요해지는 문제를 사전 차단.

## 변경 파일별 수정 내용

### CategoryIcon.tsx
- CategoryWithoutAll 타입 제거 → @/types/common의 CategoryGroup 직접 사용
- 아이콘/레이블/컬러 맵 키를 한국어 → 영문 DB 값으로 변경
  (romance, work, friend, family)
- CATEGORY_LABEL_MAP export 추가 (CategoryFilter에서 레이블 참조용)

### CategoryFilter.tsx
- Category 타입을 'all' | CategoryGroup으로 변경 (기존: 한국어 문자열)
- CATEGORIES 배열에 label 필드 추가, CATEGORY_LABEL_MAP에서 참조
- 전체 키를 '전체' → 'all'로 변경 (API 필터 미적용 값과 일치)

### CaseCard.tsx (타팀원 파일 수정)
- 수정 이유: CATEGORY_EMOJI 맵 키가 대문자('ROMANCE')였으나
  API 응답은 소문자('romance')로 내려와 emoji가 항상 '📋' fallback만 표시되는 버그 존재
- 해결 방법: emoji 방식 전체 제거, CategoryIcon 컴포넌트로 교체
- categoryGroup prop 타입을 string → CategoryGroup으로 명시
- categoryGroup 미전달 시 아이콘 미표시 처리 (optional 유지)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update src/components/ui/CategoryIcon.tsx

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: CategoryIcon 중복 import 제거 및 CategoryFilter discriminated union 타입 에러 수정

- CategoryIcon: FamilyRestroomIcon, CategoryGroup 중복 import 제거
- CategoryFilter: discriminated union(CodeRabbit 피드백 반영) 유지하면서
  props 전체로 받아 props.mode로 narrowing 처리해 타입 에러 해결
  (mode='single'일 때 onChange가 CategoryGroup을 기대하는 문제)
- Tab.module.scss: height → min-height 변경 (유연한 높이 대응)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard 카테고리 아이콘을 제목 왼쪽 인라인으로 이동

- card__header 구조 변경: titleRow(아이콘+제목)와 badge를 좌우 배치
- card__titleRow 추가: flex row, align-items center, gap 6px
- 아이콘이 제목 위에 쌓이던 문제 수정 → 제목 왼쪽에 인라인 배치
- card__icon: font-size/line-height(이모지 잔재) → display:flex 로 변경
- card__title: margin-bottom 제거(card__header margin-bottom으로 대체)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 공통 컴포넌트 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard titleRow flex 축소 보완 (min-width: 0, flex: 1)

긴 제목에서 card__titleRow가 축소되지 않아 배지가 밀리는 문제 방지.
card__header가 space-between일 때 titleRow가 flex: 1로 가용 공간을 차지하고
min-width: 0으로 내부 콘텐츠가 넘치지 않도록 제약.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix(common): BottomNavigation 아이콘 MUI MD2 기본 스타일로 수정 (#39)

* fix(common): BottomNavigation 아이콘을 MUI MD2 기본 스타일로 수정

- HomeRounded → Home
- GavelRounded → MenuBook (사건기록 아이콘 자체 변경)
- CalendarMonthRounded → CalendarMonth
- PersonRounded → Person
디자인 시안 기준 MD2 filled 아이콘으로 통일

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: BottomNavigation 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): BottomNavigation 활성 탭 레이블 색상 black-700으로 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): BottomNavigation 테스트 스크린샷 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: wjdalss21 <jungxmin21@gmail.com>

* feat: 사건·방 도메인 타입 정의 및 API 구현 (#40)

* feat: room DTO 타입 정의

- RoomMode, RoomDto, CreateRoomRequest, RoomListResponse

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 방 목록 조회·생성·상세 조회·종료·삭제 API 구현

- GET  /api/v1/rooms — 내 방 목록 조회 (페이지네이션)
- POST /api/v1/rooms — AI 대화방 생성 (roomMode = ai_chat)
- GET  /api/v1/rooms/:id — 방 상세 조회
- POST /api/v1/rooms/:id/close — 방 종료 (closedAt + roomMode = closed)
- DELETE /api/v1/rooms/:id — 방 소프트 삭제 (deletedAt + roomMode = deleted)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 방 목록 페이지네이션 파라미터 NaN 방어 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: API 라우트 경로 v1 버전 세그먼트 제거 (#42)

* fix: API 라우트 경로에서 v1 버전 세그먼트 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 라우트 핸들러 주석 경로 v1 제거 (/api/v1/ -> /api/)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): 서비스 흐름 기반 문서 구조 수정 및 페이지 문서 생성 (#43)

* fix(docs): 서비스 흐름 기반 문서 구조 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): PAGES.md 코드 블록 언어 명시 추가 (MD040)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: personal-analyses 페이지 및 API 폴더 삭제 (#45)

* fix: personal-analyses 페이지 및 API 폴더 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): personal-analysis 도메인 참조 MD 문서 일괄 정리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 API 구현 (GET /api/statistics/categories) (#44)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 공통 컴포넌트 생성

- 전체/연애/직장/친구/가족 카테고리 필터 구현
- 아이콘 박스 44x44, border-radius 8, 아이콘 24x24
- 선택 상태: icon-primary bg / 미선택: bg-disabled
- MUI icons 사용 (GridViewRounded, Favorite, BusinessCenter, Diversity3, FamilyRestroom)
- Category 타입 export

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Tab 라벨 폰트 스타일 명시

- item.label을 span.label로 래핑
- Body-M 기준 font-size 16, line-height 28 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: @mui/icons-material 패키지 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 스타일 및 single 모드 적용

- 선택: bg-page + border-brand(1px) + icon-primary + 텍스트 bold
- 미선택: bg-page + border-default(1px) + icon-secondary + 텍스트 regular
- mode prop 추가 (filter 기본값 / single: 선택된 박스 하나만 표시)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 타입을 DB CategoryGroup 기준으로 통일

## 수정 배경

CategoryIcon, CategoryFilter가 한국어 문자열('연애', '직장' 등)을 타입으로 사용하고 있어
API/DB의 CategoryGroup('romance', 'work' 등)과 불일치가 발생.
페이지에서 연결 시 별도 변환 레이어가 필요해지는 문제를 사전 차단.

## 변경 파일별 수정 내용

### CategoryIcon.tsx
- CategoryWithoutAll 타입 제거 → @/types/common의 CategoryGroup 직접 사용
- 아이콘/레이블/컬러 맵 키를 한국어 → 영문 DB 값으로 변경
  (romance, work, friend, family)
- CATEGORY_LABEL_MAP export 추가 (CategoryFilter에서 레이블 참조용)

### CategoryFilter.tsx
- Category 타입을 'all' | CategoryGroup으로 변경 (기존: 한국어 문자열)
- CATEGORIES 배열에 label 필드 추가, CATEGORY_LABEL_MAP에서 참조
- 전체 키를 '전체' → 'all'로 변경 (API 필터 미적용 값과 일치)

### CaseCard.tsx (타팀원 파일 수정)
- 수정 이유: CATEGORY_EMOJI 맵 키가 대문자('ROMANCE')였으나
  API 응답은 소문자('romance')로 내려와 emoji가 항상 '📋' fallback만 표시되는 버그 존재
- 해결 방법: emoji 방식 전체 제거, CategoryIcon 컴포넌트로 교체
- categoryGroup prop 타입을 string → CategoryGroup으로 명시
- categoryGroup 미전달 시 아이콘 미표시 처리 (optional 유지)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update src/components/ui/CategoryIcon.tsx

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: CategoryIcon 중복 import 제거 및 CategoryFilter discriminated union 타입 에러 수정

- CategoryIcon: FamilyRestroomIcon, CategoryGroup 중복 import 제거
- CategoryFilter: discriminated union(CodeRabbit 피드백 반영) 유지하면서
  props 전체로 받아 props.mode로 narrowing 처리해 타입 에러 해결
  (mode='single'일 때 onChange가 CategoryGroup을 기대하는 문제)
- Tab.module.scss: height → min-height 변경 (유연한 높이 대응)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard 카테고리 아이콘을 제목 왼쪽 인라인으로 이동

- card__header 구조 변경: titleRow(아이콘+제목)와 badge를 좌우 배치
- card__titleRow 추가: flex row, align-items center, gap 6px
- 아이콘이 제목 위에 쌓이던 문제 수정 → 제목 왼쪽에 인라인 배치
- card__icon: font-size/line-height(이모지 잔재) → display:flex 로 변경
- card__title: margin-bottom 제거(card__header margin-bottom으로 대체)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 공통 컴포넌트 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard titleRow flex 축소 보완 (min-width: 0, flex: 1)

긴 제목에서 card__titleRow가 축소되지 않아 배지가 밀리는 문제 방지.
card__header가 space-between일 때 titleRow가 flex: 1로 가용 공간을 차지하고
min-width: 0으로 내부 콘텐츠가 넘치지 않도록 제약.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 도메인 서비스 레이어 생성 (statisticsService.ts)

## 생성 이유
통계 API의 DB 쿼리 로직을 Route Handler와 분리하기 위해
도메인 서비스 레이어를 별도 파일로 작성했다.

## 폴더 선택 이유
src/domains/statistics/
- CLAUDE.md §4 아키텍처 원칙에 따라 도메인별 비즈니스 로직은
  src/domains/{domain}/ 에 위치한다.
- statistics는 MVP 도메인 목록에 포함된 독립 도메인이다.
- Route Handler(src/app/api/)는 요청/응답 처리만 담당하고,
  실제 DB 쿼리 로직은 서비스 레이어에서 관리한다.

## 구현 내용

### getSummary()
- 서비스 전체 판결 완료 건수(totalJudgements) 집계
- dispute.status = JUDGED 조건 명시: ai_judgements는 판결 완료 시에만
  생성되지만 의도를 코드에 명시적으로 표현
- deletedAt / anonymizedAt IS NULL: 삭제·익명화된 사건 제외 (CLAUDE.md §7)

### getTopTypes(size = 5)
- ai_judgements.result_conflict_detail_id 기준 GROUP BY COUNT DESC
- 결과 유형 마스터(conflict_type_details)를 JOIN해 detailCode·displayName 반환
- isActive = true 필터: 비활성화된 유형은 통계에서 제외
- percentage 서버 계산: count / total * 100 (소수점 1자리)
  FE에서 별도 계산 없이 바로 사용할 수 있도록 서버에서 내려줌
- prisma.conflictTypeDetail 사용 (prisma.conflictDetail은 스키마에 존재하지 않음)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 API Route Handler 생성 (GET /api/v1/statistics/top-types)

## 생성 이유
statisticsService의 getTopTypes()를 HTTP 엔드포인트로 노출하기 위해
Next.js App Router 기반 Route Handler를 생성했다.

## 폴더 선택 이유
src/app/api/v1/statistics/top-types/
- CLAUDE.md §4 아키텍처 원칙에 따라 API Route는 src/app/api/v1/ 하위에 위치한다.
- API_SPEC.md §4.9 기준 엔드포인트 경로: GET /api/v1/statistics/top-types
- summary 엔드포인트는 현재 MVP 범위에서 불필요하여 top-types만 생성

## 구현 내용
- getServerSession으로 서버에서 직접 세션 검증
  (FE 리다이렉트만으로는 API 직접 호출을 막을 수 없으므로 서버 검증 필수 — CLAUDE.md §7)
- 인증 실패 시 401 UNAUTHORIZED 반환
- getTopTypes(5) 호출 → 판결 완료 기준 Top5 유형 + 비율 반환
- ApiResponse 타입 준수: data/error는 null 아닌 undefined(optional) 사용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: statistics top-types 인증 제거 (메인 페이지 공개 접근 허용)

메인 페이지에서도 통계 차트가 노출되는 익명 집계 데이터이므로
세션 없이 접근 가능하도록 수정.

- getServerSession 및 관련 import 제거
- 401 인증 체크 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: statistics top-types 에러 핸들링 보완

코드래빗 피드백 반영:
- catch {} -> catch (error): 에러 정보 유실 방지
- 타임아웃 감지 후 504 분기 처리
- console.error 로깅 추가 (CLAUDE.md 11 API 오류 로그 대상)
- 세션 체크는 이전 커밋에서 이미 제거됨 (공개 엔드포인트)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: 통계 API 카테고리 기준으로 재설계

- 결과 유형(top-types) → 작성 카테고리(ROMANCE/FAMILY/FRIEND/WORK) 기준으로 변경
- route.ts에 DB 쿼리 직접 작성, statisticsService.ts 제거
- 비율 계산은 프론트 훅(useStatistics)에서 담당
- revalidate = 86400 (하루 1회 재계산)
- src/hooks/ 폴더 신설 및 useStatistics.ts 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 통계 API 서버 측 세션 인증 추가

- GET /api/statistics/categories 진입 시 getServerSession으로 인증 검증
- 미인증 요청 401 UNAUTHORIZED 반환

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* feat: Header variant 분리 (logo/title) 및 홈 화면 적용 (#47)

* feat: 홈 화면 기본 구조 생성 (헤더, 일기 박스)

- 헤더: 세션 유저명 + character-welcome.png 부엉이 이미지
- 일기 박스: 365x88, border black-700 2px, bg primary-100
- TODO: GangwonEduPower 폰트 추가 후 헤더 로고 텍스트 적용 필요

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Header variant 분리 (logo/title) 및 홈 화면 적용

- Header.tsx에 variant prop 추가 (logo | title)
  - logo: 좌측 상단 말해부엉 로고 표시 (66x19, h:56, padding: 16px 20px)
  - title: 기존 뒤로가기 + 페이지 제목 형태 유지
- Header.module.scss에 __logo 스타일 추가
- home/page.tsx에 Header variant='logo' 적용
  - 헤더를 컨테이너 padding 밖으로 분리하여 상단 여백 제거
- home/page.module.scss diaryBox에 align-self: center 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건기록 페이지 생성 및 로고 헤더 적용 (/records)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: diaryBox 고정 폭을 max-width + width 100%로 반응형 처리

- width: 365px → width: 100% + max-width: 365px
- 작은 화면에서 좌우 패딩과 결합 시 오버플로우 방지

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 감정일기 작성 버튼 /diary/new 네비게이션 연결

- 일기 박스 전체를 Link로 변경 (텍스트 + 버튼 모두 클릭 가능)
- diaryBox에 text-decoration: none, cursor: pointer 추가
- /diary/new 경로는 임시 지정 (담당자 확인 후 수정 예정)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면 캐릭터 이미지 교체 및 위치 조정

- character-welcome.png → character-home.png 교체 (169x138)
- 캐릭터 절대 위치 적용 (top: 41px, right: -20px)
- 캐릭터가 일기 박스 뒤에 위치하도록 z-index 조정 (character: 0, container: 1)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 홈 화면 코드래빗 피드백 반영

- 캐릭터 이미지 가로 스크롤 방지: .page에 overflow-x: hidden 추가
- 비로그인 사용자 분기 처리: 말해부엉 알아보기 박스 추가 (/login 이동)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: 홈 화면 typography 믹신 적용

- greetingText, diaryTitle, diarySubtitle에 typography 믹신 사용
- 개별 font 속성 직접 선언 → @include m.text-* 토큰으로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 비로그인 알아보기 박스 위치 수정

- 인사/일기 박스는 로그인 여부 무관하게 항상 표시
- 말해부엉 알아보기 박스를 진행중인 사건 위치(구분선 아래)로 이동
- 비로그인 인사: '안녕하세요' 표시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면에 통계 섹션 및 구분선 통합

- StatsCategorySection, useStatistics, QueryProvider 병합
- 고민 카테고리 TOP4 통계 섹션 추가
- 통계 섹션 하단 구분선 추가 (h:8px, black-100, gap:42px)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: 개발 편의용 로그인 상태 강제 설정 (배포 전 제거 필요)

- isLoggedIn = true 하드코딩으로 로그인 상태 유지
- TODO 주석으로 배포 전 제거 안내 표시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건작성 페이지 구현 (disputes/[id]/statement) (#46)

* feat: 사건작성 페이지 구현 (disputes/[id]/statement)

- 사건 카테고리 선택 (연애/직장/친구/가족)
- MBTI 선택 드롭다운
- 진술 내용 입력 (최대 1000자)
- 진술저장 버튼 (내용 입력 시 활성화)
- TODO: 진술 저장 API 연결

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 사건작성 페이지 카테고리/간격/드롭다운 수정

- 카테고리를 searchParams에서 읽어 하나만 표시 (비상호작용)
- 카테고리 없을 시 모달 표시 후 이전 페이지로 이동
- Select/Textarea 사이 간격 8px (statementGroup)
- label/Select 사이 간격 16px 유지
- Textarea placeholder 줄바꿈 적용 (\n)
- content overflow-y 제거 → Select 드롭다운 아래 방향 열림 수정
- Select placeholder 색상 var(--text-secondary) 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 없음 모달에서 버튼 제거 — 페이지 블로킹만 유지

확인 버튼 클릭 시 이동하지 않고 Header 뒤로가기로만 탈출 가능

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 기본값 romance 적용, 모달 확인 버튼 복원

- searchParams에 카테고리 없을 시 임시로 romance 기본값 사용
- 모달 확인 버튼 클릭 시 router.back() 복원
- TODO: 이전 페이지 카테고리 데이터 연동 후 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 커스텀 드롭다운 교체 및 Textarea focus 스타일 제거

- Select: 네이티브 select → 커스텀 드롭다운 (항상 아래 방향 열림)
- Select: placeholder 색상 --text-secondary 적용 (option 색 영향 없음)
- Select: 아이콘 회전 애니메이션 추가
- Textarea: focus 시 border-color 변경 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: Button 좌우 패딩 16 → 12으로 조정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: SCSS import 상대경로 → 절대경로(@/) 변환 및 컨벤션 문서 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 접근성 및 스타일 개선

- ul 기본 margin 리셋
- hasValue를 options.find 기준으로 판단 (빈 문자열 오인 방지)
- aria-invalid / aria-describedby 연결로 보조기기 지원
- 키보드 내비게이션 추가 (ArrowUp/Down, Enter/Space, Escape)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: dispute 생성 조건을 active room 전체로 완화 (ONE_TO_ONE 제한 제거)

혼자서도 판결 가능한 흐름을 지원하기 위해
room.roomMode !== 'ONE_TO_ONE' 체크를 제거하고
CLOSED/EXPIRED 방만 차단하도록 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select id 안정화, 빈 options 가드, Tab 기본 포커스 이동 허용

- resolvedId를 label 문자열 대신 useId() 기반으로 고정
- option id를 value 대신 index 기반으로 변경
- Enter/Space 시 options 길이 가드 추가 (크래시 방지)
- Tab은 preventDefault 제거 — 닫기만 하고 포커스 이동은 브라우저에 위임

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독 판결 MVP 포함 및 관련 정책 업데이트 (#51)

- Section 1: 단독 판결 / 1:1 판결 흐름 분리 명시
- Section 2: 단독 판결을 MVP 포함으로 이동, MVP 제외에서 제거
- Section 3: AI 대화방 정책 수정 (ai_chat/invite_ready 상태 단독 판결 허용)
- Section 3: 단독 판결 vs 1:1 판결 제공 결과 비교 섹션 추가
- Section 14: 단독 판결 관련 STOP Condition 항목 제거

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Feature/verdict record display - 캘린더 페이지 ui 제작  (#41)

* feat : 다이어리 (감정일기 , 사건기록)탭분리

* feat : 달력 ui 커스텀 추가 및 감정일기 사건기록 분기처리

* refactor:  및 캘린더 페이지구조 개선 (리뷰 피드백 반영)

* feat : 감정일기카드 컴포넌트 구현

* fix: build 에러 ( 임시 페이지 )

* refactor: 감정일기 컴포넌트 SCSS 모듈 적용 및 믹스인 토큰 사용

* feat: 달력 페이지 UI 구현 및 스타일 정리

- MUI DateCalendar 커스텀
- 감정일기 / 사건기록 탭 전환 구조 구현
- EmotionDiaryList, RecordList 빈 상태 UI 추가
- DiaryCard mixin 적용 (text-title-s, text-body-s, text-label-s)
- 인라인 style 제거 → SCSS 모듈로 분리
- outsideCurrentMonth 감정 아이콘 노출 차단
- 새 일기 FAB 버튼 추가 (감정일기 탭 전용)
- 불필요한 파일 삭제 (DiaryMode, EmotionDiaryCard 등)

* style : EmotionDiaryList.moulde 스타일 수정

* feat: 달력 RecordList에 CaseCard 연동 및 스타일 개선

* Update model name from 'gpt-5.5' to 'gemini-2.5-flash'

seed.ts Ai modelName 수정

---------

Co-authored-by: 배근영 <bgy09270@naver.com>

* feat: 사건작성(진술서) 페이지 구현 및 욕설 감지 필터 연동 (#49)

* feat: 사건작성 페이지 구현 (disputes/[id]/statement)

- 사건 카테고리 선택 (연애/직장/친구/가족)
- MBTI 선택 드롭다운
- 진술 내용 입력 (최대 1000자)
- 진술저장 버튼 (내용 입력 시 활성화)
- TODO: 진술 저장 API 연결

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 사건작성 페이지 카테고리/간격/드롭다운 수정

- 카테고리를 searchParams에서 읽어 하나만 표시 (비상호작용)
- 카테고리 없을 시 모달 표시 후 이전 페이지로 이동
- Select/Textarea 사이 간격 8px (statementGroup)
- label/Select 사이 간격 16px 유지
- Textarea placeholder 줄바꿈 적용 (\n)
- content overflow-y 제거 → Select 드롭다운 아래 방향 열림 수정
- Select placeholder 색상 var(--text-secondary) 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 없음 모달에서 버튼 제거 — 페이지 블로킹만 유지

확인 버튼 클릭 시 이동하지 않고 Header 뒤로가기로만 탈출 가능

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 기본값 romance 적용, 모달 확인 버튼 복원

- searchParams에 카테고리 없을 시 임시로 romance 기본값 사용
- 모달 확인 버튼 클릭 시 router.back() 복원
- TODO: 이전 페이지 카테고리 데이터 연동 후 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 커스텀 드롭다운 교체 및 Textarea focus 스타일 제거

- Select: 네이티브 select → 커스텀 드롭다운 (항상 아래 방향 열림)
- Select: placeholder 색상 --text-secondary 적용 (option 색 영향 없음)
- Select: 아이콘 회전 애니메이션 추가
- Textarea: focus 시 border-color 변경 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: Button 좌우 패딩 16 → 12으로 조정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: SCSS import 상대경로 → 절대경로(@/) 변환 및 컨벤션 문서 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 접근성 및 스타일 개선

- ul 기본 margin 리셋
- hasValue를 options.find 기준으로 판단 (빈 문자열 오인 방지)
- aria-invalid / aria-describedby 연결로 보조기기 지원
- 키보드 내비게이션 추가 (ArrowUp/Down, Enter/Space, Escape)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: dispute 생성 조건을 active room 전체로 완화 (ONE_TO_ONE 제한 제거)

혼자서도 판결 가능한 흐름을 지원하기 위해
room.roomMode !== 'ONE_TO_ONE' 체크를 제거하고
CLOSED/EXPIRED 방만 차단하도록 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select id 안정화, 빈 options 가드, Tab 기본 포커스 이동 허용

- resolvedId를 label 문자열 대신 useId() 기반으로 고정
- option id를 value 대신 index 기반으로 변경
- Enter/Space 시 options 길이 가드 추가 (크래시 방지)
- Tab은 preventDefault 제거 — 닫기만 하고 포커스 이동은 브라우저에 위임

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Textarea 바이트 카운팅 및 filterMessage prop 추가

- 한글 2바이트/ASCII 1바이트 기준으로 글자 수 계산
- maxLength 초과 시 바이트 기준으로 자동 truncate
- filterMessage prop 추가 — 욕설 차단 메시지 동적 표시
- border 색상 변경은 error prop에만 적용 (filter는 border 유지)
- filter-warning 텍스트: Body-S + var(--text-danger)
- field gap 8 → 10px (Figma 기준)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 욕설 감지 필터 구현 (Gemini 2.5 Flash)

- moderation.ts: Gemini 2.5 Flash 기반 욕설/개인정보 감지
  - isBlocked: 욕설·혐오·위협 차단 (보수적 기준)
  - hasPersonalInfo: 개인정보 경고 (차단 없음)
  - fail-open: Gemini 실패 시 pending 상태로 저장
- statements/route.ts: 진술 저장 API
  - 모더레이션 통과 후 upsert + ModerationLog 트랜잭션
  - 차단 시 ModerationLog만 기록, 저장 없이 422 반환
  - dev bypass: 개발 환경에서 세션 없이 모더레이션 테스트 가능
- page.tsx: handleSave 연결, filterMessage 상태, 개인정보 경고 모달
- StatementPage.module.scss: 모달 스타일, Stylelint 공백 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: PR #49 코드리뷰 수정 — MBTI 연동, 파싱 에러, 인젝션, 타임아웃

- MBTI: GET /api/user/me 신규 생성, statement 페이지 마운트 시 user.mbti 초기화
- MBTI: handleSave body에 mbti 포함, statements route에서 user.mbti 업데이트 (트랜잭션)
- statement/page.tsx: res.json() 파싱 실패를 별도 try-catch로 분리
- Textarea.tsx: e.target.value 직접 변경 → Object.assign으로 새 이벤트 객체 전달
- moderation.ts: content 삽입 전 < > HTML 이스케이프 (프롬프트 인젝션 방지)
- moderation.ts: Promise.race() 기반 10초 타임아웃 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: user/me route catch 블록에 에러 로깅 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: judge route 1인 판결 허용 — isSolo 분기 및 rollback 상태 수정

- 2인: BOTH_SUBMITTED 상태 확인 유지
- 1인: 진술 제출 여부만 확인 (statements.length > 0)
- 롤백 대상을 하드코딩된 BOTH_SUBMITTED → previousStatus로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 카카오 로그인 기능 구현 (#50)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 absolute 배치

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 카카오 로그인 기능 구현

- 로그인 페이지 UI 및 카카오 signIn 버튼 연결
- @auth/prisma-adapter 설치 및 authOptions에 적용
- 최초 로그인 시 kakaoId, nickname, termsAgreedAt 자동 설정
- 닉네임 자동 생성 유틸 추가 (~하는부엉이 + 4자리 난수)
- middleware 추가: 비인증 사용자 /login 리다이렉트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 로그인 페이지 및 인증 로직 개선

- SCSS import 절대경로(@/) 수정
- 캐릭터 이미지 Next/Image fill → img 태그로 변경
- 이용약관/개인정보처리방침 링크(/terms, /privacy) 추가 및 스타일 적용
- 닉네임 유니크 제약(@unique) 추가 및 충돌 재시도 로직 구현 (최대 10회)
- middleware matcher 패턴 보완 (/login-help 등 우회 경로 차단)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: disclaimer mixin 적용, nickname 유실 복구 및 fallback 랜덤화

- .disclaimer에 @include m.text-caption mixin 적용
- 유실된 nickname.ts 복구
- fallback 닉네임 Date.now() → 랜덤 8자리 숫자로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독/1:1 판결 공통 진입 흐름 반영 및 관련 문서 일괄 수정 (#54)

- 단독 판결과 1:1 판결이 완전히 분리된 진입이 아니라
  AI 대화방 → 진술저장 → [분기] → disputes/[id]/statement 경로를 공통으로 거침
- CLAUDE.md: 핵심 서비스 흐름 분기 구조로 수정, 단독 판결 MVP 포함 반영,
  AI 대화방 정책 단독/1:1 병행 기술, dispute_status 단독 경로 추가
- PROJECT_DECISIONS.md: 흐름·MVP포함·MVP제외·dispute_status 동기화
- STATUS_TRANSITION.md: 단독 판결 경로(draft→judging→judged) 추가
- DISPUTE.md: 상태 전이 단독/1:1 경로 분리 기술, 주의사항 확정 내용 반영
- ROOM.md: 진술저장 후 분기 흐름 포함 기능에 명시

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Login 페이지 hydration removeChild 에러 수정 (#55)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react …
evenif99 added a commit that referenced this pull request Jun 29, 2026
* chore: initialize project folder structure (#1)

* chore: initialize project folder structure

- Add base directory layout for Next.js + domain-driven architecture
- Add .gitkeep to track empty directories in git
- Exclude MVP out-of-scope domains (shop, points, user-items)
- No implementation files included, structure only

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update README.md

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add CLAUDE.md with project rules and work guidelines (#2)

- Add project overview and MVP scope definition
- Add fixed product rules (categories, AI chat policy, judgement output)
- Add architecture, domain scope, and state transition rules
- Add auth/security, DB, frontend state, API, logging rules
- Add Git workflow, Claude work process, STOP conditions
- Add approval-required list and required reference documents

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: setup project config and install dependencies (#3)

- Add package.json with Next.js 15, React 19, TypeScript stack
- Add next.config.ts (minimal Next.js 15 config)
- Add tsconfig.json (strict mode, @/* path alias)
- Add eslint.config.mjs (next/core-web-vitals + next/typescript)
- Add .prettierrc and .prettierignore
- Add .gitignore (node_modules, .next, .env.local, etc.)
- Add .env.example (key names only, no real values)
- Add prisma/schema.prisma (generator + datasource only)
- Add data/mock/db.json (health check stub for json-server)
- Add docs/TECH_STACK.md (package list and selection rationale)
- Update README.md with run commands and env guide

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add base documentation structure (#4)

- Add PROJECT_DECISIONS.md (MVP scope, architecture, security principles)
- Add guides/CLAUDE_WORKFLOW.md (work process, STOP conditions, approval rules)
- Add guides/GIT_WORKFLOW.md (branch naming, commit convention, workflow)
- Add guides/PR_RULES.md (PR target, title rules, review criteria)
- Add guides/ENV_GUIDE.md (Vercel env pull, .env.example management)
- Add guides/CODING_CONVENTION.md (naming, state management, folder rules)
- Add db/STATUS_TRANSITION.md (room_mode, dispute_status transitions)
- Add db/PRISMA_MAPPING.md (snake_case/camelCase mapping rules)
- Add db/MASTER_DATA.md (categories, result types, DB master principles)
- Add domains/README.md (domain list, MVP scope, writing guidelines)
- Add domains/_DOMAIN_TEMPLATE.md (template for domain docs)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add domain document drafts for all MVP domains (#5)

- Add AUTH.md (kakao login, terms, session management)
- Add COMMON.md (error handling, logging, common response)
- Add ROOM.md (AI chat room, invite link, room_mode transitions)
- Add PERSONAL_ANALYSIS.md (AI-based personal conflict analysis)
- Add DISPUTE.md (1:1 mediation, roles, statements, dispute_status)
- Add JUDGEMENT.md (AI judgement, Gemini API, result card)
- Add GIFT.md (gift recommendation after judgement)
- Add USER.md (mypage, profile, bottom tab)
- Add CALENDAR.md (date-based record marking, monthly summary)
- Add DIARY.md (emotion diary, author-only access, content protection)
- Add STATISTICS.md (anonymous aggregation, summary components)
- Add SHOP_FUTURE.md (v2.0 planned, MVP excluded)
- Add POINTS_FUTURE.md (v2.0 planned, MVP excluded)
- Add USER_ITEMS_FUTURE.md (v2.0 planned, MVP excluded)

All documents are draft templates with TODO markers for assignees.
No implementation, no API routes, no schema changes.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: add Next.js App Router entry files and SCSS base structure (#6)

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Infra/init next setup (#7)

* infra: add Next.js App Router entry files and SCSS base structure

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: resolve ESLint and TypeScript config warnings

- eslint.config.mjs: ignore next-env.d.ts and .next/** (auto-generated by Next.js, triple-slash reference false positive)
- tsconfig.json: remove deprecated baseUrl option (TypeScript 5.x+, paths works without baseUrl)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update README.md (#8)

* docs(infra): confirm Supabase as project infrastructure (#9)

* chore(github): add collaboration templates and policy (#10)

* docs(env): document environment variable management (#11)

* docs(calendar): confirm MUI date picker usage (#12)

달력 UI 라이브러리로 MUI X Date Pickers + Day.js 사용을 확정하고
관련 문서(TECH_STACK, PROJECT_DECISIONS, CODING_CONVENTION, CALENDAR, DIARY, CLAUDE.md)에 반영한다.

* chore(deps): install MUI X Date Pickers and peer dependencies (#13)

달력 UI 구현을 위해 MUI X Date Pickers 및 필수 peer dependency를 설치한다.
@mui/material@9.1.1, @emotion/react@11.14.0, @emotion/styled@11.14.1,
@mui/x-date-pickers@9.5.0, dayjs@1.11.21

* Update README.md (#15)

* fix: resolve ESLint and TypeScript config warnings (#20)

* infra: add Next.js App Router entry files and SCSS base structure

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: resolve ESLint and TypeScript config warnings

- eslint.config.mjs: ignore next-env.d.ts and .next/** (auto-generated by Next.js, triple-slash reference false positive)
- tsconfig.json: remove deprecated baseUrl option (TypeScript 5.x+, paths works without baseUrl)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: add MVP Prisma schema with NextAuth and TALKY-OWL models (#21)

- datasource: add directUrl for Supabase connection pooler support
- enums: CategoryGroup, RoomMode, DisputeStatus, ParticipantRole, etc.
- NextAuth models: User (with TALKY-OWL fields), Account, Session, VerificationToken
- core models: DisputeRoom, RoomAiConversation, RoomAiMessage
- dispute models: Dispute, DisputeParticipant, DisputeStatement
- judgment models: AiJudgment, JudgmentResultCard
- gift models: GiftRecommendation, GiftRecommendationItem
- feature models: EmotionDiary, CalendarRecord
- master data: ConflictTypeGroup, ConflictTypeDetail (DB-based, no enum hardcoding)
- log models: AuditLog, ApiErrorLog, ModerationLog, RoomAccessLog, UserDeletionLog
- .env.example: add DIRECT_URL for Supabase directUrl
- v2.0 TODO: ShopItem, PointTransaction, UserItem, DisputeStatistic excluded

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: align project structure with guide v2 (#22)

folders added:
- src/components/{personal-analysis,room,dispute,judgement,calendar,diary,statistics,gift}
- src/app/api/auth/[...nextauth]
- src/app/api/v1/{users,personal-analyses,rooms,disputes,statements,calendar,diary,statistics,cron}

files added:
- prisma/seed.ts (placeholder for ConflictTypeGroup master data)

docs updated (minimal):
- docs/domains/COMMON.md: add log table list, judgement_logs TODO note
- docs/domains/JUDGEMENT.md: clarify Storage is MVP-excluded scaffolding
- docs/guides/ENV_GUIDE.md: clarify Supabase Storage vars are MVP-excluded

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: rename src/app/page to src/app/(page) for correct Next.js route group (#23)

src/app/page/ (괄호 없음)는 /page/* URL segment를 생성하므로,
Next.js App Router route group 문법인 src/app/(page)/로 변경한다.
URL은 /landing, /home 등으로 노출되어야 하며 /page/... 가 아니다.

관련 문서 내 경로 참조도 모두 업데이트 (CLAUDE.md, docs/domains/*, docs/guides/*).

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* [Style] 디자인 토큰 및 전역 스타일 설정 (#25)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 디자인 시스템 기반 설정 (#27)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: rem 스케일 토큰 추가 및 타이포그래피 변수 rem 참조로 전환

- Rem scale 섹션 추가 (0.25rem ~ 30rem)
- 폰트 토큰에서 누락된 0.875rem(14px), 1.125rem(18px) 추가
- font-size, line-height 변수를 rem 스케일 변수 참조로 전환
- rem 스케일을 typography 섹션보다 상단으로 이동 (선언 순서)
- 컴포넌트 width/height 대응을 위해 큰 단위(9rem~30rem) 포함

Co-Authored-By: Claude <noreply@anthropic.com>

* style: r() 함수 분리 및 타이포그래피 변수 함수 기반으로 전환

- _functions.scss 신규 추가 — px → rem 변환 함수 r() 단독 관리
- _variables.scss에서 rem 스케일 변수 제거, fn.r() 참조로 전환
- _mixins.scss에 functions @use 추가
- 순환 참조 없이 variables → functions → (없음) 단방향 의존성 구성

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Feature/common component jw (#28)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* fix: :root {} 시맨틱 토큰을 _global.scss로 분리 (#29)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: rem 스케일 토큰 추가 및 타이포그래피 변수 rem 참조로 전환

- Rem scale 섹션 추가 (0.25rem ~ 30rem)
- 폰트 토큰에서 누락된 0.875rem(14px), 1.125rem(18px) 추가
- font-size, line-height 변수를 rem 스케일 변수 참조로 전환
- rem 스케일을 typography 섹션보다 상단으로 이동 (선언 순서)
- 컴포넌트 width/height 대응을 위해 큰 단위(9rem~30rem) 포함

Co-Authored-By: Claude <noreply@anthropic.com>

* style: r() 함수 분리 및 타이포그래피 변수 함수 기반으로 전환

- _functions.scss 신규 추가 — px → rem 변환 함수 r() 단독 관리
- _variables.scss에서 rem 스케일 변수 제거, fn.r() 참조로 전환
- _mixins.scss에 functions @use 추가
- 순환 참조 없이 variables → functions → (없음) 단방향 의존성 구성

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: :root {} 시맨틱 토큰을 _global.scss로 분리

_variables.scss에 :root {}가 있으면 module.scss에서 @use 시
CSS Modules 'not pure' 에러 발생.
SCSS 변수는 _variables.scss, CSS 출력은 _global.scss로 분리.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): 공통 UI 컴포넌트 추가 및 MUI 정책 적용 (#30)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 목록 공통 UI 컴포넌트 추가 (Tab, StatusBadge) (#31)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 위치 수정 (#32)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 absolute 배치

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 공통 및 dispute·judgment DTO 타입 정의

- ApiResponse, ApiError, ApiFieldError, CategoryGroup (common.ts)
- DisputeDto, CreateDisputeRequest, DisputeListResponse 등 (dispute.ts)
- AiJudgmentDto, CreateAiJudgmentRequest 등 (judgment.ts)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: dispute 도메인 공유 상수·헬퍼·mapper 추가

- VALID_CATEGORY_GROUPS, IMMUTABLE_DISPUTE_STATUSES 상수 (constants/dispute.ts)
- getSessionUserId NextAuth 세션 헬퍼 (auth/session.ts)
- toAiJudgmentDto 공유 mapper (judgement/judgment.mapper.ts)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 목록 조회·생성·수정·삭제 API 구현

- GET /api/v1/disputes — 참여 사건 목록, categoryGroup 필터, 페이지네이션
- POST /api/v1/disputes — 사건 생성 + role_a 참여자 트랜잭션 등록
- GET /api/v1/disputes/:id — 사건 상세 조회
- PATCH /api/v1/disputes/:id — 사건 수정 (role_a 전용, 변경 불가 상태 차단)
- DELETE /api/v1/disputes/:id — 사건 소프트 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: AI 판결 요청·결과 조회 API 구현

- POST /api/v1/disputes/:id/judge — AI 판결 요청, JUDGING 상태 잠금으로 멱등성 보장
- GET /api/v1/disputes/:id/result — 판결 결과 조회 (참여자 전용)
- AI 모듈 미구현 구간은 TODO 주석으로 마킹, 완료 전까지 503 반환

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 공통 UI 컴포넌트 - StatusBadge, Tab, 진행 상태 (#33)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Prisma 클라이언트, NextAuth Kakao OAuth 설정 및 핸들러 추가

- src/lib/db/index.ts — Prisma 전역 싱글턴
- src/lib/auth/index.ts — NextAuth authOptions (Kakao OAuth, session user.id 매핑)
- src/app/api/auth/[...nextauth]/route.ts — NextAuth GET/POST 핸들러
- @mui/icons-material 패키지 설치 (빌드 에러 해결)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: 빌드 스크립트에 prisma generate 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: MVP 전체 API 명세서 작성 (API_SPEC.md) (#36)

* docs: MVP 전체 API 명세서 작성 (API_SPEC.md)

- 도메인 문서 및 기존 합의 기반 MVP API 명세 초안 작성
- 공통 응답 구조, 에러 코드 체계 정의
- Auth / User / Room / Dispute / Statement / Judgement / Diary / Calendar / Statistics / Gift / Cron 도메인 API 명세 포함
- 경로 충돌 항목 (withdraw, judge/result, diary 경로) 확정 필요 사항으로 명시
- 미확정 TODO 항목 섹션 7에 전체 정리
- MVP 제외 항목 (shop, points, 단독판결, 독립 통계 화면 등) 명시적으로 제거 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독 판결 MVP 포함 반영 및 라우트 주석 명확화

- 단독 판결(상대방 없는 AI 판결)을 MVP 포함 범위로 변경
- Personal Analysis 섹션에 단독 판결 API 초안 추가 (POST/GET /api/v1/personal-analyses)
- 라우트 트리 personal-analyses 디렉터리 구조 구체화
- /auth/withdraw route.ts 주석을 경로 충돌 상호 참조가 명확한 형태로 수정
  (경로 충돌 → /auth/withdraw vs DELETE /users/me)
- MVP 제외 목록에서 단독 판결 항목 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 카카오 로그인 시 약관 동의 자동 간주 정책 반영

- 카카오 OAuth 로그인 완료를 약관 동의로 간주
- 별도 약관 동의 페이지 이동 플로우 제거
- 확정 필요 항목에서 약관 동의 기준 항목 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 도메인 API 목록 중복 제거 및 회원탈퇴 경로 확정

- docs/domains/*.md 8개 파일의 API 목록 섹션을 docs/API_SPEC.md 참조로 교체
  (AUTH, USER, ROOM, DISPUTE, JUDGEMENT, DIARY, CALENDAR, STATISTICS)
- API_SPEC.md 단일 소스 체계 확립
- 회원탈퇴 경로 DELETE /api/v1/users/me 채택 확정
  - §3 요약표, §4.1·§4.2 상세, §5 라우트 트리, §6 충돌 목록, §7 체크리스트 반영
  - /auth/withdraw 라우트 제거, /users/me route.ts에 DELETE 추가
- CLAUDE_WORKFLOW.md PR 템플릿 준수 문구 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 날짜 포맷 및 Pagination 구조 확정 반영

- 날짜/시간 포맷 ISO 8601 (YYYY-MM-DDTHH:mm:ssZ) 확정
- Pagination 공통 구조 확정
  - data 필드: items 배열
  - page 필드: page / totalPages / sortBy / isNext
- 섹션 7 확정 필요 항목 두 개 체크 처리
- Room 목록, Diary 목록 섹션 Pagination 참조로 갱신

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: Pagination 구조에 size / sort / hasNext / hasPrevious 추가

- size: 한 번에 가져오는 항목 수
- sort: 정렬 방향 (asc | desc)
- isNext → hasNext로 변경 (다음 페이지 존재 여부)
- hasPrevious 추가 (이전 페이지 존재 여부)
- §7 체크리스트 항목 갱신

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 날짜 포맷 코드블록 언어 지정자 추가 (MD040)

코드래빗 지적 사항 반영 — 언어 미지정 펜스 코드블록에 text 지정자 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 통계 API 비로그인 공개 조회로 변경

홈 화면 진입 시 비로그인 회원도 통계 조회 가능하도록 수정
- GET /api/v1/statistics/summary: 🔒 → 공개
- GET /api/v1/statistics/top-types: 🔒 → 공개
- §3 요약표, §4.9 상세 명세 인증 표기 및 설명 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 목록 응답 예시에 page 객체 추가 (코드래빗 지적 반영)

- GET /api/v1/rooms 응답 예시에 page 객체 추가
- GET /api/v1/diary 응답 예시에 page 객체 추가
- GET /api/v1/statistics/top-types 응답 예시에 page 객체 추가
  (Top5 고정 목록 특성 반영: size=5, totalPages=1, hasNext=false)
- 코드래빗 제안의 구버전 필드(isNext) 대신 확정 구조(hasNext/hasPrevious/size/sort) 적용
- §7 Room Pagination 항목 체크 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Spinner, Avatar, AvatarGroup 공통 컴포넌트 추가 (#37)

* chore: 정적 이미지 에셋 추가 및 정리

주요 페이지용 캐릭터 이미지 추가 및 공통 에셋 정리.
gift, loading 캐릭터를 common에서 characters로 이동하여
캐릭터 이미지를 한 폴더로 통합.

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: Spinner 공통 컴포넌트 추가

캐릭터 로딩 이미지를 중앙에 배치한 88x88 스피너 컴포넌트 추가.
트랙(배경 원)과 애니메이션 링을 분리하여 각각 border-default, bg-brand 색상 적용.

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: Avatar, AvatarGroup 공통 컴포넌트 추가

MUI Avatar, AvatarGroup 래핑 컴포넌트 추가.
size prop으로 s/m/l 사이즈 조절, src prop으로 프로필 사진 지원.
global.scss에 --color-white, --color-black CSS 변수 추가.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: Avatar Context로 AvatarGroup size 전달 및 토큰 수정

AvatarGroup size prop이 자식 Avatar에 적용 안 되는 버그 수정.
Context를 통해 size를 내려주고 Avatar가 그룹 size를 우선 적용.
color 토큰 --color-white를 --text-inverse로 교체.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: Avatar src 없을 때 기본 썸네일 이미지로 fallback 처리

Co-Authored-By: Claude <noreply@anthropic.com>

* test: Spinner, Avatar, AvatarGroup 테스트 페이지 추가

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

* feat: 공통 UI 컴포넌트 - CategoryFilter, CategoryIcon, Tab, StatusBadge (#38)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 공통 컴포넌트 생성

- 전체/연애/직장/친구/가족 카테고리 필터 구현
- 아이콘 박스 44x44, border-radius 8, 아이콘 24x24
- 선택 상태: icon-primary bg / 미선택: bg-disabled
- MUI icons 사용 (GridViewRounded, Favorite, BusinessCenter, Diversity3, FamilyRestroom)
- Category 타입 export

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Tab 라벨 폰트 스타일 명시

- item.label을 span.label로 래핑
- Body-M 기준 font-size 16, line-height 28 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: @mui/icons-material 패키지 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 스타일 및 single 모드 적용

- 선택: bg-page + border-brand(1px) + icon-primary + 텍스트 bold
- 미선택: bg-page + border-default(1px) + icon-secondary + 텍스트 regular
- mode prop 추가 (filter 기본값 / single: 선택된 박스 하나만 표시)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 타입을 DB CategoryGroup 기준으로 통일

## 수정 배경

CategoryIcon, CategoryFilter가 한국어 문자열('연애', '직장' 등)을 타입으로 사용하고 있어
API/DB의 CategoryGroup('romance', 'work' 등)과 불일치가 발생.
페이지에서 연결 시 별도 변환 레이어가 필요해지는 문제를 사전 차단.

## 변경 파일별 수정 내용

### CategoryIcon.tsx
- CategoryWithoutAll 타입 제거 → @/types/common의 CategoryGroup 직접 사용
- 아이콘/레이블/컬러 맵 키를 한국어 → 영문 DB 값으로 변경
  (romance, work, friend, family)
- CATEGORY_LABEL_MAP export 추가 (CategoryFilter에서 레이블 참조용)

### CategoryFilter.tsx
- Category 타입을 'all' | CategoryGroup으로 변경 (기존: 한국어 문자열)
- CATEGORIES 배열에 label 필드 추가, CATEGORY_LABEL_MAP에서 참조
- 전체 키를 '전체' → 'all'로 변경 (API 필터 미적용 값과 일치)

### CaseCard.tsx (타팀원 파일 수정)
- 수정 이유: CATEGORY_EMOJI 맵 키가 대문자('ROMANCE')였으나
  API 응답은 소문자('romance')로 내려와 emoji가 항상 '📋' fallback만 표시되는 버그 존재
- 해결 방법: emoji 방식 전체 제거, CategoryIcon 컴포넌트로 교체
- categoryGroup prop 타입을 string → CategoryGroup으로 명시
- categoryGroup 미전달 시 아이콘 미표시 처리 (optional 유지)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update src/components/ui/CategoryIcon.tsx

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: CategoryIcon 중복 import 제거 및 CategoryFilter discriminated union 타입 에러 수정

- CategoryIcon: FamilyRestroomIcon, CategoryGroup 중복 import 제거
- CategoryFilter: discriminated union(CodeRabbit 피드백 반영) 유지하면서
  props 전체로 받아 props.mode로 narrowing 처리해 타입 에러 해결
  (mode='single'일 때 onChange가 CategoryGroup을 기대하는 문제)
- Tab.module.scss: height → min-height 변경 (유연한 높이 대응)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard 카테고리 아이콘을 제목 왼쪽 인라인으로 이동

- card__header 구조 변경: titleRow(아이콘+제목)와 badge를 좌우 배치
- card__titleRow 추가: flex row, align-items center, gap 6px
- 아이콘이 제목 위에 쌓이던 문제 수정 → 제목 왼쪽에 인라인 배치
- card__icon: font-size/line-height(이모지 잔재) → display:flex 로 변경
- card__title: margin-bottom 제거(card__header margin-bottom으로 대체)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 공통 컴포넌트 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard titleRow flex 축소 보완 (min-width: 0, flex: 1)

긴 제목에서 card__titleRow가 축소되지 않아 배지가 밀리는 문제 방지.
card__header가 space-between일 때 titleRow가 flex: 1로 가용 공간을 차지하고
min-width: 0으로 내부 콘텐츠가 넘치지 않도록 제약.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix(common): BottomNavigation 아이콘 MUI MD2 기본 스타일로 수정 (#39)

* fix(common): BottomNavigation 아이콘을 MUI MD2 기본 스타일로 수정

- HomeRounded → Home
- GavelRounded → MenuBook (사건기록 아이콘 자체 변경)
- CalendarMonthRounded → CalendarMonth
- PersonRounded → Person
디자인 시안 기준 MD2 filled 아이콘으로 통일

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: BottomNavigation 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): BottomNavigation 활성 탭 레이블 색상 black-700으로 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): BottomNavigation 테스트 스크린샷 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: wjdalss21 <jungxmin21@gmail.com>

* feat: 사건·방 도메인 타입 정의 및 API 구현 (#40)

* feat: room DTO 타입 정의

- RoomMode, RoomDto, CreateRoomRequest, RoomListResponse

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 방 목록 조회·생성·상세 조회·종료·삭제 API 구현

- GET  /api/v1/rooms — 내 방 목록 조회 (페이지네이션)
- POST /api/v1/rooms — AI 대화방 생성 (roomMode = ai_chat)
- GET  /api/v1/rooms/:id — 방 상세 조회
- POST /api/v1/rooms/:id/close — 방 종료 (closedAt + roomMode = closed)
- DELETE /api/v1/rooms/:id — 방 소프트 삭제 (deletedAt + roomMode = deleted)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 방 목록 페이지네이션 파라미터 NaN 방어 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: API 라우트 경로 v1 버전 세그먼트 제거 (#42)

* fix: API 라우트 경로에서 v1 버전 세그먼트 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 라우트 핸들러 주석 경로 v1 제거 (/api/v1/ -> /api/)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): 서비스 흐름 기반 문서 구조 수정 및 페이지 문서 생성 (#43)

* fix(docs): 서비스 흐름 기반 문서 구조 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): PAGES.md 코드 블록 언어 명시 추가 (MD040)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: personal-analyses 페이지 및 API 폴더 삭제 (#45)

* fix: personal-analyses 페이지 및 API 폴더 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): personal-analysis 도메인 참조 MD 문서 일괄 정리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 API 구현 (GET /api/statistics/categories) (#44)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 공통 컴포넌트 생성

- 전체/연애/직장/친구/가족 카테고리 필터 구현
- 아이콘 박스 44x44, border-radius 8, 아이콘 24x24
- 선택 상태: icon-primary bg / 미선택: bg-disabled
- MUI icons 사용 (GridViewRounded, Favorite, BusinessCenter, Diversity3, FamilyRestroom)
- Category 타입 export

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Tab 라벨 폰트 스타일 명시

- item.label을 span.label로 래핑
- Body-M 기준 font-size 16, line-height 28 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: @mui/icons-material 패키지 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 스타일 및 single 모드 적용

- 선택: bg-page + border-brand(1px) + icon-primary + 텍스트 bold
- 미선택: bg-page + border-default(1px) + icon-secondary + 텍스트 regular
- mode prop 추가 (filter 기본값 / single: 선택된 박스 하나만 표시)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 타입을 DB CategoryGroup 기준으로 통일

## 수정 배경

CategoryIcon, CategoryFilter가 한국어 문자열('연애', '직장' 등)을 타입으로 사용하고 있어
API/DB의 CategoryGroup('romance', 'work' 등)과 불일치가 발생.
페이지에서 연결 시 별도 변환 레이어가 필요해지는 문제를 사전 차단.

## 변경 파일별 수정 내용

### CategoryIcon.tsx
- CategoryWithoutAll 타입 제거 → @/types/common의 CategoryGroup 직접 사용
- 아이콘/레이블/컬러 맵 키를 한국어 → 영문 DB 값으로 변경
  (romance, work, friend, family)
- CATEGORY_LABEL_MAP export 추가 (CategoryFilter에서 레이블 참조용)

### CategoryFilter.tsx
- Category 타입을 'all' | CategoryGroup으로 변경 (기존: 한국어 문자열)
- CATEGORIES 배열에 label 필드 추가, CATEGORY_LABEL_MAP에서 참조
- 전체 키를 '전체' → 'all'로 변경 (API 필터 미적용 값과 일치)

### CaseCard.tsx (타팀원 파일 수정)
- 수정 이유: CATEGORY_EMOJI 맵 키가 대문자('ROMANCE')였으나
  API 응답은 소문자('romance')로 내려와 emoji가 항상 '📋' fallback만 표시되는 버그 존재
- 해결 방법: emoji 방식 전체 제거, CategoryIcon 컴포넌트로 교체
- categoryGroup prop 타입을 string → CategoryGroup으로 명시
- categoryGroup 미전달 시 아이콘 미표시 처리 (optional 유지)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update src/components/ui/CategoryIcon.tsx

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: CategoryIcon 중복 import 제거 및 CategoryFilter discriminated union 타입 에러 수정

- CategoryIcon: FamilyRestroomIcon, CategoryGroup 중복 import 제거
- CategoryFilter: discriminated union(CodeRabbit 피드백 반영) 유지하면서
  props 전체로 받아 props.mode로 narrowing 처리해 타입 에러 해결
  (mode='single'일 때 onChange가 CategoryGroup을 기대하는 문제)
- Tab.module.scss: height → min-height 변경 (유연한 높이 대응)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard 카테고리 아이콘을 제목 왼쪽 인라인으로 이동

- card__header 구조 변경: titleRow(아이콘+제목)와 badge를 좌우 배치
- card__titleRow 추가: flex row, align-items center, gap 6px
- 아이콘이 제목 위에 쌓이던 문제 수정 → 제목 왼쪽에 인라인 배치
- card__icon: font-size/line-height(이모지 잔재) → display:flex 로 변경
- card__title: margin-bottom 제거(card__header margin-bottom으로 대체)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 공통 컴포넌트 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard titleRow flex 축소 보완 (min-width: 0, flex: 1)

긴 제목에서 card__titleRow가 축소되지 않아 배지가 밀리는 문제 방지.
card__header가 space-between일 때 titleRow가 flex: 1로 가용 공간을 차지하고
min-width: 0으로 내부 콘텐츠가 넘치지 않도록 제약.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 도메인 서비스 레이어 생성 (statisticsService.ts)

## 생성 이유
통계 API의 DB 쿼리 로직을 Route Handler와 분리하기 위해
도메인 서비스 레이어를 별도 파일로 작성했다.

## 폴더 선택 이유
src/domains/statistics/
- CLAUDE.md §4 아키텍처 원칙에 따라 도메인별 비즈니스 로직은
  src/domains/{domain}/ 에 위치한다.
- statistics는 MVP 도메인 목록에 포함된 독립 도메인이다.
- Route Handler(src/app/api/)는 요청/응답 처리만 담당하고,
  실제 DB 쿼리 로직은 서비스 레이어에서 관리한다.

## 구현 내용

### getSummary()
- 서비스 전체 판결 완료 건수(totalJudgements) 집계
- dispute.status = JUDGED 조건 명시: ai_judgements는 판결 완료 시에만
  생성되지만 의도를 코드에 명시적으로 표현
- deletedAt / anonymizedAt IS NULL: 삭제·익명화된 사건 제외 (CLAUDE.md §7)

### getTopTypes(size = 5)
- ai_judgements.result_conflict_detail_id 기준 GROUP BY COUNT DESC
- 결과 유형 마스터(conflict_type_details)를 JOIN해 detailCode·displayName 반환
- isActive = true 필터: 비활성화된 유형은 통계에서 제외
- percentage 서버 계산: count / total * 100 (소수점 1자리)
  FE에서 별도 계산 없이 바로 사용할 수 있도록 서버에서 내려줌
- prisma.conflictTypeDetail 사용 (prisma.conflictDetail은 스키마에 존재하지 않음)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 API Route Handler 생성 (GET /api/v1/statistics/top-types)

## 생성 이유
statisticsService의 getTopTypes()를 HTTP 엔드포인트로 노출하기 위해
Next.js App Router 기반 Route Handler를 생성했다.

## 폴더 선택 이유
src/app/api/v1/statistics/top-types/
- CLAUDE.md §4 아키텍처 원칙에 따라 API Route는 src/app/api/v1/ 하위에 위치한다.
- API_SPEC.md §4.9 기준 엔드포인트 경로: GET /api/v1/statistics/top-types
- summary 엔드포인트는 현재 MVP 범위에서 불필요하여 top-types만 생성

## 구현 내용
- getServerSession으로 서버에서 직접 세션 검증
  (FE 리다이렉트만으로는 API 직접 호출을 막을 수 없으므로 서버 검증 필수 — CLAUDE.md §7)
- 인증 실패 시 401 UNAUTHORIZED 반환
- getTopTypes(5) 호출 → 판결 완료 기준 Top5 유형 + 비율 반환
- ApiResponse 타입 준수: data/error는 null 아닌 undefined(optional) 사용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: statistics top-types 인증 제거 (메인 페이지 공개 접근 허용)

메인 페이지에서도 통계 차트가 노출되는 익명 집계 데이터이므로
세션 없이 접근 가능하도록 수정.

- getServerSession 및 관련 import 제거
- 401 인증 체크 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: statistics top-types 에러 핸들링 보완

코드래빗 피드백 반영:
- catch {} -> catch (error): 에러 정보 유실 방지
- 타임아웃 감지 후 504 분기 처리
- console.error 로깅 추가 (CLAUDE.md 11 API 오류 로그 대상)
- 세션 체크는 이전 커밋에서 이미 제거됨 (공개 엔드포인트)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: 통계 API 카테고리 기준으로 재설계

- 결과 유형(top-types) → 작성 카테고리(ROMANCE/FAMILY/FRIEND/WORK) 기준으로 변경
- route.ts에 DB 쿼리 직접 작성, statisticsService.ts 제거
- 비율 계산은 프론트 훅(useStatistics)에서 담당
- revalidate = 86400 (하루 1회 재계산)
- src/hooks/ 폴더 신설 및 useStatistics.ts 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 통계 API 서버 측 세션 인증 추가

- GET /api/statistics/categories 진입 시 getServerSession으로 인증 검증
- 미인증 요청 401 UNAUTHORIZED 반환

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* feat: Header variant 분리 (logo/title) 및 홈 화면 적용 (#47)

* feat: 홈 화면 기본 구조 생성 (헤더, 일기 박스)

- 헤더: 세션 유저명 + character-welcome.png 부엉이 이미지
- 일기 박스: 365x88, border black-700 2px, bg primary-100
- TODO: GangwonEduPower 폰트 추가 후 헤더 로고 텍스트 적용 필요

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Header variant 분리 (logo/title) 및 홈 화면 적용

- Header.tsx에 variant prop 추가 (logo | title)
  - logo: 좌측 상단 말해부엉 로고 표시 (66x19, h:56, padding: 16px 20px)
  - title: 기존 뒤로가기 + 페이지 제목 형태 유지
- Header.module.scss에 __logo 스타일 추가
- home/page.tsx에 Header variant='logo' 적용
  - 헤더를 컨테이너 padding 밖으로 분리하여 상단 여백 제거
- home/page.module.scss diaryBox에 align-self: center 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건기록 페이지 생성 및 로고 헤더 적용 (/records)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: diaryBox 고정 폭을 max-width + width 100%로 반응형 처리

- width: 365px → width: 100% + max-width: 365px
- 작은 화면에서 좌우 패딩과 결합 시 오버플로우 방지

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 감정일기 작성 버튼 /diary/new 네비게이션 연결

- 일기 박스 전체를 Link로 변경 (텍스트 + 버튼 모두 클릭 가능)
- diaryBox에 text-decoration: none, cursor: pointer 추가
- /diary/new 경로는 임시 지정 (담당자 확인 후 수정 예정)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면 캐릭터 이미지 교체 및 위치 조정

- character-welcome.png → character-home.png 교체 (169x138)
- 캐릭터 절대 위치 적용 (top: 41px, right: -20px)
- 캐릭터가 일기 박스 뒤에 위치하도록 z-index 조정 (character: 0, container: 1)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 홈 화면 코드래빗 피드백 반영

- 캐릭터 이미지 가로 스크롤 방지: .page에 overflow-x: hidden 추가
- 비로그인 사용자 분기 처리: 말해부엉 알아보기 박스 추가 (/login 이동)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: 홈 화면 typography 믹신 적용

- greetingText, diaryTitle, diarySubtitle에 typography 믹신 사용
- 개별 font 속성 직접 선언 → @include m.text-* 토큰으로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 비로그인 알아보기 박스 위치 수정

- 인사/일기 박스는 로그인 여부 무관하게 항상 표시
- 말해부엉 알아보기 박스를 진행중인 사건 위치(구분선 아래)로 이동
- 비로그인 인사: '안녕하세요' 표시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면에 통계 섹션 및 구분선 통합

- StatsCategorySection, useStatistics, QueryProvider 병합
- 고민 카테고리 TOP4 통계 섹션 추가
- 통계 섹션 하단 구분선 추가 (h:8px, black-100, gap:42px)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: 개발 편의용 로그인 상태 강제 설정 (배포 전 제거 필요)

- isLoggedIn = true 하드코딩으로 로그인 상태 유지
- TODO 주석으로 배포 전 제거 안내 표시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건작성 페이지 구현 (disputes/[id]/statement) (#46)

* feat: 사건작성 페이지 구현 (disputes/[id]/statement)

- 사건 카테고리 선택 (연애/직장/친구/가족)
- MBTI 선택 드롭다운
- 진술 내용 입력 (최대 1000자)
- 진술저장 버튼 (내용 입력 시 활성화)
- TODO: 진술 저장 API 연결

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 사건작성 페이지 카테고리/간격/드롭다운 수정

- 카테고리를 searchParams에서 읽어 하나만 표시 (비상호작용)
- 카테고리 없을 시 모달 표시 후 이전 페이지로 이동
- Select/Textarea 사이 간격 8px (statementGroup)
- label/Select 사이 간격 16px 유지
- Textarea placeholder 줄바꿈 적용 (\n)
- content overflow-y 제거 → Select 드롭다운 아래 방향 열림 수정
- Select placeholder 색상 var(--text-secondary) 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 없음 모달에서 버튼 제거 — 페이지 블로킹만 유지

확인 버튼 클릭 시 이동하지 않고 Header 뒤로가기로만 탈출 가능

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 기본값 romance 적용, 모달 확인 버튼 복원

- searchParams에 카테고리 없을 시 임시로 romance 기본값 사용
- 모달 확인 버튼 클릭 시 router.back() 복원
- TODO: 이전 페이지 카테고리 데이터 연동 후 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 커스텀 드롭다운 교체 및 Textarea focus 스타일 제거

- Select: 네이티브 select → 커스텀 드롭다운 (항상 아래 방향 열림)
- Select: placeholder 색상 --text-secondary 적용 (option 색 영향 없음)
- Select: 아이콘 회전 애니메이션 추가
- Textarea: focus 시 border-color 변경 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: Button 좌우 패딩 16 → 12으로 조정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: SCSS import 상대경로 → 절대경로(@/) 변환 및 컨벤션 문서 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 접근성 및 스타일 개선

- ul 기본 margin 리셋
- hasValue를 options.find 기준으로 판단 (빈 문자열 오인 방지)
- aria-invalid / aria-describedby 연결로 보조기기 지원
- 키보드 내비게이션 추가 (ArrowUp/Down, Enter/Space, Escape)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: dispute 생성 조건을 active room 전체로 완화 (ONE_TO_ONE 제한 제거)

혼자서도 판결 가능한 흐름을 지원하기 위해
room.roomMode !== 'ONE_TO_ONE' 체크를 제거하고
CLOSED/EXPIRED 방만 차단하도록 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select id 안정화, 빈 options 가드, Tab 기본 포커스 이동 허용

- resolvedId를 label 문자열 대신 useId() 기반으로 고정
- option id를 value 대신 index 기반으로 변경
- Enter/Space 시 options 길이 가드 추가 (크래시 방지)
- Tab은 preventDefault 제거 — 닫기만 하고 포커스 이동은 브라우저에 위임

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독 판결 MVP 포함 및 관련 정책 업데이트 (#51)

- Section 1: 단독 판결 / 1:1 판결 흐름 분리 명시
- Section 2: 단독 판결을 MVP 포함으로 이동, MVP 제외에서 제거
- Section 3: AI 대화방 정책 수정 (ai_chat/invite_ready 상태 단독 판결 허용)
- Section 3: 단독 판결 vs 1:1 판결 제공 결과 비교 섹션 추가
- Section 14: 단독 판결 관련 STOP Condition 항목 제거

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Feature/verdict record display - 캘린더 페이지 ui 제작  (#41)

* feat : 다이어리 (감정일기 , 사건기록)탭분리

* feat : 달력 ui 커스텀 추가 및 감정일기 사건기록 분기처리

* refactor:  및 캘린더 페이지구조 개선 (리뷰 피드백 반영)

* feat : 감정일기카드 컴포넌트 구현

* fix: build 에러 ( 임시 페이지 )

* refactor: 감정일기 컴포넌트 SCSS 모듈 적용 및 믹스인 토큰 사용

* feat: 달력 페이지 UI 구현 및 스타일 정리

- MUI DateCalendar 커스텀
- 감정일기 / 사건기록 탭 전환 구조 구현
- EmotionDiaryList, RecordList 빈 상태 UI 추가
- DiaryCard mixin 적용 (text-title-s, text-body-s, text-label-s)
- 인라인 style 제거 → SCSS 모듈로 분리
- outsideCurrentMonth 감정 아이콘 노출 차단
- 새 일기 FAB 버튼 추가 (감정일기 탭 전용)
- 불필요한 파일 삭제 (DiaryMode, EmotionDiaryCard 등)

* style : EmotionDiaryList.moulde 스타일 수정

* feat: 달력 RecordList에 CaseCard 연동 및 스타일 개선

* Update model name from 'gpt-5.5' to 'gemini-2.5-flash'

seed.ts Ai modelName 수정

---------

Co-authored-by: 배근영 <bgy09270@naver.com>

* feat: 사건작성(진술서) 페이지 구현 및 욕설 감지 필터 연동 (#49)

* feat: 사건작성 페이지 구현 (disputes/[id]/statement)

- 사건 카테고리 선택 (연애/직장/친구/가족)
- MBTI 선택 드롭다운
- 진술 내용 입력 (최대 1000자)
- 진술저장 버튼 (내용 입력 시 활성화)
- TODO: 진술 저장 API 연결

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 사건작성 페이지 카테고리/간격/드롭다운 수정

- 카테고리를 searchParams에서 읽어 하나만 표시 (비상호작용)
- 카테고리 없을 시 모달 표시 후 이전 페이지로 이동
- Select/Textarea 사이 간격 8px (statementGroup)
- label/Select 사이 간격 16px 유지
- Textarea placeholder 줄바꿈 적용 (\n)
- content overflow-y 제거 → Select 드롭다운 아래 방향 열림 수정
- Select placeholder 색상 var(--text-secondary) 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 없음 모달에서 버튼 제거 — 페이지 블로킹만 유지

확인 버튼 클릭 시 이동하지 않고 Header 뒤로가기로만 탈출 가능

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 기본값 romance 적용, 모달 확인 버튼 복원

- searchParams에 카테고리 없을 시 임시로 romance 기본값 사용
- 모달 확인 버튼 클릭 시 router.back() 복원
- TODO: 이전 페이지 카테고리 데이터 연동 후 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 커스텀 드롭다운 교체 및 Textarea focus 스타일 제거

- Select: 네이티브 select → 커스텀 드롭다운 (항상 아래 방향 열림)
- Select: placeholder 색상 --text-secondary 적용 (option 색 영향 없음)
- Select: 아이콘 회전 애니메이션 추가
- Textarea: focus 시 border-color 변경 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: Button 좌우 패딩 16 → 12으로 조정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: SCSS import 상대경로 → 절대경로(@/) 변환 및 컨벤션 문서 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 접근성 및 스타일 개선

- ul 기본 margin 리셋
- hasValue를 options.find 기준으로 판단 (빈 문자열 오인 방지)
- aria-invalid / aria-describedby 연결로 보조기기 지원
- 키보드 내비게이션 추가 (ArrowUp/Down, Enter/Space, Escape)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: dispute 생성 조건을 active room 전체로 완화 (ONE_TO_ONE 제한 제거)

혼자서도 판결 가능한 흐름을 지원하기 위해
room.roomMode !== 'ONE_TO_ONE' 체크를 제거하고
CLOSED/EXPIRED 방만 차단하도록 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select id 안정화, 빈 options 가드, Tab 기본 포커스 이동 허용

- resolvedId를 label 문자열 대신 useId() 기반으로 고정
- option id를 value 대신 index 기반으로 변경
- Enter/Space 시 options 길이 가드 추가 (크래시 방지)
- Tab은 preventDefault 제거 — 닫기만 하고 포커스 이동은 브라우저에 위임

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Textarea 바이트 카운팅 및 filterMessage prop 추가

- 한글 2바이트/ASCII 1바이트 기준으로 글자 수 계산
- maxLength 초과 시 바이트 기준으로 자동 truncate
- filterMessage prop 추가 — 욕설 차단 메시지 동적 표시
- border 색상 변경은 error prop에만 적용 (filter는 border 유지)
- filter-warning 텍스트: Body-S + var(--text-danger)
- field gap 8 → 10px (Figma 기준)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 욕설 감지 필터 구현 (Gemini 2.5 Flash)

- moderation.ts: Gemini 2.5 Flash 기반 욕설/개인정보 감지
  - isBlocked: 욕설·혐오·위협 차단 (보수적 기준)
  - hasPersonalInfo: 개인정보 경고 (차단 없음)
  - fail-open: Gemini 실패 시 pending 상태로 저장
- statements/route.ts: 진술 저장 API
  - 모더레이션 통과 후 upsert + ModerationLog 트랜잭션
  - 차단 시 ModerationLog만 기록, 저장 없이 422 반환
  - dev bypass: 개발 환경에서 세션 없이 모더레이션 테스트 가능
- page.tsx: handleSave 연결, filterMessage 상태, 개인정보 경고 모달
- StatementPage.module.scss: 모달 스타일, Stylelint 공백 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: PR #49 코드리뷰 수정 — MBTI 연동, 파싱 에러, 인젝션, 타임아웃

- MBTI: GET /api/user/me 신규 생성, statement 페이지 마운트 시 user.mbti 초기화
- MBTI: handleSave body에 mbti 포함, statements route에서 user.mbti 업데이트 (트랜잭션)
- statement/page.tsx: res.json() 파싱 실패를 별도 try-catch로 분리
- Textarea.tsx: e.target.value 직접 변경 → Object.assign으로 새 이벤트 객체 전달
- moderation.ts: content 삽입 전 < > HTML 이스케이프 (프롬프트 인젝션 방지)
- moderation.ts: Promise.race() 기반 10초 타임아웃 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: user/me route catch 블록에 에러 로깅 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: judge route 1인 판결 허용 — isSolo 분기 및 rollback 상태 수정

- 2인: BOTH_SUBMITTED 상태 확인 유지
- 1인: 진술 제출 여부만 확인 (statements.length > 0)
- 롤백 대상을 하드코딩된 BOTH_SUBMITTED → previousStatus로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 카카오 로그인 기능 구현 (#50)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 absolute 배치

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 카카오 로그인 기능 구현

- 로그인 페이지 UI 및 카카오 signIn 버튼 연결
- @auth/prisma-adapter 설치 및 authOptions에 적용
- 최초 로그인 시 kakaoId, nickname, termsAgreedAt 자동 설정
- 닉네임 자동 생성 유틸 추가 (~하는부엉이 + 4자리 난수)
- middleware 추가: 비인증 사용자 /login 리다이렉트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 로그인 페이지 및 인증 로직 개선

- SCSS import 절대경로(@/) 수정
- 캐릭터 이미지 Next/Image fill → img 태그로 변경
- 이용약관/개인정보처리방침 링크(/terms, /privacy) 추가 및 스타일 적용
- 닉네임 유니크 제약(@unique) 추가 및 충돌 재시도 로직 구현 (최대 10회)
- middleware matcher 패턴 보완 (/login-help 등 우회 경로 차단)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: disclaimer mixin 적용, nickname 유실 복구 및 fallback 랜덤화

- .disclaimer에 @include m.text-caption mixin 적용
- 유실된 nickname.ts 복구
- fallback 닉네임 Date.now() → 랜덤 8자리 숫자로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독/1:1 판결 공통 진입 흐름 반영 및 관련 문서 일괄 수정 (#54)

- 단독 판결과 1:1 판결이 완전히 분리된 진입이 아니라
  AI 대화방 → 진술저장 → [분기] → disputes/[id]/statement 경로를 공통으로 거침
- CLAUDE.md: 핵심 서비스 흐름 분기 구조로 수정, 단독 판결 MVP 포함 반영,
  AI 대화방 정책 단독/1:1 병행 기술, dispute_status 단독 경로 추가
- PROJECT_DECISIONS.md: 흐름·MVP포함·MVP제외·dispute_status 동기화
- STATUS_TRANSITION.md: 단독 판결 경로(draft→judging→judged) 추가
- DISPUTE.md: 상태 전이 단독/1:1 경로 분리 기술, 주의사항 확정 내용 반영
- ROOM.md: 진술저장 후 분기 흐름 포함 기능에 명시

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Login 페이지 hydration removeChild 에러 수정 (#55)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이…
evenif99 added a commit that referenced this pull request Jul 1, 2026
* chore: initialize project folder structure (#1)

* chore: initialize project folder structure

- Add base directory layout for Next.js + domain-driven architecture
- Add .gitkeep to track empty directories in git
- Exclude MVP out-of-scope domains (shop, points, user-items)
- No implementation files included, structure only

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update README.md

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add CLAUDE.md with project rules and work guidelines (#2)

- Add project overview and MVP scope definition
- Add fixed product rules (categories, AI chat policy, judgement output)
- Add architecture, domain scope, and state transition rules
- Add auth/security, DB, frontend state, API, logging rules
- Add Git workflow, Claude work process, STOP conditions
- Add approval-required list and required reference documents

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: setup project config and install dependencies (#3)

- Add package.json with Next.js 15, React 19, TypeScript stack
- Add next.config.ts (minimal Next.js 15 config)
- Add tsconfig.json (strict mode, @/* path alias)
- Add eslint.config.mjs (next/core-web-vitals + next/typescript)
- Add .prettierrc and .prettierignore
- Add .gitignore (node_modules, .next, .env.local, etc.)
- Add .env.example (key names only, no real values)
- Add prisma/schema.prisma (generator + datasource only)
- Add data/mock/db.json (health check stub for json-server)
- Add docs/TECH_STACK.md (package list and selection rationale)
- Update README.md with run commands and env guide

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add base documentation structure (#4)

- Add PROJECT_DECISIONS.md (MVP scope, architecture, security principles)
- Add guides/CLAUDE_WORKFLOW.md (work process, STOP conditions, approval rules)
- Add guides/GIT_WORKFLOW.md (branch naming, commit convention, workflow)
- Add guides/PR_RULES.md (PR target, title rules, review criteria)
- Add guides/ENV_GUIDE.md (Vercel env pull, .env.example management)
- Add guides/CODING_CONVENTION.md (naming, state management, folder rules)
- Add db/STATUS_TRANSITION.md (room_mode, dispute_status transitions)
- Add db/PRISMA_MAPPING.md (snake_case/camelCase mapping rules)
- Add db/MASTER_DATA.md (categories, result types, DB master principles)
- Add domains/README.md (domain list, MVP scope, writing guidelines)
- Add domains/_DOMAIN_TEMPLATE.md (template for domain docs)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add domain document drafts for all MVP domains (#5)

- Add AUTH.md (kakao login, terms, session management)
- Add COMMON.md (error handling, logging, common response)
- Add ROOM.md (AI chat room, invite link, room_mode transitions)
- Add PERSONAL_ANALYSIS.md (AI-based personal conflict analysis)
- Add DISPUTE.md (1:1 mediation, roles, statements, dispute_status)
- Add JUDGEMENT.md (AI judgement, Gemini API, result card)
- Add GIFT.md (gift recommendation after judgement)
- Add USER.md (mypage, profile, bottom tab)
- Add CALENDAR.md (date-based record marking, monthly summary)
- Add DIARY.md (emotion diary, author-only access, content protection)
- Add STATISTICS.md (anonymous aggregation, summary components)
- Add SHOP_FUTURE.md (v2.0 planned, MVP excluded)
- Add POINTS_FUTURE.md (v2.0 planned, MVP excluded)
- Add USER_ITEMS_FUTURE.md (v2.0 planned, MVP excluded)

All documents are draft templates with TODO markers for assignees.
No implementation, no API routes, no schema changes.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: add Next.js App Router entry files and SCSS base structure (#6)

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Infra/init next setup (#7)

* infra: add Next.js App Router entry files and SCSS base structure

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: resolve ESLint and TypeScript config warnings

- eslint.config.mjs: ignore next-env.d.ts and .next/** (auto-generated by Next.js, triple-slash reference false positive)
- tsconfig.json: remove deprecated baseUrl option (TypeScript 5.x+, paths works without baseUrl)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update README.md (#8)

* docs(infra): confirm Supabase as project infrastructure (#9)

* chore(github): add collaboration templates and policy (#10)

* docs(env): document environment variable management (#11)

* docs(calendar): confirm MUI date picker usage (#12)

달력 UI 라이브러리로 MUI X Date Pickers + Day.js 사용을 확정하고
관련 문서(TECH_STACK, PROJECT_DECISIONS, CODING_CONVENTION, CALENDAR, DIARY, CLAUDE.md)에 반영한다.

* chore(deps): install MUI X Date Pickers and peer dependencies (#13)

달력 UI 구현을 위해 MUI X Date Pickers 및 필수 peer dependency를 설치한다.
@mui/material@9.1.1, @emotion/react@11.14.0, @emotion/styled@11.14.1,
@mui/x-date-pickers@9.5.0, dayjs@1.11.21

* Update README.md (#15)

* fix: resolve ESLint and TypeScript config warnings (#20)

* infra: add Next.js App Router entry files and SCSS base structure

- Add src/app/layout.tsx (root layout with metadata and globals.scss import)
- Add src/app/page.tsx (minimal root page for build verification)
- Add src/app/globals.scss (imports src/styles/main.scss)
- Add src/app/error.tsx (minimal error boundary with reset)
- Add src/app/not-found.tsx (minimal 404 page)
- Add src/app/loading.tsx (minimal loading page)
- Add src/styles/main.scss (ordered SCSS entry point)
- Add src/styles/abstracts/_variables.scss (color, typography, spacing tokens)
- Add src/styles/abstracts/_mixins.scss (flex-center, respond-to breakpoints)
- Add src/styles/base/_reset.scss (box-sizing, margin, button, img reset)
- Add src/styles/base/_global.scss (body font, background, color defaults)
- Add src/styles/layout/_page.scss (placeholder for page layout)

Verified: type-check, lint, build all pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: resolve ESLint and TypeScript config warnings

- eslint.config.mjs: ignore next-env.d.ts and .next/** (auto-generated by Next.js, triple-slash reference false positive)
- tsconfig.json: remove deprecated baseUrl option (TypeScript 5.x+, paths works without baseUrl)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: add MVP Prisma schema with NextAuth and TALKY-OWL models (#21)

- datasource: add directUrl for Supabase connection pooler support
- enums: CategoryGroup, RoomMode, DisputeStatus, ParticipantRole, etc.
- NextAuth models: User (with TALKY-OWL fields), Account, Session, VerificationToken
- core models: DisputeRoom, RoomAiConversation, RoomAiMessage
- dispute models: Dispute, DisputeParticipant, DisputeStatement
- judgment models: AiJudgment, JudgmentResultCard
- gift models: GiftRecommendation, GiftRecommendationItem
- feature models: EmotionDiary, CalendarRecord
- master data: ConflictTypeGroup, ConflictTypeDetail (DB-based, no enum hardcoding)
- log models: AuditLog, ApiErrorLog, ModerationLog, RoomAccessLog, UserDeletionLog
- .env.example: add DIRECT_URL for Supabase directUrl
- v2.0 TODO: ShopItem, PointTransaction, UserItem, DisputeStatistic excluded

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: align project structure with guide v2 (#22)

folders added:
- src/components/{personal-analysis,room,dispute,judgement,calendar,diary,statistics,gift}
- src/app/api/auth/[...nextauth]
- src/app/api/v1/{users,personal-analyses,rooms,disputes,statements,calendar,diary,statistics,cron}

files added:
- prisma/seed.ts (placeholder for ConflictTypeGroup master data)

docs updated (minimal):
- docs/domains/COMMON.md: add log table list, judgement_logs TODO note
- docs/domains/JUDGEMENT.md: clarify Storage is MVP-excluded scaffolding
- docs/guides/ENV_GUIDE.md: clarify Supabase Storage vars are MVP-excluded

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* infra: rename src/app/page to src/app/(page) for correct Next.js route group (#23)

src/app/page/ (괄호 없음)는 /page/* URL segment를 생성하므로,
Next.js App Router route group 문법인 src/app/(page)/로 변경한다.
URL은 /landing, /home 등으로 노출되어야 하며 /page/... 가 아니다.

관련 문서 내 경로 참조도 모두 업데이트 (CLAUDE.md, docs/domains/*, docs/guides/*).

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* [Style] 디자인 토큰 및 전역 스타일 설정 (#25)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 디자인 시스템 기반 설정 (#27)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: rem 스케일 토큰 추가 및 타이포그래피 변수 rem 참조로 전환

- Rem scale 섹션 추가 (0.25rem ~ 30rem)
- 폰트 토큰에서 누락된 0.875rem(14px), 1.125rem(18px) 추가
- font-size, line-height 변수를 rem 스케일 변수 참조로 전환
- rem 스케일을 typography 섹션보다 상단으로 이동 (선언 순서)
- 컴포넌트 width/height 대응을 위해 큰 단위(9rem~30rem) 포함

Co-Authored-By: Claude <noreply@anthropic.com>

* style: r() 함수 분리 및 타이포그래피 변수 함수 기반으로 전환

- _functions.scss 신규 추가 — px → rem 변환 함수 r() 단독 관리
- _variables.scss에서 rem 스케일 변수 제거, fn.r() 참조로 전환
- _mixins.scss에 functions @use 추가
- 순환 참조 없이 variables → functions → (없음) 단방향 의존성 구성

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Feature/common component jw (#28)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* fix: :root {} 시맨틱 토큰을 _global.scss로 분리 (#29)

* feat(styles): 디자인 토큰 및 전역 스타일 설정

- _variables.scss에 글로벌 컬러 팔레트, 타이포그래피 변수, 시맨틱 CSS 커스텀 프로퍼티(:root) 추가
- _mixins.scss에 타이포그래피 mixin 추가 (text-display ~ text-value-m)
- _global.scss body 폰트 Pretendard 적용
- next/font/local로 PretendardVariable 폰트 로드 (layout.tsx)
- GIT_WORKFLOW.md 커밋 메시지 예시 한글로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 컨테이너 max-width 1000px 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 루트 레이아웃 container 적용 및 개발 확인용 임시 border 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: 개발 확인용 임시 border 색상 회색으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: container min-height 100vh 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 커밋 타입 style 추가 및 scope 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: rem 스케일 토큰 추가 및 타이포그래피 변수 rem 참조로 전환

- Rem scale 섹션 추가 (0.25rem ~ 30rem)
- 폰트 토큰에서 누락된 0.875rem(14px), 1.125rem(18px) 추가
- font-size, line-height 변수를 rem 스케일 변수 참조로 전환
- rem 스케일을 typography 섹션보다 상단으로 이동 (선언 순서)
- 컴포넌트 width/height 대응을 위해 큰 단위(9rem~30rem) 포함

Co-Authored-By: Claude <noreply@anthropic.com>

* style: r() 함수 분리 및 타이포그래피 변수 함수 기반으로 전환

- _functions.scss 신규 추가 — px → rem 변환 함수 r() 단독 관리
- _variables.scss에서 rem 스케일 변수 제거, fn.r() 참조로 전환
- _mixins.scss에 functions @use 추가
- 순환 참조 없이 variables → functions → (없음) 단방향 의존성 구성

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: :root {} 시맨틱 토큰을 _global.scss로 분리

_variables.scss에 :root {}가 있으면 module.scss에서 @use 시
CSS Modules 'not pure' 에러 발생.
SCSS 변수는 _variables.scss, CSS 출력은 _global.scss로 분리.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): 공통 UI 컴포넌트 추가 및 MUI 정책 적용 (#30)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 목록 공통 UI 컴포넌트 추가 (Tab, StatusBadge) (#31)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 위치 수정 (#32)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 absolute 배치

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 공통 및 dispute·judgment DTO 타입 정의

- ApiResponse, ApiError, ApiFieldError, CategoryGroup (common.ts)
- DisputeDto, CreateDisputeRequest, DisputeListResponse 등 (dispute.ts)
- AiJudgmentDto, CreateAiJudgmentRequest 등 (judgment.ts)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: dispute 도메인 공유 상수·헬퍼·mapper 추가

- VALID_CATEGORY_GROUPS, IMMUTABLE_DISPUTE_STATUSES 상수 (constants/dispute.ts)
- getSessionUserId NextAuth 세션 헬퍼 (auth/session.ts)
- toAiJudgmentDto 공유 mapper (judgement/judgment.mapper.ts)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 목록 조회·생성·수정·삭제 API 구현

- GET /api/v1/disputes — 참여 사건 목록, categoryGroup 필터, 페이지네이션
- POST /api/v1/disputes — 사건 생성 + role_a 참여자 트랜잭션 등록
- GET /api/v1/disputes/:id — 사건 상세 조회
- PATCH /api/v1/disputes/:id — 사건 수정 (role_a 전용, 변경 불가 상태 차단)
- DELETE /api/v1/disputes/:id — 사건 소프트 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: AI 판결 요청·결과 조회 API 구현

- POST /api/v1/disputes/:id/judge — AI 판결 요청, JUDGING 상태 잠금으로 멱등성 보장
- GET /api/v1/disputes/:id/result — 판결 결과 조회 (참여자 전용)
- AI 모듈 미구현 구간은 TODO 주석으로 마킹, 완료 전까지 503 반환

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 공통 UI 컴포넌트 - StatusBadge, Tab, 진행 상태 (#33)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Prisma 클라이언트, NextAuth Kakao OAuth 설정 및 핸들러 추가

- src/lib/db/index.ts — Prisma 전역 싱글턴
- src/lib/auth/index.ts — NextAuth authOptions (Kakao OAuth, session user.id 매핑)
- src/app/api/auth/[...nextauth]/route.ts — NextAuth GET/POST 핸들러
- @mui/icons-material 패키지 설치 (빌드 에러 해결)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: 빌드 스크립트에 prisma generate 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: MVP 전체 API 명세서 작성 (API_SPEC.md) (#36)

* docs: MVP 전체 API 명세서 작성 (API_SPEC.md)

- 도메인 문서 및 기존 합의 기반 MVP API 명세 초안 작성
- 공통 응답 구조, 에러 코드 체계 정의
- Auth / User / Room / Dispute / Statement / Judgement / Diary / Calendar / Statistics / Gift / Cron 도메인 API 명세 포함
- 경로 충돌 항목 (withdraw, judge/result, diary 경로) 확정 필요 사항으로 명시
- 미확정 TODO 항목 섹션 7에 전체 정리
- MVP 제외 항목 (shop, points, 단독판결, 독립 통계 화면 등) 명시적으로 제거 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독 판결 MVP 포함 반영 및 라우트 주석 명확화

- 단독 판결(상대방 없는 AI 판결)을 MVP 포함 범위로 변경
- Personal Analysis 섹션에 단독 판결 API 초안 추가 (POST/GET /api/v1/personal-analyses)
- 라우트 트리 personal-analyses 디렉터리 구조 구체화
- /auth/withdraw route.ts 주석을 경로 충돌 상호 참조가 명확한 형태로 수정
  (경로 충돌 → /auth/withdraw vs DELETE /users/me)
- MVP 제외 목록에서 단독 판결 항목 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 카카오 로그인 시 약관 동의 자동 간주 정책 반영

- 카카오 OAuth 로그인 완료를 약관 동의로 간주
- 별도 약관 동의 페이지 이동 플로우 제거
- 확정 필요 항목에서 약관 동의 기준 항목 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 도메인 API 목록 중복 제거 및 회원탈퇴 경로 확정

- docs/domains/*.md 8개 파일의 API 목록 섹션을 docs/API_SPEC.md 참조로 교체
  (AUTH, USER, ROOM, DISPUTE, JUDGEMENT, DIARY, CALENDAR, STATISTICS)
- API_SPEC.md 단일 소스 체계 확립
- 회원탈퇴 경로 DELETE /api/v1/users/me 채택 확정
  - §3 요약표, §4.1·§4.2 상세, §5 라우트 트리, §6 충돌 목록, §7 체크리스트 반영
  - /auth/withdraw 라우트 제거, /users/me route.ts에 DELETE 추가
- CLAUDE_WORKFLOW.md PR 템플릿 준수 문구 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 날짜 포맷 및 Pagination 구조 확정 반영

- 날짜/시간 포맷 ISO 8601 (YYYY-MM-DDTHH:mm:ssZ) 확정
- Pagination 공통 구조 확정
  - data 필드: items 배열
  - page 필드: page / totalPages / sortBy / isNext
- 섹션 7 확정 필요 항목 두 개 체크 처리
- Room 목록, Diary 목록 섹션 Pagination 참조로 갱신

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: Pagination 구조에 size / sort / hasNext / hasPrevious 추가

- size: 한 번에 가져오는 항목 수
- sort: 정렬 방향 (asc | desc)
- isNext → hasNext로 변경 (다음 페이지 존재 여부)
- hasPrevious 추가 (이전 페이지 존재 여부)
- §7 체크리스트 항목 갱신

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 날짜 포맷 코드블록 언어 지정자 추가 (MD040)

코드래빗 지적 사항 반영 — 언어 미지정 펜스 코드블록에 text 지정자 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 통계 API 비로그인 공개 조회로 변경

홈 화면 진입 시 비로그인 회원도 통계 조회 가능하도록 수정
- GET /api/v1/statistics/summary: 🔒 → 공개
- GET /api/v1/statistics/top-types: 🔒 → 공개
- §3 요약표, §4.9 상세 명세 인증 표기 및 설명 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 목록 응답 예시에 page 객체 추가 (코드래빗 지적 반영)

- GET /api/v1/rooms 응답 예시에 page 객체 추가
- GET /api/v1/diary 응답 예시에 page 객체 추가
- GET /api/v1/statistics/top-types 응답 예시에 page 객체 추가
  (Top5 고정 목록 특성 반영: size=5, totalPages=1, hasNext=false)
- 코드래빗 제안의 구버전 필드(isNext) 대신 확정 구조(hasNext/hasPrevious/size/sort) 적용
- §7 Room Pagination 항목 체크 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Spinner, Avatar, AvatarGroup 공통 컴포넌트 추가 (#37)

* chore: 정적 이미지 에셋 추가 및 정리

주요 페이지용 캐릭터 이미지 추가 및 공통 에셋 정리.
gift, loading 캐릭터를 common에서 characters로 이동하여
캐릭터 이미지를 한 폴더로 통합.

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: Spinner 공통 컴포넌트 추가

캐릭터 로딩 이미지를 중앙에 배치한 88x88 스피너 컴포넌트 추가.
트랙(배경 원)과 애니메이션 링을 분리하여 각각 border-default, bg-brand 색상 적용.

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: Avatar, AvatarGroup 공통 컴포넌트 추가

MUI Avatar, AvatarGroup 래핑 컴포넌트 추가.
size prop으로 s/m/l 사이즈 조절, src prop으로 프로필 사진 지원.
global.scss에 --color-white, --color-black CSS 변수 추가.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: Avatar Context로 AvatarGroup size 전달 및 토큰 수정

AvatarGroup size prop이 자식 Avatar에 적용 안 되는 버그 수정.
Context를 통해 size를 내려주고 Avatar가 그룹 size를 우선 적용.
color 토큰 --color-white를 --text-inverse로 교체.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: Avatar src 없을 때 기본 썸네일 이미지로 fallback 처리

Co-Authored-By: Claude <noreply@anthropic.com>

* test: Spinner, Avatar, AvatarGroup 테스트 페이지 추가

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

* feat: 공통 UI 컴포넌트 - CategoryFilter, CategoryIcon, Tab, StatusBadge (#38)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 공통 컴포넌트 생성

- 전체/연애/직장/친구/가족 카테고리 필터 구현
- 아이콘 박스 44x44, border-radius 8, 아이콘 24x24
- 선택 상태: icon-primary bg / 미선택: bg-disabled
- MUI icons 사용 (GridViewRounded, Favorite, BusinessCenter, Diversity3, FamilyRestroom)
- Category 타입 export

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Tab 라벨 폰트 스타일 명시

- item.label을 span.label로 래핑
- Body-M 기준 font-size 16, line-height 28 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: @mui/icons-material 패키지 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 스타일 및 single 모드 적용

- 선택: bg-page + border-brand(1px) + icon-primary + 텍스트 bold
- 미선택: bg-page + border-default(1px) + icon-secondary + 텍스트 regular
- mode prop 추가 (filter 기본값 / single: 선택된 박스 하나만 표시)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 타입을 DB CategoryGroup 기준으로 통일

## 수정 배경

CategoryIcon, CategoryFilter가 한국어 문자열('연애', '직장' 등)을 타입으로 사용하고 있어
API/DB의 CategoryGroup('romance', 'work' 등)과 불일치가 발생.
페이지에서 연결 시 별도 변환 레이어가 필요해지는 문제를 사전 차단.

## 변경 파일별 수정 내용

### CategoryIcon.tsx
- CategoryWithoutAll 타입 제거 → @/types/common의 CategoryGroup 직접 사용
- 아이콘/레이블/컬러 맵 키를 한국어 → 영문 DB 값으로 변경
  (romance, work, friend, family)
- CATEGORY_LABEL_MAP export 추가 (CategoryFilter에서 레이블 참조용)

### CategoryFilter.tsx
- Category 타입을 'all' | CategoryGroup으로 변경 (기존: 한국어 문자열)
- CATEGORIES 배열에 label 필드 추가, CATEGORY_LABEL_MAP에서 참조
- 전체 키를 '전체' → 'all'로 변경 (API 필터 미적용 값과 일치)

### CaseCard.tsx (타팀원 파일 수정)
- 수정 이유: CATEGORY_EMOJI 맵 키가 대문자('ROMANCE')였으나
  API 응답은 소문자('romance')로 내려와 emoji가 항상 '📋' fallback만 표시되는 버그 존재
- 해결 방법: emoji 방식 전체 제거, CategoryIcon 컴포넌트로 교체
- categoryGroup prop 타입을 string → CategoryGroup으로 명시
- categoryGroup 미전달 시 아이콘 미표시 처리 (optional 유지)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update src/components/ui/CategoryIcon.tsx

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: CategoryIcon 중복 import 제거 및 CategoryFilter discriminated union 타입 에러 수정

- CategoryIcon: FamilyRestroomIcon, CategoryGroup 중복 import 제거
- CategoryFilter: discriminated union(CodeRabbit 피드백 반영) 유지하면서
  props 전체로 받아 props.mode로 narrowing 처리해 타입 에러 해결
  (mode='single'일 때 onChange가 CategoryGroup을 기대하는 문제)
- Tab.module.scss: height → min-height 변경 (유연한 높이 대응)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard 카테고리 아이콘을 제목 왼쪽 인라인으로 이동

- card__header 구조 변경: titleRow(아이콘+제목)와 badge를 좌우 배치
- card__titleRow 추가: flex row, align-items center, gap 6px
- 아이콘이 제목 위에 쌓이던 문제 수정 → 제목 왼쪽에 인라인 배치
- card__icon: font-size/line-height(이모지 잔재) → display:flex 로 변경
- card__title: margin-bottom 제거(card__header margin-bottom으로 대체)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 공통 컴포넌트 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard titleRow flex 축소 보완 (min-width: 0, flex: 1)

긴 제목에서 card__titleRow가 축소되지 않아 배지가 밀리는 문제 방지.
card__header가 space-between일 때 titleRow가 flex: 1로 가용 공간을 차지하고
min-width: 0으로 내부 콘텐츠가 넘치지 않도록 제약.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix(common): BottomNavigation 아이콘 MUI MD2 기본 스타일로 수정 (#39)

* fix(common): BottomNavigation 아이콘을 MUI MD2 기본 스타일로 수정

- HomeRounded → Home
- GavelRounded → MenuBook (사건기록 아이콘 자체 변경)
- CalendarMonthRounded → CalendarMonth
- PersonRounded → Person
디자인 시안 기준 MD2 filled 아이콘으로 통일

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: BottomNavigation 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): BottomNavigation 활성 탭 레이블 색상 black-700으로 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): BottomNavigation 테스트 스크린샷 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: wjdalss21 <jungxmin21@gmail.com>

* feat: 사건·방 도메인 타입 정의 및 API 구현 (#40)

* feat: room DTO 타입 정의

- RoomMode, RoomDto, CreateRoomRequest, RoomListResponse

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 방 목록 조회·생성·상세 조회·종료·삭제 API 구현

- GET  /api/v1/rooms — 내 방 목록 조회 (페이지네이션)
- POST /api/v1/rooms — AI 대화방 생성 (roomMode = ai_chat)
- GET  /api/v1/rooms/:id — 방 상세 조회
- POST /api/v1/rooms/:id/close — 방 종료 (closedAt + roomMode = closed)
- DELETE /api/v1/rooms/:id — 방 소프트 삭제 (deletedAt + roomMode = deleted)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 방 목록 페이지네이션 파라미터 NaN 방어 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: API 라우트 경로 v1 버전 세그먼트 제거 (#42)

* fix: API 라우트 경로에서 v1 버전 세그먼트 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 라우트 핸들러 주석 경로 v1 제거 (/api/v1/ -> /api/)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): 서비스 흐름 기반 문서 구조 수정 및 페이지 문서 생성 (#43)

* fix(docs): 서비스 흐름 기반 문서 구조 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): PAGES.md 코드 블록 언어 명시 추가 (MD040)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: personal-analyses 페이지 및 API 폴더 삭제 (#45)

* fix: personal-analyses 페이지 및 API 폴더 삭제

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): personal-analysis 도메인 참조 MD 문서 일괄 정리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 API 구현 (GET /api/statistics/categories) (#44)

* feat: 사건조회 페이지 판결,유형 tab 공통 컴포넌트 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건 관련 페이지의 진행 상태 컴포넌트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: StatusBadge CSS 변수 하드코딩 제거 및 Tab className trailing space 수정

* fix: StatusBadge 크기 조정 및 .playwright-mcp gitignore 추가

- StatusBadge min-width, height, padding, border-radius 수정
- justify-content: center 추가
- .playwright-mcp/ gitignore 등록
- package-lock.json peer dependency 재분류 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 공통 컴포넌트 생성

- 전체/연애/직장/친구/가족 카테고리 필터 구현
- 아이콘 박스 44x44, border-radius 8, 아이콘 24x24
- 선택 상태: icon-primary bg / 미선택: bg-disabled
- MUI icons 사용 (GridViewRounded, Favorite, BusinessCenter, Diversity3, FamilyRestroom)
- Category 타입 export

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Tab 라벨 폰트 스타일 명시

- item.label을 span.label로 래핑
- Body-M 기준 font-size 16, line-height 28 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: @mui/icons-material 패키지 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: CategoryFilter 스타일 및 single 모드 적용

- 선택: bg-page + border-brand(1px) + icon-primary + 텍스트 bold
- 미선택: bg-page + border-default(1px) + icon-secondary + 텍스트 regular
- mode prop 추가 (filter 기본값 / single: 선택된 박스 하나만 표시)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 타입을 DB CategoryGroup 기준으로 통일

## 수정 배경

CategoryIcon, CategoryFilter가 한국어 문자열('연애', '직장' 등)을 타입으로 사용하고 있어
API/DB의 CategoryGroup('romance', 'work' 등)과 불일치가 발생.
페이지에서 연결 시 별도 변환 레이어가 필요해지는 문제를 사전 차단.

## 변경 파일별 수정 내용

### CategoryIcon.tsx
- CategoryWithoutAll 타입 제거 → @/types/common의 CategoryGroup 직접 사용
- 아이콘/레이블/컬러 맵 키를 한국어 → 영문 DB 값으로 변경
  (romance, work, friend, family)
- CATEGORY_LABEL_MAP export 추가 (CategoryFilter에서 레이블 참조용)

### CategoryFilter.tsx
- Category 타입을 'all' | CategoryGroup으로 변경 (기존: 한국어 문자열)
- CATEGORIES 배열에 label 필드 추가, CATEGORY_LABEL_MAP에서 참조
- 전체 키를 '전체' → 'all'로 변경 (API 필터 미적용 값과 일치)

### CaseCard.tsx (타팀원 파일 수정)
- 수정 이유: CATEGORY_EMOJI 맵 키가 대문자('ROMANCE')였으나
  API 응답은 소문자('romance')로 내려와 emoji가 항상 '📋' fallback만 표시되는 버그 존재
- 해결 방법: emoji 방식 전체 제거, CategoryIcon 컴포넌트로 교체
- categoryGroup prop 타입을 string → CategoryGroup으로 명시
- categoryGroup 미전달 시 아이콘 미표시 처리 (optional 유지)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update src/components/ui/CategoryIcon.tsx

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: CategoryIcon 중복 import 제거 및 CategoryFilter discriminated union 타입 에러 수정

- CategoryIcon: FamilyRestroomIcon, CategoryGroup 중복 import 제거
- CategoryFilter: discriminated union(CodeRabbit 피드백 반영) 유지하면서
  props 전체로 받아 props.mode로 narrowing 처리해 타입 에러 해결
  (mode='single'일 때 onChange가 CategoryGroup을 기대하는 문제)
- Tab.module.scss: height → min-height 변경 (유연한 높이 대응)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard 카테고리 아이콘을 제목 왼쪽 인라인으로 이동

- card__header 구조 변경: titleRow(아이콘+제목)와 badge를 좌우 배치
- card__titleRow 추가: flex row, align-items center, gap 6px
- 아이콘이 제목 위에 쌓이던 문제 수정 → 제목 왼쪽에 인라인 배치
- card__icon: font-size/line-height(이모지 잔재) → display:flex 로 변경
- card__title: margin-bottom 제거(card__header margin-bottom으로 대체)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 공통 컴포넌트 테스트 스크린샷 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: CaseCard titleRow flex 축소 보완 (min-width: 0, flex: 1)

긴 제목에서 card__titleRow가 축소되지 않아 배지가 밀리는 문제 방지.
card__header가 space-between일 때 titleRow가 flex: 1로 가용 공간을 차지하고
min-width: 0으로 내부 콘텐츠가 넘치지 않도록 제약.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 도메인 서비스 레이어 생성 (statisticsService.ts)

## 생성 이유
통계 API의 DB 쿼리 로직을 Route Handler와 분리하기 위해
도메인 서비스 레이어를 별도 파일로 작성했다.

## 폴더 선택 이유
src/domains/statistics/
- CLAUDE.md §4 아키텍처 원칙에 따라 도메인별 비즈니스 로직은
  src/domains/{domain}/ 에 위치한다.
- statistics는 MVP 도메인 목록에 포함된 독립 도메인이다.
- Route Handler(src/app/api/)는 요청/응답 처리만 담당하고,
  실제 DB 쿼리 로직은 서비스 레이어에서 관리한다.

## 구현 내용

### getSummary()
- 서비스 전체 판결 완료 건수(totalJudgements) 집계
- dispute.status = JUDGED 조건 명시: ai_judgements는 판결 완료 시에만
  생성되지만 의도를 코드에 명시적으로 표현
- deletedAt / anonymizedAt IS NULL: 삭제·익명화된 사건 제외 (CLAUDE.md §7)

### getTopTypes(size = 5)
- ai_judgements.result_conflict_detail_id 기준 GROUP BY COUNT DESC
- 결과 유형 마스터(conflict_type_details)를 JOIN해 detailCode·displayName 반환
- isActive = true 필터: 비활성화된 유형은 통계에서 제외
- percentage 서버 계산: count / total * 100 (소수점 1자리)
  FE에서 별도 계산 없이 바로 사용할 수 있도록 서버에서 내려줌
- prisma.conflictTypeDetail 사용 (prisma.conflictDetail은 스키마에 존재하지 않음)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 통계 API Route Handler 생성 (GET /api/v1/statistics/top-types)

## 생성 이유
statisticsService의 getTopTypes()를 HTTP 엔드포인트로 노출하기 위해
Next.js App Router 기반 Route Handler를 생성했다.

## 폴더 선택 이유
src/app/api/v1/statistics/top-types/
- CLAUDE.md §4 아키텍처 원칙에 따라 API Route는 src/app/api/v1/ 하위에 위치한다.
- API_SPEC.md §4.9 기준 엔드포인트 경로: GET /api/v1/statistics/top-types
- summary 엔드포인트는 현재 MVP 범위에서 불필요하여 top-types만 생성

## 구현 내용
- getServerSession으로 서버에서 직접 세션 검증
  (FE 리다이렉트만으로는 API 직접 호출을 막을 수 없으므로 서버 검증 필수 — CLAUDE.md §7)
- 인증 실패 시 401 UNAUTHORIZED 반환
- getTopTypes(5) 호출 → 판결 완료 기준 Top5 유형 + 비율 반환
- ApiResponse 타입 준수: data/error는 null 아닌 undefined(optional) 사용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: statistics top-types 인증 제거 (메인 페이지 공개 접근 허용)

메인 페이지에서도 통계 차트가 노출되는 익명 집계 데이터이므로
세션 없이 접근 가능하도록 수정.

- getServerSession 및 관련 import 제거
- 401 인증 체크 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: statistics top-types 에러 핸들링 보완

코드래빗 피드백 반영:
- catch {} -> catch (error): 에러 정보 유실 방지
- 타임아웃 감지 후 504 분기 처리
- console.error 로깅 추가 (CLAUDE.md 11 API 오류 로그 대상)
- 세션 체크는 이전 커밋에서 이미 제거됨 (공개 엔드포인트)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: 통계 API 카테고리 기준으로 재설계

- 결과 유형(top-types) → 작성 카테고리(ROMANCE/FAMILY/FRIEND/WORK) 기준으로 변경
- route.ts에 DB 쿼리 직접 작성, statisticsService.ts 제거
- 비율 계산은 프론트 훅(useStatistics)에서 담당
- revalidate = 86400 (하루 1회 재계산)
- src/hooks/ 폴더 신설 및 useStatistics.ts 생성

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 통계 API 서버 측 세션 인증 추가

- GET /api/statistics/categories 진입 시 getServerSession으로 인증 검증
- 미인증 요청 401 UNAUTHORIZED 반환

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: jungmin park <jungxmin21@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* feat: Header variant 분리 (logo/title) 및 홈 화면 적용 (#47)

* feat: 홈 화면 기본 구조 생성 (헤더, 일기 박스)

- 헤더: 세션 유저명 + character-welcome.png 부엉이 이미지
- 일기 박스: 365x88, border black-700 2px, bg primary-100
- TODO: GangwonEduPower 폰트 추가 후 헤더 로고 텍스트 적용 필요

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Header variant 분리 (logo/title) 및 홈 화면 적용

- Header.tsx에 variant prop 추가 (logo | title)
  - logo: 좌측 상단 말해부엉 로고 표시 (66x19, h:56, padding: 16px 20px)
  - title: 기존 뒤로가기 + 페이지 제목 형태 유지
- Header.module.scss에 __logo 스타일 추가
- home/page.tsx에 Header variant='logo' 적용
  - 헤더를 컨테이너 padding 밖으로 분리하여 상단 여백 제거
- home/page.module.scss diaryBox에 align-self: center 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건기록 페이지 생성 및 로고 헤더 적용 (/records)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: diaryBox 고정 폭을 max-width + width 100%로 반응형 처리

- width: 365px → width: 100% + max-width: 365px
- 작은 화면에서 좌우 패딩과 결합 시 오버플로우 방지

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 감정일기 작성 버튼 /diary/new 네비게이션 연결

- 일기 박스 전체를 Link로 변경 (텍스트 + 버튼 모두 클릭 가능)
- diaryBox에 text-decoration: none, cursor: pointer 추가
- /diary/new 경로는 임시 지정 (담당자 확인 후 수정 예정)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면 캐릭터 이미지 교체 및 위치 조정

- character-welcome.png → character-home.png 교체 (169x138)
- 캐릭터 절대 위치 적용 (top: 41px, right: -20px)
- 캐릭터가 일기 박스 뒤에 위치하도록 z-index 조정 (character: 0, container: 1)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 홈 화면 코드래빗 피드백 반영

- 캐릭터 이미지 가로 스크롤 방지: .page에 overflow-x: hidden 추가
- 비로그인 사용자 분기 처리: 말해부엉 알아보기 박스 추가 (/login 이동)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: 홈 화면 typography 믹신 적용

- greetingText, diaryTitle, diarySubtitle에 typography 믹신 사용
- 개별 font 속성 직접 선언 → @include m.text-* 토큰으로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 비로그인 알아보기 박스 위치 수정

- 인사/일기 박스는 로그인 여부 무관하게 항상 표시
- 말해부엉 알아보기 박스를 진행중인 사건 위치(구분선 아래)로 이동
- 비로그인 인사: '안녕하세요' 표시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 홈 화면에 통계 섹션 및 구분선 통합

- StatsCategorySection, useStatistics, QueryProvider 병합
- 고민 카테고리 TOP4 통계 섹션 추가
- 통계 섹션 하단 구분선 추가 (h:8px, black-100, gap:42px)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: 개발 편의용 로그인 상태 강제 설정 (배포 전 제거 필요)

- isLoggedIn = true 하드코딩으로 로그인 상태 유지
- TODO 주석으로 배포 전 제거 안내 표시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 사건작성 페이지 구현 (disputes/[id]/statement) (#46)

* feat: 사건작성 페이지 구현 (disputes/[id]/statement)

- 사건 카테고리 선택 (연애/직장/친구/가족)
- MBTI 선택 드롭다운
- 진술 내용 입력 (최대 1000자)
- 진술저장 버튼 (내용 입력 시 활성화)
- TODO: 진술 저장 API 연결

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 사건작성 페이지 카테고리/간격/드롭다운 수정

- 카테고리를 searchParams에서 읽어 하나만 표시 (비상호작용)
- 카테고리 없을 시 모달 표시 후 이전 페이지로 이동
- Select/Textarea 사이 간격 8px (statementGroup)
- label/Select 사이 간격 16px 유지
- Textarea placeholder 줄바꿈 적용 (\n)
- content overflow-y 제거 → Select 드롭다운 아래 방향 열림 수정
- Select placeholder 색상 var(--text-secondary) 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 없음 모달에서 버튼 제거 — 페이지 블로킹만 유지

확인 버튼 클릭 시 이동하지 않고 Header 뒤로가기로만 탈출 가능

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 기본값 romance 적용, 모달 확인 버튼 복원

- searchParams에 카테고리 없을 시 임시로 romance 기본값 사용
- 모달 확인 버튼 클릭 시 router.back() 복원
- TODO: 이전 페이지 카테고리 데이터 연동 후 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 커스텀 드롭다운 교체 및 Textarea focus 스타일 제거

- Select: 네이티브 select → 커스텀 드롭다운 (항상 아래 방향 열림)
- Select: placeholder 색상 --text-secondary 적용 (option 색 영향 없음)
- Select: 아이콘 회전 애니메이션 추가
- Textarea: focus 시 border-color 변경 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: Button 좌우 패딩 16 → 12으로 조정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: SCSS import 상대경로 → 절대경로(@/) 변환 및 컨벤션 문서 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 접근성 및 스타일 개선

- ul 기본 margin 리셋
- hasValue를 options.find 기준으로 판단 (빈 문자열 오인 방지)
- aria-invalid / aria-describedby 연결로 보조기기 지원
- 키보드 내비게이션 추가 (ArrowUp/Down, Enter/Space, Escape)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: dispute 생성 조건을 active room 전체로 완화 (ONE_TO_ONE 제한 제거)

혼자서도 판결 가능한 흐름을 지원하기 위해
room.roomMode !== 'ONE_TO_ONE' 체크를 제거하고
CLOSED/EXPIRED 방만 차단하도록 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select id 안정화, 빈 options 가드, Tab 기본 포커스 이동 허용

- resolvedId를 label 문자열 대신 useId() 기반으로 고정
- option id를 value 대신 index 기반으로 변경
- Enter/Space 시 options 길이 가드 추가 (크래시 방지)
- Tab은 preventDefault 제거 — 닫기만 하고 포커스 이동은 브라우저에 위임

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독 판결 MVP 포함 및 관련 정책 업데이트 (#51)

- Section 1: 단독 판결 / 1:1 판결 흐름 분리 명시
- Section 2: 단독 판결을 MVP 포함으로 이동, MVP 제외에서 제거
- Section 3: AI 대화방 정책 수정 (ai_chat/invite_ready 상태 단독 판결 허용)
- Section 3: 단독 판결 vs 1:1 판결 제공 결과 비교 섹션 추가
- Section 14: 단독 판결 관련 STOP Condition 항목 제거

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Feature/verdict record display - 캘린더 페이지 ui 제작  (#41)

* feat : 다이어리 (감정일기 , 사건기록)탭분리

* feat : 달력 ui 커스텀 추가 및 감정일기 사건기록 분기처리

* refactor:  및 캘린더 페이지구조 개선 (리뷰 피드백 반영)

* feat : 감정일기카드 컴포넌트 구현

* fix: build 에러 ( 임시 페이지 )

* refactor: 감정일기 컴포넌트 SCSS 모듈 적용 및 믹스인 토큰 사용

* feat: 달력 페이지 UI 구현 및 스타일 정리

- MUI DateCalendar 커스텀
- 감정일기 / 사건기록 탭 전환 구조 구현
- EmotionDiaryList, RecordList 빈 상태 UI 추가
- DiaryCard mixin 적용 (text-title-s, text-body-s, text-label-s)
- 인라인 style 제거 → SCSS 모듈로 분리
- outsideCurrentMonth 감정 아이콘 노출 차단
- 새 일기 FAB 버튼 추가 (감정일기 탭 전용)
- 불필요한 파일 삭제 (DiaryMode, EmotionDiaryCard 등)

* style : EmotionDiaryList.moulde 스타일 수정

* feat: 달력 RecordList에 CaseCard 연동 및 스타일 개선

* Update model name from 'gpt-5.5' to 'gemini-2.5-flash'

seed.ts Ai modelName 수정

---------

Co-authored-by: 배근영 <bgy09270@naver.com>

* feat: 사건작성(진술서) 페이지 구현 및 욕설 감지 필터 연동 (#49)

* feat: 사건작성 페이지 구현 (disputes/[id]/statement)

- 사건 카테고리 선택 (연애/직장/친구/가족)
- MBTI 선택 드롭다운
- 진술 내용 입력 (최대 1000자)
- 진술저장 버튼 (내용 입력 시 활성화)
- TODO: 진술 저장 API 연결

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 사건작성 페이지 카테고리/간격/드롭다운 수정

- 카테고리를 searchParams에서 읽어 하나만 표시 (비상호작용)
- 카테고리 없을 시 모달 표시 후 이전 페이지로 이동
- Select/Textarea 사이 간격 8px (statementGroup)
- label/Select 사이 간격 16px 유지
- Textarea placeholder 줄바꿈 적용 (\n)
- content overflow-y 제거 → Select 드롭다운 아래 방향 열림 수정
- Select placeholder 색상 var(--text-secondary) 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 없음 모달에서 버튼 제거 — 페이지 블로킹만 유지

확인 버튼 클릭 시 이동하지 않고 Header 뒤로가기로만 탈출 가능

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 카테고리 기본값 romance 적용, 모달 확인 버튼 복원

- searchParams에 카테고리 없을 시 임시로 romance 기본값 사용
- 모달 확인 버튼 클릭 시 router.back() 복원
- TODO: 이전 페이지 카테고리 데이터 연동 후 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 커스텀 드롭다운 교체 및 Textarea focus 스타일 제거

- Select: 네이티브 select → 커스텀 드롭다운 (항상 아래 방향 열림)
- Select: placeholder 색상 --text-secondary 적용 (option 색 영향 없음)
- Select: 아이콘 회전 애니메이션 추가
- Textarea: focus 시 border-color 변경 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: Button 좌우 패딩 16 → 12으로 조정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: SCSS import 상대경로 → 절대경로(@/) 변환 및 컨벤션 문서 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select 접근성 및 스타일 개선

- ul 기본 margin 리셋
- hasValue를 options.find 기준으로 판단 (빈 문자열 오인 방지)
- aria-invalid / aria-describedby 연결로 보조기기 지원
- 키보드 내비게이션 추가 (ArrowUp/Down, Enter/Space, Escape)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: dispute 생성 조건을 active room 전체로 완화 (ONE_TO_ONE 제한 제거)

혼자서도 판결 가능한 흐름을 지원하기 위해
room.roomMode !== 'ONE_TO_ONE' 체크를 제거하고
CLOSED/EXPIRED 방만 차단하도록 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Select id 안정화, 빈 options 가드, Tab 기본 포커스 이동 허용

- resolvedId를 label 문자열 대신 useId() 기반으로 고정
- option id를 value 대신 index 기반으로 변경
- Enter/Space 시 options 길이 가드 추가 (크래시 방지)
- Tab은 preventDefault 제거 — 닫기만 하고 포커스 이동은 브라우저에 위임

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Textarea 바이트 카운팅 및 filterMessage prop 추가

- 한글 2바이트/ASCII 1바이트 기준으로 글자 수 계산
- maxLength 초과 시 바이트 기준으로 자동 truncate
- filterMessage prop 추가 — 욕설 차단 메시지 동적 표시
- border 색상 변경은 error prop에만 적용 (filter는 border 유지)
- filter-warning 텍스트: Body-S + var(--text-danger)
- field gap 8 → 10px (Figma 기준)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 욕설 감지 필터 구현 (Gemini 2.5 Flash)

- moderation.ts: Gemini 2.5 Flash 기반 욕설/개인정보 감지
  - isBlocked: 욕설·혐오·위협 차단 (보수적 기준)
  - hasPersonalInfo: 개인정보 경고 (차단 없음)
  - fail-open: Gemini 실패 시 pending 상태로 저장
- statements/route.ts: 진술 저장 API
  - 모더레이션 통과 후 upsert + ModerationLog 트랜잭션
  - 차단 시 ModerationLog만 기록, 저장 없이 422 반환
  - dev bypass: 개발 환경에서 세션 없이 모더레이션 테스트 가능
- page.tsx: handleSave 연결, filterMessage 상태, 개인정보 경고 모달
- StatementPage.module.scss: 모달 스타일, Stylelint 공백 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: PR #49 코드리뷰 수정 — MBTI 연동, 파싱 에러, 인젝션, 타임아웃

- MBTI: GET /api/user/me 신규 생성, statement 페이지 마운트 시 user.mbti 초기화
- MBTI: handleSave body에 mbti 포함, statements route에서 user.mbti 업데이트 (트랜잭션)
- statement/page.tsx: res.json() 파싱 실패를 별도 try-catch로 분리
- Textarea.tsx: e.target.value 직접 변경 → Object.assign으로 새 이벤트 객체 전달
- moderation.ts: content 삽입 전 < > HTML 이스케이프 (프롬프트 인젝션 방지)
- moderation.ts: Promise.race() 기반 10초 타임아웃 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: user/me route catch 블록에 에러 로깅 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: judge route 1인 판결 허용 — isSolo 분기 및 rollback 상태 수정

- 2인: BOTH_SUBMITTED 상태 확인 유지
- 1인: 진술 제출 여부만 확인 (statements.length > 0)
- 롤백 대상을 하드코딩된 BOTH_SUBMITTED → previousStatus로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 카카오 로그인 기능 구현 (#50)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react 아이콘
- toastStore: Zustand UI 상태 (show/hide/message)

* docs: update collaboration policy

- GitHub Ruleset 브랜치 규칙 추가 (브랜치 Pattern 2, PR 제목 Pattern 1 분리)
- Issues / Milestones / Project Board 미사용으로 관련 내용 제거
- GIT_WORKFLOW 작업 흐름에서 Issue 생성/자동종료 단계 제거
- PR_RULES PR 본문에서 관련 Issue 항목 제거

* feat(common): add Tabs, CaseCard, ActionPrompt, Input, Select, Textarea components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(common): apply MUI icons and Snackbar, update MUI usage policy

- Toast: MUI Snackbar (3s auto-dismiss)
- BottomNavigation, Header, Select: lucide-react → @mui/icons-material
- Install @mui/icons-material
- CLAUDE.md, CODING_CONVENTION.md: MUI usage policy updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update icon policy — @mui/icons-material except diary feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(common): ActionPrompt message 제거 및 Textarea 글자수 카운터 absolute 배치

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: 카카오 로그인 기능 구현

- 로그인 페이지 UI 및 카카오 signIn 버튼 연결
- @auth/prisma-adapter 설치 및 authOptions에 적용
- 최초 로그인 시 kakaoId, nickname, termsAgreedAt 자동 설정
- 닉네임 자동 생성 유틸 추가 (~하는부엉이 + 4자리 난수)
- middleware 추가: 비인증 사용자 /login 리다이렉트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: 로그인 페이지 및 인증 로직 개선

- SCSS import 절대경로(@/) 수정
- 캐릭터 이미지 Next/Image fill → img 태그로 변경
- 이용약관/개인정보처리방침 링크(/terms, /privacy) 추가 및 스타일 적용
- 닉네임 유니크 제약(@unique) 추가 및 충돌 재시도 로직 구현 (최대 10회)
- middleware matcher 패턴 보완 (/login-help 등 우회 경로 차단)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: disclaimer mixin 적용, nickname 유실 복구 및 fallback 랜덤화

- .disclaimer에 @include m.text-caption mixin 적용
- 유실된 nickname.ts 복구
- fallback 닉네임 Date.now() → 랜덤 8자리 숫자로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: 단독/1:1 판결 공통 진입 흐름 반영 및 관련 문서 일괄 수정 (#54)

- 단독 판결과 1:1 판결이 완전히 분리된 진입이 아니라
  AI 대화방 → 진술저장 → [분기] → disputes/[id]/statement 경로를 공통으로 거침
- CLAUDE.md: 핵심 서비스 흐름 분기 구조로 수정, 단독 판결 MVP 포함 반영,
  AI 대화방 정책 단독/1:1 병행 기술, dispute_status 단독 경로 추가
- PROJECT_DECISIONS.md: 흐름·MVP포함·MVP제외·dispute_status 동기화
- STATUS_TRANSITION.md: 단독 판결 경로(draft→judging→judged) 추가
- DISPUTE.md: 상태 전이 단독/1:1 경로 분리 기술, 주의사항 확정 내용 반영
- ROOM.md: 진술저장 후 분기 흐름 포함 기능에 명시

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Login 페이지 hydration removeChild 에러 수정 (#55)

* feat(common): add Button, Toast, Header, BottomNavigation components

- Button: primary / outline / disabled variants, design token 기반
- Toast: Zustand store 연동, 상단 고정, 시맨틱 컬러 토큰 적용
- Header: 뒤로가기 + title + subtitle 구조, 조건부 title centering
- BottomNavigation: 4탭(홈/사건기록/일기/마이페이지), lucide-react …
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants