import os import json base = r"d:/edunlab/milicontent2/uploads/DAT06" os.makedirs(base, exist_ok=True) for sub in ["docs", "src/connectors", "src/engine", "src/ai", "src/utils", "src/ui", "src/workflow", "src/pipeline", "config", "data/samples", "tests", "dist/dat06_package"]: os.makedirs(os.path.join(base, sub), exist_ok=True) # 1. requirements.txt with open(os.path.join(base, "requirements.txt"), "w", encoding="utf-8") as f: f.write("""pandas>=2.0.0 numpy>=1.24.0 streamlit>=1.28.0 pyyaml>=6.0 pytest>=7.4.0 tabulate>=0.9.0 """) # 2. config/rules_config.yaml with open(os.path.join(base, "config/rules_config.yaml"), "w", encoding="utf-8") as f: f.write("""version: "1.0.0" settlement_rules: material: max_monthly_issue_limit_ratio: 1.5 standard_depreciation_rate: 0.05 spare_parts: unit_cost_warning_threshold: 5000000 critical_parts_min_stock_ratio: 0.20 ammo: max_unreturned_tolerance_ratio: 0.00 live_fire_deduction_rate: 1.00 readiness: target_operational_readiness_rate: 0.85 critical_readiness_threshold: 0.70 anomaly_detection: zscore_threshold: 2.5 iqr_multiplier: 1.5 rolling_window_months: 3 top_k_recommendations: 3 """) # 3. config/rbac_config.yaml with open(os.path.join(base, "config/rbac_config.yaml"), "w", encoding="utf-8") as f: f.write("""roles: officer: name: "군수담당관" level: 1 permissions: ["read", "write", "submit_draft"] supply_master: name: "보급관" level: 2 permissions: ["read", "review_1st", "reject"] logistics_chief: name: "군수과장" level: 3 permissions: ["read", "approve_final", "reject", "publish"] admin: name: "시스템관리자" level: 9 permissions: ["all"] """) # 4. Sample Data with open(os.path.join(base, "data/samples/material_issue_sample.csv"), "w", encoding="utf-8") as f: f.write("""date,unit_code,item_code,item_name,category,initial_stock,received_qty,issued_qty,ending_stock,unit_price 2026-09-01,UNIT_01,MAT_101,전투식량 1형,일반물자,1000,500,600,900,8000 2026-09-05,UNIT_01,MAT_102,방한피복 상의,피복,200,50,30,220,45000 2026-09-10,UNIT_02,MAT_101,전투식량 1형,일반물자,800,400,500,700,8000 2026-09-15,UNIT_02,MAT_103,수통 및 요대 세트,장구류,150,0,20,130,25000 2026-09-20,UNIT_03,MAT_101,전투식량 1형,일반물자,1200,600,1100,700,8000 2026-09-25,UNIT_03,MAT_104,야전 텐트(4인용),일반물자,50,10,5,55,150000 """) with open(os.path.join(base, "data/samples/spare_parts_sample.csv"), "w", encoding="utf-8") as f: f.write("""date,unit_code,part_code,part_name,equipment_model,consumed_qty,requested_qty,unit_cost,total_cost 2026-09-02,UNIT_01,PRT_501,엔진오일 필터,K-200,10,12,35000,350000 2026-09-08,UNIT_01,PRT_502,궤도 패드 세트,K-200,4,4,450000,1800000 2026-09-12,UNIT_02,PRT_501,엔진오일 필터,K-511,8,8,35000,280000 2026-09-18,UNIT_02,PRT_503,브레이크 실린더,K-511,2,3,210000,420000 2026-09-22,UNIT_03,PRT_504,변속기 클러치 디스크,K-1A1,1,1,1850000,1850000 """) with open(os.path.join(base, "data/samples/ammo_settlement_sample.csv"), "w", encoding="utf-8") as f: f.write("""date,unit_code,ammo_code,ammo_name,caliber,initial_stock,received_qty,expended_qty,returned_qty,ending_stock 2026-09-03,UNIT_01,AMM_001,5.56mm 보통탄,5.56mm,15000,5000,4800,200,15000 2026-09-07,UNIT_01,AMM_002,7.62mm 기관총탄,7.62mm,8000,2000,1900,100,8000 2026-09-14,UNIT_02,AMM_001,5.56mm 보통탄,5.56mm,12000,4000,3900,100,12000 2026-09-21,UNIT_03,AMM_003,12.7mm 중기관총탄,12.7mm,5000,1000,1000,0,5000 2026-09-28,UNIT_03,AMM_004,40mm 유탄,40mm,600,200,180,20,600 """) with open(os.path.join(base, "data/samples/equipment_readiness_sample.csv"), "w", encoding="utf-8") as f: f.write("""date,unit_code,equipment_code,equipment_name,authorized_qty,operating_qty,maintenance_qty,standby_qty 2026-09-30,UNIT_01,EQP_001,K-200 장갑차,20,18,2,0 2026-09-30,UNIT_01,EQP_002,K-511 전술트럭,15,14,1,0 2026-09-30,UNIT_02,EQP_001,K-200 장갑차,18,15,2,1 2026-09-30,UNIT_02,EQP_003,소형전술차량,12,11,1,0 2026-09-30,UNIT_03,EQP_004,K-1A1 전차,14,12,2,0 """) train_json = { "UNIT_01": [ {"event": "대대 전술훈련평가", "start": "2026-09-02", "end": "2026-09-05", "impact_category": ["material", "ammo"]}, {"event": "정기 사격집체훈련", "start": "2026-09-07", "end": "2026-09-08", "impact_category": ["ammo"]} ], "UNIT_02": [ {"event": "혹서기 정비주간", "start": "2026-09-10", "end": "2026-09-14", "impact_category": ["spare_parts"]}, {"event": "야간 야외기동훈련", "start": "2026-09-20", "end": "2026-09-22", "impact_category": ["material", "readiness"]} ], "UNIT_03": [ {"event": "포병/기보 합동 야외훈련", "start": "2026-09-18", "end": "2026-09-25", "impact_category": ["material", "spare_parts", "ammo"]} ] } with open(os.path.join(base, "data/samples/training_schedule.json"), "w", encoding="utf-8") as f: json.dump(train_json, f, ensure_ascii=False, indent=2) print("Base setup completed.")