MyGo 云音乐
Go와 MyGo로 만든 서드파티 네이버 클라우드 뮤직 데스크톱 클라이언트
A Guide and Helper for Quick Preparations Before Worship
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗ ╔═══════════════════════════════════════════════════╗
║ ║
║ ( ˶ˆᗜˆ˵ ) ✝ easyPreparation ║
║ ║
║ 매주 예배 준비... 이제 쉽게 해요! ║
║ ║
╚═══════════════════════════════════════════════════╝
교회 주보 · 가사 PPT · 예배 화면 자동화 플랫폼 ✝️
🏠 홈페이지 · 📥 다운로드 · 💳 요금제 · 🚀 릴리즈
┌─────────────────────────────────────────────────────────────────┐
│ │
│ 📄 주보 PDF 🎵 가사 PPT 📖 성경 검색 │
│ 인쇄용 + 발표용 bugs.co.kr 연동 7개 번역판 지원 │
│ │
│ 🎬 OBS 연동 📱 모바일 리모컨 ⏰ 자동 스케줄러 │
│ 씬 전환 + 송출 PWA 스마트폰 예배 시간 자동 감지 │
│ │
│ 🎼 찬송가 검색 📺 예배 화면 💾 Desktop 앱 │
│ 645곡 DB 기반 실시간 슬라이드 Wails v2 macOS │
│ │
└─────────────────────────────────────────────────────────────────┘
flowchart TD
subgraph Client["Client — 단일 Next.js 앱 (ui/) 의 페이지들"]
UI_B["/bulletin\n주보 편집"]
UI_L["/lyrics\n가사 PPT · 찬송가"]
UI_BIBLE["/bible\n성경 검색"]
DISPLAY["Display\n(OBS Browser Source / 별도 창)"]
MOBILE["Mobile PWA\n(스마트폰 리모컨)"]
end
subgraph Desktop["Desktop App (Wails v2)"]
WAILS["Wails WebView\n→ localhost:8080"]
end
subgraph Server["Go API Server :8080"]
WS["/ws\nWebSocket"]
SUB["/submit"]
SUB_L["/submitLyrics"]
SEARCH["/searchLyrics"]
DL["/download"]
DISP["/display/*\nDisplay API"]
SCHED["Scheduler\n자동 스케줄러"]
LICENSE["License\n기능 게이팅"]
VERSION["Version\n자동 업데이트 체크"]
end
subgraph Bulletin["Bulletin Pipeline"]
B_QUOTE["Quote\n성경 구절 조회"]
B_PRINT["bulletin.go\n인쇄용 PDF"]
B_PRES["forPresentation\n프레젠테이션 PDF"]
end
subgraph Lyrics["Lyrics Pipeline"]
L_CRAWL["Parser\n가사 크롤링"]
L_PDF["Lyrics PDF\n슬라이드 생성"]
end
subgraph Ext["External Services"]
R2["Oracle Cloud nginx\n찬송가 · 성시교독 PDF/PNG (로컬 캐시)"]
BUGS["bugs.co.kr\n가사 검색"]
OBS["OBS WebSocket\n씬 전환 + 스트리밍"]
PTZ["PTZ 카메라\n프리셋 이동 (HTTP)"]
SQLITE[("SQLite\n성경 DB + 찬송가 + 설정")]
YOUTUBE["YouTube API\n라이브 방송 + 썸네일"]
GITHUB["GitHub Releases\n자동 업데이트 체크"]
end
subgraph Output["output/"]
OUT_BP["bulletin/print/*.pdf"]
OUT_BPR["bulletin/presentation/*.pdf"]
OUT_L["lyrics/*.pdf"]
end
UI_B -->|POST| SUB
UI_L -->|POST| SUB_L
UI_L -->|POST| SEARCH
UI_B -->|GET| DL
UI_B -->|POST /display/order| DISP
UI_L -->|POST /display/append| DISP
UI_BIBLE -->|POST /display/append| DISP
MOBILE -->|WS + REST| Server
WAILS -->|WebView| Server
Server -->|progress| WS
WS -.->|실시간 알림| Client
DISP -.->|슬라이드 제어| DISPLAY
SCHED -->|T-0 순서 로드| DISP
SCHED -->|스트리밍 시작| OBS
SCHED -.->|카운트다운| WS
LICENSE -->|기능 차단 403| Server
VERSION -->|최신 버전 조회| GITHUB
SUB --> B_QUOTE
B_QUOTE --> SQLITE
SUB --> B_PRINT
SUB --> B_PRES
B_PRINT --> R2
B_PRES --> R2
B_PRINT --> OUT_BP
B_PRES --> OUT_BPR
SEARCH --> L_CRAWL
L_CRAWL --> BUGS
SUB_L --> L_PDF
L_PDF --> OUT_L
DL -->|ZIP| OUT_BP
DL -->|ZIP| OUT_BPR
DISP --> OBS
DISP -->|항목 점프 시 프리셋| PTZ
Server --> YOUTUBE
| 기능 | 설명 | 플랜 |
|---|---|---|
| 📄 주보 생성 | 인쇄용(A4) + 프레젠테이션용 PDF 자동 생성 | Free |
| ✏️ 주보 편집 | 예배 순서 드래그 앤 드롭, 성경 구절 선택, 교회 소식 트리 편집 | Free |
| 🎵 가사 PPT 생성 | 곡명 입력 → 가사 자동 검색(bugs.co.kr) → 중복 제거 → ZIP | Free |
| 🎼 찬송가 검색 | 645곡 새찬송가 번호/제목/가사 검색, Display 전송 | Free |
| 📖 성경 검색 | 구약/신약 탭, 장/절 선택, 7개 번역판, 비교 모드(2컬럼) | Free |
| 🖥️ 예배 화면 | OBS Browser Source 연동, 성경/찬송/교독/가사 슬라이드 | Free |
| 🎛️ Display 제어 | append 방식 항목 추가, 제어판에서 삭제/점프/자동 넘김 | Free |
| ⚡ 실시간 상태 | WebSocket 파일 생성 진행 + Display 위치 브로드캐스트 | Free |
| 💾 Desktop 앱 | Wails v2 macOS .app — 서버 내장, 별도 설치 없이 실행 | Free |
| 📱 모바일 PWA | /mobile — 스마트폰으로 슬라이드 next/prev 리모컨 제어 | Free |
| 🧙 초기 설정 위저드 | 첫 실행 시 교회명(한글/영문) 입력, 간편 온보딩 | Free |
| 🔔 자동 업데이트 알림 | GitHub Releases → 새 버전 발견 시 헤더 배너 표시 | Free |
| 🎥 PTZ 카메라 제어 | 항목별 프리셋 매핑(config/obs.json presets) → Display 점프 시 자동 이동, 스트림 프리뷰·수동 이동 (/api/ptz/*) | Free |
| 🔑 라이선스 시스템 | Free / Pro / Enterprise, FeatureGate로 기능 게이팅 | — |
| 📡 OBS 통합 제어 | 씬 전환 + 스트리밍 시작/종료 + 상태 모니터링 | Pro |
| ⏰ 자동 스케줄러 | 예배 시간 자동 감지 → 카운트다운 → OBS 스트리밍 시작 | Pro |
주보 편집 화면 — 예배 순서 선택 → 항목 편집 → 미리보기
┌────────┬──────────────────────────────────────────────┐
│ │ TopHeader [교회명] │
│ Left ├──────────────┬────────────┬─────────────────┤
│ Side │ 예배 순서 │ 선택 순서 │ 생성된 내용 │
│ bar │ 선택하기 │ │ │
│ │ ────────── │ [전주] │ 전주 │
│ [주보] │ [전주] │ [예배부름] │ 예배의 부름 │
│ [찬양] │ [예배부름] │ [찬송] │ 찬송 27장 │
│ [성경] │ [찬송] │ [교독] ... │ 성시교독 31편 │
│ │ [성경봉독] │ ────────── │ ... │
│ [설정] │ ... │ [상세편집] │ │
└────────┴──────────────┴────────────┴─────────────────┘
easyPreparation은 콘텐츠 · 타이밍 · 제어를 담당하고, OBS는 인코딩 · 합성 · 송출만 담당합니다.
┌─ easyPreparation (두뇌) ─────────────────┐ ┌─ OBS Studio (근육) ──────────┐
│ │ │ │
│ 스케줄러 │ │ │
│ ├─ 예배 시간 자동 감지 │ │ │
│ ├─ T-N분: 카운트다운 시작 ──────┼──ws──┼→ 씬 전환 │
│ └─ T-0초: 순서 로드 + 스트리밍 ──────┼──ws──┼→ 스트리밍 시작/종료 │
│ │ │ │
│ Display 렌더링 │ │ ┌──────────────────────┐ │
│ ├─ /display (프로젝터용) ◀─────┼──────┼── │ Browser Source #1 │ │
│ ├─ /display/overlay (방송 자막) ◀─────┼──────┼── │ Browser Source #2 │ │
│ └─ 카운트다운 오버레이 │ │ └──────────────────────┘ │
│ │ │ │
│ 제어판 │ │ 카메라 입력 │
│ ├─ 항목 점프 / 드래그 재배치 │ │ 오디오 믹싱 │
│ ├─ LIVE 뱃지 + 수동 방송 시작/종료 │ │ 씬 합성 + 트랜지션 │
│ └─ 카운트다운 배너 │ │ RTMP 인코딩 + 송출 │
│ │ │ │
└───────────────────────────────────────────┘ └──────────────────────────────┘
│ │
└─────────────── WebSocket (goobs) ──────────────────┘
| 자체 구현 시 | OBS 활용 시 |
|---|---|
| RTMP 인코딩, 오디오 믹싱, 하드웨어 가속 직접 구현 | 10년+ 검증된 인코딩 파이프라인 |
| 카메라 + 마이크 + 화면 합성 = 수개월 작업 | 이미 완성된 씬 합성 시스템 |
| 실시간 방송 안정성 보장 어려움 | 전 세계 방송에서 검증됨 |
sequenceDiagram
participant S as 스케줄러
participant D as Display / Overlay
participant C as 제어판
participant O as OBS
Note over S: 예배 시간 N분 전
loop 매초 카운트다운
S->>D: schedule_countdown (WS)
S->>C: schedule_countdown (WS)
D-->>D: 카운트다운 오버레이 표시
C-->>C: 빨간 배너 MM:SS
end
Note over S: 예배 시간 도달 (T-0)
S->>S: config/{worshipType}.json 로드
S->>D: order (WS) — 예배 순서 교체
S->>O: StartStream (goobs)
S->>O: SwitchScene (goobs)
S->>C: schedule_started (WS)
D-->>D: 카운트다운 해제 → 첫 슬라이드
C-->>C: 카운트다운 해제 → LIVE 뱃지
https://obsproject.com 에서 운영체제에 맞는 버전을 다운로드합니다.
OBS 28 이상 권장 — WebSocket 서버가 내장되어 별도 플러그인 불필요
OBS 메뉴 → 도구(Tools) → WebSocket 서버 설정
| 항목 | 값 |
|---|---|
| WebSocket 서버 활성화 | ✅ 체크 |
| 서버 포트 | 4455 (기본값) |
| 인증 활성화 | 선택 — 활성화 시 비밀번호 설정 |
config/obs.json 작성{
"host": "localhost:4455",
"password": "your_password_here",
"scenes": {
"찬송": "camera",
"기도": "camera",
"말씀": "camera",
"성경": "monitor",
"교독문": "monitor"
},
"cameraScene": "camera",
"displayScene": "monitor",
"fadeMs": 800,
"fadeDelaySec": 3
}
config/obs.json이 없으면 OBS 연동 전체 비활성(에러 없음)
| Source | URL | 용도 |
|---|---|---|
| Browser Source #1 | http://localhost:8080/display | 프로젝터 출력 (악보 이미지 포함) |
| Browser Source #2 | http://localhost:8080/display/overlay | 방송 자막 (반투명 배경, 가사/성경) |
easyPreparation/
├── 🚀 cmd/
│ ├── server/ # Go 서버 진입점 (:8080) — app.Initialize() 호출
│ │ └── main.go
│ └── desktop/ # Wails v2 Desktop 앱 진입점 — 같은 app.Initialize() 공유
│ ├── main.go # Wails 생명주기 + 헬스체크/롤백 다이얼로그 + 창 표시
│ ├── uibase_dev.go # //go:build dev → WebView 가 Next.js dev(:3000) 로
│ └── uibase_prod.go # //go:build !dev → WebView 가 내장 서버(:8080) 로
│
├── ⚙️ internal/ # Go 백엔드 패키지
│ ├── api/ # HTTP 라우터 (StartServer, StopServer)
│ ├── app/ # 서버·데스크톱 공통 초기화 (DB, 라이선스, OBS, YouTube, 스케줄러, 헬스체크)
│ ├── embedded/ # 서버·데스크톱 공용 embed 자산 — frontend/ (ui/out) + data/ (bible.db, schema.sql, defaults/)
│ │ # `make embed-assets` 가 채움. //go:build dev 에서는 nil (로컬 파일 사용)
│ ├── httpx/ # HTTP 응답 헬퍼 — 모든 API 에러는 {"error": "..."} JSON
│ ├── safefile/ # 설정 JSON 원자적 저장 (임시파일 → 검증 → .backup → rename) + 손상 시 자동 복구
│ ├── path/ # 데이터 루트 결정 (EASYPREP_DATA_DIR → 저장소(dev) → 포터블 → OS 사용자 디렉터리)
│ ├── bulletin/ # 주보 PDF 생성
│ │ ├── bulletin.go # 인쇄용 PDF
│ │ ├── forPresentation/ # 프레젠테이션용 PDF
│ │ ├── define/ # 예배 순서 정의
│ │ └── templates/ # 주보 시안 JSX 템플릿 (브라우저 인쇄)
│ ├── handlers/ # HTTP + WebSocket + Display + 스케줄러 + 방송 시작(broadcast.go) 핸들러
│ ├── ptz/ # PTZ 카메라 제어 (프리셋 이동, 스트림 프록시)
│ ├── license/ # 라이선스 매니저 (Plan/Feature/오프라인 캐시)
│ │ ├── types.go # Plan/Feature 상수, PlanFeatures 맵
│ │ ├── manager.go # 싱글턴 (DB + 파일 캐시 이중 저장)
│ │ ├── offline.go # data/license.json 캐시, 디바이스 ID
│ │ └── keygen.go # 라이선스 키 서명 검증
│ ├── lyrics/ # 가사 PDF 생성
│ ├── middleware/ # CORS + FeatureGate 미들웨어
│ ├── obs/ # OBS WebSocket 매니저 (goobs, 자동 재연결)
│ ├── presentation/ # gofpdf PDF 렌더러 (NFC 정규화)
│ ├── quote/ # 성경 구절 DB 조회 (SQLite, 다중 버전)
│ ├── selfupdate/ # GitHub Releases API 업데이트 체커
│ ├── thumbnail/ # YouTube 썸네일 생성
│ ├── assets/ # PDF/PNG 에셋 다운로더 (Oracle Cloud nginx `AssetBaseURL` + data/cache 로컬 캐시)
│ └── youtube/ # YouTube OAuth + 라이브 방송 + 썸네일 업로드
│
├── 🎨 ui/ # Next.js 프론트엔드 (Tailwind CSS v3)
│ ├── tailwind.config.ts # Stitch 디자인 토큰
│ └── app/
│ ├── bulletin/ # 주보 편집 페이지
│ │ └── components/
│ │ ├── WorshipOrder.tsx
│ │ ├── SelectedOrder.tsx
│ │ ├── Detail.tsx, BibleSelect.tsx
│ │ ├── ResultPage.tsx
│ │ └── DisplayControlPanel.tsx
│ ├── lyrics/ # 가사 PPT 생성 + 찬송가 검색
│ │ └── components/
│ │ ├── LyricsManager.tsx
│ │ └── HymnSearch.tsx
│ ├── bible/ # 성경 검색 (7개 번역판, 비교 모드)
│ ├── components/ # 전역 컴포넌트
│ │ ├── AppShell.tsx # CSS Grid 루트 레이아웃
│ │ ├── LeftSidebar.tsx # 좌측 수직 네비게이션
│ │ ├── TopHeader.tsx # 상단 페이지 헤더
│ │ ├── SetupWizard.tsx # 첫 실행 교회 정보 입력
│ │ ├── LicensePanel.tsx # 라이선스 키 입력 + 상태
│ │ ├── SchedulePanel.tsx # 스케줄 설정 모달
│ │ ├── OBSSourcePanel.tsx # OBS 소스 관리
│ │ ├── YouTubePanel.tsx # YouTube 연동 + 방송 생성
│ │ └── UpdateChecker.tsx # 자동 업데이트 배너
│ └── lib/
│ ├── apiClient.ts # Go 서버 API 호출 중앙화
│ ├── LocalAuthContext.tsx # 로컬 인증 Context
│ └── LicenseContext.tsx # 라이선스 상태 전역 Context
│
├── 🌐 landing/ # 홍보 랜딩 페이지 (Next.js 14, Vercel 배포)
├── ☁️ workers/license-api/ # CF Workers 라이선스 API 서버 (Hono + 토스페이먼츠) — 에셋 서빙 아님
├── 🔧 tools/ # Go 유틸 스크립트 (찬송 크롤러, DB 마이그레이션) — PostgreSQL 접속은 PG_DSN 또는 config/db.json "dsn"
├── 📦 config/ # 설정 파일 (gitignore) + 예배 순서 config/{type}.json
├── 💾 data/ # SQLite DB, PDF/PNG 캐시, 상태 파일 (*.backup = safefile 롤백 사본, gitignore)
│ ├── schema.sql # 앱 DB 자동 초기화 스키마 (embed 에 포함, 첫 실행 시 적용)
│ ├── easyprep.db # 앱 DB (churches, licenses, custom_songs …) — 첫 실행 시 생성
│ ├── bible.db # 성경·찬송가 DB (embed 에서 추출)
│ ├── church_info.json # 교회 정보 (설정 화면에서 저장, 런타임 데이터 — git 미추적)
│ ├── display_state.json # Display 상태 영속화
│ ├── schedule.json # 스케줄 설정 영속화
│ └── license.json # 라이선스 캐시 (권한 0600)
├── 📂 output/ # 생성된 PDF 출력
└── Makefile
RecoilProvider
└─ LocalAuthProvider (교회 설정 상태, SetupWizard 트리거)
└─ LicenseProvider (라이선스 플랜, FeatureGate)
└─ WebSocketProvider
└─ AppShell (CSS Grid)
├─ LeftSidebar (좌측 네비)
├─ TopHeader (상단 헤더)
├─ { children }
└─ GlobalDisplayPanel (조건부)
| 토큰 | 값 |
|---|---|
| 폰트 | Inter (Google Fonts) + Material Symbols Outlined |
| 액센트 | electric-blue #3B82F6 |
| 카드 | bg-white rounded-2xl border-slate-100 shadow-sm |
worshipOrderState // Record<WorshipType, WorshipOrderItem[]> 예배 순서 전체
selectedDetailState // WorshipOrderItem 현재 편집 항목
userInfoState // UserChurchInfo 교회 정보
userSettingsState // UserSettings 선호 설정
displayPanelOpenState // boolean 제어판 열림 여부
displayItemsState // WorshipOrderItem[] Display 항목 목록
lyricsSongsState // LyricsSong[] 가사 곡 목록
apiClient.startDisplay(items) // POST /display/order (전체 교체)
apiClient.appendToDisplay(items) // POST /display/append (추가)
apiClient.removeFromDisplay(index) // POST /display/remove (삭제)
apiClient.jumpDisplay(index, subPage?) // POST /display/jump
apiClient.navigateDisplay(direction) // POST /display/navigate
apiClient.getDisplayStatus() // GET /display/status
apiClient.getSchedule() // GET /api/schedule
apiClient.saveSchedule(config) // POST /api/schedule
openDisplayWindow() // Display 창 열기 (중복 reload 방지)
# Go 1.25+ (go.mod 기준)
# Node.js 22+ (npm)
# Ghostscript (PDF → PNG 변환)
# macOS
brew install ghostscript
# Ubuntu / Debian
apt install ghostscript
config/ 디렉토리에 배치 (git 미포함):
| 파일 | 용도 | 필수 여부 |
|---|---|---|
db.json | {"path": "..."} 앱 SQLite 파일 경로 (없으면 data/easyprep.db). "dsn" 키는 tools/ 스크립트 전용 PostgreSQL 접속 문자열 | 선택 |
google_oauth.json | YouTube OAuth Client ID/Secret | Pro 전용 |
obs.json | OBS WebSocket 씬 매핑 + PTZ 프리셋(presets) (없으면 OBS 비활성) | Pro 전용 |
custom.json | PDF 크기 / 폰트 / 색상 설정 | 선택 |
{type}_worship.json | 예배 순서 (main/after/wed/fri). 없으면 embed 기본 템플릿이 첫 실행 시 생성됨 | 자동 생성 |
SQLite 자동 초기화:
config/db.json이 없어도 서버 시작 시data/easyprep.db에 자동 스키마 적용. 별도 DB 서버 없이 바로 실행 가능합니다.
# ui/.env.local (기본값: http://localhost:8080)
NEXT_PUBLIC_API_BASE_URL=http://localhost:8080
# Go 서버
EASYPREP_DATA_DIR=/path/to/data-root # 데이터 루트 강제 지정 (config/, data/, logs/ 가 이 아래에 생성). 테스트·다중 인스턴스용
EASYPREP_DEV=true # 개발 모드 판정 강제 (make dev 가 설정) — 저장소 루트를 데이터 루트로 사용
DB_PATH=/path/to/easyprep.db # 앱 DB 파일 경로 (config/db.json 보다 우선)
# tools/ 스크립트 (찬송 크롤러 등)
PG_DSN=postgres://user:pass@host:5432/bible_db?sslmode=disable # 없으면 config/db.json 의 "dsn"
데이터 루트 결정 순서(
internal/path):EASYPREP_DATA_DIR→ 개발 모드(저장소 루트) → 포터블(실행 파일 옆easyPreparation/) → OS 사용자 디렉터리(%APPDATA%\easyPreparation,~/Library/Application Support/easyPreparation,~/.config/easyPreparation). 빌드된 바이너리를 저장소 폴더 안에서 실행하면 개발 모드로 판정되어 저장소 데이터를 쓰니, 배포 동작 테스트는 저장소 밖에서 실행할 것.
# 개발 (Go + Next.js 동시)
make dev
# 개별 실행
go run -tags dev ./cmd/server/ # Go 서버 :8080
cd ui && npm install && npm run dev # Next.js :3000
# 프로덕션 빌드
make build # bin/server (프론트엔드 내장 단독 실행 파일)
# Desktop 앱 빌드 (macOS — Wails v2)
make build-desktop # → cmd/desktop/build/bin/easyPreparation.app
make dev-desktop # Desktop 개발 모드
서버는 0.0.0.0:8080에서 실행됩니다.
에러 응답 규칙: 모든 API 에러는 상태코드와 함께
{"error": "<message>"}JSON 으로 반환됩니다(internal/httpx). 프론트는 상태코드와 무관하게body.error를 읽으면 됩니다. 기능 게이트 차단은403 {"error": "feature_locked", ...}.
| Method | Path | 설명 |
|---|---|---|
WS | /ws | WebSocket (진행 상황 + Display 제어 + 카운트다운) |
POST | /submit | 주보 생성 요청 |
POST | /submitLyrics | 가사 PDF 생성 → ZIP 응답 |
POST | /searchLyrics | 가사 검색 (bugs.co.kr) |
GET | /download?target=<name> | 주보 PDF ZIP 다운로드 |
| Method | Path | 설명 |
|---|---|---|
GET | /display | 예배 슬라이드 HTML (프로젝터용) |
GET | /display/overlay | 텍스트 오버레이 HTML (방송용, 반투명 배경) |
POST | /display/order | 예배 순서 전송 — 전체 교체 |
POST | /display/append | 항목 추가 |
POST | /display/remove | 항목 삭제 (인덱스 기반) |
POST | /display/reorder | 드래그 앤 드롭 순서 변경 |
POST | /display/navigate | 슬라이드 이동 (next/prev) |
POST | /display/jump | 특정 항목으로 점프 (subPageIdx 지원) |
POST | /display/timer | 자동 넘김 타이머 제어 |
GET | /display/status | 현재 상태 (items, idx, OBS, stream) |
| Method | Path | 설명 |
|---|---|---|
GET | /api/bible/books | 성경 구조 (책/장/절) |
GET | /api/bible/versions | 성경 번역본 목록 |
GET | /api/bible/verses | 성경 구절 조회 |
GET | /api/bible/search | 성경 구절 검색 |
GET | /api/hymns/search | 찬송가 검색 (번호/제목/가사) |
GET | /api/hymns/detail | 찬송가 상세 (가사 포함) |
| Method | Path | 설명 |
|---|---|---|
GET | /api/setup/status | 초기 설정 여부 |
POST | /api/setup | 교회 정보 저장 |
GET/POST | /api/user | 교회/사용자 정보 조회/수정 |
GET/PUT | /api/settings | 사용자 설정 조회/저장 |
GET | /api/history | 생성 이력 조회 |
GET/PUT | /api/worship-order | 예배 순서 조회/저장 |
| Method | Path | 설명 |
|---|---|---|
GET | /api/license | 현재 라이선스 상태 |
POST | /api/license/activate | 라이선스 키 활성화 |
POST | /api/license/deactivate | 라이선스 비활성화 (Free 복귀) |
| Method | Path | 설명 |
|---|---|---|
GET/POST | /api/schedule | 스케줄 설정 조회/저장 |
POST | /api/schedule/test | 테스트 — {action: "countdown"|"trigger"} |
POST | /api/schedule/stream | OBS 스트리밍 수동 제어 |
| Method | Path | 설명 |
|---|---|---|
GET | /api/version | {version, commit, buildTime} |
GET | /api/update/check | GitHub Releases 비교 |
GET | /api/youtube/auth | YouTube OAuth 동의 화면 |
POST | /api/youtube/setup-obs | 방송 생성 + 스트림 키 → OBS 자동 설정 |
POST | /api/thumbnail/generate | 썸네일 생성 (Pro) |
GET | /mobile | 스마트폰 리모컨 PWA |
GET | /mobile/qr.png | QR 코드 (로컬 IP 자동 감지) |
| 기능 | Free | Pro | Enterprise |
|---|---|---|---|
| 주보/가사 PDF 생성 | ✅ | ✅ | ✅ |
| 성경/찬송가 검색 | ✅ | ✅ | ✅ |
| 예배 화면 (Display) | ✅ | ✅ | ✅ |
| Desktop 앱 | ✅ | ✅ | ✅ |
| 모바일 PWA 리모컨 | ✅ | ✅ | ✅ |
| OBS 씬 전환 + 스트리밍 | ✅ | ✅ | |
| 자동 스케줄러 | ✅ | ✅ | |
| YouTube 라이브 연동 | ✅ | ✅ | |
| 썸네일 자동 생성/업로드 | ✅ | ✅ | |
| 다중 예배 유형 | ✅ | ✅ | |
| 클라우드 백업 | ✅ |
// server.go — Pro 기능에 FeatureGate 미들웨어 적용
mux.Handle("/api/schedule", middleware.FeatureGate(license.FeatureAutoScheduler, handlers.ScheduleHandler))
기능이 잠긴 경우 HTTP 403:
{"error": "feature_locked", "feature": "auto_scheduler", "plan": "free",
"message": "이 기능은 Pro 플랜에서 사용할 수 있습니다."}
1. 제어판 → 라이선스 아이콘 → LicensePanel 모달
2. 라이선스 키 입력 → POST /api/license/activate
3. 키 서명 검증 통과 시 Pro 활성화
4. 활성화 정보 → data/license.json 캐시 (DB 없는 환경도 유지)
| 파일 | 트리거 | 동작 |
|---|---|---|
release.yml | v* 태그 push | Server 4플랫폼 + Desktop 3플랫폼 빌드 → GitHub Release |
test.yml | master push + Pull Request | 3 OS go vet/go build/-race 스모크 테스트, integration(dev 빌드 API 테스트), fresh-install(prod 빌드 신규 설치 기동 검증) |
landing.yml | landing/ 변경 PR | 랜딩 페이지 빌드 검증 |
| 아티팩트 | 플랫폼 |
|---|---|
easyPreparation_desktop_darwin_arm64.dmg | macOS ARM Desktop (.dmg 안의 .app) |
easyPreparation_desktop_windows_amd64_setup.exe | Windows Desktop |
easyPreparation_desktop_linux_amd64 | Linux Desktop |
easyPreparation_server_darwin_arm64 | macOS ARM Server |
easyPreparation_server_darwin_amd64 | macOS Intel Server |
easyPreparation_server_linux_amd64 | Linux Server |
easyPreparation_server_windows_amd64.exe | Windows Server |
checksums.txt | SHA256 체크섬 |
파이프라인: build-frontend(1회) → build-server(4플랫폼) + build-desktop(3플랫폼) → release
# 변경사항 커밋 + push
git add -p && git commit -m "feat: ..." && git push
# 태그 생성 + push → GitHub Actions 자동 빌드 + Release 생성
git tag v1.2.0 && git push origin v1.2.0
| 태그 형식 | GitHub Release | 자동업데이트(/api/update/check) |
|---|---|---|
vX.Y.Z | 정식 | 대상 — releases/latest 가 가리킴 → 모든 사용자에게 알림 |
vX.Y.Z-beta.N | prerelease (release.yml 이 -beta 포함 태그를 자동 표시) | 대상 아님 — 릴리즈 페이지 링크로만 배포 |
# 베타 교회에만 배포 → 확인 후 정식 태그
git tag v1.2.0-beta.1 && git push origin v1.2.0-beta.1 # prerelease, latest 는 그대로
git tag v1.2.0 && git push origin v1.2.0 # 정식 → latest 갱신 → 자동업데이트
test.yml의fresh-install잡이 매 push 마다 "prod 빌드 → 빈 디렉터리 기동 → schema 적용 →/api/health200 → graceful 종료" 를 검증하므로, 신규 설치 경로가 깨지면 CI 에서 먼저 실패합니다.
easyPreparation.app
└─ Wails WebView
└─ http://localhost:8080 ←→ Go HTTP 서버 (내장)
└─ cmd/desktop/main.go
└─ internal/api/server.go (동일 라우터)
startup() — DB/OBS/YouTube/스케줄러 초기화 → HTTP 서버 시작 → WindowShowshutdown() — HTTP graceful shutdown(5초) → 스케줄러 중지 → OBS/DB 닫기# macOS 빌드 (필수 CGO_LDFLAGS)
CGO_LDFLAGS="-framework UniformTypeIdentifiers" wails build -o easyPreparation
같은 WiFi: http://{로컬IP}:8080/mobile
QR 코드: http://{로컬IP}:8080/mobile/qr.png
제어판 UI → QR 아이콘 클릭 → 스마트폰으로 스캔 → 예배 슬라이드 next/prev 제어
iOS/Android Chrome에서 홈 화면에 추가하면 전체화면 앱으로 실행됩니다.
예배 순서 JSON의 info 필드 규칙:
| 값 | 설명 | Detail 컴포넌트 동작 |
|---|---|---|
"c_edit" | 찬송번호/제목 편집 | textarea + lead input |
"b_edit" | 성경 구절 편집 | BibleSelect + lead input |
"edit" | 자유 텍스트 편집 | textarea + lead input |
"r_edit" | lead만 편집 (obj 자동) | lead input only |
"notice" | 교회 소식 블록 | ChurchNews UI |
"-" | 자동 처리 (편집 불가) | "이 항목은 자동으로 처리됩니다" |
| 테이블 | 설명 |
|---|---|
bible_versions | 성경 번역판 목록 (7개) |
books | 성경 책 정보 |
verses | 성경 구절 (버전별 약 31,000절) |
hymns | 찬송가 (645곡 새찬송가 메타데이터) |
churches | 교회 정보 (name, english_name, email) |
user_settings | 선호 버전, 테마, 폰트, BPM |
generation_history | 생성 이력 + 예배 순서 데이터 |
licenses | 라이선스 정보 (plan, device_id, expires_at, signature) |
DB 엔진: SQLite (modernc.org/sqlite, CGO 불필요). data/schema.sql 기반 자동 초기화.
| ID | 이름 | 비고 |
|---|---|---|
| 1 | 개역개정 | 기본값 |
| 2 | 개역한글 | |
| 3 | 공동번역 | |
| 4 | 표준새번역 | |
| 5 | NIV | 영문 |
| 6 | KJV | 영문 |
| 7 | 우리말성경 |
비교 모드: Bible 페이지에서 두 번역판을 나란히 비교 가능.
| 리소스 | 용도 |
|---|---|
| Oracle Cloud nginx | 찬송가 악보 · 성시교독 PDF/PNG 에셋 서빙 (internal/assets, 로컬 data/cache 캐시). tools/upload-r2.sh 는 과거 Cloudflare R2 업로드 스크립트로 현재 런타임 경로와 무관 |
| SQLite | 성경 구절 DB (7개 번역판), 찬송가, 사용자 설정/이력, 라이선스 |
| OBS WebSocket | 방송 씬 전환 + 스트리밍 + 상태 모니터링 (goobs) |
| YouTube Data API v3 | 라이브 방송 생성/관리, 썸네일 업로드 (OAuth 2.0) |
| GitHub Releases API | 자동 업데이트 체크 (AwesomeYelim/easyPreparation) |
| bugs.co.kr | 가사 검색 크롤링 |
코드 기본값 (internal/extract/extract.go initConfig). config/custom.json 으로 덮어쓸 수 있으며, 아래 수치는 OS 와 무관하게 동일합니다.
# 주보 인쇄용 (Bulletin.Print)
width : 1409.0, height : 996.0
inner — width : 584, height : 860 (본문 박스)
font : Nanum Gothic 45
# 주보 프레젠테이션용 (Bulletin.Presentation, 16:10)
width : 1409.0, height : 880.6
inner — width : 1210, height : 590
font : Nanum Gothic 100
# 가사 슬라이드 (Lyrics.Presentation)
width : 1409.0, height : 880.0
| ▶️ YouTube 연동 |
| OAuth → 라이브 방송 자동 생성 → OBS 스트림 키 자동 설정 |
| Pro |
| 🖼️ 썸네일 자동 생성 | 예배 유형 + 날짜 기반 YouTube 썸네일 생성 + 업로드 | Pro |