Skip to content

Feat: 모바일 애플 로그인 - #602

Merged
songwol38 merged 11 commits into
developfrom
feat/issue-543
Aug 8, 2026
Merged

songwol38 merged 11 commits into
developfrom
feat/issue-543

Conversation

@soyun0318

@soyun0318 soyun0318 commented Aug 1, 2026 •

Copy link
Copy Markdown
Collaborator

📌 PR 제목 (제목 작성 후 해당 부분은 내용에서 지워주세요!)

[Feat/#이슈 번호] " pr message "
(예시 : [Feat/#1] "로그인 기능 추가")

📌 관련 이슈번호

(Closes 키워드가 있어야 PR이 머지되었을 때 이슈가 자동으로 닫힌다)

  • Closes #이슈 번호

📌 PR 유형

어떤 변경 사항이 있나요?

  • 새 기능 추가
  • 버그 수정
  • 리팩토링

📌 PR 요약

해당 PR을 간단하게 요약해 주세요

📌 작업 세부 내용

📸 스크린샷 (선택)

🔗 참고 자료

Summary by CodeRabbit

  • 새 기능

    • 모바일 앱에서 Apple 로그인을 지원합니다.
    • Apple 인증 토큰을 사용해 신규 및 기존 사용자가 로그인할 수 있습니다.
    • 로그인 성공 시 인증 토큰과 사용자 정보를 제공합니다.
    • 탈퇴 계정 복구와 만료되거나 유효하지 않은 인증 정보 처리를 지원합니다.
  • 문서

    • 요청 형식, 성공 응답 및 주요 오류 상황을 API 문서에 추가했습니다.

@soyun0318 soyun0318 self-assigned this Aug 1, 2026
@coderabbitai

coderabbitai Bot commented Aug 1, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

백엔드에 모바일 Apple 로그인 기능을 추가합니다. 새 라우트가 LoginController를 호출합니다. 컨트롤러는 입력을 검증하고 AppleAuthService를 호출한 후 인증 결과를 반환합니다. Swagger가 요청 및 응답 형식을 문서화합니다.

Changes

모바일 Apple 로그인

Layer / File(s) Summary
Apple 로그인 엔드포인트 흐름
src/routes/auth.route.js, src/controllers/login.controller.js, src/services/auth.service.js
POST /app/signin/apple 라우트를 추가합니다. 컨트롤러는 identityToken과 선택적 사용자 JSON을 검증하고 Apple 로그인 결과를 반환합니다. 탈퇴 계정 응답과 예상하지 못한 오류 로깅을 처리합니다.
Apple 로그인 API 계약
src/swagger/swagger.yml
필수 identityToken, 선택적 user, 성공 응답 및 토큰 검증·요청·서버 오류 응답을 문서화합니다.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant MobileApp
  participant AuthRoute
  participant LoginController
  participant AppleAuthService
  MobileApp->>AuthRoute: POST /app/signin/apple with identityToken
  AuthRoute->>LoginController: appAppleLogin(req, res, next)
  LoginController->>AppleAuthService: handleAppleLogin(credentials)
  AppleAuthService-->>LoginController: authentication result or error
  LoginController-->>MobileApp: tokens, user data, or error response
Loading

Possibly related PRs

Suggested reviewers: jungmini-developer

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title 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/issue-543

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 oasdiff (1.27.0)
src/swagger/swagger.yml

Error: failed to load base spec from "/tmp/coderabbit-oasdiff-base.OL8pcC": failed to unmarshal data: json error: invalid character 'o' looking for beginning of value, yaml error: error converting YAML to JSON: yaml: unmarshal errors:
line 2381: mapping key "/api/v1/task/{taskId}/member/{userId}" already defined at line 2293


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: 4

🤖 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/controllers/login.controller.js`:
- Around line 435-447: Update the Apple credential validation near the
identityToken and appleUser parsing in the login controller: require
identityToken to be a non-empty string, and reject malformed user JSON or
invalid non-object user values with BadRequestError instead of converting them
to null and continuing. Preserve valid stringified and object user inputs for
token verification.

In `@src/swagger/swagger.yml`:
- Around line 4687-4708: Align the documented 409 response with the behavior of
AppleAuthService.handleAppleLogin: map email uniqueness conflicts to the
project’s conflict error so EMAIL_ALREADY_EXISTS is returned with the documented
payload, or remove the 409 response schema from the Swagger contract if that
mapping is not supported.
- Around line 4653-4658: Update each affected failure response schema in the
Swagger definition to replace the exposed code property with statusCode and
consistently document statusCode, errorCode, reason, and optional data. Apply
the same schema shape to all referenced failure schemas, preserving their
existing examples where applicable.
- Around line 4605-4642: Update the 200 response schema for appAppleLogin to use
oneOf with separate schemas for the normal token payload and the
withdrawn-account payload. Preserve the existing accessToken, refreshToken,
isNewUser, and user shape in one branch, and add withdrawnUser and restoreToken
in the other so generated clients support both flows.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 69475c28-be98-47c1-b2e7-e1be26bb372c

📥 Commits

Reviewing files that changed from the base of the PR and between f9b4d36 and 74eb8cc.

📒 Files selected for processing (4)
  • src/controllers/login.controller.js
  • src/routes/auth.route.js
  • src/services/auth.service.js
  • src/swagger/swagger.yml

Comment thread src/controllers/login.controller.js Resolved
Comment thread src/swagger/swagger.yml Resolved
Comment thread src/swagger/swagger.yml Resolved
Comment thread src/swagger/swagger.yml Resolved
@coderabbitai

coderabbitai Bot commented Aug 8, 2026 •

Copy link
Copy Markdown

Caution

Docstrings generation - FAILED

No docstrings were generated.

@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 `@src/swagger/swagger.yml`:
- Around line 4611-4662: Update the two schemas in the oneOf response under the
Apple login definition: require resultType, message, and data on each top-level
object, then require accessToken, refreshToken, isNewUser, and user in the
normal-login data schema and withdrawnUser and restoreToken in the
withdrawn-account data schema. Keep the existing property definitions and
examples unchanged.
🪄 Autofix

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: 5b01d82f-b79b-43bc-a26a-2f11b6739736

📥 Commits

Reviewing files that changed from the base of the PR and between 74eb8cc and 2454835.

📒 Files selected for processing (2)
  • src/controllers/login.controller.js
  • src/swagger/swagger.yml
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/controllers/login.controller.js

Comment thread src/swagger/swagger.yml
Comment on lines +4611 to +4662
oneOf:
- type: object
description: "정상 로그인 성공 응답"
properties:
resultType:
type: string
example: "SUCCESS"
message:
type: string
example: "애플 앱 로그인이 완료되었습니다."
data:
type: object
properties:
accessToken:
type: string
example: "eyJhbGciOiJIUzI1Ni..."
refreshToken:
type: string
example: "8c9d0e11-d3c4..."
isNewUser:
type: boolean
example: false
user:
type: object
properties:
id:
type: number
example: 3
email:
type: string
example: "test@apple.com"
nickname:
type: string
example: "홍길동"
- type: object
description: "탈퇴 처리된 계정으로 로그인 시도한 경우의 응답"
properties:
resultType:
type: string
example: "SUCCESS"
message:
type: string
example: "탈퇴 처리된 애플 계정입니다."
data:
type: object
properties:
withdrawnUser:
type: boolean
example: true
restoreToken:
type: string
example: "b3a1c2d4-e5f6-7890-abcd-ef1234567890"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -e

printf '%s\n' '--- swagger target ---'
sed -n '4570,4685p' src/swagger/swagger.yml

printf '%s\n' '--- related Apple-login symbols ---'
rg -n -C 3 'withdrawnUser|restoreToken|isNewUser|애플 앱 로그인이 완료되었습니다|탈퇴 처리된 계정' . \
  -g '!node_modules' -g '!dist' -g '!build'

printf '%s\n' '--- candidate response declarations ---'
rg -n -C 5 'oneOf:|Apple|apple|애플' src/swagger/swagger.yml | tail -n 240

Repository: check-task/backend

Length of output: 34890


🏁 Script executed:

#!/bin/bash
set -e

python3 - <<'PY'
from pathlib import Path

p = Path("src/swagger/swagger.yml")
lines = p.read_text().splitlines()
for n in range(4600, 4668):
    print(f"{n+1:5}: {lines[n]}")
PY

printf '%s\n' '--- response-producing code references ---'
rg -n -C 8 'withdrawnUser|restoreToken|isNewUser' . \
  -g '!node_modules' -g '!dist' -g '!build' \
  -g '*.ts' -g '*.js' -g '*.json' -g '*.yml' -g '*.yaml'

printf '%s\n' '--- available YAML parsers (read-only check) ---'
python3 - <<'PY'
try:
    import yaml
    print("PyYAML available:", yaml.__version__)
except Exception as exc:
    print("PyYAML unavailable:", type(exc).__name__)
PY

Repository: check-task/backend

Length of output: 40847


🏁 Script executed:

#!/bin/bash
set -e

python3 - <<'PY'
# Read-only behavioral probe for the two object schemas in the review.
# With no required properties and the OpenAPI default additionalProperties=true,
# each schema accepts every JSON object whose values satisfy any declared
# properties. The probe models the relevant validation rule for the supplied
# response shapes.
schemas = {
    "normal": {"accessToken", "refreshToken", "isNewUser", "user"},
    "withdrawn": {"withdrawnUser", "restoreToken"},
}
responses = {
    "normal response": {
        "resultType": "SUCCESS",
        "message": "애플 앱 로그인이 완료되었습니다.",
        "data": {
            "accessToken": "token",
            "refreshToken": "refresh",
            "isNewUser": False,
            "user": {"id": 3},
        },
    },
    "withdrawn response": {
        "resultType": "SUCCESS",
        "message": "탈퇴 처리된 애플 계정입니다.",
        "data": {"withdrawnUser": True, "restoreToken": "restore"},
    },
    "empty response": {},
}
for response_name, response in responses.items():
    matches = []
    for schema_name in schemas:
        # All declared properties are optional, and undeclared properties are
        # allowed by default, so every object matches both branches.
        if isinstance(response, dict) and isinstance(response.get("data", {}), dict):
            matches.append(schema_name)
    print(response_name, "matches", matches, "oneOf-valid=", len(matches) == 1)
PY

Repository: check-task/backend

Length of output: 359


oneOf 분기에 필수 필드를 지정하세요.

현재 정상 응답과 탈퇴 응답의 모든 필드가 선택적이고 추가 속성도 허용됩니다. 따라서 실제 두 응답이 모두 두 스키마에 일치하여 oneOf 검증에 실패합니다. 각 최상위 객체에 resultType, message, data를 지정하고, 각 data 객체에 분기별 필수 필드를 지정하세요.

🤖 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/swagger/swagger.yml` around lines 4611 - 4662, Update the two schemas in
the oneOf response under the Apple login definition: require resultType,
message, and data on each top-level object, then require accessToken,
refreshToken, isNewUser, and user in the normal-login data schema and
withdrawnUser and restoreToken in the withdrawn-account data schema. Keep the
existing property definitions and examples unchanged.

@songwol38
songwol38 merged commit dce0c38 into develop Aug 8, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants