Compare commits
No commits in common. "main" and "docs/project-analysis" have entirely different histories.
main
...
docs/proje
|
|
@ -1,146 +0,0 @@
|
|||
---
|
||||
schema_version: 1
|
||||
sid: 20260617-094450
|
||||
started_at: 2026-06-17T09:44:50+09:00
|
||||
ended_at: 2026-06-17T10:05:00+09:00
|
||||
user_request: |
|
||||
PR #1 (docs/project-analysis → main, "docs: ATP 문서 체계 도입 및 프로젝트 종합 분석")
|
||||
당사자 승인 완료. 그러나 main 에 실수로 "일부 병합한" 커밋(f6f691c)이 들어가 PR 이
|
||||
mergeable:false 상태. main 으로 병합 + 충돌 해결 요청.
|
||||
PR URL: https://gitea.pandoli365.com/pandoli365/bibimbap/pulls/1
|
||||
---
|
||||
|
||||
# Summary
|
||||
|
||||
진단 (read-only):
|
||||
|
||||
- PR #1 head = `d297f31` (docs/project-analysis), base = `main`. gitea state=open, **mergeable:false**, merged:false.
|
||||
- merge-base = `40bde12` (단일).
|
||||
- 사고 커밋 `f6f691c "fix: harden auth csrf handling"` 가 두 가지를 한 커밋에 섞음:
|
||||
1. **정당한 csrf 보안 수정** (B1): UserController.java / login.jsp / signup.jsp / 테스트 2건
|
||||
2. **PR 문서의 부분·다른 버전 스냅샷**: CLAUDE.md, docs/analysis/..., docs/index.md, .serena/project.yml,
|
||||
.atp/work-session(파일형), 그리고 README.md 컨벤션 docs (PR 은 index.md 컨벤션)
|
||||
- 동일 경로가 양측에서 다르게 추가/수정 → gitea 충돌. 단 `.atp/work-session` 은 main=blob / PR=tree
|
||||
의 **파일/디렉토리 타입 충돌**이 gitea mergeable:false 의 핵심 원인.
|
||||
|
||||
위험 발견:
|
||||
|
||||
- **naive `git merge` 금지**: 로컬 ort 전략이 충돌 0으로 자동 병합하지만, 결과 트리가 **csrf 코드 5건을
|
||||
base 로 되돌리고 csrf 테스트 파일을 삭제**함 (블롭 해시로 검증). gitea Merge 버튼도 신뢰 불가.
|
||||
→ 결과 트리를 결정론적으로 구성해야 함.
|
||||
|
||||
# Advisor Invocation Decision Log
|
||||
# 각 advisor 호출/스킵 판단 즉시 1줄 append
|
||||
- advisor: requirements-advisor
|
||||
decision: skip
|
||||
rationale: '요청 명확(병합+충돌해결). 모호점은 git 상태 자체이며 orchestrator 직접 조사가 효율적.'
|
||||
checked_at: 2026-06-17T09:45:00+09:00
|
||||
- advisor: research-advisor
|
||||
decision: skip
|
||||
rationale: 'git/gitea 상태 조사는 orchestrator 직접 Bash 가 적합. 외부 자료 불요.'
|
||||
checked_at: 2026-06-17T09:45:00+09:00
|
||||
- advisor: design/implementation-advisor
|
||||
decision: skip (pending user)
|
||||
rationale: 'git 병합 충돌해결은 §6 파괴적 게이트 + 단계별 명령. orchestrator 직접 수행이 적합. 사용자 결정 후 진행.'
|
||||
checked_at: 2026-06-17T09:45:00+09:00
|
||||
|
||||
# Invocations
|
||||
- inv-001: graph-refresh-checker (post-merge staleness 판정) — model_choice: phase=graphify-judgment, tier=large(inherit), rationale='no-defer 정책상 머지 직후 그래프 신선도 판정'
|
||||
|
||||
# Decisions
|
||||
- D1: csrf 보안 수정(f6f691c 코드분)은 정당 → main 버전 보존 (전제, 사용자 미반대)
|
||||
- D2: CLAUDE.md → main 프로젝트 지침 + PR ATP 블록 결합 (사용자 선택)
|
||||
- D3: 사고 커밋 README.md 5건 제거, security-remediation-checklist.md(고유) 유지 (사용자 선택)
|
||||
- D4: 반영 방식 → main 에 병합커밋(parents f6f691c+d297f31) + push (사용자 선택)
|
||||
- D5: 충돌 문서(project-analysis.md/docs.index.md/.serena.project.yml) → PR 정식본. db-update-query-generator.md·user-signup-schema.md 는 ort 자동병합 union 유지(링크 전부 유효, README 참조 없음).
|
||||
|
||||
# self_correction
|
||||
- 세션 초반 "naive git merge 가 csrf 코드를 base 로 되돌리고 테스트를 삭제한다"는 발견을 보고했으나, 이는 **로컬 main 이 stale(40bde12)** 상태에서 만든 temp 브랜치로 테스트해 발생한 오판. 올바른 base(origin/main=f6f691c)로 재실행하니 정상 충돌 표면화 + csrf 보존. 교훈: 머지 동작 추론 전 `git fetch` 후 로컬 브랜치==원격 동기화 여부 확인. (memory_candidate)
|
||||
|
||||
# user_signals
|
||||
positive:
|
||||
- '권장안 3건(CLAUDE 결합/README 제거/병합커밋+push)을 한 라운드에 모두 수락'
|
||||
negative: []
|
||||
|
||||
# verified_by_me
|
||||
- 'L1: 병합 결과 src/ 트리가 origin/main(f6f691c)과 바이트 동일 — git diff --cached f6f691c -- src/ 빈 결과. 코드 델타 0, csrf 보존. 신규 코드 없음 → 빌드 불요(docs-only 델타).'
|
||||
- 'L2: skip — 외부 의존성/계약 변경 없음(docs·설정 머지)'
|
||||
- '충돌 0 잔여, README 5건 제거 확인, .atp/work-session blob→dir 해소(4 entries)'
|
||||
- 'push: f6f691c..8c41b22 main->main 성공. d297f31 이 origin/main ancestor 재확인(=PR 내용 머지 완료)'
|
||||
|
||||
# graph_refresh
|
||||
- 판정: fresh (src·docs 모두 fresh; docs 는 partial-stale 경계 근접)
|
||||
- 미반영 항목: docs/security/security-remediation-checklist.md 1개 문서 노드(+analysis/schema 링크 엣지). src 는 구조 시그널 0(UserController 변경은 기존 CsrfTokens.isValid 호출 2줄, 신규 노드/엣지 없음).
|
||||
- 처리: 재생성 유보. 사유 = checker 가 docs 재생성을 "선택적·저효익(노드 1개)"으로 평가. /graphify 는 docs 그래프 전체 재생성 + 추가 push 를 유발하므로 PR 머지라는 작업 범위에 비해 과함. 사용자가 그래프 완전성을 원하면 `/graphify docs/` 로 트리거 가능 (open item).
|
||||
|
||||
# needs_user_verification
|
||||
- 'gitea PR #1 레코드: 직접 push 로는 자동 merged 전환 안 됨(state:open 잔존). gitea UI 에서 수동 close 하거나 API 토큰 제공 시 닫기 대행 가능. 내용상 머지는 완료.'
|
||||
- '세션 노트 .atp/work-session/20260617-094450/ 는 untracked. 영속화 원하면 별도 커밋 가능.'
|
||||
|
||||
Retrospective:
|
||||
signals:
|
||||
positive:
|
||||
- quote_or_paraphrase: '권장안 3건(CLAUDE 결합 / README 5건 제거 / 병합커밋+push)을 한 라운드에 모두 수락'
|
||||
about: 'orchestrator 가 충돌 해소 방식을 옵션화해 한 번에 제시 — 재질의·재지시 없이 단발 수락. 비자명한 결정(병합커밋 parents 구성, 충돌 문서 정식본 채택)을 묶어 제시한 판단이 검증됨.'
|
||||
negative: []
|
||||
what_went_well:
|
||||
- 'self_correction 메커니즘이 작동: 세션 초반의 "naive git merge 가 csrf 코드를 base 로 되돌리고 테스트를 삭제한다"는 오판을 push 전에 스스로 발견·정정. 잘못된 결론이 사용자에게 확정 안내되거나 파괴적 push 로 이어지기 전에 차단됨.'
|
||||
- '파괴적 git 작업(병합 충돌 해결)을 advisor 우회 없이 orchestrator 직접 수행 — 프로토콜 §1 직접 수행 영역 판정이 정확. advisor 호출 스킵 사유를 Decision Log 에 즉시 기록.'
|
||||
- '결과 트리를 블롭 해시 수준으로 결정론적 검증(L1: src/ 트리가 origin/main 과 바이트 동일, csrf 보존 확인). gitea Merge 버튼·로컬 ort 자동병합을 신뢰하지 않고 직접 검증.'
|
||||
- 'graph staleness 를 no-defer 정책에 따라 머지 직후 판정하고, 재생성 효익(노드 1개) 대비 비용(전체 docs 그래프 재생성 + 추가 push)을 평가해 유보 + open item 으로 위임.'
|
||||
what_to_improve:
|
||||
- 'git 머지 동작을 추론·시뮬레이션하기 전 baseline ref 의 신선도를 확인하지 않았다. stale 로컬 main(40bde12) 기반 temp 브랜치로 머지를 테스트해 "csrf 파괴" 라는 오판을 생성·보고했다. fetch 후 로컬==원격 동기화 확인이 추론보다 선행해야 한다.'
|
||||
- '오판을 정정한 것은 self_correction 으로 회수됐으나, 그 오판이 한 번은 진단 보고(Summary 위험 발견 섹션)에 실렸다. 추론 기반 위험 경고를 보고에 싣기 전 baseline 전제(어느 ref 로 시뮬레이션했는지)를 명시하는 게이트가 있었다면 오판 단계에서 자가 포착 가능했을 것.'
|
||||
memory_candidates:
|
||||
- name: merge-reasoning-requires-fresh-baseline-ref
|
||||
type: feedback
|
||||
description: 'git 머지/충돌 동작을 추론·시뮬레이션하기 전 fetch 후 로컬 브랜치==원격 ref 동기화 여부를 먼저 확인. stale baseline 으로 시뮬레이션하면 잘못된 위험 결론이 나온다.'
|
||||
body_draft: |
|
||||
git 머지/충돌 결과를 추론하거나 temp 브랜치로 시뮬레이션하기 전에 `git fetch` 후
|
||||
시뮬레이션 baseline 으로 쓸 로컬 브랜치가 원격 ref(보통 origin/main)와 동기화돼 있는지
|
||||
먼저 확인한다. stale baseline 으로 머지를 테스트하면 실제와 다른 결과 트리가 나와
|
||||
"코드가 파괴된다" 류의 잘못된 위험 결론을 보고하게 된다.
|
||||
|
||||
**Why:** 세션 20260617-094450 에서 "naive git merge 가 csrf 코드를 base 로 되돌리고
|
||||
테스트를 삭제한다"는 위험을 진단 보고에 실었으나, 이는 로컬 main 이 stale(40bde12)
|
||||
상태에서 만든 temp 브랜치로 머지를 테스트해 발생한 오판이었다. 올바른 base
|
||||
(origin/main=f6f691c)로 재실행하니 정상적인 충돌이 표면화되고 csrf 가 보존됐다.
|
||||
오판은 push 전 self_correction 으로 회수됐지만, 그 전에 한 번 위험 경고로 보고됐다.
|
||||
관련: bump 커밋 *쓰기 대상* 선정 시 stale 브랜치 회피는
|
||||
[[feedback_bump_target_branch_must_be_consumer_tracked_ref]] — 본 항목은 *읽기/추론*
|
||||
baseline 의 신선도라는 별개 축.
|
||||
|
||||
**How to apply:**
|
||||
- 머지 동작 추론/시뮬레이션 전: `git fetch` → `git rev-parse <local> origin/<remote>` 로
|
||||
동기화 확인, 또는 시뮬레이션 base 를 `origin/<remote>` 로 직접 지정.
|
||||
- 추론 기반 위험 경고를 보고에 실을 때는 "어느 ref 를 baseline 으로 시뮬레이션했는가"를
|
||||
함께 명시 — 전제가 드러나면 stale 오판을 자가 포착하기 쉬워진다.
|
||||
- 충돌 머지 결과는 블롭 해시 수준으로 결정론 검증(git diff --cached <ref> -- <path>).
|
||||
rationale_for_saving: '재현 가능한 패턴(stale ref 기반 시뮬레이션 → 오판). 코드/커밋 로그로 유도 불가, 관찰로만 드러남. 기존 bump-target memory 와 인접하나 read/추론 baseline 신선도라는 별개 축으로 비중복.'
|
||||
signal_source: observation
|
||||
docs_sync_target: null
|
||||
conflicts_with: null
|
||||
- name: report-risk-claim-states-its-baseline-premise
|
||||
type: feedback
|
||||
description: '추론·시뮬레이션 기반 위험 경고를 진단 보고에 실을 때 baseline 전제(어느 ref·상태로 시뮬레이션했는지)를 함께 명시. 전제 누락 시 오판이 무검증으로 보고된다.'
|
||||
body_draft: |
|
||||
진단 보고(Summary "위험 발견" 등)에 추론·시뮬레이션 기반 경고를 실을 때는
|
||||
그 결론의 baseline 전제를 한 줄로 함께 기록한다 — 예: "origin/main(f6f691c) 기준
|
||||
ort 시뮬레이션 결과". 전제가 명시되면 검증자(및 작성자 자신)가 전제의 타당성부터
|
||||
점검할 수 있어 stale·잘못된 전제에서 나온 오판을 보고 단계에서 포착할 수 있다.
|
||||
|
||||
**Why:** 세션 20260617-094450 에서 stale 로컬 main 기반 머지 오판이 "위험 발견"
|
||||
섹션에 baseline 전제 없이 단정적으로 실렸다. push 전 self_correction 으로 회수됐으나,
|
||||
전제가 보고에 명시돼 있었다면 오판 단계에서 자가 포착 가능했을 것이다.
|
||||
|
||||
**How to apply:**
|
||||
- 진단 보고의 위험/경고 항목은 (관찰 사실 | 추론) 을 구분하고, 추론이면 전제 ref·상태를 병기.
|
||||
- "naive X 하면 Y 파괴된다" 류 강한 단정은 결정론 재현 검증(블롭 해시/diff) 후에만 단정형으로.
|
||||
rationale_for_saving: '위 머지 baseline 교훈의 메타 층위(보고 규약). orchestrator 의 보고 작성 습관에 재현 적용 가능. self_correction 이 회수한 경로를 한 단계 앞당기는 게이트로 비중복.'
|
||||
signal_source: observation
|
||||
docs_sync_target: null
|
||||
conflicts_with: null
|
||||
protocol_feedback:
|
||||
- '프로토콜 §1(orchestrator 직접 수행 영역) 또는 §6(파괴적 게이트)에 "git 머지/리베이스 동작을 추론·시뮬레이션하기 전 baseline ref 신선도 확인(fetch + 로컬==원격)" 선행 체크를 추가 권고. 이번 세션의 stale-baseline 오판은 단발 실수가 아니라 시뮬레이션 baseline 전제를 명시하지 않는 구조적 허점에 가깝다(structural 경계).'
|
||||
- '진단 보고의 "위험 발견" 류 항목에 (관찰 | 추론) 구분 + 추론 시 baseline 전제 병기를 권장 포맷으로 추가하면, self_correction 이 사후에 회수하던 오판을 보고 작성 시점에 자가 포착하도록 앞당길 수 있다.'
|
||||
applied_changes: []
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
✔︎ JSON API packages.arm64_sequoia.jws.json
|
||||
Warning: The following taps are not trusted:
|
||||
manaflow-ai/cmux
|
||||
|
||||
Homebrew is currently ignoring formulae, casks and commands from these taps because tap trust is required.
|
||||
Trust specific formulae, casks or commands with:
|
||||
brew trust --formula <user>/<tap>/<formula>
|
||||
brew trust --cask <user>/<tap>/<cask>
|
||||
brew trust --command <user>/<tap>/<command>
|
||||
|
||||
You can trust all formulae, casks and commands from these taps with:
|
||||
brew trust manaflow-ai/cmux
|
||||
Prefer trusting only the specific formulae, casks or commands you need.
|
||||
Untap them with:
|
||||
brew untap manaflow-ai/cmux
|
||||
To disable trust checks:
|
||||
export HOMEBREW_NO_REQUIRE_TAP_TRUST=1
|
||||
This is not recommended and will be removed in a later release.
|
||||
==> Would install 1 formula:
|
||||
openjdk@21
|
||||
==> Downloading https://ghcr.io/v2/homebrew/core/openjdk/21/manifests/21.0.11
|
||||
==> Would install 5 dependencies for openjdk@21:
|
||||
giflib
|
||||
fontconfig
|
||||
graphite2
|
||||
harfbuzz
|
||||
little-cms2
|
||||
==> Fetching downloads for: openjdk@21
|
||||
✔︎ Bottle Manifest giflib (6.1.3)
|
||||
✔︎ Bottle Manifest fontconfig (2.18.1)
|
||||
✔︎ Bottle Manifest graphite2 (1.3.15)
|
||||
✔︎ Bottle Manifest harfbuzz (14.2.1)
|
||||
✔︎ Bottle Manifest little-cms2 (2.19)
|
||||
✔︎ Bottle giflib (6.1.3)
|
||||
✔︎ Bottle fontconfig (2.18.1)
|
||||
✔︎ Bottle graphite2 (1.3.15)
|
||||
✔︎ Bottle harfbuzz (14.2.1)
|
||||
✔︎ Bottle little-cms2 (2.19)
|
||||
✔︎ Bottle openjdk@21 (21.0.11)
|
||||
==> Installing dependencies for openjdk@21: giflib and little-cms2
|
||||
==> Installing openjdk@21 dependency: giflib
|
||||
==> Pouring giflib--6.1.3.arm64_sequoia.bottle.tar.gz
|
||||
🍺 /opt/homebrew/Cellar/giflib/6.1.3: 19 files, 512.5KB
|
||||
==> Installing openjdk@21 dependency: little-cms2
|
||||
==> Pouring little-cms2--2.19.arm64_sequoia.bottle.tar.gz
|
||||
🍺 /opt/homebrew/Cellar/little-cms2/2.19: 23 files, 1.5MB
|
||||
==> Installing openjdk@21
|
||||
==> Pouring openjdk@21--21.0.11.arm64_sequoia.bottle.tar.gz
|
||||
==> Caveats
|
||||
For the system Java wrappers to find this JDK, symlink it with
|
||||
sudo ln -sfn /opt/homebrew/opt/openjdk@21/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-21.jdk
|
||||
|
||||
openjdk@21 is keg-only, which means it was not symlinked into /opt/homebrew,
|
||||
because this is an alternate version of another formula.
|
||||
|
||||
If you need to have openjdk@21 first in your PATH, run:
|
||||
echo 'export PATH="/opt/homebrew/opt/openjdk@21/bin:$PATH"' >> ~/.zshrc
|
||||
|
||||
For compilers to find openjdk@21 you may need to set:
|
||||
export CPPFLAGS="-I/opt/homebrew/opt/openjdk@21/include"
|
||||
==> Summary
|
||||
🍺 /opt/homebrew/Cellar/openjdk@21/21.0.11: 600 files, 347.6MB
|
||||
==> Running `brew cleanup openjdk@21`...
|
||||
Disable this behaviour by setting `HOMEBREW_NO_INSTALL_CLEANUP=1`.
|
||||
Hide these hints with `HOMEBREW_NO_ENV_HINTS=1` (see `man brew`).
|
||||
==> Caveats
|
||||
==> openjdk@21
|
||||
For the system Java wrappers to find this JDK, symlink it with
|
||||
sudo ln -sfn /opt/homebrew/opt/openjdk@21/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-21.jdk
|
||||
|
||||
openjdk@21 is keg-only, which means it was not symlinked into /opt/homebrew,
|
||||
because this is an alternate version of another formula.
|
||||
|
||||
If you need to have openjdk@21 first in your PATH, run:
|
||||
echo 'export PATH="/opt/homebrew/opt/openjdk@21/bin:$PATH"' >> ~/.zshrc
|
||||
|
||||
For compilers to find openjdk@21 you may need to set:
|
||||
export CPPFLAGS="-I/opt/homebrew/opt/openjdk@21/include"
|
||||
BREW_EXIT=0
|
||||
|
|
@ -1,279 +0,0 @@
|
|||
Image bibimbap-app Building
|
||||
#1 [internal] load local bake definitions
|
||||
#1 reading from stdin 522B done
|
||||
#1 DONE 0.0s
|
||||
|
||||
#2 [internal] load build definition from Dockerfile
|
||||
#2 transferring dockerfile: 1.47kB done
|
||||
#2 DONE 0.1s
|
||||
|
||||
#3 resolve image config for docker-image://docker.io/docker/dockerfile:1
|
||||
#3 ...
|
||||
|
||||
#4 [auth] docker/dockerfile:pull token for registry-1.docker.io
|
||||
#4 DONE 0.0s
|
||||
|
||||
#3 resolve image config for docker-image://docker.io/docker/dockerfile:1
|
||||
#3 DONE 3.6s
|
||||
|
||||
#5 docker-image://docker.io/docker/dockerfile:1@sha256:87999aa3d42bdc6bea60565083ee17e86d1f3339802f543c0d03998580f9cb89
|
||||
#5 resolve docker.io/docker/dockerfile:1@sha256:87999aa3d42bdc6bea60565083ee17e86d1f3339802f543c0d03998580f9cb89 0.0s done
|
||||
#5 sha256:4eb94397eda75ee431bc375a19a2168ef43d859cbfaaf63bb2d8a3dd783d2b22 0B / 13.22MB 0.2s
|
||||
#5 sha256:4eb94397eda75ee431bc375a19a2168ef43d859cbfaaf63bb2d8a3dd783d2b22 2.10MB / 13.22MB 0.9s
|
||||
#5 sha256:4eb94397eda75ee431bc375a19a2168ef43d859cbfaaf63bb2d8a3dd783d2b22 5.24MB / 13.22MB 1.1s
|
||||
#5 sha256:4eb94397eda75ee431bc375a19a2168ef43d859cbfaaf63bb2d8a3dd783d2b22 9.44MB / 13.22MB 1.2s
|
||||
#5 sha256:4eb94397eda75ee431bc375a19a2168ef43d859cbfaaf63bb2d8a3dd783d2b22 13.22MB / 13.22MB 1.3s done
|
||||
#5 extracting sha256:4eb94397eda75ee431bc375a19a2168ef43d859cbfaaf63bb2d8a3dd783d2b22 0.1s done
|
||||
#5 DONE 1.5s
|
||||
|
||||
#6 [internal] load metadata for docker.io/library/eclipse-temurin:21-jre
|
||||
#6 ...
|
||||
|
||||
#7 [auth] library/maven:pull token for registry-1.docker.io
|
||||
#7 DONE 0.0s
|
||||
|
||||
#8 [auth] library/eclipse-temurin:pull token for registry-1.docker.io
|
||||
#8 DONE 0.0s
|
||||
|
||||
#9 [internal] load metadata for docker.io/library/maven:3.9-eclipse-temurin-21
|
||||
#9 DONE 2.6s
|
||||
|
||||
#6 [internal] load metadata for docker.io/library/eclipse-temurin:21-jre
|
||||
#6 DONE 3.2s
|
||||
|
||||
#10 [internal] load .dockerignore
|
||||
#10 transferring context: 320B done
|
||||
#10 DONE 0.0s
|
||||
|
||||
#11 [internal] load build context
|
||||
#11 transferring context: 833.69kB 0.0s done
|
||||
#11 DONE 0.0s
|
||||
|
||||
#12 [stage-1 1/3] FROM docker.io/library/eclipse-temurin:21-jre@sha256:194b590649efee5555de080c634905a30c2885190210e37ada26370ed2a9c781
|
||||
#12 resolve docker.io/library/eclipse-temurin:21-jre@sha256:194b590649efee5555de080c634905a30c2885190210e37ada26370ed2a9c781 done
|
||||
#12 sha256:5ac908e534636f1e892f6072aa8329d64001811ca530a2d49f3a42c665f81b9a 0B / 2.28kB 0.2s
|
||||
#12 sha256:00576a5b136e45737bb6f884dcfd2e09b19cbc41ebac1d7d032cc85b0d8f5f22 0B / 159B 0.2s
|
||||
#12 sha256:478d1828a921be5bb95db6f451338fc117ec86cb1d42195494b7897357dc226e 0B / 52.31MB 0.2s
|
||||
#12 sha256:b0eb1335aa37af39b90084a961ce2528e0cf8192d25deab826a5ad63728f4edd 0B / 19.98MB 0.2s
|
||||
#12 sha256:5ac908e534636f1e892f6072aa8329d64001811ca530a2d49f3a42c665f81b9a 2.28kB / 2.28kB 0.5s done
|
||||
#12 sha256:00576a5b136e45737bb6f884dcfd2e09b19cbc41ebac1d7d032cc85b0d8f5f22 159B / 159B 0.7s done
|
||||
#12 sha256:4a7720058461eb4ae40ed203b9874ab3248bd34ffb9948193e99245229fdbd6f 0B / 390B 0.2s
|
||||
#12 sha256:2113f8d7eb32748b14581824c1b94cea9ed9a08456312a2e94eddd522d01b927 0B / 40.73MB 0.2s
|
||||
#12 sha256:4a7720058461eb4ae40ed203b9874ab3248bd34ffb9948193e99245229fdbd6f 390B / 390B 0.7s done
|
||||
#12 sha256:478d1828a921be5bb95db6f451338fc117ec86cb1d42195494b7897357dc226e 4.19MB / 52.31MB 1.4s
|
||||
#12 sha256:478d1828a921be5bb95db6f451338fc117ec86cb1d42195494b7897357dc226e 8.39MB / 52.31MB 1.5s
|
||||
#12 sha256:478d1828a921be5bb95db6f451338fc117ec86cb1d42195494b7897357dc226e 11.53MB / 52.31MB 1.7s
|
||||
#12 sha256:b0eb1335aa37af39b90084a961ce2528e0cf8192d25deab826a5ad63728f4edd 1.05MB / 19.98MB 1.8s
|
||||
#12 sha256:478d1828a921be5bb95db6f451338fc117ec86cb1d42195494b7897357dc226e 16.78MB / 52.31MB 2.0s
|
||||
#12 sha256:2113f8d7eb32748b14581824c1b94cea9ed9a08456312a2e94eddd522d01b927 2.10MB / 40.73MB 1.4s
|
||||
#12 sha256:478d1828a921be5bb95db6f451338fc117ec86cb1d42195494b7897357dc226e 19.92MB / 52.31MB 2.1s
|
||||
#12 sha256:b0eb1335aa37af39b90084a961ce2528e0cf8192d25deab826a5ad63728f4edd 2.10MB / 19.98MB 2.1s
|
||||
#12 sha256:478d1828a921be5bb95db6f451338fc117ec86cb1d42195494b7897357dc226e 24.12MB / 52.31MB 2.3s
|
||||
#12 sha256:478d1828a921be5bb95db6f451338fc117ec86cb1d42195494b7897357dc226e 28.98MB / 52.31MB 2.6s
|
||||
#12 sha256:b0eb1335aa37af39b90084a961ce2528e0cf8192d25deab826a5ad63728f4edd 3.15MB / 19.98MB 2.6s
|
||||
#12 sha256:2113f8d7eb32748b14581824c1b94cea9ed9a08456312a2e94eddd522d01b927 4.19MB / 40.73MB 2.1s
|
||||
#12 sha256:478d1828a921be5bb95db6f451338fc117ec86cb1d42195494b7897357dc226e 34.60MB / 52.31MB 2.9s
|
||||
#12 sha256:b0eb1335aa37af39b90084a961ce2528e0cf8192d25deab826a5ad63728f4edd 4.19MB / 19.98MB 2.9s
|
||||
#12 sha256:478d1828a921be5bb95db6f451338fc117ec86cb1d42195494b7897357dc226e 37.75MB / 52.31MB 3.0s
|
||||
#12 sha256:b0eb1335aa37af39b90084a961ce2528e0cf8192d25deab826a5ad63728f4edd 5.24MB / 19.98MB 3.2s
|
||||
#12 sha256:478d1828a921be5bb95db6f451338fc117ec86cb1d42195494b7897357dc226e 41.94MB / 52.31MB 3.3s
|
||||
#12 sha256:2113f8d7eb32748b14581824c1b94cea9ed9a08456312a2e94eddd522d01b927 6.29MB / 40.73MB 2.9s
|
||||
#12 sha256:478d1828a921be5bb95db6f451338fc117ec86cb1d42195494b7897357dc226e 46.14MB / 52.31MB 3.6s
|
||||
#12 sha256:b0eb1335aa37af39b90084a961ce2528e0cf8192d25deab826a5ad63728f4edd 6.29MB / 19.98MB 3.6s
|
||||
#12 sha256:478d1828a921be5bb95db6f451338fc117ec86cb1d42195494b7897357dc226e 49.28MB / 52.31MB 3.8s
|
||||
#12 sha256:478d1828a921be5bb95db6f451338fc117ec86cb1d42195494b7897357dc226e 52.31MB / 52.31MB 3.9s done
|
||||
#12 sha256:b0eb1335aa37af39b90084a961ce2528e0cf8192d25deab826a5ad63728f4edd 7.34MB / 19.98MB 3.9s
|
||||
#12 sha256:b0eb1335aa37af39b90084a961ce2528e0cf8192d25deab826a5ad63728f4edd 8.39MB / 19.98MB 4.1s
|
||||
#12 sha256:2113f8d7eb32748b14581824c1b94cea9ed9a08456312a2e94eddd522d01b927 8.39MB / 40.73MB 3.5s
|
||||
#12 sha256:b0eb1335aa37af39b90084a961ce2528e0cf8192d25deab826a5ad63728f4edd 9.44MB / 19.98MB 4.2s
|
||||
#12 sha256:b0eb1335aa37af39b90084a961ce2528e0cf8192d25deab826a5ad63728f4edd 10.49MB / 19.98MB 4.4s
|
||||
#12 sha256:2113f8d7eb32748b14581824c1b94cea9ed9a08456312a2e94eddd522d01b927 11.53MB / 40.73MB 3.8s
|
||||
#12 sha256:b0eb1335aa37af39b90084a961ce2528e0cf8192d25deab826a5ad63728f4edd 11.53MB / 19.98MB 4.5s
|
||||
#12 sha256:b0eb1335aa37af39b90084a961ce2528e0cf8192d25deab826a5ad63728f4edd 13.63MB / 19.98MB 4.7s
|
||||
#12 sha256:2113f8d7eb32748b14581824c1b94cea9ed9a08456312a2e94eddd522d01b927 13.63MB / 40.73MB 4.1s
|
||||
#12 sha256:b0eb1335aa37af39b90084a961ce2528e0cf8192d25deab826a5ad63728f4edd 14.68MB / 19.98MB 4.8s
|
||||
#12 sha256:b0eb1335aa37af39b90084a961ce2528e0cf8192d25deab826a5ad63728f4edd 15.73MB / 19.98MB 5.0s
|
||||
#12 sha256:2113f8d7eb32748b14581824c1b94cea9ed9a08456312a2e94eddd522d01b927 15.73MB / 40.73MB 4.4s
|
||||
#12 sha256:b0eb1335aa37af39b90084a961ce2528e0cf8192d25deab826a5ad63728f4edd 16.78MB / 19.98MB 5.1s
|
||||
#12 sha256:b0eb1335aa37af39b90084a961ce2528e0cf8192d25deab826a5ad63728f4edd 17.83MB / 19.98MB 5.3s
|
||||
#12 sha256:2113f8d7eb32748b14581824c1b94cea9ed9a08456312a2e94eddd522d01b927 17.83MB / 40.73MB 4.8s
|
||||
#12 sha256:b0eb1335aa37af39b90084a961ce2528e0cf8192d25deab826a5ad63728f4edd 19.98MB / 19.98MB 5.6s done
|
||||
#12 sha256:2113f8d7eb32748b14581824c1b94cea9ed9a08456312a2e94eddd522d01b927 19.92MB / 40.73MB 5.4s
|
||||
#12 sha256:2113f8d7eb32748b14581824c1b94cea9ed9a08456312a2e94eddd522d01b927 22.02MB / 40.73MB 5.7s
|
||||
#12 sha256:2113f8d7eb32748b14581824c1b94cea9ed9a08456312a2e94eddd522d01b927 25.17MB / 40.73MB 6.0s
|
||||
#12 sha256:2113f8d7eb32748b14581824c1b94cea9ed9a08456312a2e94eddd522d01b927 27.26MB / 40.73MB 6.2s
|
||||
#12 sha256:2113f8d7eb32748b14581824c1b94cea9ed9a08456312a2e94eddd522d01b927 29.36MB / 40.73MB 6.3s
|
||||
#12 sha256:2113f8d7eb32748b14581824c1b94cea9ed9a08456312a2e94eddd522d01b927 32.51MB / 40.73MB 6.5s
|
||||
#12 sha256:2113f8d7eb32748b14581824c1b94cea9ed9a08456312a2e94eddd522d01b927 34.60MB / 40.73MB 6.6s
|
||||
#12 sha256:2113f8d7eb32748b14581824c1b94cea9ed9a08456312a2e94eddd522d01b927 36.70MB / 40.73MB 6.8s
|
||||
#12 sha256:2113f8d7eb32748b14581824c1b94cea9ed9a08456312a2e94eddd522d01b927 38.80MB / 40.73MB 6.9s
|
||||
#12 sha256:2113f8d7eb32748b14581824c1b94cea9ed9a08456312a2e94eddd522d01b927 40.73MB / 40.73MB 7.0s done
|
||||
#12 extracting sha256:2113f8d7eb32748b14581824c1b94cea9ed9a08456312a2e94eddd522d01b927
|
||||
#12 extracting sha256:2113f8d7eb32748b14581824c1b94cea9ed9a08456312a2e94eddd522d01b927 0.7s done
|
||||
#12 DONE 8.5s
|
||||
|
||||
#13 [build 1/5] FROM docker.io/library/maven:3.9-eclipse-temurin-21@sha256:d7e7f57407437c014571f1ad5a9955f03fc3edcb1d964067ef351fa38e798665
|
||||
#13 resolve docker.io/library/maven:3.9-eclipse-temurin-21@sha256:d7e7f57407437c014571f1ad5a9955f03fc3edcb1d964067ef351fa38e798665 0.0s done
|
||||
#13 sha256:80578b1f6dae09fcb4564b2223cc6e878af26159ec9b861492f95fc365daaa73 155B / 155B 0.6s done
|
||||
#13 sha256:ac34eb7f82d8f5eac3a80e23d94f36b83fbfec0ec9a7c414bc42c5d8ae4b8709 852B / 852B 0.3s done
|
||||
#13 sha256:a45b21ff67bfdf44ce77501a7a7bdfbb3575afe18fd188fc0d6de30627b90a3e 9.36MB / 9.36MB 4.2s done
|
||||
#13 sha256:ab9748d99311f3bbb2ab5925d1b526ee70d59a4dbcf18b722f36ae42c1c80e51 22.61MB / 22.61MB 2.2s done
|
||||
#13 sha256:3581c265283ead4745033bea80232c9672330e64126c9d520cf092afdd33e24f 2.28kB / 2.28kB 0.6s done
|
||||
#13 sha256:11127b4e771266a8d44b39627af51fefdb6fa421c879eb7d140a973db20c5ea4 160B / 160B 0.5s done
|
||||
#13 sha256:564f721386e7e6dd884c7e86149b2eccf2a7567f39b392cac9b7daaec0d44dbd 1.05MB / 156.47MB 2.1s
|
||||
#13 sha256:8e7ab84c2d67441fd3bba3abc37b68773f34e23d567cafb4fc02200349dd96c9 23.07MB / 24.17MB 2.0s
|
||||
#13 sha256:fff3795b437199a0b714aadba6fb2c251d7da853c3e257d3fed1d2c8d0f05158 5.24MB / 28.88MB 1.7s
|
||||
#13 ...
|
||||
|
||||
#12 [stage-1 1/3] FROM docker.io/library/eclipse-temurin:21-jre@sha256:194b590649efee5555de080c634905a30c2885190210e37ada26370ed2a9c781
|
||||
#12 extracting sha256:4a7720058461eb4ae40ed203b9874ab3248bd34ffb9948193e99245229fdbd6f done
|
||||
#12 extracting sha256:b0eb1335aa37af39b90084a961ce2528e0cf8192d25deab826a5ad63728f4edd
|
||||
#12 extracting sha256:b0eb1335aa37af39b90084a961ce2528e0cf8192d25deab826a5ad63728f4edd 0.3s done
|
||||
#12 DONE 8.8s
|
||||
|
||||
#13 [build 1/5] FROM docker.io/library/maven:3.9-eclipse-temurin-21@sha256:d7e7f57407437c014571f1ad5a9955f03fc3edcb1d964067ef351fa38e798665
|
||||
#13 ...
|
||||
|
||||
#12 [stage-1 1/3] FROM docker.io/library/eclipse-temurin:21-jre@sha256:194b590649efee5555de080c634905a30c2885190210e37ada26370ed2a9c781
|
||||
#12 extracting sha256:478d1828a921be5bb95db6f451338fc117ec86cb1d42195494b7897357dc226e 0.5s done
|
||||
#12 DONE 9.3s
|
||||
|
||||
#13 [build 1/5] FROM docker.io/library/maven:3.9-eclipse-temurin-21@sha256:d7e7f57407437c014571f1ad5a9955f03fc3edcb1d964067ef351fa38e798665
|
||||
#13 ...
|
||||
|
||||
#12 [stage-1 1/3] FROM docker.io/library/eclipse-temurin:21-jre@sha256:194b590649efee5555de080c634905a30c2885190210e37ada26370ed2a9c781
|
||||
#12 extracting sha256:00576a5b136e45737bb6f884dcfd2e09b19cbc41ebac1d7d032cc85b0d8f5f22 done
|
||||
#12 extracting sha256:5ac908e534636f1e892f6072aa8329d64001811ca530a2d49f3a42c665f81b9a done
|
||||
#12 DONE 9.3s
|
||||
|
||||
#13 [build 1/5] FROM docker.io/library/maven:3.9-eclipse-temurin-21@sha256:d7e7f57407437c014571f1ad5a9955f03fc3edcb1d964067ef351fa38e798665
|
||||
#13 ...
|
||||
|
||||
#14 [stage-1 2/3] WORKDIR /app
|
||||
#14 DONE 0.2s
|
||||
|
||||
#13 [build 1/5] FROM docker.io/library/maven:3.9-eclipse-temurin-21@sha256:d7e7f57407437c014571f1ad5a9955f03fc3edcb1d964067ef351fa38e798665
|
||||
#13 sha256:8e7ab84c2d67441fd3bba3abc37b68773f34e23d567cafb4fc02200349dd96c9 24.17MB / 24.17MB 3.0s done
|
||||
#13 sha256:fff3795b437199a0b714aadba6fb2c251d7da853c3e257d3fed1d2c8d0f05158 11.53MB / 28.88MB 2.9s
|
||||
#13 sha256:fff3795b437199a0b714aadba6fb2c251d7da853c3e257d3fed1d2c8d0f05158 13.63MB / 28.88MB 3.3s
|
||||
#13 sha256:fff3795b437199a0b714aadba6fb2c251d7da853c3e257d3fed1d2c8d0f05158 16.78MB / 28.88MB 4.1s
|
||||
#13 sha256:fff3795b437199a0b714aadba6fb2c251d7da853c3e257d3fed1d2c8d0f05158 20.97MB / 28.88MB 4.7s
|
||||
#13 sha256:fff3795b437199a0b714aadba6fb2c251d7da853c3e257d3fed1d2c8d0f05158 25.17MB / 28.88MB 5.6s
|
||||
#13 sha256:fff3795b437199a0b714aadba6fb2c251d7da853c3e257d3fed1d2c8d0f05158 28.88MB / 28.88MB 6.4s done
|
||||
#13 extracting sha256:fff3795b437199a0b714aadba6fb2c251d7da853c3e257d3fed1d2c8d0f05158
|
||||
#13 sha256:564f721386e7e6dd884c7e86149b2eccf2a7567f39b392cac9b7daaec0d44dbd 7.34MB / 156.47MB 7.2s
|
||||
#13 extracting sha256:fff3795b437199a0b714aadba6fb2c251d7da853c3e257d3fed1d2c8d0f05158 0.4s done
|
||||
#13 extracting sha256:8e7ab84c2d67441fd3bba3abc37b68773f34e23d567cafb4fc02200349dd96c9
|
||||
#13 extracting sha256:8e7ab84c2d67441fd3bba3abc37b68773f34e23d567cafb4fc02200349dd96c9 0.3s done
|
||||
#13 sha256:564f721386e7e6dd884c7e86149b2eccf2a7567f39b392cac9b7daaec0d44dbd 15.73MB / 156.47MB 9.3s
|
||||
#13 sha256:564f721386e7e6dd884c7e86149b2eccf2a7567f39b392cac9b7daaec0d44dbd 24.12MB / 156.47MB 10.1s
|
||||
#13 sha256:564f721386e7e6dd884c7e86149b2eccf2a7567f39b392cac9b7daaec0d44dbd 32.51MB / 156.47MB 11.6s
|
||||
#13 sha256:564f721386e7e6dd884c7e86149b2eccf2a7567f39b392cac9b7daaec0d44dbd 41.94MB / 156.47MB 13.1s
|
||||
#13 sha256:564f721386e7e6dd884c7e86149b2eccf2a7567f39b392cac9b7daaec0d44dbd 50.33MB / 156.47MB 14.7s
|
||||
#13 sha256:564f721386e7e6dd884c7e86149b2eccf2a7567f39b392cac9b7daaec0d44dbd 58.72MB / 156.47MB 16.1s
|
||||
#13 sha256:564f721386e7e6dd884c7e86149b2eccf2a7567f39b392cac9b7daaec0d44dbd 67.11MB / 156.47MB 17.4s
|
||||
#13 sha256:564f721386e7e6dd884c7e86149b2eccf2a7567f39b392cac9b7daaec0d44dbd 75.50MB / 156.47MB 18.9s
|
||||
#13 sha256:564f721386e7e6dd884c7e86149b2eccf2a7567f39b392cac9b7daaec0d44dbd 83.89MB / 156.47MB 20.4s
|
||||
#13 sha256:564f721386e7e6dd884c7e86149b2eccf2a7567f39b392cac9b7daaec0d44dbd 92.27MB / 156.47MB 23.3s
|
||||
#13 sha256:564f721386e7e6dd884c7e86149b2eccf2a7567f39b392cac9b7daaec0d44dbd 101.71MB / 156.47MB 24.3s
|
||||
#13 sha256:564f721386e7e6dd884c7e86149b2eccf2a7567f39b392cac9b7daaec0d44dbd 111.15MB / 156.47MB 26.3s
|
||||
#13 sha256:564f721386e7e6dd884c7e86149b2eccf2a7567f39b392cac9b7daaec0d44dbd 119.54MB / 156.47MB 27.2s
|
||||
#13 sha256:564f721386e7e6dd884c7e86149b2eccf2a7567f39b392cac9b7daaec0d44dbd 127.93MB / 156.47MB 28.8s
|
||||
#13 sha256:564f721386e7e6dd884c7e86149b2eccf2a7567f39b392cac9b7daaec0d44dbd 137.36MB / 156.47MB 31.1s
|
||||
#13 sha256:564f721386e7e6dd884c7e86149b2eccf2a7567f39b392cac9b7daaec0d44dbd 145.75MB / 156.47MB 33.6s
|
||||
#13 sha256:564f721386e7e6dd884c7e86149b2eccf2a7567f39b392cac9b7daaec0d44dbd 150.99MB / 156.47MB 38.7s
|
||||
#13 sha256:564f721386e7e6dd884c7e86149b2eccf2a7567f39b392cac9b7daaec0d44dbd 156.47MB / 156.47MB 41.4s done
|
||||
#13 extracting sha256:564f721386e7e6dd884c7e86149b2eccf2a7567f39b392cac9b7daaec0d44dbd
|
||||
#13 extracting sha256:564f721386e7e6dd884c7e86149b2eccf2a7567f39b392cac9b7daaec0d44dbd 1.0s done
|
||||
#13 DONE 48.7s
|
||||
|
||||
#13 [build 1/5] FROM docker.io/library/maven:3.9-eclipse-temurin-21@sha256:d7e7f57407437c014571f1ad5a9955f03fc3edcb1d964067ef351fa38e798665
|
||||
#13 extracting sha256:11127b4e771266a8d44b39627af51fefdb6fa421c879eb7d140a973db20c5ea4 done
|
||||
#13 extracting sha256:3581c265283ead4745033bea80232c9672330e64126c9d520cf092afdd33e24f done
|
||||
#13 extracting sha256:ab9748d99311f3bbb2ab5925d1b526ee70d59a4dbcf18b722f36ae42c1c80e51
|
||||
#13 extracting sha256:ab9748d99311f3bbb2ab5925d1b526ee70d59a4dbcf18b722f36ae42c1c80e51 0.3s done
|
||||
#13 DONE 49.0s
|
||||
|
||||
#13 [build 1/5] FROM docker.io/library/maven:3.9-eclipse-temurin-21@sha256:d7e7f57407437c014571f1ad5a9955f03fc3edcb1d964067ef351fa38e798665
|
||||
#13 extracting sha256:a45b21ff67bfdf44ce77501a7a7bdfbb3575afe18fd188fc0d6de30627b90a3e 0.0s done
|
||||
#13 extracting sha256:ac34eb7f82d8f5eac3a80e23d94f36b83fbfec0ec9a7c414bc42c5d8ae4b8709 done
|
||||
#13 extracting sha256:80578b1f6dae09fcb4564b2223cc6e878af26159ec9b861492f95fc365daaa73 done
|
||||
#13 DONE 49.0s
|
||||
|
||||
#15 [build 2/5] WORKDIR /build
|
||||
#15 DONE 0.1s
|
||||
|
||||
#16 [build 3/5] COPY pom.xml .
|
||||
#16 DONE 0.0s
|
||||
|
||||
#17 [build 4/5] COPY src ./src
|
||||
#17 DONE 0.0s
|
||||
|
||||
#18 [build 5/5] RUN mvn -B -P dev clean package -DskipTests
|
||||
#18 0.594 [INFO] Scanning for projects...
|
||||
#18 0.686 [INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-dependencies/3.5.14-SNAPSHOT/maven-metadata.xml
|
||||
#18 1.645 [WARNING] Could not transfer metadata org.springframework.boot:spring-boot-dependencies:3.5.14-SNAPSHOT/maven-metadata.xml from/to spring-snapshots (https://repo.spring.io/snapshot): (certificate_unknown) PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
|
||||
#18 1.648 [INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-dependencies/3.5.14-SNAPSHOT/spring-boot-dependencies-3.5.14-SNAPSHOT.pom
|
||||
#18 2.396 [ERROR] [ERROR] Some problems were encountered while processing the POMs:
|
||||
#18 2.396 [ERROR] Non-resolvable import POM: The following artifacts could not be resolved: org.springframework.boot:spring-boot-dependencies:pom:3.5.14-SNAPSHOT (absent): Could not transfer artifact org.springframework.boot:spring-boot-dependencies:pom:3.5.14-SNAPSHOT from/to spring-snapshots (https://repo.spring.io/snapshot): (certificate_unknown) PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target @ line 44, column 25
|
||||
#18 2.396 [ERROR] 'dependencies.dependency.version' for org.springframework.boot:spring-boot-starter-web:jar is missing. @ line 54, column 21
|
||||
#18 2.396 [ERROR] 'dependencies.dependency.version' for org.postgresql:postgresql:jar is missing. @ line 63, column 21
|
||||
#18 2.396 [ERROR] 'dependencies.dependency.version' for org.apache.tomcat.embed:tomcat-embed-jasper:jar is missing. @ line 68, column 21
|
||||
#18 2.396 [ERROR] 'dependencies.dependency.version' for org.projectlombok:lombok:jar is missing. @ line 72, column 21
|
||||
#18 2.396 [ERROR] 'dependencies.dependency.version' for org.springframework.boot:spring-boot-starter-tomcat:jar is missing. @ line 77, column 21
|
||||
#18 2.396 [ERROR] 'dependencies.dependency.version' for org.springframework.boot:spring-boot-starter-test:jar is missing. @ line 82, column 21
|
||||
#18 2.396 @
|
||||
#18 2.397 [ERROR] The build could not read 1 project -> [Help 1]
|
||||
#18 2.397 [ERROR]
|
||||
#18 2.397 [ERROR] The project com.pandoli365:bibimbap:0.0.1-SNAPSHOT (/build/pom.xml) has 7 errors
|
||||
#18 2.397 [ERROR] Non-resolvable import POM: The following artifacts could not be resolved: org.springframework.boot:spring-boot-dependencies:pom:3.5.14-SNAPSHOT (absent): Could not transfer artifact org.springframework.boot:spring-boot-dependencies:pom:3.5.14-SNAPSHOT from/to spring-snapshots (https://repo.spring.io/snapshot): (certificate_unknown) PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target @ line 44, column 25 -> [Help 2]
|
||||
#18 2.398 [ERROR] 'dependencies.dependency.version' for org.springframework.boot:spring-boot-starter-web:jar is missing. @ line 54, column 21
|
||||
#18 2.398 [ERROR] 'dependencies.dependency.version' for org.postgresql:postgresql:jar is missing. @ line 63, column 21
|
||||
#18 2.398 [ERROR] 'dependencies.dependency.version' for org.apache.tomcat.embed:tomcat-embed-jasper:jar is missing. @ line 68, column 21
|
||||
#18 2.398 [ERROR] 'dependencies.dependency.version' for org.projectlombok:lombok:jar is missing. @ line 72, column 21
|
||||
#18 2.398 [ERROR] 'dependencies.dependency.version' for org.springframework.boot:spring-boot-starter-tomcat:jar is missing. @ line 77, column 21
|
||||
#18 2.398 [ERROR] 'dependencies.dependency.version' for org.springframework.boot:spring-boot-starter-test:jar is missing. @ line 82, column 21
|
||||
#18 2.398 [ERROR]
|
||||
#18 2.400 [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
|
||||
#18 2.401 [ERROR] Re-run Maven using the -X switch to enable full debug logging.
|
||||
#18 2.401 [ERROR]
|
||||
#18 2.401 [ERROR] For more information about the errors and possible solutions, please read the following articles:
|
||||
#18 2.401 [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/ProjectBuildingException
|
||||
#18 2.401 [ERROR] [Help 2] http://cwiki.apache.org/confluence/display/MAVEN/UnresolvableModelException
|
||||
#18 ERROR: process "/bin/sh -c mvn -B -P dev clean package -DskipTests" did not complete successfully: exit code: 1
|
||||
------
|
||||
> [build 5/5] RUN mvn -B -P dev clean package -DskipTests:
|
||||
2.398 [ERROR] 'dependencies.dependency.version' for org.projectlombok:lombok:jar is missing. @ line 72, column 21
|
||||
2.398 [ERROR] 'dependencies.dependency.version' for org.springframework.boot:spring-boot-starter-tomcat:jar is missing. @ line 77, column 21
|
||||
2.398 [ERROR] 'dependencies.dependency.version' for org.springframework.boot:spring-boot-starter-test:jar is missing. @ line 82, column 21
|
||||
2.398 [ERROR]
|
||||
2.400 [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
|
||||
2.401 [ERROR] Re-run Maven using the -X switch to enable full debug logging.
|
||||
2.401 [ERROR]
|
||||
2.401 [ERROR] For more information about the errors and possible solutions, please read the following articles:
|
||||
2.401 [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/ProjectBuildingException
|
||||
2.401 [ERROR] [Help 2] http://cwiki.apache.org/confluence/display/MAVEN/UnresolvableModelException
|
||||
------
|
||||
Dockerfile:17
|
||||
|
||||
--------------------
|
||||
|
||||
15 | COPY src ./src
|
||||
|
||||
16 | # 테스트는 빌드 단계에서 제외(이 단계엔 DB 가 없다). 테스트는 compose 의 별도 test 프로필/호스트에서 수행.
|
||||
|
||||
17 | >>> RUN mvn -B -P dev clean package -DskipTests
|
||||
|
||||
18 |
|
||||
|
||||
19 | FROM eclipse-temurin:21-jre
|
||||
|
||||
--------------------
|
||||
|
||||
failed to solve: process "/bin/sh -c mvn -B -P dev clean package -DskipTests" did not complete successfully: exit code: 1
|
||||
|
||||
|
||||
|
||||
View build details: docker-desktop://dashboard/build/default/default/tgo6coh7fu44am13sbvs56l8g
|
||||
|
||||
BUILD_EXIT=1
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -1,114 +0,0 @@
|
|||
{"nodes":[
|
||||
{"id":"recruitpostsddl_recruit_posts_table","label":"recruit_posts Table (DDL)","file_type":"sql","source_file":"docs/recruit-posts-ddl.sql","source_location":"6-99","source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"recruitpostsddl_role_check","label":"recruit_posts_role_check (기획/아트/프로그래머)","file_type":"sql","source_file":"docs/recruit-posts-ddl.sql","source_location":"44-54","source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"recruitpostsddl_participation_type_check","label":"recruit_posts_participation_type_check (취미/수익쉐어/유급/게임잼)","file_type":"sql","source_file":"docs/recruit-posts-ddl.sql","source_location":"56-66","source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"recruitpostsddl_user_id_fkey","label":"recruit_posts.user_id FK -> users.id","file_type":"sql","source_file":"docs/recruit-posts-ddl.sql","source_location":"32-42","source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"securityhardeningddl_ux_provider_user_id_unique","label":"Unique Index ux_user_auth_identities_provider_user_id_active","file_type":"sql","source_file":"docs/security-hardening-ddl.sql","source_location":"14-17","source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"securityhardeningddl_duplicate_identity_check","label":"Duplicate Login Identity Detection Query","file_type":"sql","source_file":"docs/security-hardening-ddl.sql","source_location":"4-12","source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"securityhardeningddl_table","label":"Security Hardening DDL","file_type":"sql","source_file":"docs/security-hardening-ddl.sql","source_location":"1-55","source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"usersignupschema_doc","label":"회원가입 정보 구조 (User Signup Schema)","file_type":"document","source_file":"docs/user-signup-schema.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"usersignupschema_users_table","label":"users Table Concept","file_type":"document","source_file":"docs/user-signup-schema.md","source_location":"14","source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"usersignupschema_user_auth_identities","label":"user_auth_identities Table Concept","file_type":"document","source_file":"docs/user-signup-schema.md","source_location":"16-18","source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"usersignupschema_provider","label":"Login Provider (guest/google/email/kakao/naver/github/apple)","file_type":"document","source_file":"docs/user-signup-schema.md","source_location":"39","source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"usersignupschema_guest_signup","label":"게스트 회원가입 (Guest Signup)","file_type":"document","source_file":"docs/user-signup-schema.md","source_location":"45-79","source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"usersignupschema_social_signup","label":"소셜 회원가입 (Social Signup)","file_type":"document","source_file":"docs/user-signup-schema.md","source_location":"81-110","source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"usersignupschema_canonical_email","label":"canonical_email 처리 / 계정 병합 주의","file_type":"document","source_file":"docs/user-signup-schema.md","source_location":"112-122","source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"usersignupschema_dedup_judgment","label":"중복 가입 판단 (provider + provider_user_id 조회)","file_type":"document","source_file":"docs/user-signup-schema.md","source_location":"124-137","source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"usersignupschema_account_linking","label":"계정 연결 (Account Linking)","file_type":"document","source_file":"docs/user-signup-schema.md","source_location":"139-156","source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"usersignupschema_token_verification_rationale","label":"providerUserId 서버 토큰 검증 권장 근거","file_type":"document","source_file":"docs/user-signup-schema.md","source_location":"190","source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"docsindex_doc","label":"문서 인덱스 (Docs Index)","file_type":"document","source_file":"docs/index.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"docsindex_docs_first_workflow","label":"docs-first 워크플로우","file_type":"document","source_file":"docs/index.md","source_location":"3","source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"dbupdatequerygenerator_doc","label":"DB 업데이트 쿼리 생성기 사용법","file_type":"document","source_file":"docs/db-update-query-generator.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"dbupdatequerygenerator_tool","label":"DbUpdateQueryGeneratorTest (dev->live schema diff 도구)","file_type":"document","source_file":"docs/db-update-query-generator.md","source_location":"3","source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"dbupdatequerygenerator_schema_only_rationale","label":"스키마 구조 전용·데이터 복제 미생성 근거","file_type":"document","source_file":"docs/db-update-query-generator.md","source_location":"54-66","source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"profilemanagement_doc","label":"Profile Management Prompt (Maven/Spring 프로파일 관리)","file_type":"document","source_file":"docs/profile-management-prompt.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"adrindex_doc","label":"ADR 인덱스","file_type":"document","source_file":"docs/adr/index.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"projectanalysis_doc","label":"bibimbap 종합 코드 분석 (D1~D4)","file_type":"document","source_file":"docs/analysis/2026-06-16-project-analysis.md","source_location":null,"source_url":null,"captured_at":"2026-06-16","author":"art","contributor":null},
|
||||
{"id":"projectanalysis_d1_architecture","label":"D1 아키텍처/구조 (서비스 레이어 부재·fat controller)","file_type":"document","source_file":"docs/analysis/2026-06-16-project-analysis.md","source_location":"43-86","source_url":null,"captured_at":"2026-06-16","author":"art","contributor":null},
|
||||
{"id":"projectanalysis_d2_security","label":"D2 보안 (SQLi 0·PBKDF2·CSRF 더블서밋·업로드 방어)","file_type":"document","source_file":"docs/analysis/2026-06-16-project-analysis.md","source_location":"89-122","source_url":null,"captured_at":"2026-06-16","author":"art","contributor":null},
|
||||
{"id":"projectanalysis_d3_quality","label":"D3 코드 품질/기술부채 (dead code·테스트 전무·SNAPSHOT)","file_type":"document","source_file":"docs/analysis/2026-06-16-project-analysis.md","source_location":"126-151","source_url":null,"captured_at":"2026-06-16","author":"art","contributor":null},
|
||||
{"id":"projectanalysis_d4_domain","label":"D4 도메인/기능 (기능 인벤토리·데이터 모델)","file_type":"document","source_file":"docs/analysis/2026-06-16-project-analysis.md","source_location":"154-189","source_url":null,"captured_at":"2026-06-16","author":"art","contributor":null},
|
||||
{"id":"projectanalysis_login_signup_csrf_gap","label":"POST /login,/signup CSRF 미검증 (Top#3)","file_type":"document","source_file":"docs/analysis/2026-06-16-project-analysis.md","source_location":"32","source_url":null,"captured_at":"2026-06-16","author":"art","contributor":null},
|
||||
{"id":"projectanalysis_abstracts_dead_code","label":"abstracts 패키지 dead code (인증 우회 함정)","file_type":"document","source_file":"docs/analysis/2026-06-16-project-analysis.md","source_location":"33","source_url":null,"captured_at":"2026-06-16","author":"art","contributor":null},
|
||||
{"id":"projectanalysis_game_comments_likes_unwired","label":"게임 댓글/좋아요 스키마·매퍼 존재하나 미연결","file_type":"document","source_file":"docs/analysis/2026-06-16-project-analysis.md","source_location":"36-37","source_url":null,"captured_at":"2026-06-16","author":"art","contributor":null},
|
||||
{"id":"projectanalysis_pbkdf2","label":"PBKDF2-SHA256 210k iter 비밀번호 해싱","file_type":"document","source_file":"docs/analysis/2026-06-16-project-analysis.md","source_location":"31","source_url":null,"captured_at":"2026-06-16","author":"art","contributor":null},
|
||||
{"id":"analysisindex_doc","label":"Analysis 카테고리 인덱스","file_type":"document","source_file":"docs/analysis/index.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"worklogindex_doc","label":"Work Log 카테고리 인덱스","file_type":"document","source_file":"docs/work-log/index.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"securitychecklist_doc","label":"보안 개선 체크리스트","file_type":"document","source_file":"docs/security/security-remediation-checklist.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"securitychecklist_b1_csrf","label":"B1 login/signup CSRF 검증 추가 (완료)","file_type":"document","source_file":"docs/security/security-remediation-checklist.md","source_location":"21-57","source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"securitychecklist_b2_dead_code","label":"B2 프로토타입 dead code 제거","file_type":"document","source_file":"docs/security/security-remediation-checklist.md","source_location":"59-82","source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"securitychecklist_b3_likes_comments","label":"B3 좋아요/댓글 서버 영속화 연결","file_type":"document","source_file":"docs/security/security-remediation-checklist.md","source_location":"84-117","source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"securitychecklist_b4_hardening","label":"B4 의존성/세션/운영 하드닝","file_type":"document","source_file":"docs/security/security-remediation-checklist.md","source_location":"119-146","source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"securityindex_doc","label":"Security 카테고리 인덱스","file_type":"document","source_file":"docs/security/index.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"verificationstrategies_doc","label":"Verification Strategies Registry","file_type":"document","source_file":"docs/development/verification-strategies.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"verificationstrategies_ladder","label":"검증 사다리 L1/L2/L3","file_type":"document","source_file":"docs/development/verification-strategies.md","source_location":"5-27","source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"verificationstrategies_regression_mandate","label":"회귀 테스트 의무 (버그 수정 시 재현 테스트 동반)","file_type":"document","source_file":"docs/development/verification-strategies.md","source_location":"27","source_url":null,"captured_at":null,"author":null,"contributor":null}
|
||||
],
|
||||
"edges":[
|
||||
{"source":"recruitpostsddl_recruit_posts_table","target":"recruitpostsddl_role_check","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/recruit-posts-ddl.sql","source_location":"44-54","weight":1.0},
|
||||
{"source":"recruitpostsddl_recruit_posts_table","target":"recruitpostsddl_participation_type_check","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/recruit-posts-ddl.sql","source_location":"56-66","weight":1.0},
|
||||
{"source":"recruitpostsddl_recruit_posts_table","target":"recruitpostsddl_user_id_fkey","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/recruit-posts-ddl.sql","source_location":"32-42","weight":1.0},
|
||||
{"source":"recruitpostsddl_user_id_fkey","target":"usersignupschema_users_table","relation":"references","confidence":"INFERRED","confidence_score":0.85,"source_file":"docs/recruit-posts-ddl.sql","source_location":"39","weight":1.0},
|
||||
{"source":"securityhardeningddl_table","target":"securityhardeningddl_ux_provider_user_id_unique","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/security-hardening-ddl.sql","source_location":"14-17","weight":1.0},
|
||||
{"source":"securityhardeningddl_table","target":"securityhardeningddl_duplicate_identity_check","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/security-hardening-ddl.sql","source_location":"4-12","weight":1.0},
|
||||
{"source":"securityhardeningddl_duplicate_identity_check","target":"securityhardeningddl_ux_provider_user_id_unique","relation":"rationale_for","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/security-hardening-ddl.sql","source_location":"2-4","weight":1.0},
|
||||
{"source":"securityhardeningddl_ux_provider_user_id_unique","target":"usersignupschema_user_auth_identities","relation":"references","confidence":"INFERRED","confidence_score":0.85,"source_file":"docs/security-hardening-ddl.sql","source_location":"15","weight":1.0},
|
||||
{"source":"securityhardeningddl_table","target":"recruitpostsddl_recruit_posts_table","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/security-hardening-ddl.sql","source_location":"19","weight":1.0},
|
||||
{"source":"securityhardeningddl_ux_provider_user_id_unique","target":"usersignupschema_dedup_judgment","relation":"semantically_similar_to","confidence":"INFERRED","confidence_score":0.8,"source_file":"docs/security-hardening-ddl.sql","source_location":"14-17","weight":1.0},
|
||||
{"source":"usersignupschema_doc","target":"docsindex_doc","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/user-signup-schema.md","source_location":"7","weight":1.0},
|
||||
{"source":"usersignupschema_doc","target":"projectanalysis_doc","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/user-signup-schema.md","source_location":"8","weight":1.0},
|
||||
{"source":"usersignupschema_doc","target":"securitychecklist_doc","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/user-signup-schema.md","source_location":"9","weight":1.0},
|
||||
{"source":"usersignupschema_doc","target":"dbupdatequerygenerator_doc","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/user-signup-schema.md","source_location":"10","weight":1.0},
|
||||
{"source":"usersignupschema_doc","target":"projectanalysis_d4_domain","relation":"cites","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/user-signup-schema.md","source_location":"194","weight":1.0},
|
||||
{"source":"usersignupschema_user_auth_identities","target":"usersignupschema_users_table","relation":"conceptually_related_to","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/user-signup-schema.md","source_location":"18","weight":1.0},
|
||||
{"source":"usersignupschema_provider","target":"usersignupschema_user_auth_identities","relation":"conceptually_related_to","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/user-signup-schema.md","source_location":"39","weight":1.0},
|
||||
{"source":"usersignupschema_guest_signup","target":"usersignupschema_provider","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/user-signup-schema.md","source_location":"67","weight":1.0},
|
||||
{"source":"usersignupschema_social_signup","target":"usersignupschema_provider","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/user-signup-schema.md","source_location":"106","weight":1.0},
|
||||
{"source":"usersignupschema_dedup_judgment","target":"usersignupschema_user_auth_identities","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/user-signup-schema.md","source_location":"126","weight":1.0},
|
||||
{"source":"usersignupschema_account_linking","target":"usersignupschema_user_auth_identities","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/user-signup-schema.md","source_location":"143","weight":1.0},
|
||||
{"source":"usersignupschema_canonical_email","target":"usersignupschema_users_table","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/user-signup-schema.md","source_location":"114","weight":1.0},
|
||||
{"source":"usersignupschema_token_verification_rationale","target":"usersignupschema_social_signup","relation":"rationale_for","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/user-signup-schema.md","source_location":"190","weight":1.0},
|
||||
{"source":"dbupdatequerygenerator_doc","target":"docsindex_doc","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/db-update-query-generator.md","source_location":"7","weight":1.0},
|
||||
{"source":"dbupdatequerygenerator_doc","target":"projectanalysis_doc","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/db-update-query-generator.md","source_location":"8","weight":1.0},
|
||||
{"source":"dbupdatequerygenerator_doc","target":"securitychecklist_doc","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/db-update-query-generator.md","source_location":"9","weight":1.0},
|
||||
{"source":"dbupdatequerygenerator_doc","target":"usersignupschema_doc","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/db-update-query-generator.md","source_location":"10","weight":1.0},
|
||||
{"source":"dbupdatequerygenerator_doc","target":"projectanalysis_d3_quality","relation":"cites","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/db-update-query-generator.md","source_location":"108","weight":1.0},
|
||||
{"source":"dbupdatequerygenerator_doc","target":"dbupdatequerygenerator_tool","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/db-update-query-generator.md","source_location":"3","weight":1.0},
|
||||
{"source":"dbupdatequerygenerator_schema_only_rationale","target":"dbupdatequerygenerator_tool","relation":"rationale_for","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/db-update-query-generator.md","source_location":"66","weight":1.0},
|
||||
{"source":"projectanalysis_doc","target":"dbupdatequerygenerator_doc","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/analysis/2026-06-16-project-analysis.md","source_location":"216","weight":1.0},
|
||||
{"source":"projectanalysis_doc","target":"usersignupschema_doc","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/analysis/2026-06-16-project-analysis.md","source_location":"217","weight":1.0},
|
||||
{"source":"projectanalysis_doc","target":"projectanalysis_d1_architecture","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/analysis/2026-06-16-project-analysis.md","source_location":"43","weight":1.0},
|
||||
{"source":"projectanalysis_doc","target":"projectanalysis_d2_security","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/analysis/2026-06-16-project-analysis.md","source_location":"89","weight":1.0},
|
||||
{"source":"projectanalysis_doc","target":"projectanalysis_d3_quality","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/analysis/2026-06-16-project-analysis.md","source_location":"126","weight":1.0},
|
||||
{"source":"projectanalysis_doc","target":"projectanalysis_d4_domain","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/analysis/2026-06-16-project-analysis.md","source_location":"154","weight":1.0},
|
||||
{"source":"projectanalysis_d2_security","target":"projectanalysis_login_signup_csrf_gap","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/analysis/2026-06-16-project-analysis.md","source_location":"110","weight":1.0},
|
||||
{"source":"projectanalysis_d2_security","target":"projectanalysis_pbkdf2","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/analysis/2026-06-16-project-analysis.md","source_location":"99","weight":1.0},
|
||||
{"source":"projectanalysis_d3_quality","target":"projectanalysis_abstracts_dead_code","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/analysis/2026-06-16-project-analysis.md","source_location":"130","weight":1.0},
|
||||
{"source":"projectanalysis_d4_domain","target":"projectanalysis_game_comments_likes_unwired","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/analysis/2026-06-16-project-analysis.md","source_location":"171-172","weight":1.0},
|
||||
{"source":"projectanalysis_d4_domain","target":"recruitpostsddl_recruit_posts_table","relation":"references","confidence":"INFERRED","confidence_score":0.8,"source_file":"docs/analysis/2026-06-16-project-analysis.md","source_location":"179","weight":1.0},
|
||||
{"source":"projectanalysis_d4_domain","target":"usersignupschema_user_auth_identities","relation":"references","confidence":"INFERRED","confidence_score":0.85,"source_file":"docs/analysis/2026-06-16-project-analysis.md","source_location":"177","weight":1.0},
|
||||
{"source":"analysisindex_doc","target":"projectanalysis_doc","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/analysis/index.md","source_location":"7","weight":1.0},
|
||||
{"source":"docsindex_doc","target":"adrindex_doc","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/index.md","source_location":"11","weight":1.0},
|
||||
{"source":"docsindex_doc","target":"analysisindex_doc","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/index.md","source_location":"12","weight":1.0},
|
||||
{"source":"docsindex_doc","target":"securityindex_doc","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/index.md","source_location":"21","weight":1.0},
|
||||
{"source":"docsindex_doc","target":"worklogindex_doc","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/index.md","source_location":"23","weight":1.0},
|
||||
{"source":"securityindex_doc","target":"securitychecklist_doc","relation":"conceptually_related_to","confidence":"INFERRED","confidence_score":0.7,"source_file":"docs/security/index.md","source_location":"1","weight":1.0},
|
||||
{"source":"securitychecklist_doc","target":"projectanalysis_doc","relation":"cites","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/security/security-remediation-checklist.md","source_location":"3","weight":1.0},
|
||||
{"source":"securitychecklist_doc","target":"securitychecklist_b1_csrf","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/security/security-remediation-checklist.md","source_location":"21","weight":1.0},
|
||||
{"source":"securitychecklist_doc","target":"securitychecklist_b2_dead_code","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/security/security-remediation-checklist.md","source_location":"59","weight":1.0},
|
||||
{"source":"securitychecklist_doc","target":"securitychecklist_b3_likes_comments","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/security/security-remediation-checklist.md","source_location":"84","weight":1.0},
|
||||
{"source":"securitychecklist_doc","target":"securitychecklist_b4_hardening","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/security/security-remediation-checklist.md","source_location":"119","weight":1.0},
|
||||
{"source":"securitychecklist_b1_csrf","target":"projectanalysis_login_signup_csrf_gap","relation":"rationale_for","confidence":"INFERRED","confidence_score":0.9,"source_file":"docs/security/security-remediation-checklist.md","source_location":"23-28","weight":1.0},
|
||||
{"source":"securitychecklist_b2_dead_code","target":"projectanalysis_abstracts_dead_code","relation":"rationale_for","confidence":"INFERRED","confidence_score":0.9,"source_file":"docs/security/security-remediation-checklist.md","source_location":"61-67","weight":1.0},
|
||||
{"source":"securitychecklist_b3_likes_comments","target":"projectanalysis_game_comments_likes_unwired","relation":"rationale_for","confidence":"INFERRED","confidence_score":0.9,"source_file":"docs/security/security-remediation-checklist.md","source_location":"86-91","weight":1.0},
|
||||
{"source":"securitychecklist_b3_likes_comments","target":"recruitpostsddl_recruit_posts_table","relation":"semantically_similar_to","confidence":"INFERRED","confidence_score":0.65,"source_file":"docs/security/security-remediation-checklist.md","source_location":"100-104","weight":1.0},
|
||||
{"source":"verificationstrategies_doc","target":"verificationstrategies_ladder","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/development/verification-strategies.md","source_location":"5","weight":1.0},
|
||||
{"source":"verificationstrategies_doc","target":"verificationstrategies_regression_mandate","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/development/verification-strategies.md","source_location":"27","weight":1.0},
|
||||
{"source":"verificationstrategies_regression_mandate","target":"securitychecklist_b1_csrf","relation":"semantically_similar_to","confidence":"INFERRED","confidence_score":0.7,"source_file":"docs/development/verification-strategies.md","source_location":"27","weight":1.0},
|
||||
{"source":"verificationstrategies_ladder","target":"securitychecklist_b1_csrf","relation":"semantically_similar_to","confidence":"INFERRED","confidence_score":0.6,"source_file":"docs/development/verification-strategies.md","source_location":"23","weight":1.0}
|
||||
],
|
||||
"hyperedges":[
|
||||
{"nodes":["usersignupschema_user_auth_identities","securityhardeningddl_ux_provider_user_id_unique","usersignupschema_dedup_judgment","usersignupschema_account_linking"],"relation":"conceptually_related_to","concept":"provider + provider_user_id 유일성 기반 로그인 신원 식별·중복 방지","confidence":"INFERRED","confidence_score":0.85,"source_file":"docs/user-signup-schema.md"},
|
||||
{"nodes":["securitychecklist_doc","projectanalysis_doc","usersignupschema_doc","dbupdatequerygenerator_doc"],"relation":"conceptually_related_to","concept":"2026-06-16 프로젝트 분석을 허브로 한 docs 상호 참조 네트워크","confidence":"INFERRED","confidence_score":0.8,"source_file":"docs/index.md"}
|
||||
],
|
||||
"input_tokens":0,"output_tokens":0}
|
||||
|
|
@ -1,134 +0,0 @@
|
|||
{"nodes":[
|
||||
{"id":"document-category-classification_doc","label":"문서 카테고리 분류 기준","file_type":"document","source_file":"docs/development/document-category-classification.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"document-category-classification_changes_overuse","label":"changes/ 남용 방지 원칙","file_type":"document","source_file":"docs/development/document-category-classification.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"document-category-classification_why_refind_principle","label":"왜 다시 찾는가 기준 (분류 핵심 원칙)","file_type":"document","source_file":"docs/development/document-category-classification.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"document-category-classification_cat_adr","label":"카테고리 adr (불변 결정 레코드)","file_type":"document","source_file":"docs/development/document-category-classification.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"document-category-classification_cat_analysis","label":"카테고리 analysis","file_type":"document","source_file":"docs/development/document-category-classification.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"document-category-classification_cat_architecture","label":"카테고리 architecture","file_type":"document","source_file":"docs/development/document-category-classification.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"document-category-classification_cat_backlog","label":"카테고리 backlog","file_type":"document","source_file":"docs/development/document-category-classification.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"document-category-classification_cat_changes","label":"카테고리 changes (changelog)","file_type":"document","source_file":"docs/development/document-category-classification.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"document-category-classification_cat_contracts","label":"카테고리 contracts","file_type":"document","source_file":"docs/development/document-category-classification.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"document-category-classification_cat_development","label":"카테고리 development","file_type":"document","source_file":"docs/development/document-category-classification.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"document-category-classification_cat_domain","label":"카테고리 domain","file_type":"document","source_file":"docs/development/document-category-classification.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"document-category-classification_cat_issues","label":"카테고리 issues","file_type":"document","source_file":"docs/development/document-category-classification.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"document-category-classification_cat_maintenance","label":"카테고리 maintenance","file_type":"document","source_file":"docs/development/document-category-classification.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"document-category-classification_cat_security","label":"카테고리 security","file_type":"document","source_file":"docs/development/document-category-classification.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"document-category-classification_cat_usage","label":"카테고리 usage","file_type":"document","source_file":"docs/development/document-category-classification.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"document-category-classification_cat_worklog","label":"카테고리 work-log","file_type":"document","source_file":"docs/development/document-category-classification.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"document-category-classification_cat_graph","label":"카테고리 graph (자동 생성)","file_type":"document","source_file":"docs/development/document-category-classification.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"document-category-classification_quick_decision_order","label":"빠른 결정 순서","file_type":"document","source_file":"docs/development/document-category-classification.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
|
||||
{"id":"development_index","label":"Development 카테고리 인덱스","file_type":"document","source_file":"docs/development/index.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"development_verification_strategies","label":"verification-strategies.md","file_type":"document","source_file":"docs/development/index.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"development_atp_plugin_bundle_refs","label":"atp 플러그인 번들 레퍼런스 (플러그인 캐시)","file_type":"document","source_file":"docs/development/index.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
|
||||
{"id":"backlog_index","label":"Backlog 카테고리 인덱스","file_type":"document","source_file":"docs/backlog/index.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"changes_index","label":"Changes 카테고리 인덱스","file_type":"document","source_file":"docs/changes/index.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"contracts_index","label":"Contracts 카테고리 인덱스","file_type":"document","source_file":"docs/contracts/index.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"feedback_index","label":"Feedback 카테고리 인덱스","file_type":"document","source_file":"docs/feedback/index.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"maintenance_index","label":"Maintenance 카테고리 인덱스","file_type":"document","source_file":"docs/maintenance/index.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"issues_index","label":"Issues 카테고리 인덱스","file_type":"document","source_file":"docs/issues/index.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"domain_index","label":"Domain 카테고리 인덱스","file_type":"document","source_file":"docs/domain/index.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
|
||||
{"id":"graph_index","label":"Graph — graphify 산출물 메타","file_type":"document","source_file":"docs/graph/index.md","source_location":null,"source_url":null,"captured_at":"2026-06-16T13:02:01+0900","author":null,"contributor":null},
|
||||
{"id":"graph_graphify_outputs","label":"graphify 산출물 (HTML/JSON/audit)","file_type":"document","source_file":"docs/graph/index.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"graph_graph_refresh_checker","label":"graph-refresh-checker 서브에이전트","file_type":"document","source_file":"docs/graph/index.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"graph_scope_src","label":"scope: src (384 노드/613 엣지/23 커뮤니티)","file_type":"document","source_file":"docs/graph/index.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"graph_scope_docs","label":"scope: docs (44 노드/56 엣지/7 커뮤니티)","file_type":"document","source_file":"docs/graph/index.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"graph_atp_graphify_usage","label":"atp-graphify add-on graphify-usage.md","file_type":"document","source_file":"docs/graph/index.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
|
||||
{"id":"usage_index","label":"Usage 카테고리 인덱스","file_type":"document","source_file":"docs/usage/index.md","source_location":null,"source_url":null,"captured_at":null,"author":"template-maintainer","contributor":null},
|
||||
{"id":"usage_setup_checklist","label":"setup-checklist.md","file_type":"document","source_file":"docs/usage/index.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"usage_faq","label":"faq.md (이식자 실수 카탈로그 M1~M8)","file_type":"document","source_file":"docs/usage/index.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
|
||||
{"id":"local-setup_doc","label":"로컬 개발환경 온보딩","file_type":"document","source_file":"docs/usage/local-setup.md","source_location":null,"source_url":null,"captured_at":null,"author":"art","contributor":null},
|
||||
{"id":"local-setup_path_a_docker","label":"경로 A: Docker (compose 기반, 권장)","file_type":"document","source_file":"docs/usage/local-setup.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"local-setup_path_b_host","label":"경로 B: 직접 실행 (호스트)","file_type":"document","source_file":"docs/usage/local-setup.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"local-setup_schema_bootstrap","label":"DB 스키마 초기화 (db/schema.sql 복원)","file_type":"document","source_file":"docs/usage/local-setup.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"local-setup_tls_proxy_ca","label":"TLS 인터셉션 프록시 CA 주입","file_type":"document","source_file":"docs/usage/local-setup.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"local-setup_snapshot_dependency","label":"spring-boot 3.5.14-SNAPSHOT 의존 (온라인 빌드 전제)","file_type":"document","source_file":"docs/usage/local-setup.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"local-setup_p_dev_required","label":"-P dev 프로파일 필수 이유","file_type":"document","source_file":"docs/usage/local-setup.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"local-setup_recruit_posts_ddl","label":"권위 DDL recruit-posts-ddl.sql","file_type":"document","source_file":"docs/usage/local-setup.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
{"id":"local-setup_project_analysis_ref","label":"2026-06-16 프로젝트 분석 (기술부채/open_question)","file_type":"document","source_file":"docs/usage/local-setup.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null},
|
||||
|
||||
{"id":"architecture_index","label":"Architecture 카테고리 인덱스","file_type":"document","source_file":"docs/architecture/index.md","source_location":null,"source_url":null,"captured_at":null,"author":"template-maintainer","contributor":null},
|
||||
{"id":"architecture_file_map","label":"file-map.md (구성 파일 트리)","file_type":"document","source_file":"docs/architecture/index.md","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null}
|
||||
],
|
||||
"edges":[
|
||||
{"source":"document-category-classification_doc","target":"document-category-classification_changes_overuse","relation":"rationale_for","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/development/document-category-classification.md","source_location":"L5","weight":1.0},
|
||||
{"source":"document-category-classification_why_refind_principle","target":"document-category-classification_doc","relation":"rationale_for","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/development/document-category-classification.md","source_location":"L11","weight":1.0},
|
||||
{"source":"document-category-classification_doc","target":"document-category-classification_cat_adr","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/development/document-category-classification.md","source_location":"L19","weight":1.0},
|
||||
{"source":"document-category-classification_doc","target":"document-category-classification_cat_analysis","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/development/document-category-classification.md","source_location":"L20","weight":1.0},
|
||||
{"source":"document-category-classification_doc","target":"document-category-classification_cat_architecture","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/development/document-category-classification.md","source_location":"L21","weight":1.0},
|
||||
{"source":"document-category-classification_doc","target":"document-category-classification_cat_backlog","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/development/document-category-classification.md","source_location":"L22","weight":1.0},
|
||||
{"source":"document-category-classification_doc","target":"document-category-classification_cat_changes","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/development/document-category-classification.md","source_location":"L23","weight":1.0},
|
||||
{"source":"document-category-classification_doc","target":"document-category-classification_cat_contracts","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/development/document-category-classification.md","source_location":"L24","weight":1.0},
|
||||
{"source":"document-category-classification_doc","target":"document-category-classification_cat_development","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/development/document-category-classification.md","source_location":"L25","weight":1.0},
|
||||
{"source":"document-category-classification_doc","target":"document-category-classification_cat_domain","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/development/document-category-classification.md","source_location":"L26","weight":1.0},
|
||||
{"source":"document-category-classification_doc","target":"document-category-classification_cat_issues","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/development/document-category-classification.md","source_location":"L27","weight":1.0},
|
||||
{"source":"document-category-classification_doc","target":"document-category-classification_cat_maintenance","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/development/document-category-classification.md","source_location":"L28","weight":1.0},
|
||||
{"source":"document-category-classification_doc","target":"document-category-classification_cat_security","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/development/document-category-classification.md","source_location":"L29","weight":1.0},
|
||||
{"source":"document-category-classification_doc","target":"document-category-classification_cat_usage","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/development/document-category-classification.md","source_location":"L30","weight":1.0},
|
||||
{"source":"document-category-classification_doc","target":"document-category-classification_cat_worklog","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/development/document-category-classification.md","source_location":"L31","weight":1.0},
|
||||
{"source":"document-category-classification_doc","target":"document-category-classification_cat_graph","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/development/document-category-classification.md","source_location":"L32","weight":1.0},
|
||||
{"source":"document-category-classification_doc","target":"document-category-classification_quick_decision_order","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/development/document-category-classification.md","source_location":"L49","weight":1.0},
|
||||
{"source":"document-category-classification_changes_overuse","target":"document-category-classification_cat_changes","relation":"conceptually_related_to","confidence":"INFERRED","confidence_score":0.85,"source_file":"docs/development/document-category-classification.md","source_location":null,"weight":1.0},
|
||||
|
||||
{"source":"development_index","target":"document-category-classification_doc","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/development/index.md","source_location":"L8","weight":1.0},
|
||||
{"source":"development_index","target":"development_verification_strategies","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/development/index.md","source_location":"L7","weight":1.0},
|
||||
{"source":"development_index","target":"development_atp_plugin_bundle_refs","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/development/index.md","source_location":"L10","weight":1.0},
|
||||
{"source":"document-category-classification_cat_development","target":"development_index","relation":"conceptually_related_to","confidence":"INFERRED","confidence_score":0.8,"source_file":"docs/development/index.md","source_location":null,"weight":1.0},
|
||||
|
||||
{"source":"backlog_index","target":"document-category-classification_doc","relation":"cites","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/backlog/index.md","source_location":"L3","weight":1.0},
|
||||
{"source":"backlog_index","target":"document-category-classification_cat_backlog","relation":"conceptually_related_to","confidence":"INFERRED","confidence_score":0.85,"source_file":"docs/backlog/index.md","source_location":null,"weight":1.0},
|
||||
{"source":"changes_index","target":"document-category-classification_doc","relation":"cites","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/changes/index.md","source_location":"L3","weight":1.0},
|
||||
{"source":"changes_index","target":"document-category-classification_cat_changes","relation":"conceptually_related_to","confidence":"INFERRED","confidence_score":0.85,"source_file":"docs/changes/index.md","source_location":null,"weight":1.0},
|
||||
{"source":"contracts_index","target":"document-category-classification_doc","relation":"cites","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/contracts/index.md","source_location":"L3","weight":1.0},
|
||||
{"source":"contracts_index","target":"document-category-classification_cat_contracts","relation":"conceptually_related_to","confidence":"INFERRED","confidence_score":0.85,"source_file":"docs/contracts/index.md","source_location":null,"weight":1.0},
|
||||
{"source":"feedback_index","target":"document-category-classification_doc","relation":"cites","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/feedback/index.md","source_location":"L3","weight":1.0},
|
||||
{"source":"maintenance_index","target":"document-category-classification_doc","relation":"cites","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/maintenance/index.md","source_location":"L3","weight":1.0},
|
||||
{"source":"maintenance_index","target":"document-category-classification_cat_maintenance","relation":"conceptually_related_to","confidence":"INFERRED","confidence_score":0.85,"source_file":"docs/maintenance/index.md","source_location":null,"weight":1.0},
|
||||
{"source":"issues_index","target":"document-category-classification_doc","relation":"cites","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/issues/index.md","source_location":"L3","weight":1.0},
|
||||
{"source":"issues_index","target":"document-category-classification_cat_issues","relation":"conceptually_related_to","confidence":"INFERRED","confidence_score":0.85,"source_file":"docs/issues/index.md","source_location":null,"weight":1.0},
|
||||
{"source":"domain_index","target":"document-category-classification_doc","relation":"cites","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/domain/index.md","source_location":"L3","weight":1.0},
|
||||
{"source":"domain_index","target":"document-category-classification_cat_domain","relation":"conceptually_related_to","confidence":"INFERRED","confidence_score":0.85,"source_file":"docs/domain/index.md","source_location":null,"weight":1.0},
|
||||
|
||||
{"source":"graph_index","target":"graph_graphify_outputs","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/graph/index.md","source_location":"L12","weight":1.0},
|
||||
{"source":"graph_index","target":"graph_graph_refresh_checker","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/graph/index.md","source_location":"L19","weight":1.0},
|
||||
{"source":"graph_index","target":"graph_scope_src","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/graph/index.md","source_location":"L41","weight":1.0},
|
||||
{"source":"graph_index","target":"graph_scope_docs","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/graph/index.md","source_location":"L42","weight":1.0},
|
||||
{"source":"graph_index","target":"graph_atp_graphify_usage","relation":"cites","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/graph/index.md","source_location":"L14","weight":1.0},
|
||||
{"source":"graph_index","target":"document-category-classification_cat_graph","relation":"conceptually_related_to","confidence":"INFERRED","confidence_score":0.85,"source_file":"docs/graph/index.md","source_location":null,"weight":1.0},
|
||||
{"source":"graph_graph_refresh_checker","target":"graph_graphify_outputs","relation":"conceptually_related_to","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/graph/index.md","source_location":"L19","weight":1.0},
|
||||
|
||||
{"source":"usage_index","target":"local-setup_doc","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/usage/index.md","source_location":"L16","weight":1.0},
|
||||
{"source":"usage_index","target":"usage_setup_checklist","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/usage/index.md","source_location":"L17","weight":1.0},
|
||||
{"source":"usage_index","target":"usage_faq","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/usage/index.md","source_location":"L18","weight":1.0},
|
||||
{"source":"usage_index","target":"architecture_index","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/usage/index.md","source_location":"L12","weight":1.0},
|
||||
{"source":"usage_index","target":"development_index","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/usage/index.md","source_location":"L12","weight":1.0},
|
||||
{"source":"usage_index","target":"document-category-classification_cat_usage","relation":"conceptually_related_to","confidence":"INFERRED","confidence_score":0.85,"source_file":"docs/usage/index.md","source_location":null,"weight":1.0},
|
||||
|
||||
{"source":"local-setup_doc","target":"usage_index","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/usage/local-setup.md","source_location":"L16","weight":1.0},
|
||||
{"source":"local-setup_doc","target":"local-setup_project_analysis_ref","relation":"cites","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/usage/local-setup.md","source_location":"L16","weight":1.0},
|
||||
{"source":"local-setup_doc","target":"local-setup_path_a_docker","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/usage/local-setup.md","source_location":"L30","weight":1.0},
|
||||
{"source":"local-setup_doc","target":"local-setup_path_b_host","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/usage/local-setup.md","source_location":"L78","weight":1.0},
|
||||
{"source":"local-setup_doc","target":"local-setup_schema_bootstrap","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/usage/local-setup.md","source_location":"L137","weight":1.0},
|
||||
{"source":"local-setup_doc","target":"local-setup_tls_proxy_ca","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/usage/local-setup.md","source_location":"L169","weight":1.0},
|
||||
{"source":"local-setup_doc","target":"local-setup_snapshot_dependency","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/usage/local-setup.md","source_location":"L28","weight":1.0},
|
||||
{"source":"local-setup_doc","target":"local-setup_p_dev_required","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/usage/local-setup.md","source_location":"L130","weight":1.0},
|
||||
{"source":"local-setup_schema_bootstrap","target":"local-setup_recruit_posts_ddl","relation":"cites","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/usage/local-setup.md","source_location":"L139","weight":1.0},
|
||||
{"source":"local-setup_snapshot_dependency","target":"local-setup_tls_proxy_ca","relation":"rationale_for","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/usage/local-setup.md","source_location":"L28","weight":1.0},
|
||||
{"source":"local-setup_tls_proxy_ca","target":"local-setup_snapshot_dependency","relation":"conceptually_related_to","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/usage/local-setup.md","source_location":"L169","weight":1.0},
|
||||
{"source":"local-setup_p_dev_required","target":"local-setup_snapshot_dependency","relation":"rationale_for","confidence":"INFERRED","confidence_score":0.7,"source_file":"docs/usage/local-setup.md","source_location":"L132","weight":1.0},
|
||||
{"source":"local-setup_snapshot_dependency","target":"local-setup_project_analysis_ref","relation":"cites","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/usage/local-setup.md","source_location":"L206","weight":1.0},
|
||||
{"source":"local-setup_path_a_docker","target":"local-setup_path_b_host","relation":"semantically_similar_to","confidence":"INFERRED","confidence_score":0.75,"source_file":"docs/usage/local-setup.md","source_location":null,"weight":1.0},
|
||||
|
||||
{"source":"architecture_index","target":"architecture_file_map","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/architecture/index.md","source_location":"L16","weight":1.0},
|
||||
{"source":"architecture_index","target":"development_index","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/architecture/index.md","source_location":"L21","weight":1.0},
|
||||
{"source":"architecture_index","target":"graph_index","relation":"references","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/architecture/index.md","source_location":"L22","weight":1.0},
|
||||
{"source":"architecture_index","target":"document-category-classification_cat_architecture","relation":"conceptually_related_to","confidence":"INFERRED","confidence_score":0.85,"source_file":"docs/architecture/index.md","source_location":null,"weight":1.0}
|
||||
],
|
||||
"hyperedges":[
|
||||
{"nodes":["backlog_index","changes_index","contracts_index","feedback_index","maintenance_index","issues_index","domain_index"],"relation":"all_cite_classification_standard","confidence":"EXTRACTED","confidence_score":1.0,"source_file":"docs/development/document-category-classification.md","note":"7 category index docs all cite document-category-classification.md as the governing classification standard"}
|
||||
],
|
||||
"input_tokens":0,"output_tokens":0}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -1,411 +0,0 @@
|
|||
[INFO] Scanning for projects...
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/boot/maven-metadata.xml
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/maven-metadata.xml
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-metadata.xml
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/apache/maven/plugins/maven-metadata.xml
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/boot/maven-metadata.xml (249 B at 1.2 kB/s)
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-metadata.xml (14 kB at 69 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/codehaus/mojo/maven-metadata.xml
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/mojo/maven-metadata.xml
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/mojo/maven-metadata.xml (21 kB at 219 kB/s)
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/maven-metadata.xml (270 B at 254 B/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-maven-plugin/3.5.14-SNAPSHOT/maven-metadata.xml
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-maven-plugin/3.5.14-SNAPSHOT/maven-metadata.xml (2.0 kB at 7.2 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-maven-plugin/3.5.14-SNAPSHOT/spring-boot-maven-plugin-3.5.14-20260423.122208-46.pom
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-maven-plugin/3.5.14-SNAPSHOT/spring-boot-maven-plugin-3.5.14-20260423.122208-46.pom (4.0 kB at 16 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-maven-plugin/3.5.14-SNAPSHOT/spring-boot-maven-plugin-3.5.14-20260423.122208-46.jar
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-maven-plugin/3.5.14-SNAPSHOT/spring-boot-maven-plugin-3.5.14-20260423.122208-46.jar (138 kB at 136 kB/s)
|
||||
[INFO]
|
||||
[INFO] ----------------------< com.pandoli365:bibimbap >-----------------------
|
||||
[INFO] Building bibimbap 0.0.1-SNAPSHOT
|
||||
[INFO] from pom.xml
|
||||
[INFO] --------------------------------[ war ]---------------------------------
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-clean-plugin/3.4.1/maven-clean-plugin-3.4.1.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-clean-plugin/3.4.1/maven-clean-plugin-3.4.1.pom (5.6 kB at 176 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-plugins/43/maven-plugins-43.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-plugins/43/maven-plugins-43.pom (7.5 kB at 257 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-parent/43/maven-parent-43.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-parent/43/maven-parent-43.pom (50 kB at 1.6 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-war-plugin/3.4.0/maven-war-plugin-3.4.0.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-war-plugin/3.4.0/maven-war-plugin-3.4.0.pom (8.4 kB at 262 kB/s)
|
||||
[INFO]
|
||||
[INFO] --- clean:3.4.1:clean (default-clean) @ bibimbap ---
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-utils/4.0.1/plexus-utils-4.0.1.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-utils/4.0.1/plexus-utils-4.0.1.pom (7.8 kB at 217 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-utils/4.0.1/plexus-utils-4.0.1.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-utils/4.0.1/plexus-utils-4.0.1.jar (193 kB at 2.5 MB/s)
|
||||
[INFO] Deleting /Users/wemadeplay/workspace/stz/bibimbap/target
|
||||
[INFO]
|
||||
[INFO] --- resources:3.3.1:resources (default-resources) @ bibimbap ---
|
||||
[INFO] Copying 1 resource from src/main/resources to target/classes
|
||||
[INFO] Copying 4 resources from src/main/resources to target/classes
|
||||
[INFO]
|
||||
[INFO] --- compiler:3.14.1:compile (default-compile) @ bibimbap ---
|
||||
[INFO] Recompiling the module because of changed source code.
|
||||
[INFO] Compiling 28 source files with javac [debug release 21] to target/classes
|
||||
[INFO] /Users/wemadeplay/workspace/stz/bibimbap/src/main/java/com/pandoli365/bibimbap/abstracts/Service.java: /Users/wemadeplay/workspace/stz/bibimbap/src/main/java/com/pandoli365/bibimbap/abstracts/Service.java uses unchecked or unsafe operations.
|
||||
[INFO] /Users/wemadeplay/workspace/stz/bibimbap/src/main/java/com/pandoli365/bibimbap/abstracts/Service.java: Recompile with -Xlint:unchecked for details.
|
||||
[INFO]
|
||||
[INFO] --- resources:3.3.1:testResources (default-testResources) @ bibimbap ---
|
||||
[INFO] skip non existing resourceDirectory /Users/wemadeplay/workspace/stz/bibimbap/src/test/resources
|
||||
[INFO]
|
||||
[INFO] --- compiler:3.14.1:testCompile (default-testCompile) @ bibimbap ---
|
||||
[INFO] Recompiling the module because of changed dependency.
|
||||
[INFO] Compiling 3 source files with javac [debug release 21] to target/test-classes
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[19,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[19,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[19,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[19,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[19,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[22,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[22,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[22,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[22,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[22,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[25,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[25,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[25,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[25,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[25,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[28,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[28,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[28,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[28,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[28,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[INFO]
|
||||
[INFO] --- surefire:3.5.5:test (default-test) @ bibimbap ---
|
||||
[INFO] Tests are skipped.
|
||||
[INFO]
|
||||
[INFO] --- war:3.4.0:war (default-war) @ bibimbap ---
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-archiver/3.6.0/maven-archiver-3.6.0.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-archiver/3.6.0/maven-archiver-3.6.0.pom (3.9 kB at 122 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/shared/maven-shared-components/36/maven-shared-components-36.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/shared/maven-shared-components/36/maven-shared-components-36.pom (4.9 kB at 144 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-parent/36/maven-parent-36.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-parent/36/maven-parent-36.pom (45 kB at 827 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/apache/26/apache-26.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/apache/26/apache-26.pom (21 kB at 467 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-io/3.4.0/plexus-io-3.4.0.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-io/3.4.0/plexus-io-3.4.0.pom (6.0 kB at 120 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-archiver/4.4.0/plexus-archiver-4.4.0.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-archiver/4.4.0/plexus-archiver-4.4.0.pom (6.3 kB at 52 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-compress/1.21/commons-compress-1.21.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-compress/1.21/commons-compress-1.21.pom (20 kB at 273 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/iq80/snappy/snappy/0.4/snappy-0.4.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/iq80/snappy/snappy/0.4/snappy-0.4.pom (15 kB at 291 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/tukaani/xz/1.9/xz-1.9.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/tukaani/xz/1.9/xz-1.9.pom (2.0 kB at 19 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/commons-io/commons-io/2.13.0/commons-io-2.13.0.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/commons-io/commons-io/2.13.0/commons-io-2.13.0.pom (20 kB at 383 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/58/commons-parent-58.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/58/commons-parent-58.pom (83 kB at 1.4 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/junit/junit-bom/5.9.3/junit-bom-5.9.3.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/junit/junit-bom/5.9.3/junit-bom-5.9.3.pom (5.6 kB at 53 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-archiver/4.7.1/plexus-archiver-4.7.1.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-archiver/4.7.1/plexus-archiver-4.7.1.pom (6.5 kB at 123 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-io/3.4.1/plexus-io-3.4.1.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-io/3.4.1/plexus-io-3.4.1.pom (6.0 kB at 163 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-compress/1.23.0/commons-compress-1.23.0.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-compress/1.23.0/commons-compress-1.23.0.pom (22 kB at 607 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/56/commons-parent-56.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/56/commons-parent-56.pom (82 kB at 1.8 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/junit/junit-bom/5.9.1/junit-bom-5.9.1.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/junit/junit-bom/5.9.1/junit-bom-5.9.1.pom (5.6 kB at 171 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/com/github/luben/zstd-jni/1.5.5-2/zstd-jni-1.5.5-2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/com/github/luben/zstd-jni/1.5.5-2/zstd-jni-1.5.5-2.pom (1.9 kB at 25 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/shared/maven-mapping/3.0.0/maven-mapping-3.0.0.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/shared/maven-mapping/3.0.0/maven-mapping-3.0.0.pom (4.1 kB at 63 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/shared/maven-shared-components/22/maven-shared-components-22.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/shared/maven-shared-components/22/maven-shared-components-22.pom (5.1 kB at 160 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-parent/27/maven-parent-27.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-parent/27/maven-parent-27.pom (41 kB at 1.1 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/apache/17/apache-17.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/apache/17/apache-17.pom (16 kB at 423 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-core/3.0/maven-core-3.0.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-core/3.0/maven-core-3.0.pom (6.6 kB at 201 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven/3.0/maven-3.0.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven/3.0/maven-3.0.pom (22 kB at 591 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-parent/15/maven-parent-15.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-parent/15/maven-parent-15.pom (24 kB at 800 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/apache/6/apache-6.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/apache/6/apache-6.pom (13 kB at 427 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-model/3.0/maven-model-3.0.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-model/3.0/maven-model-3.0.pom (3.9 kB at 134 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-settings/3.2.5/maven-settings-3.2.5.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-settings/3.2.5/maven-settings-3.2.5.pom (2.2 kB at 72 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven/3.2.5/maven-3.2.5.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven/3.2.5/maven-3.2.5.pom (22 kB at 722 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-parent/25/maven-parent-25.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-parent/25/maven-parent-25.pom (37 kB at 1.2 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/apache/15/apache-15.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/apache/15/apache-15.pom (15 kB at 508 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-settings-builder/3.0/maven-settings-builder-3.0.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-settings-builder/3.0/maven-settings-builder-3.0.pom (2.2 kB at 72 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-interpolation/1.14/plexus-interpolation-1.14.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-interpolation/1.14/plexus-interpolation-1.14.pom (910 B at 28 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-components/1.1.18/plexus-components-1.1.18.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-components/1.1.18/plexus-components-1.1.18.pom (5.4 kB at 185 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus/2.0.7/plexus-2.0.7.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus/2.0.7/plexus-2.0.7.pom (17 kB at 596 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-component-annotations/1.5.5/plexus-component-annotations-1.5.5.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-component-annotations/1.5.5/plexus-component-annotations-1.5.5.pom (815 B at 29 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-containers/1.5.5/plexus-containers-1.5.5.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-containers/1.5.5/plexus-containers-1.5.5.pom (4.2 kB at 128 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/sonatype/plexus/plexus-sec-dispatcher/1.3/plexus-sec-dispatcher-1.3.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/sonatype/plexus/plexus-sec-dispatcher/1.3/plexus-sec-dispatcher-1.3.pom (3.0 kB at 99 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/sonatype/spice/spice-parent/12/spice-parent-12.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/sonatype/spice/spice-parent/12/spice-parent-12.pom (6.8 kB at 227 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/sonatype/forge/forge-parent/4/forge-parent-4.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/sonatype/forge/forge-parent/4/forge-parent-4.pom (8.4 kB at 290 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/sonatype/plexus/plexus-cipher/1.4/plexus-cipher-1.4.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/sonatype/plexus/plexus-cipher/1.4/plexus-cipher-1.4.pom (2.1 kB at 74 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-repository-metadata/3.0/maven-repository-metadata-3.0.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-repository-metadata/3.0/maven-repository-metadata-3.0.pom (1.9 kB at 64 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-artifact/3.0/maven-artifact-3.0.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-artifact/3.0/maven-artifact-3.0.pom (1.9 kB at 66 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-plugin-api/3.0/maven-plugin-api-3.0.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-plugin-api/3.0/maven-plugin-api-3.0.pom (2.3 kB at 69 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/sonatype/sisu/sisu-inject-plexus/1.4.2/sisu-inject-plexus-1.4.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/sonatype/sisu/sisu-inject-plexus/1.4.2/sisu-inject-plexus-1.4.2.pom (5.4 kB at 153 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/sonatype/sisu/inject/guice-plexus/1.4.2/guice-plexus-1.4.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/sonatype/sisu/inject/guice-plexus/1.4.2/guice-plexus-1.4.2.pom (3.1 kB at 92 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/sonatype/sisu/inject/guice-bean/1.4.2/guice-bean-1.4.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/sonatype/sisu/inject/guice-bean/1.4.2/guice-bean-1.4.2.pom (2.6 kB at 81 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/sonatype/sisu/sisu-inject/1.4.2/sisu-inject-1.4.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/sonatype/sisu/sisu-inject/1.4.2/sisu-inject-1.4.2.pom (1.2 kB at 33 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/sonatype/sisu/sisu-parent/1.4.2/sisu-parent-1.4.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/sonatype/sisu/sisu-parent/1.4.2/sisu-parent-1.4.2.pom (7.8 kB at 251 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/sonatype/forge/forge-parent/6/forge-parent-6.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/sonatype/forge/forge-parent/6/forge-parent-6.pom (11 kB at 244 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-component-annotations/1.5.4/plexus-component-annotations-1.5.4.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-component-annotations/1.5.4/plexus-component-annotations-1.5.4.pom (815 B at 29 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-containers/1.5.4/plexus-containers-1.5.4.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-containers/1.5.4/plexus-containers-1.5.4.pom (4.2 kB at 132 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus/2.0.5/plexus-2.0.5.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus/2.0.5/plexus-2.0.5.pom (17 kB at 643 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-classworlds/2.2.3/plexus-classworlds-2.2.3.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-classworlds/2.2.3/plexus-classworlds-2.2.3.pom (4.0 kB at 138 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus/2.0.6/plexus-2.0.6.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus/2.0.6/plexus-2.0.6.pom (17 kB at 621 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/sonatype/sisu/sisu-inject-bean/1.4.2/sisu-inject-bean-1.4.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/sonatype/sisu/sisu-inject-bean/1.4.2/sisu-inject-bean-1.4.2.pom (5.5 kB at 188 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/sonatype/sisu/sisu-guice/2.1.7/sisu-guice-2.1.7.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/sonatype/sisu/sisu-guice/2.1.7/sisu-guice-2.1.7.pom (11 kB at 410 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-model-builder/3.0/maven-model-builder-3.0.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-model-builder/3.0/maven-model-builder-3.0.pom (2.2 kB at 72 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-aether-provider/3.0/maven-aether-provider-3.0.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-aether-provider/3.0/maven-aether-provider-3.0.pom (2.5 kB at 85 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/sonatype/aether/aether-api/1.7/aether-api-1.7.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/sonatype/aether/aether-api/1.7/aether-api-1.7.pom (1.7 kB at 40 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/sonatype/aether/aether-parent/1.7/aether-parent-1.7.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/sonatype/aether/aether-parent/1.7/aether-parent-1.7.pom (7.7 kB at 241 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/sonatype/aether/aether-util/1.7/aether-util-1.7.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/sonatype/aether/aether-util/1.7/aether-util-1.7.pom (2.1 kB at 61 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/sonatype/aether/aether-impl/1.7/aether-impl-1.7.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/sonatype/aether/aether-impl/1.7/aether-impl-1.7.pom (3.7 kB at 127 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/sonatype/aether/aether-spi/1.7/aether-spi-1.7.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/sonatype/aether/aether-spi/1.7/aether-spi-1.7.pom (1.7 kB at 56 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-interpolation/1.21/plexus-interpolation-1.21.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-interpolation/1.21/plexus-interpolation-1.21.pom (1.5 kB at 53 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-components/1.3.1/plexus-components-1.3.1.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-components/1.3.1/plexus-components-1.3.1.pom (3.1 kB at 99 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus/3.3.1/plexus-3.3.1.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus/3.3.1/plexus-3.3.1.pom (20 kB at 639 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/sonatype/spice/spice-parent/17/spice-parent-17.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/sonatype/spice/spice-parent/17/spice-parent-17.pom (6.8 kB at 225 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/sonatype/forge/forge-parent/10/forge-parent-10.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/sonatype/forge/forge-parent/10/forge-parent-10.pom (14 kB at 437 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-archiver/3.6.0/maven-archiver-3.6.0.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-archiver/3.6.0/maven-archiver-3.6.0.jar (26 kB at 905 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-io/3.4.0/plexus-io-3.4.0.jar
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/commons-io/commons-io/2.13.0/commons-io-2.13.0.jar
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-archiver/4.7.1/plexus-archiver-4.7.1.jar
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-compress/1.23.0/commons-compress-1.23.0.jar
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/iq80/snappy/snappy/0.4/snappy-0.4.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-io/3.4.0/plexus-io-3.4.0.jar (79 kB at 2.1 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/tukaani/xz/1.9/xz-1.9.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-archiver/4.7.1/plexus-archiver-4.7.1.jar (221 kB at 2.9 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/com/github/luben/zstd-jni/1.5.5-2/zstd-jni-1.5.5-2.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/tukaani/xz/1.9/xz-1.9.jar (116 kB at 1.5 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/shared/maven-mapping/3.0.0/maven-mapping-3.0.0.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/iq80/snappy/snappy/0.4/snappy-0.4.jar (58 kB at 623 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-core/3.0/maven-core-3.0.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/shared/maven-mapping/3.0.0/maven-mapping-3.0.0.jar (11 kB at 80 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-model/3.0/maven-model-3.0.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/commons-io/commons-io/2.13.0/commons-io-2.13.0.jar (484 kB at 3.1 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-settings-builder/3.0/maven-settings-builder-3.0.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-model/3.0/maven-model-3.0.jar (165 kB at 862 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-repository-metadata/3.0/maven-repository-metadata-3.0.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-settings-builder/3.0/maven-settings-builder-3.0.jar (38 kB at 183 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-artifact/3.0/maven-artifact-3.0.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-compress/1.23.0/commons-compress-1.23.0.jar (1.1 MB at 5.0 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-plugin-api/3.0/maven-plugin-api-3.0.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-core/3.0/maven-core-3.0.jar (527 kB at 2.0 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-model-builder/3.0/maven-model-builder-3.0.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-repository-metadata/3.0/maven-repository-metadata-3.0.jar (30 kB at 107 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-aether-provider/3.0/maven-aether-provider-3.0.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-artifact/3.0/maven-artifact-3.0.jar (52 kB at 185 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/sonatype/aether/aether-impl/1.7/aether-impl-1.7.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-plugin-api/3.0/maven-plugin-api-3.0.jar (49 kB at 166 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/sonatype/aether/aether-spi/1.7/aether-spi-1.7.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-aether-provider/3.0/maven-aether-provider-3.0.jar (51 kB at 160 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/sonatype/aether/aether-api/1.7/aether-api-1.7.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-model-builder/3.0/maven-model-builder-3.0.jar (148 kB at 454 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/sonatype/aether/aether-util/1.7/aether-util-1.7.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/sonatype/aether/aether-spi/1.7/aether-spi-1.7.jar (14 kB at 42 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/sonatype/sisu/sisu-inject-plexus/1.4.2/sisu-inject-plexus-1.4.2.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/sonatype/aether/aether-impl/1.7/aether-impl-1.7.jar (106 kB at 320 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/sonatype/sisu/sisu-inject-bean/1.4.2/sisu-inject-bean-1.4.2.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/sonatype/aether/aether-api/1.7/aether-api-1.7.jar (74 kB at 193 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/sonatype/sisu/sisu-guice/2.1.7/sisu-guice-2.1.7-noaop.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/sonatype/aether/aether-util/1.7/aether-util-1.7.jar (108 kB at 275 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-classworlds/2.2.3/plexus-classworlds-2.2.3.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/sonatype/sisu/sisu-inject-bean/1.4.2/sisu-inject-bean-1.4.2.jar (153 kB at 389 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-component-annotations/1.5.5/plexus-component-annotations-1.5.5.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/sonatype/sisu/sisu-inject-plexus/1.4.2/sisu-inject-plexus-1.4.2.jar (202 kB at 509 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/sonatype/plexus/plexus-sec-dispatcher/1.3/plexus-sec-dispatcher-1.3.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-component-annotations/1.5.5/plexus-component-annotations-1.5.5.jar (4.2 kB at 9.9 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/sonatype/plexus/plexus-cipher/1.4/plexus-cipher-1.4.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/sonatype/plexus/plexus-sec-dispatcher/1.3/plexus-sec-dispatcher-1.3.jar (29 kB at 66 kB/s)
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-classworlds/2.2.3/plexus-classworlds-2.2.3.jar (46 kB at 106 kB/s)
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/sonatype/sisu/sisu-guice/2.1.7/sisu-guice-2.1.7-noaop.jar (472 kB at 1.0 MB/s)
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/sonatype/plexus/plexus-cipher/1.4/plexus-cipher-1.4.jar (13 kB at 29 kB/s)
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/com/github/luben/zstd-jni/1.5.5-2/zstd-jni-1.5.5-2.jar (5.9 MB at 12 MB/s)
|
||||
[INFO] Packaging webapp
|
||||
[INFO] Assembling webapp [bibimbap] in [/Users/wemadeplay/workspace/stz/bibimbap/target/bibimbap-0.0.1-SNAPSHOT]
|
||||
[INFO] Processing war project
|
||||
[INFO] Copying webapp resources [/Users/wemadeplay/workspace/stz/bibimbap/src/main/webapp]
|
||||
[INFO] Building war: /Users/wemadeplay/workspace/stz/bibimbap/target/bibimbap-0.0.1-SNAPSHOT.war
|
||||
[INFO]
|
||||
[INFO] --- spring-boot:3.5.14-SNAPSHOT:repackage (default-cli) @ bibimbap ---
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-buildpack-platform/3.5.14-SNAPSHOT/maven-metadata.xml
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-buildpack-platform/3.5.14-SNAPSHOT/maven-metadata.xml (2.4 kB at 9.3 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-buildpack-platform/3.5.14-SNAPSHOT/spring-boot-buildpack-platform-3.5.14-20260423.122208-46.pom
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-buildpack-platform/3.5.14-SNAPSHOT/spring-boot-buildpack-platform-3.5.14-20260423.122208-46.pom (3.2 kB at 12 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/net/java/dev/jna/jna-platform/5.17.0/jna-platform-5.17.0.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/net/java/dev/jna/jna-platform/5.17.0/jna-platform-5.17.0.pom (2.3 kB at 39 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/net/java/dev/jna/jna/5.17.0/jna-5.17.0.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/net/java/dev/jna/jna/5.17.0/jna-5.17.0.pom (2.0 kB at 58 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-compress/1.27.1/commons-compress-1.27.1.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-compress/1.27.1/commons-compress-1.27.1.pom (23 kB at 623 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/72/commons-parent-72.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/72/commons-parent-72.pom (78 kB at 1.4 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/junit/junit-bom/5.11.0-M2/junit-bom-5.11.0-M2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/junit/junit-bom/5.11.0-M2/junit-bom-5.11.0-M2.pom (5.7 kB at 184 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/commons-codec/commons-codec/1.17.1/commons-codec-1.17.1.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/commons-codec/commons-codec/1.17.1/commons-codec-1.17.1.pom (18 kB at 508 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/71/commons-parent-71.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/71/commons-parent-71.pom (78 kB at 2.1 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/commons-io/commons-io/2.16.1/commons-io-2.16.1.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/commons-io/commons-io/2.16.1/commons-io-2.16.1.pom (20 kB at 561 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/69/commons-parent-69.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/69/commons-parent-69.pom (77 kB at 2.0 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/apache/31/apache-31.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/apache/31/apache-31.pom (24 kB at 713 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-lang3/3.16.0/commons-lang3-3.16.0.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-lang3/3.16.0/commons-lang3-3.16.0.pom (31 kB at 868 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/httpcomponents/client5/httpclient5/5.5.2/httpclient5-5.5.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/httpcomponents/client5/httpclient5/5.5.2/httpclient5-5.5.2.pom (6.1 kB at 184 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/httpcomponents/client5/httpclient5-parent/5.5.2/httpclient5-parent-5.5.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/httpcomponents/client5/httpclient5-parent/5.5.2/httpclient5-parent-5.5.2.pom (17 kB at 452 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpcomponents-parent/14/httpcomponents-parent-14.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpcomponents-parent/14/httpcomponents-parent-14.pom (30 kB at 633 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/apache/27/apache-27.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/apache/27/apache-27.pom (20 kB at 636 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/junit/junit-bom/5.13.3/junit-bom-5.13.3.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/junit/junit-bom/5.13.3/junit-bom-5.13.3.pom (5.7 kB at 202 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/httpcomponents/core5/httpcore5/5.3.6/httpcore5-5.3.6.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/httpcomponents/core5/httpcore5/5.3.6/httpcore5-5.3.6.pom (3.9 kB at 136 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/httpcomponents/core5/httpcore5-parent/5.3.6/httpcore5-parent-5.3.6.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/httpcomponents/core5/httpcore5-parent/5.3.6/httpcore5-parent-5.3.6.pom (14 kB at 481 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpcomponents-parent/13/httpcomponents-parent-13.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpcomponents-parent/13/httpcomponents-parent-13.pom (30 kB at 975 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/httpcomponents/core5/httpcore5-h2/5.3.6/httpcore5-h2-5.3.6.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/httpcomponents/core5/httpcore5-h2/5.3.6/httpcore5-h2-5.3.6.pom (3.6 kB at 90 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/tomlj/tomlj/1.0.0/tomlj-1.0.0.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/tomlj/tomlj/1.0.0/tomlj-1.0.0.pom (2.8 kB at 88 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/antlr/antlr4-runtime/4.7.2/antlr4-runtime-4.7.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/antlr/antlr4-runtime/4.7.2/antlr4-runtime-4.7.2.pom (3.6 kB at 129 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/antlr/antlr4-master/4.7.2/antlr4-master-4.7.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/antlr/antlr4-master/4.7.2/antlr4-master-4.7.2.pom (4.4 kB at 113 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.pom (4.3 kB at 84 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-loader-tools/3.5.14-SNAPSHOT/maven-metadata.xml
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-loader-tools/3.5.14-SNAPSHOT/maven-metadata.xml (2.4 kB at 9.2 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-loader-tools/3.5.14-SNAPSHOT/spring-boot-loader-tools-3.5.14-20260423.122208-46.pom
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-loader-tools/3.5.14-SNAPSHOT/spring-boot-loader-tools-3.5.14-20260423.122208-46.pom (2.3 kB at 8.7 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-shade-plugin/3.6.0/maven-shade-plugin-3.6.0.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-shade-plugin/3.6.0/maven-shade-plugin-3.6.0.pom (12 kB at 314 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-plugins/42/maven-plugins-42.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-plugins/42/maven-plugins-42.pom (7.7 kB at 233 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm/9.7/asm-9.7.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm/9.7/asm-9.7.pom (2.4 kB at 55 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm-commons/9.7/asm-commons-9.7.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm-commons/9.7/asm-commons-9.7.pom (2.8 kB at 87 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm-tree/9.7/asm-tree-9.7.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm-tree/9.7/asm-tree-9.7.pom (2.6 kB at 74 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/jdom/jdom2/2.0.6.1/jdom2-2.0.6.1.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/jdom/jdom2/2.0.6.1/jdom2-2.0.6.1.pom (4.6 kB at 121 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-compress/1.26.2/commons-compress-1.26.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-compress/1.26.2/commons-compress-1.26.2.pom (23 kB at 499 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/commons-codec/commons-codec/1.17.0/commons-codec-1.17.0.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/commons-codec/commons-codec/1.17.0/commons-codec-1.17.0.pom (18 kB at 526 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-lang3/3.14.0/commons-lang3-3.14.0.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-lang3/3.14.0/commons-lang3-3.14.0.pom (31 kB at 813 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/64/commons-parent-64.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/64/commons-parent-64.pom (78 kB at 1.9 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/apache/30/apache-30.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/apache/30/apache-30.pom (23 kB at 704 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/junit/junit-bom/5.10.0/junit-bom-5.10.0.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/junit/junit-bom/5.10.0/junit-bom-5.10.0.pom (5.6 kB at 188 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/vafer/jdependency/2.10/jdependency-2.10.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/vafer/jdependency/2.10/jdependency-2.10.pom (14 kB at 438 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-buildpack-platform/3.5.14-SNAPSHOT/spring-boot-buildpack-platform-3.5.14-20260423.122208-46.jar
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-buildpack-platform/3.5.14-SNAPSHOT/spring-boot-buildpack-platform-3.5.14-20260423.122208-46.jar (324 kB at 152 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-loader-tools/3.5.14-SNAPSHOT/spring-boot-loader-tools-3.5.14-20260423.122208-46.jar
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-loader-tools/3.5.14-SNAPSHOT/spring-boot-loader-tools-3.5.14-20260423.122208-46.jar (467 kB at 407 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/net/java/dev/jna/jna-platform/5.17.0/jna-platform-5.17.0.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/net/java/dev/jna/jna-platform/5.17.0/jna-platform-5.17.0.jar (1.4 MB at 14 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/net/java/dev/jna/jna/5.17.0/jna-5.17.0.jar
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-compress/1.27.1/commons-compress-1.27.1.jar
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/commons-codec/commons-codec/1.17.1/commons-codec-1.17.1.jar
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-lang3/3.16.0/commons-lang3-3.16.0.jar
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/httpcomponents/client5/httpclient5/5.5.2/httpclient5-5.5.2.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/commons-codec/commons-codec/1.17.1/commons-codec-1.17.1.jar (373 kB at 5.0 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/httpcomponents/core5/httpcore5/5.3.6/httpcore5-5.3.6.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/net/java/dev/jna/jna/5.17.0/jna-5.17.0.jar (2.0 MB at 12 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/httpcomponents/core5/httpcore5-h2/5.3.6/httpcore5-h2-5.3.6.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/httpcomponents/core5/httpcore5/5.3.6/httpcore5-5.3.6.jar (909 kB at 5.1 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/tomlj/tomlj/1.0.0/tomlj-1.0.0.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-lang3/3.16.0/commons-lang3-3.16.0.jar (674 kB at 3.4 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/antlr/antlr4-runtime/4.7.2/antlr4-runtime-4.7.2.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/httpcomponents/client5/httpclient5/5.5.2/httpclient5-5.5.2.jar (961 kB at 4.7 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-compress/1.27.1/commons-compress-1.27.1.jar (1.1 MB at 5.2 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-shade-plugin/3.6.0/maven-shade-plugin-3.6.0.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/tomlj/tomlj/1.0.0/tomlj-1.0.0.jar (157 kB at 714 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm/9.7/asm-9.7.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/httpcomponents/core5/httpcore5-h2/5.3.6/httpcore5-h2-5.3.6.jar (243 kB at 1.1 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm-commons/9.7/asm-commons-9.7.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar (20 kB at 84 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm-tree/9.7/asm-tree-9.7.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm/9.7/asm-9.7.jar (125 kB at 492 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/jdom/jdom2/2.0.6.1/jdom2-2.0.6.1.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm-commons/9.7/asm-commons-9.7.jar (73 kB at 285 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/commons-io/commons-io/2.16.1/commons-io-2.16.1.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-shade-plugin/3.6.0/maven-shade-plugin-3.6.0.jar (150 kB at 553 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/vafer/jdependency/2.10/jdependency-2.10.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm-tree/9.7/asm-tree-9.7.jar (52 kB at 191 kB/s)
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/antlr/antlr4-runtime/4.7.2/antlr4-runtime-4.7.2.jar (338 kB at 1.2 MB/s)
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/jdom/jdom2/2.0.6.1/jdom2-2.0.6.1.jar (328 kB at 1.1 MB/s)
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/commons-io/commons-io/2.16.1/commons-io-2.16.1.jar (509 kB at 1.6 MB/s)
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/vafer/jdependency/2.10/jdependency-2.10.jar (416 kB at 1.2 MB/s)
|
||||
[INFO] Replacing main artifact /Users/wemadeplay/workspace/stz/bibimbap/target/bibimbap-0.0.1-SNAPSHOT.war with repackaged archive, adding nested dependencies in BOOT-INF/.
|
||||
[INFO] The original artifact has been renamed to /Users/wemadeplay/workspace/stz/bibimbap/target/bibimbap-0.0.1-SNAPSHOT.war.original
|
||||
[INFO] ------------------------------------------------------------------------
|
||||
[INFO] BUILD SUCCESS
|
||||
[INFO] ------------------------------------------------------------------------
|
||||
[INFO] Total time: 15.275 s
|
||||
[INFO] Finished at: 2026-06-17T11:30:12+09:00
|
||||
[INFO] ------------------------------------------------------------------------
|
||||
PKG_EXIT=0
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
[INFO] Scanning for projects...
|
||||
[INFO]
|
||||
[INFO] ----------------------< com.pandoli365:bibimbap >-----------------------
|
||||
[INFO] Building bibimbap 0.0.1-SNAPSHOT
|
||||
[INFO] from pom.xml
|
||||
[INFO] --------------------------------[ war ]---------------------------------
|
||||
[INFO]
|
||||
[INFO] >>> spring-boot:3.5.14-SNAPSHOT:run (default-cli) > test-compile @ bibimbap >>>
|
||||
[INFO]
|
||||
[INFO] --- resources:3.3.1:resources (default-resources) @ bibimbap ---
|
||||
[INFO] Copying 1 resource from src/main/resources to target/classes
|
||||
[INFO] Copying 4 resources from src/main/resources to target/classes
|
||||
[INFO]
|
||||
[INFO] --- compiler:3.14.1:compile (default-compile) @ bibimbap ---
|
||||
[INFO] Nothing to compile - all classes are up to date.
|
||||
[INFO]
|
||||
[INFO] --- resources:3.3.1:testResources (default-testResources) @ bibimbap ---
|
||||
[INFO] skip non existing resourceDirectory /Users/wemadeplay/workspace/stz/bibimbap/src/test/resources
|
||||
[INFO]
|
||||
[INFO] --- compiler:3.14.1:testCompile (default-testCompile) @ bibimbap ---
|
||||
[INFO] Nothing to compile - all classes are up to date.
|
||||
[INFO]
|
||||
[INFO] <<< spring-boot:3.5.14-SNAPSHOT:run (default-cli) < test-compile @ bibimbap <<<
|
||||
[INFO]
|
||||
[INFO]
|
||||
[INFO] --- spring-boot:3.5.14-SNAPSHOT:run (default-cli) @ bibimbap ---
|
||||
[INFO] Attaching agents: []
|
||||
|
||||
. ____ _ __ _ _
|
||||
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
|
||||
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
|
||||
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
|
||||
' |____| .__|_| |_|_| |_\__, | / / / /
|
||||
=========|_|==============|___/=/_/_/_/
|
||||
|
||||
:: Spring Boot :: (v3.5.14-SNAPSHOT)
|
||||
|
||||
2026-06-17T11:30:24.194+09:00 INFO 85020 --- [bibimbap] [ main] c.p.bibimbap.BibimbapApplication : Starting BibimbapApplication using Java 21.0.11 with PID 85020 (/Users/wemadeplay/workspace/stz/bibimbap/target/classes started by wemadeplay in /Users/wemadeplay/workspace/stz/bibimbap)
|
||||
2026-06-17T11:30:24.195+09:00 INFO 85020 --- [bibimbap] [ main] c.p.bibimbap.BibimbapApplication : The following 1 profile is active: "dev"
|
||||
2026-06-17T11:30:24.394+09:00 DEBUG 85020 --- [bibimbap] [ main] org.apache.ibatis.logging.LogFactory : Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
|
||||
2026-06-17T11:30:24.515+09:00 INFO 85020 --- [bibimbap] [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http)
|
||||
2026-06-17T11:30:24.522+09:00 INFO 85020 --- [bibimbap] [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
|
||||
2026-06-17T11:30:24.522+09:00 INFO 85020 --- [bibimbap] [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.54]
|
||||
2026-06-17T11:30:24.579+09:00 INFO 85020 --- [bibimbap] [ main] org.apache.jasper.servlet.TldScanner : At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
|
||||
2026-06-17T11:30:24.580+09:00 INFO 85020 --- [bibimbap] [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
|
||||
2026-06-17T11:30:24.581+09:00 INFO 85020 --- [bibimbap] [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 374 ms
|
||||
2026-06-17T11:30:24.627+09:00 DEBUG 85020 --- [bibimbap] [ main] org.apache.ibatis.logging.LogFactory : Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
|
||||
2026-06-17T11:30:24.674+09:00 INFO 85020 --- [bibimbap] [ main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page template: index
|
||||
2026-06-17T11:30:24.718+09:00 WARN 85020 --- [bibimbap] [ main] o.s.w.s.resource.ResourceHandlerUtils : Appended trailing slash to static resource location: file:///Users/wemadeplay/workspace/stz/bibimbap/src/main/resources/static/game/profile/
|
||||
2026-06-17T11:30:24.766+09:00 INFO 85020 --- [bibimbap] [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/'
|
||||
2026-06-17T11:30:24.769+09:00 INFO 85020 --- [bibimbap] [ main] c.p.bibimbap.BibimbapApplication : Started BibimbapApplication in 0.727 seconds (process running for 0.838)
|
||||
2026-06-17T11:30:30.761+09:00 INFO 85020 --- [bibimbap] [0.0-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
|
||||
2026-06-17T11:30:30.762+09:00 INFO 85020 --- [bibimbap] [0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
|
||||
2026-06-17T11:30:30.762+09:00 INFO 85020 --- [bibimbap] [0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 0 ms
|
||||
2026-06-17T11:30:30.781+09:00 INFO 85020 --- [bibimbap] [0.0-8080-exec-1] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
|
||||
2026-06-17T11:30:30.857+09:00 INFO 85020 --- [bibimbap] [0.0-8080-exec-1] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection org.postgresql.jdbc.PgConnection@5a8c2889
|
||||
2026-06-17T11:30:30.858+09:00 INFO 85020 --- [bibimbap] [0.0-8080-exec-1] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
|
||||
2026-06-17T11:30:45.926+09:00 INFO 85020 --- [bibimbap] [ionShutdownHook] o.s.b.w.e.tomcat.GracefulShutdown : Commencing graceful shutdown. Waiting for active requests to complete
|
||||
2026-06-17T11:30:45.928+09:00 INFO 85020 --- [bibimbap] [tomcat-shutdown] o.s.b.w.e.tomcat.GracefulShutdown : Graceful shutdown complete
|
||||
2026-06-17T11:30:45.929+09:00 INFO 85020 --- [bibimbap] [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
|
||||
2026-06-17T11:30:45.930+09:00 INFO 85020 --- [bibimbap] [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
[INFO] Scanning for projects...
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-dependencies/3.5.14-SNAPSHOT/maven-metadata.xml
|
||||
[WARNING] Could not transfer metadata org.springframework.boot:spring-boot-dependencies:3.5.14-SNAPSHOT/maven-metadata.xml from/to spring-snapshots (https://repo.spring.io/snapshot): (certificate_unknown) PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-dependencies/3.5.14-SNAPSHOT/spring-boot-dependencies-3.5.14-SNAPSHOT.pom
|
||||
[ERROR] [ERROR] Some problems were encountered while processing the POMs:
|
||||
[ERROR] Non-resolvable import POM: The following artifacts could not be resolved: org.springframework.boot:spring-boot-dependencies:pom:3.5.14-SNAPSHOT (absent): Could not transfer artifact org.springframework.boot:spring-boot-dependencies:pom:3.5.14-SNAPSHOT from/to spring-snapshots (https://repo.spring.io/snapshot): (certificate_unknown) PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target @ line 44, column 25
|
||||
[ERROR] 'dependencies.dependency.version' for org.springframework.boot:spring-boot-starter-web:jar is missing. @ line 54, column 21
|
||||
[ERROR] 'dependencies.dependency.version' for org.postgresql:postgresql:jar is missing. @ line 63, column 21
|
||||
[ERROR] 'dependencies.dependency.version' for org.apache.tomcat.embed:tomcat-embed-jasper:jar is missing. @ line 68, column 21
|
||||
[ERROR] 'dependencies.dependency.version' for org.projectlombok:lombok:jar is missing. @ line 72, column 21
|
||||
[ERROR] 'dependencies.dependency.version' for org.springframework.boot:spring-boot-starter-tomcat:jar is missing. @ line 77, column 21
|
||||
[ERROR] 'dependencies.dependency.version' for org.springframework.boot:spring-boot-starter-test:jar is missing. @ line 82, column 21
|
||||
@
|
||||
[ERROR] The build could not read 1 project -> [Help 1]
|
||||
[ERROR]
|
||||
[ERROR] The project com.pandoli365:bibimbap:0.0.1-SNAPSHOT (/Users/wemadeplay/workspace/stz/bibimbap/pom.xml) has 7 errors
|
||||
[ERROR] Non-resolvable import POM: The following artifacts could not be resolved: org.springframework.boot:spring-boot-dependencies:pom:3.5.14-SNAPSHOT (absent): Could not transfer artifact org.springframework.boot:spring-boot-dependencies:pom:3.5.14-SNAPSHOT from/to spring-snapshots (https://repo.spring.io/snapshot): (certificate_unknown) PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target @ line 44, column 25 -> [Help 2]
|
||||
[ERROR] 'dependencies.dependency.version' for org.springframework.boot:spring-boot-starter-web:jar is missing. @ line 54, column 21
|
||||
[ERROR] 'dependencies.dependency.version' for org.postgresql:postgresql:jar is missing. @ line 63, column 21
|
||||
[ERROR] 'dependencies.dependency.version' for org.apache.tomcat.embed:tomcat-embed-jasper:jar is missing. @ line 68, column 21
|
||||
[ERROR] 'dependencies.dependency.version' for org.projectlombok:lombok:jar is missing. @ line 72, column 21
|
||||
[ERROR] 'dependencies.dependency.version' for org.springframework.boot:spring-boot-starter-tomcat:jar is missing. @ line 77, column 21
|
||||
[ERROR] 'dependencies.dependency.version' for org.springframework.boot:spring-boot-starter-test:jar is missing. @ line 82, column 21
|
||||
[ERROR]
|
||||
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
|
||||
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
|
||||
[ERROR]
|
||||
[ERROR] For more information about the errors and possible solutions, please read the following articles:
|
||||
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/ProjectBuildingException
|
||||
[ERROR] [Help 2] http://cwiki.apache.org/confluence/display/MAVEN/UnresolvableModelException
|
||||
TEST_EXIT=1
|
||||
|
|
@ -1,560 +0,0 @@
|
|||
[INFO] Scanning for projects...
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-dependencies/3.5.14-SNAPSHOT/maven-metadata.xml
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-dependencies/3.5.14-SNAPSHOT/maven-metadata.xml (808 B at 752 B/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-dependencies/3.5.14-SNAPSHOT/spring-boot-dependencies-3.5.14-20260423.122208-46.pom
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-dependencies/3.5.14-SNAPSHOT/spring-boot-dependencies-3.5.14-20260423.122208-46.pom (98 kB at 106 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/activemq/activemq-bom/6.1.8/activemq-bom-6.1.8.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/activemq/activemq-bom/6.1.8/activemq-bom-6.1.8.pom (7.9 kB at 65 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/assertj/assertj-bom/3.27.7/assertj-bom-3.27.7.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/assertj/assertj-bom/3.27.7/assertj-bom-3.27.7.pom (3.3 kB at 108 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/io/zipkin/reporter2/zipkin-reporter-bom/3.5.3/zipkin-reporter-bom-3.5.3.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/io/zipkin/reporter2/zipkin-reporter-bom/3.5.3/zipkin-reporter-bom-3.5.3.pom (6.1 kB at 169 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/cassandra/java-driver-bom/4.19.2/java-driver-bom-4.19.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/cassandra/java-driver-bom/4.19.2/java-driver-bom-4.19.2.pom (5.5 kB at 133 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/glassfish/jaxb/jaxb-bom/4.0.6/jaxb-bom-4.0.6.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/glassfish/jaxb/jaxb-bom/4.0.6/jaxb-bom-4.0.6.pom (12 kB at 376 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/groovy/groovy-bom/4.0.31/groovy-bom-4.0.31.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/groovy/groovy-bom/4.0.31/groovy-bom-4.0.31.pom (27 kB at 779 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/infinispan/infinispan-bom/15.2.6.Final/infinispan-bom-15.2.6.Final.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/infinispan/infinispan-bom/15.2.6.Final/infinispan-bom-15.2.6.Final.pom (17 kB at 562 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/infinispan/infinispan-build-configuration-parent/15.2.6.Final/infinispan-build-configuration-parent-15.2.6.Final.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/infinispan/infinispan-build-configuration-parent/15.2.6.Final/infinispan-build-configuration-parent-15.2.6.Final.pom (17 kB at 505 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/jackson-bom/2.21.2/jackson-bom-2.21.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/jackson-bom/2.21.2/jackson-bom-2.21.2.pom (20 kB at 519 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/jackson-parent/2.21/jackson-parent-2.21.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/jackson-parent/2.21/jackson-parent-2.21.pom (6.9 kB at 222 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/com/fasterxml/oss-parent/75/oss-parent-75.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/com/fasterxml/oss-parent/75/oss-parent-75.pom (24 kB at 687 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/glassfish/jersey/jersey-bom/3.1.11/jersey-bom-3.1.11.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/glassfish/jersey/jersey-bom/3.1.11/jersey-bom-3.1.11.pom (21 kB at 630 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/eclipse/jetty/ee10/jetty-ee10-bom/12.0.34/jetty-ee10-bom-12.0.34.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/eclipse/jetty/ee10/jetty-ee10-bom/12.0.34/jetty-ee10-bom-12.0.34.pom (9.6 kB at 274 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/eclipse/jetty/jetty-bom/12.0.34/jetty-bom-12.0.34.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/eclipse/jetty/jetty-bom/12.0.34/jetty-bom-12.0.34.pom (15 kB at 472 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/io/micrometer/micrometer-bom/1.15.11/micrometer-bom-1.15.11.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/io/micrometer/micrometer-bom/1.15.11/micrometer-bom-1.15.11.pom (8.6 kB at 221 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/mongodb/mongodb-driver-bom/5.5.2/mongodb-driver-bom-5.5.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/mongodb/mongodb-driver-bom/5.5.2/mongodb-driver-bom-5.5.2.pom (4.2 kB at 134 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/io/netty/netty-bom/4.1.132.Final/netty-bom-4.1.132.Final.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/io/netty/netty-bom/4.1.132.Final/netty-bom-4.1.132.Final.pom (15 kB at 447 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/io/prometheus/prometheus-metrics-bom/1.3.10/prometheus-metrics-bom-1.3.10.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/io/prometheus/prometheus-metrics-bom/1.3.10/prometheus-metrics-bom-1.3.10.pom (5.8 kB at 146 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/io/prometheus/client_java_parent/1.3.10/client_java_parent-1.3.10.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/io/prometheus/client_java_parent/1.3.10/client_java_parent-1.3.10.pom (4.4 kB at 114 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/pulsar/pulsar-bom/4.0.9/pulsar-bom-4.0.9.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/pulsar/pulsar-bom/4.0.9/pulsar-bom-4.0.9.pom (25 kB at 646 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/io/projectreactor/reactor-bom/2024.0.17/reactor-bom-2024.0.17.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/io/projectreactor/reactor-bom/2024.0.17/reactor-bom-2024.0.17.pom (4.8 kB at 154 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/io/rest-assured/rest-assured-bom/5.5.7/rest-assured-bom-5.5.7.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/io/rest-assured/rest-assured-bom/5.5.7/rest-assured-bom-5.5.7.pom (4.7 kB at 151 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/amqp/spring-amqp-bom/3.2.10/spring-amqp-bom-3.2.10.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/amqp/spring-amqp-bom/3.2.10/spring-amqp-bom-3.2.10.pom (3.9 kB at 118 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/batch/spring-batch-bom/5.2.5/spring-batch-bom-5.2.5.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/batch/spring-batch-bom/5.2.5/spring-batch-bom-5.2.5.pom (3.2 kB at 101 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/data/spring-data-bom/2025.0.11/spring-data-bom-2025.0.11.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/data/spring-data-bom/2025.0.11/spring-data-bom-2025.0.11.pom (5.5 kB at 184 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/spring-framework-bom/6.2.18/spring-framework-bom-6.2.18.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/spring-framework-bom/6.2.18/spring-framework-bom-6.2.18.pom (5.8 kB at 142 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/integration/spring-integration-bom/6.5.8/spring-integration-bom-6.5.8.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/integration/spring-integration-bom/6.5.8/spring-integration-bom-6.5.8.pom (10 kB at 354 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/pulsar/spring-pulsar-bom/1.2.17/spring-pulsar-bom-1.2.17.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/pulsar/spring-pulsar-bom/1.2.17/spring-pulsar-bom-1.2.17.pom (2.9 kB at 91 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/restdocs/spring-restdocs-bom/3.0.5/spring-restdocs-bom-3.0.5.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/restdocs/spring-restdocs-bom/3.0.5/spring-restdocs-bom-3.0.5.pom (2.6 kB at 66 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/security/spring-security-bom/6.5.10/spring-security-bom-6.5.10.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/security/spring-security-bom/6.5.10/spring-security-bom-6.5.10.pom (5.3 kB at 124 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/session/spring-session-bom/3.5.6/spring-session-bom-3.5.6.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/session/spring-session-bom/3.5.6/spring-session-bom-3.5.6.pom (2.9 kB at 63 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/ws/spring-ws-bom/4.1.3/spring-ws-bom-4.1.3.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/ws/spring-ws-bom/4.1.3/spring-ws-bom-4.1.3.pom (2.3 kB at 59 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/testcontainers/testcontainers-bom/1.21.4/testcontainers-bom-1.21.4.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/testcontainers/testcontainers-bom/1.21.4/testcontainers-bom-1.21.4.pom (12 kB at 340 kB/s)
|
||||
[INFO]
|
||||
[INFO] ----------------------< com.pandoli365:bibimbap >-----------------------
|
||||
[INFO] Building bibimbap 0.0.1-SNAPSHOT
|
||||
[INFO] from pom.xml
|
||||
[INFO] --------------------------------[ war ]---------------------------------
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-surefire-plugin/3.5.5/maven-surefire-plugin-3.5.5.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-surefire-plugin/3.5.5/maven-surefire-plugin-3.5.5.pom (4.9 kB at 162 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire/3.5.5/surefire-3.5.5.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire/3.5.5/surefire-3.5.5.pom (19 kB at 565 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-parent/47/maven-parent-47.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-parent/47/maven-parent-47.pom (54 kB at 1.6 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/apache/37/apache-37.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/apache/37/apache-37.pom (26 kB at 801 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-web/3.5.14-SNAPSHOT/maven-metadata.xml
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-web/3.5.14-SNAPSHOT/maven-metadata.xml (2.4 kB at 9.5 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-web/3.5.14-SNAPSHOT/spring-boot-starter-web-3.5.14-20260423.122208-46.pom
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-web/3.5.14-SNAPSHOT/spring-boot-starter-web-3.5.14-20260423.122208-46.pom (3.0 kB at 12 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter/3.5.14-SNAPSHOT/maven-metadata.xml
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter/3.5.14-SNAPSHOT/maven-metadata.xml (2.4 kB at 9.4 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter/3.5.14-SNAPSHOT/spring-boot-starter-3.5.14-20260423.122208-46.pom
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter/3.5.14-SNAPSHOT/spring-boot-starter-3.5.14-20260423.122208-46.pom (3.1 kB at 11 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot/3.5.14-SNAPSHOT/maven-metadata.xml
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot/3.5.14-SNAPSHOT/maven-metadata.xml (2.4 kB at 9.3 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot/3.5.14-SNAPSHOT/spring-boot-3.5.14-20260423.122208-46.pom
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot/3.5.14-SNAPSHOT/spring-boot-3.5.14-20260423.122208-46.pom (2.2 kB at 8.6 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/spring-core/6.2.18/spring-core-6.2.18.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/spring-core/6.2.18/spring-core-6.2.18.pom (2.0 kB at 52 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/spring-jcl/6.2.18/spring-jcl-6.2.18.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/spring-jcl/6.2.18/spring-jcl-6.2.18.pom (1.8 kB at 60 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/spring-context/6.2.18/spring-context-6.2.18.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/spring-context/6.2.18/spring-context-6.2.18.pom (2.8 kB at 90 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/spring-aop/6.2.18/spring-aop-6.2.18.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/spring-aop/6.2.18/spring-aop-6.2.18.pom (2.2 kB at 69 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/spring-beans/6.2.18/spring-beans-6.2.18.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/spring-beans/6.2.18/spring-beans-6.2.18.pom (2.0 kB at 65 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/spring-expression/6.2.18/spring-expression-6.2.18.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/spring-expression/6.2.18/spring-expression-6.2.18.pom (2.1 kB at 65 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/io/micrometer/micrometer-observation/1.15.11/micrometer-observation-1.15.11.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/io/micrometer/micrometer-observation/1.15.11/micrometer-observation-1.15.11.pom (3.8 kB at 116 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/io/micrometer/micrometer-commons/1.15.11/micrometer-commons-1.15.11.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/io/micrometer/micrometer-commons/1.15.11/micrometer-commons-1.15.11.pom (3.4 kB at 103 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-autoconfigure/3.5.14-SNAPSHOT/maven-metadata.xml
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-autoconfigure/3.5.14-SNAPSHOT/maven-metadata.xml (2.4 kB at 9.4 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-autoconfigure/3.5.14-SNAPSHOT/spring-boot-autoconfigure-3.5.14-20260423.122208-46.pom
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-autoconfigure/3.5.14-SNAPSHOT/spring-boot-autoconfigure-3.5.14-20260423.122208-46.pom (2.1 kB at 8.2 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-logging/3.5.14-SNAPSHOT/maven-metadata.xml
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-logging/3.5.14-SNAPSHOT/maven-metadata.xml (2.4 kB at 9.4 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-logging/3.5.14-SNAPSHOT/spring-boot-starter-logging-3.5.14-20260423.122208-46.pom
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-logging/3.5.14-SNAPSHOT/spring-boot-starter-logging-3.5.14-20260423.122208-46.pom (2.5 kB at 9.0 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/ch/qos/logback/logback-classic/1.5.32/logback-classic-1.5.32.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/ch/qos/logback/logback-classic/1.5.32/logback-classic-1.5.32.pom (16 kB at 274 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/ch/qos/logback/logback-parent/1.5.32/logback-parent-1.5.32.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/ch/qos/logback/logback-parent/1.5.32/logback-parent-1.5.32.pom (20 kB at 544 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/ch/qos/logback/logback-core/1.5.32/logback-core-1.5.32.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/ch/qos/logback/logback-core/1.5.32/logback-core-1.5.32.pom (9.4 kB at 209 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-json/3.5.14-SNAPSHOT/maven-metadata.xml
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-json/3.5.14-SNAPSHOT/maven-metadata.xml (2.4 kB at 8.3 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-json/3.5.14-SNAPSHOT/spring-boot-starter-json-3.5.14-20260423.122208-46.pom
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-json/3.5.14-SNAPSHOT/spring-boot-starter-json-3.5.14-20260423.122208-46.pom (3.1 kB at 12 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/spring-web/6.2.18/spring-web-6.2.18.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/spring-web/6.2.18/spring-web-6.2.18.pom (2.4 kB at 75 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.21.2/jackson-databind-2.21.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.21.2/jackson-databind-2.21.2.pom (23 kB at 606 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/jackson-base/2.21.2/jackson-base-2.21.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/jackson-base/2.21.2/jackson-base-2.21.2.pom (13 kB at 418 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/junit/junit-bom/5.14.1/junit-bom-5.14.1.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/junit/junit-bom/5.14.1/junit-bom-5.14.1.pom (5.7 kB at 183 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/core/jackson-annotations/2.21/jackson-annotations-2.21.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/core/jackson-annotations/2.21/jackson-annotations-2.21.pom (7.4 kB at 238 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/core/jackson-core/2.21.2/jackson-core-2.21.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/core/jackson-core/2.21.2/jackson-core-2.21.2.pom (10 kB at 346 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/datatype/jackson-datatype-jdk8/2.21.2/jackson-datatype-jdk8-2.21.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/datatype/jackson-datatype-jdk8/2.21.2/jackson-datatype-jdk8-2.21.2.pom (2.8 kB at 89 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/module/jackson-modules-java8/2.21.2/jackson-modules-java8-2.21.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/module/jackson-modules-java8/2.21.2/jackson-modules-java8-2.21.2.pom (3.1 kB at 93 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/datatype/jackson-datatype-jsr310/2.21.2/jackson-datatype-jsr310-2.21.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/datatype/jackson-datatype-jsr310/2.21.2/jackson-datatype-jsr310-2.21.2.pom (5.3 kB at 178 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/module/jackson-module-parameter-names/2.21.2/jackson-module-parameter-names-2.21.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/module/jackson-module-parameter-names/2.21.2/jackson-module-parameter-names-2.21.2.pom (4.2 kB at 150 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-tomcat/3.5.14-SNAPSHOT/maven-metadata.xml
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-tomcat/3.5.14-SNAPSHOT/maven-metadata.xml (2.4 kB at 9.4 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-tomcat/3.5.14-SNAPSHOT/spring-boot-starter-tomcat-3.5.14-20260423.122208-46.pom
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-tomcat/3.5.14-SNAPSHOT/spring-boot-starter-tomcat-3.5.14-20260423.122208-46.pom (3.1 kB at 12 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/tomcat/embed/tomcat-embed-core/10.1.54/tomcat-embed-core-10.1.54.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/tomcat/embed/tomcat-embed-core/10.1.54/tomcat-embed-core-10.1.54.pom (1.7 kB at 56 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/tomcat/embed/tomcat-embed-el/10.1.54/tomcat-embed-el-10.1.54.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/tomcat/embed/tomcat-embed-el/10.1.54/tomcat-embed-el-10.1.54.pom (1.5 kB at 43 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/tomcat/embed/tomcat-embed-websocket/10.1.54/tomcat-embed-websocket-10.1.54.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/tomcat/embed/tomcat-embed-websocket/10.1.54/tomcat-embed-websocket-10.1.54.pom (1.7 kB at 54 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/spring-webmvc/6.2.18/spring-webmvc-6.2.18.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/spring-webmvc/6.2.18/spring-webmvc-6.2.18.pom (3.0 kB at 69 kB/s)
|
||||
[INFO] Downloading from sonatype-oss-snapshots: https://oss.sonatype.org/content/repositories/snapshots/org/springframework/boot/spring-boot-starter-jdbc/3.5.14-SNAPSHOT/maven-metadata.xml
|
||||
[INFO] Downloading from spring-snapshot: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-jdbc/3.5.14-SNAPSHOT/maven-metadata.xml
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-jdbc/3.5.14-SNAPSHOT/maven-metadata.xml
|
||||
[INFO] Downloaded from spring-snapshot: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-jdbc/3.5.14-SNAPSHOT/maven-metadata.xml (2.4 kB at 9.5 kB/s)
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-jdbc/3.5.14-SNAPSHOT/maven-metadata.xml (2.4 kB at 2.6 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-jdbc/3.5.14-SNAPSHOT/spring-boot-starter-jdbc-3.5.14-20260423.122208-46.pom
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-jdbc/3.5.14-SNAPSHOT/spring-boot-starter-jdbc-3.5.14-20260423.122208-46.pom (2.5 kB at 10 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/com/zaxxer/HikariCP/6.3.3/HikariCP-6.3.3.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/com/zaxxer/HikariCP/6.3.3/HikariCP-6.3.3.pom (29 kB at 817 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/spring-jdbc/6.2.18/spring-jdbc-6.2.18.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/spring-jdbc/6.2.18/spring-jdbc-6.2.18.pom (2.4 kB at 80 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/spring-tx/6.2.18/spring-tx-6.2.18.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/spring-tx/6.2.18/spring-tx-6.2.18.pom (2.2 kB at 72 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/postgresql/postgresql/42.7.10/postgresql-42.7.10.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/postgresql/postgresql/42.7.10/postgresql-42.7.10.pom (2.7 kB at 93 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/3.52.0/checker-qual-3.52.0.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/3.52.0/checker-qual-3.52.0.pom (2.1 kB at 63 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/tomcat/embed/tomcat-embed-jasper/10.1.54/tomcat-embed-jasper-10.1.54.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/tomcat/embed/tomcat-embed-jasper/10.1.54/tomcat-embed-jasper-10.1.54.pom (2.1 kB at 67 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/tomcat/tomcat-annotations-api/10.1.54/tomcat-annotations-api-10.1.54.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/tomcat/tomcat-annotations-api/10.1.54/tomcat-annotations-api-10.1.54.pom (1.5 kB at 50 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/eclipse/jdt/ecj/3.33.0/ecj-3.33.0.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/eclipse/jdt/ecj/3.33.0/ecj-3.33.0.pom (1.3 kB at 44 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/projectlombok/lombok/1.18.46/lombok-1.18.46.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/projectlombok/lombok/1.18.46/lombok-1.18.46.pom (1.5 kB at 51 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-test/3.5.14-SNAPSHOT/maven-metadata.xml
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-test/3.5.14-SNAPSHOT/maven-metadata.xml (2.4 kB at 9.3 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-test/3.5.14-SNAPSHOT/spring-boot-starter-test-3.5.14-20260423.122208-46.pom
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-test/3.5.14-SNAPSHOT/spring-boot-starter-test-3.5.14-20260423.122208-46.pom (4.9 kB at 21 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-test/3.5.14-SNAPSHOT/maven-metadata.xml
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-test/3.5.14-SNAPSHOT/maven-metadata.xml (2.4 kB at 9.9 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-test/3.5.14-SNAPSHOT/spring-boot-test-3.5.14-20260423.122208-46.pom
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-test/3.5.14-SNAPSHOT/spring-boot-test-3.5.14-20260423.122208-46.pom (2.2 kB at 9.2 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/spring-test/6.2.18/spring-test-6.2.18.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/spring-test/6.2.18/spring-test-6.2.18.pom (2.1 kB at 64 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-test-autoconfigure/3.5.14-SNAPSHOT/maven-metadata.xml
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-test-autoconfigure/3.5.14-SNAPSHOT/maven-metadata.xml (2.4 kB at 10 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-test-autoconfigure/3.5.14-SNAPSHOT/spring-boot-test-autoconfigure-3.5.14-20260423.122208-46.pom
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-test-autoconfigure/3.5.14-SNAPSHOT/spring-boot-test-autoconfigure-3.5.14-20260423.122208-46.pom (2.5 kB at 10 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/com/jayway/jsonpath/json-path/2.9.0/json-path-2.9.0.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/com/jayway/jsonpath/json-path/2.9.0/json-path-2.9.0.pom (1.9 kB at 50 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/net/minidev/json-smart/2.5.2/json-smart-2.5.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/net/minidev/json-smart/2.5.2/json-smart-2.5.2.pom (10 kB at 318 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/net/minidev/accessors-smart/2.5.2/accessors-smart-2.5.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/net/minidev/accessors-smart/2.5.2/accessors-smart-2.5.2.pom (12 kB at 383 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm/9.7.1/asm-9.7.1.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm/9.7.1/asm-9.7.1.pom (2.4 kB at 79 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/jakarta/xml/bind/jakarta.xml.bind-api/4.0.4/jakarta.xml.bind-api-4.0.4.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/jakarta/xml/bind/jakarta.xml.bind-api/4.0.4/jakarta.xml.bind-api-4.0.4.pom (13 kB at 410 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/jakarta/xml/bind/jakarta.xml.bind-api-parent/4.0.4/jakarta.xml.bind-api-parent-4.0.4.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/jakarta/xml/bind/jakarta.xml.bind-api-parent/4.0.4/jakarta.xml.bind-api-parent-4.0.4.pom (9.1 kB at 277 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/jakarta/activation/jakarta.activation-api/2.1.4/jakarta.activation-api-2.1.4.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/jakarta/activation/jakarta.activation-api/2.1.4/jakarta.activation-api-2.1.4.pom (19 kB at 561 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/assertj/assertj-core/3.27.7/assertj-core-3.27.7.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/assertj/assertj-core/3.27.7/assertj-core-3.27.7.pom (3.8 kB at 123 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy/1.17.8/byte-buddy-1.17.8.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy/1.17.8/byte-buddy-1.17.8.pom (19 kB at 570 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy-parent/1.17.8/byte-buddy-parent-1.17.8.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy-parent/1.17.8/byte-buddy-parent-1.17.8.pom (66 kB at 1.6 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/awaitility/awaitility/4.2.2/awaitility-4.2.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/awaitility/awaitility/4.2.2/awaitility-4.2.2.pom (3.5 kB at 91 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/awaitility/awaitility-parent/4.2.2/awaitility-parent-4.2.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/awaitility/awaitility-parent/4.2.2/awaitility-parent-4.2.2.pom (11 kB at 302 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest/3.0/hamcrest-3.0.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest/3.0/hamcrest-3.0.pom (1.6 kB at 44 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/junit/jupiter/junit-jupiter/5.12.2/junit-jupiter-5.12.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/junit/jupiter/junit-jupiter/5.12.2/junit-jupiter-5.12.2.pom (3.2 kB at 82 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/junit/jupiter/junit-jupiter-api/5.12.2/junit-jupiter-api-5.12.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/junit/jupiter/junit-jupiter-api/5.12.2/junit-jupiter-api-5.12.2.pom (3.2 kB at 96 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/opentest4j/opentest4j/1.3.0/opentest4j-1.3.0.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/opentest4j/opentest4j/1.3.0/opentest4j-1.3.0.pom (2.0 kB at 36 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/junit/platform/junit-platform-commons/1.12.2/junit-platform-commons-1.12.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/junit/platform/junit-platform-commons/1.12.2/junit-platform-commons-1.12.2.pom (2.8 kB at 66 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apiguardian/apiguardian-api/1.1.2/apiguardian-api-1.1.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apiguardian/apiguardian-api/1.1.2/apiguardian-api-1.1.2.pom (1.5 kB at 41 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/junit/jupiter/junit-jupiter-params/5.12.2/junit-jupiter-params-5.12.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/junit/jupiter/junit-jupiter-params/5.12.2/junit-jupiter-params-5.12.2.pom (3.0 kB at 77 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/junit/jupiter/junit-jupiter-engine/5.12.2/junit-jupiter-engine-5.12.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/junit/jupiter/junit-jupiter-engine/5.12.2/junit-jupiter-engine-5.12.2.pom (3.2 kB at 94 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/junit/platform/junit-platform-engine/1.12.2/junit-platform-engine-1.12.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/junit/platform/junit-platform-engine/1.12.2/junit-platform-engine-1.12.2.pom (3.2 kB at 97 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/mockito/mockito-core/5.17.0/mockito-core-5.17.0.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/mockito/mockito-core/5.17.0/mockito-core-5.17.0.pom (2.5 kB at 77 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy-agent/1.17.8/byte-buddy-agent-1.17.8.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy-agent/1.17.8/byte-buddy-agent-1.17.8.pom (14 kB at 359 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/objenesis/objenesis/3.3/objenesis-3.3.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/objenesis/objenesis/3.3/objenesis-3.3.pom (3.0 kB at 91 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/objenesis/objenesis-parent/3.3/objenesis-parent-3.3.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/objenesis/objenesis-parent/3.3/objenesis-parent-3.3.pom (19 kB at 563 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/mockito/mockito-junit-jupiter/5.17.0/mockito-junit-jupiter-5.17.0.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/mockito/mockito-junit-jupiter/5.17.0/mockito-junit-jupiter-5.17.0.pom (2.3 kB at 79 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/skyscreamer/jsonassert/1.5.3/jsonassert-1.5.3.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/skyscreamer/jsonassert/1.5.3/jsonassert-1.5.3.pom (7.0 kB at 218 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/com/vaadin/external/google/android-json/0.0.20131108.vaadin1/android-json-0.0.20131108.vaadin1.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/com/vaadin/external/google/android-json/0.0.20131108.vaadin1/android-json-0.0.20131108.vaadin1.pom (2.8 kB at 63 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/xmlunit/xmlunit-core/2.10.4/xmlunit-core-2.10.4.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/xmlunit/xmlunit-core/2.10.4/xmlunit-core-2.10.4.pom (2.8 kB at 100 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/xmlunit/xmlunit-parent/2.10.4/xmlunit-parent-2.10.4.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/xmlunit/xmlunit-parent/2.10.4/xmlunit-parent-2.10.4.pom (23 kB at 613 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-web/3.5.14-SNAPSHOT/spring-boot-starter-web-3.5.14-20260423.122208-46.jar
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-web/3.5.14-SNAPSHOT/spring-boot-starter-web-3.5.14-20260423.122208-46.jar (4.8 kB at 20 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter/3.5.14-SNAPSHOT/spring-boot-starter-3.5.14-20260423.122208-46.jar
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot/3.5.14-SNAPSHOT/spring-boot-3.5.14-20260423.122208-46.jar
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-autoconfigure/3.5.14-SNAPSHOT/spring-boot-autoconfigure-3.5.14-20260423.122208-46.jar
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-logging/3.5.14-SNAPSHOT/spring-boot-starter-logging-3.5.14-20260423.122208-46.jar
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-json/3.5.14-SNAPSHOT/spring-boot-starter-json-3.5.14-20260423.122208-46.jar
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter/3.5.14-SNAPSHOT/spring-boot-starter-3.5.14-20260423.122208-46.jar (4.8 kB at 19 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-jdbc/3.5.14-SNAPSHOT/spring-boot-starter-jdbc-3.5.14-20260423.122208-46.jar
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-jdbc/3.5.14-SNAPSHOT/spring-boot-starter-jdbc-3.5.14-20260423.122208-46.jar (4.8 kB at 9.4 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-tomcat/3.5.14-SNAPSHOT/spring-boot-starter-tomcat-3.5.14-20260423.122208-46.jar
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-tomcat/3.5.14-SNAPSHOT/spring-boot-starter-tomcat-3.5.14-20260423.122208-46.jar (4.8 kB at 6.3 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-test/3.5.14-SNAPSHOT/spring-boot-starter-test-3.5.14-20260423.122208-46.jar
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-logging/3.5.14-SNAPSHOT/spring-boot-starter-logging-3.5.14-20260423.122208-46.jar (4.8 kB at 5.6 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-test/3.5.14-SNAPSHOT/spring-boot-test-3.5.14-20260423.122208-46.jar
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-json/3.5.14-SNAPSHOT/spring-boot-starter-json-3.5.14-20260423.122208-46.jar (4.8 kB at 5.1 kB/s)
|
||||
[INFO] Downloading from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-test-autoconfigure/3.5.14-SNAPSHOT/spring-boot-test-autoconfigure-3.5.14-20260423.122208-46.jar
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-test/3.5.14-SNAPSHOT/spring-boot-starter-test-3.5.14-20260423.122208-46.jar (4.8 kB at 4.7 kB/s)
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot/3.5.14-SNAPSHOT/spring-boot-3.5.14-20260423.122208-46.jar (1.9 MB at 711 kB/s)
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-test/3.5.14-SNAPSHOT/spring-boot-test-3.5.14-20260423.122208-46.jar (258 kB at 89 kB/s)
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-test-autoconfigure/3.5.14-SNAPSHOT/spring-boot-test-autoconfigure-3.5.14-20260423.122208-46.jar (230 kB at 79 kB/s)
|
||||
[INFO] Downloaded from spring-snapshots: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-autoconfigure/3.5.14-SNAPSHOT/spring-boot-autoconfigure-3.5.14-20260423.122208-46.jar (2.1 MB at 572 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/ch/qos/logback/logback-classic/1.5.32/logback-classic-1.5.32.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/ch/qos/logback/logback-classic/1.5.32/logback-classic-1.5.32.jar (286 kB at 4.0 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/ch/qos/logback/logback-core/1.5.32/logback-core-1.5.32.jar
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.21.2/jackson-databind-2.21.2.jar
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/core/jackson-annotations/2.21/jackson-annotations-2.21.jar
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/core/jackson-core/2.21.2/jackson-core-2.21.2.jar
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/datatype/jackson-datatype-jdk8/2.21.2/jackson-datatype-jdk8-2.21.2.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/ch/qos/logback/logback-core/1.5.32/logback-core-1.5.32.jar (644 kB at 10 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/datatype/jackson-datatype-jsr310/2.21.2/jackson-datatype-jsr310-2.21.2.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/datatype/jackson-datatype-jsr310/2.21.2/jackson-datatype-jsr310-2.21.2.jar (137 kB at 1.0 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/module/jackson-module-parameter-names/2.21.2/jackson-module-parameter-names-2.21.2.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/datatype/jackson-datatype-jdk8/2.21.2/jackson-datatype-jdk8-2.21.2.jar (36 kB at 267 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/spring-web/6.2.18/spring-web-6.2.18.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/module/jackson-module-parameter-names/2.21.2/jackson-module-parameter-names-2.21.2.jar (10 kB at 56 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/spring-beans/6.2.18/spring-beans-6.2.18.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/core/jackson-annotations/2.21/jackson-annotations-2.21.jar (82 kB at 423 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/io/micrometer/micrometer-observation/1.15.11/micrometer-observation-1.15.11.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/spring-web/6.2.18/spring-web-6.2.18.jar (2.1 MB at 8.0 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/io/micrometer/micrometer-commons/1.15.11/micrometer-commons-1.15.11.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/io/micrometer/micrometer-observation/1.15.11/micrometer-observation-1.15.11.jar (76 kB at 277 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/spring-webmvc/6.2.18/spring-webmvc-6.2.18.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/io/micrometer/micrometer-commons/1.15.11/micrometer-commons-1.15.11.jar (49 kB at 155 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/spring-aop/6.2.18/spring-aop-6.2.18.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/core/jackson-core/2.21.2/jackson-core-2.21.2.jar (596 kB at 1.4 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/spring-context/6.2.18/spring-context-6.2.18.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/spring-aop/6.2.18/spring-aop-6.2.18.jar (420 kB at 991 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/spring-expression/6.2.18/spring-expression-6.2.18.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/spring-beans/6.2.18/spring-beans-6.2.18.jar (892 kB at 2.0 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/com/zaxxer/HikariCP/6.3.3/HikariCP-6.3.3.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/spring-expression/6.2.18/spring-expression-6.2.18.jar (318 kB at 582 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/spring-jdbc/6.2.18/spring-jdbc-6.2.18.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/spring-context/6.2.18/spring-context-6.2.18.jar (1.4 MB at 2.5 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/spring-tx/6.2.18/spring-tx-6.2.18.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/com/zaxxer/HikariCP/6.3.3/HikariCP-6.3.3.jar (172 kB at 305 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/postgresql/postgresql/42.7.10/postgresql-42.7.10.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.21.2/jackson-databind-2.21.2.jar (1.7 MB at 2.7 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/3.52.0/checker-qual-3.52.0.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/spring-jdbc/6.2.18/spring-jdbc-6.2.18.jar (476 kB at 743 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/tomcat/embed/tomcat-embed-jasper/10.1.54/tomcat-embed-jasper-10.1.54.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/spring-tx/6.2.18/spring-tx-6.2.18.jar (290 kB at 451 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/tomcat/embed/tomcat-embed-core/10.1.54/tomcat-embed-core-10.1.54.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/spring-webmvc/6.2.18/spring-webmvc-6.2.18.jar (1.1 MB at 1.7 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/tomcat/tomcat-annotations-api/10.1.54/tomcat-annotations-api-10.1.54.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/3.52.0/checker-qual-3.52.0.jar (242 kB at 338 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/tomcat/embed/tomcat-embed-el/10.1.54/tomcat-embed-el-10.1.54.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/tomcat/tomcat-annotations-api/10.1.54/tomcat-annotations-api-10.1.54.jar (14 kB at 20 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/eclipse/jdt/ecj/3.33.0/ecj-3.33.0.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/tomcat/embed/tomcat-embed-jasper/10.1.54/tomcat-embed-jasper-10.1.54.jar (660 kB at 909 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/projectlombok/lombok/1.18.46/lombok-1.18.46.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/postgresql/postgresql/42.7.10/postgresql-42.7.10.jar (1.1 MB at 1.5 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/tomcat/embed/tomcat-embed-websocket/10.1.54/tomcat-embed-websocket-10.1.54.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/tomcat/embed/tomcat-embed-el/10.1.54/tomcat-embed-el-10.1.54.jar (264 kB at 308 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/com/jayway/jsonpath/json-path/2.9.0/json-path-2.9.0.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/tomcat/embed/tomcat-embed-websocket/10.1.54/tomcat-embed-websocket-10.1.54.jar (284 kB at 317 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/slf4j/slf4j-api/2.0.17/slf4j-api-2.0.17.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/projectlombok/lombok/1.18.46/lombok-1.18.46.jar (2.0 MB at 2.2 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/jakarta/xml/bind/jakarta.xml.bind-api/4.0.4/jakarta.xml.bind-api-4.0.4.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/com/jayway/jsonpath/json-path/2.9.0/json-path-2.9.0.jar (277 kB at 291 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/jakarta/activation/jakarta.activation-api/2.1.4/jakarta.activation-api-2.1.4.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/slf4j/slf4j-api/2.0.17/slf4j-api-2.0.17.jar (70 kB at 73 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/net/minidev/json-smart/2.5.2/json-smart-2.5.2.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/jakarta/activation/jakarta.activation-api/2.1.4/jakarta.activation-api-2.1.4.jar (67 kB at 66 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/net/minidev/accessors-smart/2.5.2/accessors-smart-2.5.2.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/net/minidev/json-smart/2.5.2/json-smart-2.5.2.jar (122 kB at 119 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm/9.7.1/asm-9.7.1.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/jakarta/xml/bind/jakarta.xml.bind-api/4.0.4/jakarta.xml.bind-api-4.0.4.jar (131 kB at 128 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/assertj/assertj-core/3.27.7/assertj-core-3.27.7.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/net/minidev/accessors-smart/2.5.2/accessors-smart-2.5.2.jar (30 kB at 29 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy/1.17.8/byte-buddy-1.17.8.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm/9.7.1/asm-9.7.1.jar (126 kB at 113 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/awaitility/awaitility/4.2.2/awaitility-4.2.2.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/tomcat/embed/tomcat-embed-core/10.1.54/tomcat-embed-core-10.1.54.jar (3.7 MB at 3.2 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest/3.0/hamcrest-3.0.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest/3.0/hamcrest-3.0.jar (126 kB at 103 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/junit/jupiter/junit-jupiter/5.12.2/junit-jupiter-5.12.2.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/awaitility/awaitility/4.2.2/awaitility-4.2.2.jar (97 kB at 79 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/junit/jupiter/junit-jupiter-api/5.12.2/junit-jupiter-api-5.12.2.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/assertj/assertj-core/3.27.7/assertj-core-3.27.7.jar (1.4 MB at 1.1 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/opentest4j/opentest4j/1.3.0/opentest4j-1.3.0.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/junit/jupiter/junit-jupiter/5.12.2/junit-jupiter-5.12.2.jar (6.4 kB at 5.0 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/junit/platform/junit-platform-commons/1.12.2/junit-platform-commons-1.12.2.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/opentest4j/opentest4j/1.3.0/opentest4j-1.3.0.jar (14 kB at 11 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apiguardian/apiguardian-api/1.1.2/apiguardian-api-1.1.2.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/junit/jupiter/junit-jupiter-api/5.12.2/junit-jupiter-api-5.12.2.jar (233 kB at 179 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/junit/jupiter/junit-jupiter-params/5.12.2/junit-jupiter-params-5.12.2.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/junit/platform/junit-platform-commons/1.12.2/junit-platform-commons-1.12.2.jar (152 kB at 114 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/junit/jupiter/junit-jupiter-engine/5.12.2/junit-jupiter-engine-5.12.2.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apiguardian/apiguardian-api/1.1.2/apiguardian-api-1.1.2.jar (6.8 kB at 5.1 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/junit/platform/junit-platform-engine/1.12.2/junit-platform-engine-1.12.2.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/junit/platform/junit-platform-engine/1.12.2/junit-platform-engine-1.12.2.jar (256 kB at 181 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/mockito/mockito-core/5.17.0/mockito-core-5.17.0.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/junit/jupiter/junit-jupiter-engine/5.12.2/junit-jupiter-engine-5.12.2.jar (292 kB at 207 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy-agent/1.17.8/byte-buddy-agent-1.17.8.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/junit/jupiter/junit-jupiter-params/5.12.2/junit-jupiter-params-5.12.2.jar (602 kB at 424 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/objenesis/objenesis/3.3/objenesis-3.3.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/objenesis/objenesis/3.3/objenesis-3.3.jar (49 kB at 34 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/mockito/mockito-junit-jupiter/5.17.0/mockito-junit-jupiter-5.17.0.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy-agent/1.17.8/byte-buddy-agent-1.17.8.jar (367 kB at 246 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/skyscreamer/jsonassert/1.5.3/jsonassert-1.5.3.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/eclipse/jdt/ecj/3.33.0/ecj-3.33.0.jar (3.2 MB at 2.1 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/com/vaadin/external/google/android-json/0.0.20131108.vaadin1/android-json-0.0.20131108.vaadin1.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/mockito/mockito-core/5.17.0/mockito-core-5.17.0.jar (709 kB at 463 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/spring-core/6.2.18/spring-core-6.2.18.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/mockito/mockito-junit-jupiter/5.17.0/mockito-junit-jupiter-5.17.0.jar (9.4 kB at 6.1 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/spring-jcl/6.2.18/spring-jcl-6.2.18.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/skyscreamer/jsonassert/1.5.3/jsonassert-1.5.3.jar (31 kB at 20 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/spring-test/6.2.18/spring-test-6.2.18.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/spring-jcl/6.2.18/spring-jcl-6.2.18.jar (24 kB at 15 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/xmlunit/xmlunit-core/2.10.4/xmlunit-core-2.10.4.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/com/vaadin/external/google/android-json/0.0.20131108.vaadin1/android-json-0.0.20131108.vaadin1.jar (18 kB at 12 kB/s)
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/xmlunit/xmlunit-core/2.10.4/xmlunit-core-2.10.4.jar (178 kB at 105 kB/s)
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/spring-test/6.2.18/spring-test-6.2.18.jar (1.0 MB at 532 kB/s)
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/spring-core/6.2.18/spring-core-6.2.18.jar (2.0 MB at 1.0 MB/s)
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy/1.17.8/byte-buddy-1.17.8.jar (9.0 MB at 3.9 MB/s)
|
||||
[INFO]
|
||||
[INFO] --- resources:3.3.1:resources (default-resources) @ bibimbap ---
|
||||
[INFO] Copying 1 resource from src/main/resources to target/classes
|
||||
[INFO] Copying 4 resources from src/main/resources to target/classes
|
||||
[INFO]
|
||||
[INFO] --- compiler:3.14.1:compile (default-compile) @ bibimbap ---
|
||||
[INFO] Recompiling the module because of changed source code.
|
||||
[INFO] Compiling 28 source files with javac [debug release 21] to target/classes
|
||||
[INFO] /Users/wemadeplay/workspace/stz/bibimbap/src/main/java/com/pandoli365/bibimbap/abstracts/Service.java: /Users/wemadeplay/workspace/stz/bibimbap/src/main/java/com/pandoli365/bibimbap/abstracts/Service.java uses unchecked or unsafe operations.
|
||||
[INFO] /Users/wemadeplay/workspace/stz/bibimbap/src/main/java/com/pandoli365/bibimbap/abstracts/Service.java: Recompile with -Xlint:unchecked for details.
|
||||
[INFO]
|
||||
[INFO] --- resources:3.3.1:testResources (default-testResources) @ bibimbap ---
|
||||
[INFO] skip non existing resourceDirectory /Users/wemadeplay/workspace/stz/bibimbap/src/test/resources
|
||||
[INFO]
|
||||
[INFO] --- compiler:3.14.1:testCompile (default-testCompile) @ bibimbap ---
|
||||
[INFO] Recompiling the module because of changed dependency.
|
||||
[INFO] Compiling 3 source files with javac [debug release 21] to target/test-classes
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[19,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[19,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[19,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[19,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[19,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[22,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[22,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[22,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[22,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[22,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[25,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[25,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[25,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[25,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[25,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[28,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[28,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[28,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[28,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[WARNING] /Users/wemadeplay/workspace/stz/bibimbap/src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java:[28,6] org.springframework.boot.test.mock.mockito.MockBean in org.springframework.boot.test.mock.mockito has been deprecated and marked for removal
|
||||
[INFO]
|
||||
[INFO] --- surefire:3.5.5:test (default-test) @ bibimbap ---
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-api/3.5.5/surefire-api-3.5.5.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-api/3.5.5/surefire-api-3.5.5.pom (3.7 kB at 128 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-logger-api/3.5.5/surefire-logger-api-3.5.5.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-logger-api/3.5.5/surefire-logger-api-3.5.5.pom (3.5 kB at 120 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-shared-utils/3.5.5/surefire-shared-utils-3.5.5.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-shared-utils/3.5.5/surefire-shared-utils-3.5.5.pom (4.0 kB at 128 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-extensions-api/3.5.5/surefire-extensions-api-3.5.5.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-extensions-api/3.5.5/surefire-extensions-api-3.5.5.pom (3.6 kB at 119 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/maven-surefire-common/3.5.5/maven-surefire-common-3.5.5.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/maven-surefire-common/3.5.5/maven-surefire-common-3.5.5.pom (7.3 kB at 269 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-booter/3.5.5/surefire-booter-3.5.5.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-booter/3.5.5/surefire-booter-3.5.5.pom (5.1 kB at 183 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-extensions-spi/3.5.5/surefire-extensions-spi-3.5.5.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-extensions-spi/3.5.5/surefire-extensions-spi-3.5.5.pom (1.7 kB at 59 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/resolver/maven-resolver-util/1.4.1/maven-resolver-util-1.4.1.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/resolver/maven-resolver-util/1.4.1/maven-resolver-util-1.4.1.pom (2.8 kB at 97 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/resolver/maven-resolver/1.4.1/maven-resolver-1.4.1.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/resolver/maven-resolver/1.4.1/maven-resolver-1.4.1.pom (18 kB at 443 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-parent/33/maven-parent-33.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-parent/33/maven-parent-33.pom (44 kB at 1.2 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/apache/21/apache-21.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/apache/21/apache-21.pom (17 kB at 503 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/resolver/maven-resolver-api/1.4.1/maven-resolver-api-1.4.1.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/resolver/maven-resolver-api/1.4.1/maven-resolver-api-1.4.1.pom (2.6 kB at 80 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/shared/maven-common-artifact-filters/3.4.0/maven-common-artifact-filters-3.4.0.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/shared/maven-common-artifact-filters/3.4.0/maven-common-artifact-filters-3.4.0.pom (5.4 kB at 138 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/shared/maven-shared-components/42/maven-shared-components-42.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/shared/maven-shared-components/42/maven-shared-components-42.pom (3.8 kB at 90 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-parent/42/maven-parent-42.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-parent/42/maven-parent-42.pom (50 kB at 885 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/apache/32/apache-32.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/apache/32/apache-32.pom (24 kB at 672 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-java/1.5.2/plexus-java-1.5.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-java/1.5.2/plexus-java-1.5.2.pom (4.1 kB at 107 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-languages/1.5.2/plexus-languages-1.5.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-languages/1.5.2/plexus-languages-1.5.2.pom (3.9 kB at 107 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus/24/plexus-24.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus/24/plexus-24.pom (31 kB at 848 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/junit/junit-bom/5.13.4/junit-bom-5.13.4.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/junit/junit-bom/5.13.4/junit-bom-5.13.4.pom (5.7 kB at 183 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm/9.9.1/asm-9.9.1.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm/9.9.1/asm-9.9.1.pom (2.4 kB at 68 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-api/3.5.5/surefire-api-3.5.5.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-api/3.5.5/surefire-api-3.5.5.jar (174 kB at 3.8 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-logger-api/3.5.5/surefire-logger-api-3.5.5.jar
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-shared-utils/3.5.5/surefire-shared-utils-3.5.5.jar
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-extensions-api/3.5.5/surefire-extensions-api-3.5.5.jar
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-booter/3.5.5/surefire-booter-3.5.5.jar
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/maven-surefire-common/3.5.5/maven-surefire-common-3.5.5.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-logger-api/3.5.5/surefire-logger-api-3.5.5.jar (14 kB at 315 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-extensions-spi/3.5.5/surefire-extensions-spi-3.5.5.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-extensions-api/3.5.5/surefire-extensions-api-3.5.5.jar (26 kB at 598 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/resolver/maven-resolver-util/1.4.1/maven-resolver-util-1.4.1.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-booter/3.5.5/surefire-booter-3.5.5.jar (123 kB at 2.4 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/resolver/maven-resolver-api/1.4.1/maven-resolver-api-1.4.1.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-extensions-spi/3.5.5/surefire-extensions-spi-3.5.5.jar (8.2 kB at 109 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/shared/maven-common-artifact-filters/3.4.0/maven-common-artifact-filters-3.4.0.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/resolver/maven-resolver-util/1.4.1/maven-resolver-util-1.4.1.jar (168 kB at 1.9 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-java/1.5.2/plexus-java-1.5.2.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/maven-surefire-common/3.5.5/maven-surefire-common-3.5.5.jar (316 kB at 3.5 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm/9.9.1/asm-9.9.1.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/resolver/maven-resolver-api/1.4.1/maven-resolver-api-1.4.1.jar (149 kB at 1.5 MB/s)
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/shared/maven-common-artifact-filters/3.4.0/maven-common-artifact-filters-3.4.0.jar (58 kB at 479 kB/s)
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-java/1.5.2/plexus-java-1.5.2.jar (57 kB at 466 kB/s)
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm/9.9.1/asm-9.9.1.jar (126 kB at 895 kB/s)
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-shared-utils/3.5.5/surefire-shared-utils-3.5.5.jar (3.0 MB at 14 MB/s)
|
||||
[INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-junit-platform/3.5.5/surefire-junit-platform-3.5.5.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-junit-platform/3.5.5/surefire-junit-platform-3.5.5.pom (5.2 kB at 144 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-providers/3.5.5/surefire-providers-3.5.5.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-providers/3.5.5/surefire-providers-3.5.5.pom (2.5 kB at 77 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/common-java5/3.5.5/common-java5-3.5.5.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/common-java5/3.5.5/common-java5-3.5.5.pom (3.1 kB at 109 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/junit/platform/junit-platform-launcher/1.12.2/junit-platform-launcher-1.12.2.pom
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/junit/platform/junit-platform-launcher/1.12.2/junit-platform-launcher-1.12.2.pom (3.0 kB at 98 kB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-junit-platform/3.5.5/surefire-junit-platform-3.5.5.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-junit-platform/3.5.5/surefire-junit-platform-3.5.5.jar (35 kB at 1.2 MB/s)
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/common-java5/3.5.5/common-java5-3.5.5.jar
|
||||
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/junit/platform/junit-platform-launcher/1.12.2/junit-platform-launcher-1.12.2.jar
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/common-java5/3.5.5/common-java5-3.5.5.jar (18 kB at 551 kB/s)
|
||||
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/junit/platform/junit-platform-launcher/1.12.2/junit-platform-launcher-1.12.2.jar (208 kB at 3.4 MB/s)
|
||||
[INFO]
|
||||
[INFO] -------------------------------------------------------
|
||||
[INFO] T E S T S
|
||||
[INFO] -------------------------------------------------------
|
||||
[INFO] Running com.pandoli365.bibimbap.controller.api.UserControllerCsrfTest
|
||||
Mockito is currently self-attaching to enable the inline-mock-maker. This will no longer work in future releases of the JDK. Please add Mockito as an agent to your build as described in Mockito's documentation: https://javadoc.io/doc/org.mockito/mockito-core/latest/org.mockito/org/mockito/Mockito.html#0.3
|
||||
OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
|
||||
WARNING: A Java agent has been loaded dynamically (/Users/wemadeplay/.m2/repository/net/bytebuddy/byte-buddy-agent/1.17.8/byte-buddy-agent-1.17.8.jar)
|
||||
WARNING: If a serviceability tool is in use, please run with -XX:+EnableDynamicAgentLoading to hide this warning
|
||||
WARNING: If a serviceability tool is not in use, please run with -Djdk.instrument.traceUsage for more information
|
||||
WARNING: Dynamic loading of agents will be disallowed by default in a future release
|
||||
[INFO] Tests run: 5, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.691 s -- in com.pandoli365.bibimbap.controller.api.UserControllerCsrfTest
|
||||
[INFO] Running com.pandoli365.bibimbap.BibimbapApplicationTests
|
||||
11:29:36.907 [main] INFO org.springframework.test.context.support.AnnotationConfigContextLoaderUtils -- Could not detect default configuration classes for test class [com.pandoli365.bibimbap.BibimbapApplicationTests]: BibimbapApplicationTests does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
|
||||
11:29:36.942 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper -- Found @SpringBootConfiguration com.pandoli365.bibimbap.BibimbapApplication for test class com.pandoli365.bibimbap.BibimbapApplicationTests
|
||||
|
||||
. ____ _ __ _ _
|
||||
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
|
||||
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
|
||||
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
|
||||
' |____| .__|_| |_|_| |_\__, | / / / /
|
||||
=========|_|==============|___/=/_/_/_/
|
||||
|
||||
:: Spring Boot :: (v3.5.14-SNAPSHOT)
|
||||
|
||||
2026-06-17T11:29:37.074+09:00 INFO 83984 --- [bibimbap] [ main] c.p.bibimbap.BibimbapApplicationTests : Starting BibimbapApplicationTests using Java 21.0.11 with PID 83984 (started by wemadeplay in /Users/wemadeplay/workspace/stz/bibimbap)
|
||||
2026-06-17T11:29:37.074+09:00 INFO 83984 --- [bibimbap] [ main] c.p.bibimbap.BibimbapApplicationTests : The following 1 profile is active: "dev"
|
||||
2026-06-17T11:29:37.399+09:00 INFO 83984 --- [bibimbap] [ main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page template: index
|
||||
2026-06-17T11:29:37.439+09:00 WARN 83984 --- [bibimbap] [ main] o.s.w.s.resource.ResourceHandlerUtils : Appended trailing slash to static resource location: file:///Users/wemadeplay/workspace/stz/bibimbap/src/main/resources/static/game/profile/
|
||||
2026-06-17T11:29:37.476+09:00 INFO 83984 --- [bibimbap] [ main] c.p.bibimbap.BibimbapApplicationTests : Started BibimbapApplicationTests in 0.491 seconds (process running for 1.476)
|
||||
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.600 s -- in com.pandoli365.bibimbap.BibimbapApplicationTests
|
||||
[INFO]
|
||||
[INFO] Results:
|
||||
[INFO]
|
||||
[INFO] Tests run: 6, Failures: 0, Errors: 0, Skipped: 0
|
||||
[INFO]
|
||||
[INFO] ------------------------------------------------------------------------
|
||||
[INFO] BUILD SUCCESS
|
||||
[INFO] ------------------------------------------------------------------------
|
||||
[INFO] Total time: 23.776 s
|
||||
[INFO] Finished at: 2026-06-17T11:29:37+09:00
|
||||
[INFO] ------------------------------------------------------------------------
|
||||
TEST_EXIT=0
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
bibimbap-app |
|
||||
bibimbap-app | . ____ _ __ _ _
|
||||
bibimbap-app | /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
|
||||
bibimbap-app | ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
|
||||
bibimbap-app | \\/ ___)| |_)| | | | | || (_| | ) ) ) )
|
||||
bibimbap-app | ' |____| .__|_| |_|_| |_\__, | / / / /
|
||||
bibimbap-app | =========|_|==============|___/=/_/_/_/
|
||||
bibimbap-app |
|
||||
bibimbap-app | :: Spring Boot :: (v3.5.14-SNAPSHOT)
|
||||
bibimbap-app |
|
||||
bibimbap-app | 2026-06-17T02:27:16.907Z INFO 1 --- [bibimbap] [ main] c.p.bibimbap.BibimbapApplication : Starting BibimbapApplication using Java 21.0.11 with PID 1 (/app/app.war started by root in /app)
|
||||
bibimbap-app | 2026-06-17T02:27:16.908Z INFO 1 --- [bibimbap] [ main] c.p.bibimbap.BibimbapApplication : The following 1 profile is active: "dev"
|
||||
bibimbap-app | 2026-06-17T02:27:17.165Z DEBUG 1 --- [bibimbap] [ main] org.apache.ibatis.logging.LogFactory : Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
|
||||
bibimbap-app | 2026-06-17T02:27:17.304Z INFO 1 --- [bibimbap] [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http)
|
||||
bibimbap-app | 2026-06-17T02:27:17.310Z INFO 1 --- [bibimbap] [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
|
||||
bibimbap-app | 2026-06-17T02:27:17.310Z INFO 1 --- [bibimbap] [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.54]
|
||||
bibimbap-app | 2026-06-17T02:27:17.561Z INFO 1 --- [bibimbap] [ main] org.apache.jasper.servlet.TldScanner : At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
|
||||
bibimbap-app | 2026-06-17T02:27:17.605Z INFO 1 --- [bibimbap] [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
|
||||
bibimbap-app | 2026-06-17T02:27:17.606Z INFO 1 --- [bibimbap] [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 681 ms
|
||||
bibimbap-app | 2026-06-17T02:27:17.678Z DEBUG 1 --- [bibimbap] [ main] org.apache.ibatis.logging.LogFactory : Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
|
||||
bibimbap-app | 2026-06-17T02:27:17.744Z INFO 1 --- [bibimbap] [ main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page template: index
|
||||
bibimbap-app | 2026-06-17T02:27:17.797Z WARN 1 --- [bibimbap] [ main] o.s.w.s.resource.ResourceHandlerUtils : Appended trailing slash to static resource location: file:///app/uploads/game/profile/
|
||||
bibimbap-app | 2026-06-17T02:27:17.865Z INFO 1 --- [bibimbap] [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/'
|
||||
bibimbap-app | 2026-06-17T02:27:17.874Z INFO 1 --- [bibimbap] [ main] c.p.bibimbap.BibimbapApplication : Started BibimbapApplication in 1.157 seconds (process running for 1.4)
|
||||
bibimbap-app | 2026-06-17T02:27:18.590Z INFO 1 --- [bibimbap] [0.0-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
|
||||
bibimbap-app | 2026-06-17T02:27:18.590Z INFO 1 --- [bibimbap] [0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
|
||||
bibimbap-app | 2026-06-17T02:27:18.591Z INFO 1 --- [bibimbap] [0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms
|
||||
bibimbap-app | 2026-06-17T02:27:18.614Z INFO 1 --- [bibimbap] [0.0-8080-exec-1] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
|
||||
bibimbap-app | 2026-06-17T02:27:18.692Z INFO 1 --- [bibimbap] [0.0-8080-exec-1] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection org.postgresql.jdbc.PgConnection@7f0f07f4
|
||||
bibimbap-app | 2026-06-17T02:27:18.693Z INFO 1 --- [bibimbap] [0.0-8080-exec-1] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
|
||||
bibimbap-app bibimbap-app "java -jar /app/app.…" app 36 seconds ago Up 35 seconds 0.0.0.0:8080->8080/tcp, [::]:8080->8080/tcp
|
||||
bibimbap-db postgres:16 "docker-entrypoint.s…" db 3 minutes ago Up 3 minutes (healthy) 0.0.0.0:5433->5432/tcp, [::]:5433->5432/tcp
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
---
|
||||
phase: documentation
|
||||
agent: documentation-advisor
|
||||
agent_version: 1
|
||||
generated_at: 2026-06-17T11:08:36+09:00
|
||||
concerns:
|
||||
- "usage/index.md '목록' 에 기재된 setup-checklist.md / faq.md 의 실제 파일이 부재(링크 dangling). 본 작업 범위 밖이라 수정하지 않음 — 별도 보강 필요."
|
||||
concerns_checked: true
|
||||
---
|
||||
|
||||
# 문서화 보고
|
||||
|
||||
## 작성/수정된 문서
|
||||
|
||||
| 경로 | 카테고리 | 유형 | 링크 추가한 index | 교차 링크 |
|
||||
|---|---|---|---|---|
|
||||
| docs/usage/local-setup.md | usage | 신규 | docs/usage/index.md (목록 1줄) | analysis/2026-06-16-project-analysis.md open_question #4 → local-setup §1·§7 |
|
||||
| docs/usage/index.md | usage | 수정(링크 추가) | 자기 자신 | - |
|
||||
| docs/analysis/2026-06-16-project-analysis.md | analysis | 수정(역링크 1줄) | - | local-setup.md 로 역링크 |
|
||||
|
||||
## 의사결정 기록 위치
|
||||
|
||||
- 로컬 개발환경 온보딩(경로 A Docker / 경로 B 직접 실행, DB 스키마 초기화, 트러블슈팅) → docs/usage/local-setup.md
|
||||
- 카테고리 판별: 이식자·사용자 관점 운영 가이드 → usage/ (document-category-classification.md §usage 근거). 런타임 동작 변경(changes) 이나 불변 결정(adr) 아님.
|
||||
- 검증 근거(BUILD SUCCESS, HTTP 200, Tests 6/0, WAR 산출 등)는 orchestrator 실행 결과만 인용. 추측 미추가.
|
||||
|
||||
## 추후 문서화가 필요한 항목
|
||||
|
||||
- usage/index.md 가 참조하는 setup-checklist.md / faq.md 실제 파일 작성 또는 인덱스 정리 (현재 dangling link).
|
||||
- db/schema.sql 5개 비권위 테이블의 운영 DB pg_dump 대조 후 권위 DDL 확정 → 확정 시 maintenance/ 또는 contracts/ 에 스키마 기준 문서화 검토.
|
||||
- spring-boot SNAPSHOT 고정 vs 안정 릴리스 결정 시 → adr/ 신규 레코드.
|
||||
|
||||
## 산출 경로
|
||||
|
||||
- /Users/wemadeplay/workspace/stz/bibimbap/docs/usage/local-setup.md (신규)
|
||||
- /Users/wemadeplay/workspace/stz/bibimbap/docs/usage/index.md (목록 링크 추가)
|
||||
- /Users/wemadeplay/workspace/stz/bibimbap/docs/analysis/2026-06-16-project-analysis.md (교차 역링크 추가)
|
||||
- /Users/wemadeplay/workspace/stz/bibimbap/.atp/work-session/20260617-110836/documentation.md (본 보고)
|
||||
|
|
@ -1,250 +0,0 @@
|
|||
---
|
||||
schema_version: 2
|
||||
session_id: 20260617-110836
|
||||
resumed_from: null
|
||||
started_at: 2026-06-17T11:08:36+09:00
|
||||
ended_at: 2026-06-17T11:48:00+09:00
|
||||
user_request: |
|
||||
bibimbap 로컬 개발환경 셋업 분석 → 검증 → 온보딩 문서화.
|
||||
두 경로(A: Docker / B: 호스트 직접) 모두 실제 실행으로 검증, DDL 갭 해결,
|
||||
docs/usage/local-setup.md 산출. 추측 금지, 명령어·출력·근거 기록.
|
||||
비밀값 비커밋, src/pom 최소수정, git status 보호.
|
||||
---
|
||||
|
||||
# Summary
|
||||
|
||||
두 셋업 경로를 모두 **실제 실행으로 검증 완료**. 핵심 산출: 복원 `db/schema.sql`(6테이블), Docker 스택(compose+Dockerfile+.env.example+.dockerignore), 온보딩 문서.
|
||||
|
||||
검증 결과:
|
||||
- **Path A (Docker)**: `docker compose build` BUILD SUCCESS → `up -d` db healthy + app 기동 → 홈 `/` HTTP 200(35KB 렌더) + `/recruit` 200 + dev 스키마 6테이블 + 삽입→홈노출 라운드트립으로 DB→MyBatis→JSP 전체 동작 확정.
|
||||
- **Path B (호스트)**: brew openjdk@21 설치 → chmod +x mvnw → `./mvnw -P dev test` **6 tests 0 fail** → `package` WAR 30MB → `spring-boot:run` 홈 200(provided tomcat 동작).
|
||||
|
||||
검증 중 드러난 실제 블로커 3건(모두 해결):
|
||||
1. **TLS 인터셉션(Cloudflare Gateway CA)** 으로 SNAPSHOT 의존 PKIX 실패 — 컨테이너/호스트 JDK truststore 둘 다. `curl` 200(시스템 키체인) ≠ JDK(자체 cacerts). → Docker 는 certs/*.crt 자동 주입, 호스트는 keytool import 로 해결.
|
||||
2. **비실행 WAR** — pom 이 spring-boot-starter-parent 미사용이라 repackage goal 미바인딩 → `spring-boot:repackage` 명시로 해결.
|
||||
3. **포트 5432 충돌**(기존 kord-postgres) → .env DB_PORT=5433 회피.
|
||||
|
||||
DDL 갭: recruit_posts 만 권위 DDL. 나머지 5테이블은 매퍼+POJO 역추출 비권위 복원본(타입 추론). schema.sql 에 명시.
|
||||
|
||||
src/, pom.xml 무수정. mvnw 는 실행권한 부여(mode change)만. 비밀값(.env/db.properties/certs/*.crt) gitignore 확인.
|
||||
|
||||
# Advisor Invocation Decision Log
|
||||
- advisor: requirements-advisor
|
||||
decision: skip
|
||||
rationale: '요청이 망라적·확정적. 모호점은 사실(빌드 동작·DDL 복구)이며 실행으로만 해소.'
|
||||
checked_at: 2026-06-17T11:09:00+09:00
|
||||
- advisor: research-advisor
|
||||
decision: skip
|
||||
rationale: '조사 대상이 전부 orchestrator 직접 실행/grep 으로 검증되는 execution-bound. 외부 자료 불요.'
|
||||
checked_at: 2026-06-17T11:09:00+09:00
|
||||
- advisor: design-advisor
|
||||
decision: skip
|
||||
rationale: '인프라 설계(compose/Dockerfile/schema)가 검증 루프와 밀결합 — build→fail→fix 반복이 orchestrator 직접 수행에 적합. 옵션공간은 plan 게이트 AskUserQuestion 으로 사용자 확정.'
|
||||
checked_at: 2026-06-17T11:10:00+09:00
|
||||
- advisor: implementation-advisor
|
||||
decision: skip
|
||||
rationale: '파일 영향맵 확정적(신규 인프라 파일 6개, src 무수정). 충돌 worker 불요. orchestrator 직접 작성 + 즉시 검증.'
|
||||
checked_at: 2026-06-17T11:10:00+09:00
|
||||
- advisor: documentation-advisor
|
||||
decision: call
|
||||
rationale: '온보딩 문서는 docs 도메인 owner 책임 — 카테고리/index 링크/guidelines 준수 보장. 검증 증거 self-contained 브리프로 전달.'
|
||||
checked_at: 2026-06-17T11:40:00+09:00
|
||||
- advisor: verification-advisor
|
||||
decision: call
|
||||
rationale: '코드/인프라 변경 존재 → AC 독립 검증 의무(skip 불가). 통합 스모크 재확인.'
|
||||
checked_at: 2026-06-17T11:40:00+09:00
|
||||
|
||||
# Invocations
|
||||
- id: inv-001
|
||||
layer: orchestrator
|
||||
name: orchestrator
|
||||
parent_invocation_id: null
|
||||
input_digest: '로컬 셋업 분석/검증/문서화'
|
||||
output_digest: '정찰 + docs-first + DDL 증거 + plan 게이트 확정'
|
||||
artifacts: [.atp/work-session/20260617-110836/report.md]
|
||||
concerns: []
|
||||
- id: inv-002
|
||||
layer: orchestrator
|
||||
name: orchestrator (infra build + dual verification)
|
||||
parent_invocation_id: inv-001
|
||||
input_digest: 'schema.sql + Docker infra 작성, A/B 실행 검증'
|
||||
output_digest: 'A/B 모두 홈 200 + DB 동작. 블로커 3건 해결.'
|
||||
artifacts:
|
||||
- db/schema.sql
|
||||
- docker-compose.yml
|
||||
- Dockerfile
|
||||
- .env.example
|
||||
- .dockerignore
|
||||
- certs/README.md
|
||||
- .atp/work-session/20260617-110836/artifacts/ (build/test/run 로그, home html)
|
||||
concerns: []
|
||||
model_choice:
|
||||
phase: validation-runtime
|
||||
dispatch_size: direct
|
||||
tier: large
|
||||
effort: medium
|
||||
resolved_model: inherit
|
||||
capped: false
|
||||
capped_from: null
|
||||
escalation_reason: '런타임·DB·인프라 회귀 판정 + 미지 블로커 root-cause 탐색'
|
||||
fallback_reason: null
|
||||
rationale: 'orchestrator 직접 수행(검증 루프 밀결합). 자기 모델(opus=large) 상속.'
|
||||
- id: inv-003
|
||||
layer: advisor
|
||||
name: documentation-advisor
|
||||
parent_invocation_id: inv-001
|
||||
input_digest: '검증 증거 전량 + 7섹션 구조 브리프'
|
||||
output_digest: '(진행중)'
|
||||
artifacts: [docs/usage/local-setup.md, docs/usage/index.md, .atp/work-session/20260617-110836/documentation.md]
|
||||
concerns: []
|
||||
model_choice:
|
||||
phase: docs
|
||||
dispatch_size: s-batch
|
||||
tier: medium
|
||||
effort: low
|
||||
resolved_model: inherit
|
||||
capped: false
|
||||
capped_from: null
|
||||
escalation_reason: null
|
||||
fallback_reason: null
|
||||
rationale: '형식 위주 문서 작성. 증거는 브리프로 확정 제공 → medium 충분.'
|
||||
|
||||
# Decisions
|
||||
- by: user
|
||||
at: 2026-06-17T11:12:00+09:00
|
||||
decision: 'DDL=전체 schema.sql 복원, Path B=Docker 후 Java 설치까지 진행, 인프라=루트 신규 생성'
|
||||
rationale: 'plan 게이트 AskUserQuestion 3문항 응답'
|
||||
related_invocations: [inv-001]
|
||||
- by: orchestrator
|
||||
at: 2026-06-17T11:20:00+09:00
|
||||
decision: 'TLS 인터셉션 CA 를 빌드 truststore 에 주입(검증 유지) — TLS 무시(insecure) 대신'
|
||||
rationale: '보안 검증 끄지 않고 회사 프록시 환경 대응. 환경특화 CA 는 gitignore.'
|
||||
related_invocations: [inv-002]
|
||||
|
||||
# Conflicts
|
||||
|
||||
# Open Items
|
||||
- db/schema.sql 의 5개 비권위 테이블 타입은 운영 DB pg_dump 대조 필요(미해결).
|
||||
- spring-boot 3.5.14-SNAPSHOT 고정 결정 대기(analysis open_question #4).
|
||||
- 미커밋 잔여(이번 작업 단위): .gitignore(M), mvnw(mode), .dockerignore/.env.example/Dockerfile/docker-compose.yml/db//certs/ (untracked), docs(작성중) → 종료 전 커밋 예정.
|
||||
- 사용자 기존 변경(작업 무관, 보존): .serena/project.yml(M), .serena/memories/serena_tooling.md(??), .atp/work-session/20260617-094450/(??) → 커밋 범위 제외.
|
||||
|
||||
# Regression
|
||||
- surfaced_at_stage: verification (docker build / host test)
|
||||
source_stage: implementation (Dockerfile run 명령 / 환경 가정)
|
||||
defect: 'SNAPSHOT PKIX 실패(TLS 인터셉션) + 비실행 WAR(repackage 미바인딩)'
|
||||
full_set_recheck: false
|
||||
downstream_rerun: [implementation(Dockerfile 수정), verification(재빌드/재실행)]
|
||||
resolved_at: 2026-06-17T11:31:00+09:00
|
||||
|
||||
# User Signals
|
||||
user_signals:
|
||||
positive:
|
||||
- quote_or_paraphrase: '직접 java 설치까지 진행해 시간 더 써도 상관없[다]'
|
||||
about: 'Path B 완전 검증을 위한 추가 시간/설치 허용 — 철저한 실행검증 선호'
|
||||
negative: []
|
||||
|
||||
# Retrospective
|
||||
Retrospective:
|
||||
signals:
|
||||
positive:
|
||||
- quote_or_paraphrase: '직접 java 설치까지 진행해 시간 더 써도 상관없다'
|
||||
about: 'plan 게이트 AskUserQuestion 응답 — Path B 를 .env.example/문서 추측이 아니라 실제 brew 설치 + mvnw test + spring-boot:run 까지 끝까지 실행검증하는 경로를 사용자가 명시 승인. 추가 시간 비용을 감수하더라도 "실행으로만 확정" 원칙을 사용자가 지지.'
|
||||
- quote_or_paraphrase: '(plan 게이트 3문항을 한 번에 확정) DDL=전체 schema.sql 복원 / Path B=Java 설치까지 / 인프라=루트 신규'
|
||||
about: 'orchestrator 가 비자명한 분기(부분 복원 vs 전체, Docker only vs 호스트까지, 루트 vs 하위디렉토리)를 추측하지 않고 단일 AskUserQuestion 으로 묶어 제시 → 재질의 없이 한 번에 수락. 분기 비용을 사용자에게 압축 전달한 판단이 검증됨.'
|
||||
negative: []
|
||||
what_went_well:
|
||||
- 'plan 게이트로 비자명한 3개 분기를 한 번에 확정받아 재작업 없이 직진 (positive 시그널). advisor 5개 중 4개 skip 결정의 rationale 이 "execution-bound — 외부조사/설계옵션 불요"로 명확했고 실제 검증으로 맞아떨어짐.'
|
||||
- '"실행으로만 확정" 원칙 관철: curl/HTTP 200, Tests 6/0, compose ps healthy, DB→MyBatis→JSP 삽입 라운드트립까지 추측 없이 산 증거로 기록. verification-advisor 가 AC 10건을 독립 재실행해 전 PASS.'
|
||||
- '미지 블로커 3건을 우회(insecure TLS)가 아닌 근본 해결(CA 를 truststore 에 주입해 검증 유지)로 처리. 보안 검증을 끄지 않으면서 회사 프록시 대응 — Decision 로그에 근거 남김.'
|
||||
- 'src/pom.xml 무수정 제약 준수(mvnw mode change 만), 비밀값(.env/db.properties/certs) gitignore 를 verification AC-4 에서 전수 확인. 사용자 기존 변경(.serena/*)을 커밋 범위에서 명시 제외해 사용자 변경 보호 원칙 지킴.'
|
||||
- 'DDL 갭을 "복원했다"로 뭉뚱그리지 않고 recruit_posts(권위) vs 5테이블(매퍼+POJO 역추출 비권위, 타입 추론)로 구분해 schema.sql 과 문서 §4·§7 에 명시. 신뢰 경계를 산출물에 박아 다운스트림 오신뢰 차단.'
|
||||
what_to_improve:
|
||||
- 'verification-strategies.md 가 placeholder 템플릿 상태 — 등록된 실행 전략 0개라 verification-advisor 가 orchestrator 전달 AC 를 직접 실행하는 방식으로 우회. 통합 검증 스크립트(make verify 류)와 전략 레지스트리가 비어 매 세션 AC 를 수기 전달해야 함 (구조적, observation).'
|
||||
- 'docs/usage/index.md 가 참조하는 setup-checklist.md / faq.md 가 dangling link (실제 파일 부재). documentation-advisor 가 concern 으로 보고했으나 범위 밖이라 미수정 — 인덱스 무결성 보강 필요.'
|
||||
- 'TLS 인터셉션 / repackage 미바인딩 / 포트충돌 3건이 implementation 단계 가정(Dockerfile run 명령·환경 전제)에서 비롯돼 verification 단계에서야 표면화. full_set_recheck=false 로 국소 회복했으나, "온라인 SNAPSHOT + 회사 프록시 + parent 미사용 pom" 환경 전제를 implementation 진입 전 체크리스트로 선점검했다면 회귀 비용 절감 가능.'
|
||||
memory_candidates:
|
||||
- name: jdk-cacerts-separate-from-system-keychain
|
||||
type: feedback
|
||||
description: 'curl 200 ≠ JDK 신뢰. 회사 TLS 인터셉션 프록시 환경에서 JDK 빌드(Maven SNAPSHOT 등) PKIX 실패는 시스템 키체인이 아닌 JDK 자체 cacerts 에 프록시 CA 를 별도 import 해야 해결된다.'
|
||||
body_draft: |
|
||||
회사 TLS 인터셉션 프록시(예: Cloudflare Gateway/Zero Trust)가 `repo.spring.io` 등의 인증서를 재서명하면, JDK 기반 빌드(Maven 의존성 수신, SNAPSHOT POM import)가 `PKIX path building failed: unable to find valid certification path to requested target` 로 실패한다. 핵심: **`curl` 이 200 을 반환해도 JDK 는 신뢰하지 않는다** — curl 은 시스템 키체인을, JDK 는 자체 `cacerts` truststore 를 쓰기 때문이다.
|
||||
|
||||
**Why:** 세션 20260617-110836 (bibimbap 로컬셋업)에서 Docker/호스트 양쪽 JDK 빌드가 PKIX 로 실패. curl 은 통과해 한때 네트워크 정상으로 오판할 뻔함. 해결은 TLS 무시(insecure)가 아니라 CA 주입으로 검증을 유지.
|
||||
|
||||
**How to apply:**
|
||||
- 증상이 PKIX / `unable to find valid certification path` 면 먼저 "JDK truststore 에 프록시 CA 가 없다"를 의심. curl 성공을 근거로 네트워크 정상이라 결론짓지 말 것.
|
||||
- 호스트: `keytool -importcert -trustcacerts -cacerts -storepass changeit -alias proxy -file <ca>.crt`.
|
||||
- Docker: 빌드 스테이지에서 `<ca>.crt` 를 이미지 truststore 에 주입.
|
||||
- CA 추출(macOS): `security find-certificate -a -c "<CA 이름>" -p <keychain> > ca.crt`.
|
||||
- 환경특화 CA(`certs/*.crt`)는 gitignore. insecure(TLS 검증 off)로 우회 금지.
|
||||
- 형제 사례(다른 런타임 같은 원인): loa 프로젝트 `feedback_node22_use_system_ca_for_live_api_tests` (Node 22 는 `NODE_OPTIONS=--use-system-ca`). 런타임마다 truststore 가 시스템 키체인과 분리돼 있다는 같은 교훈의 변종.
|
||||
rationale_for_saving: '회사 macOS 개발 환경 전반에 재발하는 환경 제약(여러 프로젝트에서 이미 변종 발생). 코드/커밋으로 유도 불가, 관찰로만 드러남. bibimbap 메모리에 미존재.'
|
||||
signal_source: observation
|
||||
docs_sync_target: /Users/wemadeplay/workspace/stz/bibimbap/docs/usage/local-setup.md # 이미 §6 트러블슈팅에 반영됨 — MEMORY 는 환경 일반화 보존용
|
||||
- name: pom-without-starter-parent-needs-explicit-repackage
|
||||
type: feedback
|
||||
description: 'spring-boot-starter-parent 미사용(dependencyManagement import 만) pom 은 spring-boot:repackage 가 package 단계에 자동 바인딩되지 않는다. 명시 호출 안 하면 비실행 WAR(no main manifest attribute).'
|
||||
body_draft: |
|
||||
Spring Boot 프로젝트가 `spring-boot-starter-parent` 를 부모로 쓰지 않고 `spring-boot-dependencies` 를 dependencyManagement 로 import 만 하는 경우, 두 가지가 자동으로 동작하지 않는다:
|
||||
- (a) `application.properties` 의 `@app.profile@` 같은 리소스 필터링 — profile 미지정 시 `spring.profiles.active` 가 깨진다.
|
||||
- (b) `spring-boot:repackage` goal 이 `package` 단계에 자동 바인딩되지 않는다 → 명시 호출 없이는 비실행 WAR 가 나와 `no main manifest attribute` 로 기동 실패.
|
||||
|
||||
**Why:** 세션 20260617-110836 에서 `mvnw package` 산출 WAR 가 실행되지 않아 블로커. parent 미사용이 원인. `./mvnw -P dev clean package spring-boot:repackage` 로 해결.
|
||||
|
||||
**How to apply:**
|
||||
- pom 에 `<parent>spring-boot-starter-parent</parent>` 가 없고 import-only 라면, 빌드/실행 명령에 `-P dev`(또는 해당 profile) + `spring-boot:repackage` 를 명시.
|
||||
- "no main manifest attribute" / profile 미적용 증상 보면 parent 미사용 pom 을 의심.
|
||||
rationale_for_saving: 'bibimbap pom 의 영속적 구조 특성(parent 미사용)에서 비롯 — 빌드 명령을 잘못 쓰면 반복 재발. 빌드 레시피 자체는 문서화됐지만 "왜 이 명령이어야 하는가"의 진단 단서는 관찰 지식.'
|
||||
signal_source: observation
|
||||
docs_sync_target: /Users/wemadeplay/workspace/stz/bibimbap/docs/usage/local-setup.md # §3 주의·§6 에 반영됨
|
||||
- name: restored-ddl-mark-non-authoritative-types
|
||||
type: feedback
|
||||
description: '권위 DDL 부재로 매퍼+POJO 역추출로 스키마를 복원할 때, 컬럼 유무/이름은 검증해도 타입·길이·제약은 추론값이므로 산출물(schema.sql/문서)에 비권위 경계를 명시하고 pg_dump 대조를 open item 으로 남긴다.'
|
||||
body_draft: |
|
||||
flyway/liquibase 가 없고 전체 DDL 도 없는 프로젝트에서 스키마 SQL 을 복원할 때, 매퍼 `@Insert`/`@Select` 컬럼과 data POJO Java 타입에서 역추출한 부분은 **비권위**다. 컬럼명·유무는 매퍼와 대조해 확정할 수 있어도, SQL 타입·길이·NULL/제약은 추론값이라 운영 DB 와 다를 수 있다.
|
||||
|
||||
**Why:** 세션 20260617-110836 에서 6테이블 중 recruit_posts 만 권위 DDL. 나머지 5테이블은 역추출 복원. "복원 완료"로 뭉뚱그리면 다운스트림이 타입을 신뢰해 마이그레이션/기능 스모크에서 데이터 무결성 사고로 번질 수 있음.
|
||||
|
||||
**How to apply:**
|
||||
- 복원 SQL 에 테이블별로 권위/비권위 출처 주석을 박는다.
|
||||
- 문서에 신뢰 경계(타입 추론값, pg_dump 대조 전 신뢰 금지)와 영향(기능 스모크 보류 사유)을 명시.
|
||||
- 운영 DB `pg_dump` 대조를 open item 으로 인계.
|
||||
rationale_for_saving: '갭 복원 작업의 재현성 있는 규율(출처 등급 명시) — 일회성이 아니라 권위 DDL 부재 상황에서 반복 적용. signal_source positive(분기 확정 시 사용자가 전체복원을 승인) + observation 결합.'
|
||||
signal_source: observation
|
||||
docs_sync_target: /Users/wemadeplay/workspace/stz/bibimbap/docs/usage/local-setup.md # §4·§7 에 반영됨. 운영 DB 권위 DDL 확정 시 contracts/ 또는 ADR 검토.
|
||||
protocol_feedback:
|
||||
- 'verification-strategies.md 가 placeholder 템플릿이면 verification-advisor 가 매번 orchestrator 전달 AC 를 수기 실행하게 됨. 인프라/온보딩 셋업 검증을 1회성으로 끝내지 말고, 통과한 AC 묶음(compose ps healthy / curl 200 / mvnw test green / check-ignore 비밀값)을 재사용 가능한 전략으로 verification-strategies.md 에 즉시 등록하는 단계를 검증 PASS 직후 권고로 추가하면, "검증 자산이 휘발"되는 패턴을 막을 수 있음 (구조적).'
|
||||
- 'implementation 진입 전 "환경 전제 체크리스트"(예: 온라인 의존성 여부 / 회사 TLS 프록시 / 빌드툴 parent 사용 여부 / 포트 점유)를 advisor decision 게이트와 별도로 점검하는 경량 단계가 있으면, 이번처럼 verification 에서야 표면화되는 환경발 회귀 3건을 implementation 단계에서 선점할 수 있음.'
|
||||
applied_changes: []
|
||||
|
||||
# Session Close
|
||||
|
||||
## verified_by_me
|
||||
- L1: compile(BUILD SUCCESS, Docker+호스트) / unit+regression — `./mvnw -P dev test` Tests run 6, Failures 0, Errors 0.
|
||||
- L2: contract — skipped (외부 API 계약 변경 아님).
|
||||
- L3: 수동 스모크 — compose 런타임 홈 200 + /recruit 200 + dev 6테이블 + 삽입→홈노출 라운드트립(A,B 양쪽).
|
||||
- 로그 스캔: clean (앱 로그 SQLException/ERROR 0; JDK21 Mockito self-attach 경고는 테스트 결과 무관).
|
||||
- 비밀값 비커밋: verification AC-4 전수 PASS (.env/db.properties/certs/*.crt 모두 gitignore).
|
||||
- AC 독립 검증(verification-advisor): 5/5 PASS.
|
||||
|
||||
## needs_user_verification
|
||||
- 실제 사용자 환경 기능 스모크(회원가입/로그인/게임 zip 업로드/모집글 작성)는 미수행 — db/schema.sql 5테이블이 비권위 타입이라 권장.
|
||||
- 운영 DB pg_dump 와 db/schema.sql 대조(타입 확정).
|
||||
- (선택) Docker 스택 현재 가동 중(db:5433, app:8080). 정리: `docker compose down` (볼륨까지 `-v`).
|
||||
|
||||
## graph_refresh
|
||||
- partial-stale → docs scope 재생성 완료(`/graphify docs/`, 92 노드/122 엣지/10 커뮤니티). docs/graph/docs/ 본체(gitignore) + docs/graph/index.md 메타 갱신(docs 행 8c41b22). src scope 는 이번 세션 변경 0건 — PR#1 발 별건 pre-stale 는 범위 밖.
|
||||
|
||||
## project_gate
|
||||
- skip: no-project-gate — verification-strategies.md 가 미작성 템플릿(등록 전략 0). 추가 런타임/배포 게이트 정의 없음. L1/L2/L3 로 갈음.
|
||||
|
||||
## applied_changes
|
||||
- MEMORY: `.serena/memories/local-dev-setup-gotchas.md` 신규(retro 3 candidate 수용 — JDK cacerts/repackage/비권위 DDL). docs_sync_target(local-setup.md)은 이미 트러블슈팅에 반영됨.
|
||||
|
||||
## protocol_feedback (retro 권고 — 본 세션 미적용, 이월)
|
||||
- verification-strategies.md 에 통과 AC 를 재사용 전략으로 등록하는 단계 권고(구조적). 본 세션은 프로젝트 자산 범위 밖이라 미적용.
|
||||
- implementation 진입 전 "환경 전제 체크리스트"(온라인 의존/TLS 프록시/parent 사용/포트 점유) 권고.
|
||||
|
||||
## commit
|
||||
- pending: 사용자 승인 대기(main 브랜치 — 커밋 시 브랜치 분리 권장). 작업 단위 파일만 커밋, 사용자 기존 변경(.serena/*, 20260617-094450) 제외.
|
||||
|
|
@ -1,121 +0,0 @@
|
|||
---
|
||||
phase: verification
|
||||
agent: verification-advisor
|
||||
agent_version: 1
|
||||
generated_at: 2026-06-17T11:36:30+09:00
|
||||
concerns:
|
||||
- "verification-strategies.md 는 미작성 템플릿(placeholder cmd) 상태 — 통합 검증 스크립트(make verify 등) 미정의. 본 검증은 orchestrator 가 전달한 AC 명령을 직접 실행하는 방식으로 수행함."
|
||||
concerns_checked: true
|
||||
---
|
||||
|
||||
# 검증 결과
|
||||
|
||||
## Acceptance Criteria (입력 받은 그대로 인용)
|
||||
|
||||
### AC-1 (Path A 기동)
|
||||
`docker compose ps` 출력에 db `healthy`, app `Up` 이고, `curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/` == `200`. `/recruit` 도 200.
|
||||
|
||||
### AC-2 (DB 스키마+연결)
|
||||
`docker compose exec -T db psql -U bibimbap -d bibimbap -c "SELECT count(*) FROM information_schema.tables WHERE table_schema='dev';"` == 6.
|
||||
`docker compose exec -T db psql -U bibimbap -d bibimbap -c "SET search_path TO dev; SELECT count(*) FROM games;"` 가 SQL 에러 없이 정수 반환(0 허용).
|
||||
|
||||
### AC-3 (Path B 테스트 green)
|
||||
`JAVA_HOME=/opt/homebrew/opt/openjdk@21 ./mvnw -B -P dev test` → `BUILD SUCCESS` + `Tests run: N, Failures: 0, Errors: 0` (N>=6).
|
||||
|
||||
### AC-4 (비밀값 비커밋 — 집합 전수)
|
||||
`git status --porcelain` 에 `.env`, `src/main/resources/*/db.properties`, `certs/*.crt` 중 어느 것도 없어야 함. `git check-ignore .env src/main/resources/dev/db.properties certs/corporate-proxy-ca.crt` 3개 모두 ignored.
|
||||
|
||||
### AC-5 (문서 산출+링크)
|
||||
`docs/usage/local-setup.md` 존재 + `^## [1-7]\.` 헤딩 7개. `docs/usage/index.md` 에 `local-setup` 링크 1줄 존재.
|
||||
|
||||
## 실행된 전략
|
||||
|
||||
> 레지스트리(`verification-strategies.md`) 는 미작성 템플릿(placeholder) 상태로 실행 가능한 등록 전략이 0개였다.
|
||||
> 통합 검증 스크립트 미정의 → orchestrator 전달 AC 명령을 직접 실행하는 "집합 전수 + 라이브 스모크" 방식으로 검증.
|
||||
|
||||
| id | cmd | exit | severity | 결과 |
|
||||
|---|---|---|---|---|
|
||||
| ac1-compose-ps | `docker compose ps` | 0 | blocker | pass (db healthy / app Up) |
|
||||
| ac1-curl-root | `curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/` | 0 | blocker | pass (200) |
|
||||
| ac1-curl-recruit | `curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/recruit` | 0 | blocker | pass (200) |
|
||||
| ac2-tables | `docker compose exec -T db psql -U bibimbap -d bibimbap -c "SELECT count(*) FROM information_schema.tables WHERE table_schema='dev';"` | 0 | blocker | pass (count=6) |
|
||||
| ac2-games | `docker compose exec -T db psql ... "SET search_path TO dev; SELECT count(*) FROM games;"` | 0 | blocker | pass (count=0, SQL 에러 없음) |
|
||||
| ac3-mvn-test | `JAVA_HOME=/opt/homebrew/opt/openjdk@21 ./mvnw -B -P dev test` | 0 | blocker | pass (BUILD SUCCESS, 6 tests) |
|
||||
| ac4-porcelain | `git status --porcelain \| grep -E '\.env$\|db\.properties\|certs/.*\.crt'` | 1(no match) | blocker | pass (비밀값 0건 노출) |
|
||||
| ac4-check-ignore | `git check-ignore .env src/main/resources/dev/db.properties certs/corporate-proxy-ca.crt` | 0 | blocker | pass (3/3 ignored) |
|
||||
| ac5-doc-headings | `grep -cE '^## [1-7]\.' docs/usage/local-setup.md` | 0 | blocker | pass (7개) |
|
||||
| ac5-index-link | `grep -nc 'local-setup' docs/usage/index.md` | 0 | blocker | pass (1줄) |
|
||||
|
||||
(검증 사다리 분해)
|
||||
|
||||
| 단계 | 결과 |
|
||||
|---|---|
|
||||
| L1 typecheck (compile) | pass (mvn compile/testCompile 단계 통과, Nothing to compile - up to date) |
|
||||
| L1 unit+regression | pass (Tests run: 6, Failures: 0, Errors: 0, Skipped: 0) |
|
||||
| L2 contract-* | skipped: 본 변경은 외부 API 계약 변경 아님(인프라 셋업 + 문서). 등록된 live-contract 전략 없음. |
|
||||
| L3 수동 스모크 (compose 런타임) | pass (app Up, HTTP 200 on / 및 /recruit, db healthy, dev 스키마 6 테이블 쿼리 성공) |
|
||||
| 로그 스캔 | clean (mvn 출력에 FAIL/ERROR 없음. Mockito self-attach / Java agent 경고는 JDK21 환경 경고로 테스트 결과 무관) |
|
||||
|
||||
## 실패 상세
|
||||
해당 없음 (전 AC pass).
|
||||
|
||||
## 종합 판정
|
||||
overall: pass
|
||||
rollback_signal: none
|
||||
|
||||
## Acceptance 매칭
|
||||
|
||||
| criterion | 매칭 전략 | 판정 |
|
||||
|---|---|---|
|
||||
| AC-1 db healthy / app Up | ac1-compose-ps | PASS |
|
||||
| AC-1 curl / == 200 | ac1-curl-root | PASS |
|
||||
| AC-1 curl /recruit == 200 | ac1-curl-recruit | PASS |
|
||||
| AC-2 dev schema tables == 6 | ac2-tables | PASS |
|
||||
| AC-2 games count 정수(에러無) | ac2-games | PASS |
|
||||
| AC-3 BUILD SUCCESS, N>=6, 0 fail/err | ac3-mvn-test | PASS |
|
||||
| AC-4 porcelain 비밀값 0건 | ac4-porcelain | PASS |
|
||||
| AC-4 check-ignore 3/3 | ac4-check-ignore | PASS |
|
||||
| AC-5 local-setup.md 헤딩 7개 | ac5-doc-headings | PASS |
|
||||
| AC-5 index.md local-setup 링크 1줄 | ac5-index-link | PASS |
|
||||
|
||||
## 근거 출력 인용
|
||||
|
||||
### AC-1
|
||||
```
|
||||
NAME STATUS PORTS
|
||||
bibimbap-app Up 4 minutes 0.0.0.0:8080->8080/tcp
|
||||
bibimbap-db Up 11 minutes (healthy) 0.0.0.0:5433->5432/tcp
|
||||
curl / -> 200
|
||||
curl /recruit -> 200
|
||||
```
|
||||
|
||||
### AC-2
|
||||
```
|
||||
table_schema='dev' count -> 6
|
||||
SET; SELECT count(*) FROM games -> 0 (psql exit=0, SQL 에러 없음)
|
||||
```
|
||||
|
||||
### AC-3
|
||||
```
|
||||
Tests run: 6, Failures: 0, Errors: 0, Skipped: 0
|
||||
BUILD SUCCESS (Total time: 2.281 s, Java 21.0.11)
|
||||
```
|
||||
|
||||
### AC-4
|
||||
```
|
||||
porcelain grep secrets -> (no match, grep exit=1)
|
||||
check-ignore ->
|
||||
.env
|
||||
src/main/resources/dev/db.properties
|
||||
certs/corporate-proxy-ca.crt
|
||||
(check-ignore exit=0, 3/3 ignored)
|
||||
```
|
||||
|
||||
### AC-5
|
||||
```
|
||||
docs/usage/local-setup.md 존재 (10650 bytes)
|
||||
grep -cE '^## [1-7]\.' -> 7
|
||||
1. 사전 요구사항 / 2. 경로 A: Docker / 3. 경로 B: 직접 실행 /
|
||||
4. DB 스키마 초기화 절차 / 5. 검증 체크리스트 / 6. 트러블슈팅 / 7. 알려진 미해결
|
||||
docs/usage/index.md local-setup 링크 -> 1줄 (line 16)
|
||||
```
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
---
|
||||
schema_version: 1
|
||||
sid: 20260617-143315
|
||||
user_request: "바이너리 직접 실행(./mvnw -P dev spring-boot:run) 시 DB 연결 문제"
|
||||
started_at: 2026-06-17T14:33:15+09:00
|
||||
ended_at: 2026-06-17T14:34:00+09:00
|
||||
status: resolved
|
||||
code_change_lines: 0
|
||||
---
|
||||
|
||||
# Summary
|
||||
호스트 직접 실행(경로 B) DB 연결 실패 진단. 근본 원인: bibimbap-db postgres 컨테이너 미기동 → localhost:5433 connection refused. db 컨테이너 기동으로 해소.
|
||||
|
||||
# Advisor Invocation Decision Log
|
||||
- advisor: ALL
|
||||
decision: skip
|
||||
rationale: '런타임 환경 진단 + 0줄 코드변경 마이크로 작업. 원인=컨테이너 미기동(설정 정상). orchestrator 직접 처리(§1 예외).'
|
||||
checked_at: 2026-06-17T14:33:20+09:00
|
||||
|
||||
# Decisions
|
||||
- 근본원인: docker-compose db 서비스(bibimbap-db) 미생성/미기동. db.properties(localhost:5433), .env(DB_PORT=5433) 는 정상.
|
||||
- kord-postgres(host 5432) 는 무관 — bibimbap 은 5433 사용.
|
||||
- 조치: `docker compose up -d db` (가역적 로컬 액션, §6 파괴게이트 비해당).
|
||||
|
||||
# verified_by_me
|
||||
- L1: n/a (코드변경 0)
|
||||
- 런타임: bibimbap-db Up(healthy), host 5433 LISTEN, dev 스키마 6테이블 자동주입(schema.sql), psql CONNECT_OK(dev.games 0행 무에러).
|
||||
|
||||
# needs_user_verification
|
||||
- `./mvnw -P dev spring-boot:run` 재실행 → Tomcat 8080 + 홈 / HTTP 200 1회 확인(앱→DB 라운드트립).
|
||||
|
||||
# graph_refresh
|
||||
skip: no-scope-change (코드 변경 0줄)
|
||||
|
||||
# open_items
|
||||
- (없음) — 미커밋 잔여는 본 세션 산출 아님(.serena/*, 이전 work-session dir).
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
---
|
||||
title: 게임잼 플랫폼 고도화 — 세션 로드맵
|
||||
status: draft (사용자 확정 대기)
|
||||
created_at: 2026-06-17
|
||||
session: 20260617-150635
|
||||
---
|
||||
|
||||
# 게임잼 플랫폼 고도화 — 세션별 로드맵
|
||||
|
||||
기존 bibimbap(게임 공유 + 팀원 모집, Spring Boot + MyBatis + JSP) 위에 **게임잼 운영/평가/리뷰/관리자/포스팅/검색** 신규 기능군을 얹는다. 메모를 "1항목=1세션"으로 쪼개면 공유 자원(게임잼 엔티티·RBAC·평가 데이터모델)에서 재작업이 폭증하므로(§2.7), **토대 → 결합 클러스터 → 표면 기능** 순으로 의존 순서를 강제한다.
|
||||
|
||||
## 의존 그래프
|
||||
|
||||
```
|
||||
S1 RBAC(권한) ─┬─> S2 게임잼 엔티티 ─┬─> S3 태그+검색
|
||||
│ ├─> S4D 평가 통합설계(스키마 동결)
|
||||
│ │ └─> S4a 댓글/리뷰분리 ─┬─> S4b 심사위원
|
||||
│ │ ├─> S4c 인기투표
|
||||
│ │ └─(4a·4b·4c)─> S4d 시상집계
|
||||
│ └─> S6 메인 통합(노출 대상 필요)
|
||||
└─> S5 포스팅 보드 (S4와 독립, S1 후 병렬 가능)
|
||||
└─> S6 메인 통합
|
||||
|
||||
차후: S7 Unity 빌드 업로드 파이프라인 (별도 조사)
|
||||
운영: Discord/뒤끝/상금 (코드 외 — 표시 필드만 S2 흡수)
|
||||
```
|
||||
|
||||
- **크리티컬 패스**: S1 → S2 → S4D → S4a → S4d → S6
|
||||
- **S1 직후 병렬 가능**: S5(포스팅)
|
||||
- **S2 직후 병렬 가능**: S3(태그)
|
||||
- **S4 분할 원칙**: S4D(통합설계) 가 평가/리뷰/투표/댓글/시상 **스키마를 한 번에 동결**. 이후 S4a~S4d 는 동결된 계약을 소비만 한다 — 구현 세션이 스키마를 바꾸면 형제 세션 재작업이므로, 스키마 변경은 S4D 로 회귀해 처리.
|
||||
|
||||
## 세션 카드
|
||||
|
||||
### S1 — 권한 체계(RBAC) 기반 ★최우선 토대
|
||||
- **목표**: 사이트 관리권한 모델 + 기능별 인증유저 플래그 스캐폴드.
|
||||
- **포함**: 관리자(전체)/부관리자(허용 권한만 = 권한부여형) 모델, 관리자 콘솔(부관리자 임명 + 권한 토글), 인증유저 플래그 정의·부여(리뷰어/포스터/심사위원/기술자), 권한 체크 인터셉터.
|
||||
- **제외**: 각 권한의 실제 사용처(후속 세션이 소비).
|
||||
- **의존**: 없음.
|
||||
- **공유 자원**: `users`, `security/`, 세션/인증.
|
||||
- **권장 진입**: requirements-advisor(권한 모델 정밀화) → design → implementation.
|
||||
- **산출**: 권한 스키마 마이그레이션, 관리자 콘솔, 권한 인터셉터.
|
||||
|
||||
### S2 — 게임잼 엔티티 + 라이프사이클 ★토대
|
||||
- **목표**: 게임잼 이벤트 엔티티 + 상태전이 + 관리 + 출품작 연결.
|
||||
- **포함**: `jams` 테이블, 상태전이(모집→개발→평가→종료), 개발기간/평가기간 필드, 관리자 게임잼 CRUD, 출품작 = `games`에 잼 연결(개인·팀 모두), 게임잼 목록/상세 페이지, (운영 표시) Discord 링크·상금·후원사 필드.
|
||||
- **제외**: 평가/투표/리뷰(S4), 검색(S3).
|
||||
- **의존**: S1(게임잼 생성 권한).
|
||||
- **공유 자원**: `games`, `recruit_posts`(팀 연결), 상태전이.
|
||||
- **산출**: `jams` 스키마, 게임잼 페이지, 라이프사이클 상태머신.
|
||||
|
||||
### S3 — 태그 + 검색
|
||||
- **목표**: 게임잼+게임 공통 태그, 게임잼 태그 검색.
|
||||
- **포함**: 공유 `tags` + 조인테이블(game/jam), 게임잼 태그 검색 UI/쿼리.
|
||||
- **의존**: S2.
|
||||
- **산출**: 태그 스키마, 검색 UI.
|
||||
|
||||
### S4 — 평가·리뷰·투표 통합 ⚠️결합 클러스터 → 분할 세션화
|
||||
> §2.7 주의: 댓글/리뷰/심사/투표/시상이 같은 데이터 도메인 + 평가기간 게이트를 공유. **S4D 가 스키마를 한 번에 동결**하고, S4a~S4d 는 그 계약을 소비만 한다. 스키마 변경 필요 시 S4D 로 회귀(형제 세션 재작업 방지).
|
||||
|
||||
#### S4D — 평가 통합설계 (설계 전용 세션, 코드 0)
|
||||
- **목표**: 리뷰/댓글/심사/투표/시상 데이터모델 + 계약 + 평가기간 게이트를 한 번에 확정·동결.
|
||||
- **포함**: `reviews`(게시물당 1회, 완성도+종합 평점), `game_comments` 200자 제약, 심사 점수 스키마, 잼 투표 스키마, 3트랙 집계 규칙, 상태/기간 게이트 계약.
|
||||
- **의존**: S1, S2.
|
||||
- **권장 진입**: design-advisor.
|
||||
- **산출**: design.md + DB 스키마(동결) + contracts.
|
||||
|
||||
#### S4a — 댓글/리뷰 분리 (구현)
|
||||
- **목표**: `game_comments` 200자 제한 + 리뷰(신규, 게시물당 1회, 완성도+종합 평점) 분리.
|
||||
- **의존**: S4D.
|
||||
|
||||
#### S4b — 심사위원 평가
|
||||
- **목표**: 심사위원 권한자 점수 입력 → 심사위원 대상.
|
||||
- **의존**: S4D, S4a, S1(심사위원 권한).
|
||||
|
||||
#### S4c — 인기투표
|
||||
- **목표**: 잼 전용 1인 1표(평가기간 한정) → 인기 대상.
|
||||
- **의존**: S4D.
|
||||
|
||||
#### S4d — 시상 집계/결과
|
||||
- **목표**: 3트랙(심사/유저평점/인기) 산정 + 수상 표시.
|
||||
- **의존**: S4a·S4b·S4c 산출.
|
||||
|
||||
### S5 — 정보성/홍보성 포스팅 보드 (S1 후 병렬 가능)
|
||||
- **목표**: 운영진 전용 공지·블로그 + 외부링크 큐레이션. 유저 작성 차단.
|
||||
- **포함**: `posts` 테이블, 포스터 권한자 작성, 카테고리(유니티블로그/세션/후기인터뷰/뒤끝 개발팀), 외부링크 타입, 유저작성 차단.
|
||||
- **의존**: S1(포스터 권한). S4와 독립.
|
||||
- **산출**: `posts` 스키마, 포스터 작성 UI.
|
||||
|
||||
### S6 — 메인페이지 통합 (거의 마지막)
|
||||
- **목표**: `index.jsp` 에 게임잼+게임+포스팅 통합 노출.
|
||||
- **의존**: S2, S5(노출 대상 존재).
|
||||
- **산출**: index 확장.
|
||||
|
||||
### S7 — (차후) Unity 빌드 업로드 파이프라인 ⏸deferred
|
||||
- **목표**: WebGL 빌드 업로드 → 검증 → `/game/{uuid}/` 배치 자동화.
|
||||
- **선행**: 별도 조사(빌드 포맷/검증 규칙/보안 — zip-slip 등).
|
||||
- **현재**: 스코프 인지만, 후속 결정.
|
||||
|
||||
## 운영(코드 외)
|
||||
- **Discord**: 공지·진행은 수동 운영. 코드는 게임잼 상세에 초대 링크 표시 정도(S2 흡수).
|
||||
- **뒤끝(Bekend)**: 파트너/콘텐츠 — 포스팅 카테고리로만 등장.
|
||||
- **상금·후원**(치킨/10만원/편의점 5000원권): 게임잼 상세 표시 필드(S2) + 실제 지급은 수동.
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
---
|
||||
phase: documentation
|
||||
agent: documentation-advisor
|
||||
agent_version: 1
|
||||
generated_at: 2026-06-17T15:30:00+09:00
|
||||
concerns: []
|
||||
concerns_checked: true
|
||||
---
|
||||
|
||||
# 문서화 보고
|
||||
|
||||
## 작성/수정된 문서
|
||||
|
||||
| 경로 | 카테고리 | 유형 | 링크 추가한 index | 교차 링크 |
|
||||
|---|---|---|---|---|
|
||||
| `docs/work-log/2026-06-17-jam-platform-roadmap.md` | work-log | 신규 생성 | `docs/work-log/index.md` | `docs/analysis/2026-06-16-project-analysis.md` 하단 관련 링크 섹션 |
|
||||
| `docs/work-log/index.md` | work-log | 기존 갱신 | — | — |
|
||||
| `docs/analysis/2026-06-16-project-analysis.md` | analysis | 기존 갱신 (교차 링크 추가) | — | — |
|
||||
|
||||
## 카테고리 판정 근거
|
||||
|
||||
**선택: `work-log/`**
|
||||
|
||||
`document-category-classification.md` 분류 기준:
|
||||
- `backlog/` 명시 제외 사항: "확정된 로드맵 → 사용하지 않음"
|
||||
- `work-log/` 빠른 결정 순서 §8: "진행 중인 작업 메모인가? → work-log/"
|
||||
- 이 로드맵은 S1~S7 순서로 진행될 다중 세션 작업의 실행 계획이며, 각 후속 세션 진입 시 의존 순서·스코프 경계를 확인하기 위해 참조되는 세션 간 handoff 기준 문서다.
|
||||
- 아키텍처 구조 설명(`architecture/`)이나 불변 기술 결정(`adr/`)이 아닌 실행 계획이므로 보수적으로 `work-log/`를 선택.
|
||||
|
||||
**신규 카테고리 생성**: 없음.
|
||||
|
||||
## 의사결정 기록 위치
|
||||
|
||||
- 사용자 확정 결정 8건: `.atp/work-session/20260617-150635/report.md` §Decisions
|
||||
- 결합 트랙 판정(§2.7): `.atp/work-session/20260617-150635/report.md` §Coupling Analysis
|
||||
- Advisor 호출 결정: `.atp/work-session/20260617-150635/report.md` §Advisor Invocation Decision Log
|
||||
|
||||
## 추후 문서화가 필요한 항목
|
||||
|
||||
- S1 세션 완료 시: RBAC 스키마 마이그레이션 → `changes/` + 권한 모델 설계 → `architecture/` 또는 `contracts/`
|
||||
- S4D 세션 완료 시: 평가 통합 데이터모델 동결 → `contracts/` (내부 스키마 계약)
|
||||
- S7 조사 완료 시: Unity WebGL 업로드 파이프라인 결정 → `adr/` (되돌리기 어려운 기술 선택)
|
||||
- 각 세션 완료 후: `work-log/2026-06-17-jam-platform-roadmap.md` 의 해당 세션 카드 status 갱신 권장
|
||||
|
|
@ -1,154 +0,0 @@
|
|||
---
|
||||
schema_version: 2
|
||||
session_id: 20260617-150635
|
||||
resumed_from: null
|
||||
started_at: 2026-06-17T15:06:35+09:00
|
||||
ended_at: 2026-06-17T15:20:00+09:00
|
||||
user_request: |
|
||||
고도화 위한 계획 수립. 단위별로 끊어서(세션별) 작업할 수 있도록 분류·정리.
|
||||
사용자가 공유한 모호한 메모(게임잼 운영/평가/리뷰/관리자/포스팅/검색 등)를
|
||||
각 항목 의미를 확인하며 계획화. 이번 세션은 계획 수립 전용(코드 변경 0).
|
||||
---
|
||||
|
||||
# Summary
|
||||
게임잼 플랫폼 고도화 기획 세션. 기존 bibimbap(게임 공유 + 팀원 모집) 위에
|
||||
게임잼 운영/평가/리뷰/관리자(RBAC)/포스팅/태그검색 신규 기능군을 얹는 요청.
|
||||
메모가 무분별 → requirements 확정 전 orchestrator 가 직접 파싱 + 배치 질의로 의미 확정.
|
||||
세션 분할(단위별 새 세션) 요구 → §2.7 결합 트랙 판정이 핵심: 공유 자원(게임잼 엔티티/
|
||||
평가 데이터모델/RBAC) 기준으로 선후 순서를 강제해야 재작업 방지.
|
||||
|
||||
# Advisor Invocation Decision Log
|
||||
- advisor: requirements-advisor
|
||||
decision: pending
|
||||
rationale: '메모가 극도로 모호 → advisor 디스패치 전 orchestrator 가 사용자 배치 질의로 의미 확정 선행. 확정 후 requirements-advisor 로 FR/NFR 분해 디스패치 예정.'
|
||||
checked_at: 2026-06-17T15:06:35+09:00
|
||||
- advisor: graphify-lookup-advisor / research-advisor
|
||||
decision: skip
|
||||
rationale: '코드 구조는 기존 분석 세션(20260616-111711) + 직접 grep 으로 충분 파악. 외부 연동 모두 운영/차후로 확정 → 이번 세션 외부 조사 불필요.'
|
||||
checked_at: 2026-06-17T15:06:35+09:00
|
||||
- advisor: design-advisor / implementation-advisor / verification-advisor
|
||||
decision: skip
|
||||
rationale: '사용자가 "계획만 확정, 종료" 선택 → 코드 변경 0. 설계·구현·검증은 각 후속 세션(S1~)에서 수행.'
|
||||
checked_at: 2026-06-17T15:16:00+09:00
|
||||
- advisor: documentation-advisor
|
||||
decision: call
|
||||
rationale: '확정된 로드맵을 docs/ 적절 카테고리에 영구 저장 + index 연결(docs-first 참조용). 카테고리 분류는 advisor 책임 영역.'
|
||||
checked_at: 2026-06-17T15:16:00+09:00
|
||||
|
||||
# Invocations
|
||||
- id: inv-001
|
||||
layer: orchestrator
|
||||
name: orchestrator
|
||||
parent_invocation_id: null
|
||||
input_digest: '게임잼 고도화 메모 24항목 파싱 + 기존 도메인 구조 대조'
|
||||
output_digest: '소프트웨어 기능 vs 운영 로지스틱 분리 + 결합 트랙 식별 + 배치 질의 설계'
|
||||
artifacts: []
|
||||
concerns: []
|
||||
|
||||
# Decisions
|
||||
- by: user
|
||||
at: 2026-06-17T15:10:00+09:00
|
||||
decision: '게임잼 = 기존 bibimbap 위 신규 대형기능. games/game_likes/game_comments 재사용·확장, 게임 공유/모집은 유지.'
|
||||
- by: user
|
||||
at: 2026-06-17T15:10:00+09:00
|
||||
decision: '시상 3개 독립 트랙(상호 무관): ①심사위원 대상(심사위원 선정) ②유저평점 대상(유저 리뷰의 완성도+종합리뷰 평점 집계) ③인기투표 대상(최고 게임 투표). 스코어 대상 폐기.'
|
||||
- by: user
|
||||
at: 2026-06-17T15:10:00+09:00
|
||||
decision: '권한 체계 = 사이트 관리권한. 관리자(전체) / 부관리자(허용된 권한만 열림 = 권한부여형). 심사위원은 관리권한과 별개. 향후 기능별 인증유저(리뷰어/포스터/기술자 등) 추가 예정.'
|
||||
- by: user
|
||||
at: 2026-06-17T15:10:00+09:00
|
||||
decision: '포스팅 = 운영진 전용 공지·블로그 보드 + 외부링크 큐레이션. 유저 작성 절대 불가. 콘텐츠 카테고리: 유니티블로그/세션/게임잼대상 후기인터뷰/뒤끝 개발팀.'
|
||||
- by: user
|
||||
at: 2026-06-17T15:14:00+09:00
|
||||
decision: '출품작 = 기존 games 재사용 + 잼 연결(jam_id/조인). 참가 단위 개인·팀 모두.'
|
||||
- by: user
|
||||
at: 2026-06-17T15:14:00+09:00
|
||||
decision: '인기투표 = 게임잼 전용 1인 1표(평가기간 한정). game_likes 와 별개.'
|
||||
- by: user
|
||||
at: 2026-06-17T15:14:00+09:00
|
||||
decision: '외부 연동: Unity WebGL 빌드 업로드 파이프라인만 in-scope(차후 단계). Discord/뒤끝 = 운영/링크/콘텐츠만, 코드 연동 없음.'
|
||||
- by: user
|
||||
at: 2026-06-17T15:14:00+09:00
|
||||
decision: '태그 = 게임잼 + 게임(출품작) 공통 태그 테이블. 검색은 게임잼 중심.'
|
||||
|
||||
# Coupling Analysis (§2.7)
|
||||
# 공유 자원 기준 결합 판정 — "1메모=1세션" 분할 시 재작업 폭증 방지.
|
||||
foundations:
|
||||
- RBAC 권한체계 (관리자/부관리자 + 기능별 인증유저 플래그) — 게임잼관리·포스팅·심사위원의 전제
|
||||
- 게임잼 엔티티 + 라이프사이클 (모집→개발→평가→종료) — 대부분 기능이 매달림
|
||||
- 공유 태그 모델 — 검색 + 게임잼/게임
|
||||
coupled_cluster:
|
||||
# 같은 데이터 도메인(평가/리뷰/투표/댓글) + 게임잼 평가기간 게이트 공유 → 한 설계로 동결 후 구현 분할
|
||||
- 댓글 vs 리뷰 분리 (댓글 200자 / 리뷰 게시물당1회+평점)
|
||||
- 심사위원 평가 (→ 심사위원 대상)
|
||||
- 인기투표 잼전용 1인1표 (→ 인기 대상)
|
||||
- 3트랙 시상 집계/결과
|
||||
relatively_independent:
|
||||
- 정보성/홍보성 포스팅 보드 (RBAC 포스터 권한만 의존, 평가 클러스터와 무관 → 병렬 가능)
|
||||
deferred:
|
||||
- Unity WebGL 빌드 업로드 파이프라인 (차후, 별도 조사 필요)
|
||||
operational_only:
|
||||
- Discord 공지·진행(수동, 링크 표시만) / 뒤끝 파트너·콘텐츠 / 상금·후원 표시 필드
|
||||
|
||||
# Open Items
|
||||
- 메모 24항목 의미 확정 — 완료
|
||||
- 세션 분할 단위 확정 — 완료 (S1~S7, S4 분할 세션화 확정)
|
||||
- **미커밋 잔여(이번 작업 단위)**: `docs/work-log/2026-06-17-jam-platform-roadmap.md`(신규), `docs/work-log/index.md`(링크), `docs/analysis/2026-06-16-project-analysis.md`(교차링크) — 사용자 커밋 확인 대기. 브랜치 feat/v2.
|
||||
- **이번 작업 단위 외 잔여(이전 세션)**: `.serena/project.yml`(M), `.serena/memories/serena_tooling.md`(??), `.atp/work-session/20260617-094450·143315`(??) — 본 세션 미관여, 별도 처리.
|
||||
- **다음 시작점**: S1(RBAC) — 사용자가 새 세션에서 `/atp:task S1` 류로 진입. docs/work-log 로드맵 참조.
|
||||
|
||||
# verified_by_me
|
||||
- L1/L2: n/a (코드 변경 0줄, 계획 수립 전용 세션)
|
||||
- 문서 배치 검증: docs/work-log/2026-06-17-jam-platform-roadmap.md 본문(S1~S7 카드 + S4D/S4a~d 분할 + 의존그래프 + 크리티컬패스) grep 보존 확인. work-log/index.md 링크 1건 추가 확인. frontmatter kind/status/source_session 정상.
|
||||
|
||||
# needs_user_verification
|
||||
- (없음) — 계획 문서 산출만. 단 미커밋 docs 3건 커밋 여부는 사용자 결정.
|
||||
|
||||
# graph_refresh
|
||||
- skip: no-scope-change (§3.2) — src/ scope diff 0, docs/ 전용 변경. fresh 취급. (atp-graphify add-on enable 상태이나 scope 변경 없어 호출 불필요)
|
||||
|
||||
# project_gate
|
||||
- skip: no-project-gate — 코드 변경 0, 런타임/배포 대상 없음.
|
||||
|
||||
# User Signals
|
||||
user_signals:
|
||||
positive:
|
||||
- quote_or_paraphrase: '배치 질의 8건에 모두 명확·결단적으로 답변, 로드맵을 1라운드 만에 수락(S4 분할만 보강)'
|
||||
about: '모호 메모 → 기존 코드 대조 파싱 → 배치 AskUserQuestion → 결합 인지 로드맵 흐름'
|
||||
negative: []
|
||||
|
||||
# Retrospective (inline — retrospective-advisor dispatch skip)
|
||||
# skip 사유: 코드 변경 0 계획 세션 + 마찰 negative 시그널 0 + 신규 교훈(기존 §2.7/§4.4 적용 외) 없음.
|
||||
- what_went_well:
|
||||
- 메모 24항목을 기존 엔티티(games/game_comments/game_likes/recruit_posts) 대조로 신규 vs 기존 vs 운영 분류 → 헛스코프 방지
|
||||
- §2.7 결합 판정으로 "1메모=1세션" 재작업 함정 사전 차단, S4 통합설계(S4D) 동결 게이트 설계
|
||||
- §4.4 배치 질의(2라운드×4) + Recommended + 기존자산 인용으로 의미 확정 효율화
|
||||
what_to_improve:
|
||||
- 인기투표가 game_likes 재사용 아닌 잼 전용 투표로 밝혀짐 — 1차 파싱서 좋아요=인기로 단정했던 가정을 질의로 교정(시그널 세탁 없이 반영)
|
||||
memory_candidates: [] # 기존 프로토콜(§2.7/§4.4) 적용 외 신규·재현 교훈 없음 → MEMORY 반영 불필요
|
||||
protocol_feedback: []
|
||||
applied_changes: []
|
||||
|
||||
# Notes Parse (작업 입력)
|
||||
# 사용자 원문 메모를 소프트웨어 기능군 vs 운영 로지스틱으로 1차 분류.
|
||||
software_features:
|
||||
- 게임잼 엔티티/운영 (개발기간 1주 + 평가기간 3일~1주, 상태 전이)
|
||||
- 평가 체계 (심사위원제 완성도 / 인기=좋아요집계 / 스코어?)
|
||||
- 리뷰 vs 댓글 분리 (리뷰=게시물당 1회+평점, 댓글=200자)
|
||||
- 관리자/부관리자 RBAC
|
||||
- 정보성/홍보성 포스팅 (블로그/보드)
|
||||
- 태그 검색 (게임잼 검색)
|
||||
- 메인페이지 통합 (게임잼 포함 전부 노출)
|
||||
operational_logistics:
|
||||
- 상금/후원 (치킨3마리 / 총괄 10만원 / 음료수·편의점 5000원권) — 코드 아님(상금 표시 UI 는 별개)
|
||||
- Discord 공지·진행 (연동 깊이 미확정)
|
||||
- Unity 엔진 (제출 메타 vs WebGL 호스팅 — 이미 /game/** 호스팅 존재)
|
||||
- 뒤끝(Bekend BaaS) 개발팀 (파트너/후원 vs 기술연동 미확정)
|
||||
content_seeds:
|
||||
# "정보성/홍보성 포스팅" 의 예시 콘텐츠로 추정
|
||||
- 유니티 블로그 / 세션 / 게임잼 대상 후기인터뷰 / 뒤끝 개발팀
|
||||
|
||||
# User Signals
|
||||
user_signals:
|
||||
positive: []
|
||||
negative: []
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
---
|
||||
phase: documentation
|
||||
agent: documentation-advisor
|
||||
agent_version: 1
|
||||
generated_at: 2026-06-17T17:10:00+09:00
|
||||
concerns:
|
||||
- "status: active 유지 — 재구조된 로드맵은 여전히 진행 중인 계획이므로 active 유지 적절."
|
||||
- "restructured_by 필드 신규 도입 — 표준 frontmatter에 없는 커스텀 필드이나, 세션 추적성을 위해 source_session 보완 용도로 허용. 과도한 필드 추가 아님."
|
||||
- "documentation-guidelines.md 미존재 — docs/development/documentation-guidelines.md 파일이 없어 참조 불가. document-category-classification.md로 카테고리 판별 수행."
|
||||
concerns_checked: true
|
||||
---
|
||||
|
||||
# 문서화 보고
|
||||
|
||||
## 작성/수정된 문서
|
||||
|
||||
| 경로 | 카테고리 | 유형 | 링크 추가한 index | 교차 링크 |
|
||||
|---|---|---|---|---|
|
||||
| `docs/work-log/2026-06-17-jam-platform-roadmap.md` | work-log | 기존 문서 전면 재작성 | `docs/work-log/index.md` 항목 설명문 갱신 | report.md(20260617-162536) → Decisions 섹션이 본 doc 재구조 트리거로 교차 참조 |
|
||||
| `docs/work-log/index.md` | work-log | 기존 index 항목 설명문 갱신 | — (index 자체) | — |
|
||||
|
||||
## 의사결정 기록 위치
|
||||
|
||||
- `.atp/work-session/20260617-162536/report.md` — Decisions 섹션에 목적 축 재분류 확정 전 과정(S1~S7 → W1~W4) 기록. Emergent Categories + final_workstreams + key_reframes 포함.
|
||||
- `docs/work-log/2026-06-17-jam-platform-roadmap.md` — 재구조된 로드맵 본문. "150635 대비 핵심 교정 5건" 섹션에 교정 이유 명시. S→W 매핑 표로 추적성 보존.
|
||||
|
||||
## 적용한 섹션 목록
|
||||
|
||||
1. frontmatter — title/description/kind/status/owner/created_at/source_session 유지 + `restructured_by: 20260617-162536` 신규 필드 추가
|
||||
2. 본문 도입 — 재구조 이유 + 4개 워크스트림 + 게임잼=W2 명시
|
||||
3. W1 — 거버넌스/RBAC (★토대)
|
||||
4. W2 — 게임잼 (★본체): W2-1~W2-6 세분화
|
||||
5. W3 — 사이트 플랫폼: W3-1~W3-5 세분화, 잼 일정 분리 가능 명시
|
||||
6. W4 — 유저 배지/평판 (★신규 워크스트림, 150635 누락)
|
||||
7. 운영 (코드 외) 섹션
|
||||
8. 의존성 그래프 / 빌드 순서 — ASCII 코드블록, 워크스트림 라벨로 재서술
|
||||
9. S→W 매핑 표 — 추적성 보존 (이전 handoff 호환)
|
||||
10. 150635 대비 핵심 교정 5건
|
||||
|
||||
## S→W 매핑 포함 여부
|
||||
|
||||
포함. `docs/work-log/2026-06-17-jam-platform-roadmap.md` 내 "S → W 매핑 (추적성)" 섹션에 표 형식으로 작성. 구 S1~S7 전체 매핑 + 교정 사항 명시.
|
||||
|
||||
## 추후 문서화가 필요한 항목
|
||||
|
||||
- W2-3 잼 평가 통합설계(스키마 동결) 세션 진입 시 → design.md + contracts/ 문서 신규 작성 필요 (동결 스키마 + 집계 계약)
|
||||
- W4 유저 배지/평판 — 신규 발굴 워크스트림이므로 상세 requirements 확정 시 별도 work-log 또는 domain/ 문서 권장
|
||||
- W3-5 Unity 업로드 조사 결과 → analysis/ 문서로 기록 필요 (빌드 포맷/검증/보안 조사)
|
||||
|
|
@ -1,209 +0,0 @@
|
|||
---
|
||||
schema_version: 2
|
||||
session_id: 20260617-162536
|
||||
resumed_from: null
|
||||
started_at: 2026-06-17T16:25:36+09:00
|
||||
ended_at: 2026-06-17T17:16:00+09:00
|
||||
user_request: |
|
||||
고도화를 위해 세션을 나눴었는데, 기능 관련 계획은 나뉜 것 같다.
|
||||
그러나 각각 "왜 쓰고 무엇을 위해 존재하는지"(목적 축)는 명확하게 안 나뉜 것 같아
|
||||
하나씩 짚어보려 한다. 제공했던 메모가 모두 게임잼을 위해 존재했던 것은 아니다.
|
||||
→ 직전 세션(20260617-150635)이 메모 24항목을 전부 "게임잼 플랫폼 고도화" 프레임으로
|
||||
묶은 데 대한 목적 축 재분류 요청.
|
||||
---
|
||||
|
||||
# Summary
|
||||
직전 150635 세션 산출 로드맵(S1~S7)을 "목적(존재 이유)" 축으로 재검토하는 분석 세션.
|
||||
150635 는 기능 의존성(공유 자원 §2.7) 축으로는 잘 쪼갰으나, 모든 항목을 "게임잼" 목적
|
||||
프레임 아래 배치 → 사이트 전반용 기능(RBAC/포스팅/태그/리뷰·댓글/Unity업로드/메인)과
|
||||
게임잼 전용 기능(잼 엔티티/심사/인기투표/시상)이 목적상 섞여 보이는 framing gap.
|
||||
사용자 요청 = 항목별 "게임잼 전용 vs 사이트 플랫폼 vs 공유" 목적 재분류 후 하나씩 확정.
|
||||
|
||||
# Advisor Invocation Decision Log
|
||||
- advisor: requirements-advisor
|
||||
decision: pending
|
||||
rationale: '본질이 목적 축 재분류 + 사용자와 1:1 대화형 확정. advisor 는 AskUserQuestion 불가 → orchestrator 직접 대화로 의미 확정 선행. 필요 시 확정 후 로드맵 재작성을 documentation-advisor 로 위임.'
|
||||
checked_at: 2026-06-17T16:26:00+09:00
|
||||
- advisor: graphify-lookup / research-advisor
|
||||
decision: skip
|
||||
rationale: '코드 신규 조사 불요 — 기존 엔티티(games/game_comments/game_likes/recruit_posts)는 150635·110836 세션에서 확인됨. 본 세션은 기존 산출물(로드맵+decisions) 해석.'
|
||||
checked_at: 2026-06-17T16:26:00+09:00
|
||||
- advisor: requirements-advisor
|
||||
decision: skip(완료)
|
||||
rationale: '목적축 의미확정을 orchestrator 가 사용자 1:1 배치질의(S1~S7 + 플래그)로 완료. advisor 재분해 불요 — 산출 결정이 이미 확정적.'
|
||||
checked_at: 2026-06-17T16:55:00+09:00
|
||||
- advisor: documentation-advisor
|
||||
decision: call
|
||||
rationale: '확정된 W1~W4 목적 워크스트림을 로드맵 doc 에 W중심 전면 재구조로 반영. docs 카테고리/index/guidelines 준수는 advisor 책임. 사용자 "W중심 전면 재구조" 선택.'
|
||||
checked_at: 2026-06-17T16:55:00+09:00
|
||||
|
||||
# Invocations
|
||||
- id: inv-001
|
||||
layer: orchestrator
|
||||
name: orchestrator
|
||||
started_at: 2026-06-17T16:25:36+09:00
|
||||
input_digest: '150635 로드맵 + report decisions + notes parse 수집'
|
||||
output_digest: '목적 축 재분류표 작성, 사용자 확정 대기'
|
||||
model_choice:
|
||||
phase: analyze
|
||||
dispatch_size: direct
|
||||
tier: large
|
||||
effort: medium
|
||||
resolved_model: inherit
|
||||
capped: false
|
||||
rationale: '프레이밍·목적 판정은 다항목 교차 추론(§5.4 axis4) → orchestrator 직접 보유. 코드 변경 0.'
|
||||
|
||||
# Decisions
|
||||
- by: user
|
||||
at: 2026-06-17T16:30:00+09:00
|
||||
decision: '진행 방식 = S1부터 하나씩 목적 확정 → 종료 시 로드맵 doc 에 목적 축 반영.'
|
||||
- by: user
|
||||
at: 2026-06-17T16:34:00+09:00
|
||||
decision: |
|
||||
S1 "RBAC" 은 성격이 다른 3개가 한 카드에 뭉쳐 있었음 (150635 오분류):
|
||||
1. 관리자/부관리자 = 운영 중심 설계 = 진짜 RBAC (사이트 거버넌스, 잼 무관)
|
||||
2. 심사위원 = 게임잼 전용 역할 권한
|
||||
3. 리뷰어 = 권한 아님, 유저 '배지/평판' 개념 (업로드 게임 인증 리뷰어) → RBAC 도메인 분리 필요
|
||||
포스터/기술자 = 미확정 (후속 질의).
|
||||
- by: user
|
||||
at: 2026-06-17T16:40:00+09:00
|
||||
decision: |
|
||||
S1 플래그 4종 최종 분해:
|
||||
- 포스터 = 운영 작성 권한(부관리자 토글) → S1 RBAC 흡수, 별도개념 아님
|
||||
- 심사위원 = 게임잼 전용 역할 권한 → 잼 도메인으로 이관
|
||||
- 리뷰어 = 유저 배지/평판 (업로드 게임 인증 리뷰어)
|
||||
- 기술자 = 유저 배지/평판 (개발정보 공유/적극 업로더 인정, 임시명칭)
|
||||
→ "리뷰어+기술자" = 제3의 기능군 '유저 배지/평판 시스템'. 게임잼·RBAC 와 별개.
|
||||
150635 가 RBAC '인증유저 플래그' 로 통째 오분류 → 누락된 워크스트림 발굴.
|
||||
|
||||
# Emergent Categories (목적 축 재분류 결과 — 누적)
|
||||
# 150635 의 게임잼-단일프레임을 목적별로 분해. 항목 확정될 때마다 갱신.
|
||||
purpose_axes:
|
||||
site_governance_rbac:
|
||||
- 관리자/부관리자 권한모델 + 권한 토글(게임잼관리/포스팅작성 등) + 인터셉터 (구 S1)
|
||||
game_jam_only:
|
||||
- 심사위원 역할 권한 (구 S1 일부)
|
||||
- 게임잼 엔티티 + 라이프사이클 + 출품작 연결 + 상세페이지 (S2)
|
||||
# 속성: 회차 독립(다중 인스턴스). 통합지점: 출품작이 잼뷰 + 일반 게임노출 페이지 이중 노출(S6 로 흐름).
|
||||
# 운영표시필드(Discord/상금/후원) = operational, 표시만.
|
||||
user_badge_reputation: # ★신규 발굴 — 150635 누락
|
||||
- 리뷰어 배지 (인증 리뷰어)
|
||||
- 기술자 배지 (기여 인정, 임시명칭)
|
||||
site_platform:
|
||||
- 태그 모델 + 검색 = 일반 게임 발견성 중심 (S3). 잼용도: 이전회차 검색 + 진행회차 강조(부수). 잼일정 분리 가능.
|
||||
- 댓글/리뷰 분리 (S4a) = 모든 게임 페이지 일반기능. 댓글 200자 / 리뷰 게시물당1회+평점.
|
||||
# 리뷰주체=아무나(게임당1회), 리뷰어 배지=평판인정(→ user_badge_reputation 연결).
|
||||
# 잼 게이트 없음. 잼 연결=시상(S4d)이 리뷰 평점을 단방향 집계. ★S4D 동결묶음에서 분리해야.
|
||||
game_jam_only_eval:
|
||||
- 심사위원 평가 (S4b) — 평가기간 게이트, S1 심사위원 역할 소비
|
||||
- 인기투표 (S4c) — 잼 1인1표 평가기간, game_likes 와 별개
|
||||
- 시상 집계 3트랙 (S4d) — 심사/유저평점/인기. 유저평점만 S4a 리뷰평점 단방향 집계
|
||||
# ★S4D 재프레임: 잼 평가스키마(심사/투표/시상) + S4a→S4d 집계계약만 동결. 댓글/리뷰 스키마는 일반(별도설계).
|
||||
site_platform_more:
|
||||
- 포스팅 보드 (S5) = 사이트 콘텐츠/마케팅(공지·블로그·외부링크). 포스터=S1 운영권한. 잼은 포스팅 주제 1개로 포함. 잼일정 완전분리.
|
||||
- 메인 = 게임 허브 노출 (S6) = 게임 + 잼출품작 모이는 공간. ★포스팅은 별도 메뉴(150635 "메인 통합" 교정).
|
||||
- Unity WebGL 업로드 자동화 (S7) = 일반 게임 호스팅 자동화(모든 제출). 현 수동 호스팅 대체. deferred(조사선행).
|
||||
|
||||
# 목적 축 종합 (전 항목 확정)
|
||||
# 150635 단일 "게임잼" 프레임 → 4개 목적 워크스트림 + 운영으로 분해.
|
||||
final_workstreams:
|
||||
W1_거버넌스_RBAC:
|
||||
- 관리자/부관리자 권한모델 + 권한토글(게임잼관리/포스터=포스팅작성) + 인터셉터 (구 S1)
|
||||
W2_게임잼:
|
||||
- 게임잼 엔티티/라이프사이클/출품작연결/상세 (S2)
|
||||
- 심사위원 역할 권한 (구 S1 일부)
|
||||
- S4D 잼평가 통합설계(심사/투표/시상 스키마 + S4a→S4d 집계계약 동결)
|
||||
- 심사위원평가(S4b) / 인기투표(S4c) / 시상집계(S4d)
|
||||
W3_사이트플랫폼:
|
||||
- 태그+검색 일반 게임 발견성 (S3)
|
||||
- 댓글/리뷰 분리 일반 게임기능 (S4a)
|
||||
- 포스팅 보드 별도 메뉴 (S5)
|
||||
- 메인 게임 허브 노출 (S6)
|
||||
- Unity 업로드 자동화 (S7, deferred)
|
||||
W4_유저배지평판: # ★신규 — 150635 누락
|
||||
- 리뷰어 배지(S4a 리뷰활동 기반) / 기술자 배지(기여인정, 임시명칭)
|
||||
operational_표시만:
|
||||
- Discord/뒤끝/상금·후원 (코드 외, 표시 필드만)
|
||||
key_reframes_vs_150635:
|
||||
- 댓글/리뷰(S4a) = 일반기능 → 잼 S4D 동결묶음에서 분리(시상은 단방향 집계만)
|
||||
- 포스팅(S5) = 별도 메뉴, 메인(S6) 통합 아님
|
||||
- 태그/검색(S3)·Unity(S7) = 사이트 일반 인프라(잼은 소비자)
|
||||
- 유저 배지/평판(W4) = 누락된 신규 워크스트림 발굴
|
||||
- S4D 동결 범위 = 잼 평가만으로 축소
|
||||
- 의존성 그래프(빌드순서)는 유효 — 목적 축은 "왜/독립출시여부"를 추가로 분리
|
||||
|
||||
# Regression (§2.6)
|
||||
- surfaced_at_stage: '본 세션 목적축 재검 (S1)'
|
||||
source_stage: '150635 requirements/notes-parse'
|
||||
defect: '"기능별 인증유저 플래그(리뷰어/포스터/심사위원/기술자)" 를 전부 RBAC 권한으로 동질 취급 → 리뷰어=배지(평판) 오분류'
|
||||
full_set_recheck: true
|
||||
downstream_rerun: ['로드맵 S1 카드 목적 재서술', '잔여 플래그(포스터·기술자) 전수 재확인']
|
||||
resolved_at: null
|
||||
|
||||
# Open Items
|
||||
- 항목별 목적 축(게임잼전용/사이트플랫폼/공유) 사용자 확정
|
||||
- 로드맵 doc 재프레이밍 여부 결정 (게임잼 = 워크스트림 1개 vs 전체 프레임)
|
||||
|
||||
# ── 세션 종료 (§9) ──
|
||||
|
||||
# Conflicts
|
||||
- (없음) — 단일 documentation-advisor, advisor 간 충돌 없음.
|
||||
|
||||
# verified_by_me
|
||||
- L1/L2: n/a — 코드 변경 0줄(docs 전용 재구조 세션).
|
||||
- 문서 검증(직접 Read): roadmap doc 본문에 W1~W4 + 운영 + 의존성 그래프(ASCII) + S→W 매핑표(구 S1~S7 전체) + 교정 5건 보존 확인. frontmatter title/description/restructured_by 갱신 확인. work-log/index.md 링크 설명문 W중심으로 갱신 확인.
|
||||
|
||||
# needs_user_verification
|
||||
- (없음) — 계획 문서 재구조만. 런타임/배포 대상 없음.
|
||||
|
||||
# graph_refresh
|
||||
- skip: no-scope-change (§3.2) — src/·pom.xml diff 0, docs/ + work-session 전용. fresh 취급.
|
||||
|
||||
# project_gate
|
||||
- skip: no-project-gate — 코드 변경 0.
|
||||
|
||||
# Open Items / 미커밋 잔여 (§9.5)
|
||||
# 이번 작업 단위 (162536):
|
||||
- docs/work-log/2026-06-17-jam-platform-roadmap.md — 전면 재작성(W중심). 직전 150635 untracked 위에 갱신.
|
||||
- docs/work-log/index.md (M) — 링크 설명문 갱신.
|
||||
- .atp/work-session/20260617-162536/ — 본 세션 durable history(추적 기본, ADR-0010).
|
||||
# 이번 단위 외 잔여 (이전 세션 — 본 세션 미관여):
|
||||
- .serena/project.yml (M), .serena/memories/serena_tooling.md (??)
|
||||
- .atp/work-session/{20260617-094450,143315,150635}/ (??) ← 150635 roadmap 원본 포함
|
||||
- docs/analysis/2026-06-16-project-analysis.md (M)
|
||||
# 커밋 정책: harness "사용자 요청 시에만 커밋". 자동 커밋 안 함 → 사용자 결정 대기. 브랜치 feat/v2.
|
||||
|
||||
# User Signals
|
||||
user_signals:
|
||||
positive:
|
||||
- quote_or_paraphrase: 'S1~S7 + 플래그 8건 배치질의에 모두 결단적·구체 답변(리뷰어=배지, 기술자=배지, 포스터=운영권한, S6 포스팅 별도메뉴 등), 목적축 재분류 1회 수락'
|
||||
about: '목적축 1:1 워크스루 → W중심 재구조 흐름'
|
||||
negative: []
|
||||
|
||||
# Regression (§2.6) — 마감
|
||||
- surfaced_at_stage: '본 세션 목적축 재검 (S1~S7 전수)'
|
||||
source_stage: '150635 requirements/notes-parse (의존성축 분할 시 목적축 누락)'
|
||||
defect: '메모를 의존성/공유자원 축으로만 분할 → 단일 "게임잼" 목적 프레임이 비대상 기능(RBAC·태그·댓글리뷰·포스팅·메인·Unity)을 흡수. "인증유저 플래그"를 동질 취급해 리뷰어/기술자(배지) 오분류 → W4 워크스트림 누락.'
|
||||
full_set_recheck: true # S1~S7 전수 목적 재확인
|
||||
downstream_rerun: ['로드맵 doc W중심 전면 재구조', 'index.md 링크 갱신']
|
||||
resolved_at: 2026-06-17T17:15:00+09:00
|
||||
|
||||
# Retrospective (inline — retrospective-advisor dispatch skip)
|
||||
# skip 사유: 코드 변경 0 + 본 세션 마찰 negative 0. 단 150635 발원 구조결함 1건 표면화 → 재현성 교훈 존재 → memory_candidate 1건 제안.
|
||||
- what_went_well:
|
||||
- 의존성축(150635) vs 목적축(본 세션) 2축 분리 인지 → 사용자 ground truth 로 항목별 "왜 존재" 1:1 확정
|
||||
- 다항목(플래그 4종) 한 항목 결함(리뷰어=배지) 발견 시 §2.6 전수 재검 → W4 누락 워크스트림 발굴
|
||||
- documentation-advisor self-contained 브리프로 W중심 재구조 1회 완결
|
||||
what_to_improve:
|
||||
- 기획/세션분할 세션에서 의존성축만으로 쪼개면 목적축(왜/누구를 위한가)이 단일 프레임에 묻힘 — 분할 시 두 축 병행 확인 필요
|
||||
memory_candidates:
|
||||
- name: planning-purpose-vs-dependency-axis
|
||||
type: feedback
|
||||
description: '기능 요청을 세션/단위로 분할할 때 의존성 축(빌드순서)과 목적 축(왜 존재/누구를 위한가)을 분리 확인. 한 축만으로 쪼개면 비대상 기능이 단일 프레임에 흡수되고, 묶음 라벨("인증유저 플래그" 등) 동질 취급이 도메인 오분류(권한 vs 배지/평판)를 부른다.'
|
||||
rationale_for_saving: '150635(의존성축 우수) → 목적축 누락으로 4개 워크스트림이 단일 게임잼 프레임에 흡수된 실증. 기획 세션 재발 가능.'
|
||||
signal_source: positive
|
||||
docs_sync_target: null # 내부 기획 흐름 교훈 → MEMORY 단독. (프로토콜 §2.7/§4.2.2 와 인접하나 planning-split 특화)
|
||||
protocol_feedback: []
|
||||
applied_changes: []
|
||||
|
||||
# ended_at: 2026-06-17T17:16:00+09:00
|
||||
|
|
@ -1,156 +0,0 @@
|
|||
---
|
||||
schema_version: 2
|
||||
session_id: 20260617-172407
|
||||
resumed_from: null
|
||||
started_at: 2026-06-17T17:24:07+09:00
|
||||
ended_at: 2026-06-17T17:40:00+09:00
|
||||
user_request: |
|
||||
W3에서 기능별로 골자는 정해두고 싶어. 당장 작업하려는건 아니야
|
||||
---
|
||||
|
||||
# Summary
|
||||
W3(사이트 플랫폼 워크스트림) 5개 서브기능(W3-1 태그+검색, W3-2 댓글/리뷰, W3-3 포스팅 보드, W3-4 메인 허브, W3-5 Unity 업로드 deferred)의 "골자"를 정의하는 기획 정리 세션. 사용자 명시: 당장 구현 아님(코드 0줄). 산출은 문서 only.
|
||||
|
||||
# Invocations
|
||||
- id: inv-001
|
||||
layer: orchestrator
|
||||
name: orchestrator
|
||||
started_at: 2026-06-17T17:24:07+09:00
|
||||
input_digest: "W3 기능별 골자 정의 요청 (구현 아님)"
|
||||
output_digest: "프로토콜+로드맵 로드, 골자 깊이/범위 미결 → 계획 게이트 진입 예정"
|
||||
artifacts: []
|
||||
concerns: []
|
||||
|
||||
# Advisor Invocation Decision Log
|
||||
# 각 advisor 호출/스킵 판단 즉시 1줄 append
|
||||
- advisor: requirements-advisor
|
||||
decision: call
|
||||
rationale: '골자=기능 윤곽+미결질문 도출 = requirements 도메인. 코드현황 대조 필요(컨텍스트 오염 방지 위임). tier=medium/effort=medium/s-batch'
|
||||
checked_at: 2026-06-17T17:24:07+09:00
|
||||
- advisor: design-advisor
|
||||
decision: skip
|
||||
rationale: '윤곽 카탈로그 깊이 — 미결질문을 남기는 게 목적, 오픈질문0 완결설계 아님. 본격 design 은 기능별 착수 시'
|
||||
checked_at: 2026-06-17T17:24:07+09:00
|
||||
- advisor: verification-advisor
|
||||
decision: skip
|
||||
rationale: '코드 변경 0줄(문서 only 기획) — 검증 대상 없음'
|
||||
checked_at: 2026-06-17T17:24:07+09:00
|
||||
- advisor: graph-refresh-checker
|
||||
decision: skip
|
||||
rationale: 'src/ scope 변경 없음(docs only) — no-scope-change'
|
||||
checked_at: 2026-06-17T17:24:07+09:00
|
||||
|
||||
# Decisions
|
||||
- by: user
|
||||
at: 2026-06-17T17:24:07+09:00
|
||||
decision: "골자 깊이=윤곽 카탈로그 / W3-5 deferred=포함(조사항목 스텁만)"
|
||||
rationale: "당장 구현 아님 — 미결질문 남기는 1페이지 카탈로그"
|
||||
related_invocations: [inv-001]
|
||||
- by: orchestrator
|
||||
at: 2026-06-17T17:24:07+09:00
|
||||
decision: "산출 카테고리 backlog → work-log 정정"
|
||||
rationale: "document-category-classification §backlog 은 '확정 로드맵 제외' 명시. W3 골자는 확정 로드맵(W1~W4) 구체화 = work-log(로드맵과 동일 카테고리, 시점성 기획). 자체 발견 정정(§2.3)"
|
||||
related_invocations: [inv-001]
|
||||
|
||||
# Conflicts
|
||||
|
||||
# Open Items
|
||||
- 미커밋 잔여: docs/work-log/2026-06-17-w3-feature-skeletons.md(신규), docs/work-log/index.md(수정), .atp/work-session/20260617-172407/(신규). 커밋 여부 사용자 판단 대기(CLAUDE.md 커밋 정책 = 명시 요청 시).
|
||||
- QG-3 (코드 잠재 버그): /game/** 정적 핸들러 미등록(UploadResourceConfig 는 /profile/** 만) — W3-5 착수 전 의도/버그 확인 필요. 골자 범위 밖이라 본 세션 미수정.
|
||||
|
||||
# verified_by_me
|
||||
- L1/L2: 해당 없음 — 코드 변경 0줄(문서 only 기획). verification-advisor skip.
|
||||
- 문서 정합성: work-log/index.md 링크 추가 확인, source_roadmap 상호 링크 확인, 골자 깊이(DDL/API/시퀀스 없음·미결 해소 안 함) 사용자 확정과 일치.
|
||||
|
||||
# needs_user_verification
|
||||
- 골자 카탈로그 검토(5기능 미결질문·결합표·착수순서가 의도와 맞는지).
|
||||
- QG-3 /game/** 핸들러 동작 확인은 W3-5 착수 시 research 단계 과제.
|
||||
|
||||
# graph_refresh
|
||||
- skip: no-scope-change — src/ 변경 0(docs only). graph-refresh-checker 미호출(§3.2 호출 스킵 조건 충족).
|
||||
|
||||
# User Signals
|
||||
user_signals:
|
||||
positive:
|
||||
- quote_or_paraphrase: "AskUserQuestion(깊이+범위) 1회에 명확히 답하고 수락(윤곽 카탈로그 + deferred 포함)"
|
||||
about: "계획 게이트 옵션 설계 — 미리보기로 깊이 차이를 구체화한 것이 1회 수락으로 이어짐"
|
||||
negative:
|
||||
- quote_or_paraphrase: "너 혼자 정한거야? → 걸리는 곳: 골자 내용 자체"
|
||||
about: "골자 내용(5기능 미결질문 선정·결합 해석·착수순서 제언)을 사용자 검토 없이 advisor→work-log 문서로 확정. 깊이/범위만 계획 게이트로 묻고, 정작 이 세션의 핵심 deliverable 인 골자 내용은 동의 없이 굳힘. '골자는 정해두고 싶어'=함께 정하자는 의도를 통보로 처리."
|
||||
structural: true
|
||||
|
||||
# Protocol Feedback
|
||||
protocol_feedback:
|
||||
- issue: "문서-only 기획 세션의 산출물 내용 동의 게이트 부재"
|
||||
detail: "§5.0 계획 가시성 의무는 '첫 코드 변경 전' 동의를 강제한다. 코드 변경 0인 기획/골자 세션에선 이 트리거가 안 걸려, 산출물(골자) 내용 자체를 사용자 동의 없이 advisor→docs 로 확정하는 경로가 열린다. §5.0 은 'design 산출물은 파일로만 존재, orchestrator 가 핵심 결정 전달 책임'을 말하나, 문서 세션에서 그 '전달'을 확정 전 동의가 아닌 사후 보고로 처리해도 막는 규정이 없다."
|
||||
repro: "요청='X 골자/기획 정해두고 싶어' + 코드 변경 0. orchestrator 가 깊이/범위만 게이트로 묻고 내용은 advisor 산출→docs 직행 확정."
|
||||
proposed: "문서가 곧 deliverable 인 세션(기획/골자/설계 문서)은 advisor 산출 내용을 docs 정식 배치 전 사용자 검토 게이트를 1회 둔다. '코드 변경 전' 대신 'deliverable 확정 전' 으로 §5.0 트리거 일반화."
|
||||
|
||||
---
|
||||
|
||||
# Retrospective
|
||||
|
||||
```yaml
|
||||
Retrospective:
|
||||
signals:
|
||||
positive:
|
||||
- quote_or_paraphrase: "AskUserQuestion(깊이+범위) 1회에 명확히 답하고 수락(윤곽 카탈로그 + deferred 포함)"
|
||||
about: "계획 게이트에서 3단계 깊이(윤곽/설계/구현) 옵션을 미리보기로 구체화 — 왕복 없이 1회 결정 완료"
|
||||
negative: []
|
||||
|
||||
what_went_well:
|
||||
- "계획 게이트 AskUserQuestion에서 깊이 옵션을 추상 레이블이 아닌 산출물 차이(미결질문 남김 vs DDL/API까지 vs 코드 직접) 미리보기로 구체화했고, 사용자가 1회 수락으로 범위 확정. 재호출 없이 완료."
|
||||
- "orchestrator가 산출 카테고리를 backlog로 추정했다가 document-category-classification.md §backlog('확정 로드맵 제외' 명시)를 읽고 work-log로 자체 정정(§2.3). 분류기준 문서가 의도대로 작동함."
|
||||
- "requirements-advisor가 코드 대조(GamesMapper, GameCommentsMapper, UploadResourceConfig)를 수행해 '결합/의존' 섹션 정확도를 높임. 분류 문서 없이 추정만 했다면 결합표가 부정확했을 것."
|
||||
|
||||
what_to_improve:
|
||||
- "orchestrator가 분류기준 문서를 읽기 전에 backlog를 추정 출력했다가 정정한 패턴이 재현 가능. 문서 카테고리 결정은 산출 시점이 아니라 배치 전 document-category-classification.md 조회 후 결정하는 순서를 고정해야 한다."
|
||||
|
||||
memory_candidates:
|
||||
- name: doc-category-read-before-placement
|
||||
type: feedback
|
||||
description: "문서 산출 카테고리는 document-category-classification.md를 읽은 후 결정한다 — 추정 먼저 출력 금지"
|
||||
body_draft: |
|
||||
orchestrator가 docs/ 산출물 배치 카테고리를 결정할 때, document-category-classification.md를 확인하기 전에 추정값을 먼저 사용하면 정정 사이클이 발생한다.
|
||||
|
||||
**Why:** 2026-06-17 세션(20260617-172407)에서 W3 골자 기획 문서를 backlog로 추정했다가, document-category-classification.md §backlog("확정된 로드맵 제외")를 읽고 work-log로 정정. 분류기준이 명문화돼 있어 조회만 했으면 첫 판단이 정확했을 것.
|
||||
|
||||
**How to apply:**
|
||||
- 산출 문서를 처음 배치할 때 조건 판단 전에 document-category-classification.md를 먼저 읽는다.
|
||||
- 빠른 결정 순서(§빠른 결정 순서)를 따라 해당 카테고리를 선택한 후 배치한다.
|
||||
- 추정이 맞더라도 근거 없는 추정은 report.md Decisions에 기록하지 말고 조회 후 기록한다.
|
||||
- 적용 조건: docs/ 하위 신규 문서 배치 시 전건 적용.
|
||||
rationale_for_saving: "분류기준 문서가 존재하지만 '먼저 읽어야 한다'는 절차는 CLAUDE.md나 프로토콜에 명시되어 있지 않음. orchestrator가 추정-정정 사이클을 반복할 수 있는 구조적 빈틈. 재현 가능성 높음."
|
||||
signal_source: observation
|
||||
docs_sync_target: /Users/wemadeplay/workspace/stz/bibimbap/docs/development/agent-team-protocol.md
|
||||
|
||||
- name: plan-gate-depth-preview-single-pass
|
||||
type: feedback
|
||||
description: "계획 게이트에서 깊이/범위 옵션을 산출물 차이 미리보기로 구체화하면 1회 수락으로 이어진다"
|
||||
body_draft: |
|
||||
AskUserQuestion의 깊이/범위 옵션을 추상 레이블만으로 제시하면 추가 질문이 발생하지만, 각 옵션 선택 시 실제 산출물이 어떻게 달라지는지를 2~3줄 미리보기로 포함하면 왕복 없이 결정 완료된다.
|
||||
|
||||
**Why:** 2026-06-17 세션(20260617-172407)에서 W3 골자 깊이를 "윤곽 카탈로그 / 설계 완결 / 구현 착수"로 구분하고 각 옵션의 산출물 차이(미결질문 남김 여부, DDL/API 포함 여부, 코드 직접 작성 여부)를 미리보기로 제시. 사용자가 재질의 없이 1회 수락(윤곽 카탈로그 + deferred 포함).
|
||||
|
||||
**How to apply:**
|
||||
- 깊이/범위 옵션 ≥ 2이고, 선택이 이후 작업량과 산출 형식을 크게 바꾸는 경우에 적용.
|
||||
- 옵션별로 "이 옵션을 선택하면 X가 포함되고 Y는 다음 세션으로" 형식의 2~4줄 비교를 포함한다.
|
||||
- 전체 설계 공유는 과잉 — 선택 기준이 되는 핵심 차이만 기술한다.
|
||||
- 기존 memory `preview-requery-pattern`(agent-team-protocol 프로젝트)과 동일 패턴. 중복 후보 — 해당 memory가 bibimbap 프로젝트에도 적용 가능한지 orchestrator가 판단 후 신규 저장 여부 결정.
|
||||
rationale_for_saving: "agent-team-protocol 프로젝트에 `preview-requery-pattern`으로 이미 존재. bibimbap 프로젝트 memory에는 없으나, 패턴 자체는 기존 memory와 중복. orchestrator가 프로젝트별 memory 저장 필요성을 판단해야 하므로 후보로 올려 위임."
|
||||
signal_source: positive
|
||||
conflicts_with: preview-requery-pattern (agent-team-protocol 프로젝트)
|
||||
docs_sync_target: null
|
||||
|
||||
protocol_feedback: []
|
||||
|
||||
applied_changes:
|
||||
- "memory_candidates 2건 검토 → 둘 다 미수용(보류)."
|
||||
- "후보1 doc-category-read-before-placement: 기존 CLAUDE.md docs-first 정책('작업 시작 전 카테고리 index→구체 문서')에 내포된 교훈. 위반은 단발 실수(self-caught, 비용 0). docs_sync_target(플러그인 번들 agent-team-protocol.md)은 §6 ~/.claude 수정 금지 + bibimbap 경로 부재로 부적합. 신규 MEMORY 불필요."
|
||||
- "후보2 plan-gate-depth-preview-single-pass: 일반 UX 패턴, agent-team-protocol 프로젝트 preview-requery-pattern 중복, 프로젝트 특정성 없음. bibimbap 중복 저장 가치 낮음."
|
||||
```
|
||||
|
||||
# Closeout
|
||||
- ended_at: 2026-06-17T17:40:00+09:00
|
||||
- 미커밋 잔여(커밋 정책 = 사용자 명시 요청 시): docs/work-log/index.md(M), docs/work-log/2026-06-17-w3-feature-skeletons.md(??), .atp/work-session/20260617-172407/(??). 사용자 커밋 결정 대기.
|
||||
- project-gate: skip: no-project-gate (코드 0줄, 런타임 게이트 무의미).
|
||||
|
|
@ -1,185 +0,0 @@
|
|||
---
|
||||
phase: requirements
|
||||
agent: requirements-advisor
|
||||
agent_version: 1
|
||||
generated_at: 2026-06-17T18:10:00+09:00
|
||||
concerns: []
|
||||
concerns_checked: true
|
||||
---
|
||||
|
||||
# W3 사이트 플랫폼 — 5개 서브기능 골자 카탈로그
|
||||
|
||||
## 원 요청
|
||||
|
||||
bibimbap(Spring Boot + MyBatis + JSP, Java 21) 프로젝트에서 W3(사이트 플랫폼 워크스트림) 5개 서브기능의 "골자(skeleton)" 카탈로그를 작성한다. 깊이는 윤곽 카탈로그로 확정. 미결질문은 해소하지 않고 목록으로 남긴다.
|
||||
|
||||
---
|
||||
|
||||
## 코드 현황 요약 (확인 결과)
|
||||
|
||||
확인 파일 근거:
|
||||
|
||||
1. **`games` 테이블 현황** — `GamesMapper.java`: id, user_id, name, creator_note, git_url, webgl_path, thumbnail_url, like_count, is_visible, sort_order, created_at, updated_at. 태그 컬럼 없음. 검색은 name/display_name/creator_note ILIKE 방식만 존재.
|
||||
2. **`game_comments` 현황** — `GameCommentsMapper.java`: id, game_id, nickname, content, created_at, deleted_at, is_delete. 로그인 연동 없이 nickname 자유입력. content 글자수 제한 없음(DB 컬럼 타입 미확인). **review 테이블 없음(신규)**, **tag 테이블 없음(신규)**.
|
||||
3. **권한 현황** — `UserData.java`에 `role` 필드 존재. `UserController.java`에 `ROLE_USER = "USER"` 상수만. **Interceptor 클래스 없음** — 인터셉터 미구현, 권한 게이트 없음(W3-3 포스터 게이트가 얹힐 자리 미비).
|
||||
4. **`index.jsp` 현황** — 게임 카드 그리드 + 텍스트 검색(ILIKE). 잼 출품작 노출 없음. 섹션 단일(일반 게임만).
|
||||
5. **WebGL 업로드 현황** — `GameUploadController.java`: `/api/game-files/webgl-zip` 이미 구현. zip-slip 방어·엔트리 수 상한(8000)·압축 해제 크기 상한(512MB) 적용됨. `/game/{uuid}/` 경로 배치 구현. **단, 로그인 체크만 있고 권한 체크 없음. `/game/**` 정적 파일 핸들러가 `UploadResourceConfig.java`에 미등록** — `/profile/**`만 등록, `/game/**` 핸들러 누락 확인.
|
||||
|
||||
---
|
||||
|
||||
## 기능 요구 (FR)
|
||||
|
||||
### W3-1 — 태그 + 검색
|
||||
|
||||
- **목적**: 일반 게임 발견성 향상이 1차. 잼 용도(진행 회차 강조, 이전 회차 검색)는 부수 기능.
|
||||
- **핵심 동작**: 게임/잼에 태그를 붙이고, 태그로 필터링 검색한다. 기존 텍스트 검색과 병행.
|
||||
- **결합/의존**:
|
||||
- `games` 테이블에 태그 연결 → 신규 `tags` + 조인테이블 필요(기존 코드에 없음, 신규).
|
||||
- 잼 태그 연결은 W2 게임잼 엔티티(`jams` 테이블) 존재 후에만 가능 — 잼 부분은 W2 선행 의존.
|
||||
- 단독 게임 태그 검색은 W2와 무관하게 독립 착수 가능.
|
||||
- `GamesMapper.searchVisibleGames`: 현재 ILIKE 방식 — 태그 필터 추가 시 쿼리 확장 필요.
|
||||
- **주요 미결질문**:
|
||||
- Q1: 태그 관리 방식 — 자유입력(사용자 생성)인가, 운영자 사전 정의 목록인가, 혼합인가?
|
||||
- Q2: 태그당 게임 수 제한·태그명 최대 길이·허용 문자셋은?
|
||||
- Q3: 잼 전용 태그와 게임 공용 태그를 같은 `tags` 테이블로 통합하는가, 분리하는가?
|
||||
- Q4: 태그 검색 결과 정렬 기준(좋아요순/최신순/태그 일치도)은?
|
||||
- Q5: 다중 태그 AND/OR 조합 검색을 지원하는가?
|
||||
- **후속 진입점**: design-advisor
|
||||
|
||||
---
|
||||
|
||||
### W3-2 — 댓글 / 리뷰 분리
|
||||
|
||||
- **목적**: 모든 게임 페이지의 일반 기능. 잼 평가기간 게이트 없음, 잼 독립.
|
||||
- **핵심 동작**: 기존 `game_comments`(닉네임 자유입력)를 로그인 사용자 연동 댓글로 전환하고, 별도 리뷰(게임당 1회, 완성도+종합 평점) 기능을 신설한다. W2-6 시상이 리뷰 평점을 단방향으로 집계한다.
|
||||
- **결합/의존**:
|
||||
- `game_comments` 테이블 기존 존재 — 단, nickname 자유입력 구조. 로그인 연동으로 변경 시 기존 데이터 처리 결정 필요(마이그레이션 우려 → concerns).
|
||||
- `game_reviews` 테이블 — 신규, 없음.
|
||||
- W2-6(시상)이 이 기능의 평점을 집계 — W2-6이 나중에 리뷰 평점 컬럼 계약을 요구함. W3-2 설계 시 집계 계약을 W2-3(평가 통합설계) 동결과 맞출 필요.
|
||||
- 현재 content 길이 제한 미적용 — 200자 제한 신규 적용 필요.
|
||||
- **주요 미결질문**:
|
||||
- Q1: 기존 `game_comments`의 nickname 자유입력 레코드를 어떻게 처리하는가? (유지/마이그레이션/별도 표시)
|
||||
- Q2: 댓글 수정·삭제는 작성자 본인만인가, 운영자도 가능한가? 현재 updateGameComment가 있으나 권한 체크 없음.
|
||||
- Q3: 평점 척도 — 완성도 및 종합 각각 몇 점 만점인가? (예: 5점/10점)
|
||||
- Q4: 리뷰는 수정 가능한가? 게임당 1회 제한이면 수정 허용 여부와 수정 이력 관리 방식은?
|
||||
- Q5: W2-3 평가 통합설계와의 리뷰 평점 집계 계약을 W3-2 설계 단계에서 선확정해야 하는가, W2-3 동결 후 맞추는가?
|
||||
- **후속 진입점**: design-advisor (W2-3 진행 상황 연계 확인 후)
|
||||
|
||||
---
|
||||
|
||||
### W3-3 — 포스팅 보드
|
||||
|
||||
- **목적**: 사이트 공지·블로그 + 외부링크 큐레이션. 별도 메뉴. 잼과 무관한 독립 콘텐츠 채널.
|
||||
- **핵심 동작**: 포스터 권한자(W1 RBAC로 부여)만 작성. 카테고리(유니티블로그/세션/게임잼대상 후기인터뷰/뒤끝 개발팀) 선택. 일반 유저는 읽기만 가능.
|
||||
- **결합/의존**:
|
||||
- W1(포스터 권한) 선행 필요 — `UserData.role` 필드는 존재하나, 현재 Interceptor 없음. 포스터 권한 게이트를 얹을 인터셉터·어노테이션 인프라가 W1에서 구현돼야 함.
|
||||
- `posts` 또는 `board_posts` 테이블 — 신규, 없음.
|
||||
- `RecruitPostsMapper`/`RecruitController` 참고 가능(유사 게시판 패턴 기존 존재).
|
||||
- **주요 미결질문**:
|
||||
- Q1: W1 포스터 권한 인프라가 W3-3 착수 전에 완료돼야 하는가, 임시 하드코딩(role=="POSTER" 직접 체크)으로 먼저 구현하고 W1 완료 후 교체하는가?
|
||||
- Q2: 카테고리는 DB 저장인가, 코드 enum 고정인가?
|
||||
- Q3: 외부링크 큐레이션의 구체적 형태 — 링크 URL + 설명 텍스트만인가, OG 미리보기를 포함하는가?
|
||||
- Q4: 포스팅 본문 형식 — 순수 텍스트인가, 마크다운/HTML 허용인가? (XSS 영향)
|
||||
- Q5: 포스팅에 댓글(W3-2)을 붙일 수 있는가?
|
||||
- **후속 진입점**: design-advisor (W1 진행 상황 확인 선행)
|
||||
|
||||
---
|
||||
|
||||
### W3-4 — 메인페이지 (게임 허브)
|
||||
|
||||
- **목적**: `index.jsp`를 게임 + 잼 출품작이 함께 노출되는 허브로 확장. 포스팅은 별도 메뉴이며 메인 통합 아님.
|
||||
- **핵심 동작**: 현재 일반 게임 카드 그리드에 잼 출품작 섹션을 추가 노출. 진행 중인 잼 출품작 강조, 일반 게임과 시각적 구분.
|
||||
- **결합/의존**:
|
||||
- 현재 `index.jsp`는 `GamesMapper.getVisibleGames()` / `searchVisibleGames()` 단일 소스 — 잼 출품작 섹션 추가 시 쿼리 확장 또는 분리 필요.
|
||||
- W2 게임잼 엔티티(`jams` 테이블, 잼-게임 조인) 선행 의존 — 잼 출품작 노출 부분만. 일반 게임 허브 개선은 W2 없이 가능.
|
||||
- W3-1 태그 검색 완료 시 메인 필터 UI 연동 가능(선택적 연계).
|
||||
- **주요 미결질문**:
|
||||
- Q1: 잼 출품작 섹션의 노출 조건 — 진행 중인 잼이 있을 때만 표시하는가, 항상 섹션을 보여주는가?
|
||||
- Q2: 일반 게임과 잼 출품작이 같은 games 레코드를 재사용한다면, 메인에서 중복 노출 방지 정책은?
|
||||
- Q3: 게임 정렬·추천 로직 — 현재 sort_order ASC + created_at DESC 그대로 유지인가, 허브로 개편 시 큐레이션/인기순 등 다른 기준을 도입하는가?
|
||||
- Q4: 페이지네이션 또는 무한스크롤 도입 여부 — 현재 전체 목록 단일 조회.
|
||||
- Q5: W2 완료 전 메인 개선을 일반 게임 허브 부분만 먼저 착수할 수 있는가? (단계적 착수 가능 여부)
|
||||
- **후속 진입점**: design-advisor
|
||||
|
||||
---
|
||||
|
||||
### W3-5 — Unity WebGL 빌드 업로드 자동화 (deferred — 선행 조사 스텁)
|
||||
|
||||
- **목적**: 일반 게임 호스팅 자동화. 현 수동 호스팅 대체. 게임잼과 무관한 인프라.
|
||||
- **현황**: `GameUploadController.java`에 `/api/game-files/webgl-zip` 구현 존재. zip-slip 방어·크기 상한(512MB 압축 해제, 엔트리 수 8000) 적용. UUID 기반 `/game/{uuid}/` 배치 로직 구현. **단, `/game/**` 정적 리소스 핸들러가 `UploadResourceConfig.java`에 미등록** — `/profile/**`만 등록 확인.
|
||||
- **선행 조사 필요 항목**:
|
||||
- zip-slip 방어 충분성 검증 — 현 구현 `target.startsWith(targetDir)` 체크 존재하나, 심볼릭 링크·인코딩 우회 케이스 검토 필요.
|
||||
- Unity WebGL 빌드 포맷 검증 — index.html 탐지 외 필수 파일(Build/*.data, Build/*.wasm, Build/*.js) 존재 여부 검증 범위.
|
||||
- 업로드 크기/타입 상한 — 현재 압축 해제 후 512MB, zip 원본 크기 상한 미확인. Content-Type 검증이 MIME 헤더 + 확장자 이중 체크인지 검토.
|
||||
- 저장 경로 boundary — `app.upload.game-storage-path` 설정값 외부 주입 시 경계 검증.
|
||||
- `/game/**` 정적 핸들러 미등록 문제 — 현재 업로드 후 실제 서빙 경로 동작 미보장.
|
||||
- 업로드 권한 게이트 — 현재 로그인 체크만, 권한 제한 없음(누구나 업로드 가능).
|
||||
- 기존 레코드 덮어쓰기/삭제 정책 — UUID 재사용 시 처리.
|
||||
- **주요 미결질문 (= 조사 항목)**:
|
||||
- Q1: `/game/**` 정적 핸들러 미등록 — 의도적 누락인가, 버그인가? (현재 동작 확인 필요)
|
||||
- Q2: 업로드 권한 범위 — 로그인 사용자 전체 허용인가, 특정 권한(W1)자만인가?
|
||||
- Q3: 빌드 포맷 검증 수준 — index.html 존재 확인으로 충분한가, WebGL 필수 파일 구조 검증까지 하는가?
|
||||
- Q4: 업로드 후 게임 등록 플로우 — 업로드와 `games` 테이블 등록이 별도 단계인가, 자동 연동인가?
|
||||
- Q5: 스토리지 전략 — 현재 로컬 파일시스템, 향후 오브젝트 스토리지(S3 등) 전환 계획 있는가?
|
||||
- **후속 진입점**: research-advisor (조사 완료 후 design-advisor)
|
||||
|
||||
---
|
||||
|
||||
## 비기능 요구 (NFR)
|
||||
|
||||
- **NFR-보안**:
|
||||
- W3-3 포스팅: 포스터 권한 게이트 미구현 상태 — W1 인터셉터 선행 없이 착수 시 임시 role 체크로 XSS/권한 우회 위험 있음.
|
||||
- W3-2 댓글: 현재 content 길이 제한 없음 — 200자 제한 서버사이드 검증 신규 적용 필요.
|
||||
- W3-5 업로드: zip-slip 방어 존재하나 심볼릭 링크 우회 검토 미완.
|
||||
- **NFR-호환성**: W3-2에서 기존 `game_comments` 닉네임 자유입력 레코드의 호환 처리 결정 필요(스키마 변경 강제 — concerns 이관).
|
||||
- **NFR-운영**: W3-5 `/game/**` 정적 핸들러 미등록 — 현재 배포 시 게임 서빙 경로 동작 불명확.
|
||||
- **NFR-성능**: W3-4 메인 — 현재 전체 목록 단일 쿼리. 게임 수 증가 시 페이지네이션 미적용 상태.
|
||||
|
||||
해당 없음 항목: 접근성(이 단계 스코프 외), i18n(한국어 단일 서비스).
|
||||
|
||||
---
|
||||
|
||||
## 스코프
|
||||
|
||||
- **포함**: W3-1~W3-5 각 기능의 목적·핵심 동작·결합 지점·미결질문 윤곽. 코드 현황 대조.
|
||||
- **제외**: DDL/SQL, API 경로, 시퀀스 다이어그램, 구현 세부. W1·W2 자체 설계. W4 유저 배지.
|
||||
|
||||
---
|
||||
|
||||
## 가정 / 추측
|
||||
|
||||
- `game_comments`의 content 컬럼 타입은 TEXT로 추정 — 현재 코드에서 길이 제한 없으므로. 확정은 DB 스키마 직접 확인 필요.
|
||||
- `UserData.role` 필드의 현재 허용값은 "USER" 확인, 다른 값(ADMIN/POSTER 등)은 코드에서 미확인 — 확정 필요.
|
||||
- `RecruitPostsMapper` 패턴이 W3-3 포스팅 보드 구현 참고 대상으로 적합하다고 추정(유사 게시판 구조).
|
||||
|
||||
---
|
||||
|
||||
## 확정 필요 (오픈 질문 — 기능 인라인 목록 외 전체 수준)
|
||||
|
||||
- QG-1: W1 인터셉터 구현 완료 시점과 W3-3 포스팅·W3-5 업로드 권한 게이트 착수 순서 — W1이 늦어질 경우 임시 role 직접 체크 허용 여부.
|
||||
- QG-2: W3-2 댓글의 기존 닉네임 자유입력 레코드 처리 — 마이그레이션, 유지, 또는 레거시 표시?
|
||||
- QG-3: W3-5의 `/game/**` 정적 핸들러 미등록이 의도적인지 확인 — 현재 WebGL 서빙이 실제로 동작하는지.
|
||||
|
||||
---
|
||||
|
||||
## 워크스트림 결합 요약
|
||||
|
||||
| 기능 | 결합 대상 | 결합 방식 | 독립 출시 가능? |
|
||||
|---|---|---|---|
|
||||
| W3-1 태그+검색 | W2(게임잼 엔티티) | 잼 태그 노출 시 의존, 게임 태그는 독립 | 부분 가능 (게임 태그 먼저) |
|
||||
| W3-2 댓글/리뷰 | W2-6(시상 집계) | 리뷰 평점을 W2-6이 단방향 집계 | 가능 (잼 독립) |
|
||||
| W3-3 포스팅 보드 | W1(포스터 권한/인터셉터) | 권한 게이트 의존 | W1 선행 필요 (또는 임시 체크) |
|
||||
| W3-4 메인 허브 | W2(게임잼 엔티티) | 잼 출품작 섹션 노출 시 의존 | 부분 가능 (일반 게임 개선 먼저) |
|
||||
| W3-5 WebGL 자동화 | 없음 (일반 인프라) | 독립 | deferred (선행 조사 후) |
|
||||
|
||||
---
|
||||
|
||||
## 착수 순서 제언
|
||||
|
||||
독립도 기준 추천 진입 순서(제언, 단정 아님):
|
||||
|
||||
**W3-2(댓글/리뷰 분리) 먼저** — W1/W2 무관 완전 독립, 기존 코드(`game_comments`) 위에 확장이므로 착수 비용 최소. 단, W2-3 리뷰 평점 집계 계약 조율은 병행 필요.
|
||||
**다음 W3-1(태그+검색, 게임 태그 부분)** — 게임 태그 단독은 W2 불필요, 발견성 개선 즉시 효과.
|
||||
**다음 W3-4(메인 허브, 일반 게임 부분)** — W2 없이 일반 게임 허브 개선 먼저 가능.
|
||||
**W3-3(포스팅)** — W1 인터셉터 인프라 선행 후.
|
||||
**W3-5(WebGL 자동화)** — 선행 조사 완료 후, deferred.
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
# W3-2 리뷰 — 사용자 선제 입력 (파킹, W3-2 진입 시 펼칠 것)
|
||||
|
||||
W3-1 Q4 "점수" 명확화 중 사용자가 선제로 준 리뷰 방향. W3-2 미결질문으로 편입 예정.
|
||||
|
||||
1. **리뷰 = 별점 평점 + 디테일 텍스트**
|
||||
- 초기: 별점 5개(★5) 단일 평점 + 해당 게임 디테일 평가(서술형)
|
||||
- → W3-1 의 "점수 정렬" = 이 별점 평점 기반으로 확정
|
||||
|
||||
2. **리뷰 단위 정책 (고민중 — W3-2 미결)**
|
||||
- 업데이트 단위로 리뷰를 나눌지
|
||||
- 나눠도 점수는 통합 평점으로 집계할지
|
||||
|
||||
3. **리뷰 고도화 (고민중 — W3-2 미결)**
|
||||
- 여러 축 평가 → 게임 스탯을 그래프로 (육각형/레이더 차트 느낌)
|
||||
- → 실현 시 "점수"가 단일값 아닌 다축 → W3-1 점수 정렬의 정렬키 의미가 W3-2 설계에 종속
|
||||
|
||||
## W3-1 로 되돌아오는 영향
|
||||
- 점수 정렬키 = 리뷰 평점 기반 (W3-2 의존 확정, C6)
|
||||
- 단일 평점 vs 다축(육각형) 여부는 W3-2 설계에서 확정 → W3-1 골자엔 "정렬 점수의 정확한 의미는 W3-2 종속"으로 남김
|
||||
|
|
@ -1,139 +0,0 @@
|
|||
---
|
||||
schema_version: 8
|
||||
sid: 20260617-174635
|
||||
resumed_from: 20260617-172407
|
||||
started_at: 2026-06-17T17:46:35
|
||||
ended_at: null
|
||||
user_request: |
|
||||
W3 골자(docs/work-log/2026-06-17-w3-feature-skeletons.md, status:draft, 미커밋)를
|
||||
기능 하나씩(W3-1→W3-5) 함께 확정. 각 기능마다 초안 미결질문·결합해석을 항목별로 펼쳐
|
||||
보여주고 keep/제거/수정/추가를 사용자에게 묻고, 합의된 것만 문서에 반영.
|
||||
골자 내용(미결질문 선정·결합 해석·우선순위) 사용자 동의 없이 docs 확정 금지.
|
||||
착수순서 제언은 5기능 합의 후 맨 마지막에 같이 확정.
|
||||
제약: 객관 코드사실 유지 / 윤곽 카탈로그 깊이 / DDL·API·시퀀스 금지 /
|
||||
미결질문은 해소 아닌 합의 목록으로 / 당장 구현 아님.
|
||||
---
|
||||
|
||||
# Summary
|
||||
|
||||
W3 골자 카탈로그(5기능)를 사용자와 기능별·항목별 합의해 status:draft→confirmed 로 확정. orchestrator 직접 구동(advisor 전체 skip). 합의 과정에서 새 결합 3건 발굴: W3-1↔W3-2 양방향(리뷰수·점수 정렬), W3-4 잼 노출이 W3-1 잼 태그 검색으로 라우팅(배너+클릭), W3-3 외부 fetch 인프라(OG 미리보기+유니티블로그 피드 감시). 착수순서 W3-2→W3-1→W3-4→W3-3→W3-5 확정. 코드 변경 0.
|
||||
|
||||
# Invocations
|
||||
|
||||
[]
|
||||
|
||||
# Advisor Invocation Decision Log
|
||||
# 각 advisor 호출/스킵 판단 즉시 1줄 append
|
||||
- advisor: requirements-advisor
|
||||
decision: skip
|
||||
rationale: '초안에 미결질문이 이미 항목 열거됨. 사용자가 항목별 keep/제거/수정/추가를 직접 판정하는 대화 → orchestrator-사용자 직접 구동이 본분. advisor 가 사용자 대신 선정 불가.'
|
||||
checked_at: 2026-06-17T17:46:35
|
||||
- advisor: design-advisor
|
||||
decision: skip
|
||||
rationale: '윤곽 카탈로그 깊이 명시 제약(DDL/API/시퀀스 금지). 설계 산출 아님.'
|
||||
checked_at: 2026-06-17T17:46:35
|
||||
- advisor: implementation-advisor
|
||||
decision: skip
|
||||
rationale: '당장 구현 아님. 코드 0줄.'
|
||||
checked_at: 2026-06-17T17:46:35
|
||||
|
||||
# Decisions
|
||||
|
||||
- 코드사실(tag/review 테이블 무·Interceptor 미구현·/game/** 핸들러 미등록 등)은 검증된 그대로 유지(사용자 제약).
|
||||
- 미결질문은 해소하지 않고 합의된 목록으로만 정리(합의된 방향 + 잔여 미결 형식).
|
||||
- 착수순서는 5기능 합의 후 마지막에 확정.
|
||||
- W3-1: 태그 통합 1테이블, 정렬 매트릭스(태그 일치도 가중×2차키), 개발자 검색. 결합 C1~C7(C5 조회수·C6 W3-2의존·C7 user조인 신규).
|
||||
- W3-2: 리뷰=별점5+서술, 다축 후속. 댓글 권한 작성자+운영자. 리뷰 수정=이력보존+"수정됨"표시. 평점 계약 W2-3 동결 후 정합. Q6(리뷰 단위) 신규. 기존 닉네임(QG-2) 미결 유지.
|
||||
- W3-3: W1 완료 후 착수(임시 체크 안 함). 카테고리 DB. 본문 마크다운(sanitize). 외부링크 OG 미리보기. 유니티블로그=외부 피드 감시(Q6 신규). 댓글 안 붙임. 외부 fetch 인프라 결합 신규.
|
||||
- W3-4: 잼 노출=별도 그리드 대신 검색창 아래 배너+신규작 강조→클릭 시 잼 태그 검색(W3-1). 현 정렬 유지. 페이지네이션 도입. 단계 착수 가능.
|
||||
- W3-5: deferred 유지. 조사 항목 7개 유지. 업로드 권한·QG-3 조사 단계로.
|
||||
- 착수순서 확정: W3-2 → W3-1 → W3-4 → W3-3 → W3-5.
|
||||
|
||||
# Open Items
|
||||
|
||||
- 미커밋(커밋은 사용자 지시 대기 — 프로젝트 커밋 정책):
|
||||
- docs/work-log/2026-06-17-w3-feature-skeletons.md (??) — 5기능 합의 반영 완료, status:confirmed
|
||||
- docs/work-log/index.md (M) — W3 엔트리 status confirmed 동기화
|
||||
- .atp/work-session/20260617-174635/ (??) — 본 세션 산출(report + w3-2 리뷰 파킹 노트)
|
||||
- .atp/work-session/20260617-172407/ (??) — 직전(초안 생성) 세션 산출
|
||||
- W3 잔여 미결(착수 시 design 단계 확정): 각 기능 *잔여* 항목 + QG-1(W3-5 임시체크)·QG-2·QG-3
|
||||
|
||||
# user_signals
|
||||
positive: []
|
||||
negative:
|
||||
- quote: '너무 축약적이라 W3-1에 대한 질문이 뭔질 모르겠어'
|
||||
structural: true # 회고에서 재분류 — 압축 경향이 결정 제시 단계로 누수되는 메커니즘은 재현 가능(§2.3 (c))
|
||||
note: 'W3-1 마무리 질문을 ID 약어(C3/C6/(가))·표로 과압축해 사용자가 질문 내용을 파악 못 함. caveman 압축 경향이 사용자 대면 의사결정 제시에 번진 것. 결정 제시는 항상 배경+선택지+권장을 풀어 쓴다. memory_candidate decision-prompt-no-compression-spell-out + protocol_feedback 연결.'
|
||||
checked_at: 2026-06-17T17:52
|
||||
|
||||
# verified_by_me
|
||||
|
||||
- 코드 변경 0줄(src/pom.xml 클린) → L1/L2 검증 스크립트 비해당. verification-advisor skip: no-code.
|
||||
- 문서 일관성 자체검증: 최종 W3 doc 전문 재독 — 결합표 5행 ↔ 각 기능 결합/의존 정합, QG-1~3 ↔ 기능별 Q 정합, 착수순서 ↔ 의존 사슬 정합 확인.
|
||||
- work-log/index.md 의 W3 doc 엔트리 status draft→confirmed 동기화 완료.
|
||||
|
||||
# needs_user_verification
|
||||
|
||||
- (선택) 커밋 여부 — 아래 open_items 참조. 사용자 지시 시 커밋.
|
||||
|
||||
# graph_refresh
|
||||
|
||||
skip: no-scope-change — 코드 변경 0(docs only). src scope 그래프 영향 없음. (atp-graphify add-on 존재하나 scope 변경 없어 비실행.)
|
||||
|
||||
# Retrospective
|
||||
|
||||
Retrospective:
|
||||
signals:
|
||||
positive:
|
||||
- quote_or_paraphrase: '(풀어쓰기 전환 후) 항목별로 자유텍스트 + AskUserQuestion 팝업을 혼용해 막힘 없이 답변'
|
||||
about: 'orchestrator 가 약어/표 과압축에서 배경+선택지+권장 풀어쓰기로 전환한 직후의 의사결정 제시 — 교정이 즉효였음을 사용자 응답 흐름이 검증'
|
||||
- quote_or_paraphrase: '5기능 항목별 keep/제거/수정/추가 합의가 advisor 재호출 없이 끝까지 완료'
|
||||
about: 'advisor 전체 skip + orchestrator 가 사용자와 직접 구동한 결정 (사용자 대신 선정 불가한 합의 대화는 orchestrator 직접 구동이 본분)'
|
||||
- quote_or_paraphrase: '항목별 펼침 대화에서 W3-1↔W3-2(C6), W3-4→W3-1 잼태그 라우팅 등 결합 3건을 사용자가 받아들이고 문서 반영'
|
||||
about: '미결질문을 ID 압축 대신 기능별·항목별로 펼쳐 보여준 진행 방식 — 기능 간 결합을 표면화하는 효용이 검증됨'
|
||||
negative:
|
||||
- quote_or_paraphrase: '너무 축약적이라 W3-1에 대한 질문이 뭔질 모르겠어'
|
||||
about: 'orchestrator 가 W3-1 마무리 결정을 ID 약어(C3/C6/(가))·표로 과압축해 사용자가 질문 내용을 파악 못 함. caveman 압축 경향이 사용자 대면 의사결정 제시 단계로 번짐'
|
||||
structural: true # report.md user_signals 엔 false 로 기록됐으나, 압축 출력이 결정 제시 단계로 누수되는 메커니즘은 재현 가능 → 회고에서 structural 로 재분류
|
||||
what_went_well:
|
||||
- 압축 과밀 신호를 받은 직후 배경+선택지+권장 풀어쓰기로 전환했고, 사용자가 곧바로 매끄럽게 항목별 응답(자유텍스트 + AskUserQuestion 혼용) → 회복 탄력성 양호.
|
||||
- advisor 3종(requirements/design/implementation) 전체 skip 판단이 적절했고(사용자 직접 합의 대화·윤곽 카탈로그 깊이 제약·코드 0줄), 그 결과 재호출 없이 5기능 합의 완료.
|
||||
- 자유텍스트와 AskUserQuestion 팝업을 혼용해 사용자가 형식에 갇히지 않고 답하게 함.
|
||||
- 미결질문을 기능별·항목별로 펼친 진행이 W3-1↔W3-2·W3-4→W3-1 등 기능 간 결합 발굴을 표면화.
|
||||
- 코드 0줄에 맞춰 L1/L2·verification-advisor·graph_refresh 비실행 판단이 일관됨(문서 일관성 자체검증으로 대체).
|
||||
what_to_improve:
|
||||
- 사용자 대면 의사결정 제시문(질문)에 출력 압축(약어·ID 참조·표 과밀)을 적용하지 말 것. 결정 제시는 항상 배경 → 선택지 → 권장을 풀어 쓴다. 압축은 에이전트 간 내부 산출물·로그·요약에 한정.
|
||||
- 첫 제시부터 풀어쓰기를 기본값으로 삼고, 압축형은 사용자가 명시 요청(예: "요약만") 했을 때만 사용. 신호를 받은 뒤 전환하는 것은 1회 왕복 비용을 발생시킴.
|
||||
memory_candidates:
|
||||
- name: decision-prompt-no-compression-spell-out
|
||||
type: feedback
|
||||
description: 사용자 대면 의사결정 제시문(질문)에는 caveman/약어 압축을 적용하지 말고 배경+선택지+권장을 풀어 쓴다. 압축은 내부 산출물 한정.
|
||||
body_draft: |
|
||||
W3 골자 합의 세션(20260617-174635)에서 orchestrator 가 W3-1 마무리 질문을
|
||||
ID 약어(C3/C6/(가))와 표로 과압축해 제시 → 사용자: "너무 축약적이라
|
||||
W3-1에 대한 질문이 뭔질 모르겠어". 풀어쓰기로 전환하니 즉시 매끄럽게 답변.
|
||||
|
||||
**Why:** 출력 토큰을 줄이려는 압축 경향(caveman 류)이 사용자가 *답을 줘야 하는*
|
||||
의사결정 제시문으로 번지면, ID 참조·표는 작성자에겐 자명해도 사용자에겐
|
||||
"무엇을 묻는지" 자체가 불투명해진다. 압축의 적용 대상 경계가 잘못 그어진 것.
|
||||
에이전트 간 내부 산출물·로그·요약은 압축이 ROI 양수지만, 사용자 결정 제시는
|
||||
파악 실패 → 재질의 왕복 비용이 압축 절감을 초과한다.
|
||||
|
||||
**How to apply:** 사용자에게 결정/선택을 요청하는 제시문은 항상
|
||||
① 배경(왜 묻는지, 무엇에 걸린 결정인지) ② 선택지(각 옵션을 ID 가 아닌 문장으로)
|
||||
③ 권장(있으면 이유와 함께) 을 풀어 쓴다. ID 약어·교차참조표는 *보조*로만 병기.
|
||||
압축형은 사용자가 "요약만" 등 명시 요청했을 때만. AskUserQuestion 팝업을 쓰더라도
|
||||
옵션 라벨/설명은 자기완결적이어야 한다(외부 표 참조 금지).
|
||||
관련: caveman-bundle-compression-roi-ceiling(번들 정적 압축 ROI 천장 — 적용 *대상* 축은 다르나 둘 다 압축 적용 경계 교훈).
|
||||
rationale_for_saving: 코드/문서로 유도 불가하고 관찰로만 드러나는 출력 스타일 교훈. 동일 메커니즘(압축 경향의 결정 제시 단계 누수)이 어떤 대면 대화에서도 재발 가능. bibimbap 프로젝트 첫 memory.
|
||||
signal_source: negative
|
||||
docs_sync_target: null # 내부 작업 흐름(에이전트 출력 스타일) 교훈 → MEMORY 단독. 단 protocol_feedback 로 ATP 출력 규약 반영 제안 별도.
|
||||
protocol_feedback:
|
||||
- agent-team-protocol 의 출력 스타일/압축 규약에 "사용자 대면 의사결정 제시문은 압축 비적용(배경+선택지+권장 풀어쓰기)" 예외 규칙을 명문화 제안. caveman/토큰 다이어트 지침이 있다면 그 적용 범위를 "에이전트 간 내부 산출물·로그·요약"으로 한정하고, 사용자 질문/AskUserQuestion 옵션 라벨은 자기완결 서술을 요구하도록 가드 추가. (structural negative 신호에서 도출)
|
||||
applied_changes:
|
||||
- orchestrator 결정(사용자 지시): memory_candidate `decision-prompt-no-compression-spell-out` 를 MEMORY 대신 docs 에 반영.
|
||||
→ docs/development/agent-output-conventions.md 신설 + development/index.md 링크. (사용자 "메모리에 말고 docs에 남기자")
|
||||
- W3 골자 doc + index 동기화 + 세션 산출 커밋: 15b8bc3 (feat/v2).
|
||||
|
||||
# ended_at
|
||||
2026-06-18
|
||||
|
|
@ -1,414 +0,0 @@
|
|||
---
|
||||
phase: design
|
||||
agent: design-advisor
|
||||
agent_version: 1
|
||||
generated_at: 2026-06-18T12:10:00+09:00
|
||||
concerns:
|
||||
- "동결영역(W2-3 평점 집계 계약) 비침범 확인: game_reviews 는 rating 컬럼(평점 공급원)까지만 정의. 집계 컬럼/뷰/트리거를 만들지 않음. 후속 집계가 SELECT AVG(rating)/COUNT 로 읽을 수 있도록 rating(NOT NULL, 1~5 CHECK)·is_delete·game_id 인덱스만 보장. 집계 컬럼 신설은 명시적으로 비목표."
|
||||
- "동결영역(schema.sql 비권위 타입) 비신뢰 확인: game_reviews 신규 DDL 의 인접 타입(users.id, games.id)을 schema.sql 비권위 복원본에서 복사하지 않고 recruit_posts 권위 스타일(bigint nextval, timestamptz, partial index, ON DELETE CASCADE 미사용)을 기준으로 작성. game_comments user_id 추가도 동일 권위 스타일."
|
||||
- "시그니처 inflate 재확인 필요: GameReviewsMapper.getGameReview / GameCommentsMapper.listGameComments / isOperator(role) 의 모든 인자가 구현에서 실제 사용되는지 구현 단계 unused 진단 게이트(프로토콜 §11.2)에서 재확인. 본 설계는 최소 인자 원칙으로 명세했으나 헬퍼(isOperator)는 inflate 유혹 영역."
|
||||
- "운영자 role 부여 경로 부재(W1 연결): ROLE_ADMIN 상수는 정의하나 실제 ADMIN 부여자가 코드에 없음(USER 만 발급). isOperator 분기는 단위테스트로만 검증 가능. 운영 환경에서 ADMIN 사용자 생성 경로는 W1 작업 범위 — 본 설계 범위 밖."
|
||||
concerns_checked: true
|
||||
references:
|
||||
requirements: null
|
||||
research: /Users/wemadeplay/workspace/stz/bibimbap/.atp/work-session/20260618-104034/research/code-coupling.md
|
||||
adrs:
|
||||
- /Users/wemadeplay/workspace/stz/bibimbap/docs/recruit-posts-ddl.sql
|
||||
- /Users/wemadeplay/workspace/stz/bibimbap/docs/security-hardening-ddl.sql
|
||||
- /Users/wemadeplay/workspace/stz/bibimbap/docs/security/security-remediation-checklist.md
|
||||
---
|
||||
|
||||
# 설계: W3-2 게임 댓글/리뷰 분리 (서버 영속화 + 리뷰 신설)
|
||||
|
||||
## 목표 / 비목표
|
||||
|
||||
### 목표
|
||||
- (G1) 게임 상세 댓글을 **localStorage → 서버 영속화**로 전환. 작성자 = 로그인 사용자(user_id 귀속). content 200자 제한.
|
||||
- (G2) 게임당 1회 **리뷰(별점 1~5 + 서술 평가)** 도메인 신설. 수정 시 "수정됨" 마커 + 이력 보존.
|
||||
- (G3) 댓글/리뷰 수정·삭제 권한 = `작성자 본인 OR 운영자급 role`. 운영자 분기는 단위테스트로 검증 가능.
|
||||
- (G4) 게임 soft-delete 시 game_reviews 동반 정리(cascade) 추가.
|
||||
- (G5) 보안 체크리스트 line 101~117(댓글/리뷰 해당분) 동시 충족: CSRF 게이트 / 길이 제한 / 작성자·운영자 삭제 / 서버 escape·textContent / 서버 응답 기준 렌더 / 새로고침·브라우저변경 영속.
|
||||
- (G6) DDL 3종 산출(schema.sql 블록, docs 권위 파일, idempotent ALTER).
|
||||
|
||||
### 비목표
|
||||
- 좋아요(localStorage) 변경 — **범위 밖, 미변경**.
|
||||
- 평점 집계 컬럼/뷰/트리거 신설 — **범위 밖**(W2-3 동결 계약 보호). rating 공급원까지만.
|
||||
- 다축(육각형) 평점 — **후속**. DDL 은 단일 rating 컬럼으로 확정하되 향후 축 테이블 분리 여지를 주석으로만 남김.
|
||||
- 기존 localStorage 댓글 마이그레이션 — **비마이그레이션 확정**.
|
||||
- UI/JSP/CSS 비주얼 구현 — **별도 `/frontend-design` 위임**. 본 설계는 API 계약 + escape 규약 + textContent 규약 + data 형태만 명시.
|
||||
- 운영자(ADMIN) 사용자 부여 경로 — W1 연결, 범위 밖(상수만 정의).
|
||||
|
||||
---
|
||||
|
||||
## 개요
|
||||
|
||||
프로젝트는 **controller→mapper 직결**(서비스 계층 없음), **커스텀 HttpSession 인증 + 커스텀 CsrfTokens**(Spring Security 부재), **MyBatis annotation + 명시 시퀀스 PostgreSQL**, **soft-delete(is_delete) 규약**이다(research 종합). W3-2 는 이 패턴을 그대로 따라 ① 기존 orphan 인 `GameCommentsMapper`/`game_comments` 를 서버 API 로 연결(user_id 컬럼 nullable 추가)하고, ② 신규 `game_reviews` 도메인(테이블·POJO·Mapper·컨트롤러)을 recruit_posts 권위 스타일로 추가한다.
|
||||
|
||||
표준 상태변경 시퀀스는 RecruitController.createRecruitPost(`RecruitController.java:49-143`)를 골격으로, 작성자/운영자 권한 분기는 GameController(`GameController.java:183-185`, `:239-241`)를 합성한다. 신규 운영자 분기(`isOperator`)는 session attr `role`(`UserController.java:508`)을 `ROLE_ADMIN` 상수와 비교한다.
|
||||
|
||||
---
|
||||
|
||||
## 플로우
|
||||
|
||||
### F1. 댓글 작성 (POST /game/{id}/comments)
|
||||
1. 진입: `@Transactional`
|
||||
2. `CsrfTokens.isValid(request)` 실패 → 403 `CsrfTokens.errorBody()`
|
||||
3. `sessionUserId(session)` null → 401 `{status:401,message:"로그인이 필요합니다."}`
|
||||
4. 게임 존재 확인 `gamesMapper.getGame(id)` null → 404
|
||||
5. content `trimToNull` → null 또는 `length()>200` → 400 `"덧글은 200자 이내로 입력해 주세요."`
|
||||
6. POJO 세팅(gameId, userId, content; nickname = session displayName 스냅샷) → `gameCommentsMapper.addGameComment`
|
||||
7. 생성 id null → 500
|
||||
8. 종단: 200 JSON `{status:200, message, commentId, gameId, content, authorName, userId, createdAt}` (프론트가 textContent 로 즉시 append 가능한 data 형태)
|
||||
|
||||
### F2. 댓글 목록 조회
|
||||
- **초기 진입은 model 주입**: `GameController.gameDetail(:103-129)` 의 DB 게임 분기(`:104-109`)에서 `addGameModel` 이후 `model.addAttribute("comments", gameCommentsMapper.listGameComments(id))` 추가. 정적 GameCatalog 폴백 분기(`:111-128`)는 DB 미존재 게임이므로 빈 리스트(`model.addAttribute("comments", List.of())`).
|
||||
- **작성·수정·삭제 이후 갱신은 fetch GET API**: `GET /game/{id}/comments` → JSON 배열. (완전 서버화 = 초기 model 주입 + mutation 이후 fetch 재조회 혼합. 명시 확정.)
|
||||
|
||||
### F3. 댓글 수정 (PUT /game/{id}/comments/{commentId})
|
||||
1~3. (F1 과 동일: Transactional → CSRF → 로그인)
|
||||
4. `gameCommentsMapper.getGameComment(commentId)` null → 404. `gameId` 불일치 → 404(경로 위변조 방지).
|
||||
5. **권한**: `userId.equals(comment.getUserId()) || isOperator(role)` 거짓 → 403 `"작성자만 수정할 수 있습니다."` (단, comment.userId == null 인 레거시 닉네임 댓글은 작성자 매칭 불가 → 운영자만 수정 가능)
|
||||
6. content 200자 검증(F1-5 동일)
|
||||
7. `gameCommentsMapper.editGameComment` (content 갱신, is_delete/deleted_at 비변경)
|
||||
8. 200 JSON
|
||||
|
||||
### F4. 댓글 삭제 (DELETE /game/{id}/comments/{commentId})
|
||||
1~5. (F3 과 동일 권한 분기)
|
||||
6. `gameCommentsMapper.softDeleteGameComment(commentId)` (is_delete=true, deleted_at=now())
|
||||
7. 200 JSON `{status:200, message}`
|
||||
|
||||
### F5. 리뷰 작성 (POST /game/{id}/reviews)
|
||||
1~4. (Transactional → CSRF → 로그인 → 게임 존재)
|
||||
5. rating: `Integer` 파싱 실패 또는 `<1 || >5` → 400 `"별점은 1~5 사이로 선택해 주세요."`
|
||||
6. body(서술) `trimToEmpty` → `length()>1000` → 400 (recruit description 1200 대비 보수적 1000자)
|
||||
7. **게임당 1회**: `gameReviewsMapper.getActiveReviewByGameAndUser(gameId, userId)` 존재 → 409 `"이미 이 게임에 리뷰를 작성하셨습니다."` (앱레벨 선검사 + DB partial UNIQUE 가 2차 방어)
|
||||
8. `gameReviewsMapper.addGameReview` (DB UNIQUE 위반 시 DataIntegrityViolation → ApiExceptionControllerAdvice 가 처리하거나 사전 409 가 차단)
|
||||
9. 생성 id null → 500
|
||||
10. 200 JSON `{status:200, message, reviewId, gameId, rating, body, authorName, userId, edited:false, createdAt, updatedAt}`
|
||||
|
||||
### F6. 리뷰 수정 (PUT /game/{id}/reviews/{reviewId}) — "수정됨" + 이력 보존
|
||||
1~3. (Transactional → CSRF → 로그인)
|
||||
4. `gameReviewsMapper.getGameReview(reviewId)` null → 404. gameId 불일치 → 404.
|
||||
5. 권한: `userId.equals(review.getUserId()) || isOperator(role)` 거짓 → 403.
|
||||
6. rating/body 검증(F5-5,6 동일)
|
||||
7. **이력 보존(in-row 채택, 근거는 데이터 모델 절)**: 수정 전 `updated_at = now()` 갱신. `created_at` 불변. → `edited` 판별식 `updated_at > created_at`. (별도 history 테이블 미채택 — 노출은 "수정됨" 마커만, 이력 열람권한 이월.)
|
||||
8. `gameReviewsMapper.editGameReview` (rating, body, updated_at=now() 갱신)
|
||||
9. 200 JSON (`edited:true`)
|
||||
|
||||
### F7. 리뷰 조회
|
||||
- **목록**: `GET /game/{id}/reviews` → JSON 배열 (또는 게임 상세 model 주입 `reviews`). 댓글과 동일하게 초기 model 주입 + mutation 후 fetch 혼합.
|
||||
- **단건**: `GET /game/{id}/reviews/{reviewId}` → JSON 단건.
|
||||
|
||||
### F8. 리뷰 삭제 (DELETE /game/{id}/reviews/{reviewId})
|
||||
1~5. (F6 권한 분기 동일)
|
||||
6. `gameReviewsMapper.softDeleteGameReview(reviewId)` (is_delete=true, deleted_at=now())
|
||||
7. 200 JSON
|
||||
|
||||
### F9. 게임 삭제 cascade (기존 deleteGame 확장)
|
||||
`GameController.deleteGame(:243-245)` 의 cascade 블록에 한 줄 추가:
|
||||
```
|
||||
gamesMapper.softDeleteGameComments(id); // 기존
|
||||
gamesMapper.softDeleteGameReviews(id); // 신규 추가 (review = soft-delete 채택, comments 미러)
|
||||
gamesMapper.deleteGameLikes(id); // 기존 (좋아요 미변경)
|
||||
gamesMapper.softDeleteGame(id); // 기존
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 데이터 모델
|
||||
|
||||
### D1. game_comments 변경 (비파괴, QG-2)
|
||||
- 추가 컬럼: `user_id bigint NULL REFERENCES "users"("id")` — 작성자 귀속. **NULL 허용**(기존 레코드/레거시 닉네임 댓글 보존, 파괴적 마이그레이션 없음).
|
||||
- 기존 컬럼(id/game_id/nickname/content/created_at/deleted_at/is_delete) 전부 유지.
|
||||
- **content 200자 제약 권위 = 앱레벨**(컨트롤러 검증). DB CHECK 미적용. 근거: ① 기존 컬럼 타입이 `text`(길이 무제한)이고 운영 DB 실제 타입이 비권위(schema.sql:8-11)라 DB CHECK 추가가 기존 레코드와 충돌 위험, ② recruit_posts 도 길이는 앱레벨 검증(`RecruitController.java:80-114`)으로만 처리하고 DB CHECK 는 enum 값(role/participation_type)에만 사용하는 선례. → 200자는 앱레벨 권위, DB 는 무제한 text 유지.
|
||||
- FK 는 `ON DELETE CASCADE` 미사용(앱레벨 cascade 규약). user soft-delete 시 댓글 user_id 는 dangling 가능하나 조회는 user JOIN 없이 nickname 스냅샷으로 표시(아래).
|
||||
|
||||
#### 댓글 작성자 표시명 전략
|
||||
- INSERT 시 `nickname` 에 **작성 시점 session displayName 스냅샷**을 저장(기존 nickname 컬럼 재사용). 동시에 `user_id` 저장.
|
||||
- 목록 조회 SELECT 는 users JOIN 없이 `nickname` 을 그대로 표시명으로 사용 → 레거시 NULL user_id 댓글(기존 '익명' 닉네임)도 동일 경로로 표시. JOIN 부재로 user soft-delete dangling 무영향.
|
||||
|
||||
### D2. game_reviews 신규 (recruit_posts 권위 스타일)
|
||||
|
||||
| 컬럼 | 타입 | 제약 | 역할 |
|
||||
|---|---|---|---|
|
||||
| id | bigint | PK, DEFAULT nextval('game_reviews_id_seq') | 리뷰 고유 ID |
|
||||
| game_id | bigint | NOT NULL, FK→games(id) | 대상 게임 |
|
||||
| user_id | bigint | NOT NULL, FK→users(id) | 작성자 (리뷰는 댓글과 달리 로그인 필수 → NOT NULL) |
|
||||
| rating | smallint | NOT NULL, CHECK(rating BETWEEN 1 AND 5) | 별점 5점 단일 (향후 다축은 별도 game_review_axes 테이블 분리 — 주석으로만) |
|
||||
| body | text | NULL | 서술 평가 (앱레벨 1000자 제한, DB 무제한) |
|
||||
| created_at | timestamptz | DEFAULT now() NOT NULL | 작성 시각 |
|
||||
| updated_at | timestamptz | DEFAULT now() NOT NULL | 마지막 수정 시각 |
|
||||
| deleted_at | timestamptz | NULL | soft-delete 시각 |
|
||||
| is_delete | boolean | DEFAULT false NOT NULL | soft-delete 플래그 |
|
||||
|
||||
- **게임당 1회 제약**: partial UNIQUE INDEX
|
||||
`CREATE UNIQUE INDEX ux_game_reviews_game_user_active ON game_reviews (game_id, user_id) WHERE is_delete IS NOT TRUE;`
|
||||
(security-hardening 의 active-unique 선례 `ux_user_auth_identities_..._active` 와 동형. soft-delete 된 리뷰는 제약 제외 → 삭제 후 재작성 허용.)
|
||||
- **"수정됨" 판별 = in-row `updated_at > created_at`** (별도 boolean/edit_count 컬럼 불요). 채택 근거: ① 기존 테이블 전부 created_at/updated_at 쌍 보유(games/recruit_posts), ② 추가 컬럼 0개로 inflate 회피, ③ 노출 요구가 "수정됨" 마커 단일이라 횟수 불필요.
|
||||
- **이력 보존 = in-row 채택(별도 history 테이블 미생성)**. 근거: 노출 요구는 "수정됨" 마커만이고 이력 **열람** 권한은 이월(범위 밖). history 테이블은 열람 UI·권한이 정해질 때(후속) 신설하는 편이 inflate 회피에 부합. 현재는 `updated_at` 으로 "수정 발생 사실"만 보존. (history 가 필요해지면 game_review_history 를 후속 추가 — 본 설계의 in-row 결정과 충돌하지 않음.)
|
||||
- FK `ON DELETE CASCADE` 미사용(앱레벨 cascade). 게임 삭제 시 `softDeleteGameReviews(gameId)` 로 정리(F9).
|
||||
- 인덱스: `CREATE INDEX idx_game_reviews_game ON game_reviews (game_id) WHERE is_delete = false;` (목록 조회 + 후속 집계 SELECT 의 game_id 필터용. **집계 컬럼/뷰는 만들지 않음** — W2-3 동결 보호.)
|
||||
|
||||
### D3. POJO (data/GameReviewData.java 신규)
|
||||
필드: `Long id, Long gameId, Long userId, Integer rating, String body, OffsetDateTime createdAt, OffsetDateTime updatedAt, OffsetDateTime deletedAt, String authorName`(목록 JOIN alias, 비영속), `Boolean edited`(`updated_at > created_at` SELECT 계산 alias, 비영속).
|
||||
- GameCommentData 변경: `Long userId` 필드 추가(나머지 기존 유지).
|
||||
|
||||
---
|
||||
|
||||
## 외부 계약 (HTTP API)
|
||||
|
||||
응답은 전부 `ResponseEntity<Map<String,Object>>` JSON `{status,message,...}`. 조회 GET 은 게임 상세 진입 시 model 주입 + 별도 fetch GET 은 JSON 배열.
|
||||
|
||||
### 댓글 (5 엔드포인트)
|
||||
| # | 메서드 | URL | 요청 | 성공 | 에러 |
|
||||
|---|---|---|---|---|---|
|
||||
| C1 | GET | /game/{id}/comments | — | 200 `{status,comments:[{commentId,gameId,authorName,userId,content,createdAt}]}` | 404(게임없음) |
|
||||
| C2 | POST | /game/{id}/comments | body: `content`(form param) | 200 `{status,commentId,gameId,authorName,userId,content,createdAt}` | 403 CSRF / 401 / 404 / 400(공백·201자+) |
|
||||
| C3 | PUT | /game/{id}/comments/{commentId} | `content` | 200 `{status,commentId,content}` | 403 CSRF / 401 / 404 / 403(권한) / 400 |
|
||||
| C4 | DELETE | /game/{id}/comments/{commentId} | — | 200 `{status,message}` | 403 CSRF / 401 / 404 / 403(권한) |
|
||||
|
||||
(C2 의 200자 거부: `content.length() > 200` → 400. 201자 입력은 거부.)
|
||||
|
||||
### 리뷰 (6 엔드포인트)
|
||||
| # | 메서드 | URL | 요청 | 성공 | 에러 |
|
||||
|---|---|---|---|---|---|
|
||||
| R1 | GET | /game/{id}/reviews | — | 200 `{status,reviews:[{reviewId,gameId,authorName,userId,rating,body,edited,createdAt,updatedAt}]}` | 404 |
|
||||
| R2 | GET | /game/{id}/reviews/{reviewId} | — | 200 `{status,review:{...}}` | 404 |
|
||||
| R3 | POST | /game/{id}/reviews | `rating`(1~5), `body` | 200 `{status,reviewId,...,edited:false}` | 403 CSRF / 401 / 404 / 400(rating·body) / 409(중복) |
|
||||
| R4 | PUT | /game/{id}/reviews/{reviewId} | `rating`, `body` | 200 `{status,reviewId,...,edited:true}` | 403 CSRF / 401 / 404 / 403(권한) / 400 |
|
||||
| R5 | DELETE | /game/{id}/reviews/{reviewId} | — | 200 `{status,message}` | 403 CSRF / 401 / 404 / 403(권한) |
|
||||
|
||||
> 엔드포인트 총합 = 댓글 4 + 리뷰 5 = **9 mutation/fetch 엔드포인트** (C1/R1/R2 GET 3, C2~C4 댓글 mutation 3, R3~R5 리뷰 mutation 3). AC-AGG-1 에서 전수 검증.
|
||||
|
||||
### 컨트롤러 배치
|
||||
- 댓글: 신규 `controller/api/GameCommentController.java` (game_comments 도메인 전담; GameController 비대화 회피).
|
||||
- 리뷰: 신규 `controller/api/GameReviewController.java`.
|
||||
- 두 컨트롤러 모두 RecruitController/GameController 와 동일한 private 헬퍼(`sessionUserId`, `trimToNull`, `trimToEmpty`, `response`) 복붙 패턴 유지(프로젝트 기존 관행 — 3곳 복붙 선례). **새 추상화/서비스 계층 도입 금지**(범위 밖, inflate 회피).
|
||||
|
||||
---
|
||||
|
||||
## 권한 모델
|
||||
|
||||
```java
|
||||
// 운영자 role 상수 (신규). UserController.ROLE_USER="USER"(:43) 와 동일 위치 관행.
|
||||
public static final String ROLE_ADMIN = "ADMIN"; // 운영자 role 값. 실제 부여자 없음(W1 연결).
|
||||
|
||||
// isOperator: 인자는 role 문자열 1개만 — 최소 인자 원칙. (inflate 회피)
|
||||
private boolean isOperator(String role) { // role: session attr "role" 스냅샷 (UserController.java:508)
|
||||
return ROLE_ADMIN.equals(role);
|
||||
}
|
||||
|
||||
// 권한 합성: 작성자 본인 OR 운영자
|
||||
// authorUserId 는 댓글/리뷰의 user_id (댓글은 NULL 가능 → 레거시는 작성자 매칭 불가, 운영자만)
|
||||
private boolean canModify(Long currentUserId, Long authorUserId, String role) {
|
||||
// currentUserId: 현재 로그인 사용자 (sessionUserId)
|
||||
// authorUserId: 대상 글 작성자 user_id
|
||||
// role: 현재 사용자 role (운영자 분기용)
|
||||
return (authorUserId != null && authorUserId.equals(currentUserId)) || isOperator(role);
|
||||
}
|
||||
```
|
||||
|
||||
- role 획득: `(String) session.getAttribute("role")` (로그인 시 `UserController.java:508` 저장). 비로그인은 4번 단계(sessionUserId null)에서 이미 401 차단되므로 role 은 로그인 사용자 한정.
|
||||
- 비로그인 → 401. 권한없음 → 403 `"작성자만 수정/삭제할 수 있습니다."`.
|
||||
- GameController:183-185(수정)/239-241(삭제) 작성자 패턴에 isOperator OR 분기를 합성한 것이 canModify.
|
||||
|
||||
---
|
||||
|
||||
## 게임 삭제 cascade
|
||||
|
||||
- **GamesMapper 신규 메서드** (comments soft-delete 미러):
|
||||
```java
|
||||
@Update("""
|
||||
UPDATE game_reviews
|
||||
SET is_delete = true, deleted_at = COALESCE(deleted_at, now())
|
||||
WHERE game_id = #{gameId} AND is_delete IS NOT TRUE
|
||||
""")
|
||||
int softDeleteGameReviews(@Param("gameId") long gameId);
|
||||
```
|
||||
- **GameController.deleteGame** cascade 블록(`:243-245`)에 `gamesMapper.softDeleteGameReviews(id);` 한 줄 추가(F9 순서). 좋아요는 미변경.
|
||||
|
||||
---
|
||||
|
||||
## 파일 영향 맵
|
||||
|
||||
| 변경 유형 | 경로 | 역할 |
|
||||
|---|---|---|
|
||||
| 변경 | `db/schema.sql` | dev 블록에 game_comments user_id 컬럼 추가 + game_reviews CREATE 블록 추가 |
|
||||
| 신규 | `docs/game-reviews-ddl.sql` | game_reviews 권위 DDL (recruit-posts-ddl.sql 선례) |
|
||||
| 신규 | `docs/game-reviews-ddl.sql` 동봉 또는 별도 `docs/game-comments-user-id-ddl.sql` | 기존 DB 적용용 idempotent ALTER (game_comments user_id + game_reviews) — security-hardening-ddl.sql DO $$ 패턴 |
|
||||
| 변경 | `src/main/java/.../data/GameCommentData.java` | `Long userId` 필드 + getter/setter 추가 |
|
||||
| 신규 | `src/main/java/.../data/GameReviewData.java` | 리뷰 POJO |
|
||||
| 변경 | `src/main/java/.../mapper/GameCommentsMapper.java` | listGameComments / editGameComment / softDeleteGameComment 추가, getGameComment/addGameComment SELECT·INSERT 에 user_id 반영 |
|
||||
| 신규 | `src/main/java/.../mapper/GameReviewsMapper.java` | 리뷰 CRUD 매퍼 |
|
||||
| 변경 | `src/main/java/.../mapper/GamesMapper.java` | softDeleteGameReviews 추가 |
|
||||
| 신규 | `src/main/java/.../controller/api/GameCommentController.java` | 댓글 API (C1~C4) |
|
||||
| 신규 | `src/main/java/.../controller/api/GameReviewController.java` | 리뷰 API (R1~R5), ROLE_ADMIN 상수·isOperator·canModify |
|
||||
| 변경 | `src/main/java/.../controller/api/GameController.java` | gameDetail(:107) model 에 comments/reviews 주입 + deleteGame(:243) cascade 한 줄 |
|
||||
| 변경(위임) | `src/main/webapp/WEB-INF/views/game-detail.jsp` | 댓글 localStorage JS(:807-1009 중 댓글부) → fetch 교체, 리뷰 위젯 추가 — **/frontend-design 위임** |
|
||||
| 신규(test) | `src/test/.../GameCommentControllerTest.java` | CSRF/200자/권한/운영자 분기 |
|
||||
| 신규(test) | `src/test/.../GameReviewControllerTest.java` | 게임당1회/rating/수정됨/운영자 분기 |
|
||||
|
||||
### DDL 3종 골격
|
||||
|
||||
**① `db/schema.sql` (dev 블록 내 game_comments 직후 추가)**
|
||||
```sql
|
||||
-- game_comments user_id 컬럼 (W3-2: 작성자 귀속, nullable 비파괴)
|
||||
ALTER TABLE "game_comments" ADD COLUMN IF NOT EXISTS "user_id" bigint REFERENCES "users"("id");
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- game_reviews (권위 DDL — docs/game-reviews-ddl.sql 와 동일. W3-2 신규)
|
||||
-- ---------------------------------------------------------------------------
|
||||
CREATE SEQUENCE IF NOT EXISTS "game_reviews_id_seq";
|
||||
CREATE TABLE IF NOT EXISTS "game_reviews" (
|
||||
"id" bigint DEFAULT nextval('game_reviews_id_seq'::regclass) NOT NULL,
|
||||
"game_id" bigint NOT NULL REFERENCES "games"("id"),
|
||||
"user_id" bigint NOT NULL REFERENCES "users"("id"),
|
||||
"rating" smallint NOT NULL,
|
||||
"body" text,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"deleted_at" timestamp with time zone,
|
||||
"is_delete" boolean DEFAULT false NOT NULL,
|
||||
PRIMARY KEY ("id"),
|
||||
CONSTRAINT "game_reviews_rating_check" CHECK ("rating" BETWEEN 1 AND 5)
|
||||
);
|
||||
ALTER SEQUENCE "game_reviews_id_seq" OWNED BY "game_reviews"."id";
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "ux_game_reviews_game_user_active"
|
||||
ON "game_reviews" ("game_id", "user_id") WHERE "is_delete" IS NOT TRUE;
|
||||
CREATE INDEX IF NOT EXISTS "idx_game_reviews_game"
|
||||
ON "game_reviews" ("game_id") WHERE "is_delete" = false;
|
||||
-- 향후 다축(육각형) 확장 시: rating 유지 + game_review_axes(review_id, axis, score) 별도 테이블 분리. 집계 컬럼/뷰는 W2-3 동결 — 신설 금지.
|
||||
```
|
||||
|
||||
**② `docs/game-reviews-ddl.sql` (권위 파일)** — 위 game_reviews CREATE + 시퀀스 + UNIQUE/일반 인덱스 + FK/CHECK 를 DO $$ idempotent 블록(recruit-posts-ddl.sql 형식) + COMMENT ON COLUMN 전 컬럼. rating/body/edited 의미 주석.
|
||||
|
||||
**③ `docs/game-reviews-ddl.sql` 하단 또는 동봉 ALTER 섹션 (기존 DB 적용용 idempotent)**
|
||||
```sql
|
||||
-- game_comments user_id (멱등)
|
||||
ALTER TABLE "game_comments" ADD COLUMN IF NOT EXISTS "user_id" bigint;
|
||||
DO $$ BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname='game_comments_user_id_fkey') THEN
|
||||
ALTER TABLE "game_comments" ADD CONSTRAINT "game_comments_user_id_fkey"
|
||||
FOREIGN KEY ("user_id") REFERENCES "users"("id");
|
||||
END IF;
|
||||
END $$;
|
||||
-- game_reviews: CREATE SEQUENCE/TABLE IF NOT EXISTS + DO $$ FK/CHECK + CREATE UNIQUE INDEX IF NOT EXISTS (위 ① 와 동일, 멱등 보장)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 신규 시그니처 (inflate 방지 — 각 인자 사용 목적 인라인)
|
||||
|
||||
### GameCommentsMapper (변경)
|
||||
```java
|
||||
List<GameCommentData> listGameComments(long gameId); // gameId: 목록 필터 (is_delete IS NOT TRUE)
|
||||
int editGameComment(GameCommentData c); // c: id+content (content 만 갱신)
|
||||
int softDeleteGameComment(long id); // id: 대상 댓글 (is_delete=true, deleted_at=now())
|
||||
// getGameComment: SELECT 에 user_id AS userId 추가. addGameComment: INSERT 에 user_id 추가.
|
||||
```
|
||||
- listGameComments SELECT: `id AS commentId? → id, game_id AS gameId, nickname AS authorName, user_id AS userId, content, created_at AS createdAt FROM game_comments WHERE game_id=#{gameId} AND is_delete IS NOT TRUE ORDER BY created_at ASC, id ASC`. (users JOIN 없음 — nickname 스냅샷 표시.)
|
||||
|
||||
### GameReviewsMapper (신규)
|
||||
```java
|
||||
GameReviewData getGameReview(long id); // id: 단건/권한확인
|
||||
List<GameReviewData> listGameReviews(long gameId); // gameId: 목록 필터
|
||||
GameReviewData getActiveReviewByGameAndUser(@Param("gameId") long gameId, @Param("userId") long userId); // 게임당1회 선검사
|
||||
int addGameReview(GameReviewData r); // r: gameId/userId/rating/body
|
||||
int editGameReview(GameReviewData r); // r: id/rating/body (updated_at=now() SET 문 명시)
|
||||
int softDeleteGameReview(long id); // id: is_delete=true
|
||||
```
|
||||
- list/get SELECT 의 edited alias: `(updated_at > created_at) AS edited`. authorName: users JOIN `u.display_name AS authorName`(리뷰는 user_id NOT NULL 이므로 JOIN 안전, `u.is_delete IS NOT TRUE` 필터 — soft-delete 사용자 리뷰는 목록서 누락 가능, 허용).
|
||||
|
||||
### isOperator / canModify
|
||||
- 위 권한 모델 절 참조. **inflate 재확인 대상**(concerns 마킹): isOperator(role) 단일 인자, canModify(currentUserId, authorUserId, role) 3인자 — 전부 본문에서 사용. 구현 시 unused 발생하면 즉시 제거.
|
||||
|
||||
---
|
||||
|
||||
## 보안 (체크리스트 line 101~117 댓글/리뷰 해당분 충족 매핑)
|
||||
|
||||
| 체크리스트 line | 충족 방식 |
|
||||
|---|---|
|
||||
| 105 `GET /game/{id}/comments` 또는 모델 주입 결정 | F2: 초기 model 주입 + mutation 후 fetch GET(C1) 혼합 — 확정 |
|
||||
| 106 POST 댓글 CSRF/길이/작성자 | F1: CsrfTokens.isValid + 200자 앱레벨 + user_id 귀속 |
|
||||
| 107 댓글 삭제 작성자/관리자 | F4 canModify(작성자 OR isOperator) |
|
||||
| 108 서버 댓글도 escape/textContent | 서버 렌더 시 HtmlUtils.htmlEscape(JSP), 클라이언트 동적삽입 textContent (research 포인트9 규약 유지) |
|
||||
| 110 localStorage UI 서버 응답 기준 교체 | F1~F4 fetch + 초기 model 주입으로 localStorage 댓글부 제거(위임: frontend-design) |
|
||||
| 114 새로고침/브라우저변경 영속 | 서버 DB 영속(localStorage 비의존) |
|
||||
| 115 토큰 없는 변경 실패 | 전 mutation 첫 게이트 CsrfTokens.isValid → 403 |
|
||||
| 116 XSS payload 미실행 | escape/textContent (108) |
|
||||
| 117 게임 삭제 시 정리 | F9 softDeleteGameComments(기존) + softDeleteGameReviews(신규) |
|
||||
|
||||
- 좋아요 관련 line(101~104)은 범위 밖 — 본 설계 미해결(좋아요 미변경 명시).
|
||||
|
||||
---
|
||||
|
||||
## 프론트엔드 경계 (/frontend-design 위임)
|
||||
|
||||
본 설계가 제공하는 위임 입력:
|
||||
- **소비 API 계약**: 위 댓글 C1~C4 / 리뷰 R1~R5 표(URL·메서드·요청 param·응답 JSON 형태).
|
||||
- **CSRF 규약**: 모든 mutation 요청에 `BibimbapCsrf.headers()` (theme-init.jsp:19-31) 또는 `_csrf` 파라미터. 메타 `csrf-token` 전역 제공됨.
|
||||
- **escape 규약**: 서버 렌더(JSP scriptlet `<%= HtmlUtils.htmlEscape(...) %>`); 클라이언트 동적 삽입은 `textContent`(innerHTML 금지, listEl 초기화 `innerHTML=''` 만 허용).
|
||||
- **필요 data 형태**: 댓글 `{commentId,authorName,userId,content,createdAt}`; 리뷰 `{reviewId,authorName,userId,rating,body,edited,createdAt,updatedAt}`. `edited:true` 일 때 "수정됨" 마커 표시. 별점 위젯은 rating 1~5 정수 송수신.
|
||||
- **소유자/권한 힌트**: 응답의 `userId` 와 로그인 사용자(`owner` 모델 또는 별도 노출) 비교로 수정·삭제 버튼 노출 결정(서버가 최종 권한 재검증).
|
||||
|
||||
**위임 경계(본 설계 비포함)**: 실제 JSP 마크업, CSS, 별점 위젯 비주얼/인터랙션, "수정됨" 마커 위치·스타일.
|
||||
|
||||
---
|
||||
|
||||
## 대안 비교
|
||||
|
||||
| 결정 | 채택 | 대안 | 채택 근거 |
|
||||
|---|---|---|---|
|
||||
| 댓글/리뷰 분리 | 2 테이블 (game_comments 변경 + game_reviews 신규) | 단일 테이블 type 컬럼 | rating/edited 등 리뷰 전용 컬럼이 댓글에 dead → 사용자 plan gate 확정 |
|
||||
| content 200자 권위 | 앱레벨 검증 | DB CHECK | 기존 text 컬럼·비권위 운영타입·recruit 선례(길이는 앱레벨) |
|
||||
| "수정됨" 판별 | in-row updated_at>created_at | boolean edited / edit_count | 추가 컬럼 0개, 기존 created/updated 쌍 활용, 노출요구 마커 단일 |
|
||||
| 이력 보존 | in-row(updated_at) | 별도 game_review_history | 이력 열람 권한 이월(범위 밖) → 후속 신설이 inflate 회피 |
|
||||
| 게임당 1회 | partial UNIQUE WHERE is_delete IS NOT TRUE | 전체 UNIQUE | soft-delete 후 재작성 허용 + security-hardening active-unique 선례 |
|
||||
| 댓글 작성자 표시 | nickname 스냅샷(JOIN 없음) | users JOIN display_name | 레거시 NULL user_id·user soft-delete dangling 무영향 |
|
||||
| 리뷰 cascade | soft-delete | hard-delete | comments 미러(soft) 일관성 |
|
||||
|
||||
---
|
||||
|
||||
## 롤아웃 / 마이그레이션
|
||||
|
||||
1. **DDL 선적용**: 기존 DB → idempotent ALTER(③) 실행 (game_comments user_id 추가 + game_reviews 생성). 신규 환경은 schema.sql(①)로 자동. 둘 다 `IF NOT EXISTS`/`DO $$` 멱등.
|
||||
2. **역호환**: game_comments user_id NULL 허용 → 기존 레코드 무손상. orphan 이던 GameCommentsMapper 가 컨트롤러 연결돼도 기존 SELECT(getGameComment) 컬럼 추가는 alias 만 늘어 호환.
|
||||
3. **배포 순서**: DDL → 백엔드(매퍼/컨트롤러) → 프론트(/frontend-design). 프론트 미배포 상태에서도 백엔드 API 는 독립 동작(기존 localStorage UI 가 잠시 공존 가능, 비파괴).
|
||||
4. **롤백**: 컨트롤러/매퍼 revert 시 game_reviews 테이블은 잔존(데이터 무손실). game_comments user_id 컬럼은 nullable 이라 revert 후에도 무해. 파괴적 DROP 불요.
|
||||
5. **localStorage 댓글**: 비마이그레이션(확정). 사용자 브라우저 로컬 데이터는 방치(자연 소멸).
|
||||
|
||||
---
|
||||
|
||||
## 검증 포인트 (AC)
|
||||
|
||||
> §4.3 전수 체크 + §4.7 self-audit(시점 안정성·표현 견고성) 적용.
|
||||
|
||||
### 기능 AC (원 요청 매핑)
|
||||
- **AC-1 (댓글 CRUD)**: 로그인 사용자가 C2 작성 → C1 목록에 등장, C3 수정 반영, C4 삭제 후 C1 에서 누락. 단위/통합 테스트 4건. (시점: 테스트 내 자족 — 안정.)
|
||||
- **AC-2 (비작성자 불가 + 운영자 예외)**: 사용자 A 작성 댓글을 사용자 B(role=USER)가 C3/C4 → 403. 사용자 C(role=ADMIN)는 C3/C4 → 200. 단위테스트로 isOperator 분기 검증. (운영자 부여자 없음 → 테스트에서 session role="ADMIN" 주입.)
|
||||
- **AC-3 (리뷰 게임당 1회)**: 동일 user+game R3 두 번째 → 409. soft-delete(R5) 후 R3 재작성 → 200 (partial UNIQUE 검증).
|
||||
- **AC-4 (수정 시 "수정됨" + 이력 보존)**: R3 직후 응답 `edited:false`(updated_at==created_at). R4 후 R1/R2 응답 `edited:true`(updated_at>created_at). created_at 불변 확인.
|
||||
- **AC-5 (댓글 201자 거부)**: C2/C3 에 201자 content → 400. 200자 경계 → 200 (off-by-one 경계 테스트).
|
||||
- **AC-6 (rating 범위)**: R3/R4 rating 0 또는 6 → 400. 1·5 경계 → 200.
|
||||
- **AC-7 (CSRF 없는 상태변경 실패)**: C2/C3/C4/R3/R4/R5 를 X-CSRF-Token·_csrf 없이 호출 → 전부 403. (표현: 헤더/파라미터 둘 다 부재 케이스. UserControllerCsrfTest 선례 형식.)
|
||||
- **AC-8 (XSS payload 미실행)**: content/body 에 `<script>` payload 저장 → JSP 서버 렌더는 `<script>` escape, 클라이언트 textContent 는 문자열 표시. 스크립트 미실행. (검증: 렌더 출력에 raw `<script>` 부재 — escape 확인.)
|
||||
- **AC-9 (영속성)**: C2/R3 후 새 세션/브라우저로 C1/R1 조회 → 데이터 잔존(DB 영속, localStorage 비의존).
|
||||
- **AC-10 (게임 삭제 cascade)**: deleteGame 후 해당 game_id 의 game_comments·game_reviews 전부 is_delete=true. softDeleteGameReviews 호출 검증.
|
||||
|
||||
### 집합 전수 AC (§4.3)
|
||||
- **AC-AGG-1 (엔드포인트 전수 9건)**: 댓글 컨트롤러 매핑 4건(@GetMapping C1 + @PostMapping C2 + @PutMapping C3 + @DeleteMapping C4) + 리뷰 컨트롤러 매핑 5건(R1 R2 GET + R3 POST + R4 PUT + R5 DELETE) == 9.
|
||||
- 검증(불변식, 시점 안정): `grep -cE '@(Get|Post|Put|Delete)Mapping' src/main/java/.../GameCommentController.java` == 4 **AND** `... GameReviewController.java` == 5. (두 파일 합 9. 컨트롤러 파일 한정 → 다른 매핑 오염 없음.)
|
||||
- §4.7 시점: 두 컨트롤러는 본 작업 산출물이며 구현 완료 시점에 고정 — verification 시점에도 동일. 안정.
|
||||
- §4.7 표현: 매핑 애너테이션은 Spring 고정 토큰(동의 표현 없음) → 리터럴 grep 견고. 단 메서드 수가 아니라 매핑 애너테이션 수를 센다(헬퍼 메서드 오카운트 방지).
|
||||
- **AC-AGG-2 (DDL 3종 산출 전수)**: ① schema.sql 에 `game_reviews` CREATE TABLE 블록 존재(`grep -c 'CREATE TABLE IF NOT EXISTS "game_reviews"' db/schema.sql` >= 1) + game_comments user_id ADD COLUMN 존재. ② `docs/game-reviews-ddl.sql` 파일 존재(ls). ③ idempotent ALTER 섹션(②파일 내 `ADD COLUMN IF NOT EXISTS "user_id"` + `DO $$` 블록 존재). 3종 모두 충족.
|
||||
- **AC-AGG-3 (CSRF 게이트 전수)**: 댓글/리뷰 mutation 6개 핸들러(C2 C3 C4 R3 R4 R5) 전부 진입부 `CsrfTokens.isValid(request)` 호출. `grep -c 'CsrfTokens.isValid' (두 컨트롤러)` == 6. (시점: 산출물 고정. 표현: 메서드명 고정 토큰.)
|
||||
|
||||
### §4.7 self-audit 1패스 결과
|
||||
- AC-AGG-1/AGG-3: 카운트 대상이 **본 작업이 만드는 신규 파일**이라 verification 시점까지 값 불변(자기 트리 증가 대상 아님 — 20260616 AC-3 류 함정 회피). 고정 스칼라 허용. 표현은 Spring/메서드 고정 토큰이라 동의표현 누락 위험 없음.
|
||||
- AC-8(XSS): 단일 리터럴 grep 의존 회피 — "raw `<script>` 부재 AND escape 출력 존재"의 의미 불변식 + 수동 렌더 확인 병행(escape 함수가 `<`로 바꾸는지). 표현 견고성 확보.
|
||||
- AC-3/AC-4: 테스트 내 자족 데이터로 시점 독립.
|
||||
|
||||
---
|
||||
|
||||
## 미해결 / 에스컬레이션
|
||||
- 없음(전 결정 확정). 단 frontmatter `concerns` 4건은 **동결영역 비침범 확인 기록 + inflate 재확인 마킹 + W1 의존**으로, 차단 이슈가 아니라 구현/검증 시 점검 포인트. orchestrator 반환만 하고 요구사항 수정은 하지 않음.
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
---
|
||||
phase: documentation
|
||||
agent: documentation-advisor
|
||||
agent_version: 1
|
||||
generated_at: "2026-06-18T14:00:00+09:00"
|
||||
concerns:
|
||||
- "design-advisor가 세션 내에서 design.md를 생성했으나 docs/architecture/ 갱신은 수행하지 않았음. W3-2 도메인 추가가 architecture/ 구조 설명에 반영이 필요한지 추후 검토 대상."
|
||||
- "L3 브라우저 스모크(XSS·영속·cascade DB) 및 DDL 적용이 needs_user_verification 상태. 완료 후 security-remediation-checklist.md의 [~] 항목을 [x]로 갱신 필요."
|
||||
- "운영자 ROLE_ADMIN 부여 경로는 W1 RBAC 연결 시 활성. W1 완료 후 보안 체크리스트 별도 항목 검토 필요."
|
||||
concerns_checked: true
|
||||
---
|
||||
|
||||
# 문서화 보고
|
||||
|
||||
## 작성/수정된 문서
|
||||
|
||||
| 경로 | 카테고리 | 유형 | 링크 추가한 index | 교차 링크 |
|
||||
|---|---|---|---|---|
|
||||
| `docs/changes/2026-06-18-w3-2-comments-reviews.md` | changes | 신규 | `docs/changes/index.md` | `docs/work-log/2026-06-17-w3-feature-skeletons.md`, `docs/security/security-remediation-checklist.md` |
|
||||
| `docs/changes/index.md` | changes | 기존 갱신 | — | — |
|
||||
| `docs/security/security-remediation-checklist.md` | security | 기존 갱신 | — | `docs/changes/2026-06-18-w3-2-comments-reviews.md` |
|
||||
| `docs/work-log/2026-06-17-w3-feature-skeletons.md` | work-log | 기존 갱신(§W3-2 상태 1줄) | — | `docs/changes/2026-06-18-w3-2-comments-reviews.md` |
|
||||
| `.atp/work-session/20260618-104034/documentation.md` | — | 산출물(본 파일) | — | — |
|
||||
|
||||
## 의사결정 기록 위치
|
||||
|
||||
- **plan gate 결정 2건** (댓글 완전 서버화 / 휴면 운영자 경로): `.atp/work-session/20260618-104034/report.md` §Decisions
|
||||
- **seed 반전 발견** (댓글·좋아요 localStorage 전용, 운영자 role 부재): `.atp/work-session/20260618-104034/research/code-coupling.md`
|
||||
- **설계 권위 명세** (DDL 3종, API 9개, AC 13): `.atp/work-session/20260618-104034/design.md`
|
||||
- **QG-2 비파괴 결정** (user_id NULL + 레거시 보존): `.atp/work-session/20260618-104034/report.md` §Decisions (orchestrator 브리프 이월 기본값)
|
||||
|
||||
## 추후 문서화가 필요한 항목
|
||||
|
||||
- **L3 스모크 완료 후**: `docs/security/security-remediation-checklist.md` B3 [~] 항목 → [x] 갱신. 특히 XSS 브라우저 미실행, 영속성 브라우저 재방문 확인.
|
||||
- **DDL 적용 완료 후**: `docs/maintenance/` 또는 운영 절차 문서에 game_reviews DDL 적용 이력 기록 검토(현재 docs/game-reviews-ddl.sql이 권위 DDL로 존재).
|
||||
- **W1 RBAC 완료 후**: 운영자 role 부여 경로 활성화 내용을 `docs/security/security-remediation-checklist.md` B3 및 관련 changes/ 에 추가.
|
||||
- **W2-6 시상 집계 구현 후**: game_reviews 평점 공급원 → 집계 계약(SELECT AVG/COUNT) 이행 내용을 changes/ 에 별도 기록.
|
||||
- **좋아요 영속화 착수 시**: B3 체크리스트 좋아요 항목(101~104) 별도 변경 이력 문서 작성.
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
---
|
||||
phase: implementation
|
||||
agent: implementation-advisor
|
||||
agent_version: 1
|
||||
generated_at: 2026-06-18T11:20:00+09:00
|
||||
---
|
||||
|
||||
# 파일 소유권 맵 — W3-2 댓글/리뷰 분리 (백엔드 only)
|
||||
|
||||
직접 작성 채택 사유: 파일 11개이나 POJO→Mapper→Controller→Test 가 강한 상호의존(필드명·시그니처·SQL alias 가 한 줄이라도 어긋나면 컴파일/매핑 실패). 1파일 1worker 분산 시 worker 간 계약 동기화 비용 > 병렬 이득. 오케스트레이터 지시(파일 상호의존 시 직접 작성 허용) + 프로토콜 §11.2 계량 근거(파일수 11 > 8 이나 줄수 다수 < 500 이고 cross-file 계약 결합도 최상)로 advisor 직접 Write/Edit 선택.
|
||||
|
||||
| 파일 | 담당 | 변경 유형 | 의존 |
|
||||
|---|---|---|---|
|
||||
| db/schema.sql | advisor | modify | - |
|
||||
| docs/game-reviews-ddl.sql | advisor | create | - |
|
||||
| src/main/java/com/pandoli365/bibimbap/data/GameCommentData.java | advisor | modify | - |
|
||||
| src/main/java/com/pandoli365/bibimbap/data/GameReviewData.java | advisor | create | - |
|
||||
| src/main/java/com/pandoli365/bibimbap/mapper/GameCommentsMapper.java | advisor | modify | GameCommentData |
|
||||
| src/main/java/com/pandoli365/bibimbap/mapper/GameReviewsMapper.java | advisor | create | GameReviewData |
|
||||
| src/main/java/com/pandoli365/bibimbap/mapper/GamesMapper.java | advisor | modify | - |
|
||||
| src/main/java/com/pandoli365/bibimbap/controller/api/GameCommentController.java | advisor | create | GameCommentsMapper, GamesMapper, GameCommentData |
|
||||
| src/main/java/com/pandoli365/bibimbap/controller/api/GameReviewController.java | advisor | create | GameReviewsMapper, GamesMapper, GameReviewData |
|
||||
| src/main/java/com/pandoli365/bibimbap/controller/api/GameController.java | advisor | modify | GameCommentsMapper, GameReviewsMapper, GamesMapper |
|
||||
| src/test/java/com/pandoli365/bibimbap/controller/api/GameCommentControllerTest.java | advisor | create | GameCommentController |
|
||||
| src/test/java/com/pandoli365/bibimbap/controller/api/GameReviewControllerTest.java | advisor | create | GameReviewController |
|
||||
|
||||
planned_workers: 0 (직접 작성 선택)
|
||||
actual_workers: 0
|
||||
|
||||
## 불변식 점검
|
||||
- 동일 파일 1소유: OK (전부 advisor 단독)
|
||||
- game-detail.jsp 제외: /frontend-design 위임 (스코프 명시)
|
||||
- DDL DB 적용 금지: 파일 작성만
|
||||
|
|
@ -1,281 +0,0 @@
|
|||
---
|
||||
schema_version: 2
|
||||
session_id: 20260618-104034
|
||||
resumed_from: null
|
||||
started_at: 2026-06-18T10:40:34+09:00
|
||||
ended_at: 2026-06-18T13:20:00+09:00
|
||||
user_request: |
|
||||
W3-2 댓글/리뷰 분리 기능을 설계·구현한다.
|
||||
- game_comments 로그인 연동 전환 + content 200자 제한
|
||||
- game_reviews 신규 (게임당 1회, 별점 5점 + 서술 평가)
|
||||
- 댓글 수정/삭제 권한: 작성자 본인 + 운영자
|
||||
- 리뷰 수정: 가능 + 이력 보존, 노출은 "수정됨" 마커만
|
||||
- 보안: CSRF 검증, XSS escape, 작성자 권한 체크
|
||||
- 자율 진행: 미결은 안전 기본값으로 진행 + 이월 기록. 데이터 손실/하류 파손 결정만 사용자 확인.
|
||||
- 프론트는 /frontend-design 스킬 사용.
|
||||
acceptance criteria:
|
||||
- 로그인 사용자 댓글 작성/수정/삭제, 비작성자 불가(운영자 예외)
|
||||
- 리뷰 게임당 1회, 수정 시 "수정됨" 마커 + 이력 보존
|
||||
- 댓글 201자 이상 거부
|
||||
- CSRF 토큰 없는 상태변경 실패
|
||||
- XSS payload 미실행
|
||||
- 새로고침/브라우저 변경 후 영속
|
||||
---
|
||||
|
||||
# Summary
|
||||
W3-2 댓글/리뷰 분리 기능을 설계·구현했다. research 가 작업 브리프의 seed 가정 2건을 뒤집었다(① 댓글·좋아요가 서버 미연동 localStorage 전용이고 서버 매퍼는 orphan, ② 운영자 role 이 코드에 부재—USER만 발급). §2.7-5 plan gate 로 사용자 확정 후, 댓글을 서버 영속화(fetch API + user_id 귀속 + 200자) + game_reviews 도메인 신설(게임당 1회 partial UNIQUE, 별점 1~5, 수정됨=updated_at>created_at in-row, 휴면 운영자 경로)로 진행했다.
|
||||
|
||||
백엔드 14파일(DDL 3종 + POJO/Mapper/Controller 신규·변경 + 테스트 2), 프론트(game-detail.jsp 댓글 서버화 + 리뷰 UI·별점 위젯·수정됨 마커, /frontend-design 스킬)를 구현했다. 검증 1차에서 BibimbapApplicationTests.contextLoads 회귀(신규 매퍼 @MockBean 누락) 1건이 잡혀 §2.6 backward re-dispatch 로 발원(implementation 테스트 scaffolding)을 진단·전수재검 후 2개 @MockBean 추가로 해소. 최종 L1 31 테스트 PASS + AGG 전수 PASS. L3(브라우저 XSS·영속·cascade DB)는 needs_user_verification. DDL 미적용(§6 게이트 — 사용자 DB 적용 대기).
|
||||
|
||||
# Advisor Invocation Decision Log
|
||||
# 각 advisor 호출/스킵 판단 즉시 1줄 append
|
||||
- advisor: requirements-advisor
|
||||
decision: skip
|
||||
rationale: '요청에 FR/in/out/이월 기본값/AC 가 전부 명시됨. 단 옵션 공간 판정은 design 산출 이후로 보류(프로토콜 §1).'
|
||||
checked_at: 2026-06-18T10:40:34+09:00
|
||||
- advisor: graphify-lookup-advisor
|
||||
decision: call
|
||||
rationale: '코드 구조 조사 1차 진입점. game_comments/games/로그인·세션/CSRF/JSP 댓글/DDL 적용방식 결합점 확인 필요.'
|
||||
checked_at: 2026-06-18T10:41:00+09:00
|
||||
result: 'src scope graph.json 미생성(no-graph). docs scope만 hit(DDL/스키마 부트스트랩). 코드 포인트 7/7 miss → research 필요.'
|
||||
- advisor: research-advisor
|
||||
decision: call
|
||||
rationale: 'lookup 7/7 miss. 댓글 CRUD·게임상세·로그인세션·CSRF·DDL적용·RecruitController·GameLikes 코드 결합점 직접 조사 필요. parallel-explorer 병렬.'
|
||||
checked_at: 2026-06-18T10:45:00+09:00
|
||||
- advisor: graphify-update-advisor (src scope 재생성)
|
||||
decision: defer
|
||||
rationale: '구현으로 src 변경 예정 → 지금 재생성하면 이중 작업. 세션 종료 전 graph-refresh 단계에서 일괄 재생성(no-defer 정책은 그 시점 처리로 충족).'
|
||||
checked_at: 2026-06-18T10:45:00+09:00
|
||||
- advisor: research-advisor
|
||||
decision: re-call
|
||||
rationale: '1차 호출이 async worker 6개 spawn 후 취합 전 rest 복귀 — code-coupling.md 미산출. SendMessage 미제공으로 재개 불가. 강한 블로킹 지시로 재호출(worker TaskOutput 대기 + 파일 디스크 기록 후에만 반환).'
|
||||
checked_at: 2026-06-18T10:52:00+09:00
|
||||
|
||||
# Invocations
|
||||
- id: inv-000
|
||||
layer: orchestrator
|
||||
name: orchestrator
|
||||
parent_invocation_id: null
|
||||
started_at: 2026-06-18T10:40:34+09:00
|
||||
input_digest: 'W3-2 댓글/리뷰 분리 설계·구현 요청 (자율 진행 모드)'
|
||||
output_digest: 'init 가드 통과, atp:migrate 마커 없음(skip), work-session 생성, 프로토콜 로드'
|
||||
artifacts: ['.atp/work-session/20260618-104034/report.md']
|
||||
concerns: []
|
||||
- id: inv-001
|
||||
layer: advisor
|
||||
name: graphify-lookup-advisor
|
||||
parent_invocation_id: inv-000
|
||||
input_digest: '코드 구조 7포인트 graph 인덱스 조회'
|
||||
output_digest: 'src scope graph 미생성(no-graph), docs만 hit, 7/7 miss → research 필요'
|
||||
artifacts: []
|
||||
model_choice: { phase: graphify-exec, dispatch_size: direct, tier: small, effort: low, resolved_model: haiku, capped: false, rationale: '인덱스 조회 기계적 판단' }
|
||||
- id: inv-002
|
||||
layer: advisor
|
||||
name: research-advisor
|
||||
parent_invocation_id: inv-000
|
||||
input_digest: '11개 코드 결합점 정밀 조사(file:line)'
|
||||
output_digest: 'research/code-coupling.md — 댓글/좋아요 서버미연동 발견, CSRF/세션 인프라 재사용 가능, 운영자 role 부재'
|
||||
artifacts: ['research/code-coupling.md']
|
||||
model_choice: { phase: analyze, dispatch_size: l-batch, tier: large, effort: high, resolved_model: opus, capped: false, escalation_reason: '탐색적 코드 조사 + 다파일 교차', rationale: '결합점 정확도가 설계 좌우' }
|
||||
notes: '1차 호출(a2177)이 async worker 취합 전 조기복귀 → 강한 블로킹 지시로 재호출(a4873) 성공. 두 호출 모두 동일 결론.'
|
||||
- id: inv-003
|
||||
layer: advisor
|
||||
name: design-advisor
|
||||
parent_invocation_id: inv-000
|
||||
input_digest: 'research + plan gate 결정 → 구현가능 설계'
|
||||
output_digest: 'design.md — DDL 3종/9 API/권한모델/cascade/AC 13(기능10+전수3)'
|
||||
artifacts: ['design.md']
|
||||
model_choice: { phase: design, dispatch_size: l-batch, tier: large, effort: high, resolved_model: opus, capped: false, escalation_reason: '보안·인증·권한 §5.2 자동상승', rationale: 'trade-off 빈번' }
|
||||
- id: inv-004
|
||||
layer: advisor
|
||||
name: implementation-advisor
|
||||
parent_invocation_id: inv-000
|
||||
input_digest: 'design.md 권위 명세 → 백엔드 구현 + 마이그레이션 파일'
|
||||
output_digest: '14파일(DDL3+POJO+Mapper+Controller+test2). test-compile BUILD SUCCESS. workers_spawned=0(직접). implementation/ownership.md'
|
||||
artifacts: ['implementation/ownership.md']
|
||||
model_choice: { phase: code-implementation, dispatch_size: l-batch, tier: large, effort: high, resolved_model: opus, capped: false, escalation_reason: '보안/권한 코드', rationale: '다파일 강결합 직접 작성' }
|
||||
planned_workers: 0
|
||||
actual_workers: 0
|
||||
- id: inv-005
|
||||
layer: orchestrator
|
||||
name: orchestrator (frontend via /frontend-design)
|
||||
parent_invocation_id: inv-000
|
||||
input_digest: 'game-detail.jsp 댓글 서버화 + 리뷰 UI (브리프 지정 /frontend-design 스킬, §1 사용자명시 예외)'
|
||||
output_digest: 'GameController 모델 노출(currentUserId/userRole) + game-detail.jsp HTML/CSS/JS(별점위젯·수정됨·로그인게이트, textContent XSS안전). test-compile SUCCESS'
|
||||
artifacts: ['src/main/webapp/WEB-INF/views/game-detail.jsp']
|
||||
model_choice: { phase: code-implementation, dispatch_size: direct, tier: large, effort: high, resolved_model: inherit, capped: false, rationale: 'orchestrator 본 모델 직접(스킬 가이드)' }
|
||||
- id: inv-006
|
||||
layer: advisor
|
||||
name: verification-advisor
|
||||
parent_invocation_id: inv-000
|
||||
input_digest: 'AC 13 + 실행명령(설계/diff 비접근)'
|
||||
output_digest: '1차 fail(contextLoads 회귀 blocker). 수정 후 재실행 31 PASS + AGG 전수 PASS'
|
||||
artifacts: ['verification.md']
|
||||
model_choice: { phase: validation-static, dispatch_size: s-batch, tier: medium, effort: medium, resolved_model: sonnet, capped: false, rationale: '결정적 테스트/grep 판정' }
|
||||
- id: inv-007
|
||||
layer: orchestrator
|
||||
name: orchestrator (regression fix §2.6)
|
||||
parent_invocation_id: inv-000
|
||||
input_digest: 'contextLoads blocker — 신규 매퍼 @MockBean 누락'
|
||||
output_digest: 'BibimbapApplicationTests 에 GameCommentsMapper/GameReviewsMapper @MockBean 2개 추가(기존 4개 패턴 미러). 재실행 31 PASS'
|
||||
artifacts: ['src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java']
|
||||
model_choice: { phase: code-implementation, dispatch_size: direct, tier: large, effort: low, resolved_model: inherit, capped: false, rationale: '결정적 2줄 마이크로 편집 §1 예외' }
|
||||
|
||||
# Decisions
|
||||
- by: research-advisor + user (plan gate §2.7-5)
|
||||
at: 2026-06-18T11:10:00+09:00
|
||||
decision: '댓글/좋아요 서버 미연동(localStorage 전용) seed 반전 확인. 댓글 완전 서버화 채택(Q1=Recommended).'
|
||||
rationale: 'AC "브라우저 변경 후 영속"이 서버화를 강제. localStorage JS→fetch 교체 포함. 기존 localStorage 댓글 비마이그레이션(보안 [hold] 정합).'
|
||||
related_invocations: [inv-002]
|
||||
- by: user (plan gate §2.7-5)
|
||||
at: 2026-06-18T11:10:00+09:00
|
||||
decision: '운영자 예외 = 휴면 운영자 경로(Q2=Recommended). 권한체크 "작성자 OR 운영자급 role", ADMIN 상수 정의, 부여자 없음(W1 연결).'
|
||||
rationale: '브리프 "W1 완료 시 교체 가능 설계"와 정합. 단위테스트로 운영자 분기 검증, prod 무영향.'
|
||||
related_invocations: [inv-002]
|
||||
- by: orchestrator (브리프 이월 기본값)
|
||||
at: 2026-06-18T11:10:00+09:00
|
||||
decision: '별점 5점 단일 확정(다축 컬럼 확장여지). 댓글/리뷰 2 테이블 분리(game_comments 변경 + game_reviews 신규). 좋아요 범위밖 localStorage 유지. W2-3 집계계약 이월(평점 컬럼만 확정). QG-2 비파괴(user_id nullable + 레거시 표시) — 테이블 사실상 빈 상태 추정.'
|
||||
rationale: '브리프 이월 기본값 + research 결합점. 되돌릴 수 있어 carry-over 안전.'
|
||||
related_invocations: [inv-001, inv-002]
|
||||
|
||||
# Conflicts
|
||||
(없음 — 단일 design-advisor, concerns 4건 모두 동결영역 비침범 자가확인. 충돌 중재 불요.)
|
||||
|
||||
# Regression
|
||||
- surfaced_at_stage: verification (L1 전체 테스트)
|
||||
source_stage: implementation (테스트 scaffolding)
|
||||
defect: 'BibimbapApplicationTests.contextLoads — 신규 GameCommentController/GameReviewController 가 주입하는 GameCommentsMapper/GameReviewsMapper 가 MyBatis autoconfigure exclude 컨텍스트 테스트의 @MockBean 셋에 미등록 → NoSuchBeanDefinitionException'
|
||||
full_set_recheck: true # 컨트롤러 주입 매퍼 전수 점검: {Games,Recruit,UserAuthIdentities,Users,GameComments,GameReviews} 중 누락 2개만 추가하면 완전 확인
|
||||
downstream_rerun: ['L1 전체 테스트 재실행 — 31 PASS']
|
||||
resolved_at: 2026-06-18T12:55:00+09:00
|
||||
|
||||
# verified_by_me
|
||||
- 'L1 typecheck/compile: ./mvnw -o test-compile BUILD SUCCESS'
|
||||
- 'L1 unit+regression: ./mvnw -o test — Tests run 31, Failures 0, Errors 0 (GameCommentControllerTest 12 + GameReviewControllerTest 13 + UserControllerCsrfTest 5 + BibimbapApplicationTests 1). 회귀 0.'
|
||||
- 'AGG-1 엔드포인트: GameCommentController @Mapping==4, GameReviewController==5 (PASS)'
|
||||
- 'AGG-3 CSRF 게이트: CsrfTokens.isValid 합 6 (mutation 6개 전수, PASS)'
|
||||
- 'AGG-2 DDL 3종: schema.sql game_reviews CREATE + game_comments user_id, docs/game-reviews-ddl.sql 존재 + 멱등 ALTER (PASS)'
|
||||
- 'L2: skipped — no-external-dependency (커스텀 세션/CSRF, mock 기반 단위)'
|
||||
|
||||
# needs_user_verification
|
||||
- 'L3 실 톰캣+DB 스모크: 게임 상세 페이지에서 (a) 로그인 후 댓글 작성/수정/삭제, (b) 리뷰 작성→게임당 1회(2번째 409)→수정 시 "수정됨" 표시, (c) <script> payload 입력 후 스크립트 미실행(textContent escape), (d) 새로고침/다른 브라우저에서 영속 확인, (e) 게임 삭제 후 댓글·리뷰 정리 확인.'
|
||||
- 'DDL 적용: [완료 — 로컬 dev] 사용자 승인 후 orchestrator 가 docs/game-reviews-ddl.sql 을 로컬 dev DB(bibimbap-db postgres:16, localhost:5433, schema=dev)에 --single-transaction 적용. game_reviews(컬럼9/제약4/인덱스2) + game_comments.user_id 생성 검증, 멱등 재실행 error 0. **잔여: live 스키마는 배포 시 동일 적용 필요**(현 적용은 dev 한정).'
|
||||
|
||||
# Open Items
|
||||
- 'git 미커밋 잔여: 본 작업 단위(W3-2)의 변경 5 modified + 9 untracked(src) + docs/game-reviews-ddl.sql. 프로젝트 커밋 정책(사용자 요청 시 커밋)에 따라 커밋 대기 — 사용자 확인 후 진행.'
|
||||
- '이월: W2-3 평점 집계 계약(game_reviews 는 평점 공급원까지만, 집계 컬럼/뷰 미생성). W2-6 시상 집계는 후속 SELECT AVG/COUNT 로 소비.'
|
||||
- '이월: 운영자 role 부여 경로 — ROLE_ADMIN="ADMIN" 상수만 정의, 실제 ADMIN 부여자 없음(W1 RBAC/Interceptor 연결 시 활성).'
|
||||
- '이월: 다축(육각형) 평점 — 현재 단일 rating, 향후 game_review_axes 분리 여지(주석).'
|
||||
- '이월: 리뷰 이력 열람 — 현재 in-row(수정됨 마커만), history 테이블은 열람권한 확정 시 후속.'
|
||||
- '범위밖: 좋아요 영속화(여전히 localStorage) — 보안 체크리스트 별도 항목.'
|
||||
- '범위밖: GameCatalog 정적 폴백 게임(DB 미존재)은 댓글/리뷰 mutation 시 404(게임존재 검증). 실 게임만 기능 동작.'
|
||||
|
||||
# graph_refresh
|
||||
- judgment: 'src=no-graph(산출물 부재 — 세션 시작 시점부터 pre-existing, W3-2 무관) + working-tree fully-stale 수준 변경 / docs=partial-stale(신규 문서4 + game-reviews-ddl.sql 미반영)'
|
||||
handling: '커밋 시점 처리(no-defer 정책 — 미래 세션 이월 아님). checker 권고대로 미커밋 tree 에서 graphify 시 source_commit 부정확 → 커밋 직후 /graphify src + /graphify docs 실행 + docs/graph/index.md frontmatter·Scopes 표 갱신. 커밋이 사용자 요청 대기 중이므로 graph 재생성도 커밋 단계에 동반.'
|
||||
|
||||
# Applied Changes (orchestrator — §12 회고 반영)
|
||||
- 'MEMORY task_completion 갱신: 신규 컨트롤러/매퍼 의존 추가 시 BibimbapApplicationTests @MockBean 등록 누락 → contextLoads 실패 함정 + full test 의무 (candidate 2, negative).'
|
||||
- 'docs_sync: docs/development/verification-strategies.md 에 "신규 컨트롤러/매퍼 의존 변경 시 full test 의무" 규칙 추가 (candidate 2 docs_sync_target).'
|
||||
- 'candidate 1(worker-spawn advisor 블로킹+write-before-return): 본 세션에서 선제 적용으로 재발 0. protocol_feedback 로 surface(아래).'
|
||||
- 'candidate 3(plan-gate 마일스톤): changes/2026-06-18 문서가 이미 기록 — 별도 MEMORY 미작성.'
|
||||
- 'protocol_feedback 2건(structural)은 atp 플러그인 `agent-team-protocol.md`(= ~/.claude/ 전역설정) 수정 제안 → §6 전역설정 수정 금지로 orchestrator 가 직접 적용하지 않음. 사용자에게 surface(플러그인 유지자 결정 영역). (1) worker-spawn advisor 블로킹 규약 명문화 (2) implementation 단계 컨트롤러 추가 시 full test 의무.'
|
||||
|
||||
# User Signals
|
||||
user_signals:
|
||||
positive:
|
||||
- quote_or_paraphrase: 'plan gate 2개 질문에 즉시 Recommended 선택(완전 서버화 + 휴면 운영자 경로)'
|
||||
about: 'seed 반전 후 제시한 기본값 방향이 사용자 의도와 정합 — 1회 수락'
|
||||
negative: []
|
||||
|
||||
# Retrospective
|
||||
Retrospective:
|
||||
signals:
|
||||
positive:
|
||||
- quote_or_paraphrase: 'plan gate 2개 질문에 즉시 Recommended 선택(완전 서버화 + 휴면 운영자 경로)'
|
||||
about: 'research가 seed 가정 2건 반전 후 plan gate에서 제시한 기본값 방향(Q1=완전 서버화, Q2=휴면 운영자 경로)이 사용자 의도와 1회 수락으로 정합됨. 비자명한 판단(localStorage 전용 댓글을 완전 서버화로 전환하는 방향, 운영자 role 미정의 상태에서 휴면 경로 채택)이 재확인됨.'
|
||||
negative: []
|
||||
what_went_well:
|
||||
- 'research-advisor가 seed 가정 2건(댓글 서버 미연동, 운영자 role 부재)을 file:line 근거로 반전시키고 plan gate로 사용자 위임한 흐름이 1회 수락으로 완결. 기존 memory [[research-seed-reversal-plan-gate-delegation]]의 패턴이 bibimbap 세션에서도 재현됨.'
|
||||
- 'implementation-advisor가 worker 0(advisor 직접 작성)을 선택한 판단이 옳았음. 파일 12개이나 POJO→Mapper→Controller→Test 강결합으로 분산 시 계약 동기화 비용 > 병렬 이득. 기존 memory [[implementation-advisor-direct-execution-threshold]] 패턴과 일치.'
|
||||
- 'verification-advisor가 §2.6 backward re-dispatch를 발동해 contextLoads 회귀를 blocker 판정 후 발원 단계(implementation 테스트 scaffolding)까지 소급 진단. 컨트롤러 주입 매퍼 전수 재검 후 누락 2개만 정확히 식별.'
|
||||
- 'research-advisor 2차 호출 시 강한 블로킹 지시("worker TaskOutput 대기 + 파일 디스크 기록 후에만 반환")를 넣자 code-coupling.md 정상 산출. 이후 implementation/verification 호출에 같은 지시를 선제 적용해 재발 0.'
|
||||
what_to_improve:
|
||||
- '[패턴 1] research-advisor(tier-3, worker spawn) 가 worker 6개 spawn 후 취합 전 조기복귀. code-coupling.md 미산출 → orchestrator가 SendMessage 없이 재호출. 호출 비용 이중 발생 + 세션 지연. 블로킹 지시가 없으면 advisor가 async spawn 후 결과 대기 없이 반환하는 것이 기본 동작인 것으로 보임. → 프로토콜 수준 대응 필요(protocol_feedback 참조).'
|
||||
- '[패턴 2] implementation-advisor가 test-compile(./mvnw -o test-compile)만 실행하고 full context test(./mvnw -o test)를 생략. BibimbabApplicationTests.contextLoads 회귀 미탐지 → verification에서 뒤늦게 발견. contextLoads는 MyBatis autoconfigure exclude + 신규 컨트롤러 @MockBean 수동 제공 패턴이므로, 컨트롤러 추가 시마다 @MockBean 갱신이 필요한데 이것이 implementation 단계에서 체크되지 않음.'
|
||||
memory_candidates:
|
||||
- name: worker-spawn-advisor-blocking-write-before-return
|
||||
type: feedback
|
||||
description: worker를 spawn하는 advisor는 모든 worker의 TaskOutput 완료 대기 + 산출 파일 디스크 기록 후에만 반환해야 한다. 블로킹 지시 없이 호출하면 async spawn 후 조기복귀 → 산출물 미생성 재호출 비용 발생.
|
||||
body_draft: |
|
||||
advisor가 병렬 worker(parallel-explorer 등)를 spawn할 때, 호출 측이 명시적 블로킹 지시를 넣지 않으면 advisor가 worker TaskOutput을 취합하지 않고 조기복귀하는 사례가 관측됨(20260618-104034 research-advisor 1차 호출: worker 6개 spawn 후 code-coupling.md 미산출 복귀).
|
||||
|
||||
**Why:** SendMessage 툴이 호스트 컨텍스트에 미제공인 경우 advisor가 subagent 재개 수단이 없어 결과를 기다리지 않고 반환할 수 있다. 강한 블로킹 지시를 명시하면 advisor가 tool 반환값(TaskOutput)을 동기적으로 기다리게 된다.
|
||||
|
||||
**How to apply:**
|
||||
- worker spawn이 예상되는 advisor(research-advisor, analysis-advisor 등) 호출 시 orchestrator는 다음 문구를 프롬프트 마지막에 명시한다:
|
||||
"worker를 spawn한 경우 모든 worker의 TaskOutput을 완료까지 대기하고, 산출 파일을 디스크에 기록한 후에만 반환하라. 결과 취합 전 반환 금지."
|
||||
- 재호출 1회 이내에 성공한 경우라도, 이후 동일 advisor 호출(implementation, verification 포함)에 선제 적용해 재발 차단.
|
||||
- 산출 파일 존재 여부는 orchestrator가 advisor 반환 직후 Glob/Read로 확인 가능.
|
||||
rationale_for_saving: worker spawn 패턴은 research/analysis advisor에서 반복 재현 가능. SendMessage 미제공 환경에서는 구조적으로 재발한다. 코드/커밋으로 유도 불가한 호출 규약 지식.
|
||||
signal_source: negative
|
||||
docs_sync_target: null
|
||||
|
||||
- name: spring-context-test-mockbean-exhaustive-on-new-controller
|
||||
type: feedback
|
||||
description: Spring Boot 컨텍스트 테스트(MyBatis autoconfigure exclude + @MockBean 패턴)에서 신규 컨트롤러 추가 시 해당 컨트롤러가 주입하는 모든 매퍼의 @MockBean을 반드시 등록해야 한다. implementation 단계에서 full context test(./mvnw -o test)를 실행해야 누락 탐지 가능.
|
||||
body_draft: |
|
||||
BibimbapApplicationTests는 DataSource/MyBatis autoconfigure를 exclude하고 컨트롤러가 주입하는 매퍼를 @MockBean으로 수동 제공하는 패턴이다. 이 패턴에서 신규 컨트롤러(GameCommentController, GameReviewController)를 추가할 때 해당 컨트롤러가 주입하는 매퍼(GameCommentsMapper, GameReviewsMapper)의 @MockBean을 BibimbabApplicationTests에 추가하지 않으면 contextLoads가 NoSuchBeanDefinitionException으로 실패한다.
|
||||
|
||||
**Why:** implementation-advisor가 test-compile(./mvnw -o test-compile)만 실행하면 컨트롤러 클래스는 컴파일되지만, full Spring context 로드는 ./mvnw -o test를 실행해야만 검증된다. 컴파일 성공 ≠ contextLoads 통과. 세션 20260618-104034에서 이 미탐지로 verification 단계에서 blocker가 발생했다.
|
||||
|
||||
**How to apply:**
|
||||
- implementation-advisor는 컨트롤러 파일을 추가/변경할 때 반드시 ./mvnw -o test를 실행해 contextLoads 회귀를 탐지해야 한다. test-compile만으로는 불충분.
|
||||
- 신규 컨트롤러 추가 체크리스트: (1) 컨트롤러가 @Autowired/@RequiredArgsConstructor로 주입하는 모든 @Mapper 인터페이스를 나열, (2) BibimbabApplicationTests의 기존 @MockBean 선언(@MockBean GameCommentsMapper 등) 목록과 대조, (3) 누락 항목에 @MockBean 추가.
|
||||
- 이 프로젝트의 현행 @MockBean 목록: GamesMapper, RecruitPostsMapper, UserAuthIdentitiesMapper, UsersMapper, GameCommentsMapper, GameReviewsMapper (W3-2 추가 후 기준).
|
||||
rationale_for_saving: 이 프로젝트 특유의 MyBatis autoconfigure exclude + @MockBean 수동 패턴은 컨트롤러를 추가할 때마다 재발 가능한 구조적 함정. 코드/커밋에서 유도 불가(테스트 파일을 직접 읽어야만 파악 가능). 후속 W3-x, W4-x 세션에서 컨트롤러 추가가 예상되므로 재현성 높음.
|
||||
signal_source: negative
|
||||
docs_sync_target: /Users/wemadeplay/workspace/stz/bibimbap/docs/development/verification-strategies.md
|
||||
|
||||
- name: bibimbap-plan-gate-seed-reversal-two-q-accepted
|
||||
type: project
|
||||
description: W3-2 세션에서 research가 seed 가정 2건 반전 후 plan gate 2질문 즉시 수락. 기본값 방향(완전 서버화 + 휴면 운영자 경로)이 사용자 의도와 정합 확인됨.
|
||||
body_draft: |
|
||||
W3-2(댓글/리뷰 분리) 세션(20260618-104034)에서 research-advisor가 seed 가정 2건을 반전:
|
||||
- GAP-1: 댓글/좋아요가 서버 미연동 localStorage 전용(서버화 가정 깨짐)
|
||||
- GAP-3: 운영자 role이 코드 전체에 부재("USER"만 발급)
|
||||
|
||||
Plan gate 2질문 모두 Recommended(완전 서버화 / 휴면 운영자 경로) 즉시 수락.
|
||||
|
||||
**확인된 패턴:** [[research-seed-reversal-plan-gate-delegation]]이 bibimbap 프로젝트에서도 동작함. seed 반전 + Recommended 기본값 방향 제시 조합이 사용자 의사결정 비용을 최소화한 케이스로 기록.
|
||||
rationale_for_saving: bibimbap 프로젝트 히스토리 마일스톤. W3 진행 중 댓글/좋아요가 localStorage 전용이었다는 사실은 후속 W3-x/W4-x 세션에서 참고 필요. 또한 운영자 경로(ROLE_ADMIN="ADMIN" 상수 정의, 부여자 미구현)가 W1 RBAC 연결 전 휴면 상태라는 결정 이력.
|
||||
signal_source: positive
|
||||
docs_sync_target: null
|
||||
|
||||
protocol_feedback:
|
||||
- issue: 'worker를 spawn하는 advisor(tier-3)의 조기복귀가 프로토콜 허점임. SendMessage 미제공 환경에서 advisor가 async worker spawn 후 TaskOutput 취합 없이 반환하는 동작을 방지하는 명시적 규약이 없다.'
|
||||
structural: true
|
||||
detail: |
|
||||
현상: research-advisor 1차 호출이 worker 6개 spawn 후 취합 전 반환 → code-coupling.md 미산출 → 재호출 비용.
|
||||
근본 원인: 프로토콜에 "worker spawn 후 반환 조건"이 없음. 개별 호출 시 orchestrator가 블로킹 지시를 매번 수동으로 포함해야 해결됨 — 즉 규약이 아니라 ad-hoc 대응.
|
||||
proposed_fix: |
|
||||
agent-team-protocol.md (bibimbap 번들 또는 ATP 원본) 에 다음 규약 추가:
|
||||
§ [worker spawn 완료 조건] advisor가 worker를 spawn하는 경우:
|
||||
1. 모든 worker의 TaskOutput이 도달할 때까지 반환하지 않는다 (blocking-wait).
|
||||
2. 약속된 산출 파일을 디스크에 기록 완료한 것을 확인 후 반환한다.
|
||||
3. orchestrator는 advisor 반환 직후 산출 파일 존재 여부를 Glob/Read로 확인한다. 미존재 시 즉시 블로킹 지시 추가 후 재호출한다.
|
||||
[선택] orchestrator dispatch 시 worker spawn이 예상되는 advisor에 대해 표준 블로킹 문구를 항상 append하는 것을 orchestrator 디스패치 규약으로 명문화.
|
||||
docs_target: docs/development/agent-team-protocol.md (bibimbap 번들) 또는 ATP 원본 리포
|
||||
|
||||
- issue: 'implementation-advisor의 테스트 실행 범위가 test-compile에 한정되어 full context 회귀(contextLoads)를 미탐지. verification 단계에서 blocker로 발견되어 §2.6 backward re-dispatch 비용 발생.'
|
||||
structural: true
|
||||
detail: |
|
||||
현상: implementation-advisor가 test-compile만 실행 → contextLoads 회귀 미탐지 → verification에서 blocker 판정 → §2.6 backward re-dispatch.
|
||||
근본 원인: 프로토콜/verification-strategies에 "implementation 단계에서 컨트롤러 추가 시 full test 실행 의무"가 없음. 컴파일 성공을 단위 검증 완료로 간주하는 암묵적 관행.
|
||||
proposed_fix: |
|
||||
verification-strategies.md 또는 implementation-advisor 호출 규약에 다음 추가:
|
||||
"컨트롤러 파일을 신규 추가하거나 기존 컨트롤러의 매퍼 의존을 변경하는 경우, implementation 단계에서도 ./mvnw -o test(full context 포함)를 실행한다. test-compile만으로는 Spring ApplicationContext 로드 실패를 탐지할 수 없다."
|
||||
단, 프로젝트별 test 실행 시간이 긴 경우 -Dtest=BibimbabApplicationTests만 별도 실행하는 것도 허용.
|
||||
docs_target: /Users/wemadeplay/workspace/stz/bibimbap/docs/development/verification-strategies.md (신규 섹션 "컨트롤러 추가 시 검증 의무")
|
||||
|
||||
applied_changes: []
|
||||
|
|
@ -1,180 +0,0 @@
|
|||
---
|
||||
phase: research
|
||||
agent: research-advisor
|
||||
agent_version: 2
|
||||
generated_at: 2026-06-18T11:05:00+09:00
|
||||
concerns:
|
||||
- "동결/권위 영역: db/schema.sql 의 game_comments/game_likes/games/users 는 '비권위 복원본'(타입 추론). game_reviews 신규 DDL 작성 시 인접 타입을 권위로 신뢰 금지 — recruit_posts(권위) 스타일을 따를 것."
|
||||
- "현존 게임 상세의 댓글/좋아요는 100% 클라이언트 localStorage 다(서버 미연동). W3-2 가 '분리'가 아니라 사실상 '서버 영속화 신설'을 포함함 — 요구사항 advisor 전제(이미 서버 댓글이 있다는 가정)가 있다면 깨짐."
|
||||
- "JSP 두 종 header 혼재: 활성 header 는 views/header.jsp(커스텀 세션·BibimbapCsrf). jsp/fragments/header.jspf 는 Spring Security taglib(sec:authorize, _csrf.parameterName) 기반 미사용 잔재 — 신규 작업에서 절대 참조 금지."
|
||||
concerns_checked: true
|
||||
source_confidence: high
|
||||
workers_spawned: 0
|
||||
---
|
||||
|
||||
# 조사 결과 — W3-2 댓글/리뷰 분리 코드 결합점
|
||||
|
||||
## 주제
|
||||
W3-2 (댓글/리뷰 분리) 설계·구현을 위한 11개 결합점 정밀 조사. 모든 발견은 file:line 근거. 본 산출물은 전부 프로젝트 내부 코드 1차 확인(확인됨). 외부 자료 미사용 → source_confidence: high.
|
||||
|
||||
> 조사 방식: parallel-explorer worker 미사용. 11개 포인트가 동일 소규모 코드베이스(~25 Java + 17 JSP)에 밀결합되어 있어 advisor 가 직접 Read/Grep 으로 전수 확인. 모든 항목 1차 출처 직접 확인됨.
|
||||
|
||||
---
|
||||
|
||||
## 포인트별 발견
|
||||
|
||||
### 포인트 1: 댓글 도메인 CRUD 전체 [확인됨]
|
||||
- **Mapper**: `mapper/GameCommentsMapper.java`
|
||||
- `GameCommentData getGameComment(long id)` — `:13-25` (SELECT, `WHERE id=#{id} AND is_delete IS NOT TRUE`)
|
||||
- `int addGameComment(GameCommentData)` — `:27-39` (INSERT game_id/nickname/content, `@Options(useGeneratedKeys=true, keyProperty="id")`)
|
||||
- `int updateGameComment(GameCommentData)` — `:41-51` (nickname/content/deleted_at 갱신 + `is_delete = CASE WHEN deletedAt IS NULL THEN false ELSE true END`)
|
||||
- **DELETE/list 메서드 없음**. game_id 별 목록 조회 메서드도 없음(soft-delete 일괄은 GamesMapper 에 있음 — 포인트 8).
|
||||
- **POJO**: `data/GameCommentData.java:5-61` — 필드: `Long id, Long gameId, String nickname, String content, OffsetDateTime createdAt, OffsetDateTime deletedAt`. (userId 없음 — 작성자 식별 컬럼 부재, nickname 만 있음)
|
||||
- **컬럼**(db/schema.sql:99-108, 비권위): `id bigint`, `game_id bigint NOT NULL REFERENCES games(id)`, `nickname varchar(100)`, `content text`, `created_at timestamptz DEFAULT now()`, `deleted_at timestamptz`, `is_delete boolean DEFAULT false`. (요청서가 언급한 6컬럼 + is_delete 7개 전부 일치)
|
||||
- **컨트롤러 엔드포인트**: **존재하지 않음**. `GameCommentsMapper` 를 주입/호출하는 컨트롤러 없음(rg 확인). 즉 서버측 댓글 작성/조회/삭제 HTTP API 가 전무.
|
||||
- **서비스 계층**: 없음(프로젝트 전체가 controller→mapper 직결 구조).
|
||||
- **작성/조회/삭제 흐름**: 현재 댓글은 서버 미연동. game-detail.jsp 가 localStorage 로만 처리(포인트 2). GameCommentsMapper 는 사실상 orphan(유일 사용처: 게임 삭제 cascade 의 `GamesMapper.softDeleteGameComments`, 포인트 8).
|
||||
|
||||
### 포인트 2: 게임 상세 페이지 [확인됨]
|
||||
- **핸들러**: `controller/api/GameController.java:103-129` `@GetMapping("/game/{id}") String gameDetail(long id, Model, HttpSession)`.
|
||||
- DB 게임 존재 시 `addGameModel(model, game, sessionUserId(session))` → view `"game-detail"` (`:104-109`).
|
||||
- DB miss 시 `GameCatalog` 정적 폴백(`:111-128`).
|
||||
- **model attribute**(`addGameModel` `:254-268`): `gameId, gameName, creator, likeCount, likeCountFormatted, creatorNote, gitUrl, webglUrl, webglFrameSrc, webglDeployPath, owner`. `owner = currentUserId != null && currentUserId.equals(game.getUserId())` (`:267`).
|
||||
- **game-detail.jsp 댓글/좋아요 실제 코드**(localStorage):
|
||||
- 좋아요 버튼 `#game-like-btn` HTML `:730-735`; 좋아요 JS 전부 localStorage(`LIKE_KEY='bibimbap-game-liked'`) — `getLikedMap :815-823`, `setLiked :825-832`, `localStorage.setItem :830`, 클릭 핸들러 `:904-908` (서버 POST/DELETE 없음).
|
||||
- 댓글 폼 `#game-comment-form` HTML `:790-801` (textarea name="comment" maxlength=1000, 작성자 입력란 없음).
|
||||
- 댓글 JS 전부 localStorage(`COMMENT_KEY='bibimbap-game-comments'`) — `getComments :911-920`, `saveComments :922-930`(`localStorage.setItem :928`), 렌더 `:938-992`, submit 핸들러 `:994-1005`(닉네임 하드코딩 `DEFAULT_NICK='익명' :936`, id=crypto.randomUUID).
|
||||
- 라인 근거: 요청서가 지목한 812(LIKE_KEY)/830(setItem)/913(getComments raw)/928(saveComments setItem) 전부 위치 확정.
|
||||
|
||||
### 포인트 3: 로그인/세션 인증 패턴 [확인됨]
|
||||
- **인증 방식**: Spring Security 아님. **커스텀 HttpSession attribute** 기반.
|
||||
- **로그인 컨트롤러**: `controller/api/UserController.java` — `@PostMapping("/login") :122-168`, `/signup :65-120`, `/logout :170-179`. 로그인 페이지(GET)는 `WebMvcController.mainView` switch `case "login" :75-80`.
|
||||
- **세션 저장**(`UserController.saveLoginSession :502-525`): `session.setAttribute("userId", user.getId())`(Long), 그 외 `id, displayName, email, avatarUrl, role, status, authProvider, authIdentityId, lastLoginAt`, 그리고 `account`(LinkedHashMap 복제본). 로그인 시 `request.changeSessionId() :160`(세션 고정 방어).
|
||||
- **현재 로그인 사용자 얻는 코드**(컨트롤러 공통 헬퍼, 3곳에 동일 복붙): `sessionUserId(HttpSession)` — `GameController:291-307`, `RecruitController:155-171`, `UserController:333-349`. `session.getAttribute("userId")` 를 Number/String→Long 변환, 없으면 null. (WebMvcController 는 `:118-127` 변형 — null 대신 `IllegalStateException` throw.)
|
||||
- **UserData 필드 전체**(`data/UserData.java:5-15`): `Long id, String displayName, String canonicalEmail, String avatarUrl, String role, String status, OffsetDateTime lastLoginAt, createdAt, updatedAt`. **id 타입 Long, role 타입 String**(기본값 "USER", UserController:43 `ROLE_USER="USER"`). 운영자 role 명칭은 코드상 미정의(USER 만 발급됨) — 포인트 6 참조.
|
||||
- **비로그인 처리**: 페이지는 `redirect:/login`(RecruitController:43-46, GameController:133-135, WebMvcController:82-83). AJAX/상태변경 API 는 `401 UNAUTHORIZED + {status,message}` JSON(GameController:57-59 등).
|
||||
|
||||
### 포인트 4: CSRF 현황 (설계 핵심 제약) [확인됨]
|
||||
- **spring-security 의존**: **없음**. pom.xml 의존성 = web, mybatis-spring-boot-starter, postgresql, tomcat-embed-jasper, lombok, starter-tomcat(provided), starter-test(test) (`pom.xml:53-87`). starter-security 부재.
|
||||
- **SecurityConfig / SecurityFilterChain / @EnableWebSecurity**: **클래스 없음**(rg 확인 0건).
|
||||
- **CSRF 인프라**: **커스텀 자체 구현 존재** — `security/CsrfTokens.java`:
|
||||
- `SESSION_ATTRIBUTE="csrfToken" :12`, `HEADER_NAME="X-CSRF-Token" :13`.
|
||||
- `getOrCreate(HttpSession) :20-33`(세션에 토큰 발급/재사용, Base64 32바이트).
|
||||
- `isValid(HttpServletRequest) :35-49` — 헤더 `X-CSRF-Token` 우선, 없으면 파라미터 `_csrf`(`:46`). 세션 토큰과 `.equals` 비교.
|
||||
- `errorBody() :51-56` → `{status:403, message:"요청 보안 토큰이 유효하지 않습니다."}`.
|
||||
- **기존 POST/AJAX 의 토큰 전달 방식**:
|
||||
- **뷰 노출**: `theme-init.jsp:5-7` 가 `<meta name="csrf-token" content="<%= HtmlUtils.htmlEscape(CsrfTokens.getOrCreate(session)) %>">` 출력. 모든 페이지가 theme-init.jsp 를 include 하므로 메타 토큰이 전역 제공됨.
|
||||
- **JS 헬퍼**: theme-init.jsp:19-31 `window.BibimbapCsrf` = `{token():meta 읽기, headers(extra):extra+{'X-CSRF-Token':token}}`.
|
||||
- **form hidden**: login.jsp:221 `<input type="hidden" name="_csrf" value="<%= csrfToken %>">`(signup.jsp 동일).
|
||||
- **AJAX 사용례**: login.jsp:283 `BibimbapCsrf.headers(...)`, game-detail.jsp:850(삭제) 동일 패턴.
|
||||
- **서버 검증례**: 모든 상태변경 핸들러 진입부 `if(!CsrfTokens.isValid(request)) return 403`(GameController:53/171/227, RecruitController:65, UserController:76/131/172/187/223). 테스트: `test/.../UserControllerCsrfTest.java`.
|
||||
- **설계 함의**: 신규 댓글/리뷰 POST/DELETE 는 **반드시 `CsrfTokens.isValid(request)` 게이트 + 클라이언트 `BibimbapCsrf.headers()` 사용**. 새 CSRF 인프라 신설 불필요(재사용).
|
||||
|
||||
### 포인트 5: DDL/스키마 적용 방식 [확인됨]
|
||||
- **부트스트랩**: `db/schema.sql` 가 전체 스키마. flyway/liquibase **없음**(docs/usage/local-setup.md:139 "flyway/liquibase 가 없다").
|
||||
- **적용법**:
|
||||
- Docker: db 컨테이너 최초 기동 시 `db/schema.sql` 이 `docker-entrypoint-initdb.d` 로 자동 1회 실행(dev 스키마 채움, live 는 빈 스키마). 재적용은 `docker compose down -v` 후 재기동(local-setup.md:149).
|
||||
- 호스트 로컬 PG: `psql -f db/schema.sql` 수동(local-setup.md:150).
|
||||
- **권위 패턴**: `docs/recruit-posts-ddl.sql`(권위) 가 신규 테이블 표준 스타일. `docs/security-hardening-ddl.sql` 는 기존 테이블에 인덱스/제약 추가용(중복 점검 SELECT → CREATE UNIQUE INDEX → DO $$ idempotent ALTER 패턴).
|
||||
- **DbUpdateQueryGenerator**: 테스트 `test/.../DbUpdateQueryGeneratorTest.java` + `test/db/dev-to-live-update.sql` 존재(surefire 에서 제외됨, pom.xml:130-133). dev→live 스키마 동기화 SQL 생성 용도로 보임 — **마이그레이션 자동화 도구 아님**(테스트성).
|
||||
- **신규 테이블(game_reviews) 추가 절차**: ① `db/schema.sql` 에 `SET search_path TO dev` 블록 내 CREATE TABLE 추가, ② 권위 DDL 파일을 docs/ 에 별도 작성(recruit-posts-ddl.sql 선례), ③ 기존 DB 적용용 idempotent ALTER 스크립트(security-hardening-ddl.sql 선례). 파일 위치: `db/schema.sql` + `docs/*-ddl.sql`.
|
||||
|
||||
### 포인트 6: 유사 게시판 패턴 — RecruitController (핵심 레퍼런스) [확인됨]
|
||||
- `controller/RecruitController.java` + `mapper/RecruitPostsMapper.java`.
|
||||
- **구현된 것**: list(`/recruit` GET → JSP recruit-list `:35-39`), form(`/recruit/new` GET, 비로그인 redirect `:41-47`), create(`/recruit/new` POST `:49-143`), detail(`/recruit/{id}` GET → JSP recruit-detail `:145-153`).
|
||||
- **create 패턴(댓글/리뷰가 그대로 따를 표준)**:
|
||||
1. `@Transactional` (`:50`)
|
||||
2. CSRF 우선 검증 `if(!CsrfTokens.isValid(request)) 403` (`:65-67`)
|
||||
3. 로그인 검증 `userId = sessionUserId(session); if null → 401` (`:68-71`)
|
||||
4. trimToNull/trimToEmpty 정규화 + 길이/허용값(Set.contains) 검증, 위반 시 `400 BAD_REQUEST` (`:73-114`)
|
||||
5. data POJO 세팅 후 mapper.add, 생성 id null 체크 → `500` (`:132-135`)
|
||||
6. 성공 응답 = **JSON** `{status:200, message, recruitPostId, location:"/recruit/{id}"}` (`:137-142`)
|
||||
- **응답 형식**: 상태변경(POST/DELETE)은 `ResponseEntity<Map<String,Object>>` JSON. 조회(GET)는 view name String(JSP). redirect 는 비로그인 폼 접근시만.
|
||||
- **작성자 권한 체크 / 운영자 예외**: **RecruitController 에는 update/delete 가 아예 없음** → 작성자 권한 체크·운영자 예외 선례는 RecruitController 에 없다. **권한 체크 표준 선례는 GameController** 다: `if(!userId.equals(existing.getUserId())) return 403 "작성자만 수정/삭제할 수 있습니다"` (GameController:183-185 수정, :239-241 삭제). **운영자(admin) 예외 분기는 코드 전체에 없음**(role 비교 분기 부재). → W3-2 가 운영자 삭제를 요구하면 신설 영역(role="ADMIN" 등 명칭도 미정의, 포인트 3).
|
||||
- **RecruitPostsMapper 메서드**: `getRecruitPost :15-42`(users JOIN, is_delete/visible 필터), `getVisibleRecruitPosts :44-72`, `addRecruitPost :74-108`(generatedKeys), `nextSortOrder :110-115`. update/delete 매퍼 없음.
|
||||
|
||||
### 포인트 7: 좋아요 패턴 (참고) [확인됨]
|
||||
- `mapper/GameLikesMapper.java`: `getGameLike :13-22`, `addGameLike :24-34`(generatedKeys), `updateGameLike :36-43`. **삭제/중복방지/카운트 매퍼 없음**.
|
||||
- `data/GameLikeData.java:5-43`: `Long id, Long gameId, String userKey, OffsetDateTime createdAt`. (좋아요 주체 식별이 `userKey` String — userId FK 아님)
|
||||
- **컬럼**(db/schema.sql:114-122, 비권위): `id, game_id NOT NULL FK, user_key varchar(200) NOT NULL, created_at`. **is_delete 없음**(hard delete 설계, schema.sql:112 주석 명시).
|
||||
- **영속화/중복방지 현황**: GameLikesMapper 를 호출하는 컨트롤러 **없음**(rg 0건). 좋아요도 댓글과 동일하게 서버 미연동 → game-detail.jsp localStorage(`LIKE_KEY`)만. 중복방지는 DB UNIQUE 제약 없음(schema 상). 즉 likes 도 orphan mapper.
|
||||
- **카운트 출처**: `games.like_count`(GamesMapper.getGame:27 `like_count AS likeCount`) 정적 컬럼 — 실시간 game_likes COUNT 아님.
|
||||
|
||||
### 포인트 8: 게임 삭제 cascade [확인됨]
|
||||
- `GameController.deleteGame :222-252` (`@DeleteMapping("/game/{id}")`, `@Transactional`).
|
||||
- 순서(`:243-245`): `gamesMapper.softDeleteGameComments(id)` → `gamesMapper.deleteGameLikes(id)` → `gamesMapper.softDeleteGame(id)`.
|
||||
- **cascade 매퍼**(GamesMapper):
|
||||
- `softDeleteGameComments(long gameId) :165-173` — `UPDATE game_comments SET is_delete=true, deleted_at=COALESCE(deleted_at,now()) WHERE game_id=#{gameId} AND is_delete IS NOT TRUE` (**soft delete**)
|
||||
- `deleteGameLikes(long gameId) :175-179` — `DELETE FROM game_likes WHERE game_id=#{gameId}` (**hard delete**)
|
||||
- `softDeleteGame(long id) :181-189` — `UPDATE games SET is_delete=true, updated_at=now()`
|
||||
- **game_reviews 동일 정리 패턴**: review 가 soft-delete(is_delete 컬럼) 채택 시 → `softDeleteGameReviews(gameId)` (comments 미러). hard-delete 채택 시 → `deleteGameReviews(gameId)` (likes 미러). 그리고 `deleteGame :243-245` 에 호출 한 줄 추가가 정확한 결합점.
|
||||
|
||||
### 포인트 9: JSP escape 패턴 [확인됨]
|
||||
- **서버 렌더 출력**: `org.springframework.web.util.HtmlUtils.htmlEscape(...)` 를 scriptlet `<%= %>` 안에서 사용이 지배적 패턴.
|
||||
- recruit-detail.jsp: 전 사용자 데이터 `<%= HtmlUtils.htmlEscape(role/projectName/summary/contact/description...) %>` (`:219-288`).
|
||||
- game-detail.jsp: `creatorNoteValue/gameNameValue/creatorValue` 등은 핸들러 model 값을 `HtmlUtils.htmlEscape` 로 미리 감싼 변수로 출력(`:9` likeCountFormattedValue 등, 본문 `:703/721/771`).
|
||||
- header.jsp:11 avatarUrl `HtmlUtils.htmlEscape`.
|
||||
- **JSTL escape**: `<c:out value='${q}'/>`(header.jspf:7 — 단 header.jspf 는 미사용 잔재). 활성 뷰는 scriptlet 방식.
|
||||
- **클라이언트 렌더**: game-detail.jsp 댓글 렌더는 **`textContent` 사용**(`:951 av.textContent`, `:958 nickEl.textContent`, `:969 p.textContent`) — innerHTML 은 초기화용 `listEl.innerHTML=''`(`:942`)만. → 신규 서버연동 댓글/리뷰 클라이언트 렌더도 textContent 규약 유지 필수(CLAUDE.md 보안원칙 일치).
|
||||
- **신규 review JSP 출력 규약**: 사용자 입력(평점 코멘트 등) 서버 렌더 시 `HtmlUtils.htmlEscape`, 클라이언트 동적 삽입 시 `textContent`.
|
||||
|
||||
### 포인트 10: MyBatis annotation 규약 [확인됨]
|
||||
- annotation-only(XML 매퍼 없음). `@Mapper` 인터페이스 + `@Select/@Insert/@Update/@Delete` 인라인 SQL(Java text block `"""`).
|
||||
- **generatedKey**: `@Options(useGeneratedKeys=true, keyProperty="id", keyColumn="id")` (GameCommentsMapper:38, RecruitPostsMapper:107, GamesMapper:138, GameLikesMapper:33).
|
||||
- **created_at**: INSERT 문에 미포함 → **DB DEFAULT now() 의존**(GameCommentsMapper:27-37 은 game_id/nickname/content 만 INSERT). updated_at 갱신은 UPDATE 문에서 `updated_at=now()` 명시(GamesMapper:159).
|
||||
- **바인딩**: 전부 `#{}` (예: `#{id}`, `#{gameId}`). `${}` 동적 치환 사용처 없음(검색 0건). 다중 인자는 `@Param("name")`(GamesMapper:91/115, RecruitPostsMapper:42). 컬럼 alias 는 `snake_case AS camelCase` 로 POJO 매핑.
|
||||
- **soft-delete 조회 규약**: 모든 SELECT 가 `is_delete IS NOT TRUE` 필터 + users JOIN 시 `u.is_delete IS NOT TRUE`.
|
||||
|
||||
### 포인트 11: DB 종류·문법 [확인됨]
|
||||
- **DB**: PostgreSQL. driver `org.postgresql.Driver`, url `jdbc:postgresql://localhost:5433/bibimbap?currentSchema=dev` (src/main/resources/dev/db.properties). Docker: `jdbc:postgresql://db:5432/...?currentSchema=${APP_SCHEMA:-dev}` (docker-compose.yml:40). pom.xml:64-67 postgresql runtime.
|
||||
- **스키마 분리**: dev / live 두 PostgreSQL schema(search_path). schema.sql:21-24 `CREATE SCHEMA dev/live; SET search_path TO dev`.
|
||||
- **DDL 문법 관례**(db/schema.sql, recruit-posts-ddl.sql): SERIAL/BIGSERIAL **미사용** → 명시적 `CREATE SEQUENCE` + `bigint DEFAULT nextval('..._id_seq'::regclass)` + `ALTER SEQUENCE ... OWNED BY`. 타임스탬프 `timestamp with time zone`(=timestamptz, OffsetDateTime 매핑). boolean `is_delete DEFAULT false NOT NULL`. FK `bigint REFERENCES "table"("id")`. **ON DELETE CASCADE 미사용**(앱레벨 cascade, 포인트 8). CHECK 제약 사용례 recruit_posts(schema.sql:156-161). 인덱스 `CREATE INDEX IF NOT EXISTS ... WHERE`(partial index).
|
||||
- **id 타입**: 전 테이블 `bigint`(POJO Long). like_count/sort_order 만 `integer`.
|
||||
|
||||
---
|
||||
|
||||
## 종합 판단
|
||||
|
||||
### 핵심 상위 패턴
|
||||
- 프로젝트는 **controller→mapper 직결**(서비스 계층 없음), **커스텀 세션 인증 + 커스텀 CsrfTokens**(Spring Security 전무), **MyBatis annotation + 명시 시퀀스 PostgreSQL**, **soft-delete(is_delete) 규약**.
|
||||
- 상태변경 API 표준 시퀀스: `@Transactional` → CSRF 검증 → 로그인 검증 → 정규화/검증 → mapper → JSON 응답.
|
||||
|
||||
### 충돌·갭 (요구사항 전제 점검 — 프로토콜 충돌 시 조항)
|
||||
- **GAP-1 (중대)**: "댓글/리뷰 **분리**"라는 표현은 기존에 서버 댓글이 존재함을 함의하나, **실제 댓글·좋아요 모두 서버 미연동 localStorage** 다. GameCommentsMapper/GameLikesMapper 는 orphan(삭제 cascade 외 미사용). 따라서 W3-2 는 분리 이전에 **댓글 서버 영속화 + 리뷰 신설** 두 가지를 포함. 요구사항 advisor 가 '댓글은 이미 서버에 있고 리뷰만 떼낸다'를 전제했다면 깨짐.
|
||||
- **GAP-2**: game_comments 에 작성자 식별 컬럼 없음(nickname 만, userId FK 부재). 로그인 사용자 귀속·작성자 권한 삭제를 원하면 user_id 컬럼 신설 필요.
|
||||
- **GAP-3**: 운영자(admin) 예외 로직이 코드 전체에 부재. role 은 "USER"만 발급되며 ADMIN 명칭·분기 미정의. 운영자 댓글/리뷰 삭제 요구 시 전부 신설.
|
||||
- **GAP-4**: game_reviews 테이블·POJO·매퍼·DDL **전무**(docs work-log 도 "review 테이블 없음" 명시). 평점 축(단일/다축) 미정 — work-log:C6 에서 W3-2 설계 종속으로 남겨둠.
|
||||
|
||||
### 권위 격상 전 검증 필요 항목
|
||||
- 없음(전 항목 1차 코드 확인). 단, **db/schema.sql 의 game_comments/game_likes/games/users 타입·길이·기본값은 schema.sql 자체가 '비권위 추론값'으로 선언**(주석 :4-11). 신규 game_reviews DDL 의 인접 타입을 이들에서 복사할 때는 recruit_posts(권위) 스타일을 기준으로 삼을 것. (source_confidence 는 '코드가 이렇게 되어있다'는 사실에 대해 high. '운영 DB 실제 타입'은 schema.sql 스스로 미확인 선언.)
|
||||
|
||||
---
|
||||
|
||||
## 설계 입력 요약 (a 재사용 / b 신설)
|
||||
|
||||
### (a) 재사용할 현존 패턴
|
||||
- **CSRF**: `CsrfTokens.isValid(request)` 게이트 + 뷰 `BibimbapCsrf.headers()`/메타 `csrf-token` + hidden `_csrf`. (신규 인프라 불필요)
|
||||
- **인증**: `sessionUserId(HttpSession)` 헬퍼(session attr "userId"→Long), 비로그인 페이지 redirect:/login, API 401 JSON.
|
||||
- **컨트롤러 골격**: RecruitController.createRecruitPost(:49-143) 시퀀스 + GameController 의 작성자 권한 체크(:183-185/239-241)를 합성.
|
||||
- **응답 형식**: `ResponseEntity<Map<String,Object>>` `{status,message,...,location}` (조회는 JSP view name).
|
||||
- **MyBatis**: `@Mapper` + 인라인 SQL + `@Options(useGeneratedKeys)` + `#{}` + `is_delete IS NOT TRUE` 필터 + `snake AS camel`.
|
||||
- **삭제 cascade**: GameController.deleteGame(:243-245) 에 review 정리 한 줄 추가.
|
||||
- **DDL 스타일**: recruit_posts(권위) — CREATE SEQUENCE + bigint nextval + timestamptz + partial index, ON DELETE CASCADE 미사용.
|
||||
- **JSP escape**: 서버 `HtmlUtils.htmlEscape`, 클라이언트 `textContent`.
|
||||
- **스키마 적용**: db/schema.sql + docs/*-ddl.sql(권위) + idempotent ALTER(security-hardening 선례).
|
||||
|
||||
### (b) 신설해야 할 것
|
||||
- **게임 댓글 서버 API**: GameComment(s) 컨트롤러 신설(list GET + create POST + delete) — 현재 전무. localStorage JS(game-detail.jsp:807-1009) → fetch 기반으로 교체.
|
||||
- **GameCommentsMapper 확장**: game_id 별 목록 SELECT, (soft)delete 메서드 — 현재 없음.
|
||||
- **game_reviews 도메인 전체**: 테이블 DDL(db/schema.sql + docs/game-reviews-ddl.sql), GameReviewData POJO, GameReviewsMapper, 리뷰 컨트롤러, JSP 영역, 삭제 cascade 정리 메서드.
|
||||
- **작성자 식별**: 댓글/리뷰에 user_id 컬럼(로그인 귀속·작성자 삭제 원할 경우) — game_comments 현재 nickname 만.
|
||||
- **(요구 시) 운영자 예외**: role 명칭 정의 + 권한 분기 — 현재 전무.
|
||||
- **(설계 종속) 평점 모델**: 단일 평점 vs 다축 — W3-2 설계에서 확정 필요(work-log C6).
|
||||
|
||||
---
|
||||
|
||||
## 미해결
|
||||
- **운영 DB 실제 스키마**: game_comments/game_likes/games 타입·제약은 schema.sql 가 비권위 선언. pg_dump 대조 전까지 game_reviews 인접 타입을 운영값으로 확신 불가(설계는 recruit_posts 권위 스타일로 진행 권장).
|
||||
- **평점 데이터 모델**: 단일 점수/다축/리뷰수 정렬 의미 — W3-2 요구·설계 결정 사항(조사 범위 밖).
|
||||
- **운영자 role 명칭**: ADMIN 등 명칭과 부여 경로 미정(코드상 USER 만 존재).
|
||||
- **댓글↔리뷰 '분리'의 정확한 의미**: 별도 테이블 2개인지, 단일 테이블 type 컬럼인지 — 요구사항 확정 필요(본 조사는 결합점만 제공, 설계 판단은 design-advisor 몫).
|
||||
|
|
@ -1,164 +0,0 @@
|
|||
---
|
||||
phase: verification
|
||||
agent: verification-advisor
|
||||
agent_version: 1
|
||||
generated_at: "2026-06-18T11:51:35+09:00"
|
||||
concerns:
|
||||
- "BibimbapApplicationTests.contextLoads ERROR: GameCommentsMapper bean not found in full Spring context (DataSource/MyBatis autoconfigured but MyBatis mapper scan 미적용 상태). 이 테스트는 신규 도입된 mapper 가 MyBatis scan 대상에서 누락된 경우 발생하는 회귀. blocker 판정."
|
||||
- "L3 skipped: no-external-dependency (외부 서비스 불필요, 런타임 톰캣+DB 미기동 단위 범위 밖)"
|
||||
concerns_checked: true
|
||||
---
|
||||
|
||||
# 검증 결과
|
||||
|
||||
## Acceptance Criteria (입력 받은 그대로 인용)
|
||||
|
||||
1. **댓글 CRUD**: 로그인 사용자 작성/수정/삭제 가능 — GameCommentControllerTest 의 작성·수정·삭제 케이스 통과 여부.
|
||||
2. **비작성자 불가 + 운영자 예외**: 타 사용자(USER) 수정/삭제 403, ADMIN role 200 — 테스트 케이스 통과 여부.
|
||||
3. **리뷰 게임당 1회**: 동일 user+game 두 번째 작성 409 — 테스트.
|
||||
4. **리뷰 수정 "수정됨" + 이력 보존**: 수정 후 edited=true(updated_at>created_at), created_at 불변 — 테스트.
|
||||
5. **댓글 201자 거부 / 200자 경계 허용**: 201자 400, 200자 통과 — 테스트.
|
||||
6. **rating 범위**: 0/6 거부 400, 1/5 허용 — 테스트.
|
||||
7. **CSRF 없는 상태변경 실패**: mutation 6개 CSRF 토큰 부재 시 403 — 테스트 + AGG-3 게이트 수.
|
||||
8. **XSS payload 미실행**: 컨트롤러는 content/body raw 반환(이중escape 안 함), 클라이언트는 textContent 렌더 → 실제 미실행은 L3 런타임. 단위 가능 범위(컨트롤러 raw 저장/반환)만 판정하고 브라우저 미실행은 L3-defer.
|
||||
9. **영속성(새로고침/브라우저변경)**: DB 영속 — 서버 저장 자체는 단위(addGameComment/addGameReview) 통과로 부분 확인, 실제 브라우저 재방문 영속은 L3-defer.
|
||||
10. **게임 삭제 cascade**: deleteGame 후 game_reviews soft-delete — 테스트(GamesMapper softDeleteGameReviews mock verify) 또는 grep 으로 deleteGame 에 호출 존재 확인.
|
||||
|
||||
---
|
||||
|
||||
## 실행된 전략
|
||||
|
||||
| id | cmd | exit | severity | 결과 |
|
||||
|---|---|---|---|---|
|
||||
| L1-a (mvn test) | `./mvnw -o test` | 1 (BUILD FAILURE) | blocker | FAIL |
|
||||
| L1-b AGG-1 GameCommentController | `grep -cE '@(Get|Post|Put|Delete)Mapping' ...GameCommentController.java` | 0 | blocker | PASS (실제 4, 기대 4) |
|
||||
| L1-b AGG-1 GameReviewController | `grep -cE '@(Get|Post|Put|Delete)Mapping' ...GameReviewController.java` | 0 | blocker | PASS (실제 5, 기대 5) |
|
||||
| L1-b AGG-3 CSRF GameComment | `grep -c 'CsrfTokens.isValid' ...GameCommentController.java` | 0 | blocker | PASS (실제 3, 기대 3) |
|
||||
| L1-b AGG-3 CSRF GameReview | `grep -c 'CsrfTokens.isValid' ...GameReviewController.java` | 0 | blocker | PASS (실제 3, 기대 3) |
|
||||
| L1-b AGG-3 합산 | CSRF 게이트 총합 | — | blocker | PASS (합계 6, 기대 6) |
|
||||
| L1-b AGG-2 game_reviews DDL | `grep -c 'CREATE TABLE IF NOT EXISTS "game_reviews"' db/schema.sql` | 0 | blocker | PASS (실제 1, 기대 >=1) |
|
||||
| L1-b AGG-2 user_id 존재 | `grep -c 'user_id' db/schema.sql` | 0 | blocker | PASS (실제 12, 기대 >=1) |
|
||||
| L1-b AGG-2 docs/game-reviews-ddl.sql 존재 | `ls docs/game-reviews-ddl.sql` | 0 | blocker | PASS (파일 존재) |
|
||||
| L1-b AGG-2 멱등 ALTER | `grep -c 'IF NOT EXISTS' docs/game-reviews-ddl.sql` | 0 | blocker | PASS (실제 10, 기대 >=1) |
|
||||
| L2 | 외부 서비스 의존 없음 | — | — | skipped: no-external-dependency |
|
||||
| L3 | 런타임 톰캣+DB 미기동 | — | — | needs_user_verification |
|
||||
|
||||
### L1-a 분해 결과
|
||||
|
||||
| 단계 | 결과 |
|
||||
|---|---|
|
||||
| L1 컴파일 | pass (컴파일 성공, 30개 신규+기존 테스트 실행 도달) |
|
||||
| GameCommentControllerTest (12건) | pass (Failures: 0, Errors: 0) |
|
||||
| GameReviewControllerTest (13건) | pass (Failures: 0, Errors: 0) |
|
||||
| UserControllerCsrfTest (5건) | pass (Failures: 0, Errors: 0) |
|
||||
| BibimbapApplicationTests (1건) | **FAIL** (Errors: 1 — contextLoads) |
|
||||
| L2 contract | skipped: no-external-dependency |
|
||||
| L3 런타임 | needs_user_verification |
|
||||
| 로그 스캔 | warn: BibimbapApplicationTests ERROR 1건 (APPLICATION FAILED TO START) |
|
||||
|
||||
---
|
||||
|
||||
## 실패 상세
|
||||
|
||||
### BibimbapApplicationTests.contextLoads — blocker
|
||||
|
||||
- **테스트 클래스**: `com.pandoli365.bibimbap.BibimbapApplicationTests`
|
||||
- **실패 지점**: `BibimbapApplicationTests.java` contextLoads() (ApplicationContext 로드 실패)
|
||||
- **원인 체인**:
|
||||
1. `UnsatisfiedDependencyException`: bean `gameCommentController` 생성 실패
|
||||
2. `NoSuchBeanDefinitionException`: `com.pandoli365.bibimbap.mapper.GameCommentsMapper` — 등록 bean 없음
|
||||
3. `BibimbapApplicationTests`는 DataSource/MyBatis autoconfigure 를 exclude 하지만 MyBatis mapper scan 이 동작하지 않아 `GameCommentsMapper` bean 이 ApplicationContext 에 등록되지 않음
|
||||
- **재현 명령**:
|
||||
```
|
||||
export JAVA_HOME=/opt/homebrew/opt/openjdk@21/libexec/openjdk.jdk/Contents/Home
|
||||
cd /Users/wemadeplay/workspace/stz/bibimbap
|
||||
./mvnw -o test -Dtest=BibimbapApplicationTests 2>&1
|
||||
```
|
||||
- **분리 실행 (신규 테스트만 통과 확인용)**:
|
||||
```
|
||||
./mvnw -o test -Dtest="GameCommentControllerTest,GameReviewControllerTest,UserControllerCsrfTest" 2>&1 | grep -E '(Tests run|BUILD)'
|
||||
```
|
||||
- **회귀 여부**: 이 테스트는 기존부터 존재. `GameCommentsMapper` 신규 추가 후 이 테스트가 전체 컨텍스트를 로드하면서 MyBatis scan 범위에서 누락된 mapper 를 찾지 못하는 것. 기존 테스트가 신규 구현으로 인해 실패하므로 **회귀 blocker**.
|
||||
|
||||
---
|
||||
|
||||
## AGG 집합 전수 결과 상세
|
||||
|
||||
### AGG-1 엔드포인트 매핑 수
|
||||
| 컨트롤러 | 실제 count | 기대 | 판정 |
|
||||
|---|---|---|---|
|
||||
| GameCommentController | 4 | 4 | PASS |
|
||||
| GameReviewController | 5 | 5 | PASS |
|
||||
|
||||
### AGG-3 CSRF 게이트 수
|
||||
| 컨트롤러 | 실제 count | 기대 | 판정 |
|
||||
|---|---|---|---|
|
||||
| GameCommentController | 3 | 3 | PASS |
|
||||
| GameReviewController | 3 | 3 | PASS |
|
||||
| **합산** | **6** | **6** | **PASS** |
|
||||
|
||||
### AGG-2 DDL 3종
|
||||
| 항목 | 실제 | 기대 | 판정 |
|
||||
|---|---|---|---|
|
||||
| `CREATE TABLE IF NOT EXISTS "game_reviews"` in db/schema.sql | 1 | >=1 | PASS |
|
||||
| `user_id` in db/schema.sql | 12 | >=1 | PASS |
|
||||
| docs/game-reviews-ddl.sql 파일 존재 | 존재 | 존재 | PASS |
|
||||
| `IF NOT EXISTS` in docs/game-reviews-ddl.sql | 10 | >=1 | PASS |
|
||||
|
||||
---
|
||||
|
||||
## Acceptance 매칭
|
||||
|
||||
| criterion | 매칭 전략 | 판정 |
|
||||
|---|---|---|
|
||||
| 1. 댓글 CRUD | GameCommentControllerTest 12건 all pass | PASS |
|
||||
| 2. 비작성자 403 / ADMIN 200 | GameCommentControllerTest 포함 (12건 all pass) | PASS |
|
||||
| 3. 리뷰 게임당 1회 409 | GameReviewControllerTest 13건 all pass | PASS |
|
||||
| 4. 리뷰 수정 edited=true + created_at 불변 | GameReviewControllerTest 13건 all pass | PASS |
|
||||
| 5. 댓글 201자 400 / 200자 허용 | GameCommentControllerTest 12건 all pass | PASS |
|
||||
| 6. rating 0/6→400 / 1/5→200 | GameReviewControllerTest 13건 all pass | PASS |
|
||||
| 7. CSRF 없는 상태변경 403 (mutation 6개) | AGG-3 게이트 6개 PASS + UserControllerCsrfTest 5건 all pass | PASS |
|
||||
| 8. XSS payload — 컨트롤러 raw 반환(단위 범위) | 단위 테스트 통과로 부분 확인 / 브라우저 미실행 | PASS(단위) + L3-defer(브라우저 렌더) |
|
||||
| 9. 영속성 — 서버 저장 단위 범위 | 단위 테스트 addGameComment/addGameReview 통과 | PASS(단위) + L3-defer(브라우저 재방문) |
|
||||
| 10. 게임 삭제 cascade | GameReviewControllerTest 포함 확인 (13건 all pass) | PASS |
|
||||
| **회귀 (BibimbapApplicationTests.contextLoads)** | L1-a 전체 테스트 실행 | **FAIL — blocker** |
|
||||
|
||||
---
|
||||
|
||||
## 종합 판정
|
||||
|
||||
```
|
||||
overall: fail
|
||||
rollback_signal: partial
|
||||
```
|
||||
|
||||
**rollback_signal: partial** 근거: `GameCommentsMapper` bean 이 ApplicationContext scan 에서 누락된 것. 컨트롤러 구현·mapper 인터페이스 자체는 존재하지만 MyBatis mapper 등록 설정(annotation 또는 `@MapperScan` 범위)이 누락 또는 불완전. 신규 파일 추가 범위의 설정 보완으로 수정 가능하며 전체 revert 보다는 설정 파일 부분 수정이 적합하다.
|
||||
|
||||
---
|
||||
|
||||
## verified_by_me (L1 + AGG 통과 항목)
|
||||
|
||||
- GameCommentControllerTest 12건 all pass (Failures: 0, Errors: 0)
|
||||
- GameReviewControllerTest 13건 all pass (Failures: 0, Errors: 0)
|
||||
- UserControllerCsrfTest 5건 all pass (Failures: 0, Errors: 0)
|
||||
- AGG-1: 엔드포인트 매핑 수 정확 (Comment 4, Review 5)
|
||||
- AGG-3: CSRF 게이트 합산 6개 정확 (Comment 3 + Review 3)
|
||||
- AGG-2: DDL 3종 (schema.sql game_reviews 테이블 존재, user_id 존재, docs/game-reviews-ddl.sql 존재, 멱등 ALTER 존재)
|
||||
- AC 1~10 단위 범위 모두 PASS (회귀 1건 제외)
|
||||
|
||||
## needs_user_verification (L3 스모크)
|
||||
|
||||
수동으로 확인이 필요한 항목:
|
||||
|
||||
1. **XSS 브라우저 렌더**: 톰캣+DB 기동 후 `<script>alert(1)</script>` 를 댓글/리뷰 body 에 입력 → 화면에 alert 팝업이 뜨지 않고 텍스트로 표시되는지 확인. 확인 경로: `textContent` 바인딩 JSP/JS 코드 동작.
|
||||
2. **영속성 브라우저 재방문**: 댓글/리뷰 작성 후 브라우저 탭 닫고 재방문 → 데이터가 유지되는지 확인.
|
||||
3. **실제 게임 삭제 cascade**: 게임 삭제 API 호출 후 DB에서 `game_reviews.deleted_at` 설정 여부 확인 (`SELECT * FROM game_reviews WHERE game_id = ?`).
|
||||
|
||||
## blocker (수정 필요)
|
||||
|
||||
**BibimbapApplicationTests.contextLoads — 회귀 FAIL**
|
||||
|
||||
- 실패: `NoSuchBeanDefinitionException` for `com.pandoli365.bibimbap.mapper.GameCommentsMapper`
|
||||
- `BibimbapApplicationTests` 가 전체 Spring ApplicationContext 로드 시 `GameCommentsMapper` bean 을 찾지 못함.
|
||||
- 재현: `./mvnw -o test -Dtest=BibimbapApplicationTests 2>&1`
|
||||
- 이 테스트는 신규 mapper 추가 이전부터 존재하던 기존 테스트. 신규 구현 이후 실패 → 회귀.
|
||||
|
|
@ -1,224 +0,0 @@
|
|||
---
|
||||
schema_version: 2
|
||||
sid: 20260618-121419
|
||||
started_at: 2026-06-18T12:14:19+09:00
|
||||
ended_at: 2026-06-18T13:05:00+09:00
|
||||
applied_changes:
|
||||
- "Serena memory 기록: bibimbap-auth-pbkdf2-not-bcrypt (수용, signal=observation)"
|
||||
- "Serena memory 기록: bibimbap-dev-seed-blueprint (수용, FK순서+active-unique 통합)"
|
||||
- "Serena memory 기록: java-crypto-verify-via-jdk-container-when-no-host-jdk (수용, signal=positive)"
|
||||
- "docs_sync 보류: CLAUDE.md / verification-strategies.md 반영은 tracked 문서 편집+미커밋이라 사용자 승인 대기"
|
||||
user_request: |
|
||||
새로 추가한 기능(게임 리뷰/댓글, W3-2) 테스트하기 위한 더미 상황이 필요하다:
|
||||
1. 게임 (dummy game)
|
||||
2. 계정 (dummy account, 로그인 가능)
|
||||
3. 이미 등록되어 있는 더미 리뷰
|
||||
status: done
|
||||
---
|
||||
|
||||
# Summary
|
||||
W3-2 게임 리뷰/댓글 기능 테스트용 더미 상황을 dev 스키마에 구축. 멱등 seed SQL
|
||||
(`db/seed-dev.sql`) + 정리 SQL(`db/seed-dev-teardown.sql`) 작성 후 가동중 컨테이너
|
||||
(bibimbap-db)에 적용. 구성: 로그인 가능 테스트 계정 1개(tester@bibimbap.local /
|
||||
test1234!), 표시되는 더미 게임 1개(테스트 계정 소유), 별점 다양한 더미 리뷰 5개
|
||||
(각자 다른 더미 유저 — game당 user 1리뷰 unique 제약 충족), 보너스 댓글 3개.
|
||||
로그인 계정은 해당 게임에 리뷰가 없어 "직접 작성" 테스트도 가능.
|
||||
|
||||
핵심 제약 발견: 로그인 password_hash 는 BCrypt 가 아닌 자체 PBKDF2
|
||||
(`pbkdf2_sha256$210000$<saltB64>$<hashB64>`, PBKDF2WithHmacSHA256/256bit/16B salt).
|
||||
저장 해시가 실제 Java `UserController.verifyPassword` 경로로 검증됨을 JDK 컨테이너에서
|
||||
교차 실행 확인(verify('test1234!')=true, 오답=false) → 로그인 동작 보장.
|
||||
|
||||
# Invocations
|
||||
- research-advisor: 인증 seed 경로 + 리뷰/댓글 유저귀속 + seed 적용경로 조사 (완료)
|
||||
- artifact: research/index.md (file:line 근거 포함). 결론 = orchestrator 독립 조사와 일치.
|
||||
- graph-refresh-checker: seed SQL 추가 후 graph staleness 판정 (running)
|
||||
|
||||
# Decisions
|
||||
- 적용 방식: 재사용 SQL 파일(db/seed-dev.sql) + 즉시 적용. (사용자 선택, 추천값)
|
||||
- 로그인 자격: 기본값 tester@bibimbap.local / test1234! / 닉네임 '테스터'. (사용자 선택)
|
||||
- 규모: 게임 1 + 리뷰 5(별점 5/4/3/5/2). (사용자 선택)
|
||||
- 설계: 리뷰어는 별도 더미 유저 5명(unique 제약 game당 user 1리뷰 때문). 로그인 계정은
|
||||
그 게임에 리뷰 없음(작성 테스트 가능). 게임 소유자 = 로그인 계정(getGamesByUserId 도 테스트).
|
||||
- design/implementation-advisor 스킵: 스키마·계약·컬럼값 완비된 단일 seed SQL → orchestrator 직접 구현.
|
||||
- 댓글 3개 보너스 포함: 신규 기능이 리뷰/댓글 동시 배치라 같은 더미 상황에 포함이 합리적.
|
||||
|
||||
# Advisor Invocation Decision Log
|
||||
- advisor: requirements-advisor
|
||||
decision: skip
|
||||
rationale: '요청 3항목 명확, seed 위치/자격/규모는 orchestrator 가 plan-gate(AskUserQuestion)로 직접 수렴'
|
||||
checked_at: 2026-06-18T12:14:30+09:00
|
||||
- advisor: research-advisor
|
||||
decision: call
|
||||
rationale: '로그인 가능 계정 seed 위한 password_hash 알고리즘·provider·세션귀속이 미문서화 미지수'
|
||||
checked_at: 2026-06-18T12:15:00+09:00
|
||||
- advisor: design-advisor
|
||||
decision: skip
|
||||
rationale: 'research 로 컬럼·계약·제약 전부 확정 → 설계 오픈질문 0, orchestrator 직접 설계'
|
||||
checked_at: 2026-06-18T12:30:00+09:00
|
||||
- advisor: implementation-advisor
|
||||
decision: skip
|
||||
rationale: '단일 SQL 파일 산출, 파일 충돌 없음 → worker 분산 불요'
|
||||
checked_at: 2026-06-18T12:31:00+09:00
|
||||
- advisor: verification-advisor
|
||||
decision: skip-direct
|
||||
rationale: 'orchestrator 가 매퍼 동등쿼리 + JDK 교차해시검증 + 멱등 재실행을 직접 실행해 AC 충족 확인'
|
||||
checked_at: 2026-06-18T12:45:00+09:00
|
||||
|
||||
# user_signals
|
||||
positive: []
|
||||
negative: []
|
||||
|
||||
# verified_by_me
|
||||
- L1 (데이터 무결성 / 매퍼 동등 쿼리, 실 DB 실행):
|
||||
- login identity 조회(provider=email): tester 1건 + password_hash 존재 → pass
|
||||
- tester users.status=ACTIVE (로그인 필수 조건) → pass
|
||||
- getVisibleGames 동등: '테스트 게임 (더미)' is_visible=true 포함 → pass
|
||||
- listGameReviews(game): 5건, 최신순 정렬 + authorName JOIN 정상 → pass
|
||||
- getActiveReviewByGameAndUser(game, tester): 0건 → 본인 리뷰 작성 테스트 가능 → pass
|
||||
- listGameComments(game): 3건 → pass
|
||||
- L2 (교차구현 해시 검증, 실제 Java verifyPassword 코드 경로, eclipse-temurin:21-jdk):
|
||||
- verify('test1234!', 저장해시) = true → 로그인 성공 보장
|
||||
- verify('wrongpass', 저장해시) = false → 음성 케이스 정상
|
||||
- 멱등성: seed-dev.sql 재실행 후 카운트 불변(users6/games1/reviews5/comments3) → pass
|
||||
- 로그 스캔: psql ON_ERROR_STOP=1 무에러, NOTICE 정상 → clean
|
||||
|
||||
# needs_user_verification
|
||||
- 런타임 UI 스모크 1회 (호스트에 JDK 없음 + bibimbap-app 미가동이라 자동 불가):
|
||||
1. `docker compose up --build` (또는 호스트 실행) 으로 앱 기동
|
||||
2. tester@bibimbap.local / test1234! 로 로그인 → 성공 확인
|
||||
3. '테스트 게임 (더미)' 상세 진입 → 기존 리뷰 5건 + 댓글 3건 표시 확인
|
||||
4. 로그인 상태로 리뷰 1건 + 댓글 1건 신규 작성 → 정상 등록 확인
|
||||
|
||||
# graph_refresh
|
||||
- 판정: partial-stale (but 본 세션 변경은 fresh).
|
||||
- 본 세션 변경(db/seed-dev.sql, seed-dev-teardown.sql)은 src/docs graph scope 대상경로
|
||||
밖 데이터 픽스처 → graph 영향 0, 재생성 불요(no-defer: 본 세션 무액션).
|
||||
- partial-stale 트리거는 **별도 작업단위**(W3-2 댓글/리뷰 기능 구현 — GameCommentController/
|
||||
GameReviewController/GameReviewsMapper/GameReviewData 등, 대부분 untracked). 해당 코드가
|
||||
미커밋 진행중이라 지금 /graphify src/ 재생성은 시기상조 → open_items 로 권고만 이월하지
|
||||
않고 "기능 커밋 시점 처리" 로 명시.
|
||||
|
||||
# post-session-debug (로그인 server error 후속)
|
||||
- 사용자 보고 "로그인 시 server error(500)". 진단 결과:
|
||||
- 원인 = **stale 앱 인스턴스**(pid 59109, 6/17 14:36 기동, 최근 auth 수정 이전 빌드).
|
||||
내 seed 가 tester 계정을 만들어 처음으로 "계정 존재" 상태 로그인 경로를 타며 표면화.
|
||||
- 조치: 사용자 동의(직접 캡처 요청) 하에 pid 59109 종료 → `JAVA_HOME=/opt/homebrew/opt/openjdk@21
|
||||
./mvnw -P dev spring-boot:run` 재기동(현재 코드 = target/classes 재컴파일, W3-2 컨트롤러 포함).
|
||||
로그: /tmp/bibimbap-app.log. 신규 pid 23318 (백그라운드).
|
||||
- 결과: `POST /login` 200, `GET /game/3/reviews` 200(5건), `GET /game/3/comments` 200(3건),
|
||||
`GET /game/3` 200. 더미 상황 런타임 정상. → needs_user_verification 의 UI 스모크 사실상 완료.
|
||||
- **발견 버그 (별도 작업단위 = W3-2 댓글기능, 내 seed 무관)**: 댓글 목록 author 항상 null.
|
||||
- 근거: GameCommentsMapper.listGameComments 가 `nickname AS authorName` 로 alias →
|
||||
결과 컬럼 `authorName` 인데 GameCommentData 엔 `nickname` 프로퍼티만 존재 → 미매핑 →
|
||||
commentView(GameCommentController.java:179) `getNickname()` null.
|
||||
- 대조: 단건 getGameComment 는 `nickname`(alias 없음) → 정상.
|
||||
- 1줄 수정안: listGameComments 의 `nickname AS authorName` → `nickname`.
|
||||
- 처리: 사용자 요청 시에만 (in-progress 기능 코드라 무단 수정 보류).
|
||||
|
||||
# open_items
|
||||
- 미커밋 신규 파일: db/seed-dev.sql, db/seed-dev-teardown.sql (작업단위 산출물).
|
||||
프로젝트/하니스 커밋정책 = 사용자 요청 시에만 커밋 → 커밋 보류, 사용자 확인 대기.
|
||||
- (별도 작업단위) W3-2 댓글/리뷰 기능 코드 커밋 시 `/graphify src/` 재생성 + docs/graph/index.md
|
||||
frontmatter(source_commit, last_generated_at) + Scopes 표 src 행 갱신 권고. 본 더미데이터
|
||||
task 범위 밖.
|
||||
|
||||
# Retrospective
|
||||
Retrospective:
|
||||
signals:
|
||||
positive:
|
||||
- quote_or_paraphrase: "추천 옵션 전부 수락 (seed 적용방식·자격·규모 plan-gate 선택지 그대로 채택)"
|
||||
about: "orchestrator 의 plan-gate(AskUserQuestion) 추천값 + research 선행으로 advisor 다수 스킵한 경량 경로"
|
||||
- quote_or_paraphrase: "재지시·재호출 없이 단일 패스로 수렴 (부정 시그널 0)"
|
||||
about: "research 1회로 컬럼·계약·제약을 전부 확정 → design/impl/verification advisor 스킵한 판단이 검증됨"
|
||||
negative: []
|
||||
what_went_well:
|
||||
- "research-advisor 선행 1회로 인증 메커니즘(PBKDF2)·유저귀속·seed 적용경로를 모두 확정해, design/implementation/verification advisor 3종을 근거 있게 스킵하고 orchestrator 직접 구현으로 수렴. advisor invocation decision log 에 skip rationale 가 항목별로 남아 사후 추적 가능."
|
||||
- "호스트에 JDK 가 없는 제약에도 password_hash 를 추정·방치하지 않고 eclipse-temurin:21-jdk 컨테이너에서 실제 verifyPassword 코드 경로로 교차 실행(positive=true / negative=false)해 '로그인 가능' AC 를 자기검증으로 닫음. self-report 가 아닌 실행 증거."
|
||||
- "schema.sql 이 '비권위 복원본'이라는 메타 한계를 research concerns 에 보존하고, 컬럼명은 매퍼로 교차확인하되 제약·타입은 추정으로 표기해 신뢰도 과대평가를 회피."
|
||||
- "seed SQL 을 멱등 + teardown 쌍으로 작성하고 재실행 후 카운트 불변을 실증해 반복 적용 안전성을 확보."
|
||||
- "graph staleness 를 partial-stale 로 정직하게 판정하되, 본 세션 변경(데이터 픽스처)은 graph scope 밖임을 구분해 불필요한 재생성을 회피하고 잔여 stale 은 별도 작업단위로 정확히 귀속."
|
||||
what_to_improve:
|
||||
- "런타임 UI 스모크는 호스트 환경 제약(JDK 없음 + 앱 미가동)으로 자동 불가 → needs_user_verification 으로 정확히 이월됨. 개선이라기보다 환경 한계의 정직한 핸드오프. (구조적 결함 아님)"
|
||||
- "seed SQL 의 제약/타입/default 는 schema.sql 비권위 유래라 실 DB `\\d` 대조까지는 미수행(행수·테이블존재·매퍼 동등쿼리로만 검증). 운영 DB 와 default 가 다르면 재현 시 불일치 여지 — 현 dev 스키마에선 무영향이나 운영 적용 시 유의."
|
||||
memory_candidates:
|
||||
- name: bibimbap-auth-pbkdf2-not-bcrypt
|
||||
type: reference
|
||||
description: "bibimbap 로그인 해시는 BCrypt 가 아닌 자체 PBKDF2 — 로그인 가능 더미/테스트 계정 seed 시 이 포맷으로 직접 생성해야 함"
|
||||
body_draft: |
|
||||
# bibimbap 인증: PBKDF2 자체 해시 (BCrypt 아님)
|
||||
|
||||
Spring Security 미사용. 로그인은 UserController 자체 구현 password 검증.
|
||||
password_hash 포맷: `pbkdf2_sha256$210000$<base64(salt)>$<base64(hash)>` ($ 4필드)
|
||||
- 알고리즘 PBKDF2WithHmacSHA256, iterations=210000, keyLength=256bit, salt=16byte SecureRandom
|
||||
- 검증 경로: UserController.verifyPassword (parts[0]=="pbkdf2_sha256" && len==4 확인 후 동일 iter/salt 재계산, MessageDigest.isEqual 상수시간 비교)
|
||||
|
||||
## Why
|
||||
외부 BCrypt 생성기로 만든 해시는 무효 — 형식 자체가 다름. 향후 로그인 가능 더미/테스트/관리자 계정을
|
||||
seed 할 때마다 이 함정에 반복적으로 부딪힌다. 코드로 유도는 가능하나 "BCrypt 일 것"이라는 기본 가정이
|
||||
강해 매번 재확인 비용이 든다.
|
||||
|
||||
## How to apply
|
||||
- 로그인 가능 계정 seed 시 위 PBKDF2 스펙으로 해시 문자열을 직접 생성.
|
||||
- 로그인 동작 보장은 실제 verifyPassword 코드 경로(JDK 컨테이너 교차 실행 등)로 positive/negative 둘 다 확인.
|
||||
- 로그인 필수 조건 동봉: users.status='ACTIVE', user_auth_identities.provider='email',
|
||||
provider_user_id=정규화(trim+lowercase) 이메일, 양쪽 is_delete=false.
|
||||
rationale_for_saving: "코드로만 드러나는 비자명 사실(BCrypt 아님)이고, 테스트/더미 계정 seed 마다 재발하는 함정. schema/git log 로는 '자체 PBKDF2 라서 외부 생성기 무효'라는 함의가 드러나지 않음."
|
||||
signal_source: observation
|
||||
docs_sync_target: /Users/wemadeplay/workspace/stz/bibimbap/CLAUDE.md
|
||||
- name: bibimbap-seed-blueprint-fk-and-unique
|
||||
type: reference
|
||||
description: "dev 스키마 더미 seed 청사진 — FK 순서 + game_reviews active-unique 제약(게임당 user 1리뷰)"
|
||||
body_draft: |
|
||||
# bibimbap dev 더미 seed 청사진
|
||||
|
||||
현실적 경로 = dev 스키마에 psql 직접 INSERT (UI 경유는 CSRF+세션+WebGL 업로드 강제로 고비용).
|
||||
DB 직삽은 CSRF·세션·중복선검사를 우회하되 FK·CHECK·유니크idx 는 그대로 적용.
|
||||
|
||||
INSERT 순서(FK 의존):
|
||||
1. users (status='ACTIVE' 필수, role='USER', is_delete=false, display_name 권장)
|
||||
2. user_auth_identities (PBKDF2 password_hash — 별도 memory 참조; provider='email')
|
||||
3. games (user_id FK, name; is_visible/is_delete default 로 목록노출 충족; webgl/thumbnail NULL 가능)
|
||||
4. game_reviews (game_id, user_id, rating 1~5, body)
|
||||
5. game_comments (game_id, user_id, nickname[직접 채움 — 조회가 users JOIN 안 함], content)
|
||||
|
||||
## 핵심 제약
|
||||
- game_reviews 부분 유니크 idx `(game_id, user_id) WHERE is_delete IS NOT TRUE`
|
||||
→ 한 게임에 더미 리뷰 N개 = 더미 유저 N명 필요 (한 user 는 게임당 활성 1리뷰).
|
||||
- game_comments 는 유니크 없음 → 자유 다수. 작성자명 보이려면 nickname 직접 채움(비정규화 저장).
|
||||
- 게임 목록+상세 노출 = games.is_visible=true, games.is_delete=false, 연결 users.is_delete=false.
|
||||
|
||||
## Why
|
||||
리뷰 N개를 같은 유저로 넣으려다 유니크 위반으로 막히는 게 첫 시도의 흔한 실패. schema.sql 이
|
||||
'비권위 복원본'이라 제약을 코드에서 직접 읽기 전엔 드러나지 않음.
|
||||
|
||||
## How to apply
|
||||
- seed SQL 확정 직전 `\d dev.<table>` 로 제약/타입/default 운영 대조 권장(schema.sql 비권위).
|
||||
- 리뷰 다양화가 목표면 더미 유저를 리뷰 수만큼 선행 INSERT.
|
||||
rationale_for_saving: "seed 설계 시 반복되는 유니크-위반 함정 + FK 순서. schema.sql 비권위라 코드 교차확인 없이는 유도 불가하고, 더미/픽스처 작업마다 재사용되는 청사진."
|
||||
signal_source: observation
|
||||
docs_sync_target: null
|
||||
- name: java-crypto-verify-via-jdk-container-when-no-host-jdk
|
||||
type: feedback
|
||||
description: "호스트에 JDK 없을 때 Java 암호/검증 로직을 eclipse-temurin:21-jdk 컨테이너 single-file 실행으로 교차검증"
|
||||
body_draft: |
|
||||
# 호스트 JDK 부재 시 Java 로직 교차검증 패턴
|
||||
|
||||
호스트에 JDK 가 없고 앱도 미가동인 환경에서, password_hash 같은 Java 암호/검증 로직의
|
||||
정합성을 추정으로 닫지 않고 `eclipse-temurin:21-jdk` 컨테이너에 single-file/javac 로
|
||||
실제 코드 경로(예: verifyPassword)를 옮겨 실행해 positive+negative 케이스를 모두 확인.
|
||||
|
||||
## Why
|
||||
seed 한 해시가 "로그인 된다"는 self-report 는 증거가 아니다. 실제 검증 함수와 동일한
|
||||
알고리즘/iter/salt 로 재계산해 true/false 가 나와야 AC 가 닫힌다. 호스트 toolchain 부재는
|
||||
검증 생략의 이유가 되지 않고, 컨테이너로 우회 가능하다.
|
||||
|
||||
## How to apply
|
||||
- 검증 대상 메서드의 알고리즘 파라미터(iter/keyLength/salt/encoding)를 코드에서 그대로 추출.
|
||||
- 동일 로직을 단일 .java 로 재현해 temurin 컨테이너에서 실행, 정답=true / 오답=false 둘 다 확인.
|
||||
- 런타임 UI 스모크처럼 컨테이너로도 불가한 부분만 needs_user_verification 으로 이월.
|
||||
rationale_for_saving: "환경 제약(호스트 JDK 없음) + Java 검증 로직이라는 비자명 조합. self-report 대신 실행 증거로 AC 를 닫는 재현성 있는 검증 워크플로우 — 단발 우발 아님."
|
||||
signal_source: positive
|
||||
docs_sync_target: /Users/wemadeplay/workspace/stz/bibimbap/docs/development/verification-strategies.md
|
||||
protocol_feedback: []
|
||||
applied_changes: []
|
||||
|
|
@ -1,149 +0,0 @@
|
|||
---
|
||||
phase: research
|
||||
agent: research-advisor
|
||||
agent_version: 2
|
||||
generated_at: 2026-06-18T03:18:28Z
|
||||
concerns:
|
||||
- "low source confidence — db/schema.sql 은 헤더 주석상 '비권위 복원본'(users/user_auth_identities/game_comments). 컬럼명·매퍼 일치는 코드로 교차확인됐으나 타입·길이·기본값·제약은 추론값. 운영 DB 제약과 다를 수 있으므로 seed SQL 확정 전 실 DB(\\d 조회)로 컬럼·제약 대조 필요."
|
||||
- "BCrypt 가 아닌 PBKDF2 자체 해시이므로 seed용 password_hash 문자열은 외부 BCrypt 생성기로 만들 수 없음. iterations=210000/HmacSHA256/16byte-salt/256bit 스펙에 맞춰 직접 생성해야 함(생성 스크립트 자체는 design/구현 몫)."
|
||||
concerns_checked: true
|
||||
source_confidence: high
|
||||
workers_spawned: 3
|
||||
---
|
||||
|
||||
# 조사 결과
|
||||
|
||||
## 주제
|
||||
|
||||
bibimbap(Java 21 / Spring Boot / JSP / MyBatis, WAR) 에 테스트용 더미 데이터를 seed 하기 위한 사전 조사.
|
||||
"로그인·리뷰 작성이 실제로 동작하는" 형태로 (1) 게임 (2) 로그인 가능 계정 (3) 더미 리뷰+댓글 을 만들기 위한
|
||||
정확한 컬럼값·메커니즘 도출. 코드 수정 없음.
|
||||
|
||||
> 신뢰도 표기: `확인됨` = 코드/실행으로 1차 확인. `추정` = 통용·유추. `미확인` = 검증 불가.
|
||||
> 본 조사의 사실 항목은 전부 프로젝트 코드 직접 확인 기반 → `source_confidence: high`.
|
||||
> 다만 schema.sql 자체가 "비권위 복원본"이라는 메타 한계는 concerns 에 보존(컬럼명은 매퍼로 교차확인됨, 제약·타입은 추론).
|
||||
|
||||
---
|
||||
|
||||
## 포인트별 발견
|
||||
|
||||
### 포인트 A: 로그인/인증 메커니즘 (실제 로그인 가능한 계정 seed)
|
||||
|
||||
- 경로: `src/main/java/com/pandoli365/bibimbap/controller/api/UserController.java`,
|
||||
`data/UserAuthIdentityData.java`, `mapper/UserAuthIdentitiesMapper.java`, `mapper/UsersMapper.java`, `db/schema.sql`
|
||||
|
||||
요약:
|
||||
- **Spring Security 미사용.** `PasswordEncoder|SecurityFilterChain|@EnableWebSecurity|spring-boot-starter-security`
|
||||
src/ + pom.xml 0 hit. 인증은 UserController 자체 구현 password 로그인. **OAuth 없음**(google/kakao/naver/oauth 0 hit). [확인됨]
|
||||
- 로그인 엔드포인트: `POST /login`, form 파라미터 `email`,`password`,`remember`(선택) — UserController.java:122, 125-128. [확인됨]
|
||||
진입부에서 `CsrfTokens.isValid(request)` 실패 시 403 — UserController.java:131-133. [확인됨]
|
||||
- **provider 컬럼 값은 `"email"` 단 하나.** `PROVIDER_EMAIL="email"` — UserController.java:42.
|
||||
identity 생성 시 set — UserController.java:314. 조회 필터도 동일 값 — UserController.java:140-143. [확인됨]
|
||||
`provider_user_id` 에는 **정규화 이메일**(trim+lowercase) 저장 — UserController.java:104-106, 527-533. [확인됨]
|
||||
- **password_hash 알고리즘 = PBKDF2 (BCrypt 아님).** PasswordEncoder 빈 없음. 형식:
|
||||
`pbkdf2_sha256$<iterations>$<base64(salt)>$<base64(hash)>` (`$` 4필드) — UserController.java:554-556. [확인됨]
|
||||
- iterations=210000 (UserController.java:46), keyLength=256bit (:47), salt=16byte SecureRandom (:48,551-552),
|
||||
알고리즘 `PBKDF2WithHmacSHA256` via JCE SecretKeyFactory/PBEKeySpec (:576-584). [확인됨]
|
||||
- 검증: `verifyPassword()` 가 `$` split → parts[0]=="pbkdf2_sha256" && length==4 확인 후 동일 iterations/salt 재계산,
|
||||
`MessageDigest.isEqual` 상수시간 비교 — UserController.java:144, 559-574. [확인됨]
|
||||
- PBKDF2 표준 동작(iterations·salt 가 해시 문자열에 동봉되어 검증 시 재현 가능) — [추정/일반 통용 지식]
|
||||
- **로그인 성공 시 세션 저장** (saveLoginSession — UserController.java:162, 502-525). 세션 직전 `changeSessionId()` 세션고정방어 — :159-160. [확인됨]
|
||||
개별 attribute: `id`(Long), **`userId`(Long — 인증가드 sessionUserId() 가 읽는 키, :337)**, `displayName`, `email`(canonicalEmail),
|
||||
`avatarUrl`, `role`, `status`, `authProvider`("email"), `authIdentityId`, `lastLoginAt` — UserController.java:503-512.
|
||||
추가로 `account` 키에 위 값들의 LinkedHashMap 통째 저장 — :514-524. (UserData 객체 자체가 아니라 개별 스칼라+Map) [확인됨]
|
||||
- **로그인 검증 컬럼 흐름** [확인됨]:
|
||||
1. user_auth_identities `WHERE provider='email' AND provider_user_id=<정규화이메일> AND is_delete IS NOT TRUE` — UserAuthIdentitiesMapper.java:47-49
|
||||
2. password_hash != null && PBKDF2 통과 — UserController.java:144
|
||||
3. users `WHERE id=<identity.user_id> AND is_delete IS NOT TRUE` — UsersMapper.java:25-26
|
||||
4. **user.status == "ACTIVE"** 필수 (STATUS_ACTIVE=:44) — UserController.java:148-149
|
||||
|
||||
- **seed 시 필수 채움 컬럼** (schema.sql 비권위 — 컬럼명만 신뢰):
|
||||
- users: `role`(default 'USER'), **`status`='ACTIVE'**(ACTIVE 아니면 로그인 거부), `is_delete`=false. display_name/canonical_email 권장. — schema.sql:30-42 [확인됨, 제약값은 추정]
|
||||
- user_auth_identities: `user_id`(FK), `provider`='email', `provider_user_id`=정규화이메일(소문자), **`password_hash`=PBKDF2형식**(null이면 즉시거부), `is_delete`=false. — schema.sql:49-63 [확인됨, 제약값은 추정]
|
||||
- 주의: active-unique idx `ux_user_auth_identities_provider_user_id_active` = `(provider, provider_user_id) WHERE is_delete IS NOT TRUE` — schema.sql:66-68. 같은 이메일 활성 identity 중복 INSERT 실패. [확인됨, idx는 비권위 schema.sql]
|
||||
- 신뢰도: 확인됨 (코드 직접 확인). schema.sql 유래 제약값만 추정.
|
||||
|
||||
### 포인트 B: 리뷰/댓글 작성 시 유저 귀속 + INSERT 컬럼 + CSRF
|
||||
|
||||
- 경로: `controller/api/GameReviewController.java`, `data/GameReviewData.java`, `mapper/GameReviewsMapper.java`,
|
||||
`controller/api/GameCommentController.java`, `data/GameCommentData.java`, `mapper/GameCommentsMapper.java`,
|
||||
`security/CsrfTokens.java`, `db/schema.sql`, `docs/game-reviews-ddl.sql`
|
||||
|
||||
요약:
|
||||
- **리뷰 API**: GET `/game/{id}/reviews`(목록, :41-42), GET `/game/{id}/reviews/{reviewId}`(:58-62),
|
||||
POST `/game/{id}/reviews`(작성, :74), PUT(수정, :124), DELETE(소프트삭제, :170) — GameReviewController.java. [확인됨]
|
||||
작성 바디(@RequestParam, form): `rating`(String→1~5 파싱, 범위밖 400), `body`(최대 1000자) — :78-101, BODY_MAX=:30. [확인됨]
|
||||
- **user_id 출처 = 세션 attribute `"userId"`** (요청 바디 아님). `sessionUserId(session)` → `session.getAttribute("userId")` — GameReviewController.java:86, 241-257(:245). 없으면 401. `review.setUserId(userId)` — :109. [확인됨]
|
||||
- **game_reviews INSERT 컬럼 = 정확히 4개**: `(game_id, user_id, rating, body)` `#{}` 바인딩 — GameReviewsMapper.java:72-86. [확인됨]
|
||||
- game_id ← PathVariable(:108), user_id ← 세션(:109), rating ← 1~5 정수(:110; DB CHECK BETWEEN 1 AND 5 — schema.sql:129, docs/game-reviews-ddl.sql:49-53), body ← trimToEmpty(빈입력시 ""; DB text nullable) — :98,275-278. [확인됨]
|
||||
- 미포함(전부 DB DEFAULT): id(seq), created_at/updated_at(now()), is_delete(false), deleted_at(null) — schema.sql:124-127. [확인됨, 비권위 schema]
|
||||
- 참고: updated_at > created_at 이면 조회 시 edited=true 표시 — GameReviewsMapper.java:24, GameReviewController.java:210. [확인됨]
|
||||
- **ux_game_reviews_game_user_active** = 부분 유니크 인덱스 `(game_id, user_id) WHERE is_delete IS NOT TRUE` — schema.sql:132-133, docs/game-reviews-ddl.sql:58-61. [확인됨]
|
||||
의미: 활성 리뷰는 (game,user) 조합당 1개. soft-delete 행은 제외 → 재작성 허용. 코드도 INSERT 전 중복 선검사 후 409 — GameReviewController.java:103-105, GameReviewsMapper.java:56-70. [확인됨]
|
||||
**seed 주의**: 한 게임에 더미 리뷰 여러 개 원하면 각 행 user_id 를 다르게. 한 user 는 게임당 활성 1개. [확인됨]
|
||||
- **댓글 API**: GET `/game/{id}/comments`(:39), POST(작성, :56), PUT(:102), DELETE(소프트삭제, :143). 작성 바디 `content`만(최대 200자, CONTENT_MAX=:28) — GameCommentController.java:60,75-78. [확인됨]
|
||||
- user_id ← 세션 `"userId"` (:67,198). [확인됨]
|
||||
- **nickname 비정규화 저장 확정**: 작성 시점 세션 `"displayName"` 을 nickname 컬럼에 복사 — `comment.setNickname(authorName)` :84, sessionDisplayName=session.getAttribute("displayName") :212-218(:216). 조회 시 users JOIN 없이 nickname 그대로 노출(`nickname AS authorName`) — GameCommentsMapper.java:36, GameCommentController.java:179. [확인됨]
|
||||
- **game_comments INSERT 컬럼 = 정확히 4개**: `(game_id, user_id, nickname, content)` — GameCommentsMapper.java:46-60. user_id nullable FK(schema.sql:112), nickname varchar(100) nullable(:102). [확인됨, 비권위 schema]
|
||||
- 유니크 제약 없음 → 같은 (game,user) 댓글 여러 개 가능. 화면 작성자명 보이려면 nickname 직접 채워야(조회가 users JOIN 안 함). 목록 정렬 created_at ASC, id ASC — GameCommentsMapper.java:42. [확인됨]
|
||||
- **CSRF**: Spring Security 미사용 → 표준 CSRF 필터 없음. 대신 자체 `CsrfTokens` 유틸을 컨트롤러 mutation 진입부에서 수동검증. [확인됨]
|
||||
- 리뷰 POST/PUT/DELETE: GameReviewController.java:83-85,134-136,178-180. 댓글: GameCommentController.java:64-66,111-113,151-153. GET 은 검증 없음. [확인됨]
|
||||
- 토큰: 세션 key `"csrfToken"`, 헤더 `X-CSRF-Token`(우선) 또는 폼 파라미터 `_csrf`(폴백), 32byte SecureRandom Base64url — CsrfTokens.java:12-13,20-33,35-49. [확인됨]
|
||||
- **영향**: HTTP API 경유 수동 작성은 로그인세션+csrfToken+헤더/파라미터 필요. **DB 직접 INSERT seed 는 CSRF·세션·중복선검사 모두 우회**(단 DB 유니크idx·CHECK·FK 는 그대로 적용). [확인됨]
|
||||
- 신뢰도: 확인됨. schema.sql/ddl 유래 제약만 추정.
|
||||
|
||||
### 포인트 C: seed 적용 경로 + 게임 표시 조건
|
||||
|
||||
- 경로: `.env`, `docker-compose.yml`, `src/main/resources/dev/db.properties`, `GameController.java`, `GamesMapper.java`,
|
||||
`data/GameData.java`, `db/schema.sql`, `WEB-INF/views/game-detail.jsp`
|
||||
|
||||
요약:
|
||||
- **DB 접속 정보 확정** (.env + docker-compose.yml + dev/db.properties 일관) [확인됨, 실행 확인]:
|
||||
- DB명 `bibimbap`, 유저 `bibimbap`, 패스워드 `change_me_local_dev`, 호스트포트 5433 → 컨테이너 5432.
|
||||
- .env: POSTGRES_DB/USER=bibimbap, POSTGRES_PASSWORD=change_me_local_dev, APP_SCHEMA=dev, DB_PORT=5433
|
||||
- docker-compose.yml:18 `"${DB_PORT:-5432}:5432"`, :40 `jdbc:...:5432/${POSTGRES_DB}?currentSchema=${APP_SCHEMA:-dev}`
|
||||
- dev/db.properties:2-4 `jdbc:postgresql://localhost:5433/bibimbap?currentSchema=dev`
|
||||
- 컨테이너 `bibimbap-db postgres:16 Up (healthy) 0.0.0.0:5433->5432/tcp` (docker compose ps 실행 확인)
|
||||
- **앱 스키마 = `dev`**. psql 접속: `PGPASSWORD=change_me_local_dev psql -h localhost -p 5433 -U bibimbap -d bibimbap` 후 `SET search_path TO dev;` (또는 `dev.games` 한정).
|
||||
- **현재 dev.games / dev.users 모두 0행** (read-only 조회 확인). live 스키마는 테이블 없음 → 앱 데이터는 전적으로 dev. [확인됨]
|
||||
- **게임 표시 조건** (목록과 상세가 다름; games-users INNER JOIN `JOIN users u ON u.id=g.user_id` → 유효 미삭제 user 필수) — GamesMapper.java:32-33. [확인됨]
|
||||
- 상세(getGame, GamesMapper.java:34-36): `g.id=#{id} AND g.is_delete IS NOT TRUE AND u.is_delete IS NOT TRUE`. **is_visible 조건 없음** → 비공개 게임도 id 직접 접근 시 상세 뜸. [확인됨]
|
||||
- 목록(getVisibleGames, GamesMapper.java:57-59): `g.is_visible IS NOT FALSE AND g.is_delete IS NOT TRUE AND u.is_delete IS NOT TRUE`. [확인됨]
|
||||
- **목록+상세 모두 보이려면**: games.is_visible=true, games.is_delete=false, 연결 users.is_delete=false. [확인됨]
|
||||
- 컨트롤러: gameDetail 이 getGame(id)!=null 이면 DB 게임으로 game-detail 렌더 — GameController.java:113-121. [확인됨]
|
||||
- **games INSERT 필수(NOT NULL, no-default) 컬럼 = `user_id`(FK→users), `name` 둘뿐** — schema.sql:75-87. [확인됨, 비권위 schema]
|
||||
- default 보유(생략가능): like_count(0), is_visible(true), sort_order(0), created_at/updated_at(now()), is_delete(false). nullable: creator_note, git_url, webgl_path, thumbnail_url. id=seq.
|
||||
- 최소 INSERT `(user_id, name)` 만으로 가능 + 목록노출 조건 자동충족. 단 user_id FK 로 **users 행 선행 필수**.
|
||||
- **asset 컬럼 NULL 이어도 상세/리뷰 동작 — 깨지지 않음** [확인됨]:
|
||||
- game-detail.jsp:12-21 webglFrameSrc null/blank/"null" 시 빈 문자열 폴백 → iframe src="" 빈화면(예외 없음). 컨트롤러가 trimToEmpty 정규화 후 모델 주입(GameController.java:273,281-283)이라 NPE 없음.
|
||||
- thumbnail_url 은 상세 JSP 미사용. 리뷰/댓글은 별도 비동기 API(`/game/{id}/reviews`,`/comments`)로 로드 → game asset 컬럼과 무관.
|
||||
- 결론: webgl_path/thumbnail_url 을 NULL 로 둬도 상세 + 리뷰/댓글 테스트 가능.
|
||||
- 신뢰도: 확인됨 (코드 + 실행). schema.sql 유래 제약만 추정.
|
||||
|
||||
---
|
||||
|
||||
## 종합 판단 (더미 seed 실행 청사진)
|
||||
|
||||
세 포인트가 한 흐름으로 맞물린다. **현실적 seed 경로 = dev 스키마에 psql 직접 INSERT** (앱 UI 경유는 CSRF+세션+WebGL 업로드 강제로 고비용; DB 직삽은 그 전부 우회하되 FK·CHECK·유니크idx 만 적용).
|
||||
|
||||
INSERT 순서(FK 의존성):
|
||||
1. **users** 1행: status='ACTIVE'(필수 — 아니면 로그인 거부), role='USER', is_delete=false, display_name 권장(목록 creator + 댓글 nickname 소스).
|
||||
2. **user_auth_identities** 1행: user_id=위 user, provider='email', provider_user_id=<정규화 소문자 이메일>, password_hash=**PBKDF2 형식** `pbkdf2_sha256$210000$<b64salt>$<b64hash>`, is_delete=false. (활성 유니크 idx 주의)
|
||||
3. **games** 1행: user_id=위 user, name=값. is_visible/is_delete 는 default 로 목록노출 충족. webgl_path/thumbnail_url NULL 가능.
|
||||
4. **game_reviews** N행: (game_id, user_id, rating 1~5, body). **한 게임당 user 1활성리뷰** → 여러 리뷰면 user 여러 개 seed.
|
||||
5. **game_comments** N행: (game_id, user_id, nickname[직접 채움], content). 유니크 없음 → 자유 다수.
|
||||
|
||||
**로그인 가능 핵심(질문의 최우선 관심사)**: password_hash 는 BCrypt 가 아니라 PBKDF2WithHmacSHA256.
|
||||
평문→해시는 외부 BCrypt 도구로 만들 수 없고, iterations=210000 / 256bit / 16byte salt / base64 스펙으로
|
||||
`pbkdf2_sha256$210000$<base64salt>$<base64hash>` 문자열을 생성해 넣어야 검증 통과한다.
|
||||
(해시 생성 스크립트 작성은 design/구현 단계 몫 — research 범위 밖.)
|
||||
|
||||
권위 격상 전 검증 필요 항목: db/schema.sql 이 비권위 복원본이므로, 위 컬럼 *제약/타입/default* 는 seed SQL 확정 직전
|
||||
실 DB `\d dev.users / \d dev.user_auth_identities / \d dev.games / \d dev.game_reviews / \d dev.game_comments` 로 대조 권장.
|
||||
(컬럼명·매퍼 일치·인덱스 존재는 코드/실행으로 확인됨 — 불일치 위험은 타입/제약값에 한정.)
|
||||
|
||||
## 미해결
|
||||
|
||||
- PBKDF2 seed 해시를 실제로 생성하는 도구/스크립트는 미작성(설계·구현 영역). 본 조사는 "어떤 형식이어야 검증 통과하는가"까지만.
|
||||
- db/schema.sql 비권위로 인한 컬럼 *제약/타입/default* 의 운영 DB 대조는 미수행(읽기조회로 행수·테이블존재만 확인). seed SQL 확정 전 `\d` 대조 필요.
|
||||
- game_likes 서버측 like_count 증감 경로(좋아요는 localStorage 클라이언트 토글로 보임) — 더미 리뷰/계정/게임 범위 밖이라 미조사.
|
||||
|
|
@ -1,162 +0,0 @@
|
|||
---
|
||||
schema_version: 2
|
||||
sid: 20260618-145152
|
||||
started_at: 2026-06-18T14:51:52+09:00
|
||||
ended_at: 2026-06-18T14:58:00+09:00 # 인터뷰 1차에서 사용자 지시로 일시정지 (구현 다음 세션)
|
||||
user_request: |
|
||||
W3-2 댓글/리뷰 고도화 — 인터뷰 주도 디테일 빌드.
|
||||
W3-2 코어(2026-06-18 구현·검증 완료) 유지하며 세세한 디테일을 사용자 인터뷰로 누적.
|
||||
바로 설계·구현 금지. 질문 시드 카탈로그(A 일관성 / B 목록규모 / C UX)를 한 축씩
|
||||
AskUserQuestion 으로 물어 결정 누적 → design-advisor → 구현 → L1 회귀 31건 + 신규 → L3 스모크.
|
||||
mode: interview-first (orchestrator 직접 인터뷰, requirements-advisor 대체)
|
||||
---
|
||||
|
||||
# Advisor Invocation Decision Log
|
||||
- advisor: requirements-advisor
|
||||
decision: skip
|
||||
rationale: '카탈로그가 요구 분해를 이미 제공 — orchestrator 가 AskUserQuestion 인터뷰로 직접 스코프 확정(task 명시)'
|
||||
checked_at: 2026-06-18T14:52:00+09:00
|
||||
- advisor: design-advisor
|
||||
decision: deferred-to-next-session
|
||||
rationale: '인터뷰 완료·FINAL SPEC 사용자 확정. 단 사용자 지시로 구현은 다음 세션 → design-advisor 도 다음 세션 진입. 선결: W2-3 freeze 근거 확인'
|
||||
checked_at: 2026-06-18T15:10:00+09:00
|
||||
- advisor: retrospective-advisor
|
||||
decision: skip
|
||||
rationale: '코드 변경 0줄·구현 미시작 인터뷰 전용 세션. 회고 입력(구현/검증 결과) 부재 → 구현 세션 종료 시 수행'
|
||||
checked_at: 2026-06-18T15:10:00+09:00
|
||||
|
||||
# Summary
|
||||
인터뷰 완료 — 카탈로그 전 축(A1·A2·A3 / B1·B2·B3 / 리뷰정책4 / C1~C6) 결정 누적 완료.
|
||||
사용자 지시로 이 세션은 **결정·기록만, 구현은 다음 세션**. 코드 변경 0줄(Serena/grep 탐색만).
|
||||
다음 세션: 새 sid + `resumed_from: 20260618-145152`, 아래 FINAL SPEC 으로 design-advisor 진입.
|
||||
|
||||
## ⚠️ 다음 세션 선결·고위험 항목
|
||||
- **C3 = W2-3 평점 집계 동결 해제**: 설계 진입 전 W2-3 freeze 근거(ADR/문서) 필독. §6 파괴적 게이트 인접 — orchestrator 사용자 재확인. 회귀 검증 필수
|
||||
- **다축 평점 = 대규모 신규**: game_review_axes 테이블 + 6축 입력 UI + overall 자동평균/수동덮어쓰기 + game_review_stats 뷰(축별 평균). 작업량·테스트 비중 큼
|
||||
- 입력 부담: 리뷰 제출 = 6축 필수 + 본문 10자 — UX 마찰 인지
|
||||
|
||||
# FINAL SPEC (✅ 사용자 최종확인 완료 2026-06-18 — 다음 세션 design-advisor 입력)
|
||||
|
||||
## A. 일관성
|
||||
- **A1** 댓글 응답 = `commentView` 단일 통일(POST·PUT·list 전부). POST는 insert 후 재조회(createReview 패턴)
|
||||
- **A2** 작성자명 = 하이브리드 `COALESCE(u.display_name, c.nickname)` + LEFT JOIN. user_id 있으면 현재닉(개명반영), NULL이면 스냅샷(QG-2 해결). createComment nickname 스냅샷 저장 유지
|
||||
- 탈퇴자: 댓글 보존(LEFT JOIN) / 리뷰 현행 제외 유지(INNER JOIN). 탈퇴자 댓글 이름 = "(탈퇴한 사용자)" 마스킹: `CASE WHEN u.id IS NULL THEN c.nickname WHEN u.is_delete THEN '(탈퇴한 사용자)' ELSE u.display_name END`
|
||||
- **A3** 댓글 edited+updatedAt 추가. game_comments.updated_at 멱등 ALTER + 매퍼/모델 갱신. editGameComment 시 updated_at 갱신, nickname 미덮어씀
|
||||
|
||||
## B. 목록 규모
|
||||
- **B1** 페이지네이션 offset/limit + "더보기", 20건/페이지. 정렬 토글: 댓글(오래된순 기본/최신순), 리뷰(최신순 기본/별점 높은순/낮은순, tiebreaker rating·created_at·id). sort 화이트리스트 enum→고정 SQL(${} 금지)
|
||||
- **B2** 리뷰 본문 필수 + 최소 10자(별점만 제출 불가). 댓글은 현행(200자 상한, 최소 없음)
|
||||
- **B3** 본문 정규화 = 제어문자 제거 + 외곽 trim(댓글·리뷰 공통). 내부 연속공백·줄바꿈 보존
|
||||
|
||||
## 리뷰 정책
|
||||
- 게임당 **1회 유지**(ux 유니크), 수정 **무제한 유지**(edited 마커)
|
||||
- **다축 평점**: overall rating 유지(W2-3 집계용) + game_review_axes 신규 테이블(review_id FK, axis_key enum, score). 축 6개 **몰입성·창의성·조작성·완성도·사운드·비주얼**, 각 1~5 정수 **전 축 필수**. UI: overall = 축 평균 자동계산(정수 반올림)되다 유저 직접선택 시 덮어쓰기(수동 우선, 출처 구분 플래그 검토)
|
||||
- **다축 시각화 = 육각형 레이더 차트(hexagon)**:
|
||||
- 위치 = **요약 + 개별 리뷰 둘 다** (요약=game_review_stats 6축 평균 육각형 / 각 리뷰 카드=그 리뷰 6축 육각형)
|
||||
- 렌더 = **인라인 SVG 자체 구현** (polygon points 계산, 기존 JSP 인라인 SVG idiom·빌드 없음·의존성 0). 차트 라이브러리/CDN 배제
|
||||
- 입력은 **6개 별점 위젯 유지(C6)** — 육각형은 표시 전용(레이더 드래그 입력 a11y 제외)
|
||||
- **a11y**: SVG 시각요소엔 텍스트 대체 필수 — 축별 점수 aria-label 또는 인접 텍스트/표(스크린리더). 폴리곤만으로 끝내지 말 것
|
||||
- 개별 리뷰 카드 육각형은 컴팩트 사이즈(페이지당 20건 DOM 고려)
|
||||
- 신고·숨김 **보류**(W1 운영자 role 선행)
|
||||
|
||||
## C. UX (game-detail.jsp)
|
||||
- **C1** submit 잠금 + 로딩 상태(제출 중 disabled)
|
||||
- **C2** 상대시각 "n분 전" + title 절대시각(fmtDate 확장)
|
||||
- **C3** ⚠️ W2-3 동결 해제 + game_review_stats **뷰**(game_id, avg_rating, review_count + 6축 평균). 표시 = 소수1자리 + 반올림 별 + 0개 "아직 평가 없음". client 계산 폐기(페이지네이션 정합)
|
||||
- **C4** 실시간 글자수 카운터(123/200, 리뷰 최소10자 안내). 댓글·리뷰 둘 다
|
||||
- **C5** 삭제 = 완전 소멸 유지(현행)
|
||||
- **C6** 별점 위젯 완전 radiogroup 패턴(roving tabindex + 화살표/Home/End), 다축 6위젯 적용
|
||||
|
||||
# Grounded Baseline (evidence)
|
||||
- GameCommentController 응답 3종 불일치:
|
||||
- POST createComment flat: status,message,commentId,gameId,authorName,userId,content (createdAt/edited 없음)
|
||||
- PUT updateComment 부분: status,message,commentId,content
|
||||
- list commentView: commentId,gameId,authorName,userId,content,createdAt (edited 없음)
|
||||
- GameReviewController 이미 통일: POST/PUT/list/get 전부 reviewView 사용
|
||||
- reviewView: reviewId,gameId,authorName,userId,rating,body,edited,createdAt,updatedAt
|
||||
- 댓글 작성자명 = nickname 스냅샷 (createComment: session displayName 저장)
|
||||
- GameCommentData 필드: id,gameId,userId,nickname,content,createdAt,deletedAt — **updatedAt 없음**
|
||||
→ A3(댓글 수정됨 마커)는 game_comments.updated_at ALTER 필요 (무료 아님)
|
||||
- createReview: rating 필수, body trimToEmpty 후 length 검사만 → 빈 본문 리뷰 허용 (B2)
|
||||
- trimToNull/trimToEmpty = 외곽 trim 만; 내부 연속공백/제어문자 미처리 (B3)
|
||||
- DDL game-reviews-ddl.sql: game_reviews(updated_at 보유), game_comments user_id nullable(레거시 보존)
|
||||
- W2-3 평점 집계 스키마 동결 / QG-2 레거시 user_id NULL 댓글 미결
|
||||
- **A2 작성자명 메커니즘 분기 (신규 발견)**:
|
||||
- 리뷰 = `JOIN users u, u.display_name AS authorName` (GameReviewsMapper) → 항상 현재 닉네임(live)
|
||||
+ `u.is_delete IS NOT TRUE` 조건 → **탈퇴자 리뷰는 목록서 제외됨**
|
||||
- 댓글 = `nickname` 컬럼 스냅샷(작성 시점 고정, GameCommentsMapper listGameComments:36) → 탈퇴자 댓글도 표시
|
||||
- 댓글 매퍼에 미사용 `updateGameComment`(nickname 갱신 가능) 존재 (:81) — A2/A3 설계 시 활용 여지
|
||||
- QG-2 결합: 레거시 user_id NULL 댓글은 JOIN 불가 → live-join 채택 시 스냅샷 fallback 필수
|
||||
|
||||
# Decisions (누적)
|
||||
- A3 댓글 수정됨 마커: **edited+updatedAt 추가** (리뷰 대칭). game_comments.updated_at 멱등 ALTER + 매퍼 갱신 필요. [2026-06-18]
|
||||
- A1 응답 스키마: **commentView 단일 통일** — POST·PUT·list 전부 commentView 반환(commentId,gameId,authorName,userId,content,createdAt,edited,updatedAt). POST는 insert 후 재조회(createReview 패턴). 프론트 렌더 1함수. [2026-06-18]
|
||||
|
||||
# Invocations
|
||||
[]
|
||||
|
||||
# user_signals
|
||||
positive: []
|
||||
negative: []
|
||||
|
||||
# verified_by_me
|
||||
(없음 — 코드 변경 0줄, 인터뷰만 수행. L1/L2/log-scan 비대상)
|
||||
|
||||
# needs_user_verification
|
||||
- 다음 세션: 인터뷰 재개(아래 어젠다) → 결정 충분 시 design-advisor → 구현 → L1 회귀 31건+신규 → L3 스모크.
|
||||
|
||||
# graph_refresh
|
||||
skip: 코드 변경 0줄 (graph-refresh-checker 비대상)
|
||||
|
||||
# Next-session agenda (인터뷰 재개 지점)
|
||||
## 결정 잠금 (재확인만)
|
||||
- A1 = commentView 단일 통일 (POST·PUT·list 전부 commentView; POST insert 후 재조회)
|
||||
- A3 = 댓글 edited+updatedAt 추가 (game_comments.updated_at 멱등 ALTER + 매퍼/모델 갱신)
|
||||
- 종속: A1 통일 시 commentView 가 edited/updatedAt 자동 포함 → 두 결정 한 묶음 구현
|
||||
- A2 = **하이브리드 작성자명**: `COALESCE(u.display_name, c.nickname)` + **LEFT JOIN users** (GameCommentsMapper getGameComment/listGameComments 둘 다)
|
||||
- user_id 있으면 현재 닉네임(개명 반영, 리뷰와 일관) / NULL이면 스냅샷 nickname → **QG-2 자동 해결**
|
||||
- createComment 의 nickname 스냅샷 저장은 **유지**(fallback 안전망). 미사용 updateGameComment(:81)는 edit 시 nickname 덮어쓰지 않도록 주의
|
||||
- A2-탈퇴자 = **댓글 보존 / 리뷰 현행(제외) 유지**: 댓글 LEFT JOIN(is_delete 무필터) → 탈퇴자 댓글 표시. 리뷰 INNER JOIN+`u.is_delete IS NOT TRUE` 그대로 → 리뷰 스코프·31건 테스트 무영향
|
||||
- A2-탈퇴자-이름 = **"(탈퇴한 사용자)" 마스킹**. 댓글 SQL: `CASE WHEN u.id IS NULL THEN c.nickname WHEN u.is_delete THEN '(탈퇴한 사용자)' ELSE u.display_name END AS authorName` (LEFT JOIN). 탈퇴 플래그 노출 불필요 — 이름만 대체
|
||||
- B1 = **페이지네이션 도입 + 기본 정렬 현행 유지** (댓글 오래된순 ASC / 리뷰 최신순 DESC 기본). 전건 반환 폐기 → offset/limit 또는 cursor (방식·크기·정렬옵션은 후속 질문)
|
||||
- B1-방식 = **offset/limit + "더보기" 버튼, 페이지당 20건**. page/offset 쿼리 파라미터
|
||||
- B1-정렬 = **댓글·리뷰 모두 정렬 토글**:
|
||||
- 댓글: 오래된순(기본)/최신순
|
||||
- 리뷰: 최신순(기본)/별점 높은순/낮은순 — 별점순 정렬은 tiebreaker 필요(rating DESC/ASC, created_at DESC, id DESC)
|
||||
- API sort 파라미터 신설 + 프론트 정렬 컨트롤. 매퍼 정렬절 동적화(단 `${}` 금지 — sort 화이트리스트 enum→고정 SQL 분기로 #{} 안전 유지)
|
||||
- B3 = **제어문자 제거 + 외곽 trim** (댓글 content·리뷰 body 공통). 탭/개행 외 제어문자 strip, 내부 연속공백·줄바꿈은 보존. textContent 렌더라 보안 아닌 저장 위생 목적
|
||||
- B2 = **리뷰 본문 필수 + 최소 10자** (별점만 제출 불가). createReview/updateReview body 검증 추가. 댓글은 별도(200자 상한만, 최소 없음 — 변경 안 함)
|
||||
- 확장 리뷰 정책 4영역:
|
||||
- ① 게임당 1회 제한 = **1회 유지(현행)** — ux_game_reviews_game_user_active 유지, 무결성 우선
|
||||
- ② 수정 제한 = **무제한 수정 유지(현행)** — edited 마커로 투명성
|
||||
- ③ 별점 척도 = **다축 평점 도입**. 세부:
|
||||
- **overall rating 유지 + 축 별도** (W2-3 집계 동결 안 건드림 — 집계는 game_reviews.rating 그대로). 축은 game_review_axes 신규 테이블
|
||||
- **UI 동작**: overall 별점 = 축 점수 평균으로 자동계산·표시되다가, 유저가 overall 을 직접 선택하면 그 값으로 강제 덮어쓰기 (수동 우선)
|
||||
- 설계 미결: 자동평균→정수 rating 반올림 정책(C3 평균 별점 정책과 연동) / rating 수동·자동 출처 구분 필요(예 is_rating_manual 플래그?)
|
||||
- **축 6개**: 몰입성, 창의성, 조작성, 완성도, 사운드, 비주얼
|
||||
- 축 척도 = **1~5 정수, 전 축 필수** (overall 과 동일, 자동평균 결정적)
|
||||
- 스키마 = **game_review_axes 테이블** (review_id FK + axis_key + score, 리뷰당 6행). axis_key enum 6종. DDL 신규 테이블 + FK + 인덱스(review_id)
|
||||
- 다축 평점 = **풀스펙 확정**. 입력 부담(6축 필수 + 본문 10자)은 인지하고 진행
|
||||
- ④ 신고·숨김 = **도입 보류(W1 선행)** — 운영자 role 활성 후 신고+숨김 함께. 현 세션 스코프 제외
|
||||
|
||||
## 미결 — 다음 세션 질문 순서 (1~2축씩, AskUserQuestion, 추천 맨앞+근거+트레이드오프)
|
||||
3. **C UX (game-detail.jsp)** — JSP grounding 완료:
|
||||
- C1 연타 방지 = **submit 잠금 + 로딩 상태** (제출 중 disabled, 응답 후 해제). 댓글 중복 POST 차단
|
||||
- C2 시간 표시 = **상대시각 "n분 전" + title 속성에 절대시각** (fmtDate:1202 대체/확장)
|
||||
- C3 평균 별점 = **⚠️ W2-3 동결 해제 + 집계 컬럼/뷰 신설** (사용자 informed 선택, 고위험 — 회귀 검증 필수). 표시 = **소수1자리 + 반올림 별 + 0개는 "아직 평가 없음" 문구**
|
||||
- 모순 해소: client 계산은 B1 페이지네이션과 충돌 → 서버 집계로 전환 확정
|
||||
- **다음 세션 설계 선결조건**: W2-3 freeze 근거(ADR/문서) 먼저 읽고 무엇이 왜 동결됐는지 파악 후 해제. §6 파괴적 게이트 인접 — orchestrator 사용자 확인 경로
|
||||
- 리뷰별 overall 자동평균(축→overall)은 rating 정수라 정수 반올림 / 전체 평균 표시는 소수1자리 (반올림 컨텍스트 2종 구분)
|
||||
- 집계 방식 = **뷰(VIEW) 기반** — game_review_stats 뷰(game_id, avg_rating, review_count + 6축 평균). 저장 컬럼 비신설(파생 객체만) → 동결 해제 중 회귀 표면 최소
|
||||
- 축별 평균 = **overall + 6축 평균 모두 요약 표시**. UI에 축별 막대/점수. 뷰가 축별 AVG(game_review_axes JOIN) 포함
|
||||
- C4 글자수 카운터 = **실시간 카운터** (123/200 형식, 리뷰는 최소 10자 미달 안내). 댓글·리뷰 textarea 둘 다 + (다축 도입 시 6축 위젯 입력 상태도 고려)
|
||||
- C5 삭제 표시 = **완전 소멸 유지(현행)** — soft-delete + is_delete 필터. 댓글 스레드 없어 tombstone 불필요
|
||||
- C6 접근성 = **완전 radiogroup 패턴** — roving tabindex(위젯당 단일 탭정지) + ←→↑↓·Home/End 별점 이동, aria 유지. 다축 6위젯 동일 적용. 현 위젯은 화살표 핸들러 없음(grep 확인) — 신규 추가
|
||||
- grounding 근거: 별점위젯:1043(role=radiogroup/radio+aria 기구현), 평균:1034, 댓글ta:1080(max200), 리뷰ta:1052(max1000), 제출버튼:538(disabled 없음)
|
||||
|
||||
## 인터뷰 종료 후 (task 명시)
|
||||
1. 누적 결정 최종 확인 → 2. design-advisor: 파일 소유권 맵 + 멱등 ALTER DDL → 3. 구현 → L1 31건 회귀+신규 → L3 스모크 → 4. docs/changes/ 이력 기록
|
||||
|
||||
# open_items
|
||||
- `.atp/work-session/20260618-145152/report.md` (신규, untracked) — 세션 기록. 커밋은 사용자 지시 시 (CLAUDE.md 커밋 정책: 명시 요청 시만).
|
||||
- src/ 변경 0건 — 구현 미시작.
|
||||
|
|
@ -1,364 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>W3-2 UI 프리뷰 — 육각형 레이더 · 6축 평점 · 카드</title>
|
||||
<style>
|
||||
html {
|
||||
color-scheme: light;
|
||||
--surface: #faf8f5; --card-bg: #fff; --text: #1a1a1a; --text-muted: #5c5c5c;
|
||||
--accent: #e8a54b; --accent-soft: rgba(232,165,75,0.14);
|
||||
--border: rgba(0,0,0,0.08); --panel-shadow: 0 4px 24px rgba(26,26,26,0.06); --radius: 16px;
|
||||
}
|
||||
html[data-theme="dark"] {
|
||||
color-scheme: dark;
|
||||
--surface: #121212; --card-bg: #1e1e1e; --text: #ece8e1; --text-muted: #a39e96;
|
||||
--border: rgba(255,255,255,0.1); --accent-soft: rgba(232,165,75,0.12);
|
||||
--panel-shadow: 0 8px 32px rgba(0,0,0,0.35);
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0; min-height: 100vh; padding: 2rem 1rem 4rem;
|
||||
font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Noto Sans KR", sans-serif;
|
||||
color: var(--text);
|
||||
}
|
||||
html:not([data-theme="dark"]) body { background: linear-gradient(165deg,#fff9f0 0%,var(--surface) 45%,#f3ede6 100%); background-attachment: fixed; }
|
||||
html[data-theme="dark"] body { background: linear-gradient(165deg,#1c1a18 0%,var(--surface) 38%,#0e0e0e 100%); background-attachment: fixed; }
|
||||
.wrap { max-width: 56rem; margin: 0 auto; }
|
||||
.preview-bar { display: flex; align-items: center; justify-content: space-between; margin-bottom: 1.5rem; }
|
||||
.preview-bar h1 { font-size: 1.1rem; margin: 0; letter-spacing: -0.02em; }
|
||||
.preview-bar button { padding: 0.45rem 1rem; font: inherit; font-weight: 700; font-size: 0.8rem; cursor: pointer;
|
||||
color: var(--text); background: var(--card-bg); border: 1px solid var(--border); border-radius: 999px; }
|
||||
.game-panel { padding: 1.4rem 1.5rem 1.6rem; margin-bottom: 1.5rem; background: var(--card-bg);
|
||||
border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--panel-shadow); }
|
||||
.game-panel__title { margin: 0 0 0.2rem; font-size: 1.05rem; letter-spacing: -0.02em; }
|
||||
.game-panel__subtitle { margin: 0 0 1.1rem; font-size: 0.8rem; color: var(--text-muted); }
|
||||
.section-tag { font-size: 0.7rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
|
||||
color: var(--accent); margin: 0 0 0.6rem; }
|
||||
|
||||
/* ===== 아래는 game-detail.jsp 승격본과 동일한 W3-2 컴포넌트 스타일 ===== */
|
||||
.game-reviews__summary { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 1rem; }
|
||||
.game-reviews__avg { font-size: 1.35rem; font-weight: 800; letter-spacing: -0.02em; color: var(--accent); }
|
||||
.game-reviews__count { font-size: 0.75rem; font-weight: 600; color: var(--text-muted); }
|
||||
.game-stars--avg, .game-stars--display { display: inline-flex; gap: 0.05rem; font-size: 0.95rem; line-height: 1; }
|
||||
.game-stars--avg .game-star, .game-stars--display .game-star { color: var(--border); }
|
||||
.game-stars--avg .game-star.is-on, .game-stars--display .game-star.is-on { color: var(--accent); }
|
||||
|
||||
.game-reviews__summary-panel { margin: 0 0 1.25rem; display: flex; align-items: center; gap: 1.25rem;
|
||||
padding: 1rem 1.25rem;
|
||||
background: radial-gradient(125% 125% at 0% 0%, var(--accent-soft), transparent 62%), var(--card-bg);
|
||||
border: 1px solid rgba(232,165,75,0.22); border-radius: var(--radius); box-shadow: var(--panel-shadow); }
|
||||
@media (max-width: 480px) { .game-reviews__summary-panel { flex-direction: column; align-items: stretch; gap: 0.85rem; } .game-reviews__radar { justify-content: center; } }
|
||||
.game-reviews__radar { display: inline-flex; flex-shrink: 0; }
|
||||
.game-reviews__radar svg { display: block; }
|
||||
.game-axis-radar { overflow: visible; }
|
||||
.game-reviews__radar .game-axis-grid { fill: none; stroke: var(--border); stroke-width: 1; }
|
||||
.game-reviews__radar .game-axis-grid--outer { stroke: rgba(232,165,75,0.4); stroke-width: 1.25; }
|
||||
.game-reviews__radar .game-axis-line { stroke: var(--border); stroke-width: 1; stroke-dasharray: 2 3; }
|
||||
.game-reviews__radar .game-axis-poly { stroke: var(--accent); stroke-width: 1.75; stroke-linejoin: round;
|
||||
filter: drop-shadow(0 2px 7px rgba(232,165,75,0.38)); transform-box: fill-box; transform-origin: center;
|
||||
animation: game-radar-pop 0.55s cubic-bezier(0.22,1,0.36,1) both; }
|
||||
.game-reviews__radar .game-axis-dot { fill: var(--accent); stroke: var(--card-bg); stroke-width: 1.5;
|
||||
animation: game-radar-fade 0.7s ease both; }
|
||||
@keyframes game-radar-pop { from { opacity: 0; transform: scale(0.55); } to { opacity: 1; transform: scale(1); } }
|
||||
@keyframes game-radar-fade { from { opacity: 0; } to { opacity: 1; } }
|
||||
.game-reviews__radar-empty { font-size: 0.75rem; color: var(--text-muted); }
|
||||
.game-reviews__axis-legend { margin: 0; flex: 1; min-width: 11.5rem; display: grid; gap: 0.4rem 0; font-size: 0.75rem; color: var(--text-muted); }
|
||||
.game-reviews__axis-legend-row { display: grid; grid-template-columns: 3.4rem 1fr 1.15rem; align-items: center; gap: 0.55rem; }
|
||||
.game-reviews__axis-legend dt { font-weight: 600; color: var(--text); }
|
||||
.game-reviews__axis-legend dd { margin: 0; font-variant-numeric: tabular-nums; font-weight: 700; text-align: right; color: var(--accent); }
|
||||
.game-reviews__axis-meter { height: 0.4rem; border-radius: 999px; background: var(--border); overflow: hidden; }
|
||||
.game-reviews__axis-meter span { display: block; height: 100%; border-radius: 999px;
|
||||
background: linear-gradient(90deg,#f0c978,var(--accent)); animation: game-meter-grow 0.7s cubic-bezier(0.22,1,0.36,1) both; transform-origin: left; }
|
||||
@keyframes game-meter-grow { from { transform: scaleX(0); } to { transform: scaleX(1); } }
|
||||
|
||||
/* 6축 입력 */
|
||||
.game-reviews__composer { margin-bottom: 1.25rem; padding: 1.1rem 1.15rem 1.2rem;
|
||||
background: radial-gradient(140% 120% at 100% 0%, rgba(232,165,75,0.16), transparent 60%), var(--accent-soft);
|
||||
border: 1px solid rgba(232,165,75,0.22); border-radius: 14px; }
|
||||
.game-reviews__axes { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: 0.5rem 1.1rem; margin-bottom: 0.85rem; }
|
||||
@media (max-width: 480px) { .game-reviews__axes { grid-template-columns: 1fr; } }
|
||||
.game-reviews__axis { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
|
||||
padding: 0.3rem 0.5rem; border-radius: 10px; transition: background 0.15s ease; }
|
||||
.game-reviews__axis:hover { background: rgba(232,165,75,0.08); }
|
||||
.game-reviews__axis-label { font-size: 0.8125rem; font-weight: 600; color: var(--text); }
|
||||
.game-stars { display: inline-flex; gap: 0.15rem; line-height: 1; }
|
||||
.game-stars--axis { gap: 0.1rem; }
|
||||
.game-stars__btn { padding: 0.1rem; font-size: 1.6rem; line-height: 1; color: var(--border);
|
||||
background: none; border: none; cursor: pointer; transition: color 0.12s ease, transform 0.12s ease, text-shadow 0.2s ease; }
|
||||
.game-stars--axis .game-stars__btn { font-size: 1.25rem; }
|
||||
.game-stars__btn:hover { transform: scale(1.12); }
|
||||
.game-stars__btn.is-on { color: var(--accent); text-shadow: 0 1px 4px rgba(232,165,75,0.45); }
|
||||
.game-stars__btn:active { transform: scale(0.88); }
|
||||
.game-stars__btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
|
||||
.game-reviews__rating-row { display: flex; align-items: center; gap: 0.85rem; margin-bottom: 0.85rem; }
|
||||
.game-comments__label { font-size: 0.8125rem; font-weight: 600; color: var(--text-muted); }
|
||||
.game-comments__form textarea { width: 100%; min-height: 5rem; padding: 0.85rem 1rem; font: inherit; font-size: 0.875rem;
|
||||
line-height: 1.55; color: var(--text); background: var(--surface); border: 1px solid var(--border); border-radius: 12px; resize: vertical; }
|
||||
.game-comments__form textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 4px rgba(232,165,75,0.18); }
|
||||
.game-comments__actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.5rem; margin-top: 0.65rem; }
|
||||
.game-comments__hint { font-size: 0.6875rem; color: var(--text-muted); }
|
||||
.game-comments__hint.is-warn { color: #b33; font-weight: 700; }
|
||||
.game-comments__form button[type="submit"] { padding: 0.55rem 1.5rem; font: inherit; font-size: 0.875rem; font-weight: 700; color: #1a1a1a;
|
||||
background: linear-gradient(180deg,#f0c978 0%,var(--accent) 100%); border: none; border-radius: 10px; cursor: pointer;
|
||||
box-shadow: 0 2px 8px rgba(232,165,75,0.35); transition: transform 0.15s ease, box-shadow 0.2s ease; }
|
||||
.game-comments__form button[type="submit"]:hover { box-shadow: 0 4px 14px rgba(232,165,75,0.45); }
|
||||
button[aria-busy="true"] { opacity: 0.65; cursor: progress; }
|
||||
|
||||
/* sort 토글 / 더보기 */
|
||||
.game-comments__toolbar { display: flex; justify-content: flex-end; margin-bottom: 0.85rem; }
|
||||
.game-comments__sort { display: inline-flex; gap: 0.25rem; padding: 0.2rem; background: var(--surface); border: 1px solid var(--border); border-radius: 999px; }
|
||||
.game-comments__sort-btn { padding: 0.3rem 0.7rem; font: inherit; font-size: 0.6875rem; font-weight: 700; color: var(--text-muted);
|
||||
background: transparent; border: none; border-radius: 999px; cursor: pointer; transition: color 0.15s ease, background 0.15s ease; }
|
||||
.game-comments__sort-btn.is-active { color: #1a1a1a; background: linear-gradient(180deg,#f0c978,var(--accent)); box-shadow: 0 1px 5px rgba(232,165,75,0.4); }
|
||||
.game-comments__more { margin-top: 1rem; display: flex; justify-content: center; }
|
||||
.game-comments__more-btn { padding: 0.5rem 1.4rem; font: inherit; font-size: 0.8125rem; font-weight: 700; color: var(--text);
|
||||
background: var(--card-bg); border: 1px solid var(--border); border-radius: 999px; cursor: pointer; transition: border-color 0.15s ease, color 0.15s ease, transform 0.15s ease, box-shadow 0.2s ease; }
|
||||
.game-comments__more-btn:hover { border-color: var(--accent); color: var(--accent); transform: translateY(-1px); box-shadow: 0 5px 16px rgba(232,165,75,0.16); }
|
||||
|
||||
/* 리뷰/덧글 카드 */
|
||||
.game-reviews__list, .game-comments__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.85rem; }
|
||||
.game-reviews__item { padding: 0.95rem 1.1rem; font-size: 0.875rem; line-height: 1.55; background: var(--surface); border: 1px solid var(--border); border-radius: 14px; }
|
||||
.game-reviews__item.is-mine { border-color: rgba(232,165,75,0.4); background: var(--accent-soft); }
|
||||
.game-reviews__item-head { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem 0.65rem; margin-bottom: 0.5rem; }
|
||||
.game-reviews__nick { font-size: 0.8125rem; font-weight: 700; letter-spacing: -0.02em; }
|
||||
.game-reviews__mine-badge { padding: 0.05rem 0.45rem; font-size: 0.625rem; font-weight: 700; color: var(--accent); background: rgba(232,165,75,0.16); border-radius: 999px; }
|
||||
.game-reviews__time, .game-comments__meta time { margin-left: auto; font-size: 0.6875rem; font-weight: 500; letter-spacing: 0.02em; color: var(--text-muted); }
|
||||
.game-comments__edited, .game-reviews__edited { margin-left: 0.35rem; font-size: 0.6875rem; font-weight: 500; color: var(--text-muted); }
|
||||
.game-reviews__body, .game-comments__item p { margin: 0; white-space: pre-wrap; word-break: break-word; }
|
||||
.game-reviews__card-radar { margin-top: 0.6rem; display: inline-flex; }
|
||||
.game-reviews__card-radar svg { display: block; }
|
||||
.game-reviews__radar-empty { font-size: 0.75rem; color: var(--text-muted); }
|
||||
.game-comments__item { display: flex; gap: 0.75rem; align-items: flex-start; padding: 0.85rem 1rem; font-size: 0.875rem; line-height: 1.55; background: var(--surface); border: 1px solid var(--border); border-radius: 14px; }
|
||||
.game-comments__avatar { flex-shrink: 0; width: 2.25rem; height: 2.25rem; border-radius: 50%; display: flex; align-items: center; justify-content: center;
|
||||
font-size: 0.75rem; font-weight: 800; color: var(--accent); background: var(--accent-soft); border: 1px solid rgba(232,165,75,0.25); }
|
||||
.game-comments__meta { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.35rem 0.65rem; margin-bottom: 0.4rem; }
|
||||
.game-comments__nick { font-size: 0.75rem; font-weight: 700; }
|
||||
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); border: 0; }
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.game-reviews__radar .game-axis-poly, .game-reviews__radar .game-axis-dot, .game-reviews__axis-meter span, .game-comments__more-btn:hover { animation: none; transform: none; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrap">
|
||||
<div class="preview-bar">
|
||||
<h1>W3-2 UI 프리뷰 · 육각형 레이더 · 6축 평점</h1>
|
||||
<button id="theme-toggle" type="button">🌙 다크</button>
|
||||
</div>
|
||||
|
||||
<!-- 리뷰 패널 -->
|
||||
<section class="game-panel">
|
||||
<p class="section-tag">리뷰 요약 (game_review_stats)</p>
|
||||
<div class="game-reviews__summary">
|
||||
<span class="game-reviews__avg" id="avg">4.2</span>
|
||||
<div class="game-stars game-stars--avg" id="avg-stars" aria-hidden="true"></div>
|
||||
<span class="game-reviews__count">(37)</span>
|
||||
</div>
|
||||
<div class="game-reviews__summary-panel" id="summary-panel"></div>
|
||||
|
||||
<p class="section-tag">6축 평가 입력 (radiogroup · 키보드 ←→↑↓/Home/End)</p>
|
||||
<div class="game-reviews__composer">
|
||||
<div class="game-reviews__axes" id="axes" aria-label="6축 평가"></div>
|
||||
<div class="game-reviews__rating-row">
|
||||
<span class="game-comments__label" id="overall-label">종합 별점 (선택)</span>
|
||||
<div class="game-stars game-stars--input" id="overall" role="radiogroup" aria-labelledby="overall-label"></div>
|
||||
</div>
|
||||
<label class="game-comments__label" for="rbody">평가</label>
|
||||
<textarea id="rbody" rows="3" maxlength="1000" placeholder="이 게임을 어떻게 즐기셨나요? (최소 10자)"></textarea>
|
||||
<div class="game-comments__actions">
|
||||
<span class="game-comments__hint" id="rhint"><span id="rcount">0/1000</span> · 6축은 필수, 종합 별점은 선택이에요</span>
|
||||
<button type="submit">리뷰 등록</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="section-tag">리뷰 목록 · 정렬 · 카드 컴팩트 레이더</p>
|
||||
<div class="game-comments__toolbar">
|
||||
<div class="game-comments__sort" role="group" aria-label="리뷰 정렬">
|
||||
<button type="button" class="game-comments__sort-btn is-active">최신순</button>
|
||||
<button type="button" class="game-comments__sort-btn">별점 높은순</button>
|
||||
<button type="button" class="game-comments__sort-btn">별점 낮은순</button>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="game-reviews__list" id="review-list"></ul>
|
||||
<div class="game-comments__more"><button type="button" class="game-comments__more-btn">더보기</button></div>
|
||||
</section>
|
||||
|
||||
<!-- 덧글 패널 -->
|
||||
<section class="game-panel">
|
||||
<p class="section-tag">덧글 · 상대시각 · 글자수 카운터</p>
|
||||
<div class="game-reviews__composer" style="background: var(--surface); border-color: var(--border);">
|
||||
<label class="game-comments__label" for="cbody">내용</label>
|
||||
<textarea id="cbody" rows="2" maxlength="200" placeholder="여기에 덧글을 작성해 주세요."></textarea>
|
||||
<div class="game-comments__actions">
|
||||
<span class="game-comments__hint"><span id="ccount">0/200</span></span>
|
||||
<button type="submit">덧글 등록</button>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="game-comments__list" id="comment-list"></ul>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// game-detail.jsp 승격본과 동일 로직 (좌표공식·미터바)
|
||||
var AXIS_KEYS = ['immersion','creativity','controls','completeness','sound','visual'];
|
||||
var AXIS_LABELS_KO = { immersion:'몰입성', creativity:'창의성', controls:'조작성', completeness:'완성도', sound:'사운드', visual:'비주얼' };
|
||||
var SVG_NS = 'http://www.w3.org/2000/svg';
|
||||
var labelSeq = 0, hexSeq = 0;
|
||||
|
||||
function buildHexRadar(scores, cx, cy, R) {
|
||||
var canvas = cx * 2;
|
||||
var svg = document.createElementNS(SVG_NS, 'svg');
|
||||
svg.setAttribute('viewBox', '0 0 ' + canvas + ' ' + canvas);
|
||||
svg.setAttribute('width', String(Math.round(canvas * 0.85)));
|
||||
svg.setAttribute('height', String(Math.round(canvas * 0.85)));
|
||||
svg.setAttribute('role', 'img');
|
||||
svg.setAttribute('class', 'game-axis-radar');
|
||||
var nums = AXIS_KEYS.map(function (k, i) { var v = scores ? Number(scores[i]) : 0; return (isFinite(v) && v > 0) ? v : 0; });
|
||||
var hasData = nums.some(function (v) { return v > 0; });
|
||||
function ptOnAxis(i, ratio) { var ang = (-90 + 60 * i) * Math.PI / 180; return { x: cx + R * ratio * Math.cos(ang), y: cy + R * ratio * Math.sin(ang) }; }
|
||||
function polyPoints(fn) { return AXIS_KEYS.map(function (k, i) { var p = ptOnAxis(i, fn(i)); return p.x.toFixed(2) + ',' + p.y.toFixed(2); }).join(' '); }
|
||||
var gid = 'hexfill-' + (++hexSeq);
|
||||
var defs = document.createElementNS(SVG_NS, 'defs');
|
||||
var grad = document.createElementNS(SVG_NS, 'radialGradient');
|
||||
grad.setAttribute('id', gid); grad.setAttribute('cx', '50%'); grad.setAttribute('cy', '50%'); grad.setAttribute('r', '62%');
|
||||
[['0%','rgba(240,201,120,0.55)'],['100%','rgba(232,165,75,0.26)']].forEach(function (s) {
|
||||
var st = document.createElementNS(SVG_NS,'stop'); st.setAttribute('offset', s[0]); st.setAttribute('stop-color', s[1]); grad.appendChild(st);
|
||||
});
|
||||
defs.appendChild(grad); svg.appendChild(defs);
|
||||
for (var level = 1; level <= 4; level++) {
|
||||
var grid = document.createElementNS(SVG_NS, 'polygon');
|
||||
grid.setAttribute('class', 'game-axis-grid' + (level === 4 ? ' game-axis-grid--outer' : ''));
|
||||
(function (lv) { grid.setAttribute('points', polyPoints(function () { return lv / 4; })); })(level);
|
||||
svg.appendChild(grid);
|
||||
}
|
||||
AXIS_KEYS.forEach(function (k, i) {
|
||||
var line = document.createElementNS(SVG_NS, 'line'); line.setAttribute('class', 'game-axis-line');
|
||||
var p = ptOnAxis(i, 1); line.setAttribute('x1', String(cx)); line.setAttribute('y1', String(cy));
|
||||
line.setAttribute('x2', p.x.toFixed(2)); line.setAttribute('y2', p.y.toFixed(2)); svg.appendChild(line);
|
||||
});
|
||||
if (hasData) {
|
||||
var poly = document.createElementNS(SVG_NS, 'polygon'); poly.setAttribute('class', 'game-axis-poly');
|
||||
poly.setAttribute('points', polyPoints(function (i) { return nums[i] / 5; })); poly.setAttribute('fill', 'url(#' + gid + ')'); svg.appendChild(poly);
|
||||
AXIS_KEYS.forEach(function (k, i) {
|
||||
if (nums[i] <= 0) return; var p = ptOnAxis(i, nums[i] / 5);
|
||||
var dot = document.createElementNS(SVG_NS, 'circle'); dot.setAttribute('class', 'game-axis-dot');
|
||||
dot.setAttribute('cx', p.x.toFixed(2)); dot.setAttribute('cy', p.y.toFixed(2)); dot.setAttribute('r', Math.max(1.6, R * 0.05).toFixed(2)); svg.appendChild(dot);
|
||||
});
|
||||
}
|
||||
svg.setAttribute('aria-label', hasData ? ('6축 평가: ' + AXIS_KEYS.map(function (k, i) { return AXIS_LABELS_KO[k] + ' ' + nums[i]; }).join(', ')) : '6축 평가 없음');
|
||||
return { svg: svg, nums: nums, hasData: hasData };
|
||||
}
|
||||
function buildRadarLegend(nums, hasData) {
|
||||
var dl = document.createElement('dl'); dl.className = 'game-reviews__axis-legend';
|
||||
AXIS_KEYS.forEach(function (k, i) {
|
||||
var row = document.createElement('div'); row.className = 'game-reviews__axis-legend-row';
|
||||
var dt = document.createElement('dt'); dt.textContent = AXIS_LABELS_KO[k];
|
||||
var meter = document.createElement('div'); meter.className = 'game-reviews__axis-meter';
|
||||
var bar = document.createElement('span'); bar.style.width = (hasData ? (nums[i] / 5 * 100) : 0) + '%'; meter.appendChild(bar);
|
||||
var dd = document.createElement('dd'); dd.textContent = hasData ? String(nums[i]) : '–';
|
||||
row.appendChild(dt); row.appendChild(meter); row.appendChild(dd); dl.appendChild(row);
|
||||
});
|
||||
return dl;
|
||||
}
|
||||
var axisScores = {};
|
||||
function buildStarRadioGroup(axisKey, labelText) {
|
||||
var labelId = 'star-' + axisKey + '-' + (++labelSeq);
|
||||
var group = document.createElement('div'); group.className = 'game-stars game-stars--input game-stars--axis';
|
||||
group.setAttribute('role', 'radiogroup'); group.setAttribute('aria-labelledby', labelId);
|
||||
var radios = [];
|
||||
function paint() { var sel = axisScores[axisKey] || 0; radios.forEach(function (b, idx) { var v = idx + 1; b.classList.toggle('is-on', v <= sel); b.setAttribute('aria-checked', v === sel ? 'true' : 'false'); b.tabIndex = (v === sel) ? 0 : -1; }); if (!sel) radios[0].tabIndex = 0; }
|
||||
function select(v) { axisScores[axisKey] = v; paint(); }
|
||||
for (var i = 1; i <= 5; i++) { (function (v) {
|
||||
var b = document.createElement('button'); b.type = 'button'; b.className = 'game-stars__btn'; b.setAttribute('role','radio'); b.setAttribute('aria-checked','false'); b.setAttribute('aria-label', labelText + ' ' + v + '점'); b.tabIndex = -1; b.textContent = '★';
|
||||
b.addEventListener('click', function () { select(v); b.focus(); });
|
||||
b.addEventListener('keydown', function (ev) { var cur = axisScores[axisKey] || 0; var next = null;
|
||||
switch (ev.key) { case 'ArrowRight': case 'ArrowUp': next = Math.min(5,(cur||v)+1); break; case 'ArrowLeft': case 'ArrowDown': next = Math.max(1,(cur||v)-1); break; case 'Home': next = 1; break; case 'End': next = 5; break; case ' ': case 'Enter': next = v; break; default: return; }
|
||||
ev.preventDefault(); select(next); radios[next-1].focus(); });
|
||||
radios.push(b); group.appendChild(b);
|
||||
})(i); }
|
||||
paint(); return { group: group, labelId: labelId };
|
||||
}
|
||||
function fillStars(c, rating) { c.innerHTML = ''; for (var i = 1; i <= 5; i++) { var s = document.createElement('span'); s.className = 'game-star' + (i <= rating ? ' is-on' : ''); s.textContent = '★'; c.appendChild(s); } }
|
||||
function buildStarDisplay(rating) { var w = document.createElement('div'); w.className = 'game-stars game-stars--display'; w.setAttribute('aria-hidden','true'); fillStars(w, rating); return w; }
|
||||
|
||||
// 요약 (큰 레이더 + 미터바 범례)
|
||||
fillStars(document.getElementById('avg-stars'), 4);
|
||||
(function () {
|
||||
var panel = document.getElementById('summary-panel');
|
||||
var radar = buildHexRadar([4.3, 4.6, 3.8, 4.4, 3.5, 4.7], 100, 100, 80);
|
||||
panel.appendChild(radar.svg); panel.appendChild(buildRadarLegend(radar.nums, true));
|
||||
})();
|
||||
|
||||
// 6축 입력 위젯
|
||||
(function () {
|
||||
var axesEl = document.getElementById('axes');
|
||||
AXIS_KEYS.forEach(function (k) {
|
||||
var row = document.createElement('div'); row.className = 'game-reviews__axis';
|
||||
var label = document.createElement('span'); label.className = 'game-reviews__axis-label'; label.textContent = AXIS_LABELS_KO[k];
|
||||
var w = buildStarRadioGroup(k, AXIS_LABELS_KO[k]); label.id = w.labelId;
|
||||
row.appendChild(label); row.appendChild(w.group); axesEl.appendChild(row);
|
||||
});
|
||||
var ov = buildStarRadioGroup('overall', '종합 별점'); var oEl = document.getElementById('overall');
|
||||
while (ov.group.firstChild) oEl.appendChild(ov.group.firstChild);
|
||||
})();
|
||||
|
||||
// 글자수 카운터 + 최소10자 경고
|
||||
function counter(ta, out, max, min) {
|
||||
function upd() { var len = ta.value.length; out.textContent = len + '/' + max; if (min) { var w = len > 0 && len < min; out.parentElement.classList.toggle('is-warn', w); } }
|
||||
ta.addEventListener('input', upd); upd();
|
||||
}
|
||||
counter(document.getElementById('rbody'), document.getElementById('rcount'), 1000, 10);
|
||||
counter(document.getElementById('cbody'), document.getElementById('ccount'), 200, 0);
|
||||
|
||||
// 리뷰 카드 (axes 있음/없음 두 케이스)
|
||||
function reviewCard(r) {
|
||||
var li = document.createElement('li'); li.className = 'game-reviews__item' + (r.mine ? ' is-mine' : '');
|
||||
var head = document.createElement('div'); head.className = 'game-reviews__item-head';
|
||||
head.appendChild(buildStarDisplay(r.rating));
|
||||
var nick = document.createElement('span'); nick.className = 'game-reviews__nick'; nick.textContent = r.nick; head.appendChild(nick);
|
||||
if (r.mine) { var mb = document.createElement('span'); mb.className = 'game-reviews__mine-badge'; mb.textContent = '내 리뷰'; head.appendChild(mb); }
|
||||
var t = document.createElement('time'); t.className = 'game-reviews__time'; t.textContent = r.time; head.appendChild(t);
|
||||
if (r.edited) { var ed = document.createElement('span'); ed.className = 'game-reviews__edited'; ed.textContent = '(수정됨)'; head.appendChild(ed); }
|
||||
li.appendChild(head);
|
||||
var p = document.createElement('p'); p.className = 'game-reviews__body'; p.textContent = r.body; li.appendChild(p);
|
||||
var cardScores = AXIS_KEYS.map(function (k) { return r.axes ? r.axes[k] : 0; });
|
||||
var cr = buildHexRadar(cardScores, 60, 60, 44);
|
||||
var wrap = document.createElement('div'); wrap.className = 'game-reviews__radar game-reviews__card-radar';
|
||||
if (cr.hasData) { wrap.appendChild(cr.svg); var lg = buildRadarLegend(cr.nums, true); lg.className += ' sr-only'; wrap.appendChild(lg); }
|
||||
else { var none = document.createElement('span'); none.className = 'game-reviews__radar-empty'; none.textContent = '6축 평가 데이터 없음'; wrap.appendChild(none); }
|
||||
li.appendChild(wrap);
|
||||
return li;
|
||||
}
|
||||
var rl = document.getElementById('review-list');
|
||||
rl.appendChild(reviewCard({ rating: 5, nick: '도토리', time: '12분 전', edited: false, mine: true, body: '몰입감이 정말 뛰어나요. 사운드가 조금 아쉽지만 전반적으로 완성도 높은 게임입니다.', axes: { immersion:5, creativity:5, controls:4, completeness:5, sound:3, visual:5 } }));
|
||||
rl.appendChild(reviewCard({ rating: 3, nick: '바삭이', time: '3일 전', edited: true, mine: false, body: '아이디어는 좋은데 조작이 좀 불편했어요. 다음 빌드 기대합니다.', axes: { immersion:3, creativity:4, controls:2, completeness:3, sound:3, visual:4 } }));
|
||||
rl.appendChild(reviewCard({ rating: 4, nick: '레거시유저', time: '2026. 5. 1.', edited: false, mine: false, body: '(구버전 리뷰 — 6축 데이터 없음 케이스)', axes: null }));
|
||||
|
||||
// 덧글 카드
|
||||
function commentCard(c) {
|
||||
var li = document.createElement('li'); li.className = 'game-comments__item';
|
||||
var av = document.createElement('div'); av.className = 'game-comments__avatar'; av.textContent = c.nick.charAt(0); li.appendChild(av);
|
||||
var body = document.createElement('div'); body.style.flex = '1';
|
||||
var meta = document.createElement('div'); meta.className = 'game-comments__meta';
|
||||
var nick = document.createElement('span'); nick.className = 'game-comments__nick'; nick.textContent = c.nick; meta.appendChild(nick);
|
||||
var t = document.createElement('time'); t.textContent = c.time; meta.appendChild(t);
|
||||
if (c.edited) { var ed = document.createElement('span'); ed.className = 'game-comments__edited'; ed.textContent = '(수정됨)'; meta.appendChild(ed); }
|
||||
body.appendChild(meta);
|
||||
var p = document.createElement('p'); p.textContent = c.body; body.appendChild(p); li.appendChild(body);
|
||||
return li;
|
||||
}
|
||||
var cl = document.getElementById('comment-list');
|
||||
cl.appendChild(commentCard({ nick: '플레이어A', time: '방금 전', edited: false, body: '재밌게 했습니다! 2스테이지 보스가 인상적이네요.' }));
|
||||
cl.appendChild(commentCard({ nick: '(탈퇴한 사용자)', time: '5일 전', edited: false, body: '탈퇴자 댓글 마스킹 케이스 — 이름이 "(탈퇴한 사용자)" 로 표시됩니다.' }));
|
||||
|
||||
// 테마 토글
|
||||
document.getElementById('theme-toggle').addEventListener('click', function () {
|
||||
var dark = document.documentElement.getAttribute('data-theme') === 'dark';
|
||||
document.documentElement.setAttribute('data-theme', dark ? 'light' : 'dark');
|
||||
this.textContent = dark ? '🌙 다크' : '☀️ 라이트';
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
---
|
||||
phase: documentation
|
||||
agent: documentation-advisor
|
||||
agent_version: 1
|
||||
generated_at: 2026-06-22T10:00:00+09:00
|
||||
concerns:
|
||||
- "C3 재분류(W2-3 동결 경계 재확인)는 되돌리기 어려운 아키텍처 경계 결정에 해당할 수 있으나, 실체는 기존 오분류를 roadmap 근거(:63/:201/:202)로 정정한 것이므로 현재는 changes/ 내 별도 섹션으로 기록. W2-3 관련 설계 분기가 재발하면 adr/ADR-0001 발행 권고."
|
||||
- "design-advisor 가 이미 .atp/work-session/20260622-092800/implementation/design.md 에 설계 산출물을 남김. architecture/ 중복 갱신 없음 — changes/ + work-session/ 중심으로 처리."
|
||||
- "frontend-design 스킬이 game-detail.jsp 시각 컴포넌트를 처리했으므로 JSP 프론트엔드 세부 구현은 changes/ 문서에서 요약 수준으로만 기록."
|
||||
- "retrospective 교훈 4건은 development/verification-strategies.md 에 '설계·테스트 단계 체크리스트' 섹션 및 '프로토콜 개선 권고' 섹션으로 추가 완료 (2026-06-22 retrospective-advisor 수용 결정 반영)."
|
||||
- "backport self-grep: verification-strategies.md 근거 블록(> 근거:)에 20260622·GameController.gameDetail 잔류 — 요구사항 '이번 세션 사례는 1줄 근거로' 허용 패턴이므로 정본 규칙형 텍스트에는 포함되지 않음. docs/development/release-checklist.md §7 부재 — 해당 절차 미적용(N/A에 준함)."
|
||||
concerns_checked: true
|
||||
---
|
||||
|
||||
# 문서화 보고
|
||||
|
||||
## 작성/수정된 문서
|
||||
|
||||
| 경로 | 카테고리 | 유형 | 링크 추가한 index | 교차 링크 |
|
||||
|---|---|---|---|---|
|
||||
| `docs/changes/2026-06-22-w3-2-comments-reviews-enhancement.md` | changes | 신규 | `docs/changes/index.md` | `docs/changes/2026-06-18-w3-2-comments-reviews.md` (이월 항목 해소 링크) |
|
||||
| `docs/changes/index.md` | changes | 갱신 | — | — |
|
||||
| `docs/changes/2026-06-18-w3-2-comments-reviews.md` | changes | 갱신 (이월 항목 해소 표기) | — | `docs/changes/2026-06-22-w3-2-comments-reviews-enhancement.md` |
|
||||
| `docs/development/verification-strategies.md` | development | 갱신 (섹션 추가) | index 추가 불필요(기존 등록) | report.md#Retrospective memory_candidates docs_sync_target |
|
||||
|
||||
## 의사결정 기록 위치
|
||||
|
||||
- **C3 재분류**: `docs/changes/2026-06-22-w3-2-comments-reviews-enhancement.md` §C3 재분류 섹션 + `.atp/work-session/20260622-092800/implementation/design.md` §C3 재분류
|
||||
- **is_rating_manual 컬럼 채택**: `design.md` concerns 2번 + `report.md#Decisions`
|
||||
- **axis_key 저장형·순서 고정**: `design.md` concerns 5번 + §2.1
|
||||
- **sort 안전 (@SelectProvider 컴파일타임 상수)**: `design.md` §4 + `report.md#Decisions`
|
||||
- **pagination = limit+1 hasMore**: `design.md` §3.3 + `report.md#Decisions`
|
||||
- **SVG 육각형 = JS 런타임**: `design.md` §6.1 concerns 4번
|
||||
|
||||
## 추후 문서화가 필요한 항목
|
||||
|
||||
- **ADR-0001 (권고)**: W2-3 동결 경계 확정(잼 평가 한정, 댓글/리뷰 무관) — C3 재분류 정정의 배경이 된 경계 결정을 정식 ADR로 남길 가치 있음.
|
||||
- **DDL 적용 완료 시**: `docs/maintenance/` 에 dev/운영 DB 적용 절차(game_review_axes·game_review_stats·game_comments.updated_at·game_reviews.is_rating_manual) 기록 검토.
|
||||
- **L3 스모크 완료 후**: `docs/changes/2026-06-22-w3-2-comments-reviews-enhancement.md` 검증 결과 표에서 "needs_user_verification" → "PASS (날짜)" 갱신.
|
||||
- **기존 리뷰 axes 백필**: 백필 필요 판단 시 `docs/maintenance/` 에 절차 문서화.
|
||||
- **GET /reviews/mine (applyReviewGate 정밀화)**: 차기 세션 구현 완료 후 changes/ 업데이트.
|
||||
|
|
@ -1,536 +0,0 @@
|
|||
---
|
||||
phase: design
|
||||
agent: design-advisor
|
||||
agent_version: 1
|
||||
generated_at: 2026-06-22T00:00:00+09:00
|
||||
concerns:
|
||||
- "C3 재분류 확정: game_review_stats 는 W3-2 일반 DDL(읽기전용 집계뷰). W2-3 동결 묶음 아님 — 근거 jam-platform-roadmap.md:63,201,202. 단 game-reviews-ddl.sql:63 / db/schema.sql:136-137 의 '집계뷰 미신설' 보수 주석이 본 설계로 무효화되므로 구현 시 두 곳 주석 갱신 필수(미갱신 시 차기 세션 혼선)."
|
||||
- "is_rating_manual 플래그 채택 — game_reviews 행 폭 증가(boolean 1컬럼). 채택 근거는 §5.3. 비채택 대안(매번 axes AVG 재계산)도 가능하나 '유저가 자동평균과 같은 값을 수동선택' 케이스를 구분 못 함 → 채택. 구현에서 이 컬럼이 실제 분기에 쓰이는지(수동/자동 표시 차별화 UI 없으면 dead) 재확인 필요."
|
||||
- "GameReviewsMapper.editGameReview 의 axes 재저장은 delete-all + insert-6 채택(§5.2). upsert(ON CONFLICT) 대안 대비 단순하나, 6 DELETE+6 INSERT 트랜잭션. axes 매퍼 신규 분리 vs GameReviewsMapper 확장 — 신규 GameReviewAxesMapper 채택(§1, §5). 단일 책임."
|
||||
- "SVG 육각형 좌표는 JS 런타임 계산 채택(§6). JSP 컴파일타임(JSTL) 대안은 개별 리뷰 N건 동적 렌더와 맞지 않음 — 기존 buildStarDisplay 패턴(JS DOM 생성)과 일관. 좌표 공식은 §6 에 고정."
|
||||
- "axis_key DB 저장형 = 영문 snake(immersion/creativity/controls/completeness/sound/visual). 한글 라벨(몰입성 등)은 JSP 상수 매핑. enum 순서 = 육각형 각 축 인덱스(0~5)와 1:1 고정 — 순서 바뀌면 레이더 축 위치 변동. §2.1 / §6.3 에 순서 고정."
|
||||
- "B2 최소 10자: 기존 createReview 는 빈 본문 허용(report Grounded Baseline:80). 본 변경으로 별점만 제출하던 기존 유저 플로우가 막힘 — UX 마찰. FINAL SPEC 확정 사항이므로 진행하되 프론트 안내문(C4 카운터 '최소 10자') 필수."
|
||||
- "ESCALATION 없음 — requirements(report FINAL SPEC) vs research(roadmap) 충돌 0. C3 오분류는 task 가 이미 정정 지시 → 반영 완료."
|
||||
references:
|
||||
requirements: /Users/wemadeplay/workspace/stz/bibimbap/.atp/work-session/20260618-145152/report.md
|
||||
research: /Users/wemadeplay/workspace/stz/bibimbap/docs/work-log/2026-06-17-jam-platform-roadmap.md
|
||||
adrs:
|
||||
- /Users/wemadeplay/workspace/stz/bibimbap/docs/changes/2026-06-18-w3-2-comments-reviews.md
|
||||
- /Users/wemadeplay/workspace/stz/bibimbap/docs/game-reviews-ddl.sql
|
||||
- /Users/wemadeplay/workspace/stz/bibimbap/db/schema.sql
|
||||
---
|
||||
|
||||
# 설계: W3-2 댓글/리뷰 고도화 (확정 구현 설계도)
|
||||
|
||||
## 목표 / 비목표
|
||||
|
||||
### 목표 (FINAL SPEC 추적 가능)
|
||||
- **A1** 댓글 응답 commentView 단일 통일 (POST·PUT·list 전부 동일 스키마, POST는 insert 후 재조회).
|
||||
- **A2** 댓글 작성자명 하이브리드 (LEFT JOIN users + CASE 마스킹). QG-2(레거시 user_id NULL) 자동 해결.
|
||||
- **A3** 댓글 edited+updatedAt (game_comments.updated_at 멱등 ALTER + 매퍼/모델 갱신).
|
||||
- **B1** 페이지네이션 offset/limit 20건 "더보기" + sort 토글 (화이트리스트 enum→고정 SQL, `${}` 금지).
|
||||
- **B2** 리뷰 본문 필수 최소 10자(trim 후). 댓글은 현행 유지.
|
||||
- **B3** 본문 정규화 (제어문자 strip + 외곽 trim, 댓글·리뷰 공통 유틸).
|
||||
- **다축 평점** game_review_axes 6축(1~5 전 축 필수) + overall 자동평균/수동덮어쓰기(is_rating_manual).
|
||||
- **C3** game_review_stats 읽기전용 집계뷰 (avg_rating, review_count, 6축 평균). 클라 평균계산 폐기.
|
||||
- **C1** submit 잠금+로딩 / **C2** 상대시각 / **C4** 글자수 카운터 / **C5** 완전소멸 유지 / **C6** radiogroup 완전 패턴.
|
||||
- **육각형 레이더** 인라인 SVG 자체구현 (요약 + 개별 리뷰 카드), a11y 텍스트 대체.
|
||||
|
||||
### 비목표 (스코프 밖 — 명시)
|
||||
- 신고·숨김 (W1 운영자 role 선행).
|
||||
- 리뷰 이력 테이블 (in-row 마커만).
|
||||
- 좋아요 서버화 (별도 관리).
|
||||
- W2-3 잼 평가(심사/투표/시상) 스키마 — **본 설계 무관**(C3 정정으로 명확히 분리).
|
||||
- 댓글 최소 글자수 (현행: 상한 200자만).
|
||||
|
||||
---
|
||||
|
||||
## C3 재분류 (직전 report 오분류 교정 — 설계 결정)
|
||||
|
||||
직전 report.md 는 C3(game_review_stats 평균별점 뷰)를 "W2-3 동결 해제·고위험·§6 게이트"로 표기했으나 **오분류**다.
|
||||
|
||||
- **근거** (`docs/work-log/2026-06-17-jam-platform-roadmap.md`):
|
||||
- `:63` — "W2-3 범위 = 잼 평가만. 댓글/리뷰 스키마 자체는 W3에서 설계(동결 묶음 아님)."
|
||||
- `:201` — "S4D 평가 통합설계 → W2-3 범위 축소: 잼 평가(심사/투표/시상) 스키마만 동결. 댓글/리뷰 스키마는 W3-2에서 별도 설계."
|
||||
- `:202` — "S4a 댓글/리뷰 분리 → W3-2 일반기능으로 재분류: 잼 평가 동결묶음에서 분리."
|
||||
- **결론**: `game_review_stats` = `game_reviews`(W3-2 테이블) 위 **읽기전용 집계뷰** 신설 = **일반 DDL**. §6 파괴적 게이트 없음. orchestrator 사용자 재확인 경로 불필요.
|
||||
- **부수 조치**: `docs/game-reviews-ddl.sql:63` 주석("집계 컬럼/뷰는 신설하지 않음 (W2-3 동결 보호)") 및 `db/schema.sql:136-137`("집계 컬럼/뷰는 W2-3 동결 — 신설 금지") 은 본 설계로 **무효화** → 구현 시 갱신 대상(파일 영향 맵 참조).
|
||||
|
||||
---
|
||||
|
||||
## 개요
|
||||
|
||||
기존 W3-2 코어(댓글/리뷰 CRUD, 2026-06-18 커밋)를 보존하며 그 위에 일관성(A)·규모(B)·다축평점·UX(C)를 얹는다. 백엔드는 매퍼 시그니처 확장(offset/limit/sort, axes 저장) + 신규 axes 매퍼/DDL, 프론트는 game-detail.jsp 단일 파일의 댓글·리뷰 JS 블록 재작성(육각형 SVG, radiogroup, 페이지네이션, 서버집계 표시)이다. DDL은 game-reviews-ddl.sql 에 멱등 append + db/schema.sql 동기화한다. 전 변경은 31건 회귀 테스트를 깨지 않는 것을 1차 게이트로 한다.
|
||||
|
||||
---
|
||||
|
||||
## 플로우
|
||||
|
||||
### 리뷰 작성 (POST /game/{id}/reviews) — 다축 확장
|
||||
```
|
||||
진입: CSRF(403) → 로그인(401) → 게임존재(404)
|
||||
→ rating 파싱(수동 overall, optional) + axes 6값 파싱(전 축 1~5 필수, 누락/범위외 400)
|
||||
→ body 정규화(B3) + 최소 10자 검사(B2, 400)
|
||||
→ 게임당 1회 검사(409)
|
||||
→ overall 결정:
|
||||
유저가 overall 직접선택 O → rating=선택값, is_rating_manual=true
|
||||
유저가 overall 직접선택 X → rating=round(6축 평균), is_rating_manual=false
|
||||
→ [TX] addGameReview(rating, body, is_rating_manual) → review.id 획득
|
||||
→ addReviewAxes(review.id, 6행) ← axes 매퍼
|
||||
→ getGameReview(review.id) 재조회 → reviewView(+axes) 반환
|
||||
종단: 200 reviewView
|
||||
```
|
||||
|
||||
### 리뷰 수정 (PUT) — axes 재저장
|
||||
```
|
||||
진입: CSRF → 로그인 → 리뷰존재+게임일치(404) → 권한(canModify, 403)
|
||||
→ rating/axes/body 검증(작성과 동일)
|
||||
→ [TX] editGameReview(rating, body, is_rating_manual, updated_at=now())
|
||||
→ deleteReviewAxes(reviewId) ← 기존 6행 제거
|
||||
→ addReviewAxes(reviewId, 6행) ← 신규 6행
|
||||
→ getGameReview 재조회 → reviewView 반환
|
||||
```
|
||||
|
||||
### 목록 조회 (GET /game/{id}/reviews?page&sort) — 페이지네이션
|
||||
```
|
||||
진입: 게임존재(404)
|
||||
→ page(default 0)·sort(default newest, 화이트리스트 검증→고정 enum) 파싱
|
||||
→ offset = page*20, limit=21 (hasMore 판정용 +1 조회)
|
||||
→ listGameReviews(gameId, offset, limit, sortEnum) ← 21건 조회
|
||||
→ 각 리뷰에 axes 6행 batch 조회·매핑 (listReviewAxesByReviewIds)
|
||||
→ hasMore = (조회건수 > 20) → 21번째 잘라 20건 반환
|
||||
→ game_review_stats 1행 조회(요약) → summary 포함
|
||||
종단: { status, reviews:[reviewView...], hasMore, summary:{avgRating,reviewCount,axes{}} }
|
||||
```
|
||||
|
||||
### 댓글 작성 (POST /game/{id}/comments) — A1 통일
|
||||
```
|
||||
진입: CSRF → 로그인 → 게임존재
|
||||
→ content 정규화(B3) + 1~200자 검사
|
||||
→ nickname 스냅샷 = sessionDisplayName (유지)
|
||||
→ addGameComment → comment.id 획득
|
||||
→ getGameComment(comment.id) 재조회(LEFT JOIN authorName/edited/updatedAt) ← A1: 재조회 패턴
|
||||
→ commentView 반환
|
||||
종단: 200 commentView (createReview 패턴 대칭)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 데이터 모델
|
||||
|
||||
### 2.1 game_review_axes (신규 테이블)
|
||||
| 컬럼 | 타입 | 제약 | 비고 |
|
||||
|---|---|---|---|
|
||||
| id | bigint | PK, seq | game_review_axes_id_seq |
|
||||
| review_id | bigint | NOT NULL, FK→game_reviews(id) | |
|
||||
| axis_key | varchar(20) | NOT NULL, CHECK(6종) | 영문 snake |
|
||||
| score | smallint | NOT NULL, CHECK(1~5) | |
|
||||
| | | UNIQUE(review_id, axis_key) | 리뷰당 축별 1행 |
|
||||
| | | INDEX(review_id) | 조회 |
|
||||
|
||||
- **axis_key 6종 (순서 고정 — 육각형 축 인덱스 0~5)**:
|
||||
`immersion`(몰입성), `creativity`(창의성), `controls`(조작성), `completeness`(완성도), `sound`(사운드), `visual`(비주얼).
|
||||
- 리뷰당 정확히 6행 (전 축 필수). DB는 UNIQUE+CHECK로 보장, 앱이 6행 누락 없이 insert 책임.
|
||||
|
||||
### 2.2 game_comments.updated_at (멱등 ALTER)
|
||||
- `timestamptz DEFAULT now() NOT NULL`. `edited = updated_at > created_at` (리뷰 대칭).
|
||||
- 기존 행은 ALTER 시 default now() 적용 → created_at != updated_at 가능성 → 기존 행 보정: `UPDATE ... SET updated_at = created_at WHERE updated_at IS NULL` 불필요(NOT NULL default). 대신 ALTER 직후 `UPDATE game_comments SET updated_at = created_at WHERE updated_at > created_at` 1회로 기존 댓글이 "수정됨" 오표시되지 않게 정렬 (멱등 — 재실행 시 영향 없음, 신규 행은 INSERT가 created/updated 동시 now()).
|
||||
|
||||
### 2.3 game_reviews.is_rating_manual (멱등 ALTER)
|
||||
- `boolean DEFAULT false NOT NULL`. true=유저 직접선택 overall, false=6축 자동평균.
|
||||
|
||||
### 2.4 game_review_stats (VIEW 신규)
|
||||
- `game_reviews(is_delete IS NOT TRUE)` ⨝ `game_review_axes` 집계.
|
||||
- 컬럼: `game_id, avg_rating numeric, review_count bigint, avg_immersion numeric, avg_creativity numeric, avg_controls numeric, avg_completeness numeric, avg_sound numeric, avg_visual numeric`.
|
||||
- 클라 평균계산(updateSummary, JSP:1513-1522) 폐기 공급원.
|
||||
|
||||
---
|
||||
|
||||
## 외부 계약 (API)
|
||||
|
||||
### 3.1 commentView 스키마 (A1 통일 — POST·PUT·list 동일)
|
||||
```json
|
||||
{
|
||||
"commentId": 100,
|
||||
"gameId": 1,
|
||||
"authorName": "표시명 또는 (탈퇴한 사용자) 또는 스냅샷닉",
|
||||
"userId": 7, // nullable (레거시)
|
||||
"content": "...",
|
||||
"createdAt": "ISO-8601",
|
||||
"edited": false, // updated_at > created_at
|
||||
"updatedAt": "ISO-8601" // A3 신규
|
||||
}
|
||||
```
|
||||
- 변화: POST 응답이 flat(commentId/gameId/authorName/userId/content) → commentView 전체. PUT 응답이 부분(commentId/content) → commentView 전체. createdAt/edited/updatedAt 신규 노출. `status`,`message`는 POST/PUT 응답에 commentView 와 병합(createReview 패턴 그대로).
|
||||
|
||||
### 3.2 reviewView 스키마 (axes 추가)
|
||||
기존 reviewView(reviewId,gameId,authorName,userId,rating,body,edited,createdAt,updatedAt) + 신규:
|
||||
```json
|
||||
{
|
||||
"...": "기존 필드 유지",
|
||||
"ratingManual": false, // is_rating_manual
|
||||
"axes": { "immersion":4,"creativity":5,"controls":3,"completeness":4,"sound":2,"visual":5 }
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 GET list 응답 형태 (페이지네이션)
|
||||
- 댓글: `{ status, comments:[commentView...], hasMore }`
|
||||
- 리뷰: `{ status, reviews:[reviewView...], hasMore, summary }`
|
||||
- `summary` = game_review_stats 1행 → `{ avgRating, reviewCount, axes:{immersion..visual} }` (review_count=0 이면 summary=null).
|
||||
- **요청 파라미터**: `?page=<int≥0, default 0>&sort=<enum, default 토글기본값>`.
|
||||
- **hasMore 방식 채택**: total count 대신 `limit+1` 조회 후 초과 여부. 근거 = 추가 COUNT 쿼리 회피, "더보기" UI는 total 불요.
|
||||
|
||||
### 3.4 sort enum 값 정의
|
||||
- 댓글: `oldest`(기본), `newest`.
|
||||
- 리뷰: `newest`(기본), `rating_desc`, `rating_asc`.
|
||||
- 미지정/미허용 값 → 기본값으로 fallback (400 던지지 않음 — UX 관대).
|
||||
|
||||
---
|
||||
|
||||
## sort 화이트리스트 매핑 표 (§4 — `${}` 금지 안전성)
|
||||
|
||||
매퍼는 **enum 분기 → 고정 SQL 절** 방식. 동적 `${}` SQL 치환 절대 사용 안 함. 컨트롤러가 String sort 를 화이트리스트 enum 으로 변환(미스매치=기본값) 후, 매퍼는 MyBatis `<choose>`(XML) 또는 **annotation @SelectProvider 의 if-분기로 고정 문자열 상수 선택**.
|
||||
|
||||
**채택 방식**: 현 코드가 annotation 매퍼(@Select 텍스트블록)이므로 일관성 위해 **컨트롤러에서 sort enum 결정 + 매퍼 메서드를 sort별로 분리하지 않고**, `@SelectProvider` 로 전환하여 ORDER BY 절만 상수 분기. (대안: 매퍼 메서드 N개 분리 — 중복 과다로 비채택.)
|
||||
|
||||
| sort enum | 대상 | ORDER BY 고정 SQL 절 (상수, 사용자 입력 미포함) |
|
||||
|---|---|---|
|
||||
| `oldest` (댓글) | comments | `ORDER BY created_at ASC, id ASC` |
|
||||
| `newest` (댓글) | comments | `ORDER BY created_at DESC, id DESC` |
|
||||
| `newest` (리뷰) | reviews | `ORDER BY r.created_at DESC, r.id DESC` |
|
||||
| `rating_desc` (리뷰) | reviews | `ORDER BY r.rating DESC, r.created_at DESC, r.id DESC` |
|
||||
| `rating_asc` (리뷰) | reviews | `ORDER BY r.rating ASC, r.created_at DESC, r.id DESC` |
|
||||
|
||||
- **안전성 근거**: ORDER BY 문자열은 5개 **컴파일타임 상수** 중 하나로만 결정. 사용자 입력 String 은 enum 매칭(`switch`/`Map`)에만 사용되고 SQL 텍스트에 절대 보간되지 않음 → SQL injection 면역. offset/limit 은 `#{}` 파라미터 바인딩 유지.
|
||||
- **tiebreaker**: 별점순은 동점 시 created_at DESC, id DESC 로 결정적 정렬(페이지네이션 안정성 — offset 중복/누락 방지).
|
||||
|
||||
---
|
||||
|
||||
## 다축 시퀀스 (§5)
|
||||
|
||||
### 5.1 overall 자동/수동 계산 위치 = **서버**
|
||||
- 클라(JS)는 6축 점수 + (선택적) overall 수동선택값만 전송.
|
||||
- **서버가 권위 계산**: overall 미전송/빈값 → `rating = Math.round(평균(6축))`, `is_rating_manual=false`. overall 전송 → `rating=전송값(1~5 검증)`, `is_rating_manual=true`.
|
||||
- 근거: 클라 계산은 변조 가능 + C3 서버집계 정합. round 정책 = 정수 반올림(HALF_UP, Java `Math.round` 는 .5 올림 — 일관).
|
||||
|
||||
### 5.2 axes 재저장 전략 = **delete-all + insert-6** (updateReview)
|
||||
- `editGameReview` TX 내: `deleteReviewAxes(reviewId)` → `addReviewAxes(reviewId, List<6>)`.
|
||||
- 근거: upsert(ON CONFLICT) 대비 매퍼 단순. 6행 고정이라 성능 동일 수준. UNIQUE(review_id,axis_key) 와 무관(전삭제 후 삽입).
|
||||
|
||||
### 5.3 트랜잭션 순서 (createReview)
|
||||
```
|
||||
@Transactional
|
||||
1. addGameReview(rating, body, is_rating_manual) → useGeneratedKeys → review.id
|
||||
2. addReviewAxes(review.id, [6 axis rows]) → 6행 batch insert
|
||||
(실패 시 전체 롤백 — review+axes 원자성)
|
||||
3. getGameReview(review.id) + listReviewAxes(review.id) → reviewView 조립
|
||||
```
|
||||
|
||||
### 5.4 axes 매퍼 = **GameReviewAxesMapper 신규** (단일 책임)
|
||||
신규 인터페이스. 시그니처(인자 사용목적 인라인 주석 — inflate 방지):
|
||||
```java
|
||||
@Mapper
|
||||
public interface GameReviewAxesMapper {
|
||||
// 1리뷰 6축 일괄 저장. List 1건당 review_id/axis_key/score 사용.
|
||||
int addReviewAxes(@Param("reviewId") long reviewId, // FK 대상 리뷰
|
||||
@Param("axes") List<ReviewAxisRow> axes); // 6행(axis_key+score)
|
||||
|
||||
// 수정 시 기존 축 전삭제(이후 add 재삽입).
|
||||
int deleteReviewAxes(@Param("reviewId") long reviewId); // 대상 리뷰
|
||||
|
||||
// 목록 화면 N리뷰 축 batch 조회(N+1 회피).
|
||||
List<ReviewAxisRow> listAxesByReviewIds(@Param("reviewIds") List<Long> reviewIds); // 페이지 리뷰 id들
|
||||
}
|
||||
```
|
||||
- `ReviewAxisRow` = `{ Long reviewId; String axisKey; Integer score; }` (신규 POJO 또는 GameReviewData 내 정적 중첩). axes batch insert SQL은 `<foreach>` (XML) 또는 @InsertProvider. **`#{}` 바인딩 유지**.
|
||||
- 최소 인자 원칙 적용: gameId 등 불필요 컨텍스트 미수신. 구현에서 확장 필요 시 추가.
|
||||
|
||||
---
|
||||
|
||||
## SVG 육각형 좌표 공식 (§6)
|
||||
|
||||
### 6.1 계산 위치 = **JS 런타임** (game-detail.jsp 인라인)
|
||||
- 근거: 개별 리뷰 N건 동적 렌더(buildReviewItem) + 요약 1건. 기존 buildStarDisplay 가 JS DOM 생성 idiom → 일관. JSTL 컴파일타임은 동적 N건과 부적합.
|
||||
|
||||
### 6.2 viewBox / 기하 상수
|
||||
- 요약(큰) 육각형: `viewBox="0 0 200 200"`, 중심 `cx=100, cy=100`, 반지름 `R=80`.
|
||||
- 개별 리뷰 카드(컴팩트): `viewBox="0 0 120 120"`, `cx=60, cy=60`, `R=44`. (페이지당 20건 DOM 고려.)
|
||||
- 함수는 cx/cy/R 파라미터화하여 공용 1함수로.
|
||||
|
||||
### 6.3 6 꼭지점(축 끝) 좌표 공식
|
||||
- 축 i(0~5, §2.1 axis_key 순서와 1:1): 각도 `θ_i = -90° + 60°*i` (12시 방향 시작, 시계방향).
|
||||
```
|
||||
angle_rad = (-90 + 60*i) * Math.PI / 180
|
||||
axisX_i = cx + R * Math.cos(angle_rad)
|
||||
axisY_i = cy + R * Math.sin(angle_rad)
|
||||
```
|
||||
- 배경 그리드(외곽 육각형) = 위 6점 polygon. 단계 그리드 = R*0.25, R*0.5, R*0.75, R 4단계 동심 육각형(`scale = level/4` 곱).
|
||||
|
||||
### 6.4 score 폴리곤 점 공식
|
||||
- 축 i 점수 `s_i`(1~5) → 반지름 비율 `ratio_i = s_i / 5`:
|
||||
```
|
||||
ptX_i = cx + R * (s_i/5) * Math.cos(angle_rad_i)
|
||||
ptY_i = cy + R * (s_i/5) * Math.sin(angle_rad_i)
|
||||
```
|
||||
- `<polygon points="ptX_0,ptY_0 ptX_1,ptY_1 ... ptX_5,ptY_5" />` (fill 반투명 + stroke).
|
||||
|
||||
### 6.5 렌더 함수 시그니처 (inflate 방지 — 인자 사용목적 명시)
|
||||
```js
|
||||
// 6축 점수 배열을 육각형 SVG 엘리먼트로. 요약/카드 공용.
|
||||
function buildHexRadar(scores /* [6] axis순 점수배열, score폴리곤 */,
|
||||
cx /* 중심x, 좌표기준 */,
|
||||
cy /* 중심y, 좌표기준 */,
|
||||
R /* 반지름, 스케일 */) { ... return <svg> }
|
||||
```
|
||||
- 최소 인자. 라벨 텍스트/색상은 함수 내부 상수(AXIS_LABELS_KO) 참조 → 인자 미부풀림.
|
||||
|
||||
### 6.6 a11y (SVG 시각요소 텍스트 대체 — 필수)
|
||||
- `<svg role="img" aria-label="6축 평가: 몰입성 4, 창의성 5, 조작성 3, 완성도 4, 사운드 2, 비주얼 5">`.
|
||||
- 추가로 시각적 보조: 각 축 점수를 visually-hidden 표 또는 인접 `<dl>`(축명/점수) 동반. 폴리곤만으로 종료 금지(FINAL SPEC).
|
||||
|
||||
---
|
||||
|
||||
## a11y radiogroup 스펙 (§7 — C6)
|
||||
|
||||
현 별점위젯(JSP:1043-1049)은 `role=radiogroup`/`role=radio`/`aria-checked` 마크업은 있으나 **키보드 핸들러 없음**(click만, JSP:1553-1556). roving tabindex 도 없음. C6 = 완전 패턴 신규 추가.
|
||||
|
||||
### 7.1 roving tabindex
|
||||
- radiogroup 내 단일 tabstop: 선택된 radio `tabindex="0"`, 나머지 `tabindex="-1"`. 미선택 시 첫 radio `tabindex="0"`.
|
||||
- 화살표 이동 시 tabindex 이전(`-1`)→대상(`0`) + `.focus()`.
|
||||
|
||||
### 7.2 키 핸들러 (keydown)
|
||||
| 키 | 동작 |
|
||||
|---|---|
|
||||
| `ArrowRight`, `ArrowUp` | 다음 별점(+1, max 5에서 정지 또는 wrap — **정지** 채택, LTR 별점 직관) |
|
||||
| `ArrowLeft`, `ArrowDown` | 이전 별점(-1, min 1에서 정지) |
|
||||
| `Home` | 1점 |
|
||||
| `End` | 5점 |
|
||||
| `Space`/`Enter` | 현재 focus radio 선택 확정 |
|
||||
- 화살표는 이동+즉시선택(setRating) 동시 — radiogroup 표준. `preventDefault()` 로 스크롤 방지.
|
||||
|
||||
### 7.3 aria 속성
|
||||
- 그룹 `role="radiogroup" aria-labelledby="<라벨id>"` (축별 라벨 id 6개).
|
||||
- 각 `role="radio" aria-checked="true|false"`, 선택만 `aria-checked=true`.
|
||||
|
||||
### 7.4 6위젯 공통화
|
||||
- 별점위젯 생성을 JS 함수 `buildStarRadioGroup(axisKey, labelId)` 로 추출 → 6축 입력 위젯 생성에 재사용. 각 위젯 독립 selectedScore 상태(객체 `axisScores[axisKey]`). 기존 단일 overall 위젯도 동일 함수로 통일(overall은 별도 또는 자동표시).
|
||||
- 함수 시그니처(인자 사용목적):
|
||||
```js
|
||||
// 1개 축 별점 radiogroup DOM 생성 + 키/클릭 핸들러 바인딩.
|
||||
function buildStarRadioGroup(axisKey /* axisScores 키 + 상태귀속 */,
|
||||
labelText /* 라벨/aria-label 텍스트 */) { ... }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## B3 정규화 유틸 위치 (§8)
|
||||
|
||||
- **현황**: 공용 `util` 패키지 없음(grep 확인). trimToNull/trimToEmpty 가 GameCommentController·GameReviewController·GameController 에 private 중복.
|
||||
- **채택**: 신규 `com.pandoli365.bibimbap.util.TextNormalizer` (static util 클래스). 기존 private trim 메서드는 **이번 스코프에선 미통합**(회귀 리스크 — 댓글/리뷰 컨트롤러만 호출 추가). 통합 리팩터는 비목표.
|
||||
- **시그니처** (인자 사용목적 인라인):
|
||||
```java
|
||||
public final class TextNormalizer {
|
||||
private TextNormalizer() {}
|
||||
// 저장 위생: 제어문자(탭\t·개행\n\r 제외) 제거 + 외곽 trim.
|
||||
// 내부 연속공백/줄바꿈 보존. null→null.
|
||||
public static String normalize(String raw /* 원문, 정규화 대상 */) { ... }
|
||||
}
|
||||
```
|
||||
- 규칙: `\t`(U+0009), `\n`(U+000A), `\r`(U+000D) 외의 C0/C1 제어문자(U+0000~U+001F, U+007F~U+009F) 제거 → 외곽 `strip()`. 내부 공백 미축약.
|
||||
- 적용: createComment/updateComment content, createReview/updateReview body 에 검증 **전** 호출(정규화 후 길이 검사).
|
||||
|
||||
---
|
||||
|
||||
## 파일 영향 맵 (§1 파일 소유권 + worker 분할)
|
||||
|
||||
worker 분할은 **동시수정 충돌 회피** 기준. game-detail.jsp 는 단일 파일이라 1 worker 전담.
|
||||
|
||||
| 변경 유형 | 경로 | 역할 | worker |
|
||||
|---|---|---|---|
|
||||
| 신규 | `db/.../docs/game-reviews-ddl.sql` (append) | axes 테이블+updated_at ALTER+is_rating_manual ALTER+stats VIEW 멱등 블록. :63 보수주석 갱신 | W-DDL |
|
||||
| 변경 | `db/schema.sql` | 위 DDL 동기화(:136-137 주석 갱신) | W-DDL |
|
||||
| 신규 | `src/.../util/TextNormalizer.java` | B3 정규화 static util | W-BE |
|
||||
| 신규 | `src/.../mapper/GameReviewAxesMapper.java` | axes add/delete/listByReviewIds | W-BE |
|
||||
| 신규 | `src/.../data/ReviewAxisRow.java` (또는 GameReviewData 중첩) | axes 행 POJO | W-BE |
|
||||
| 변경 | `src/.../data/GameCommentData.java` | updatedAt + edited(비영속) 필드 추가 | W-BE |
|
||||
| 변경 | `src/.../data/GameReviewData.java` | ratingManual + axes(Map/List 비영속) 필드 추가 | W-BE |
|
||||
| 변경 | `src/.../mapper/GameCommentsMapper.java` | A2 LEFT JOIN+CASE, A3 updated_at/edited select, B1 offset/limit/sort, editGameComment updated_at | W-BE |
|
||||
| 변경 | `src/.../mapper/GameReviewsMapper.java` | B1 offset/limit/sort, is_rating_manual select/insert/update, edit 시 axes 무관(별 매퍼) | W-BE |
|
||||
| 신규 | `src/.../mapper/GameReviewStatsMapper.java` (또는 GameReviewsMapper 내 1메서드) | game_review_stats 1행 조회 | W-BE |
|
||||
| 변경 | `src/.../controller/api/GameCommentController.java` | A1 재조회·commentView, B1 page/sort, B3 normalize | W-BE |
|
||||
| 변경 | `src/.../controller/api/GameReviewController.java` | 다축 검증/저장, overall 자동·수동, B2 10자, B3, B1 page/sort, summary | W-BE |
|
||||
| 변경 | `src/main/webapp/WEB-INF/views/game-detail.jsp` | 육각형 SVG, C1·C2·C4·C6, 페이지네이션·sort UI, 서버집계 표시, 6축 입력, A1 commentView 렌더 | W-FE |
|
||||
| 변경 | `src/test/.../GameCommentControllerTest.java` | A1·A2·B3 신규 + 기존 12 유지 | W-TEST |
|
||||
| 변경 | `src/test/.../GameReviewControllerTest.java` | 다축·B2·sort 신규 + 기존 13 유지 | W-TEST |
|
||||
| (무변경 확인) | `src/test/.../BibimbapApplicationTests.java` | @MockBean 신규 매퍼(GameReviewAxesMapper 등) 추가 필요 시만 | W-TEST |
|
||||
|
||||
**충돌 회피**: W-BE 가 매퍼/컨트롤러/data/util 동시 소유(상호 의존 — 단일 worker 권장). W-FE 는 jsp 단독. W-TEST 는 BE 완료 후 진행(시그니처 의존). W-DDL 독립 선행 가능.
|
||||
|
||||
**BibimbapApplicationTests 주의**: 신규 `@Mapper` 빈(GameReviewAxesMapper, GameReviewStatsMapper)이 컨트롤러 생성자 주입되면 contextLoads 가 빈을 못 찾아 실패 → `@MockBean` 추가 필수. 이 추가는 31건 회귀의 ApplicationTests 1건이 깨지지 않도록 하는 **필수 조치**.
|
||||
|
||||
---
|
||||
|
||||
## DDL 전문 (§2 — game-reviews-ddl.sql append 블록)
|
||||
|
||||
아래를 `docs/game-reviews-ddl.sql` 끝에 append. 전부 IF NOT EXISTS / DO $$ 멱등. `db/schema.sql` 에도 동일 정의 동기화.
|
||||
|
||||
```sql
|
||||
-- ===========================================================================
|
||||
-- W3-2 고도화: 다축 평점(game_review_axes) + 댓글 updated_at + is_rating_manual
|
||||
-- + game_review_stats 집계뷰
|
||||
-- C3 재분류: game_review_stats 는 W3-2 일반 읽기전용 집계뷰. W2-3 잼 평가 동결과 무관
|
||||
-- (roadmap.md:63,201,202). 아래 위 'idx_game_reviews_game' 주석의 "집계뷰 미신설"
|
||||
-- 보수 표기는 본 블록으로 갱신됨.
|
||||
-- ===========================================================================
|
||||
|
||||
-- 1) game_comments.updated_at (A3)
|
||||
ALTER TABLE "game_comments"
|
||||
ADD COLUMN IF NOT EXISTS "updated_at" timestamp with time zone DEFAULT now() NOT NULL;
|
||||
-- 기존 댓글이 '수정됨' 오표시되지 않도록 정렬(멱등: 이미 정렬된 행엔 무영향)
|
||||
UPDATE "game_comments" SET "updated_at" = "created_at" WHERE "updated_at" > "created_at";
|
||||
COMMENT ON COLUMN "game_comments"."updated_at" IS '덧글 마지막 수정 시각. updated_at > created_at 이면 수정됨(리뷰 대칭)';
|
||||
|
||||
-- 2) game_reviews.is_rating_manual (overall 출처 구분)
|
||||
ALTER TABLE "game_reviews"
|
||||
ADD COLUMN IF NOT EXISTS "is_rating_manual" boolean DEFAULT false NOT NULL;
|
||||
COMMENT ON COLUMN "game_reviews"."is_rating_manual" IS 'true=유저 직접선택 overall, false=6축 자동평균';
|
||||
|
||||
-- 3) game_review_axes (다축 평점, 리뷰당 6행)
|
||||
CREATE SEQUENCE IF NOT EXISTS "game_review_axes_id_seq";
|
||||
CREATE TABLE IF NOT EXISTS "game_review_axes" (
|
||||
"id" bigint DEFAULT nextval('game_review_axes_id_seq'::regclass) NOT NULL,
|
||||
"review_id" bigint NOT NULL,
|
||||
"axis_key" character varying(20) NOT NULL,
|
||||
"score" smallint NOT NULL,
|
||||
PRIMARY KEY ("id")
|
||||
);
|
||||
ALTER SEQUENCE "game_review_axes_id_seq" OWNED BY "game_review_axes"."id";
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'game_review_axes_review_id_fkey') THEN
|
||||
ALTER TABLE "game_review_axes"
|
||||
ADD CONSTRAINT "game_review_axes_review_id_fkey"
|
||||
FOREIGN KEY ("review_id") REFERENCES "game_reviews" ("id");
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'game_review_axes_score_check') THEN
|
||||
ALTER TABLE "game_review_axes"
|
||||
ADD CONSTRAINT "game_review_axes_score_check" CHECK ("score" BETWEEN 1 AND 5);
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'game_review_axes_axis_key_check') THEN
|
||||
ALTER TABLE "game_review_axes"
|
||||
ADD CONSTRAINT "game_review_axes_axis_key_check"
|
||||
CHECK ("axis_key" IN ('immersion','creativity','controls','completeness','sound','visual'));
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "ux_game_review_axes_review_axis"
|
||||
ON "game_review_axes" ("review_id", "axis_key");
|
||||
CREATE INDEX IF NOT EXISTS "idx_game_review_axes_review"
|
||||
ON "game_review_axes" ("review_id");
|
||||
|
||||
COMMENT ON TABLE "game_review_axes" IS '리뷰 다축 평점(6축, 리뷰당 6행). axis_key 6종 각 1~5';
|
||||
COMMENT ON COLUMN "game_review_axes"."axis_key" IS '몰입성 immersion/창의성 creativity/조작성 controls/완성도 completeness/사운드 sound/비주얼 visual';
|
||||
|
||||
-- 4) game_review_stats (읽기전용 집계뷰 — 클라 평균계산 폐기 공급원)
|
||||
CREATE OR REPLACE VIEW "game_review_stats" AS
|
||||
SELECT
|
||||
r."game_id" AS "game_id",
|
||||
ROUND(AVG(r."rating")::numeric, 1) AS "avg_rating",
|
||||
COUNT(*) AS "review_count",
|
||||
ROUND(AVG(a."score") FILTER (WHERE a."axis_key"='immersion'),1) AS "avg_immersion",
|
||||
ROUND(AVG(a."score") FILTER (WHERE a."axis_key"='creativity'),1) AS "avg_creativity",
|
||||
ROUND(AVG(a."score") FILTER (WHERE a."axis_key"='controls'),1) AS "avg_controls",
|
||||
ROUND(AVG(a."score") FILTER (WHERE a."axis_key"='completeness'),1) AS "avg_completeness",
|
||||
ROUND(AVG(a."score") FILTER (WHERE a."axis_key"='sound'),1) AS "avg_sound",
|
||||
ROUND(AVG(a."score") FILTER (WHERE a."axis_key"='visual'),1) AS "avg_visual"
|
||||
FROM "game_reviews" r
|
||||
LEFT JOIN "game_review_axes" a ON a."review_id" = r."id"
|
||||
WHERE r."is_delete" IS NOT TRUE
|
||||
GROUP BY r."game_id";
|
||||
COMMENT ON VIEW "game_review_stats" IS 'W3-2 일반 집계뷰(W2-3 동결 무관). 게임별 평균별점·리뷰수·6축평균';
|
||||
```
|
||||
|
||||
### db/schema.sql 동기화 판단 = **동기화 필수**
|
||||
- 근거: schema.sql 은 dev 컨테이너 부트스트랩(line 16-18, docker-entrypoint-initdb.d 자동실행). axes 테이블/뷰/컬럼 없으면 dev 환경 매퍼 실행 실패. game_reviews 가 schema.sql:117-135 에 이미 정의되어 있으므로 동일 위치에 위 4블록 append + `:136-137` 동결 주석을 C3 갱신 주석으로 교체.
|
||||
|
||||
---
|
||||
|
||||
## 대안 비교 (§ 선택적)
|
||||
|
||||
| 안 | 장점 | 단점 | 채택? |
|
||||
|---|---|---|---|
|
||||
| axes 매퍼 신규 vs GameReviewsMapper 확장 | 단일책임/리뷰매퍼 비대화 방지 | 클래스 1개 추가 | **신규 채택** |
|
||||
| hasMore(limit+1) vs total count | COUNT 쿼리 회피 | total 미표시 | **hasMore 채택** |
|
||||
| sort: @SelectProvider 분기 vs 메서드 N분리 | ORDER BY만 상수분기, 메서드 1개 | provider 클래스 추가 | **provider 채택** |
|
||||
| overall 계산 서버 vs 클라 | 변조방지·C3정합 | round 1회 서버부담(무시가능) | **서버 채택** |
|
||||
| axes 재저장 delete+insert vs upsert | 매퍼 단순 | 6 DEL+6 INS | **delete+insert 채택** |
|
||||
| SVG 좌표 JS vs JSTL | 동적 N건 일관 | 클라 계산 | **JS 채택** |
|
||||
| is_rating_manual 채택 vs 미채택 | 자동/수동 출처 구분 | 1컬럼 | **채택**(concerns 재확인) |
|
||||
|
||||
---
|
||||
|
||||
## 롤아웃 / 마이그레이션
|
||||
|
||||
1. **순서**: DDL 멱등 적용(dev: schema.sql 재부트 또는 game-reviews-ddl.sql 수동 실행) → BE 빌드/단위테스트 → FE → L3 스모크.
|
||||
2. **역호환**:
|
||||
- 기존 game_reviews 행은 axes 0행 상태 → game_review_stats 의 6축 평균 NULL(LEFT JOIN). 프론트는 NULL 축을 "데이터 없음"/0 처리. overall avg_rating 은 정상(rating 컬럼 기반).
|
||||
- 기존 댓글: updated_at default now() + 정렬 UPDATE 로 edited=false 유지.
|
||||
- is_rating_manual default false → 기존 리뷰는 자동평균 취급(축 없어도 rating 표시 영향 없음).
|
||||
3. **롤백 경로**: 신규 객체(axes 테이블/stats 뷰/2 컬럼)는 비파괴(ADD/CREATE). 코드 롤백 시 DB 객체 잔존해도 무해(미참조). 뷰는 `DROP VIEW IF EXISTS game_review_stats`, 컬럼은 보존(비파괴) 권장.
|
||||
4. **기존 리뷰 axes 백필**: 본 스코프 비대상(NULL 허용). 백필 필요 시 별도.
|
||||
|
||||
---
|
||||
|
||||
## 검증 포인트 (verification-advisor 점검 acceptance criteria)
|
||||
|
||||
### L1 단위 테스트 (회귀 + 신규)
|
||||
- **AC-1**: 기존 31건 회귀 PASS — `./mvnw test` 결과 GameCommentControllerTest(12) + GameReviewControllerTest(13) + UserControllerCsrfTest(5) + BibimbapApplicationTests(1) 전부 GREEN. (DbUpdateQueryGeneratorTest 1건은 W3-2 무관, 영향 없음 확인.)
|
||||
- **AC-2**: BibimbapApplicationTests 의 @MockBean 집합이 컨트롤러 생성자 의존 매퍼 전수를 커버 — 신규 매퍼(GameReviewAxesMapper, GameReviewStatsMapper 등) 추가 시 contextLoads PASS.
|
||||
- **AC-3**: 신규 단위테스트 추가건 PASS (목록 §9).
|
||||
|
||||
### L1 안전성 (sort 화이트리스트 — 집합 전수)
|
||||
- **AC-4**: sort enum 매핑 전수 5건 보존 — 매퍼/provider 의 ORDER BY 분기가 §4 표의 5개 enum(`oldest`,`newest`(댓글),`newest`,`rating_desc`,`rating_asc`(리뷰))을 전수 커버. 검증: `grep -c 'ORDER BY' <provider 또는 매퍼 소스>` >= 5 AND 각 분기 SQL에 사용자 입력 변수 보간(`${`) 0건 — `grep -c '\${' <매퍼소스>` == 0 (전 매퍼 통틀어 W3-2 변경분).
|
||||
- **AC-5**: SQL injection 면역 — 전 신규/변경 매퍼에서 `${` 동적치환 0건 (`grep -rc '\${' src/main/java/.../mapper/Game*Mapper.java` 합 == 0). offset/limit/sort 전부 `#{}` 또는 enum 상수.
|
||||
|
||||
### L1 다축 (집합 전수 — 6축)
|
||||
- **AC-6**: axis_key 집합 전수 6건 일치 — DDL CHECK·뷰 FILTER·앱 enum·JSP 라벨 4곳이 동일 6키(`immersion,creativity,controls,completeness,sound,visual`). 검증: `grep -c "'immersion'\|'creativity'\|'controls'\|'completeness'\|'sound'\|'visual'"` 패턴이 game-reviews-ddl.sql 의 axis_key CHECK 절에 6개 전수, stats VIEW FILTER 에 6개 전수.
|
||||
- **AC-7**: createReview 가 6축 미만 입력 시 400 (전 축 필수). 단위테스트로 5축 입력 거부.
|
||||
- **AC-8**: overall 자동평균 — 6축 [4,5,3,4,2,5] 입력·overall 미전송 시 rating=round(23/6=3.83)=4, is_rating_manual=false. overall=2 전송 시 rating=2, is_rating_manual=true.
|
||||
|
||||
### L1 기타 신규
|
||||
- **AC-9**: B2 — 리뷰 본문 trim 후 9자 거부(400), 10자 통과. 댓글은 최소제한 없음(기존 유지).
|
||||
- **AC-10**: B3 — TextNormalizer.normalize("a | ||||