Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Every Seoul Frontend

에브리서울 프론트엔드 애플리케이션입니다. React 19, Vite 8, TypeScript, Tailwind CSS v4, Zustand를 사용합니다.

시작하기

pnpm install
copy .env.example .env
pnpm dev

개발 서버의 기본 주소는 http://localhost:5173 입니다. Vite가 다른 포트를 사용 중이라고 판단하면 터미널에 표시되는 주소로 접속하면 됩니다.

환경 변수

로컬 개발 환경에서는 .env.example을 복사해 .env를 만든 뒤 값을 채웁니다.

이름 설명 기본 예시
VITE_API_BASE_URL 프론트엔드가 호출할 백엔드 API 기본 주소 http://localhost:8000/api
VITE_GOOGLE_CLIENT_ID Google Identity Services 웹 클라이언트 ID *.apps.googleusercontent.com
VITE_VAPID_PUBLIC_KEY 브라우저 Web Push 구독용 공개키 B...

프로덕션 Docker 컨테이너는 시작 시점에 런타임 설정을 /env.js로 생성합니다. 그래서 이미 빌드된 이미지도 API_BASE_URL, GOOGLE_CLIENT_ID, VAPID_PUBLIC_KEY 환경 변수만 바꿔 다른 환경에서 실행할 수 있습니다.

Web Push 알림

브라우저 푸시 알림은 VAPID 키가 필요합니다. 백엔드 저장소에서 다음 명령으로 키를 생성한 뒤, 출력값을 프론트엔드와 백엔드 환경 변수에 나눠 설정합니다.

python scripts/generate_vapid_keys.py

프론트엔드에는 VITE_VAPID_PUBLIC_KEY, 백엔드에는 VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY, VAPID_CLAIM_EMAIL을 설정합니다. 프로덕션 Docker에서는 VAPID_PUBLIC_KEY가 웹 컨테이너 런타임 설정에도 전달됩니다.

주요 명령어

pnpm dev           # 개발 서버 실행
pnpm lint          # ESLint 검사
pnpm typecheck     # TypeScript 타입 검사
pnpm build         # 타입 검사 후 프로덕션 빌드
pnpm check         # lint + build 전체 검증
pnpm format        # Prettier 포맷 적용
pnpm format:check  # 포맷 검사

프로젝트 구조

src/App.tsx                  앱 조립
src/components/layout        셸, 헤더, 사이드바 레이아웃
src/components/newsletter    뉴스레터 탭 UI
src/components/life-info     생활 정보 탭 UI
src/components/policy        정책 탭 UI
src/components/modals        모달 UI
src/components/shared        작은 재사용 UI
src/components/auth          인증 UI와 Google 로그인
src/auth                     인증 연동 헬퍼
src/data                     태그, 자치구 등 정적 선택지
src/hooks                    상태를 가진 앱 훅
src/store                    Zustand 스토어
src/types                    공용 타입
src/utils                    순수 유틸리티
src/styles/index.css         전역 CSS와 Tailwind 진입점

App.tsx는 앱 구성만 담당하도록 얇게 유지합니다. 새로운 동작은 역할에 맞게 컴포넌트, 훅, 스토어, 데이터, 유틸리티에 나눠 둡니다.

백엔드 연동

로컬 백엔드 저장소는 보통 이 저장소와 같은 상위 폴더 아래에 둡니다.

every-seoul
every-seoul-backend

백엔드 API의 기본 로컬 주소는 http://localhost:8000/api 입니다. 프론트엔드에서 다른 주소를 호출해야 하면 .envVITE_API_BASE_URL 값을 변경합니다.

Google OAuth 설정

Google Cloud Console에서 OAuth 클라이언트를 만들 때 애플리케이션 유형은 웹 애플리케이션을 선택합니다.

로컬 개발용 승인된 JavaScript 원본:

http://localhost:5173
http://127.0.0.1:5173

프로덕션 배포 시에는 실제 도메인도 추가합니다.

https://everyseoul.com

같은 Google 클라이언트 ID를 프론트엔드와 백엔드 환경 변수에 설정합니다. 현재 프론트엔드는 화면 표시와 세션 상태를 위해 Google ID 토큰을 파싱합니다. 실제 프로덕션 인증에서는 이 ID 토큰을 백엔드로 보내 서버에서 검증한 뒤 세션을 생성해야 합니다.

Docker 이미지 빌드

프론트엔드 이미지는 정적 파일을 빌드한 뒤 Nginx로 제공합니다.

docker build -t every-seoul-web .

전체 스택 Docker Compose

compose.prod.yml은 Caddy, 프론트엔드, 백엔드, PostgreSQL을 함께 실행합니다. Caddy가 80, 443 포트를 열고 Let's Encrypt 인증서를 자동 발급합니다. 백엔드 저장소가 이 저장소와 같은 상위 폴더 아래에 있다고 가정합니다.

every-seoul
every-seoul-backend

배포 환경 변수는 템플릿을 복사해 별도 파일로 관리합니다. 실제 .env.production은 Git에 커밋하지 않습니다.

cp .env.production.example .env.production

.env.production에서 PUBLIC_WEB_HOST, PUBLIC_WEB_ORIGIN, POSTGRES_PASSWORD, GOOGLE_CLIENT_ID, ADMIN_API_KEY, SEOUL_OPEN_API_KEY, OPENROUTER_API_KEY를 실제 값으로 바꾼 뒤 실행합니다.

ADMIN_API_KEY는 뉴스레터 수집 파이프라인을 수동 실행할 때 쓰는 관리자 토큰입니다. 충분히 긴 임의 문자열로 설정하고 Git에 커밋하지 않습니다.

docker compose --env-file .env.production -f compose.prod.yml up --build -d
docker compose --env-file .env.production -f compose.prod.yml logs -f
docker compose --env-file .env.production -f compose.prod.yml down

Windows PowerShell에서도 같은 Compose 파일을 사용할 수 있습니다.

Copy-Item .env.production.example .env.production
notepad .env.production
docker compose --env-file .env.production -f compose.prod.yml up --build -d
docker compose --env-file .env.production -f compose.prod.yml logs -f
docker compose --env-file .env.production -f compose.prod.yml down

상태 확인:

curl http://localhost/health
curl http://localhost/api/health
curl https://everyseoul.com/health
curl https://everyseoul.com/api/health

PowerShell에서 상태를 확인할 때는 다음 명령을 사용할 수 있습니다.

Invoke-WebRequest http://localhost/health
Invoke-WebRequest http://localhost/api/health
Invoke-WebRequest https://everyseoul.com/health
Invoke-WebRequest https://everyseoul.com/api/health

뉴스레터 수집 파이프라인

뉴스레터 탭의 "오늘의 강남구 요약"은 백엔드 DB에 저장된 뉴스레터를 표시합니다. 프론트엔드의 새로고침 버튼은 이미 저장된 최신 데이터를 다시 불러오며, 새 뉴스레터를 직접 생성하지는 않습니다.

백엔드는 ENABLE_SCHEDULER=true일 때 매일 04:00 KST에 서울 RSS, 문화행사, 생활 센서 데이터를 수집하고 자치구별 브리핑을 생성합니다.

배포 직후 바로 데이터를 채우고 싶다면 관리자 토큰으로 수동 실행합니다.

curl -X POST http://localhost/api/admin/pipeline/trigger \
  -H "X-Admin-Token: $ADMIN_API_KEY"

도메인으로 호출할 수도 있습니다.

curl -X POST https://everyseoul.com/api/admin/pipeline/trigger \
  -H "X-Admin-Token: $ADMIN_API_KEY"

PowerShell에서는 다음처럼 실행합니다.

Invoke-WebRequest `
  -Method Post `
  -Uri https://everyseoul.com/api/admin/pipeline/trigger `
  -Headers @{"X-Admin-Token" = $env:ADMIN_API_KEY}

실행 후 API 로그에서 진행 상황을 확인합니다.

docker compose --env-file .env.production -f compose.prod.yml logs -f api

생성 결과는 다음처럼 확인할 수 있습니다.

curl "http://localhost/api/newsletters/today?district=강남구"

실제 배포 전 확인 사항

  • VPS, 클라우드 VM, Render, Fly.io, Railway 등 Docker 실행이 가능한 배포 대상을 정합니다.
  • 실제 도메인을 서버에 연결합니다.
  • 서버의 80/443 포트를 열고 도메인의 A 레코드가 서버를 가리키게 합니다. compose의 Caddy가 HTTPS를 자동 적용합니다.
  • 프로덕션 도메인용 Google OAuth 웹 클라이언트 ID를 준비하거나 기존 클라이언트에 프로덕션 원본을 추가합니다.
  • .env.production을 만들고 PUBLIC_WEB_HOST=everyseoul.com, PUBLIC_WEB_ORIGIN=https://everyseoul.com으로 설정합니다.
  • API_BASE_URL을 프론트엔드가 호출할 API 경로로 설정합니다. 일반적으로 /api를 사용합니다.
  • POSTGRES_PASSWORD를 강한 고유 비밀번호로 바꿉니다.
  • ADMIN_API_KEY를 강한 고유 토큰으로 바꿉니다.
  • 필요한 경우 SEOUL_OPEN_API_KEY, OPENROUTER_API_KEY를 실제 값으로 설정합니다.
  • 운영 환경에서 뉴스레터 수집을 자동 실행하려면 ENABLE_SCHEDULER=true로 설정합니다.
  • 초기 소규모 배포에서는 CREATE_DB_TABLES=true를 사용할 수 있지만, 운영이 안정되면 마이그레이션을 사용하고 CREATE_DB_TABLES=false로 전환하는 편이 좋습니다.
  • postgres_data Docker 볼륨을 백업하거나 관리형 PostgreSQL 사용을 검토합니다.
  • 방화벽은 필요한 포트만 열어 둡니다. 이 compose 구성에서는 HTTP/HTTPS만 외부에 노출하고 PostgreSQL은 내부에 둡니다.

배포 전 검증 예시:

pnpm check
python -m compileall ..\every-seoul-backend\app
python -m pytest -s ..\every-seoul-backend\tests
docker compose --env-file .env.production -f compose.prod.yml config

배포 후에는 실제 Google 계정으로 로그인, 로그아웃, 사용자 설정 저장, 북마크 저장/해제, 뉴스레터 수집 결과 표시가 정상 동작하는지 확인합니다.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages