Server-develop(구축)#16
Conversation
- scheme을 더 세분화 하여 구분하기 위한 DTO수정
- schemeType을 세분화함에 따라 각 scheme의 필터링 로직 추가 - 정확한 탐지를 위해 pattern, matcher 라이브러리 사용
- 잘못된 메소드명 수정 - be2에게 보내는 json 데이터 구체화
Fixed 2 file(s) based on 3 unresolved review comments. Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
Added a comprehensive guide for connecting to the Veri-Q server and local development setup, including service ports, Docker deployment, and GitHub Actions for automatic deployment.
Updated database connection details in README.
Added docker-compose configuration for MySQL, Redis, Spring, and FastAPI services.
schemeClassifier 클래스 수정
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
Walkthrough배포 워크플로우·컨테이너 설정 및 README가 추가되었고, 신규 Gateway 애플리케이션(요청 제한·reCAPTCHA 포함)과 BE3의 QR 처리 호출·스킴 분류 로직이 확장되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
actor Client
participant Gateway as Gateway (앱)
participant Security as SecurityService (Redis)
participant BE3 as BE3 Backend
participant Google as Google reCAPTCHA
Client->>Gateway: POST /scan (guest_uuid + image)
Gateway->>Security: isAllowed(guestUuid)
Security->>Security: Redis 조회/카운트 처리
alt 제한 초과 (≥10)
Security-->>Gateway: false
Gateway-->>Client: 429 REJECTED (REQUIRE_CAPTCHA)
else 허용
Security-->>Gateway: true
Gateway->>BE3: Forward multipart /api/v1/scan/upload
BE3-->>Gateway: QrScanResponse
Gateway-->>Client: 200 PENDING
end
sequenceDiagram
actor Client
participant Gateway as Gateway (앱)
participant Security as SecurityService (Redis)
participant Google as Google reCAPTCHA
Client->>Gateway: POST /auth/captcha/verify (captchaToken, guestUuid)
Gateway->>Security: verifyWithGoogle(token)
Security->>Google: POST verification (secret + token)
alt 검증 성공
Google-->>Security: success=true
Security->>Security: resetCount(guestUuid) (Redis 키 삭제)
Security-->>Gateway: true
Gateway-->>Client: 200 SUCCESS
else 검증 실패
Google-->>Security: success=false
Security-->>Gateway: false
Gateway-->>Client: 400 REJECTED
end
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 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: 12
🧹 Nitpick comments (10)
src/main/resources/application-be3.yml (1)
14-16: 프로덕션 환경에서ddl-auto: update사용은 위험합니다.
ddl-auto: update는 애플리케이션 시작 시 예기치 않은 스키마 변경을 일으킬 수 있습니다. 개발 환경에서는 괜찮지만, 프로덕션 환경에서는validate또는none을 사용하고 Flyway나 Liquibase 같은 마이그레이션 도구를 사용하는 것이 좋습니다.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/resources/application-be3.yml` around lines 14 - 16, 현재 설정의 jpa.hibernate.ddl-auto: update는 프로덕션에서 예기치 않은 스키마 변경을 초래할 수 있으니, 프로덕션 프로파일에서는 해당 값을 'validate' 또는 'none'으로 변경하고 스키마 변경은 Flyway 또는 Liquibase 같은 마이그레이션 도구로 관리하도록 설정을 변경하세요; 즉 설정 키 jpa.hibernate.ddl-auto를 프로덕션 구성에서 update가 아닌 validate/none으로 바꾸고, DB 마이그레이션을 위해 Flyway/Liquibase 설정 및 마이그레이션 스크립트를 추가해 배포 시 스키마 변경을 안전하게 적용되게 하세요.src/main/java/com/veriq/veriqbe3/controller/QrScanController.java (1)
22-28: 예외 처리에서 오류 정보가 손실됩니다.모든 예외를 잡아서 빈 400 응답을 반환하면 디버깅이 어려워집니다. 최소한 로깅을 추가하거나, 클라이언트에게 유용한 오류 메시지를 제공하는 것이 좋습니다.
♻️ 개선 제안
+import lombok.extern.slf4j.Slf4j; + +@Slf4j `@RestController` `@RequestMapping`("/api/v1/scan") `@RequiredArgsConstructor` public class QrScanController { // ... try { QrScanResponse response = processQrScan.process(image, guestUuid); - return ResponseEntity.ok(response); - + return ResponseEntity.ok(response); } catch (Exception e) { + log.error("QR 스캔 처리 중 오류 발생: {}", e.getMessage(), e); return ResponseEntity.badRequest().build(); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/veriq/veriqbe3/controller/QrScanController.java` around lines 22 - 28, The catch-all in QrScanController that returns an empty 400 loses error details; update the exception handling around the call to processQrScan.process(image, guestUuid) to log the exception (use a Logger for QrScanController) including e.getMessage() and stacktrace, and return a more informative ResponseEntity (e.g., ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ErrorResponse(...)) or include a simple error message in the body) so callers and logs retain the error information.src/main/resources/application.yml (1)
1-27: 설정 파일 간 중복이 많습니다.
application.yml,application-be1.yml,application-be3.yml이 거의 동일한 설정(datasource, JPA, Redis)을 포함하고 있습니다. 공통 설정은 기본application.yml에 두고, 프로필별 파일에는 차이점(예: 포트 번호)만 정의하는 것이 좋습니다.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/resources/application.yml` around lines 1 - 27, The config files duplicate datasource, JPA, and Redis settings across application.yml, application-be1.yml, and application-be3.yml; refactor by keeping common properties (spring.datasource.*, spring.jpa.*, spring.data.redis.* and hibernate dialect/format settings) in the base application.yml and move only profile-specific overrides (e.g., server.port, hostnames or any environment-specific values) into application-be1.yml and application-be3.yml using Spring profiles (spring.profiles: be1 / be3 or application-be1.yml naming convention) so the duplicate blocks are removed and each profile file contains only the differences.src/main/java/com/veriq/veriqbe3/service/ProcessQrScan.java (2)
37-51: 응답 빌더 코드 중복을 줄일 수 있습니다.WEB/SHORT_URL 분기와 기본 분기에서 동일한 빌더 패턴이 반복됩니다. status 값만 다르므로 통합할 수 있습니다.
♻️ 중복 제거 제안
- String status = "COMPLETED"; - - //WEB이나 단축 URL이면 - if (result.type() == SchemeType.WEB || result.type() == SchemeType.SHORT_URL) { - return QrScanResponse.builder() - .guestUuid(guest_uuid) - .schemeType(result.type()) - .typeInfo(result.typeInfo()) - .status("ANALYSIS_COMPLETED") // BE2 연동 후 실제 결과 상태로 변경 - .build(); - } + String status = (result.type() == SchemeType.WEB || result.type() == SchemeType.SHORT_URL) + ? "ANALYSIS_COMPLETED" // BE2 연동 후 실제 결과 상태로 변경 + : "COMPLETED"; + return QrScanResponse.builder() - .guestUuid(guest_uuid) // FE가 보낸 식별자 + .guestUuid(guest_uuid) .schemeType(result.type()) .typeInfo(result.typeInfo()) .status(status) .build();🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/veriq/veriqbe3/service/ProcessQrScan.java` around lines 37 - 51, In ProcessQrScan.java refactor the duplicated QrScanResponse.builder() calls by computing the status value first (e.g., determine a local variable like resolvedStatus = (result.type() == SchemeType.WEB || result.type() == SchemeType.SHORT_URL) ? "ANALYSIS_COMPLETED" : status) and then perform a single QrScanResponse.builder().guestUuid(guest_uuid).schemeType(result.type()).typeInfo(result.typeInfo()).status(resolvedStatus).build(); this removes the conditional duplication while preserving the special-case status for WEB/SHORT_URL.
21-21: 파라미터 이름이 Java 명명 규칙을 따르지 않습니다.
guest_uuid는 Java의 camelCase 규칙에 따라guestUuid로 변경하는 것이 좋습니다.♻️ 명명 규칙 수정 제안
- public QrScanResponse process(MultipartFile image, String guest_uuid) throws Exception { + public QrScanResponse process(MultipartFile image, String guestUuid) throws Exception {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/veriq/veriqbe3/service/ProcessQrScan.java` at line 21, Rename the method parameter guest_uuid to follow Java camelCase (guestUuid) in the ProcessQrScan.process method signature and update all references inside the method and any callers; specifically change the parameter name in public QrScanResponse process(MultipartFile image, String guest_uuid) to guestUuid, update uses of guest_uuid within the ProcessQrScan class (and any related methods or member variable assignments), and adjust all places that call ProcessQrScan.process(...) to pass and reference guestUuid so compilation and naming consistency are preserved.src/main/java/com/veriq/veriqgateway/dto/ScanResponse.java (1)
8-13: 필드 접근 제어자와 명명 규칙 문제가 있습니다.
guestUuid필드에private접근 제어자가 누락되었습니다.error_code는 Java 명명 규칙에 따라errorCode로 변경해야 합니다.♻️ 수정 제안
public class ScanResponse { - String guestUuid; // 사용자 식별용 + private String guestUuid; // 사용자 식별용 private String status; // PENDING 등 - private String error_code; // REQUIRE_CAPTCHA + private String errorCode; // REQUIRE_CAPTCHA private String message; }만약 JSON 응답에서
error_code형태를 유지해야 한다면,@JsonProperty("error_code")를 사용하세요.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/veriq/veriqgateway/dto/ScanResponse.java` around lines 8 - 13, Make guestUuid private and rename the field error_code to errorCode in the ScanResponse class to follow Java access and naming conventions; update any usages accordingly (e.g., field references, getters/setters). If the API must emit/consume snake_case JSON, annotate the renamed field with `@JsonProperty`("error_code") on the field (or its getter/setter) so JSON remains error_code while the Java field is errorCode. Ensure the class compiles by adjusting any constructors, equals/hashCode, or serialization logic that referenced the old names.README.md (2)
9-16: 마크다운 포맷팅: 테이블 주변에 빈 줄을 추가하세요.테이블 앞뒤에 빈 줄이 없으면 일부 마크다운 렌더러에서 올바르게 표시되지 않을 수 있습니다.
📝 수정 제안
### 서비스별 포트 + | 서비스 | 포트 | 용도 | | :--- | :--- | :--- | ... | **Redis** | `6379` | 캐시 서버 | + ---🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@README.md` around lines 9 - 16, The markdown table starting at the header "### 서비스별 포트" lacks blank lines before and after it; update the README.md so there is one empty line above the "### 서비스별 포트" heading (or at least between the previous paragraph and the heading) and one empty line after the table block (after the last Redis row) to ensure proper rendering in all markdown renderers; locate the table by the header text and the table rows containing "Spring BE1", "Spring BE3", "FastAPI", "MySQL", and "Redis" and insert the blank lines accordingly.
26-26: 마크다운 포맷팅: 강조 마커 내부 공백을 제거하세요.
**.🍃 Spring Boot, ⚡ FastAPI **형식이 올바르지 않습니다.📝 수정 제안
-### **.🍃 Spring Boot, ⚡ FastAPI ** +### 🍃 Spring Boot / ⚡ FastAPI🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@README.md` at line 26, Update the Markdown emphasis so the bold markers directly wrap the text: replace the string "**.🍃 Spring Boot, ⚡ FastAPI **" with "**.🍃 Spring Boot, ⚡ FastAPI**" (remove the extra space before the closing ** in the heading) so the bold formatting is valid; locate and edit the heading line shown as ".🍃 Spring Boot, ⚡ FastAPI" in the README.src/main/java/com/veriq/veriqgateway/VeriQGatewayApplication.java (1)
22-25: RestTemplate에 타임아웃 설정을 추가하세요.기본 RestTemplate은 타임아웃이 무제한이므로, 외부 서비스(Google reCAPTCHA, BE3)가 응답하지 않으면 요청이 무한히 대기할 수 있습니다.
♻️ 타임아웃 설정 추가 제안
+import org.springframework.http.client.SimpleClientHttpRequestFactory; + `@Bean` public RestTemplate restTemplate() { - return new RestTemplate(); + SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); + factory.setConnectTimeout(5000); // 연결 타임아웃 5초 + factory.setReadTimeout(10000); // 읽기 타임아웃 10초 + return new RestTemplate(factory); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/veriq/veriqgateway/VeriQGatewayApplication.java` around lines 22 - 25, The RestTemplate bean (restTemplate() in VeriQGatewayApplication) lacks timeouts so calls can hang; replace the plain new RestTemplate() with one backed by a ClientHttpRequestFactory that sets connect and read timeouts (e.g., HttpComponentsClientHttpRequestFactory or SimpleClientHttpRequestFactory), configure sensible values (e.g., connectTimeout and readTimeout) or wire them from properties, and return the RestTemplate built with that factory so external calls (Google reCAPTCHA, BE3) cannot wait indefinitely..github/workflows/deploy.yml (1)
20-25: 배포 스크립트에 오류 처리와 검증이 없습니다.
- 명령이 실패해도 이후 명령이 계속 실행됩니다.
- 배포 후 서비스 상태 확인이 없습니다.
sudo ./gradlew bootJar가 루트 권한으로 파일을 생성하여 이후 권한 문제가 발생할 수 있습니다.♻️ 개선된 배포 스크립트 제안
script: | + set -e # 오류 시 즉시 중단 cd /home/sk38808738/main-server git pull origin develop chmod +x gradlew - sudo ./gradlew bootJar - sudo docker-compose up --build -d + ./gradlew bootJar + sudo docker-compose up --build -d + # 헬스체크 + sleep 10 + docker ps | grep -E "(veriq-be1|veriq-be3)" | grep -v "Restarting"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/deploy.yml around lines 20 - 25, The deployment script runs commands unguarded and uses sudo for gradle which can cause permission issues; update the script block so failures stop subsequent commands (e.g., enable "set -e" / fail-fast), check the exit status of critical commands like "git pull origin develop" and "sudo ./gradlew bootJar", avoid running "./gradlew bootJar" as root (run as the deploy user or chown build outputs afterward), and add post-deploy verification after "sudo docker-compose up --build -d" such as "docker-compose ps" or healthcheck probes and conditional rollback/logging if the service is unhealthy; implement clear error logging and early exits on failures.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/workflows/deploy.yml:
- Around line 14-15: Replace the floating ref uses: appleboy/ssh-action@master
with a pinned release tag to avoid unexpected upstream changes; update the uses
line (appleboy/ssh-action@master) to use a concrete version tag (for example
appleboy/ssh-action@vX.Y.Z) by choosing the latest stable release from the
action’s releases and commit that exact tag in the workflow.
In `@docker-compose.yml`:
- Around line 32-34: Replace hardcoded absolute host paths and unused entrypoint
in the docker-compose service by referencing the repository Dockerfile and using
a relative build context: add a build: directive pointing to the service folder
(so docker-compose uses the repository Dockerfile), change the volumes mapping
to a relative path or named volume instead of /home/sk38808738/main-server/...,
and remove the entrypoint override so the image’s Dockerfile ENTRYPOINT is used
(or if you must override, use a portable command). Update the service where the
current volumes and entrypoint keys are defined and ensure the Dockerfile’s
ENTRYPOINT handles java -jar with the appropriate profile.
- Around line 53-61: The veriq-analysis service is using the base image
python:3.9-slim without a command/entrypoint, so the container exits immediately
and restarts; fix by configuring the veriq-analysis service to either (A)
specify a runtime command/entrypoint that launches the FastAPI app (e.g., run
uvicorn pointing to your app module) in the docker-compose service block, or (B)
add a Dockerfile for the FastAPI app, build that image in compose, and set the
service to use the built image, ensuring the Dockerfile sets CMD/ENTRYPOINT to
start the FastAPI server; update the veriq-analysis service accordingly.
- Around line 11-13: The docker-compose service currently hardcodes
MYSQL_ROOT_PASSWORD and exposes the MySQL port; remove the literal
`MYSQL_ROOT_PASSWORD: veriq123` and replace it with an environment variable
reference (e.g., use an env var name like `MYSQL_ROOT_PASSWORD` loaded from an
external .env or secrets store / env_file) and keep `MYSQL_DATABASE` as needed;
also stop publishing port 3306 to all interfaces (remove or restrict the
`ports:` mapping or bind it to localhost) so the MySQL port is not publicly
exposed. Locate the environment block that mentions `MYSQL_ROOT_PASSWORD` and
`MYSQL_DATABASE` and the service `ports` config for port 3306 and update them to
use external secret management or .env variables and to restrict or remove port
exposure.
In `@Dockerfile`:
- Around line 1-6: The Dockerfile currently runs the container as root and uses
the JDK image; change the base to a JRE runtime (e.g., eclipse-temurin:21-jre)
to reduce image size, create a non-root user and group (e.g., appuser), ensure
the JAR (JAR_FILE / app.jar) is owned by that user (use COPY
--chown=appuser:appuser or chown after copy), set appropriate filesystem
permissions, and switch to that user with USER appuser before the ENTRYPOINT so
the container runs non-root while still launching java -jar /app.jar.
In `@README.md`:
- Around line 93-116: Update the README.md "GitHub Actions 자동 배포 (deploy.yml)"
section so it matches the actual .github/workflows/deploy.yml workflow: replace
the docker-compose commands with the real commands (e.g., ./gradlew bootJar) and
correct the working directory from cd /home/sk38808738 to cd
/home/sk38808738/main-server, and ensure the YAML snippet mirrors the real
deploy.yml content and steps exactly.
- Around line 5-7: Replace the hardcoded sensitive values in README.md: remove
the real IP "34.64.218.236" and password "veriq123" and replace them with clear
placeholders (e.g., "[공통 외부 IP]" or "[IP 주소]", "[비밀번호]") in the lines under the
"**공통 외부 IP**", "**관리자 계정**" and the server user entry (currently showing
"sk38808738"); also update the other occurrences noted (lines referenced
132-133) to use the same placeholders and commit the change so no real
credentials remain in the repo.
In `@src/main/java/com/veriq/veriqgateway/controller/GatewayController.java`:
- Around line 33-35: processScan currently uses the caller-provided header
guest_uuid directly as the rate-limit key, letting clients bypass limits by
swapping the header; change processScan to validate and bind the request
identifier to a server-issued value (e.g., a stored session ID, an auth token or
a signed guest token) and refuse or normalize arbitrary guest_uuid headers, and
incorporate additional server-side signals (client IP, server session id, or a
signature in a token) when building the rate-limit key; also ensure the same
verification is applied to the endpoint that initializes counters (such as
/auth/captcha/verify) so counters can only be created for server-verified
identifiers.
- Around line 22-25: The hardcoded BE3_URL constant in GatewayController
(BE3_URL) points to localhost which breaks in Docker; change it to be
externalized (read from application properties or environment) and replace its
value in docker-compose/deployed env with the service DNS (e.g.,
http://veriq-platform:8083/api/v1/scan/upload). Update GatewayController to
obtain the URL from a property (e.g., via `@Value` or configuration properties)
instead of the private final BE3_URL literal so the compose network uses the
service name at runtime.
In `@src/main/java/com/veriq/veriqgateway/service/SecurityService.java`:
- Around line 31-53: The isAllowed method currently does non-atomic
GET/compare/SET which races; replace that flow with an atomic increment using
redisTemplate.opsForValue().increment(key) and use the returned long to decide
allowance: call increment(key) to get newCount, if newCount == 1 then set
TTL(Duration.ofHours(1)) on key, if newCount > LIMIT then call decrement(key) to
roll back (or delete) and return false, otherwise return true. Ensure you
reference the existing key construction ("limit:"+guestUuid), LIMIT constant,
and use redisTemplate.opsForValue().increment/decrement and expire methods so
the decision is based on the atomic result.
In `@src/main/resources/application-be3.yml`:
- Around line 7-8: The YAML currently hardcodes DB credentials (username: root,
password: veriq123); remove these values and change the configuration to read
credentials from environment variables or a secrets store (e.g., use keys like
DB_USERNAME and DB_PASSWORD or a secrets-manager integration) and update the
app's config loader to pull from that source; also replace the root account with
a dedicated, least-privilege application database user and ensure secrets are
not committed to source control and are managed/rotated by your secret
management system.
In `@src/main/resources/application.yml`:
- Around line 6-8: The YAML currently hardcodes url, username, and password;
change these to environment variable placeholders (e.g. use ${DB_URL},
${DB_USERNAME}, ${DB_PASSWORD} style) so that the url, username and password
keys pull from env vars instead of literals, mirroring the approach used in
application-be3.yml; update any documentation or README to list the required env
var names (DB_URL, DB_USERNAME, DB_PASSWORD) and ensure Spring will resolve them
at runtime.
---
Nitpick comments:
In @.github/workflows/deploy.yml:
- Around line 20-25: The deployment script runs commands unguarded and uses sudo
for gradle which can cause permission issues; update the script block so
failures stop subsequent commands (e.g., enable "set -e" / fail-fast), check the
exit status of critical commands like "git pull origin develop" and "sudo
./gradlew bootJar", avoid running "./gradlew bootJar" as root (run as the deploy
user or chown build outputs afterward), and add post-deploy verification after
"sudo docker-compose up --build -d" such as "docker-compose ps" or healthcheck
probes and conditional rollback/logging if the service is unhealthy; implement
clear error logging and early exits on failures.
In `@README.md`:
- Around line 9-16: The markdown table starting at the header "### 서비스별 포트"
lacks blank lines before and after it; update the README.md so there is one
empty line above the "### 서비스별 포트" heading (or at least between the previous
paragraph and the heading) and one empty line after the table block (after the
last Redis row) to ensure proper rendering in all markdown renderers; locate the
table by the header text and the table rows containing "Spring BE1", "Spring
BE3", "FastAPI", "MySQL", and "Redis" and insert the blank lines accordingly.
- Line 26: Update the Markdown emphasis so the bold markers directly wrap the
text: replace the string "**.🍃 Spring Boot, ⚡ FastAPI **" with "**.🍃 Spring
Boot, ⚡ FastAPI**" (remove the extra space before the closing ** in the heading)
so the bold formatting is valid; locate and edit the heading line shown as ".🍃
Spring Boot, ⚡ FastAPI" in the README.
In `@src/main/java/com/veriq/veriqbe3/controller/QrScanController.java`:
- Around line 22-28: The catch-all in QrScanController that returns an empty 400
loses error details; update the exception handling around the call to
processQrScan.process(image, guestUuid) to log the exception (use a Logger for
QrScanController) including e.getMessage() and stacktrace, and return a more
informative ResponseEntity (e.g.,
ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ErrorResponse(...)) or
include a simple error message in the body) so callers and logs retain the error
information.
In `@src/main/java/com/veriq/veriqbe3/service/ProcessQrScan.java`:
- Around line 37-51: In ProcessQrScan.java refactor the duplicated
QrScanResponse.builder() calls by computing the status value first (e.g.,
determine a local variable like resolvedStatus = (result.type() ==
SchemeType.WEB || result.type() == SchemeType.SHORT_URL) ? "ANALYSIS_COMPLETED"
: status) and then perform a single
QrScanResponse.builder().guestUuid(guest_uuid).schemeType(result.type()).typeInfo(result.typeInfo()).status(resolvedStatus).build();
this removes the conditional duplication while preserving the special-case
status for WEB/SHORT_URL.
- Line 21: Rename the method parameter guest_uuid to follow Java camelCase
(guestUuid) in the ProcessQrScan.process method signature and update all
references inside the method and any callers; specifically change the parameter
name in public QrScanResponse process(MultipartFile image, String guest_uuid) to
guestUuid, update uses of guest_uuid within the ProcessQrScan class (and any
related methods or member variable assignments), and adjust all places that call
ProcessQrScan.process(...) to pass and reference guestUuid so compilation and
naming consistency are preserved.
In `@src/main/java/com/veriq/veriqgateway/dto/ScanResponse.java`:
- Around line 8-13: Make guestUuid private and rename the field error_code to
errorCode in the ScanResponse class to follow Java access and naming
conventions; update any usages accordingly (e.g., field references,
getters/setters). If the API must emit/consume snake_case JSON, annotate the
renamed field with `@JsonProperty`("error_code") on the field (or its
getter/setter) so JSON remains error_code while the Java field is errorCode.
Ensure the class compiles by adjusting any constructors, equals/hashCode, or
serialization logic that referenced the old names.
In `@src/main/java/com/veriq/veriqgateway/VeriQGatewayApplication.java`:
- Around line 22-25: The RestTemplate bean (restTemplate() in
VeriQGatewayApplication) lacks timeouts so calls can hang; replace the plain new
RestTemplate() with one backed by a ClientHttpRequestFactory that sets connect
and read timeouts (e.g., HttpComponentsClientHttpRequestFactory or
SimpleClientHttpRequestFactory), configure sensible values (e.g., connectTimeout
and readTimeout) or wire them from properties, and return the RestTemplate built
with that factory so external calls (Google reCAPTCHA, BE3) cannot wait
indefinitely.
In `@src/main/resources/application-be3.yml`:
- Around line 14-16: 현재 설정의 jpa.hibernate.ddl-auto: update는 프로덕션에서 예기치 않은 스키마
변경을 초래할 수 있으니, 프로덕션 프로파일에서는 해당 값을 'validate' 또는 'none'으로 변경하고 스키마 변경은 Flyway 또는
Liquibase 같은 마이그레이션 도구로 관리하도록 설정을 변경하세요; 즉 설정 키 jpa.hibernate.ddl-auto를 프로덕션
구성에서 update가 아닌 validate/none으로 바꾸고, DB 마이그레이션을 위해 Flyway/Liquibase 설정 및 마이그레이션
스크립트를 추가해 배포 시 스키마 변경을 안전하게 적용되게 하세요.
In `@src/main/resources/application.yml`:
- Around line 1-27: The config files duplicate datasource, JPA, and Redis
settings across application.yml, application-be1.yml, and application-be3.yml;
refactor by keeping common properties (spring.datasource.*, spring.jpa.*,
spring.data.redis.* and hibernate dialect/format settings) in the base
application.yml and move only profile-specific overrides (e.g., server.port,
hostnames or any environment-specific values) into application-be1.yml and
application-be3.yml using Spring profiles (spring.profiles: be1 / be3 or
application-be1.yml naming convention) so the duplicate blocks are removed and
each profile file contains only the differences.
🪄 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: f0630131-7f3a-4bd3-89e2-a124e847acac
📒 Files selected for processing (19)
.github/workflows/deploy.ymlDockerfileREADME.mdbuild.gradledocker-compose.ymlgradlewsrc/main/java/com/veriq/veriqbe3/controller/QrScanController.javasrc/main/java/com/veriq/veriqbe3/domain/SchemeType.javasrc/main/java/com/veriq/veriqbe3/service/ProcessQrScan.javasrc/main/java/com/veriq/veriqbe3/service/SchemeClassifier.javasrc/main/java/com/veriq/veriqgateway/VeriQGatewayApplication.javasrc/main/java/com/veriq/veriqgateway/controller/GatewayController.javasrc/main/java/com/veriq/veriqgateway/dto/CaptchaRequest.javasrc/main/java/com/veriq/veriqgateway/dto/GoogleCaptchaResponse.javasrc/main/java/com/veriq/veriqgateway/dto/ScanResponse.javasrc/main/java/com/veriq/veriqgateway/service/SecurityService.javasrc/main/resources/application-be1.ymlsrc/main/resources/application-be3.ymlsrc/main/resources/application.yml
| - name: SSH Remote Commands | ||
| uses: appleboy/ssh-action@master |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
What is the latest stable version of appleboy/ssh-action GitHub Action?
💡 Result:
The latest stable version of appleboy/ssh-action is v1.2.5, released on 2026-01-28.
Citations:
- 1: https://github.com/appleboy/ssh-action
- 2: https://git.durrantlab.pitt.edu/appleboy/ssh-action
- 3: https://github.com/appleboy/ssh-action/releases
보안: GitHub Action 버전을 고정하세요.
appleboy/ssh-action@master 대신 특정 버전 태그를 사용하세요. @master는 예고 없이 변경될 수 있어 보안 위험이 있습니다.
🔒 버전 고정 제안
- name: SSH Remote Commands
- uses: appleboy/ssh-action@master
+ uses: appleboy/ssh-action@v1.2.5🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/deploy.yml around lines 14 - 15, Replace the floating ref
uses: appleboy/ssh-action@master with a pinned release tag to avoid unexpected
upstream changes; update the uses line (appleboy/ssh-action@master) to use a
concrete version tag (for example appleboy/ssh-action@vX.Y.Z) by choosing the
latest stable release from the action’s releases and commit that exact tag in
the workflow.
| url: jdbc:mysql://veriq-db:3306/veriq_db?serverTimezone=Asia/Seoul&characterEncoding=UTF-8 | ||
| username: root | ||
| password: 1234 | ||
| password: veriq123 |
There was a problem hiding this comment.
하드코딩된 자격 증명 - 중복된 보안 문제
application-be3.yml과 동일하게 데이터베이스 자격 증명이 하드코딩되어 있습니다. 모든 프로필 설정 파일에서 환경 변수를 사용하도록 변경하세요.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/main/resources/application.yml` around lines 6 - 8, The YAML currently
hardcodes url, username, and password; change these to environment variable
placeholders (e.g. use ${DB_URL}, ${DB_USERNAME}, ${DB_PASSWORD} style) so that
the url, username and password keys pull from env vars instead of literals,
mirroring the approach used in application-be3.yml; update any documentation or
README to list the required env var names (DB_URL, DB_USERNAME, DB_PASSWORD) and
ensure Spring will resolve them at runtime.
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (2)
README.md (2)
5-7:⚠️ Potential issue | 🟠 Major보안: 민감한 인프라 정보/자격 정보가 문서에 그대로 노출되어 있습니다.
Line 5-7, Line 21, Line 44-47, Line 133에 실서버 IP/사용자명/DB 비밀번호 정보가 포함되어 있습니다. 공개 저장소 기준으로는 플레이스홀더로 치환하고 실제 값은 Secrets/사내 비공개 문서로 분리해 주세요.
🔒 예시 수정안
-- **공통 외부 IP**: `34.64.218.236` -* **서버 사용자**: `sk38808738` (SSH 접속 시 사용) +- **공통 외부 IP**: `<GCP_EXTERNAL_IP>` +* **서버 사용자**: `<SSH_USERNAME>` (SSH 접속 시 사용) -DB_URL = "mysql+pymysql://root:[비밀번호]@34.64.218.236:3306/veriq_db" -REDIS_HOST = "34.64.218.236" +DB_URL = "mysql+pymysql://<DB_USER>:<DB_PASSWORD>@<DB_HOST>:3306/veriq_db" +REDIS_HOST = "<REDIS_HOST>" - MYSQL_ROOT_PASSWORD: veriq123 + MYSQL_ROOT_PASSWORD: <MYSQL_ROOT_PASSWORD>Also applies to: 21-22, 44-47, 133-133
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@README.md` around lines 5 - 7, The README currently contains sensitive production details (real IP, admin/DB username and passwords shown around the "공통 외부 IP", "관리자 계정", and "서버 사용자" entries) and must be sanitized: replace all concrete values with generic placeholders (e.g., <PUBLIC_IP>, <DB_ADMIN_USER>, <SSH_USER>) in README.md wherever those entries appear (including the blocks referenced at the shown locations) and remove any plaintext DB passwords; add a short note pointing readers to the internal secrets store or docs for actual credentials and ensure actual secrets are stored in the org's secret management system instead of the repo.
94-117:⚠️ Potential issue | 🟡 Minor문서와 실제 배포 워크플로우 동기화가 필요합니다.
Line 94-117의 deploy.yml 예시가 현재 실제
.github/workflows/deploy.yml과 다르면 운영 혼선이 발생합니다. 특히 PR 설명상deploy.yml은 확정 파일이므로 README를 실제 내용 기준으로 맞춰 주세요.#!/bin/bash set -euo pipefail echo "== README deploy 섹션 (Line 94-117) ==" awk 'NR>=94 && NR<=117 {print NR ":" $0}' README.md echo echo "== 실제 워크플로 파일 위치 확인 ==" fd -i 'deploy.yml' .github/workflows echo echo "== 실제 deploy.yml 주요 명령 확인 ==" DEPLOY_FILE="$(fd -i 'deploy.yml' .github/workflows | head -n1)" awk ' /script: \|/ {flag=1} flag {print NR ":" $0} ' "$DEPLOY_FILE"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@README.md` around lines 94 - 117, The README's "GitHub Actions 자동 배포 (deploy.yml)" example is out of sync with the actual .github/workflows/deploy.yml; update the README deploy section (Lines ~94-117) so its YAML exactly reflects the real deploy.yml content (including the job name, uses: action version, secrets keys like GCP_IP/GCP_USER/GCP_SSH_KEY, and the script block commands such as cd, sudo docker-compose pull, sudo docker-compose up -d) and ensure any differences in script formatting (the "script: |" block) and branch trigger (e.g., "develop") match the real file; after editing, verify consistency by comparing the README snippet to .github/workflows/deploy.yml (deploy.yml) and adjust wording to indicate the file is authoritative if desired.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@README.md`:
- Line 26: The markdown emphasis on the heading contains extra spaces inside the
bold markers; update the heading text `**.🍃 Spring Boot, ⚡ FastAPI **` to
remove the trailing space inside the closing `**` so it becomes `**.🍃 Spring
Boot, ⚡ FastAPI**`, ensuring no spaces are present between the content and the
bold markers to satisfy MD037.
- Around line 10-16: The markdown table starting with "| 서비스 | 포트 | 용도 |" needs
blank lines immediately before and after it to satisfy Markdownlint MD058; edit
README.md and insert a single empty line above the table header and a single
empty line after the final table row so the table is separated from surrounding
content.
---
Duplicate comments:
In `@README.md`:
- Around line 5-7: The README currently contains sensitive production details
(real IP, admin/DB username and passwords shown around the "공통 외부 IP", "관리자 계정",
and "서버 사용자" entries) and must be sanitized: replace all concrete values with
generic placeholders (e.g., <PUBLIC_IP>, <DB_ADMIN_USER>, <SSH_USER>) in
README.md wherever those entries appear (including the blocks referenced at the
shown locations) and remove any plaintext DB passwords; add a short note
pointing readers to the internal secrets store or docs for actual credentials
and ensure actual secrets are stored in the org's secret management system
instead of the repo.
- Around line 94-117: The README's "GitHub Actions 자동 배포 (deploy.yml)" example
is out of sync with the actual .github/workflows/deploy.yml; update the README
deploy section (Lines ~94-117) so its YAML exactly reflects the real deploy.yml
content (including the job name, uses: action version, secrets keys like
GCP_IP/GCP_USER/GCP_SSH_KEY, and the script block commands such as cd, sudo
docker-compose pull, sudo docker-compose up -d) and ensure any differences in
script formatting (the "script: |" block) and branch trigger (e.g., "develop")
match the real file; after editing, verify consistency by comparing the README
snippet to .github/workflows/deploy.yml (deploy.yml) and adjust wording to
indicate the file is authoritative if desired.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
| | 서비스 | 포트 | 용도 | | ||
| | :--- | :--- | :--- | | ||
| | **Spring BE1** | `8081` | Gateway 서버 | | ||
| | **Spring BE3** | `8083` | Platform/Data Hub 서버 | | ||
| | **FastAPI** | `8000` | 분석 엔진 서버 | | ||
| | **MySQL** | `3306` | 데이터베이스 | | ||
| | **Redis** | `6379` | 캐시 서버 | |
There was a problem hiding this comment.
Markdownlint(MD058): 표 전후 공백 줄을 추가하세요.
Line 10의 표는 앞/뒤에 빈 줄이 필요합니다. 렌더링 일관성과 lint 통과를 위해 blank line을 넣어 주세요.
🧰 Tools
🪛 markdownlint-cli2 (0.22.0)
[warning] 10-10: Tables should be surrounded by blank lines
(MD058, blanks-around-tables)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@README.md` around lines 10 - 16, The markdown table starting with "| 서비스 | 포트
| 용도 |" needs blank lines immediately before and after it to satisfy
Markdownlint MD058; edit README.md and insert a single empty line above the
table header and a single empty line after the final table row so the table is
separated from surrounding content.
|
|
||
|
|
||
|
|
||
| ### **.🍃 Spring Boot, ⚡ FastAPI ** |
There was a problem hiding this comment.
Markdownlint(MD037): 강조 마커 내부 공백을 제거하세요.
Line 26의 ** ... ** 내부 공백 때문에 lint 경고가 발생합니다. **.🍃 Spring Boot, ⚡ FastAPI**처럼 공백 없이 정리해 주세요.
🧰 Tools
🪛 markdownlint-cli2 (0.22.0)
[warning] 26-26: Spaces inside emphasis markers
(MD037, no-space-in-emphasis)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@README.md` at line 26, The markdown emphasis on the heading contains extra
spaces inside the bold markers; update the heading text `**.🍃 Spring Boot, ⚡
FastAPI **` to remove the trailing space inside the closing `**` so it becomes
`**.🍃 Spring Boot, ⚡ FastAPI**`, ensuring no spaces are present between the
content and the bold markers to satisfy MD037.
Updated README to include environment setup and Docker configurations.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (3)
README.md (3)
9-17:⚠️ Potential issue | 🟡 Minor표 전후에 빈 줄을 추가해 markdownlint(MD058) 경고를 해소해 주세요.
현재 서비스 포트 표가 공백 줄 없이 붙어 있어 lint 경고가 발생합니다.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@README.md` around lines 9 - 17, The markdown table under the "### 서비스별 포트" heading is missing blank lines before and after it, triggering markdownlint MD058; edit README.md around the "### 서비스별 포트" section and insert an empty line both immediately before the table start (the line with '| 서비스 | 포트 | 용도 |') and immediately after the table end to ensure there is a blank line separating the heading, the table, and subsequent content.
5-7:⚠️ Potential issue | 🟠 Major보안 정보(인프라 식별자) 문서 노출을 제거해 주세요.
외부 IP와 운영 접속 정보가 README에 반복 노출되어 있습니다. 공개 저장소 기준으로는 플레이스홀더로 치환하고, 실제 값은 시크릿/내부 문서로만 관리하는 게 안전합니다.
수정 예시
-- **공통 외부 IP**: `34.64.218.236` +- **공통 외부 IP**: `<GCP_EXTERNAL_IP>` -> **공통 외부 IP**: `34.64.218.236` +> **공통 외부 IP**: `<GCP_EXTERNAL_IP>` -DB_URL = "mysql+pymysql://root:[비밀번호]@34.64.218.236:3306/veriq_db" +DB_URL = "mysql+pymysql://root:[비밀번호]@<DB_HOST>:3306/veriq_db" -REDIS_HOST = "34.64.218.236" +REDIS_HOST = "<REDIS_HOST>"Also applies to: 21-22, 107-111
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@README.md` around lines 5 - 7, Remove all hard-coded infrastructure identifiers from the README by replacing the literal values '34.64.218.236', 'root', and 'sk38808738' with non-sensitive placeholders (e.g., <EXTERNAL_IP>, <DB_ADMIN_USER>, <SSH_USER>) and add a short note pointing readers to internal/secret storage for real credentials; ensure every occurrence of those literals in the README is replaced and do not reintroduce real values elsewhere in the file.
155-167:⚠️ Potential issue | 🟠 MajorREADME 예시가 실제 배포/컴포즈 설정과 불일치합니다.
문서에는
.env기반 비밀번호 주입/로컬바인딩(127.0.0.1) 등을 안내하지만, 현재 저장소의 실제docker-compose.yml/deploy.yml스니펫과 다릅니다. 운영 절차 문서는 “실제 파일 기준”으로 맞춰야 혼선을 막을 수 있습니다. (docker-compose.yml:5-24,.github/workflows/deploy.yml:20-25참고)Also applies to: 233-267
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@README.md` around lines 155 - 167, The README's docker-compose example mismatches the repo's actual compose/deploy settings; update the README.md snippet under the "docker-compose.yml(공통) (최상위 경로)" section so it matches the real files by using the actual service names and configuration (e.g., veriq-db service, port binding behavior, and how MYSQL_ROOT_PASSWORD is provided), or else change the snippet to explicitly document the repo's current approach (env-file vs inline password and whether 127.0.0.1 binding is used) and mirror the deploy workflow settings referenced in the repo (deploy.yml); ensure you reference the veriq-db service, ports mapping, and MYSQL_ROOT_PASSWORD usage so the README and actual docker-compose/deploy configurations are consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@README.md`:
- Around line 34-35: Several README headings (for example the line starting "###
**.🍃 Spring Boot") contain unmatched emphasis markers causing render/lint
issues; fix each heading (including the other occurrences noted) by either
removing the stray asterisks or properly closing the bold markers so they become
valid Markdown (e.g., change "### **.🍃 Spring Boot" to "### .🍃 Spring Boot" or
"### **.🍃 Spring Boot**"), and scan other headings with similar patterns to
ensure no unmatched '*' remain.
---
Duplicate comments:
In `@README.md`:
- Around line 9-17: The markdown table under the "### 서비스별 포트" heading is
missing blank lines before and after it, triggering markdownlint MD058; edit
README.md around the "### 서비스별 포트" section and insert an empty line both
immediately before the table start (the line with '| 서비스 | 포트 | 용도 |') and
immediately after the table end to ensure there is a blank line separating the
heading, the table, and subsequent content.
- Around line 5-7: Remove all hard-coded infrastructure identifiers from the
README by replacing the literal values '34.64.218.236', 'root', and 'sk38808738'
with non-sensitive placeholders (e.g., <EXTERNAL_IP>, <DB_ADMIN_USER>,
<SSH_USER>) and add a short note pointing readers to internal/secret storage for
real credentials; ensure every occurrence of those literals in the README is
replaced and do not reintroduce real values elsewhere in the file.
- Around line 155-167: The README's docker-compose example mismatches the repo's
actual compose/deploy settings; update the README.md snippet under the
"docker-compose.yml(공통) (최상위 경로)" section so it matches the real files by using
the actual service names and configuration (e.g., veriq-db service, port binding
behavior, and how MYSQL_ROOT_PASSWORD is provided), or else change the snippet
to explicitly document the repo's current approach (env-file vs inline password
and whether 127.0.0.1 binding is used) and mirror the deploy workflow settings
referenced in the repo (deploy.yml); ensure you reference the veriq-db service,
ports mapping, and MYSQL_ROOT_PASSWORD usage so the README and actual
docker-compose/deploy configurations are consistent.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
| ### **.🍃 Spring Boot | ||
| `src/main/resources/application-be1.yml` 아래와 같이 수정합니다. |
There was a problem hiding this comment.
헤더 강조 마크다운 문법이 깨져 렌더링이 불안정합니다.
### **... 형태로 닫히지 않은 강조 마커가 여러 군데 있어 제목 렌더링/린트 문제가 발생할 수 있습니다.
수정 예시
-### **.🍃 Spring Boot
+### 🍃 Spring Boot
-### **⚡FastAPI
+### ⚡ FastAPI
-### **📦 인프라 및 배포 설정 파일 안내(Dockerfile)
+### 📦 인프라 및 배포 설정 파일 안내 (Dockerfile)Also applies to: 103-104, 121-121, 125-125, 145-145
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@README.md` around lines 34 - 35, Several README headings (for example the
line starting "### **.🍃 Spring Boot") contain unmatched emphasis markers
causing render/lint issues; fix each heading (including the other occurrences
noted) by either removing the stray asterisks or properly closing the bold
markers so they become valid Markdown (e.g., change "### **.🍃 Spring Boot" to
"### .🍃 Spring Boot" or "### **.🍃 Spring Boot**"), and scan other headings
with similar patterns to ensure no unmatched '*' remain.
… into develop # Please enter a commit message to explain why this merge is necessary, # especially if it merges an updated upstream into a topic branch. # # Lines starting with '#' will be ignored, and an empty message aborts # the commit.
… into develop # Please enter a commit message to explain why this merge is necessary, # especially if it merges an updated upstream into a topic branch. # # Lines starting with '#' will be ignored, and an empty message aborts # the commit.
2. /가 아닌 다른 문자도 탐지 가능하도록 변경([/?#.*)
1. 단축 url 뒤에 포트 번호 쓰는 경우도 탐지하도록 보완 2. /가 아닌 다른 문자도 탐지 가능하도록 변경([/?#.*)
📌 작업 개요
🚀 작업 내용
docker.compose.yml
Dockerfile
deploy.yml은 확정지은거라 건드리지 말아주세요! 서버 세팅 완료된거라 건들면 다시 등록해야합니다
develop에 be1과 be3합쳐서 푸쉬했습니다. 따로 application,yml만들었습니다
📸 스크린샷 (선택)
✅ 체크리스트
Summary by CodeRabbit
새로운 기능
문서
기타