feat: 3-System 분리 프로젝트 초기 코드 작성
TK-FB(공장관리+신고)와 M-Project(부적합관리)를 3개 독립 시스템으로 분리하기 위한 전체 코드 구조 작성. - SSO 인증 서비스 (bcrypt + pbkdf2 이중 해시 지원) - System 1: 공장관리 (TK-FB 기반, 신고 코드 제거) - System 2: 신고 (TK-FB에서 workIssue 코드 추출) - System 3: 부적합관리 (M-Project 기반) - Gateway 포털 (path-based 라우팅) - 통합 docker-compose.yml 및 배포 스크립트 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
46
scripts/backup.sh
Executable file
46
scripts/backup.sh
Executable file
@@ -0,0 +1,46 @@
|
||||
#!/bin/bash
|
||||
# ===================================================================
|
||||
# TK Factory Services - 백업 스크립트
|
||||
# ===================================================================
|
||||
# 사용법: ./scripts/backup.sh [backup_dir]
|
||||
# ===================================================================
|
||||
|
||||
set -e
|
||||
|
||||
BACKUP_DIR="${1:-./backups/$(date +%Y%m%d_%H%M%S)}"
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
echo "=== TK Factory Services Backup ==="
|
||||
echo "Backup directory: $BACKUP_DIR"
|
||||
echo ""
|
||||
|
||||
# 1. MariaDB 백업
|
||||
echo "[1/4] Backing up MariaDB..."
|
||||
docker exec tk-mariadb mysqldump -u root -p"${MYSQL_ROOT_PASSWORD}" --all-databases \
|
||||
> "$BACKUP_DIR/mariadb_all.sql" 2>/dev/null && \
|
||||
echo " MariaDB backup: OK" || echo " MariaDB backup: SKIPPED (not running)"
|
||||
|
||||
# 2. PostgreSQL 백업
|
||||
echo "[2/4] Backing up PostgreSQL..."
|
||||
docker exec tk-postgres pg_dump -U "${POSTGRES_USER:-mproject}" "${POSTGRES_DB:-mproject}" \
|
||||
> "$BACKUP_DIR/postgres_mproject.sql" 2>/dev/null && \
|
||||
echo " PostgreSQL backup: OK" || echo " PostgreSQL backup: SKIPPED (not running)"
|
||||
|
||||
# 3. Upload 파일 백업
|
||||
echo "[3/4] Backing up uploads..."
|
||||
for vol in system1_uploads system2_uploads system3_uploads; do
|
||||
if docker volume inspect "tk-factory-services_${vol}" >/dev/null 2>&1; then
|
||||
docker run --rm -v "tk-factory-services_${vol}:/data" -v "$(cd "$BACKUP_DIR" && pwd):/backup" \
|
||||
alpine tar czf "/backup/${vol}.tar.gz" -C /data . 2>/dev/null && \
|
||||
echo " ${vol}: OK" || echo " ${vol}: SKIPPED"
|
||||
fi
|
||||
done
|
||||
|
||||
# 4. 설정 파일 백업
|
||||
echo "[4/4] Backing up config files..."
|
||||
cp -f .env "$BACKUP_DIR/.env.bak" 2>/dev/null || true
|
||||
cp -f docker-compose.yml "$BACKUP_DIR/docker-compose.yml.bak" 2>/dev/null || true
|
||||
|
||||
echo ""
|
||||
echo "=== Backup complete: $BACKUP_DIR ==="
|
||||
ls -la "$BACKUP_DIR/"
|
||||
75
scripts/deploy.sh
Executable file
75
scripts/deploy.sh
Executable file
@@ -0,0 +1,75 @@
|
||||
#!/bin/bash
|
||||
# ===================================================================
|
||||
# TK Factory Services - 배포 스크립트
|
||||
# ===================================================================
|
||||
# 사용법: ./scripts/deploy.sh [--build] [--restart service_name]
|
||||
# ===================================================================
|
||||
|
||||
set -e
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
echo "=== TK Factory Services Deploy ==="
|
||||
echo ""
|
||||
|
||||
# .env 파일 확인
|
||||
if [ ! -f .env ]; then
|
||||
echo "ERROR: .env file not found!"
|
||||
echo "Run: cp .env.example .env && vi .env"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
source .env
|
||||
|
||||
case "${1:-}" in
|
||||
--build)
|
||||
echo "[1/3] Building all services..."
|
||||
docker compose build --parallel
|
||||
|
||||
echo "[2/3] Starting services..."
|
||||
docker compose up -d
|
||||
|
||||
echo "[3/3] Checking health..."
|
||||
sleep 10
|
||||
./scripts/health-check.sh
|
||||
;;
|
||||
|
||||
--restart)
|
||||
SERVICE="${2:?Service name required}"
|
||||
echo "Restarting $SERVICE..."
|
||||
docker compose restart "$SERVICE"
|
||||
sleep 5
|
||||
docker compose ps "$SERVICE"
|
||||
;;
|
||||
|
||||
--stop)
|
||||
echo "Stopping all services..."
|
||||
docker compose down
|
||||
echo "All services stopped."
|
||||
;;
|
||||
|
||||
--logs)
|
||||
SERVICE="${2:-}"
|
||||
if [ -n "$SERVICE" ]; then
|
||||
docker compose logs -f --tail=100 "$SERVICE"
|
||||
else
|
||||
docker compose logs -f --tail=50
|
||||
fi
|
||||
;;
|
||||
|
||||
--status)
|
||||
docker compose ps
|
||||
echo ""
|
||||
echo "=== Resource Usage ==="
|
||||
docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}" \
|
||||
$(docker compose ps -q 2>/dev/null) 2>/dev/null || echo "No containers running"
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Usage:"
|
||||
echo " ./scripts/deploy.sh --build # Build and start all services"
|
||||
echo " ./scripts/deploy.sh --restart SERVICE # Restart a specific service"
|
||||
echo " ./scripts/deploy.sh --stop # Stop all services"
|
||||
echo " ./scripts/deploy.sh --logs [SERVICE] # View logs"
|
||||
echo " ./scripts/deploy.sh --status # Show status and resource usage"
|
||||
;;
|
||||
esac
|
||||
61
scripts/health-check.sh
Executable file
61
scripts/health-check.sh
Executable file
@@ -0,0 +1,61 @@
|
||||
#!/bin/bash
|
||||
# ===================================================================
|
||||
# TK Factory Services - Health Check
|
||||
# ===================================================================
|
||||
|
||||
echo "=== TK Factory Services Health Check ==="
|
||||
echo ""
|
||||
|
||||
PASS=0
|
||||
FAIL=0
|
||||
SKIP=0
|
||||
|
||||
check_service() {
|
||||
local name="$1"
|
||||
local url="$2"
|
||||
local port="$3"
|
||||
|
||||
printf "%-25s " "$name"
|
||||
|
||||
# 포트 열림 확인
|
||||
if ! nc -z localhost "$port" 2>/dev/null; then
|
||||
echo "SKIP (port $port not open)"
|
||||
((SKIP++))
|
||||
return
|
||||
fi
|
||||
|
||||
# HTTP 확인
|
||||
local status
|
||||
status=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 3 "$url" 2>/dev/null)
|
||||
|
||||
if [ "$status" -ge 200 ] && [ "$status" -lt 400 ]; then
|
||||
echo "OK ($status)"
|
||||
((PASS++))
|
||||
else
|
||||
echo "FAIL ($status)"
|
||||
((FAIL++))
|
||||
fi
|
||||
}
|
||||
|
||||
check_service "Gateway" "http://localhost:30000/" 30000
|
||||
check_service "SSO Auth" "http://localhost:30050/health" 30050
|
||||
check_service "System 1 API" "http://localhost:30005/api/health" 30005
|
||||
check_service "System 1 Web" "http://localhost:30080/" 30080
|
||||
check_service "System 1 FastAPI" "http://localhost:30008/health" 30008
|
||||
check_service "System 2 API" "http://localhost:30105/api/health" 30105
|
||||
check_service "System 2 Web" "http://localhost:30180/" 30180
|
||||
check_service "System 3 API" "http://localhost:30200/api/health" 30200
|
||||
check_service "System 3 Web" "http://localhost:30280/" 30280
|
||||
check_service "phpMyAdmin" "http://localhost:30880/" 30880
|
||||
|
||||
echo ""
|
||||
echo "=== Docker Container Status ==="
|
||||
docker compose ps --format "table {{.Name}}\t{{.Status}}\t{{.Ports}}" 2>/dev/null || \
|
||||
echo "docker compose not available in this directory"
|
||||
|
||||
echo ""
|
||||
echo "Results: PASS=$PASS FAIL=$FAIL SKIP=$SKIP"
|
||||
|
||||
if [ "$FAIL" -gt 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
99
scripts/migrate-users.sql
Normal file
99
scripts/migrate-users.sql
Normal file
@@ -0,0 +1,99 @@
|
||||
-- ===================================================================
|
||||
-- TK Factory Services - SSO 통합 유저 마이그레이션
|
||||
-- ===================================================================
|
||||
-- 이 스크립트는 MariaDB 초기 구동 시 자동 실행됩니다.
|
||||
-- 기존 DB에 적용할 때는 수동으로 실행하세요.
|
||||
-- ===================================================================
|
||||
|
||||
-- 1. SSO 통합 유저 테이블 생성
|
||||
CREATE TABLE IF NOT EXISTS sso_users (
|
||||
user_id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
username VARCHAR(50) UNIQUE NOT NULL,
|
||||
password_hash VARCHAR(255) NOT NULL,
|
||||
name VARCHAR(100),
|
||||
department VARCHAR(50),
|
||||
role ENUM('system','admin','support_team','leader','user') DEFAULT 'user',
|
||||
system1_access BOOLEAN DEFAULT TRUE,
|
||||
system2_access BOOLEAN DEFAULT TRUE,
|
||||
system3_access BOOLEAN DEFAULT TRUE,
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
last_login DATETIME NULL,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- 2. work_issue_reports 테이블에 M-Project 연동 컬럼 추가
|
||||
-- (테이블이 존재하는 경우에만 실행)
|
||||
-- ALTER TABLE은 IF NOT EXISTS를 지원하지 않으므로 프로시저 사용
|
||||
DELIMITER //
|
||||
CREATE PROCEDURE IF NOT EXISTS add_mproject_columns()
|
||||
BEGIN
|
||||
-- work_issue_reports 테이블 존재 확인
|
||||
IF EXISTS (SELECT 1 FROM information_schema.tables
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'work_issue_reports') THEN
|
||||
|
||||
-- m_project_issue_id 컬럼 추가
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'work_issue_reports'
|
||||
AND column_name = 'm_project_issue_id') THEN
|
||||
ALTER TABLE work_issue_reports
|
||||
ADD COLUMN m_project_issue_id INT NULL;
|
||||
END IF;
|
||||
|
||||
-- m_project_sync_status 컬럼 추가
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'work_issue_reports'
|
||||
AND column_name = 'm_project_sync_status') THEN
|
||||
ALTER TABLE work_issue_reports
|
||||
ADD COLUMN m_project_sync_status ENUM('pending','synced','failed','not_applicable')
|
||||
DEFAULT 'not_applicable';
|
||||
END IF;
|
||||
|
||||
-- m_project_synced_at 컬럼 추가
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'work_issue_reports'
|
||||
AND column_name = 'm_project_synced_at') THEN
|
||||
ALTER TABLE work_issue_reports
|
||||
ADD COLUMN m_project_synced_at DATETIME NULL;
|
||||
END IF;
|
||||
END IF;
|
||||
END //
|
||||
DELIMITER ;
|
||||
|
||||
CALL add_mproject_columns();
|
||||
DROP PROCEDURE IF EXISTS add_mproject_columns;
|
||||
|
||||
-- 3. 기존 users 테이블에서 SSO 유저 마이그레이션 (중복 무시)
|
||||
-- (TK-FB-Project의 users 테이블이 있는 경우)
|
||||
DELIMITER //
|
||||
CREATE PROCEDURE IF NOT EXISTS migrate_existing_users()
|
||||
BEGIN
|
||||
IF EXISTS (SELECT 1 FROM information_schema.tables
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'users') THEN
|
||||
INSERT IGNORE INTO sso_users (username, password_hash, name, department, role, is_active)
|
||||
SELECT
|
||||
username,
|
||||
password,
|
||||
name,
|
||||
department,
|
||||
CASE
|
||||
WHEN access_level = 'system' THEN 'system'
|
||||
WHEN access_level = 'admin' THEN 'admin'
|
||||
WHEN access_level = 'support_team' THEN 'support_team'
|
||||
WHEN access_level = 'group_leader' THEN 'leader'
|
||||
ELSE 'user'
|
||||
END AS role,
|
||||
COALESCE(is_active, TRUE)
|
||||
FROM users
|
||||
WHERE username IS NOT NULL;
|
||||
END IF;
|
||||
END //
|
||||
DELIMITER ;
|
||||
|
||||
CALL migrate_existing_users();
|
||||
DROP PROCEDURE IF EXISTS migrate_existing_users;
|
||||
Reference in New Issue
Block a user