Skip to content
sspzoaPublic

About

학교별 급식 API 밥.net의 프론트엔드

Resources

Stars

2 stars

Watchers

1 watching

Forks

Repository files navigation

bap-web

밥.net 프론트엔드. 쿠키 하나로 사이트를 고르고, UI·SEO·끼니 슬롯은 API 카탈로그에서 받습니다.

API: bap-back · 문서: api.밥.net/docs · 에이전트: AGENTS.md

개요

  • / — 식단. 쿠키가 없으면 같은 페이지에서 사이트를 고릅니다 (쿠키 bap-site-id)
  • /?site={id} — bap-site-id 쿠키를 넣고 /로 이동 (예: /?site=kdmhs)
  • /?home=1 — bap-site-id 쿠키를 지우고 사이트 선택 UI로 이동
  • /docs — API Scalar로 리다이렉트 (api.밥.net/docs)

사이트별 App Router 폴더는 없습니다. 백엔드에 프로바이더만 추가하면 홈 사이트 선택·manifest에 자동 반영됩니다.

빠른 시작

bun install --frozen-lockfile
NEXT_PUBLIC_API_BASE_URL=http://localhost:3001 bun dev   # 기본 :3000

로컬 API가 3000이면 NEXT_PUBLIC_API_BASE_URL 생략 가능 (운영 API 기본값).

bun run build
bun start
bun run lint

환경 변수

변수 기본값 설명
NEXT_PUBLIC_API_BASE_URL https://api.xn--rh3b.net API 베이스 (https://api.밥.net과 동일 호스트)

코드에서는 src/shared/lib/apiBase.ts의 API_BASE_URL을 사용합니다.

라우팅

Next.js 16 proxy.ts (middleware 대체):

경로 동작
/ + 쿠키 없음 홈에서 사이트 선택 UI (리다이렉트 없음)
/?site={id} bap-site-id 쿠키 설정 후 쿼리 제거·리다이렉트
/?home=1 bap-site-id 쿠키 삭제, 이번 요청은 사이트 선택 UI
없는 경로 → / (쿼리 유지)
/ x-site-id 헤더 주입
/docs → API_BASE_URL/docs (Scalar)
/ + 잘못된 site id 홈에서 사이트 선택 UI

클라이언트는 쿠키를 직접 읽지 않고 useSite() / SiteProvider를 씁니다. 홈으로 가면 bap-site-id를 지우고 사이트 선택 UI를 보여 줍니다.

데이터 흐름

GET / (catalog)           →  layout / 홈 선택 UI / manifest
GET /{basePath}/{date}    →  TanStack Query (useMealQuery)
GET /docs (API)           →  Scalar (백엔드가 직접 서빙)
POST /mcp                 → 에이전트 (프론트가 호출하지 않음)
SSR initialData           →  오늘 날짜에만 시드 (날짜 변경 시 다른 날 메뉴로 섞이지 않음)

디렉터리

src/
  app/              App Router (pages, OG, manifest)
  shared/
    components/     MealLayout, MealSection, Glass, …
    hooks/          useMealQuery, useMealData, …
    lib/            catalog, mealService, apiBase, queryKeys
    types/          SitePresentation, PublicDayMenu, …
  sites/
    config.ts       BRAND 상수만
    context.tsx     SiteProvider
    server.ts       getSiteId() — proxy 헤더
  proxy.ts          Edge 라우팅·쿠키
public/
  img/              끼니 배경 SVG
  icons/            PWA·favicon
  og.png            OG/Twitter 카드

새 사이트 추가

기본은 프론트 수정 없음. 학교는 bap-back 프로바이더 + presentation으로만 추가합니다. 카탈로그가 홈 사이트 선택, 엣지 패널, PWA manifest, MCP bap_list_providers에 같이 반영됩니다.

공개 문서: api.밥.net/docs · 백엔드 절차: bap-back README

하지 말 것:

  • src/sites/{id}/ 트리, SITES 맵, /kdmhs 같은 경로 하드코딩
  • 클라이언트에서 bap-site-id 쿠키를 읽어 라우팅
  • API 문서를 프론트에 다시 구현 (Scalar은 백엔드 /docs)

필요할 때만:

상황 프론트에서 할 일
기존 아침·점심·저녁 에셋 재사용 없음. presentation이 /icon/lunch.svg 등을 가리키면 됨
새 끼니 아이콘·배경 public/icon, public/img에 파일 추가 후 presentation URL 맞추기
메뉴 사진 검색 백엔드 features.foodSearch: true + handleExtraRoute. 프론트 mealSection이 플래그만 봄

presentation 계약은 백엔드 SitePresentation과 동일합니다 (src/shared/types). 카탈로그에 id, basePath, meals[]가 없으면 getCatalog()가 그 사이트를 버립니다.

스택

  • Next.js 16, React 19, Tailwind 4
  • TanStack Query (식단 fetch·prefetch)
  • Jotai (currentDateAtom만)
  • Wanted Sans (globals.css CDN)
  • Biome (lint/format)

배포

Docker (Bun 빌드, TZ=Asia/Seoul). 빌드 시 NEXT_PUBLIC_API_BASE_URL bake-in.

에이전트·기여

코딩 규칙은 AGENTS.md 참고.

알려진 이슈

  • 카탈로그 fetch 실패 시 사이트 선택이 빈 그리드 (에러 UI 없음)
  • 모든 사이트 OG 이미지 공유 (public/og.png)
  • React Query Devtools가 prod에서도 마운트됨

About

학교별 급식 API 밥.net의 프론트엔드

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages