This commit is contained in:
KIM SU BO committed 2026-10-06 13:23:42 +09:00
1 parent 618ba02cb9
commit 83278b2998
124 files changed
-49298

No files matched your search

-225
View File
@@ -1,225 +0,0 @@
import os
import json
base = r"d:/edunlab/milicontent2/uploads/DAT10"
os.makedirs(base, exist_ok=True)
for sub in ["data/schema", "data/samples", "docs", "src/preprocess", "src/models", "src/verification", "src/ui", "src/hitl", "tests", "configs"]:
os.makedirs(os.path.join(base, sub), exist_ok=True)
# 1. requirements.txt
req_content = """pandas>=2.0.0
numpy>=1.24.0
scikit-learn>=1.3.0
streamlit>=1.28.0
pyyaml>=6.0
pytest>=7.4.0
plotly>=5.17.0
cryptography>=41.0.0
"""
with open(os.path.join(base, "requirements.txt"), "w", encoding="utf-8") as f:
f.write(req_content)
# 2. data/schema/dat10_input_schema.json
schema_content = {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "DAT10_Tactical_SupplyChain_Inventory_Schema",
"description": "전술 통신 두절 환경 야전 군수 재고 및 방산 공급망 트랜잭션 표준 입력 스키마",
"type": "object",
"properties": {
"transaction_id": {
"type": "string",
"pattern": "^TX-[A-Z0-9]{8,16}$",
"description": "고유 트랜잭션 식별자 (UUID 또는 해시 기반)"
},
"terminal_id": {
"type": "string",
"pattern": "^TERM-[A-Z0-9]{4,8}$",
"description": "작전 단말기 ID"
},
"unit_id": {
"type": "string",
"pattern": "^(DIV|BDE|BN|CO)-[0-9]{2,4}$",
"description": "부대 제대 식별자"
},
"nsn_code": {
"type": "string",
"pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{3}-[0-9]{4}$",
"description": "국가재고번호 (NATO Stock Number)"
},
"item_name": {
"type": "string",
"minLength": 2,
"maxLength": 100,
"description": "품목명"
},
"supply_class": {
"type": "string",
"enum": ["Class_I", "Class_II", "Class_III", "Class_IV", "Class_V", "Class_IX"],
"description": "군수 보급 분류 (I:식량, II:피복장구, III:유류, IV:건설자재, V:탄약, IX:수리부속)"
},
"tx_type": {
"type": "string",
"enum": ["RECEIPT", "ISSUE", "TRANSFER", "DISPOSAL", "ADJUSTMENT", "FIELD_CONSUME"],
"description": "트랜잭션 유형 (입고, 불출, 이관, 폐기, 재고조정, 야전소모)"
},
"quantity": {
"type": "integer",
"minimum": 1,
"maximum": 1000000,
"description": "변동 수량"
},
"current_stock": {
"type": "integer",
"minimum": 0,
"description": "트랜잭션 발생 직후 로컬 잔여 재고"
},
"unit_cost": {
"type": "number",
"minimum": 0.0,
"description": "단위당 조달 단가 (USD / KRW)"
},
"comms_status": {
"type": "string",
"enum": ["ONLINE", "OFFLINE_LOCAL", "OFFLINE_P2P", "DEGRADED_EW"],
"description": "트랜잭션 기록 당시 통신 상태"
},
"grid_coords": {
"type": "string",
"pattern": "^[0-9]{2}[A-Z]{3}[0-9]{8}$",
"description": "MGRS 군사격자 좌표 (예: 52SDJ12345678)"
},
"weather_condition": {
"type": "string",
"enum": ["CLEAR", "HEAVY_RAIN", "SNOW_STORM", "DESERT_HEAT", "FOG"],
"description": "야전 기상 환경"
},
"lamport_timestamp": {
"type": "integer",
"minimum": 0,
"description": "분산 인과율 추적을 위한 램포트 논리 시계 (Lamport Logical Clock)"
},
"timestamp_utc": {
"type": "string",
"format": "date-time",
"description": "ISO 8601 UTC 생성 일시"
},
"prev_hash": {
"type": "string",
"pattern": "^[a-f0-9]{64}$",
"description": "이전 로컬 트랜잭션 레코드의 SHA-256 해시"
},
"record_hash": {
"type": "string",
"pattern": "^[a-f0-9]{64}$",
"description": "무결성 보증을 위한 본 트랜잭션의 SHA-256 해시"
}
},
"required": [
"transaction_id",
"terminal_id",
"unit_id",
"nsn_code",
"item_name",
"supply_class",
"tx_type",
"quantity",
"current_stock",
"comms_status",
"lamport_timestamp",
"timestamp_utc",
"prev_hash",
"record_hash"
],
"additionalProperties": False
}
with open(os.path.join(base, "data/schema/dat10_input_schema.json"), "w", encoding="utf-8") as f:
json.dump(schema_content, f, ensure_ascii=False, indent=2)
# 3. data/schema/sqlite_schema.sql
sql_content = """-- DAT10 전술 오프라인 단말 로컬 SQLite DB 스키마
PRAGMA foreign_keys = ON;
-- 1. 마스터 재고 품목 테이블
CREATE TABLE IF NOT EXISTS inventory_items (
nsn_code TEXT PRIMARY KEY,
item_name TEXT NOT NULL,
supply_class TEXT NOT NULL CHECK(supply_class IN ('Class_I', 'Class_II', 'Class_III', 'Class_IV', 'Class_V', 'Class_IX')),
criticality_level TEXT DEFAULT 'NORMAL' CHECK(criticality_level IN ('CRITICAL', 'HIGH', 'NORMAL', 'LOW')),
unit_cost REAL NOT NULL DEFAULT 0.0,
safety_stock_threshold INTEGER NOT NULL DEFAULT 10,
total_local_stock INTEGER NOT NULL DEFAULT 0,
crdt_clock INTEGER NOT NULL DEFAULT 0,
updated_at_utc TEXT NOT NULL
);
-- 2. 오프라인 트랜잭션 및 해시체인 로그 테이블
CREATE TABLE IF NOT EXISTS offline_transactions (
transaction_id TEXT PRIMARY KEY,
terminal_id TEXT NOT NULL,
unit_id TEXT NOT NULL,
nsn_code TEXT NOT NULL,
tx_type TEXT NOT NULL CHECK(tx_type IN ('RECEIPT', 'ISSUE', 'TRANSFER', 'DISPOSAL', 'ADJUSTMENT', 'FIELD_CONSUME')),
quantity INTEGER NOT NULL CHECK(quantity > 0),
stock_after INTEGER NOT NULL CHECK(stock_after >= 0),
comms_status TEXT NOT NULL,
grid_coords TEXT,
weather_condition TEXT,
lamport_timestamp INTEGER NOT NULL,
timestamp_utc TEXT NOT NULL,
prev_hash TEXT NOT NULL,
record_hash TEXT NOT NULL,
sync_status TEXT DEFAULT 'PENDING' CHECK(sync_status IN ('PENDING', 'SYNCED_P2P', 'SYNCED_CLOUD', 'CONFLICT_LOCKED')),
FOREIGN KEY(nsn_code) REFERENCES inventory_items(nsn_code)
);
-- 3. CRDT 양방향 동기화 및 충돌 큐 테이블
CREATE TABLE IF NOT EXISTS sync_conflict_queue (
conflict_id TEXT PRIMARY KEY,
transaction_id TEXT NOT NULL,
nsn_code TEXT NOT NULL,
local_stock INTEGER NOT NULL,
incoming_stock INTEGER NOT NULL,
local_clock INTEGER NOT NULL,
incoming_clock INTEGER NOT NULL,
conflict_reason TEXT NOT NULL,
hitl_status TEXT DEFAULT 'PENDING_REVIEW' CHECK(hitl_status IN ('PENDING_REVIEW', 'APPROVED_LOCAL', 'APPROVED_REMOTE', 'MANUAL_MERGED', 'REJECTED')),
resolved_by TEXT,
resolved_stock INTEGER,
resolution_memo TEXT,
resolved_at_utc TEXT,
FOREIGN KEY(transaction_id) REFERENCES offline_transactions(transaction_id)
);
-- 4. P2P 피어 단말 정보 테이블
CREATE TABLE IF NOT EXISTS p2p_peers (
peer_terminal_id TEXT PRIMARY KEY,
unit_id TEXT NOT NULL,
last_known_ip TEXT,
last_sync_timestamp TEXT,
last_sync_lamport INTEGER DEFAULT 0,
trust_score REAL DEFAULT 1.0
);
-- 5. 공급망 재난 및 이상 징후 알림 테이블
CREATE TABLE IF NOT EXISTS supply_disaster_alerts (
alert_id TEXT PRIMARY KEY,
nsn_code TEXT NOT NULL,
alert_type TEXT NOT NULL,
severity TEXT NOT NULL CHECK(severity IN ('CRITICAL', 'WARNING', 'INFO')),
confidence_score REAL NOT NULL,
description TEXT NOT NULL,
detected_at_utc TEXT NOT NULL,
is_acknowledged INTEGER DEFAULT 0
);
-- 인덱스 생성
CREATE INDEX IF NOT EXISTS idx_tx_timestamp ON offline_transactions(timestamp_utc);
CREATE INDEX IF NOT EXISTS idx_tx_nsn ON offline_transactions(nsn_code);
CREATE INDEX IF NOT EXISTS idx_tx_sync_status ON offline_transactions(sync_status);
"""
with open(os.path.join(base, "data/schema/sqlite_schema.sql"), "w", encoding="utf-8") as f:
f.write(sql_content)
print("Schema files created.")