INKSHIFT: cross out a table, keep the booking
INKSHIFT: 테이블을 바꿔도 예약은 그대로
INKSHIFT는 모임 계획을 공유하고, 일정 변경 뒤에도 참가자의 예약을 유지하는 앱입니다. Sanity의 Content Lake와 Workflows를 사용해 변경을 검토하고, 세션 ID를 보존해 장소만 옮깁니다. 동시 예약과 변경 이력 처리 방식도 소개합니다.
- 주제
AI 요약
INKSHIFT는 게임 모임이나 워크숍 계획을 공유 신청 페이지로 바꾸는 앱입니다. 주최자가 계획을 사진으로 올리거나 직접 입력하면 세션을 확인한 뒤 초대 링크를 보냅니다. 참가자는 계정 없이 예약할 수 있습니다. 계획을 수정할 때는 기존 참가자의 예약에 어떤 영향이 있는지 검토하고, 변경을 승인하면 예약을 유지한 채 새 장소로 옮깁니다.
예약을 세션에 연결합니다
Sanity Content Lake에서 공간(space), 세션(session), 등록(registration)을 서로 다른 레코드로 관리합니다. 등록은 세션을 가리키고, 세션은 공간을 가리킵니다. Ticket to Ride의 장소를 Table B에서 Table C로 바꿀 때 세션 ID는 그대로 두고 공간 참조만 변경합니다. 등록이 같은 세션을 계속 가리키므로 참가자는 다시 신청하지 않아도 됩니다.
장소 변경을 승인하기 전에는 Table C의 좌석 수와 이용 가능 시간이 충분한지 확인합니다. 계획 수정은 제안(proposal)으로 저장되며, Sanity Workflows가 Reading, Review, Applied 또는 Discarded 상태를 기록합니다. 검토 과정에서 새 참가자가 들어오면 기존 제안의 조건이 달라질 수 있습니다. 서버는 적용 직전에 이벤트와 제안의 리비전을 확인하고 좌석과 시간 조건을 다시 계산합니다. 이벤트가 바뀌었다면 주최자가 다시 검토해야 합니다. 승인된 계획과 연결 레코드, 공개 일정은 Content Lake 트랜잭션 하나로 저장합니다.
변경 이력을 데이터로 보존합니다
Paper time machine은 적용된 계획 버전을 시간순으로 보여줍니다. 각 버전에는 적용 시각, 변경 내용, 유지된 예약 수, Workflows 실행 상태가 표시됩니다. 예를 들어 버전 1에서 버전 2로 이동하면 Ticket to Ride가 Table B에서 Table C로 옮겨지고, 참가자 Ada의 토큰도 함께 따라갑니다. 폐기한 판독 결과는 버전으로 기록하지 않습니다.
버전은 애니메이션으로 꾸며낸 기록이 아니라 실제 저장 데이터를 바탕으로 만듭니다. 변경 제안이 적용될 때마다 그 결과가 계획에 반영되므로 적용된 제안의 미리보기는 생성된 계획과 일치합니다. 다만 첫 수정 전 계획은 저장하지 않았습니다. 이를 해결하려고 적용 시점에 proposal에 planBefore 스냅샷을 기록합니다. 이 기능보다 오래된 샘플 모임은 준비된 샘플 정의로 첫 버전을 다시 만들며, 화면에 Reconstructed라고 표시합니다. 예약은 생성·취소 시각을 기준으로 각 버전에 배치하고, 세션 ID를 따라가므로 장소 변경을 추측하지 않습니다.
공개 데이터와 주최자 전용 데이터를 나눕니다
App SDK는 Content Lake의 공개 일정과 예약 수를 읽고 변경을 구독합니다. 참가자 이름, 업로드한 사진, 주최자 접근 정보는 권한을 확인하는 서버 경로에서만 다룹니다. 주최자 쿠키가 없는 요청은 403으로 거부하며, Sanity 쓰기 토큰도 서버에 둡니다. 공개 일정이 바뀌면 주최자 화면은 권한을 확인하는 서버 경로에서 비공개 데이터를 새로 불러옵니다.
사진 판독은 제안으로 다룹니다
사진 판독에는 Hugging Face Inference Providers를 통한 Qwen3-VL을 사용합니다. 사진에서 일부 영역이 보이지 않는다는 이유만으로 계획에서 항목을 삭제하지 않고 검토 대상으로 남깁니다. 실제 테스트에서는 판독기가 수정된 계획 사진에서 이미 예약된 Ticket to Ride를 없어진 항목으로 읽었습니다. 검토 단계에서 이를 원래 세션과 다시 연결한 뒤 승인해 예약을 보존했습니다. 작성자는 이 사례를 근거로 검토를 필수 단계로 뒀습니다.
구현과 검증
앱은 Next.js와 React, Sanity Content Lake, App SDK, Workflows로 구성됩니다. 검증 기록은 예약 보존, 동시 변경, 접근 복구, 비공개 데이터 보호를 다룹니다. 도메인 테스트는 장소 이동, 목적지 조건, 식별 모호성, 잘린 사진, 시간 충돌, 좌석 감소를 확인합니다. 시간 이력 테스트 6개를 포함해 테스트는 모두 37개입니다. 마지막 좌석을 두고 실시간 경쟁을 재현했을 때 예약 성공은 한 건뿐이었고, 장소 이동 뒤에도 예약 ID 다섯 개가 유지됐습니다. 시간 이력 테스트에서는 적용 시각과 예약 시각이 같은 경우도 다뤘으며, 고정 시계를 사용해 테스트 결과를 안정시켰습니다.
dev.to 반응
- @aarishmansur — 진짜 멋진 프로젝트네요. 우리 둘이 같이 이벤트를 잡아봐요 😄
원문: dev.to / 번역·요약: Trawling