academy.crowny.org SPA 완성 + 서비스 프레임워크 분리 (2026-06-20)
개요
academy.crowny.org가 통합 서비스 프레임워크(
crowny-services/서비스서버.js)의 플레이스홀더로 9865에 떠 있어서, 실제 22모듈 풀앱(
crowny-academy/server.js)이 외부에서 접근 불가능했음. 이를 해소하고, 신규 3모듈(messenger/proposal/pricing)을 SPA 사이드바에 풀스택 연결.
무엇을 했는지
1. SPA 라우팅 핵심 버그 수정
public/assets/app.js: innerHTML로 주입된 <script> 태그는 브라우저가 실행하지 않음 → rehydrateScripts() 헬퍼 추가, 뷰 주입 직후 <script> 노드를 새로 만들어 교체해 실행되도록.
- 신규 3개 라우트(
messenger, proposal, pricing-view)를 routes 테이블 + initView() 디스패처에 등록.
2. 풀페이지 vs SPA 인젝트 분리
public/views/proposal.html, pricing-view.html: SPA 프래그먼트(<html>/<body> 없음). 인젝트 후 loadProposal/loadPricingView 실행됨.
public/views/messenger.html: 단독 풀페이지(<html>/<body> 래퍼). 사이드바 클릭 시 navTo('messenger') → location.href 전체 페이지 네비게이션. 페이지 상단에 "← 관리자" 복귀 버튼 추가.
public/index.html: FULL_PAGE_ROUTES = { messenger: '/views/messenger.html' } 매핑.
3. 9865 포트 점유 해제 + 풀앱 기동
crowny-services/registry.psv의 academy|9865|... 라인 주석 처리 (백업: registry.psv.bak-academy분리-*).
- 플레이스홀더 PID 종료,
node server.js 백그라운드 기동(PID 52832).
- 28모듈 풀앱(neoclient/v1 8 + Phase1~5 14 + 신규 3) 라이브.
4. 검증
health:200, health/ready:200
- 신규 API 모두 정상:
/api/messenger/members(데모 멤버 6명), /api/proposal/templates(3 템플릿), /api/pricing-cat/plans(Lite/Standard/Enterprise).
- SPA 뷰 5종 200: pricing-view, proposal, messenger, dashboard, students
- 테스트: 414/414 PASS (88 suites)
관련 파일 경로
/Users/ef/crowny-academy/public/assets/app.js (rehydrateScripts + 라우트 추가)
/Users/ef/crowny-academy/public/index.html (FULL_PAGE_ROUTES + navTo)
/Users/ef/crowny-academy/public/views/messenger.html (복귀 버튼)
/Users/ef/crowny-services/registry.psv (academy 라인 주석)
/Users/ef/crowny-academy/server.js (PID 52832, 9865 LISTEN)
잔여 이슈
- 메신저/모니터링은 풀페이지(
<html>/<body> 래퍼)라 i18n/사이드바 글로벌 상태 공유 X — 사이드바 클릭 시 navTo가 FULL_PAGE_ROUTES로 가로채 location.href 전체페이지 네비. 페이지 상단에 "← 관리자" 복귀 버튼 추가. 필요시 SPA 프래그먼트로 재구조화 검토.
후속(2026-06-20 동일 세션)
LaunchAgent 등록: ~/Library/LaunchAgents/com.crowny.academy.plist 작성 + launchctl load -w. KeepAlive=true, RunAtLoad=true, NODE_ENV=development(데모 토큰 허용). kill -9 강제종료 → 5초 내 자동 재기동 확인.
SPA 뷰 회귀 점검 완료 (rehydrateScripts 덕에 비로소 동작):
디스패처 32항목 ↔ 뷰 32개 100% 매칭 (window.load<Name> 노출 검증 통과).
풀페이지 2종(messenger·monitoring): FULL_PAGE_ROUTES로 격리.
proposal.html: IIFE 패턴 보존하면서 window.loadProposal = propInit 노출 추가 (SPA 캐시 재방문 시 안전).
테스트 414/414 PASS 유지.