Chapter 27 — End-to-End Enterprise Simulation (Refactoring a Cross-Layer Flow)
ทำไมต้องชื่อนี้และเรียนไปเพื่ออะไร?
ใน Day 18 ถึง Day 26 เราได้พัฒนาส่วนประกอบสำคัญทั้งหมดของระบบ Autonomous Software Engineering Agent ขึ้นมาเป็นโมดูลแยกส่วน: Code Intelligence (AST, Call Graph, Hybrid RRF), Safe Execution (Git Worktree, Verification Loop & Auto-Rollback) และ Pluggable Skills (Unit Test Synthesizer, PR Synthesizer, Architecture Reviewer)
วัตถุประสงค์ของ Day 27: จำลองสถานการณ์จริงระดับโปรดักชัน — “ตรวจพบบั๊กคำนวณภาษีและส่วนลดผิดพลาดที่กระทบข้าม 3 เลเยอร์ (Domain Entity → Application Service → REST Controller) พร้อมกับมีการละเมิด Clean Architecture” — แล้วให้ ReAct Agent ดำเนินการแบบอัตโนมัติ 100% ตั้งแต่ Hybrid Search + Call Graph, Git Worktree Sandbox, Architecture Reviewer, Unit Test Synthesizer, Verification Loop จนถึง PR Synthesizer
ผังโครงสร้างโปรเจกต์ใน Day 27 โดยเพิ่ม Runner สคริปต์สำหรับการจำลองสถานการณ์ End-to-End Simulation:
ศูนย์กลางการจำลอง (Simulation Harness) ควบคุม ReAct Agent ให้ทำงานสอดประสานกันทุกเลเยอร์ ตรวจสอบสถานะของ Sandbox, ตรวจจับการโหลด Skill ตาม Lifecycle และวัดผลสำเร็จแบบ End-to-End
โค้ดเบสจำลองที่มีความสัมพันธ์ข้าม 3 เลเยอร์ เพื่อใช้ทดสอบการค้นหาและ Refactor จริง
[User Prompt: Refactor Cross-Layer Pricing Flow]
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 1. RECONNAISSANCE & MAPPING │
│ - Hybrid Search ดึง DiscountPolicy + PricingService │
│ - Call Graph คำนวณ Downstream: CheckoutController │
└──────────────────────────────┬──────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 2. SANDBOX ISOLATION │
│ - สร้าง Worktree: .sandbox/wt_refactor_pricing_101 │
│ - สวิตช์ Context เข้า Sandbox ป้องกันกระทบ Branch หลัก │
└──────────────────────────────┬──────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 3. ARCHITECTURE AUDIT (Activate: architecture_reviewer) │
│ - ตรวจ Import: มั่นใจว่า DiscountPolicy ไม่ฝ่าฝืน Layer │
│ - ผลลัพธ์: PASSED -> อนุญาตให้เริ่มการ Refactor │
└──────────────────────────────┬──────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 4. REFACTOR & TEST SYNTHESIS (Activate: unit_test_synth) │
│ - ปรับแก้ Method Signature & Logic ใน Domain + Service │
│ - สร้าง Unit Test เคส Edge-case (Zero/Negative Discount) │
└──────────────────────────────┬──────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 5. VERIFICATION LOOP │
│ - รัน Maven Test ใน Sandbox │
│ - ผลลัพธ์: Tests Run: 6, Failures: 0 (ผ่าน 100%) │
└──────────────────────────────┬──────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 6. DELIVERY & PR SYNTHESIS (Activate: pr_synthesizer) │
│ - คำนวณ Blast Radius: MEDIUM (3 Layer Callers) │
│ - สังเคราะห์ Markdown PR Description + Ready to Push │
└─────────────────────────────────────────────────────────────┘
import sys
import time
from pathlib import Path
from typing import Dict, List, Any
from skills.architecture_reviewer.tools import verify_layer_dependencies, scan_security_smells
from skills.pr_synthesizer.tools import calculate_blast_radius, format_pr_markdown
class MockEnterpriseEnvironment:
"""จำลองสภาพแวดล้อม Codebase ข้ามเลเยอร์ และ Call Hierarchy Graph"""
def __init__(self):
self.files = {
"src/main/java/com/app/domain/DiscountPolicy.java": """package com.app.domain;
import java.math.BigDecimal;
public class DiscountPolicy {
// BUGGY: ไม่รองรับกรณี discount rate ติดลบ หรือค่าเกิน 100%
public BigDecimal applyDiscount(BigDecimal amount, double percentage) {
return amount.subtract(amount.multiply(BigDecimal.valueOf(percentage / 100.0)));
}
}""",
"src/main/java/com/app/service/OrderPricingService.java": """package com.app.service;
import com.app.domain.DiscountPolicy;
import java.math.BigDecimal;
public class OrderPricingService {
private final DiscountPolicy policy = new DiscountPolicy();
public BigDecimal calculateFinalPrice(BigDecimal basePrice, double discountRate) {
return policy.applyDiscount(basePrice, discountRate);
}
}""",
"src/main/java/com/app/controller/CheckoutController.java": """package com.app.controller;
import com.app.service.OrderPricingService;
import java.math.BigDecimal;
public class CheckoutController {
private final OrderPricingService pricingService = new OrderPricingService();
public BigDecimal checkout(BigDecimal cartTotal, double voucherPercent) {
return pricingService.calculateFinalPrice(cartTotal, voucherPercent);
}
}"""
}
def get_downstream_dependents(self, symbol: str) -> List[str]:
hierarchy = {
"DiscountPolicy": ["OrderPricingService", "CheckoutController"],
"OrderPricingService": ["CheckoutController"],
"CheckoutController": []
}
return hierarchy.get(symbol, [])
def simulate_pipeline():
print("=" * 70)
print("DAY 27: END-TO-END ENTERPRISE REFACTORING SIMULATION")
print("=" * 70)
env = MockEnterpriseEnvironment()
print("\n[PHASE 1] Analyzing Target Code & Call Hierarchy Graph...")
target_file = "src/main/java/com/app/domain/DiscountPolicy.java"
dependents = env.get_downstream_dependents("DiscountPolicy")
print(f" • Root Target Class : {Path(target_file).stem}")
print(f" • Downstream Callers: {dependents} (Cross-layer: Domain -> Service -> Controller)")
print("\n[PHASE 2] Initializing Isolated Git Worktree Sandbox...")
sandbox_id = "wt_refactor_pricing_v2"
print(f" • Created Sandbox: .sandbox/{sandbox_id}")
print(" • Branch: feature/fix-discount-boundary")
print(" • Host Repository protected from direct modification.")
print("\n[PHASE 3] Triggering architecture_reviewer Skill...")
mock_imports = {
target_file: ["java.math.BigDecimal"]
}
violations = verify_layer_dependencies(mock_imports)
smells = scan_security_smells({target_file: env.files[target_file]})
if not violations and not smells:
print(" • Architecture Gate: [PASSED] Clean Architecture invariant respected.")
else:
print(f" • Architecture Gate: [FAILED] {violations}")
return
print("\n[PHASE 4] Applying Refactor & Generating Edge-Case Tests...")
refactored_code = """package com.app.domain;
import java.math.BigDecimal;
public class DiscountPolicy {
public BigDecimal applyDiscount(BigDecimal amount, double percentage) {
if (amount == null || amount.compareTo(BigDecimal.ZERO) < 0) {
throw new IllegalArgumentException("Amount must be non-negative");
}
if (percentage < 0.0 || percentage > 100.0) {
throw new IllegalArgumentException("Discount percentage must be between 0 and 100");
}
BigDecimal discountFactor = BigDecimal.valueOf(percentage / 100.0);
return amount.subtract(amount.multiply(discountFactor));
}
}"""
env.files[target_file] = refactored_code
print(" • Patched: DiscountPolicy.java (added input bounds validation)")
print(" • Synthesized Test Suite: DiscountPolicyTest.java (Covering: null, negative, >100% discount)")
print("\n[PHASE 5] Executing Verification Engine in Sandbox...")
time.sleep(0.5)
test_suite_results = "Tests run: 8, Failures: 0, Errors: 0, Skipped: 0 | Execution Time: 2.81s"
print(f" • Maven Output: {test_suite_results}")
print(" • Verification Status: 100% Pass. Auto-Rollback NOT triggered.")
print("\n[PHASE 6] Triggering pr_synthesizer Skill...")
blast = calculate_blast_radius([target_file], env)
summary = (
"Refactored DiscountPolicy to enforce strict domain boundaries against "
"negative discounts and invalid amounts, preventing accounting anomalies."
)
pr_markdown = format_pr_markdown(
title="fix(pricing): enforce domain constraints on discount calculation",
summary=summary,
blast_data=blast,
test_results=test_suite_results
)
print("\n" + "=" * 30 + " SYNTHESIZED PR " + "=" * 30)
print(pr_markdown)
print("=" * 70)
print("\nEND-TO-END SIMULATION COMPLETED SUCCESSFULLY!")
print("Agent is ready for GitHub CLI dispatch (gh pr create).")
if __name__ == "__main__":
simulate_pipeline()
ขั้นตอนการรัน Simulation จริงบนเครื่อง macOS (M3):
ตรวจสอบว่าโมดูลจาก Day 25 และ Day 26 อยู่ในไดเรกทอรี skills/ เรียบร้อยแล้ว
บันทึกโค้ดในส่วนที่ 4 ลงในไฟล์ simulate_enterprise_flow.py ที่รูทของโปรเจกต์ se_agent/
python simulate_enterprise_flow.py
Agent จะตรวจจับเส้นทาง DiscountPolicy → OrderPricingService → CheckoutController, Architecture Gate เป็น [PASSED], ใส่ Input Validation, รันเทสผ่าน 8 เคส, Blast Radius เป็น MEDIUM และจัดทำ Markdown PR Description
ข้อที่ 1: ทำไมเราจึงต้องให้ Agent ตรวจสอบ Architecture Gate (Phase 3) "ก่อน" ที่จะลงมือแก้โค้ดและรันเทส?
ข้อที่ 2: หากใน Phase 5 ผลการรัน Verification Loop ปรากฏว่า Failures: 2, Errors: 0 กลไกใดในระบบที่จะทำงานทันที?
🏁 สรุปหมุดเชื่อมโยง (Chapter Wrap-up)
เนื้อหาใน Day 27 — End-to-End Enterprise Simulation ประกอบชิ้นส่วนทั้งหมดเป็นวงจรเดียว: ค้นหา → Sandbox → Architecture Gate → Refactor + Tests → Verification → PR พร้อมปิดฉากหลักสูตรใน Day 28: The Extensible Enterprise SE Companion