From 1a8b2c6615516ff2bf86e480fc1b9f86203e5cab Mon Sep 17 00:00:00 2001 From: shinhm1 Date: Fri, 26 Jun 2026 17:32:00 +0900 Subject: [PATCH 01/25] =?UTF-8?q?fix:=20Sentry=20=EC=B4=88=EA=B8=B0?= =?UTF-8?q?=ED=99=94=20=ED=8C=8C=EC=9D=BC=20=EB=94=94=EB=A0=89=ED=86=A0?= =?UTF-8?q?=EB=A6=AC=20=EC=9C=84=EC=B9=98=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/{lib/sentry => }/instrumentation-client.ts | 0 src/{lib/sentry => }/instrumentation.ts | 0 src/{lib/sentry => }/sentry.edge.config.ts | 0 src/{lib/sentry => }/sentry.server.config.ts | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename src/{lib/sentry => }/instrumentation-client.ts (100%) rename src/{lib/sentry => }/instrumentation.ts (100%) rename src/{lib/sentry => }/sentry.edge.config.ts (100%) rename src/{lib/sentry => }/sentry.server.config.ts (100%) diff --git a/src/lib/sentry/instrumentation-client.ts b/src/instrumentation-client.ts similarity index 100% rename from src/lib/sentry/instrumentation-client.ts rename to src/instrumentation-client.ts diff --git a/src/lib/sentry/instrumentation.ts b/src/instrumentation.ts similarity index 100% rename from src/lib/sentry/instrumentation.ts rename to src/instrumentation.ts diff --git a/src/lib/sentry/sentry.edge.config.ts b/src/sentry.edge.config.ts similarity index 100% rename from src/lib/sentry/sentry.edge.config.ts rename to src/sentry.edge.config.ts diff --git a/src/lib/sentry/sentry.server.config.ts b/src/sentry.server.config.ts similarity index 100% rename from src/lib/sentry/sentry.server.config.ts rename to src/sentry.server.config.ts From 106cdf0dccec449c0c17f74103294cfd4ace3fb4 Mon Sep 17 00:00:00 2001 From: shinhm1 Date: Fri, 26 Jun 2026 18:11:24 +0900 Subject: [PATCH 02/25] =?UTF-8?q?fix:=20Sentry=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=B2=98=EB=A6=AC=20=EB=B0=8F=20?= =?UTF-8?q?=EC=BA=A1=EC=B2=98=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lib/sentry/sentry.ts | 58 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/src/lib/sentry/sentry.ts b/src/lib/sentry/sentry.ts index 198d57c..d97c735 100644 --- a/src/lib/sentry/sentry.ts +++ b/src/lib/sentry/sentry.ts @@ -59,6 +59,53 @@ const sanitizeValue = ( ) } +const getErrorMessage = (error: unknown) => { + if (error instanceof Error) { + return error.message + } + + if ( + typeof error === 'object' && + error !== null && + 'message' in error && + typeof error.message === 'string' + ) { + return error.message + } + + if (typeof error === 'string') { + return error + } + + return 'Unknown application error' +} + +const toError = (error: unknown) => { + if (error instanceof Error) { + return error + } + + return new Error(getErrorMessage(error)) +} + +const getErrorField = (error: unknown, field: string) => { + if (typeof error !== 'object' || error === null || !(field in error)) { + return undefined + } + + const value = (error as Record)[field] + + if ( + typeof value === 'string' || + typeof value === 'number' || + typeof value === 'boolean' + ) { + return value + } + + return undefined +} + export const beforeSend = (event: ErrorEvent, _hint: EventHint) => { if (event.user) { event.user = { id: event.user.id } @@ -99,14 +146,23 @@ export const captureAppError = ( }, ) => { Sentry.withScope((scope) => { + const capturedError = toError(error) + scope.setTag('action', context.action) + const errorCode = getErrorField(error, 'code') + if (errorCode !== undefined) { + scope.setTag('error.code', String(errorCode)) + } + Object.entries(context.tags ?? {}).forEach(([key, value]) => { if (value !== undefined) { scope.setTag(key, String(value)) } }) + scope.setExtra('originalError', sanitizeValue(error)) + if (context.extra) { scope.setExtras(sanitizeValue(context.extra) as Record) } @@ -115,6 +171,6 @@ export const captureAppError = ( scope.setLevel(context.level) } - Sentry.captureException(error) + Sentry.captureException(capturedError) }) } From ed5172c300f783e443ca9b4c973808a19d107e2a Mon Sep 17 00:00:00 2001 From: shinhm1 Date: Thu, 2 Jul 2026 17:40:27 +0900 Subject: [PATCH 03/25] =?UTF-8?q?fix:=20=EC=B4=88=EB=8C=80=20=EC=88=98?= =?UTF-8?q?=EB=9D=BD=20RPC=20RLS=20=EA=B6=8C=ED=95=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...60702083718_secure_invite_response_rpc.sql | 122 ++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 supabase/migrations/20260702083718_secure_invite_response_rpc.sql diff --git a/supabase/migrations/20260702083718_secure_invite_response_rpc.sql b/supabase/migrations/20260702083718_secure_invite_response_rpc.sql new file mode 100644 index 0000000..79b4730 --- /dev/null +++ b/supabase/migrations/20260702083718_secure_invite_response_rpc.sql @@ -0,0 +1,122 @@ +create or replace function public.respond_to_nbread_invite( + p_invite_token text, + p_response text +) +returns jsonb +language plpgsql +security definer +set search_path = '' +as $$ +declare + v_invite public.nbread_invite%rowtype; + v_user_id uuid := auth.uid(); + v_participant_limit integer; + v_participant_count bigint; + v_participant_inserted boolean := false; + v_already_participant boolean := false; +begin + if p_response not in ('accepted', 'rejected') then + raise exception 'INVALID_INVITE_RESPONSE'; + end if; + + -- 동일 초대에 대한 동시 응답을 직렬화해 상태 변경을 한 번만 처리한다. + select * + into v_invite + from public.nbread_invite + where invite_token = p_invite_token + for update; + + if not found then + raise exception 'INVITE_NOT_FOUND'; + end if; + + if v_invite.status = 'accepted' then + raise exception 'INVITE_ALREADY_ACCEPTED'; + elsif v_invite.status = 'rejected' then + raise exception 'INVITE_ALREADY_REJECTED'; + elsif v_invite.status = 'expired' then + raise exception 'INVITE_EXPIRED'; + end if; + + if v_user_id is null then + raise exception 'LOGIN_REQUIRED'; + end if; + + if v_invite.target_user_id is not null + and v_user_id <> v_invite.target_user_id then + raise exception 'INVITE_TARGET_MISMATCH'; + end if; + + if p_response = 'accepted' then + if v_invite.target_user_id is null then + -- 링크 초대는 수락 시점의 로그인 사용자를 초대 대상자로 연결한다. + update public.nbread_invite + set target_user_id = v_user_id + where id = v_invite.id; + + v_invite.target_user_id := v_user_id; + end if; + + select exists ( + select 1 + from public.participant + where nbread_id = v_invite.nbread_id + and user_id = v_invite.target_user_id + ) + into v_already_participant; + + if not v_already_participant then + -- 서로 다른 초대를 동시에 수락해도 정원 확인과 참여자 생성을 직렬화한다. + select participant_count + into v_participant_limit + from public.nbread + where id = v_invite.nbread_id + for update; + + if not found then + raise exception 'NBREAD_NOT_FOUND'; + end if; + + select count(*) + into v_participant_count + from public.participant + where nbread_id = v_invite.nbread_id; + + if v_participant_count >= v_participant_limit then + raise exception 'INVITE_EXPIRED'; + end if; + + -- 함수 내부 검증을 통과한 초대 응답만 참여자로 등록한다. + insert into public.participant (nbread_id, user_id, is_leader) + values (v_invite.nbread_id, v_invite.target_user_id, false) + on conflict (nbread_id, user_id) do nothing; + + v_participant_inserted := found; + end if; + end if; + + update public.nbread_invite + set status = p_response + where id = v_invite.id; + + return jsonb_build_object( + 'invite_id', v_invite.id, + 'nbread_id', v_invite.nbread_id, + 'status', p_response, + 'outcome', + case + when p_response = 'rejected' then 'rejected' + when v_participant_inserted then 'joined' + else 'already_participant' + end + ); +end; +$$; + +comment on function public.respond_to_nbread_invite(text, text) is + '초대 상태와 대상을 검증하고 RLS로 보호된 참여자 생성을 제한적으로 처리'; + +revoke execute on function public.respond_to_nbread_invite(text, text) + from public, anon; +grant execute on function public.respond_to_nbread_invite(text, text) + to authenticated; From 9b6bb90f4b76f12ec99a6e5dae49d8a05278d51d Mon Sep 17 00:00:00 2001 From: shinhm1 Date: Fri, 3 Jul 2026 02:42:20 +0900 Subject: [PATCH 04/25] =?UTF-8?q?docs:=20issue,=20pr=20=ED=85=9C=ED=94=8C?= =?UTF-8?q?=EB=A6=BF=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/ISSUE_TEMPLATE/bug_report.md | 71 +++++++++++++-- .github/ISSUE_TEMPLATE/feature_request.md | 60 +++++++++++-- .github/pull_request_template.md | 105 ++++++++++++++++++++-- .gitignore | 3 - 4 files changed, 213 insertions(+), 26 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 66e31bf..c8fe369 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -6,16 +6,73 @@ labels: '' assignees: '' --- -## 어떤 버그인가요? +## Summary -> 어떤 버그인지 간결하게 설명해주세요 +> 3줄 이내로 버그를 요약합니다. -## 어떤 상황에서 발생한 버그인가요? +--- + +## Problem + +### 어떤 문제가 발생했나요? + +- 현재 발생하는 현상 +- 사용자에게 미치는 영향 +- 발생 빈도(항상/간헐적) + +--- + +## Expected + +### 원래 어떻게 동작해야 하나요? -> (가능하면) Given-When-Then 형식으로 서술해주세요 +- 기대하는 동작 + +--- + +## Reproduction + +### 어떻게 재현할 수 있나요? + +1. +2. +3. + +--- -## 예상 결과 +## Scope + +### 영향을 받는 범위 + +- 기능 +- 페이지 +- 컴포넌트 +- API +- DB + +--- + +## Suspected Cause (Optional) + +### 예상 원인 + +- 의심되는 코드 +- 의심되는 로직 +- 확실하지 않으면 비워둠 + +--- + +## Constraints + +### 수정 시 고려할 사항 + +- 기존 동작 유지 +- 변경하면 안 되는 부분 + +--- -> 예상했던 정상적인 결과가 어떤 것이었는지 설명해주세요 +## Definition of Done -## 참고할만한 자료(선택) +- [ ] 버그 재현되지 않음 +- [ ] 기존 기능 정상 동작 +- [ ] 회귀 테스트 완료 diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 07f6d8d..c679e8d 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -6,14 +6,60 @@ labels: '' assignees: '' --- -## 어떤 기능인가요? +## Summary -> 추가하려는 기능에 대해 간결하게 설명해주세요 +> 3줄 이내로 이번 작업을 요약합니다. -## 작업 상세 내용 +--- + +## Why + +### 해결하려는 문제가 무엇인가요? + +- 현재 어떤 문제가 있는가? +- 왜 지금 해결해야 하는가? +- 해결하지 않으면 어떤 문제가 발생하는가? + +--- + +## Goal + +### 완료되면 무엇이 달라지나요? + +- 이번 작업의 목표 +- 이번 작업에서 해결하지 않는 범위(Non-goal) + +--- + +## Approach + +### 어떻게 해결할 계획인가요? + +- 전체 구현 방향 +- 주요 변경 사항 +- 검토한 대안과 선택 이유 + +--- + +## Tasks + +- [ ] Task 1 +- [ ] Task 2 +- [ ] Task 3 + +--- + +## Constraints + +- 반드시 유지해야 하는 동작 +- 변경하면 안 되는 사항 +- 기술적 제약사항 + +--- -- [ ] TODO -- [ ] TODO -- [ ] TODO +## Definition of Done -## 참고할만한 자료(선택) +- [ ] 기능 동작 확인 +- [ ] 테스트 완료 +- [ ] lint / typecheck 통과 +- [ ] 문서 업데이트 diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 435f85d..36a56fc 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,15 +1,102 @@ -## #️⃣연관된 이슈 +## Summary -> ex) #이슈번호, #이슈번호 +> 3줄 이내로 이번 PR을 요약합니다. -## 📝작업 내용 +--- -> 이번 PR에서 작업한 내용을 간략히 설명해주세요(이미지 첨부 가능) +## Why -### 스크린샷 (선택) +### 왜 이 작업을 진행했나요? -## 💬리뷰 요구사항(선택) +- 어떤 문제를 해결하기 위한 PR인가요? +- 왜 지금 필요한 작업인가요? -> 리뷰어가 특별히 봐주었으면 하는 부분이 있다면 작성해주세요 -> -> ex) 메서드 XXX의 이름을 더 잘 짓고 싶은데 혹시 좋은 명칭이 있을까요? +--- + +## Decision + +### 어떤 구현 방식을 선택했나요? + +- 선택한 구현 방식 +- 검토한 대안 +- 선택 이유 + +--- + +## Changes + +### 무엇이 변경되었나요? + +#### Feature + +- + +#### Fix + +- + +#### Refactor + +- + +#### Test + +- + +#### Docs + +- *** + +## Trade-off + +### 한계와 트레이드오프 + +- 현재 구현의 한계 +- 이후 개선 가능한 부분 + +--- + +## Impact + +### 기존 기능에 미치는 영향 + +- 영향받는 기능 +- 회귀 가능성이 있는 영역 +- 배포 시 확인할 사항 + +--- + +## Edge Cases + +### Edge Case 및 실패 시나리오 + +- 고려한 예외 상황 +- 실패 가능성이 있는 시나리오 + +--- + +## Review Points + +### 리뷰어가 집중해서 봐야 할 부분 + +#### 🔴 High + +- + +#### 🟡 Medium + +- + +#### 🟢 Low + +- *** + +## Validation + +### 어떻게 검증했나요? + +- [ ] 단위 테스트 +- [ ] E2E 테스트 +- [ ] 수동 테스트 +- [ ] lint +- [ ] typecheck diff --git a/.gitignore b/.gitignore index 4f8eb38..ada04d4 100644 --- a/.gitignore +++ b/.gitignore @@ -40,9 +40,6 @@ yarn-error.log* *.tsbuildinfo next-env.d.ts -# github -.github - # pwa public/sw.js* public/workbox-*.js* From 32a4f8b8e26898e845a92ac7ae23d7e6ce286781 Mon Sep 17 00:00:00 2001 From: shinhm1 Date: Fri, 3 Jul 2026 03:09:03 +0900 Subject: [PATCH 05/25] =?UTF-8?q?docs:=20agent.md=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AGENTS.md | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..aef83aa --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,116 @@ +# Repository Guideline + +## 프로젝트 개요 + +이 프로젝트는 구독 공유 통합 관리 서비스 **엔빵**의 프론트엔드 저장소입니다. + +- Framework: Next.js (App Router) +- Language: TypeScript (Strict Mode) +- Backend: Supabase +- State Management: Zustand +- Styling: Tailwind CSS + +--- + +## 개발 원칙 + +AI는 아래 원칙을 항상 우선적으로 따릅니다. + +- 기존 기능이 정상 동작하는 것을 최우선으로 합니다. +- 필요한 범위만 최소한으로 수정합니다. +- 큰 변경보다 작은 변경을 선호합니다. +- 추측하여 구현하지 않습니다. +- 기존 코드 스타일과 프로젝트 구조를 최대한 유지합니다. + +--- + +## 작업 방식 + +모든 개발 작업은 아래 순서를 따릅니다. + +``` +구현 설계서 + ↓ +GitHub Issue + ↓ +구현 + ↓ +Pull Request + ↓ +Code Review +``` + +- 구현 전에 작업 목적과 범위를 먼저 이해합니다. +- 하나의 Issue는 가능한 하나의 PR로 구현합니다. +- PR이 너무 커질 경우 Task 단위로 작업을 다시 분리합니다. +- 구현보다 작업 분해와 영향 범위를 먼저 검토합니다. + +--- + +## 코드 작성 규칙 + +- TypeScript Strict Mode를 유지합니다. +- `any` 사용은 지양합니다. +- 기존 프로젝트의 코드 스타일을 따릅니다. +- 새로운 구조를 만들기보다 기존 패턴을 우선 재사용합니다. +- UI 컴포넌트에서 비즈니스 로직을 직접 구현하지 않습니다. +- 기존 Helper 또는 Lib가 있다면 우선 활용합니다. + +--- + +## 테스트 + +작업 완료 후 아래 내용을 확인합니다. + +- `npm run lint` +- `npm run build` + +Playwright 테스트가 존재하는 경우 영향을 받은 기능을 함께 검증합니다. + +--- + +## Review Guidelines + +리뷰의 목적은 코드 스타일을 지적하는 것이 아니라, 변경 사항의 위험 요소와 의사결정을 검증하는 것입니다. + +리뷰 시 아래 순서를 우선합니다. + +1. Why + - 이 작업을 왜 해야 하는가? + - 지금 해결해야 하는 이유가 충분한가? + +2. Decision + - 구현 방식이 문제를 해결하는 데 적절한가? + - 더 단순하거나 안전한 대안은 없는가? + +3. Impact + - 기존 기능에 영향을 주지 않는가? + - 회귀(Regression), 데이터 정합성, 성능 저하 가능성은 없는가? + +4. Review Points + - 작성자가 지정한 위험 영역을 우선 검토한다. + +코드 스타일보다 기능 안정성과 사용자 영향도를 우선하며, P0/P1 수준의 문제에 집중합니다. + +--- + +## 보안 + +- Secret 또는 `.env` 파일은 절대 커밋하지 않습니다. +- Supabase Schema 변경 시 Type을 최신 상태로 유지합니다. +- RLS 관련 변경은 특히 신중하게 검토합니다. +- 운영 환경에서만 사용하는 설정은 유지합니다. + +--- + +## AI 작업 원칙 + +작업 시 다음 내용을 항상 명확히 설명합니다. + +- 왜 이 작업이 필요한가 +- 어떤 방식을 선택했는가 +- 어떤 대안을 검토했는가 +- 어떤 영향 범위를 가지는가 +- 어떤 리스크가 존재하는가 + +불필요한 리팩토링이나 구조 변경은 제안하지 않습니다. From 92b37d971d8c6833e4535958c18cc50e3a66e039 Mon Sep 17 00:00:00 2001 From: shinhm1 Date: Fri, 3 Jul 2026 17:13:00 +0900 Subject: [PATCH 06/25] =?UTF-8?q?docs:=20AI=20=EC=9E=91=EC=97=85=20?= =?UTF-8?q?=EC=8A=A4=ED=82=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .agents/skills/feature-issue/SKILL.md | 52 +++++++++++++++ .../references/issue-title-convention.md | 28 +++++++++ .agents/skills/pull-request/SKILL.md | 63 +++++++++++++++++++ 3 files changed, 143 insertions(+) create mode 100644 .agents/skills/feature-issue/SKILL.md create mode 100644 .agents/skills/feature-issue/references/issue-title-convention.md create mode 100644 .agents/skills/pull-request/SKILL.md diff --git a/.agents/skills/feature-issue/SKILL.md b/.agents/skills/feature-issue/SKILL.md new file mode 100644 index 0000000..ef176e1 --- /dev/null +++ b/.agents/skills/feature-issue/SKILL.md @@ -0,0 +1,52 @@ +--- +name: feature-issue +description: 구현 설계서의 Task를 바탕으로 GitHub Feature Issue를 작성합니다. +--- + +# GitHub Feature Issue + +구현 설계서의 Task를 GitHub Feature Issue로 변환합니다. + +구현 설계서를 먼저 읽고 작업의 목적과 배경을 이해한 뒤 Issue를 작성합니다. + +## 사용 시점 + +다음 상황에서 사용합니다. + +- 구현 설계서에서 GitHub Issue를 생성할 때 +- 새로운 기능 구현을 시작할 때 +- 리팩토링 작업을 시작할 때 + +다음 상황에서는 사용하지 않습니다. + +- Bug Issue 작성 +- Pull Request 작성 +- Commit Message 작성 + +--- + +## 작업 원칙 + +- 구현 설계서의 Task 하나를 하나의 GitHub Issue로 작성합니다. +- 하나의 GitHub Issue는 하나의 Pull Request로 구현 가능한 크기를 유지합니다. +- 구현 설계서의 목적과 배경을 충분히 이해한 후 Issue를 작성합니다. +- 구현 설계서에 없는 내용을 추측하여 작성하지 않습니다. +- 필요한 정보가 부족한 경우 `확인 필요`로 표시합니다. + +--- + +## 출력 형식 + +이슈를 생성할 때는 `.github/ISSUE_TEMPLATE`에 있는 `feature_request.md`를 우선 사용합니다. +별도의 템플릿을 새로 만들거나 Skill의 assets에 중복 저장하지 않습니다. + +--- + +## 품질 기준 + +Issue를 작성하기 전에 아래 내용을 확인합니다. + +- 구현 설계서의 목적을 충분히 이해했는가? +- 현재 Task가 하나의 Issue로 적절한 크기인가? +- 하나의 PR로 구현 가능한가? +- 구현 설계서에 없는 내용을 추측하지 않았는가? diff --git a/.agents/skills/feature-issue/references/issue-title-convention.md b/.agents/skills/feature-issue/references/issue-title-convention.md new file mode 100644 index 0000000..5dec5dc --- /dev/null +++ b/.agents/skills/feature-issue/references/issue-title-convention.md @@ -0,0 +1,28 @@ +## Issue 제목 규칙 + +Issue 제목은 아래 컨벤션을 따릅니다. + +```text +[{라벨}-{작업번호}/{도메인}] 이슈명 +``` + +예시 + +```text +[feature-66/react-query] React Query Provider 추가 +[refactor-67/chat] ChatRoom 책임 분리 +[performance-68/chat] 채팅 렌더링 성능 개선 +[test-69/invite] 링크 초대 E2E 테스트 추가 +``` + +제목 생성 규칙은 다음과 같습니다. + +- `{라벨}`은 현재 레포지토리에 등록된 GitHub Label의 영문 이름을 그대로 사용합니다. +- `{작업번호}`는 **GitHub Issue 번호가 아닌 프로젝트 작업번호**입니다. +- 기존 Issue 제목의 컨벤션을 참고하여 가장 최근 작업번호를 찾고, 다음 번호를 사용합니다. +- `{도메인}`은 작업 대상이 되는 기능 또는 영역을 대표하는 영문 키워드를 사용합니다. (예: `chat`, `invite`, `auth`, `react-query`) +- `이슈명`은 작업 내용을 이해하기 쉬운 한국어로 작성합니다. + +작업번호는 GitHub Issue 번호와 별도로 관리되는 프로젝트 번호이며, 반드시 기존 Issue 제목을 참고하여 연속성을 유지합니다. + +--- diff --git a/.agents/skills/pull-request/SKILL.md b/.agents/skills/pull-request/SKILL.md new file mode 100644 index 0000000..489d98c --- /dev/null +++ b/.agents/skills/pull-request/SKILL.md @@ -0,0 +1,63 @@ +--- +name: pull-request +description: GitHub Issue와 Git diff를 바탕으로 사람이 빠르게 이해할 수 있는 Pull Request를 작성합니다. +--- + +# Pull Request + +프로젝트의 GitHub Pull Request Template에 맞춰 Pull Request를 작성합니다. + +Pull Request는 변경 내역이 아니라 **의사결정 문서**입니다. + +## 사용 시점 + +다음 상황에서 사용합니다. + +- GitHub Issue 구현이 완료되었을 때 +- Pull Request를 생성할 때 +- 변경 사항, 영향 범위, 리뷰 포인트를 정리할 때 + +다음 상황에서는 사용하지 않습니다. + +- GitHub Issue 작성 +- Commit Message 작성 +- Bug Report 작성 + +--- + +## 작업 원칙 + +- 하나의 GitHub Issue는 하나의 Pull Request로 구현합니다. +- 연결된 GitHub Issue의 Why, Goal, Constraints를 먼저 이해한 후 Pull Request를 작성합니다. +- Git diff를 확인하여 실제 변경 사항만 작성합니다. +- PR 본문은 한국어로 작성합니다. +- PR은 `Why → Decision → Changes → Impact → Review Points → Validation` 흐름으로 작성합니다. +- 변경 사항을 나열하기보다 왜 그렇게 구현했는지 설명합니다. +- 확인하지 않은 테스트는 실행했다고 작성하지 않습니다. +- 불확실한 내용은 `확인 필요`로 표시합니다. +- 리뷰어가 집중해서 봐야 할 위험 영역을 명확히 표시합니다. +- Review Points는 가능하면 3개 이내로 제한합니다. +- 연결된 GitHub Issue가 없다면 먼저 Issue 생성을 제안합니다. + +--- + +## 출력 형식 + +프로젝트의 `.github/pull_request_template.md`를 사용합니다. + +Pull Request 제목은 연결된 GitHub Issue 제목과 동일하게 작성합니다. + +별도의 템플릿을 생성하거나 Skill의 `assets`에 중복 저장하지 않습니다. + +--- + +## 품질 기준 + +PR을 작성하기 전에 아래 내용을 확인합니다. + +- 관련 Issue의 Why와 Goal이 PR에 반영되었는가? +- 구현 방식의 선택 이유가 설명되어 있는가? +- 실제 Git diff에 없는 내용을 작성하지 않았는가? +- 기존 기능에 미치는 영향이 정리되었는가? +- 한계와 트레이드오프가 있다면 명시했는가? +- Review Points와 Validation이 실제 구현 내용과 일치하는가? From d2e8829950971549fcea284304baeb97280ff5a6 Mon Sep 17 00:00:00 2001 From: shinhm1 Date: Fri, 3 Jul 2026 17:23:10 +0900 Subject: [PATCH 07/25] =?UTF-8?q?docs:=20AI=20=EA=B0=9C=EB=B0=9C=20?= =?UTF-8?q?=EC=9B=8C=ED=81=AC=ED=94=8C=EB=A1=9C=EC=9A=B0=20=EB=AC=B8?= =?UTF-8?q?=EC=84=9C=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .agents/skills/workflow.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .agents/skills/workflow.md diff --git a/.agents/skills/workflow.md b/.agents/skills/workflow.md new file mode 100644 index 0000000..6566bcd --- /dev/null +++ b/.agents/skills/workflow.md @@ -0,0 +1,31 @@ +# AI Workflow + +## 전체 흐름 + +구현 설계서 → GitHub Issue → Codex 구현 → Commit → Pull Request → Codex Review → Merge + +## 역할 분리 + +- ChatGPT: 구현 설계서 작성, Task 분해, Issue 초안 작성 +- Codex: Issue 구현, Commit, Pull Request 작성, Code Review 대응 +- GitHub: Issue / PR / Review 관리 +- Notion: 구현 설계서 관리 + +## 원칙 + +- 구현 설계서의 Task 1개는 GitHub Issue 1개로 변환한다. +- GitHub Issue 1개는 Pull Request 1개로 구현한다. +- Pull Request 제목은 연결된 Issue 제목과 동일하게 작성한다. +- PR은 변경사항 나열이 아니라 의사결정 문서로 작성한다. +- Codex Review는 P0/P1 수준의 위험 요소를 확인하는 용도로 사용한다. + +## 작업 순서 + +1. Notion에서 구현 설계서를 작성한다. +2. 구현 설계서의 Task를 기준으로 GitHub Issue를 생성한다. +3. Codex가 Issue 단위로 구현한다. +4. 변경 사항을 논리적인 작업 단위로 Commit한다. +5. Issue 제목과 동일한 제목으로 PR을 생성한다. +6. `@codex review`로 리뷰를 요청한다. +7. 필요 시 `@codex fix`로 수정 작업을 요청한다. +8. 최종 확인 후 Merge한다. From 9c2c3b958c567153e306212a0f5260a9ef270767 Mon Sep 17 00:00:00 2001 From: shinhm1 Date: Fri, 3 Jul 2026 17:31:37 +0900 Subject: [PATCH 08/25] =?UTF-8?q?docs:=20GitHub=20=EB=A9=94=ED=83=80?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=84=A4=EC=A0=95=20=EA=B7=9C?= =?UTF-8?q?=EC=B9=99=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .agents/skills/feature-issue/SKILL.md | 13 +++++++++++++ .agents/skills/pull-request/SKILL.md | 11 +++++++++++ 2 files changed, 24 insertions(+) diff --git a/.agents/skills/feature-issue/SKILL.md b/.agents/skills/feature-issue/SKILL.md index ef176e1..4a8ac93 100644 --- a/.agents/skills/feature-issue/SKILL.md +++ b/.agents/skills/feature-issue/SKILL.md @@ -35,6 +35,19 @@ description: 구현 설계서의 Task를 바탕으로 GitHub Feature Issue를 --- +## GitHub 설정 + +Issue를 생성할 때 아래 설정을 함께 적용합니다. + +- Assignee는 `hm1n`으로 고정합니다. +- Label은 Issue 제목의 라벨과 동일한 GitHub Label을 추가합니다. + - 예: Issue 제목이 `[setting-66/ai-agent] Agent 주도 개발 환경 도입`이면 `Setting` 라벨을 추가합니다. + - Issue 제목의 라벨이 GitHub Label과 정확히 일치하지 않으면, 기존 Label 목록에서 의미가 같은 라벨을 확인해 사용합니다. +- Project는 `KANBAN`으로 지정합니다. +- Project Status는 `TO-DO`로 지정합니다. + +--- + ## 출력 형식 이슈를 생성할 때는 `.github/ISSUE_TEMPLATE`에 있는 `feature_request.md`를 우선 사용합니다. diff --git a/.agents/skills/pull-request/SKILL.md b/.agents/skills/pull-request/SKILL.md index 489d98c..a5c5ffd 100644 --- a/.agents/skills/pull-request/SKILL.md +++ b/.agents/skills/pull-request/SKILL.md @@ -41,6 +41,17 @@ Pull Request는 변경 내역이 아니라 **의사결정 문서**입니다. --- +## GitHub 설정 + +PR을 생성할 때 아래 설정을 함께 적용합니다. + +- Assignee는 `hm1n`으로 고정합니다. +- Label은 PR 제목의 라벨과 동일한 GitHub Label을 추가합니다. + - 예: PR 제목이 `[setting-66/ai-agent] Agent 주도 개발 환경 도입`이면 `Setting` 라벨을 추가합니다. + - PR 제목의 라벨이 GitHub Label과 정확히 일치하지 않으면, 기존 Label 목록에서 의미가 같은 라벨을 확인해 사용합니다. + +--- + ## 출력 형식 프로젝트의 `.github/pull_request_template.md`를 사용합니다. From ade2d062714729432854acdacbfc38e03778bc1f Mon Sep 17 00:00:00 2001 From: shinhm1 Date: Thu, 9 Jul 2026 15:59:57 +0900 Subject: [PATCH 09/25] =?UTF-8?q?feat:=20=EA=B3=B5=EA=B0=9C=20=EB=9E=9C?= =?UTF-8?q?=EB=94=A9=ED=8E=98=EC=9D=B4=EC=A7=80=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/image/landing/home.png | Bin 0 -> 28849 bytes src/app/home/page.tsx | 113 +++++++ src/app/nbread/preview/page.tsx | 2 +- src/app/page.tsx | 434 ++++++++++++++++++------- src/app/protectRoute.tsx | 10 +- src/assets/icons/search.svg | 9 +- src/components/home/Header.tsx | 2 +- src/components/nbread/NbreadDetail.tsx | 4 +- src/lib/authRedirect.ts | 6 +- tailwind.config.ts | 4 +- 10 files changed, 464 insertions(+), 120 deletions(-) create mode 100644 public/image/landing/home.png create mode 100644 src/app/home/page.tsx diff --git a/public/image/landing/home.png b/public/image/landing/home.png new file mode 100644 index 0000000000000000000000000000000000000000..f7348518441fc18bd65745051e203f04aba33503 GIT binary patch literal 28849 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 Eg74S=Jpcdz literal 0 HcmV?d00001 diff --git a/src/app/home/page.tsx b/src/app/home/page.tsx new file mode 100644 index 0000000..5da6e5b --- /dev/null +++ b/src/app/home/page.tsx @@ -0,0 +1,113 @@ +'use client' +import { useEffect, useState } from 'react' +import { getUserNbreads } from '@/lib/nbread' +import Header from '@/components/home/Header' +import MonthlyNbread from '@/components/home/MonthlyNbread' +import MyNbread from '@/components/home/MyNbread' +import { Nbread } from '@/types/nbread' +import useUserStore from '@/stores/useAuthStore' +import { getParticipants } from '@/lib/participant' +import Spinner from '@/components/common/spinner/Spinner' +import NotificationPermissionModal from '@/components/common/modal/NotificationPermissionModal' +import NotificationDeniedModal from '@/components/common/modal/NotificationDeniedModal' +import ReceivedInviteBanner from '@/components/home/ReceivedInviteBanner' +import { getPendingInvites } from '@/lib/invite/getPendingInvites' +import type { PendingInvite } from '@/lib/invite/getPendingInvites' + +// [ ] OS 알림 허용 후 모달 닫힘 +// [ ] OS 알림 허용 상태 확인해서 모달 열기 + +const HomePage = () => { + const user = useUserStore((state) => state.user) + const [monthlyNbreadList, setMonthlyNbreadList] = useState([]) + const [myNbreadList, setMyNbreadList] = useState([]) + const [pendingInvites, setPendingInvites] = useState([]) + const [totalAmount, setTotalAmount] = useState(0) + const [isLoading, setIsLoading] = useState(true) + const [isNotificationDeniedModalOpen, setIsNotificationDeniedModalOpen] = + useState(false) + const currentMonth = new Date().getMonth() + 1 + + // Nbread 및 Participant 정보를 DB로부터 fetch + const fetchNbreads = async (userId: string) => { + try { + const [{ monthlyNbreads, myNbreads }, invites] = await Promise.all([ + getUserNbreads(userId), + // 초대 조회 실패가 기존 홈 엔빵 조회까지 막지 않도록 빈 목록으로 처리한다. + getPendingInvites(userId).catch(() => []), + ]) + + const myNbreadsWithParticipants = await Promise.all( + myNbreads.map(async (nbread) => { + const participants = await getParticipants(nbread.id) + return { ...nbread, participants } + }), + ) + const nbreadsById = new Map( + myNbreadsWithParticipants.map((nbread) => [nbread.id, nbread]), + ) + const monthlyNbreadsWithParticipants = monthlyNbreads.map( + (nbread) => nbreadsById.get(nbread.id) ?? nbread, + ) + + setMonthlyNbreadList(monthlyNbreadsWithParticipants) + setMyNbreadList(myNbreadsWithParticipants) + setPendingInvites(invites) + } catch { + setMonthlyNbreadList([]) + setMyNbreadList([]) + setPendingInvites([]) + } finally { + setIsLoading(false) + } + } + + useEffect(() => { + if (!user) return + fetchNbreads(user.id) + // testSendPaymentNotification() + // test() + }, [user]) + + // NbreadList가 업데이트된 후 totalAmount 계산 + useEffect(() => { + const total = monthlyNbreadList.reduce( + (sum: number, nbread: Nbread) => + sum + Math.floor(nbread.amount / Math.max(nbread.participantCount, 1)), + 0, + ) + setTotalAmount(total) + }, [monthlyNbreadList]) + + return ( +
+
+
+ {isLoading ? ( + + ) : ( + <> + + + + + )} +
+ {/* iOS 알림 권한 요청 모달 */} + setIsNotificationDeniedModalOpen(true)} + /> + setIsNotificationDeniedModalOpen(false)} + /> +
+ ) +} + +export default HomePage diff --git a/src/app/nbread/preview/page.tsx b/src/app/nbread/preview/page.tsx index 25b6828..1661f8b 100644 --- a/src/app/nbread/preview/page.tsx +++ b/src/app/nbread/preview/page.tsx @@ -55,7 +55,7 @@ const Page = () => { clearNbread() setPreviewNbreadData(null) useToast.success('엔빵 만들기에 성공했어요.') - router.push('/') + router.push('/home') } catch (error) { useToast.error('엔빵 만들기에 실패했어요. 다시 시도해주세요.') console.error(error) diff --git a/src/app/page.tsx b/src/app/page.tsx index 5da6e5b..b6484a3 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,113 +1,329 @@ -'use client' -import { useEffect, useState } from 'react' -import { getUserNbreads } from '@/lib/nbread' -import Header from '@/components/home/Header' -import MonthlyNbread from '@/components/home/MonthlyNbread' -import MyNbread from '@/components/home/MyNbread' -import { Nbread } from '@/types/nbread' -import useUserStore from '@/stores/useAuthStore' -import { getParticipants } from '@/lib/participant' -import Spinner from '@/components/common/spinner/Spinner' -import NotificationPermissionModal from '@/components/common/modal/NotificationPermissionModal' -import NotificationDeniedModal from '@/components/common/modal/NotificationDeniedModal' -import ReceivedInviteBanner from '@/components/home/ReceivedInviteBanner' -import { getPendingInvites } from '@/lib/invite/getPendingInvites' -import type { PendingInvite } from '@/lib/invite/getPendingInvites' - -// [ ] OS 알림 허용 후 모달 닫힘 -// [ ] OS 알림 허용 상태 확인해서 모달 열기 - -const HomePage = () => { - const user = useUserStore((state) => state.user) - const [monthlyNbreadList, setMonthlyNbreadList] = useState([]) - const [myNbreadList, setMyNbreadList] = useState([]) - const [pendingInvites, setPendingInvites] = useState([]) - const [totalAmount, setTotalAmount] = useState(0) - const [isLoading, setIsLoading] = useState(true) - const [isNotificationDeniedModalOpen, setIsNotificationDeniedModalOpen] = - useState(false) - const currentMonth = new Date().getMonth() + 1 - - // Nbread 및 Participant 정보를 DB로부터 fetch - const fetchNbreads = async (userId: string) => { - try { - const [{ monthlyNbreads, myNbreads }, invites] = await Promise.all([ - getUserNbreads(userId), - // 초대 조회 실패가 기존 홈 엔빵 조회까지 막지 않도록 빈 목록으로 처리한다. - getPendingInvites(userId).catch(() => []), - ]) - - const myNbreadsWithParticipants = await Promise.all( - myNbreads.map(async (nbread) => { - const participants = await getParticipants(nbread.id) - return { ...nbread, participants } - }), - ) - const nbreadsById = new Map( - myNbreadsWithParticipants.map((nbread) => [nbread.id, nbread]), - ) - const monthlyNbreadsWithParticipants = monthlyNbreads.map( - (nbread) => nbreadsById.get(nbread.id) ?? nbread, - ) - - setMonthlyNbreadList(monthlyNbreadsWithParticipants) - setMyNbreadList(myNbreadsWithParticipants) - setPendingInvites(invites) - } catch { - setMonthlyNbreadList([]) - setMyNbreadList([]) - setPendingInvites([]) - } finally { - setIsLoading(false) - } - } - - useEffect(() => { - if (!user) return - fetchNbreads(user.id) - // testSendPaymentNotification() - // test() - }, [user]) - - // NbreadList가 업데이트된 후 totalAmount 계산 - useEffect(() => { - const total = monthlyNbreadList.reduce( - (sum: number, nbread: Nbread) => - sum + Math.floor(nbread.amount / Math.max(nbread.participantCount, 1)), - 0, - ) - setTotalAmount(total) - }, [monthlyNbreadList]) +import Link from 'next/link' +import Image from 'next/image' +import type { ReactNode } from 'react' +import Icon, { type IconType } from '@/components/common/icon/Icon' +import NbreadsImage from '@/components/common/nbreadImage/NbreadsImage' +import NbreadLogo from '@/assets/logo/nbread-logo-text.svg' +const painCards: { + icon: IconType + title: string + description: string +}[] = [ + { + icon: 'warning', + title: '어디서 얼마 내는지 기억이 안 나요', + description: + '넷플릭스, 유튜브, 왓챠, 라프텔... 공유 중인 구독이 많아질수록 어디서 얼마를 내는지 헷갈리기 시작해요.', + }, + { + icon: 'calendar', + title: '결제일을 깜빡해서 구독 취소된 적 있어요', + description: + '매번 결제일을 따로 확인해야 해서 놓치기 쉬워요. 자동으로 정리된 결제 흐름이 필요해요.', + }, + { + icon: 'search', + title: '누가 얼마 보냈는지 일일이 확인해야 해요', + description: + '카카오페이 내역, 계좌 이체 내역, 메시지 내용을 뒤져야 하는 정산 확인. 그 번거로움이 싫어서 그냥 포기하게 돼요.', + }, +] + +const solutionPoints = [ + { + title: '그룹 단위 관리', + description: + '구독 서비스별로 그룹을 만들고, 결제 정보를 체계적으로 정리할 수 있어요.', + }, + { + title: '1/N 정산 계산기', + description: '인원 수에 맞게 자동으로 나눠진 금액을 바로 확인할 수 있어요.', + }, + { + title: '정산 현황 추적', + description: + '누가 정산을 완료했는지, 완료하지 않았는지 실시간으로 한 눈에 확인할 수 있어요.', + }, +] + +const featureCards: { + icon: string + title: string + description: string + wide?: boolean +}[] = [ + { + icon: '👥', + title: '그룹 관리', + description: '구독 서비스별로\n그룹을 만들고\n멤버와 월 요금을\n한 눈에', + }, + { + icon: '🔗', + title: '간편 초대', + description: `초대 링크만\n카톡으로 보내면\n누구나 쉽게\n초대 가능`, + }, + { + icon: '✅', + title: '정산 추적', + description: '참여 중인 사람들이\n모두 냈는지\n정산 여부\n바로 확인 가능', + }, + { + icon: '📢', + title: '채팅 및 공지', + description: '계정 정보나\n중요한 공지를\n채팅과 게시글로\n간편하게 공유', + }, + { + icon: '🔔', + title: '주요 알림', + description: + '결제일 알림, 결제 완료 알림, 채팅 알림 등 정산에 관한 중요 정보 푸시 알림', + wide: true, + }, +] + +const steps = [ + { + label: 'STEP 1', + title: '그룹 만들기', + description: + '구독 서비스 이름, 월/연 요금, 결제일만 입력하면 1분만에 그룹을 만들 수 있어요.', + }, + { + label: 'STEP 2', + title: '멤버 초대하기', + description: + '초대 링크를 카톡으로 공유해 멤버를 초대해보세요. 자동으로 1/N 금액이 계산돼요.', + }, + { + label: 'STEP 3', + title: '정산 현황 확인', + description: + '정산을 완료한 멤버는 정산 완료를 직접 체크해요. 그룹장이 직접 체크할 수도 있어요.', + }, +] + +const SectionHeading = ({ + eyebrow, + title, +}: { + eyebrow: string + title: ReactNode +}) => ( +
+

{eyebrow}

+

+ {title} +

+
+) + +export default function LandingPage() { return ( -
-
-
- {isLoading ? ( - - ) : ( - <> - - - - - )} -
- {/* iOS 알림 권한 요청 모달 */} - setIsNotificationDeniedModalOpen(true)} - /> - setIsNotificationDeniedModalOpen(false)} - /> -
+
+
+
+ + + 시작하기 + +
+ +
+

+ 구독 나눔, 이제 쉽게 +

+

+ 구독 공유, +
+ 헷갈리게 쓰지 말고 +
+ 엔빵으로 딱 정리 +

+

+ 넷플릭스, 유튜브 프리미엄, 왓챠 등 친구, 가족과 나누는 구독 서비스의 + 결제일과 정산 현황을 한 곳에서 관리할 수 있어요. +

+
+ + + 지금 시작하기 → + + + 엔빵 홈 화면 미리보기 +
+ +
+
+

+ 이런 경험 있으신가요? +

+
+

+ 매달 반복되는 +
+ 정산하기 +

+

+ 구독 공유는 편리하지만, +
+ 매달 정산이 번거롭고 헷갈려요. +

+ +
+ {painCards.map((card) => ( +
+ +

+ {card.title} +

+

+ {card.description} +

+
+ ))} +
+
+ +
+ + 구독 공유의 모든 것을 +
한 곳에서 + + } + /> +

+ 그룹 생성, 친구 초대, 이달의 구독료 정산까지 엔빵에서 모두 끝낼 수 + 있어요. +

+ +
+ {solutionPoints.map((point, index) => ( +
+
+ +

{point.title}

+
+

+ {point.description} +

+
+ ))} +
+
+ +
+ + 불필요한 건 빼고 +
+ 필요한 것만 넣었어요 + + } + /> +

+ 구독 공유에 필요한 기능만 모았어요. +

+ +
+ {featureCards.map((feature) => ( +
+

+ {feature.icon} + {feature.title} +

+

+ {feature.description} +

+
+ ))} +
+
+ +
+ + 3단계로 +
+ 바로 시작하기 + + } + /> +

+ 복잡한 설정 필요 없이 +
+ 3단계면 충분해요. +

+ +
+ {steps.map((step, index) => ( +
+

{step.label}

+

+ {step.title} +

+

+ {step.description} +

+
+ ))} +
+
+ +
+
+ +
+

+ 지금 바로 시작하고 +
+ 정산 스트레스에서 벗어나세요 +

+ + 지금 시작하기 → + +
+
) } - -export default HomePage diff --git a/src/app/protectRoute.tsx b/src/app/protectRoute.tsx index 6c66166..1cfa4c5 100644 --- a/src/app/protectRoute.tsx +++ b/src/app/protectRoute.tsx @@ -11,7 +11,15 @@ import { } from '@/lib/termsAgreement' import { hasPersistedUser } from '@/lib/authStorage' -const publicRoutes = ['/login', '/auth/callback', '/terms-agreement'] +const publicRoutes = [ + '/', + '/login', + '/auth/callback', + '/terms-agreement', + '/terms-of-service', + '/privacy-policy', + '/ios-guide', +] const termsAgreementExemptRoutes = [ ...publicRoutes, '/terms-of-service', diff --git a/src/assets/icons/search.svg b/src/assets/icons/search.svg index 1b196c0..d55ed12 100644 --- a/src/assets/icons/search.svg +++ b/src/assets/icons/search.svg @@ -1,3 +1,10 @@ - + + + + + + + + diff --git a/src/components/home/Header.tsx b/src/components/home/Header.tsx index bd6bb9c..e2643d3 100644 --- a/src/components/home/Header.tsx +++ b/src/components/home/Header.tsx @@ -34,7 +34,7 @@ const Header = () => { return (
-
router.replace('/')}> +
router.replace('/home')}>
diff --git a/src/components/nbread/NbreadDetail.tsx b/src/components/nbread/NbreadDetail.tsx index 1d77981..4b46693 100644 --- a/src/components/nbread/NbreadDetail.tsx +++ b/src/components/nbread/NbreadDetail.tsx @@ -89,7 +89,7 @@ const nbreadDetail = ({ nbreadData, setNbreadData }: nbreadDetailProps) => { await deleteNbread(nbreadId) setIsNbreadDeleteModalOpen(false) useToast.success('엔빵이 삭제되었어요.') - router.push('/') + router.push('/home') } catch (error) { console.error(error) useToast.error('엔빵 삭제에 실패했어요. 다시 시도해주세요.') @@ -117,7 +117,7 @@ const nbreadDetail = ({ nbreadData, setNbreadData }: nbreadDetailProps) => { await deleteParticipants(userData?.id!, nbreadData!.id) setIsQuitNbreadModalOpen(false) useToast.success('엔빵 나가기에 성공했어요.') - router.replace('/') + router.replace('/home') } catch (error) { useToast.success('엔빵 나가기에 실패했어요.') } diff --git a/src/lib/authRedirect.ts b/src/lib/authRedirect.ts index 5985440..e19032b 100644 --- a/src/lib/authRedirect.ts +++ b/src/lib/authRedirect.ts @@ -1,4 +1,4 @@ -const DEFAULT_REDIRECT_PATH = '/' +const DEFAULT_REDIRECT_PATH = '/home' export const getSafeRedirectPath = (next: string | null | undefined) => { if (!next) { @@ -12,8 +12,8 @@ export const getSafeRedirectPath = (next: string | null | undefined) => { return DEFAULT_REDIRECT_PATH } - // 현재 로그인 후 리다이렉트는 토큰 초대 페이지 경로만 허용한다. - const isAllowedPath = next.startsWith('/invite/') + // 현재 로그인 후 리다이렉트는 홈과 토큰 초대 페이지 경로만 허용한다. + const isAllowedPath = next === '/home' || next.startsWith('/invite/') if (!isAllowedPath) { return DEFAULT_REDIRECT_PATH diff --git a/tailwind.config.ts b/tailwind.config.ts index cfcda8f..237d5e3 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -67,8 +67,8 @@ export default { }, /* box shadow */ boxShadow: { - avatar: '0px 0px 1px rgba(0,0,0,0.12))', - card: '0px 0px 4px rgba(0,0,0,0.12))', + avatar: '0px 0px 1px rgba(0,0,0,0.12)', + card: '0px 0px 4px rgba(0,0,0,0.12)', modal: '0px 0px 8px rgba(0,0,0,0.12)', }, }, From 526e98f012968174d0c4c175534a763220cedf2e Mon Sep 17 00:00:00 2001 From: shinhm1 Date: Thu, 9 Jul 2026 16:00:19 +0900 Subject: [PATCH 10/25] =?UTF-8?q?feat:=20=EA=B2=80=EC=83=89=EC=97=94?= =?UTF-8?q?=EC=A7=84=20=ED=81=AC=EB=A1=A4=EB=A7=81=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- next-sitemap.config.js | 4 ++++ public/robots.txt | 2 ++ public/sitemap-0.xml | 9 ++++----- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/next-sitemap.config.js b/next-sitemap.config.js index 9657d56..53eee60 100644 --- a/next-sitemap.config.js +++ b/next-sitemap.config.js @@ -9,8 +9,10 @@ module.exports = { '/auth/*', '/calendar', '/friendList', + '/home', '/icon.ico', '/inviteAccept', + '/invites', '/manifest.json', '/mypage', '/mypage/*', @@ -30,7 +32,9 @@ module.exports = { '/auth/', '/calendar', '/friendList', + '/home', '/inviteAccept', + '/invites', '/mypage', '/nbread/', '/notification', diff --git a/public/robots.txt b/public/robots.txt index 223dccc..4ed5a42 100644 --- a/public/robots.txt +++ b/public/robots.txt @@ -7,7 +7,9 @@ User-agent: * Disallow: /auth/ Disallow: /calendar Disallow: /friendList +Disallow: /home Disallow: /inviteAccept +Disallow: /invites Disallow: /mypage Disallow: /nbread/ Disallow: /notification diff --git a/public/sitemap-0.xml b/public/sitemap-0.xml index 1ada202..4c34b5c 100644 --- a/public/sitemap-0.xml +++ b/public/sitemap-0.xml @@ -1,8 +1,7 @@ -https://nbread-nbread.vercel.app/ios-guide2026-06-04T11:49:35.254Zweekly0.7 -https://nbread-nbread.vercel.app/terms-of-service2026-06-04T11:49:35.257Zweekly0.7 -https://nbread-nbread.vercel.app2026-06-04T11:49:35.257Zweekly0.7 -https://nbread-nbread.vercel.app/privacy-policy2026-06-04T11:49:35.257Zweekly0.7 -https://nbread-nbread.vercel.app/login2026-06-04T11:49:35.257Zweekly0.7 +https://nbread-nbread.vercel.app/ios-guide2026-07-08T09:43:41.344Zweekly0.7 +https://nbread-nbread.vercel.app2026-07-08T09:43:41.347Zweekly0.7 +https://nbread-nbread.vercel.app/privacy-policy2026-07-08T09:43:41.347Zweekly0.7 +https://nbread-nbread.vercel.app/terms-of-service2026-07-08T09:43:41.347Zweekly0.7 \ No newline at end of file From 7fa013c050a40a3ffe3b58ef77d6d3afea18655e Mon Sep 17 00:00:00 2001 From: shinhm1 Date: Thu, 9 Jul 2026 16:03:57 +0900 Subject: [PATCH 11/25] =?UTF-8?q?fix:=20=EB=9E=9C=EB=94=A9=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=ED=99=88=20=ED=99=94=EB=A9=B4=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=20=EA=B3=A0=ED=99=94=EC=A7=88=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/image/landing/home.png | Bin 28849 -> 122316 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/public/image/landing/home.png b/public/image/landing/home.png index f7348518441fc18bd65745051e203f04aba33503..90d15ac322b0c722d17683c8946efc8563957e51 100644 GIT binary patch literal 122316 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 Eg74S=Jpcdz From c8e78386a39672ed582a34b5558984ef77131fe3 Mon Sep 17 00:00:00 2001 From: shinhm1 Date: Thu, 9 Jul 2026 16:18:31 +0900 Subject: [PATCH 12/25] =?UTF-8?q?feat:=20=EB=9E=9C=EB=94=A9=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EC=8A=A4=ED=81=AC=EB=A1=A4=20=EC=95=A0?= =?UTF-8?q?=EB=8B=88=EB=A9=94=EC=9D=B4=EC=85=98=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/page.tsx | 215 ++++++++++++---------- src/components/landing/RevealOnScroll.tsx | 75 ++++++++ 2 files changed, 195 insertions(+), 95 deletions(-) create mode 100644 src/components/landing/RevealOnScroll.tsx diff --git a/src/app/page.tsx b/src/app/page.tsx index b6484a3..ffd8659 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -3,6 +3,7 @@ import Image from 'next/image' import type { ReactNode } from 'react' import Icon, { type IconType } from '@/components/common/icon/Icon' import NbreadsImage from '@/components/common/nbreadImage/NbreadsImage' +import RevealOnScroll from '@/components/landing/RevealOnScroll' import NbreadLogo from '@/assets/logo/nbread-logo-text.svg' const painCards: { @@ -132,7 +133,7 @@ export default function LandingPage() {
-
+

구독 나눔, 이제 쉽게

@@ -147,47 +148,55 @@ export default function LandingPage() { 넷플릭스, 유튜브 프리미엄, 왓챠 등 친구, 가족과 나누는 구독 서비스의 결제일과 정산 현황을 한 곳에서 관리할 수 있어요.

-
+ - - 지금 시작하기 → - + + + 지금 시작하기 → + + - 엔빵 홈 화면 미리보기 + + 엔빵 홈 화면 미리보기 +
-
-

- 이런 경험 있으신가요? + +

+

+ 이런 경험 있으신가요? +

+
+

+ 매달 반복되는 +
+ 정산하기 +

+

+ 구독 공유는 편리하지만, +
+ 매달 정산이 번거롭고 헷갈려요.

-
-

- 매달 반복되는 -
- 정산하기 -

-

- 구독 공유는 편리하지만, -
- 매달 정산이 번거롭고 헷갈려요. -

+
- {painCards.map((card) => ( -
( + {card.description}

-
+ ))}
- - 구독 공유의 모든 것을 -
한 곳에서 - - } - /> -

- 그룹 생성, 친구 초대, 이달의 구독료 정산까지 엔빵에서 모두 끝낼 수 - 있어요. -

+ + + 구독 공유의 모든 것을 +
한 곳에서 + + } + /> +

+ 그룹 생성, 친구 초대, 이달의 구독료 정산까지 엔빵에서 모두 끝낼 수 + 있어요. +

+
-
+ {solutionPoints.map((point, index) => (
@@ -238,31 +252,35 @@ export default function LandingPage() {

))} -
+
- - 불필요한 건 빼고 -
- 필요한 것만 넣었어요 - - } - /> -

- 구독 공유에 필요한 기능만 모았어요. -

+ + + 불필요한 건 빼고 +
+ 필요한 것만 넣었어요 + + } + /> +

+ 구독 공유에 필요한 기능만 모았어요. +

+
- {featureCards.map((feature) => ( -
( +

{feature.icon} @@ -271,29 +289,34 @@ export default function LandingPage() {

{feature.description}

-

+ ))}
- - 3단계로 -
- 바로 시작하기 - - } - /> -

- 복잡한 설정 필요 없이 -
- 3단계면 충분해요. -

+ + + 3단계로 +
+ 바로 시작하기 + + } + /> +

+ 복잡한 설정 필요 없이 +
+ 3단계면 충분해요. +

+
-
+ {steps.map((step, index) => (

{step.label}

@@ -305,24 +328,26 @@ export default function LandingPage() {

))} -
+
-
- -
-

- 지금 바로 시작하고 -
- 정산 스트레스에서 벗어나세요 -

- - 지금 시작하기 → - + +
+ +
+

+ 지금 바로 시작하고 +
+ 정산 스트레스에서 벗어나세요 +

+ + 지금 시작하기 → + +
) diff --git a/src/components/landing/RevealOnScroll.tsx b/src/components/landing/RevealOnScroll.tsx new file mode 100644 index 0000000..a99815b --- /dev/null +++ b/src/components/landing/RevealOnScroll.tsx @@ -0,0 +1,75 @@ +'use client' + +import { + type CSSProperties, + type ElementType, + type ReactNode, + useEffect, + useRef, + useState, +} from 'react' + +type RevealOnScrollProps = { + as?: ElementType + children: ReactNode + className?: string + delay?: number + threshold?: number +} + +const RevealOnScroll = ({ + as: Component = 'div', + children, + className = '', + delay = 0, + threshold = 0.18, +}: RevealOnScrollProps) => { + const [isVisible, setIsVisible] = useState(false) + const ref = useRef(null) + + useEffect(() => { + const element = ref.current + + if (!element) return + + if (!('IntersectionObserver' in window)) { + setIsVisible(true) + return + } + + const observer = new IntersectionObserver( + ([entry]) => { + if (!entry.isIntersecting) return + + setIsVisible(true) + observer.unobserve(entry.target) + }, + { + rootMargin: '0px 0px -8% 0px', + threshold, + }, + ) + + observer.observe(element) + + return () => { + observer.disconnect() + } + }, [threshold]) + + const transitionClass = isVisible + ? 'translate-y-0 opacity-100' + : 'translate-y-18 opacity-0' + + return ( + + {children} + + ) +} + +export default RevealOnScroll From 934761a56b68e63e893b5bc1a9d0cd15fa4ebb1d Mon Sep 17 00:00:00 2001 From: shinhm1 Date: Thu, 9 Jul 2026 23:11:30 +0900 Subject: [PATCH 13/25] =?UTF-8?q?fix:=20=EB=B9=84=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=9D=B8=20=EB=B3=B4=ED=98=B8=20=EA=B2=BD=EB=A1=9C=20=EB=9E=9C?= =?UTF-8?q?=EB=94=A9=20=EB=A6=AC=EB=8B=A4=EC=9D=B4=EB=A0=89=ED=8A=B8=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/protectRoute.tsx | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/app/protectRoute.tsx b/src/app/protectRoute.tsx index 1cfa4c5..d621b0f 100644 --- a/src/app/protectRoute.tsx +++ b/src/app/protectRoute.tsx @@ -2,7 +2,6 @@ import { useEffect, useState } from 'react' import { usePathname, useRouter } from 'next/navigation' -import LoginConfirmModal from '@/components/common/modal/LoginConfirmModal' import { setSentryUser } from '@/lib/sentry/sentry' import useUserStore from '@/stores/useAuthStore' import { @@ -34,7 +33,8 @@ export default function ProtectRoute({ const router = useRouter() const pathname = usePathname() const user = useUserStore((state) => state.user) - const [isProtectedRoute, setIsProtectedRoute] = useState(false) + const [isRedirectingToLanding, setIsRedirectingToLanding] = + useState(false) useEffect(() => { setSentryUser(user ? { id: user.id } : null) @@ -49,9 +49,13 @@ export default function ProtectRoute({ publicRoutes.includes(pathname) || pathname.startsWith('/invite/') if (!hasStoredUser && !isPublicRoute && !isNotFoundPage) { - setIsProtectedRoute(true) + setIsRedirectingToLanding(true) + router.replace('/') + return } - }, [pathname]) + + setIsRedirectingToLanding(false) + }, [pathname, router]) useEffect(() => { if (!user?.id || termsAgreementExemptRoutes.includes(pathname)) return @@ -73,15 +77,7 @@ export default function ProtectRoute({ return (
- {children} - setIsProtectedRoute(false)} - onSubmit={() => { - router.replace('/login') - setIsProtectedRoute(false) - }} - /> + {isRedirectingToLanding ? null : children}
) } From 581b0bff9c1190fe3df5a42157c1a1c0d2be6e35 Mon Sep 17 00:00:00 2001 From: shinhm1 Date: Thu, 9 Jul 2026 23:11:54 +0900 Subject: [PATCH 14/25] =?UTF-8?q?fix:=20=EB=9E=9C=EB=94=A9=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EC=A0=91=EA=B7=BC=EC=84=B1=20=EC=86=8D?= =?UTF-8?q?=EC=84=B1=20=EB=B3=B4=EC=99=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/page.tsx | 12 ++++++++---- src/components/common/icon/Icon.tsx | 15 +++++++++++++-- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/app/page.tsx b/src/app/page.tsx index ffd8659..2d38745 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -124,7 +124,7 @@ export default function LandingPage() {
- + - 지금 시작하기 → + 지금 시작하기 @@ -203,6 +203,7 @@ export default function LandingPage() { width={20} height={20} fill="text-secondary-300" + ariaHidden />

{card.title} @@ -244,6 +245,7 @@ export default function LandingPage() { width={16} height={16} fill="text-secondary-300" + ariaHidden />

{point.title}

@@ -283,7 +285,9 @@ export default function LandingPage() { delay={index * 70} >

- {feature.icon} + {feature.title}

@@ -345,7 +349,7 @@ export default function LandingPage() { href="/login" className="btn btn-large btn-primary mt-28 flex items-center justify-center" > - 지금 시작하기 → + 지금 시작하기

diff --git a/src/components/common/icon/Icon.tsx b/src/components/common/icon/Icon.tsx index 9739dbd..a045f37 100644 --- a/src/components/common/icon/Icon.tsx +++ b/src/components/common/icon/Icon.tsx @@ -42,10 +42,20 @@ interface IconProps { width: number | string height: number | string fill?: string + ariaHidden?: boolean + ariaLabel?: string onClick?: () => void } -const Icon = ({ type, width, height, fill = '', onClick }: IconProps) => { +const Icon = ({ + type, + width, + height, + fill = '', + ariaHidden, + ariaLabel, + onClick, +}: IconProps) => { const SelectedIcon = iconMap[type] return ( @@ -53,7 +63,8 @@ const Icon = ({ type, width, height, fill = '', onClick }: IconProps) => { width={width} height={height} className={`fill-current ${fill}`} - aria-label={type} + aria-hidden={ariaHidden} + aria-label={ariaHidden ? undefined : ariaLabel || type} viewBox="0 0 24 24" onClick={onClick} /> From e32cdc9f15aa3c4aae0d9e01ef1cfd816459ef6e Mon Sep 17 00:00:00 2001 From: shinhm1 Date: Thu, 9 Jul 2026 23:23:28 +0900 Subject: [PATCH 15/25] =?UTF-8?q?fix:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=9E=AC=EC=9D=B8=EC=A6=9D=20?= =?UTF-8?q?=EC=A7=84=EC=9E=85=20=EB=B0=A9=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/login/page.tsx | 25 ++++++++++------- src/components/auth/LoginRedirectGuard.tsx | 31 ++++++++++++++++++++++ 2 files changed, 46 insertions(+), 10 deletions(-) create mode 100644 src/components/auth/LoginRedirectGuard.tsx diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx index 245b49c..b750d26 100644 --- a/src/app/login/page.tsx +++ b/src/app/login/page.tsx @@ -1,5 +1,6 @@ import NbreadsImage from '@/components/common/nbreadImage/NbreadsImage' import LoginButton from '@/components/user/LoginButton' +import LoginRedirectGuard from '@/components/auth/LoginRedirectGuard' import NbreadText from '@/assets/logo/nbread-text.svg' import { getSafeRedirectPath } from '@/lib/authRedirect' @@ -14,17 +15,21 @@ const LoginPage = async ({ searchParams }: LoginPageProps) => { ) return ( -
-
- - -

구독 공유 관리 서비스

+ +
+
+ + +

구독 공유 관리 서비스

+
+
+ + +
-
- - -
-
+ ) } export default LoginPage diff --git a/src/components/auth/LoginRedirectGuard.tsx b/src/components/auth/LoginRedirectGuard.tsx new file mode 100644 index 0000000..bfe6409 --- /dev/null +++ b/src/components/auth/LoginRedirectGuard.tsx @@ -0,0 +1,31 @@ +'use client' + +import { useEffect, useState } from 'react' +import { useRouter } from 'next/navigation' +import { hasPersistedUser } from '@/lib/authStorage' + +interface LoginRedirectGuardProps { + children: React.ReactNode +} + +const LoginRedirectGuard = ({ children }: LoginRedirectGuardProps) => { + const router = useRouter() + const [shouldRenderLogin, setShouldRenderLogin] = useState(false) + + useEffect(() => { + if (hasPersistedUser()) { + router.replace('/home') + return + } + + setShouldRenderLogin(true) + }, [router]) + + if (!shouldRenderLogin) { + return null + } + + return children +} + +export default LoginRedirectGuard From c9824589b8fa8466136cbcdc1915b6072c50f8d4 Mon Sep 17 00:00:00 2001 From: shinhm1 Date: Fri, 10 Jul 2026 16:49:47 +0900 Subject: [PATCH 16/25] =?UTF-8?q?feat:=20=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=EB=B3=84=20SEO=20=EB=A9=94=ED=83=80=EB=8D=B0=EC=9D=B4=ED=84=B0?= =?UTF-8?q?=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- next-sitemap.config.js | 2 +- public/robots.txt | 4 +-- public/sitemap-0.xml | 8 ++--- public/sitemap.xml | 2 +- src/app/ios-guide/page.tsx | 10 +++++-- src/app/layout.tsx | 6 ++-- src/app/page.tsx | 9 ++++++ src/app/privacy-policy/page.tsx | 11 ++++--- src/app/terms-of-service/page.tsx | 13 ++++---- src/lib/seo.ts | 50 +++++++++++++++++++++++++++++++ 10 files changed, 92 insertions(+), 23 deletions(-) create mode 100644 src/lib/seo.ts diff --git a/next-sitemap.config.js b/next-sitemap.config.js index 53eee60..35cdf46 100644 --- a/next-sitemap.config.js +++ b/next-sitemap.config.js @@ -1,6 +1,6 @@ /** @type {import('next-sitemap').IConfig} */ module.exports = { - siteUrl: process.env.SITE_URL || 'https://nbread-nbread.vercel.app', + siteUrl: 'https://www.nbread.co.kr', generateRobotsTxt: true, changefreq: 'weekly', priority: 0.7, diff --git a/public/robots.txt b/public/robots.txt index 4ed5a42..7124598 100644 --- a/public/robots.txt +++ b/public/robots.txt @@ -16,7 +16,7 @@ Disallow: /notification Disallow: /terms-agreement # Host -Host: https://nbread-nbread.vercel.app +Host: https://www.nbread.co.kr # Sitemaps -Sitemap: https://nbread-nbread.vercel.app/sitemap.xml +Sitemap: https://www.nbread.co.kr/sitemap.xml diff --git a/public/sitemap-0.xml b/public/sitemap-0.xml index 4c34b5c..1560313 100644 --- a/public/sitemap-0.xml +++ b/public/sitemap-0.xml @@ -1,7 +1,7 @@ -https://nbread-nbread.vercel.app/ios-guide2026-07-08T09:43:41.344Zweekly0.7 -https://nbread-nbread.vercel.app2026-07-08T09:43:41.347Zweekly0.7 -https://nbread-nbread.vercel.app/privacy-policy2026-07-08T09:43:41.347Zweekly0.7 -https://nbread-nbread.vercel.app/terms-of-service2026-07-08T09:43:41.347Zweekly0.7 +https://www.nbread.co.kr/ios-guide2026-07-09T15:37:43.343Zweekly0.7 +https://www.nbread.co.kr/privacy-policy2026-07-09T15:37:43.343Zweekly0.7 +https://www.nbread.co.kr2026-07-09T15:37:43.343Zweekly0.7 +https://www.nbread.co.kr/terms-of-service2026-07-09T15:37:43.343Zweekly0.7 \ No newline at end of file diff --git a/public/sitemap.xml b/public/sitemap.xml index 0cff401..2d62498 100644 --- a/public/sitemap.xml +++ b/public/sitemap.xml @@ -1,4 +1,4 @@ -https://nbread-nbread.vercel.app/sitemap-0.xml +https://www.nbread.co.kr/sitemap-0.xml \ No newline at end of file diff --git a/src/app/ios-guide/page.tsx b/src/app/ios-guide/page.tsx index e482dda..f1e1ee3 100644 --- a/src/app/ios-guide/page.tsx +++ b/src/app/ios-guide/page.tsx @@ -1,7 +1,13 @@ -'use client' - import DetailHeader from '@/components/common/header/DetailHeader' import Image from 'next/image' +import { createPageMetadata } from '@/lib/seo' + +export const metadata = createPageMetadata({ + title: 'iOS 홈 화면 추가 가이드', + description: + 'iPhone Safari에서 엔빵을 홈 화면에 추가하고 앱처럼 실행하는 방법을 단계별로 안내합니다.', + path: '/ios-guide', +}) const addToHomeSteps = [ { diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 60171a5..a0b7a06 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -6,9 +6,10 @@ import GoogleAnalytics from '@/lib/analytics/GoogleAnalytics' import PageViewTracker from '@/lib/analytics/PageViewTracker' import ClarityProvider from '@/lib/analytics/ClarityProvider' import Footer from '@/components/common/Footer' +import { SITE_URL } from '@/lib/seo' export const metadata: Metadata = { - metadataBase: new URL('https://nbread-nbread.vercel.app'), + metadataBase: new URL(SITE_URL), title: { default: '엔빵', template: '%s | 엔빵', @@ -26,9 +27,6 @@ export const metadata: Metadata = { ], applicationName: '엔빵', manifest: '/manifest.json', - alternates: { - canonical: '/', - }, robots: { index: true, follow: true, diff --git a/src/app/page.tsx b/src/app/page.tsx index 2d38745..7ef00c6 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -5,6 +5,15 @@ import Icon, { type IconType } from '@/components/common/icon/Icon' import NbreadsImage from '@/components/common/nbreadImage/NbreadsImage' import RevealOnScroll from '@/components/landing/RevealOnScroll' import NbreadLogo from '@/assets/logo/nbread-logo-text.svg' +import { createPageMetadata } from '@/lib/seo' + +export const metadata = createPageMetadata({ + title: '엔빵', + description: + '친구와 가족과 나누는 구독 서비스의 결제일과 정산 현황을 한 곳에서 관리하는 구독 공유 관리 서비스', + path: '/', + absoluteTitle: true, +}) const painCards: { icon: IconType diff --git a/src/app/privacy-policy/page.tsx b/src/app/privacy-policy/page.tsx index 2e873dd..b557c4f 100644 --- a/src/app/privacy-policy/page.tsx +++ b/src/app/privacy-policy/page.tsx @@ -1,9 +1,12 @@ import DetailHeader from '@/components/common/header/DetailHeader' -import type { Metadata } from 'next' +import { createPageMetadata } from '@/lib/seo' -export const metadata: Metadata = { +export const metadata = createPageMetadata({ title: '개인정보처리방침', -} + description: + '엔빵의 개인정보 수집 항목, 이용 목적, 보유 기간, 처리 위탁, 이용자 권리와 보호 조치를 안내합니다.', + path: '/privacy-policy', +}) const sectionTitleClass = 'text-heading04 text-gray-800 mt-16' const bodyClass = 'mt-8 whitespace-pre-line text-paragraph text-gray-700' @@ -115,7 +118,7 @@ export default function PrivacyPolicyPage() {

10. 개인정보 보호책임자 및 문의

서비스명: 엔빵(N빵) - {'\n'}서비스 URL: https://nbread-nbread.vercel.app + {'\n'}서비스 URL: https://www.nbread.co.kr {'\n'}팀명: 엔빵(andbread) {'\n'}문의: GitHub Issues (https://github.com/andbread/Andbread_Frontend/issues) diff --git a/src/app/terms-of-service/page.tsx b/src/app/terms-of-service/page.tsx index 9c02f6f..6bfc416 100644 --- a/src/app/terms-of-service/page.tsx +++ b/src/app/terms-of-service/page.tsx @@ -1,9 +1,12 @@ import DetailHeader from '@/components/common/header/DetailHeader' -import type { Metadata } from 'next' - -export const metadata: Metadata = { - title: '서비스이용약관', -} +import { createPageMetadata } from '@/lib/seo' + +export const metadata = createPageMetadata({ + title: '서비스 이용약관', + description: + '엔빵 구독 공유 관리 서비스의 이용 조건, 이용자 의무, 서비스 제공 범위와 책임 기준을 안내합니다.', + path: '/terms-of-service', +}) const sectionTitleClass = 'text-heading04 text-gray-800 mt-16' const bodyClass = 'mt-8 whitespace-pre-line text-paragraph text-gray-700' diff --git a/src/lib/seo.ts b/src/lib/seo.ts new file mode 100644 index 0000000..47fd649 --- /dev/null +++ b/src/lib/seo.ts @@ -0,0 +1,50 @@ +import type { Metadata } from 'next' + +export const SITE_URL = 'https://www.nbread.co.kr' + +const SITE_NAME = '엔빵' +const OG_IMAGE = { + url: '/assets/logo/open-graph-logo.png', + width: 1200, + height: 630, + alt: '엔빵 로고', +} + +interface PageMetadataParams { + title: string + description: string + path: string + absoluteTitle?: boolean +} + +export const createPageMetadata = ({ + title, + description, + path, + absoluteTitle = false, +}: PageMetadataParams): Metadata => { + const socialTitle = absoluteTitle ? title : `${title} | ${SITE_NAME}` + + return { + title: absoluteTitle ? { absolute: title } : title, + description, + alternates: { + canonical: path, + }, + openGraph: { + title: socialTitle, + description, + url: path, + siteName: SITE_NAME, + locale: 'ko_KR', + type: 'website', + images: [OG_IMAGE], + }, + twitter: { + card: 'summary_large_image', + title: socialTitle, + description, + images: [OG_IMAGE.url], + }, + } +} From 40dfeb2dbcc584472b722fa2a274ad77fb3262aa Mon Sep 17 00:00:00 2001 From: shinhm1 Date: Fri, 10 Jul 2026 17:55:34 +0900 Subject: [PATCH 17/25] =?UTF-8?q?feat:=20sitemap=20=EB=B0=8F=20robots=20?= =?UTF-8?q?=EC=A0=95=EC=B1=85=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- next-sitemap.config.js | 6 ++++-- package-lock.json | 4 ++-- public/robots.txt | 3 ++- public/sitemap-0.xml | 8 ++++---- src/app/invite/[token]/page.tsx | 3 +++ src/app/login/page.tsx | 3 +++ src/app/terms-agreement/page.tsx | 3 +++ src/lib/seo.ts | 11 +++++++++++ 8 files changed, 32 insertions(+), 9 deletions(-) diff --git a/next-sitemap.config.js b/next-sitemap.config.js index 35cdf46..ff42650 100644 --- a/next-sitemap.config.js +++ b/next-sitemap.config.js @@ -11,8 +11,9 @@ module.exports = { '/friendList', '/home', '/icon.ico', - '/inviteAccept', + '/invite/*', '/invites', + '/login', '/manifest.json', '/mypage', '/mypage/*', @@ -33,8 +34,9 @@ module.exports = { '/calendar', '/friendList', '/home', - '/inviteAccept', + '/invite/', '/invites', + '/login', '/mypage', '/nbread/', '/notification', diff --git a/package-lock.json b/package-lock.json index 40d5e02..a38a982 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "andbread", - "version": "0.1.0", + "version": "2.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "andbread", - "version": "0.1.0", + "version": "2.1.0", "dependencies": { "@microsoft/clarity": "^1.0.2", "@sentry/nextjs": "^10.53.1", diff --git a/public/robots.txt b/public/robots.txt index 7124598..7db64ca 100644 --- a/public/robots.txt +++ b/public/robots.txt @@ -8,8 +8,9 @@ Disallow: /auth/ Disallow: /calendar Disallow: /friendList Disallow: /home -Disallow: /inviteAccept +Disallow: /invite/ Disallow: /invites +Disallow: /login Disallow: /mypage Disallow: /nbread/ Disallow: /notification diff --git a/public/sitemap-0.xml b/public/sitemap-0.xml index 1560313..8049278 100644 --- a/public/sitemap-0.xml +++ b/public/sitemap-0.xml @@ -1,7 +1,7 @@ -https://www.nbread.co.kr/ios-guide2026-07-09T15:37:43.343Zweekly0.7 -https://www.nbread.co.kr/privacy-policy2026-07-09T15:37:43.343Zweekly0.7 -https://www.nbread.co.kr2026-07-09T15:37:43.343Zweekly0.7 -https://www.nbread.co.kr/terms-of-service2026-07-09T15:37:43.343Zweekly0.7 +https://www.nbread.co.kr/ios-guide2026-07-10T08:31:23.836Zweekly0.7 +https://www.nbread.co.kr/privacy-policy2026-07-10T08:31:23.839Zweekly0.7 +https://www.nbread.co.kr2026-07-10T08:31:23.839Zweekly0.7 +https://www.nbread.co.kr/terms-of-service2026-07-10T08:31:23.839Zweekly0.7 \ No newline at end of file diff --git a/src/app/invite/[token]/page.tsx b/src/app/invite/[token]/page.tsx index 1db604a..7555fa6 100644 --- a/src/app/invite/[token]/page.tsx +++ b/src/app/invite/[token]/page.tsx @@ -1,4 +1,7 @@ import InvitePageClient from '@/components/invite/InvitePageClient' +import { NO_INDEX_METADATA } from '@/lib/seo' + +export const metadata = NO_INDEX_METADATA interface InvitePageProps { params: Promise<{ token: string }> diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx index b750d26..bcf018b 100644 --- a/src/app/login/page.tsx +++ b/src/app/login/page.tsx @@ -3,6 +3,9 @@ import LoginButton from '@/components/user/LoginButton' import LoginRedirectGuard from '@/components/auth/LoginRedirectGuard' import NbreadText from '@/assets/logo/nbread-text.svg' import { getSafeRedirectPath } from '@/lib/authRedirect' +import { NO_INDEX_METADATA } from '@/lib/seo' + +export const metadata = NO_INDEX_METADATA interface LoginPageProps { searchParams: Promise<{ redirect?: string | string[] }> diff --git a/src/app/terms-agreement/page.tsx b/src/app/terms-agreement/page.tsx index fdf8f67..3f0ac0e 100644 --- a/src/app/terms-agreement/page.tsx +++ b/src/app/terms-agreement/page.tsx @@ -1,5 +1,8 @@ import TermsAgreementPageClient from '@/components/auth/TermsAgreementPageClient' import { getSafeRedirectPath } from '@/lib/authRedirect' +import { NO_INDEX_METADATA } from '@/lib/seo' + +export const metadata = NO_INDEX_METADATA interface TermsAgreementPageProps { searchParams: Promise<{ next?: string | string[] }> diff --git a/src/lib/seo.ts b/src/lib/seo.ts index 47fd649..d5a71ea 100644 --- a/src/lib/seo.ts +++ b/src/lib/seo.ts @@ -2,6 +2,17 @@ import type { Metadata } from 'next' export const SITE_URL = 'https://www.nbread.co.kr' +export const NO_INDEX_METADATA: Metadata = { + robots: { + index: false, + follow: false, + googleBot: { + index: false, + follow: false, + }, + }, +} + const SITE_NAME = '엔빵' const OG_IMAGE = { url: '/assets/logo/open-graph-logo.png', From 3cb87a4d82630dbbfd4f0b588ae110472f5465a2 Mon Sep 17 00:00:00 2001 From: shinhm1 Date: Fri, 10 Jul 2026 18:11:36 +0900 Subject: [PATCH 18/25] =?UTF-8?q?fix:=20noindex=20=EB=9D=BC=EC=9A=B0?= =?UTF-8?q?=ED=8A=B8=20robots=20=EC=B0=A8=EB=8B=A8=20=ED=95=B4=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- next-sitemap.config.js | 2 -- public/robots.txt | 2 -- public/sitemap-0.xml | 8 ++++---- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/next-sitemap.config.js b/next-sitemap.config.js index ff42650..95c22d8 100644 --- a/next-sitemap.config.js +++ b/next-sitemap.config.js @@ -34,9 +34,7 @@ module.exports = { '/calendar', '/friendList', '/home', - '/invite/', '/invites', - '/login', '/mypage', '/nbread/', '/notification', diff --git a/public/robots.txt b/public/robots.txt index 7db64ca..799d608 100644 --- a/public/robots.txt +++ b/public/robots.txt @@ -8,9 +8,7 @@ Disallow: /auth/ Disallow: /calendar Disallow: /friendList Disallow: /home -Disallow: /invite/ Disallow: /invites -Disallow: /login Disallow: /mypage Disallow: /nbread/ Disallow: /notification diff --git a/public/sitemap-0.xml b/public/sitemap-0.xml index 8049278..5c01073 100644 --- a/public/sitemap-0.xml +++ b/public/sitemap-0.xml @@ -1,7 +1,7 @@ -https://www.nbread.co.kr/ios-guide2026-07-10T08:31:23.836Zweekly0.7 -https://www.nbread.co.kr/privacy-policy2026-07-10T08:31:23.839Zweekly0.7 -https://www.nbread.co.kr2026-07-10T08:31:23.839Zweekly0.7 -https://www.nbread.co.kr/terms-of-service2026-07-10T08:31:23.839Zweekly0.7 +https://www.nbread.co.kr/ios-guide2026-07-10T09:10:58.779Zweekly0.7 +https://www.nbread.co.kr2026-07-10T09:10:58.780Zweekly0.7 +https://www.nbread.co.kr/privacy-policy2026-07-10T09:10:58.780Zweekly0.7 +https://www.nbread.co.kr/terms-of-service2026-07-10T09:10:58.780Zweekly0.7 \ No newline at end of file From b972e061adbef9ca7bb7d0491d16aea4ea8f4107 Mon Sep 17 00:00:00 2001 From: shinhm1 Date: Fri, 10 Jul 2026 21:51:41 +0900 Subject: [PATCH 19/25] =?UTF-8?q?feat:=20JSON-LD=20=EA=B5=AC=EC=A1=B0?= =?UTF-8?q?=ED=99=94=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/assets/logo/nbread-logo.svg | 6 + src/app/page.tsx | 443 ++++++++++++++-------------- src/components/seo/JsonLdScript.tsx | 18 ++ src/lib/jsonLd.ts | 61 ++++ 4 files changed, 311 insertions(+), 217 deletions(-) create mode 100644 public/assets/logo/nbread-logo.svg create mode 100644 src/components/seo/JsonLdScript.tsx create mode 100644 src/lib/jsonLd.ts diff --git a/public/assets/logo/nbread-logo.svg b/public/assets/logo/nbread-logo.svg new file mode 100644 index 0000000..96680fc --- /dev/null +++ b/public/assets/logo/nbread-logo.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/app/page.tsx b/src/app/page.tsx index 7ef00c6..cea5da3 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -4,7 +4,9 @@ import type { ReactNode } from 'react' import Icon, { type IconType } from '@/components/common/icon/Icon' import NbreadsImage from '@/components/common/nbreadImage/NbreadsImage' import RevealOnScroll from '@/components/landing/RevealOnScroll' +import JsonLdScript from '@/components/seo/JsonLdScript' import NbreadLogo from '@/assets/logo/nbread-logo-text.svg' +import { landingPageJsonLd } from '@/lib/jsonLd' import { createPageMetadata } from '@/lib/seo' export const metadata = createPageMetadata({ @@ -130,238 +132,245 @@ const SectionHeading = ({ export default function LandingPage() { return ( -

-
-
- - - 시작하기 - -
- - -

- 구독 나눔, 이제 쉽게 -

-

- 구독 공유, -
- 헷갈리게 쓰지 말고 -
- 엔빵으로 딱 정리 -

-

- 넷플릭스, 유튜브 프리미엄, 왓챠 등 친구, 가족과 나누는 구독 서비스의 - 결제일과 정산 현황을 한 곳에서 관리할 수 있어요. -

-
- - - - 지금 시작하기 - - - - - 엔빵 홈 화면 미리보기 - -
+ <> + +
+
+
+ + + 시작하기 + +
-
- -
-

- 이런 경험 있으신가요? + +

+ 구독 나눔, 이제 쉽게

-
-

- 매달 반복되는 -
- 정산하기 -

-

- 구독 공유는 편리하지만, -
- 매달 정산이 번거롭고 헷갈려요. -

-
+

+ 구독 공유, +
+ 헷갈리게 쓰지 말고 +
+ 엔빵으로 딱 정리 +

+

+ 넷플릭스, 유튜브 프리미엄, 왓챠 등 친구, 가족과 나누는 구독 + 서비스의 결제일과 정산 현황을 한 곳에서 관리할 수 있어요. +

+ -
- {painCards.map((card, index) => ( - + - -

- {card.title} -

-

- {card.description} -

-
- ))} -
-
+ 지금 시작하기 + + -
- - - 구독 공유의 모든 것을 -
한 곳에서 - - } - /> -

- 그룹 생성, 친구 초대, 이달의 구독료 정산까지 엔빵에서 모두 끝낼 수 - 있어요. -

-
+ + 엔빵 홈 화면 미리보기 + +
- - {solutionPoints.map((point, index) => ( -
-
+
+ +
+

+ 이런 경험 있으신가요? +

+
+

+ 매달 반복되는 +
+ 정산하기 +

+

+ 구독 공유는 편리하지만, +
+ 매달 정산이 번거롭고 헷갈려요. +

+
+ +
+ {painCards.map((card, index) => ( + -

{point.title}

-
-

- {point.description} -

-
- ))} - -
- -
- - - 불필요한 건 빼고 -
- 필요한 것만 넣었어요 - - } - /> -

- 구독 공유에 필요한 기능만 모았어요. -

-
+

+ {card.title} +

+

+ {card.description} +

+ + ))} +
+ -
- {featureCards.map((feature, index) => ( - -

- - {feature.title} -

-

- {feature.description} -

-
- ))} -
- +
+ + + 구독 공유의 모든 것을 +
한 곳에서 + + } + /> +

+ 그룹 생성, 친구 초대, 이달의 구독료 정산까지 엔빵에서 모두 끝낼 수 + 있어요. +

+
-
- - - 3단계로 -
- 바로 시작하기 - - } - /> -

- 복잡한 설정 필요 없이 -
- 3단계면 충분해요. -

-
+ + {solutionPoints.map((point, index) => ( +
+
+ +

+ {point.title} +

+
+

+ {point.description} +

+
+ ))} +
+
- - {steps.map((step, index) => ( -
-

{step.label}

-

- {step.title} -

-

- {step.description} -

-
- ))} -
-
+
+ + + 불필요한 건 빼고 +
+ 필요한 것만 넣었어요 + + } + /> +

+ 구독 공유에 필요한 기능만 모았어요. +

+
-
- -
- +
+ {featureCards.map((feature, index) => ( + +

+ + {feature.title} +

+

+ {feature.description} +

+
+ ))}
-

- 지금 바로 시작하고 -
- 정산 스트레스에서 벗어나세요 -

- + +
+ + + 3단계로 +
+ 바로 시작하기 + + } + /> +

+ 복잡한 설정 필요 없이 +
+ 3단계면 충분해요. +

+
+ + - 지금 시작하기 - - -
-
+ {steps.map((step, index) => ( +
+

+ {step.label} +

+

+ {step.title} +

+

+ {step.description} +

+
+ ))} + + + +
+ +
+ +
+

+ 지금 바로 시작하고 +
+ 정산 스트레스에서 벗어나세요 +

+ + 지금 시작하기 + +
+
+ + ) } diff --git a/src/components/seo/JsonLdScript.tsx b/src/components/seo/JsonLdScript.tsx new file mode 100644 index 0000000..f57e961 --- /dev/null +++ b/src/components/seo/JsonLdScript.tsx @@ -0,0 +1,18 @@ +import type { JsonLdObject } from '@/lib/jsonLd' + +interface JsonLdScriptProps { + data: JsonLdObject +} + +const JsonLdScript = ({ data }: JsonLdScriptProps) => { + const json = JSON.stringify(data).replace(/ + ) +} + +export default JsonLdScript diff --git a/src/lib/jsonLd.ts b/src/lib/jsonLd.ts new file mode 100644 index 0000000..404dc0c --- /dev/null +++ b/src/lib/jsonLd.ts @@ -0,0 +1,61 @@ +import { SITE_URL } from '@/lib/seo' + +type JsonLdValue = + | string + | number + | boolean + | null + | JsonLdObject + | JsonLdValue[] + +export interface JsonLdObject { + [key: string]: JsonLdValue +} + +const SITE_NAME = '엔빵' +const SITE_DESCRIPTION = + '친구와 가족과 나누는 구독 서비스의 결제일과 정산 현황을 한 곳에서 관리하는 구독 공유 관리 서비스' + +const getAbsoluteUrl = (path: string) => new URL(path, SITE_URL).toString() + +export const landingPageJsonLd: JsonLdObject = { + '@context': 'https://schema.org', + '@graph': [ + { + '@type': 'Organization', + '@id': `${SITE_URL}/#organization`, + name: SITE_NAME, + url: SITE_URL, + logo: { + '@type': 'ImageObject', + url: getAbsoluteUrl('/assets/logo/nbread-logo.svg'), + width: 40, + height: 40, + }, + }, + { + '@type': 'WebSite', + '@id': `${SITE_URL}/#website`, + name: SITE_NAME, + url: SITE_URL, + description: SITE_DESCRIPTION, + inLanguage: 'ko-KR', + publisher: { + '@id': `${SITE_URL}/#organization`, + }, + }, + { + '@type': 'WebApplication', + '@id': `${SITE_URL}/#web-application`, + name: SITE_NAME, + url: SITE_URL, + description: SITE_DESCRIPTION, + inLanguage: 'ko-KR', + applicationCategory: 'UtilitiesApplication', + operatingSystem: 'Web', + publisher: { + '@id': `${SITE_URL}/#organization`, + }, + }, + ], +} From 9d4af205708fce94dc698394e7ae59ae72a159f8 Mon Sep 17 00:00:00 2001 From: shinhm1 Date: Fri, 10 Jul 2026 22:08:24 +0900 Subject: [PATCH 20/25] =?UTF-8?q?fix:=20JSON-LD=20=EB=A1=9C=EA=B3=A0=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20=ED=81=AC=EA=B8=B0=20=EC=A1=B0?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/assets/logo/nbread-logo.png | Bin 0 -> 45798 bytes public/assets/logo/nbread-logo.svg | 6 ------ src/lib/jsonLd.ts | 6 +++--- 3 files changed, 3 insertions(+), 9 deletions(-) create mode 100644 public/assets/logo/nbread-logo.png delete mode 100644 public/assets/logo/nbread-logo.svg diff --git a/public/assets/logo/nbread-logo.png b/public/assets/logo/nbread-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..e6dd982a6a6bfb2bba881413186e151926086e92 GIT binary patch literal 45798 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 d1%VtrARV*6C@g - - - - - diff --git a/src/lib/jsonLd.ts b/src/lib/jsonLd.ts index 404dc0c..1f2be84 100644 --- a/src/lib/jsonLd.ts +++ b/src/lib/jsonLd.ts @@ -28,9 +28,9 @@ export const landingPageJsonLd: JsonLdObject = { url: SITE_URL, logo: { '@type': 'ImageObject', - url: getAbsoluteUrl('/assets/logo/nbread-logo.svg'), - width: 40, - height: 40, + url: getAbsoluteUrl('/assets/logo/nbread-logo.png'), + width: 512, + height: 512, }, }, { From e8f5419f0b8344351cf9e33ebfad4efb9e32d60e Mon Sep 17 00:00:00 2001 From: shinhm1 Date: Sun, 12 Jul 2026 21:29:50 +0900 Subject: [PATCH 21/25] =?UTF-8?q?docs:=20=ED=94=84=EB=A1=9C=EB=8D=95?= =?UTF-8?q?=EC=85=98=20=EB=A6=B4=EB=A6=AC=EC=A6=88=20=EC=8A=A4=ED=82=AC=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .agents/skills/production-release/SKILL.md | 82 ++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 .agents/skills/production-release/SKILL.md diff --git a/.agents/skills/production-release/SKILL.md b/.agents/skills/production-release/SKILL.md new file mode 100644 index 0000000..cf8dffd --- /dev/null +++ b/.agents/skills/production-release/SKILL.md @@ -0,0 +1,82 @@ +--- +name: production-release +description: 엔빵의 프로덕션 릴리즈를 준비하고 develop에서 main으로 릴리즈 PR을 생성합니다. +--- + +# Production Release + +프로덕션 릴리즈를 준비할 때 사용하는 스킬입니다. + +## Workflow + +1. 원격 브랜치와 태그를 최신 상태로 조회합니다. +2. 최신 버전 태그와 현재 `develop`, `main` 상태를 확인합니다. +3. 최신 태그 이후 `develop`에 병합된 PR을 수집합니다. +4. 각 PR의 번호, 제목, 라벨, `Summary`를 읽습니다. +5. `Summary`만으로 사용자 영향이 불명확한 경우에만 `Impact`를 확인합니다. +6. PR 본문만으로 판단하기 어려운 경우에만 제한적으로 Diff를 확인합니다. +7. 관련 PR을 기능 또는 목적 단위로 묶어 릴리즈 노트를 작성합니다. +8. 변경 유형과 최신 태그를 기준으로 다음 버전을 제안합니다. +9. 버전 중복과 변경사항 누락 여부를 검사합니다. +10. `npm run lint`, `npm run build`를 실행합니다. +11. 검증에 성공하면 `references/release-note.md`의 템플릿에 따라 `develop → main` 릴리즈 PR을 생성합니다. + +## Release Scope + +- 최신 태그가 가리키는 커밋 이후 `develop`에 포함된 변경을 대상으로 합니다. +- 기본적으로 base가 `develop`인 merged PR을 수집합니다. +- 릴리즈 PR, merge-only PR, 중복된 PR은 제외합니다. +- `develop`과 `main` 사이에 릴리즈할 변경이 없으면 PR을 생성하지 않습니다. + +## Pull Request Context + +PR 정보는 아래 순서로 확인합니다. + +1. PR 번호 +2. PR 제목 +3. PR 라벨 +4. PR 본문의 `Summary` +5. 필요한 경우 `Impact` +6. 필요한 경우 Diff + +다음 경우에만 Diff를 확인합니다. + +- `Summary`가 없거나 실제 변경 결과를 설명하지 않는 경우 +- PR 제목과 `Summary`가 충돌하는 경우 +- 보안, 데이터 구조, 호환성 파괴 변경이 포함된 경우 +- 버전 제안에 필요한 정보가 부족한 경우 + +## Version Rules + +버전 형식은 `vX.Y.Z`를 사용합니다. + +- `major`: 기존 기능과 호환되지 않는 변경 또는 주요 사용자 흐름의 파괴적 변경 +- `minor`: 새로운 사용자 기능, 공개 페이지, 사용자 흐름 또는 기존 기능의 의미 있는 확장 +- `patch`: 버그 수정, 기존 기능 개선, 성능, 접근성, SEO, 내부 안정성 개선 + +여러 변경 유형이 함께 있으면 가장 높은 버전을 선택합니다. + +`major > minor > patch` + +다음 조건을 확인합니다. + +- 제안한 버전 태그가 이미 존재하지 않는지 확인합니다. +- 최신 태그보다 낮거나 같은 버전을 제안하지 않습니다. +- PR 제목과 본문의 버전이 동일한지 확인합니다. +- 태그가 없는 경우 버전을 자동 결정하지 않고 사용자 확인이 필요하다고 알립니다. + +## Missing Change Check + +수집한 모든 PR은 다음 중 하나의 상태를 가져야 합니다. + +1. 주요 변경사항에 반영 +2. 다른 PR과 통합하여 반영 +3. 내부 변경 또는 중복으로 제외 + +반영 또는 제외 사유가 없는 PR이 있으면 릴리즈 PR을 생성하지 않습니다. + +`포함된 Pull Request` 섹션에는 이번 릴리즈 범위의 PR을 빠짐없이 작성합니다. + +## Validation + +릴리즈 PR 생성 전에 다음 명령을 순서대로 실행합니다. From d2a82d5e02ab60fa9185a6c24dca947277faf7d0 Mon Sep 17 00:00:00 2001 From: shinhm1 Date: Wed, 15 Jul 2026 21:01:17 +0900 Subject: [PATCH 22/25] =?UTF-8?q?docs:=20=ED=94=84=EB=A1=9C=EB=8D=95?= =?UTF-8?q?=EC=85=98=20=EB=A6=B4=EB=A6=AC=EC=A6=88=20=EC=8A=A4=ED=82=AC=20?= =?UTF-8?q?=EB=B3=B4=EA=B0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .agents/skills/production-release/SKILL.md | 220 ++++++++++++++---- .../production-release/agents/openai.yaml | 4 + .../references/release-note.md | 167 +++++++++++++ .../references/release-pr-template.md | 47 ++++ 4 files changed, 396 insertions(+), 42 deletions(-) create mode 100644 .agents/skills/production-release/agents/openai.yaml create mode 100644 .agents/skills/production-release/references/release-note.md create mode 100644 .agents/skills/production-release/references/release-pr-template.md diff --git a/.agents/skills/production-release/SKILL.md b/.agents/skills/production-release/SKILL.md index cf8dffd..c9a1f11 100644 --- a/.agents/skills/production-release/SKILL.md +++ b/.agents/skills/production-release/SKILL.md @@ -7,76 +7,212 @@ description: 엔빵의 프로덕션 릴리즈를 준비하고 develop에서 main 프로덕션 릴리즈를 준비할 때 사용하는 스킬입니다. +## Source of Truth + +릴리즈 정보는 다음 우선순위를 기준으로 판단합니다. + +1. Git 태그 +2. Pull Request +3. Git History + +`package.json`의 `version`은 릴리즈 버전 판단에 사용하지 않습니다. + ## Workflow -1. 원격 브랜치와 태그를 최신 상태로 조회합니다. -2. 최신 버전 태그와 현재 `develop`, `main` 상태를 확인합니다. -3. 최신 태그 이후 `develop`에 병합된 PR을 수집합니다. -4. 각 PR의 번호, 제목, 라벨, `Summary`를 읽습니다. -5. `Summary`만으로 사용자 영향이 불명확한 경우에만 `Impact`를 확인합니다. -6. PR 본문만으로 판단하기 어려운 경우에만 제한적으로 Diff를 확인합니다. -7. 관련 PR을 기능 또는 목적 단위로 묶어 릴리즈 노트를 작성합니다. -8. 변경 유형과 최신 태그를 기준으로 다음 버전을 제안합니다. -9. 버전 중복과 변경사항 누락 여부를 검사합니다. -10. `npm run lint`, `npm run build`를 실행합니다. -11. 검증에 성공하면 `references/release-note.md`의 템플릿에 따라 `develop → main` 릴리즈 PR을 생성합니다. +1. 원격 저장소의 `origin/develop`, `origin/main`, Git 태그를 최신 상태로 동기화합니다. +2. 릴리즈 기준이 되는 최신 `vX.Y.Z` 태그를 확인합니다. +3. 최신 태그 이후 현재 `origin/develop`에 포함된 변경사항을 확인합니다. +4. 해당 변경 범위에 포함된 병합 PR을 수집합니다. +5. 각 PR의 번호, 제목, 라벨, `Summary`를 읽습니다. +6. `Summary`만으로 사용자 영향이 불명확한 경우에만 `Impact`를 확인합니다. +7. 다음 경우에만 제한적으로 PR diff를 확인합니다. + - `Summary`가 없는 경우 + - 제목과 `Summary`가 충돌하는 경우 + - 보안, 데이터 마이그레이션, 호환성 파괴 변경인 경우 + - 버전 판단에 필요한 정보가 부족한 경우 +8. 관련 PR을 기능 또는 목적 단위로 묶어 릴리즈 노트를 작성합니다. +9. 최근 태그와 변경 유형을 기준으로 다음 버전을 제안합니다. +10. 버전 중복과 변경사항 누락 여부를 검사합니다. +11. `npm run lint`, `npm run build`를 실행합니다. +12. 검증에 성공하면 `references/release-pr-template.md`를 사용해 릴리즈 PR 본문을 작성합니다. +13. `[release] vX.Y.Z` 형식으로 `develop → main` 릴리즈 PR을 생성합니다. + +## Latest Release Tag + +릴리즈 기준 태그는 다음 조건을 모두 만족하는 태그 중 버전이 가장 높은 태그를 사용합니다. + +- 정확히 `vX.Y.Z` 형식인가 +- Semantic Versioning 형식인가 +- 버전 순으로 가장 높은 태그인가 + +다음 태그는 릴리즈 기준으로 사용하지 않습니다. + +- `release-*` +- 테스트 또는 임시 태그 +- prerelease 태그 +- `vX.Y.Z` 형식이 아닌 태그 + +릴리즈 기준 태그가 없으면 버전을 자동으로 결정하지 않고 사용자에게 확인을 요청합니다. + +## Release Range + +릴리즈 대상 변경사항은 다음 범위를 기준으로 판단합니다. -## Release Scope +- 최신 릴리즈 태그가 가리키는 커밋 이후 +- 현재 `origin/develop`에 포함된 변경사항 -- 최신 태그가 가리키는 커밋 이후 `develop`에 포함된 변경을 대상으로 합니다. -- 기본적으로 base가 `develop`인 merged PR을 수집합니다. -- 릴리즈 PR, merge-only PR, 중복된 PR은 제외합니다. -- `develop`과 `main` 사이에 릴리즈할 변경이 없으면 PR을 생성하지 않습니다. +기본 비교 범위는 다음과 같습니다. -## Pull Request Context +latest_tag..origin/develop -PR 정보는 아래 순서로 확인합니다. +최신 태그가 없으면 다음 범위를 참고하되, 자동으로 릴리즈 PR을 생성하지 않습니다. + +origin/main..origin/develop + +릴리즈 대상 PR은 다음 조건을 만족해야 합니다. + +- `develop`에 병합된 PR인가 +- 비교 범위의 커밋이 `origin/develop`에 포함되어 있는가 +- 릴리즈 PR이나 merge-only PR이 아닌가 +- 동일한 PR이 중복 수집되지 않았는가 + +Git 커밋 범위와 GitHub PR 목록을 함께 확인합니다. + +1. `latest_tag..origin/develop`의 커밋을 확인합니다. +2. 해당 커밋과 연결된 병합 PR을 수집합니다. +3. PR의 merge commit 또는 포함 커밋이 비교 범위에 존재하는지 확인합니다. +4. 비교 범위에 포함되지 않은 PR은 제외합니다. +5. PR과 연결되지 않은 커밋이 있으면 누락 가능성으로 보고합니다. + +릴리즈 대상 변경사항이나 병합 PR이 없다면 릴리즈 PR을 생성하지 않습니다. + +## Pull Request Information + +각 PR에서 다음 정보를 우선적으로 확인합니다. 1. PR 번호 2. PR 제목 3. PR 라벨 -4. PR 본문의 `Summary` +4. `Summary` 5. 필요한 경우 `Impact` -6. 필요한 경우 Diff - -다음 경우에만 Diff를 확인합니다. +6. 예외적으로 PR diff -- `Summary`가 없거나 실제 변경 결과를 설명하지 않는 경우 -- PR 제목과 `Summary`가 충돌하는 경우 -- 보안, 데이터 구조, 호환성 파괴 변경이 포함된 경우 -- 버전 제안에 필요한 정보가 부족한 경우 +Merge Commit 메시지는 릴리즈 노트의 직접적인 입력으로 사용하지 않습니다. ## Version Rules -버전 형식은 `vX.Y.Z`를 사용합니다. +버전은 `vX.Y.Z` 형식의 Semantic Versioning을 사용합니다. + +### Major + +- 기존 기능과 호환되지 않는 변경 +- 주요 사용자 흐름 또는 공개 인터페이스의 파괴적 변경 -- `major`: 기존 기능과 호환되지 않는 변경 또는 주요 사용자 흐름의 파괴적 변경 -- `minor`: 새로운 사용자 기능, 공개 페이지, 사용자 흐름 또는 기존 기능의 의미 있는 확장 -- `patch`: 버그 수정, 기존 기능 개선, 성능, 접근성, SEO, 내부 안정성 개선 +### Minor -여러 변경 유형이 함께 있으면 가장 높은 버전을 선택합니다. +- 새로운 사용자 기능 추가 +- 기존 기능의 의미 있는 확장 +- 새로운 공개 페이지 또는 사용자 흐름 추가 -`major > minor > patch` +### Patch + +- 버그 수정 +- 기존 기능 개선 +- 성능, 접근성, SEO, 내부 안정성 개선 + +여러 변경 유형이 포함되면 가장 높은 버전 수준을 선택합니다. + +major > minor > patch + +버전 수준을 신뢰성 있게 판단하기 어렵다면 자동으로 결정하지 않고 사용자에게 확인을 요청합니다. 다음 조건을 확인합니다. -- 제안한 버전 태그가 이미 존재하지 않는지 확인합니다. -- 최신 태그보다 낮거나 같은 버전을 제안하지 않습니다. -- PR 제목과 본문의 버전이 동일한지 확인합니다. -- 태그가 없는 경우 버전을 자동 결정하지 않고 사용자 확인이 필요하다고 알립니다. +- 제안한 버전 태그가 이미 존재하지 않는가 +- 최신 릴리즈 태그보다 높은 버전인가 +- PR 제목과 PR 본문의 버전이 일치하는가 +- 동일 버전의 열린 릴리즈 PR이 존재하지 않는가 +- 동일한 `develop → main` 릴리즈 PR이 이미 열려 있지 않은가 ## Missing Change Check -수집한 모든 PR은 다음 중 하나의 상태를 가져야 합니다. +수집한 모든 PR은 다음 중 하나로 처리합니다. + +1. 주요 변경사항에 직접 반영 +2. 다른 PR과 기능 또는 목적 단위로 통합하여 반영 +3. 내부 변경, 중복 또는 릴리즈 제외 대상으로 분류 + +반영 또는 제외 사유가 없는 PR이 있다면 릴리즈 PR을 생성하지 않습니다. -1. 주요 변경사항에 반영 -2. 다른 PR과 통합하여 반영 -3. 내부 변경 또는 중복으로 제외 +`포함된 Pull Request` 섹션에는 릴리즈 대상 PR을 모두 작성합니다. -반영 또는 제외 사유가 없는 PR이 있으면 릴리즈 PR을 생성하지 않습니다. +다음 항목도 확인합니다. -`포함된 Pull Request` 섹션에는 이번 릴리즈 범위의 PR을 빠짐없이 작성합니다. +- 비교 범위에는 있으나 PR 목록에 없는 커밋이 있는가 +- 수집한 PR 중 릴리즈 노트와 포함 PR 목록에서 누락된 항목이 있는가 +- 동일 PR이 두 번 이상 포함되어 있는가 +- 최신 태그 이전 변경사항이 잘못 포함되어 있는가 ## Validation 릴리즈 PR 생성 전에 다음 명령을 순서대로 실행합니다. + +1. `npm run lint` +2. `npm run build` + +하나라도 실패하면 릴리즈 PR을 생성하지 않습니다. + +실패 시 다음 내용을 보고합니다. + +- 실패한 명령 +- 주요 오류 내용 +- 실패한 파일 또는 검사 영역 +- 릴리즈 PR을 생성하지 않았다는 사실 + +기존 저장소 문제인지 이번 릴리즈 변경 때문인지 확실한 근거 없이 추정하지 않습니다. + +기존 문제로 보이는 경우에도 검증이 실패했다면 릴리즈 PR 생성은 중단합니다. + +관련 테스트 명령이 존재하거나 변경사항에 필요한 경우 추가로 실행합니다. + +## Pull Request + +- Base branch: `main` +- Head branch: `develop` +- Title: `[release] vX.Y.Z` +- Body: `references/release-pr-template.md` 사용 + +다음 조건 중 하나라도 만족하면 새 릴리즈 PR을 생성하지 않습니다. + +- 릴리즈 대상 변경사항이 없음 +- 동일 버전의 릴리즈 PR이 존재함 +- 동일한 `develop → main` 열린 PR이 존재함 +- 제안 버전 태그가 이미 존재함 +- 변경사항 누락 검사가 실패함 +- lint 또는 build가 실패함 + +PR 생성 전 다음을 확인합니다. + +- `origin/develop`과 로컬 `develop`이 일치하는가 +- `origin/main`과 로컬 `main`이 일치하는가 +- 릴리즈할 변경사항이 존재하는가 +- 동일한 버전의 릴리즈 PR이 존재하지 않는가 +- 동일한 base와 head를 사용하는 열린 PR이 존재하지 않는가 +- lint와 build가 모두 성공했는가 + +## Constraints + +- `package.json` 버전은 변경하지 않습니다. +- 릴리즈 브랜치를 생성하지 않습니다. +- 릴리즈 이슈를 생성하지 않습니다. +- Git 태그를 생성하지 않습니다. +- GitHub Release를 생성하지 않습니다. +- 프로덕션 배포를 직접 수행하지 않습니다. +- GitHub 자동 릴리즈 노트와 Release Drafter를 사용하지 않습니다. +- 코드 diff 전체 분석은 기본 동작에서 제외합니다. +- 구현 세부사항보다 기능과 사용자 영향을 우선 설명합니다. + +## References + +- `references/release-note.md` +- `references/release-pr-template.md` diff --git a/.agents/skills/production-release/agents/openai.yaml b/.agents/skills/production-release/agents/openai.yaml new file mode 100644 index 0000000..008cca7 --- /dev/null +++ b/.agents/skills/production-release/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Production Release" + short_description: "엔빵의 프로덕션 릴리즈 PR을 준비하고 생성합니다." + default_prompt: "이전 릴리즈 이후 변경사항을 확인하고 릴리즈 노트를 작성한 뒤 develop에서 main으로 프로덕션 릴리즈 PR을 생성해 주세요." diff --git a/.agents/skills/production-release/references/release-note.md b/.agents/skills/production-release/references/release-note.md new file mode 100644 index 0000000..72a8de9 --- /dev/null +++ b/.agents/skills/production-release/references/release-note.md @@ -0,0 +1,167 @@ +# Release Note Guide + +이 문서는 릴리즈 PR과 GitHub Release에 사용할 릴리즈 노트 작성 규칙을 정의합니다. + +릴리즈 PR의 제목과 전체 본문 구조는 `references/release-pr-template.md`를 따릅니다. + +## 목적 + +릴리즈 노트는 단순한 개발 기록이 아니라 사용자와 개발자가 이번 릴리즈에서 무엇이 변경되었는지 빠르게 이해할 수 있는 문서입니다. + +구현 방법보다 변경 결과와 사용자 영향을 우선 설명합니다. + +## 정보 조회 우선순위 + +각 PR의 다음 정보를 순서대로 사용합니다. + +1. PR `Summary` +2. PR 제목 +3. PR `Impact` +4. PR diff + +`Summary`만으로 변경사항을 이해할 수 있다면 `Impact`와 diff는 확인하지 않습니다. + +## Summary 활용 규칙 + +PR의 `Summary`를 그대로 나열하거나 복사하지 않습니다. + +수집한 Summary를 비교해 다음 작업을 수행합니다. + +- 중복 내용 제거 +- 관련 PR 통합 +- 기능 또는 목적 단위로 재구성 +- 사용자 또는 운영 관점으로 재작성 + +여러 PR이 하나의 기능을 구성한다면 각각의 Summary를 한 개의 변경사항으로 통합합니다. + +Summary에서 확인할 수 없는 효과나 결과는 추측하지 않습니다. + +## 작성 원칙 + +### 사용자 관점에서 작성합니다 + +좋은 예 + +- 비회원도 서비스 기능을 확인할 수 있도록 공개 랜딩페이지를 추가했습니다. +- 검색엔진이 페이지를 더 정확하게 이해할 수 있도록 SEO 설정을 개선했습니다. + +좋지 않은 예 + +- `app/page.tsx`를 수정했습니다. +- `generateMetadata`를 공통 함수로 분리했습니다. + +### 관련 PR을 하나의 변경사항으로 묶습니다 + +여러 PR이 하나의 기능이나 목적을 구성한다면 하나의 항목으로 통합합니다. + +예시 PR + +- 랜딩페이지 구현 +- metadata 적용 +- sitemap 추가 + +예시 릴리즈 노트 + +### 공개 페이지와 검색 노출 개선 + +- 비회원용 공개 랜딩페이지를 추가했습니다. +- 검색엔진이 페이지를 올바르게 인식하도록 메타데이터와 검색 노출 설정을 개선했습니다. + +### 구현 세부사항은 최소화합니다 + +다음 내용은 특별한 이유가 없다면 작성하지 않습니다. + +- 함수명 +- 컴포넌트명 +- 파일 경로 +- 리팩터링 과정 +- 내부 구현 방식 + +필요한 경우 변경 목적과 결과만 설명합니다. + +### 내부 작업은 필요한 경우만 포함합니다 + +사용자에게 영향이 없는 작업은 릴리즈 노트에서 제외할 수 있습니다. + +예시 + +- 코드 스타일 수정 +- lint 설정 변경 +- 단순 내부 리팩터링 +- 영향이 없는 의존성 업데이트 +- merge-only 작업 + +운영 안정성이나 개발 생산성에 의미 있는 변화가 있다면 `내부 개선`으로 작성합니다. + +## 버전 표기 규칙 + +- PR 제목과 본문의 버전은 모두 `vX.Y.Z` 형식을 사용합니다. +- PR 제목과 본문의 버전은 반드시 일치해야 합니다. +- 최신 릴리즈 태그보다 낮거나 같은 버전을 작성하지 않습니다. +- 이미 존재하는 태그 또는 열린 릴리즈 PR의 버전을 다시 사용하지 않습니다. +- `package.json`의 버전은 릴리즈 버전 판단에 사용하지 않습니다. + +## 포함된 Pull Request 작성 규칙 + +- 릴리즈 대상 PR을 모두 나열합니다. +- 주요 변경사항에서 여러 PR을 통합했더라도 각 PR은 목록에 별도로 작성합니다. +- 내부 변경으로 제외한 PR도 릴리즈 범위에 포함된다면 목록에 작성할 수 있습니다. +- 릴리즈 PR 자체는 포함하지 않습니다. +- 중복 PR은 한 번만 작성합니다. +- 최신 태그 이후 비교 범위에 포함된 PR만 작성합니다. + +## 작성 규칙 + +- 사용자 또는 운영 관점의 변화를 설명합니다. +- 구현 방법보다 변경 목적과 결과를 작성합니다. +- 같은 의미의 변경사항은 하나로 묶습니다. +- 중복 설명을 작성하지 않습니다. +- 릴리즈 요약은 2~3문장으로 작성합니다. +- 각 변경사항은 가능한 한 한두 문장으로 작성합니다. +- 실제 PR 내용에서 확인할 수 없는 효과를 추측하지 않습니다. +- Merge Commit 메시지를 그대로 릴리즈 노트에 사용하지 않습니다. + +## 제외 대상 + +다음 내용은 기본적으로 주요 변경사항에서 제외합니다. + +- Merge Commit +- Release PR +- Version Update +- 단순 GitHub Actions 수정 +- 단순 CI 설정 변경 +- Chore 성격의 작업 +- 사용자가 인지할 수 없는 내부 수정 + +단, 사용자 경험, 운영 안정성 또는 개발 생산성에 의미 있는 영향이 있다면 포함할 수 있습니다. + +## Quality Rules + +릴리즈 노트는 단순한 변경 로그가 아니라 프로젝트의 변경 이력을 설명하는 문서입니다. + +GitHub Release뿐 아니라 포트폴리오, 프로젝트 문서, 변경 이력으로도 활용할 수 있는 품질을 목표로 합니다. + +릴리즈 노트를 작성할 때 아래 질문에 모두 답할 수 있어야 합니다. + +- 이번 릴리즈에서 무엇이 달라졌는가 +- 왜 이 변경을 했는가 +- 사용자는 어떤 변화를 경험하는가 + +위 질문에 답할 수 없는 내용은 릴리즈 노트에 포함하지 않습니다. + +### 체크리스트 + +릴리즈 노트를 작성한 후 아래 항목을 확인합니다. + +- 변경사항이 사용자 관점에서 작성되었는가 +- 구현 방법보다 변경 결과를 설명하고 있는가 +- 여러 PR을 하나의 기능 단위로 적절히 묶었는가 +- Summary를 그대로 복사하지 않고 재구성했는가 +- 수집한 모든 PR이 반영되거나 제외 사유를 가지고 있는가 +- 비교 범위 밖의 PR이 포함되지 않았는가 +- 중복되거나 불필요한 설명이 없는가 +- PR 제목과 본문의 버전이 일치하는가 +- 릴리즈 전체를 2~3분 안에 이해할 수 있는가 +- GitHub Release로 그대로 게시해도 될 정도의 품질인가 + +모든 항목을 만족하지 못하면 릴리즈 노트를 다시 수정합니다. diff --git a/.agents/skills/production-release/references/release-pr-template.md b/.agents/skills/production-release/references/release-pr-template.md new file mode 100644 index 0000000..90884f2 --- /dev/null +++ b/.agents/skills/production-release/references/release-pr-template.md @@ -0,0 +1,47 @@ +# Release PR Template + +## Title + +```text +[release] vX.Y.Z +``` + +## Body + +```markdown +## 릴리즈 버전 + +`vX.Y.Z` + + + +## 릴리즈 요약 + +이번 릴리즈의 핵심 변화와 목적을 사용자 또는 운영 관점에서 2~3문장으로 작성합니다. + +## 주요 변경사항 + +### 기능 또는 목표 단위 제목 + +- 사용자 또는 운영 관점에서 달라진 내용을 작성합니다. +- 여러 PR이 하나의 기능을 구성한다면 하나의 변경사항으로 통합합니다. + +## 포함된 Pull Request + +- #PR번호 PR 제목 + + + +## 검증 + +- [x] `npm run lint` +- [x] `npm run build` +- [ ] 프로덕션 배포 확인 +``` + +## Rules + +- PR 제목은 반드시 `[release] vX.Y.Z` 형식을 사용합니다. +- PR 본문의 버전과 제목의 버전은 반드시 일치해야 합니다. +- `release-note:start`와 `release-note:end` 사이의 내용은 이후 GitHub Release 본문으로 사용합니다. +- `검증` 섹션은 릴리즈 PR 검토를 위한 정보이며 GitHub Release에는 포함하지 않습니다. From 0a1fbd77cebad598008fc008f6ba775b4f5f95f8 Mon Sep 17 00:00:00 2001 From: shinhm1 Date: Wed, 15 Jul 2026 21:37:44 +0900 Subject: [PATCH 23/25] =?UTF-8?q?docs:=20=EB=A6=B4=EB=A6=AC=EC=A6=88=20?= =?UTF-8?q?=EC=8A=A4=ED=82=AC=20=EB=A6=AC=EB=B7=B0=20=ED=94=BC=EB=93=9C?= =?UTF-8?q?=EB=B0=B1=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .agents/skills/production-release/SKILL.md | 34 ++++--------------- .../references/release-pr-template.md | 6 ---- 2 files changed, 6 insertions(+), 34 deletions(-) diff --git a/.agents/skills/production-release/SKILL.md b/.agents/skills/production-release/SKILL.md index c9a1f11..688788d 100644 --- a/.agents/skills/production-release/SKILL.md +++ b/.agents/skills/production-release/SKILL.md @@ -33,17 +33,17 @@ description: 엔빵의 프로덕션 릴리즈를 준비하고 develop에서 main 8. 관련 PR을 기능 또는 목적 단위로 묶어 릴리즈 노트를 작성합니다. 9. 최근 태그와 변경 유형을 기준으로 다음 버전을 제안합니다. 10. 버전 중복과 변경사항 누락 여부를 검사합니다. -11. `npm run lint`, `npm run build`를 실행합니다. -12. 검증에 성공하면 `references/release-pr-template.md`를 사용해 릴리즈 PR 본문을 작성합니다. -13. `[release] vX.Y.Z` 형식으로 `develop → main` 릴리즈 PR을 생성합니다. +11. `references/release-pr-template.md`를 사용해 릴리즈 PR 본문을 작성합니다. +12. `[release] vX.Y.Z` 형식으로 `develop → main` 릴리즈 PR을 생성합니다. ## Latest Release Tag -릴리즈 기준 태그는 다음 조건을 모두 만족하는 태그 중 버전이 가장 높은 태그를 사용합니다. +릴리즈 기준 태그는 `origin/main` 릴리즈 계보에서 접근 가능한 태그 중 다음 조건을 모두 만족하고 버전이 가장 높은 태그를 사용합니다. - 정확히 `vX.Y.Z` 형식인가 - Semantic Versioning 형식인가 - 버전 순으로 가장 높은 태그인가 +- 태그가 가리키는 커밋이 `origin/main` 이력에 포함되어 있는가 다음 태그는 릴리즈 기준으로 사용하지 않습니다. @@ -54,6 +54,8 @@ description: 엔빵의 프로덕션 릴리즈를 준비하고 develop에서 main 릴리즈 기준 태그가 없으면 버전을 자동으로 결정하지 않고 사용자에게 확인을 요청합니다. +전역에서 가장 높은 버전 태그가 있더라도 `origin/main` 릴리즈 계보에서 접근할 수 없다면 릴리즈 기준으로 사용하지 않습니다. + ## Release Range 릴리즈 대상 변경사항은 다음 범위를 기준으로 판단합니다. @@ -153,28 +155,6 @@ major > minor > patch - 동일 PR이 두 번 이상 포함되어 있는가 - 최신 태그 이전 변경사항이 잘못 포함되어 있는가 -## Validation - -릴리즈 PR 생성 전에 다음 명령을 순서대로 실행합니다. - -1. `npm run lint` -2. `npm run build` - -하나라도 실패하면 릴리즈 PR을 생성하지 않습니다. - -실패 시 다음 내용을 보고합니다. - -- 실패한 명령 -- 주요 오류 내용 -- 실패한 파일 또는 검사 영역 -- 릴리즈 PR을 생성하지 않았다는 사실 - -기존 저장소 문제인지 이번 릴리즈 변경 때문인지 확실한 근거 없이 추정하지 않습니다. - -기존 문제로 보이는 경우에도 검증이 실패했다면 릴리즈 PR 생성은 중단합니다. - -관련 테스트 명령이 존재하거나 변경사항에 필요한 경우 추가로 실행합니다. - ## Pull Request - Base branch: `main` @@ -189,7 +169,6 @@ major > minor > patch - 동일한 `develop → main` 열린 PR이 존재함 - 제안 버전 태그가 이미 존재함 - 변경사항 누락 검사가 실패함 -- lint 또는 build가 실패함 PR 생성 전 다음을 확인합니다. @@ -198,7 +177,6 @@ PR 생성 전 다음을 확인합니다. - 릴리즈할 변경사항이 존재하는가 - 동일한 버전의 릴리즈 PR이 존재하지 않는가 - 동일한 base와 head를 사용하는 열린 PR이 존재하지 않는가 -- lint와 build가 모두 성공했는가 ## Constraints diff --git a/.agents/skills/production-release/references/release-pr-template.md b/.agents/skills/production-release/references/release-pr-template.md index 90884f2..ffe67ac 100644 --- a/.agents/skills/production-release/references/release-pr-template.md +++ b/.agents/skills/production-release/references/release-pr-template.md @@ -32,11 +32,6 @@ -## 검증 - -- [x] `npm run lint` -- [x] `npm run build` -- [ ] 프로덕션 배포 확인 ``` ## Rules @@ -44,4 +39,3 @@ - PR 제목은 반드시 `[release] vX.Y.Z` 형식을 사용합니다. - PR 본문의 버전과 제목의 버전은 반드시 일치해야 합니다. - `release-note:start`와 `release-note:end` 사이의 내용은 이후 GitHub Release 본문으로 사용합니다. -- `검증` 섹션은 릴리즈 PR 검토를 위한 정보이며 GitHub Release에는 포함하지 않습니다. From 538ec460c92a20c3f33011611bec1a03726dd549 Mon Sep 17 00:00:00 2001 From: shinhm1 Date: Thu, 16 Jul 2026 02:42:00 +0900 Subject: [PATCH 24/25] =?UTF-8?q?ci:=20Vercel=20=EB=B0=B0=ED=8F=AC=20?= =?UTF-8?q?=EC=84=B1=EA=B3=B5=20=ED=9B=84=20=EB=A6=B4=EB=A6=AC=EC=A6=88=20?= =?UTF-8?q?=EC=9E=90=EB=8F=99=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/create-release-note.yml | 211 ++++++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 .github/workflows/create-release-note.yml diff --git a/.github/workflows/create-release-note.yml b/.github/workflows/create-release-note.yml new file mode 100644 index 0000000..14cd942 --- /dev/null +++ b/.github/workflows/create-release-note.yml @@ -0,0 +1,211 @@ +name: Create production release + +on: + status: + +permissions: + contents: write + pull-requests: read + +concurrency: + group: production-release-${{ github.event.sha }}-${{ github.event.context }}-${{ github.event.state }} + cancel-in-progress: false + +jobs: + create-release: + if: >- + github.event.context == 'Vercel' && + github.event.state == 'success' + runs-on: ubuntu-latest + env: + EVENT_SHA: ${{ github.event.sha }} + GH_TOKEN: ${{ github.token }} + + steps: + - name: Checkout main + uses: actions/checkout@v6 + with: + fetch-depth: 0 + ref: main + + - name: Verify latest main deployment + id: main + shell: bash + run: | + set -euo pipefail + + git fetch origin main --tags + + MAIN_SHA="$(git rev-parse origin/main)" + if [[ "$MAIN_SHA" != "$EVENT_SHA" ]]; then + echo "현재 main 최신 커밋의 배포가 아니므로 릴리즈를 생성하지 않습니다." + echo "event_sha=$EVENT_SHA" + echo "main_sha=$MAIN_SHA" + echo "eligible=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + + echo "Vercel 성공 상태가 현재 main 최신 커밋과 일치합니다: $EVENT_SHA" + echo "eligible=true" >> "$GITHUB_OUTPUT" + + - name: Resolve release pull request + if: steps.main.outputs.eligible == 'true' + id: release + shell: bash + run: | + set -euo pipefail + + PULLS_JSON="$( + gh api \ + -H "Accept: application/vnd.github+json" \ + "repos/${GITHUB_REPOSITORY}/commits/${EVENT_SHA}/pulls?per_page=100" + )" + + MATCHING_PULLS="$( + jq \ + --arg repository "$GITHUB_REPOSITORY" \ + '[ + .[] + | select( + .merged_at != null + and .base.ref == "main" + and .head.ref == "develop" + and .head.repo.full_name == $repository + and (.title | test("^\\[release\\] v[0-9]+\\.[0-9]+\\.[0-9]+$")) + ) + ]' \ + <<< "$PULLS_JSON" + )" + + PULL_COUNT="$(jq 'length' <<< "$MATCHING_PULLS")" + if [[ "$PULL_COUNT" -ne 1 ]]; then + echo "배포 SHA에 연결된 유효한 릴리즈 PR은 정확히 1개여야 합니다. 발견: $PULL_COUNT" >&2 + jq -r '.[] | "- #\(.number) \(.title) (\(.head.ref) -> \(.base.ref))"' <<< "$MATCHING_PULLS" >&2 + exit 1 + fi + + PR_NUMBER="$(jq -r '.[0].number' <<< "$MATCHING_PULLS")" + PR_TITLE="$(jq -r '.[0].title' <<< "$MATCHING_PULLS")" + PR_BODY="$(jq -r '.[0].body // ""' <<< "$MATCHING_PULLS")" + + if [[ "$PR_TITLE" =~ ^\[release\]\ (v[0-9]+\.[0-9]+\.[0-9]+)$ ]]; then + VERSION="${BASH_REMATCH[1]}" + else + echo "릴리즈 PR 제목 형식이 올바르지 않습니다: $PR_TITLE" >&2 + exit 1 + fi + + BODY_VERSION="$( + awk ' + /^## 릴리즈 버전[[:space:]]*$/ { in_version_section = 1; next } + in_version_section && /^## / { exit } + in_version_section && match($0, /`v[0-9]+\.[0-9]+\.[0-9]+`/) { + print substr($0, RSTART + 1, RLENGTH - 2) + exit + } + ' <<< "$PR_BODY" + )" + + if [[ "$BODY_VERSION" != "$VERSION" ]]; then + echo "릴리즈 PR 제목과 본문의 버전이 일치하지 않습니다." >&2 + echo "title_version=$VERSION" >&2 + echo "body_version=${BODY_VERSION:-missing}" >&2 + exit 1 + fi + + START_COUNT="$(grep -cF '' <<< "$PR_BODY" || true)" + END_COUNT="$(grep -cF '' <<< "$PR_BODY" || true)" + if [[ "$START_COUNT" -ne 1 || "$END_COUNT" -ne 1 ]]; then + echo "릴리즈 노트 시작/종료 마커가 각각 정확히 1개 필요합니다." >&2 + echo "start_count=$START_COUNT" >&2 + echo "end_count=$END_COUNT" >&2 + exit 1 + fi + + START_LINE="$(grep -nF '' <<< "$PR_BODY" | cut -d: -f1)" + END_LINE="$(grep -nF '' <<< "$PR_BODY" | cut -d: -f1)" + if [[ "$START_LINE" -ge "$END_LINE" ]]; then + echo "릴리즈 노트 마커의 순서가 올바르지 않습니다." >&2 + exit 1 + fi + + sed -n "$((START_LINE + 1)),$((END_LINE - 1))p" <<< "$PR_BODY" > release-notes.md + if [[ ! -s release-notes.md ]]; then + echo "릴리즈 PR에서 추출한 릴리즈 노트가 비어 있습니다." >&2 + exit 1 + fi + + echo "릴리즈 PR을 확인했습니다: #$PR_NUMBER $PR_TITLE" + echo "pr_number=$PR_NUMBER" >> "$GITHUB_OUTPUT" + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + + - name: Create or recover production release + if: steps.main.outputs.eligible == 'true' + shell: bash + env: + PR_NUMBER: ${{ steps.release.outputs.pr_number }} + VERSION: ${{ steps.release.outputs.version }} + run: | + set -euo pipefail + + TAG_REF="$(git ls-remote --tags origin "refs/tags/${VERSION}")" + if [[ -n "$TAG_REF" ]]; then + TAG_EXISTS=true + else + TAG_EXISTS=false + fi + + if gh api --silent "repos/${GITHUB_REPOSITORY}/releases/tags/${VERSION}" 2> release-error.txt; then + RELEASE_EXISTS=true + elif grep -q 'HTTP 404' release-error.txt; then + RELEASE_EXISTS=false + else + echo "GitHub Release 존재 여부를 확인하지 못했습니다." >&2 + cat release-error.txt >&2 + exit 1 + fi + + if [[ "$TAG_EXISTS" == true ]]; then + git fetch origin "refs/tags/${VERSION}:refs/tags/${VERSION}" + TAG_SHA="$(git rev-list -n 1 "$VERSION")" + if [[ "$TAG_SHA" != "$EVENT_SHA" ]]; then + echo "기존 태그가 현재 배포 SHA와 다른 커밋을 가리킵니다." >&2 + echo "version=$VERSION" >&2 + echo "tag_sha=$TAG_SHA" >&2 + echo "event_sha=$EVENT_SHA" >&2 + exit 1 + fi + fi + + if [[ "$TAG_EXISTS" == true && "$RELEASE_EXISTS" == true ]]; then + echo "태그와 GitHub Release가 이미 존재합니다: $VERSION" + exit 0 + fi + + if [[ "$TAG_EXISTS" == false && "$RELEASE_EXISTS" == true ]]; then + echo "GitHub Release는 존재하지만 대응하는 Git 태그가 없습니다: $VERSION" >&2 + exit 1 + fi + + if [[ "$TAG_EXISTS" == false ]]; then + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git tag -a "$VERSION" "$EVENT_SHA" -m "$VERSION" + git push origin "refs/tags/${VERSION}" + echo "배포 SHA에 태그를 생성했습니다: $VERSION -> $EVENT_SHA" + else + echo "기존 태그를 사용해 GitHub Release 생성을 재시도합니다: $VERSION" + fi + + gh release create "$VERSION" \ + --repo "$GITHUB_REPOSITORY" \ + --title "$VERSION" \ + --notes-file release-notes.md \ + --verify-tag + + { + echo "### Production release" + echo "- Version: \`$VERSION\`" + echo "- Commit: \`$EVENT_SHA\`" + echo "- Pull Request: #$PR_NUMBER" + } >> "$GITHUB_STEP_SUMMARY" From bcaca5b9f8044256dbf4ca2e2f8e13f1f05f2770 Mon Sep 17 00:00:00 2001 From: shinhm1 Date: Thu, 16 Jul 2026 02:58:28 +0900 Subject: [PATCH 25/25] =?UTF-8?q?fix:=20Vercel=20status=20=EC=B6=9C?= =?UTF-8?q?=EC=B2=98=20=EB=B0=8F=20=EB=A6=B4=EB=A6=AC=EC=A6=88=20=EB=85=B8?= =?UTF-8?q?=ED=8A=B8=20=EA=B2=80=EC=A6=9D=20=EA=B0=95=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/create-release-note.yml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/.github/workflows/create-release-note.yml b/.github/workflows/create-release-note.yml index 14cd942..1b15ce0 100644 --- a/.github/workflows/create-release-note.yml +++ b/.github/workflows/create-release-note.yml @@ -15,7 +15,9 @@ jobs: create-release: if: >- github.event.context == 'Vercel' && - github.event.state == 'success' + github.event.state == 'success' && + github.event.sender.login == 'vercel[bot]' && + startsWith(github.event.target_url, 'https://vercel.com/hm1n/nbread/') runs-on: ubuntu-latest env: EVENT_SHA: ${{ github.event.sha }} @@ -129,9 +131,14 @@ jobs: exit 1 fi + if [[ "$END_LINE" -le "$((START_LINE + 1))" ]]; then + echo "릴리즈 노트 마커 사이에 본문이 없습니다." >&2 + exit 1 + fi + sed -n "$((START_LINE + 1)),$((END_LINE - 1))p" <<< "$PR_BODY" > release-notes.md - if [[ ! -s release-notes.md ]]; then - echo "릴리즈 PR에서 추출한 릴리즈 노트가 비어 있습니다." >&2 + if ! grep -q '[^[:space:]]' release-notes.md; then + echo "릴리즈 PR에서 추출한 릴리즈 노트에 비공백 내용이 없습니다." >&2 exit 1 fi