The keycloak project ended with four open questions that design could not
settle. A two-VM lab was built to answer them by measurement, and this is
that material: 26 experiments, 125 raw command outputs, 22 browser captures.
Follows the import procedure in README.md.
source/ the originating repository verbatim — 78 documents, 28 SVGs,
8 manifests, plus .source-revision recording the commit
final/ the SSOT
document.md 729 lines written from the 29 experiment documents, not
concatenated: what was predicted, what was measured, and
where the measurement itself was wrong
evidence/raw 125 outputs, flattened to <experiment>__<file> because
the originals collided (01-baseline.txt appeared three
times) and the audit only globs the top level
evidence/meta one per raw file; command and exitCode are null and the
README says why rather than inventing them
evidence/browser 22 captures
assets/ three diagrams through techviz
.techviz/ their VizSpecs
A separate project rather than an addition to keycloak: the B-layer answers
that project's four questions, but the A, C and D layers are about cluster
failure, SSO and operations, and one document.md should hold one subject.
The four question records there can point here through 관계.
Recorded rather than papered over: only three of the 28 diagrams were
remade. The repository forbids hand-drawn SVG and forbids titles inside the
canvas; all 28 originals carry both, so converting them is redrawing, not
reformatting. They stay in source/ and the gap is written into the document.
verify-pipeline.py passes. audit-records.py reports no issues.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
321 lines
66 KiB
XML
321 lines
66 KiB
XML
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="6662" viewBox="0 0 1200 6662" role="img">
|
|
<title>terminal evidence</title>
|
|
<desc>Terminal-style rendering generated from retained command output. Sensitive-looking values are redacted in the visual asset.</desc>
|
|
<rect x="1" y="1" width="1198" height="6660" rx="14" fill="#0d1117" stroke="#30363d"/>
|
|
<rect x="1" y="1" width="1198" height="44" rx="14" fill="#161b22"/>
|
|
<rect x="1" y="30" width="1198" height="14" fill="#161b22"/>
|
|
<circle cx="24" cy="22" r="6" fill="#ff5f57"/>
|
|
<circle cx="44" cy="22" r="6" fill="#febc2e"/>
|
|
<circle cx="64" cy="22" r="6" fill="#28c840"/>
|
|
<text x="92" y="27" fill="#8b949e" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace">terminal evidence</text>
|
|
<text x="24" y="68" fill="#c9d1d9" font-size="15" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">$ #!/bin/bash
|
|
set -euo pipefail
|
|
cd /shared/codebase/clean-architecture-backend-template
|
|
|
|
hits() {
|
|
local out rc
|
|
out=$</tspan><tspan x="24" dy="22">(git grep -nE "$1" -- "$2") && rc=0 || rc=$?
|
|
[ "$rc" -le 1 ] || { echo "SEARCH FAILED rc=$rc : $1" >&2; exit 2; }
|
|
[ </tspan><tspan x="24" dy="22">"$rc" -eq 0 ] && printf '%s\n' "$out" || true
|
|
}
|
|
mod() { sed -E 's#^src/(.*)/src/([a-zA-Z]+)/java/.*/([A-Za-z]+\.java):([</tspan><tspan x="24" dy="22">0-9]+): *# \1 · \2 · \3:\4 #'; }
|
|
|
|
P=src/application-core/src/main/java/dev/caskeleton/application/notification/platf</tspan><tspan x="24" dy="22">orm/admin/AdminOperationStorePort.java
|
|
A=src/application-core/src/main/java/dev/caskeleton/application/notification/plat</tspan><tspan x="24" dy="22">form/admin/AdminOperationClaim.java
|
|
J=src/adapter/outbound/persistence-jpa/src/main/java/dev/caskeleton/adapter/outbound</tspan><tspan x="24" dy="22">/persistence/notification/platform/JpaAdminOperationStore.java
|
|
R=src/adapter/outbound/persistence-jpa/src/main/java/dev/</tspan><tspan x="24" dy="22">caskeleton/adapter/outbound/persistence/notification/platform/AdminAuditJpaRepository.java
|
|
S=src/application-core/src/ma</tspan><tspan x="24" dy="22">in/java/dev/caskeleton/application/notification/platform/admin/NotificationAdminApplicationService.java
|
|
V=$(git ls-files</tspan><tspan x="24" dy="22"> -- '**/V8__notification_admin_claim.sql')
|
|
T=$(git ls-files -- '**/AdminOperationClaimContractTest.java')
|
|
for f in "$P" </tspan><tspan x="24" dy="22">"$A" "$J" "$R" "$S" "$V" "$T"; do test -f "$f"; done
|
|
|
|
echo "# 포트가 선언한 세 연산 ($(wc -l < "$P") 줄 전문)"
|
|
awk '{pri</tspan><tspan x="24" dy="22">ntf " AdminOperationStorePort.java:%d %s\n", NR, $0}' "$P"
|
|
|
|
echo
|
|
echo "# claim 이 돌려주는 네 답"
|
|
awk 'NR>=5 && NR<=35 </tspan><tspan x="24" dy="22">{printf " AdminOperationClaim.java:%d %s\n", NR, $0}' "$A"
|
|
|
|
echo
|
|
echo "# 그 연산이 생긴 이유 — 마이그레이션 헤더"
|
|
awk </tspan><tspan x="24" dy="22">'NR>=1 && NR<=11 {printf " V8__notification_admin_claim.sql:%d %s\n", NR, $0}' "$V"
|
|
|
|
echo
|
|
echo "# JPA 구현이 무엇을 보</tspan><tspan x="24" dy="22">내고 무엇으로 판단하는가"
|
|
awk 'NR>=30 && NR<=71 {printf " JpaAdminOperationStore.java:%d %s\n", NR, $0}' "$J"
|
|
echo
|
|
awk </tspan><tspan x="24" dy="22">'NR>=28 && NR<=45 {printf " AdminAuditJpaRepository.java:%d %s\n", NR, $0}' "$R"
|
|
|
|
echo
|
|
echo "# 서비스가 operations 포트</tspan><tspan x="24" dy="22">에 거는 호출 전부"
|
|
grep -n 'operations\.[a-zA-Z]*(' "$S" | sed -E 's#^([0-9]+): *# NotificationAdminApplicationService.</tspan><tspan x="24" dy="22">java:\1 #'
|
|
echo " operations.claim : $({ grep -c 'operations\.claim' "$S" || true; }) 줄"
|
|
echo " [자기시험] operation</tspan><tspan x="24" dy="22">s.claimZZZ : $({ grep -c 'operations\.claimZZZ' "$S" || true; }) 줄 (0 이어야 정상)"
|
|
echo " [대조] operations.save : $(</tspan><tspan x="24" dy="22">{ grep -c 'operations\.save' "$S" || true; }) 줄 (0 이면 검색이 깨진 것)"
|
|
echo " commandFingerprint 를 계산하는 자리 :"</tspan><tspan x="24" dy="22">
|
|
hits 'commandFingerprint|command_fingerprint' 'src/**/*.java' | mod
|
|
|
|
echo
|
|
echo "# 네 경로가 조회와 저장 사이에 부르는 </tspan><tspan x="24" dy="22">협력자"
|
|
FIELDS=$(grep -oP '^\s+private final \S+\s+\K\w+(?=;)' "$S" | paste -sd'|')
|
|
[ -n "$FIELDS" ] || { echo "no field</tspan><tspan x="24" dy="22">s parsed" >&2; exit 2; }
|
|
echo " (서비스가 선언한 협력자 필드에서 유도한 패턴 : $FIELDS)"
|
|
for m in redrive reconcile sup</tspan><tspan x="24" dy="22">press setProviderState; do
|
|
s=$(grep -n "public [A-Za-z]* $m(" "$S" | cut -d: -f1) || true
|
|
[ -n "$s" ] || { echo "met</tspan><tspan x="24" dy="22">hod $m not found" >&2; exit 2; }
|
|
e=$(awk -v s="$s" 'NR>s && /^ }$/ {print NR; exit}' "$S")
|
|
[ -n "$e" ] || { echo "n</tspan><tspan x="24" dy="22">o closing brace for $m" >&2; exit 2; }
|
|
printf ' %-16s (:%s~:%s)\n' "$m" "$s" "$e"
|
|
awk -v s="$s" -v e="$e" -v f="($F</tspan><tspan x="24" dy="22">IELDS)\\." '
|
|
NR>=s && NR<=e && $0 !~ /^\s*(\/\/|\*|\/\*)/ &&
|
|
($0 ~ f || $0 ~ /^\s*(if \(|\} else)/) {
|
|
gs</tspan><tspan x="24" dy="22">ub(/^ +/,""); printf " :%d %s\n", NR, $0 }' "$S"
|
|
done
|
|
|
|
echo
|
|
echo "# 그 경합을 고정한 시험이 어느 레인에서 도는가"
|
|
ech</tspan><tspan x="24" dy="22">o " 파일 : $T"
|
|
{ grep -n '@Tag' "$T" || true; } | sed -E 's#^([0-9]+): *# AdminOperationClaimContractTest.java:\1 #</tspan><tspan x="24" dy="22">'
|
|
{ grep -n "jpaPlatformContractTest'\|'jpa-contract'" src/adapter/outbound/persistence-jpa/build.gradle || true; } \
|
|
</tspan><tspan x="24" dy="22">| sed -E 's#^([0-9]+): *# persistence-jpa/build.gradle:\1 #'
|
|
echo " 그 태스크를 부르는 워크플로 :"
|
|
{ grep -rn 'jpaP</tspan><tspan x="24" dy="22">latformContractTest' .github/workflows/*.yml || true; } \
|
|
| sed -E 's#^\.github/workflows/([a-z-]+\.yml):([0-9]+): *# </tspan><tspan x="24" dy="22"> \1:\2 #'
|
|
echo " 그 워크플로가 도는 조건 :"
|
|
awk 'NR>=14 && NR<=16 || NR>=21 && NR<=24 {printf " notification-plat</tspan><tspan x="24" dy="22">form.yml:%d %s\n", NR, $0}' \
|
|
.github/workflows/notification-platform.yml
|
|
echo " NotificationAdminApplicationService </tspan><tspan x="24" dy="22">를 이름에 가진 시험 파일 : $(
|
|
{ git ls-files -- 'src/**/*Test*.java' | grep -c 'NotificationAdminApplicationService' |</tspan><tspan x="24" dy="22">| true; }) 개"
|
|
</tspan></text>
|
|
<text x="24" y="860" fill="#8b949e" font-size="13" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">cwd: /shared/codebase/clean-architecture-backend-template</tspan></text>
|
|
<text x="24" y="882" fill="#8b949e" font-size="13" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">time: 2026-09-04T05:03:05+00:00 · exit 0</tspan></text>
|
|
<line x1="24" y1="896" x2="1176" y2="896" stroke="#30363d"/>
|
|
<text x="24" y="936" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 포트가 선언한 세 연산 (33 줄 전문)</tspan></text>
|
|
<text x="24" y="958" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:1 package dev.caskeleton.application.notification.platform.admin;</tspan></text>
|
|
<text x="24" y="980" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:2 </tspan></text>
|
|
<text x="24" y="1002" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:3 import java.util.Optional;</tspan></text>
|
|
<text x="24" y="1024" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:4 </tspan></text>
|
|
<text x="24" y="1046" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:5 /** Idempotent record of operator actions, so a retried request cannot redrive twice. */</tspan></text>
|
|
<text x="24" y="1068" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:6 public interface AdminOperationStorePort {</tspan></text>
|
|
<text x="24" y="1090" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:7 </tspan></text>
|
|
<text x="24" y="1112" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:8 /** Claim an operation id, or return the previous result for it. */</tspan></text>
|
|
<text x="24" y="1134" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:9 Optional<AdminOperationResult> findByOperationId(String operationId);</tspan></text>
|
|
<text x="24" y="1156" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:10 </tspan></text>
|
|
<text x="24" y="1178" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:11 /** Store the result of an operation. */</tspan></text>
|
|
<text x="24" y="1200" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:12 AdminOperationResult save(AdminOperationResult result, AdminActor actor, String action);</tspan></text>
|
|
<text x="24" y="1222" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:13 </tspan></text>
|
|
<text x="24" y="1244" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:14 /**</tspan></text>
|
|
<text x="24" y="1266" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:15 * Claims an operation id before anything happens, atomically.</tspan></text>
|
|
<text x="24" y="1288" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:16 *</tspan></text>
|
|
<text x="24" y="1310" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:17 * <p>The admin path was find, then side effect, then save. Two callers presenting the same</tspan></text>
|
|
<text x="24" y="1332" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:18 * operation id both read "not found", both ran the redrive, and both saved — the idempoten</tspan><tspan x="24" dy="22">cy key</tspan></text>
|
|
<text x="24" y="1376" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:19 * was checked but never held, so it prevented a repeat and not a race. A destructive operat</tspan><tspan x="24" dy="22">ion</tspan></text>
|
|
<text x="24" y="1420" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:20 * run twice concurrently is the exact failure the id exists to stop.</tspan></text>
|
|
<text x="24" y="1442" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:21 *</tspan></text>
|
|
<text x="24" y="1464" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:22 * <p>The fingerprint is part of the claim: the same id with a different command is not a re</tspan><tspan x="24" dy="22">play,</tspan></text>
|
|
<text x="24" y="1508" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:23 * it is a conflict, and answering it with the earlier result would silently execute neither</tspan><tspan x="24" dy="22">.</tspan></text>
|
|
<text x="24" y="1552" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:24 *</tspan></text>
|
|
<text x="24" y="1574" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:25 * @param operationId the caller's idempotency key</tspan></text>
|
|
<text x="24" y="1596" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:26 * @param commandFingerprint a digest of the command this id was presented with</tspan></text>
|
|
<text x="24" y="1618" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:27 * @param actor who is asking</tspan></text>
|
|
<text x="24" y="1640" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:28 * @param action what they are asking for</tspan></text>
|
|
<text x="24" y="1662" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:29 * @return whether this caller may proceed, and what the earlier one did if not</tspan></text>
|
|
<text x="24" y="1684" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:30 */</tspan></text>
|
|
<text x="24" y="1706" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:31 AdminOperationClaim claim(</tspan></text>
|
|
<text x="24" y="1728" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:32 String operationId, String commandFingerprint, AdminActor actor, String action);</tspan></text>
|
|
<text x="24" y="1750" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationStorePort.java:33 }</tspan></text>
|
|
<text x="24" y="1772" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
|
|
<text x="24" y="1794" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># claim 이 돌려주는 네 답</tspan></text>
|
|
<text x="24" y="1816" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationClaim.java:5 </tspan></text>
|
|
<text x="24" y="1838" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationClaim.java:6 /**</tspan></text>
|
|
<text x="24" y="1860" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationClaim.java:7 * What an admin operation id claim decided.</tspan></text>
|
|
<text x="24" y="1882" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationClaim.java:8 *</tspan></text>
|
|
<text x="24" y="1904" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationClaim.java:9 * <p>Four outcomes, because collapsing them loses the distinction that matters. A replay must</tspan></text>
|
|
<text x="24" y="1926" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationClaim.java:10 * return the earlier result without acting; an in-progress claim must not act and must not preten</tspan><tspan x="24" dy="22">d</tspan></text>
|
|
<text x="24" y="1970" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationClaim.java:11 * the work is done; and the same id with a different command is a mistake worth reporting rather</tspan></text>
|
|
<text x="24" y="1992" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationClaim.java:12 * than an idempotent repeat.</tspan></text>
|
|
<text x="24" y="2014" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationClaim.java:13 *</tspan></text>
|
|
<text x="24" y="2036" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationClaim.java:14 * @param outcome what the caller may do</tspan></text>
|
|
<text x="24" y="2058" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationClaim.java:15 * @param existing the earlier result, when there is one</tspan></text>
|
|
<text x="24" y="2080" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationClaim.java:16 */</tspan></text>
|
|
<text x="24" y="2102" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationClaim.java:17 public record AdminOperationClaim(Outcome outcome, Optional<AdminOperationResult> existing) {</tspan></text>
|
|
<text x="24" y="2124" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationClaim.java:18 </tspan></text>
|
|
<text x="24" y="2146" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationClaim.java:19 /** The four answers a claim can give. */</tspan></text>
|
|
<text x="24" y="2168" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationClaim.java:20 public enum Outcome {</tspan></text>
|
|
<text x="24" y="2190" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationClaim.java:21 </tspan></text>
|
|
<text x="24" y="2212" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationClaim.java:22 /** This caller holds the operation and may proceed. */</tspan></text>
|
|
<text x="24" y="2234" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationClaim.java:23 CLAIMED,</tspan></text>
|
|
<text x="24" y="2256" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationClaim.java:24 </tspan></text>
|
|
<text x="24" y="2278" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationClaim.java:25 /** The operation already completed; {@code existing} is what it produced. */</tspan></text>
|
|
<text x="24" y="2300" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationClaim.java:26 REPLAY,</tspan></text>
|
|
<text x="24" y="2322" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationClaim.java:27 </tspan></text>
|
|
<text x="24" y="2344" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationClaim.java:28 /** Another caller holds it right now. Nothing has been decided yet. */</tspan></text>
|
|
<text x="24" y="2366" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationClaim.java:29 IN_PROGRESS,</tspan></text>
|
|
<text x="24" y="2388" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationClaim.java:30 </tspan></text>
|
|
<text x="24" y="2410" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationClaim.java:31 /** The same id was presented with a different command. */</tspan></text>
|
|
<text x="24" y="2432" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationClaim.java:32 CONFLICT</tspan></text>
|
|
<text x="24" y="2454" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationClaim.java:33 }</tspan></text>
|
|
<text x="24" y="2476" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationClaim.java:34 </tspan></text>
|
|
<text x="24" y="2498" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationClaim.java:35 /** Validates the claim. */</tspan></text>
|
|
<text x="24" y="2520" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
|
|
<text x="24" y="2542" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 그 연산이 생긴 이유 — 마이그레이션 헤더</tspan></text>
|
|
<text x="24" y="2564" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> V8__notification_admin_claim.sql:1 -- NTF-020 — the admin path was find, then side effect, then save.</tspan></text>
|
|
<text x="24" y="2586" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> V8__notification_admin_claim.sql:2 --</tspan></text>
|
|
<text x="24" y="2608" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> V8__notification_admin_claim.sql:3 -- Two callers presenting the same operation id both read "not found", both ran the redrive</tspan><tspan x="24" dy="22">, and</tspan></text>
|
|
<text x="24" y="2652" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> V8__notification_admin_claim.sql:4 -- both saved. The unique constraint on operation_id was already there and made the *second</tspan><tspan x="24" dy="22"> save*</tspan></text>
|
|
<text x="24" y="2696" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> V8__notification_admin_claim.sql:5 -- fail — after the second side effect had already happened. An idempotency key that is ch</tspan><tspan x="24" dy="22">ecked but</tspan></text>
|
|
<text x="24" y="2740" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> V8__notification_admin_claim.sql:6 -- never held prevents a repeat and does nothing about a race, which is the case that matte</tspan><tspan x="24" dy="22">rs for a</tspan></text>
|
|
<text x="24" y="2784" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> V8__notification_admin_claim.sql:7 -- destructive operation.</tspan></text>
|
|
<text x="24" y="2806" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> V8__notification_admin_claim.sql:8 --</tspan></text>
|
|
<text x="24" y="2828" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> V8__notification_admin_claim.sql:9 -- The claim is now the insert itself: ON CONFLICT DO NOTHING means exactly one caller crea</tspan><tspan x="24" dy="22">tes the</tspan></text>
|
|
<text x="24" y="2872" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> V8__notification_admin_claim.sql:10 -- row, and everyone else reads what that caller is doing.</tspan></text>
|
|
<text x="24" y="2894" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> V8__notification_admin_claim.sql:11 </tspan></text>
|
|
<text x="24" y="2916" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
|
|
<text x="24" y="2938" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># JPA 구현이 무엇을 보내고 무엇으로 판단하는가</tspan></text>
|
|
<text x="24" y="2960" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:30 </tspan></text>
|
|
<text x="24" y="2982" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:31 @Override</tspan></text>
|
|
<text x="24" y="3004" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:32 public dev.caskeleton.application.notification.platform.admin.AdminOperationClaim claim(</tspan></text>
|
|
<text x="24" y="3026" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:33 String operationId, String commandFingerprint, AdminActor actor, String action) {</tspan></text>
|
|
<text x="24" y="3048" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:34 Objects.requireNonNull(operationId, "operationId");</tspan></text>
|
|
<text x="24" y="3070" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:35 Objects.requireNonNull(commandFingerprint, "commandFingerprint");</tspan></text>
|
|
<text x="24" y="3092" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:36 Objects.requireNonNull(actor, "actor");</tspan></text>
|
|
<text x="24" y="3114" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:37 Objects.requireNonNull(action, "action");</tspan></text>
|
|
<text x="24" y="3136" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:38 </tspan></text>
|
|
<text x="24" y="3158" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:39 int claimed =</tspan></text>
|
|
<text x="24" y="3180" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:40 audits.claimOperation(</tspan></text>
|
|
<text x="24" y="3202" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:41 ids.nextId(),</tspan></text>
|
|
<text x="24" y="3224" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:42 operationId,</tspan></text>
|
|
<text x="24" y="3246" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:43 action,</tspan></text>
|
|
<text x="24" y="3268" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:44 actor.actorRef(),</tspan></text>
|
|
<text x="24" y="3290" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:45 commandFingerprint,</tspan></text>
|
|
<text x="24" y="3312" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:46 clock.instant());</tspan></text>
|
|
<text x="24" y="3334" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:47 if (claimed == 1) {</tspan></text>
|
|
<text x="24" y="3356" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:48 return dev.caskeleton.application.notification.platform.admin.AdminOperationClaim.claimed</tspan><tspan x="24" dy="22">();</tspan></text>
|
|
<text x="24" y="3400" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:49 }</tspan></text>
|
|
<text x="24" y="3422" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:50 // Somebody else has the row. What they are doing decides this caller's answer.</tspan></text>
|
|
<text x="24" y="3444" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:51 List<Object[]> existing = audits.phaseOf(operationId);</tspan></text>
|
|
<text x="24" y="3466" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:52 if (existing.isEmpty()) {</tspan></text>
|
|
<text x="24" y="3488" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:53 // The row vanished between the insert and the read, which only a concurrent delete expla</tspan><tspan x="24" dy="22">ins.</tspan></text>
|
|
<text x="24" y="3532" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:54 // Refusing is safer than assuming the operation is free.</tspan></text>
|
|
<text x="24" y="3554" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:55 return dev.caskeleton.application.notification.platform.admin.AdminOperationClaim</tspan></text>
|
|
<text x="24" y="3576" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:56 .inProgress();</tspan></text>
|
|
<text x="24" y="3598" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:57 }</tspan></text>
|
|
<text x="24" y="3620" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:58 String phase = String.valueOf(existing.get(0)[0]);</tspan></text>
|
|
<text x="24" y="3642" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:59 String fingerprint = existing.get(0)[1] == null ? null : String.valueOf(existing.get(0)[1])</tspan><tspan x="24" dy="22">;</tspan></text>
|
|
<text x="24" y="3686" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:60 if (fingerprint != null && !fingerprint.equals(commandFingerprint)) {</tspan></text>
|
|
<text x="24" y="3708" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:61 // The same id, a different command. Returning the earlier result would execute neither.</tspan></text>
|
|
<text x="24" y="3730" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:62 return dev.caskeleton.application.notification.platform.admin.AdminOperationClaim.conflic</tspan><tspan x="24" dy="22">t();</tspan></text>
|
|
<text x="24" y="3774" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:63 }</tspan></text>
|
|
<text x="24" y="3796" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:64 if ("CLAIMED".equals(phase)) {</tspan></text>
|
|
<text x="24" y="3818" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:65 return dev.caskeleton.application.notification.platform.admin.AdminOperationClaim</tspan></text>
|
|
<text x="24" y="3840" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:66 .inProgress();</tspan></text>
|
|
<text x="24" y="3862" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:67 }</tspan></text>
|
|
<text x="24" y="3884" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:68 return findByOperationId(operationId)</tspan></text>
|
|
<text x="24" y="3906" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:69 .map(dev.caskeleton.application.notification.platform.admin.AdminOperationClaim::replay</tspan><tspan x="24" dy="22">)</tspan></text>
|
|
<text x="24" y="3950" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:70 .orElseGet(</tspan></text>
|
|
<text x="24" y="3972" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaAdminOperationStore.java:71 dev.caskeleton.application.notification.platform.admin.AdminOperationClaim::inProgr</tspan><tspan x="24" dy="22">ess);</tspan></text>
|
|
<text x="24" y="4016" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
|
|
<text x="24" y="4038" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminAuditJpaRepository.java:28 *</tspan></text>
|
|
<text x="24" y="4060" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminAuditJpaRepository.java:29 * @return 1 when this caller claimed it, 0 when somebody else already had</tspan></text>
|
|
<text x="24" y="4082" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminAuditJpaRepository.java:30 */</tspan></text>
|
|
<text x="24" y="4104" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminAuditJpaRepository.java:31 @org.springframework.data.jpa.repository.Modifying</tspan></text>
|
|
<text x="24" y="4126" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminAuditJpaRepository.java:32 @org.springframework.data.jpa.repository.Query(</tspan></text>
|
|
<text x="24" y="4148" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminAuditJpaRepository.java:33 value =</tspan></text>
|
|
<text x="24" y="4170" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminAuditJpaRepository.java:34 "INSERT INTO notification_admin_audit ("</tspan></text>
|
|
<text x="24" y="4192" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminAuditJpaRepository.java:35 + " id, operation_id, action, actor_ref, attributes, dry_run, occurred_at,"</tspan></text>
|
|
<text x="24" y="4214" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminAuditJpaRepository.java:36 + " command_fingerprint, phase, claimed_at)"</tspan></text>
|
|
<text x="24" y="4236" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminAuditJpaRepository.java:37 + " VALUES (:id, :operationId, :action, :actorRef, '{}'::jsonb, false, :now,"</tspan></text>
|
|
<text x="24" y="4258" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminAuditJpaRepository.java:38 + " :fingerprint, 'CLAIMED', :now)"</tspan></text>
|
|
<text x="24" y="4280" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminAuditJpaRepository.java:39 + " ON CONFLICT (operation_id) DO NOTHING",</tspan></text>
|
|
<text x="24" y="4302" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminAuditJpaRepository.java:40 nativeQuery = true)</tspan></text>
|
|
<text x="24" y="4324" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminAuditJpaRepository.java:41 int claimOperation(</tspan></text>
|
|
<text x="24" y="4346" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminAuditJpaRepository.java:42 @org.springframework.data.repository.query.Param("id") java.util.UUID id,</tspan></text>
|
|
<text x="24" y="4368" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminAuditJpaRepository.java:43 @org.springframework.data.repository.query.Param("operationId") String operationId,</tspan></text>
|
|
<text x="24" y="4390" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminAuditJpaRepository.java:44 @org.springframework.data.repository.query.Param("action") String action,</tspan></text>
|
|
<text x="24" y="4412" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminAuditJpaRepository.java:45 @org.springframework.data.repository.query.Param("actorRef") String actorRef,</tspan></text>
|
|
<text x="24" y="4434" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
|
|
<text x="24" y="4456" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 서비스가 operations 포트에 거는 호출 전부</tspan></text>
|
|
<text x="24" y="4478" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> NotificationAdminApplicationService.java:94 Optional<AdminOperationResult> replayed = operations.findByOperationId(command.op</tspan><tspan x="24" dy="22">erationId());</tspan></text>
|
|
<text x="24" y="4522" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> NotificationAdminApplicationService.java:145 return operations.save(result, actor, "ADMIN_REDRIVE");</tspan></text>
|
|
<text x="24" y="4544" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> NotificationAdminApplicationService.java:154 Optional<AdminOperationResult> replayed = operations.findByOperationId(command.o</tspan><tspan x="24" dy="22">perationId());</tspan></text>
|
|
<text x="24" y="4588" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> NotificationAdminApplicationService.java:194 return operations.save(result, actor, "ADMIN_RECONCILE");</tspan></text>
|
|
<text x="24" y="4610" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> NotificationAdminApplicationService.java:203 Optional<AdminOperationResult> replayed = operations.findByOperationId(command.o</tspan><tspan x="24" dy="22">perationId());</tspan></text>
|
|
<text x="24" y="4654" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> NotificationAdminApplicationService.java:272 return operations.save(</tspan></text>
|
|
<text x="24" y="4676" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> NotificationAdminApplicationService.java:282 Optional<AdminOperationResult> replayed = operations.findByOperationId(command.o</tspan><tspan x="24" dy="22">perationId());</tspan></text>
|
|
<text x="24" y="4720" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> NotificationAdminApplicationService.java:328 return operations.save(result, actor, "ADMIN_PROVIDER_STATE");</tspan></text>
|
|
<text x="24" y="4742" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> operations.claim : 0 줄</tspan></text>
|
|
<text x="24" y="4764" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> [자기시험] operations.claimZZZ : 0 줄 (0 이어야 정상)</tspan></text>
|
|
<text x="24" y="4786" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> [대조] operations.save : 4 줄 (0 이면 검색이 깨진 것)</tspan></text>
|
|
<text x="24" y="4808" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> commandFingerprint 를 계산하는 자리 :</tspan></text>
|
|
<text x="24" y="4830" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> adapter/outbound/persistence-jpa · main · AdminAuditJpaRepository.java:36 + " command_fingerprint, phase, claimed_at)"</tspan></text>
|
|
<text x="24" y="4852" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> adapter/outbound/persistence-jpa · main · AdminAuditJpaRepository.java:52 "SELECT phase, command_fingerprint FROM notificat</tspan><tspan x="24" dy="22">ion_admin_audit"</tspan></text>
|
|
<text x="24" y="4896" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> adapter/outbound/persistence-jpa · main · JpaAdminOperationStore.java:33 String operationId, String commandFingerprint, Adm</tspan><tspan x="24" dy="22">inActor actor, String action) {</tspan></text>
|
|
<text x="24" y="4940" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> adapter/outbound/persistence-jpa · main · JpaAdminOperationStore.java:35 Objects.requireNonNull(commandFingerprint, "comman</tspan><tspan x="24" dy="22">dFingerprint");</tspan></text>
|
|
<text x="24" y="4984" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> adapter/outbound/persistence-jpa · main · JpaAdminOperationStore.java:45 commandFingerprint,</tspan></text>
|
|
<text x="24" y="5006" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> adapter/outbound/persistence-jpa · main · JpaAdminOperationStore.java:60 if (fingerprint != null && !fingerprint.equals(com</tspan><tspan x="24" dy="22">mandFingerprint)) {</tspan></text>
|
|
<text x="24" y="5050" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> adapter/outbound/persistence-jpa · postgresqlIntegrationTest · AdminOperationClaimContractTest.java:123 + " command_fingerp</tspan><tspan x="24" dy="22">rint, phase, claimed_at)"</tspan></text>
|
|
<text x="24" y="5094" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> adapter/outbound/persistence-jpa · postgresqlIntegrationTest · AdminOperationClaimContractTest.java:141 return column(opera</tspan><tspan x="24" dy="22">tionId, "command_fingerprint");</tspan></text>
|
|
<text x="24" y="5138" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> application-core · main · AdminOperationStorePort.java:26 * @param commandFingerprint a digest of the command this id was p</tspan><tspan x="24" dy="22">resented with</tspan></text>
|
|
<text x="24" y="5182" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> application-core · main · AdminOperationStorePort.java:32 String operationId, String commandFingerprint, AdminActor actor, </tspan><tspan x="24" dy="22">String action);</tspan></text>
|
|
<text x="24" y="5226" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
|
|
<text x="24" y="5248" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 네 경로가 조회와 저장 사이에 부르는 협력자</tspan></text>
|
|
<text x="24" y="5270" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> (서비스가 선언한 협력자 필드에서 유도한 패턴 : authorization|duplicateRiskGuard|attempts|recipients|reconciliation|suppression</tspan><tspan x="24" dy="22">s|runtimes|operations|audit|transactions|clock)</tspan></text>
|
|
<text x="24" y="5314" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> redrive (:90~:147)</tspan></text>
|
|
<text x="24" y="5336" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :92 authorization.require(actor, NotificationAdminAuthority.REDRIVE);</tspan></text>
|
|
<text x="24" y="5358" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :94 Optional<AdminOperationResult> replayed = operations.findByOperationId(command.operationId());</tspan></text>
|
|
<text x="24" y="5380" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :103 authorization.requireTenant(actor, original.tenantId());</tspan></text>
|
|
<text x="24" y="5402" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :104 duplicateRiskGuard.verify(original, command.approveDuplicateRisk());</tspan></text>
|
|
<text x="24" y="5424" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :117 return transactions.inWrite(</tspan></text>
|
|
<text x="24" y="5446" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :121 recipients.transition(</tspan></text>
|
|
<text x="24" y="5468" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :124 Optional.of(clock.instant()));</tspan></text>
|
|
<text x="24" y="5490" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :135 audit.record(</tspan></text>
|
|
<text x="24" y="5512" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :141 clock.instant(),</tspan></text>
|
|
<text x="24" y="5534" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :145 return operations.save(result, actor, "ADMIN_REDRIVE");</tspan></text>
|
|
<text x="24" y="5556" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> reconcile (:150~:195)</tspan></text>
|
|
<text x="24" y="5578" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :152 authorization.require(actor, NotificationAdminAuthority.RECONCILE);</tspan></text>
|
|
<text x="24" y="5600" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :154 Optional<AdminOperationResult> replayed = operations.findByOperationId(command.operationId());</tspan></text>
|
|
<text x="24" y="5622" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :172 reconciliation.reconcile(attemptId);</tspan></text>
|
|
<text x="24" y="5644" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :186 audit.record(</tspan></text>
|
|
<text x="24" y="5666" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :192 clock.instant(),</tspan></text>
|
|
<text x="24" y="5688" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :194 return operations.save(result, actor, "ADMIN_RECONCILE");</tspan></text>
|
|
<text x="24" y="5710" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> suppress (:198~:275)</tspan></text>
|
|
<text x="24" y="5732" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :200 authorization.require(actor, NotificationAdminAuthority.SUPPRESS);</tspan></text>
|
|
<text x="24" y="5754" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :201 authorization.requireTenant(actor, command.tenantId());</tspan></text>
|
|
<text x="24" y="5776" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :203 Optional<AdminOperationResult> replayed = operations.findByOperationId(command.operationId());</tspan></text>
|
|
<text x="24" y="5798" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :218 return transactions.inWrite(</tspan></text>
|
|
<text x="24" y="5820" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :227 command.tenantId(), command.targetFingerprint(), clock.instant())</tspan></text>
|
|
<text x="24" y="5842" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :229 .map(entry -> suppressions.remove(command.tenantId(), entry.id()))</tspan></text>
|
|
<text x="24" y="5864" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :236 suppressions.upsert(</tspan></text>
|
|
<text x="24" y="5886" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :249 clock.instant(),</tspan></text>
|
|
<text x="24" y="5908" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :264 audit.record(</tspan></text>
|
|
<text x="24" y="5930" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :270 clock.instant(),</tspan></text>
|
|
<text x="24" y="5952" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :272 return operations.save(</tspan></text>
|
|
<text x="24" y="5974" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> setProviderState (:278~:329)</tspan></text>
|
|
<text x="24" y="5996" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :280 authorization.require(actor, NotificationAdminAuthority.PROVIDER_CONTROL);</tspan></text>
|
|
<text x="24" y="6018" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :282 Optional<AdminOperationResult> replayed = operations.findByOperationId(command.operationId());</tspan></text>
|
|
<text x="24" y="6040" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :298 runtimes.setState(command.profileId(), command.desiredState(), command.reason());</tspan></text>
|
|
<text x="24" y="6062" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :318 audit.record(</tspan></text>
|
|
<text x="24" y="6084" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :324 clock.instant(),</tspan></text>
|
|
<text x="24" y="6106" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> :328 return operations.save(result, actor, "ADMIN_PROVIDER_STATE");</tspan></text>
|
|
<text x="24" y="6128" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
|
|
<text x="24" y="6150" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 그 경합을 고정한 시험이 어느 레인에서 도는가</tspan></text>
|
|
<text x="24" y="6172" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 파일 : src/adapter/outbound/persistence-jpa/src/postgresqlIntegrationTest/java/dev/caskeleton/adapter/outbound/persistence/not</tspan><tspan x="24" dy="22">ification/AdminOperationClaimContractTest.java</tspan></text>
|
|
<text x="24" y="6216" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AdminOperationClaimContractTest.java:34 @Tag("jpa-contract")</tspan></text>
|
|
<text x="24" y="6238" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> persistence-jpa/build.gradle:251 'jpaPlatformContractTest',</tspan></text>
|
|
<text x="24" y="6260" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> persistence-jpa/build.gradle:252 'jpa-contract',</tspan></text>
|
|
<text x="24" y="6282" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 그 태스크를 부르는 워크플로 :</tspan></text>
|
|
<text x="24" y="6304" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> jpa-nightly.yml:49 :adapter:outbound:persistence-jpa:jpaPlatformContractTest</tspan></text>
|
|
<text x="24" y="6326" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> jpa-pr.yml:86 :adapter:outbound:persistence-jpa:jpaPlatformContractTest</tspan></text>
|
|
<text x="24" y="6348" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> notification-platform.yml:85 run: ./gradlew :adapter:outbound:persistence-jpa:jpaPlatformContractTest --console=plain</tspan></text>
|
|
<text x="24" y="6370" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> notification-platform.yml:139 run: ./gradlew :adapter:outbound:persistence-jpa:jpaPlatformContractTest :adapter:outbound:pe</tspan><tspan x="24" dy="22">rsistence-jpa:jpaPlatformFailureTest --console=plain</tspan></text>
|
|
<text x="24" y="6414" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 그 워크플로가 도는 조건 :</tspan></text>
|
|
<text x="24" y="6436" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> notification-platform.yml:14 on:</tspan></text>
|
|
<text x="24" y="6458" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> notification-platform.yml:15 pull_request:</tspan></text>
|
|
<text x="24" y="6480" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> notification-platform.yml:16 paths:</tspan></text>
|
|
<text x="24" y="6502" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> notification-platform.yml:21 - 'src/application-core/src/**/notification/**'</tspan></text>
|
|
<text x="24" y="6524" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> notification-platform.yml:22 - 'src/adapter/outbound/notification/**'</tspan></text>
|
|
<text x="24" y="6546" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> notification-platform.yml:23 - 'src/adapter/outbound/persistence-jpa/src/**/notification/**'</tspan></text>
|
|
<text x="24" y="6568" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> notification-platform.yml:24 - 'src/adapter/outbound/persistence-jpa/src/main/resources/db/migration/jpa/notification-</tspan><tspan x="24" dy="22">platform/**'</tspan></text>
|
|
<text x="24" y="6612" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> NotificationAdminApplicationService 를 이름에 가진 시험 파일 : 0 개</tspan></text>
|
|
</svg>
|