Skip to content

변경 이력(감사) ​

오퍼레이터가 Operator API 로 바꾼 설정은 모두 플랫폼 감사 기록에 남습니다. 이 API 로 자기 조작 기록을 조회하고, 조작 전 값으로 되돌릴(복구) 수 있습니다.

메서드경로용도
GET/operator/v1/audit감사 기록 조회
POST/operator/v1/audit/{audit_id}/restore조작 하나를 조작 전 값으로 되돌리기

감사 기록이 남는 방식 ​

  • POST /launch 를 뺀 쓰기 요청(POST · PUT · PATCH · DELETE)은 응답 헤더 X-Audit-Id: <정수> 로 감사 기록 번호를 돌려줍니다. 관리 화면에서 조작 로그를 따로 남긴다면 이 번호를 함께 저장해 두세요. 나중에 GET /audit?ids= 로 상태를 보거나 복구할 때 씁니다.
  • 기록은 요청이 성공(2xx)했을 때만 저장됩니다. 실패한 요청에도 X-Audit-Id 헤더가 실릴 수 있지만 그 번호의 기록은 없습니다.
  • 설정을 바꾸는 요청은 바뀌기 전 · 뒤 값(스냅숏)이 기록에 붙습니다. 스냅숏이 있는 기록만 되돌릴 수 있습니다.
  • 요청에 X-Operator-Admin: <관리자 아이디> 헤더(^[A-Za-z0-9_.@-]{1,40}$, 서명 대상 아님)를 넣으면 조작자가 operator:<오퍼레이터 코드>/<관리자 아이디> 로 기록됩니다. 없으면 operator:<오퍼레이터 코드> 입니다. 이 값은 누가 눌렀는지 적는 표시일 뿐 권한과는 무관합니다.
  • 오퍼레이터는 자기 오퍼레이터 코드로 남은 기록만 보고 되돌릴 수 있습니다. 본사가 바꾼 설정은 이 API 에 보이지 않습니다.

되돌릴 수 있는 조작 ​

조작되돌리면
PUT /games/{game_code}/bet-limits · PUT /games/{game_code}/lobby게임 베팅 한도 · 로비 표시 설정
PATCH /tables/{table_id} · POST /tables/{table_id}/close · PUT /tables/{table_id}/{settings, live, timers, rake-rule, card-design, currency}전용 테이블 설정 (닫은 테이블 다시 열기 포함)
PUT /settings · PUT /card-design오퍼레이터 설정
PUT /rake-defaults수수료 기본값과, apply_all · rake_floor 로 함께 바뀐 전용 테이블들
POST /players/{external_id}/logout플레이어 차단 상태(block)만. 끊긴 세션은 되살아나지 않습니다
PATCH /dealers/{dealer_id} · PUT /dealers/{dealer_id}/photo · DELETE /dealers/{dealer_id}/photo딜러 이름 · 역할 · 사용 여부 · 사진 (PIN 은 되돌리지 않음)
DELETE /private-tables/{private_id}프라이빗 예약 취소
복구(audit.restore) 자체복구를 취소 — 복구 직전 값으로

만들기 요청(POST /tables · POST /dealers · POST /private-tables), 사원증 발급 · 회수, 로비 배너 그림 올리기는 기록만 남고 되돌릴 수 없습니다(restorable: false).

GET /operator/v1/audit ​

감사 기록을 최신순(id 내림차순)으로 조회합니다. 두 가지 방식이 있습니다.

쿼리 파라미터 ​

방식 1 — 번호로 조회

파라미터타입필수설명
idsstring예쉼표로 구분한 감사 기록 번호, 최대 500개 (예: ids=1204,1207). 숫자가 아닌 값은 건너뜁니다

ids 를 주면 아래 필터 · 페이지 파라미터는 무시하고, 그중 자기 기록만 돌려줍니다(has_more 는 항상 false).

방식 2 — 필터로 조회

파라미터타입필수설명
actionstring아니오조작 이름 앞부분 일치 (예: table. 이면 table.settings, table.close …)
targetstring아니오대상 정확히 일치 (예: tbl_…, 딜러 ID, 오퍼레이터 코드)
restorable1아니오스냅숏이 붙은 기록만
limit정수아니오페이지 크기. 기본 100, 최대 500
page정수아니오1부터 시작하는 페이지 번호 (기본 1)

요청 예시 ​

http
GET /operator/v1/audit?action=table.&restorable=1&limit=50&page=1 HTTP/1.1
Host: {API_HOST}
X-Operator: acme
X-Api-Key: ak_live_…
X-Timestamp: 1760839200123
X-Nonce: 8d0f2b4a6c8e0d2f4b6a8c0e
X-Signature: 5c1d…

응답 예시 ​

json
{
  "entries": [
    {
      "id": 1207,
      "admin": "operator:acme/jane",
      "action": "table.settings",
      "target": "tbl_0198c1d2e3f47a5b8c9d0e1f2a3b4c5d",
      "detail": { "currency": "PHP", "active": true, "before": { "…": "…" }, "after": { "…": "…" } },
      "ip": "198.51.100.7",
      "created_at": "2026-10-19T03:40:12.88Z",
      "changes": [
        {
          "kind": "table",
          "key": "0198c1d2-e3f4-7a5b-8c9d-0e1f2a3b4c5d",
          "op": "update",
          "fields": {
            "limits.sb": { "before": 100, "after": 200 },
            "limits.bb": { "before": 200, "after": 400 }
          }
        }
      ],
      "restore_of": null,
      "restored_by": null,
      "restorable": true
    },
    {
      "id": 1204,
      "admin": "operator:acme/jane",
      "action": "operator.watch_limit",
      "target": "acme",
      "detail": { "before": 0, "after": 600 },
      "ip": "198.51.100.7",
      "created_at": "2026-10-19T03:31:02.4Z",
      "changes": [
        { "kind": "operator", "key": "0198a0b1-c2d3-7e4f-8a5b-6c7d8e9f0a1b", "op": "update", "fields": { "watch_limit_sec": { "before": 0, "after": 600 } } }
      ],
      "restore_of": null,
      "restored_by": 1210,
      "restorable": true
    }
  ],
  "has_more": false
}

응답 필드 ​

필드타입설명
entries[].idint64감사 기록 번호 (= 그 요청의 X-Audit-Id)
entries[].adminstring조작자 — operator:<코드> 또는 operator:<코드>/<관리자 아이디>
entries[].actionstring조작 이름 (아래 표)
entries[].targetstring대상 (테이블 ID · 딜러 ID · 게임 코드 · 플레이어 external_id · 오퍼레이터 코드 등)
entries[].detailobject조작 내용 (조작마다 모양이 다름, 보통 before · after)
entries[].ipstring | null요청한 서버 IP
entries[].created_at시각기록 시각
entries[].changesarray바뀐 설정 요약 (스냅숏이 있을 때만) — 아래 표
entries[].restore_ofint64 | null이 기록이 복구라면 되돌린 원래 기록 번호
entries[].restored_byint64 | null이 기록을 되돌린 복구 기록 번호 (되돌리지 않았으면 null)
entries[].restorablebool되돌릴 수 있는 기록인지
has_morebool다음 페이지가 있는지 (page 를 1 늘려 조회)

changes[]

필드설명
kind바뀐 대상 종류 — operator · operator_game · table · dealer · dealer_photo · player · private_reservation
key대상 행의 내부 키
opupdate · create · delete
fields바뀐 항목 → { before, after }. JSON 설정은 바뀐 칸만 점 경로(예: config.rake.rake_floor)로 펼칩니다. 비밀번호 같은 값은 가려서 보여 주고, 사진 바이트처럼 큰 값은 줄여 보여 줍니다

changes 와 detail 은 화면 표시용 요약입니다. 항목 이름은 플랫폼 내부 저장 이름이라 바뀔 수 있으니, 프로그램 판단에는 action · target · restorable 을 쓰세요.

조작 이름(action) ​

범위이름
게임game.bet_limits · game.lobby
테이블table.create · table.update · table.close · table.settings · table.currency · table.live · table.timers · table.rake_rule · table.card_design · table.private · table.private_cancel
오퍼레이터operator.timezone · operator.multi_table · operator.watch_limit · operator.rake_defaults · operator.card_design
플레이어player.logout
딜러dealer.create · dealer.update · dealer.badge_issue · dealer.badge_reissue · dealer.badge_revoke · dealer.photo · dealer.photo_delete
복구audit.restore
그 밖api <METHOD> <경로 패턴> — 전용 이름이 없는 쓰기 요청 (예: api PUT /operator/v1/lobby-banners)

한 요청이 여러 설정을 바꾸면(예: PUT /settings 로 시간대와 중복 게임을 함께) 기록이 여러 줄 남을 수 있습니다. 이때 스냅숏과 X-Audit-Id 는 첫 번째 기록에 붙습니다.

오류 ​

HTTP코드상황
500INTERNAL_ERROR일시적인 서버 오류

POST /operator/v1/audit/{audit_id}/restore ​

감사 기록 하나의 조작을 조작 전 값으로 되돌립니다. 되돌린 결과도 새 감사 기록(audit.restore)으로 남고, 원래 기록의 restored_by 에 그 번호가 적힙니다. 복구 기록을 다시 복구하면 복구가 취소됩니다.

운영 중인 테이블 · 딜러툴 · 입장 설정에도 바로 반영됩니다.

경로 · 요청 필드 ​

필드타입필수설명
audit_idint (경로)예되돌릴 감사 기록 번호
forcebool (본문)아니오그 조작 뒤에 같은 설정이 다시 바뀌었어도 덮어쓰고 되돌림. 기본 false

본문은 생략할 수 있습니다(빈 본문 또는 {} 로 서명하면 force: false).

충돌 처리 ​

되돌리기 전에 지금 값이 "그 조작 직후 값"과 같은지 확인합니다. 그 뒤에 누군가 같은 설정을 또 바꿨다면 아무것도 바꾸지 않고 409 RESTORE_CONFLICT 와 충돌 목록을 돌려줍니다. 이때는

  1. 나중 조작들을 최신 것부터 먼저 되돌리거나,
  2. 나중 변경을 무시하고 덮어쓰려면 force: true 로 다시 요청합니다.

요청 예시 ​

bash
curl -X POST {API_BASE}/operator/v1/audit/1207/restore \
  -H 'Content-Type: application/json; charset=utf-8' \
  -H 'X-Operator: acme' -H 'X-Api-Key: ak_live_…' -H 'X-Operator-Admin: jane' \
  -H 'X-Timestamp: 1760839200123' -H 'X-Nonce: 2f4b6a8c0e2d4f6b8a0c2e4d' -H 'X-Signature: b83a…' \
  -d '{}'

응답 예시 ​

200 OK (응답 헤더 X-Audit-Id 도 복구 기록 번호)

json
{
  "ok": true,
  "audit_id": 1211,
  "changes": [
    {
      "kind": "table",
      "key": "0198c1d2-e3f4-7a5b-8c9d-0e1f2a3b4c5d",
      "op": "update",
      "fields": {
        "limits.sb": { "before": 200, "after": 100 },
        "limits.bb": { "before": 400, "after": 200 }
      }
    }
  ]
}
필드타입설명
okbool항상 true
audit_idint64새로 남은 복구 기록 번호
changesarray복구가 실제로 바꾼 설정 요약 (모양은 목록의 changes 와 같음)

오류 ​

HTTP코드details상황
404NOT_FOUND—형식이 틀린 번호, 없는 기록, 다른 오퍼레이터 · 본사의 기록
403NOT_RESTORABLE—오퍼레이터 권한으로 되돌릴 수 없는 종류의 변경이 섞여 있음
409NOT_RESTORABLE—되돌릴 스냅숏이 없음(만들기 요청 · 사원증 등) 또는 이 환경에서 복구 기능이 꺼져 있음
409RESTORE_BLOCKED{ "kind": "table", "key": "…" }지금 상태에서는 되돌릴 수 없음 — 예: 플레이어가 앉아 있는 테이블의 통화 되돌리기. message 에 이유가 담깁니다. 상황이 바뀐 뒤 다시 시도하세요
409RESTORE_CONFLICT{ "conflicts": [ { "kind": "table", "key": "…" } ] }그 조작 뒤에 같은 설정이 다시 바뀜 — 위 충돌 처리
500INTERNAL_ERROR—복구 중 서버 오류

RESTORE_CONFLICT 응답 예:

json
{
  "error": {
    "code": "RESTORE_CONFLICT",
    "message": "changed again after this action — restore the later changes first, or force",
    "details": { "conflicts": [ { "kind": "table", "key": "0198c1d2-e3f4-7a5b-8c9d-0e1f2a3b4c5d" } ] }
  }
}

문서 v1.0.0 · Operator API v1