generated from ttipo/project-base
c54df9cefa
아임웹 관리자 페이지에서 회원을 유입경로·그룹 기준으로 보고, 무료 강의 신청을 기록·조회하기 위한 백엔드다. 관리자 화면(아임웹)과 API(wandergo.net)가 다른 사이트라 인증은 쿠키 대신 Bearer 토큰으로 한다. - 관리자 인증: env 단일 계정(ADMIN_USERNAME/PASSWORD)을 여러 사람이 공유, 기기별 세션(로그아웃은 그 기기만, 비밀번호 변경 시 전체 무효) - 아임웹 Open API 연동: OAuth 연결·토큰 갱신, 회원·그룹 주기 동기화, 가입 폼 '홈페이지' 항목의 유입정보 파싱, 회원 엑셀 '유입경로' 가져오기 스크립트 - 회원 조회: 유입경로·그룹·기간 필터, 유입원 집계 - 강의 신청 기록: 신청 완료 화면이 보내는 공개 API(회원 확인·중복 방지·요청 제한), 오픈카톡 클릭 기록, 관리자 신청 내역 조회 - CORS 다중 도메인, env 검증(운영 필수값), CI e2e 전 마이그레이션 적용, 개발 컨테이너 메모리 한도 2g, 에러 코드 IMWEB_001~005·APPLY_001 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
148 lines
4.6 KiB
YAML
148 lines
4.6 KiB
YAML
name: CI
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
pull_request:
|
|
|
|
# 같은 브랜치에서 새 푸시가 오면 이전 실행을 취소한다
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
backend:
|
|
name: Backend (lint · test · e2e · build)
|
|
runs-on: ubuntu-latest
|
|
# 멈춘 잡이 러너를 무한 점유하지 않도록 상한을 둔다
|
|
timeout-minutes: 20
|
|
defaults:
|
|
run:
|
|
working-directory: backend
|
|
# e2e 는 응답 계약을 실제 HTTP 로 검증하므로 DB 가 필요하다.
|
|
#
|
|
# ⚠️ 호스트 포트 매핑(ports)을 두지 않는다.
|
|
# Gitea Actions 러너는 잡을 **컨테이너로** 실행하고 서비스와 같은 네트워크에 붙여준다.
|
|
# 따라서 서비스 이름(postgres)으로 바로 접근할 수 있고, 호스트 포트는 필요 없다.
|
|
# 오히려 개발 DB 가 이미 5432 를 쓰고 있으면 충돌해 잡 전체가 시작조차 못 한다.
|
|
# (GitHub Actions 는 잡이 VM 위에서 직접 돌아 localhost + ports 를 쓰는 점이 다르다)
|
|
services:
|
|
postgres:
|
|
image: postgres:15-alpine
|
|
env:
|
|
POSTGRES_USER: ci_user
|
|
POSTGRES_PASSWORD: ci_password
|
|
POSTGRES_DB: ci_db
|
|
options: >-
|
|
--health-cmd "pg_isready -U ci_user -d ci_db"
|
|
--health-interval 10s
|
|
--health-timeout 5s
|
|
--health-retries 5
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '20'
|
|
cache: npm
|
|
cache-dependency-path: backend/package-lock.json
|
|
|
|
- run: npm ci
|
|
|
|
# Warning 0 (.claude/rules/checklist.md)
|
|
- name: Lint
|
|
run: npm run lint
|
|
|
|
- name: Test
|
|
run: npm run test
|
|
|
|
# e2e 는 실제 스키마가 필요하다 — 부팅 시 테이블을 읽는 모듈(아임웹 동기화)이 있다.
|
|
# 마이그레이션이 빈 DB 에 깨끗하게 적용되는지도 함께 검증된다.
|
|
- name: Migrate
|
|
run: npm run migration:run
|
|
env:
|
|
NODE_ENV: test
|
|
DB_HOST: postgres
|
|
DB_PORT: 5432
|
|
DB_USER: ci_user
|
|
DB_PASSWORD: ci_password
|
|
DB_NAME: ci_db
|
|
|
|
# 표준 응답 래퍼·에러 코드·traceId 계약 검증 (.claude/rules/response-format.md)
|
|
- name: E2E test
|
|
run: npm run test:e2e
|
|
env:
|
|
NODE_ENV: test
|
|
# 서비스 컨테이너의 네트워크 별칭 (localhost 는 잡 컨테이너 자신을 가리킨다)
|
|
DB_HOST: postgres
|
|
DB_PORT: 5432
|
|
DB_USER: ci_user
|
|
DB_PASSWORD: ci_password
|
|
DB_NAME: ci_db
|
|
|
|
- name: Build
|
|
run: npm run build
|
|
|
|
frontend:
|
|
name: Frontend (lint · type-check · test)
|
|
runs-on: ubuntu-latest
|
|
# 멈춘 잡이 러너를 무한 점유하지 않도록 상한을 둔다
|
|
timeout-minutes: 15
|
|
defaults:
|
|
run:
|
|
working-directory: frontend
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '20'
|
|
cache: npm
|
|
cache-dependency-path: frontend/package-lock.json
|
|
|
|
- run: npm ci
|
|
|
|
- name: Lint
|
|
run: npm run lint
|
|
|
|
- name: Type check
|
|
run: npm run type-check
|
|
|
|
- name: Test
|
|
run: npm run test:unit -- --run
|
|
|
|
error-codes-sync:
|
|
name: 에러 코드 SSOT 동기화 검사
|
|
runs-on: ubuntu-latest
|
|
# 멈춘 잡이 러너를 무한 점유하지 않도록 상한을 둔다
|
|
timeout-minutes: 10
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '20'
|
|
cache: npm
|
|
cache-dependency-path: backend/package-lock.json
|
|
|
|
- name: Install backend deps
|
|
working-directory: backend
|
|
run: npm ci
|
|
|
|
# 레지스트리만 고치고 sync 를 안 돌린 경우를 잡아낸다.
|
|
# 생성 파일이 최신이면 diff 가 비어 있어야 한다.
|
|
- name: Regenerate client error lexicons
|
|
working-directory: backend
|
|
run: npm run sync:error-codes
|
|
|
|
- name: Fail if generated files are stale
|
|
run: |
|
|
if ! git diff --exit-code -- \
|
|
frontend/src/shared/constants/error-codes.generated.ts \
|
|
flutter/lib/core/api/error_lexicon.g.dart; then
|
|
echo ""
|
|
echo "::error::에러 코드 생성 파일이 레지스트리와 어긋났습니다."
|
|
echo "backend 에서 'npm run sync:error-codes' 를 실행하고 생성 파일을 함께 커밋하세요."
|
|
exit 1
|
|
fi
|