Skip to content

✨ 지원자 현황 조회에 소속 대학 파라미터 추가 - #626

Closed
manNomi wants to merge 1 commit into
mainfrom
feat/applicants-home-university-param
Closed

✨ 지원자 현황 조회에 소속 대학 파라미터 추가#626
manNomi wants to merge 1 commit into
mainfrom
feat/applicants-home-university-param

Conversation

@manNomi

@manNomi manNomi commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

요약

GET /applications(지원자 현황) 호출 시 homeUniversityId를 쿼리 파라미터로 함께 보냅니다. 대학 검색 API(/univ-apply-infos/search/text)가 homeUniversityId를 받는 것과 같은 방식입니다.

값의 출처

클라이언트가 임의로 정하는 값이 아니라, access token에서 파싱된 로그인 사용자의 소속 대학을 그대로 보냅니다.

useAuthStore가 이미 JWT의 home_university 클레임을 homeUniversityId로 파싱해 두고 있어(parseAuthToken), 그 값을 그대로 사용했습니다. 별도 파싱 로직을 추가하지 않았습니다.

변경 내용

  • apis/applications/api.tsgetApplicationsList{ homeUniversityId }를 받아 쿼리 파라미터로 전달. universities/api.ts와 동일한 normalizePositiveInt 규칙을 적용해 유효한 양의 정수만 내보냅니다(소속 대학이 없으면 파라미터 자체가 빠짐).
  • apis/applications/getApplicants.tsuseAuthStore에서 homeUniversityId를 읽어 전달하고, queryKey에도 포함했습니다. 포함하지 않으면 계정 전환 시 다른 소속 대학의 응답이 캐시에서 그대로 재사용됩니다.

호출부(ApplicationUniversityDetailContent, ApprovedApplicationStatusPage) 수정은 필요 없습니다. 훅 내부에서 처리합니다.

확인 필요: 서버가 아직 이 파라미터를 받지 않습니다

현재 ApplicationController.getApplicantsregion, keyword@RequestParam으로 선언되어 있습니다.

public ResponseEntity<ApplicationsResponse> getApplicants(
        @AuthorizedUser long siteUserId,
        @RequestParam(required = false, defaultValue = "") String region,
        @RequestParam(required = false, defaultValue = "") String keyword
)

Spring은 선언되지 않은 쿼리 파라미터를 조용히 무시하므로, 이 PR만으로는 응답이 달라지지 않습니다. 서버에서 homeUniversityId를 받아 필터에 반영하는 작업이 함께 배포되어야 실제 범위 제한이 동작합니다.

서버 작업이 이미 진행 중이라면 그대로 두시면 되고, 아직이라면 이 PR은 그때까지 무해한 상태로 대기합니다(파라미터만 추가로 전송).

검증

  • pnpm --filter @solid-connect/web run lint:check — 통과
  • pnpm --filter @solid-connect/web run typecheck — 통과
  • 파라미터 정규화 동작 확인: 3 → 3, null/undefined/0/-1 → 미전송

🤖 Generated with Claude Code

@manNomi
manNomi requested a review from wibaek as a code owner August 3, 2026 16:38
@vercel

vercel Bot commented Aug 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
solid-connect-university-web Ready Ready Preview Aug 3, 2026 4:41pm
solid-connection-web Ready Ready Preview Aug 3, 2026 4:41pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
solid-connect-web-admin Skipped Skipped Aug 3, 2026 4:41pm

@vercel
vercel Bot temporarily deployed to Preview – solid-connect-web-admin August 3, 2026 16:38 Inactive
@github-actions github-actions Bot added the web label Aug 3, 2026
@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

  1. 대학 식별자 API 파라미터
    양의 정수만 정규화하여 /applications 요청의 쿼리 파라미터로 전달합니다.

  2. 훅 요청 및 캐시 연결
    useAuthStorehomeUniversityId를 API 호출과 React Query 캐시 키에 포함합니다.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: wibaek, enunsnv

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed 제목은 GET /applications에 로그인 사용자의 소속 대학 파라미터를 추가하는 핵심 변경을 간결하게 설명합니다.
Description check ✅ Passed 설명은 변경 내용, 값의 출처, 캐시 키 처리, 서버 의존성, 검증 결과를 구체적으로 포함합니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/applicants-home-university-param

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 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/src/apis/applications/api.ts`:
- Around line 48-57: The comment above getApplicationsList incorrectly describes
homeUniversityId as exclusively derived from the authenticated user and raises a
server authorization concern. Remove or revise that client-side assertion to
match the API contract, and ensure the server-side applications endpoint
validates the token-derived university scope before using homeUniversityId only
as a permitted filter; document the required authorization contract if server
validation is outside this diff.
🪄 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 Plus

Run ID: 9a7c033c-c685-4469-bbe0-91daf9d3409c

📥 Commits

Reviewing files that changed from the base of the PR and between 71f088b and 939a8f8.

📒 Files selected for processing (2)
  • apps/web/src/apis/applications/api.ts
  • apps/web/src/apis/applications/getApplicants.ts

Comment on lines +48 to +57
*
* homeUniversityId 는 클라이언트가 임의로 정하는 값이 아니라,
* access token 에서 파싱된 로그인 사용자의 소속 대학(useAuthStore.homeUniversityId)을 그대로 전달한다.
*/
getApplicationsList: async (): Promise<AxiosResponse<ApplicationListResponse>> => {
return axiosInstance.get("/applications");
getApplicationsList: async (params?: {
homeUniversityId?: number | null;
}): Promise<AxiosResponse<ApplicationListResponse>> => {
return axiosInstance.get("/applications", {
params: { homeUniversityId: normalizePositiveInt(params?.homeUniversityId) },
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 대학 식별자와 애플리케이션 조회의 서버 처리 위치를 찾는다.
rg -n -C 8 'homeUniversityId|home_university|/applications' .

Repository: solid-connection/solid-connect-web

Length of output: 50397


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== apps/web/src/apis/applications/api.ts =="
cat -n apps/web/src/apis/applications/api.ts

echo
echo "== token parsing and store =="
cat -n apps/web/src/lib/zustand/useAuthStore.ts | sed -n '1,120p'

echo
echo "== application calls/usages in apps/web =="
rg -n 'getApplicationsList|ApplicationsList|applicationsList|homeUniversityId' apps/web --glob '*.{ts,tsx}'

Repository: solid-connection/solid-connect-web

Length of output: 16914


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== GET /applications and competitors fixtures =="
for f in \
  packages/bruno-api-typescript/tests/fixtures/bruno-v2/applications/get-applicants.bru-1-meta \
  packages/bruno-api-typescript/tests/fixtures/bruno-v2/applications/get-applicants.bru \
  packages/bruno-api-typescript/tests/fixtures/bruno-v2/applications/get-competitors.bru \
  packages/bruno-api-typescript/tests/fixtures/bruno/applications/get-applicants.bru-1-meta \
  packages/bruno-api-typescript/tests/fixtures/bruno/applications/get-applicants.bru \
  packages/bruno-api-typescript/tests/fixtures/bruno/applications/get-competitors.bru
do
  if [ -f "$f" ]; then
    echo "--- $f"
    cat -n "$f" | sed -n '1,220p'
  fi
done

echo "== API definitions for /applications =="
rg -n -C 12 '"path": "\{\{URL\}\}/applications"|"/applications"|applicants|homeUniversityId' packages/api-schema src apps packages/bruno-api-typescript/tests/fixtures/bruno packages/bruno-api-typescript/tests/fixtures/bruno-v2 | sed -n '1,260p'

echo "== generated schema paths containing applications =="
python3 - <<'PY'
import json, pathlib
for p in pathlib.Path('packages/api-schema').rglob('*.json'):
    try:
        data=json.loads(p.read_text())
    except Exception: continue
    k='/applications'
    ks='/applications/competitors'
    ks2='/applications/applicants'
    hits=[]
    for path, methods in data.get('paths',{}).items():
        if path == k or path == ks or path == ks2:
            hits.append((str(p),path,methods))
    if hits:
        for hit in hits:
            print('---',hit[0])
            print(hit[1], list(hit[2]))
            for m,v in hit[2].items():
                print(m,v)
PY

Repository: solid-connection/solid-connect-web

Length of output: 22682


1. homeUniversityId가 클라이언트 임의 값임을 문서에 포함하지 마세요.

- `GET /applications`는 현재 accept header와 query params만 명시되어 있어, client가 token에서 읽은 값을 그대로 query string으로 바꿀 수 있습니다.
- `"homeUniversityId 는 클라이언트가 임의로 정하는 값이 아니라"`라는 주석은 서버 계약과 다릅니다.

2. 서버는 token 기반으로 접근 범위를 검증하세요.

- 서버가 `homeUniversityId`를 사용한다면 서버 내부 인증 정보에서 파손되지 않은 값으로 권한 경계를 확인한 후 필터로만 사용하세요.
- request가 단순 필터처럼 보이거나 서버 검증이 보이지 않으면 권한 bypass 위험을 문서화해 서버 쪽 보안 검증 계약과 맞추세요.
🤖 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/src/apis/applications/api.ts` around lines 48 - 57, The comment
above getApplicationsList incorrectly describes homeUniversityId as exclusively
derived from the authenticated user and raises a server authorization concern.
Remove or revise that client-side assertion to match the API contract, and
ensure the server-side applications endpoint validates the token-derived
university scope before using homeUniversityId only as a permitted filter;
document the required authorization contract if server validation is outside
this diff.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant