"""카페24 상품 상세페이지 관리 모듈 라우터. - 경로: /cafe24 - 권한: 로그인 + `cafe24` 모듈 권한 (관리자는 항상 통과). 서버 측 검사. 카페24 연결(OAuth) 변경은 `is_admin` 만. - 데이터: Cafe24Store (cafe24_db / PostgreSQL) 전용. CAFE24_DB_URL 미설정 시 store 가 None 이며, 각 페이지는 "설정 필요" 안내. - 카페24 API 호출은 app/integrations/cafe24 공통 계층을 통해서만 한다. 라우트가 많아 기능별 파일로 나눈다(다른 모듈의 단일 router.py 패턴을 규모 때문에 확장한 것). 여기서는 루트 라우터를 만들고 서브 라우터를 결합한다. routes_products 상품 목록/검색 · 상세설명 조회 routes_system 연결(OAuth)·상태·API 로그·작업 로그 (Phase 5) routes_schedules """ from __future__ import annotations import logging from fastapi import APIRouter, Request from fastapi.responses import HTMLResponse from .common import base_ctx, guard from .routes_products import products_router from .routes_system import system_router logger = logging.getLogger("cafe24.router") router = APIRouter(prefix="/cafe24", tags=["cafe24"]) router.include_router(products_router) router.include_router(system_router) @router.get("/health") def health() -> dict[str, str]: """포털 카드의 상태 점(dot) 용. 인증 불필요 — 상태 문자열만 반환.""" return {"status": "ok"} @router.get("/schedules", response_class=HTMLResponse) def schedules(request: Request) -> HTMLResponse: """예약관리 안내. Phase 5 에서 routes_schedules.py 로 옮긴다. 상단 탭에 링크가 있으므로 404 를 내지 않고 안내 화면을 보여준다. """ from app.main import render_template # noqa: WPS433 checked = guard(request) if not isinstance(checked, tuple): return checked _st, user = checked ctx = base_ctx(request, user, active_tab="schedules") ctx.update( { "page_title": "카페24 — 예약관리", "page_subtitle": "예약 적용 · 자동 복원", } ) return render_template(request, "cafe24/schedules.html", ctx)