尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证빈자리 취소석 자동 매칭 솔루션
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗전국 뷰티샵 디스커버리 — 웹(themuselab.kr) + Apps-in-Toss 미니앱 (동일 코드 dual-build). 지도에서 내 주변 뷰티샵(네일·헤어·속눈썹·왁싱·반영구·피부·마사지·태닝)을 둘러보고, 오늘 당장 예약 가능한 빈자리를 찾아 바로 네이버 예약으로 연결한다.
네이버 플레이스에서 수집한 전국 뷰티샵 4만+곳의 위치·사진·메뉴·가격·리뷰·예약 정보 + **실시간 빈자리(슬롯)**를 지도로 보여준다. 데이터는 Supabase에 적재하고 앱은 지도 영역(뷰포트) 기준으로 조회한다.
인터랙티브 버전: docs/diagrams/data-pipeline.html
인터랙티브 버전: docs/diagrams/architecture.html
slots.yml(빈자리, 매시) · events.yml(할인) · price-sync.yml(가격·영업시간·리뷰) · partners.yml(파트너 사진·메뉴)가 네이버를 읽어 백엔드 /internal/* API로 보내고, 백엔드가 RDS에 저장한다.slot_ingest.py가 받은 새 빈자리는 백엔드 알림 API를 거쳐 앱 푸시로 나간다. today-open.yml은 네이버 없이 초록핀만 재계산한다./api/v1/web/*를 호출한다. SEO 랜딩(/nail/:gu)·sitemap·rss는 Vercel 함수가 api/regions.json(seo_generate.py로 수동 생성)을 읽어 렌더한다.ga4-discord.yml · app-discord.yml이 GA4와 백엔드 지표를 Discord로 보낸다.DDD-lite + 헥사고날(클린아키텍처) + 읽기/쓰기 분리(CQRS-lite). 자세한 규칙은 ARCHITECTURE.md.
src/
├─ contexts/ # 독립 도메인 (bounded contexts) — 서로 직접 import 금지
│ ├─ catalog/ # 🔵 샵 탐색·필터·상세·컬렉션 (읽기측, Query)
│ ├─ analytics/ # 🟢 클릭/노출 이벤트 (쓰기 + 읽기)
│ ├─ lead/ # 🟡 취소석 전화번호 등록 (쓰기)
│ └─ reservation/ # 🔵 예약/슬롯 조회 — Supabase slots(빈자리) provider
├─ shared/ # 공통 커널 (값객체·플랫폼 어댑터·공통 UI)
└─ app/ # 조립(composition-root) + 라우팅
각 컨텍스트는 4겹 레이어:
ui → application → domain
│
▼
ports ◀── infrastructure (어댑터)
domain/ — 순수 비즈니스 로직. React·fetch·DB import 금지.application/ — 유스케이스. 포트로만 도메인 오케스트레이션.ports/ — 인터페이스(의존성 역전 경계).infrastructure/ — 어댑터. 외부 의존(fetch/JSON/SDK)은 여기만.src/app/composition-root.ts 한 곳에서 포트↔어댑터를 연결.예약/슬롯은
SlotProvider포트 + Supabase 어댑터로 구현돼 있다. 앱은 실시간으로 네이버를 호출하지 않고, GitHub Actions 배치가 미리 채워둔slots테이블(오늘~3일치 빈자리)만 읽는다.
앱은 외부 API를 실시간 호출하지 않고, 데이터 파이프라인이 미리 적재한 Supabase read model만 읽는다 (CQRS 읽기측).
shops — 가게 요약/상세(jsonb) + 파생필드(가격대·이벤트·파트너·오늘빈자리 today_open)slots — 오늘~3일치 빈자리 (shop_id, date, time)events / leads — 클릭 이벤트 / 취소석 등록 (쓰기측)앱은 지도 영역(뷰포트) 기준으로 핀/요약을 조회하고(egress 절약), 상세는 진입 시 지연 로딩한다.
scraper/)| 워크플로 | 주기 | 역할 |
|---|---|---|
slot-ingest | 매시 :00/:30 (2분할) | 네이버 빈자리 → slots + today_open 갱신 |
event-ingest | 매일 (4분할) | 할인/이벤트 텍스트 수집 |
partner-sync | 매시 :15 | is_partner 켜진 샵 사진·가격 재수집(Playwright) |
report | 08:00 | 검증 리포트 → Discord |
전국 수집/가공 스크립트는 별도 레포(
muse/syak/)에 있다. 원본 대용량 수집 데이터는 레포에 포함하지 않는다.
npm install
npm run dev:web # 일반 웹(Vercel 타깃) 개발 서버 — vite dev
npm run dev # 앱인토스(granite) 개발
npm run build:web # Vercel 빌드 (VITE_TARGET=vercel vite build)
npm run build # 앱인토스 빌드 (ait build)
지도는 카카오 JS 키를 쓴다(VITE_KAKAO_KEY env 우선, 없으면 fallback). JS 키는 도메인 제한이라
배포 도메인을 카카오 디벨로퍼 콘솔의 사이트 도메인 화이트리스트에 추가해야
지도가 렌더된다. (localhost / 배포 도메인 각각 등록)
vercel.json 포함. Vercel에 이 레포를 연결하면 VITE_TARGET=vercel vite build로 빌드된다.
/data/*는 SPA 리라이트에서 제외돼 정적 JSON으로 서빙된다.
클릭집계(
/api/track)·전화등록(/api/submit)은 별도 백엔드(themuselab.kr)로 전송한다.
SlotProvider, 오늘/내일 빈자리 표시