[FIX] 지원서 날짜 밀림, 지원서 수정 안됨 버그 수정#408
Conversation
codex가 프로젝트를 이해하는데 가이드 역할을 하는 AGENT.MD파일들을 생성했습니다.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Walkthrough여러 디렉터리(루트, apps/web/app, apps/web/app/_api, apps/web/app/admin, packages/shared)에 AGENTS.md 문서를 신규 추가했다. 또한 지원서 편집 화면의 편집 가능 범위 계산을 isRecruiting에서 canEditForm/canEditContent로 분리하고, 날짜 포맷팅을 UTC 대신 로컬 타임존 기준(parseLocalDate)으로 변경했다. ChangesAGENTS.md 문서 추가
Estimated code review effort: 2 (Simple) | ~10 minutes 지원서 생성/편집 날짜 및 권한 로직 수정
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant FormEditPage
participant useFormEdit
participant transformFormData
User->>FormEditPage: 편집 모드 진입
FormEditPage->>useFormEdit: canEditForm/canEditContent 조회
useFormEdit->>useFormEdit: startDate/endDate 기준 권한 계산
useFormEdit-->>FormEditPage: canEditForm, canEditContent 반환
FormEditPage->>FormEditPage: readOnly = !isEditing || !canEditContent 적용
User->>FormEditPage: 저장 클릭
FormEditPage->>useFormEdit: handleSave 호출
alt canEditContent true
useFormEdit->>useFormEdit: validateBasicInfo, validateQuestions
useFormEdit->>transformFormData: formatFormData(basicInfo, sections, formField)
else canEditContent false
useFormEdit->>useFormEdit: startDate/endDate 누락 검증
useFormEdit->>useFormEdit: formatDate로 모집 기간만 재구성
end
useFormEdit-->>FormEditPage: 저장 payload 반환
Estimated code review effort: 3 (Moderate) | ~25 minutes Related issues: Suggested labels: documentation, bug Suggested reviewers: COW-dev 팀 리뷰어 🐰 로컬 시간에 발 맞춰 뛰는 토끼, 🚥 Pre-merge checks | ✅ 2 | ❌ 3❌ Failed checks (3 warnings)
✅ Passed checks (2 passed)
✨ 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 |
|
Update: 2026년 07월 01일 20시 43분 27초 |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 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 `@apps/web/app/admin/apply/`[id]/edit/_hooks/useFormEdit.ts:
- Around line 30-53: `useFormEdit`의 `useMemo`가 `formData.startDate`와
`formData.endDate`만 의존해서 자정을 넘겨도 `canEditForm`/`canEditContent`가 갱신되지 않는 문제를
수정하세요. `handleSave()`가 최신 날짜 기준으로 권한을 다시 판단하도록, 현재 날짜를 상태/의존성에 포함해 갱신되게 하거나 저장
시점에 `parseLocalDate`와 `today`를 기준으로 재계산하도록 `useFormEdit`의 권한 계산 로직을 조정하세요.
In `@apps/web/app/admin/apply/new/_utils/format.ts`:
- Around line 10-29: The date helper is currently scoped too narrowly under the
new apply route, but it is now reused by edit-related code as well. Move the
shared formatting logic from parseLocalDate and formatDate into an apply-level
utility location such as apps/web/app/admin/apply/_utils/format.ts, then update
the imports in transformFormData and useFormEdit to reference the new shared
path. Keep the helper within the admin apply domain boundary rather than tying
edit to the new route’s internal _utils folder.
- Line 16: Remove the remaining debug console output from parseLocalDate() in
format.ts by deleting the console.log(date) statement. Keep the function
behavior unchanged so repeated calls from the admin apply flow no longer emit
date values to the browser console.
🪄 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
Run ID: 88e5fff9-4d19-4518-99bb-1dc4abb7b458
📒 Files selected for processing (10)
AGENTS.mdapps/web/app/AGENTS.mdapps/web/app/_api/AGENTS.mdapps/web/app/admin/AGENTS.mdapps/web/app/admin/apply/[id]/edit/_hooks/useFormEdit.tsapps/web/app/admin/apply/[id]/edit/_pages/FormEditPage.tsxapps/web/app/admin/apply/[id]/edit/_utils/transformFormData.tsapps/web/app/admin/apply/new/_components/FormHeaderSection.tsxapps/web/app/admin/apply/new/_utils/format.tspackages/shared/AGENTS.md
| const { canEditForm, canEditContent } = useMemo(() => { | ||
| if (!formData.startDate || !formData.endDate) { | ||
| return { | ||
| canEditForm: false, | ||
| canEditContent: false, | ||
| }; | ||
| } | ||
| const today = new Date(); | ||
| today.setHours(0, 0, 0, 0); | ||
| const startDate = new Date(formData.startDate); | ||
| const startDate = parseLocalDate(formData.startDate); | ||
| startDate.setHours(0, 0, 0, 0); | ||
| const endDate = new Date(formData.endDate); | ||
| const endDate = parseLocalDate(formData.endDate); | ||
| endDate.setHours(0, 0, 0, 0); | ||
|
|
||
| return ( | ||
| const isBeforeRecruiting = today.getTime() < startDate.getTime(); | ||
| const isRecruiting = | ||
| startDate.getTime() <= today.getTime() && | ||
| today.getTime() <= endDate.getTime() | ||
| ); | ||
| today.getTime() <= endDate.getTime(); | ||
|
|
||
| return { | ||
| canEditForm: isBeforeRecruiting || isRecruiting, | ||
| canEditContent: isBeforeRecruiting, | ||
| }; | ||
| }, [formData.startDate, formData.endDate]); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
권한 계산이 날짜 경계 이후에도 고정됩니다.
canEditForm/canEditContent가 formData.startDate와 formData.endDate 변경에만 묶여 있어서, 페이지를 열어 둔 채 모집 시작일/종료일 자정을 넘기면 값이 그대로 남습니다. 그 상태에서 handleSave()도 같은 캐시 값을 사용하므로, 실제로는 수정이 막혀야 하는 시점 이후에도 저장이 통과할 수 있습니다.
제안
+const getEditPermissions = (
+ startDateText?: string | null,
+ endDateText?: string | null,
+) => {
+ if (!startDateText || !endDateText) {
+ return { canEditForm: false, canEditContent: false };
+ }
+
+ const today = new Date();
+ today.setHours(0, 0, 0, 0);
+
+ const startDate = parseLocalDate(startDateText);
+ startDate.setHours(0, 0, 0, 0);
+
+ const endDate = parseLocalDate(endDateText);
+ endDate.setHours(0, 0, 0, 0);
+
+ const isBeforeRecruiting = today.getTime() < startDate.getTime();
+ const isRecruiting =
+ startDate.getTime() <= today.getTime() &&
+ today.getTime() <= endDate.getTime();
+
+ return {
+ canEditForm: isBeforeRecruiting || isRecruiting,
+ canEditContent: isBeforeRecruiting,
+ };
+};
+
-const { canEditForm, canEditContent } = useMemo(() => {
- ...
-}, [formData.startDate, formData.endDate]);
+const { canEditForm, canEditContent } = getEditPermissions(
+ formData.startDate,
+ formData.endDate,
+);
...
const handleSave = () => {
- if (canEditContent && !validateBasicInfo(basicInfo)) {
+ const currentPermissions = getEditPermissions(
+ formData.startDate,
+ formData.endDate,
+ );
+
+ if (!currentPermissions.canEditForm) {
+ toast.error('더 이상 지원서를 수정할 수 없습니다.');
+ return;
+ }
+
+ if (currentPermissions.canEditContent && !validateBasicInfo(basicInfo)) {
return;
}Also applies to: 98-149
🤖 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 `@apps/web/app/admin/apply/`[id]/edit/_hooks/useFormEdit.ts around lines 30 -
53, `useFormEdit`의 `useMemo`가 `formData.startDate`와 `formData.endDate`만 의존해서 자정을
넘겨도 `canEditForm`/`canEditContent`가 갱신되지 않는 문제를 수정하세요. `handleSave()`가 최신 날짜
기준으로 권한을 다시 판단하도록, 현재 날짜를 상태/의존성에 포함해 갱신되게 하거나 저장 시점에 `parseLocalDate`와 `today`를
기준으로 재계산하도록 `useFormEdit`의 권한 계산 로직을 조정하세요.
| export function parseLocalDate(date: string): Date { | ||
| const [yearText, monthText, dayText] = date.split('-'); | ||
|
|
||
| if (!yearText || !monthText || !dayText) { | ||
| return new Date(date); | ||
| } | ||
| console.log(date); | ||
|
|
||
| return new Date(Number(yearText), Number(monthText) - 1, Number(dayText)); | ||
| } | ||
|
|
||
| export function formatDate(date: Date | string | null): string { | ||
| if (!date) return ''; | ||
| if (date instanceof Date) return date.toISOString().split('T')[0]; | ||
| return new Date(date).toISOString().split('T')[0]; | ||
|
|
||
| const localDate = date instanceof Date ? date : parseLocalDate(date); | ||
| const year = localDate.getFullYear(); | ||
| const month = String(localDate.getMonth() + 1).padStart(2, '0'); | ||
| const day = String(localDate.getDate()).padStart(2, '0'); | ||
|
|
||
| return `${year}-${month}-${day}`; |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win
이 날짜 유틸은 apply 공용 위치로 올려주세요.
이제 이 파일이 apps/web/app/admin/apply/[id]/edit/_utils/transformFormData.ts:3와 apps/web/app/admin/apply/[id]/edit/_hooks/useFormEdit.ts:11-15에서도 쓰이므로, /new/_utils에 두면 edit 라우트가 new 라우트 내부 구현에 직접 결합됩니다. apps/web/app/admin/apply/_utils/format.ts 같은 apply 레벨 공용 위치로 승격하는 편이 현재 사용 범위와 경계에 맞습니다.
As per coding guidelines, "Keep admin feature code inside its domain route folder..." and "Do not move admin-only helpers to app-wide _utils just because another admin file imports them; keep the route boundary tight until reused outside admin." Based on learnings, "Keep route-specific code inside the route folder; promote it to app-wide _components, _hooks, _utils, or _constants only when it is reused across multiple routes."
🤖 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 `@apps/web/app/admin/apply/new/_utils/format.ts` around lines 10 - 29, The date
helper is currently scoped too narrowly under the new apply route, but it is now
reused by edit-related code as well. Move the shared formatting logic from
parseLocalDate and formatDate into an apply-level utility location such as
apps/web/app/admin/apply/_utils/format.ts, then update the imports in
transformFormData and useFormEdit to reference the new shared path. Keep the
helper within the admin apply domain boundary rather than tying edit to the new
route’s internal _utils folder.
Sources: Coding guidelines, Learnings
| if (!yearText || !monthText || !dayText) { | ||
| return new Date(date); | ||
| } | ||
| console.log(date); |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
디버그 로그는 제거해주세요.
parseLocalDate()가 초기 렌더, 권한 계산, 저장 포맷팅에서 반복 호출돼서 날짜값이 운영 브라우저 콘솔에 계속 남습니다.
제안
- console.log(date);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| console.log(date); |
🤖 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 `@apps/web/app/admin/apply/new/_utils/format.ts` at line 16, Remove the
remaining debug console output from parseLocalDate() in format.ts by deleting
the console.log(date) statement. Keep the function behavior unchanged so
repeated calls from the admin apply flow no longer emit date values to the
browser console.
🔥 연관 이슈
🚀 작업 내용
날짜 밀림 버그
기존 문제는 toISOString()이 항상 UTC 기준 문자열을 만들기 때문에, 한국 시간 2026-07-01 00:00 같은 로컬 날짜가 UTC로는 2026-06-30T15:00:00.000Z가 되면서 날짜가 하루 앞당겨질 수 있었습니다.
이번 수정은: API에서 받은 '2026-07-01' 문자열을 new Date('2026-07-01')로 바로 만들지 않고 year, month, day를 직접 쪼개서
new Date(2026, 6, 1)처럼 로컬 날짜 객체로 만들고 다시 API에 보낼 때도 toISOString()을 쓰지 않고 getFullYear(), getMonth(), getDate()로 YYYY-MM-DD를 직접 조립해서 결과를 리턴했습니다.
지원서 수정 안되는 버그
useFormEdit.ts에는 canEditForm, canEditContent 계산이 들어가 있었습니다.
그런데 FormEditPage.tsx는 여전히 기존 값인 isRecruiting을 쓰고 있었습니다.
FormHeaderSection.tsx도 여전히 readOnly 하나로 제목/설명/모집기간을 같이 잠그고 있었습니다.
🤔 고민했던 내용
지원서 수정이 안되는 버그를 수정하며 값을 명시 시키는게 좋다고 생각하여 handelBasicInfoChange 함수가 길어졌는데 이런 부분이 괜찮을지 궁금합니다.
💬 리뷰 중점사항
제가 이해하고 있는 것으로는 모집일 전, 그리고 모집일 이후 지원서 날짜 변경이 가능한 것으로 알고있습니다.
혹여나 제가 이해하고 있는게 다를 수 있어 피드백 주시면 수정하겠습니다.
Summary by CodeRabbit
Bug Fixes
Documentation