← 목록

crowny-project — 플렉시블팩토리 v3.0 (실사용 사이클 + 추천보상 + 라이프 그래프 + 12년 최적화 + 프로덕션 고도화)

개요

project.crowny.org:9730 — 플렉시블팩토리(고객) → 광주 은광교회 LED Wall 설치 건을 실제로 굴릴 수 있도록 PM 사이클 전반을 보강. 동시에 사용자 템플릿 생태계와 크로스-프로젝트 통합 시각화(라이프 그래프)를 추가.

무엇을 했는가

A. 프로젝트 라이프사이클 (실사용 기능)

테이블/엔드포인트 추가 (server.js):

엔드포인트:
  • DELETE /api/projects/:id — 프로젝트 삭제 (manager↑)
  • POST /api/projects/:id/rename — 이름 변경
  • POST /api/projects/:id/clone — 복제 (트리 깊은 복사)
  • POST /api/projects/:id/to-template — 템플릿 변환
  • visibility: personal | team | public
  • public + price>0 → 배포 시 사용료 자동 송금
  • GET /api/user-templates?scope=&sort= — 사용자 템플릿 갤러리
  • scope: all | mine | team | public
  • sort: new | popular | recommends | downloads
  • GET/DELETE /api/user-templates/:id
  • POST /api/user-templates/:id/deploy
  • POST /api/user-templates/:id/recommend — 토글식 추천 (1인 1표)
  • stripTreeForTemplate() 헬퍼 — 트리 → 템플릿 변환 시 PII/상태 제거 (assignee/managers/log/tiomtaum 초기화)

    UI: 프로젝트 상세 패널에 5개 버튼 추가 (체크리스트/스냅샷/이름수정/템플릿화/삭제)

    B. 체크리스트 + 8종 프리셋

    CHECKLIST_PRESETS 상수 (8종, 59항목): install-pre / install-active / install-post / contract / site-survey / claim / delivery / meeting

    엔드포인트:

    UI: renderChecklistPanel() — 노드 트리에서 체크리스트 보기 + 프리셋 다중선택 prompt

    C. 스냅샷/롤백

    엔드포인트:

    UI: renderSnapshotPanel() — 생성/롤백/삭제

    D. 추천/보상 시스템 (사용자 템플릿 생태계)

    핵심 로직:

    인기도 정렬: popularity = recommends × 3 + downloads × 2

    UI: 템플릿 카드에 ♥ 추천 버튼 (voted 상태 색상 변화), 정렬 토글 4종 (최신/인기/추천/다운로드)

    검증:

    E. 라이프 그래프 (크로스-프로젝트 시각화)

    GET /api/life-graph 신규:

    UI: 환영 대시보드에 "라이프 그래프" 카드:
  • KPI 4개 (건강도 색상등급 / 진행중 프로젝트 / 맘 보유 / 30일 적립)
  • Chart.js 차트 3개:
  • 프로젝트 진행률 수평 바 (80%↑녹/40~80주황/↓40빨)
  • 보상 추이 라인차트 (맘 노란/포네 보라)
  • 활동 히트맵 바차트 (밀도별 투명도)
  • F. 안정성/보안 강화 (감사 후 보강)

    서버 감사로 발견된 5개 이슈 모두 해결:

    1. /api/life-graph try/catch — 손상 노드 있어도 다른 프로젝트 집계 계속
    2. /api/projects/:id/gantt try/catch + canReadProject — 권한 없는 사용자 차단 + 손상 노드 안전 처리
    3. GET /api/teams/:id — 팀원만 조회 가능 (이전엔 누구나)
    4. /api/projects/:id/contacts — canReadProject 필요 (이전엔 누구나)
    5. /api/projects/:id/split — 자식 이름 3개 필수 + 공백 거절 + sanitizeStr

    G. share.html 데이터 활용 보강

    공개 API가 description/meta/tree 모두 반환했지만 share.html에서 미사용이던 부분 모두 표시:

    검증 결과 (curl 스모크)

    [life-graph]    GET  /api/life-graph                      → projects=2, health=20, timeline OK ✅
    [split 검증]    POST /api/projects/:id/split (빈이름)     → 400 "공백일 수 없음"             ✅
    [gantt 권한]    GET  /api/projects/:id/gantt (외부유저)   → 403 "읽기 권한 없음"             ✅
    [추천 보상]     POST /api/user-templates/:id/recommend     → +1맘 작성자 자동 지급           ✅
    [자기 추천]     POST /api/user-templates/:id/recommend     → 400 "자기 템플릿에는 추천 불가" ✅
    [정렬 인기순]   GET  /api/user-templates?sort=popular     → recommends×3+downloads×2 정렬   ✅
    [공유 페이지]   GET  /api/public/projects/:id            → name/desc/meta/tree 전부 반환   ✅
    

    관련 파일

  • /Users/ef/crowny-project/server.js (4400+ 줄)
  • db.table('user_templates'/'checklists'/'snapshots'/'template_votes') — 312~315
  • CHECKLIST_PRESETS 8종 — search "install-pre"
  • stripTreeForTemplate() — 3533
  • POST /api/projects/:id/to-template — 3543
  • GET /api/user-templates (sort/voted/popularity) — 3585
  • POST /api/user-templates/:id/recommend (보상지급) — 3637
  • GET /api/life-graph — 3099
  • splitMatch 입력검증 — 4120
  • ganttMatch try/catch + canReadProject — 4064
  • teamMatch GET 팀원체크 — 2688
  • contactsMatch canReadProject — 3020
  • /Users/ef/crowny-project/public/js/app.js
  • renderLifeGraph() Chart.js — 369
  • openUserTemplatePanel(scope, sort) 정렬+추천 — 2680
  • 5개 버튼 (rename/clone/template/snapshot/checklist/delete) — renderProject 내부
  • /Users/ef/crowny-project/public/share.html
  • 설명/메타태그/트리 표시 추가
  • 추가 완료 (2026-04-16 후속)

    H. 인쇄 가능 견적서 페이지 ✅

  • GET /api/public/estimates/:id — 공개 견적 JSON (estimate + project + issue 정보)
  • GET /estimate/:id — 정적 HTML 리라이트 (server.js:2518)
  • public/estimate.html — A4 인쇄 친화 견적서 (회사/고객/항목표/합계/조건)
  • @media print → 브라우저 Ctrl+P → PDF 저장
  • 도구바(PDF 저장 버튼) + 헤더(견적번호/발행일) + 공급자/고객 블록
  • 항목표(역할/인원/일수/단가/가산/금액) + 공급가액/VAT/합계
  • 견적 조건 5항 + 직인란
  • share.html 제출 결과에 "📄 견적서 보기 / PDF 저장 →" 링크 표시
  • 검증: curl /api/public/estimates/e7b30282... → projectName=광주은광교회2026, total=13915000, lines=4
  • I. 간트 차트 직접 진입 ✅

    잔여 이슈 / 다음 단계

    채울 수 있는 기능 — 우선순위 순:

    1. 체크리스트 카운트 사이드바 노출 — 미완료 체크 항목 수를 프로젝트 카드/사이드바에
    배지로 표시 (현재는 패널 열어야 보임).

    1. 스냅샷 diff 뷰 — 두 스냅샷 비교 (어떤 노드가 변경됐는지). 현재는 롤백만 가능.
    1. 워크플로우 자동 트리거 검증/api/workflow-presets 5종 + 커스텀 룰은
    생성/조회만 됨. 실제 trigger 발동 코드 경로 추적 + 알림 연결 필요.

    1. 실시간 라이프 그래프 갱신 — 현재는 페이지 진입 시 1회 fetch.
    WebSocket으로 reward/activity 이벤트 수신 시 차트 partial update.

    1. 템플릿 가격 송금 검증 — public + price>0 deploy 시 송금 코드 있으나
    잔액 부족/수신자 미존재 케이스 E2E 미검증.

    1. 공유 링크 만료/조회제한 — 현재 /share/:id 무한 공개. 만료일/조회수
    제한/특정 사용자만 옵션 필요 (shares 테이블 확장).

    1. 모바일 반응형 — 환영 대시보드 grid 4열이 좁은 화면에서 깨질 수 있음.
    라이프 그래프 차트 2열 → 1열 폴백.

    1. 백엔드 일괄 try/catch 확장 — life-graph/gantt 외에도 analytics, insight,
    tiomtaum-batch 등 트리 순회 엔드포인트 전체에 동일 패턴 적용.

    1. 간트 일정 편집 UX 개선 — 날짜 미설정 노드의 📅 버튼은 있으나 드래그로 바 조정은 미지원.
    좌/우 핸들 드래그 → startDate/endDate 업데이트 (PATCH /schedule) 연결 필요.

    다음 세션 참고

    RPS 폭증 우려 시 template_votes insert 전 rate limit 추가 검토.

    활동 테이블 커지면 인덱스 (at desc) 필요.

    모든 신규 프로젝트 엔드포인트에 의무 적용.

    J. 초대 시스템 (2026-04-16 추가)

    권한 지정 초대 링크/SMS 발송 → 수락 시 자동 가입·로그인·프로젝트 입장.

    백엔드

  • invites 테이블 추가 (token 24 hex, 일회용, TTL 기본 14일 · 최대 90일)
  • 매니저↑ 엔드포인트:
  • POST /api/projects/:id/invite — {inviteeName, inviteeContact, permission, ttlDays, note} → {invite, link, smsText}
  • GET /api/projects/:id/invite — 목록
  • DELETE /api/projects/:id/invites/:iid — 회수
  • 공개 엔드포인트 (무인증):
  • GET /api/invite/:token — 초대 정보 + 프로젝트 프리뷰 + 통계
  • POST /api/invite/:token/accept — {mode:'register'|'login', username, password, displayName}
  • - crownyAuth로 유저 생성/로그인 → shares 로우에 permission 반영 → used=true - 반환 {token, user, projectId, projectName, permission}

    프론트

  • /invite/:tokenpublic/invite.html (무인증, 신규가입/기존로그인 탭)
  • 수락 성공 시 localStorage.setItem('pj_token', r.token) + pj_autoOpenProject=projectId/ 이동 → 자동 진입
  • 메인 앱 헤더 초대하기 버튼 → 모달 (이름/연락처/권한/유효일/메시지)
  • 발송 후 [링크 복사] / [문자 복사] / [SMS 앱 열기] 3버튼
  • 초대 이력 리스트 (대기/사용됨/만료, 회수 버튼)
  • E2E 스모크 통과

    1. PM 로그인 · 초대 생성 (JSON newline escape 정상)
    2. 초대 토큰으로 프리뷰 조회
    3. mode:'register' 로 신규 유저 kimyoungsang 가입 + share 생성
    4. 신규 토큰으로 프로젝트 읽기 성공
    5. 같은 토큰 재사용 → 이미 사용된 초대 (410 차단)

    L. LED 카탈로그 + 설계 엔진 (2026-04-17 추가, DOT-QUOTE v45 포팅)

    DOT-QUOTE v45 (4958줄 JSX)에서 핵심 로직 포팅:

    카탈로그 DB (3테이블)

    설계 엔진 (5함수)

    API

    자재/노무 기본 단가 (₩/㎡)

    항목₩/㎡
    Steel Frame47,000
    Steel Labor80,000
    HF-IX Cable18,000
    CAT6 Cable10,000
    PSU64,000
    Harmonic Filter40,000
    Installation250,000
    Scaffold30,000
    EWP25,000
    Dismantling20,000
    Conduit15,000

    M. 현장 파악 (Site Survey) 모듈 (2026-04-17 추가)

    DOT-QUOTE에 없는 신규 기능.

    데이터 모델

    survey: {
      id, projectId, surveyDate, surveyedBy, location,
      photos: [{id, url, annotation, timestamp}],
      dimensions: {wallW, wallH, ceilingH, powerKw, hangPoints, accessRoute},
      environment: {indoorOutdoor, lighting, temperature, humidity},
      notes
    }
    

    API

    현장→설계 자동 전이

    벽면 W/H 입력 → "→ 설계로 전이" 버튼 → LED 설계 패널에 desiredW/desiredH 자동 채움

    N. 하드웨어 견적 (BOM 기반) (2026-04-17 추가)

    DOT-QUOTE의 calcPricing() 포팅 — 기존 인건비 견적(buildEstimate)과 별도.

    가격 엔진 (calcHwPricing)

    1. 모듈 비용: moduleGroups[] → USD원가 × 패킹비(5%) × 환율 × ㎡
    2. 프로세서: 원가(krw) / 판가(marginPct% 기본 20%, 만원 올림)
    3. 자재 5종: ㎡ auto 또는 직접입력
    4. 노무 6종: ㎡ auto 또는 직접입력
    5. 마진: B2B(20%) / B2C(30%) / PUBLIC(15%) / CUSTOM
    6. VAT 10% → 할인% → 만원 절사

    API

    프론트 3버튼 워크플로우

    현장조사 → (벽면 W/H) → LED설계 → (모듈+㎡+프로세서) → 하드웨어견적 각 단계에서 "→ 다음 단계" 버튼으로 데이터 자동 전이

    스모크 테스트 결과 (P1.86 GOB, 3200×1920mm)

    K. 튜토리얼 페이지 (2026-04-16 추가)

    1. TOAU 개요 2. 프로젝트 생성 3. 범주 3분할 4. TOAU 상태전이 5. 초대/권한 6. 체크리스트 7. 견적서 8. 간트 9. 라이프 그래프 10. 스냅샷/템플릿

    O. 12년 운영 최적화 (v2.6, 2026-04-16)

    보안

    CellDB 내구성

    안정성

    프론트엔드

    P. 프로덕션 고도화 (v2.7, 2026-04-17)

    보안 헤더

    공격 방어

    성능

    안정성

    Q. 옵저버빌리티 + 방어 심화 (v2.8, 2026-04-17)

    구조화 로깅

    옵저버빌리티

    보안

    데이터 보호

    API 개선

    R. 데이터 무결성 + 접근성 (v2.9, 2026-04-18)

    데이터 무결성

    DB 성능

    프론트엔드 복원력

    접근성 (ARIA)

    S. 입력 검증 강화 + WS 방어 + 증분 동기화 (v3.0, 2026-04-17)

    수치 입력 검증 강화

    에러 메시지 정보 유출 차단

    WebSocket 방어

    WS 증분 동기화