Files
2nd/10_Wiki/Topic_Programming/AI_and_ML/Legacy_Modernization.md
T
Antigravity Agent 9148c358d0 docs(10_Wiki): 위키 전체 재구성 — Topic_* 폴더를 4개 카테고리로 통합 + 대규모 중복 제거
Topic_Agent/Topic_Blog/Topics/Topics_Biz/Topics_Meeting/Topics_Rag의 마크다운 지식 문서를
Topic_General/Topic_Programming/Topic_Graphic/Topic_Business 4개 카테고리로 재분류.

- 중복 제거: frontmatter의 status:duplicate/merged + duplicate_of/redirect_to 필드로
  자기 자신을 중복으로 선언한 리다이렉트 stub 1032개 제거, 완전 동일 내용 파일 472개 제거,
  동일 파일명·다른 내용 충돌 시 더 큰(완전한) 버전만 유지(162개 제거) — 총 1639개 중복 제거.
- 분류: 폴더 단위로 명확한 항목(AI_and_ML/Coding/Architecture 등 → Programming,
  Comfyui/Visual_Effects → Graphic, Topics_Biz/Topics_Meeting/사업 등 → Business,
  Poetic_Blog_Writing/창의성/Game_Design 등 → General)은 폴더 우선순위로,
  나머지 혼재 폴더(Topic_Agent/Topic_Blog/Topics 루트/Thinking & Reasoning/Other/UI_UX_Assets)는
  title/tags 키워드 스코어링으로 파일 단위 분류(불명확한 경우 General로 폴백).
  원본 폴더명은 "From_*" 서브폴더로 보존해 추적 가능성 유지.
- 최종 배치: Programming 2784 / General 1608 / Graphic 285 / Business 249 = 4926개 문서.
- 에이전트 운영 상태(.astra/.agent/.obsidian/sessions/memory/_company/docs/lessons/_shared/src)는
  지식 콘텐츠가 아니므로 재분류 대상에서 제외하고 원위치 유지.
- Topics/Topic_email(상위 보호 폴더 Topic_email과 파일명 100% 중복) 삭제 — 보호 폴더 자체는 미변경.
- 완전히 비게 된 Topic_Agent/Topic_Blog/Topics_Biz/Topics_Rag 폴더 제거.
2026-07-05 00:33:48 +09:00

5.4 KiB

id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
id title category status canonical_id aliases duplicate_of source_trust_level confidence_score verification_status tags raw_sources last_reinforced github_commit tech_stack
wiki-2026-0508-legacy-modernization Legacy Modernization 10_Wiki/Topics verified self
Legacy Migration
Legacy Systems
Strangler Fig
Modernization
none A 0.9 applied
legacy
modernization
strangler-fig
refactor
migration
2026-05-10 pending
language framework
any any

Legacy Modernization

매 한 줄

"매 big-bang 은 죽는다". Strangler fig 로 incremental 하게 둘러싸고 잘라낸다, parallel run 으로 검증.

매 핵심

매 5 pattern

  • Strangler Fig (Fowler): 신규 시스템이 점진적으로 legacy 를 둘러싸고 대체. 가장 안전
  • Branch by Abstraction: 인터페이스 추출 → 두 구현 공존 → 신구 전환 → 구 제거
  • Parallel Run: 신구 동시 실행, 결과 비교, 신뢰 쌓이면 cutover
  • Rewrite vs Refactor: 비즈니스 로직 명확하면 refactor, 아키 자체가 문제면 rewrite
  • Anti-corruption Layer (DDD): legacy 모델이 신규에 새지 않도록 adapter

매 응용

  1. Monolith → microservice 분해
  2. On-prem → cloud
  3. Legacy DB schema 점진적 마이그레이션
  4. COBOL → Java/Go
  5. SOAP → REST/gRPC

💻 패턴

Pattern 1: Strangler Fig with reverse proxy

# nginx routes traffic: new endpoints → new svc, rest → legacy
location /api/v2/users { proxy_pass http://new-service; }
location /api/v2/orders { proxy_pass http://new-service; }
location / { proxy_pass http://legacy-monolith; }
# 매주 endpoint 추가 → legacy 점점 축소

Pattern 2: Branch by Abstraction

# 1. 추출
class PaymentGateway(Protocol):
    def charge(self, amount: int) -> str: ...

class LegacyPayment(PaymentGateway): ...  # 기존
class NewPayment(PaymentGateway): ...     # 신규

# 2. Feature flag 로 전환
def get_payment() -> PaymentGateway:
    return NewPayment() if flag.enabled("new_payment") else LegacyPayment()

Pattern 3: Parallel run with shadow traffic

def process_order(order):
    legacy_result = legacy.process(order)
    try:
        new_result = new.process(order)
        if new_result != legacy_result:
            log_diff(order, legacy_result, new_result)
    except Exception as e:
        log_error(e)
    return legacy_result  # 아직 legacy 가 truth

Pattern 4: Anti-corruption Layer

# Legacy 의 이상한 model 을 새 domain 으로 변환
class LegacyCustomerAdapter:
    def to_domain(self, row: dict) -> Customer:
        # legacy: cust_nm, cust_dt_birth, cust_flg_act
        return Customer(
            name=row["cust_nm"],
            birthday=parse_legacy_date(row["cust_dt_birth"]),
            active=row["cust_flg_act"] == "Y",
        )

Pattern 5: Database expand-contract

-- Phase 1 expand: 새 컬럼 추가, 양쪽 쓰기
ALTER TABLE users ADD COLUMN email_v2 VARCHAR(255);
-- App: write to both email AND email_v2

-- Phase 2 backfill: 기존 데이터 복사
UPDATE users SET email_v2 = LOWER(TRIM(email)) WHERE email_v2 IS NULL;

-- Phase 3 contract: 신규 read, 구 제거
-- App: read from email_v2 only
ALTER TABLE users DROP COLUMN email;
ALTER TABLE users RENAME COLUMN email_v2 TO email;

Pattern 6: Characterization tests before refactor

# Legacy 동작을 "있는 그대로" 고정 — golden master
def test_legacy_behavior():
    for input_case in load_production_samples():
        actual = legacy.process(input_case)
        assert actual == load_golden(input_case.id)
# Refactor 후에도 통과해야 함

Pattern 7: Event interception (Strangler 변형)

# Legacy 가 발행하는 event 를 새 서비스가 구독
@on_event("OrderCreated")
def new_handler(event):
    new_service.create_order(event.payload)
# Legacy 는 그대로, 새 시스템이 옆에서 동기화

매 결정 기준

상황 Approach
비즈니스 로직 명확, 코드 더러움 Refactor (in place)
아키 자체가 잘못 Rewrite + Strangler Fig
Risk 매우 높음 Parallel run + shadow
DB schema 변경 Expand-contract
Legacy 모델이 새 시스템 오염 Anti-corruption Layer
Big bang 유혹 거의 항상 X

기본값: Strangler Fig + Branch by Abstraction + Characterization tests.

🔗 Graph

🤖 LLM 활용

언제: legacy 코드 의도 파악, characterization test 생성, COBOL → Java 변환 후 검증. 언제 X: 결정론적 schema migration (sqitch/flyway), 비즈니스 룰 단독 추출 (사람 검증 필수).

안티패턴

  • Big bang rewrite ("2년만 주세요") → 프로젝트 사망
  • Test 없이 refactor → 회귀 무한
  • Strangler 시작했는데 끝까지 안 감 → 이중 유지보수 영원
  • DB schema 한번에 변경 → 롤백 불가
  • 비즈니스 사용자 무시 → 신규 기능 deliver 정지

🧪 검증 / 중복

  • Verified (Fowler StranglerFigApplication, Feathers WELC, Evans DDD ACL). 신뢰도 A.
  • Legacy-Systems.md 가 본 문서 redirect.

🕓 Changelog

날짜 변경
2026-05-08 Phase 1
2026-05-10 Manual cleanup — canonical, 5 pattern + 7 code recipe