← 목록
기타 2026-06-23 23KB 읽기 22분

chess.crowny.org — 맘을 선물하는 체스 (크라우니 회원 서비스)

개요

chess.com을 스크리닝해 만든 크라우니 회원용 체스 서비스. 결정적 차별점은 맘 선물 경제: 이기고 지면 맘을 주고받는 베팅이 아니라, 사람이 "느껴서" 자발적으로 맘을 선물한다.
  • 이겨서 기분 좋으면 → 감사의 맘
  • 상대가 져서 속상할까 → 위로의 맘
  • 상대 수에서 배웠으면 → 배움의 맘
맘은 결과로 자동 이전되지 않는다(대국 종료 시 잔액 변동 0). 순위도 승수가 아니라 베푼 맘 / 받은 맘 기준.

  • 도메인: chess.crowny.org → :9945 (crowny-ports.sh 등록, 게이트웨이 8080/8443 자동결선 확인)
  • 위치: /Users/ef/crowny-chess/
  • 영속: LaunchAgent org.crowny.chess (KeepAlive, RunAtLoad)

무엇을 했는지

  1. 맘선물판정.한선 (한선씨 SSOT, 신규 핵심 로직 먼저 작성) — 전송 4상 판정(티/옴/타/음). 컴파일·검증 7/7. 학습 등록(맘선물판정_4상전송).
  2. public/js/chess.js — 순수 체스 엔진(외부 라이브러리 0). perft(1)=20·(2)=400·(3)=8902 정확값 일치(앙파상·캐슬링·승급 포함), 풀스메이트 탐지. 알파베타 AI(깊이 2~3).
  3. server.js (Node, :9945) — SSO(X-Crowny-Owner), 로그인/자동가입(환영 맘 100), 회원 비동기 대국(서버 권위 수 검증=안티치트, moves[] 재생), 맘 선물(앵커 해시체인 기록), 받은함/순위/나. 한선씨 판정 미러링.
  4. 프론트엔드 — index.html / style.css(티옴타 디자인표준: choco·cream·gold) / board.js(유니코드 기물·합법수 하이라이트·승급·체크) / app.js(SPA: 로그인·컴퓨터 로컬대국·회원 폴링대국·맘 선물 모달).
  5. 체스규칙.한선 — chess.js 핵심 판정의 한선씨 동반(칸 4상·나이트·착지판정). 컴파일·검증 7/7. 학습 등록(체스_칸판정_4상착지).

검증

  • 엔진: perft 1/2/3 정확값 일치, 메이트 탐지 OK.
  • 서버 E2E(curl): e2e4→차례전환, 상대차례 거부, 불법수("불법 수") 차단, 맘선물 phase=T 잔액이전, 자기선물/잔액초과 phase=A 거부, 순위 sent 집계 OK.
  • 헤드리스 크롬: 로그인(100맘)→탭→컴퓨터 대국→보드 렌더 정상, 모달 [hidden] 버그 수정.
  • 게이트웨이: 8443 SNI·8080 Host 둘 다 /api/health 라우팅 OK.

관련 파일

  • 서버: /Users/ef/crowny-chess/server.js
  • 한선씨: /Users/ef/crowny-chess/맘선물판정.한선, 체스규칙.한선 (+ .toau)
  • 프론트: /Users/ef/crowny-chess/public/{index.html,css/style.css,js/{chess,board,app}.js}
  • LaunchAgent: ~/Library/LaunchAgents/org.crowny.chess.plist
  • 스크리닝: /Users/ef/crowny-chess/chess.com-스크리닝.md

2차 추가 (2026-06-23) — 실시간 + 지갑

  • 실시간 대국: SSE /api/game/:id/stream(즉시 수 전파) + /api/stream(사용자 알림: 도전장·내차례·선물·매칭) + 빠른 대국 로비(open/list/accept) + 10분 클럭(서버 권위 시간패). 클라 EventSource, 끊기면 폴링 폴백.
  • 지갑 연동: 맘=CRM, bank :9400. POST /api/wallet/link(genesis_code+admin_key→token 저장) · GET /api/wallet(by-uid 실 CRM 잔액) · POST /api/wallet/unlink. 양쪽 연동 회원 선물 = 실 CRM 송금(/api/transfer asset=crm), 미연동/실패 = 플레이 맘 폴백(유실 0). onchain "실맘(CRM)" 표시.
  • 한선씨 동반: 지갑선물판정.한선(라우팅 4상 T실CRM/O폴백/A불가 + 클럭 시간패, 검증 8/8, 학습), 체스규칙.한선.
  • 검증: curl(로비 open·list·accept·클럭, SSE 2이벤트 실시간, 지갑 그레이스풀 502), 헤드리스 크롬(로비·지갑카드 렌더).

3차 추가 (2026-06-25) — 복기 + 클럭 + 리매치

  • Game Review: chess.js reviewGame(깊이3, 30수 ~490ms) → 수별 5등급(최선/좋음/부정확/실수/블런더, 손실 centipawn 기준) + 정확도(100·exp(-acpl/300)) + 배움 자동추천(내 실수 직후 상대의 정확한 대응 or 상대 베스트 → "N수에서 배웠어요" 배움 맘 바로 선물). 복기 화면=정확도 카드·스텝 보드·기보·배움 카드. ※자료형 평가라 참고용(임계 넉넉).
  • 클럭 다양화: 로비에서 1분 / 블리츠 3분 / 래피드 10분 / 장고 30분 선택. seek.tc → game.clock.
  • 무승부/리매치: /api/game/:id/draw(offer/accept/decline) + /rematch(offer/accept, 색 교환·같은 시간). SSE 푸시 + 제안 배너 + 종료 액션 버튼. 컴퓨터 대국=다시 두기(색 교환).
  • 한선씨 동반: 복기판정.한선(5등급 분류 + 배움추천 + 정확도, 검증 8/8, 학습). 한선씨 동반 총 4개(맘선물판정·지갑선물판정·체스규칙·복기판정).
  • 검증: node(reviewGame·perft 회귀 8902), curl(클럭180·무승부 합의·리매치 색교환), 헤드리스 크롬(로비 시간칩·복기 화면 79%/78%).

잔여 이슈

  • SAN 기보/PGN 내보내기, 토너먼트, 퍼즐.
  • 복기 평가 품질 향상(자료형→포지셔널/엔진 강화).
  • 시간 증분(increment), 관전 모드.
  • ecosystem.crowny.org 등재.

4차 — 공개 도메인 결선 (2026-06-25)

  • A레코드: chess.crowny.org + game.crowny.org → 112.144.147.144 (공인IP, 라우터→맥 192.168.219.153:443 포워딩).
  • chess.crowny.org TLS: 전용 certbot 인증서 발급(--cert-name chess-crowny -d chess.crowny.org -d game.crowny.org, webroot=/Users/ef/crowny-gateway/webroot, 만료 2026-09-23). stunnel-live-443.conf에 SNI 블록 수동 추가(chess 신규 [s443-chess-crowny-org], game 기존 s29 블록 cert를 chess-crowny로 교체). stunnel 재기동(kill+워치독/수동) → verify=0. 전체 212도메인 cert 재발급 회피(전용 cert만, 블래스트 반경 최소).
  • game.crowny.org: 기존 :9775 crowny-game("게임으로 성장하다") 서비스 운영 중. 덮어쓰지 않고 크라우니 체스 피처드 카드 + 푸터 링크 추가(안내/연결). public/index.html.
  • 검증: 실 포워딩 경로(192.168.219.153:443)에서 chess/game verify=0 code=200, crowny.org/docs 무손상.
  • 함정: ① 공인IP(112.144.147.144) 직접 TLS 테스트는 NAT 헤어핀으로 실패/오인 → 실 검증은 LAN IP(192.168.219.153)로. ② stunnel SIGHUP은 신규 [섹션] 미반영(전체 재시작 필요), cert 파일 갱신만 SIGHUP 반영. ③ 수동 SNI 블록은 SNI생성기.한선 재생성 시 유실 위험(irum 선례와 동일 패턴) — 지속화하려면 생성기에 chess-crowny lineage 학습 필요.

4차 정정 (2026-06-25) — 실제 공개 엣지는 8443

  • 함정 정정: 라우터가 공인 443 → 맥 :8443 (stunnel-live.conf)로 포워딩. :443 (stunnel-live-443.conf)는 공개 경로 아님. 처음 :443만 고쳐서 "둘 다 안 열림" 발생.
  • 진단 키: :8443 SNI=chess는 hansunc(폴백)인데 :443은 정상 → 공개 hairpin이 :8443과 일치 = 공개 엣지=8443. (crowny.org는 8443 config에 있어 정상이라 chess만 깨져 보임)
  • 수정: stunnel-live.conf(부모 [https], sni 접두 https: ≠ 443conf의 https443:)에 chess 블록 추가 + game s29블록 cert를 chess-crowny로 교체 → 8443 stunnel 클린 재기동(kill+수동기동). 결과 공개경로 verify=0/200.
  • 양쪽 conf(443·8443) 모두 chess 블록 보유(중복 무해). 8443 감독=gwlive헬스워치독(conf 정본 기반).

5차 — 몰입 고도화 + 한선씨 리코딩 (2026-06-27)

  • 사운드: public/js/sound.js Web Audio 합성(에셋 0) — move/capture/castle/check/promote/win/lose/draw/gift/notify. 토글 🔊(localStorage), 첫 제스처 unlock.
  • 이동 애니메이션: board.js FLIP — 도착칸 기물을 출발칸에서 미끄러져 오게(transform transition .19s). 모든 수(사람/AI/서버)에 animate.
  • 실시간 수 분석 + 모달 알림: 매 내 수마다 Chess.analyzeMove(최선/최악/내 수 centipawn) → 상단 모달 알림(notify-card) + 보드 아래 분석패널(최선/내수/최악 막대+수치). 알림은 모달 카드로 통일(선물·도전·종료·체크).
  • 코칭(핵심): Chess.recommendMove(state, 내평균손실, 2) — 내 수준(ACPL, 최근30수 평균손실 localStorage)보다 한 단계 낮은 수를 보드에 청록 하이라이트 + "이 추천 수보다 더 좋은 수를 찾아보세요". 항상 더 좋은 수가 존재 → 능가 유도. 토글 🎯.
  • 한선씨 리코딩: 신규 판정 로직 추천수판정.한선(추천목표=ACPL×1.3 최소25, 손실배열에서 목표 근접·블런더(>400) 제외·최선 제외 선택. 배열 인덱싱 배열[i] 동작 확인. 검증 5/5, 학습). 사운드/애니메이션은 Web Audio/DOM 런타임이라 JS 유지(판정만 한선씨 — 5connect 패턴). 한선씨 동반 총 5개(맘선물판정·지갑선물판정·체스규칙·복기판정·추천수판정).
  • 검증: node(analyzeMove·recommendMove·perft 8902 회귀), 헤드리스 크롬(코칭바+보드 청록 추천수 b1→a3+사운드 아이콘 렌더). 정적 디스크서빙이라 서버 무재기동.

6차 — 모바일 PWA 승격 + 두뇌단련 로드맵 (2026-06-27)

"할수록 머리가 좋아지는" 개발 방향 7가지(각 인지능력 대응):
  1. 매일 3판 루틴 + 스트릭(습관·일관성) ✅구현
  2. 두뇌 점수 & 성장 그래프(메타인지) ✅구현
  3. 전술 퍼즐 트레이너(패턴 인식) — 내 실수에서 생성·반복학습 ◻
  4. 코칭: 한 단계 위 사고 유도(계산력) ✅구현(5차)
  5. 시각화/블라인드 훈련(작업기억) ◻
  6. 적응형 난이도(몰입·최적 도전) ◻
  7. 복기 스페이스드 리피티션(기억 공고화) ◻
이번 구현:
  • 모바일/태블릿 PWA: studio.crowny.org=비주얼 퍼블리싱 도구(랜딩), Crowny 표준 PWA 패턴(manifest+sw+아이콘) 적용. manifest.json(standalone·portrait·shortcuts 오늘의3판/복기), sw.js(셸 cache-first·API network), 아이콘 192/512/maskable. 반응형 CSS: safe-area-inset, 태블릿 720/1024 브레이크포인트(보드 확대), 가로모드 컴팩트, touch-action, overscroll-contain. PWA 설치 배너(beforeinstallprompt). viewport-fit=cover.
  • 최적화 도구 제작: make-icons.sh(SVG→PNG 래스터화, 헤드리스 크롬, 외부 라이브러리 0).
  • 방향①매일3판·스트릭: 서버 GET/POST /api/daily·/api/daily/record(컴퓨터·회원 공통, 게임종료 시 클라 기록). 일일목표 3판, KST 날짜 롤오버, 스트릭(어제 두면 +1). 일일 허브 UI(♟3/3·🔥스트릭·완료 셀러브레이션).
  • 방향②두뇌점수: 게임별 정확도(100·exp(-avgCPL/300))→일일 평균=두뇌점수, 30일 성장 스파크라인, 7일 추세(▲▼).
  • 한선씨 동반: 일일두뇌판정.한선(스트릭갱신/목표달성/두뇌점수/추세, 검증 9/9, 학습). 한선씨 동반 6개.
  • 검증: curl(daily 3판→done·두뇌점수·history), 헤드리스 크롬 390px(일일 허브·모드카드·로비 렌더), PWA 에셋 공개 200. 정적 디스크서빙→무재기동(server.js만 재기동).

7차 — 인간화·게스트·27레벨 코칭 (2026-06-27)

  • ① 컴퓨터 인간화 속도: aiMove humanDelay(선택지 수×22 + 350~1850ms 지터, 체크 대응 빠름, 0.45~3.4s) → 사람처럼 생각. "상대가 생각 중…".
  • ② 게스트 무료 첫판 + 2번째 가입 안내: 로그인 화면 "♟ 로그인 없이 바로 두기"→게스트 모드(멤버탭/로비/멤버카드/맘 숨김, 게스트 허브). 컴퓨터 연습 자유. 2번째 판 시작 시 가입 결정 모달(🧠 "회원이 되면 더 똑똑해져요" 3혜택 + [그냥 계속 두기]/[회원가입]). 거절하면 계속 두기(declined 플래그로 재안내 안 함). 게스트는 서버기록 없음(localStorage 카운트).
  • ③ 코칭 미리보기(기존 5차): 내 수준보다 한 단계 낮은 추천수 보드 청록 하이라이트 → 늘 그보다 좋은 수 찾기.
  • ④ 27레벨 + 한 레벨 위: Chess.analyzeMovelevel(27레벨, 손실/15)+nextUp(존재하는 가장 가까운 더 높은 레벨의 최선수). 매 수 모달/패널에 "내 수 레벨 L/27 · 한 레벨 위: Nf3 (레벨 L+, +Ycp 더 좋아요)" → 점진적 성장.
  • ⑤ 상대 수 모달: AI·회원 상대가 두면 showOpponentMove(👀 기물 글리프 + from→to + 잡음/체크 태그) 사각 모달.
  • 한선씨 동반: 레벨판정.한선(27레벨/한레벨위/레벨손실/코칭판정, 검증 8/8, 학습. JS=floor vs 한선씨=자연반올림 1레벨 차 무방). 한선씨 동반 7개.
  • 검증: node(analyzeMove level/nextUp: 나쁜수→레벨5+102cp위 / 최선급→이미최선, perft 8902), 헤드리스 390px(게스트 허브+가입모달). 정적 디스크서빙→무재기동.

8차 — 방향③ 전술 퍼즐 트레이너 (2026-06-28)

"할수록 머리가 좋아지는" 방향③ 구현 — 패턴 인식(내 실수 → 스페이스드 리피티션):
  • 자동 생성: 대국 중 내 수가 실수/블런더(손실≥100cp)면, 그 직전 위치 + 내가 놓친 최선수를 퍼즐로 서버 저장(POST /api/puzzle/add, 같은 위치+해법 dedup, 한도 60·잘 푸는 것부터 정리). analyzeMyMove에서 캡처(회원 전용, 게스트 제외).
  • 스페이스드 리피티션(SRS): 6단계 간격 1·3·7·16·35·75일. 맞히면 단계↑(간격↑), 틀리면 단계 0(자주 복습). srsNext, due ≤ now 인 퍼즐만 복습 노출.
  • 퍼즐 풀이 화면: 일일 허브 "🧩 복습할 전술 퍼즐 N개 — 풀기" → 전용 보드(별도 인스턴스). "최선의 수를 찾으세요" + 진행(k/N) + 힌트(움직일 기물)/정답 보기 + 정오 피드백 + 다음. 정답=SRS 단계↑·sound win, 첫 오답=실패 기록 후 재시도, 정답보기/오답=단계 리셋.
  • 엔드포인트: POST /api/puzzle/add · GET /api/puzzle/due · POST /api/puzzle/result. dailyState에 puzzles{total,dueCount} 포함. pubPuzzle에 해법 포함(본인 학습용 클라 검증).
  • 한선씨 동반: 퍼즐SRS판정.한선(다음단계/단계간격/퍼즐자격/복습필요, 검증 11/11, 학습). 한선씨 동반 8개.
  • 검증: curl(add·dedup·due·result SRS step 0→1 due+3일), 헤드리스 390px(퍼즐 화면: 보드·1/1·최선의수·힌트/정답). 로드맵 방향③ ✅.

9차 — 방향⑤ 시각화/블라인드 훈련 (2026-06-28)

"할수록 머리가 좋아지는" 방향⑤ — 작업기억(블라인드 나이트 추적):
  • 블라인드 추적: 빈 보드(좌표만)에서 나이트가 수순(노테이션)만 보여주며 이동 → 사용자가 머릿속으로 추적해 최종 칸을 클릭. 보드 없이 수를 계산하는 작업기억 훈련.
  • 난이도(레벨 1~9): 추적 수순 = 레벨+1수, 노출시간 = 1500−레벨×90ms(최소 680). 맞히면 레벨↑(길고 빠르게), 틀리면 레벨↓.
  • 흐름: 시작 위치 잠깐 표시 → 빈 보드로 전환, 수순 한 개씩 누적 노출(블라인드) → "최종 위치 클릭" → 정/오 피드백 + 정답 표시 + SRS식 레벨 갱신. 다시 보기/다음.
  • 자체 생성: knightWalk(랜덤 합법 나이트 워크, 즉시 백트랙 회피). 빈 보드 전용 경량 렌더러(좌표·하이라이트·정답/오답 링). Chess 엔진 불필요.
  • 엔드포인트: GET /api/viz · POST /api/viz/record {level,correct}. dailyState에 viz{level,best,solved}. 일일 허브에 트레이너 행(🧩 퍼즐 + 👁 시각화 Lv N) 2버튼.
  • 한선씨 동반: 시각화레벨판정.한선(다음레벨/수순길이/노출시간, 검증 10/10, 학습). 한선씨 동반 9개.
  • 검증: curl(viz 정답→레벨↑·오답→레벨↓·daily 포함), 헤드리스 390px(빈 보드+좌표+"시작 g1→h3→g5"+최종위치 클릭). 로드맵 방향⑤ ✅.

10차 — 방향⑥ 적응형 난이도 (2026-06-28)

"할수록 머리가 좋아지는" 방향⑥ — 몰입/최적 도전(AI가 내 실력에 자동 맞춤):
  • 연속 강도(스킬 0~100): Chess.adaptiveMove(state, skill, depth) — 스킬↓ 허용손실=(100−스킬)×4.5만큼 약한 수 허용 + 상위권 집중도(conc=0.5+스킬/100×4) 가중샘플. 측정: 스킬10→평균손실92cp, 35→26, 60→11, 90→1, 100→0 (부드러운 단조 스케일).
  • 자동 조절: 게임 종료 시 결과·정확도로 스킬 ±. 승+8/패−8/무는 정확도로 ±3, 잘두면(≥85)+3·못두면(<40)−3, 클램프 5~100. 이기면 강해지고 지면 약해져 ~50% 승률 몰입대 유지. 초기 스킬=두뇌점수×0.7(15~80) 없으면 35.
  • 모드: 난이도 선택에 "🎚 적응형"(기본/추천) + 하수/보통/고수. 상대 이름 "컴퓨터 (적응형 · 실력 N)" 동적 표시. 종료 시 "난이도 ↑/↓" 알림. 리매치도 적응형 유지.
  • 회원=서버 저장(GET /api/adaptive·POST /api/adaptive/result), 게스트=localStorage(adjustSkillLocal 미러). 두 경로 동일 공식.
  • 한선씨 동반: 적응난이도판정.한선(스킬조정/허용손실/초기스킬, 검증 8/8, 학습. 허용손실 292 vs JS 293 자연반올림 1cp차 무방). 한선씨 동반 10개.
  • 검증: node(adaptiveMove 스킬별 손실·perft 8902), curl(적응 승+85→스킬46·패+30→35), 헤드리스 390px("컴퓨터 적응형·실력 35" 상대 이름). 로드맵 방향⑥ ✅.

11차 — 방향⑦ 복기 스페이스드 리피티션 + 로드맵 완주 🏁 (2026-06-28)

방향⑦ — 기억 공고화(내 대국 전체를 간격 두고 회상). ③전술퍼즐(단일위치 즉시풀이)과 구분:
  • 복기 카드 자동 생성: 회원 게임 종료 시 Chess.reviewGame로 내 전환점(실수/블런더, 손실≥100cp) 최대 3개 추출 → moves+key 저장. 첫 복습 due=내일(공고화 간격), SRS 6단계(퍼즐과 동일).
  • 복기 다시보기 화면: 일일허브 "📖 복기 N" → 지난 대국의 전환점을 보드 위에 내 수(골드)+최선(청록) 동시 하이라이트 + "내 수 b1c3·실수 / 🎯 최선 (+cp)" + "이 자리를 기억하세요". 전환점 스텝 → "기억 완료" → SRS 간격↑ → 다음 대국. 회상 기반(블라인드 풀이 아님).
  • 엔드포인트: POST /api/recall/add · GET /api/recall/due · POST /api/recall/done. dailyState에 recalls{total,dueCount}. 트레이너 행 3버튼(🧩퍼즐·👁시각화·📖복기).
  • 한선씨 동반: 복기큐판정.한선(전환점자격/카드자격/채택/복습필요, 검증 9/9, 학습). 한선씨 동반 11개.
  • 검증: curl(recall add·due·daily), 헤드리스 390px(복기 화면: 내수vs최선 보드+전환점+기억완료).

🏁 두뇌단련 로드맵 7방향 완주

1.매일3판·스트릭(습관) 2.두뇌점수·성장그래프(메타인지) 3.전술퍼즐(패턴인식) 4.코칭 한단계위(계산력) 5.시각화/블라인드(작업기억) 6.적응형난이도(몰입) 7.복기SRS(기억공고화) — 전부 ✅. 각 인지능력에 대응하는 "할수록 머리가 좋아지는" 모바일 PWA 두뇌단련 체스 완성. 한선씨 동반 11개(맘선물·지갑선물·체스규칙·복기·추천수·레벨·퍼즐SRS·일일두뇌·시각화·적응난이도·복기큐).

12차 — 4기능 울트라 워크플로우 (2026-06-28)

울트라 에이전트 워크플로우(4 sonnet 병렬, 481K토큰)로 4기능 동시 설계·코드생성 → 직렬 통합·검증. git worktree 불가라 에이전트는 새파일·한선씨만 직접작성, 공유파일은 삽입블록을 structured output 반환 → 내가 충돌없이 통합.
  • ① 두뇌 종합점수: cogScore(a)=대국정확도40%·전술퍼즐(reps)25%·시각화(level)20%·복기(reps)15% 가중합산 0~100. dailyState.cognitive + GET /api/cognitive. 클라 renderDailyHub 래핑으로 일일허브에 종합점수 배지+🔬두뇌분석 버튼→영역별 막대 오버레이(#cogScreen). 동반 종합점수판정.한선.
  • ② PGN 내보내기: 신규 public/js/pgn.js(toSAN: 기물·잡기x·캐슬 O-O·승급=Q·체크+·메이트#·모호성해소, movesToPGN: 표준헤더+본문+결과). 복기화면·종료액션에 PGN 버튼→클립보드/공유/다운로드. 동반 PGN판정.한선. node 자체검증 "1. e4 e5 2. Nf3".
  • ③ 실시간 관전: GET /api/spectate/list(ongoing+live 대국) + 기존 game SSE 재사용(읽기전용). 별도 Board+EventSource 실시간 갱신. #spectateScreen. 동반 관전판정.한선.
  • ④ 아레나 토너먼트: 생성/목록/참가/순위 라우트 + tourneys 영속(data/tourneys.json). 승3·무1·패0, finishGame→tourneyReport 자동 승점반영(g.id 중복방지). #tourneyScreen(목록·생성·실시간 순위 5초폴링). 동반 토너먼트판정.한선.
  • 통합 보완: 토너먼트 화면 .screen.tourney{position:fixed} 오버레이 규칙 누락→추가. 관전·토너먼트는 trainersRow 대신 플레이메뉴 소셜행(📺·🏆) 배치.
  • 검증: 서버 6엔드포인트 curl OK, 토너먼트 승점 E2E(갑 기권→을 +3점 자동반영), 헤드리스 390px(종합점수 배지·소셜행·토너먼트 화면). 한선씨 동반 15개(+4). 정적 디스크서빙→server.js만 재기동.

13차 — 4기능 직접 통합 (페어링·채팅·PGN가져오기·온보딩, 2026-06-28)

밀착결합 확장이라 워크플로우 fan-out 대신 직접 직렬 구현(분별).
  • ① 토너먼트 자동 페어링: POST /api/tourney/:id/pair(+unpair). 인메모리 대기풀(tourneyPools)에 들어가 유효 상대 있으면 즉시 라이브 블리츠(180s) 대국 생성+기존 'matched' SSE 재사용. 상세화면 "⚡ 자동 매칭" 버튼. 동반 페어링판정.한선. E2E(A대기→B매칭→라이브) ✓.
  • ② 관전/대국 채팅: POST /api/game/:id/chat(길이200·스로틀1.2s·역할 player/spectator). chatStore 인메모리 ring(50), 게임 SSE에 'chat'/'chathist' 이벤트. 대국뷰(#liveChat 라이브만)·관전뷰(#specChat) 채팅 위젯(chatMount/Push/Hist). 동반 채팅판정.한선. E2E(전송·스로틀차단·관전자) ✓.
  • ③ PGN 가져오기: pgn.js parsePGN(헤더/주석/NAG/변형 제거, SAN→이동 toSAN 역매칭, 캐슬 0-0 정규화). 가져오기 모달→복기화면 로드(import GAME 컨텍스트). 소셜행 "📥 기보". 동반 기보가져오기판정.한선. 라운드트립 일치·외부PGN 파싱 ✓.
  • ④ 통합 온보딩 투어: 첫 로그인 시 6단계 가이드(환영·일일단련·트레이너·소셜·바로두기·맘선물), 스포트라이트(box-shadow 9999px 딤)+카드+점, localStorage 1회. 토픽바 ❓ 재실행. 동반 온보딩판정.한선.
  • 검증: 헤드리스(투어 환영 카드·딤), 신규 6엔드포인트 스모크, 한선씨 동반 19개(+4). 정적 디스크서빙.