여러 줄 주석이 설명보다 경위(예전·실측·지적)를 적고 있어 읽는 사람이 결론을 찾기 어려웠다. - ts·tsx·js·mjs·css·py 478개: 여러 줄 주석은 첫 문장 한 줄로, 과거형·날짜 문장은 삭제 - 주석 위치는 TypeScript 파서·파이썬 tokenize/ast 로 찾는다 — 문자열 안의 # · /* 는 건드리지 않는다 - eslint·ts·noqa·type: ignore 같은 지시 주석은 그대로 둔다 파이썬 275개 정리 전후 AST 동일, TS 298개 주석 뺀 토큰 동일(빈 JSX 주석 10곳만 차이). site·frontend·admin tsc, site vitest 105 passed Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
78 lines
3.7 KiB
Python
78 lines
3.7 KiB
Python
import uuid
|
|
|
|
from fastapi import APIRouter, Depends, Query
|
|
|
|
from common.enums import LocalContentStatus
|
|
from common.models.gmodel import UserInfo
|
|
from router.v1.validator.dependencies import RequireOwner, RemoveNoneResponse
|
|
from services.local_content_service import LocalContentService
|
|
from .protocol import (
|
|
ReqHidePlaceContent, ReqPublishLocalContent, ReqUpdateLocalContent,
|
|
ResLocalContentList, ResLocalGuide, ResPlaceContentList, ResSyncPlace, ResWeather,
|
|
)
|
|
|
|
router = APIRouter(prefix="/v1/admin/local-content", tags=["LocalContent"])
|
|
weather_router = APIRouter(prefix="/v1/local", tags=["LocalContent"])
|
|
|
|
|
|
@weather_router.get("/weather", response_model=ResWeather, summary="현재 날씨 조회 (cache-aside)")
|
|
async def get_weather(
|
|
region_code: str = Query(min_length=1, max_length=10),
|
|
latitude: float = Query(ge=-90, le=90),
|
|
longitude: float = Query(ge=-180, le=180),
|
|
service: LocalContentService = Depends(),
|
|
):
|
|
return RemoveNoneResponse(await service.get_weather(region_code, latitude, longitude))
|
|
|
|
|
|
@weather_router.get("/guide", response_model=ResLocalGuide, summary="업장 주변 가이드(맛집·명소·축제·코스) — 에디터 캔버스용")
|
|
async def get_guide(
|
|
place_id: uuid.UUID = Query(),
|
|
service: LocalContentService = Depends(),
|
|
):
|
|
"""날씨와 같은 공개 조회다 — 운영자가 숨기지 않은 공공데이터만 나가므로 인증을 요구하지 않는다."""
|
|
return RemoveNoneResponse(await service.get_guide(place_id))
|
|
|
|
|
|
@router.get("/place/{place_id}", response_model=ResPlaceContentList, summary="업장 주변정보 목록 (숨김 포함)")
|
|
async def list_place_contents(place_id: uuid.UUID, service: LocalContentService = Depends(), _user=Depends(RequireOwner)):
|
|
return RemoveNoneResponse(await service.list_place_contents(place_id))
|
|
|
|
|
|
@router.post("/place/{place_id}/sync", response_model=ResSyncPlace, summary="업장 주변정보 재수집 (TourAPI 반경)")
|
|
async def sync_place(place_id: uuid.UUID, service: LocalContentService = Depends(), _user=Depends(RequireOwner)):
|
|
"""빌드가 매번 하는 것과 같은 수집을 운영자가 직접 누른다."""
|
|
return RemoveNoneResponse(await service.sync_place_by_id(place_id))
|
|
|
|
|
|
@router.post("/place-content/{place_content_id}/hide", response_model=ResPlaceContentList, summary="주변정보 숨김/해제")
|
|
async def hide_place_content(
|
|
place_content_id: uuid.UUID, req: ReqHidePlaceContent,
|
|
service: LocalContentService = Depends(), _user=Depends(RequireOwner),
|
|
):
|
|
"""숨긴 항목은 재수집이 되살리지 않는다."""
|
|
return RemoveNoneResponse(await service.set_hidden(place_content_id, req.hidden))
|
|
|
|
|
|
@router.get("", response_model=ResLocalContentList)
|
|
async def list_contents(
|
|
status: LocalContentStatus | None = Query(None), region_code: str | None = Query(None),
|
|
service: LocalContentService = Depends(), _user: UserInfo = Depends(RequireOwner),
|
|
):
|
|
return RemoveNoneResponse(await service.list(status.value if status else None, region_code))
|
|
|
|
|
|
@router.post("/publish", response_model=ResLocalContentList)
|
|
async def publish(req: ReqPublishLocalContent, service: LocalContentService = Depends(), user=Depends(RequireOwner)):
|
|
return RemoveNoneResponse(await service.publish(req.content_ids, user.user_id))
|
|
|
|
|
|
@router.patch("/{content_id}", response_model=ResLocalContentList)
|
|
async def update_content(content_id: str, req: ReqUpdateLocalContent, service: LocalContentService = Depends(), _user=Depends(RequireOwner)):
|
|
return RemoveNoneResponse(await service.update(content_id, req))
|
|
|
|
|
|
@router.post("/{content_id}/end", response_model=ResLocalContentList)
|
|
async def end_content(content_id: str, service: LocalContentService = Depends(), _user=Depends(RequireOwner)):
|
|
return RemoveNoneResponse(await service.end(content_id))
|