사부작의 타임캡슐 생성, 조회, 수정, 삭제와 익명 메시지 작성을 담당하는 Express + TypeScript 기반 백엔드 서버입니다.
Zod 기반 입력 검증, OpenAPI 문서 생성, PostgreSQL 연동을 중심으로 MVP API를 구성하고 있습니다.
"미래의 나와 우리에게 남기는 메시지"
사부작은 특정 시점에 열리는 타임캡슐을 만들고, 그 안에 익명 메시지를 모아 공개 시점 이후 함께 확인하는 서비스입니다.
이 저장소는 프론트엔드와 협업하기 위한 REST API, OpenAPI 문서, 로컬 개발 환경 구성을 포함합니다.
| Service | URL |
|---|---|
| Frontend | webfull-9-10-sabujak-fe.vercel.app |
| Swagger UI | webfull-9-10-sabujak-be.onrender.com/api-docs |
- 타임캡슐 생성 및 공개 시점 기반 상태 관리
- 슬러그 예약 기반 중복 방지 흐름
- 공개 전/후 단일 조회 API 제공
- 익명 메시지 작성 및 닉네임 중복 제어
- Swagger UI와 OpenAPI JSON 제공
- Docker Compose 기반 로컬 개발 환경 지원
| Category | Stack |
|---|---|
| Runtime | Node.js 20+, TypeScript |
| Server | Express 5 |
| Validation | Zod |
| API Docs | @asteasolutions/zod-to-openapi, Swagger UI |
| Database | PostgreSQL, Redis |
| Tooling | pnpm, ESLint, Prettier, Husky |
| Infra | Docker Compose |
flowchart LR
FE["Frontend Client"] -->|HTTP Request| API["Express API Server"]
API --> ROUTER["Route Layer"]
ROUTER --> CTRL["Controller"]
CTRL --> VALID["Zod DTO Validation"]
CTRL --> SERVICE["Service"]
SERVICE --> REPO["Repository"]
REPO --> DB[("PostgreSQL")]
REPO --> REDIS[("Redis")]
API --> DOCS["Swagger UI / OpenAPI"]
DOCS --> SPEC["openapi.json"]
subgraph PIPE["Schema-to-Client Pipeline"]
DTO["src/modules/*/dto"] --> REG["OpenAPI Registry"]
REG --> SPEC
SPEC --> ORVAL["Orval Client Generation"]
ORVAL --> FECLIENT["Frontend API Client"]
end
subgraph DEPLOY["Deployment Architecture"]
VERCEL["Vercel Frontend"] --> RENDER["Render Backend"]
RENDER --> NEON[("Neon PostgreSQL")]
end
DTO -.schema source.-> VALID
FECLIENT --> FE
VERCEL -.client requests.-> FE
RENDER -.runtime environment.-> API
NEON -.managed database.-> DB
사부작 백엔드는 Express 라우터가 요청을 받고, Controller가 입력 DTO를 Zod로 검증한 뒤 Service와 Repository를 거쳐 PostgreSQL/Redis와 통신합니다.
또한 src/modules/*/dto에서 정의한 Zod 스키마를 src/openapi/registry.ts에 등록해 OpenAPI 문서를 만들고, 그 산출물을 프론트엔드 Orval 클라이언트와 맞추는 흐름을 사용합니다.
.
├── src
│ ├── app.ts
│ ├── main.ts
│ ├── routes.ts
│ ├── common
│ ├── db
│ ├── modules
│ │ ├── capsules
│ │ │ └── dto
│ │ └── system
│ ├── openapi
│ └── redis
├── docs
│ ├── API_SPEC.md
│ ├── ERD.md
│ ├── architecture-guide.md
│ ├── db-guide.md
│ ├── reports
│ └── reviews
├── scripts
├── openapi.json
├── docker-compose.yml
└── README.md
| 산출물 | 정본 위치 | 설명 |
|---|---|---|
| 백엔드 unit/integration 테스트 코드 | 백엔드 레포 | 구현과 함께 변경되는 검증 자산 |
| 백엔드 기술 문서 | 백엔드 docs/ |
아키텍처, API, 스키마 문서 |
| 블랙박스 QA 결과 보고서 | QA 레포 docs/reports/backend/ |
smoke/regression, 장애보고서, 대응 계획 |
- 기능 요구사항을 기준으로
docs/API_SPEC.md와 필요 시docs/ERD.md를 먼저 갱신합니다. - DB 스키마는
src/db/schema.ts와drizzle/*만 정본으로 관리하고,pnpm run db:generate -> db:migrate -> db:schema:export -> db:schema:check순서로 반영합니다. docs/schema.sql은 Drizzle 기준 참조 스냅샷이며 직접 실행하지 않습니다.- 배포 환경에서는 앱 기동 전에 운영
DATABASE_URL기준pnpm run db:migrate를 먼저 실행하고, 서버 시작이 migration을 대체하지 않도록 유지합니다. src/modules/*/dto/에 Zod 스키마를 정의하고, 필요한 경우controller,service,repository를 순서대로 보강합니다.src/openapi/registry.ts에 경로와 스키마를 등록한 뒤pnpm run openapi:generate또는pnpm run openapi:check로 산출물을 맞춥니다.- 생성된
openapi.json을 기준으로 프론트엔드에서 Orval 클라이언트를 동기화합니다. - Swagger UI, 로컬 실행, 배포 환경(Render/Neon)에서 최종 동작을 확인합니다.
- Node.js
20+ - pnpm
9.x - Docker / Docker Compose
corepack enable
corepack use pnpm@9.0.0
pnpm installpackage.json의 packageManager와 동일한 pnpm major를 사용해야 lockfile 해석 차이로 인한 의존성 누락을 피할 수 있습니다.
cp .env.example .env필요 시 .env에서 포트, DB 연결 정보, CORS 허용 출처를 프로젝트 환경에 맞게 수정합니다.
docker compose up --build기본적으로 API 서버, PostgreSQL, Redis가 함께 실행됩니다.
DB와 Redis가 준비되어 있다면 아래 명령으로 개발 서버를 실행할 수 있습니다.
pnpm dev| Command | Description |
|---|---|
pnpm dev |
개발 서버 실행 |
pnpm build |
프로덕션 번들 생성 |
pnpm start |
빌드 결과 실행 |
pnpm typecheck |
타입 검사 |
pnpm lint |
린트 검사 |
pnpm lint:fix |
린트 자동 수정 |
pnpm test |
Jest 테스트 실행 |
pnpm test:unit |
동일한 Jest 테스트 실행 |
pnpm db:generate |
Drizzle migration 생성 |
pnpm db:migrate |
Drizzle migration 적용 |
pnpm db:schema:export |
docs/schema.sql 스냅샷 갱신 |
pnpm db:schema:check |
DB 스키마 워크플로우 검증 |
pnpm db:repair:legacy-drift |
legacy drift 수동 복구 |
pnpm openapi:generate |
OpenAPI 문서 생성 |
pnpm openapi:check |
OpenAPI 산출물 검증 |
pnpm test:rate-limit |
rate limit 관련 스크립트 실행 |
로컬 실행 기준 주요 접근 경로입니다.
| Path | Description |
|---|---|
/ |
기본 확인용 엔드포인트 |
/healthCheck |
서버 상태 확인 |
/openapi.json |
OpenAPI 스펙 |
/api-docs |
Swagger UI |
/capsules/* |
타임캡슐 관련 API |
자세한 예시는 .env.example에 정리되어 있습니다.
| Variable | Description |
|---|---|
NODE_ENV |
실행 환경 |
API_PORT |
API 서버 포트 |
POSTGRES_USER |
로컬 PostgreSQL 계정 |
POSTGRES_PASSWORD |
로컬 PostgreSQL 비밀번호 |
POSTGRES_DB |
로컬 PostgreSQL DB 이름 |
DATABASE_URL |
DB 연결 문자열 |
REDIS_URL |
로컬 Redis 연결 문자열 |
CORS_ORIGIN |
허용할 CORS origin 목록 |
CHOKIDAR_USEPOLLING |
Docker 개발 환경 파일 감시 옵션 |
UPSTASH_REDIS_REST_URL |
Upstash Redis REST URL |
UPSTASH_REDIS_REST_TOKEN |
Upstash Redis REST 토큰 |
| 프로필 | 이름 | 역할 | GitHub |
|---|---|---|---|
![]() |
이윤하 | Backend | @labyrinth30 |
![]() |
김인수 | Backend | @insu1170 |
![]() |
한재민 | Frontend | @s576air |
![]() |
송창욱 | Frontend | @supersoldier132 |
![]() |
이연희 | Frontend | @yomiyoni |
- API 변경 시
docs/API_SPEC.md와openapi.json을 함께 갱신합니다. - 데이터 모델 변경 시
docs/ERD.md와docs/db-guide.md흐름도 함께 반영합니다. - DB 변경은 수동 SQL 대신 Drizzle migration만 사용합니다.
- 배포 시 DB migration은 앱 시작 전에 한 번만 실행하고, 서버 재기동으로 스키마를 맞추지 않습니다.
- 외부 입력은 Zod 스키마로 검증하는 규칙을 유지합니다.
- 민감 정보는
.env.example이 아닌 실제.env또는 배포 환경 변수로 관리합니다.




