📊 이슈 ETF 시스템 문서

정치 이슈별 구성종목 묶음 상품 — 시스템이 AP(지정참가회사) 역할 수행

1. 라이프사이클

발제펀딩선발상장(Active)리밸런싱해산
단계설명주요 행위자
펀딩시드 자금 모집, 확신 보증금 10,000 Voice발제자 + 시드펀더
선발정치인 신청 + 시드펀더 O/X 투표 (50% 이상 찬성)정치인 + 시드펀더
상장시드머니로 구성종목 매입, ETF 주식 발행시스템(AP)
거래NAV 기반 매수(생성)/매도(환매), ±0.5% 스프레드일반 사용자
리밸런싱90일 주기, 보유자 투표로 구성종목 교체ETF 보유자
해산투표 또는 구성종목 부족 시 자동시스템

2. 사용자 API

메서드경로설명
GET/api/etf/get-etfsETF 목록 조회
POST/api/etf/create-proposalETF 발제 (확신 보증금 차감)
POST/api/etf/contribute-funding펀딩 참여 (Voice 차감)
POST/api/etf/politician-apply정치인 신청
POST/api/etf/vote-selection선발 투표 (시드펀더만)
POST/api/etf/buy-etfETF 매수 (NAV + 0.5%)
POST/api/etf/sell-etfETF 매도 (NAV - 0.5%, 보유량 검증)
POST/api/etf/rebalance리밸런싱 (start/vote/finalize)
POST/api/etf/dissolveETF 해산

3. 어드민 API

메서드경로설명
GET/api/admin/etf/listETF 목록 (상태 필터 + 통계)
GET/api/admin/etf/detail?id=상세 (정치인 이름 resolved, 보유자 수)
POST/api/admin/etf/actions관리자 액션

관리자 액션 목록

Action설명허용 상태
force-dissolve강제 해산 (펀딩→환불, 활성→보유자 배분)전체
finalize-selection선발 수동 마감selection
expire-funding펀딩 만료 + 환불funding
update-navNAV 강제 재계산active, rebalancing
start-rebalancing리밸런싱 시작active

4. 자동화 Cron

Job Type설명주기
etf_funding_check펀딩 만료 ETF 자동 환불1일 1회
etf_rebalancing_triggernextRebalancingDate 초과 → 리밸런싱 자동 시작1일 1회
POST /api/admin/run-scheduled-job
{ "jobType": "etf_funding_check", "targetDate": "2026-02-21" }

5. 금융 플로우

NAV 계산

NAV = Σ(구성종목별_보유주식수 × 현재가) ÷ 총발행주식수

매수 (생성)

1. 사용자 voiceAmount 지불
2. 매수가격 = NAV × 1.005 (0.5% 스프레드)
3. 생성 주식수 = floor(voiceAmount / 매수가격)
4. 시스템(AP): 구성종목 비율대로 stocks 매입
5. ETF 주식 발행 → 포트폴리오 추가
6. Voice 차감 (Firestore 트랜잭션)

매도 (환매)

1. 보유량 검증 (portfolios 컬렉션)
2. 매도가격 = NAV × 0.995 (0.5% 스프레드)
3. 시스템(AP): 구성종목 비율대로 stocks 매도
4. ETF 주식 소각
5. Voice 지급 (Firestore 트랜잭션)

6. 핵심 설정값

설정설명
CONVICTION_DEPOSIT10,000 Voice확신 보증금
MIN_FUNDING_GOAL10,000,000 Voice최소 모집 금액
MIN/MAX_CONSTITUENTS3~10구성종목 수 범위
MIN_APPROVAL_RATE50%선발 최소 찬성률
CREATION_SPREAD0.5%생성(매수) 스프레드
REDEMPTION_SPREAD0.5%환매(매도) 스프레드
REBALANCING_PERIOD90일리밸런싱 주기
REMOVAL_THRESHOLD2/3퇴출 정족수
INITIAL_PRICE1,000 Voice기준가

7. Firestore 스키마

컬렉션용도
etfsETF 문서 (라이프사이클, 구성종목, 펀딩 등)
etfs/{id}/rebalancing_votes리밸런싱 투표 기록 (서브컬렉션)
usersvoiceBalance 차감/지급
portfoliosETF 보유량 (holdings[].assetType === "etf")
stocks구성종목 현재가 (currentPrice)
politicians정치인 이름 resolving (displayName)
scheduled_jobsETF Cron 작업 기록

8. 파일 구조

src/
├── services/etfService.ts              # 핵심 비즈니스 로직 (Firestore)
├── pages/api/etf/
│   ├── _auth.ts                        # 인증 헬퍼
│   ├── get-etfs.ts / create-proposal.ts / contribute-funding.ts
│   ├── politician-apply.ts / vote-selection.ts
│   ├── buy-etf.ts / sell-etf.ts / rebalance.ts / dissolve.ts
├── pages/api/admin/etf/
│   ├── list.ts / detail.ts / actions.ts
├── app/admin/etf/page.tsx              # 어드민 관리 UI
├── components/etf/
│   ├── ETFList.tsx / ETFCard.tsx / ETFScreen.tsx
│   ├── ETFDetailScreen.tsx / ETFProposalForm.tsx
└── types/index.ts                      # ETF 타입 정의