사이드바 브랜딩을 PharmQ Super Admin (PSA)로 업데이트
- base.html 상단 네비게이션 브랜딩 변경 - 팜큐 약국 관리 시스템 → PharmQ Super Admin (PSA) - UI 일관성 향상을 위한 브랜딩 통합 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
209
farmq-admin/init_sample_data.py
Normal file
209
farmq-admin/init_sample_data.py
Normal file
@@ -0,0 +1,209 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
FARMQ 관리 시스템 - 샘플 데이터 초기화 스크립트
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime, timedelta
|
||||
import random
|
||||
from sqlalchemy import text
|
||||
|
||||
# 현재 디렉토리를 파이썬 경로에 추가
|
||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, current_dir)
|
||||
|
||||
from config import config
|
||||
from utils.database import init_database, get_session, close_session
|
||||
from models import PharmacyInfo, MachineSpecs, MonitoringData, Alert, User, Node
|
||||
|
||||
def init_sample_data():
|
||||
"""샘플 데이터 초기화"""
|
||||
print("🔧 Initializing sample data for FARMQ Admin System...")
|
||||
|
||||
# 데이터베이스 세션 획득
|
||||
session = get_session()
|
||||
|
||||
try:
|
||||
# 1. 기존 샘플 데이터 정리
|
||||
print("📝 Cleaning existing sample data...")
|
||||
session.query(Alert).delete()
|
||||
session.query(MonitoringData).delete()
|
||||
session.query(MachineSpecs).delete()
|
||||
session.query(PharmacyInfo).delete()
|
||||
|
||||
# 2. 샘플 약국 데이터 생성
|
||||
print("🏥 Creating sample pharmacy data...")
|
||||
pharmacies = [
|
||||
{
|
||||
'pharmacy_name': '서울약국',
|
||||
'business_number': '123-45-67890',
|
||||
'manager_name': '김철수',
|
||||
'phone': '02-1234-5678',
|
||||
'address': '서울특별시 강남구 테헤란로 123',
|
||||
'proxmox_host': '192.168.1.100',
|
||||
'user_id': 'seoul-pharmacy'
|
||||
},
|
||||
{
|
||||
'pharmacy_name': '부산메디컬약국',
|
||||
'business_number': '987-65-43210',
|
||||
'manager_name': '이영희',
|
||||
'phone': '051-2345-6789',
|
||||
'address': '부산광역시 해운대구 센텀대로 456',
|
||||
'proxmox_host': '192.168.1.101',
|
||||
'user_id': 'busan-medical'
|
||||
},
|
||||
{
|
||||
'pharmacy_name': '대구건강약국',
|
||||
'business_number': '456-78-91234',
|
||||
'manager_name': '박민수',
|
||||
'phone': '053-3456-7890',
|
||||
'address': '대구광역시 중구 동성로 789',
|
||||
'proxmox_host': '192.168.1.102',
|
||||
'user_id': 'daegu-health'
|
||||
},
|
||||
{
|
||||
'pharmacy_name': '인천바다약국',
|
||||
'business_number': '321-54-87695',
|
||||
'manager_name': '최수진',
|
||||
'phone': '032-4567-8901',
|
||||
'address': '인천광역시 연수구 송도대로 321',
|
||||
'proxmox_host': '192.168.1.103',
|
||||
'user_id': 'incheon-sea'
|
||||
},
|
||||
{
|
||||
'pharmacy_name': '광주햇살약국',
|
||||
'business_number': '654-32-10987',
|
||||
'manager_name': '정태영',
|
||||
'phone': '062-5678-9012',
|
||||
'address': '광주광역시 서구 상무대로 654',
|
||||
'proxmox_host': '192.168.1.104',
|
||||
'user_id': 'gwangju-sunshine'
|
||||
}
|
||||
]
|
||||
|
||||
pharmacy_objects = []
|
||||
for pharmacy_data in pharmacies:
|
||||
pharmacy = PharmacyInfo(**pharmacy_data)
|
||||
session.add(pharmacy)
|
||||
pharmacy_objects.append(pharmacy)
|
||||
|
||||
session.flush() # ID 생성을 위해 flush
|
||||
|
||||
# 3. 기존 Headscale 사용자와 연결
|
||||
print("👥 Linking with existing Headscale users...")
|
||||
existing_users = session.query(User).all()
|
||||
existing_nodes = session.query(Node).all()
|
||||
|
||||
print(f"📊 Found {len(existing_users)} users and {len(existing_nodes)} nodes in Headscale")
|
||||
|
||||
# 4. 머신 스펙 데이터 생성
|
||||
print("💻 Creating machine specifications...")
|
||||
cpu_models = [
|
||||
'Intel Core i5-11400',
|
||||
'Intel Core i7-10700',
|
||||
'AMD Ryzen 5 5600X',
|
||||
'AMD Ryzen 7 5700G',
|
||||
'Intel Core i3-10100'
|
||||
]
|
||||
|
||||
machine_specs = []
|
||||
for node in existing_nodes:
|
||||
specs = MachineSpecs(
|
||||
machine_id=node.id,
|
||||
cpu_model=random.choice(cpu_models),
|
||||
cpu_cores=random.choice([4, 6, 8]),
|
||||
ram_gb=random.choice([8, 16, 32]),
|
||||
storage_gb=random.choice([256, 512, 1024]),
|
||||
network_speed=random.choice([100, 1000]),
|
||||
os_info=f"Ubuntu 22.04 LTS",
|
||||
created_at=datetime.now()
|
||||
)
|
||||
session.add(specs)
|
||||
machine_specs.append(specs)
|
||||
|
||||
# 5. 모니터링 데이터 생성 (최근 24시간)
|
||||
print("📈 Creating monitoring data...")
|
||||
for spec in machine_specs:
|
||||
# 각 머신별로 최근 24시간 데이터 생성
|
||||
base_time = datetime.now() - timedelta(hours=24)
|
||||
|
||||
for i in range(144): # 10분 간격으로 24시간 = 144개 데이터
|
||||
monitoring_time = base_time + timedelta(minutes=i * 10)
|
||||
|
||||
# 시간대별로 사실적인 패턴 생성
|
||||
hour = monitoring_time.hour
|
||||
base_cpu = 20 if 6 <= hour <= 22 else 10 # 업무시간 vs 야간
|
||||
|
||||
monitoring = MonitoringData(
|
||||
machine_id=spec.machine_id,
|
||||
cpu_usage=max(0, min(100, base_cpu + random.gauss(0, 10))),
|
||||
memory_usage=max(10, min(90, 30 + random.gauss(0, 15))),
|
||||
disk_usage=max(20, min(80, 45 + random.gauss(0, 5))),
|
||||
cpu_temperature=max(35, min(85, 55 + random.gauss(0, 8))),
|
||||
network_in_bytes=random.randint(1000, 50000),
|
||||
network_out_bytes=random.randint(500, 25000),
|
||||
collected_at=monitoring_time
|
||||
)
|
||||
session.add(monitoring)
|
||||
|
||||
# 6. 알림 데이터 생성
|
||||
print("🚨 Creating alert data...")
|
||||
alert_types = ['HIGH_CPU', 'HIGH_MEMORY', 'HIGH_TEMPERATURE', 'DISK_SPACE', 'NETWORK_ISSUE']
|
||||
alert_levels = ['INFO', 'WARNING', 'ERROR', 'CRITICAL']
|
||||
|
||||
for i in range(15): # 15개의 알림 생성
|
||||
alert_time = datetime.now() - timedelta(hours=random.randint(1, 72))
|
||||
machine_id = random.choice([spec.machine_id for spec in machine_specs])
|
||||
|
||||
alert_type = random.choice(alert_types)
|
||||
level = random.choice(alert_levels)
|
||||
|
||||
messages = {
|
||||
'HIGH_CPU': f'CPU 사용률 80% 초과',
|
||||
'HIGH_MEMORY': f'메모리 사용률 85% 초과',
|
||||
'HIGH_TEMPERATURE': f'CPU 온도 75°C 초과',
|
||||
'DISK_SPACE': f'디스크 사용률 80% 초과',
|
||||
'NETWORK_ISSUE': f'네트워크 연결 불안정'
|
||||
}
|
||||
|
||||
alert = Alert(
|
||||
machine_id=machine_id,
|
||||
alert_type=alert_type,
|
||||
level=level,
|
||||
message=messages[alert_type],
|
||||
created_at=alert_time,
|
||||
is_resolved=random.choice([True, False])
|
||||
)
|
||||
session.add(alert)
|
||||
|
||||
# 커밋
|
||||
session.commit()
|
||||
|
||||
print("✅ Sample data initialization completed!")
|
||||
print(f" - {len(pharmacy_objects)} pharmacies created")
|
||||
print(f" - {len(machine_specs)} machine specifications created")
|
||||
print(f" - {144 * len(machine_specs)} monitoring records created")
|
||||
print(f" - 15 alerts created")
|
||||
|
||||
# 통계 출력
|
||||
print("\n📊 Database Statistics:")
|
||||
print(f" - Total Users: {session.query(User).count()}")
|
||||
print(f" - Total Nodes: {session.query(Node).count()}")
|
||||
print(f" - Total Pharmacies: {session.query(PharmacyInfo).count()}")
|
||||
print(f" - Total Monitoring Records: {session.query(MonitoringData).count()}")
|
||||
print(f" - Active Alerts: {session.query(Alert).filter_by(is_resolved=False).count()}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Error initializing sample data: {e}")
|
||||
session.rollback()
|
||||
raise
|
||||
finally:
|
||||
close_session()
|
||||
|
||||
if __name__ == '__main__':
|
||||
# 데이터베이스 초기화
|
||||
init_database('/srv/headscale-setup/headscale-data/db.sqlite')
|
||||
|
||||
# 샘플 데이터 생성
|
||||
init_sample_data()
|
||||
Reference in New Issue
Block a user