Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Walkthrough
Estimated code review effort๐ฏ 3 (Moderate) | โฑ๏ธ ~30 minutes Suggested reviewers
๐ฅ Pre-merge checks | โ 4 | โ 1โ Failed checks (1 inconclusive)
โ Passed checks (4 passed)
โ๏ธ Tip: You can configure your own custom pre-merge checks in the settings. โจ Finishing touches
๐งช 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: 2
๐ค Fix all issues with AI agents
In `@apps/web/src/apis/community/deletePost.ts`:
- Around line 20-34: The revalidation call in revalidateCommunityPage currently
awaits fetch but doesn't check HTTP status, so 4xx/5xx responses silently
succeed; update revalidateCommunityPage to capture the fetch response, check
response.ok, and if false log or throw an error including response.status and
response.statusText (or response.text()) so failed ISR revalidations are
visible; ensure this handling occurs after the fetch and before returning from
revalidateCommunityPage.
In `@apps/web/src/apis/community/patchUpdatePost.ts`:
- Around line 19-33: The fetch in revalidateCommunityPage currently treats all
HTTP responses as success; update the function to check the Response.ok after
the await fetch (in revalidateCommunityPage) and handle non-ok responses by
throwing or logging a descriptive error (include response.status and response
text) so the existing try/catch can surface failures; ensure the
Authorization/header/body logic remains unchanged and that failures end up
logged or rethrown for callers to observe.
๐งน Nitpick comments (2)
apps/web/src/components/mentor/ArticleBottomSheetModal/hooks/useArticleSchema.ts (2)
109-113: 2. handleModalClose์์์ ์ค๋ณต ์ด๊ธฐํ
handleModalCloseํจ์์์reset()๊ณผsetImagePreview(null)์ ์ง์ ํธ์ถํ๊ณ ์์ต๋๋ค. ๊ทธ๋ฌ๋ Line 66-69์useEffect๊ฐisOpen์ดfalse๊ฐ ๋ ๋ ์ด๋ฏธ ๋์ผํ ์ด๊ธฐํ๋ฅผ ์ํํฉ๋๋ค.
handleClose()๊ฐ ๋ด๋ถ์ ์ผ๋กisOpen์false๋ก ์ค์ ํ๋ค๋ฉด, ์ฌ๊ธฐ์์reset()๊ณผsetImagePreview(null)ํธ์ถ์ ์ค๋ณต๋ฉ๋๋ค. ์ฝ๋ ์ผ๊ด์ฑ์ ์ํด ์ ๋ฆฌ๋ฅผ ๊ณ ๋ คํด ๋ณด์ธ์.โป๏ธ ๊ฐ์ํ ์ ์
const handleModalClose = () => { handleClose(); - reset(); - setImagePreview(null); };
88-106: โ ์ข์ ๋ณ๊ฒฝ์ ๋๋ค. ์๋ฌ ์ฒ๋ฆฌ๊ฐ mutation ํ ์ ์ ๊ตฌํ๋์ด ์์ต๋๋ค.
usePostAddArticle๊ณผusePutModifyArticleํ ์ ํ์ธํ ๊ฒฐ๊ณผ, ๋ ํ ๋ชจ๋onError์ฝ๋ฐฑ์์ toast๋ฅผ ํตํ ์๋ฌ ํผ๋๋ฐฑ์ ์ด๋ฏธ ์ฒ๋ฆฌํ๊ณ ์์ต๋๋ค. Mutation ์ฑ๊ณต ์์๋ง ๋ชจ๋ฌ์ ๋ซ๊ณ ํผ์ ๋ฆฌ์ ํ๋๋ก ๊ฐ์ ํ์ ๋ถ๋ถ๋ PR ๋ชฉํ์ ๋ง๊ฒ ์ ๊ตฌํ๋์์ต๋๋ค.๋ค๋ง ํ๋์ ์ต์ ํ ์ ์ ์ ์ํฉ๋๋ค:
- ์ค๋ณต reset() ์ ๊ฑฐ ์ ์
onSuccess์์reset()ํธ์ถ ํhandleClose()๊ฐisOpen์false๋ก ๋ณ๊ฒฝํ๋ฉด, useEffect (line 52-69)๊ฐ ๋ค์reset()์ ํธ์ถํฉ๋๋ค.- ๋์์๋ ๋ฌธ์ ์์ผ๋, useEffect๊ฐ ์ด๋ฏธ ๋ชจ๋ฌ ๋ซํ ๋ ์ํ ์ด๊ธฐํ๋ฅผ ๋ด๋นํ๋ฏ๋ก ๋ถํ์ํ ์ค๋ณต์ ๋๋ค.
โป๏ธ ๊ฐ์ ๋ฐฉ์
putModifyArticle( { body: data, articleId }, { onSuccess: () => { handleClose(); - reset(); }, } ); } else { postAddArticle(data, { onSuccess: () => { handleClose(); - reset(); }, }); }
| const revalidateCommunityPage = async (boardCode: string, accessToken: string) => { | ||
| try { | ||
| if (!accessToken) { | ||
| console.warn("Revalidation skipped: No access token available"); | ||
| return; | ||
| } | ||
|
|
||
| await fetch("/api/revalidate", { | ||
| method: "POST", | ||
| headers: { | ||
| "Content-Type": "application/json", | ||
| Authorization: `Bearer ${accessToken}`, | ||
| }, | ||
| body: JSON.stringify({ boardCode }), | ||
| }); |
There was a problem hiding this comment.
ISR revalidate๊ฐ โ์กฐ์ฉํ ์คํจโํ ์ ์์ด์.
fetch๋ 4xx/5xx์์๋ ์์ธ๋ฅผ ๋์ง์ง ์์์, ํ์ฌ๋ ์คํจ๊ฐ ๋ก๊ทธ ์์ด ํต๊ณผ๋ ์ ์์ต๋๋ค. ์๋ต ok ์ฒดํฌ๋ฅผ ์ถ๊ฐํด ์ฃผ์ธ์.
๐ง ์์ ์ ์
- await fetch("/api/revalidate", {
+ const response = await fetch("/api/revalidate", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${accessToken}`,
},
body: JSON.stringify({ boardCode }),
});
+ if (!response.ok) {
+ throw new Error(`Revalidate failed: ${response.status}`);
+ }๐ค Prompt for AI Agents
In `@apps/web/src/apis/community/deletePost.ts` around lines 20 - 34, The
revalidation call in revalidateCommunityPage currently awaits fetch but doesn't
check HTTP status, so 4xx/5xx responses silently succeed; update
revalidateCommunityPage to capture the fetch response, check response.ok, and if
false log or throw an error including response.status and response.statusText
(or response.text()) so failed ISR revalidations are visible; ensure this
handling occurs after the fetch and before returning from
revalidateCommunityPage.
| const revalidateCommunityPage = async (boardCode: string, accessToken: string) => { | ||
| try { | ||
| if (!accessToken) { | ||
| console.warn("Revalidation skipped: No access token available"); | ||
| return; | ||
| } | ||
|
|
||
| await fetch("/api/revalidate", { | ||
| method: "POST", | ||
| headers: { | ||
| "Content-Type": "application/json", | ||
| Authorization: `Bearer ${accessToken}`, | ||
| }, | ||
| body: JSON.stringify({ boardCode }), | ||
| }); |
There was a problem hiding this comment.
์ฌ๊ธฐ๋ revalidate ์คํจ๊ฐ ์จ๊ฒจ์ง ์ ์์ด์.
fetch๋ 4xx/5xx์์๋ ์ฑ๊ณต์ผ๋ก resolve๋๋ฏ๋ก, ์๋ต ok ์ฒดํฌ๋ก ์คํจ๋ฅผ ๋ช
์ํด ์ฃผ์ธ์.
๐ง ์์ ์ ์
- await fetch("/api/revalidate", {
+ const response = await fetch("/api/revalidate", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${accessToken}`,
},
body: JSON.stringify({ boardCode }),
});
+ if (!response.ok) {
+ throw new Error(`Revalidate failed: ${response.status}`);
+ }๐ 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.
| const revalidateCommunityPage = async (boardCode: string, accessToken: string) => { | |
| try { | |
| if (!accessToken) { | |
| console.warn("Revalidation skipped: No access token available"); | |
| return; | |
| } | |
| await fetch("/api/revalidate", { | |
| method: "POST", | |
| headers: { | |
| "Content-Type": "application/json", | |
| Authorization: `Bearer ${accessToken}`, | |
| }, | |
| body: JSON.stringify({ boardCode }), | |
| }); | |
| const revalidateCommunityPage = async (boardCode: string, accessToken: string) => { | |
| try { | |
| if (!accessToken) { | |
| console.warn("Revalidation skipped: No access token available"); | |
| return; | |
| } | |
| const response = await fetch("/api/revalidate", { | |
| method: "POST", | |
| headers: { | |
| "Content-Type": "application/json", | |
| Authorization: `Bearer ${accessToken}`, | |
| }, | |
| body: JSON.stringify({ boardCode }), | |
| }); | |
| if (!response.ok) { | |
| throw new Error(`Revalidate failed: ${response.status}`); | |
| } |
๐ค Prompt for AI Agents
In `@apps/web/src/apis/community/patchUpdatePost.ts` around lines 19 - 33, The
fetch in revalidateCommunityPage currently treats all HTTP responses as success;
update the function to check the Response.ok after the await fetch (in
revalidateCommunityPage) and handle non-ok responses by throwing or logging a
descriptive error (include response.status and response text) so the existing
try/catch can surface failures; ensure the Authorization/header/body logic
remains unchanged and that failures end up logged or rethrown for callers to
observe.
There was a problem hiding this comment.
Actionable comments posted: 1
๐ค Fix all issues with AI agents
In `@apps/web/package.json`:
- Line 29: The package.json currently includes an unused dependency
"@vercel/speed-insights"; remove the "@vercel/speed-insights": "^1.3.1" entry
from apps/web package.json if there is no planned usage in this PR, or
alternatively add a brief note in the PR/commit message explaining why
"@vercel/speed-insights" is being introduced and where it will be used; update
package.json accordingly and run dependency install/lockfile update to keep
package-lock/yarn.lock consistent.
๐งน Nitpick comments (4)
apps/web/src/app/university/application/ScoreSheet.tsx (1)
42-48: ์ฃผ์ ์ฒ๋ฆฌ๋ ์ฝ๋๊ฐ ๋จ์์์ต๋๋ค.์ด๋ฒ PR์ ๋ณ๊ฒฝ ์ฌํญ์ ์๋์ง๋ง,
isMine๊ด๋ จ ๋ก์ง์ด ์ฃผ์์ผ๋ก ๋จ์์๋ค์. ํฅํ ์ฌ์ฉ ๊ณํ์ด ์๋ค๋ฉด ์ ๊ฑฐํ๋ ๊ฒ์ด ์ฝ๋ ์ ๋ฆฌ์ ๋์์ด ๋ ์ ์์ต๋๋ค. ๊ธํ์ง ์์ผ๋ ํธํ์ค ๋ ์ ๋ฆฌํด ์ฃผ์ธ์. ๐apps/web/src/app/community/[boardCode]/[postId]/KebabMenu.tsx (3)
10-26:handler๊ฐ ๋งค ๋ ๋๋ง๋ค ์ ์ฐธ์กฐ๋ฅผ ์์ฑํ์ฌ ์ด๋ฒคํธ ๋ฆฌ์ค๋๊ฐ ๋ฐ๋ณต ๋ฑ๋ก/ํด์ ๋ฉ๋๋ค.
- ํธ์ถ๋ถ(Line 58-60)์์ ์ธ๋ผ์ธ ํ์ดํ ํจ์๋ก
handler๋ฅผ ์ ๋ฌํ๊ณ ์์ด, ๋งค ๋ ๋๋ง๋ค ์๋ก์ด ํจ์ ์ฐธ์กฐ๊ฐ ๋ง๋ค์ด์ง๋๋ค.useEffect์ ์์กด์ฑ ๋ฐฐ์ด์handler๊ฐ ํฌํจ๋์ด ์์ผ๋ฏ๋ก, ๋ ๋๋ง๋ค ๋ฆฌ์ค๋๊ฐ cleanup โ ์ฌ๋ฑ๋ก๋ฉ๋๋ค.
useRef๋ก ์ต์ handler๋ฅผ ์บก์ฒํ๋ฉด ์ด๋ฒคํธ ๋ฆฌ์ค๋ ์ฌ๋ฑ๋ก์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.โป๏ธ useRef๋ฅผ ํ์ฉํ ์์ ์ ์ธ handler ์ฐธ์กฐ ์์
-const useClickOutside = (ref: RefObject<HTMLDivElement | null>, handler: (event: MouseEvent | TouchEvent) => void) => { +const useClickOutside = (ref: RefObject<HTMLDivElement | null>, handler: (event: MouseEvent | TouchEvent) => void) => { + const handlerRef = useRef(handler); + handlerRef.current = handler; + useEffect(() => { const listener = (event: MouseEvent | TouchEvent) => { const current = ref.current; if (!current) return; if (!(event.target instanceof Node)) return; if (current.contains(event.target)) return; - handler(event); + handlerRef.current(event); }; document.addEventListener("mousedown", listener); document.addEventListener("touchstart", listener); return () => { document.removeEventListener("mousedown", listener); document.removeEventListener("touchstart", listener); }; - }, [ref, handler]); + }, [ref]); };
36-38: SVG ์์ฑ์ kebab-case ๋์ camelCase ์ฌ์ฉ์ ๊ถ์ฅํฉ๋๋ค.
stroke-widthโstrokeWidthstroke-linecapโstrokeLinecapstroke-linejoinโstrokeLinejoinReact JSX์์๋ camelCase๊ฐ ๊ด๋ก์ด๋ฉฐ, kebab-case๋ ์ฝ์ ๊ฒฝ๊ณ ๋ฅผ ์ ๋ฐํ ์ ์์ต๋๋ค.
28-28: ๋ถํ์ํ ์ฃผ์์ ๋๋ค.
useClickOutsideํ ์ด ๋ฐ๋ก ์์ ์์ ํ ๊ตฌํ๋์ด ์์ผ๋ฏ๋ก, "(๊ฐ์ )"์ด๋ผ๋ ํํ์ด ์คํด๋ฅผ ์ค ์ ์์ต๋๋ค. ์ ๊ฑฐํ๊ฑฐ๋ ์ ๋ฐ์ดํธํด ์ฃผ์ธ์.
| "@tanstack/react-query": "^5.84.1", | ||
| "@tanstack/react-query-devtools": "^5.84.1", | ||
| "@tanstack/react-virtual": "^3.13.12", | ||
| "@vercel/speed-insights": "^1.3.1", |
There was a problem hiding this comment.
๐งฉ Analysis chain
๐ Script executed:
#!/bin/bash
# Search for `@vercel/speed-insights` usage in the codebase
echo "=== Searching for `@vercel/speed-insights` imports ==="
rg "@vercel/speed-insights" --type-list | head -20
rg "speed-insights|SpeedInsights" -i --type ts --type tsx --type js --type jsx 2>/dev/null || echo "No matches found in ts/tsx/js/jsx"
# Check the actual apps/web structure
echo ""
echo "=== Checking apps/web structure ==="
find apps/web -maxdepth 2 -type f -name "*.ts" -o -name "*.tsx" | head -20Repository: solid-connection/solid-connect-web
Length of output: 827
๐ Script executed:
#!/bin/bash
# Check for imports in the main app files
echo "=== Searching in apps/web directory ==="
rg -i "vercel|speed.insights|speed-insights" apps/web --type ts --type tsx -A 2 2>/dev/null | head -50
# Also check if there's any configuration or setup
echo ""
echo "=== Checking package.json context ==="
cat apps/web/package.json | grep -A 10 -B 10 "@vercel/speed-insights" || echo "Not in grep output"Repository: solid-connection/solid-connect-web
Length of output: 890
๐ Script executed:
#!/bin/bash
# Get file listing to understand the structure
echo "=== Apps/web main files ==="
ls -la apps/web/*.json 2>/dev/null | head -20
ls -la apps/web/src/ 2>/dev/null | head -20
# Search more broadly for any vercel imports
echo ""
echo "=== All vercel related imports ==="
rg "@vercel" apps/web --type ts --type tsx --type json 2>/dev/nullRepository: solid-connection/solid-connect-web
Length of output: 1128
@vercel/speed-insights ์์กด์ฑ์ด ์ฝ๋์์ ์ฌ์ฉ๋์ง ์๊ณ ์์ต๋๋ค.
-
์ฝ๋์์ ์ํฌํธ/์ฌ์ฉ ์์: ๊ฒ์ ๊ฒฐ๊ณผ,
@vercel/speed-insights๋package.json์๋ง ์ถ๊ฐ๋์ด ์๊ณ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ด๋ค ํ์ผ์์๋ ์ค์ ๋ก ์ํฌํธ๋๊ฑฐ๋ ์ฌ์ฉ๋์ง ์์ต๋๋ค. -
PR ๋ฒ์ ์ธ ๋ณ๊ฒฝ: ์ด PR์ ๋ชฉ์ ์ธ
#405โ๋ฉํฐ ์ ์ฒญํ๊ธฐ -> ๋ฉํ ๋ง ์ ์ฒญํ๊ธฐย #409 ๋ฒ๊ทธ ์์ ๊ณผ๋ ๋ฌด๊ดํ ์์กด์ฑ ์ถ๊ฐ์ ๋๋ค.
๋ถํ์ํ ์์กด์ฑ์ ์ ๊ฑฐํ๊ฑฐ๋, ์ค์ ์ฌ์ฉ ๊ณํ์ด ์๋ค๋ฉด ์ปค๋ฐ ๋ฉ์์ง๋ PR ์ค๋ช ์ ์ด์ ๋ฅผ ๋ช ์ํด์ฃผ์ธ์.
๐ค Prompt for AI Agents
In `@apps/web/package.json` at line 29, The package.json currently includes an
unused dependency "@vercel/speed-insights"; remove the "@vercel/speed-insights":
"^1.3.1" entry from apps/web package.json if there is no planned usage in this
PR, or alternatively add a brief note in the PR/commit message explaining why
"@vercel/speed-insights" is being introduced and where it will be used; update
package.json accordingly and run dependency install/lockfile update to keep
package-lock/yarn.lock consistent.
์์ฝ
์ต๊ทผ ์ ๊ธฐ๋ 5๊ฐ์ ๋ฒ๊ทธ ์ด์๋ฅผ ์์ฐจ์ ์ผ๋ก ์์ ํ๊ณ , ์ฝ๋ ๋ฆฌ๋ทฐ ํผ๋๋ฐฑ์ ๋ฐ์ํ์ฌ ์ฌ์ฉ์ ๊ฒฝํ์ ๊ฐ์ ํ์ต๋๋ค.
์์ ๋ด์ญ
โจ #409: ๋ฉํฐ ์ ์ฒญํ๊ธฐ โ ๋ฉํ ๋ง ์ ์ฒญํ๊ธฐ ํ ์คํธ ๋ณ๊ฒฝ
apps/web/src/components/mentor/MentorCard/index.tsx๐จ #408: ํฉ๊ฒฉ ๋ ์ํผ ์ ์ฅ ๋ฒ๊ทธ ์์ ๋ฐ ํ ์คํธ ์์ ๊ฐ์
passTipํ๋๋ฅผmyMentorProfile์์ ์ฌ๋ฐ๋ฅด๊ฒ ๋ก๋ํ๋๋ก ์์ apps/web/src/types/mentor.tsapps/web/src/app/mentor/modify/_ui/ModifyContent/_hooks/useModifyHookForm.tsapps/web/src/app/mentor/modify/_ui/ModifyContent/index.tsx๐พ #407: ๋ฉํ ์ํฐํด ์ ์ฅ ๊ฐ์
z.union์ฌ์ฉ)apps/web/src/components/mentor/ArticleBottomSheetModal/hooks/useArticleSchema.tsapps/web/src/components/mentor/ArticleBottomSheetModal/lib/schema.ts๐ #406: ๋ฉํ ๋๊ธฐ ํ์ด์ง UI ๊ฐ์
p-4โ ์ ๊ฑฐ)apps/web/src/app/mentor/waiting/_ui/WaitingContent/index.tsx๐ #405: ์ปค๋ฎค๋ํฐ ํ์ด์ง ISR Revalidate ์ถ๊ฐ
apps/web/src/apis/community/patchUpdatePost.tsapps/web/src/apis/community/deletePost.tsapps/web/src/app/community/[boardCode]/[postId]/modify/PostModifyForm.tsxapps/web/src/app/community/[boardCode]/[postId]/KebabMenu.tsx์ฝ๋ ๋ฆฌ๋ทฐ ๋ฐ์ ์ฌํญ
๐ ํผ ์ ํจ์ฑ ๊ฒ์ฌ ๊ฐ์
๐ ์ง๋ฌธ ํ ๊ธ ๊ธฐ๋ฅ ๊ฐ์
โณ ๋๊ธฐ UI ํ ์คํธ ๋ฐ ์นด์ดํธ ๊ฐ์
๐ฑ๏ธ ์ ๋ ฅ ์ค ์ธ๋ถ ํด๋ฆญ ์ฒ๋ฆฌ
๐ maxLength ์์ฑ ์ถ๊ฐ
๐ฃ Hook ๋ฐํ๊ฐ ์ต์ ํ
๊ฒ์ฆ
๊ด๋ จ ์ด์
Closes #405, Closes #406, Closes #407, Closes #408, Closes #409