zioinfo-mail/docs/db_schema.md
DESKTOP-TKLFCPR\ython e228faabf5 feat(itsm): G-1~G-12 확장 기능 + 하네스/봇/설치스크립트 구현
G-1: 메신저 Webhook Relay + _send_to_room 실제 httpx 호출 구현
G-2: POST /api/tasks/bulk SR 대량작업 엔드포인트 (최대 100건)
G-3: 라이선스 만료 알림 스케줄러 (매일 09:00 KST)
G-4: 체험판 upgrade_banner 필드 + license.py 배너 로직
G-5: core/auto_rca.py + incidents/problem auto-rca 엔드포인트
G-6: core/deploy_impact.py + vibe impact-analysis 엔드포인트
G-7: core/ticket_classifier.py + SR 생성 시 AI 분류 + ai-suggestion API
G-8: VulnPatchRecord 모델 + vuln_scan 패치추적 4개 엔드포인트
G-9: core/jira_sync.py + gateway Jira/Confluence 연동 엔드포인트
G-10: core/push_notify.py + routers/push.py + PushSubscription 모델
G-11: approvals 다중승인 (위임/서명/기한초과/마감연장)
G-12: alembic.ini + migrations/ + cicd/migrate_to_postgres.sh

하네스: guardia-orchestrator 확장기능 Phase 반영
봇명령어: /sr /status /license /bulk 슬래시 명령어 추가
설치스크립트: setup/ (Ubuntu, CentOS, RHEL, Windows) --test 옵션 포함

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 18:18:52 +09:00

16 KiB

[Specification] GUARDiA 데이터베이스 스키마 설계서

DBMS: PostgreSQL 15+
원칙: root 계정 금지. 전용 서비스 계정 사용. 비밀번호 컬럼 AES-256 암호화 필수.


1. 인프라 자산 영역 (CMDB)

TB_INST_META (관공서 마스터)

CREATE TABLE TB_INST_META (
    inst_id         VARCHAR(20)  PRIMARY KEY,   -- 기관 코드 (예: MOF, MOIS)
    inst_name       VARCHAR(100) NOT NULL,      -- 기관명 (예: 기획재정부)
    pm_contact      VARCHAR(50),               -- 담당 PM 사번
    phone           VARCHAR(20),               -- 대표 연락처
    address         VARCHAR(300),              -- 주소
    region          VARCHAR(50),               -- 지역 (예: 서울, 세종, 부산)
    contract_start  DATE,                      -- 유지보수 계약 시작일
    contract_end    DATE,                      -- 유지보수 계약 종료일
    sla_hours       INT          DEFAULT 4,    -- SLA 응답시간 (시간)
    note            TEXT,                      -- 기타 메모
    is_active       CHAR(1)      DEFAULT 'Y',  -- Y: 활성 / N: 비활성
    created_at      TIMESTAMP    DEFAULT CURRENT_TIMESTAMP,
    updated_at      TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
);

TB_INST_CONTACT (기관 담당자 연락처)

CREATE TABLE TB_INST_CONTACT (
    contact_id   BIGSERIAL    PRIMARY KEY,
    inst_id      VARCHAR(20)  REFERENCES TB_INST_META(inst_id) ON DELETE CASCADE,
    contact_name VARCHAR(50)  NOT NULL,        -- 담당자 이름
    dept         VARCHAR(100),                -- 부서명
    position     VARCHAR(50),                 -- 직책/직급
    role         VARCHAR(30)  NOT NULL,        -- MANAGER | ENGINEER | PM | SECURITY | HELPDESK
    email        VARCHAR(100),                -- 이메일 (필수 권장)
    phone        VARCHAR(20),                 -- 직통 전화
    mobile       VARCHAR(20),                 -- 휴대폰
    is_primary   CHAR(1)      DEFAULT 'N',    -- Y: 주 담당자
    is_active    CHAR(1)      DEFAULT 'Y',
    note         TEXT,
    created_at   TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_contact_inst ON TB_INST_CONTACT(inst_id, role);

TB_SERVER_INFO (서버 노드 마스터 — 확장)

CREATE TABLE TB_SERVER_INFO (
    server_id       VARCHAR(30)  PRIMARY KEY,   -- 서버 고유 ID (예: MOF-WAS-01)
    inst_id         VARCHAR(20)  REFERENCES TB_INST_META(inst_id),
    system_name     VARCHAR(100) NOT NULL,      -- 업무 시스템명
    layer           VARCHAR(10)  NOT NULL,      -- WEB | WAS | DB | ESB | BATCH
    hostname        VARCHAR(100),
    ip_address      VARCHAR(45)  NOT NULL,      -- ※ API 응답 노출 금지
    ssh_port        INT          DEFAULT 22,
    ssh_method      VARCHAR(20)  DEFAULT 'PASSWORD',  -- PASSWORD | KEY | KEY_WITH_PASS
    ssh_key_path    VARCHAR(255),               -- SSH 키 파일 경로 (서버측 관제 PC 경로)
    ftp_path        VARCHAR(255),               -- 배포 기본 경로
    os_user         VARCHAR(50),               -- SSH 접속 계정 ※ API 응답 노출 금지
    os_pw_enc       TEXT,                      -- AES-256-GCM 암호화 비밀번호 ※ 절대 노출 금지
    os_type         VARCHAR(20)  DEFAULT 'LINUX',   -- LINUX | WINDOWS | AIX | HP-UX
    os_version      VARCHAR(50),                -- OS 버전 (예: RHEL 8.6, Ubuntu 22.04)
    -- WEB 서버 정보
    web_server      VARCHAR(50),                -- Apache | Nginx | IIS | WebtoB
    web_version     VARCHAR(30),
    web_port        INT,
    web_conf_path   VARCHAR(255),               -- WEB 설정 파일 경로
    -- WAS 서버 정보
    was_type        VARCHAR(50),                -- Tomcat | JBoss | WebLogic | JEUS | WebSphere
    was_version     VARCHAR(30),
    was_port        INT,
    was_home        VARCHAR(255),               -- WAS_HOME 경로
    was_deploy_path VARCHAR(255),               -- 배포 경로
    jdk_version     VARCHAR(20),                -- JDK 버전
    heap_min        VARCHAR(20),                -- JVM 최소 힙 (예: 512m)
    heap_max        VARCHAR(20),                -- JVM 최대 힙 (예: 2048m)
    -- DB 서버 정보
    db_type         VARCHAR(30),                -- PostgreSQL | Oracle | MySQL | MSSQL | Tibero | Altibase
    db_version      VARCHAR(30),
    db_port         INT,
    db_name         VARCHAR(100),               -- DB명 / SID
    db_schema       VARCHAR(100),               -- 스키마명
    -- 유지보수 정보
    cpu_cores       INT,                        -- CPU 코어 수
    memory_gb       INT,                        -- 메모리 (GB)
    disk_total_gb   INT,                        -- 전체 디스크 (GB)
    maintenance_contact VARCHAR(50),            -- 서버 담당자 사번
    install_date    DATE,                       -- 설치일
    eol_date        DATE,                       -- 지원 만료일 (EOL)
    backup_path     VARCHAR(255),               -- 백업 경로
    ssl_cert_path   VARCHAR(255),               -- SSL 인증서 경로
    ssl_expire_date DATE,                       -- SSL 만료일
    note            TEXT,                       -- 유지보수 기타 메모
    status          VARCHAR(20)  DEFAULT 'ACTIVE',  -- ACTIVE | MAINTENANCE | DECOMMISSIONED
    last_check      TIMESTAMP,
    created_at      TIMESTAMP    DEFAULT CURRENT_TIMESTAMP,
    updated_at      TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_server_inst ON TB_SERVER_INFO(inst_id, layer);
CREATE INDEX idx_server_ssl ON TB_SERVER_INFO(ssl_expire_date) WHERE ssl_expire_date IS NOT NULL;

TB_SYSTEM_OWNER (시스템 담당자 매핑)

CREATE TABLE TB_SYSTEM_OWNER (
    system_id      VARCHAR(30)  PRIMARY KEY,
    inst_id        VARCHAR(20)  REFERENCES TB_INST_META(inst_id),
    owner_id       VARCHAR(50)  NOT NULL,   -- 1순위 승인권자 사번
    deputy_id      VARCHAR(50),             -- 2순위 대리 승인자
    supervisor_id  VARCHAR(50),             -- 3순위 상위 관리자
    sla_minutes    INT          DEFAULT 10, -- 승인 대기 SLA (분)
    is_active      CHAR(1)      DEFAULT 'Y' -- Y: 근무중 / N: 부재중
);

2. 운영 작업 영역 (Ops Task)

TB_OPS_TASK (운영 작업 헤더)

CREATE TABLE TB_OPS_TASK (
    task_id         VARCHAR(30)  PRIMARY KEY,   -- 예: OPS-20260523-001
    task_category   VARCHAR(50)  NOT NULL,      -- DEPLOY | INFRA | DATA | MAINTENANCE
    task_sub_type   VARCHAR(50),                -- SSL_REPLACE | LOG_ANALYSIS | RESTART
    raw_request     TEXT         NOT NULL,      -- 사용자 원문 자연어
    status          VARCHAR(30)  DEFAULT 'RECEIVED',
    requester_id    VARCHAR(50)  NOT NULL,
    inst_id         VARCHAR(20)  REFERENCES TB_INST_META(inst_id),
    playbook_id     VARCHAR(50),               -- 실행 플레이북 ID
    created_at      TIMESTAMP    DEFAULT CURRENT_TIMESTAMP,
    updated_at      TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
);
-- 상태값: RECEIVED | PARSED | PENDING_APPROVAL | ESCALATED | APPROVED | IN_PROGRESS | PENDING_PM_VALIDATION | COMPLETED | FAILED_ROLLBACK
CREATE INDEX idx_task_status ON TB_OPS_TASK(status, created_at DESC);

TB_DEPLOY_HISTORY (배포 상세 이력)

CREATE TABLE TB_DEPLOY_HISTORY (
    deploy_id      BIGSERIAL    PRIMARY KEY,
    task_id        VARCHAR(30)  REFERENCES TB_OPS_TASK(task_id),
    server_id      VARCHAR(30)  REFERENCES TB_SERVER_INFO(server_id),
    user_id        VARCHAR(50)  NOT NULL,
    sr_no          VARCHAR(30),
    artifact_list  JSONB,                  -- 배포된 파일 목록
    deploy_status  CHAR(1)      DEFAULT 'P', -- P:대기 S:성공 F:실패
    backup_path    VARCHAR(255),
    result_hash    CHAR(64),               -- SHA-256
    deployed_at    TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
);

3. 거버넌스 승인 영역

TB_APPROVAL_FLOW (다단계 승인 이력)

CREATE TABLE TB_APPROVAL_FLOW (
    flow_id         BIGSERIAL    PRIMARY KEY,
    task_id         VARCHAR(30)  REFERENCES TB_OPS_TASK(task_id),
    step_order      INT          NOT NULL,     -- 1, 2, 3...
    approver_id     VARCHAR(50)  NOT NULL,
    approval_status CHAR(1)      DEFAULT 'P', -- P:대기 A:승인 R:반려
    comments        VARCHAR(500),
    escalation_type VARCHAR(20),              -- DIRECT | DEPUTY | SUPERVISOR
    approved_at     TIMESTAMP
);
CREATE INDEX idx_approval_task ON TB_APPROVAL_FLOW(task_id, step_order);

4. 감사 영역 (Audit — 위변조 방지)

TB_AUDIT_LOG (SHA-256 해시 체인)

CREATE TABLE TB_AUDIT_LOG (
    log_id       BIGSERIAL    PRIMARY KEY,
    task_id      VARCHAR(30)  REFERENCES TB_OPS_TASK(task_id),
    server_ip    VARCHAR(45),
    exec_time    TIMESTAMP    DEFAULT CURRENT_TIMESTAMP,
    command      TEXT         NOT NULL,
    exit_code    INT,
    result_hash  CHAR(64),   -- SHA256(현재 결과 + 이전 hash)
    operator_id  VARCHAR(50)
);
-- 해시 체이닝: Log[n].result_hash = SHA256(Log[n].output || Log[n-1].result_hash)

TB_SR_REQUEST (SR 티켓 — 레거시 호환)

CREATE TABLE TB_SR_REQUEST (
    sr_no        VARCHAR(30)  PRIMARY KEY,  -- SR-2026-001
    requester    VARCHAR(100),
    system_id    VARCHAR(30)  REFERENCES TB_SERVER_INFO(server_id),
    raw_text     TEXT,
    task_type    VARCHAR(50),               -- UI_FIX | DEPLOY | LOG_ANALYSIS
    status       VARCHAR(20)  DEFAULT 'PENDING',
    assigned_ai  VARCHAR(50),              -- 에이전트 실행 ID
    created_at   TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
);

5. 메신저 채팅 영역

TB_MSG_ROOMS (대화방)

CREATE TABLE TB_MSG_ROOMS (
    room_id    VARCHAR(50) PRIMARY KEY,
    room_name  VARCHAR(100) NOT NULL,
    inst_id    VARCHAR(20)  REFERENCES TB_INST_META(inst_id),
    created_at TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
);

TB_MSG_CHAT_LOG (채팅 이력)

CREATE TABLE TB_MSG_CHAT_LOG (
    chat_id      BIGSERIAL   PRIMARY KEY,
    room_id      VARCHAR(50) REFERENCES TB_MSG_ROOMS(room_id),
    sender_id    VARCHAR(50) NOT NULL,
    sender_name  VARCHAR(100),
    sender_type  VARCHAR(20) NOT NULL,  -- HUMAN | BOT | AGENT
    message_text TEXT,
    is_command   BOOLEAN     DEFAULT FALSE,
    task_id      VARCHAR(30),
    itsm_ticket_id VARCHAR(50),        -- 향후 ITSM 연동용 (null 허용)
    asset_code   VARCHAR(50),          -- 인프라 자산 코드
    created_at   TIMESTAMP   DEFAULT CURRENT_TIMESTAMP
);

6. 쉘 스크립트 관리 영역

TB_SHELL_SCRIPT (쉘 스크립트 라이브러리)

CREATE TABLE TB_SHELL_SCRIPT (
    script_id    BIGSERIAL    PRIMARY KEY,
    script_name  VARCHAR(200) NOT NULL,           -- 스크립트 이름
    category     VARCHAR(30)  NOT NULL,           -- SM | REGULAR | ADHOC | DEPLOY | SECURITY | MONITORING
    sub_category VARCHAR(50),                     -- 세부 분류 (예: DISK_CHECK, LOG_ROTATE, SSL_RENEW)
    target_layer VARCHAR(20),                     -- WEB | WAS | DB | ESB | ALL
    os_type      VARCHAR(20)  DEFAULT 'LINUX',    -- LINUX | WINDOWS | ALL
    description  TEXT         NOT NULL,           -- 스크립트 설명 (증상/목적)
    script_body  TEXT         NOT NULL,           -- 실제 쉘 스크립트 내용
    parameters   JSONB,                           -- 파라미터 명세 [{"name":"TARGET","desc":"대상 서버","required":true}]
    sample_output TEXT,                           -- 예상 출력 샘플 (JSON)
    is_dangerous BOOLEAN      DEFAULT FALSE,      -- 위험 명령 포함 여부 (rm, kill 등)
    requires_approval BOOLEAN DEFAULT FALSE,      -- 실행 전 승인 필요 여부
    author       VARCHAR(50),                     -- 작성자 사번
    version      VARCHAR(20)  DEFAULT '1.0.0',
    tags         VARCHAR(200),                    -- 검색 태그 (콤마 구분)
    inst_id      VARCHAR(20)  REFERENCES TB_INST_META(inst_id),  -- NULL이면 공용
    is_active    BOOLEAN      DEFAULT TRUE,
    use_count    INT          DEFAULT 0,          -- 실행 횟수 (통계용)
    created_at   TIMESTAMP    DEFAULT CURRENT_TIMESTAMP,
    updated_at   TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_script_category ON TB_SHELL_SCRIPT(category, target_layer);
CREATE INDEX idx_script_inst ON TB_SHELL_SCRIPT(inst_id);

카테고리 정의

category 설명
SM 시스템 관리 (일상 운영)
REGULAR 정기점검 스크립트 (월간/분기/반기)
ADHOC 수시점검 스크립트 (장애 대응, 긴급 확인)
DEPLOY 배포 관련 스크립트
SECURITY 보안 감사·계정 점검
MONITORING 모니터링·헬스체크

7. 작업 타임테이블 영역

TB_WORK_TIMETABLE (작업 이력 타임테이블)

CREATE TABLE TB_WORK_TIMETABLE (
    timetable_id   BIGSERIAL    PRIMARY KEY,
    work_type      VARCHAR(30)  NOT NULL,          -- REGULAR_CHECK | PM | SR | ADHOC | DEPLOY | EMERGENCY
    title          VARCHAR(200) NOT NULL,          -- 작업 제목 (예: 2025년 1분기 정기점검 - MOF)
    inst_id        VARCHAR(20)  REFERENCES TB_INST_META(inst_id),
    server_id      VARCHAR(30)  REFERENCES TB_SERVER_INFO(server_id),
    sr_id          VARCHAR(30),                   -- SR 연계 (있을 경우)
    script_id      BIGINT       REFERENCES TB_SHELL_SCRIPT(script_id),
    scheduled_at   TIMESTAMP    NOT NULL,          -- 처리 예정 일시
    started_at     TIMESTAMP,                      -- 실제 시작 일시
    completed_at   TIMESTAMP,                      -- 완료 일시
    content        TEXT         NOT NULL,          -- 처리 내용 상세
    command_or_shell TEXT,                         -- 실행한 명령어 또는 쉘 스크립트
    result         TEXT,                           -- 처리 결과
    result_status  VARCHAR(20)  DEFAULT 'PENDING', -- PENDING | SUCCESS | FAILED | PARTIAL | CANCELLED
    assignee       VARCHAR(50),                    -- 담당자 사번
    reviewer       VARCHAR(50),                    -- 검토자 사번 (PM)
    attachments    JSONB,                          -- 첨부파일 목록 [{"filename":"...","path":"..."}]
    note           TEXT,                           -- 비고
    created_by     VARCHAR(50),
    created_at     TIMESTAMP    DEFAULT CURRENT_TIMESTAMP,
    updated_at     TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_timetable_inst ON TB_WORK_TIMETABLE(inst_id, scheduled_at DESC);
CREATE INDEX idx_timetable_type ON TB_WORK_TIMETABLE(work_type, result_status);
CREATE INDEX idx_timetable_sr ON TB_WORK_TIMETABLE(sr_id) WHERE sr_id IS NOT NULL;

작업 유형 정의

work_type 설명
REGULAR_CHECK 정기점검 (월간·분기·반기·연간)
PM 예방 정비 (Preventive Maintenance)
SR SR 기반 작업 (요청 처리)
ADHOC 수시점검 / 긴급 대응
DEPLOY 배포 작업
EMERGENCY 장애 대응 / 긴급 복구

8. 더미 데이터 (로컬 테스트용)

-- 관공서 기관
INSERT INTO TB_INST_META (inst_id, inst_name, pm_contact) VALUES
('MOF', '기획재정부', 'PM001'),
('MOIS', '행정안전부', 'PM002'),
('MSS', '중소벤처기업부', 'PM003');

-- 서버 노드
INSERT INTO TB_SERVER_INFO (server_id, inst_id, system_name, layer, ip_address, ssh_port, ftp_path, os_user) VALUES
('MOF-WAS-01', 'MOF', '예산시스템', 'WAS', '192.168.10.11', 22, '/app/mof/webapps/ROOT', 'mofadmin'),
('MOF-WAS-02', 'MOF', '예산시스템', 'WAS', '192.168.10.12', 22, '/app/mof/webapps/ROOT', 'mofadmin'),
('MOF-DB-01',  'MOF', '예산시스템', 'DB',  '192.168.10.13', 5432, '/var/lib/postgresql', 'postgres');

-- 담당자 매핑
INSERT INTO TB_SYSTEM_OWNER (system_id, inst_id, owner_id, deputy_id, supervisor_id) VALUES
('MOF-WAS-01', 'MOF', 'EMP-0101', 'EMP-0102', 'EMP-0100'),
('MOF-DB-01',  'MOF', 'EMP-0201', NULL,        'EMP-0200');