Gemini와의 대화 웹사이트에서 호줄 승인하여 원격지원 하는 사이트를 만들고 싶다 가능한가? 웹사이트에서 고객이 원격지원을 요청하고 상담원이 이를 승인하여 연결하는 시스템은 충분히 구현할 수 있으며, 시스템 구축 범위(브라우저 내 화면 공유 vs PC 전체 제어)에 따라 두 가지 기술 방식으로 나뉩니다. 1. 웹 브라우저 화면만 공유 및 안내 (설치 불필요) 고객이 별도의 프로그램을 설치하지 않고, 현재 보고 있는 웹사이트나 브라우저 화면만 상담원과 공유하는 방식입니다. 핵심 기술: WebRTC (navigator.mediaDevices.getDisplayMedia API)와 WebSocket (Socket.io 등)을 활용합니다. 동작 방식: 고객이 '원격지원 요청'을 누르면 WebSocket을 통해 상담원 대시보드에 알림이 뜨고, 상담원이 '승인'하면 WebRTC 시그널링이 이루어져 실시간으로 고객의 화면이 스트리밍됩니다. 제어 수준: 보안 정책상 웹 브라우저만으로는 고객의 마우스나 키보드를 직접 움직일 수 없습니다. 대신 상담원이 화면 위에 마우스 포인터를 표시하거나 그림을 그려 안내하는 공동 브라우징(Co-browsing) 형태로 구현합니다. 2. 고객 PC 전체 화면 공유 및 마우스·키보드 제어 (에이전트 설치 필요) 팀뷰어(TeamViewer)나 애니데스크(AnyDesk)처럼 상담원이 고객의 마우스와 키보드를 직접 조작해야 하는 방식입니다. 핵심 기술: 웹사이트(호출·승인 중계) + 로컬 에이전트 프로그램 (Electron, C#, C++, Rust 등으로 제작)의 결합이 필요합니다. 동작 방식: 웹사이트에서 호출 및 승인이 완료되면, 고객 PC에 경량 실행 파일(.exe 등)이 다운로드되거나 커스텀 URL 스키마(myremote:// 등)를 통해 이미 설치된 프로그램이 실행됩니다. 이 프로그램이 OS의 화면 캡처 및 마우스·키보드 제어 API(Windows API 등) 권한을 얻어 동작합니다. 필수 인프라 및 구현 요소 시그널링 서버 (Signaling Server): Node.js(Socket.io)나 Spring WebSocket 등을 이용해 고객의 '호출 요청', 상담원의 '승인 응답', 연결 상태 및 접속 코드(6자리 숫자 등)를 실시간으로 중계합니다. STUN / TURN 서버: 방화벽이나 공유기(NAT) 환경에 있는 고객과 상담원을 연결하기 위해 필수적입니다. 오픈소스인 Coturn을 자체 서버에 구축하거나 클라우드 미디어 서버(Twilio, LiveKit, AWS Kinesis 등)를 사용합니다. 직접 모든 원격 제어 엔진을 개발하는 것이 부담스럽다면, 오픈소스 원격 데스크톱 프로젝트인 RustDesk의 자체 서버 기능을 웹과 연동하거나, 코브라우징 SDK(Surfly, Cobrowse.io 등)를 웹사이트에 임베딩하여 구축 기간을 단축할 수 있습니다. 직접 개발하는 대신 오픈소스 원격 제어 솔루션(RustDesk 등)을 웹사이트에 연동하여 구축하는 방법을 알려줘. 오픈소스 원격 제어 솔루션을 활용하면 화면 캡처, 인코딩, 네트워크 우회(NAT Traversal), 마우스·키보드 제어 등 가장 까다로운 코어 엔진 개발을 건너뛰고 '웹사이트의 호출 및 승인 워크플로우'에만 집중할 수 있습니다. 목적에 따라 가장 많이 쓰이는 3가지 오픈소스와 이를 웹사이트에 연동하는 구체적인 아키텍처는 다음과 같습니다. 1. 주요 오픈소스 솔루션 비교 및 선택 RustDesk (가장 추천 - PC 직접 접속 방식): TeamViewer나 AnyDesk를 대체하는 가장 강력한 오픈소스입니다. 자체 중계 서버(Self-hosted)를 무료로 구축할 수 있고, 실행 파일 이름이나 로고를 바꾸고 자체 서버 주소를 내장한 맞춤형 경량 클라이언트(QuickSupport 형태)를 만들 수 있습니다. MeshCentral (웹 브라우저 내 제어 방식): Node.js로 만들어진 오픈소스 원격 관리 서버입니다. 고객은 작은 에이전트만 실행하면 되고, 상담원은 별도 프로그램 없이 웹 브라우저 화면 안에서 고객의 PC를 실시간으로 제어할 수 있어 웹 관리자 페이지에 통합(iframe 또는 API)하기 가장 좋습니다. Apache Guacamole (서버/특정 PC 게이트웨이 방식): HTML5 기반의 클라이언트리스 원격 데스크톱 게이트웨이입니다. VNC나 RDP를 웹 브라우저로 중계해주며, 사내 PC나 고정된 단말기를 웹에서 승인 후 접속할 때 유리합니다. 2. RustDesk + 자체 웹사이트 연동 아키텍처 (가장 대중적인 모델) 리모트콜이나 팀뷰어처럼 웹사이트에서 호출하고 승인받아 연결하는 표준적인 구축 단계입니다. 1단계: 자체 중계 서버 구축 (Docker 활용) 공용 서버 대신 자사 서버(AWS, 사내 서버 등)에 RustDesk 중계 서버를 띄워 속도와 보안을 확보합니다. hbbs (ID 및 시그널링 서버): 접속 번호 생성 및 중계 역할을 합니다. hbbr (릴레이 서버): 방화벽 환경에서 화면 데이터를 중계합니다. docker-compose.yml 파일 하나로 5분 만에 구축할 수 있습니다. 2단계: 고객용 1회성 에이전트(클라이언트) 패키징 고객이 서버 주소나 설정을 건드릴 필요 없이 실행만 하면 되도록 만듭니다. 간편 방식: 실행 파일 이름을 host=<자사서버IP>,key=<공개키>.exe 형태로 지정해 웹사이트에서 다운로드받게 하면, 실행 즉시 자사 서버로 자동 연결됩니다. 고급 방식 (소스 빌드): RustDesk 오픈소스(Flutter/Rust)를 수정하여 자사 로고를 넣고, 실행 시 생성된 ID와 일회용 비밀번호를 자사 웹 서버 REST API로 자동 전송하도록 몇 줄의 코드를 추가해 빌드합니다. 3단계: 웹사이트 '호출 - 승인 - 원격 연결' 흐름 구현 고객 호출: 고객이 웹사이트에서 [원격지원 요청] 버튼을 누르고 전용 에이전트(.exe)를 다운로드하여 실행합니다. 접속 정보 전달: 고객이 화면에 뜬 9자리 ID(또는 자동 전송된 세션 키)를 웹사이트에 입력하면, 웹 서버(WebSocket)가 상담원 대시보드에 "고객 A님이 원격지원을 요청했습니다"라는 알림을 띄웁니다. 상담원 승인 및 즉시 실행: 상담원이 웹 대시보드에서 [승인 및 연결] 버튼을 클릭합니다. URL 스키마(Custom URI Scheme) 연동: 승인 버튼에 rustdesk://connection/new/<고객ID>?password=<일회용비밀번호> 형태의 링크를 걸어두면, 웹 브라우저가 상담원 PC의 원격 제어 프로그램을 즉시 깨워 비밀번호 입력 없이 바로 고객 화면으로 접속시킵니다. 3. 상담원도 웹 브라우저에서 제어하고 싶다면? (Web Client 연동) 상담원 PC에 프로그램을 설치하지 않고 100% 웹 브라우저(관리자 페이지) 안에서 고객 화면을 보며 마우스를 제어하고 싶다면 다음 두 가지 방법을 사용합니다. MeshCentral API 연동: 자체 웹 서버 백엔드에서 MeshCentral 서버의 API를 호출해 일회용 에이전트 다운로드 링크를 생성해 고객에게 주고, 상담원이 웹에서 [승인]을 누르면 MeshCentral의 원격 제어 뷰어 URL(토큰 포함)을 관리자 페이지 내 iframe이나 새 창으로 띄웁니다. RustDesk Web Client 활용: RustDesk의 웹 클라이언트(Wasm 기반) 소스를 자사 관리자 웹 페이지에 내장하여 브라우저에서 바로 원격 세션을 열 수 있습니다. Docker Compose로 RustDesk 서버(hbbs, hbbr)를 구축하고, 웹사이트에서 URL 스키마로 원격지원을 승인·실행하는 예제 코드를 알려줘. Docker Compose를 이용해 자사 전용 RustDesk 중계 서버(hbbs, hbbr)를 구축하고, Node.js(Socket.io) 기반 웹사이트에서 실시간으로 고객의 원격지원 호출을 받아 URL 스키마(rustdesk://)로 즉시 연결하는 전체 구현 코드입니다. 1단계: Docker Compose로 RustDesk 서버 구축 리눅스 서버(Ubuntu 등)나 클라우드(AWS EC2 등)에서 아래 방화벽 포트를 먼저 개방해야 합니다. TCP: 21115, 21116, 21117, 21118, 21119 UDP: 21116 작업 디렉토리를 만들고 docker-compose.yml 파일을 작성합니다. YAML version: '3' services: hbbs: container_name: hbbs image: rustdesk/rustdesk-server:latest # <자사서버IP_또는_도메인> 자리에 실제 서버 공인 IP나 도메인을 입력하세요. # -k _ 옵션은 암호화 키가 일치하는 클라이언트만 접속을 허용하는 보안 옵션입니다. command: hbbs -r <자사서버IP_또는_도메인>:21117 -k _ volumes: - ./data:/root network_mode: "host" depends_on: - hbbr restart: always hbbr: container_name: hbbr image: rustdesk/rustdesk-server:latest command: hbbr -k _ volumes: - ./data:/root network_mode: "host" restart: always 컨테이너를 실행하고 생성된 공개키(Public Key)를 확인합니다. Bash # 서버 백그라운드 실행 docker compose up -d # 생성된 공개키 확인 (출력된 문자열을 복사해 둡니다) cat ./data/id_ed25519.pub 2단계: 고객 배포용 실행 파일 준비 (자동 서버 설정) 고객이 서버 주소를 직접 입력할 필요가 없도록, RustDesk 윈도우 클라이언트(.exe)의 파일명 규칙을 활용해 웹사이트에 업로드합니다. 파일명을 아래와 같이 변경하여 웹 서버의 다운로드 경로에 배치합니다. rustdesk-host=<자사서버IP>,key=<위에서_복사한_공개키>.exe 예시: rustdesk-host=203.0.113.10,key=Wf8xK9mP2qL5vN3zR7tY1uI4oP6aS8dF0gH2jK4lZ6x=.exe 고객이 웹사이트에서 이 파일을 다운로드해 실행하면 자동으로 자사 서버에 연결됩니다. 3단계: 웹사이트 호출 및 승인 백엔드 (Node.js + Socket.io) 고객이 원격지원을 요청하면 상담원 화면에 실시간으로 알림을 띄우는 중계 서버(server.js)입니다. Bash npm init -y npm install express socket.io JavaScript // server.js const express = require('express'); const http = require('http'); const { Server } = require('socket.io'); const app = express(); const server = http.createServer(app); const io = new Server(server); app.use(express.static('public')); io.on('connection', (socket) => { // 1. 고객이 원격지원 호출 요청 시 socket.on('request_support', (data) => { console.log('원격지원 요청 접수:', data); // 상담원 대시보드로 요청 데이터(이름, RustDesk ID, 일회용 비밀번호) 전달 io.emit('new_support_ticket', { ticketId: socket.id, customerName: data.customerName, rustdeskId: data.rustdeskId.replace(/\s+/g, ''), // 공백 제거 password: data.password, requestTime: new Date().toLocaleTimeString() }); }); // 2. 상담원이 원격지원 승인 시 socket.on('approve_support', (ticketId) => { // 해당 고객 화면에 승인 완료 상태 전달 io.to(ticketId).emit('support_approved'); }); }); server.listen(3000, () => { console.log('원격지원 웹 서버 실행 중: http://localhost:3000'); }); 4단계: 고객 요청 화면 및 상담원 승인 화면 (HTML/JS) public 폴더 안에 고객용 페이지(customer.html)와 상담원 대시보드(agent.html)를 각각 생성합니다. 고객용 페이지 (public/customer.html) HTML 고객 원격지원 요청

1. 원격지원 프로그램 다운로드

2. 원격지원 호출하기

프로그램 실행 후 표시되는 ID와 일회용 비밀번호를 입력해 주세요.







상담원 대시보드 (public/agent.html) - URL 스키마 실행 포함 HTML 상담원 원격지원 대시보드

실시간 원격지원 대기 목록

동작 및 주의사항 상담원 PC에는 RustDesk가 기본 설치되어 있고, 설정(네트워크 -> ID/릴레이 서버)에 자사 서버 IP와 공개키가 1회 등록되어 있어야 합니다. 만약 상담원 PC의 RustDesk 버전에 따라 ?password= 파라미터 자동 입력이 차단된 경우, rustdesk://connection/new/로 즉시 창을 띄우면서 동시에 navigator.clipboard.writeText(ticket.password)로 비밀번호를 클립보드에 자동 복사해 주면 상담원이 붙여넣기(Ctrl+V)만 눌러 바로 접속할 수 있습니다. 전체 개발 시간은 어느정도 걸릭까? 풀스택 웹 개발자 1명을 기준으로 오픈소스(RustDesk)를 활용해 구축할 경우, 기본 동작이 가능한 프로토타입(MVP)은 2~5일, 실제 고객에게 서비스할 수 있는 상용화 수준까지는 약 2~4주가 소요됩니다. 구현 목표와 자동화 수준에 따른 단계별 예상 소요 시간은 다음과 같습니다. 구축 수준 총 소요 기간 핵심 구현 범위 추천 용도 1단계: MVP (프로토타입) 2 ~ 5일 서버 구축, 기본 웹 호출/승인, 고객 ID 수동 입력 사내 테스트, 소규모 고객 지원 2단계: 실서비스 (자동화) 2 ~ 3주 상담원 로그인/권한, 이력 DB 저장, ID 자동 전송 스크립트 일반 기업 고객센터 도입 3단계: 고도화 (완전 맞춤형) 4 ~ 6주 이상 에이전트 자체 로고/UI 커스텀 빌드, 윈도우 코드사이닝 인증 상용 솔루션급 대외 서비스 세부 작업별 소요 시간 (실서비스 2~3주 기준) 인프라 및 중계 서버 구축 (1~2일): 클라우드 서버(AWS, 카페24 등) 생성, 방화벽 포트 설정, Docker 기반 RustDesk 서버(hbbs, hbbr) 구동 및 도메인·SSL(HTTPS) 인증서 연결에 걸리는 시간입니다. 웹 프론트엔드 및 실시간 알림 구현 (3~5일): 고객용 원격지원 요청 페이지, 상담원 전용 대시보드(대기열 목록, 알림음, 상태 표시), WebSocket(Socket.io) 연동 및 예외 처리(중복 호출 방지, 연결 끊김 감지)를 구현합니다. 관리자 기능 및 데이터베이스 연동 (3~5일): 상담원 계정 로그인, 원격지원 처리 이력(고객명, 요청 시간, 담당 상담원, 처리 메모) DB 저장 및 통계 조회 기능을 개발합니다. 고객 편의성 자동화 및 패키징 (3~5일): 고객이 9자리 ID와 비밀번호를 직접 타이핑하지 않도록 래퍼(Wrapper) 스크립트를 만들거나, 6자리 접속 번호 방식으로 매칭하는 로직을 추가하고 다양한 PC 환경(방화벽, 백신 프로그램 등)에서 테스트합니다. 일정을 좌우하는 핵심 변수 2가지 윈도우 보안 경고창 해결 (코드사이닝 인증서): 고객이 웹사이트에서 .exe 파일을 다운로드할 때 나타나는 'Windows의 PC 보호(SmartScreen)' 파란색 경고창을 없애려면 EV 코드사이닝(Code Signing) 인증서를 구매해 실행 파일에 서명해야 합니다. 개발 작업 자체는 1시간이면 끝나지만, 인증서 발급 심사(서류 제출 및 검증)에 약 1~2주가 걸리므로 상용 서비스라면 가장 먼저 신청해 두어야 합니다. 클라이언트 UI 커스터마이징 여부: RustDesk 기본 화면을 그대로 쓰면 하루 만에 배포 준비가 끝나지만, 프로그램 내부의 로고와 색상을 자사 브랜드로 완전히 바꾸고 불필요한 메뉴를 숨기려면 Flutter와 Rust 빌드 환경을 세팅해 컴파일해야 하므로 최소 1주일 이상이 추가됩니다. 기존 아파치 + PHP 운영 서버인데 여기에 설치 셋팅 가능할까? 기존 Apache + PHP(LAMP) 운영 서버에 그대로 설치 및 세팅이 완벽하게 가능하며, 오히려 별도의 Node.js 서버를 추가로 띄우지 않고 기존 환경(PHP + DB)만으로 훨씬 더 간단하고 안정적으로 구축할 수 있습니다. 핵심 이유는 다음과 같습니다: 포트 충돌 없음: Apache는 80, 443 포트를 쓰고, RustDesk 중계 서버(hbbs, hbbr)는 21115~21119번 대역의 독립된 포트를 사용하므로 기존 웹사이트 운영에 전혀 영향을 주지 않습니다. 초저사양 점유: RustDesk 서버는 메모리(RAM)를 약 20~50MB밖에 쓰지 않으며, 화면 데이터는 기본적으로 고객과 상담원 PC 간 P2P(직접 연결)로 전송되어 웹 서버 부하가 거의 없습니다. Node.js 불필요 (PHP + DB 폴링 방식): 실시간 알림을 위해 굳이 무거운 WebSocket(Node.js)을 새로 깔고 아파치 프록시를 설정할 필요 없이, PHP와 MySQL(MariaDB)에 2~3초 간격의 AJAX 조회(Polling) 또는 SSE(Server-Sent Events)를 적용하면 기존 소스 코드에 페이지 2개만 추가하여 바로 구현됩니다. Apache + PHP 환경 맞춤 구현 아키텍처 1단계: 기존 서버에 RustDesk 중계 데몬 띄우기 서버에 Docker가 있다면 이전 안내대로 실행하면 되고, Docker가 없는 일반 리눅스(Ubuntu/CentOS) 환경이라도 공식 실행 파일 2개(hbbs, hbbr)만 다운로드하여 백그라운드 서비스(systemd)로 등록하면 3분 만에 구동됩니다. 2단계: MySQL(MariaDB) 테이블 1개 추가 기존에 사용 중인 데이터베이스에 원격지원 대기열 테이블 하나만 생성합니다. SQL CREATE TABLE remote_support_queue ( id INT AUTO_INCREMENT PRIMARY KEY, customer_name VARCHAR(100) NOT NULL, rustdesk_id VARCHAR(30) NOT NULL, rustdesk_pw VARCHAR(30) NOT NULL, status ENUM('WAITING', 'APPROVED', 'CLOSED') DEFAULT 'WAITING', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); 3단계: PHP API 파일 1개 작성 (support_api.php) 고객의 호출 접수, 상담원 대시보드 목록 조회, 승인 상태 변경을 처리하는 가벼운 PHP 스크립트입니다. PHP prepare("INSERT INTO remote_support_queue (customer_name, rustdesk_id, rustdesk_pw) VALUES (?, ?, ?)"); $rustdeskId = preg_replace('/\s+/', '', $_POST['rustdesk_id']); // 공백 제거 $stmt->execute([$_POST['customer_name'], $rustdeskId, $_POST['rustdesk_pw']]); echo json_encode(['ticket_id' => $pdo->lastInsertId()]); exit; } // 2. 고객: 상담원이 승인했는지 상태 확인 (2초마다 호출) if ($action === 'check_status') { $stmt = $pdo->prepare("SELECT status FROM remote_support_queue WHERE id = ?"); $stmt->execute([$_GET['ticket_id']]); echo json_encode(['status' => $stmt->fetchColumn()]); exit; } // 3. 상담원: 대기 중인 요청 목록 조회 (2초마다 호출) if ($action === 'list') { $stmt = $pdo->query("SELECT * FROM remote_support_queue WHERE status = 'WAITING' ORDER BY id DESC"); echo json_encode($stmt->fetchAll(PDO::FETCH_ASSOC)); exit; } // 4. 상담원: 승인 클릭 시 상태 변경 if ($action === 'approve') { $stmt = $pdo->prepare("UPDATE remote_support_queue SET status = 'APPROVED' WHERE id = ?"); $stmt->execute([$_POST['ticket_id']]); echo json_encode(['success' => true]); exit; } ?> 4단계: 상담원 관리자 페이지에 JS 코드 삽입 기존에 운영 중인 PHP 관리자 페이지(Admin) 한구석에 아래 스크립트만 넣으면, 2초마다 새 요청을 확인하고 [승인 및 연결] 클릭 시 rustdesk:// 스키마로 즉시 원격 제어가 실행됩니다. HTML
대기 중인 원격지원이 없습니다.
사전 점검 사항 (이 2가지만 가능하면 100% 됩니다) 서버 SSH 루트(Root) 권한: Cafe24 등의 '웹호스팅(공유호스팅)'이 아니라, 직접 패키지를 설치할 수 있는 단독 서버, VPS, AWS EC2, Cafe24 가상서버호스팅 환경이어야 백그라운드에 RustDesk 중계 서버를 띄울 수 있습니다. 방화벽 포트 개방: 서버 방화벽(ufw, firewalld, 또는 클라우드 보안그룹)에서 TCP 21115~21119번과 UDP 21116번 포트를 열 수 있어야 합니다. 자 그럼 우분투 22서버이다. 이서버에서 rustdesk 설치부터 모든 과정을 순서대로 아주쉽게 복사 붙여넣기 수주으로 가능하도록 알려줘. 그리고 나중에 상용 서비스 할 수준으로 미리 작업을 해줘 우분투 22.04(Apache + PHP + MySQL/MariaDB) 서버에 Docker 같은 무거운 프로그램을 추가로 설치하지 않고, 리눅스 네이티브 서비스(systemd)로 가볍고 안정적이게 RustDesk 중계 서버를 올린 뒤 상용 수준의 웹 호출·승인 페이지까지 한 번에 구축하는 복사·붙여넣기 가이드입니다. 상용 서비스 기준에 맞춰 6자리 접속 번호 자동 생성, 상담원 소리 알림, 처리 상태 관리(대기/연결중/완료), 만료 처리, 보안 키 강제 적용까지 모두 포함했습니다. 1 방화벽 포트 개방 및 RustDesk 서버 설치 SSH 터미널에 루트(root) 권한으로 접속하여 그대로 복사해 붙여넣으세요 기존 Apache 웹 서버에 전혀 영향을 주지 않고 /opt/rustdesk 경로에 중계 서버를 설치한 뒤, 서버가 재부팅되어도 자동으로 켜지도록 시스템 서비스로 등록합니다. Bash # 1. 방화벽 포트 개방 (ufw 사용 시) - AWS/카페24 등 클라우드 방화벽에서도 아래 포트를 꼭 열어주세요! sudo ufw allow 21115:21119/tcp sudo ufw allow 21116/udp # 2. 설치 폴더 생성 및 최신 리눅스 바이너리 다운로드 sudo mkdir -p /opt/rustdesk cd /opt/rustdesk sudo apt-get update && sudo apt-get install -y wget unzip sudo wget https://github.com/rustdesk/rustdesk-server/releases/latest/download/rustdesk-server-linux-amd64.zip sudo unzip -j rustdesk-server-linux-amd64.zip sudo chmod +x hbbs hbbr # 3. 현재 서버의 공인 IP(또는 도메인) 자동 감지 후 systemd 서비스 등록 SERVER_IP=$(curl -s ifconfig.me) sudo tee /etc/systemd/system/rustdesk-hbbs.service > /dev/null < /dev/null < /dev/null <<'EOF' PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ]); } catch (Exception $e) { echo json_encode(['error' => 'DB 연결 실패']); exit; } // 30분 이상 대기만 하고 방치된 요청은 자동으로 취소(CANCELLED) 처리 $pdo->query("UPDATE remote_support_sessions SET status='CANCELLED' WHERE status='WAITING' AND created_at < NOW() - INTERVAL 30 MINUTE"); // 1. 고객: 원격지원 호출 접수 if ($action === 'request') { $name = trim($_POST['customer_name'] ?? ''); $phone = trim($_POST['customer_phone'] ?? ''); $inquiry = trim($_POST['inquiry_text'] ?? ''); $rId = preg_replace('/[^0-9]/', '', $_POST['rustdesk_id'] ?? ''); // 숫자만 추출 $rPw = trim($_POST['rustdesk_pw'] ?? ''); $ip = $_SERVER['REMOTE_ADDR'] ?? ''; $code = rand(100000, 999999); if (!$name || strlen($rId) < 7) { echo json_encode(['success' => false, 'message' => '고객명과 정확한 원격 ID(9자리 숫자)를 입력해 주세요.']); exit; } $stmt = $pdo->prepare("INSERT INTO remote_support_sessions (session_code, customer_name, customer_phone, inquiry_text, rustdesk_id, rustdesk_pw, client_ip) VALUES (?, ?, ?, ?, ?, ?, ?)"); $stmt->execute([$code, $name, $phone, $inquiry, $rId, $rPw, $ip]); echo json_encode(['success' => true, 'session_id' => $pdo->lastInsertId(), 'session_code' => $code]); exit; } // 2. 고객: 실시간 승인 상태 확인 if ($action === 'check_status') { $stmt = $pdo->prepare("SELECT status FROM remote_support_sessions WHERE id = ?"); $stmt->execute([$_GET['session_id'] ?? 0]); echo json_encode(['status' => $stmt->fetchColumn() ?: 'CANCELLED']); exit; } // 3. 고객: 원격지원 요청 취소 if ($action === 'cancel') { $stmt = $pdo->prepare("UPDATE remote_support_sessions SET status = 'CANCELLED' WHERE id = ? AND status = 'WAITING'"); $stmt->execute([$_POST['session_id'] ?? 0]); echo json_encode(['success' => true]); exit; } // 4. 상담원: 대기 및 진행 중인 목록 조회 if ($action === 'list') { $stmt = $pdo->query("SELECT * FROM remote_support_sessions WHERE status IN ('WAITING', 'CONNECTED') ORDER BY FIELD(status, 'WAITING', 'CONNECTED'), id DESC"); echo json_encode(['list' => $stmt->fetchAll()]); exit; } // 5. 상담원: 호출 승인 및 원격 연결 시작 if ($action === 'approve') { $stmt = $pdo->prepare("UPDATE remote_support_sessions SET status = 'CONNECTED', connected_at = NOW() WHERE id = ?"); $stmt->execute([$_POST['session_id'] ?? 0]); echo json_encode(['success' => true]); exit; } // 6. 상담원: 지원 종료 및 메모 저장 if ($action === 'complete') { $stmt = $pdo->prepare("UPDATE remote_support_sessions SET status = 'COMPLETED', agent_memo = ?, completed_at = NOW() WHERE id = ?"); $stmt->execute([$_POST['agent_memo'] ?? '', $_POST['session_id'] ?? 0]); echo json_encode(['success' => true]); exit; } ?> EOF 5 고객용 원격지원 요청 페이지 생성 (index.php) 깔끔한 상용 UI가 적용된 고객 접속 화면입니다 고객이 http://내서버도메인/support/로 접속하면 보게 되는 화면입니다. Bash sudo tee /var/www/html/support/index.php > /dev/null <<'EOF' 고객 원격지원 센터

실시간 원격지원 요청

STEP 1. 전용 원격 프로그램 실행

아래 버튼을 눌러 프로그램을 다운로드한 뒤 실행해 주세요. (이미 실행 중이면 STEP 2로 이동)

원격지원 프로그램 다운로드
STEP 2. 접속 정보 입력 및 호출

상담원 승인 대기 중...

접수번호:
상담원이 곧 원격 연결을 시작합니다. 프로그램을 끄지 말고 잠시만 기다려 주세요.

EOF 6 상담원 전용 대시보드 생성 (admin.php) 새 요청 접수 시 알림음이 울리며 원클릭으로 원격 연결이 실행됩니다 상담원이 http://내서버도메인/support/admin.php로 접속해 요청을 승인하는 관리자 화면입니다. Bash sudo tee /var/www/html/support/admin.php > /dev/null <<'EOF' 상담원 원격지원 관제 대시보드

원격지원 실시간 대기열

2초마다 자동 갱신 중 (승인 클릭 시 비밀번호가 자동 복사됩니다)
대기 중인 요청을 불러오는 중...
EOF 상담원 PC 최초 1회 설정 방법 고객은 웹사이트에서 다운로드한 파일 이름에 이미 서버 IP와 공개키가 들어 있어 아무 설정도 할 필요가 없지만, 상담원 PC에는 최초 1번만 아래 방법대로 설정해 두면 됩니다. 상담원 PC에서도 고객용 페이지(http://내서버도메인/support/)에 접속해 원격지원 프로그램 다운로드 버튼을 눌러 실행하거나, 설치된 RustDesk의 [설정] - [네트워크] - [ID/릴레이 서버] 메뉴를 엽니다. ID 서버 칸에 내서버IP, Key 칸에 1단계에서 확인한 공개키를 넣고 확인을 누릅니다. 이제 상담원이 admin.php에서 [승인 및 원격제어 실행] 버튼을 누르면 즉시 고객 화면으로 연결됩니다. 우리가 이작업을 안티그래비티로 할 예정이다 > 구글 안티그래비티(Google Antigravity) 환경에서 작업을 진행한다면, 개발자가 터미널에 명령어를 일일이 복사·붙여넣기 할 필요 없이 에이전트에게 프롬프트 한 번만 내려 서버 설치부터 파일 생성, DB 테이블 구축, 브라우저 테스트까지 전 과정을 자동으로 실행시킬 수 있습니다. 틸노트 안티그래비티는 파일 편집기와 리눅스 터미널, 내장 브라우저를 에이전트가 직접 제어하므로 아래 순서대로 연결하여 지시만 내리면 됩니다. Wikipedia 1단계: 안티그래비티에서 우분투 22.04 서버 연결 및 권한 설정 Remote-SSH로 서버 접속: 안티그래비티 IDE를 실행한 뒤 Remote-SSH를 통해 우분투 22.04 서버에 접속하고, 웹 루트 디렉토리(/var/www/html)를 워크스페이스로 엽니다. (또는 서버에 Antigravity CLI가 설치되어 있다면 바로 실행합니다.) Visual Studio Marketplace + 1 에이전트 실행 모드 설정: 현재 운영 중인 Apache + PHP 서버이므로, 에이전트가 임의로 기존 설정을 덮어쓰지 않도록 Review-driven development(검토 중심 모드)를 선택하거나, 터미널 명령어 실행 시 sudo 명령만 승인을 받도록 설정하는 것이 안전합니다. 경력만 많은 초보개발자 2단계: 안티그래비티 에이전트에게 그대로 복사해 줄 '마스터 프롬프트' 안티그래비티 사이드바 채팅창(Ctrl + L 또는 Cmd + L)을 열고, 아래 프롬프트에서 DB 접속 정보 3곳만 수정하여 그대로 붙여넣으세요. 에이전트가 알아서 구현 계획(Implementation Plan)과 작업 목록(Task List) 아티팩트를 생성한 뒤 순차적으로 구축을 완료합니다. Visual Studio Marketplace + 1 Markdown 현재 연결된 Ubuntu 22.04 서버(Apache + PHP + MySQL 운영 중)에 RustDesk 자체 중계 서버와 웹 원격지원 호출/승인 시스템을 구축해 줘. 기존 웹사이트에는 영향을 주지 않도록 아래 요구사항에 맞춰 터미널 명령 실행과 파일 생성을 직접 수행해 줘. [사전 DB 정보] - DB 호스트: localhost - DB 이름: 여기에_DB이름_입력 - DB 계정: 여기에_DB계정_입력 - DB 비밀번호: 여기에_DB비번_입력 [작업 지시사항] 1. RustDesk 서버(/opt/rustdesk) 설치 및 서비스 등록: - `/opt/rustdesk` 디렉토리를 만들고 최신 `rustdesk-server-linux-amd64.zip`을 다운로드해 압축을 풀고 실행 권한을 부여해 줘. - `curl -s ifconfig.me`로 현재 서버 공인 IP를 확인한 뒤, `rustdesk-hbbs.service` (`hbbs -r <서버IP>:21117 -k _`)와 `rustdesk-hbbr.service` (`hbbr -k _`) 두 개의 systemd 서비스를 생성하고 `enable --now`로 실행해 줘. - ufw가 활성화되어 있다면 21115:21119/tcp 및 21116/udp 포트를 허용해 줘. 2. 고객 배포용 실행 파일 준비: - `/var/www/html/support/downloads` 폴더를 생성하고 아파치 권한(`www-data:www-data`)을 맞춰줘. - 생성된 `/opt/rustdesk/id_ed25519.pub` 공개키와 서버 공인 IP를 읽어서 `rustdesk-host=<서버IP>,key=<공개키>.exe` 이름으로 공식 Windows 클라이언트를 다운로드해 저장하고, 파일명을 `filename.txt`에 기록해 줘. 3. 데이터베이스 테이블 생성: - 위 DB 정보를 사용해 `remote_support_sessions` 테이블을 생성해 줘. - 컬럼: `id`(PK), `session_code`(6자리 접수번호), `customer_name`, `customer_phone`, `inquiry_text`, `rustdesk_id`, `rustdesk_pw`, `client_ip`, `status`('WAITING','CONNECTED','COMPLETED','CANCELLED'), `agent_memo`, `created_at`, `connected_at`, `completed_at`. 4. 상용 PHP 파일 3개 작성 (`/var/www/html/support/` 경로): - `api.php`: * `download_agent`: `filename.txt`를 읽어 해당 파일명으로 `.exe` 다운로드 헤더 전송 * `request`: 고객 원격지원 요청 DB 저장 및 6자리 접수번호 반환 (30분 지난 WAITING 세션은 자동 CANCELLED 처리 포함) * `check_status`, `cancel`, `list`, `approve`, `complete` 액션 구현 - `index.php`: * 깔끔한 반응형 카드 UI. STEP 1(전용 에이전트 다운로드 버튼), STEP 2(고객명, 연락처, 9자리 ID, 일회용 비밀번호, 문의내용 입력 폼). * 요청 후 2초 주기로 `check_status`를 폴링하여 대기 중/연결됨/종료 상태를 실시간 표시. - `admin.php`: * 다크 테마 관제 대시보드. 2초 주기로 대기열(`WAITING`, `CONNECTED`) 조회, 신규 대기 건 발생 시 Web Audio API 비프음 출력. * [승인 및 원격제어 실행] 클릭 시 비밀번호를 클립보드에 복사하고 `approve` API 호출 후 `rustdesk://connection/new/?password=` 스키마 실행. * [지원 완료] 클릭 시 상담원 메모를 입력받아 `complete` 처리. 5. 검증: - 모든 작업 후 `systemctl status rustdesk-hbbs rustdesk-hbbr` 상태를 확인하고, 내장 브라우저 서브에이전트(`/browser`)로 `index.php`와 `admin.php`가 에러 없이 렌더링되는지 테스트해서 결과를 알려줘. 3단계: 안티그래비티의 특화 기능 활용 팁 작업 내역(Artifacts) 자동 문서화: 에이전트가 작업을 마치면 우측 아티팩트 뷰어에 구현 계획서(Implementation Plan)와 워크스루 보고서(Walkthrough)가 마크다운 문서로 자동 생성됩니다. 서버의 공개키 값이나 설정 경로가 모두 이 문서에 기록되므로 별도로 인수인계 문서를 작성할 필요가 없습니다. Visual Studio Marketplace + 1 내장 브라우저(/browser) 자동 테스트: 프롬프트 마지막 줄의 지시에 따라 안티그래비티의 브라우저 서브에이전트가 직접 가상 크롬을 띄워 고객 페이지에서 테스트 접수까지 눌러보고, 상담원 페이지에 알림이 뜨는 과정을 스크린샷·녹화본으로 검증해 줍니다. Visual Studio Marketplace + 1 우선 여기에 맞는 RULES 를 정의하려고 한다. 아래는 일단 내가 사용하는 룰 일부이다. 보고 우리 작업에 맞는 제대로 된 AGENTS.md 완성해줘. -> --- trigger: always_on --- # 프로젝트 기본 환경 및 구조 규칙 ## 1. 기술 스택 및 환경 **OS**: Ubuntu22.04LTS **Web Server**: Apache 2.4.52 **Backend**: PHP 7.0.33-86 (Legacy 환경 호환성 유지) **Database**: MariaDB **Frontend**: **Domain**: help.damoe.net ## 2. 계정정보 **Server**: "host": "115.71.237.146", "protocol": "sftp", "port": 22, "username": "madrun", "remotePath": "/SITE/help/public_html", "uploadOnSave": true, "useTempFile": false, "openSsh": false, "password": "tjdudtjs09!@" **GITHUB**: ## 1. [WORKSPACE_SYNC] 작업 환경 동기화 및 파일 관리 룰 (최우선) **프로젝트 종속적 파일 저장**: IDE가 구동되면서 생성하는 `implementation_plan.md`, `json_policy.md`, `task.md`, `walkthrough.md` 등 모든 작업 계획, 제안, 기억(Memory) 파일은 절대 작업 PC의 외부 전역(Global) 폴더에 저장하지 않습니다. **저장 경로 절대 강제**: 작업 시 생성하는 모든 antigravity 파일(계획서, 태스크, 스크래치/분석 자료 등)은 로컬의 시스템 글로벌 `.antigravity` / `.gemini` 폴더가 아니라, PC 여러 대에서 작업하는 환경을 고려하여 반드시 현재 프로젝트 루트의 `./.docs/` 폴더 내부에 물리적인 파일로 기록해야 합니다. - ⚠️ 아티팩트(Artifact) 옵션/메타데이터를 사용하면 시스템 전역 폴더에 숨겨지므로 **절대 사용 금지**. - 반드시 일반 파일 쓰기로 `./.docs/task.md` 등 **프로젝트 내부 경로를 직접 지정**하여 기록할 것. - 임시 스크립트·분석 원본 등 스크래치 파일은 `./.docs/scratch/` 에 저장합니다. **상대 경로 마크다운 링크 강제**: 프로젝트 문서 내 파일 참조 링크 작성 시 다른 PC 및 클라우드 동기화(OneDrive 등) 환경과의 완벽한 이동성 보장을 위해 로컬 절대경로(`file:///C:/Users/...`) 사용을 엄금하고, 반드시 프로젝트 상대 경로(예: `[03_Server_setup.md](./03_Server_setup.md)`)로 기록합니다. **이동성(Portability) 보장**: 사용자가 여러 대의 PC를 오가며 작업하더라도 프로젝트 폴더만 복사(또는 Git Clone)하면 IDE가 기존의 작업 컨텍스트와 기억을 완벽히 이어서 파악할 수 있도록 모든 문맥(Context)을 프로젝트 폴더 내부에 국한시킵니다. --- ## 2. [WORK_LOG] 작업 일지 기록 룰 **기록 파일**: [`./.docs/99.Work_log.md`](../.docs/99.Work_log.md) **기록 대상**: 사용자와 에이전트가 진행한 **그날의 모든 작업 내용** — 요청 사항, 결정 사항(Q&A 답변 포함), 생성/수정/삭제한 파일, 미결 사항, 다음 할 일. **기록 시점**: 하나의 요청(작업 단위)을 마칠 때마다 **즉시 추가 기록**합니다. 작업 종료 응답 전에 로그 갱신을 반드시 완료합니다. **기록 형식**: - 날짜별 섹션 `## 📅 YYYY-MM-DD (요일)` — 최신 날짜가 **위**에 오도록 작성 - 날짜 섹션 내부는 작업 순서대로 `### HH:MM — 작업 제목` - 각 작업 항목: `요청` / `결정 사항` / `작업 내용` / `변경 파일` / `미결·다음 할 일` - 파일 링크는 룰 1에 따라 **상대 경로**만 사용 **상단 요약 유지**: 로그 최상단의 `📌 현재 상태 요약`(진행 단계, 미결 사항, 다음 할 일)을 매번 최신으로 갱신합니다. --- ## 3. [STATUS_CHECK] 룰 점검 및 진행상황 체크 사용자가 **"룰 점검 및 진행상황 체크해줘"** (또는 유사 표현: "진행상황 알려줘", "어디까지 했지?")라고 요청하면 다음 순서로 수행합니다. 본 파일 `AGENTS.md` 의 룰을 다시 읽고 준수 여부를 점검합니다. - 전역 폴더에 저장된 작업 파일이 없는지, 문서 내 절대경로 링크가 없는지 확인 - 외부 CDN/구글 라이브러리 사용 여부 점검 - 위반 사항 발견 시 보고 후 수정 2. [`./.docs/99.Work_log.md`](../.docs/99.Work_log.md) 의 `📌 현재 상태 요약` 과 최근 작업 기록을 확인합니다. 3. `./.docs/` 의 주요 문서(예: [`01.프로젝트개요.md`](../.docs/01.프로젝트개요.md), `task.md`)를 확인합니다. 4. 사용자에게 **① 룰 점검 결과 ② 현재 진행 단계 ③ 미결 사항 ④ 다음 할 일**을 간결하게 보고합니다. --- ## 4. [DOCS] 문서 관리 기본 규칙 프로젝트 문서는 `./.docs/` 에 `NN.문서명.md` 형식으로 관리합니다. (예: `01.프로젝트개요.md`, `99.Work_log.md`) 문서는 GitHub Flavored Markdown 형식을 따르며, 다이어그램은 Mermaid를 사용합니다. `00.계정정보.md` 등 민감 정보 문서의 내용은 다른 문서나 로그에 **복사·인용하지 않습니다.** 제공해주신 기존 룰의 핵심 철학(.docs 로컬 문서화 강제, 전역 아티팩트 사용 금지, 상대 경로 유지, 작업 일지 자동화)을 그대로 계승하면서, 이번 원격지원 시스템(help.damoe.net, 115.71.237.146)의 특수 환경(PHP 7.0.33 호환성, 외부 CDN 배제, /SITE/help/public_html 경로, 보안 폴더 접근 차단)을 완벽히 반영하여 완성한 AGENTS.md 파일입니다. 프로젝트 루트(또는 .antigravity/rules/ 및 루트의 AGENTS.md)에 그대로 복사하여 저장하시면 됩니다. Markdown --- trigger: always_on --- # AGENTS.md — 원격지원 시스템(help.damoe.net) 프로젝트 룰 에이전트(Antigravity)는 모든 작업 수행 전 본 문서의 규칙을 최우선으로 숙지하고 엄격히 준수해야 합니다. --- ## 0. 프로젝트 기본 환경 및 인프라 명세 ### 0-1. 기술 스택 및 서버 환경 - **Project**: 실시간 원격지원 호출·승인 및 중계 시스템 (RustDesk Self-Hosted 연동) - **OS**: Ubuntu 22.04 LTS - **Web Server**: Apache 2.4.52 - **Backend**: **PHP 7.0.33-86** (⚠️ **Legacy 환경 호환성 엄수** — PHP 7.1+ 문법 사용 절대 금지) - **Database**: MariaDB (InnoDB, `utf8mb4`) - **Frontend**: Vanilla HTML5 / CSS3 / ES6 JavaScript (⚠️ **외부 CDN 및 구글 웹폰트/라이브러리 사용 금지**, 순수 내장 스크립트 및 로컬 에셋만 사용) - **Domain**: `help.damoe.net` - **Web Root (`remotePath`)**: `/SITE/help/public_html` - **RustDesk Server Daemon**: - 설치 경로: `/opt/rustdesk` (`hbbs`, `hbbr`, `id_ed25519.pub`) - 서비스명: `rustdesk-hbbs.service`, `rustdesk-hbbr.service` - 사용 포트: TCP `21115~21119`, UDP `21116` ### 0-2. 서버 접속 및 배포 정보 > ⚠️ 아래 접속 정보는 에이전트의 SFTP/SSH 제어 참조용이며, `./.docs/99.Work_log.md` 등 일반 문서에 비밀번호를 평문으로 재인용하지 않습니다. ```json { "host": "115.71.237.146", "protocol": "sftp", "port": 22, "username": "madrun", "remotePath": "/SITE/help/public_html", "uploadOnSave": true, "useTempFile": false, "openSsh": false, "password": "tjdudtjs09!@" } GitHub: (저장소 연결 시 상대 경로 유지 및 .docs/00.계정정보.md, config.php 등 민감 파일 .gitignore 필수 등록) 0-3. 표준 디렉토리 구조 (/SITE/help/public_html) Plaintext /SITE/help/public_html/ ├── .htaccess # ./.docs/ 및 민감 파일 외부 웹 접근 차단 규칙 필수 ├── AGENTS.md # 본 프로젝트 에이전트 수칙 ├── .docs/ # 모든 계획서, 작업 로그, 문서 저장소 (웹 접근 차단됨) │ ├── 00.계정정보.md # DB/서버 민감 정보 (타 문서 인용 금지) │ ├── 01.프로젝트개요.md # 시스템 아키텍처 및 개요 │ ├── 02.DB_스키마.md # MariaDB 테이블 명세 │ ├── 03.Server_setup.md # RustDesk 데몬 및 방화벽 설정 기록 │ ├── 99.Work_log.md # 일일 작업 일지 (매 작업 종료 시 갱신) │ ├── implementation_plan.md # 에이전트 작업 계획서 │ ├── task.md # 에이전트 태스크 체크리스트 │ ├── walkthrough.md # 에이전트 작업 검증 보고서 │ └── scratch/ # 임시 분석 자료 및 테스트 스크립트 ├── inc/ │ └── db_config.php # DB 연결 설정 (PDO, PHP 7.0 호환) ├── downloads/ │ ├── filename.txt # 배포용 에이전트 파일명 기록 │ └── rustdesk-host=....exe # 서버 IP 및 공개키가 내장된 고객 배포용 실행 파일 ├── assets/ # 로컬 CSS, JS, 아이콘 (외부 CDN 사용 금지) ├── index.php # 고객용 원격지원 호출 요청 페이지 ├── admin.php # 상담원 전용 실시간 관제 및 승인 대시보드 └── api.php # 호출/승인/상태체크/파일다운로드 백엔드 API 1. [WORKSPACE_SYNC] 작업 환경 동기화 및 파일 관리 룰 (최우선) 프로젝트 종속적 파일 저장: IDE가 구동되면서 생성하는 implementation_plan.md, json_policy.md, task.md, walkthrough.md 등 모든 작업 계획, 제안, 기억(Memory) 파일은 절대 작업 PC의 외부 전역(Global) 폴더에 저장하지 않습니다. 저장 경로 절대 강제: 작업 시 생성하는 모든 Antigravity 파일(계획서, 태스크, 스크래치/분석 자료 등)은 로컬의 시스템 글로벌 .antigravity / .gemini 폴더가 아니라, PC 여러 대에서 작업하는 환경을 고려하여 반드시 현재 프로젝트 루트의 ./.docs/ 폴더 내부에 물리적인 파일로 기록해야 합니다. ⚠️ 아티팩트(Artifact) 옵션/메타데이터를 사용하면 시스템 전역 폴더에 숨겨지므로 절대 사용 금지. 반드시 일반 파일 쓰기(File Write 도구)로 ./.docs/task.md, ./.docs/implementation_plan.md 등 프로젝트 내부 경로를 직접 지정하여 기록할 것. 임시 스크립트·분석 원본 등 스크래치 파일은 ./.docs/scratch/ 에 저장합니다. 상대 경로 마크다운 링크 강제: 프로젝트 문서 내 파일 참조 링크 작성 시 다른 PC 및 클라우드 동기화(OneDrive 등) 환경과의 완벽한 이동성 보장을 위해 로컬 절대경로(file:///C:/Users/... 또는 /SITE/help/...) 사용을 엄금하고, 반드시 문서 기준 상대 경로(예: [03.Server_setup.md](./03.Server_setup.md))로 기록합니다. 이동성(Portability) 보장: 사용자가 여러 대의 PC를 오가며 작업하더라도 프로젝트 폴더만 복사(또는 Git Clone / SFTP 동기화)하면 IDE가 기존의 작업 컨텍스트와 기억을 완벽히 이어서 파악할 수 있도록 모든 문맥(Context)을 프로젝트 폴더 내부에 국한시킵니다. 2. [WORK_LOG] 작업 일지 기록 룰 기록 파일: ./.docs/99.Work_log.md 기록 대상: 사용자와 에이전트가 진행한 그날의 모든 작업 내용 — 요청 사항, 결정 사항(Q&A 답변 포함), 생성/수정/삭제한 파일, 실행한 서버 명령어 요약, 미결 사항, 다음 할 일. 기록 시점: 하나의 요청(작업 단위)을 마칠 때마다 즉시 추가 기록합니다. 작업 종료 응답 전에 로그 갱신을 반드시 완료합니다. 기록 형식: 날짜별 섹션 ## 📅 YYYY-MM-DD (요일) — 최신 날짜가 위에 오도록 작성 (역순 정렬) 날짜 섹션 내부는 작업 순서대로 ### HH:MM — 작업 제목 각 작업 항목: 요청 / 결정 사항 / 작업 내용 / 변경 파일 / 미결·다음 할 일 파일 링크는 룰 1에 따라 상대 경로만 사용 상단 요약 유지: 로그 최상단의 📌 현재 상태 요약(진행 단계, 미결 사항, 다음 할 일)을 매번 최신으로 갱신합니다. 3. [STATUS_CHECK] 룰 점검 및 진행상황 체크 사용자가 "룰 점검 및 진행상황 체크해줘" (또는 유사 표현: "진행상황 알려줘", "어디까지 했지?")라고 요청하면 다음 순서로 수행합니다. 본 파일 AGENTS.md 의 룰을 다시 읽고 준수 여부를 점검합니다. 전역 폴더에 저장된 작업 파일이 없는지, 문서 내 절대경로 링크가 없는지 확인 외부 CDN/구글 라이브러리 사용 여부 점검 PHP 7.0.33 미지원 문법 사용 여부 및 .docs/ 웹 접근 차단(.htaccess) 적용 여부 점검 위반 사항 발견 시 보고 후 즉시 수정 ./.docs/99.Work_log.md 의 📌 현재 상태 요약 과 최근 작업 기록을 확인합니다. ./.docs/ 의 주요 문서(예: 01.프로젝트개요.md, task.md)를 확인합니다. 사용자에게 ① 룰 점검 결과 ② 현재 진행 단계 ③ 미결 사항 ④ 다음 할 일을 간결하게 보고합니다. 4. [DOCS] 문서 관리 및 보안 기본 규칙 프로젝트 문서는 ./.docs/ 에 NN.문서명.md 형식으로 관리합니다. (예: 01.프로젝트개요.md, 02.DB_스키마.md, 99.Work_log.md) 문서는 GitHub Flavored Markdown 형식을 따르며, 아키텍처 및 흐름도 다이어그램은 Mermaid를 사용합니다. 00.계정정보.md 및 AGENTS.md의 비밀번호 등 민감 정보 내용은 다른 문서나 작업 로그에 복사·인용하지 않습니다. 웹 루트 내 문서 폴더 보안 필수: /SITE/help/public_html/.docs/ 폴더가 외부 웹 브라우저(https://help.damoe.net/.docs/...)를 통해 노출되지 않도록 .htaccess 또는 ./.docs/.htaccess 파일에 Require all denied 설정을 반드시 유지합니다. 5. [CODING_RULES] 개발 및 기술 제약 수칙 (PHP 7.0 & 원격지원 특화) 5-1. PHP 7.0.33 호환성 엄수 (Critical) 서버의 PHP 버전이 7.0.33-86이므로, PHP 7.1 이상에서 도입된 아래 문법은 구문 오류(Fatal Error)를 유발하므로 절대 사용하지 않습니다. ❌ Nullable 타입 힌트 금지 (?string, ?int 사용 불가) ❌ void 반환 타입 명시 금지 (function test(): void 사용 불가) ❌ 클래스 상수 가시성 지정자 금지 (public const, private const 사용 불가 -> 일반 const 사용) ❌ 배열 구조 분해 할당 [ $a, $b ] = $array 금지 -> 반드시 list($a, $b) = $array 사용 ❌ 다중 catch 구문 catch (FirstException | SecondException $e) 금지 ❌ PHP 7.4 화살표 함수(fn($x) => $x) 및 Null 병합 할당 연산자(??=) 금지 (일반 Null 병합 연산자 $a ?? 'default'는 PHP 7.0 지원하므로 사용 가능) ✅ DB 연동은 반드시 PDO Prepared Statement를 사용하여 SQL Injection을 방지합니다. 5-2. 무의존성 프론트엔드 (No External CDN) 폐쇄망이나 엄격한 방화벽 환경의 고객 PC에서도 화면이 깨지지 않도록 외부 CDN(Bootstrap, jQuery CDN, FontAwesome, Google Fonts 등)을 일체 사용하지 않습니다. 모든 스타일은 자체 CSS(또는 파일 내