[Refactor/#137] 타입 위치 변경, 구조 정리#140
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthrough로컬에 흩어졌던 타입/DTO를 src/types/*로 통합하고, API 엔드포인트·어댑터·훅·컴포넌트·페이지에서 인라인 타입을 제거해 공용 타입(주로 interface)과 ApiResponse 제네릭으로 통일했습니다. 일부 UI에서 state 업데이트 안전성(functional updater)과 매핑(shape) 조정이 포함됩니다. Changes타입 구조 중앙화 및 통합
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. 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 |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/components/owner/MenuManagement.tsx (1)
51-58:⚠️ Potential issue | 🟡 Minor | ⚡ Quick win카테고리 강제 캐스팅 대신 런타임 정규화가 안전합니다.
(s.category as MenuCategory)는 서버에서 예상 외 문자열이 와도 그대로 통과되어 필터/표시 불일치가 생길 수 있습니다. 허용 목록 체크 후 fallback을 두는 쪽이 안전합니다.예시 수정
+const MENU_CATEGORIES: MenuCategory[] = ["MAIN", "SIDE", "BEVERAGE", "ALCOHOL"]; + +const normalizeCategory = (category: unknown): MenuCategory => + typeof category === "string" && MENU_CATEGORIES.includes(category as MenuCategory) + ? (category as MenuCategory) + : "MAIN"; + const mapServerToLocal = (s: MenuDraft, restaurantId?: string): MenuItem => ({ id: String(s.menuId ?? `MENU_${crypto.randomUUID()}`), restaurantId: restaurantId ?? "", name: s.name ?? "", description: s.description ?? "", price: s.price ?? 0, - category: (s.category as MenuCategory) ?? "MAIN", + category: normalizeCategory(s.category), imageUrl: s.imageUrl ?? undefined, isSoldOut: s.isSoldOut ?? false, isActive: s.isActive ?? true, });Also applies to: 89-90
🤖 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/components/owner/MenuManagement.tsx` around lines 51 - 58, Replace the unsafe type cast (s.category as MenuCategory) in mapServerToLocal with runtime normalization: check s.category against the allowed MenuCategory values (e.g., via Object.values(MenuCategory) or a small allowedCategories array) and use that value only if it matches, otherwise fallback to "MAIN"; do the same runtime validation for the other mapping site that reads s.category (the similar s.category handling around lines 89-90) so unexpected server strings cannot slip through.src/api/endpoints/reservations.ts (1)
38-38:⚠️ Potential issue | 🟡 Minor | ⚡ Quick win
!data.isSuccess에서 옵셔널 체이닝 누락같은 파일의
getAvailableTimes(Line 21)와createBooking(Line 58)은 모두!data?.isSuccess를 사용하는데,getAvailableTables만!data.isSuccess입니다.data가 드물게undefined/null인 상황에서 에러 분기 대신TypeError가 던져질 수 있습니다.🛠️ 제안 수정
- if (!data.isSuccess) { + if (!data?.isSuccess) {🤖 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/api/endpoints/reservations.ts` at line 38, The if-check in getAvailableTables currently uses a direct property access (if (!data.isSuccess)) which can throw when data is null/undefined; change the condition to use optional chaining (check !data?.isSuccess) so it matches getAvailableTimes and createBooking and safely handles when the response `data` is undefined; update the `getAvailableTables` branch where `data` is inspected to use `data?.isSuccess`.
🧹 Nitpick comments (11)
src/components/reservation/parts/TableMap.tsx (1)
4-11: ⚡ Quick win
Props대신TableMapProps로 명시적으로 이름 붙여주세요.현재 동작에는 문제 없지만, 컴포넌트별 props 타입 식별성이 떨어집니다. 타입 이동/재사용이 많은 PR 맥락에서는
TableMapProps처럼 구체 이름이 유지보수에 더 유리합니다.예시 변경
-interface Props { +interface TableMapProps { layout: SeatLayout; availableIds: Set<number>; selectedTableId: number | null; seatType: SeatType | null; onSelectTable: (tableId: number) => void; onSelectSeatType: (seatType: SeatType) => void; } export default function TableMap({ layout, availableIds, selectedTableId, seatType, onSelectTable, onSelectSeatType, -}: Props) { +}: TableMapProps) {As per coding guidelines,
src/components/**: "컴포넌트는 단일 책임, props 타입/네이밍 명확히, 접근성(aria) 체크."🤖 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/components/reservation/parts/TableMap.tsx` around lines 4 - 11, Rename the generic interface Props to a more specific TableMapProps and update all local references accordingly: change the interface declaration interface Props { ... } to interface TableMapProps { ... } and update the TableMap component type annotations/usages (e.g., React.FC<Props>, function parameters or any exported type names) to use TableMapProps; ensure any other local variables, exports or imports inside TableMap.tsx that referenced Props are updated to TableMapProps so the component props type remains explicit and reusable.src/types/booking.ts (1)
55-55: 💤 Low value
UserBookingItem = BookingListItem별칭이 중복이에요
BookingListItem과 완전히 동일한 타입을 가리키는 별칭이라면 유지 비용만 생깁니다.UserBookingItem을 직접BookingListItem으로 교체하거나, 두 타입 간에 의미상 차이가 생길 예정이라면 그 의도를 주석으로 남겨 주세요.🤖 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/types/booking.ts` at line 55, UserBookingItem is currently just a redundant alias of BookingListItem; remove maintenance overhead by replacing all uses of UserBookingItem with BookingListItem, or if you intend them to diverge later, keep the alias and add a clarifying comment above the declaration explaining the semantic distinction and future divergence plan (referencing the UserBookingItem and BookingListItem symbols to locate the code).src/types/reservation.ts (3)
1-12: 💤 Low value
Slot.status와SlotStatus간 의도 주석이 있으면 좋겠어요
Slot.status는"AVAILABLE" | "BOOKED" | "BLOCKED"3가지이고,SlotStatus(수정 요청용)는"AVAILABLE" | "BLOCKED"2가지예요."BOOKED"는 시스템이 자동으로 설정하는 값이라 수동 설정이 불가하다는 의도인 것 같은데, 짧은 주석 하나면 나중에 읽는 사람이 헷갈리지 않아요.💡 예시
+/** 슬롯 상태 수정 시 허용 값 (BOOKED는 시스템 전용이므로 제외) */ export type SlotStatus = "AVAILABLE" | "BLOCKED";🤖 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/types/reservation.ts` around lines 1 - 12, Add a short clarifying comment explaining the difference between Slot.status and SlotStatus: note that Slot.status (in the Slot interface) can be "AVAILABLE" | "BOOKED" | "BLOCKED" and that "BOOKED" is set by the system (not manually editable), whereas SlotStatus (the type) only includes "AVAILABLE" | "BLOCKED" and is intended for manual/patch operations; place the comment near the Slot interface’s status field and/or above the SlotStatus type to prevent future confusion.
84-94: ⚡ Quick win
status: "PENDING" | "CONFIRMED" | string도 동일한 문제예요Line 86의
status필드도 위와 동일하게| string이 리터럴 유니언을 흡수해버려요. 실제로 백엔드가 내려줄 수 있는 상태값을 모두 열거하거나,(string & {})를 사용하는 걸 권장해요.💡 제안
export interface CreateBookingResult { bookingId: number; - status: "PENDING" | "CONFIRMED" | string; + status: "PENDING" | "CONFIRMED" | "CANCELLED" | (string & {}); storeName: string; // ... }🤖 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/types/reservation.ts` around lines 84 - 94, The CreateBookingResult.type for status currently uses the broad union ' "PENDING" | "CONFIRMED" | string' which collapses the string literals; update the status definition in the CreateBookingResult interface to either enumerate all expected backend status literals (e.g., include any other known values) or replace the trailing '| string' with the open-ended type pattern '(string & {})' so the literals remain distinct (modify the status field on CreateBookingResult accordingly).
48-48: ⚡ Quick win
| string때문에 리터럴 유니언이 사실상 무력화돼요TypeScript에서
"WINDOW" | "GENERAL" | string은 컴파일러가string으로 평탄화해버려서"WINDOW","GENERAL"리터럴이 타입 검사에 전혀 기여하지 못해요. IDE 자동완성 힌트도 사라지고 오타가 있어도 컴파일 오류가 안 나요.
- API가 정해진 값만 내려준다면
| string을 제거해 완전히 좁히는 게 제일 좋아요.- API에서 확장된 값이 올 수 있다면
(string & {})패턴을 쓰면 IDE 힌트는 살리면서 임의 문자열도 허용해요.💡 제안
-export type SeatsTypes = "WINDOW" | "GENERAL" | string; +// 값이 고정돼 있을 때 +export type SeatsTypes = "WINDOW" | "GENERAL" | "ROOM" | "BAR" | "OUTDOOR"; +// 또는 확장 가능성을 열어둘 때 (IDE 힌트 유지) +export type SeatsTypes = "WINDOW" | "GENERAL" | "ROOM" | "BAR" | "OUTDOOR" | (string & {});참고로
AddTableModal.tsx의<option>값들("ROOM","BAR","OUTDOOR")도 현재SeatsTypes에 없어서 타입 불일치가 발생해요.🤖 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/types/reservation.ts` at line 48, The SeatsTypes union is being flattened by the trailing "| string" so the literal members ("WINDOW" | "GENERAL") lose type-checking and IDE hints; either remove "| string" to lock SeatsTypes to the known literals, or if you must allow unknown values change the type to the open-but-literal-friendly pattern (string & {}) for SeatsTypes; also update the literal set to include the values used in AddTableModal.tsx (e.g., "ROOM", "BAR", "OUTDOOR") so the option values match the SeatsTypes union and avoid type mismatches.src/types/payment.ts (1)
11-20: 💤 Low value
status/paymentMethod/paymentProvider필드 타입 보강 고려현재 세 필드가 순수
string이라 오타나 API 계약 이탈을 컴파일 타임에 잡지 못해요. 백엔드가 내려주는 실제 값이 고정돼 있다면 리터럴 유니언으로 좁혀두면 좋겠어요.💡 예시
export interface PaymentConfirmResult { paymentId: number; - status: string; + status: "PENDING" | "COMPLETED" | "FAILED" | "CANCELLED" | (string & {}); approvedAt: string; orderId: string; amount: number; - paymentMethod: string; - paymentProvider: string; + paymentMethod: "CARD" | "VIRTUAL_ACCOUNT" | (string & {}); + paymentProvider: "TOSS" | (string & {}); receiptUrl: string; }백엔드 스펙이 아직 유동적이라면
(string & {})패턴만 써도 IDE 힌트를 유지하면서 임의 문자열도 허용할 수 있어요.🤖 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/types/payment.ts` around lines 11 - 20, The PaymentConfirmResult interface currently types status, paymentMethod, and paymentProvider as plain strings; narrow them to safer types by replacing those fields with either literal union types of the known backend values (e.g., 'PAID' | 'PENDING' | 'FAILED' for status, specific provider/method strings) or, if the backend is still fluid, use the (string & {}) pattern to preserve IDE completions while allowing unknown values; update the PaymentConfirmResult declaration accordingly so consumers get compile-time checks or helpful IDE hints.src/api/endpoints/reservations.ts (1)
31-46: ⚡ Quick win
getAvailableTables반환 타입 명시 권장함수 반환 타입이 명시되어 있지 않아
data.result의 타입 (AvailableTablesResult | undefined | null)이 그대로 추론됩니다. 호출부에서undefined를 기대하지 않을 경우 런타임 오류로 이어질 수 있습니다.✨ 제안 수정
-export async function getAvailableTables(params: GetAvailableTablesParams) { +export async function getAvailableTables( + params: GetAvailableTablesParams, +): Promise<AvailableTablesResult> { const { storeId, ...query } = params; const { data } = await api.get<ApiResponse<AvailableTablesResult>>( `/api/v1/stores/${storeId}/bookings/available-tables`, { params: query }, ); if (!data?.isSuccess) { throw { status: 0, code: data?.code, message: data?.message ?? "예약 가능 테이블 조회를 실패하였습니다.", }; } - return data.result; + return data.result!; }
data.result가isSuccess === true일 때 항상 존재한다면!단언이 적절하며,ApiResponse<T>에서result: T로 타이핑되어 있다면 단언 없이도 됩니다.🤖 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/api/endpoints/reservations.ts` around lines 31 - 46, The getAvailableTables function lacks an explicit return type so callers may get an inferred union (AvailableTablesResult | undefined | null); update the function signature to an explicit Promise<AvailableTablesResult> (or Promise<AvailableTablesResult | null> if nullable) and ensure you return a non-null result by either asserting data.result! when you know isSuccess guarantees presence or by fixing ApiResponse<T> so result is typed as T when isSuccess is true; adjust the signature of getAvailableTables and the return statement accordingly (reference function getAvailableTables and type AvailableTablesResult / ApiResponse).src/api/owner/reservation.ts (1)
23-24: ⚡ Quick win응답 제네릭 타입을 끝까지 명시해 주세요.
patchBreakTime,cancelBookingByOwner는 현재 반환 타입 제네릭이 없어 호출부에서 타입 안전성이 끊깁니다. 동일 파일의 다른 함수들처럼ApiResponse<...>를 지정해 통일하는 게 좋아요.As per coding guidelines, "src/api/**: 에러 처리/타임아웃/리트라이 전략 확인, 응답 타입 안전성 유지."
Also applies to: 32-33
🤖 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/api/owner/reservation.ts` around lines 23 - 24, The two functions patchBreakTime and cancelBookingByOwner lack the ApiResponse generic, breaking type safety; update their returns to use the appropriate ApiResponse<T> generic (e.g., api.patch<ApiResponse<YourResponseType>>(...) and api.post<ApiResponse<YourResponseType>>(...) ) that matches the backend contract (replace YourResponseType with the actual response DTO such as BreakTimeResponse or a void/null type if no payload). Ensure both patchBreakTime and cancelBookingByOwner use the same ApiResponse<> pattern as other functions in this file so callers receive a fully typed response.src/components/owner/tableDashboard.tsx (1)
256-257: ⚡ Quick win
exhaustive-deps비활성화 대신 stale 참조를 제거해 주세요.Line 256에서 lint를 끄는 방식은 Line 229의
tableData클로저 참조 문제를 숨길 수 있습니다.setPlacedTables도 이전 상태 기반으로 이미지 URL을 보존하면tableData의존성을 제거하고 lint disable 없이 안정적으로 유지할 수 있어요.예시 수정안
- tableImageUrl: - t.tableImageUrl ?? - tableData[t.gridY * layout.gridInfo.gridCol + t.gridX + 1]?.tableImageUrl ?? - null, + tableImageUrl: t.tableImageUrl ?? null, ... - fetchLayout(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [storeId]); + fetchLayout(); + }, [storeId]);🤖 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/components/owner/tableDashboard.tsx` around lines 256 - 257, The eslint-disable hides a stale-closure bug: instead of suppressing exhaustive-deps for the effect keyed by storeId, remove the eslint-disable and update the effect body to use the functional updater of setPlacedTables so it doesn't close over tableData; compute the new placed tables from the latest tableData but when mapping/merging preserve existing image URLs by looking them up in the previous state (e.g., setPlacedTables(prev => { const prevMap = new Map(prev.map(p=>[p.id,p])); return tableData.map(t => ({ ...t, imageUrl: prevMap.get(t.id)?.imageUrl ?? t.imageUrl })); })). This keeps the effect dependent only on storeId (or explicitly adds tableData if needed) and avoids stale references to tableData without disabling react-hooks/exhaustive-deps.src/types/layout.ts (1)
31-37: ⚡ Quick win
CreateTableResponse.seatsType타입이 과도하게 넓습니다.현재
LayoutTable/CreateTableRequest는SeatsType인데 응답만string이라 후속 코드에서 불필요한 분기/캐스팅이 생깁니다. 서버 스펙이 고정이라면SeatsType으로 맞추고, 확장 가능성을 남기려면SeatsType | string처럼 의도를 명시해 주세요.타입 정합성 개선 예시
export interface CreateTableResponse { tableId: number; tableNumber: string; minSeatCount: number; maxSeatCount: number; - seatsType: string; + seatsType: SeatsType; gridX: number; gridY: number; tableImageUrl: string | null; }🤖 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/types/layout.ts` around lines 31 - 37, The CreateTableResponse interface currently types seatsType as string, causing downstream casts compared to LayoutTable/CreateTableRequest which use SeatsType; update CreateTableResponse.seatsType to use the same type to maintain consistency—either change it to SeatsType if the server spec is fixed or to SeatsType | string if you want to allow extensions, and ensure you update any imports/usages of CreateTableResponse accordingly so callers no longer need extra branching or casting.src/types/menus.ts (1)
75-80: ⚡ Quick win메뉴 생성/수정 요청의
category는 좁은 타입으로 유지하는 편이 안전합니다.요청 DTO에서
category: string이면 잘못된 값이 컴파일 단계에서 걸러지지 않습니다. 가능하면MenuCategory로 제한해 API 요청 타입 안정성을 유지해 주세요.타입 강화 예시
export interface MenuUpdateItem { name: string; description?: string; price: number; - category: string; + category: MenuCategory; imageKey?: string; } export interface MenuCreateItem { name: string; description?: string; price: number; - category: string; + category: MenuCategory; imageKey?: string; }Also applies to: 92-97
🤖 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/types/menus.ts` around lines 75 - 80, The MenuUpdateItem interface currently types category as a plain string which allows invalid values; change its category property to the existing MenuCategory union type (replace "category: string" with "category: MenuCategory") to enforce valid enum-like values at compile time, and apply the same change to the corresponding interface defined later (the other menu DTO at lines ~92-97, e.g., MenuCreateItem) so both request DTOs use MenuCategory instead of string.
🤖 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/api/endpoints/member.ts`:
- Around line 19-22: patchMemberInfo currently returns res.data.result directly
which can propagate undefined for failed responses; update patchMemberInfo to
check the ApiResponse success flag (e.g., res.data.isSuccess) and only return
res.data.result when true, otherwise throw an Error (including useful info from
res.data or status) so callers get explicit failures; ensure you follow the same
error/timeout/retry handling pattern used by other endpoints in src/api (use
existing helper logic if present) and reference the ApiResponse type and
patchMemberInfo function when applying the change.
In `@src/types/booking.ts`:
- Around line 3-55: The Booking and BookingListItem interfaces have inconsistent
shared field types (bookingTime and amount) which can cause misuse; update the
declarations for Booking and BookingListItem to document their differences with
clear JSDoc comments above each interface (mentioning which API/endpoint each
represents and the exact format: Booking.bookingTime is a formatted string and
amount may be number|null; BookingListItem.bookingTime is the serialized
LocalTime object and amount is number), or alternatively unify the types by
creating a shared type alias (e.g., BookingTimeString vs BookingTimeObject and
OptionalAmount) and reference those in Booking and BookingListItem so the intent
is explicit and safe when these types are used.
In `@src/types/member.ts`:
- Around line 9-12: PatchMemberInfo currently requires both name and phoneNumber
which conflicts with PATCH semantics and the project's PatchTableRequest
pattern; change PatchMemberInfo so name?: string and phoneNumber?: string (make
both optional) in src/types/member.ts and then update any call sites such as
MyInfoPage.tsx to handle possibly undefined fields (only include fields present
when building the PATCH payload) so partial updates work correctly.
In `@src/types/store.ts`:
- Around line 135-145: MyStore의 category 필드가 string으로 되어 있어 타입 안전성이 떨어지므로,
MyStore 인터페이스의 category 타입을 기존 유니온 타입 Category로 변경하여 RestaurantSummary와 일관되게
만드세요; 파일에 Category 선언이 동일 파일에 있는지 확인하고 없다면 해당 Category 타입을 import하거나 재사용하도록
조정하고, MyStore 인터페이스(심볼: MyStore)만 변경하면 됩니다.
- Around line 200-214: ApiStoreSummary currently exposes four optional
coordinate fields (latitude, longitude, lat, lng) causing ambiguity; change the
ApiStoreSummary interface to use only lat and lng (remove latitude/longitude),
add a short comment stating which field the API actually returns, then update
all consumers (e.g., useSearchStores.ts where you currently do s.latitude ??
s.lat, KakaoMap.tsx, StepStoreInfo.tsx) to read only lat/lng (and coerce string
→ number if needed), and normalize StoreInfo.schema.ts to accept/store lat/lng
instead of latitude/longitude so the whole codebase consistently uses lat and
lng.
- Around line 147-154: The MyStoreResponse interface duplicates the common
envelope; replace it with the generic ApiResponse usage instead of inlining
fields: remove the MyStoreResponse shape and export a type alias using
ApiResponse with the appropriate result payload (e.g., ApiResponse<{ stores:
MyStore[] }> or ApiResponse<SearchStoresResult>), keeping references to MyStore;
update any usages of MyStoreResponse to the new alias name.
In `@src/types/table.ts`:
- Around line 27-33: UpdatedTable.seatsType is currently typed as string while
PatchTableRequest.seatsType uses the narrower SeatsType; update the UpdatedTable
interface to use SeatsType instead of string, importing or referencing the
SeatsType union where it's declared, and run/adjust any affected consumers or
tests (e.g., places casting UpdatedTable.seatsType) to remove unnecessary casts
or fix type mismatches; ensure the change is applied to the UpdatedTable
declaration and any export/imports that reference it.
---
Outside diff comments:
In `@src/api/endpoints/reservations.ts`:
- Line 38: The if-check in getAvailableTables currently uses a direct property
access (if (!data.isSuccess)) which can throw when data is null/undefined;
change the condition to use optional chaining (check !data?.isSuccess) so it
matches getAvailableTimes and createBooking and safely handles when the response
`data` is undefined; update the `getAvailableTables` branch where `data` is
inspected to use `data?.isSuccess`.
In `@src/components/owner/MenuManagement.tsx`:
- Around line 51-58: Replace the unsafe type cast (s.category as MenuCategory)
in mapServerToLocal with runtime normalization: check s.category against the
allowed MenuCategory values (e.g., via Object.values(MenuCategory) or a small
allowedCategories array) and use that value only if it matches, otherwise
fallback to "MAIN"; do the same runtime validation for the other mapping site
that reads s.category (the similar s.category handling around lines 89-90) so
unexpected server strings cannot slip through.
---
Nitpick comments:
In `@src/api/endpoints/reservations.ts`:
- Around line 31-46: The getAvailableTables function lacks an explicit return
type so callers may get an inferred union (AvailableTablesResult | undefined |
null); update the function signature to an explicit
Promise<AvailableTablesResult> (or Promise<AvailableTablesResult | null> if
nullable) and ensure you return a non-null result by either asserting
data.result! when you know isSuccess guarantees presence or by fixing
ApiResponse<T> so result is typed as T when isSuccess is true; adjust the
signature of getAvailableTables and the return statement accordingly (reference
function getAvailableTables and type AvailableTablesResult / ApiResponse).
In `@src/api/owner/reservation.ts`:
- Around line 23-24: The two functions patchBreakTime and cancelBookingByOwner
lack the ApiResponse generic, breaking type safety; update their returns to use
the appropriate ApiResponse<T> generic (e.g.,
api.patch<ApiResponse<YourResponseType>>(...) and
api.post<ApiResponse<YourResponseType>>(...) ) that matches the backend contract
(replace YourResponseType with the actual response DTO such as BreakTimeResponse
or a void/null type if no payload). Ensure both patchBreakTime and
cancelBookingByOwner use the same ApiResponse<> pattern as other functions in
this file so callers receive a fully typed response.
In `@src/components/owner/tableDashboard.tsx`:
- Around line 256-257: The eslint-disable hides a stale-closure bug: instead of
suppressing exhaustive-deps for the effect keyed by storeId, remove the
eslint-disable and update the effect body to use the functional updater of
setPlacedTables so it doesn't close over tableData; compute the new placed
tables from the latest tableData but when mapping/merging preserve existing
image URLs by looking them up in the previous state (e.g., setPlacedTables(prev
=> { const prevMap = new Map(prev.map(p=>[p.id,p])); return tableData.map(t =>
({ ...t, imageUrl: prevMap.get(t.id)?.imageUrl ?? t.imageUrl })); })). This
keeps the effect dependent only on storeId (or explicitly adds tableData if
needed) and avoids stale references to tableData without disabling
react-hooks/exhaustive-deps.
In `@src/components/reservation/parts/TableMap.tsx`:
- Around line 4-11: Rename the generic interface Props to a more specific
TableMapProps and update all local references accordingly: change the interface
declaration interface Props { ... } to interface TableMapProps { ... } and
update the TableMap component type annotations/usages (e.g., React.FC<Props>,
function parameters or any exported type names) to use TableMapProps; ensure any
other local variables, exports or imports inside TableMap.tsx that referenced
Props are updated to TableMapProps so the component props type remains explicit
and reusable.
In `@src/types/booking.ts`:
- Line 55: UserBookingItem is currently just a redundant alias of
BookingListItem; remove maintenance overhead by replacing all uses of
UserBookingItem with BookingListItem, or if you intend them to diverge later,
keep the alias and add a clarifying comment above the declaration explaining the
semantic distinction and future divergence plan (referencing the UserBookingItem
and BookingListItem symbols to locate the code).
In `@src/types/layout.ts`:
- Around line 31-37: The CreateTableResponse interface currently types seatsType
as string, causing downstream casts compared to LayoutTable/CreateTableRequest
which use SeatsType; update CreateTableResponse.seatsType to use the same type
to maintain consistency—either change it to SeatsType if the server spec is
fixed or to SeatsType | string if you want to allow extensions, and ensure you
update any imports/usages of CreateTableResponse accordingly so callers no
longer need extra branching or casting.
In `@src/types/menus.ts`:
- Around line 75-80: The MenuUpdateItem interface currently types category as a
plain string which allows invalid values; change its category property to the
existing MenuCategory union type (replace "category: string" with "category:
MenuCategory") to enforce valid enum-like values at compile time, and apply the
same change to the corresponding interface defined later (the other menu DTO at
lines ~92-97, e.g., MenuCreateItem) so both request DTOs use MenuCategory
instead of string.
In `@src/types/payment.ts`:
- Around line 11-20: The PaymentConfirmResult interface currently types status,
paymentMethod, and paymentProvider as plain strings; narrow them to safer types
by replacing those fields with either literal union types of the known backend
values (e.g., 'PAID' | 'PENDING' | 'FAILED' for status, specific provider/method
strings) or, if the backend is still fluid, use the (string & {}) pattern to
preserve IDE completions while allowing unknown values; update the
PaymentConfirmResult declaration accordingly so consumers get compile-time
checks or helpful IDE hints.
In `@src/types/reservation.ts`:
- Around line 1-12: Add a short clarifying comment explaining the difference
between Slot.status and SlotStatus: note that Slot.status (in the Slot
interface) can be "AVAILABLE" | "BOOKED" | "BLOCKED" and that "BOOKED" is set by
the system (not manually editable), whereas SlotStatus (the type) only includes
"AVAILABLE" | "BLOCKED" and is intended for manual/patch operations; place the
comment near the Slot interface’s status field and/or above the SlotStatus type
to prevent future confusion.
- Around line 84-94: The CreateBookingResult.type for status currently uses the
broad union ' "PENDING" | "CONFIRMED" | string' which collapses the string
literals; update the status definition in the CreateBookingResult interface to
either enumerate all expected backend status literals (e.g., include any other
known values) or replace the trailing '| string' with the open-ended type
pattern '(string & {})' so the literals remain distinct (modify the status field
on CreateBookingResult accordingly).
- Line 48: The SeatsTypes union is being flattened by the trailing "| string" so
the literal members ("WINDOW" | "GENERAL") lose type-checking and IDE hints;
either remove "| string" to lock SeatsTypes to the known literals, or if you
must allow unknown values change the type to the open-but-literal-friendly
pattern (string & {}) for SeatsTypes; also update the literal set to include the
values used in AddTableModal.tsx (e.g., "ROOM", "BAR", "OUTDOOR") so the option
values match the SeatsTypes union and avoid type mismatches.
🪄 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: CHILL
Plan: Pro
Run ID: cf3b9166-34fc-4599-9d0e-227719e02715
📒 Files selected for processing (59)
src/api/adapters/store.adapter.tssrc/api/axios.tssrc/api/bookings.tssrc/api/dto/store.dto.tssrc/api/endpoints/bookings.tssrc/api/endpoints/member.tssrc/api/endpoints/menus.tssrc/api/endpoints/payments.tssrc/api/endpoints/reservations.tssrc/api/inquiry.tssrc/api/owner/menus.tssrc/api/owner/reservation.tssrc/api/owner/storeLayout.tssrc/api/owner/stores.tssrc/api/owner/table.tssrc/components/customer-support/support.schema.tssrc/components/main/FeatureCard.tsxsrc/components/main/Header.tsxsrc/components/map/KakaoMap.tsxsrc/components/owner/AddTableModal.tsxsrc/components/owner/BreakTimeModal.tsxsrc/components/owner/MenuManagement.tsxsrc/components/owner/StoreSettings.tsxsrc/components/owner/menuFormModal.tsxsrc/components/owner/tableDashboard.tsxsrc/components/owner/tableDetailModal.tsxsrc/components/reservation/modals/PaymentModal.tsxsrc/components/reservation/modals/ReservationCompleteModal.tsxsrc/components/reservation/modals/ReservationConfirmModal.tsxsrc/components/reservation/modals/ReservationMenuModal.tsxsrc/components/reservation/modals/ReservationModal.tsxsrc/components/reservation/parts/TableMap.tsxsrc/components/restaurant/RestaurantCard.tsxsrc/components/restaurant/RestaurantDetailModal.tsxsrc/components/restaurant/RestaurantList.tsxsrc/hooks/common/useInView.tssrc/hooks/reservation/useAvailableTables.tssrc/hooks/reservation/useAvailableTimes.tssrc/hooks/store/useRestaurantDetail.tssrc/hooks/store/useSearchStores.tssrc/pages/SearchPage.tsxsrc/pages/myPage/MyInfoPage.tsxsrc/pages/myPage/StoreRegistrationPage.tsxsrc/pages/myPage/reservationPage.tsxsrc/pages/myPage/storePage.tsxsrc/types/api.tssrc/types/auth.tssrc/types/booking.tssrc/types/inquiry.tssrc/types/kakao.d.tssrc/types/layout.tssrc/types/map.tssrc/types/member.tssrc/types/menus.tssrc/types/payment.tssrc/types/reservation.tssrc/types/restaurant.tssrc/types/store.tssrc/types/table.ts
💤 Files with no reviewable changes (2)
- src/components/customer-support/support.schema.ts
- src/api/dto/store.dto.ts
|
넵! T나 I를 안붙이는걸로 하는게 더 깔끔할것같아요! 좋습니다! |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
src/types/booking.ts (1)
38-40: ⚡ Quick win
BookingResponse와UserBookingsResult구조 중복은 한쪽을 기준으로 합치는 게 안전해요Line 11-13, Line 38-40 기준으로 두 타입이 완전히 동일해서, 이후 한쪽만 수정되는 드리프트가 생기기 쉬워요. 하나를 기준 타입으로 두고 alias 또는 extends로 정리해두면 유지보수성이 좋아집니다.
예시 코드
export interface BookingResponse extends Pagination { bookingList: BookingListItem[]; } -export interface UserBookingsResult extends Pagination { - bookingList: BookingListItem[]; -} +export type UserBookingsResult = BookingResponse;Also applies to: 11-13
🤖 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/types/booking.ts` around lines 38 - 40, The two identical interfaces BookingResponse and UserBookingsResult should be consolidated to avoid drift: pick one as the canonical type (e.g., BookingResponse) and make the other an alias or extend it (e.g., type UserBookingsResult = BookingResponse or interface UserBookingsResult extends BookingResponse {}), ensuring both still reference Pagination and bookingList: BookingListItem[]; update all usages to import/reference the canonical symbol and remove duplicated fields from the non-canonical declaration.src/types/store.ts (1)
161-163: 🏗️ Heavy lift
StoreDetailDataDTO.storeId는 단일 타입으로 고정하는 걸 권장해요Line 162의
number | string은 동일 ID라도1/"1"불일치(비교, 캐시 키, 맵 키) 리스크를 만들 수 있습니다. 공용 타입은number로 고정하고, 문자열 가능성은 어댑터에서 정규화하는 편이 안전합니다.제안 변경
export interface StoreDetailDataDTO { - storeId: number | string; + storeId: number; storeName: string; description: string; address: string; phone: string;// adapter 예시 (파일 외 변경) const normalizedStoreId = Number(dto.storeId); if (!Number.isFinite(normalizedStoreId)) { throw new Error("Invalid storeId"); }🤖 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/types/store.ts` around lines 161 - 163, Change StoreDetailDataDTO.storeId from a union to a single number type by updating the interface (StoreDetailDataDTO.storeId: number); then ensure all callers/adapters normalize incoming string IDs to numbers (e.g., in the DTO-to-domain adapter convert dto.storeId -> Number, validate Number.isFinite and throw on invalid IDs) so runtime inputs remain safe and consistent for comparisons, cache keys, and Map usage.
🤖 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.
Nitpick comments:
In `@src/types/booking.ts`:
- Around line 38-40: The two identical interfaces BookingResponse and
UserBookingsResult should be consolidated to avoid drift: pick one as the
canonical type (e.g., BookingResponse) and make the other an alias or extend it
(e.g., type UserBookingsResult = BookingResponse or interface UserBookingsResult
extends BookingResponse {}), ensuring both still reference Pagination and
bookingList: BookingListItem[]; update all usages to import/reference the
canonical symbol and remove duplicated fields from the non-canonical
declaration.
In `@src/types/store.ts`:
- Around line 161-163: Change StoreDetailDataDTO.storeId from a union to a
single number type by updating the interface (StoreDetailDataDTO.storeId:
number); then ensure all callers/adapters normalize incoming string IDs to
numbers (e.g., in the DTO-to-domain adapter convert dto.storeId -> Number,
validate Number.isFinite and throw on invalid IDs) so runtime inputs remain safe
and consistent for comparisons, cache keys, and Map usage.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 8996bf45-e597-49ad-a19d-58c8582a67ee
📒 Files selected for processing (6)
src/api/endpoints/member.tssrc/hooks/store/useSearchStores.tssrc/types/booking.tssrc/types/member.tssrc/types/store.tssrc/types/table.ts
🚧 Files skipped from review as they are similar to previous changes (4)
- src/types/member.ts
- src/hooks/store/useSearchStores.ts
- src/types/table.ts
- src/api/endpoints/member.ts
🔢 관련 이슈 링크
📌 변경사항PR
💻 작업내용
🪧 미완성 작업
🤔 논의 사항 및 참고 사항
타입스크립트 공식 가이드에서 이 방식을 비권장하고 있어 조사해보니
더 이상 변수명으로 역할 구분할 필요 없음 / 명명규칙 늘어나고 가독성 떨어짐/ 캡슐화 원칙 위반
등의 이유로 사용을 지양한다고 합니다
그래서 앞에 T나 I를 붙이지 않는 방향으로 진행하면 어떨까요?
✅ 체크리스트
Summary by CodeRabbit
Refactor
New Features