pve9-repo-fix/SCRIPT_IMPROVEMENT_PLAN.md
Claude 60be9daff4 docs: headscale 자동 등록 개선 계획 문서 추가
추가된 문서:
- SCRIPT_IMPROVEMENT_PLAN.md: 스크립트 개선 계획
- FARMQ_ADMIN_INTEGRATION_ANALYSIS.md: farmq-admin API 분석
- HEADSCALE_AUTO_REGISTER_PLAN.md: 초기 계획

주요 내용:
- Headscale VPN 등록 시 자동 DB 생성
- API 엔드포인트: demo.pharmq.kr, gateway.pharmq.kr

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-14 09:40:54 +00:00

8.0 KiB

headscale-quick-install.sh 개선 계획

목표

Headscale VPN 등록 시 farmq.db와 gateway.db에 자동으로 약국 및 관리자 계정 생성하여 스크립트 실행만으로 즉시 프론트엔드 로그인 가능하게 만들기

자동 생성 플로우

1. Headscale VPN 등록 → VPN IP 부여 (예: 100.64.0.25)
2. farmq-admin API 호출 → farmq.db에 약국 생성
   - pharmacy_code: P0005 (자동 증가)
   - pharmacy_name: 사용자 입력
   - tailscale_ip: 100.64.0.25 (VPN IP)
   - hira_code: 사용자 입력 (선택)
   - api_port: 8082 (기본값)

3. gateway API 호출 → gateway.db에 admin 계정 생성
   - username: p0005 (pharmacy_code 소문자)
   - password: 1234 (기본 비밀번호)
   - email: p0005@pharmq.internal
   - name: {pharmacy_name} 관리자
   - role: admin
   - primary_pharmacy_code: P0005
   - pharmacy_members에도 자동 매핑됨

4. 로그인 정보 출력

추가할 함수들

1. collect_pharmacy_info()

약국 기본 정보를 사용자로부터 입력받음

collect_pharmacy_info() {
    echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
    echo -e "${WHITE}약국 정보 입력${NC}"
    echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"

    # 약국명 입력 (필수)
    while [ -z "$PHARMACY_NAME" ]; do
        read -p "약국명을 입력하세요: " PHARMACY_NAME
    done

    # 요양기관부호 입력 (선택)
    read -p "요양기관부호 (선택, Enter로 건너뛰기): " HIRA_CODE

    # 약국 주소 입력 (선택)
    read -p "약국 주소 (선택): " PHARMACY_ADDRESS

    # 약국장 이름 입력 (선택)
    read -p "약국장 이름 (선택): " OWNER_NAME

    # 연락처 입력 (선택)
    read -p "약국 연락처 (선택): " PHARMACY_PHONE

    echo -e "${GREEN}✓ 약국 정보 입력 완료${NC}"
}

2. get_assigned_vpn_ip()

Headscale에서 부여받은 VPN IP 가져오기

get_assigned_vpn_ip() {
    echo -e "${BLUE}VPN IP 확인 중...${NC}"

    # tailscale status로 IP 추출
    VPN_IP=$(tailscale status --json 2>/dev/null | grep -oP '"TailscaleIPs":\["(\d+\.\d+\.\d+\.\d+)"' | grep -oP '\d+\.\d+\.\d+\.\d+' | head -1)

    if [ -z "$VPN_IP" ]; then
        echo -e "${RED}✗ VPN IP를 가져올 수 없습니다${NC}"
        return 1
    fi

    echo -e "${GREEN}✓ VPN IP: $VPN_IP${NC}"
    return 0
}

3. create_pharmacy_via_api()

farmq-admin API를 호출하여 약국 생성

create_pharmacy_via_api() {
    echo -e "${BLUE}약국 등록 중 (farmq.db)...${NC}"

    # JSON 데이터 구성
    JSON_DATA=$(cat <<EOF
{
    "pharmacy_name": "$PHARMACY_NAME",
    "vpn_ip": "$VPN_IP",
    "hira_code": "$HIRA_CODE",
    "address": "$PHARMACY_ADDRESS",
    "owner_name": "$OWNER_NAME",
    "phone": "$PHARMACY_PHONE",
    "api_port": 8082
}
EOF
)

    # API 호출 (외부 도메인)
    RESPONSE=$(curl -s -X POST https://demo.pharmq.kr/api/pharmacy \
        -H "Content-Type: application/json" \
        -d "$JSON_DATA")

    # pharmacy_code 추출
    PHARMACY_CODE=$(echo "$RESPONSE" | grep -oP '"pharmacy_code":"[^"]*"' | cut -d'"' -f4)

    if [ -z "$PHARMACY_CODE" ]; then
        echo -e "${RED}✗ 약국 생성 실패${NC}"
        echo "$RESPONSE"
        return 1
    fi

    echo -e "${GREEN}✓ 약국 생성 완료: $PHARMACY_CODE${NC}"
    return 0
}

4. create_gateway_user_via_api()

gateway API를 호출하여 관리자 계정 생성

create_gateway_user_via_api() {
    echo -e "${BLUE}관리자 계정 생성 중 (gateway.db)...${NC}"

    # username: pharmacy_code 소문자 (P0005 → p0005)
    USERNAME=$(echo "$PHARMACY_CODE" | tr '[:upper:]' '[:lower:]')
    PASSWORD="1234"  # 기본 비밀번호
    EMAIL="${USERNAME}@pharmq.internal"

    # JSON 데이터 구성
    JSON_DATA=$(cat <<EOF
{
    "username": "$USERNAME",
    "email": "$EMAIL",
    "password": "$PASSWORD",
    "name": "${PHARMACY_NAME} 관리자",
    "phone": "$PHARMACY_PHONE",
    "primary_pharmacy_code": "$PHARMACY_CODE",
    "role": "admin"
}
EOF
)

    # API 호출 (외부 도메인)
    RESPONSE=$(curl -s -X POST https://gateway.pharmq.kr/api/auth/register \
        -H "Content-Type: application/json" \
        -d "$JSON_DATA")

    # 성공 여부 확인
    if echo "$RESPONSE" | grep -q '"success":true'; then
        echo -e "${GREEN}✓ 관리자 계정 생성 완료${NC}"
        return 0
    else
        echo -e "${RED}✗ 관리자 계정 생성 실패${NC}"
        echo "$RESPONSE"
        return 1
    fi
}

5. display_login_credentials()

생성된 로그인 정보 출력

display_login_credentials() {
    echo -e "\n${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
    echo -e "${WHITE}🎉 설치 및 등록 완료!${NC}"
    echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"

    echo -e "\n${GREEN}약국 정보:${NC}"
    echo -e "  약국 코드: ${WHITE}$PHARMACY_CODE${NC}"
    echo -e "  약국명: ${WHITE}$PHARMACY_NAME${NC}"
    echo -e "  VPN IP: ${WHITE}$VPN_IP${NC}"

    echo -e "\n${GREEN}프론트엔드 로그인 정보:${NC}"
    echo -e "  URL: ${WHITE}https://pharmq.kr${NC}"
    echo -e "  아이디: ${WHITE}$(echo "$PHARMACY_CODE" | tr '[:upper:]' '[:lower:]')${NC}"
    echo -e "  비밀번호: ${WHITE}1234${NC}"
    echo -e "  ${YELLOW}⚠ 최초 로그인 후 비밀번호를 변경하세요!${NC}"

    echo -e "\n${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
}

main() 함수 수정

main() {
    print_header "팜큐(FARMQ) Headscale 원클릭 설치"

    # 사전 체크
    detect_os
    check_requirements

    # 설치 과정
    install_tailscale
    start_tailscale
    register_headscale

    # VPN IP 확인
    sleep 3  # Headscale에서 IP 할당 대기
    get_assigned_vpn_ip || exit 1

    # 약국 정보 수집
    collect_pharmacy_info

    # 약국 및 계정 생성
    create_pharmacy_via_api || exit 1
    create_gateway_user_via_api || exit 1

    # 사후 설정
    configure_firewall
    verify_connection

    # 정리 및 완료
    cleanup
    display_login_credentials
}

API 엔드포인트

API URL 용도 접근 방식
farmq-admin https://demo.pharmq.kr/api/pharmacy 약국 생성 외부 도메인 (HTTPS)
gateway https://gateway.pharmq.kr/api/auth/register 사용자 생성 외부 도메인 (HTTPS)

장점:

  • 모든 API가 외부 도메인으로 통일되어 있음
  • HTTPS로 보안 통신
  • 내부 네트워크 접근 불필요
  • VPN 망 내부/외부 어디서든 실행 가능

보안 고려사항

  1. 기본 비밀번호 1234: 간단하지만 프론트엔드에서 강제 변경 유도 필요
  2. API 키 인증: 현재는 public API지만 나중에 인증 토큰 추가 고려
  3. HTTPS: 현재 HTTP이지만 production에서는 HTTPS 사용 권장

에러 처리

  • VPN IP 할당 실패 시 스크립트 중단
  • 약국 생성 실패 시 스크립트 중단
  • 사용자 생성 실패 시 경고만 출력 (약국은 이미 생성됨)

테스트 시나리오

  1. 정상 플로우: 모든 정보 입력 → 약국 및 계정 생성 → 로그인 성공
  2. 선택 정보 생략: 약국명만 입력 → 약국 및 계정 생성 → 로그인 성공
  3. VPN IP 할당 실패: 에러 메시지 출력 후 종료
  4. 약국 생성 실패: 에러 메시지 출력 후 종료
  5. 사용자 생성 실패: 경고 출력, 수동 생성 안내

다음 단계

  1. farmq-admin API 개선 (VPN IP, hira_code 지원) - 완료
  2. gateway API 개선 (pharmacy 검증, pharmacy_members 자동 추가) - 완료
  3. headscale-quick-install.sh 수정 - 진행 중
  4. 통합 테스트