Files
reloop-v2/README.md
reloop 3d7866be7e chore(deploy): postinstall, standalone, PM2 ecosystem, README — QA-6.C2 C4 M1 M2
backend/package.json
- Add 'postinstall: prisma generate' — fresh pnpm install now produces
  a usable @prisma/client without a manual step.
- Add engines.node >= 20 and packageManager pnpm@9.12.0.

frontend/package.json
- Same engines + packageManager pin.

frontend/next.config.js
- output: 'standalone' enabled for PM2's .next/standalone/server.js
  pattern (reduces production bundle size, removes runtime node_modules
  dependency for the web process).

frontend/.env.example (new)
- Documents NEXT_PUBLIC_API_URL as a BUILD-TIME variable.

ecosystem.config.js (new)
- PM2 config for reloop-api (cwd=backend, script=dist/main.js, port
  3001) and reloop-web (cwd=frontend, script=.next/standalone/server.js,
  port 3000, HOSTNAME=0.0.0.0). max_memory_restart=512M each with
  separate error/out log files.

README.md (new)
- Root deploy guide: stack, env vars table (backend + frontend),
  local dev quickstart, prod deploy steps (rsync → pnpm install
  --frozen-lockfile → prisma migrate deploy → build → copy .next/static
  and public into standalone → pm2 start), reverse proxy mapping,
  pm2 ops. Also covers Cluster F items: 'Dev VM 에서 prisma migrate
  dev --name init' for migrations and 'pnpm install' for lockfile
  generation.

.gitignore
- Ignore .claude/state/session* + .claude/state/*.lock +
  .claude/sessions/ (ephemeral harness runtime metadata).
2026-04-12 00:09:40 +09:00

2.9 KiB

ReLoop v2

적응형 복습 스케줄링 기반 수능 학습 최적화 플랫폼. 페르소나 망각 곡선(persona-based forgetting curve)으로 개인화된 복습 간격을 산출한다.

Stack

  • Backend: NestJS 10 + Prisma 5 + MariaDB, JWT 인증
  • Frontend: Next.js 14 (App Router) + React 18 + styled-components 6
  • Deploy: PM2 on Debian VM, nginx/Caddy reverse proxy

Environment variables

Backend (backend/.env)

Var Required Default Description
DATABASE_URL mysql://user:pass@host:3306/reloop
JWT_SECRET long random string; boot fails without it
JWT_EXPIRES_IN 30d access token TTL
CORS_ORIGINS https://reloop.nabomhalang.co.kr,http://localhost:3000 comma-separated
PORT 3001 NestJS HTTP port

Frontend (frontend/.env at build time)

Var Required Default
NEXT_PUBLIC_API_URL https://reloop-api.nabomhalang.co.kr/api

NEXT_PUBLIC_* 변수는 빌드 시점에 클라이언트 번들에 박힘. 배포 환경별로 다른 값을 쓰려면 환경마다 다시 빌드해야 함.

Local development

# 1. Install
cd backend && pnpm install && cd ..
cd frontend && pnpm install && cd ..

# 2. Backend DB setup (first time)
cd backend
cp .env.example .env   # edit DATABASE_URL, JWT_SECRET
pnpm prisma migrate dev --name init
pnpm prisma:seed
pnpm dev

# 3. Frontend
cd frontend
cp .env.example .env.local
pnpm dev

Production deploy (Dev VM)

# Sync sources
rsync -avz --delete \
  --exclude node_modules --exclude .next --exclude dist \
  /path/to/reloop-v2/ dev:/home/deploy/reloop-v2/

# On Dev VM
cd /home/deploy/reloop-v2

# Backend
cd backend
pnpm install --frozen-lockfile           # postinstall runs prisma generate automatically
pnpm prisma migrate deploy               # apply migrations to prod DB
pnpm build                               # produces dist/main.js
cd ..

# Frontend
cd frontend
pnpm install --frozen-lockfile
NEXT_PUBLIC_API_URL=https://reloop-api.nabomhalang.co.kr/api pnpm build
# Copy static assets next to the standalone server
cp -r .next/static .next/standalone/.next/
cp -r public .next/standalone/ 2>/dev/null || true
cd ..

# PM2 boot
pm2 start ecosystem.config.js
pm2 save

Reverse proxy (nginx/Caddy)

  • reloop.nabomhalang.co.kr127.0.0.1:3000 (frontend)
  • reloop-api.nabomhalang.co.kr127.0.0.1:3001 (backend)

Backend allows the frontend domain via CORS_ORIGINS.

Operations

pm2 status                      # show reloop-api / reloop-web
pm2 logs reloop-api             # tail backend
pm2 reload ecosystem.config.js  # zero-downtime restart after redeploy

QA

.qa/ 아래에 Breezing QA 리포트 6개가 있어. Plans.md.claude/state/pending-fix-proposals.jsonl 에 후속 fix 이력이 있음.