import { useState, useEffect } from 'react'; import { Card } from '../../shared/ui/Card'; import { apiClient } from '../../shared/api/client'; import { Info, Cpu, Database, Server, Hash, Calendar, RefreshCw, AlertTriangle, CheckCircle2 } from 'lucide-react'; interface VersionInfo { status: string; version: string; node_version: string; platform: string; arch: string; timestamp: string; } interface UpdateEntry { version: string; date: string; title: string; changes: string[]; type: 'feature' | 'fix' | 'urgent' | 'patch'; } interface RemoteVersion { current: string; latest: string | null; needsUpdate: boolean; latestInfo: UpdateEntry | null; history: UpdateEntry[]; error?: string; } export function VersionPage() { const [healthIcon, setHealthInfo] = useState(null); const [remoteInfo, setRemoteInfo] = useState(null); const [loading, setLoading] = useState(true); const [checkingRemote, setCheckingRemote] = useState(false); const [updating, setUpdating] = useState(false); const [updateResult, setUpdateResult] = useState<{ success: boolean; message: string } | null>(null); const fetchVersion = async () => { setLoading(true); try { // Add timestamp to prevent caching const res = await apiClient.get(`/health?t=${Date.now()}`); setHealthInfo(res.data); } catch (err) { console.error('Failed to fetch version info', err); } finally { setLoading(false); } }; const fetchRemoteVersion = async () => { setCheckingRemote(true); try { const res = await apiClient.get(`/system/version/remote?t=${Date.now()}`); setRemoteInfo(res.data); } catch (err) { console.error('Failed to fetch remote version info', err); } finally { setCheckingRemote(false); } }; useEffect(() => { fetchVersion(); fetchRemoteVersion(); }, []); const handleUpdate = async () => { if (!remoteInfo?.latest) return; const info = remoteInfo.latestInfo; const changelog = info ? `\n\n[주요 변경 내역]\n${info.changes.map(c => `- ${c}`).join('\n')}` : ''; if (!confirm(`시스템을 v${info?.version || remoteInfo.latest} 버전으로 업데이트하시겠습니까?${changelog}\n\n업데이트 중에는 시스템이 일시적으로 중단될 수 있습니다.`)) { return; } setUpdating(true); setUpdateResult(null); try { const res = await apiClient.post('/system/version/update', { targetTag: remoteInfo.latest }); setUpdateResult({ success: true, message: res.data.message }); // Success: Wait a bit for server to settle, then refresh let countdown = 5; const timer = setInterval(() => { countdown -= 1; if (countdown <= 0) { clearInterval(timer); window.location.reload(); } else { setUpdateResult({ success: true, message: `${res.data.message} (${countdown}초 후 페이지가 새로고침됩니다.)` }); } }, 1000); } catch (err: any) { console.error('Update failed', err); setUpdateResult({ success: false, message: err.response?.data?.error || '업데이트 요청 중 오류가 발생했습니다.' }); setUpdating(false); } }; // Source of truth for versioning comes from the API const currentVersion = remoteInfo?.current || healthIcon?.version || '---'; const buildDate = '2026-01-25'; // Check if update is needed based on API-supplied needsUpdate flag const needsUpdate = !!remoteInfo?.needsUpdate; return (

시스템 관리 - 버전 정보

플랫폼 및 서버의 현재 릴리즈 버전을 확인하고 업데이트를 관리합니다.

{/* Update Alert Banner - Based on Frontend Version comparison */} {needsUpdate && !updateResult && (

{remoteInfo?.latestInfo?.type === 'urgent' ? '🚨 긴급 보안/시스템 업데이트 발견' : '✨ 새로운 업데이트가 가능합니다'}

{remoteInfo?.latestInfo?.type || 'patch'}

현재 버전: v{currentVersion} → 최신 버전: {remoteInfo?.latest}

{remoteInfo?.latestInfo && (

[{remoteInfo.latestInfo.title}]

    {remoteInfo.latestInfo.changes.slice(0, 3).map((c, i) => (
  • {c}
  • ))} {remoteInfo.latestInfo.changes.length > 3 &&
  • ...외 {remoteInfo.latestInfo.changes.length - 3}건
  • }
)}
)} {/* Update Result Message */} {updateResult && (
{updateResult.success ? : }

{updateResult.message}

)}
{/* Frontend Platform Version */}

Frontend Platform

Smart IMS 클라이언트

현재 버전 v{currentVersion}
빌드 일자 {buildDate}
아키텍처 React Agentic Architecture
{/* Backend Server Version */}

Backend Core

IMS 서비스 엔진

런타임 환경 {loading ? 'Checking...' : healthIcon?.node_version ? `Node.js ${healthIcon.node_version}` : 'N/A'}
운영 체제 {loading ? '...' : healthIcon?.platform ? `${healthIcon.platform} (${healthIcon.arch})` : 'Unknown'}
서버 타임스탬프 {loading ? '...' : healthIcon?.timestamp || 'Unknown'}
엔진 상태 {loading ? '...' : healthIcon?.status === 'ok' ? 'Running' : 'Offline'}
{/* Remote Info Status (Debug/Info) */} {remoteInfo && (
원격 저장소 상태: {remoteInfo.error ? `오류 (${remoteInfo.error})` : '정상'}
{!remoteInfo.error && ( 최신 배포 태그: {remoteInfo.latest || '없음'} )}
)} {/* Release History Section */}

업데이트 히스토리

{remoteInfo?.history && remoteInfo.history.length > 0 ? ( remoteInfo.history.map((entry, idx) => (
{entry.type} v{entry.version}

{entry.title}

{entry.date}
    {entry.changes.map((change, i) => (
  • {change}
  • ))}
)) ) : (
원격 저장소에서 업데이트 내역을 가져오는 중이거나 내역이 없습니다.
)}
{/* Bottom Integrity Banner */}

Platform Integrity

Smart IMS 플랫폼은 데이터 보안과 시스템 안정성을 최우선으로 설계되었습니다. 모든 모듈은 Sokuree 아키텍처 표준을 준수하며, 암호화 키 관리 시스템(L2 Protection)에 의해 보호되고 있습니다.

); } // Internal Local Components if not available in shared/ui function ShieldCheck({ size, className }: { size?: number, className?: string }) { return ( ); } function Box({ size, className }: { size?: number, className?: string }) { return ( ); }