2026년 7월 21일 화요일

app/domain/sheet/router.py



# domain/sheet/router.py

from fastapi import APIRouter, HTTPException, Request
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates

# 필요하다면 추가할 공통 모듈들
# from . import crud, schemas

# 🛠️ prefix에 공통 주소를 명시하고 맨 뒤 슬래시(/)는 생략합니다.
router = APIRouter(prefix="/api/sheets", tags=["sheets"])

# 🌟 HTMLResponse나 템플릿(Jinja2)을 사용할 때 설정
templates = Jinja2Templates(directory="templates")


def get_google_sheet_data():
    """테스트용 구글 시트 데이터 (추후 credentials.json 연동부로 대체)"""
    try:
        # 오늘 날짜 생성
        from datetime import datetime

        current_date = datetime.now().strftime("%Y-%m-%d")

        rows = [
            ["날짜", "작업명", "상태"],
            [current_date, "가짜 데이터 (통제소 가동 완료--)", "성공"],
            ["2026-06-20", "구글 클라우드 보안 대기", "대기"],
        ]
    except Exception:
        rows = []

    return rows


# 🔌 2. HTMX 표 내용물 조각 리턴 전용 API
# 🛠️ 최종 주소는 자동으로 '/api/sheets/rows'가 됩니다.
@router.get("/rows", response_class=HTMLResponse)
def serve_sheet_rows(request: Request):
    # htmx 고유 헤더 확인 장치 (브라우저 직접 타이핑 진입 차단)
    is_htmx = request.headers.get("HX-Request") or request.headers.get("hx-request")
    if not is_htmx:
        raise HTTPException(
            status_code=400, detail="통제소를 우회한 직접 접근은 금지되어 있습니다."
        )

    raw_data = get_google_sheet_data()
    rows = raw_data[1:] if raw_data and len(raw_data) > 1 else []

    return templates.TemplateResponse(
        request=request, name="table_rows.html", context={"rows": rows}
    )


database.py

import os from contextlib import contextmanager # contextmanager 임포트 from typing import Generator from dotenv...