docs.membloc.com

membloc docs

제품, 플랫폼, 운영 문서를 한곳에서 읽는 Membloc 공식 문서 포털입니다.

Phase 3: Membloc Publisher Portal — 외부 사업체 온보딩

외부 사업체(퍼블리셔)가 모듈을 등록하고, 심사를 거쳐 마켓플레이스에 게시할 수 있는 전체 파이프라인을 구축한다.


1. 목표

  • Publisher 등록/인증 플로우
  • Publisher Dashboard (웹 관리 도구)
  • 모듈 심사 시스템 (Admin)
  • Webhook 시스템
  • Module SDK 문서 사이트
  • API 키 관리

2. 퍼블리셔 온보딩 플로우

사업체 개발자
    │
    ▼
[1] developer.membloc.com 접속
    │
    ▼
[2] Firebase Auth 로그인 (Google/Email)
    │
    ▼
[3] 퍼블리셔 등록 신청
    ├── 사업체명
    ├── 사업자등록번호 (선택)
    ├── 담당자 이메일
    ├── 웹사이트
    └── 개발 목적 설명
    │
    ▼
[4] Membloc 팀 심사 (1~3 영업일)
    ├── 승인 → status: approved
    └── 반려 → 사유 안내 이메일
    │
    ▼
[5] 승인 후 Publisher Dashboard 접근
    ├── 모듈 등록
    ├── API 키 발급
    ├── 버전 관리
    └── 분석 대시보드

3. Publisher Dashboard

3.1 기술 스택

프레임워크: Next.js (App Router)
UI:        Tailwind CSS + shadcn/ui
인증:      Firebase Auth (Google 로그인)
API:       Membloc backend REST API
호스팅:    Vercel 또는 Cloudflare Pages
경로:      developer.membloc.com

3.2 화면 구성

developer.membloc.com
├── / ─────────────────── 랜딩 (문서 + 시작하기)
├── /login ────────────── Firebase Auth 로그인
├── /register ─────────── 퍼블리셔 등록 신청
├── /dashboard ────────── 대시보드 홈
│   ├── 총 설치 수
│   ├── 활성 모듈 수
│   ├── 평균 평점
│   └── 최근 7일 설치 추이 차트
├── /modules ──────────── 내 모듈 목록
│   ├── [생성] 버튼
│   └── 모듈 카드 (상태 배지: draft/review/published)
├── /modules/new ──────── 모듈 생성
│   ├── Step 1: 기본 정보 (name, key, description, category)
│   ├── Step 2: 기술 설정 (type, entry_url, permissions)
│   ├── Step 3: 스크린샷 + 상세 설명
│   └── Step 4: 확인 + 심사 제출
├── /modules/:key ─────── 모듈 상세/수정
│   ├── 기본 정보 편집
│   ├── 버전 관리 탭
│   │   ├── 현재 버전
│   │   ├── 버전 히스토리
│   │   └── [새 버전 제출]
│   ├── 분석 탭
│   │   ├── 일별 설치/해제 차트
│   │   ├── 활성 설치 수
│   │   ├── API 호출 통계
│   │   └── 에러율
│   ├── API 키 탭
│   │   ├── 키 목록
│   │   ├── [발급] / [폐기]
│   │   └── 마지막 사용 시간
│   └── Webhook 탭
│       ├── 등록된 이벤트
│       ├── [추가] / [삭제]
│       └── 발송 로그
├── /docs ─────────────── SDK 문서 (임베디드)
└── /settings ─────────── 퍼블리셔 설정
    ├── 프로필 수정
    ├── 팀 멤버 관리
    └── 알림 설정

3.3 모듈 생성 플로우 상세

Step 1: 기본 정보

필드타입필수설명
Module KeytextO역도메인 형식 (com.company.module-name)
Display NametextO한국어 모듈명 (최대 30자)
DescriptiontextO한 줄 설명 (최대 100자)
Long Descriptionmarkdown-상세 설명
CategoryselectO카테고리 선택
Tagschips-검색용 태그 (최대 5개)

Step 2: 기술 설정

필드타입필수설명
Module TyperadioOWebView / Server
Entry URLurlWebView만모듈 진입 URL
PermissionscheckboxO요청할 권한 목록
Min Membloc Versionsemver-최소 앱 버전
Settings SchemaJSON editor-모듈 설정 스키마
Webhook Eventscheckbox-구독할 이벤트

Step 3: 에셋

필드타입필수설명
Iconimage uploadO512x512 PNG
Screenshotsimage uploadO최소 2장, 최대 8장
Privacy Policy URLurlO개인정보처리방침
Support URLurlO고객지원 페이지

4. 심사 시스템

4.1 심사 기준

카테고리체크 항목
기능entry_url 접근 가능, 주요 기능 정상 동작
보안HTTPS 필수, 불필요한 권한 요청 없음, 데이터 수집 범위 적정
콘텐츠불법/유해 콘텐츠 없음, 광고 과다 아님
UXMembloc 앱 내에서 자연스러운 UI, 로딩 속도 5초 이내
메타데이터스크린샷과 실제 화면 일치, 설명 정확
개인정보privacy_policy_url 유효, 수집 항목 명시

4.2 심사 상태 흐름

draft ──[제출]──▶ review ──[승인]──▶ published
                    │                    │
                    │ [반려]             │ [정지]
                    ▼                    ▼
                 rejected           suspended
                    │                    │
                    │ [재제출]           │ [해제]
                    ▼                    ▼
                 review              published

4.3 Admin Dashboard

Membloc 팀이 심사에 사용하는 내부 도구.

admin.membloc.com (또는 developer.membloc.com/admin)
├── /admin/reviews ──────── 심사 대기 목록
│   ├── 모듈별 상세 보기
│   │   ├── manifest 내용
│   │   ├── 스크린샷
│   │   ├── entry_url 프리뷰 (iframe)
│   │   ├── 요청 권한 목록
│   │   └── 퍼블리셔 정보
│   ├── [승인] + 코멘트
│   └── [반려] + 사유
├── /admin/modules ──────── 전체 모듈 관리
│   ├── 상태별 필터
│   ├── [정지] / [해제]
│   └── 강제 버전 롤백
├── /admin/publishers ───── 퍼블리셔 관리
│   ├── 승인 대기 목록
│   ├── [승인] / [반려]
│   └── [정지]
└── /admin/stats ────────── 플랫폼 통계
    ├── 총 모듈 수 / 퍼블리셔 수
    ├── 일별 설치 추이
    └── 카테고리별 분포

5. 백엔드 확장

5.1 데이터베이스 마이그레이션

migrations/005_publisher_portal.up.sql

-- 퍼블리셔 팀 멤버
CREATE TABLE publisher_members (
    id              TEXT PRIMARY KEY DEFAULT gen_random_uuid()::text,
    publisher_id    TEXT NOT NULL REFERENCES publishers(id) ON DELETE CASCADE,
    firebase_uid    TEXT NOT NULL,
    email           TEXT NOT NULL,
    role            TEXT NOT NULL DEFAULT 'member'
                    CHECK (role IN ('owner','admin','member')),
    invited_at      TIMESTAMPTZ NOT NULL DEFAULT now(),
    accepted_at     TIMESTAMPTZ,
    UNIQUE(publisher_id, firebase_uid)
);

-- 모듈 스크린샷
CREATE TABLE module_screenshots (
    id          TEXT PRIMARY KEY DEFAULT gen_random_uuid()::text,
    module_id   TEXT NOT NULL REFERENCES modules(id) ON DELETE CASCADE,
    image_url   TEXT NOT NULL,
    sort_order  INTEGER NOT NULL DEFAULT 0,
    caption     TEXT
);

-- 심사 로그
CREATE TABLE module_review_logs (
    id          TEXT PRIMARY KEY DEFAULT gen_random_uuid()::text,
    module_id   TEXT NOT NULL REFERENCES modules(id),
    version_id  TEXT REFERENCES module_versions(id),
    reviewer_uid TEXT NOT NULL,
    action      TEXT NOT NULL CHECK (action IN ('submitted','approved','rejected','suspended','unsuspended')),
    comment     TEXT,
    created_at  TIMESTAMPTZ NOT NULL DEFAULT now()
);

-- Webhook 구독
CREATE TABLE module_webhooks (
    id          TEXT PRIMARY KEY DEFAULT gen_random_uuid()::text,
    module_key  TEXT NOT NULL,
    event_type  TEXT NOT NULL,
    target_url  TEXT NOT NULL,
    secret      TEXT NOT NULL,
    status      TEXT NOT NULL DEFAULT 'active'
                CHECK (status IN ('active','disabled')),
    failure_count INTEGER NOT NULL DEFAULT 0,
    last_triggered_at TIMESTAMPTZ,
    created_at  TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE INDEX idx_webhooks_module ON module_webhooks(module_key);
CREATE INDEX idx_webhooks_event ON module_webhooks(module_key, event_type);

-- Webhook 발송 로그
CREATE TABLE webhook_delivery_logs (
    id              TEXT PRIMARY KEY DEFAULT gen_random_uuid()::text,
    webhook_id      TEXT NOT NULL REFERENCES module_webhooks(id),
    event_type      TEXT NOT NULL,
    payload         JSONB NOT NULL,
    response_status INTEGER,
    response_body   TEXT,
    delivered_at    TIMESTAMPTZ NOT NULL DEFAULT now()
);

-- 모듈 일별 통계
CREATE TABLE module_daily_stats (
    module_key  TEXT NOT NULL,
    stat_date   DATE NOT NULL,
    installs    INTEGER NOT NULL DEFAULT 0,
    uninstalls  INTEGER NOT NULL DEFAULT 0,
    api_calls   INTEGER NOT NULL DEFAULT 0,
    errors      INTEGER NOT NULL DEFAULT 0,
    PRIMARY KEY (module_key, stat_date)
);

5.2 새로운 API 엔드포인트

# === Publisher API ===
# 인증: Firebase Auth (퍼블리셔 계정)

POST   /api/publisher/register                     # 퍼블리셔 등록 신청
GET    /api/publisher/profile                      # 내 퍼블리셔 정보
PUT    /api/publisher/profile                      # 프로필 수정

# 팀 관리
GET    /api/publisher/members                      # 팀 멤버 목록
POST   /api/publisher/members/invite               # 멤버 초대
DELETE /api/publisher/members/:uid                  # 멤버 제거

# 모듈 관리
GET    /api/publisher/modules                      # 내 모듈 목록
POST   /api/publisher/modules                      # 모듈 생성 (draft)
PUT    /api/publisher/modules/:key                  # 모듈 수정
DELETE /api/publisher/modules/:key                  # 모듈 삭제 (draft만)
POST   /api/publisher/modules/:key/submit           # 심사 제출

# 버전
GET    /api/publisher/modules/:key/versions         # 버전 목록
POST   /api/publisher/modules/:key/versions         # 새 버전 제출
GET    /api/publisher/modules/:key/versions/:ver     # 버전 상세

# API 키
GET    /api/publisher/modules/:key/api-keys         # 키 목록
POST   /api/publisher/modules/:key/api-keys         # 키 발급
DELETE /api/publisher/modules/:key/api-keys/:id      # 키 폐기

# Webhook
GET    /api/publisher/modules/:key/webhooks         # 구독 목록
POST   /api/publisher/modules/:key/webhooks         # 구독 추가
DELETE /api/publisher/modules/:key/webhooks/:id      # 구독 삭제
GET    /api/publisher/modules/:key/webhooks/:id/logs # 발송 로그

# 분석
GET    /api/publisher/modules/:key/analytics         # 통계 요약
GET    /api/publisher/modules/:key/analytics/daily   # 일별 통계
       ?from=2026-03-01&to=2026-04-01

# === Admin API ===
# 인증: Firebase Auth (Membloc 팀 — admin role)

GET    /api/admin/publishers/pending                # 승인 대기 퍼블리셔
POST   /api/admin/publishers/:id/approve            # 퍼블리셔 승인
POST   /api/admin/publishers/:id/reject             # 퍼블리셔 반려

GET    /api/admin/modules/pending                   # 심사 대기 모듈
POST   /api/admin/modules/:key/approve              # 모듈 승인
POST   /api/admin/modules/:key/reject               # 모듈 반려
POST   /api/admin/modules/:key/suspend              # 모듈 정지
POST   /api/admin/modules/:key/unsuspend            # 모듈 정지 해제

GET    /api/admin/stats                             # 플랫폼 통계

5.3 Webhook 시스템

지원 이벤트:

이벤트트리거 시점
module.installed가족이 모듈을 설치했을 때
module.uninstalled가족이 모듈을 제거했을 때
module.settings_changed모듈 설정이 변경됐을 때
family.member_joined가족에 새 멤버가 추가됐을 때
family.member_left가족에서 멤버가 나갔을 때

발송 프로토콜:

POST {target_url}
Content-Type: application/json
X-Membloc-Signature: sha256={HMAC-SHA256(payload, secret)}
X-Membloc-Event: module.installed
X-Membloc-Delivery: {delivery_id}

{
  "event": "module.installed",
  "timestamp": "2026-04-10T12:00:00Z",
  "data": {
    "moduleKey": "com.example.budget",
    "familyId": "fam_xxx",
    "installedBy": "uid_xxx",
    "version": "1.2.0"
  }
}

X-Membloc-*를 primary로 문서화하고, alias 기간 동안 X-Homb-*도 함께 송신한다.

재시도 정책:

  • 실패 시 3회 재시도 (10초, 60초, 300초 간격)
  • 연속 10회 실패 → webhook status를 disabled로 변경
  • 퍼블리셔에게 이메일 알림

5.4 백엔드 파일 구조 추가

internal/
├── handler/
│   ├── publisher.go            # [신규] 퍼블리셔 CRUD
│   ├── publisher_module.go     # [신규] 퍼블리셔의 모듈 관리
│   ├── admin.go                # [신규] Admin 심사/관리
│   └── webhook.go              # [신규] Webhook 관리
├── model/
│   ├── publisher_member.go     # [신규]
│   ├── review_log.go           # [신규]
│   ├── webhook.go              # [신규]
│   └── daily_stats.go          # [신규]
├── repository/
│   ├── publisher.go            # [신규]
│   ├── review_log.go           # [신규]
│   ├── webhook.go              # [신규]
│   └── daily_stats.go          # [신규]
├── service/
│   ├── publisher.go            # [신규]
│   ├── review.go               # [신규]
│   ├── webhook_dispatcher.go   # [신규] 이벤트 발생 시 webhook 발송
│   └── analytics.go            # [신규]
├── auth/
│   └── admin_middleware.go     # [신규] admin role 체크

6. SDK 문서 사이트

6.1 호스팅

docs.membloc.com 또는 developer.membloc.com/docs

6.2 문서 구조

시작하기
├── 퍼블리셔 등록
├── 첫 모듈 만들기 (튜토리얼)
└── 개발 환경 설정

모듈 타입
├── WebView 모듈
│   ├── 구조
│   ├── JS Bridge SDK
│   └── 로컬 개발 & 테스트
└── Server 모듈
    ├── REST API
    ├── Webhook
    └── API 키 관리

JS Bridge API 레퍼런스
├── homb.auth
├── homb.family
├── homb.data
├── homb.storage
├── homb.notifications
├── homb.activity
├── homb.ui
└── homb.settings

REST API 레퍼런스
├── 인증
├── 모듈 데이터 CRUD
├── 액티비티
└── 알림

가이드
├── 권한 모델
├── 데이터 샌드박싱
├── 에러 처리
├── Rate Limiting
└── 심사 가이드라인

변경 로그

6.3 기술 스택

VitePress 또는 Docusaurus
Markdown + OpenAPI spec
코드 예제: TypeScript (WebView), cURL (REST)

7. 작업 목록

7.1 백엔드

#작업의존성예상
B1005_publisher_portal.up.sql 마이그레이션Phase 2 완료0.5d
B2Publisher CRUD (model, repo, service, handler)B12d
B3Publisher 인증 미들웨어 (Firebase UID → publisher 매핑)B20.5d
B4Publisher 모듈 관리 APIB32d
B5버전 관리 APIB41d
B6Admin 미들웨어 + 심사 APIB12d
B7심사 로그 기록B60.5d
B8API 키 발급/검증/폐기B11d
B9Webhook 등록/삭제 APIB11d
B10Webhook dispatcher (비동기 발송 + 재시도)B92d
B11모듈 설치/제거 시 webhook 트리거 연동B100.5d
B12일별 통계 집계 (cron 또는 트리거)B11d
B13분석 APIB120.5d
B14스크린샷 업로드 (Firebase Storage 연동)-1d

7.2 Publisher Dashboard (웹)

#작업의존성예상
W1Next.js 프로젝트 scaffolding + Firebase Auth-0.5d
W2로그인 / 퍼블리셔 등록 페이지W1, B21d
W3대시보드 홈 (통계 카드 + 차트)W1, B131d
W4모듈 목록 페이지W1, B40.5d
W5모듈 생성 위저드 (4 step)W1, B42d
W6모듈 상세/수정 페이지W51d
W7버전 관리 탭W6, B51d
W8API 키 관리 탭W6, B80.5d
W9Webhook 관리 탭W6, B91d
W10분석 탭 (차트)W6, B131d
W11Admin 심사 페이지W1, B61.5d
W12Admin 퍼블리셔 관리W1, B60.5d

7.3 SDK 문서

#작업예상
D1VitePress 프로젝트 셋업0.5d
D2시작하기 가이드1d
D3JS Bridge API 레퍼런스1d
D4REST API 레퍼런스 (OpenAPI)1d
D5튜토리얼: 첫 WebView 모듈 만들기1d
D6권한 / 샌드박싱 / Rate Limiting 가이드0.5d
D7심사 가이드라인0.5d

8. 완료 기준

  • 외부 개발자가 developer.membloc.com에서 퍼블리셔 등록 가능
  • 퍼블리셔가 모듈을 생성하고 심사에 제출 가능
  • Membloc 팀이 Admin에서 모듈을 승인/반려 가능
  • 승인된 모듈이 마켓플레이스에 자동 게시
  • API 키 발급 후 Server Module이 Runtime API 호출 가능
  • Webhook 등록 후 모듈 설치 시 이벤트 수신 확인
  • 퍼블리셔 대시보드에서 설치 통계 확인 가능
  • SDK 문서 사이트에서 API 레퍼런스 열람 가능