PocketBase를 사용하며 SQLite의 한계를 느끼기 시작했지만, 데이터베이스 교체부터 진행한 것은 아니다. 화면이 컬렉션 이름과 원시 응답을 직접 알고 있는 상태라면 저장소를 바꾸는 순간 화면까지 넓게 수정해야 한다. 향후 PostgreSQL이나 다른 플랫폼을 선택할 수 있도록 이 의존성을 먼저 줄일 필요가 있었다.
예를 들어 게임 목록 수정에는 새 값 저장 외에도 권한 검사, 현재 상태 변경과 수정 이력이 필요하다. 화면에서 컬렉션을 하나씩 호출하면 일부만 성공했을 때 작업을 어디까지 되돌려야 할지 복잡해진다. 공개 문서와 비공개 초안의 조회 조건도 여러 화면에 흩어지기 쉽다.
API v2는 이런 사용자 작업을 요청의 단위로 삼는다. 화면이 의도를 전달하면 서버가 권한, 저장 순서와 실패 처리를 책임지는 방식이다. 저장소의 구조를 숨기는 동시에 같은 작업의 정책을 한곳에서 확인할 수 있도록 했다.
현재도 PocketBase의 인증과 저장 기능을 사용한다. 오락실 기능이 지원하는 작업을 문서화한 custom API로 제공하고, 브라우저에는 요청 값과 제품 정보, 권한 오류와 충돌의 의미를 전달한다. 내부 컬렉션의 표현이 바뀌어도 이 사용 방법을 유지하면 화면 수정 범위를 줄일 수 있다.
브라우저 상호작용은 Next.js Route Handler를 거쳐 DataKit 서비스로 이어지고, 서버 렌더링은 같은 서비스에 직접 접근한다. DataKit은 인증된 서버 transport와 응답 해석을 맡는다. 진입 방식이 달라도 같은 제품 타입을 사용하며 저장소의 원시 응답을 그대로 브라우저에 내보내지 않는다.
게임 편집 요청에는 오락실 ID, 편집을 시작한 상태의 ID와 추가·수정·삭제할 항목이 들어간다. 서버는 해당 오락실을 고칠 권한과 현재 상태를 확인한다. 다른 사람이 먼저 저장했다면 충돌을 반환하고, 화면은 작성 내용을 유지한 채 최신 상태와 비교할 수 있게 한다.
검사를 통과한 요청은 새 게임 상태, 현재 참조, 변경 이력과 필요한 보상을 같은 트랜잭션에서 처리한다. 트랜잭션은 이 묶음이 모두 저장되거나 함께 취소되도록 하는 데이터베이스 기능이다. 외부 서비스 호출은 밖에서 실행해 응답을 기다리는 동안 저장소 잠금을 오래 붙잡지 않도록 한다.
Core에는 재사용할 스키마와 API 동작을, Full에는 기존 데이터의 운영 이관과 설정·작업 등록을 둔다. 새 환경을 만드는 일과 이미 쌓인 이력과 참조를 보존하며 바꾸는 일은 확인해야 할 조건이 다르기 때문이다.
현재 custom API는 PocketBase와 SQLite 위에서 동작한다. PostgreSQL이나 다른 플랫폼으로의 이관은 아직 앞으로 준비할 일이다. 이번 변경으로 화면은 사용자 작업 하나의 결과를 받고, 서버는 그 작업의 권한과 저장을 함께 검증할 수 있게 됐다. 새 기능도 같은 API를 사용해야 이런 구조를 계속 유지할 수 있다.