epic-12: after epic audit and init commit

This commit is contained in:
2026-05-16 11:42:00 +04:00
commit c77277af0b
461 changed files with 28958 additions and 0 deletions
+10
View File
@@ -0,0 +1,10 @@
plugins {
id 'java-library'
id 'org.jetbrains.kotlin.jvm'
id 'org.jetbrains.kotlin.plugin.serialization'
}
dependencies {
implementation(project(":core:events"))
testImplementation(testFixtures(project(":testing:contracts")))
}
@@ -0,0 +1,11 @@
package com.correx.core.sessions
import kotlinx.serialization.Serializable
@Serializable
enum class ApprovalMode {
DENY,
PROMPT,
AUTO,
YOLO
}
@@ -0,0 +1,59 @@
package com.correx.core.sessions
import com.correx.core.events.events.SessionCompletedEvent
import com.correx.core.events.events.SessionFailedEvent
import com.correx.core.events.events.SessionPausedEvent
import com.correx.core.events.events.SessionResumedEvent
import com.correx.core.events.events.SessionStartedEvent
import com.correx.core.events.events.StageCompletedEvent
import com.correx.core.events.events.StageFailedEvent
import com.correx.core.events.events.StageStartedEvent
import com.correx.core.events.events.StoredEvent
import com.correx.core.events.events.TransitionExecutedEvent
class DefaultSessionReducer : SessionReducer {
override fun reduce(
state: SessionState,
event: StoredEvent
): SessionState {
val payload = event.payload
val newStatus = when (payload) {
is SessionStartedEvent ->
SessionStatus.ACTIVE
is SessionPausedEvent ->
SessionStatus.PAUSED
is SessionResumedEvent ->
SessionStatus.ACTIVE
is SessionCompletedEvent ->
SessionStatus.COMPLETED
is SessionFailedEvent,
is StageFailedEvent ->
SessionStatus.FAILED
is StageStartedEvent,
is StageCompletedEvent,
is TransitionExecutedEvent ->
SessionStatus.ACTIVE
else ->
state.status
}
val createdAt = state.createdAt
?: event.metadata.timestamp
return state.copy(
status = newStatus,
createdAt = createdAt,
updatedAt = event.metadata.timestamp
)
}
}
@@ -0,0 +1,16 @@
package com.correx.core.sessions
import com.correx.core.events.types.SessionId
import com.correx.core.sessions.projections.replay.EventReplayer
class DefaultSessionRepository(
private val replayer: EventReplayer<SessionState>
) {
fun getSession(sessionId: SessionId): Session = rebuild(sessionId)
fun rebuild(sessionId: SessionId): Session = Session(
sessionId,
replayer.rebuild(sessionId),
)
}
@@ -0,0 +1,8 @@
package com.correx.core.sessions
import com.correx.core.events.types.SessionId
data class Session(
val sessionId: SessionId,
val state: SessionState,
)
@@ -0,0 +1,19 @@
package com.correx.core.sessions
import com.correx.core.events.events.StoredEvent
import com.correx.core.sessions.projections.Projection
class SessionCounterProjection(
private val sessionId: String
) : Projection<SessionCounterState> {
override fun initial(): SessionCounterState =
SessionCounterState(sessionId, 0)
override fun apply(
state: SessionCounterState,
event: StoredEvent
): SessionCounterState {
return state.copy(count = state.count + 1)
}
}
@@ -0,0 +1,6 @@
package com.correx.core.sessions
data class SessionCounterState(
val sessionId: String,
val count: Int
)
@@ -0,0 +1,19 @@
package com.correx.core.sessions
import com.correx.core.events.events.StoredEvent
import com.correx.core.sessions.projections.Projection
class SessionProjector(
private val reducer: SessionReducer
) : Projection<SessionState> {
override fun initial(): SessionState =
SessionState(
status = SessionStatus.CREATED
)
override fun apply(
state: SessionState,
event: StoredEvent
): SessionState = reducer.reduce(state, event)
}
@@ -0,0 +1,10 @@
package com.correx.core.sessions
import com.correx.core.events.events.StoredEvent
interface SessionReducer {
fun reduce(
state: SessionState,
event: StoredEvent
): SessionState
}
@@ -0,0 +1,10 @@
package com.correx.core.sessions
import kotlinx.datetime.Instant
data class SessionState(
val status: SessionStatus,
val createdAt: Instant? = null,
val updatedAt: Instant? = null,
val invalidTransitions: Int = 0,
)
@@ -0,0 +1,10 @@
package com.correx.core.sessions
enum class SessionStatus {
CREATED,
ACTIVE,
PAUSED,
COMPLETED,
FAILED,
;
}
@@ -0,0 +1,6 @@
package com.correx.core.sessions
sealed interface TransitionResult {
data class Applied(val newState: SessionStatus) : TransitionResult
data object Rejected : TransitionResult
}
@@ -0,0 +1,5 @@
package com.correx.core.sessions.projections
import com.correx.testing.contracts.fixtures.projections.CountingProjectionContractTest
class SessionCounterProjectionTest : CountingProjectionContractTest()