Skip to content

[Feat] QR 스캔 미지원 브랜드, 신속한 파싱 전략 수립을 위한 디스코드 웹훅 설정 #188#189

Merged
Remaked-Swain merged 6 commits intodevelopfrom
feat/#188-qr-parsing-webhook
Mar 24, 2026
Merged

[Feat] QR 스캔 미지원 브랜드, 신속한 파싱 전략 수립을 위한 디스코드 웹훅 설정 #188#189
Remaked-Swain merged 6 commits intodevelopfrom
feat/#188-qr-parsing-webhook

Conversation

@Remaked-Swain
Copy link
Copy Markdown
Member

@Remaked-Swain Remaked-Swain commented Mar 24, 2026

🌴 작업한 브랜치

✅ 작업한 내용

미지원 브랜드에 대한 QR 스캔 시도 시, 파싱 전략 수립을 위해 디스코드 웹훅을 이용해 알림을 띄우고 QR URL을 확보할 수 있도록 했습니다.

  1. 디스코드 웹훅 주소 따와서 XCConfig 및 번들에 기록했습니다.
  2. QRScanner 모듈쪽에 Endpoint 정의해서 디스코드 웹훅을 트리거링 할 수 있습니다.
  3. 미지원 브랜드 스캔 감지 시, 미지원 브랜드를 안내하는 얼럿과 구글폼을 제공함과 동시에 Fire&Forget으로 디스코드 웹훅을 전송합니다.

그리고 자잘하게 UI 컴포넌트 디자인적 변경점이 있는 것 같아서 이참에 하려고 했는데 막상 살펴보니 바꿀게 딱히 없어서 태스크에서 제외했습니다.

❗️PR Point

간단한 구현이므로 생략합니다!

디스코드 스레드에서 해당 기능을 프론트에서 할지, 백엔드에서 할지 의논하다가 프론트에서 하는 걸로 잠정 결론나서 구현했는데, 나중에 백엔드에서 하게될 수도 있다는 점만 인지해두시면 될 듯합니다.

📸 스크린샷

디스코드 웹훅 테스트로 대체합니다!

📟 관련 이슈

Summary by CodeRabbit

  • 새로운 기능
    • QR 코드 스캔 시 현재 사용자 정보가 스캔 흐름에 포함되어 전달됩니다.
    • 지원되지 않는 QR 코드 형식이 감지되면 외부에 자동으로 알림을 전송하는 보고 기능이 추가됩니다.
    • 외부 알림 대상 URL을 설정에서 지정할 수 있도록 앱 설정 키가 추가되었습니다.

@Remaked-Swain Remaked-Swain added this to the 3차 스프린트 milestone Mar 24, 2026
@Remaked-Swain Remaked-Swain requested a review from OneTen19 March 24, 2026 10:53
@Remaked-Swain Remaked-Swain self-assigned this Mar 24, 2026
@Remaked-Swain Remaked-Swain added Add ✚ 코드, 파일, 에셋 추가 Chore 🪡 자잘한 코드 수정 Feat 💻 기능 구현 Setting ⚙️ 개발 환경 세팅 금용 🐲 금용 작업 labels Mar 24, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 24, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 10fe2dcd-dbe8-4651-9bd6-14fad1903b8d

📥 Commits

Reviewing files that changed from the base of the PR and between b1fc655 and 0719dfd.

📒 Files selected for processing (1)
  • Neki-iOS/Features/QRCodeScanner/Sources/Data/Sources/Repositories/DTOs/DiscordWebhookDTO.swift
✅ Files skipped from review due to trivial changes (1)
  • Neki-iOS/Features/QRCodeScanner/Sources/Data/Sources/Repositories/DTOs/DiscordWebhookDTO.swift

Walkthrough

QR 스캔 흐름에 사용자 컨텍스트를 전파하도록 상태와 시그니처를 변경하고, 미지원 브랜드 검출 시 Discord 웹훅으로 비동기 알림을 전송하는 로직을 추가합니다.

Changes

Cohort / File(s) Summary
State & Coordination
Neki-iOS/APP/Sources/MainTab/MainTabCoordinator.swift, Neki-iOS/Features/QRCodeScanner/Sources/Presentation/Sources/Features/QRCodeScanFeature.swift
QRCodeScanFeature 상태에 user: User 추가 및 Coordinator가 QR 스캔 목적지 초기화 시 사용자 컨텍스트 전달. 스캔 처리 흐름에서 사용자 정보를 파싱 호출로 전파.
Domain API / Client
Neki-iOS/Features/QRCodeScanner/Sources/Domain/Sources/Interfaces/QRCodeScanRepository.swift, Neki-iOS/Features/QRCodeScanner/Sources/Domain/Sources/Clients/QRCodeScannerClient.swift
parse 시그니처에 user: User 파라미터 추가(프로토콜 및 클라이언트 라이브 구현 모두 수정).
Repository Implementation
Neki-iOS/Features/QRCodeScanner/Sources/Data/Sources/Repositories/DefaultQRCodeScanRepository.swift
parse(_:user:)로 변경. 파싱 전략 미매칭 시 분기에서 detached background task로 notifyUnsupportedBrand 엔드포인트 호출 시도; 실패는 로깅으로 처리.
Network Endpoint & DTO
Neki-iOS/Features/QRCodeScanner/Sources/Data/Sources/Repositories/QRCodeScannerEndpoint.swift, Neki-iOS/Features/QRCodeScanner/Sources/Data/Sources/Repositories/DTOs/DiscordWebhookDTO.swift
새 엔드포인트 notifyUnsupportedBrand(url:user:) 추가 및 Discord 웹훅 페이로드 DTO(DiscordWebhookDTO.Request) 구현(임베드 형식, 호스트/사용자/원본 URL 포함).
Config
Neki-iOS/Info.plist
빌드 설정에서 읽는 QR_WEBHOOK_URL 키 추가.
Minor
(imports) .../DefaultQRCodeScanRepository.swift
import os 추가 및 관련 로깅 사용.

Sequence Diagram(s)

sequenceDiagram
    participant User as 사용자
    participant QRFeature as QRCodeScanFeature
    participant Client as QRScannerClient
    participant Repo as DefaultQRCodeScanRepository
    participant Strategy as QRCodeParsingStrategy
    participant Network as NetworkProvider
    participant Webhook as DiscordWebhook

    User->>QRFeature: QR 스캔(데이터)
    QRFeature->>Client: parse(urlString, user)
    Client->>Repo: parse(url, user)
    Repo->>Strategy: 파싱 시도
    Strategy-->>Repo: 매칭 실패
    Repo->>Network: detached background task로<br/>notifyUnsupportedBrand(url,user) 호출
    Network->>Webhook: POST (embed: URL, host, user)
    Webhook-->>Network: 응답
    Network-->>Repo: 완료/오류(로깅)
    Repo-->>Client: throw .unsupportedBrand
    Client-->>QRFeature: throw QRParseError
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목이 미지원 QR 브랜드 감지 시 디스코드 웹훅 설정을 통한 파싱 전략 수립에 대한 변경사항을 명확하게 설명하고 있으며, 이슈 #188과 관련된 주요 변경 내용을 잘 반영합니다.
Description check ✅ Passed PR 설명이 작업 브랜치, 상세한 작업 내용, PR Point, 관련 이슈 등 템플릿의 주요 섹션을 포함하고 있으며, 구현 내용이 명확하게 작성되었습니다.
Linked Issues check ✅ Passed 모든 이슈 #188의 코딩 요구사항이 충족되었습니다: 디스코드 웹훅 URL 환경변수 설정, API/네트워크 요청 구현, 미지원 URL 감지 시 웹훅 트리거 및 에러 핸들링이 모두 구현되었습니다.
Out of Scope Changes check ✅ Passed 모든 변경사항이 이슈 #188의 범위 내에 있습니다: 디스코드 웹훅 설정, DTO 및 엔드포인트 정의, 저장소 및 클라이언트 업데이트가 모두 미지원 브랜드 감지 및 웹훅 알림 기능과 직접적으로 관련이 있습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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/#188-qr-parsing-webhook

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 and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
Neki-iOS/Features/QRCodeScanner/Sources/Domain/Sources/Interfaces/QRCodeScanRepository.swift (1)

23-23: parse 계약을 User에 묶지 않는 편이 낫습니다.

지원 브랜드 파싱 자체는 URL만 필요해서, unsupported-brand 리포팅 때문에 User를 필수 인자로 만들면 파싱 레이어가 인증 모델에 결합됩니다. 리포터 의존성이나 최소 진단용 컨텍스트로 분리해 두면 테스트와 재사용성이 좋아집니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@Neki-iOS/Features/QRCodeScanner/Sources/Domain/Sources/Interfaces/QRCodeScanRepository.swift`
at line 23, The parse signature on QRCodeScanRepository currently couples
parsing to authentication by requiring a User; change the contract so func
parse(_ url: URL) async throws(QRParseError) -> ParsedQRResult (remove the User
parameter from parse in QRCodeScanRepository and all implementations), and move
any user-dependent reporting to a separate method or injected reporter (e.g.,
add a reportUnsupportedBrand(_ result: ParsedQRResult, by user: User) or inject
an UnsupportedBrandReporter into the higher-level use case). Update all callers
of QRCodeScanRepository.parse, repository implementations, and unit tests to
call the new parse(url) and perform user-scoped actions via the new reporter or
reporting method.
Neki-iOS/Features/QRCodeScanner/Sources/Data/Sources/Repositories/DefaultQRCodeScanRepository.swift (1)

31-35: NetworkProviderSendable 명시 추가 검토 (선택사항)

현재는 DefaultNetworkProvideractor로 선언되어 자동으로 Sendable을 준수하므로 문제가 없습니다. 다만 프로토콜 NetworkProvider 자체에 Sendable 준수를 명시하면, 향후 strict concurrency를 완전히 활성화할 때 타입 안정성을 더욱 명확히 할 수 있습니다:

public protocol NetworkProvider: Sendable {
    func requestVoid(endpoint: Endpoint) async throws -> Void
    func request(endpoint: Endpoint) async throws -> BaseResponseDTO<EmptyData>
    func request<T: Decodable>(endpoint: Endpoint) async throws -> BaseResponseDTO<T>
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@Neki-iOS/Features/QRCodeScanner/Sources/Data/Sources/Repositories/DefaultQRCodeScanRepository.swift`
around lines 31 - 35, Add explicit Sendable conformance to the NetworkProvider
protocol so the compiler enforces concurrency safety (this clarifies usage when
DefaultNetworkProvider is an actor); update the protocol declaration for
NetworkProvider to conform to Sendable and ensure its async methods
(requestVoid(endpoint:), request(endpoint:), and request<T:
Decodable>(endpoint:)) remain compatible with Sendable so Task.detached usage
with DefaultNetworkProvider is type-safe under stricter concurrency checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@Neki-iOS/Features/QRCodeScanner/Sources/Data/Sources/Repositories/DTOs/DiscordWebhookDTO.swift`:
- Around line 34-36: Remove direct personal identifiers and full QR URLs from
the Discord payload in DiscordWebhookDTO: stop sending user.nickname and user.id
and the unsupportedURL.absoluteString; instead send only non-identifying minimal
diagnostics (e.g., host/domain and a high-level event type) or a
truncated/hashed identifier if you must correlate internally, and strip any
query string or token from URLs (collect full URL only on a protected backend
endpoint). Update the Field entries (the lines constructing "👤 User", "🔗 Full
URL", etc.) accordingly so no raw PII or full URLs are emitted.

In `@Neki-iOS/Info.plist`:
- Around line 5-6: The QR_WEBHOOK_URL key in Info.plist (QR_WEBHOOK_URL) exposes
the Discord webhook in the final app bundle; remove this key/value and stop
calling the webhook directly from the client (e.g., any code referencing
QR_WEBHOOK_URL), and instead implement a server-side endpoint that the app calls
(e.g., POST /api/send-qr-webhook) which performs the actual Discord webhook
request; update the client to call that secure server API and ensure the server
stores the webhook secret in its environment/config rather than embedding it in
the app bundle.

---

Nitpick comments:
In
`@Neki-iOS/Features/QRCodeScanner/Sources/Data/Sources/Repositories/DefaultQRCodeScanRepository.swift`:
- Around line 31-35: Add explicit Sendable conformance to the NetworkProvider
protocol so the compiler enforces concurrency safety (this clarifies usage when
DefaultNetworkProvider is an actor); update the protocol declaration for
NetworkProvider to conform to Sendable and ensure its async methods
(requestVoid(endpoint:), request(endpoint:), and request<T:
Decodable>(endpoint:)) remain compatible with Sendable so Task.detached usage
with DefaultNetworkProvider is type-safe under stricter concurrency checks.

In
`@Neki-iOS/Features/QRCodeScanner/Sources/Domain/Sources/Interfaces/QRCodeScanRepository.swift`:
- Line 23: The parse signature on QRCodeScanRepository currently couples parsing
to authentication by requiring a User; change the contract so func parse(_ url:
URL) async throws(QRParseError) -> ParsedQRResult (remove the User parameter
from parse in QRCodeScanRepository and all implementations), and move any
user-dependent reporting to a separate method or injected reporter (e.g., add a
reportUnsupportedBrand(_ result: ParsedQRResult, by user: User) or inject an
UnsupportedBrandReporter into the higher-level use case). Update all callers of
QRCodeScanRepository.parse, repository implementations, and unit tests to call
the new parse(url) and perform user-scoped actions via the new reporter or
reporting method.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: e812a49f-0331-4491-b0f1-de1d006a6729

📥 Commits

Reviewing files that changed from the base of the PR and between 4c8fd3f and b1fc655.

📒 Files selected for processing (8)
  • Neki-iOS/APP/Sources/MainTab/MainTabCoordinator.swift
  • Neki-iOS/Features/QRCodeScanner/Sources/Data/Sources/Repositories/DTOs/DiscordWebhookDTO.swift
  • Neki-iOS/Features/QRCodeScanner/Sources/Data/Sources/Repositories/DefaultQRCodeScanRepository.swift
  • Neki-iOS/Features/QRCodeScanner/Sources/Data/Sources/Repositories/QRCodeScannerEndpoint.swift
  • Neki-iOS/Features/QRCodeScanner/Sources/Domain/Sources/Clients/QRCodeScannerClient.swift
  • Neki-iOS/Features/QRCodeScanner/Sources/Domain/Sources/Interfaces/QRCodeScanRepository.swift
  • Neki-iOS/Features/QRCodeScanner/Sources/Presentation/Sources/Features/QRCodeScanFeature.swift
  • Neki-iOS/Info.plist

Comment on lines +34 to +36
Field(name: "👤 User", value: "\(user.nickname) (ID: \(user.id))", inline: true),
Field(name: "🌐 Host", value: host, inline: true),
Field(name: "🔗 Full URL", value: unsupportedURL.absoluteString, inline: false)
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot Mar 24, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

개인 식별자와 QR 원문 URL을 디스코드로 직접 보내면 개인정보 유출입니다.

nickname, 내부 id, 전체 QR URL 조합이면 사용자를 재식별할 수 있고, query/token이 붙은 URL이면 접근 정보까지 외부 시스템에 남을 수 있습니다. 최소 진단 정보만 보내고, 원문 URL이 꼭 필요하면 접근 제어되는 백엔드에서 수집하세요.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@Neki-iOS/Features/QRCodeScanner/Sources/Data/Sources/Repositories/DTOs/DiscordWebhookDTO.swift`
around lines 34 - 36, Remove direct personal identifiers and full QR URLs from
the Discord payload in DiscordWebhookDTO: stop sending user.nickname and user.id
and the unsupportedURL.absoluteString; instead send only non-identifying minimal
diagnostics (e.g., host/domain and a high-level event type) or a
truncated/hashed identifier if you must correlate internally, and strip any
query string or token from URLs (collect full URL only on a protected backend
endpoint). Update the Field entries (the lines constructing "👤 User", "🔗 Full
URL", etc.) accordingly so no raw PII or full URLs are emitted.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

토큰 등을 사용하지 않는 URL이어서 원문 URL을 써도 보안상 문제될 여지는 없으므로 기각.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@Remaked-Swain, 이해했습니다. 해당 QR URL에 인증 토큰이나 민감 파라미터가 포함되지 않는다면 원문 URL 전송은 문제 없습니다. 다만 user.nickname + user.id 조합은 서비스 내 사용자 재식별이 가능한 정보이므로, 향후 백엔드 이관 시 GDPR/개인정보보호법 관점에서 수집 정책을 함께 검토하시면 좋겠습니다. 결정 존중합니다.

Comment thread Neki-iOS/Info.plist
Comment on lines +5 to +6
<key>QR_WEBHOOK_URL</key>
<string>$(QR_WEBHOOK_URL)</string>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot Mar 24, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

XCConfig를 거쳐도 웹훅 URL은 최종 앱 번들에 평문으로 포함됩니다.

디스코드 웹훅 URL 자체가 인증 비밀값이라 IPA/앱 번들에서 추출되면 아무나 채널에 임의 메시지를 보낼 수 있습니다. 클라이언트는 자체 API만 호출하고, 실제 웹훅 호출은 서버에서 중계해야 합니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Neki-iOS/Info.plist` around lines 5 - 6, The QR_WEBHOOK_URL key in Info.plist
(QR_WEBHOOK_URL) exposes the Discord webhook in the final app bundle; remove
this key/value and stop calling the webhook directly from the client (e.g., any
code referencing QR_WEBHOOK_URL), and instead implement a server-side endpoint
that the app calls (e.g., POST /api/send-qr-webhook) which performs the actual
Discord webhook request; update the client to call that secure server API and
ensure the server stores the webhook secret in its environment/config rather
than embedding it in the app bundle.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

이런 하꼬앱은 괜찮음. 나중에 고려해볼것.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@Remaked-Swain, 알겠습니다! 나중에 백엔드로 이전하실 때 함께 처리하시면 좋을 것 같습니다. 혹시 나중에 놓치지 않도록 GitHub 이슈로 등록해 드릴까요?

( T_T)\ (  ヽ♡

Copy link
Copy Markdown
Member

@OneTen19 OneTen19 left a comment

Choose a reason for hiding this comment

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

수고하셨습니다!!

나도 config 내용 줘!!


import Foundation

public enum DiscordWebhookDTO {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

p3

이 dto는 어디 나와있죠??? 맘대로 정할 수 있는건감??

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

디스코드 웹훅 API 문서를 참고했습니다.
공식문서

struct Field: Encodable {
let name: String
let value: String
let inline: Bool
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

p3

인라인은 뭐지

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

DM에 보여지는 형태를 의미합니다.

Comment on lines 26 to +38
for strategy in strategies {
guard strategy.canHandle(host: host) else { continue }
return try await strategy.parse(url, networkProvider: networkProvider)
}

Task.detached(priority: .background) {
do {
let endpoint = QRCodeScannerEndpoint.notifyUnsupportedBrand(url: url, user: user)
try await networkProvider.requestVoid(endpoint: endpoint)
} catch {
Logger.network.error("미지원 브랜드 디스코드 웹훅 발송 실패: \(error)")
}
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

p3

전략에서 적합한 부분이 없으면 return이 실행이 안 돼서 throw로 에러보내던 로직 사이에
Task.detached 문이 추가된거군. 중요도 높은 기능이 아니라 .background로 한 거일테고!!
그럼 unsupportedBrand 에러 throw도 하면서 백그라운드 스레드에서는 디코 웹훅을 보내는 구조겠군요!

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

맞습니다. 미지원 브랜드 얼럿 표시를 위해 UI 블로킹 하면 안되면서 디스코드 웹훅을 보내기 위해 별도의 비동기 작업을 진행합니다.

struct Embed: Encodable {
let title: String
let description: String
let color: Int
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

p3

color를 int로 받는 이유는 클아 때문인가요 아니면 디코 정책 때문인가요 둘 다인가요

Copy link
Copy Markdown
Member Author

@Remaked-Swain Remaked-Swain Mar 24, 2026

Choose a reason for hiding this comment

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

그냥 눈에 잘띄도록 디엠 색깔을 넣을 수 있는 옵션이 있어서 썼어요. 큰 의도는 없습니다. Constructor Injection 없이 기본값으로 빨간색 줘도 돼요.

color: 16711680, // 빨강색 (Hex: FF0000)
fields: [
Field(name: "🍎 Platform", value: "iOS", inline: true),
Field(name: "👤 User", value: "\(user.nickname) (ID: \(user.id))", inline: true),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

p3

유저가 왜 필요한가 했더니 유저 이름이랑 아이디 받고 있구나

@Remaked-Swain Remaked-Swain merged commit 0565565 into develop Mar 24, 2026
1 check passed
@Remaked-Swain Remaked-Swain deleted the feat/#188-qr-parsing-webhook branch March 24, 2026 13:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Add ✚ 코드, 파일, 에셋 추가 Chore 🪡 자잘한 코드 수정 Feat 💻 기능 구현 Setting ⚙️ 개발 환경 세팅 금용 🐲 금용 작업

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feat] QR 스캔 미지원 브랜드, 신속한 파싱 전략 수립을 위한 디스코드 웹훅 설정

2 participants