k-skill/docs/features/srt-booking.md
iamiks 52dbfee064
feat(srt-booking): SRT 좌석 확인과 탐색 우선순위 개선 (#305)
* feat(srt): 좌석 조회와 탐색 우선순위 추가

SRT search 결과의 stable train_id로 객차별 좌석을 조회하고, 특정 호차/좌석 확인과 탐색 우선순위 옵션을 제공한다.

Constraint: SRT와 KTX는 별도 upstream 표면이므로 SRT HTML 파서와 테스트를 분리함
Rejected: KTX 좌석 helper 공유 | Korail API와 SRT 웹 좌석선택 HTML 계약이 달라 혼용하면 파서 안정성이 낮아짐
Confidence: medium
Scope-risk: moderate
Directive: SRT 좌석선택 HTML에서 노출되지 않는 속성은 추정하지 말고 명시적으로 처리할 것
Tested: PYTHONPATH=.:scripts python3 -m unittest scripts.test_srt_booking scripts.test_ktx_booking; python3 -m py_compile scripts/srt_booking.py scripts/srt_seats.py scripts/test_srt_booking.py
Not-tested: 실제 예약 API에 우선순위 좌석 선택을 연결하는 흐름

* fix(srt): 좌석 조회 JSON 출력 안정화

SRT 대기열 메시지가 stdout에 섞여 seats JSON을 깨는 실제 표면 문제를 막고, 누락된 좌석 방향/위치 속성을 unknown으로 정규화한다.

Constraint: issue #303 범위는 예약 부작용이 없는 좌석 조회 보조 흐름으로 제한됨
Rejected: 실제 예약 subcommand 추가 | 좌석 선점/예약은 외부 부작용이라 이번 acceptance criteria에 포함되지 않음
Confidence: high
Scope-risk: narrow
Directive: SRTrain upstream 출력이 추가되더라도 helper stdout은 JSON 전용으로 유지할 것
Tested: RED→GREEN in .omo/ulw-loop/evidence/srt-c002-red-green-tests.txt; live SRT tmux QA in .omo/ulw-loop/evidence/srt-c001-live-search-seats.txt; npm run ci in .omo/ulw-loop/evidence/srt-c003-regression-ci.txt
Not-tested: 실제 예약/결제/취소 부작용 흐름

* test(srt): split seat helper regression coverage

---------

Co-authored-by: Jeffrey (Dongkyu) Kim <vkehfdl1@gmail.com>
2026-06-09 10:57:54 +09:00

3.2 KiB

SRT 예매 가이드

이 기능으로 할 수 있는 일

  • 수서 출발 SRT 열차 조회
  • 좌석 가능 여부 확인
  • 호차별 남은 좌석번호 확인
  • 특정 좌석 공석 여부 확인
  • 예약 진행
  • 예약 내역 확인
  • 예약 취소

먼저 필요한 것

필요한 환경변수

  • KSKILL_SRT_ID
  • KSKILL_SRT_PASSWORD

Credential resolution order

  1. 이미 환경변수에 있으면 그대로 사용한다.
  2. 에이전트가 자체 secret vault(1Password CLI, Bitwarden CLI, macOS Keychain 등)를 사용 중이면 거기서 꺼내 환경변수로 주입해도 된다.
  3. ~/.config/k-skill/secrets.env (기본 fallback) — plain dotenv 파일, 퍼미션 0600.
  4. 아무것도 없으면 유저에게 물어서 2 또는 3에 저장한다.

입력값

  • 출발역
  • 도착역
  • 날짜: YYYYMMDD
  • 희망 시작 시각: HHMMSS
  • 인원 수
  • 좌석 선호
  • 좌석 상세 조건: 객실 등급, 호차 번호, 좌석 번호, 빈 좌석만 보기, 탐색 우선순위

기본 흐름

  1. SRTrain 패키지가 없으면 다른 방법으로 우회하지 말고 먼저 전역 설치합니다.
  2. KSKILL_SRT_ID, KSKILL_SRT_PASSWORD 가 없으면 credential resolution order에 따라 확보합니다.
  3. 먼저 helper 로 열차를 조회합니다.
  4. 후보 열차의 출발/도착 시각, 좌석 여부, 운임을 보여줍니다.
  5. 사용자가 좌석번호, 호차별 잔여석, 특정 좌석 공석 여부를 물으면 seats 로 상세 좌석을 먼저 확인합니다.
  6. 대상 열차가 명확할 때만 예약합니다.
  7. 예약 확인/취소는 예약을 다시 식별한 뒤 진행합니다.

예시

python3 scripts/srt_booking.py search 수서 부산 20260328 080000 --time-limit 120000 --limit 5

상세 좌석 확인:

python3 scripts/srt_booking.py seats 수서 부산 20260328 080000 --train-id <train_id>

특정 호차의 빈 좌석만 확인:

python3 scripts/srt_booking.py seats 수서 부산 20260328 080000 --train-id <train_id> --car-no 5 --available-only

특정 좌석이 비었는지 확인:

python3 scripts/srt_booking.py seats 수서 부산 20260328 080000 --train-id <train_id> --car-no 5 --seat 11A

탐색 순서 조정:

python3 scripts/srt_booking.py seats 수서 부산 20260328 080000 \
  --train-id <train_id> \
  --car-priority center \
  --seat-priority window-forward \
  --available-only

seats 응답은 호차별 available_seat_count, available_seats, 좌석별 순방향/역방향, 창측/내측, 특정 좌석 요청 시 requested_seat_available 을 JSON 으로 반환합니다. 이 단계는 좌석을 선택하거나 선점하지 않고, 예약 전 확인만 합니다.

주의할 점

  • credential은 환경변수로 주입합니다.
  • 상세 좌석 확인은 SRT 웹 좌석선택 페이지의 공개 HTML을 조회 전용으로 파싱합니다.
  • 결제 완료까지 자동화하는 문서는 아닙니다.
  • 매진 시 공격적인 재시도 루프는 피합니다.