feat(server-03): log unmapped events at DEBUG in DomainEventMapper

Adds a file-private SLF4J logger and replaces the silent else->null branch
with a debug log line that names the payload type, sessionId, and sequence.
Test extended with a log-capture case that verifies exactly one DEBUG event
is emitted containing the payload class name for unrecognised event types.
This commit is contained in:
2026-05-24 22:36:59 +04:00
parent 70420083ac
commit 71aac8afc9
2 changed files with 48 additions and 1 deletions
@@ -21,6 +21,9 @@ import com.correx.core.events.events.TransitionExecutedEvent
import com.correx.core.events.events.WorkflowCompletedEvent
import com.correx.core.events.events.WorkflowFailedEvent
import com.correx.core.events.types.ArtifactId
import org.slf4j.LoggerFactory
private val log = LoggerFactory.getLogger("DomainEventMapper")
class DomainEventMapper(private val artifactStore: ArtifactStore = NoopArtifactStore) {
suspend fun map(event: StoredEvent): ServerMessage? =
@@ -138,7 +141,15 @@ suspend fun domainEventToServerMessage(
)
is ApprovalRequestedEvent -> mapApprovalRequested(p, seq, sessionSequence)
else -> null
else -> {
log.debug(
"DomainEventMapper: unmapped payload type={} sessionId={} sequence={}",
p::class.simpleName,
event.metadata.sessionId,
event.sequence,
)
null
}
}
}
@@ -37,8 +37,15 @@ import com.correx.core.events.types.ValidationReportId
import com.correx.core.inference.TokenUsage
import kotlinx.coroutines.test.runTest
import kotlinx.datetime.Instant
import org.apache.logging.log4j.Level
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.core.LogEvent
import org.apache.logging.log4j.core.LoggerContext
import org.apache.logging.log4j.core.appender.AbstractAppender
import org.apache.logging.log4j.core.config.Property
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertNull
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
class DomainEventMapperTest {
@@ -368,4 +375,33 @@ class DomainEventMapperTest {
val result = domainEventToServerMessage(event, noopStore, sessionSequence = 0L)
assertNull(result)
}
private class TestAppender : AbstractAppender("TestCapture", null, null, true, Property.EMPTY_ARRAY) {
val events = mutableListOf<LogEvent>()
override fun append(event: LogEvent) {
events.add(event.toImmutable())
}
}
@Test
fun `unmapped event emits debug log`(): Unit = runTest {
val ctx = LogManager.getContext(false) as LoggerContext
val logger = ctx.getLogger("DomainEventMapper")
val appender = TestAppender().also { it.start() }
logger.addAppender(appender)
val origLevel = logger.level
logger.level = Level.DEBUG
try {
val event = storedEvent(SessionStartedEvent(sessionId = sessionId))
val result = domainEventToServerMessage(event, noopStore, sessionSequence = 0L)
assertNull(result)
assertEquals(1, appender.events.size)
assertEquals(Level.DEBUG, appender.events[0].level)
assertTrue(appender.events[0].message.formattedMessage.contains("SessionStartedEvent"))
} finally {
logger.removeAppender(appender)
appender.stop()
logger.level = origLevel
}
}
}