Story Maker
두 사람이 브라우저에서 함께 이야기 카드와 세계관을 엮어 텍스트 게임의 뼈대를 만드는 협업 편집기를 만들었다.
무엇을 만들었나
선택지로 이어지는 텍스트 게임을 두 사람이 같이 기획할 수 있는 웹 편집기다. 이야기 카드를 선으로 연결하고, 능력·아이템·세계관 설정을 한곳에서 관리하며, 연결이 끊긴 곳이나 빠진 설정은 자동으로 경고해 준다. 한 사람이 쓰는 도중 다른 사람이 같은 내용을 고쳐도 작성 중인 글을 잃지 않도록 했고, 편집기를 버전 4까지 키우면서도 기존 데이터는 백업 후 안전하게 옮겼다.
구현 방식과 보안 설계는 ‘기술 상세’에 있습니다.
구조와 설계
Node.js 24와 빌드 도구 없는 바닐라 JavaScript로 만든 2인 협업 편집기로, 정본은 JSON Schema로 계약된 JSON 파일(임시 파일 동기화 후 이름 변경하는 원자적 교체 + gzip 스냅샷)이고 계정·세션은 SQLite로 분리했다. HTTP와 WebSocket 명령이 하나의 저장 함수를 지나도록 해 스키마 검증과 항목별 baseRev 충돌 검사가 두 경로에서 똑같이 적용되며, 클라이언트는 서버 정본과 작성 중 초안을 분리해 충돌 시 두 버전을 비교하게 했다. 스키마는 v1에서 v4로 확장하면서 파일을 이행할 때 원본 gzip 백업을 먼저 남기고, 이전 화면이 보내는 구형 명령도 같은 정규화 함수로 받아 열린 화면의 저장이 거절되지 않게 했다. v4에서는 조건식 파서·출력기·평가 함수를 직접 작성하고 조건·랜덤·효과 노드의 순환은 정적 검사와 실행 단계 이동 한도로 다뤘다. 작업 기록 시점에는 실제 브라우저·모바일 화면 확인과 운영 배포는 하지 않았다.
사용 기술
Node.js 24, node:sqlite, node:crypto, WebSocket (ws), JSON Schema, 바닐라 JavaScript (빌드 없음), HTML/CSS/SVG, node:test
보안·안정성 설계
- 계정별 로그인과 세션, 비밀번호 변경, 로그인 시도 제한, 요청 출처 검사, 브라우저 보안 헤더를 적용했다.
- 계정·세션은 SQLite에, 스토리 정본은 JSON 파일에 분리해 보관한다.
- 모든 저장은 JSON Schema 검증을 거치며, 항목별 baseRev가 현재 버전과 다르면 저장을 거절하고 상대 버전을 돌려준다. HTTP와 WebSocket 두 경로에서 같은 거부가 일어남을 테스트로 확인했다.
- 정본 JSON은 임시 파일을 동기화한 뒤 이름을 바꿔 교체하고 gzip 스냅샷을 남긴다. 버전 이행 시에는 원본 gzip 백업을 먼저 저장하고, 백업이 실패하면 원본 파일을 교체하지 않는다.
- 사용자가 입력한 문자열을 화면에 넣는 새 요소는 textContent를 쓰는 기존 생성 함수로만 만들었다.
- 항목별 JSON 직접 편집도 기존 명령 경로의 정규화·스키마 검증·revision 검사를 거치게 했고, ID 변경은 참조 갱신이 필요하므로 폼의 전용 절차로 제한했다.
- 앱 버전이 서버와 어긋나면 배너로 알리되 자동 새로고침은 하지 않으며, 저장하지 않은 초안이 있으면 먼저 확인한다.
작업 기록
v2: 카드·이벤트·확률 풀 확장
이벤트 묶음과 가중치 풀, 모바일 편집 흐름을 추가하고 v1 데이터를 원본 백업 후 자동 변환했다. 테스트 79개, 스모크 17개가 통과했다.
v3: 스탯·마법 반응과 구형 화면 저장 호환
스탯·아이템 개수·능력 레벨·마법 반응·시간 이벤트를 추가하고, 배포 전에 열린 v2 화면에서도 작성 중인 카드를 저장할 수 있게 했다. 버전 불일치 배너를 넣었고 테스트 139개, 스모크 23개가 통과했다.
v4: 조건식 트리와 논리 노드
조건식 파서·출력기·평가 함수를 직접 작성하고 조건 분기·가중치 랜덤 분기·효과 노드, 세계관 문서와 링크를 추가했다. 변경 파일 42개, 테스트 185개, 스모크 26개가 통과했다.
한글 어절 줄바꿈과 긴 토큰 처리
한글은 어절 단위로 줄바꿈하고 긴 ID·URL은 영역 밖으로 넘치지 않게 CSS를 정리했다. 미리보기의 이름·값이 갈라지지 않게 했고, 작업 시점 기준으로 테스트 79개와 스모크 17개가 통과했다.
협업 편집기 1차 구현과 저장 경로 통합
페이지 그래프·세계관 사전·규칙 검사를 갖춘 2인 편집 웹앱을 만들고, HTTP와 WebSocket 편집이 같은 저장 함수·스키마 검증·버전 충돌 처리를 거치게 했다. 테스트 43개, 스모크 14개가 통과했다.
이 페이지는 작업 기록 문서 5건을 바탕으로 정리했습니다. 고객 정보, 접속 주소, 비밀값은 공개 전에 걸러 냅니다.