# o2o-web4ai 환경변수 템플릿. # cp .env.example .env 후 값을 채운다. .env 는 커밋되지 않는다(.gitignore). # # 우선순위: 실제 환경변수(docker-compose 등) > .env > config/config.{APP_ENV}.toml # DB 접속·JWT 는 config.local.toml 이 기본값이다. 여기 값을 채우면 그쪽을 덮어쓴다. # 외부 API 키는 toml 을 비워두고 여기서만 관리하는 것을 권장한다. # ── 실행 ───────────────────────────────────────────────── APP_ENV=local # RELOAD=1 # uvicorn --reload (개발 컨테이너) # SCHEDULER_ENABLED=1 # 배치 스케줄러 기동. 다중 워커면 1개 프로세스에서만 1 # ── DB (비우면 config.local.toml 의 [MainDBConfig] 사용) ── # DB_HOST=127.0.0.1 # DB_PORT=5432 # DB_USER=postgres # DB_PASSWORD= # DB_NAME=web4ai_db # ── JWT 서명 키 ─────────────────────────────────────────── # ★ 도커 이미지는 시크릿을 굽지 않으므로(config.local.toml 이 플레이스홀더 사본) # 컨테이너로 띄울 땐 반드시 여기서 주입해야 한다. 비우면 공개된 플레이스홀더가 서명 키가 된다. # 생성: python -c "import secrets; print(secrets.token_urlsafe(48))" JWT_ACCESS_SECRET= JWT_REFRESH_SECRET= # ── 외부 API 키 ─────────────────────────────────────────── # 비어 있으면 해당 어댑터만 비활성된다. 서버는 그대로 뜬다. # 채널 URL 발견 (api.perplexity.ai, 모델 sonar / sonar-pro) # ★ 지금은 **기본으로 꺼져 있다**(COLLECT_USE_PERPLEXITY=0). 키가 있어도 호출하지 않는다. # 실측(2026-08-27 도플로·버터브루·힐튼 가든 인 서울 강남): 야놀자만 물어오고 네이버 # 플레이스는 0건, 필터를 넓히면 네이버 도움말 페이지를 채널로 등록했다. 게다가 # 검색 호출 요금이 토큰 요금과 별도로 붙는다(생성 1건당 15회). # ★ 답변을 사실로 쓰지 않는다. URL 발견 전용 — 동명 업소가 섞이고 환각이 있다. PERPLEXITY_API_KEY= # Perplexity 채널 URL 발견 스위치. 0=끔(기본) / 1=켬. # 코드는 지우지 않고 여기서만 끈다 — 야놀자·여기어때 어댑터가 붙으면 배포 없이 되켠다. # 끈 상태에서도 상호 → 네이버 place id 직접 해석은 계속 돈다(유일한 자동 발견 경로). COLLECT_USE_PERPLEXITY=0 # 동일 업소 검증 · 주변 정보 (dapi.kakao.com) # https://developers.kakao.com > 내 애플리케이션 > 앱 키 > REST API 키 # ★ 무료 쿼터는 개발자 계정의 "첫 번째 활성 앱" 에만 붙는다. # dev/stage/prod 앱을 따로 파면 하나만 무료다 — 앱을 나누기 전에 확인할 것. # 초과 단가: 키워드/카테고리 검색 2원, 좌표 변환 0.5원 (키워드가 4배 비싸다) # 동일 업소 검증 — 네이버 지역검색 (카카오 키 미발급이라 이쪽을 쓴다) # https://developers.naver.com/apps 검색 API # ★ 제약: display 최대 5건 · telephone 이 빈 값으로 온다 · 행정구역 코드 없음 # → 카카오보다 동일 업소 판정 근거가 약하다(AMBIGUOUS 가 늘어난다) NAVER_CLIENT_ID= NAVER_CLIENT_SECRET= KAKAO_REST_API_KEY= # 사진 분류 + 카피 작성 (Google AI Studio) # https://aistudio.google.com/apikey GEMINI_API_KEY= # 축제 · 관광지 (한국관광공사 TourAPI, data.go.kr) # ★ TourAPI 는 자체 areaCode/sigunguCode 체계를 쓴다 — 카카오 행정구역 코드와 다르므로 매핑이 필요하다. # 디코딩된 서비스키를 넣는다(인코딩 키를 넣으면 %2B 등이 이중 인코딩된다). TOUR_API_KEY= # Open-Meteo(날씨)는 API 키가 필요 없다. 좌표만 있으면 된다. # ── 발행 호스트 ── # 커스텀 도메인이 없는 사이트의 공개 주소(`https://<이 값>/s/`). # canonical·og:url·sitemap·IndexNow 가 전부 이 값을 쓴다. 비우면 w4ai.o2o.kr. # ★ 프론트(admin)의 VITE_PUBLISH_HOST 와 **같은 값**이어야 화면과 발행본이 갈리지 않는다. SITE_PUBLIC_HOST=w4ai.o2o.kr # Azure Blob 정적 사이트 발행. 비우면 기존 로컬 out/ 발행만 사용한다. AZURE_STORAGE_CONNECTION_STRING= AZURE_STORAGE_CONTAINER=$web AZURE_STORAGE_PREFIX=ai-for-web # ── 색인 통보(IndexNow) ── # 발행 즉시 네이버·Bing·Yandex 에 URL 을 알린다. 비우면 통보를 건너뛴다(발행은 정상). # 구글은 IndexNow 를 지원하지 않는다 — 구글 쪽은 Search Console 사이트맵 제출이 별도 경로다. # 값은 8~128자의 영문·숫자·하이픈 아무 문자열이면 된다(비밀이 아니다. 공개되어야 작동한다): # python3 -c "import uuid; print(uuid.uuid4().hex)" INDEXNOW_KEY=