모듈은 식당과 호텔과 의원과 상점을 하나의 앱으로 만드는 문제에 대한 Korat의 답입니다. 그 문제란, 그것의 정직한 버전이 로그인을 공유하는 네 개의 앱이라는 점입니다. 부정직한 버전은 설정 화면이 너무 커져서 모든 사업이 자기와 상관없는 것만 잔뜩 보게 되는 하나의 앱입니다. Korat은 세 번째 길을 갑니다. 업종이 모듈을 고르고, 모듈이 인터페이스를 만들며, 공개 페이지도 주인 콘솔도 식당이 무엇인지에 대한 지식을 코드에 박아 두고 있지 않습니다.
모듈 계약
모듈은 정해진 것들을 선언하고, 앱은 나머지를 거기서 조립합니다. id, 자기가 맡는 비즈니스 종류(이것이 그 모듈이 어떤 가게에 적용되는지를 정합니다), 라벨과 카탈로그 제목, 손님 페이지가 앞세우는 하나의 버튼인 기본 CTA, 그리고 카탈로그 뷰 — 음식이면 메뉴, 숙박이면 객실 타입, 의원이면 서비스, 리테일이면 상품.
네 가지 선언이 더 있는데 선택 사항이고, 이 시스템이 값어치를 하는 곳이 바로 여기입니다. 모듈은 직원 역할이 쓸 수 있는 새 권한이 되는 권한, 주인 대시보드 격자에 나타나는 콘솔 타일, 자기만의 콘솔 화면, 그리고 가게의 공개 페이지에 삽입되는 손님용 페이지 구획을 선언할 수 있습니다. 넷 중 아무것도 선언하지 않으면 순수한 카탈로그이고, 넷을 모두 선언하면 앱의 양쪽을 동시에 다시 빚습니다.
공용 UI 키트도 있습니다. 기본 CTA 버튼, 카탈로그 행, 칩, 구획 라벨, 빈 상태. 모듈은 여기서 시작하는 것이 원칙입니다. 통일감을 위한 통일감이 아니라, 따로 쓰인 모듈이 끼워 넣은 위젯이 아니라 앱의 일부처럼 보이게 만드는 장치입니다.
네 개의 핵심 모듈이 곧 업종입니다
네 개의 핵심 모듈은 애드온이 아닙니다. 업종이 뜻하는 바 그 자체입니다. Food는 식당과 카페를 맡습니다. Stay는 숙박, 호텔, 리조트, 아파트, 콘도, 빌리지 여섯 개의 이름표를 하나의 모듈로 맡습니다. 콘도 임대와 게스트하우스의 하룻밤은 표현이 다를 뿐 구조가 다르지 않기 때문입니다. Service는 서비스와 의원을 맡고, 의원 변형은 코드를 갈라놓지 않은 채 인터페이스를 예약·환자·치료 코스로 바꿔 부릅니다. Retail은 리테일을 맡습니다.
이것들이 거대한 화면 안의 분기가 아니라 모듈이기 때문에, 호텔에게 음식 모듈의 주방 화면과 옵션 그룹은 존재하지 않습니다. 플래그 뒤에 숨은 것도, 비활성화된 것도 아니라 없습니다. 가게가 보는 표면적은 그 가게가 스스로를 무엇이라 선언했는지의 함수입니다.
일곱 개의 설치형 애드온, 업종을 가리지 않습니다
핵심 모듈 위에 네 개의 애드온이 놓이고, 전부 업종과 무관하게 적용됩니다. 팀 권한이 가장 흥미로운데, 다른 모듈들로부터 자기를 짓기 때문입니다. 설치된 모든 모듈이 선언한 권한을 모아 권한 편집기를 만들어 내므로, 새 모듈을 설치하면 아무도 목록을 고치지 않아도 그 권한이 편집기에 들어옵니다.
결제 채널은 받는 채널을 설정하는 콘솔 타일과, 공개 페이지에 손님이 보는 채널 목록을 함께 더합니다. 하나의 애드온이 두 개의 선언 슬롯으로 양쪽에 씁니다. 멤버십·구독은 손님이 가게 페이지에서 바로 살 수 있는 플랜을 들여옵니다. 갱신 알림은 멤버십과 코스가 만들어 내는 후속 연락을 다룹니다. 넷 다 서드파티가 쓸 바로 그 계약에 맞춰 쓰인 자체 제작 모듈입니다. 의도적인 규율입니다. 계약은 그것을 만든 사람도 그것에 묶일 때에만 실재합니다.
설치와 삭제, 가게 단위로
애드온은 주인 콘솔 안의 플러그인 스토어에서 관리되고, 설치 범위는 하나의 비즈니스입니다. 가게 두 곳을 운영하는 주인은 한쪽에만 멤버십을 설치할 수 있고, 두 대시보드는 실제로 달라집니다.
삭제는 확인 창 뒤에 있고, 그 확인 창은 구체적인 것을 말합니다. 데이터는 삭제되지 않습니다. 들리는 것보다 중요한 문장입니다. 사람들이 삭제 버튼 앞에서 망설이는 이유는 그것이 파괴적일 것이라고 가정하기 때문이고, 그래서 쓰지도 않는 모듈을 그냥 두어 콘솔이 아무도 열지 않는 타일로 채워집니다. 무슨 일이 *일어나지 않는지* 말해 주는 것이 그 버튼을 쓸 수 있게 만듭니다. 삭제한 뒤 애드온은 아무것도 기여하지 않습니다. 타일도, 역할 편집기의 권한도, 공개 페이지의 구획도. 하지만 그 기록은 다시 설치해도 그대로 있습니다.
아직 이것이 아닌 것
서드파티 플러그인은 열려 있지 않습니다. 「곧 추가됩니다」라는 빈 선반으로 다른 인상을 주는 대신 플러그인 스토어가 직접 그렇게 적습니다. 오늘 존재하는 것은 실제 계약을 가진 모듈형 구조와, 그 계약에 맞춰 쓰이고 같은 등록 경로로 올라오는 네 개의 핵심 모듈과 네 개의 자체 애드온입니다. 서드파티 제출은 살아 있는 마켓플레이스가 아니라 다음 단계로 밝혀 둔 계획입니다. 개발자 포털도, 심사 대기열도, 공개된 SDK도 없습니다.
이렇게 쓰는 이유는 구조가 흥미로운 부분이고 그것이 오늘 사실인 반면, 마켓플레이스는 미래에 대한 주장이기 때문입니다. 계약의 시험은 오직 계약에만 기대어 쓰인 모듈이 — 타일과 권한과 페이지 구획을 갖고, 코어 코드는 건드리지 않은 채 — 앱의 원래 일부처럼 동작하느냐입니다. 넷이 그렇게 동작합니다. 그것을 외부에 여는 일은 기술보다 정책과 심사의 문제이고, 아직 풀리지 않았습니다.
왜 기능 플래그가 아니라 모듈인가
기능 플래그는 무언가를 끕니다. 모듈은 무언가를 기여합니다. 차이는 권한 편집기에서 드러납니다. 플래그로 하면 누군가 모든 권한의 마스터 목록을 관리하며 확장하는 것을 기억해야 합니다. 계약으로 하면 팀 권한 애드온이 설치된 각 모듈에게 무엇을 선언하는지 물어 답으로 편집기를 만들기 때문에 목록이 낡을 수가 없습니다. 대시보드 격자와 공개 페이지도 같은 방식입니다. 어느 것도 기능을 열거하지 않고, 전부 물어봅니다.
새로운 업종을 더하는 비용도 이것이 묶어 줍니다. Korat이 아직 다루지 않는 업종을 더하는 일은 모듈 하나입니다. 맡을 종류와 카탈로그와 CTA, 그리고 필요한 선택 슬롯을 선언하면 됩니다. 콘솔도, 페이지 렌더러도, 권한 시스템도 건드리지 않습니다. 슈퍼앱이 특수 사례의 느린 축적이 아니라 감당 가능한 것이 되는 지점이 여기입니다.
서드파티 플러그인 마켓플레이스는 없습니다. 오늘 설치 가능한 것은 전부 자체 제작이고, 스토어가 앱 안에서 그렇게 적고 있습니다. 서드파티 제출은 다음 단계로 밝혀 둔 계획이며, 개발자 포털도 공개된 SDK도 아직 없습니다.
플러그인 코드는 사용 시점에 플러그인별로 가져오는 것이 아니라 여전히 APK 안에 함께 실려 나갑니다. 알려진 한계이고, 스토어를 프로젝트 바깥에 여는 데 명백히 선행되어야 할 조건입니다.
- 필수 선언
- id · 맡는 업종 · 라벨 · 카탈로그 제목 · 기본 CTA · 카탈로그 뷰
- 선택 선언
- 권한 · 콘솔 타일 · 콘솔 화면 · 손님용 페이지 구획
- 핵심 모듈
- Food · Stay · Service · Retail
- 애드온
- 팀 권한 · 결제 채널 · 멤버십과 구독 · 갱신 알림
- 설치 범위
- 가게 단위
- 삭제
- 데이터가 지워지지 않는다고 적힌 확인 창 뒤
- 서드파티
- 열려 있지 않음 — 자체 제작 애드온만
여기 놓인 확장은 전부 1차 개발입니다. 줄서기나 주차장 같은 모듈도 외부 개발자가 쓴 것이 아니므로, 제3자가 가게 데이터에 닿는 입구 자체가 없습니다.
설치한 뒤 어느 직원에게 보이는지는 내 직장과 같은 사람별 권한이 정합니다.