feat: 모임 생성 1단계 기본 정보 입력 화면 UI 개편 및 홈 리다이렉트 추가 - #71
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Caution Review failedPull request was closed or merged during review Summary by CodeRabbit변경 사항
Walkthrough루트 페이지( Changes대시보드 인증 및 시각화
일정 생성 Step1 폼 개편
Sequence Diagram(s)sequenceDiagram
participant Browser as 브라우저
participant Home as Home (async)
participant SupabaseAuth as Supabase Auth
participant DashboardPage as DashboardPage
participant Prisma as Prisma
participant SchedulerUI as SchedulerPreview
Browser->>Home: GET /
Home->>SupabaseAuth: getUser()
SupabaseAuth-->>Home: user | null
alt user 존재
Home->>Browser: redirect('/dashboard')
Browser->>DashboardPage: GET /dashboard
DashboardPage->>SupabaseAuth: getUser()
SupabaseAuth-->>DashboardPage: user (인증 완료)
DashboardPage->>Prisma: findMany({ creatorId }, orderBy createdAt desc)
Prisma-->>DashboardPage: Schedule[]
DashboardPage->>SchedulerUI: schedules={schedules}
SchedulerUI-->>DashboardPage: 렌더링 (캘린더·"내 모임")
else user 없음
Home-->>Browser: 랜딩 페이지 렌더링
end
추정 리뷰 노력🎯 3 (Moderate) | ⏱️ ~25 minutes 관련 PR
Suggested Labels
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/app/schedule/create/CreateScheduleClient.tsx`:
- Around line 322-324: The durationMinutes parsing logic has two issues: it
lacks frontend range validation (should be 15-480 per the backend schema) and
uses a silent fallback to 60 minutes when parsing fails, which can submit
unintended values without user awareness. Add explicit range validation in the
validateScheduleForm function to check that the parsed duration falls between 15
and 480 minutes, and remove the `|| 60` fallback from the parsing logic (around
line 322-324 and the consolidated site at 332-333) to throw a validation error
instead of silently defaulting, ensuring users receive immediate feedback before
submission rather than getting a 422 error from the backend.
- Around line 470-482: The responseDeadline field in CreateScheduleClient.tsx
lacks validation logic, allowing users to set deadline times in the past or at
illogical times relative to the candidate date range. Add validation when the
user changes the responseDeadline value (in the onChange handler) or during form
submission to ensure the deadline is a future date-time and falls within a
reasonable window relative to the candidate dates. This validation should check
that responseDeadline is greater than the current time and logically positioned
within the candidate date range so participants have adequate time to respond.
- Around line 432-441: The placeholder text "예: 2시간, 반나절" in the input field
creates a mismatch with the actual parsing logic which only extracts numbers.
Users will expect natural language input to work but will instead get incorrect
durations (e.g., "2시간" becomes 2 minutes instead of 120 minutes). Update the
placeholder attribute in the input element to clearly specify the expected
format as minutes-only numeric input (e.g., "예: 120 (분 단위)"), and consider
adding explanatory text or a helper label near the input field to guide users on
the correct input format and provide examples of valid numeric entries.
- Around line 59-60: The durationMinutes state variable is declared as a string
but semantically represents a number (minutes of duration), causing a
type-meaning mismatch. Either change durationMinutes to use number type by
updating useState to initialize with a number value and adjusting the input
element to type="number", or alternatively, rename the state variable to
durationInput to clarify it represents a user input string. Choose the preferred
approach and ensure the state declaration, input element type, and any related
logic that uses this state are all updated consistently.
- Around line 443-468: Add client-side validation for the candidate date range
defined by candidateStartDate and candidateEndDate. Implement three validations:
(1) ensure candidateEndDate is after candidateStartDate, (2) ensure neither date
is in the past, and (3) verify that the selected date range is consistent with
the day-of-week selections from Step 3 (i.e., at least one of the selected
weekdays must fall within the date range). Add these validations either when
transitioning from Step 1 to Step 2 or during form submission, and display
appropriate error messages to the user when any validation fails. Reference the
state setters for candidateStartDate and candidateEndDate when implementing
these checks.
- Around line 59-63: The date state variables candidateStartDate,
candidateEndDate, and responseDeadline are defined as state hooks but are not
included in the POST request body sent to the server (around lines 330-337),
causing the user-entered date data to be lost. Add these three date fields to
the request payload when creating the schedule. Additionally, ensure the backend
schema file (src/features/schedules/schedule.schema.ts) includes these same
three date fields in the createScheduleSchema so the server accepts and
validates them properly. If these fields are intended to be client-only for
reference purposes, add explicit comments to clarify and update the UI
accordingly.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 77abb369-0439-4b21-b2bd-65eec08b1bd1
📒 Files selected for processing (2)
src/app/page.tsxsrc/app/schedule/create/CreateScheduleClient.tsx
| const [title, setTitle] = useState(""); | ||
| const [durationMinutes, setDurationMinutes] = useState(""); |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial | ⚖️ Poor tradeoff
소요시간 상태 타입 불일치 (유지보수성 저하)
durationMinutes를 string으로 선언했지만 의미론적으로는 숫자(분 단위 시간)를 나타냄. 이는 코드 가독성을 떨어뜨리고, 향후 유지보수 시 혼란을 야기할 수 있음.
Why: 타입과 의미가 일치하지 않으면 다른 개발자가 코드를 읽을 때 "왜 숫자가 아니라 문자열이지?"라는 의문을 갖게 됨. 또한 숫자 연산 시 매번 파싱이 필요함.
How:
- 권장: input을
type="number"로 변경하고 상태를number로 관리 - 대안: 상태는
string유지하되 이름을durationInput처럼 변경해 "사용자 입력값"임을 명시
♻️ 타입 일치 리팩터링안 (권장하지만 선택)
- const [durationMinutes, setDurationMinutes] = useState("");
+ const [durationMinutes, setDurationMinutes] = useState<number>(60);그리고 input 변경:
<input
+ type="number"
+ min="15"
+ max="480"
+ step="15"
value={durationMinutes}
- onChange={(event) => setDurationMinutes(event.target.value)}
+ onChange={(event) => setDurationMinutes(Number(event.target.value))}그리고 submit 로직 단순화:
- durationMinutes: String(
- parseInt(durationMinutes.replace(/[^0-9]/g, "")) || 60,
- ),
+ durationMinutes: String(durationMinutes),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/app/schedule/create/CreateScheduleClient.tsx` around lines 59 - 60, The
durationMinutes state variable is declared as a string but semantically
represents a number (minutes of duration), causing a type-meaning mismatch.
Either change durationMinutes to use number type by updating useState to
initialize with a number value and adjusting the input element to type="number",
or alternatively, rename the state variable to durationInput to clarify it
represents a user input string. Choose the preferred approach and ensure the
state declaration, input element type, and any related logic that uses this
state are all updated consistently.
| <div className="grid grid-cols-2 gap-4"> | ||
| <label className="grid gap-3 text-sm font-bold text-brand-text-primary"> | ||
| 후보 날짜 범위 (시작) | ||
| <input | ||
| type="date" | ||
| value={candidateStartDate} | ||
| onChange={(event) => | ||
| setCandidateStartDate(event.target.value) | ||
| } | ||
| className="h-12 rounded-xl border border-brand-border-gray px-4 text-base font-normal outline-none focus:border-brand-purple-light focus:ring-2 focus:ring-brand-purple-ring transition-all text-brand-text-primary" | ||
| required | ||
| /> | ||
| </label> | ||
| <label className="grid gap-3 text-sm font-bold text-brand-text-primary"> | ||
| 후보 날짜 범위 (종료) | ||
| <input | ||
| type="date" | ||
| value={candidateEndDate} | ||
| onChange={(event) => | ||
| setCandidateEndDate(event.target.value) | ||
| } | ||
| className="h-12 rounded-xl border border-brand-border-gray px-4 text-base font-normal outline-none focus:border-brand-purple-light focus:ring-2 focus:ring-brand-purple-ring transition-all text-brand-text-primary" | ||
| required | ||
| /> | ||
| </label> | ||
| </div> |
There was a problem hiding this comment.
후보 날짜 범위 검증 로직 누락 (데이터 무결성 위험)
- 시작일 < 종료일 검증 없음: 사용자가 종료일을 시작일보다 이전으로 설정해도 막지 않음.
- 과거 날짜 검증 없음: 사용자가 과거 날짜를 선택해도 허용됨.
- 요일 선택과의 정합성 미검증: 날짜 범위가 월~금요일인데 Step 3에서 토요일만 선택하면 실제 후보 시간이 없는 모순 발생 가능.
Why: 잘못된 날짜 범위는 일정 조율 알고리즘을 무의미하게 만들고, 사용자 혼란을 야기함. 백엔드 검증만으로는 UX가 떨어짐.
How: 클라이언트 측에서 즉시 검증하고 에러 메시지를 표시해야 함.
🔍 날짜 범위 검증 추가안
+ {candidateStartDate && candidateEndDate && candidateStartDate > candidateEndDate && (
+ <p className="text-sm text-destructive font-semibold">
+ 종료일은 시작일보다 늦어야 합니다.
+ </p>
+ )}그리고 handleSubmit 또는 Step 1→2 전환 시점에 검증:
<div className="pt-4 flex justify-end">
<PurpleButton
type="button"
- onClick={() => setStep(2)}
+ onClick={() => {
+ if (!title.trim()) {
+ setError("모임 제목을 입력해 주세요.");
+ return;
+ }
+ if (!candidateStartDate || !candidateEndDate) {
+ setError("후보 날짜 범위를 모두 입력해 주세요.");
+ return;
+ }
+ if (candidateStartDate > candidateEndDate) {
+ setError("종료일은 시작일보다 늦어야 합니다.");
+ return;
+ }
+ const today = new Date().toISOString().split('T')[0];
+ if (candidateStartDate < today) {
+ setError("시작일은 오늘 이후여야 합니다.");
+ return;
+ }
+ setError("");
+ setStep(2);
+ }}
className="px-6 text-sm font-bold tracking-wide active:scale-95"
>
다음 단계로 →
</PurpleButton>🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/app/schedule/create/CreateScheduleClient.tsx` around lines 443 - 468, Add
client-side validation for the candidate date range defined by
candidateStartDate and candidateEndDate. Implement three validations: (1) ensure
candidateEndDate is after candidateStartDate, (2) ensure neither date is in the
past, and (3) verify that the selected date range is consistent with the
day-of-week selections from Step 3 (i.e., at least one of the selected weekdays
must fall within the date range). Add these validations either when
transitioning from Step 1 to Step 2 or during form submission, and display
appropriate error messages to the user when any validation fails. Reference the
state setters for candidateStartDate and candidateEndDate when implementing
these checks.
#71에서 소요시간이 select→자유입력 필드로 바뀌며 기본값이 비어 제출이 막혀 5개 테스트가 4단계에 도달하지 못하던 문제를 해결. 헬퍼에서 "예상 소요시간"을 채운 뒤 단계 진행하도록 수정. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
#71에서 소요시간이 select→자유입력으로 바뀌며 getByLabel("소요 시간")
.selectOption이 타임아웃되던 문제를 "예상 소요시간" 입력으로 수정.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
🚀 작업 내용 (What)
📣 핵심 변경 이유 (Why)
📸 스크린샷 (Visuals, 선택)
🔗 관련 이슈 (Issue)
Close #