diff --git a/.forge/ACM-FW-001-attempt-3-run-cf9312821cb6.md b/.forge/ACM-FW-001-attempt-3-run-cf9312821cb6.md
deleted file mode 100644
index 4a5f0c4..0000000
--- a/.forge/ACM-FW-001-attempt-3-run-cf9312821cb6.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# ACM-FW-001-attempt-3-run-cf9312821cb6
-
-Forge 이슈 작업 브랜치 `forge/ACM-FW-001-attempt-3-run-cf9312821cb6`.
diff --git a/boot/common-framework/src/main/java/com/klaro/acquirecore/framework/TxContext.java b/boot/common-framework/src/main/java/com/klaro/acquirecore/framework/TxContext.java
index 35e5443..1a56634 100644
--- a/boot/common-framework/src/main/java/com/klaro/acquirecore/framework/TxContext.java
+++ b/boot/common-framework/src/main/java/com/klaro/acquirecore/framework/TxContext.java
@@ -1,90 +1,31 @@
package com.klaro.acquirecore.framework;
-import java.io.Serializable;
-import java.time.Instant;
+import java.util.HashMap;
import java.util.Map;
-import java.util.UUID;
/**
- * Transaction context DTO carrying runtime state across service calls.
- * Mirrors the C tx_context struct fields.
+ * 레거시 TxCore {@code TXBUF} (고정 슬롯 키/값 버퍼) 의 Spring 대체 자리표시자.
+ *
+ *
실 전환에서는 요청/응답 DTO(record) 가 정형 필드를 담고, 이 컨텍스트는
+ * 서비스 체인({@code tx_call}) 간 전달되는 느슨한 키/값 상태만 보관한다.
*/
-public class TxContext implements Serializable {
+public final class TxContext {
- private static final long serialVersionUID = 1L;
+ private final Map slots = new HashMap<>();
- private String transactionId;
- private String serviceName;
- private TxStatus status;
- private Instant startedAt;
- private Instant committedAt;
- private Map metadata;
-
- public TxContext() {
- this.transactionId = UUID.randomUUID().toString();
- this.status = TxStatus.INITIAL;
- this.startedAt = Instant.now();
+ /** TXBUF 필드 설정 (레거시 {@code Fchg} 상당). */
+ public TxContext put(String key, Object value) {
+ slots.put(key, value);
+ return this;
}
- public TxContext(String serviceName) {
- this();
- this.serviceName = serviceName;
+ /** TXBUF 필드 조회 (레거시 {@code Fget} 상당). */
+ public Object get(String key) {
+ return slots.get(key);
}
- public String getTransactionId() {
- return transactionId;
- }
-
- public void setTransactionId(String transactionId) {
- this.transactionId = transactionId;
- }
-
- public String getServiceName() {
- return serviceName;
- }
-
- public void setServiceName(String serviceName) {
- this.serviceName = serviceName;
- }
-
- public TxStatus getStatus() {
- return status;
- }
-
- public void setStatus(TxStatus status) {
- this.status = status;
- }
-
- public Instant getStartedAt() {
- return startedAt;
- }
-
- public void setStartedAt(Instant startedAt) {
- this.startedAt = startedAt;
- }
-
- public Instant getCommittedAt() {
- return committedAt;
- }
-
- public void setCommittedAt(Instant committedAt) {
- this.committedAt = committedAt;
- }
-
- public Map getMetadata() {
- return metadata;
- }
-
- public void setMetadata(Map metadata) {
- this.metadata = metadata;
- }
-
- public void markCommitted() {
- this.status = TxStatus.COMMITTED;
- this.committedAt = Instant.now();
- }
-
- public void markRolledBack() {
- this.status = TxStatus.ROLLED_BACK;
+ /** 적재된 슬롯 개수. */
+ public int size() {
+ return slots.size();
}
}
diff --git a/boot/common-framework/src/main/java/com/klaro/acquirecore/framework/TxContextTest.java b/boot/common-framework/src/main/java/com/klaro/acquirecore/framework/TxContextTest.java
deleted file mode 100644
index 429b994..0000000
--- a/boot/common-framework/src/main/java/com/klaro/acquirecore/framework/TxContextTest.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package com.klaro.acquirecore.framework;
-
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-class TxContextTest {
-
- @Test
- void defaultConstructorSetsInitialState() {
- TxContext ctx = new TxContext();
- assertNotNull(ctx.getTransactionId());
- assertEquals(TxStatus.INITIAL, ctx.getStatus());
- assertNotNull(ctx.getStartedAt());
- }
-
- @Test
- void constructorWithServiceName() {
- TxContext ctx = new TxContext("myService");
- assertEquals("myService", ctx.getServiceName());
- assertEquals(TxStatus.INITIAL, ctx.getStatus());
- }
-
- @Test
- void markCommittedUpdatesStatusAndTimestamp() {
- TxContext ctx = new TxContext();
- assertNull(ctx.getCommittedAt());
- ctx.markCommitted();
- assertEquals(TxStatus.COMMITTED, ctx.getStatus());
- assertNotNull(ctx.getCommittedAt());
- }
-
- @Test
- void markRolledBackUpdatesStatus() {
- TxContext ctx = new TxContext();
- ctx.markRolledBack();
- assertEquals(TxStatus.ROLLED_BACK, ctx.getStatus());
- }
-
- @Test
- void settersAndGetters() {
- TxContext ctx = new TxContext();
- ctx.setTransactionId("tx-123");
- ctx.setServiceName("testService");
- ctx.setStatus(TxStatus.ACTIVE);
- assertEquals("tx-123", ctx.getTransactionId());
- assertEquals("testService", ctx.getServiceName());
- assertEquals(TxStatus.ACTIVE, ctx.getStatus());
- }
-}
diff --git a/boot/common-framework/src/main/java/com/klaro/acquirecore/framework/TxResult.java b/boot/common-framework/src/main/java/com/klaro/acquirecore/framework/TxResult.java
deleted file mode 100644
index b8a0099..0000000
--- a/boot/common-framework/src/main/java/com/klaro/acquirecore/framework/TxResult.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package com.klaro.acquirecore.framework;
-
-import java.io.Serializable;
-
-/**
- * Generic result wrapper for transactional operations.
- * Mirrors C tx_result struct semantics.
- */
-public class TxResult implements Serializable {
-
- private static final long serialVersionUID = 1L;
-
- private boolean success;
- private T data;
- private String errorCode;
- private String errorMessage;
-
- public TxResult() {
- }
-
- public static TxResult ok(T data) {
- TxResult result = new TxResult<>();
- result.success = true;
- result.data = data;
- return result;
- }
-
- public static TxResult error(String errorCode, String errorMessage) {
- TxResult result = new TxResult<>();
- result.success = false;
- result.errorCode = errorCode;
- result.errorMessage = errorMessage;
- return result;
- }
-
- public boolean isSuccess() {
- return success;
- }
-
- public void setSuccess(boolean success) {
- this.success = success;
- }
-
- public T getData() {
- return data;
- }
-
- public void setData(T data) {
- this.data = data;
- }
-
- public String getErrorCode() {
- return errorCode;
- }
-
- public void setErrorCode(String errorCode) {
- this.errorCode = errorCode;
- }
-
- public String getErrorMessage() {
- return errorMessage;
- }
-
- public void setErrorMessage(String errorMessage) {
- this.errorMessage = errorMessage;
- }
-}
diff --git a/boot/common-framework/src/main/java/com/klaro/acquirecore/framework/TxService.java b/boot/common-framework/src/main/java/com/klaro/acquirecore/framework/TxService.java
deleted file mode 100644
index 27cfd16..0000000
--- a/boot/common-framework/src/main/java/com/klaro/acquirecore/framework/TxService.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.klaro.acquirecore.framework;
-
-/**
- * Functional interface for transactional service operations.
- * Represents a single unit of work within a transaction context.
- */
-@FunctionalInterface
-public interface TxService {
-
- /**
- * Execute the service operation within the given transaction context.
- *
- * @param ctx the transaction context
- * @param input the input data for the operation
- * @return the result of the operation
- */
- Object execute(TxContext ctx, Object input);
-}
diff --git a/boot/common-framework/src/main/java/com/klaro/acquirecore/framework/TxServiceRegistry.java b/boot/common-framework/src/main/java/com/klaro/acquirecore/framework/TxServiceRegistry.java
deleted file mode 100644
index 7c43a3f..0000000
--- a/boot/common-framework/src/main/java/com/klaro/acquirecore/framework/TxServiceRegistry.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package com.klaro.acquirecore.framework;
-
-import org.springframework.stereotype.Service;
-
-import jakarta.annotation.PostConstruct;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * Service registry replacing C TX_SERVICE/registry pattern.
- * Acts as a central dispatcher for transactional services.
- * Annotated with @Service for Spring component scanning.
- */
-@Service
-public class TxServiceRegistry {
-
- private final Map services = new ConcurrentHashMap<>();
-
- @PostConstruct
- public void init() {
- // Registry initialized and ready for service lookups
- }
-
- /**
- * Register a transactional service by name.
- * Mirrors C tx_registry_add().
- */
- public void registerService(String name, TxService service) {
- services.put(name, service);
- }
-
- /**
- * Unregister a service by name.
- */
- public void unregisterService(String name) {
- services.remove(name);
- }
-
- /**
- * Lookup a registered service by name.
- * Mirrors C tx_registry_lookup().
- */
- public TxService lookupService(String name) {
- return services.get(name);
- }
-
- /**
- * Execute a transactional operation on a named service.
- * Mirrors C tx_service_dispatch().
- */
- public TxResult dispatch(String serviceName, TxContext ctx, Object input) {
- TxService service = lookupService(serviceName);
- if (service == null) {
- return TxResult.error("SERVICE_NOT_FOUND", "Service not registered: " + serviceName);
- }
- try {
- Object result = service.execute(ctx, input);
- return TxResult.ok(result);
- } catch (Exception e) {
- return TxResult.error("EXECUTION_FAILED", e.getMessage());
- }
- }
-
- /**
- * Check if a service is registered.
- */
- public boolean isRegistered(String name) {
- return services.containsKey(name);
- }
-
- /**
- * Get count of registered services.
- */
- public int getServiceCount() {
- return services.size();
- }
-}
diff --git a/boot/common-framework/src/main/java/com/klaro/acquirecore/framework/TxServiceRegistryTest.java b/boot/common-framework/src/main/java/com/klaro/acquirecore/framework/TxServiceRegistryTest.java
deleted file mode 100644
index 28b362a..0000000
--- a/boot/common-framework/src/main/java/com/klaro/acquirecore/framework/TxServiceRegistryTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package com.klaro.acquirecore.framework;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-class TxServiceRegistryTest {
-
- private TxServiceRegistry registry;
-
- @BeforeEach
- void setUp() {
- registry = new TxServiceRegistry();
- registry.init();
- }
-
- @Test
- void registerAndLookupService() {
- TxService service = (ctx, input) -> "result";
- registry.registerService("testService", service);
- assertTrue(registry.isRegistered("testService"));
- assertEquals(service, registry.lookupService("testService"));
- }
-
- @Test
- void lookupUnregisteredServiceReturnsNull() {
- assertNull(registry.lookupService("nonExistent"));
- assertFalse(registry.isRegistered("nonExistent"));
- }
-
- @Test
- void unregisterService() {
- TxService service = (ctx, input) -> "result";
- registry.registerService("toRemove", service);
- registry.unregisterService("toRemove");
- assertFalse(registry.isRegistered("toRemove"));
- }
-
- @Test
- void dispatchExecutesRegisteredService() {
- TxService service = (ctx, input) -> "processed: " + input;
- registry.registerService("echo", service);
- TxContext ctx = new TxContext("echo");
- TxResult result = registry.dispatch("echo", ctx, "hello");
- assertTrue(result.isSuccess());
- assertEquals("processed: hello", result.getData());
- }
-
- @Test
- void dispatchFailsForUnregisteredService() {
- TxContext ctx = new TxContext("unknown");
- TxResult> result = registry.dispatch("unknown", ctx, null);
- assertFalse(result.isSuccess());
- assertEquals("SERVICE_NOT_FOUND", result.getErrorCode());
- }
-
- @Test
- void dispatchHandlesServiceException() {
- TxService failingService = (ctx, input) -> { throw new RuntimeException("Service error"); };
- registry.registerService("failing", failingService);
- TxContext ctx = new TxContext("failing");
- TxResult> result = registry.dispatch("failing", ctx, null);
- assertFalse(result.isSuccess());
- assertEquals("EXECUTION_FAILED", result.getErrorCode());
- }
-
- @Test
- void getServiceCount() {
- assertEquals(0, registry.getServiceCount());
- registry.registerService("s1", (ctx, input) -> null);
- registry.registerService("s2", (ctx, input) -> null);
- assertEquals(2, registry.getServiceCount());
- }
-}
diff --git a/boot/common-framework/src/main/java/com/klaro/acquirecore/framework/TxStatus.java b/boot/common-framework/src/main/java/com/klaro/acquirecore/framework/TxStatus.java
deleted file mode 100644
index 91cf88a..0000000
--- a/boot/common-framework/src/main/java/com/klaro/acquirecore/framework/TxStatus.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.klaro.acquirecore.framework;
-
-/**
- * Transaction lifecycle states mirroring C tx_status enum.
- */
-public enum TxStatus {
- INITIAL,
- ACTIVE,
- COMMITTED,
- ROLLED_BACK,
- FAILED
-}
diff --git a/boot/common-framework/src/main/java/com/klaro/acquirecore/framework/TxTemplate.java b/boot/common-framework/src/main/java/com/klaro/acquirecore/framework/TxTemplate.java
deleted file mode 100644
index a831ed2..0000000
--- a/boot/common-framework/src/main/java/com/klaro/acquirecore/framework/TxTemplate.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package com.klaro.acquirecore.framework;
-
-import org.springframework.stereotype.Component;
-import org.springframework.transaction.annotation.Transactional;
-
-/**
- * Transaction template replacing C tx_begin/tx_commit pattern.
- * Provides @Transactional-backed execution with context management.
- * Mirrors C tx_begin(), tx_commit(), tx_rollback() lifecycle.
- */
-@Component
-public class TxTemplate {
-
- /**
- * Execute a transactional operation with automatic commit on success,
- * rollback on exception. Mirrors C tx_begin + tx_commit pattern.
- *
- * @param serviceName the name of the registered service
- * @param input the input data
- * @param the result type
- * @return TxResult containing the outcome
- */
- @Transactional(rollbackFor = Exception.class)
- public TxResult execute(String serviceName, Object input) {
- return executeWithContext(serviceName, new TxContext(serviceName), input);
- }
-
- /**
- * Execute with an existing transaction context.
- *
- * @param serviceName the name of the registered service
- * @param ctx the existing transaction context
- * @param input the input data
- * @param the result type
- * @return TxResult containing the outcome
- */
- @Transactional(rollbackFor = Exception.class)
- public TxResult executeWithContext(String serviceName, TxContext ctx, Object input) {
- ctx.setStatus(TxStatus.ACTIVE);
- try {
- Object result = doExecute(serviceName, ctx, input);
- ctx.markCommitted();
- return TxResult.ok(result);
- } catch (Exception e) {
- ctx.markRolledBack();
- return TxResult.error("TX_FAILED", e.getMessage());
- }
- }
-
- /**
- * Execute without transaction boundary (read-only operations).
- *
- * @param serviceName the name of the registered service
- * @param input the input data
- * @param the result type
- * @return TxResult containing the outcome
- */
- @Transactional(readOnly = true)
- public TxResult query(String serviceName, Object input) {
- try {
- TxContext ctx = new TxContext(serviceName);
- Object result = doExecute(serviceName, ctx, input);
- return TxResult.ok(result);
- } catch (Exception e) {
- return TxResult.error("QUERY_FAILED", e.getMessage());
- }
- }
-
- private Object doExecute(String serviceName, TxContext ctx, Object input) {
- throw new UnsupportedOperationException(
- "Direct execution not supported. Use TxServiceRegistry.dispatch() or inject TxService directly."
- );
- }
-}