feat: 어드민 Bruno API 테스트베드 개선#526
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Review limit reached
Your plan includes 1 review of capacity. Refill in 19 minutes and 5 seconds. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more review capacity refills, 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 trial, open-source, and free plans. In all cases, review capacity refills continuously over time. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (8)
👀 Walkthrough이 PR은 API 정의 시스템을 동적 파싱 방식에서 정적 레지스트리 기반으로 전환하는 대규모 인프라 개선입니다. 다음과 같이 진행됩니다:
🎯 Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes 💡 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)
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
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
packages/bruno-api-typescript/src/generator/apiDefinitionGenerator.ts (1)
147-181:⚠️ Potential issue | 🟠 Major | ⚡ Quick win3.
hasBody와body타입 판정 기준을 하나로 맞춰 주세요.여기서는
hasBody를 GET/HEAD만 제외하는 규칙으로 넓혔는데,body는 아직도 POST/PUT/PATCH만 허용합니다. 그래서 DELETE + body 엔드포인트는hasBody: true인데도body가Record<string, never>로 생성됩니다.수정 예시
const requestType = responseType.replace('Response', 'Request'); - const hasBody = ['POST', 'PUT', 'PATCH'].includes(method) && Boolean(parsed.body?.content?.trim()); + const hasBody = method !== 'GET' && method !== 'HEAD' && Boolean(parsed.body?.content?.trim()); const bodyType = hasBody ? requestType : 'Record<string, never>'; @@ - hasBody: method !== 'GET' && method !== 'HEAD' && Boolean(parsed.body?.content?.trim()), + hasBody,🤖 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 `@packages/bruno-api-typescript/src/generator/apiDefinitionGenerator.ts` around lines 147 - 181, The hasBody logic is inconsistent: hasBody is computed as method !== 'GET' && method !== 'HEAD' but body/bodyType use POST/PUT/PATCH logic, causing DELETE-with-body to produce hasBody: true but body: Record<string, never>; update the code so the same hasBody boolean (computed from method !== 'GET' && method !== 'HEAD' and Boolean(parsed.body?.content?.trim())) is used everywhere—replace the POST/PUT/PATCH check in bodyType and the body field with that hasBody variable, and ensure bodyType uses requestType when hasBody is true while bodyTypeName continues to reflect parsed.body?.type.apps/admin/src/components/features/bruno/BrunoApiPageContent.tsx (1)
258-281:⚠️ Potential issue | 🟡 Minor | ⚡ Quick win3. 실패 응답에도 성공 토스트가 뜹니다.
validateStatus: () => true때문에 4xx/5xx도catch로 가지 않는데, 아래에서 항상toast.success("요청이 완료되었습니다.")를 호출하고 있습니다. HTTP 실패는 응답 패널에서 빨갛게 보이더라도 상단 토스트가 성공으로 찍혀서 상태를 반대로 전달합니다.🔧 예시 수정 방향
- toast.success("요청이 완료되었습니다."); + if (response.status >= 200 && response.status < 300) { + toast.success("요청이 완료되었습니다."); + } else { + toast.error(`요청이 실패했습니다. (HTTP ${response.status})`); + }🤖 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/admin/src/components/features/bruno/BrunoApiPageContent.tsx` around lines 258 - 281, The request handler currently passes validateStatus: () => true so all HTTP responses (including 4xx/5xx) go to the success path and always call toast.success; update the logic after the axiosInstance.request call in BrunoApiPageContent (the block that sets setRequestResult and calls toast) to inspect response.status (or use axios.isAxiosError if preferred) and call toast.success only for 2xx (e.g., status >=200 && status <300) and call toast.error for non-2xx responses, leaving setRequestResult and response header/body handling unchanged; ensure the validateStatus config remains if you want raw responses, but branch the toast based on response.status.
🤖 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/admin/src/components/features/bruno/BrunoApiPageContent.tsx`:
- Line 191: The current gating uses only selectedEndpoint?.definition.bodyType
=== "multipart-form" (selectedIsMultipart) which misses file-upload endpoints
whose generated metadata sets hasBody: false/bodyType: null; update the protocol
so the generated endpoint metadata includes an explicit execution flag (e.g.,
definition.canExecute or definition.isExecutable) and change the UI check to use
that flag (falling back to existing bodyType/hasBody heuristics if missing) when
computing selectedIsMultipart/allowed-to-execute for selectedEndpoint; locate
usages of selectedEndpoint, selectedIsMultipart, and selectedEndpoint.definition
to update the decision logic accordingly.
- Line 193: The remote-warning logic currently uses only apiServerUrl
(showRemoteWarning = isRemoteApiServer(apiServerUrl)); change it to prefer the
selected endpoint's URL when present: if selectedEndpoint?.definition?.path is
an absolute URL, pass that URL into isRemoteApiServer and use its result for
showRemoteWarning, otherwise fall back to apiServerUrl; update the code that
computes showRemoteWarning (and any banner/display logic that reads
showRemoteWarning) to reference the new computed value and add or reuse a small
isAbsoluteUrl check to detect absolute paths.
In `@packages/api-schema/src/apiDefinitionRegistry.ts`:
- Around line 770-776: The registry currently contains a real Slack webhook in
the api definition object (look for the entry with domain: "image-upload", name:
"postSlackNotification" and the definition.path field) — remove the actual
webhook value and replace it with a non-secret placeholder or an
environment-reference (e.g., "SLACK_WEBHOOK" placeholder) so no real secret is
committed; update the Bruno source/generation step that produces this entry to
strip or substitute the webhook value at generation time (ensure code that
serializes definition.path uses the placeholder), and coordinate to rotate the
exposed webhook immediately.
In `@packages/bruno-api-typescript/src/generator/apiDefinitionGenerator.ts`:
- Around line 71-95: extractPathParamTokens currently scans the entire URL
including the query string, causing query placeholders like {{default-size}} to
be treated as path params; modify extractPathParamTokens to operate only on the
path portion by trimming off the query string (everything after the first '?')
before running the brunoVarPattern and subsequent regexes, then proceed with the
existing logic (including the {{URL}} special-case and the later
removal/re-scan) so only true path tokens are returned.
- Around line 98-107: The extractInlineQueryParams function is incorrectly
filtering out query parameters with empty values (e.g., key-only params like
"nickname"); remove the value-based filter so keys with empty string values are
preserved. Locate extractInlineQueryParams in apiDefinitionGenerator.ts and
return the full set of entries from new URLSearchParams(queryString) (optionally
trim values but do not drop empty ones) so generated APIs like
getMentorApplicationList include key-only parameters.
- Around line 75-77: Replace the exec+assignment loop with matchAll iteration to
avoid implicit-any and assignment-in-conditional issues: remove the `let match;
while ((match = brunoVarPattern.exec(processedUrl)) !== null)` pattern and use
`for (const match of processedUrl.matchAll(brunoVarPattern)) { ... }`, keeping
the same body but referencing `match[1]` (or named captures) as before;
`brunoVarPattern` already has the /g flag so no other changes are needed.
---
Outside diff comments:
In `@apps/admin/src/components/features/bruno/BrunoApiPageContent.tsx`:
- Around line 258-281: The request handler currently passes validateStatus: ()
=> true so all HTTP responses (including 4xx/5xx) go to the success path and
always call toast.success; update the logic after the axiosInstance.request call
in BrunoApiPageContent (the block that sets setRequestResult and calls toast) to
inspect response.status (or use axios.isAxiosError if preferred) and call
toast.success only for 2xx (e.g., status >=200 && status <300) and call
toast.error for non-2xx responses, leaving setRequestResult and response
header/body handling unchanged; ensure the validateStatus config remains if you
want raw responses, but branch the toast based on response.status.
In `@packages/bruno-api-typescript/src/generator/apiDefinitionGenerator.ts`:
- Around line 147-181: The hasBody logic is inconsistent: hasBody is computed as
method !== 'GET' && method !== 'HEAD' but body/bodyType use POST/PUT/PATCH
logic, causing DELETE-with-body to produce hasBody: true but body:
Record<string, never>; update the code so the same hasBody boolean (computed
from method !== 'GET' && method !== 'HEAD' and
Boolean(parsed.body?.content?.trim())) is used everywhere—replace the
POST/PUT/PATCH check in bodyType and the body field with that hasBody variable,
and ensure bodyType uses requestType when hasBody is true while bodyTypeName
continues to reflect parsed.body?.type.
🪄 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: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 94d727fb-9938-4f1e-8c0e-3e93a26dc4f0
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (7)
apps/admin/package.jsonapps/admin/src/components/features/bruno/BrunoApiPageContent.tsxpackages/api-schema/package.jsonpackages/api-schema/src/apiDefinitionRegistry.tspackages/bruno-api-typescript/src/generator/apiDefinitionGenerator.tspackages/bruno-api-typescript/src/generator/index.tspackages/bruno-api-typescript/src/parser/bruParser.ts
관련 이슈
작업 내용
/bruno화면을 generated registry 기반으로 변경해 API 목록, 도메인/메서드 필터, 요청 editor 자동 초기화를 지원합니다.특이 사항
packages/api-schema/src/apiDefinitionRegistry.ts는 admin 테스트베드가 사용하는 self-contained registry입니다.packages/api-schema/src/apis/전체 생성물은 기존 ignore 정책에 따라 커밋하지 않았습니다.리뷰 요구사항 (선택)
params:query/body block 파싱 보강이 기존 codegen 산출물에 부작용이 없는지 봐주세요.검증
pnpm --filter bruno-api-typescript buildBRUNO_COLLECTION_DIR='/Users/manwook-han/Desktop/hmw/code/solid-connect/api-docs/Solid Connection' BRUNO_SOURCE_MODE=local pnpm --filter @solid-connect/api-schema run verify:schemapnpm --filter @solid-connect/api-schema run typecheckpnpm --filter @solid-connect/admin lint:checkpnpm --filter @solid-connect/admin typecheckpnpm --filter @solid-connect/admin build