Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

167 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

서초구 상인회 — 멀티테넌트 상인회 웹사이트 플랫폼

코드는 cloudflare/ 가 전부입니다. (초기 Node.js 레퍼런스 구현은 정리·제거되었습니다 — git 이력에서 열람 가능.) 개발·테스트·배포 모두 cloudflare/ 에서 진행하세요.

여러 상인회가 각자의 홈페이지를 갖고 운영할 수 있는 멀티테넌트 웹 플랫폼입니다. 슈퍼 관리자가 새 상인회 사이트를 "복제"해 발급하면, 각 상인회는 독립된 데이터·브랜딩·홈페이지 구조를 자유롭게 관리합니다.

외부 의존성 0개. Node.js 22 내장 기능(node:sqlite, node:crypto, node:http)만 사용합니다. npm install 없이 Node만 있으면 바로 실행됩니다.

☁️ 무료로 배포하고 싶다면 → cloudflare/ 폴더에 Cloudflare Workers + D1 + R2 이식 버전이 있습니다. 깃허브 push → 자동 배포, HTTPS 자동, 영구 무료 티어로 운영 가능(영상은 링크 임베드라 트래픽 비용 0). 배포법: cloudflare/DEPLOY-cloudflare.md.

핵심 개념

  • 상인회(Association / 테넌트): 각 상인회는 /t/:slug 주소의 독립 사이트를 가집니다. 업체·공지·행사·회원·브랜딩·홈 구조가 모두 분리됩니다.
  • 사이트 복제: 슈퍼 관리자가 새 상인회를 생성하면 동일 구조의 홈페이지 + 전용 관리자 계정이 발급됩니다. "다른 상인회에서도 쓰고 싶다"는 수요를 그대로 충족합니다.
  • 홈페이지 구조 편집: 복제 후에도 각 상인회 관리자가 홈 섹션의 표시/순서/문구를 독립적으로 바꿀 수 있습니다.
  • 조직 유형(kind): 같은 엔진 위에서 여러 제품이 갈립니다 — merchant(상인회 홈페이지) · esign(전자계약 전용) · franchise(모집 랜딩 + 상담 DB). 제품 소개 페이지는 각각 /, /esign, /homepage.
  • 업종 프리셋: 모집형은 문구만 갈아 끼워 업종을 바꿉니다 — 프랜차이즈 · 학원 · 헬스장 · 병원 · 분양. 정의는 cloudflare/src/kinds.js 한 곳에 있고, 추가 방법은 docs/새-제품-유형-추가하기.md.
  • 사이트 복제: 잘 만든 사이트를 본으로 새 고객사를 찍어 냅니다(화면 구성만 복사, 개인정보는 제외).

역할 (권한)

역할 권한
SUPERADMIN (1인) 플랫폼 전체 관리. 사이트 복제(새 상인회 생성)는 슈퍼 관리자만 보고 조작 가능. 모든 상인회 관리 화면 접근 가능
ADMIN (상인회별) 자기 상인회만 관리 — 업체 승인, 공지·행사, 브랜딩, 홈페이지 구조 편집
MERCHANT (업체) 자기 업체 페이지만 관리 — 정보 수정, 사진·영상 업로드

주요 기능

  • 🔐 로그인/회원가입 — scrypt 해시 + HMAC 서명 세션 쿠키(httpOnly), 3단계 역할
  • 🏢 멀티테넌트 — 상인회별 독립 사이트(/t/:slug), 데이터 완전 격리
  • 🎨 상인회별 브랜딩 — 대표 색상이 사이트 전체 팔레트에 자동 반영
  • 🧩 홈페이지 구조 편집기 — 섹션 켜기/끄기 · 순서 변경 · 문구 수정 (상인회마다 다른 구조)
  • 🏪 업체별 페이지 — 고유 URL, 소개·연락처·사진/영상 갤러리
  • 📸 사진·영상 업로드 — 드래그앤드롭, 직접 구현한 multipart 파서, 영상 Range 스트리밍
  • 📊 관리자 대시보드 — 상인회별 통계, 업체 승인/반려, 공지·행사 CRUD
  • 🛡 슈퍼 관리자 콘솔 — 상인회 생성(복제)·운영/중지, 플랫폼 전체 통계
  • 🏁 프랜차이즈 가맹점 모집 랜딩 — 한 장짜리 모집 페이지(강점·후기·절차·비용·상담 폼), 초안→발행·사진 보관함·캠페인별 사본
  • 📇 상담 신청 DB — 상태·메모·CSV, 전환율·광고 출처(UTM)·랜딩별 성과 집계, 알림톡 통지, 상담→가맹계약서 연결, 보관 기간 경과 건 자동 파기
  • 📱 완전 반응형 — 모바일·태블릿·데스크톱, 모바일 햄버거 메뉴

빠른 시작

# 요구사항: Node.js 22.5 이상
npm run seed     # 슈퍼관리자 + 기본 상인회(서초구) + 샘플 데이터
npm start        # http://localhost:3000

기본 계정 (시드 후)

역할 이메일 비밀번호 로그인 후
슈퍼 관리자 super@platform.kr super1234 /super
서초구 관리자 admin@seocho-merchants.kr admin1234 /t/seocho/admin
샘플 업체 jung@ex.kr 외 3개 merchant1234 /t/seocho/dashboard

⚠️ 운영 시 SUPERADMIN_EMAIL/PASSWORD, ADMIN_EMAIL/PASSWORD, SESSION_SECRET 환경 변수를 반드시 설정·변경하세요.

실서비스 배포

도메인 연결·HTTPS·서버 구동은 DEPLOY.md 참고.

  • 가장 쉬운 길(서버 관리 없음): Render — 저장소의 render.yaml 로 깃허브 연결 → 자동 배포·URL·HTTPS. 영속 디스크(유료 플랜) 필요.
  • 직접 서버(VPS): Dockerfile(ffmpeg 포함) · docker-compose.yml · Caddyfile(HTTPS 자동) · deploy/website.service(systemd) · .env.example. cp .env.example .env → 값 채우기 → docker compose run --rm app npm run seedDOMAIN=your.kr docker compose --profile edge up -d.

사용 흐름

  1. 슈퍼 관리자가 /super에서 새 상인회 사이트 만들기(복제) — 이름·색상·관리자 계정 입력 → /t/새슬러그 사이트 생성
  2. 발급된 상인회 관리자가 /t/:slug/admin에서 홈페이지 구조·브랜딩을 원하는 대로 편집
  3. 업체 사장님이 /t/:slug/register로 가입 → 사진·영상 업로드 → 관리자 승인 후 공개

프로젝트 구조

website/
├── package.json
├── src/
│   ├── server.js          # HTTP 서버 + 멀티테넌트 라우터 + 권한
│   ├── config.js          # 설정
│   ├── db.js              # SQLite 스키마 + 경량 마이그레이션
│   ├── auth.js            # 비밀번호 해시 · 세션 · 역할 헬퍼
│   ├── associations.js    # 상인회(테넌트) 관리 + 사이트 복제 로직
│   ├── homeLayout.js      # 홈페이지 구성 카탈로그 · 기본값 · 렌더링
│   ├── models.js          # 테넌트 스코프 도메인 쿼리
│   ├── storage.js         # 파일 스토리지 추상화 (클라우드 전환 지점)
│   ├── multipart.js       # multipart/form-data 파서
│   ├── http.js · render.js
│   ├── seed.js
│   └── handlers/
│       ├── pages.js       # 페이지 렌더링 (플랫폼·테넌트·대시보드·슈퍼)
│       └── api.js         # 폼 액션 (인증·업체·미디어·관리·복제·레이아웃)
├── public/
│   ├── css/app.css
│   └── js/                # app.js · dashboard.js · layout-editor.js
└── data/                  # app.db + uploads/ (런타임 생성, .gitignore)

주소 방식: 경로 vs 서브도메인

기본은 경로 기반(/t/:slug)이며, BASE_DOMAIN 환경 변수를 설정하면 서브도메인 라우팅이 자동 활성화됩니다.

모드 설정 상인회 주소 플랫폼(루트)
경로 (기본) example.com/t/seocho example.com/
서브도메인 BASE_DOMAIN=example.com seocho.example.com example.com/ (apex)

서브도메인 모드에서는 내부 링크가 루트 상대경로로 바뀌고, 로그인 후 리다이렉트는 해당 상인회의 절대 URL(https://seocho.example.com/admin)로 이동합니다. DNS 는 와일드카드 레코드(*.example.com)를 서버로 향하게 설정하세요.

클라우드 스토리지 (S3 / R2 / MinIO)

기본은 로컬 저장(data/uploads)입니다. STORAGE_DRIVER=s3 로 전환하면 외부 SDK 없이 AWS Signature V4 를 직접 구현한 클라이언트(src/s3.js)로 S3 호환 스토리지에 업로드합니다. 서명 로직은 AWS 공식 테스트 벡터로 검증됩니다.

npm run test:s3   # SigV4 서명 자체 검증 (네트워크 불필요)
변수 설명
STORAGE_DRIVER local(기본) 또는 s3
S3_BUCKET / S3_REGION 버킷 이름 / 리전
S3_ACCESS_KEY_ID / S3_SECRET_ACCESS_KEY 자격 증명
S3_ENDPOINT R2/MinIO 커스텀 엔드포인트 (AWS 는 비워둠)
S3_PUBLIC_BASE_URL 퍼블릭/CDN URL 베이스 (예: https://cdn.example.com)
S3_FORCE_PATH_STYLE MinIO 등에서 true

스토리지 인터페이스(save/remove/publicUrl)는 동일하므로 미디어·로고 업로드 코드는 드라이버와 무관하게 동작합니다.

미디어: 사진 업로드 + 영상 링크 임베드

사진은 직접 업로드, 영상은 외부 링크 임베드로 나눠 처리합니다. 영상을 자체 저장·전송하지 않으므로 스토리지·트래픽 비용이 들지 않습니다.

  • 사진: 업체 대시보드에서 드래그앤드롭 또는 파일 선택으로 여러 장 한 번에 업로드(JPG·PNG·WebP·GIF, 최대 8MB). 매직바이트로 실제 형식 검증.
  • 영상(임베드): 유튜브·유튜브 쇼츠·인스타그램 릴스·네이버TV 주소를 붙여넣으면 링크만 저장하고, 서버가 URL을 파싱해 provider + 영상 ID만 추출·검증합니다. 렌더는 신뢰 도메인 iframe(유튜브는 youtube-nocookie)으로만 이뤄지며, CSP frame-src도 그 도메인만 허용합니다. 업체당 최대 개수(MAX_EMBEDS_PER_BUSINESS, 기본 30).
  • 업체 페이지·대시보드에서 사진·영상을 클릭하면 **전체화면 뷰어(라이트박스)**가 열립니다:
    • 세로 영상(릴스·쇼츠형)은 9:16, 유튜브는 16:9 비율로 표시.
    • 좌우 화살표·키보드(←/→/Esc)·모바일 스와이프로 넘기기.
  • 갤러리 썸네일에는 제공자 배지(YouTube/Instagram/네이버TV)와 재생(▶) 아이콘이 표시됩니다. 유튜브는 무료 정적 썸네일(i.ytimg.com)을 사용합니다.

참고: 기존에 직접 업로드된 영상(레거시 video 종류)도 계속 재생됩니다. 신규 영상은 링크 임베드만 지원합니다.

미디어 처리 파이프라인 (ffmpeg 자동 감지)

사진 업로드 시 src/media.js 가 실행됩니다. ffmpeg 시스템 바이너리가 있으면 자동으로:

  • 이미지 썸네일: 긴 변 최대 600px로 축소한 썸네일을 생성해 목록·갤러리 그리드에 사용(원본은 뷰어 클릭 시 로드). PNG는 투명도 보존, 애니메이션 GIF는 원본 유지, 축소본이 원본보다 클 때는 원본 사용. 목록 전송량이 크게 줄어듭니다.
  • (레거시) 직접 업로드된 영상이 있으면 H.264 mp4 정규화 + 포스터 추출 로직도 그대로 남아 있습니다.

ffmpeg 가 없으면 원본을 그대로 통과시킵니다(안전한 폴백). 즉 실제 서버에 ffmpeg 만 설치하면 코드 변경 없이 이미지 썸네일이 켜집니다. 서버 시작 로그에 현재 상태(미디어: ffmpeg 있음/없음)가 표시됩니다.

변수 기본값 설명
MEDIA_TRANSCODE true ffmpeg 존재 시 영상 mp4(H.264) 정규화
MEDIA_POSTER true ffmpeg 존재 시 영상 포스터 프레임 추출

참고: 이미지 리사이즈/최적화(sharp 등)는 포함하지 않았습니다. 대량 트래픽 환경에서는 CDN 또는 외부 이미지 최적화 서비스를 앞단에 두는 것을 권장합니다.

상인회별 로고

각 상인회 관리자는 대시보드의 브랜딩 패널에서 로고 이미지를 업로드할 수 있습니다(PNG·JPG, 최대 2MB). 업로드 시 헤더·푸터·플랫폼 카드의 이니셜이 로고로 대체되며, 삭제하면 다시 이니셜로 표시됩니다.

보안

심층 방어(defense-in-depth)를 적용했습니다:

  • 인증: scrypt 비밀번호 해시, HMAC 서명 httpOnly 세션 쿠키(만료 포함).
  • CSRF: double-submit 쿠키 토큰을 모든 POST 폼에 자동 주입하고 서버에서 검증(SameSite=Lax 와 병행).
  • 로그인 시도 제한: IP별 슬라이딩 윈도우(기본 15분/8회) 레이트리밋.
  • 세션 무효화: users.session_version 기반. 값을 올리면 해당 사용자의 모든 기존 세션이 즉시 무효화(탈취·비밀번호 변경 대응). bumpSessionVersion(userId) 제공.
  • 업로드 검증: 클라이언트가 선언한 MIME 를 믿지 않고 매직바이트로 실제 형식 판별(위장 업로드 차단) + 용량 제한 + 동시 업로드 수 제한(메모리 보호).
  • 기타: 전 출력 HTML 이스케이프(XSS 방지), 테넌트 간 데이터 접근 차단, 정적/업로드 경로 이탈 방지, 시작 시 설정 검증(운영 시크릿/스토리지 자격증명 누락 시 종료).

SEO

  • 모든 페이지에 meta description, Open Graph, Twitter Card.
  • 업체 상세: schema.org LocalBusiness 구조화 데이터(JSON-LD) + 대표 이미지 og:image → 구글 검색·지도 노출 최적화.
  • 홈: Organization 구조화 데이터.
  • /sitemap.xml: 호스트 인식 동적 생성(서브도메인=해당 상인회, apex=전체 상인회+업체).
  • /robots.txt: 관리/대시보드 경로 제외, Sitemap 링크.

성능 최적화

  • gzip 압축: HTML·CSS·JS·JSON·XML 응답을 Accept-Encoding에 따라 gzip 스트리밍(이미지·영상 제외). 예: HTML ~68%, CSS ~77% 절감.
  • DB 인덱스 + 페이지네이션: 주요 컬럼 인덱스, 목록은 LIMIT/OFFSET.
  • N+1 제거: 업체 카드 대표 이미지를 단일 쿼리(getCoverImage)로 조회(전체 미디어 미로드).
  • 캐시 헤더: 정적 자산·업로드에 Cache-Control: max-age=3600. 영상은 HTTP Range 스트리밍.
  • 경량: 의존성 0 → 빠른 콜드스타트. 이미지 lazy-load, 업로드 동시성 제한.

이미지 썸네일·리사이즈는 ffmpeg 파이프라인으로 구현됨(위 미디어 처리 참고). 남은 최적화(외부/대규모): 업로드 완전 스트리밍 파서, CDN, 정적 자산 fingerprint 불변 캐시.

운영 메모

  • 영속성: data/(DB·로컬 업로드)는 재시작 시 유지되도록 영속 볼륨에 두세요. S3 모드에서는 미디어가 클라우드에 저장되므로 DB만 영속화하면 됩니다.
  • 접근성: 미디어 뷰어는 포커스 트랩·포커스 복원·키보드 조작(←/→/Esc/Tab)·aria-modal 지원.

알림 & 비밀번호 재설정 (외부 이메일 서비스 없이 내부 완결)

이메일로 처리하던 일을 외부 서비스 없이 앱 내부에서 해결합니다:

  • 앱 내 알림함: 신규 업체 가입·비밀번호 재설정 요청이 관리자/슈퍼관리자 대시보드의 알림함에 표시됩니다(미읽음 배지·모두 읽음). 승인 워크플로우가 이메일 없이 닫힙니다.
  • 관리자 주도 비밀번호 재설정: 회원이 로그인 화면의 **"비밀번호를 잊으셨나요?"**로 요청하면 소속 상인회 관리자에게 알림이 갑니다. 관리자는 회원 관리 패널에서 임시 비밀번호를 발급(발급 시 기존 세션 전부 해제)하고, 회원은 로그인 후 계정 → 비밀번호 변경에서 바꿉니다. 슈퍼관리자는 관리자 계정을 동일하게 재설정합니다.
  • 메일 훅: src/mailer.js. 기본 MAIL_DRIVER=log는 외부 서비스 없이 콘솔에 기록만 합니다(내부 완결·감사 로그).

한 가지 구조적 한계(정직하게): 지메일·네이버 등 외부 메일함으로의 실제 배달만은 내부에서 불가능합니다 — 수신자 메일서버로 보내려면 SMTP 릴레이(회사 메일서버·SES·SendGrid·Gmail SMTP 등)가 반드시 필요합니다. 이는 코드가 아니라 이메일 프로토콜의 요구사항입니다. 실제 발송이 필요해지면 src/mailer.jssendSmtp만 구현하고 MAIL_DRIVER=smtp로 전환하면 됩니다(알림·재설정 흐름은 그대로 유지).

회원 게시판

/t/:slug/board — 상인회 회원 전용 소통 게시판입니다.

  • 접근 권한: 해당 상인회 소속 회원(MERCHANT)·관리자(ADMIN)·슈퍼관리자만 열람/작성. 비로그인·타 상인회 사용자는 차단(로그인 유도).
  • 기능: 글 작성·목록(페이지네이션)·상세, 댓글, 상단 고정(관리자), 삭제(작성자 본인 또는 관리자 모더레이션).
  • 글 수정: 작성자 본인 또는 관리자가 제목·본문·첨부 이미지를 수정. 수정 시각(수정됨)이 표시됩니다.
  • 이미지 첨부(다중): 글마다 사진 최대 6장 첨부(매직바이트 검증·각 8MB, ffmpeg 있으면 썸네일 생성). 목록에 대표 썸네일·📎장수 표시, 상세에 라이트박스 갤러리, 수정 화면에서 사진 개별 삭제·추가.
  • 검색: 제목·본문 키워드 검색(LIKE 와일드카드 이스케이프). 페이지네이션과 함께 동작.
  • 모든 입력은 길이 제한·XSS 이스케이프·CSRF 검증 적용. 테넌트 간 완전 격리.

가입 점포 지도 (네이버 지도 API)

/t/:slug/map 에서 가입 점포 전체를 지도 위 마커로 표시합니다. 마커 클릭 시 업체명·업종·주소·상세 링크가 뜨고, 카테고리 필터를 지원합니다.

  • 좌표 입력: 업체 사장님이 대시보드에서 위도·경도를 직접 입력하거나(키 있을 때) 지도를 클릭해 지정합니다. 관리자는 브랜딩에서 지도 기본 중심을 설정합니다.
  • 네이버 지도 키: 네이버 클라우드 플랫폼 Maps 에서 발급한 클라이언트 ID 를 NAVER_MAP_CLIENT_ID 로 설정하고, 콘솔에 서비스 도메인을 등록하세요. (로더 파라미터명은 콘솔 버전에 따라 NAVER_MAP_PARAM=ncpKeyId 또는 ncpClientId)
  • 키 없이도 동작(폴백): 키가 없으면 점포 목록 + 각 점포의 "네이버 지도에서 열기" 딥링크로 자연스럽게 폴백합니다. 키를 넣으면 즉시 인터랙티브 지도로 전환됩니다.
  • CSP 는 키가 설정된 경우에만 네이버 도메인(oapi.map.naver.com, *.pstatic.net)을 허용합니다.
변수 설명
NAVER_MAP_CLIENT_ID 네이버 지도 클라이언트 ID (없으면 폴백)
NAVER_MAP_PARAM 로더 파라미터명 (기본 ncpClientId, 신규 콘솔은 ncpKeyId)

전자서명 (자체 구현, 외부 서비스 없이)

상인회 동의서·계약·회칙 동의 등을 플랫폼 안에서 전자서명합니다.

  • 문서: 관리자가 서명 문서(제목+본문)를 생성. 무결성을 위해 본문은 생성 후 불변이며 SHA-256 해시로 고정됩니다.
  • 서명: 회원이 대시보드의 서명 요청을 열어 캔버스로 서명을 그리고, 성명·동의 확인 후 제출합니다.
  • 무결성·감사추적: 서명 시 서명자·시각·IP·기기(UA)·문서 해시가 기록되고, 전체 기록이 Ed25519 디지털 서명으로 봉인됩니다. 공개 **검증 페이지 /verify/:code**에서 봉인·본문 무결성을 확인 — 문서 본문이나 기록이 변경되면 **"위변조 의심"**으로 즉시 드러납니다.
  • 공개키 독립 검증: 봉인이 대칭키(HMAC)가 아니라 **비대칭 서명(Ed25519)**이라, 서버 비밀 없이 공개키만으로 제3자가 독립 검증할 수 있습니다(부인방지). 개인키는 data/sign_key.json(gitignore)에 영속되며 운영에선 SIGN_PRIVATE_KEY(PEM) 환경변수 권장.
  • 증명서·검증 파일: /verify/:code/certificate 인쇄용 증명서(@media print), /verify/:code/receipt.json 다운로드 — canonical·서명·공개키가 담겨 오프라인에서도 재검증 가능.
  • 지정·다자 서명: 문서 생성 시 전체 회원 또는 특정 회원 지정으로 서명 요청. 지정 대상만 대시보드에 요청이 표시되고, 관리자는 문서별 **서명 완료 현황(누가 서명/미서명, 진행률)**을 추적합니다.
  • 순차 서명(고도화): 문서를 순차 서명으로 만들면 지정한 순서(1→N)대로만 서명 가능 — 앞 순번이 완료되기 전에는 다음 순번에게 요청이 노출되지 않고 서버에서도 차단됩니다. 관리자 화면에서 현재 서명 차례와 순번별 상태를 확인합니다. (계약서 순차 결재/연대 서명에 적합)
  • 서명 기한(고도화): 문서에 **마감일(due date)**을 지정하면 기한이 지난 뒤 서명이 자동 차단되고, 목록·상세에 기한 배지가 표시됩니다.
  • 관리자: 문서별 서명 내역·검증 상태를 표로 확인, 마감 처리.

법적 관점(정직하게): 개정 **전자서명법(2020)**으로 공인인증서 독점이 폐지되어, 위와 같은 로그인 신원확인 + 서명 의사(동의) + 위변조 방지(해시/봉인) + 감사추적을 갖춘 일반 전자서명은 다수 용도에서 효력을 가질 수 있습니다. 다만 **공인 전자서명·휴대폰 본인확인·공인 타임스탬프(TSA)**가 필요한 고강도 용도는 외부 인증기관 연동이 필수이며, 이는 향후 연동 지점으로 남겨둡니다(자체 불가 — 프로토콜·법규 구조상).

테스트

  • 통합 테스트: npm test — 임시 DB로 서버를 띄워 HTTP로 검증(홈·테넌트·404·보안헤더·CSRF·로그인/역할·권한·테넌트 격리·JSON-LD·검색·게시판·회원 CSV·공지 카테고리/검색·영상 임베드/CSP·점포 지도·sitemap/robots·헬스체크·비밀번호 재설정·전자서명 생성/서명/검증). 24개, 외부 의존성 없음.
  • S3 서명 테스트: npm run test:s3 — AWS 공식 벡터로 SigV4 검증.

더 이상적으로 — 다음 단계(외부 서비스 필요, 훅 준비됨)

이 환경(패키지 설치 제한)에서 완결하기 어려운, 실제 운영에서 붙이면 좋은 항목:

  • 외부 메일 실제 배달만: 가입/승인/재설정은 위처럼 내부 알림으로 완결됨. 외부 메일함 배달이 필요할 때만 SMTP 릴레이 연결(MAIL_DRIVER=smtp).
  • 데이터베이스: 트래픽 증가 시 SQLite → PostgreSQL(비동기·다중 writer). 데이터 접근이 models.js 로 격리돼 있어 교체 지점 명확.
  • 백그라운드 잡 큐: 영상 트랜스코딩을 업로드 응답과 분리(업로드 즉시 완료 → "처리중" → 완료 시 갱신).
  • 지도 임베드: 주소 지오코딩 + 지도 표시.
  • 스트리밍 업로드: 현재는 동시성 세마포어로 메모리를 바운드. 초대용량 대비 완전한 디스크 스트리밍 multipart 파서.
  • 관측성·백업: 접근 로그는 내장. 에러 추적(외부 APM)·DB/업로드 백업 자동화.

환경 변수 요약

변수 기본값 설명
PORT / HOST 3000 / 0.0.0.0 서버 바인딩
SESSION_SECRET (개발용) 세션 서명 키 — 운영 필수 변경
BASE_DOMAIN 설정 시 서브도메인 라우팅 활성화
PUBLIC_SCHEME https 서브도메인 절대 URL 스킴
STORAGE_DRIVER local local 또는 s3
S3_* 위 스토리지 표 참고
MEDIA_TRANSCODE / MEDIA_POSTER true ffmpeg 존재 시 영상 정규화/포스터
MAX_CONCURRENT_UPLOADS 3 동시 업로드 수 제한(메모리 보호)
MAX_EMBEDS_PER_BUSINESS 30 업체당 영상 링크(임베드) 최대 개수
SUPERADMIN_EMAIL/PASSWORD 시드 기본값 슈퍼관리자 계정
ADMIN_EMAIL/PASSWORD 시드 기본값 기본 상인회 관리자
NODE_ENV production 시 쿠키 Secure 부여

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages