유형: 설계 (A 전체 역엔지니어링 기획 — B 재구현 청사진)
최종 업데이트: 2026-07-07 (manager 초안 · 감사/클릭맵 종합)
웹뷰: https://chat.punkpoll.com/doc/reverse-eng
펑크폴 역엔지니어링 기획문서 (A → B)
목적: www.punkpoll.com(A)의 프론트·백엔드·온체인·전체 파이프라인을 실측으로 역설계해, B가 A를 온전히 재구현할 청사진을 제공한다. 이 문서는 V3 준비작업(감사·측정모델·체크리스트)이 올바른 A 이해 위에 서 있는지 검증하는 기준선이다. 근거=전 페이지 클릭맵(/doc/parity-map)+모듈 감사(/doc/audit)+온체인 매핑(ONCHAIN_A_TO_B_REVERSE_ENGINEERING.md).
1. 시스템 개요 (A 전체 지형)
| 계층 | 모듈 | 역할 |
| 진입(메신저) | kakaoChatBot(PHP·4채널)·punkpollBotAvax(텔레그램) | 사용자 진입·설문 발송·참여 수집 |
| 인증 | punkpoll-auth-gateway(NestJS) | 카카오/텔레그램 OAuth·JWT·nullifier 파생·ticket |
| 코어 API | punkpoll_api(Spring Boot) | 설문/채널/유저 CRUD·참여 수집·배포 workflow·콜백·admin |
| 저장 | punkpoll-ipfs(Node·Pinata·BullMQ) | 참여 내용 IPFS(즉시 CID + 지연 핀 + 멱등) |
| 온체인 | txSender + punkpollAvaxBlockChainApi(이원)·PunkpollFungibleTokenAvax(레거시 Mina·미사용) | 배포·참여기록·리워드·정산·토큰·콜백 |
| 운영 | punkpollUtil(panelManager) | 패널 관리·응답 스케줄 |
| 지갑 | standalone_wallet(Next 웹뷰) | 지갑 UI(A=비수탁·개인키 평문 결함) |
| 프론트 | punkpoll_web(Next14) + app/admin | 사용자 웹(74 라우트) + 관리자 콘솔 |
2. 엔드투엔드 파이프라인 (설문 생성→참여→정산)
① 설문 생성: 사용자(채널 오너) → web 빌더(/builder/poll 5스텝) → punkpoll_api(설문 저장·배포요청 SysRequestService)
② 배포: punkpoll_api → 온체인 배포(txSender: SurveyNFT 컨트랙트 배포) + 알림톡/챗봇 발송(kakao/telegram)
③ 진입: 사용자 ← 카카오/텔레그램 챗봇 링크 → auth-gateway(OAuth·nullifier·ticket) → web(설문 상세)
④ 참여: web Vote 버튼 → sendMeJoinSurvey(챗봇 참여메시지) → 사용자 응답 → punkpoll_api 수집
→ 참여내용 ipfs(즉시 CID) + 온체인 참여기록(txSender: registerParticipation, 백엔드 대행서명)
⑤ 리워드/SBT: 참여당 리워드 토큰 전송 + receipt SBT 발행(txSender/chain)
⑥ 정산: 설문 종료 → settle(잉여 리워드 반환, deposit=지급+잉여 항등식)
⑦ 반영: 온체인 이벤트 → 콜백 → punkpoll_api → web/admin 실시간 표시
핵심 불변 semantics(G6·B 보존 필수):
- nullifier = A users 저장값(resolveAUser 조회, 재계산 X) — 가명 신원, 키 미보유
- 참여서명 = keccak256(participant, tokenId, participationTime, surveyContract, chainId) 백엔드 대행서명(사용자 서명 0)
- 정산 항등식 = deposit = 리워드지급 + 잉여반환 (T5 실증 4e15=2e15+2e15)
- M4 = 이벤트 없는 성공 금지(무이벤트=실패)
- custodial 지갑 = 카카오 로그인 시 서버 지갑 생성·KEK 보관·세션 대행서명
3. 프론트엔드 역설계 (74 라우트)
전 페이지 클릭맵·요소단위 목적지 = /doc/parity-map (A-1~A-16). 요약:
- 공개: /explore(홈 피드)·/poll/id·/token/[id]·/channel(브라우즈)·/channel/id·/user/id·사이드패널(DetailSideModal)
- 오너: /channel/[id]/manager(허브 7뷰: 대시보드·배포·블록체인TX·리포트·PUNK·매니저·빌더)·/builder(5스텝)·/channel/create·edit
- 정적/특수: /live·/punk/purchase·/panel·/opinion-poll·/vote(준비중)·/daily·/feedback·/login
- 데드(포팅 제외): /explore-2·/daily(고아)·/citizen(리다이렉트)
- CSS 정확 재현(협상불가): 여백·폰트·폰트사이즈 = A 실측 클래스/px 대조(오래 고도화됨)
4. 백엔드 모듈별 A→B 매핑 (구조 최적화)
| A 모듈 | A 역할 | B 매핑(통폐합/최적화) |
| kakaoChatBot(PHP)+telegramBot | 메신저 진입·발송·수집(각 8599·2341줄 거대·SQL injection) | 공용 메신저 게이트웨이(어댑터): 카카오/텔레그램 어댑터 + 공용 핸들러. 파라미터 바인딩. |
| auth-gateway | OAuth·nullifier·ticket(키 하드코딩) | OAuthStrategy 인터페이스·nullifier=resolveAUser 조회(키 미보유)·guards |
| punkpoll_api(Spring Boot) | CRUD·배포·콜백·admin(SysRequest 1501·삼원화) | CRUD는 B core-api가 대체(데드 제거)·배포/콜백/admin은 도메인 서비스 분리 |
| ipfs | 즉시 CID·지연핀(멱등 갭) | B pin-server(멱등 강화·입력검증) |
| txSender+blockchainApi(이원) [FungibleToken=레거시 Mina·미사용] | 온체인 TX 이원(~20파일·거대·병존). A현재=Avalanche C-Chain(Fuji 43113/mainnet 43114), PUNK=Avalanche ERC20(0x6023/0xE1Cb) | B 단일 chain-worker(헥사고날 워커코어) + PUNK ERC20(0x804b). Avalanche→Avalanche. 합집합 동작 보존(4복구모드·멀티feePayer). |
| punkpollUtil | 패널 관리(1463 거대·SQL injection) | 패널 도메인 분리·파라미터 바인딩 |
| standalone_wallet | 웹뷰 지갑(개인키 평문 결함) | custodial 전환(서버생성+KEK)으로 결함 근본 제거 |
| punkpoll_web + admin | 사용자 웹 + 관리자 | .tsx·폴링→store구독·거대컴포넌트 분리·중복 6클러스터→공용 훅(audit C1~C6). admin=web/app/admin 참조 |
B 구조 최적화 3대 축: ①메신저 게이트웨이 통합 ②온체인 단일 chain-worker(이원→단일) ③프론트 부채 제거(.tsx·훅·컴포넌트 분리).
5. 전 모듈 공통 부채 (V3 근본 제거 — 감사 §7)
- 🔴 SQL injection 만연(kakao·telegram·util·admin·api) → 전 모듈 파라미터 바인딩 강제(보안 게이트)
- 🔴 지갑 개인키 평문 → custodial 전환으로 제거
- 🔴 auth 암호화키 하드코딩 → resolveAUser(키 미보유)
- 거대 파일 만연(1000~8599줄) → 단일책임 분리
- 원본/backup/Refactored 병존 → 라이브 판별 후 죽은쪽 제거
- ✅ 클린 표준 = TS + Zod 입력검증 + 에러분류 + 테스트 + 작은 파일
6. V3 준비작업 적합성 자가점검 (jegwon 요구)
| 준비 산출물 | 역엔지니어링 기획문서 적합성 |
| 전 페이지 클릭맵(parity-map) | ✅ §3 프론트 역설계의 실측 근거. A UI/UX 요소단위 목적지 확보 |
| 코드 감사(audit) | ✅ §4·§5 백엔드 매핑·공통부채의 file:line 근거 |
| 온체인 리버스엔지니어링(backend4) | ✅ §2 파이프라인 온체인 구간·§4 온체인 통폐합 근거 |
| 측정모델(G1~G6) | ✅ §2 불변 semantics = G6 기준선. G5 픽셀=§3 CSS 정확재현 |
| 기능별 체크리스트(A출처) | 🔧 이 문서 §4 매핑이 provenance 열의 출처. 체크리스트가 이 매핑을 기능단위로 분해 |
| 대시보드 | ✅ 진행 가시화 |
결론(자가점검): V3 준비작업은 역엔지니어링 기획문서의 4개 축(파이프라인·프론트·백엔드매핑·불변semantics)을 모두 근거로 보유. 적합. 남은 것 = 이 매핑을 기능단위 체크리스트로 분해 + 측정모델 게이트 확정. 브레인스토밍에서 이 문서로 팀 상호 파악 검증.
7. 리스트럭처 결정 로그 (구조적 결정)
R1. FungibleToken(LightApi) 해체 (jegwon 2026-07-07 · manager 권고)
- A 실역할(reviewer 실추적): PunkpollLightApi = ①IPFS 업로드 ②업로드 후 블록체인 job enqueue. (Mina o1js 토큰코드=레거시 데드)
- 결정: 모듈 해체 → ①IPFS→pin 서버(punkpoll-ipfs) 단일화(감사 IPFS 2중 정리) / ②job enqueue→core-api 오케스트레이션(pin=IPFS만 순수모듈·core=흐름제어) / TX→chain-worker.
- 근거: 감사 통폐합 3건(콜백 단일·IPFS 단일·TX 단일)과 일치. 도메인 경계 명확화(다른 AI 재사용 용이).
- 세부: (b2) core-api 핸드오프 = 팀 합의(reviewer·backend1·backend4). 근거: B core-api가 이미 deploy→deposit→participate 흐름제어 → CID 후 chain job enqueue도 같은 레이어. pin서버=IPFS 순수(재사용)·chain-worker=job 실행·core-api=job 주입 결정.
- reviewer 3 정합 caveat(리팩토링 후 G6 검증): ①CID=온체인 ipfsHash=결과조회 CID 정확 일치(불일치=참여내용 유실) ②핸드오프 멱등(같은 참여=job 1회·중복 enqueue 0·tokenId 결정적 채번 연동) ③IPFS 업로드 성공 후에만 체인 job(실패 시 미생성·내용없는 참여 방지).
- ✅ jegwon 승인(2026-07-07 '좋은 방향'). 확정: pin서버=CID발급+Pinata핀+멱등(IPFS 전부) / 블록체인 job=core-api / Mina 컨트랙트코드 제거. LightApi2(IPFS+큐 혼재)→IPFS(pin서버)+흐름제어(core-api) 분리.
⑤ 온체인 토큰 마이그레이션 = 없음 (해소·team 소스검증)
- A prod=Avalanche 메인넷(43114), PUNK 컨트랙트 온체인 상주. A→B 완전교체=B가 같은 메인넷+컨트랙트 승계 → 잔액 재발급/브릿지/스냅샷 불필요.
- B M11(ALLOWED_CHAIN_ENVS fuji/dry-run·mainnet=Phase6 게이트)이 환경격리 가드. 컷오버=M11 해제→메인넷 상속. 0x804b=Fuji dev throwaway(prod 무관).
- 컷오버 검증(reviewer): B config가 A 메인넷 실컨트랙트(PUNK=0xc8F7C5de·prod .env 실값 재확인 기준) 가리키는지+Fuji 잔재 0+신규설문 43114 배포. DB는 온체인 참조정보(주소·txHash·집계)만 이관.
R2. punkpollBotAvax 분리 (jegwon 2026-07-07 · 실코드 검증)
- 현황(검증): punkpollBotAvax = 텔레그램 챗봇(telegramEchoBot/index.js) + punkpollSystemApi(1684줄 grab-bag) + alimtalkTemplate. 관심사 혼재.
- 결정: 텔레그램 챗봇 분리 → B 공용 메신저 게이트웨이(카카오+텔레그램 어댑터)로 흡수(3축 ①과 일치).
R3. punkpollSystemApi 해체 + '블록체인 처리' 교통정리 (jegwon 2026-07-07)
- punkpollSystemApi 실 역할(검증 엔드포인트): /participate·/joinSurvey(참여) · /mint·/balanceOf·/token·/punkTokenStatus·/feeAmount(토큰) · alimtalk · /api/sysres/*(소셜인증·시스템응답 콜백) · /main·/channel/imageInfo·/footerInfo(웹 컨텐츠) · /kakaoLogout. = 도메인 뒤섞인 grab-bag.
- 결정: 도메인별 재배치(해체):
- 참여(joinSurvey/participate) → 참여 파이프라인(core-api → chain-worker)
- 토큰 조회/민팅(balanceOf·token·mint·feeAmount) → 블록체인/토큰 모듈(chain-worker/core-api)
- 알림톡 → 메신저/알림 모듈
- 소셜인증(sysres/socialAuth·kakaoLogout) → auth-gateway
- 웹 컨텐츠(imageInfo·footerInfo) → core-api(web 데이터)
- '블록체인 처리' 교통정리: 실 블록체인 처리가 txSender(참여TX·jobProcessor.js:326 "joinSurvey는 txSender로 분리")·blockchainApi(배포·fee)·LightApi2(참여큐)·systemApi(mint 등)에 분산 → B 단일 chain-worker(블록체인 처리 전담). '시스템 api'는 블록체인 명칭을 떼고 각 기능을 도메인 모듈로 해체(별도 grab-bag api 없앰).
- ⏳ jegwon 확정 대기.