尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證지도 기반으로 내 주변 어린이집을 빠르게 찾고, 유형·운영시간·서비스를 한눈에 비교할 수 있는 검색 서비스
翻譯準備中
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
지도 기반으로 내 주변 어린이집을 빠르게 찾고, 유형·운영시간·서비스를 한눈에 비교할 수 있는 검색 서비스 • 지도 기반 탐색 — 현재 지도 영역의 어린이집을 실시간으로 조회 • 놀이시설 레이어 — 지도에서 어린이집 ↔ 놀이시설로 전환해 주변 놀이터를 함께 확인 • 필터링 — 어린이집 유형, 서비스 유형(시간제, 장애아 등)으로 필터링 • 상세 정보 — 정원, 현원, 연령별 대기 현황, CCTV, 차량 운행 등 공공데이터 기반 상세 정보 제공 • 지역별 목록·랭킹 — 시도·시군구 단위로 어린이집을 모아보고 순위 비교 • 인터셉트 라우트 — 목록에서 상세 진입 시 모달로 표시, 직접 URL 접근 시 전용 페이지로 표시 • 콘텐츠(블로그) — 어린이집 부모를 위한 보육 제도·지원금·원 생활 가이드를 MDX로 발행 데이터 흐름과 책임을 명확히 하기 위해 도메인 기반 디렉토리 구조를 채택했습니다. 도메인마다 필요한 레이어만 둡니다. 예를 들어 region은 서버에서만 쓰이므로 apis·hooks가 없습니다.檢視完整 README ↗
지도 기반으로 내 주변 어린이집을 빠르게 찾고, 유형·운영시간·서비스를 한눈에 비교할 수 있는 검색 서비스
| 영역 | 기술 |
|---|---|
| Framework | Next.js 16 (App Router) |
| Language | TypeScript (strict) |
| Data Fetching | TanStack React Query v5 |
| URL State | nuqs |
| Styling | Tailwind CSS v4 |
| Map | Naver Maps |
| Backend | Supabase |
| Content | Velite (MDX) |
| Monorepo | Turborepo + pnpm |
| Deploy | Hostinger (Node.js, output: standalone) |
데이터 흐름과 책임을 명확히 하기 위해 도메인 기반 디렉토리 구조를 채택했습니다.
apps/web/domain/
├── daycare/ # 어린이집 검색·상세 (핵심 도메인)
│ ├── index.ts # 클라이언트 public API
│ ├── server.ts # 서버 전용 public API (server-only)
│ ├── types/ # 도메인 타입 정의
│ ├── apis/ # 외부 API 호출 (fetch)
│ ├── parser/ # API 응답 → 도메인 타입 변환
│ ├── query-keys/ # Query Key 팩토리
│ ├── query-options/ # queryOptions 팩토리 (hooks & prefetch 공유)
│ ├── hooks/ # Client-side React Query hooks
│ └── prefetch/ # SSR prefetch (server-only)
├── article/ # 블로그 아티클 조회·조회수·좋아요
├── playground/ # 어린이 놀이시설 (지도 레이어)
├── naver-blog/ # 네이버 블로그 검색 연동 (NAVER API HUB)
└── region/ # 시도·시군구 지역 데이터
도메인마다 필요한 레이어만 둡니다. 예를 들어 region은 서버에서만 쓰이므로 apis·hooks가 없습니다.
queryOptions 공유 — prefetch와 useQuery가 동일한 queryKey/queryFn을 사용하여 hydration 불일치 방지| 경로 | 설명 |
|---|---|
/ | 홈 — 서비스 소개·검색 진입·FAQ |
/map | 지도 기반 어린이집 탐색 |
/daycares, /daycares/upcoming | 어린이집 목록 — 시도 선택 / 인허가예정 |
/daycares/[sido], /daycares/[sido]/[sigungu] | 지역별 어린이집 목록 (옛 ?sido=·?arcode= 쿼리 URL은 308로 이전) |
/daycare/[id] | 어린이집 상세 (목록에서 진입 시 @modal로 인터셉트) |
/rankings, /rankings/[sido] | 지역별 어린이집 랭킹 |
/contents, /contents/[slug] | 블로그 목록·상세 |
/about, /about/editorial | 서비스 소개·편집 정책 |
/terms, /privacy-policy | 이용약관·개인정보 처리방침 |
/api/naver/blog | 네이버 블로그 검색 프록시 — NAVER API HUB 호출 후 제목에 어린이집 이름이 든 글만 반환 |
/api/article/[uuid]/view, /api/article/[uuid]/like | 아티클 조회수·좋아요 집계 |
블로그 글은 apps/web/content/blog/*.mdx에 두고 Velite가 빌드 타임에 컴파일합니다. 스키마는 apps/web/velite.config.ts에 정의되어 있으며, frontmatter 필드가 하나라도 빠지면 빌드가 실패합니다.
발행 이력과 발행 계획은 docs/content/에서 관리합니다. 새 글을 기획하기 전에 이 폴더를 먼저 확인하세요.
| 문서 | 내용 |
|---|---|
| README | 발행 워크플로, frontmatter 스키마, 카테고리 체계, 집필 규칙 |
| 발행-완료 | 발행된 글 인벤토리 |
| 발행-예정 | 후보 주제, 우선순위, 집필 전 검증 사항 |
.mdx를 커밋하기 전에는 반드시 npx velite build로 컴파일을 확인합니다.
필요 환경: Node.js ≥ 20, pnpm 9
# 패키지 설치
pnpm install
# 개발 서버 실행
pnpm dev
환경 변수는 apps/web/.env.local 에 설정합니다. (apps/web/.env.local.example 참고)
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=
NEXT_PUBLIC_NAVER_MAP_CLIENT_ID=
# 네이버 블로그 검색 프록시(/api/naver/blog)에만 필요 (서버 전용)
# 네이버 클라우드 플랫폼 → API Hub → Application → NAVER 검색(블로그)
NAVER_API_HUB_CLIENT_ID=
NAVER_API_HUB_CLIENT_SECRET=
관리자 앱은 apps/admin/.env.local 을 따로 둡니다. 관리자 계정 CRUD에 쓰는
SUPABASE_SECRET_KEY는 서버 전용이라 NEXT_PUBLIC_ 접두사를 붙이지 않습니다.
(apps/admin/.env.local.example 참고)
루트에서 실행하면 Turborepo가 모든 워크스페이스에 전파합니다. pnpm dev는 웹(3000)과
관리자(3001)를 함께 띄웁니다. 한쪽만 띄우려면 해당 앱 디렉토리에서 실행합니다.
| 명령 | 설명 |
|---|---|
pnpm dev | 개발 서버 (Turbopack) |
pnpm build | 프로덕션 빌드 |
pnpm lint | ESLint |
pnpm typecheck | tsc --noEmit |
pnpm format | Prettier |
작업을 마치기 전에 pnpm lint, pnpm typecheck, pnpm build를 통과시킵니다.
kidzly.kr/
├── apps/
│ ├── web/ # 서비스 앱 kidzly.kr (포트 3000)
│ │ ├── app/ # App Router (pages, layouts, intercepting routes)
│ │ ├── components/ # UI 컴포넌트 (도메인별 분류)
│ │ ├── content/ # 블로그 MDX 원문
│ │ ├── domain/ # 도메인 로직 (API, Query, Prefetch)
│ │ ├── hooks/ # 공통 hooks
│ │ ├── lib/ # 유틸리티 (React Query 설정, 날짜 포맷, 구조화 데이터 등)
│ │ ├── types/ # 전역 타입 선언
│ │ └── velite.config.ts
│ └── admin/ # 운영 관리자 앱 (포트 3001, Supabase Auth 로그인)
├── packages/
│ ├── ui/ # 공유 UI 컴포넌트 (shadcn/ui 기반)
│ ├── supabase/ # Supabase 클라이언트·타입 (@workspace/supabase)
│ ├── eslint-config/ # 공유 ESLint 설정
│ └── typescript-config/ # 공유 TypeScript 설정
└── docs/
└── content/ # 콘텐츠 발행 관리 문서
Supabase(PostgreSQL)를 사용합니다. 서비스 앱은 로그인이 없고 어린이집·놀이시설·아티클을
읽기 전용으로 조회합니다. 예외는 아티클 조회수·좋아요뿐으로, 테이블을 직접 쓰지 않고
RPC(increment_view_count, toggle_like)로 증분합니다. 관리자 앱만 Supabase Auth로
로그인하며, 여기서도 어린이집 데이터는 조회만 합니다.
스키마는 이 저장소가 관리하지 않습니다. 테이블·인덱스·뷰 전부 kidzly-sync의 Flyway 마이그레이션이 소유합니다. 웹이 쓰는 조회 인덱스와 필터 옵션 뷰도 마찬가지입니다. Supabase SQL 에디터에서 직접 만들지 마세요 — 이력에 남지 않아 재현이 불가능해집니다.
이 저장소가 갖는 것은 스키마의 타입 표현뿐입니다.
| 위치 | |
|---|---|
| 스키마 정의(원본) | kidzly-sync src/main/resources/db/migration/ |
| 스키마 스냅샷 | kidzly-sync schema.sql (pg_dump 생성, 손으로 고치지 않음) |
| 타입 (이 저장소) | packages/supabase/src/types.ts |
컬럼을 추가·변경해야 하면 kidzly-sync에 마이그레이션을 넣고, 운영에 적용된 것을 확인한 뒤
types.ts를 갱신하고 배포합니다. 절차는 kidzly-sync README의 "데이터베이스 스키마" 절에 있습니다.
코드 작성 규칙은 CLAUDE.md에 정리되어 있습니다. 핵심만 옮기면 다음과 같습니다.
type 사용, any·non-null assertion(!) 금지useState + fetch를 쓰지 않습니다index.ts / server.ts)만 사용하고 deep import를 금지합니다lib/format.ts의 formatDate(KST)를 씁니다