diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b8e4d10..d32fb80 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -70,13 +70,17 @@ jobs: run: chmod +x gradlew - name: Run lint - run: ./gradlew ktlintCheck + # Path scoped to :backend on purpose: :composeApp applies the Android Gradle plugin, + # which needs an Android SDK to even configure. Keeping every gradlew invocation on a + # fully-qualified project path (with org.gradle.configureondemand=true) lets CI skip + # configuring :composeApp entirely, so no Android SDK setup is needed on this runner. + run: ./gradlew :backend:ktlintCheck - name: Publish ktlint report uses: yutailang0119/action-ktlint@v5 if: always() with: - report-path: build/reports/ktlint/**/*.xml + report-path: backend/build/reports/ktlint/**/*.xml continue-on-error: false test: @@ -128,12 +132,12 @@ jobs: uses: actions/upload-artifact@v7 with: name: test-results - path: build/reports/tests/test + path: backend/build/reports/tests/test - name: Publish Test Report uses: dorny/test-reporter@v3 if: always() with: name: JUnit Tests - path: build/test-results/test/TEST-*.xml + path: backend/build/test-results/test/TEST-*.xml reporter: java-junit \ No newline at end of file diff --git a/.gitignore b/.gitignore index 65cfb0e..d5a6a3b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,15 @@ .gradle +.kotlin/ build/ !gradle/wrapper/gradle-wrapper.jar !**/src/main/**/build/ !**/src/test/**/build/ +### Android / KMP ### +local.properties +captures/ +.cxx/ + ### STS ### .apt_generated .classpath diff --git a/backend/build.gradle.kts b/backend/build.gradle.kts new file mode 100644 index 0000000..91732a9 --- /dev/null +++ b/backend/build.gradle.kts @@ -0,0 +1,105 @@ +import org.jlleitschuh.gradle.ktlint.KtlintExtension + +val ktorVersion: Provider = providers.gradleProperty("ktor_version") +val kotlinVersion: Provider = providers.gradleProperty("kotlin_version") +val kotlinSerializationVersion: Provider = providers.gradleProperty("kotlin_serialization_version") +val logbackVersion: Provider = providers.gradleProperty("logback_version") +val koinVersion: Provider = providers.gradleProperty("koin_version") +val kotlinLoggingVersion: Provider = providers.gradleProperty("kotlin_logging_version") +val kotestVersion: Provider = providers.gradleProperty("kotest_version") + +plugins { + application + kotlin("jvm") + id("io.ktor.plugin") version "3.5.1" + id("org.jetbrains.kotlin.plugin.serialization") + id("org.jlleitschuh.gradle.ktlint") version "14.2.0" +} + +group = "io.github.flecomte" + +application { + mainClass.set("eventDemo.ApplicationKt") + + val isDevelopment: Boolean = project.ext.has("development") + applicationDefaultJvmArgs = listOf("-Dio.ktor.development=$isDevelopment") +} + +configure { + version.set("1.8.0") +} +ktlint { + reporters { + reporter(org.jlleitschuh.gradle.ktlint.reporter.ReporterType.CHECKSTYLE) + } +} + +repositories { + mavenCentral() +} + +java { + toolchain { + languageVersion = JavaLanguageVersion.of(21) + } +} + +kotlin { + compilerOptions { + freeCompilerArgs.add("-opt-in=kotlin.uuid.ExperimentalUuidApi") + } +} + +tasks.withType().configureEach { + useJUnitPlatform() + jvmArgs("-Djdk.attach.allowAttachSelf=true", "-XX:+EnableDynamicAgentLoading") + // Dynamic self-attach (used by MockK/ByteBuddy) times out in Docker containers because the + // SIGQUIT-triggered AttachListener handshake never completes there. Loading the byte-buddy + // agent jar statically via -javaagent avoids the attach handshake entirely: MockK detects the + // pre-installed Instrumentation instance and skips dynamic attach. + doFirst { + val agentJar = + classpath.files.firstOrNull { it.name.startsWith("byte-buddy-agent") } + ?: error("byte-buddy-agent jar not found on test classpath") + jvmArgs("-javaagent:$agentJar") + } +} + +dependencies { + implementation(project(":shared")) + implementation("io.ktor:ktor-server-core-jvm") + implementation("io.ktor:ktor-server-auth-jvm") + implementation("io.ktor:ktor-server-auth-jwt-jvm") + implementation("io.ktor:ktor-server-auto-head-response-jvm") + implementation("io.ktor:ktor-server-resources") + implementation("io.ktor:ktor-server-content-negotiation-jvm") + implementation("io.ktor:ktor-serialization-kotlinx-json-jvm") + implementation("io.ktor:ktor-server-websockets-jvm") + implementation("io.ktor:ktor-server-cors-jvm") + implementation("io.ktor:ktor-server-host-common-jvm") + implementation("io.ktor:ktor-server-status-pages-jvm") + implementation("io.ktor:ktor-server-netty-jvm") + implementation("io.ktor:ktor-server-data-conversion") + implementation("io.ktor:ktor-client-content-negotiation") + implementation("io.ktor:ktor-client-auth") + implementation("ch.qos.logback:logback-classic:${logbackVersion.get()}") + implementation("io.insert-koin:koin-ktor:${koinVersion.get()}") + implementation("io.insert-koin:koin-logger-slf4j:${koinVersion.get()}") + implementation("io.github.oshai:kotlin-logging-jvm:${kotlinLoggingVersion.get()}") + implementation("org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:${kotlinSerializationVersion.get()}") + implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.2") + implementation("org.postgresql:postgresql:42.7.13") + implementation("com.zaxxer:HikariCP:6.3.0") + implementation("com.rabbitmq:amqp-client:5.25.0") + implementation("com.password4j:password4j:1.8.4") + + // Force version of sub library (for security) + implementation("commons-codec:commons-codec:1.13") + + testImplementation("io.kotest:kotest-extensions-koin:${kotestVersion.get()}") + testImplementation("org.jetbrains.kotlin:kotlin-test-junit:${kotlinVersion.get()}") + testImplementation("io.ktor:ktor-server-test-host-jvm:${ktorVersion.get()}") + testImplementation("io.kotest:kotest-runner-junit5:${kotestVersion.get()}") + testImplementation("io.mockk:mockk:1.14.11") + testImplementation("com.tngtech.archunit:archunit-junit5:1.3.0") +} diff --git a/src/main/kotlin/eventDemo/Application.kt b/backend/src/main/kotlin/eventDemo/Application.kt similarity index 100% rename from src/main/kotlin/eventDemo/Application.kt rename to backend/src/main/kotlin/eventDemo/Application.kt diff --git a/src/main/kotlin/eventDemo/configuration/Configuration.kt b/backend/src/main/kotlin/eventDemo/configuration/Configuration.kt similarity index 100% rename from src/main/kotlin/eventDemo/configuration/Configuration.kt rename to backend/src/main/kotlin/eventDemo/configuration/Configuration.kt diff --git a/src/main/kotlin/eventDemo/configuration/ConfigureDI.kt b/backend/src/main/kotlin/eventDemo/configuration/ConfigureDI.kt similarity index 100% rename from src/main/kotlin/eventDemo/configuration/ConfigureDI.kt rename to backend/src/main/kotlin/eventDemo/configuration/ConfigureDI.kt diff --git a/src/main/kotlin/eventDemo/configuration/ConfigureDIDataSources.kt b/backend/src/main/kotlin/eventDemo/configuration/ConfigureDIDataSources.kt similarity index 100% rename from src/main/kotlin/eventDemo/configuration/ConfigureDIDataSources.kt rename to backend/src/main/kotlin/eventDemo/configuration/ConfigureDIDataSources.kt diff --git a/src/main/kotlin/eventDemo/configuration/ConfigureKoin.kt b/backend/src/main/kotlin/eventDemo/configuration/ConfigureKoin.kt similarity index 100% rename from src/main/kotlin/eventDemo/configuration/ConfigureKoin.kt rename to backend/src/main/kotlin/eventDemo/configuration/ConfigureKoin.kt diff --git a/src/main/kotlin/eventDemo/configuration/ConfigureKtor.kt b/backend/src/main/kotlin/eventDemo/configuration/ConfigureKtor.kt similarity index 100% rename from src/main/kotlin/eventDemo/configuration/ConfigureKtor.kt rename to backend/src/main/kotlin/eventDemo/configuration/ConfigureKtor.kt diff --git a/src/main/kotlin/eventDemo/contexts/auth/application/eventStores/UserEventStoreRepository.kt b/backend/src/main/kotlin/eventDemo/contexts/auth/application/eventStores/UserEventStoreRepository.kt similarity index 93% rename from src/main/kotlin/eventDemo/contexts/auth/application/eventStores/UserEventStoreRepository.kt rename to backend/src/main/kotlin/eventDemo/contexts/auth/application/eventStores/UserEventStoreRepository.kt index 62f64f3..65513e8 100644 --- a/src/main/kotlin/eventDemo/contexts/auth/application/eventStores/UserEventStoreRepository.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/auth/application/eventStores/UserEventStoreRepository.kt @@ -2,7 +2,7 @@ package eventDemo.contexts.auth.application.eventStores import eventDemo.contexts.auth.application.ports.UserEventStore import eventDemo.contexts.auth.domain.User -import eventDemo.sharedKernel.UserId +import eventDemo.shared.ids.UserId class UserEventStoreRepository( val eventStore: UserEventStore, diff --git a/src/main/kotlin/eventDemo/contexts/auth/application/eventStores/UserRepository.kt b/backend/src/main/kotlin/eventDemo/contexts/auth/application/eventStores/UserRepository.kt similarity index 83% rename from src/main/kotlin/eventDemo/contexts/auth/application/eventStores/UserRepository.kt rename to backend/src/main/kotlin/eventDemo/contexts/auth/application/eventStores/UserRepository.kt index 4f36eb1..0c835c4 100644 --- a/src/main/kotlin/eventDemo/contexts/auth/application/eventStores/UserRepository.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/auth/application/eventStores/UserRepository.kt @@ -1,7 +1,7 @@ package eventDemo.contexts.auth.application.eventStores import eventDemo.contexts.auth.domain.User -import eventDemo.sharedKernel.UserId +import eventDemo.shared.ids.UserId interface UserRepository { fun get(id: UserId): User? diff --git a/src/main/kotlin/eventDemo/contexts/auth/application/ports/UserEventStore.kt b/backend/src/main/kotlin/eventDemo/contexts/auth/application/ports/UserEventStore.kt similarity index 85% rename from src/main/kotlin/eventDemo/contexts/auth/application/ports/UserEventStore.kt rename to backend/src/main/kotlin/eventDemo/contexts/auth/application/ports/UserEventStore.kt index e576aad..0f6cdf9 100644 --- a/src/main/kotlin/eventDemo/contexts/auth/application/ports/UserEventStore.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/auth/application/ports/UserEventStore.kt @@ -2,6 +2,6 @@ package eventDemo.contexts.auth.application.ports import eventDemo.contexts.auth.domain.events.UserEvent import eventDemo.libs.eventSource.eventStore.EventStore -import eventDemo.sharedKernel.UserId +import eventDemo.shared.ids.UserId interface UserEventStore : EventStore diff --git a/src/main/kotlin/eventDemo/contexts/auth/application/ports/UserProjectionRepository.kt b/backend/src/main/kotlin/eventDemo/contexts/auth/application/ports/UserProjectionRepository.kt similarity index 100% rename from src/main/kotlin/eventDemo/contexts/auth/application/ports/UserProjectionRepository.kt rename to backend/src/main/kotlin/eventDemo/contexts/auth/application/ports/UserProjectionRepository.kt diff --git a/src/main/kotlin/eventDemo/contexts/auth/domain/User.kt b/backend/src/main/kotlin/eventDemo/contexts/auth/domain/User.kt similarity index 96% rename from src/main/kotlin/eventDemo/contexts/auth/domain/User.kt rename to backend/src/main/kotlin/eventDemo/contexts/auth/domain/User.kt index b818559..6c123c0 100644 --- a/src/main/kotlin/eventDemo/contexts/auth/domain/User.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/auth/domain/User.kt @@ -2,7 +2,7 @@ package eventDemo.contexts.auth.domain import eventDemo.contexts.auth.domain.events.NewUserCreatedEvent import eventDemo.contexts.auth.domain.events.UserEvent -import eventDemo.sharedKernel.UserId +import eventDemo.shared.ids.UserId import kotlinx.serialization.Serializable @Serializable diff --git a/src/main/kotlin/eventDemo/contexts/auth/domain/events/NewUserCreatedEvent.kt b/backend/src/main/kotlin/eventDemo/contexts/auth/domain/events/NewUserCreatedEvent.kt similarity index 84% rename from src/main/kotlin/eventDemo/contexts/auth/domain/events/NewUserCreatedEvent.kt rename to backend/src/main/kotlin/eventDemo/contexts/auth/domain/events/NewUserCreatedEvent.kt index a269cbc..b3f14d0 100644 --- a/src/main/kotlin/eventDemo/contexts/auth/domain/events/NewUserCreatedEvent.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/auth/domain/events/NewUserCreatedEvent.kt @@ -1,7 +1,7 @@ package eventDemo.contexts.auth.domain.events -import eventDemo.libs.eventSource.EventId -import eventDemo.sharedKernel.UserId +import eventDemo.shared.ids.EventId +import eventDemo.shared.ids.UserId import kotlinx.datetime.Clock import kotlinx.datetime.Instant import kotlinx.serialization.Serializable diff --git a/src/main/kotlin/eventDemo/contexts/auth/domain/events/UserEvent.kt b/backend/src/main/kotlin/eventDemo/contexts/auth/domain/events/UserEvent.kt similarity index 83% rename from src/main/kotlin/eventDemo/contexts/auth/domain/events/UserEvent.kt rename to backend/src/main/kotlin/eventDemo/contexts/auth/domain/events/UserEvent.kt index b3913a6..b1e3764 100644 --- a/src/main/kotlin/eventDemo/contexts/auth/domain/events/UserEvent.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/auth/domain/events/UserEvent.kt @@ -1,7 +1,7 @@ package eventDemo.contexts.auth.domain.events import eventDemo.libs.eventSource.Event -import eventDemo.sharedKernel.UserId +import eventDemo.shared.ids.UserId import kotlinx.serialization.Serializable @Serializable diff --git a/src/main/kotlin/eventDemo/contexts/auth/infrastructure/HashPassword.kt b/backend/src/main/kotlin/eventDemo/contexts/auth/infrastructure/HashPassword.kt similarity index 100% rename from src/main/kotlin/eventDemo/contexts/auth/infrastructure/HashPassword.kt rename to backend/src/main/kotlin/eventDemo/contexts/auth/infrastructure/HashPassword.kt diff --git a/src/main/kotlin/eventDemo/contexts/auth/infrastructure/configure/ConfigureAuth.kt b/backend/src/main/kotlin/eventDemo/contexts/auth/infrastructure/configure/ConfigureAuth.kt similarity index 100% rename from src/main/kotlin/eventDemo/contexts/auth/infrastructure/configure/ConfigureAuth.kt rename to backend/src/main/kotlin/eventDemo/contexts/auth/infrastructure/configure/ConfigureAuth.kt diff --git a/src/main/kotlin/eventDemo/contexts/auth/infrastructure/configure/ConfigureAuthDI.kt b/backend/src/main/kotlin/eventDemo/contexts/auth/infrastructure/configure/ConfigureAuthDI.kt similarity index 100% rename from src/main/kotlin/eventDemo/contexts/auth/infrastructure/configure/ConfigureAuthDI.kt rename to backend/src/main/kotlin/eventDemo/contexts/auth/infrastructure/configure/ConfigureAuthDI.kt diff --git a/src/main/kotlin/eventDemo/contexts/auth/infrastructure/configure/ConfigureAuthRoutes.kt b/backend/src/main/kotlin/eventDemo/contexts/auth/infrastructure/configure/ConfigureAuthRoutes.kt similarity index 100% rename from src/main/kotlin/eventDemo/contexts/auth/infrastructure/configure/ConfigureAuthRoutes.kt rename to backend/src/main/kotlin/eventDemo/contexts/auth/infrastructure/configure/ConfigureAuthRoutes.kt diff --git a/src/main/kotlin/eventDemo/contexts/auth/infrastructure/configure/ConfigureKtorAuth.kt b/backend/src/main/kotlin/eventDemo/contexts/auth/infrastructure/configure/ConfigureKtorAuth.kt similarity index 97% rename from src/main/kotlin/eventDemo/contexts/auth/infrastructure/configure/ConfigureKtorAuth.kt rename to backend/src/main/kotlin/eventDemo/contexts/auth/infrastructure/configure/ConfigureKtorAuth.kt index af9159c..0bed250 100644 --- a/src/main/kotlin/eventDemo/contexts/auth/infrastructure/configure/ConfigureKtorAuth.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/auth/infrastructure/configure/ConfigureKtorAuth.kt @@ -5,7 +5,7 @@ import com.auth0.jwt.algorithms.Algorithm import eventDemo.configuration.configuration import eventDemo.contexts.auth.domain.User import eventDemo.contexts.auth.infrastructure.persistence.projection.UserProjection -import eventDemo.sharedKernel.UserId +import eventDemo.shared.ids.UserId import io.ktor.http.HttpStatusCode import io.ktor.server.application.Application import io.ktor.server.auth.authentication diff --git a/src/main/kotlin/eventDemo/contexts/auth/infrastructure/persistence/eventStore/UserEventStoreInMemory.kt b/backend/src/main/kotlin/eventDemo/contexts/auth/infrastructure/persistence/eventStore/UserEventStoreInMemory.kt similarity index 92% rename from src/main/kotlin/eventDemo/contexts/auth/infrastructure/persistence/eventStore/UserEventStoreInMemory.kt rename to backend/src/main/kotlin/eventDemo/contexts/auth/infrastructure/persistence/eventStore/UserEventStoreInMemory.kt index f0248c0..4203345 100644 --- a/src/main/kotlin/eventDemo/contexts/auth/infrastructure/persistence/eventStore/UserEventStoreInMemory.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/auth/infrastructure/persistence/eventStore/UserEventStoreInMemory.kt @@ -4,7 +4,7 @@ import eventDemo.contexts.auth.application.ports.UserEventStore import eventDemo.contexts.auth.domain.events.UserEvent import eventDemo.libs.eventSource.eventStore.EventStore import eventDemo.libs.eventSource.eventStore.EventStoreInMemory -import eventDemo.sharedKernel.UserId +import eventDemo.shared.ids.UserId /** * A stream to publish and read the user events. diff --git a/src/main/kotlin/eventDemo/contexts/auth/infrastructure/persistence/eventStore/UserEventStoreInPostgresql.kt b/backend/src/main/kotlin/eventDemo/contexts/auth/infrastructure/persistence/eventStore/UserEventStoreInPostgresql.kt similarity index 94% rename from src/main/kotlin/eventDemo/contexts/auth/infrastructure/persistence/eventStore/UserEventStoreInPostgresql.kt rename to backend/src/main/kotlin/eventDemo/contexts/auth/infrastructure/persistence/eventStore/UserEventStoreInPostgresql.kt index a82f19f..db15f21 100644 --- a/src/main/kotlin/eventDemo/contexts/auth/infrastructure/persistence/eventStore/UserEventStoreInPostgresql.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/auth/infrastructure/persistence/eventStore/UserEventStoreInPostgresql.kt @@ -4,7 +4,7 @@ import eventDemo.contexts.auth.application.ports.UserEventStore import eventDemo.contexts.auth.domain.events.UserEvent import eventDemo.libs.eventSource.eventStore.EventStore import eventDemo.libs.eventSource.eventStore.EventStoreInPostgresql -import eventDemo.sharedKernel.UserId +import eventDemo.shared.ids.UserId import kotlinx.serialization.json.Json import javax.sql.DataSource diff --git a/src/main/kotlin/eventDemo/contexts/auth/infrastructure/persistence/projection/UserProjection.kt b/backend/src/main/kotlin/eventDemo/contexts/auth/infrastructure/persistence/projection/UserProjection.kt similarity index 81% rename from src/main/kotlin/eventDemo/contexts/auth/infrastructure/persistence/projection/UserProjection.kt rename to backend/src/main/kotlin/eventDemo/contexts/auth/infrastructure/persistence/projection/UserProjection.kt index 310d2f6..4fd3bdd 100644 --- a/src/main/kotlin/eventDemo/contexts/auth/infrastructure/persistence/projection/UserProjection.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/auth/infrastructure/persistence/projection/UserProjection.kt @@ -1,6 +1,6 @@ package eventDemo.contexts.auth.infrastructure.persistence.projection -import eventDemo.sharedKernel.UserId +import eventDemo.shared.ids.UserId data class UserProjection( val id: UserId, diff --git a/src/main/kotlin/eventDemo/contexts/auth/infrastructure/persistence/projection/UserProjectionRepositoryInPostgresql.kt b/backend/src/main/kotlin/eventDemo/contexts/auth/infrastructure/persistence/projection/UserProjectionRepositoryInPostgresql.kt similarity index 88% rename from src/main/kotlin/eventDemo/contexts/auth/infrastructure/persistence/projection/UserProjectionRepositoryInPostgresql.kt rename to backend/src/main/kotlin/eventDemo/contexts/auth/infrastructure/persistence/projection/UserProjectionRepositoryInPostgresql.kt index 0246234..a3c2c76 100644 --- a/src/main/kotlin/eventDemo/contexts/auth/infrastructure/persistence/projection/UserProjectionRepositoryInPostgresql.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/auth/infrastructure/persistence/projection/UserProjectionRepositoryInPostgresql.kt @@ -3,9 +3,10 @@ package eventDemo.contexts.auth.infrastructure.persistence.projection import eventDemo.contexts.auth.application.ports.UserProjectionRepository import eventDemo.contexts.auth.infrastructure.checkPassword import eventDemo.contexts.auth.infrastructure.hashPassword -import eventDemo.sharedKernel.UserId -import java.util.UUID +import eventDemo.shared.ids.UserId import javax.sql.DataSource +import kotlin.uuid.Uuid +import kotlin.uuid.toJavaUuid class UserProjectionRepositoryInPostgresql( val dataSource: DataSource, @@ -24,7 +25,7 @@ class UserProjectionRepositoryInPostgresql( }.use { resultSet -> if (resultSet.next()) { UserProjection( - id = UserId(UUID.fromString(resultSet.getString("id"))), + id = UserId(Uuid.parse(resultSet.getString("id"))), username = resultSet.getString("username"), password = resultSet.getString("password"), ) @@ -42,7 +43,7 @@ class UserProjectionRepositoryInPostgresql( values (?, ?) """.trimIndent(), ).use { - it.setObject(1, user.id) + it.setObject(1, user.id.id.toJavaUuid()) it.setString(2, user.username) it.executeUpdate() } diff --git a/src/main/kotlin/eventDemo/contexts/auth/infrastructure/rest/LoginRoute.kt b/backend/src/main/kotlin/eventDemo/contexts/auth/infrastructure/rest/LoginRoute.kt similarity index 100% rename from src/main/kotlin/eventDemo/contexts/auth/infrastructure/rest/LoginRoute.kt rename to backend/src/main/kotlin/eventDemo/contexts/auth/infrastructure/rest/LoginRoute.kt diff --git a/src/main/kotlin/eventDemo/contexts/auth/infrastructure/rest/UserCreateRoute.kt b/backend/src/main/kotlin/eventDemo/contexts/auth/infrastructure/rest/UserCreateRoute.kt similarity index 100% rename from src/main/kotlin/eventDemo/contexts/auth/infrastructure/rest/UserCreateRoute.kt rename to backend/src/main/kotlin/eventDemo/contexts/auth/infrastructure/rest/UserCreateRoute.kt diff --git a/src/main/kotlin/eventDemo/contexts/game/application/channels/GameChannelsSubscriber.kt b/backend/src/main/kotlin/eventDemo/contexts/game/application/channels/GameChannelsSubscriber.kt similarity index 82% rename from src/main/kotlin/eventDemo/contexts/game/application/channels/GameChannelsSubscriber.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/application/channels/GameChannelsSubscriber.kt index 2c205ff..8f0f993 100644 --- a/src/main/kotlin/eventDemo/contexts/game/application/channels/GameChannelsSubscriber.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/application/channels/GameChannelsSubscriber.kt @@ -1,11 +1,11 @@ package eventDemo.contexts.game.application.channels -import eventDemo.contexts.game.application.command.models.GameCommand import eventDemo.contexts.game.application.notification.CommandSubscriber import eventDemo.contexts.game.application.notification.EventToNotificationSubscriber -import eventDemo.contexts.game.application.notification.models.Notification -import eventDemo.contexts.game.domain.game.GameId -import eventDemo.sharedKernel.UserId +import eventDemo.shared.game.command.GameCommand +import eventDemo.shared.game.notification.Notification +import eventDemo.shared.ids.GameId +import eventDemo.shared.ids.UserId import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.channels.ReceiveChannel import kotlinx.coroutines.channels.SendChannel diff --git a/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/CommandException.kt b/backend/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/CommandException.kt similarity index 100% rename from src/main/kotlin/eventDemo/contexts/game/application/command/handlers/CommandException.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/CommandException.kt diff --git a/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/GameCommandHandlerDispatcher.kt b/backend/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/GameCommandHandlerDispatcher.kt similarity index 68% rename from src/main/kotlin/eventDemo/contexts/game/application/command/handlers/GameCommandHandlerDispatcher.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/GameCommandHandlerDispatcher.kt index 2fc3068..1018c52 100644 --- a/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/GameCommandHandlerDispatcher.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/GameCommandHandlerDispatcher.kt @@ -1,11 +1,11 @@ package eventDemo.contexts.game.application.command.handlers -import eventDemo.contexts.game.application.command.models.GameCommand -import eventDemo.contexts.game.application.command.models.JoinTheGameCommand -import eventDemo.contexts.game.application.command.models.PlayCardCommand -import eventDemo.contexts.game.application.command.models.ReadyToPlayCommand -import eventDemo.contexts.game.application.command.models.TakeCartFromDrawPileCommand -import eventDemo.contexts.game.domain.game.GameId +import eventDemo.shared.game.command.GameCommand +import eventDemo.shared.game.command.JoinTheGameCommand +import eventDemo.shared.game.command.PlayCardCommand +import eventDemo.shared.game.command.ReadyToPlayCommand +import eventDemo.shared.game.command.TakeCartFromDrawPileCommand +import eventDemo.shared.ids.GameId import java.util.Collections class GameCommandHandlerDispatcher( diff --git a/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/GameEventManager.kt b/backend/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/GameEventManager.kt similarity index 94% rename from src/main/kotlin/eventDemo/contexts/game/application/command/handlers/GameEventManager.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/GameEventManager.kt index f829a33..703ee2a 100644 --- a/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/GameEventManager.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/GameEventManager.kt @@ -1,12 +1,12 @@ package eventDemo.contexts.game.application.command.handlers -import eventDemo.contexts.game.application.command.models.GameCommand import eventDemo.contexts.game.application.eventStores.GameRepository import eventDemo.contexts.game.application.ports.GameEventBus import eventDemo.contexts.game.domain.events.GameEvent import eventDemo.contexts.game.domain.game.gameState.Game -import eventDemo.libs.command.Command import eventDemo.libs.eventSource.eventStore.VersionConflictException +import eventDemo.shared.command.Command +import eventDemo.shared.game.command.GameCommand import io.github.oshai.kotlinlogging.KotlinLogging import kotlin.reflect.KClass diff --git a/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/JoinTheGameHandler.kt b/backend/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/JoinTheGameHandler.kt similarity index 93% rename from src/main/kotlin/eventDemo/contexts/game/application/command/handlers/JoinTheGameHandler.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/JoinTheGameHandler.kt index 68fb8d7..08dce48 100644 --- a/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/JoinTheGameHandler.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/JoinTheGameHandler.kt @@ -1,10 +1,10 @@ package eventDemo.contexts.game.application.command.handlers import eventDemo.contexts.auth.application.eventStores.UserRepository -import eventDemo.contexts.game.application.command.models.JoinTheGameCommand import eventDemo.contexts.game.application.eventStores.GameRepository import eventDemo.contexts.game.application.ports.GameEventBus import eventDemo.contexts.game.domain.game.gameState.GameCreated +import eventDemo.shared.game.command.JoinTheGameCommand /** * A command to perform an action to play a new card diff --git a/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/PlayCardHandler.kt b/backend/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/PlayCardHandler.kt similarity index 91% rename from src/main/kotlin/eventDemo/contexts/game/application/command/handlers/PlayCardHandler.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/PlayCardHandler.kt index 9a0c057..c03168a 100644 --- a/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/PlayCardHandler.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/PlayCardHandler.kt @@ -1,9 +1,9 @@ package eventDemo.contexts.game.application.command.handlers -import eventDemo.contexts.game.application.command.models.PlayCardCommand import eventDemo.contexts.game.application.eventStores.GameRepository import eventDemo.contexts.game.application.ports.GameEventBus import eventDemo.contexts.game.domain.game.gameState.GameStarted +import eventDemo.shared.game.command.PlayCardCommand /** * A command to perform an action to play a new card diff --git a/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/ReadyToPlayHandler.kt b/backend/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/ReadyToPlayHandler.kt similarity index 90% rename from src/main/kotlin/eventDemo/contexts/game/application/command/handlers/ReadyToPlayHandler.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/ReadyToPlayHandler.kt index 723e532..cd84063 100644 --- a/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/ReadyToPlayHandler.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/ReadyToPlayHandler.kt @@ -1,9 +1,9 @@ package eventDemo.contexts.game.application.command.handlers -import eventDemo.contexts.game.application.command.models.ReadyToPlayCommand import eventDemo.contexts.game.application.eventStores.GameRepository import eventDemo.contexts.game.application.ports.GameEventBus import eventDemo.contexts.game.domain.game.gameState.GameCreated +import eventDemo.shared.game.command.ReadyToPlayCommand /** * A command to set as ready to play diff --git a/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/TakeCartFromDrawPileHandler.kt b/backend/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/TakeCartFromDrawPileHandler.kt similarity index 90% rename from src/main/kotlin/eventDemo/contexts/game/application/command/handlers/TakeCartFromDrawPileHandler.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/TakeCartFromDrawPileHandler.kt index b35b8e3..39a0e1d 100644 --- a/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/TakeCartFromDrawPileHandler.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/application/command/handlers/TakeCartFromDrawPileHandler.kt @@ -1,9 +1,9 @@ package eventDemo.contexts.game.application.command.handlers -import eventDemo.contexts.game.application.command.models.TakeCartFromDrawPileCommand import eventDemo.contexts.game.application.eventStores.GameRepository import eventDemo.contexts.game.application.ports.GameEventBus import eventDemo.contexts.game.domain.game.gameState.GameStarted +import eventDemo.shared.game.command.TakeCartFromDrawPileCommand /** * A command to draw card on draw pile. diff --git a/src/main/kotlin/eventDemo/contexts/game/application/eventStores/GameEventStoreRepository.kt b/backend/src/main/kotlin/eventDemo/contexts/game/application/eventStores/GameEventStoreRepository.kt similarity index 93% rename from src/main/kotlin/eventDemo/contexts/game/application/eventStores/GameEventStoreRepository.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/application/eventStores/GameEventStoreRepository.kt index ac52915..e8e6701 100644 --- a/src/main/kotlin/eventDemo/contexts/game/application/eventStores/GameEventStoreRepository.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/application/eventStores/GameEventStoreRepository.kt @@ -1,9 +1,9 @@ package eventDemo.contexts.game.application.eventStores import eventDemo.contexts.game.application.ports.GameEventStore -import eventDemo.contexts.game.domain.game.GameId import eventDemo.contexts.game.domain.game.gameState.Game import eventDemo.libs.eventSource.eventStore.VersionConflictException +import eventDemo.shared.ids.GameId class GameEventStoreRepository( val eventStore: GameEventStore, diff --git a/src/main/kotlin/eventDemo/contexts/game/application/eventStores/GameRepository.kt b/backend/src/main/kotlin/eventDemo/contexts/game/application/eventStores/GameRepository.kt similarity index 92% rename from src/main/kotlin/eventDemo/contexts/game/application/eventStores/GameRepository.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/application/eventStores/GameRepository.kt index 66127e3..c8faf8b 100644 --- a/src/main/kotlin/eventDemo/contexts/game/application/eventStores/GameRepository.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/application/eventStores/GameRepository.kt @@ -1,10 +1,10 @@ package eventDemo.contexts.game.application.eventStores -import eventDemo.contexts.game.domain.game.GameId import eventDemo.contexts.game.domain.game.gameState.Game import eventDemo.contexts.game.domain.game.gameState.GameCreated import eventDemo.contexts.game.domain.game.gameState.GameInit import eventDemo.libs.eventSource.eventStore.VersionConflictException +import eventDemo.shared.ids.GameId interface GameRepository { fun get(id: GameId): Game? diff --git a/src/main/kotlin/eventDemo/contexts/game/application/logging/LoggingContext.kt b/backend/src/main/kotlin/eventDemo/contexts/game/application/logging/LoggingContext.kt similarity index 100% rename from src/main/kotlin/eventDemo/contexts/game/application/logging/LoggingContext.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/application/logging/LoggingContext.kt diff --git a/src/main/kotlin/eventDemo/contexts/game/application/logging/LoggingContextKeys.kt b/backend/src/main/kotlin/eventDemo/contexts/game/application/logging/LoggingContextKeys.kt similarity index 100% rename from src/main/kotlin/eventDemo/contexts/game/application/logging/LoggingContextKeys.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/application/logging/LoggingContextKeys.kt diff --git a/src/main/kotlin/eventDemo/contexts/game/application/notification/EventToNotification.kt b/backend/src/main/kotlin/eventDemo/contexts/game/application/notification/EventToNotification.kt similarity index 77% rename from src/main/kotlin/eventDemo/contexts/game/application/notification/EventToNotification.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/application/notification/EventToNotification.kt index e1458df..913606d 100644 --- a/src/main/kotlin/eventDemo/contexts/game/application/notification/EventToNotification.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/application/notification/EventToNotification.kt @@ -1,16 +1,5 @@ package eventDemo.contexts.game.application.notification -import eventDemo.contexts.game.application.notification.models.ItsTheTurnOfNotification -import eventDemo.contexts.game.application.notification.models.Notification -import eventDemo.contexts.game.application.notification.models.PilesShuffledNotification -import eventDemo.contexts.game.application.notification.models.PlayerAsJoinTheGameNotification -import eventDemo.contexts.game.application.notification.models.PlayerAsPlayACardNotification -import eventDemo.contexts.game.application.notification.models.PlayerHavePassNotification -import eventDemo.contexts.game.application.notification.models.PlayerWasReadyNotification -import eventDemo.contexts.game.application.notification.models.PlayerWinNotification -import eventDemo.contexts.game.application.notification.models.TheGameWasStartedNotification -import eventDemo.contexts.game.application.notification.models.WelcomeToTheGameNotification -import eventDemo.contexts.game.application.notification.models.YourNewCardNotification import eventDemo.contexts.game.domain.events.CardIsPlayedEvent import eventDemo.contexts.game.domain.events.DrawFilledWithDiscardEvent import eventDemo.contexts.game.domain.events.GameCreatedEvent @@ -23,7 +12,18 @@ import eventDemo.contexts.game.domain.events.PlayerReadyEvent import eventDemo.contexts.game.domain.events.PlayerWinEvent import eventDemo.contexts.game.domain.game.gameState.Game import eventDemo.contexts.game.domain.game.gameState.GameStarted -import eventDemo.sharedKernel.UserId +import eventDemo.shared.game.notification.ItsTheTurnOfNotification +import eventDemo.shared.game.notification.Notification +import eventDemo.shared.game.notification.PilesShuffledNotification +import eventDemo.shared.game.notification.PlayerAsJoinTheGameNotification +import eventDemo.shared.game.notification.PlayerAsPlayACardNotification +import eventDemo.shared.game.notification.PlayerHavePassNotification +import eventDemo.shared.game.notification.PlayerWasReadyNotification +import eventDemo.shared.game.notification.PlayerWinNotification +import eventDemo.shared.game.notification.TheGameWasStartedNotification +import eventDemo.shared.game.notification.WelcomeToTheGameNotification +import eventDemo.shared.game.notification.YourNewCardNotification +import eventDemo.shared.ids.UserId import io.github.oshai.kotlinlogging.KotlinLogging import io.github.oshai.kotlinlogging.withLoggingContext diff --git a/src/main/kotlin/eventDemo/contexts/game/application/notification/EventToNotificationSubscriber.kt b/backend/src/main/kotlin/eventDemo/contexts/game/application/notification/EventToNotificationSubscriber.kt similarity index 91% rename from src/main/kotlin/eventDemo/contexts/game/application/notification/EventToNotificationSubscriber.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/application/notification/EventToNotificationSubscriber.kt index 524a455..3496fc9 100644 --- a/src/main/kotlin/eventDemo/contexts/game/application/notification/EventToNotificationSubscriber.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/application/notification/EventToNotificationSubscriber.kt @@ -1,7 +1,6 @@ package eventDemo.contexts.game.application.notification import eventDemo.contexts.game.application.command.handlers.GameCommandHandlerDispatcher -import eventDemo.contexts.game.application.command.models.GameCommand import eventDemo.contexts.game.application.eventStores.GameRepository import eventDemo.contexts.game.application.logging.LoggingContextKeys.Command import eventDemo.contexts.game.application.logging.LoggingContextKeys.CurrentUserId @@ -9,12 +8,13 @@ import eventDemo.contexts.game.application.logging.LoggingContextKeys.Event import eventDemo.contexts.game.application.logging.LoggingContextKeys.Game import eventDemo.contexts.game.application.logging.LoggingContextKeys.Notification import eventDemo.contexts.game.application.logging.withLoggingContext -import eventDemo.contexts.game.application.notification.models.Notification import eventDemo.contexts.game.application.ports.GameEventBus -import eventDemo.contexts.game.domain.game.GameId import eventDemo.libs.bus.Bus import eventDemo.libs.command.CommandUnicityChecker -import eventDemo.sharedKernel.UserId +import eventDemo.shared.game.command.GameCommand +import eventDemo.shared.game.notification.Notification +import eventDemo.shared.ids.GameId +import eventDemo.shared.ids.UserId import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.Job diff --git a/src/main/kotlin/eventDemo/contexts/game/application/ports/GameEventBus.kt b/backend/src/main/kotlin/eventDemo/contexts/game/application/ports/GameEventBus.kt similarity index 100% rename from src/main/kotlin/eventDemo/contexts/game/application/ports/GameEventBus.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/application/ports/GameEventBus.kt diff --git a/src/main/kotlin/eventDemo/contexts/game/application/ports/GameEventStore.kt b/backend/src/main/kotlin/eventDemo/contexts/game/application/ports/GameEventStore.kt similarity index 81% rename from src/main/kotlin/eventDemo/contexts/game/application/ports/GameEventStore.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/application/ports/GameEventStore.kt index 4caf8ea..d575c20 100644 --- a/src/main/kotlin/eventDemo/contexts/game/application/ports/GameEventStore.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/application/ports/GameEventStore.kt @@ -1,7 +1,7 @@ package eventDemo.contexts.game.application.ports import eventDemo.contexts.game.domain.events.GameEvent -import eventDemo.contexts.game.domain.game.GameId import eventDemo.libs.eventSource.eventStore.EventStore +import eventDemo.shared.ids.GameId interface GameEventStore : EventStore diff --git a/src/main/kotlin/eventDemo/contexts/game/application/ports/GameListRepository.kt b/backend/src/main/kotlin/eventDemo/contexts/game/application/ports/GameListRepository.kt similarity index 71% rename from src/main/kotlin/eventDemo/contexts/game/application/ports/GameListRepository.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/application/ports/GameListRepository.kt index 23ea606..2975ff6 100644 --- a/src/main/kotlin/eventDemo/contexts/game/application/ports/GameListRepository.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/application/ports/GameListRepository.kt @@ -1,6 +1,6 @@ package eventDemo.domain.event.projection -import eventDemo.contexts.game.infrastructure.persistence.projections.models.GameList +import eventDemo.shared.game.projection.GameList interface GameListRepository { fun getList( diff --git a/src/main/kotlin/eventDemo/contexts/game/application/ports/GameProjectionBus.kt b/backend/src/main/kotlin/eventDemo/contexts/game/application/ports/GameProjectionBus.kt similarity index 58% rename from src/main/kotlin/eventDemo/contexts/game/application/ports/GameProjectionBus.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/application/ports/GameProjectionBus.kt index a5d20bf..4f76917 100644 --- a/src/main/kotlin/eventDemo/contexts/game/application/ports/GameProjectionBus.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/application/ports/GameProjectionBus.kt @@ -1,6 +1,6 @@ package eventDemo.contexts.game.application.ports -import eventDemo.contexts.game.infrastructure.persistence.projections.models.GameProjection import eventDemo.libs.bus.Bus +import eventDemo.shared.game.projection.GameProjection interface GameProjectionBus : Bus diff --git a/src/main/kotlin/eventDemo/contexts/game/application/projections/GameListBuilder.kt b/backend/src/main/kotlin/eventDemo/contexts/game/application/projections/GameListBuilder.kt similarity index 93% rename from src/main/kotlin/eventDemo/contexts/game/application/projections/GameListBuilder.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/application/projections/GameListBuilder.kt index 60d73fc..7bf65d6 100644 --- a/src/main/kotlin/eventDemo/contexts/game/application/projections/GameListBuilder.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/application/projections/GameListBuilder.kt @@ -9,7 +9,7 @@ import eventDemo.contexts.game.domain.events.NewPlayerEvent import eventDemo.contexts.game.domain.events.PlayerHaveDrawCardEvent import eventDemo.contexts.game.domain.events.PlayerReadyEvent import eventDemo.contexts.game.domain.events.PlayerWinEvent -import eventDemo.contexts.game.infrastructure.persistence.projections.models.GameList +import eventDemo.shared.game.projection.GameList fun GameList.applyEvent(event: GameEvent): GameList = when (event) { diff --git a/src/main/kotlin/eventDemo/contexts/game/application/reaction/ReactionListener.kt b/backend/src/main/kotlin/eventDemo/contexts/game/application/reaction/ReactionListener.kt similarity index 100% rename from src/main/kotlin/eventDemo/contexts/game/application/reaction/ReactionListener.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/application/reaction/ReactionListener.kt diff --git a/src/main/kotlin/eventDemo/contexts/game/domain/events/CardIsPlayedEvent.kt b/backend/src/main/kotlin/eventDemo/contexts/game/domain/events/CardIsPlayedEvent.kt similarity index 60% rename from src/main/kotlin/eventDemo/contexts/game/domain/events/CardIsPlayedEvent.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/domain/events/CardIsPlayedEvent.kt index 323b528..1f6bf61 100644 --- a/src/main/kotlin/eventDemo/contexts/game/domain/events/CardIsPlayedEvent.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/domain/events/CardIsPlayedEvent.kt @@ -1,15 +1,15 @@ package eventDemo.contexts.game.domain.events -import eventDemo.contexts.game.domain.game.Card -import eventDemo.contexts.game.domain.game.Card.Color -import eventDemo.contexts.game.domain.game.GameId -import eventDemo.contexts.game.domain.game.Player -import eventDemo.contexts.game.infrastructure.persistence.serializers.EventIdSerializer -import eventDemo.libs.eventSource.EventId +import eventDemo.shared.game.Card +import eventDemo.shared.game.Card.Color +import eventDemo.shared.game.Player +import eventDemo.shared.ids.EventId +import eventDemo.shared.ids.GameId +import eventDemo.shared.serializers.EventIdSerializer import kotlinx.datetime.Clock import kotlinx.datetime.Instant import kotlinx.serialization.Serializable -import java.util.UUID +import kotlin.uuid.Uuid /** * An [GameEvent] to represent a played card. @@ -24,7 +24,7 @@ data class CardIsPlayedEvent( ) : GameEvent, PlayerActionEvent { @Serializable(with = EventIdSerializer::class) - override val eventId: EventId = EventId(UUID.randomUUID()) + override val eventId: EventId = EventId(Uuid.random()) override val createdAt: Instant = Clock.System.now() val theColorCard get() = if (card is Card.CardWithColor) card.color else chosenColor diff --git a/src/main/kotlin/eventDemo/contexts/game/domain/events/DrawFilledWithDiscardEvent.kt b/backend/src/main/kotlin/eventDemo/contexts/game/domain/events/DrawFilledWithDiscardEvent.kt similarity index 58% rename from src/main/kotlin/eventDemo/contexts/game/domain/events/DrawFilledWithDiscardEvent.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/domain/events/DrawFilledWithDiscardEvent.kt index e4638a4..3f17bfa 100644 --- a/src/main/kotlin/eventDemo/contexts/game/domain/events/DrawFilledWithDiscardEvent.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/domain/events/DrawFilledWithDiscardEvent.kt @@ -1,14 +1,14 @@ package eventDemo.contexts.game.domain.events -import eventDemo.contexts.game.domain.game.DiscardPile -import eventDemo.contexts.game.domain.game.DrawPile -import eventDemo.contexts.game.domain.game.GameId -import eventDemo.contexts.game.infrastructure.persistence.serializers.EventIdSerializer -import eventDemo.libs.eventSource.EventId +import eventDemo.shared.game.DiscardPile +import eventDemo.shared.game.DrawPile +import eventDemo.shared.ids.EventId +import eventDemo.shared.ids.GameId +import eventDemo.shared.serializers.EventIdSerializer import kotlinx.datetime.Clock import kotlinx.datetime.Instant import kotlinx.serialization.Serializable -import java.util.UUID +import kotlin.uuid.Uuid /** * When the Pile are shuffled after the draw pille was empty @@ -21,6 +21,6 @@ class DrawFilledWithDiscardEvent( override val version: Int, ) : GameEvent { @Serializable(with = EventIdSerializer::class) - override val eventId: EventId = EventId(UUID.randomUUID()) + override val eventId: EventId = EventId(Uuid.random()) override val createdAt: Instant = Clock.System.now() } diff --git a/src/main/kotlin/eventDemo/contexts/game/domain/events/GameCreatedEvent.kt b/backend/src/main/kotlin/eventDemo/contexts/game/domain/events/GameCreatedEvent.kt similarity index 62% rename from src/main/kotlin/eventDemo/contexts/game/domain/events/GameCreatedEvent.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/domain/events/GameCreatedEvent.kt index f3f26bf..22c2ead 100644 --- a/src/main/kotlin/eventDemo/contexts/game/domain/events/GameCreatedEvent.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/domain/events/GameCreatedEvent.kt @@ -1,12 +1,12 @@ package eventDemo.contexts.game.domain.events -import eventDemo.contexts.game.domain.game.GameId -import eventDemo.contexts.game.infrastructure.persistence.serializers.EventIdSerializer -import eventDemo.libs.eventSource.EventId +import eventDemo.shared.ids.EventId +import eventDemo.shared.ids.GameId +import eventDemo.shared.serializers.EventIdSerializer import kotlinx.datetime.Clock import kotlinx.datetime.Instant import kotlinx.serialization.Serializable -import java.util.UUID +import kotlin.uuid.Uuid /** * This [GameEvent] is sent when all players are ready. @@ -17,6 +17,6 @@ data class GameCreatedEvent( override val version: Int, ) : GameEvent { @Serializable(with = EventIdSerializer::class) - override val eventId: EventId = EventId(UUID.randomUUID()) + override val eventId: EventId = EventId(Uuid.random()) override val createdAt: Instant = Clock.System.now() } diff --git a/src/main/kotlin/eventDemo/contexts/game/domain/events/GameEvent.kt b/backend/src/main/kotlin/eventDemo/contexts/game/domain/events/GameEvent.kt similarity index 60% rename from src/main/kotlin/eventDemo/contexts/game/domain/events/GameEvent.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/domain/events/GameEvent.kt index d97881a..7071219 100644 --- a/src/main/kotlin/eventDemo/contexts/game/domain/events/GameEvent.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/domain/events/GameEvent.kt @@ -1,10 +1,10 @@ package eventDemo.contexts.game.domain.events -import eventDemo.contexts.game.domain.game.GameId -import eventDemo.contexts.game.infrastructure.persistence.serializers.EventIdSerializer -import eventDemo.contexts.game.infrastructure.persistence.serializers.GameIdSerializer import eventDemo.libs.eventSource.Event -import eventDemo.libs.eventSource.EventId +import eventDemo.shared.ids.EventId +import eventDemo.shared.ids.GameId +import eventDemo.shared.serializers.EventIdSerializer +import eventDemo.shared.serializers.GameIdSerializer import kotlinx.serialization.Serializable /** diff --git a/src/main/kotlin/eventDemo/contexts/game/domain/events/GameStartedEvent.kt b/backend/src/main/kotlin/eventDemo/contexts/game/domain/events/GameStartedEvent.kt similarity index 53% rename from src/main/kotlin/eventDemo/contexts/game/domain/events/GameStartedEvent.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/domain/events/GameStartedEvent.kt index 6d3da65..3613799 100644 --- a/src/main/kotlin/eventDemo/contexts/game/domain/events/GameStartedEvent.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/domain/events/GameStartedEvent.kt @@ -1,17 +1,17 @@ package eventDemo.contexts.game.domain.events -import eventDemo.contexts.game.domain.game.DiscardPile -import eventDemo.contexts.game.domain.game.DrawPile -import eventDemo.contexts.game.domain.game.GameId -import eventDemo.contexts.game.domain.game.Player -import eventDemo.contexts.game.domain.game.PlayerHand -import eventDemo.contexts.game.infrastructure.persistence.serializers.EventIdSerializer -import eventDemo.contexts.game.infrastructure.persistence.serializers.PlayerIdSerializer -import eventDemo.libs.eventSource.EventId +import eventDemo.shared.game.DiscardPile +import eventDemo.shared.game.DrawPile +import eventDemo.shared.game.Player +import eventDemo.shared.game.PlayerHand +import eventDemo.shared.ids.EventId +import eventDemo.shared.ids.GameId +import eventDemo.shared.serializers.EventIdSerializer +import eventDemo.shared.serializers.PlayerIdSerializer import kotlinx.datetime.Clock import kotlinx.datetime.Instant import kotlinx.serialization.Serializable -import java.util.UUID +import kotlin.uuid.Uuid /** * This [GameEvent] is sent when all players are ready. @@ -27,6 +27,6 @@ data class GameStartedEvent( override val version: Int, ) : GameEvent { @Serializable(with = EventIdSerializer::class) - override val eventId: EventId = EventId(UUID.randomUUID()) + override val eventId: EventId = EventId(Uuid.random()) override val createdAt: Instant = Clock.System.now() } diff --git a/src/main/kotlin/eventDemo/contexts/game/domain/events/NewPlayerEvent.kt b/backend/src/main/kotlin/eventDemo/contexts/game/domain/events/NewPlayerEvent.kt similarity index 63% rename from src/main/kotlin/eventDemo/contexts/game/domain/events/NewPlayerEvent.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/domain/events/NewPlayerEvent.kt index ad39c41..b949664 100644 --- a/src/main/kotlin/eventDemo/contexts/game/domain/events/NewPlayerEvent.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/domain/events/NewPlayerEvent.kt @@ -1,13 +1,13 @@ package eventDemo.contexts.game.domain.events -import eventDemo.contexts.game.domain.game.GameId -import eventDemo.contexts.game.domain.game.Player -import eventDemo.contexts.game.infrastructure.persistence.serializers.EventIdSerializer -import eventDemo.libs.eventSource.EventId +import eventDemo.shared.game.Player +import eventDemo.shared.ids.EventId +import eventDemo.shared.ids.GameId +import eventDemo.shared.serializers.EventIdSerializer import kotlinx.datetime.Clock import kotlinx.datetime.Instant import kotlinx.serialization.Serializable -import java.util.UUID +import kotlin.uuid.Uuid /** * An [GameEvent] to represent a new player joining the game. @@ -22,6 +22,6 @@ data class NewPlayerEvent( override val playerId: Player.PlayerId get() = player.id @Serializable(with = EventIdSerializer::class) - override val eventId: EventId = EventId(UUID.randomUUID()) + override val eventId: EventId = EventId(Uuid.random()) override val createdAt: Instant = Clock.System.now() } diff --git a/src/main/kotlin/eventDemo/contexts/game/domain/events/PlayerActionEvent.kt b/backend/src/main/kotlin/eventDemo/contexts/game/domain/events/PlayerActionEvent.kt similarity index 78% rename from src/main/kotlin/eventDemo/contexts/game/domain/events/PlayerActionEvent.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/domain/events/PlayerActionEvent.kt index 9068b3f..8779c03 100644 --- a/src/main/kotlin/eventDemo/contexts/game/domain/events/PlayerActionEvent.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/domain/events/PlayerActionEvent.kt @@ -1,6 +1,6 @@ package eventDemo.contexts.game.domain.events -import eventDemo.contexts.game.domain.game.Player +import eventDemo.shared.game.Player import kotlinx.serialization.Serializable @Serializable diff --git a/src/main/kotlin/eventDemo/contexts/game/domain/events/PlayerHaveDrawCardEvent.kt b/backend/src/main/kotlin/eventDemo/contexts/game/domain/events/PlayerHaveDrawCardEvent.kt similarity index 56% rename from src/main/kotlin/eventDemo/contexts/game/domain/events/PlayerHaveDrawCardEvent.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/domain/events/PlayerHaveDrawCardEvent.kt index df769ab..8ab4fd6 100644 --- a/src/main/kotlin/eventDemo/contexts/game/domain/events/PlayerHaveDrawCardEvent.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/domain/events/PlayerHaveDrawCardEvent.kt @@ -1,15 +1,15 @@ package eventDemo.contexts.game.domain.events -import eventDemo.contexts.game.domain.game.Card -import eventDemo.contexts.game.domain.game.GameId -import eventDemo.contexts.game.domain.game.Player -import eventDemo.contexts.game.infrastructure.persistence.serializers.EventIdSerializer -import eventDemo.contexts.game.infrastructure.persistence.serializers.PlayerIdSerializer -import eventDemo.libs.eventSource.EventId +import eventDemo.shared.game.Card +import eventDemo.shared.game.Player +import eventDemo.shared.ids.EventId +import eventDemo.shared.ids.GameId +import eventDemo.shared.serializers.EventIdSerializer +import eventDemo.shared.serializers.PlayerIdSerializer import kotlinx.datetime.Clock import kotlinx.datetime.Instant import kotlinx.serialization.Serializable -import java.util.UUID +import kotlin.uuid.Uuid /** * This [GameEvent] is sent when a player can play. @@ -24,6 +24,6 @@ data class PlayerHaveDrawCardEvent( ) : GameEvent, PlayerActionEvent { @Serializable(with = EventIdSerializer::class) - override val eventId: EventId = EventId(UUID.randomUUID()) + override val eventId: EventId = EventId(Uuid.random()) override val createdAt: Instant = Clock.System.now() } diff --git a/src/main/kotlin/eventDemo/contexts/game/domain/events/PlayerReadyEvent.kt b/backend/src/main/kotlin/eventDemo/contexts/game/domain/events/PlayerReadyEvent.kt similarity index 57% rename from src/main/kotlin/eventDemo/contexts/game/domain/events/PlayerReadyEvent.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/domain/events/PlayerReadyEvent.kt index 45f9915..555ca09 100644 --- a/src/main/kotlin/eventDemo/contexts/game/domain/events/PlayerReadyEvent.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/domain/events/PlayerReadyEvent.kt @@ -1,14 +1,14 @@ package eventDemo.contexts.game.domain.events -import eventDemo.contexts.game.domain.game.GameId -import eventDemo.contexts.game.domain.game.Player -import eventDemo.contexts.game.infrastructure.persistence.serializers.EventIdSerializer -import eventDemo.contexts.game.infrastructure.persistence.serializers.PlayerIdSerializer -import eventDemo.libs.eventSource.EventId +import eventDemo.shared.game.Player +import eventDemo.shared.ids.EventId +import eventDemo.shared.ids.GameId +import eventDemo.shared.serializers.EventIdSerializer +import eventDemo.shared.serializers.PlayerIdSerializer import kotlinx.datetime.Clock import kotlinx.datetime.Instant import kotlinx.serialization.Serializable -import java.util.UUID +import kotlin.uuid.Uuid /** * This [GameEvent] is sent when a player is ready. @@ -22,6 +22,6 @@ data class PlayerReadyEvent( ) : GameEvent, PlayerActionEvent { @Serializable(with = EventIdSerializer::class) - override val eventId: EventId = EventId(UUID.randomUUID()) + override val eventId: EventId = EventId(Uuid.random()) override val createdAt: Instant = Clock.System.now() } diff --git a/src/main/kotlin/eventDemo/contexts/game/domain/events/PlayerWinEvent.kt b/backend/src/main/kotlin/eventDemo/contexts/game/domain/events/PlayerWinEvent.kt similarity index 57% rename from src/main/kotlin/eventDemo/contexts/game/domain/events/PlayerWinEvent.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/domain/events/PlayerWinEvent.kt index 4d9f3fd..3db1a51 100644 --- a/src/main/kotlin/eventDemo/contexts/game/domain/events/PlayerWinEvent.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/domain/events/PlayerWinEvent.kt @@ -1,14 +1,14 @@ package eventDemo.contexts.game.domain.events -import eventDemo.contexts.game.domain.game.GameId -import eventDemo.contexts.game.domain.game.Player -import eventDemo.contexts.game.infrastructure.persistence.serializers.EventIdSerializer -import eventDemo.contexts.game.infrastructure.persistence.serializers.PlayerIdSerializer -import eventDemo.libs.eventSource.EventId +import eventDemo.shared.game.Player +import eventDemo.shared.ids.EventId +import eventDemo.shared.ids.GameId +import eventDemo.shared.serializers.EventIdSerializer +import eventDemo.shared.serializers.PlayerIdSerializer import kotlinx.datetime.Clock import kotlinx.datetime.Instant import kotlinx.serialization.Serializable -import java.util.UUID +import kotlin.uuid.Uuid /** * This [GameEvent] is sent when a player is ready. @@ -22,6 +22,6 @@ data class PlayerWinEvent( ) : GameEvent, PlayerActionEvent { @Serializable(with = EventIdSerializer::class) - override val eventId: EventId = EventId(UUID.randomUUID()) + override val eventId: EventId = EventId(Uuid.random()) override val createdAt: Instant = Clock.System.now() } diff --git a/src/main/kotlin/eventDemo/contexts/game/domain/game/errors/GameException.kt b/backend/src/main/kotlin/eventDemo/contexts/game/domain/game/errors/GameException.kt similarity index 93% rename from src/main/kotlin/eventDemo/contexts/game/domain/game/errors/GameException.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/domain/game/errors/GameException.kt index d612630..b7cff6a 100644 --- a/src/main/kotlin/eventDemo/contexts/game/domain/game/errors/GameException.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/domain/game/errors/GameException.kt @@ -1,11 +1,11 @@ package eventDemo.contexts.game.domain.game.errors import eventDemo.contexts.game.domain.events.GameEvent -import eventDemo.contexts.game.domain.game.Card -import eventDemo.contexts.game.domain.game.Player -import eventDemo.contexts.game.domain.game.PlayerList import eventDemo.contexts.game.domain.game.gameState.Deck import eventDemo.contexts.game.domain.game.gameState.Game +import eventDemo.shared.game.Card +import eventDemo.shared.game.Player +import eventDemo.shared.game.PlayerList abstract class GameException( message: String, diff --git a/src/main/kotlin/eventDemo/contexts/game/domain/game/gameState/Game.kt b/backend/src/main/kotlin/eventDemo/contexts/game/domain/game/gameState/Game.kt similarity index 96% rename from src/main/kotlin/eventDemo/contexts/game/domain/game/gameState/Game.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/domain/game/gameState/Game.kt index 9df0565..3159ece 100644 --- a/src/main/kotlin/eventDemo/contexts/game/domain/game/gameState/Game.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/domain/game/gameState/Game.kt @@ -9,10 +9,10 @@ import eventDemo.contexts.game.domain.events.NewPlayerEvent import eventDemo.contexts.game.domain.events.PlayerHaveDrawCardEvent import eventDemo.contexts.game.domain.events.PlayerReadyEvent import eventDemo.contexts.game.domain.events.PlayerWinEvent -import eventDemo.contexts.game.domain.game.GameId -import eventDemo.contexts.game.domain.game.PlayerList import eventDemo.contexts.game.domain.game.errors.GameException import eventDemo.contexts.game.domain.game.errors.InconsistentEventVersionException +import eventDemo.shared.game.PlayerList +import eventDemo.shared.ids.GameId sealed interface Game { val aggregateId: GameId diff --git a/src/main/kotlin/eventDemo/contexts/game/domain/game/gameState/GameCreated.kt b/backend/src/main/kotlin/eventDemo/contexts/game/domain/game/gameState/GameCreated.kt similarity index 93% rename from src/main/kotlin/eventDemo/contexts/game/domain/game/gameState/GameCreated.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/domain/game/gameState/GameCreated.kt index 49ed688..ceccebf 100644 --- a/src/main/kotlin/eventDemo/contexts/game/domain/game/gameState/GameCreated.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/domain/game/gameState/GameCreated.kt @@ -4,18 +4,18 @@ import eventDemo.contexts.game.domain.events.GameEvent import eventDemo.contexts.game.domain.events.GameStartedEvent import eventDemo.contexts.game.domain.events.NewPlayerEvent import eventDemo.contexts.game.domain.events.PlayerReadyEvent -import eventDemo.contexts.game.domain.game.Card -import eventDemo.contexts.game.domain.game.DiscardPile -import eventDemo.contexts.game.domain.game.DrawPile -import eventDemo.contexts.game.domain.game.GameId -import eventDemo.contexts.game.domain.game.Player -import eventDemo.contexts.game.domain.game.PlayerHand -import eventDemo.contexts.game.domain.game.PlayerList import eventDemo.contexts.game.domain.game.errors.AllPlayerNotReadyException import eventDemo.contexts.game.domain.game.errors.DeckMissingCardsException import eventDemo.contexts.game.domain.game.errors.NeedMorePlayersToStartGameException import eventDemo.contexts.game.domain.game.errors.ThePlayerIsNotInTheGameException -import eventDemo.sharedKernel.UserId +import eventDemo.shared.game.Card +import eventDemo.shared.game.DiscardPile +import eventDemo.shared.game.DrawPile +import eventDemo.shared.game.Player +import eventDemo.shared.game.PlayerHand +import eventDemo.shared.game.PlayerList +import eventDemo.shared.ids.GameId +import eventDemo.shared.ids.UserId data class GameCreated( override val aggregateId: GameId, diff --git a/src/main/kotlin/eventDemo/contexts/game/domain/game/gameState/GameEnded.kt b/backend/src/main/kotlin/eventDemo/contexts/game/domain/game/gameState/GameEnded.kt similarity index 77% rename from src/main/kotlin/eventDemo/contexts/game/domain/game/gameState/GameEnded.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/domain/game/gameState/GameEnded.kt index 1c8361a..bcab343 100644 --- a/src/main/kotlin/eventDemo/contexts/game/domain/game/gameState/GameEnded.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/domain/game/gameState/GameEnded.kt @@ -1,9 +1,9 @@ package eventDemo.contexts.game.domain.game.gameState import eventDemo.contexts.game.domain.events.GameEvent -import eventDemo.contexts.game.domain.game.GameId -import eventDemo.contexts.game.domain.game.Player -import eventDemo.contexts.game.domain.game.PlayerList +import eventDemo.shared.game.Player +import eventDemo.shared.game.PlayerList +import eventDemo.shared.ids.GameId data class GameEnded( override val aggregateId: GameId, diff --git a/src/main/kotlin/eventDemo/contexts/game/domain/game/gameState/GameInit.kt b/backend/src/main/kotlin/eventDemo/contexts/game/domain/game/gameState/GameInit.kt similarity index 88% rename from src/main/kotlin/eventDemo/contexts/game/domain/game/gameState/GameInit.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/domain/game/gameState/GameInit.kt index 939d008..ddf02fc 100644 --- a/src/main/kotlin/eventDemo/contexts/game/domain/game/gameState/GameInit.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/domain/game/gameState/GameInit.kt @@ -2,8 +2,8 @@ package eventDemo.contexts.game.domain.game.gameState import eventDemo.contexts.game.domain.events.GameCreatedEvent import eventDemo.contexts.game.domain.events.GameEvent -import eventDemo.contexts.game.domain.game.GameId -import eventDemo.contexts.game.domain.game.PlayerList +import eventDemo.shared.game.PlayerList +import eventDemo.shared.ids.GameId data class GameInit( override val aggregateId: GameId, diff --git a/src/main/kotlin/eventDemo/contexts/game/domain/game/gameState/GameStarted.kt b/backend/src/main/kotlin/eventDemo/contexts/game/domain/game/gameState/GameStarted.kt similarity index 96% rename from src/main/kotlin/eventDemo/contexts/game/domain/game/gameState/GameStarted.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/domain/game/gameState/GameStarted.kt index 5e07153..f893f4a 100644 --- a/src/main/kotlin/eventDemo/contexts/game/domain/game/gameState/GameStarted.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/domain/game/gameState/GameStarted.kt @@ -6,13 +6,6 @@ import eventDemo.contexts.game.domain.events.GameEvent import eventDemo.contexts.game.domain.events.PlayerActionEvent import eventDemo.contexts.game.domain.events.PlayerHaveDrawCardEvent import eventDemo.contexts.game.domain.events.PlayerWinEvent -import eventDemo.contexts.game.domain.game.Card -import eventDemo.contexts.game.domain.game.Card.Color -import eventDemo.contexts.game.domain.game.DiscardPile -import eventDemo.contexts.game.domain.game.DrawPile -import eventDemo.contexts.game.domain.game.GameId -import eventDemo.contexts.game.domain.game.Player -import eventDemo.contexts.game.domain.game.PlayerList import eventDemo.contexts.game.domain.game.errors.InconsistentGameException import eventDemo.contexts.game.domain.game.errors.ItsNotTheTurnException import eventDemo.contexts.game.domain.game.errors.TheCardHasNoColorException @@ -22,6 +15,13 @@ import eventDemo.contexts.game.domain.game.errors.ThePlayerHasRemainingCardsExce import eventDemo.contexts.game.domain.game.errors.ThePlayerIsNotInTheGameException import eventDemo.contexts.game.domain.game.errors.ThePlayerMustPlayACardException import eventDemo.contexts.game.domain.game.gameState.Game.Direction +import eventDemo.shared.game.Card +import eventDemo.shared.game.Card.Color +import eventDemo.shared.game.DiscardPile +import eventDemo.shared.game.DrawPile +import eventDemo.shared.game.Player +import eventDemo.shared.game.PlayerList +import eventDemo.shared.ids.GameId fun PlayerList.nextPlayerTurn( lastPlayerId: Player.PlayerId, diff --git a/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/injections/application/ConfigureDIApplication.kt b/backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/injections/application/ConfigureDIApplication.kt similarity index 100% rename from src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/injections/application/ConfigureDIApplication.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/injections/application/ConfigureDIApplication.kt diff --git a/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/injections/application/ConfigureDICommandHandlers.kt b/backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/injections/application/ConfigureDICommandHandlers.kt similarity index 100% rename from src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/injections/application/ConfigureDICommandHandlers.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/injections/application/ConfigureDICommandHandlers.kt diff --git a/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/injections/infrastructure/ConfigureDIInfrastructure.kt b/backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/injections/infrastructure/ConfigureDIInfrastructure.kt similarity index 100% rename from src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/injections/infrastructure/ConfigureDIInfrastructure.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/injections/infrastructure/ConfigureDIInfrastructure.kt diff --git a/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/ktor/ConfigureHttp.kt b/backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/ktor/ConfigureHttp.kt similarity index 78% rename from src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/ktor/ConfigureHttp.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/ktor/ConfigureHttp.kt index 7620756..b23d7ff 100644 --- a/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/ktor/ConfigureHttp.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/ktor/ConfigureHttp.kt @@ -1,5 +1,6 @@ package eventDemo.contexts.game.infrastructure.configuration.ktor +import eventDemo.shared.http.HttpErrorBadRequest import io.ktor.http.HttpHeaders import io.ktor.http.HttpMethod import io.ktor.http.HttpStatusCode @@ -10,7 +11,6 @@ import io.ktor.server.plugins.cors.routing.CORS import io.ktor.server.plugins.statuspages.StatusPages import io.ktor.server.resources.Resources import io.ktor.server.response.respondText -import kotlinx.serialization.Serializable fun Application.configureHttpRouting() { install(CORS) { @@ -38,17 +38,3 @@ fun Application.configureHttpRouting() { class BadRequestException( val httpError: HttpErrorBadRequest, ) : Exception() - -@Serializable -class HttpErrorBadRequest( - val title: String = HttpStatusCode.BadRequest.description, - val invalidParams: List = emptyList(), -) { - val statusCode: Int = HttpStatusCode.BadRequest.value - - @Serializable - data class InvalidParam( - val name: String, - val reason: String, - ) -} diff --git a/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/ktor/ConfigureSerialization.kt b/backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/ktor/ConfigureSerialization.kt similarity index 56% rename from src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/ktor/ConfigureSerialization.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/ktor/ConfigureSerialization.kt index 89da12e..040f2c3 100644 --- a/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/ktor/ConfigureSerialization.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/ktor/ConfigureSerialization.kt @@ -1,21 +1,21 @@ package eventDemo.contexts.game.infrastructure.configuration.ktor -import eventDemo.contexts.game.domain.game.GameId -import eventDemo.contexts.game.domain.game.Player -import eventDemo.contexts.game.infrastructure.persistence.serializers.CommandIdSerializer -import eventDemo.contexts.game.infrastructure.persistence.serializers.EventIdSerializer -import eventDemo.contexts.game.infrastructure.persistence.serializers.GameIdSerializer -import eventDemo.contexts.game.infrastructure.persistence.serializers.PlayerIdSerializer -import eventDemo.libs.command.CommandId -import eventDemo.libs.eventSource.EventId -import eventDemo.libs.serializer.UUIDSerializer +import eventDemo.shared.game.Player +import eventDemo.shared.ids.CommandId +import eventDemo.shared.ids.EventId +import eventDemo.shared.ids.GameId +import eventDemo.shared.serializers.CommandIdSerializer +import eventDemo.shared.serializers.EventIdSerializer +import eventDemo.shared.serializers.GameIdSerializer +import eventDemo.shared.serializers.PlayerIdSerializer +import eventDemo.shared.serializers.UUIDSerializer import io.ktor.serialization.kotlinx.json.json import io.ktor.server.application.Application import io.ktor.server.application.install import io.ktor.server.plugins.contentnegotiation.ContentNegotiation import kotlinx.serialization.json.Json import kotlinx.serialization.modules.SerializersModule -import java.util.UUID +import kotlin.uuid.Uuid fun Application.configureSerialization() { install(ContentNegotiation) { @@ -29,7 +29,7 @@ fun defaultJsonSerializer(): Json = Json { serializersModule = SerializersModule { - contextual(UUID::class) { UUIDSerializer } + contextual(Uuid::class) { UUIDSerializer } contextual(GameId::class) { GameIdSerializer } contextual(EventId::class) { EventIdSerializer } contextual(CommandId::class) { CommandIdSerializer } diff --git a/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/ktor/ConfigureUno.kt b/backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/ktor/ConfigureUno.kt similarity index 100% rename from src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/ktor/ConfigureUno.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/ktor/ConfigureUno.kt diff --git a/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/ktor/ConfigureWebSockets.kt b/backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/ktor/ConfigureWebSockets.kt similarity index 100% rename from src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/ktor/ConfigureWebSockets.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/ktor/ConfigureWebSockets.kt diff --git a/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/ktor/DeclareHttpGameRoutes.kt b/backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/ktor/DeclareHttpGameRoutes.kt similarity index 100% rename from src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/ktor/DeclareHttpGameRoutes.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/ktor/DeclareHttpGameRoutes.kt diff --git a/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/ktor/DeclareWebSocketsGameRoute.kt b/backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/ktor/DeclareWebSocketsGameRoute.kt similarity index 100% rename from src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/ktor/DeclareWebSocketsGameRoute.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/ktor/DeclareWebSocketsGameRoute.kt diff --git a/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/listener/ConfigureGameListener.kt b/backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/listener/ConfigureGameListener.kt similarity index 100% rename from src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/listener/ConfigureGameListener.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/listener/ConfigureGameListener.kt diff --git a/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/listener/ConfigureReactionListener.kt b/backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/listener/ConfigureReactionListener.kt similarity index 100% rename from src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/listener/ConfigureReactionListener.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/configuration/listener/ConfigureReactionListener.kt diff --git a/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/eventBus/GameEventBusInMemory.kt b/backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/eventBus/GameEventBusInMemory.kt similarity index 100% rename from src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/eventBus/GameEventBusInMemory.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/eventBus/GameEventBusInMemory.kt diff --git a/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/eventBus/GameEventBusInRabbinMQ.kt b/backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/eventBus/GameEventBusInRabbinMQ.kt similarity index 100% rename from src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/eventBus/GameEventBusInRabbinMQ.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/eventBus/GameEventBusInRabbinMQ.kt diff --git a/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/eventStore/GameEventStoreInMemory.kt b/backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/eventStore/GameEventStoreInMemory.kt similarity index 90% rename from src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/eventStore/GameEventStoreInMemory.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/eventStore/GameEventStoreInMemory.kt index ea44440..cccc32e 100644 --- a/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/eventStore/GameEventStoreInMemory.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/eventStore/GameEventStoreInMemory.kt @@ -2,9 +2,9 @@ package eventDemo.contexts.game.infrastructure.persistence.eventStore import eventDemo.contexts.game.application.ports.GameEventStore import eventDemo.contexts.game.domain.events.GameEvent -import eventDemo.contexts.game.domain.game.GameId import eventDemo.libs.eventSource.eventStore.EventStore import eventDemo.libs.eventSource.eventStore.EventStoreInMemory +import eventDemo.shared.ids.GameId /** * A stream to publish and read the played card event. diff --git a/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/eventStore/GameEventStoreInPostgresql.kt b/backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/eventStore/GameEventStoreInPostgresql.kt similarity index 93% rename from src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/eventStore/GameEventStoreInPostgresql.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/eventStore/GameEventStoreInPostgresql.kt index a25e219..c52c788 100644 --- a/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/eventStore/GameEventStoreInPostgresql.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/eventStore/GameEventStoreInPostgresql.kt @@ -2,9 +2,9 @@ package eventDemo.contexts.game.infrastructure.persistence.eventStore import eventDemo.contexts.game.application.ports.GameEventStore import eventDemo.contexts.game.domain.events.GameEvent -import eventDemo.contexts.game.domain.game.GameId import eventDemo.libs.eventSource.eventStore.EventStore import eventDemo.libs.eventSource.eventStore.EventStoreInPostgresql +import eventDemo.shared.ids.GameId import kotlinx.serialization.json.Json import javax.sql.DataSource diff --git a/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/projections/GameListRepositoryInMemory.kt b/backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/projections/GameListRepositoryInMemory.kt similarity index 91% rename from src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/projections/GameListRepositoryInMemory.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/projections/GameListRepositoryInMemory.kt index 19ff6ae..899216d 100644 --- a/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/projections/GameListRepositoryInMemory.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/projections/GameListRepositoryInMemory.kt @@ -4,9 +4,9 @@ import eventDemo.contexts.game.application.ports.GameEventBus import eventDemo.contexts.game.application.ports.GameEventStore import eventDemo.contexts.game.application.ports.GameProjectionBus import eventDemo.contexts.game.application.projections.applyEvent -import eventDemo.contexts.game.domain.game.GameId -import eventDemo.contexts.game.infrastructure.persistence.projections.models.GameList import eventDemo.domain.event.projection.GameListRepository +import eventDemo.shared.game.projection.GameList +import eventDemo.shared.ids.GameId import io.github.oshai.kotlinlogging.withLoggingContext /** diff --git a/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/projections/bus/GameProjectionBusInMemory.kt b/backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/projections/bus/GameProjectionBusInMemory.kt similarity index 86% rename from src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/projections/bus/GameProjectionBusInMemory.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/projections/bus/GameProjectionBusInMemory.kt index 6dad40a..80360c4 100644 --- a/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/projections/bus/GameProjectionBusInMemory.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/projections/bus/GameProjectionBusInMemory.kt @@ -1,9 +1,9 @@ package eventDemo.contexts.game.infrastructure.persistence.projections.bus import eventDemo.contexts.game.application.ports.GameProjectionBus -import eventDemo.contexts.game.infrastructure.persistence.projections.models.GameProjection import eventDemo.libs.bus.Bus import eventDemo.libs.bus.BusInMemory +import eventDemo.shared.game.projection.GameProjection import java.util.UUID class GameProjectionBusInMemory : diff --git a/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/projections/bus/GameProjectionBusInRabbitMQ.kt b/backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/projections/bus/GameProjectionBusInRabbitMQ.kt similarity index 89% rename from src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/projections/bus/GameProjectionBusInRabbitMQ.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/projections/bus/GameProjectionBusInRabbitMQ.kt index 4f20398..580a9a8 100644 --- a/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/projections/bus/GameProjectionBusInRabbitMQ.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/projections/bus/GameProjectionBusInRabbitMQ.kt @@ -2,9 +2,9 @@ package eventDemo.contexts.game.infrastructure.persistence.projections.bus import com.rabbitmq.client.ConnectionFactory import eventDemo.contexts.game.application.ports.GameProjectionBus -import eventDemo.contexts.game.infrastructure.persistence.projections.models.GameProjection import eventDemo.libs.bus.Bus import eventDemo.libs.bus.BusInRabbitMQ +import eventDemo.shared.game.projection.GameProjection import kotlinx.serialization.json.Json import java.util.UUID diff --git a/src/main/kotlin/eventDemo/contexts/game/infrastructure/rest/GameListRoute.kt b/backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/rest/GameListRoute.kt similarity index 100% rename from src/main/kotlin/eventDemo/contexts/game/infrastructure/rest/GameListRoute.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/rest/GameListRoute.kt diff --git a/src/main/kotlin/eventDemo/contexts/game/infrastructure/rest/GetFullNotificationsRoute.kt b/backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/rest/GetFullNotificationsRoute.kt similarity index 89% rename from src/main/kotlin/eventDemo/contexts/game/infrastructure/rest/GetFullNotificationsRoute.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/rest/GetFullNotificationsRoute.kt index d1fd887..548d76c 100644 --- a/src/main/kotlin/eventDemo/contexts/game/infrastructure/rest/GetFullNotificationsRoute.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/rest/GetFullNotificationsRoute.kt @@ -3,8 +3,8 @@ package eventDemo.contexts.game.infrastructure.rest import eventDemo.contexts.game.application.eventStores.GameRepository import eventDemo.contexts.game.application.notification.toNotification import eventDemo.contexts.game.application.ports.GameEventStore -import eventDemo.contexts.game.domain.game.GameId -import eventDemo.contexts.game.infrastructure.persistence.serializers.GameIdSerializer +import eventDemo.shared.ids.GameId +import eventDemo.shared.serializers.GameIdSerializer import eventDemo.sharedKernel.currentUserId import io.ktor.http.HttpStatusCode import io.ktor.resources.Resource diff --git a/src/main/kotlin/eventDemo/contexts/game/infrastructure/websocket/GameCommandRouteWebSocket.kt b/backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/websocket/GameCommandRouteWebSocket.kt similarity index 85% rename from src/main/kotlin/eventDemo/contexts/game/infrastructure/websocket/GameCommandRouteWebSocket.kt rename to backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/websocket/GameCommandRouteWebSocket.kt index 81d66a8..d740fa9 100644 --- a/src/main/kotlin/eventDemo/contexts/game/infrastructure/websocket/GameCommandRouteWebSocket.kt +++ b/backend/src/main/kotlin/eventDemo/contexts/game/infrastructure/websocket/GameCommandRouteWebSocket.kt @@ -1,22 +1,22 @@ package eventDemo.contexts.game.infrastructure.websocket import eventDemo.contexts.game.application.channels.GameChannelsSubscriber -import eventDemo.contexts.game.domain.game.GameId import eventDemo.libs.helpers.fromFrameChannel import eventDemo.libs.helpers.toObjectChannel +import eventDemo.shared.ids.GameId import eventDemo.sharedKernel.currentUserId import io.ktor.server.auth.authenticate import io.ktor.server.routing.Route import io.ktor.server.websocket.webSocket import kotlinx.coroutines.DelicateCoroutinesApi -import java.util.UUID +import kotlin.uuid.Uuid @DelicateCoroutinesApi fun Route.gameWebSocket(channelSubscriber: GameChannelsSubscriber) { authenticate { webSocket("/games/{id}") { channelSubscriber.subscribePlayerToGameChannels( - gameId = GameId(UUID.fromString(call.parameters["id"]!!)), + gameId = GameId(Uuid.parse(call.parameters["id"]!!)), userId = call.currentUserId, incomingCommandChannel = toObjectChannel(incoming), sendNotificationChannel = fromFrameChannel(outgoing), diff --git a/src/main/kotlin/eventDemo/libs/bus/Bus.kt b/backend/src/main/kotlin/eventDemo/libs/bus/Bus.kt similarity index 100% rename from src/main/kotlin/eventDemo/libs/bus/Bus.kt rename to backend/src/main/kotlin/eventDemo/libs/bus/Bus.kt diff --git a/src/main/kotlin/eventDemo/libs/bus/BusInMemory.kt b/backend/src/main/kotlin/eventDemo/libs/bus/BusInMemory.kt similarity index 100% rename from src/main/kotlin/eventDemo/libs/bus/BusInMemory.kt rename to backend/src/main/kotlin/eventDemo/libs/bus/BusInMemory.kt diff --git a/src/main/kotlin/eventDemo/libs/bus/BusInRabbitMQ.kt b/backend/src/main/kotlin/eventDemo/libs/bus/BusInRabbitMQ.kt similarity index 100% rename from src/main/kotlin/eventDemo/libs/bus/BusInRabbitMQ.kt rename to backend/src/main/kotlin/eventDemo/libs/bus/BusInRabbitMQ.kt diff --git a/src/main/kotlin/eventDemo/libs/command/CommandUnicityChecker.kt b/backend/src/main/kotlin/eventDemo/libs/command/CommandUnicityChecker.kt similarity index 94% rename from src/main/kotlin/eventDemo/libs/command/CommandUnicityChecker.kt rename to backend/src/main/kotlin/eventDemo/libs/command/CommandUnicityChecker.kt index 7d7e6b1..51bdef3 100644 --- a/src/main/kotlin/eventDemo/libs/command/CommandUnicityChecker.kt +++ b/backend/src/main/kotlin/eventDemo/libs/command/CommandUnicityChecker.kt @@ -1,5 +1,7 @@ package eventDemo.libs.command +import eventDemo.shared.command.Command +import eventDemo.shared.ids.CommandId import kotlinx.datetime.Clock import kotlinx.datetime.Instant import java.util.concurrent.ConcurrentHashMap diff --git a/backend/src/main/kotlin/eventDemo/libs/eventSource/Event.kt b/backend/src/main/kotlin/eventDemo/libs/eventSource/Event.kt new file mode 100644 index 0000000..94282bd --- /dev/null +++ b/backend/src/main/kotlin/eventDemo/libs/eventSource/Event.kt @@ -0,0 +1,16 @@ +package eventDemo.libs.eventSource + +import eventDemo.shared.ids.AggregateId +import eventDemo.shared.ids.EventId +import kotlinx.datetime.Instant + +/** + * The basic interface for an Event + * @see eventDemo.libs.eventSource.eventStore.EventStream + */ +interface Event { + val eventId: EventId + val aggregateId: ID + val createdAt: Instant + val version: Int +} diff --git a/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStore.kt b/backend/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStore.kt similarity index 92% rename from src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStore.kt rename to backend/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStore.kt index b2e3108..0a50779 100644 --- a/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStore.kt +++ b/backend/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStore.kt @@ -1,7 +1,7 @@ package eventDemo.libs.eventSource.eventStore -import eventDemo.libs.eventSource.AggregateId import eventDemo.libs.eventSource.Event +import eventDemo.shared.ids.AggregateId import io.github.oshai.kotlinlogging.withLoggingContext interface EventStore, ID : AggregateId> { diff --git a/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStoreInMemory.kt b/backend/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStoreInMemory.kt similarity index 91% rename from src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStoreInMemory.kt rename to backend/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStoreInMemory.kt index ac85b99..5a5c21a 100644 --- a/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStoreInMemory.kt +++ b/backend/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStoreInMemory.kt @@ -1,7 +1,7 @@ package eventDemo.libs.eventSource.eventStore -import eventDemo.libs.eventSource.AggregateId import eventDemo.libs.eventSource.Event +import eventDemo.shared.ids.AggregateId import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentMap diff --git a/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStoreInPostgresql.kt b/backend/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStoreInPostgresql.kt similarity index 91% rename from src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStoreInPostgresql.kt rename to backend/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStoreInPostgresql.kt index 1dc2882..0f10ec6 100644 --- a/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStoreInPostgresql.kt +++ b/backend/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStoreInPostgresql.kt @@ -1,7 +1,7 @@ package eventDemo.libs.eventSource.eventStore -import eventDemo.libs.eventSource.AggregateId import eventDemo.libs.eventSource.Event +import eventDemo.shared.ids.AggregateId import javax.sql.DataSource class EventStoreInPostgresql, ID : AggregateId>( diff --git a/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStream.kt b/backend/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStream.kt similarity index 95% rename from src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStream.kt rename to backend/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStream.kt index faf9b2e..ad73f8b 100644 --- a/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStream.kt +++ b/backend/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStream.kt @@ -1,7 +1,7 @@ package eventDemo.libs.eventSource.eventStore -import eventDemo.libs.eventSource.AggregateId import eventDemo.libs.eventSource.Event +import eventDemo.shared.ids.AggregateId import io.github.oshai.kotlinlogging.withLoggingContext /** diff --git a/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStreamInMemory.kt b/backend/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStreamInMemory.kt similarity index 96% rename from src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStreamInMemory.kt rename to backend/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStreamInMemory.kt index 9b8428b..f7eefa7 100644 --- a/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStreamInMemory.kt +++ b/backend/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStreamInMemory.kt @@ -1,7 +1,7 @@ package eventDemo.libs.eventSource.eventStore -import eventDemo.libs.eventSource.AggregateId import eventDemo.libs.eventSource.Event +import eventDemo.shared.ids.AggregateId import io.github.oshai.kotlinlogging.KotlinLogging import java.util.Queue import java.util.concurrent.ConcurrentLinkedQueue diff --git a/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStreamInPostgresql.kt b/backend/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStreamInPostgresql.kt similarity index 91% rename from src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStreamInPostgresql.kt rename to backend/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStreamInPostgresql.kt index a41f768..1405577 100644 --- a/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStreamInPostgresql.kt +++ b/backend/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStreamInPostgresql.kt @@ -1,12 +1,13 @@ package eventDemo.libs.eventSource.eventStore -import eventDemo.libs.eventSource.AggregateId import eventDemo.libs.eventSource.Event +import eventDemo.shared.ids.AggregateId import io.github.oshai.kotlinlogging.KotlinLogging import io.github.oshai.kotlinlogging.withLoggingContext import org.postgresql.util.PGobject import org.postgresql.util.PSQLException import javax.sql.DataSource +import kotlin.uuid.toJavaUuid /** * An In-Memory implementation of an event stream. @@ -39,8 +40,8 @@ class EventStreamInPostgresql, ID : AggregateId>( on conflict (id) do nothing """.trimIndent(), ).use { - it.setObject(1, event.eventId.id) - it.setObject(2, event.aggregateId.id) + it.setObject(1, event.eventId.id.toJavaUuid()) + it.setObject(2, event.aggregateId.id.toJavaUuid()) it.setInt(3, event.version) it.setObject(4, PGJsonb(objectToString(event))) it.executeUpdate() @@ -69,7 +70,7 @@ class EventStreamInPostgresql, ID : AggregateId>( order by version asc """.trimIndent(), ).use { - it.setObject(1, aggregateId.id) + it.setObject(1, aggregateId.id.toJavaUuid()) it.executeQuery().use { resultSet -> buildSet { while (resultSet.next()) { @@ -95,7 +96,7 @@ class EventStreamInPostgresql, ID : AggregateId>( order by version asc """.trimIndent(), ).use { - it.setObject(1, aggregateId.id) + it.setObject(1, aggregateId.id.toJavaUuid()) it.executeQuery().use { resultSet -> resultSet.next() } @@ -116,7 +117,7 @@ class EventStreamInPostgresql, ID : AggregateId>( ).use { stmt -> stmt.setInt(1, version.first) stmt.setInt(2, version.last) - stmt.setObject(3, aggregateId.id) + stmt.setObject(3, aggregateId.id.toJavaUuid()) stmt.executeQuery().use { resultSet -> buildSet { while (resultSet.next()) { diff --git a/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStreamPublishException.kt b/backend/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStreamPublishException.kt similarity index 100% rename from src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStreamPublishException.kt rename to backend/src/main/kotlin/eventDemo/libs/eventSource/eventStore/EventStreamPublishException.kt diff --git a/src/main/kotlin/eventDemo/libs/helpers/FrameChannelConverter.kt b/backend/src/main/kotlin/eventDemo/libs/helpers/FrameChannelConverter.kt similarity index 100% rename from src/main/kotlin/eventDemo/libs/helpers/FrameChannelConverter.kt rename to backend/src/main/kotlin/eventDemo/libs/helpers/FrameChannelConverter.kt diff --git a/src/main/kotlin/eventDemo/libs/helpers/ListToRange.kt b/backend/src/main/kotlin/eventDemo/libs/helpers/ListToRange.kt similarity index 100% rename from src/main/kotlin/eventDemo/libs/helpers/ListToRange.kt rename to backend/src/main/kotlin/eventDemo/libs/helpers/ListToRange.kt diff --git a/src/main/kotlin/eventDemo/sharedKernel/GetUserIdCredentials.kt b/backend/src/main/kotlin/eventDemo/sharedKernel/GetUserIdCredentials.kt similarity index 68% rename from src/main/kotlin/eventDemo/sharedKernel/GetUserIdCredentials.kt rename to backend/src/main/kotlin/eventDemo/sharedKernel/GetUserIdCredentials.kt index 71098b0..bcead8d 100644 --- a/src/main/kotlin/eventDemo/sharedKernel/GetUserIdCredentials.kt +++ b/backend/src/main/kotlin/eventDemo/sharedKernel/GetUserIdCredentials.kt @@ -1,12 +1,13 @@ package eventDemo.sharedKernel +import eventDemo.shared.ids.UserId import io.ktor.server.application.ApplicationCall import io.ktor.server.auth.jwt.JWTPrincipal import io.ktor.server.auth.principal -import java.util.UUID +import kotlin.uuid.Uuid internal val ApplicationCall.currentUserId: UserId get() = principal()!!.run { - UserId(UUID.fromString(payload.getClaim("userid").asString())) + UserId(Uuid.parse(payload.getClaim("userid").asString())) } diff --git a/src/main/resources/application.conf b/backend/src/main/resources/application.conf similarity index 100% rename from src/main/resources/application.conf rename to backend/src/main/resources/application.conf diff --git a/src/main/resources/logback.xml b/backend/src/main/resources/logback.xml similarity index 100% rename from src/main/resources/logback.xml rename to backend/src/main/resources/logback.xml diff --git a/src/test/kotlin/eventDemo/Tag.kt b/backend/src/test/kotlin/eventDemo/Tag.kt similarity index 100% rename from src/test/kotlin/eventDemo/Tag.kt rename to backend/src/test/kotlin/eventDemo/Tag.kt diff --git a/src/test/kotlin/eventDemo/architecture/HexagonalArchitectureTest.kt b/backend/src/test/kotlin/eventDemo/architecture/HexagonalArchitectureTest.kt similarity index 100% rename from src/test/kotlin/eventDemo/architecture/HexagonalArchitectureTest.kt rename to backend/src/test/kotlin/eventDemo/architecture/HexagonalArchitectureTest.kt diff --git a/src/test/kotlin/eventDemo/contexts/auth/domain/UserTest.kt b/backend/src/test/kotlin/eventDemo/contexts/auth/domain/UserTest.kt similarity index 100% rename from src/test/kotlin/eventDemo/contexts/auth/domain/UserTest.kt rename to backend/src/test/kotlin/eventDemo/contexts/auth/domain/UserTest.kt diff --git a/src/test/kotlin/eventDemo/contexts/game/application/GameSimulationTest.kt b/backend/src/test/kotlin/eventDemo/contexts/game/application/GameSimulationTest.kt similarity index 93% rename from src/test/kotlin/eventDemo/contexts/game/application/GameSimulationTest.kt rename to backend/src/test/kotlin/eventDemo/contexts/game/application/GameSimulationTest.kt index a0cf0bf..80e067b 100644 --- a/src/test/kotlin/eventDemo/contexts/game/application/GameSimulationTest.kt +++ b/backend/src/test/kotlin/eventDemo/contexts/game/application/GameSimulationTest.kt @@ -4,20 +4,20 @@ import eventDemo.Tag import eventDemo.contexts.auth.application.eventStores.UserRepository import eventDemo.contexts.auth.domain.User import eventDemo.contexts.game.application.channels.GameChannelsSubscriber -import eventDemo.contexts.game.application.command.models.GameCommand import eventDemo.contexts.game.application.eventStores.GameRepository -import eventDemo.contexts.game.application.notification.models.ItsTheTurnOfNotification -import eventDemo.contexts.game.application.notification.models.Notification -import eventDemo.contexts.game.application.notification.models.PlayerAsJoinTheGameNotification -import eventDemo.contexts.game.application.notification.models.PlayerAsPlayACardNotification -import eventDemo.contexts.game.application.notification.models.PlayerWasReadyNotification -import eventDemo.contexts.game.application.notification.models.TheGameWasStartedNotification -import eventDemo.contexts.game.application.notification.models.WelcomeToTheGameNotification -import eventDemo.contexts.game.domain.game.Card -import eventDemo.contexts.game.domain.game.GameId import eventDemo.contexts.game.domain.game.gameState.Game import eventDemo.contexts.game.domain.game.gameState.GameStarted import eventDemo.contexts.game.domain.game.gameState.disableRandomForTest +import eventDemo.shared.game.Card +import eventDemo.shared.game.command.GameCommand +import eventDemo.shared.game.notification.ItsTheTurnOfNotification +import eventDemo.shared.game.notification.Notification +import eventDemo.shared.game.notification.PlayerAsJoinTheGameNotification +import eventDemo.shared.game.notification.PlayerAsPlayACardNotification +import eventDemo.shared.game.notification.PlayerWasReadyNotification +import eventDemo.shared.game.notification.TheGameWasStartedNotification +import eventDemo.shared.game.notification.WelcomeToTheGameNotification +import eventDemo.shared.ids.GameId import eventDemo.testHelpers.CreateGameWithCommandsInChannelsHelpers.createGameWithCommandsInChannels import eventDemo.testHelpers.CreateGameWithCommandsInChannelsHelpers.joinTheGame import eventDemo.testHelpers.CreateGameWithCommandsInChannelsHelpers.playCard diff --git a/src/test/kotlin/eventDemo/contexts/game/application/eventStore/GameEventStoreRepositoryTest.kt b/backend/src/test/kotlin/eventDemo/contexts/game/application/eventStore/GameEventStoreRepositoryTest.kt similarity index 98% rename from src/test/kotlin/eventDemo/contexts/game/application/eventStore/GameEventStoreRepositoryTest.kt rename to backend/src/test/kotlin/eventDemo/contexts/game/application/eventStore/GameEventStoreRepositoryTest.kt index f516afd..edeedc1 100644 --- a/src/test/kotlin/eventDemo/contexts/game/application/eventStore/GameEventStoreRepositoryTest.kt +++ b/backend/src/test/kotlin/eventDemo/contexts/game/application/eventStore/GameEventStoreRepositoryTest.kt @@ -6,7 +6,7 @@ import eventDemo.Tag import eventDemo.contexts.auth.application.eventStores.UserRepository import eventDemo.contexts.game.application.eventStores.GameEventStoreRepository import eventDemo.contexts.game.application.eventStores.GameRepository -import eventDemo.contexts.game.domain.game.GameId +import eventDemo.shared.ids.GameId import eventDemo.testHelpers.CreateGameWithCommandsHelpers import eventDemo.testHelpers.CreateGameWithCommandsHelpers.joinTheGame import eventDemo.testHelpers.createNewUser diff --git a/src/test/kotlin/eventDemo/contexts/game/application/notification/EventToNotificationSubscriberTest.kt b/backend/src/test/kotlin/eventDemo/contexts/game/application/notification/EventToNotificationSubscriberTest.kt similarity index 92% rename from src/test/kotlin/eventDemo/contexts/game/application/notification/EventToNotificationSubscriberTest.kt rename to backend/src/test/kotlin/eventDemo/contexts/game/application/notification/EventToNotificationSubscriberTest.kt index 8cd6bce..e871af7 100644 --- a/src/test/kotlin/eventDemo/contexts/game/application/notification/EventToNotificationSubscriberTest.kt +++ b/backend/src/test/kotlin/eventDemo/contexts/game/application/notification/EventToNotificationSubscriberTest.kt @@ -8,13 +8,13 @@ import eventDemo.contexts.game.application.command.handlers.JoinTheGameHandler import eventDemo.contexts.game.application.command.handlers.PlayCardHandler import eventDemo.contexts.game.application.command.handlers.ReadyToPlayHandler import eventDemo.contexts.game.application.command.handlers.TakeCartFromDrawPileHandler -import eventDemo.contexts.game.application.command.models.JoinTheGameCommand import eventDemo.contexts.game.application.eventStores.GameEventStoreRepository -import eventDemo.contexts.game.application.notification.models.Notification -import eventDemo.contexts.game.application.notification.models.WelcomeToTheGameNotification import eventDemo.contexts.game.infrastructure.persistence.eventBus.GameEventBusInMemory import eventDemo.contexts.game.infrastructure.persistence.eventStore.GameEventStoreInMemory -import eventDemo.sharedKernel.UserId +import eventDemo.shared.game.command.JoinTheGameCommand +import eventDemo.shared.game.notification.Notification +import eventDemo.shared.game.notification.WelcomeToTheGameNotification +import eventDemo.shared.ids.UserId import eventDemo.testHelpers.createNewUser import io.kotest.assertions.nondeterministic.eventually import io.kotest.core.spec.style.FunSpec diff --git a/src/test/kotlin/eventDemo/contexts/game/application/notification/ToNotificationTest.kt b/backend/src/test/kotlin/eventDemo/contexts/game/application/notification/ToNotificationTest.kt similarity index 88% rename from src/test/kotlin/eventDemo/contexts/game/application/notification/ToNotificationTest.kt rename to backend/src/test/kotlin/eventDemo/contexts/game/application/notification/ToNotificationTest.kt index be1f9a7..a1c5ef5 100644 --- a/src/test/kotlin/eventDemo/contexts/game/application/notification/ToNotificationTest.kt +++ b/backend/src/test/kotlin/eventDemo/contexts/game/application/notification/ToNotificationTest.kt @@ -1,29 +1,29 @@ package eventDemo.contexts.game.application.notification -import eventDemo.contexts.game.application.notification.models.ItsTheTurnOfNotification -import eventDemo.contexts.game.application.notification.models.PilesShuffledNotification -import eventDemo.contexts.game.application.notification.models.PlayerAsPlayACardNotification -import eventDemo.contexts.game.application.notification.models.PlayerHavePassNotification -import eventDemo.contexts.game.application.notification.models.PlayerWasReadyNotification -import eventDemo.contexts.game.application.notification.models.TheGameWasStartedNotification -import eventDemo.contexts.game.application.notification.models.WelcomeToTheGameNotification -import eventDemo.contexts.game.application.notification.models.YourNewCardNotification import eventDemo.contexts.game.domain.events.CardIsPlayedEvent import eventDemo.contexts.game.domain.events.DrawFilledWithDiscardEvent import eventDemo.contexts.game.domain.events.GameStartedEvent import eventDemo.contexts.game.domain.events.NewPlayerEvent import eventDemo.contexts.game.domain.events.PlayerHaveDrawCardEvent import eventDemo.contexts.game.domain.events.PlayerReadyEvent -import eventDemo.contexts.game.domain.game.Card -import eventDemo.contexts.game.domain.game.DiscardPile -import eventDemo.contexts.game.domain.game.DrawPile -import eventDemo.contexts.game.domain.game.GameId -import eventDemo.contexts.game.domain.game.Player -import eventDemo.contexts.game.domain.game.PlayerHand -import eventDemo.contexts.game.domain.game.PlayerList import eventDemo.contexts.game.domain.game.gameState.GameCreated import eventDemo.contexts.game.domain.game.gameState.GameStarted -import eventDemo.sharedKernel.UserId +import eventDemo.shared.game.Card +import eventDemo.shared.game.DiscardPile +import eventDemo.shared.game.DrawPile +import eventDemo.shared.game.Player +import eventDemo.shared.game.PlayerHand +import eventDemo.shared.game.PlayerList +import eventDemo.shared.game.notification.ItsTheTurnOfNotification +import eventDemo.shared.game.notification.PilesShuffledNotification +import eventDemo.shared.game.notification.PlayerAsPlayACardNotification +import eventDemo.shared.game.notification.PlayerHavePassNotification +import eventDemo.shared.game.notification.PlayerWasReadyNotification +import eventDemo.shared.game.notification.TheGameWasStartedNotification +import eventDemo.shared.game.notification.WelcomeToTheGameNotification +import eventDemo.shared.game.notification.YourNewCardNotification +import eventDemo.shared.ids.GameId +import eventDemo.shared.ids.UserId import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.shouldBe import org.junit.jupiter.api.assertInstanceOf diff --git a/src/test/kotlin/eventDemo/contexts/game/domain/game/PlayerHandTest.kt b/backend/src/test/kotlin/eventDemo/contexts/game/domain/game/PlayerHandTest.kt similarity index 82% rename from src/test/kotlin/eventDemo/contexts/game/domain/game/PlayerHandTest.kt rename to backend/src/test/kotlin/eventDemo/contexts/game/domain/game/PlayerHandTest.kt index f47d400..a4f536b 100644 --- a/src/test/kotlin/eventDemo/contexts/game/domain/game/PlayerHandTest.kt +++ b/backend/src/test/kotlin/eventDemo/contexts/game/domain/game/PlayerHandTest.kt @@ -1,5 +1,7 @@ package eventDemo.contexts.game.domain.game +import eventDemo.shared.game.Card +import eventDemo.shared.game.PlayerHand import eventDemo.testHelpers.act import eventDemo.testHelpers.arrange import eventDemo.testHelpers.assert @@ -39,8 +41,8 @@ class PlayerHandTest : }.assert { hand -> hand.size shouldBeExactly 2 assertInstanceOf>(hand.cards) - hand.cards.elementAt(0).number shouldBeExactly 1 - hand.cards.elementAt(1).number shouldBeExactly 2 + assertInstanceOf(hand.cards.elementAt(0)).number shouldBeExactly 1 + assertInstanceOf(hand.cards.elementAt(1)).number shouldBeExactly 2 } } }) diff --git a/src/test/kotlin/eventDemo/contexts/game/domain/game/gameState/GameStartedTest.kt b/backend/src/test/kotlin/eventDemo/contexts/game/domain/game/gameState/GameStartedTest.kt similarity index 96% rename from src/test/kotlin/eventDemo/contexts/game/domain/game/gameState/GameStartedTest.kt rename to backend/src/test/kotlin/eventDemo/contexts/game/domain/game/gameState/GameStartedTest.kt index c7fb713..f254d41 100644 --- a/src/test/kotlin/eventDemo/contexts/game/domain/game/gameState/GameStartedTest.kt +++ b/backend/src/test/kotlin/eventDemo/contexts/game/domain/game/gameState/GameStartedTest.kt @@ -4,15 +4,15 @@ import eventDemo.contexts.game.domain.events.CardIsPlayedEvent import eventDemo.contexts.game.domain.events.DrawFilledWithDiscardEvent import eventDemo.contexts.game.domain.events.PlayerHaveDrawCardEvent import eventDemo.contexts.game.domain.events.PlayerWinEvent -import eventDemo.contexts.game.domain.game.Card -import eventDemo.contexts.game.domain.game.DiscardPile -import eventDemo.contexts.game.domain.game.DrawPile -import eventDemo.contexts.game.domain.game.GameId -import eventDemo.contexts.game.domain.game.Player -import eventDemo.contexts.game.domain.game.PlayerHand -import eventDemo.contexts.game.domain.game.PlayerList import eventDemo.contexts.game.domain.game.gameState.Game.Direction -import eventDemo.sharedKernel.UserId +import eventDemo.shared.game.Card +import eventDemo.shared.game.DiscardPile +import eventDemo.shared.game.DrawPile +import eventDemo.shared.game.Player +import eventDemo.shared.game.PlayerHand +import eventDemo.shared.game.PlayerList +import eventDemo.shared.ids.GameId +import eventDemo.shared.ids.UserId import eventDemo.testHelpers.act import eventDemo.testHelpers.assert import io.kotest.core.spec.style.FunSpec diff --git a/src/test/kotlin/eventDemo/contexts/game/domain/game/gameState/NewDeckTest.kt b/backend/src/test/kotlin/eventDemo/contexts/game/domain/game/gameState/NewDeckTest.kt similarity index 96% rename from src/test/kotlin/eventDemo/contexts/game/domain/game/gameState/NewDeckTest.kt rename to backend/src/test/kotlin/eventDemo/contexts/game/domain/game/gameState/NewDeckTest.kt index f017394..c432e83 100644 --- a/src/test/kotlin/eventDemo/contexts/game/domain/game/gameState/NewDeckTest.kt +++ b/backend/src/test/kotlin/eventDemo/contexts/game/domain/game/gameState/NewDeckTest.kt @@ -1,6 +1,6 @@ package eventDemo.contexts.game.domain.game.gameState -import eventDemo.contexts.game.domain.game.Card +import eventDemo.shared.game.Card import io.kotest.assertions.retry import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.collections.shouldHaveSize diff --git a/src/test/kotlin/eventDemo/contexts/game/intrastructure/AuthHelper.kt b/backend/src/test/kotlin/eventDemo/contexts/game/intrastructure/AuthHelper.kt similarity index 100% rename from src/test/kotlin/eventDemo/contexts/game/intrastructure/AuthHelper.kt rename to backend/src/test/kotlin/eventDemo/contexts/game/intrastructure/AuthHelper.kt diff --git a/src/test/kotlin/eventDemo/contexts/game/intrastructure/TestHttpClient.kt b/backend/src/test/kotlin/eventDemo/contexts/game/intrastructure/TestHttpClient.kt similarity index 100% rename from src/test/kotlin/eventDemo/contexts/game/intrastructure/TestHttpClient.kt rename to backend/src/test/kotlin/eventDemo/contexts/game/intrastructure/TestHttpClient.kt diff --git a/src/test/kotlin/eventDemo/contexts/game/intrastructure/persistence/connectors/PostgresqlTest.kt b/backend/src/test/kotlin/eventDemo/contexts/game/intrastructure/persistence/connectors/PostgresqlTest.kt similarity index 100% rename from src/test/kotlin/eventDemo/contexts/game/intrastructure/persistence/connectors/PostgresqlTest.kt rename to backend/src/test/kotlin/eventDemo/contexts/game/intrastructure/persistence/connectors/PostgresqlTest.kt diff --git a/src/test/kotlin/eventDemo/contexts/game/intrastructure/persistence/connectors/RabbitMQTest.kt b/backend/src/test/kotlin/eventDemo/contexts/game/intrastructure/persistence/connectors/RabbitMQTest.kt similarity index 100% rename from src/test/kotlin/eventDemo/contexts/game/intrastructure/persistence/connectors/RabbitMQTest.kt rename to backend/src/test/kotlin/eventDemo/contexts/game/intrastructure/persistence/connectors/RabbitMQTest.kt diff --git a/src/test/kotlin/eventDemo/contexts/game/intrastructure/persistence/eventBus/GameEventBusInRabbitMQTest.kt b/backend/src/test/kotlin/eventDemo/contexts/game/intrastructure/persistence/eventBus/GameEventBusInRabbitMQTest.kt similarity index 92% rename from src/test/kotlin/eventDemo/contexts/game/intrastructure/persistence/eventBus/GameEventBusInRabbitMQTest.kt rename to backend/src/test/kotlin/eventDemo/contexts/game/intrastructure/persistence/eventBus/GameEventBusInRabbitMQTest.kt index 8edb240..7d2c8a8 100644 --- a/src/test/kotlin/eventDemo/contexts/game/intrastructure/persistence/eventBus/GameEventBusInRabbitMQTest.kt +++ b/backend/src/test/kotlin/eventDemo/contexts/game/intrastructure/persistence/eventBus/GameEventBusInRabbitMQTest.kt @@ -3,11 +3,11 @@ package eventDemo.contexts.game.intrastructure.persistence.eventBus import com.rabbitmq.client.ConnectionFactory import eventDemo.contexts.game.application.ports.GameEventBus import eventDemo.contexts.game.domain.events.NewPlayerEvent -import eventDemo.contexts.game.domain.game.GameId -import eventDemo.contexts.game.domain.game.Player import eventDemo.contexts.game.infrastructure.persistence.eventBus.GameEventBusInMemory import eventDemo.contexts.game.infrastructure.persistence.eventBus.GameEventBusInRabbinMQ -import eventDemo.sharedKernel.UserId +import eventDemo.shared.game.Player +import eventDemo.shared.ids.GameId +import eventDemo.shared.ids.UserId import eventDemo.testHelpers.spyPing import eventDemo.testHelpers.testKoinApplicationWithConfig import io.kotest.core.spec.style.FunSpec diff --git a/src/test/kotlin/eventDemo/contexts/game/intrastructure/rest/GameListRouteTest.kt b/backend/src/test/kotlin/eventDemo/contexts/game/intrastructure/rest/GameListRouteTest.kt similarity index 98% rename from src/test/kotlin/eventDemo/contexts/game/intrastructure/rest/GameListRouteTest.kt rename to backend/src/test/kotlin/eventDemo/contexts/game/intrastructure/rest/GameListRouteTest.kt index 0a1cdf0..baec65c 100644 --- a/src/test/kotlin/eventDemo/contexts/game/intrastructure/rest/GameListRouteTest.kt +++ b/backend/src/test/kotlin/eventDemo/contexts/game/intrastructure/rest/GameListRouteTest.kt @@ -1,9 +1,9 @@ package eventDemo.contexts.game.intrastructure.rest import eventDemo.contexts.auth.application.eventStores.UserRepository -import eventDemo.contexts.game.infrastructure.persistence.projections.models.GameList import eventDemo.contexts.game.intrastructure.httpClient import eventDemo.contexts.game.intrastructure.withAuth +import eventDemo.shared.game.projection.GameList import eventDemo.testHelpers.CreateGameWithCommandsHelpers import eventDemo.testHelpers.CreateGameWithCommandsHelpers.joinTheGame import eventDemo.testHelpers.CreateGameWithCommandsHelpers.readyToPlay diff --git a/src/test/kotlin/eventDemo/libs/bus/BusTest.kt b/backend/src/test/kotlin/eventDemo/libs/bus/BusTest.kt similarity index 100% rename from src/test/kotlin/eventDemo/libs/bus/BusTest.kt rename to backend/src/test/kotlin/eventDemo/libs/bus/BusTest.kt diff --git a/src/test/kotlin/eventDemo/libs/command/CommandForTest.kt b/backend/src/test/kotlin/eventDemo/libs/command/CommandForTest.kt similarity index 66% rename from src/test/kotlin/eventDemo/libs/command/CommandForTest.kt rename to backend/src/test/kotlin/eventDemo/libs/command/CommandForTest.kt index 1e4a0be..e35a5af 100644 --- a/src/test/kotlin/eventDemo/libs/command/CommandForTest.kt +++ b/backend/src/test/kotlin/eventDemo/libs/command/CommandForTest.kt @@ -1,5 +1,7 @@ package eventDemo.libs.command +import eventDemo.shared.command.Command +import eventDemo.shared.ids.CommandId import kotlinx.serialization.Serializable @Serializable diff --git a/src/test/kotlin/eventDemo/libs/command/CommandUnicityCheckerTest.kt b/backend/src/test/kotlin/eventDemo/libs/command/CommandUnicityCheckerTest.kt similarity index 96% rename from src/test/kotlin/eventDemo/libs/command/CommandUnicityCheckerTest.kt rename to backend/src/test/kotlin/eventDemo/libs/command/CommandUnicityCheckerTest.kt index f86128f..619d0b6 100644 --- a/src/test/kotlin/eventDemo/libs/command/CommandUnicityCheckerTest.kt +++ b/backend/src/test/kotlin/eventDemo/libs/command/CommandUnicityCheckerTest.kt @@ -1,5 +1,6 @@ package eventDemo.libs.command +import eventDemo.shared.ids.CommandId import eventDemo.testHelpers.spyPing import io.kotest.core.spec.style.FunSpec import org.junit.jupiter.api.assertThrows diff --git a/src/test/kotlin/eventDemo/libs/eventSource/EventStreamTest.kt b/backend/src/test/kotlin/eventDemo/libs/eventSource/EventStreamTest.kt similarity index 100% rename from src/test/kotlin/eventDemo/libs/eventSource/EventStreamTest.kt rename to backend/src/test/kotlin/eventDemo/libs/eventSource/EventStreamTest.kt diff --git a/src/test/kotlin/eventDemo/libs/eventSource/TestEvents.kt b/backend/src/test/kotlin/eventDemo/libs/eventSource/TestEvents.kt similarity index 70% rename from src/test/kotlin/eventDemo/libs/eventSource/TestEvents.kt rename to backend/src/test/kotlin/eventDemo/libs/eventSource/TestEvents.kt index bee5701..307c0ba 100644 --- a/src/test/kotlin/eventDemo/libs/eventSource/TestEvents.kt +++ b/backend/src/test/kotlin/eventDemo/libs/eventSource/TestEvents.kt @@ -1,17 +1,19 @@ package eventDemo.libs.eventSource -import eventDemo.contexts.game.infrastructure.persistence.serializers.EventIdSerializer -import eventDemo.libs.serializer.UUIDSerializer +import eventDemo.shared.ids.AggregateId +import eventDemo.shared.ids.EventId +import eventDemo.shared.serializers.EventIdSerializer +import eventDemo.shared.serializers.UUIDSerializer import kotlinx.datetime.Clock import kotlinx.datetime.Instant import kotlinx.serialization.Serializable -import java.util.UUID +import kotlin.uuid.Uuid @JvmInline @Serializable value class IdTest( @Serializable(with = UUIDSerializer::class) - override val id: UUID = UUID.randomUUID(), + override val id: Uuid = Uuid.random(), ) : AggregateId @Serializable diff --git a/src/test/kotlin/eventDemo/libs/helpers/FrameChannelConverterTest.kt b/backend/src/test/kotlin/eventDemo/libs/helpers/FrameChannelConverterTest.kt similarity index 88% rename from src/test/kotlin/eventDemo/libs/helpers/FrameChannelConverterTest.kt rename to backend/src/test/kotlin/eventDemo/libs/helpers/FrameChannelConverterTest.kt index 56d1635..1399f51 100644 --- a/src/test/kotlin/eventDemo/libs/helpers/FrameChannelConverterTest.kt +++ b/backend/src/test/kotlin/eventDemo/libs/helpers/FrameChannelConverterTest.kt @@ -1,22 +1,22 @@ package eventDemo.libs.helpers import eventDemo.libs.command.CommandForTest -import eventDemo.libs.command.CommandId +import eventDemo.shared.ids.CommandId import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.equals.shouldBeEqual import io.ktor.websocket.Frame import io.ktor.websocket.readText import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.launch -import java.util.UUID import kotlin.test.assertIs +import kotlin.uuid.Uuid class FrameChannelConverterTest : FunSpec({ test("toObjectChannel") { val uuid = "d737c631-76af-406e-bc29-f3e5b97226a5" - val id = CommandId(UUID.fromString(uuid)) + val id = CommandId(Uuid.parse(uuid)) val jsonCommand = """{"id":"$uuid"}""" val channel = Channel() @@ -32,7 +32,7 @@ class FrameChannelConverterTest : test("fromFrameChannel") { val uuid = "d737c631-76af-406e-bc29-f3e5b97226a5" - val id = CommandId(UUID.fromString(uuid)) + val id = CommandId(Uuid.parse(uuid)) val command = CommandForTest(id) val jsonCommand = """{"id":"$uuid"}""" diff --git a/src/test/kotlin/eventDemo/testHelpers/CreateGameWithCommandsHelpers.kt b/backend/src/test/kotlin/eventDemo/testHelpers/CreateGameWithCommandsHelpers.kt similarity index 81% rename from src/test/kotlin/eventDemo/testHelpers/CreateGameWithCommandsHelpers.kt rename to backend/src/test/kotlin/eventDemo/testHelpers/CreateGameWithCommandsHelpers.kt index de91377..c5ad2fe 100644 --- a/src/test/kotlin/eventDemo/testHelpers/CreateGameWithCommandsHelpers.kt +++ b/backend/src/test/kotlin/eventDemo/testHelpers/CreateGameWithCommandsHelpers.kt @@ -2,15 +2,16 @@ package eventDemo.testHelpers import eventDemo.contexts.auth.domain.User import eventDemo.contexts.game.application.command.handlers.GameCommandHandlerDispatcher -import eventDemo.contexts.game.application.command.models.JoinTheGameCommand -import eventDemo.contexts.game.application.command.models.PlayCardCommand -import eventDemo.contexts.game.application.command.models.ReadyToPlayCommand import eventDemo.contexts.game.application.eventStores.GameRepository -import eventDemo.contexts.game.domain.game.Card -import eventDemo.contexts.game.domain.game.GameId -import eventDemo.contexts.game.domain.game.Player +import eventDemo.shared.game.Card +import eventDemo.shared.game.Player +import eventDemo.shared.game.command.JoinTheGameCommand +import eventDemo.shared.game.command.PlayCardCommand +import eventDemo.shared.game.command.ReadyToPlayCommand +import eventDemo.shared.ids.GameId import org.koin.core.Koin import java.util.UUID +import kotlin.uuid.toKotlinUuid object CreateGameWithCommandsHelpers { class Data( @@ -26,7 +27,7 @@ object CreateGameWithCommandsHelpers { gameName: String = "testGame${UUID.randomUUID()}", block: context(CreateGameWithCommandsHelpers, GameCommandHandlerDispatcher) Data.() -> T, ): T { - val gameId = GameId(UUID.nameUUIDFromBytes(gameName.encodeToByteArray())) + val gameId = GameId(UUID.nameUUIDFromBytes(gameName.encodeToByteArray()).toKotlinUuid()) val repo = koin.get() repo.create(gameId) diff --git a/src/test/kotlin/eventDemo/testHelpers/CreateGameWithCommandsInChannelsHelpers.kt b/backend/src/test/kotlin/eventDemo/testHelpers/CreateGameWithCommandsInChannelsHelpers.kt similarity index 82% rename from src/test/kotlin/eventDemo/testHelpers/CreateGameWithCommandsInChannelsHelpers.kt rename to backend/src/test/kotlin/eventDemo/testHelpers/CreateGameWithCommandsInChannelsHelpers.kt index a2be1f3..475d7b9 100644 --- a/src/test/kotlin/eventDemo/testHelpers/CreateGameWithCommandsInChannelsHelpers.kt +++ b/backend/src/test/kotlin/eventDemo/testHelpers/CreateGameWithCommandsInChannelsHelpers.kt @@ -1,15 +1,15 @@ package eventDemo.testHelpers import eventDemo.contexts.auth.domain.User -import eventDemo.contexts.game.application.command.models.GameCommand -import eventDemo.contexts.game.application.command.models.JoinTheGameCommand -import eventDemo.contexts.game.application.command.models.PlayCardCommand -import eventDemo.contexts.game.application.command.models.ReadyToPlayCommand import eventDemo.contexts.game.application.eventStores.GameRepository -import eventDemo.contexts.game.domain.game.Card -import eventDemo.contexts.game.domain.game.GameId -import eventDemo.contexts.game.domain.game.Player import eventDemo.contexts.game.domain.game.gameState.Game +import eventDemo.shared.game.Card +import eventDemo.shared.game.Player +import eventDemo.shared.game.command.GameCommand +import eventDemo.shared.game.command.JoinTheGameCommand +import eventDemo.shared.game.command.PlayCardCommand +import eventDemo.shared.game.command.ReadyToPlayCommand +import eventDemo.shared.ids.GameId import kotlinx.coroutines.channels.Channel import org.koin.core.Koin diff --git a/src/test/kotlin/eventDemo/testHelpers/LogHelper.kt b/backend/src/test/kotlin/eventDemo/testHelpers/LogHelper.kt similarity index 100% rename from src/test/kotlin/eventDemo/testHelpers/LogHelper.kt rename to backend/src/test/kotlin/eventDemo/testHelpers/LogHelper.kt diff --git a/src/test/kotlin/eventDemo/testHelpers/NewUserHelper.kt b/backend/src/test/kotlin/eventDemo/testHelpers/NewUserHelper.kt similarity index 100% rename from src/test/kotlin/eventDemo/testHelpers/NewUserHelper.kt rename to backend/src/test/kotlin/eventDemo/testHelpers/NewUserHelper.kt diff --git a/src/test/kotlin/eventDemo/testHelpers/TestAllCardCountHelpers.kt b/backend/src/test/kotlin/eventDemo/testHelpers/TestAllCardCountHelpers.kt similarity index 100% rename from src/test/kotlin/eventDemo/testHelpers/TestAllCardCountHelpers.kt rename to backend/src/test/kotlin/eventDemo/testHelpers/TestAllCardCountHelpers.kt diff --git a/src/test/kotlin/eventDemo/testHelpers/TestApplicationHelpers.kt b/backend/src/test/kotlin/eventDemo/testHelpers/TestApplicationHelpers.kt similarity index 100% rename from src/test/kotlin/eventDemo/testHelpers/TestApplicationHelpers.kt rename to backend/src/test/kotlin/eventDemo/testHelpers/TestApplicationHelpers.kt diff --git a/src/test/kotlin/eventDemo/testHelpers/TestDataHelper.kt b/backend/src/test/kotlin/eventDemo/testHelpers/TestDataHelper.kt similarity index 100% rename from src/test/kotlin/eventDemo/testHelpers/TestDataHelper.kt rename to backend/src/test/kotlin/eventDemo/testHelpers/TestDataHelper.kt diff --git a/src/test/kotlin/eventDemo/testHelpers/TestHelper.kt b/backend/src/test/kotlin/eventDemo/testHelpers/TestHelper.kt similarity index 100% rename from src/test/kotlin/eventDemo/testHelpers/TestHelper.kt rename to backend/src/test/kotlin/eventDemo/testHelpers/TestHelper.kt diff --git a/build.gradle.kts b/build.gradle.kts index 00684f7..9121c18 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,98 +1,16 @@ -import org.jlleitschuh.gradle.ktlint.KtlintExtension - -val ktorVersion: Provider = providers.gradleProperty("ktor_version") -val kotlinVersion: Provider = providers.gradleProperty("kotlin_version") -val kotlinSerializationVersion: Provider = providers.gradleProperty("kotlin_serialization_version") -val logbackVersion: Provider = providers.gradleProperty("logback_version") -val koinVersion: Provider = providers.gradleProperty("koin_version") -val kotlinLoggingVersion: Provider = providers.gradleProperty("kotlin_logging_version") -val kotestVersion: Provider = providers.gradleProperty("kotest_version") +buildscript { + configurations.classpath { + resolutionStrategy { + force("org.jetbrains:annotations:23.0.0") + } + } +} plugins { - application - kotlin("jvm") version "2.1.21" - id("io.ktor.plugin") version "3.5.1" - id("org.jetbrains.kotlin.plugin.serialization") version "2.4.10" - id("org.jlleitschuh.gradle.ktlint") version "14.2.0" -} - -group = "io.github.flecomte" - -application { - mainClass.set("eventDemo.ApplicationKt") - - val isDevelopment: Boolean = project.ext.has("development") - applicationDefaultJvmArgs = listOf("-Dio.ktor.development=$isDevelopment") -} - -configure { - version.set("1.8.0") -} -ktlint { - reporters { - reporter(org.jlleitschuh.gradle.ktlint.reporter.ReporterType.CHECKSTYLE) - } -} - -repositories { - mavenCentral() -} - -java { - toolchain { - languageVersion = JavaLanguageVersion.of(21) - } -} - -tasks.withType().configureEach { - useJUnitPlatform() - jvmArgs("-Djdk.attach.allowAttachSelf=true", "-XX:+EnableDynamicAgentLoading") - // Dynamic self-attach (used by MockK/ByteBuddy) times out in Docker containers because the - // SIGQUIT-triggered AttachListener handshake never completes there. Loading the byte-buddy - // agent jar statically via -javaagent avoids the attach handshake entirely: MockK detects the - // pre-installed Instrumentation instance and skips dynamic attach. - doFirst { - val agentJar = - classpath.files.firstOrNull { it.name.startsWith("byte-buddy-agent") } - ?: error("byte-buddy-agent jar not found on test classpath") - jvmArgs("-javaagent:$agentJar") - } -} - -dependencies { - implementation("io.ktor:ktor-server-core-jvm") - implementation("io.ktor:ktor-server-auth-jvm") - implementation("io.ktor:ktor-server-auth-jwt-jvm") - implementation("io.ktor:ktor-server-auto-head-response-jvm") - implementation("io.ktor:ktor-server-resources") - implementation("io.ktor:ktor-server-content-negotiation-jvm") - implementation("io.ktor:ktor-serialization-kotlinx-json-jvm") - implementation("io.ktor:ktor-server-websockets-jvm") - implementation("io.ktor:ktor-server-cors-jvm") - implementation("io.ktor:ktor-server-host-common-jvm") - implementation("io.ktor:ktor-server-status-pages-jvm") - implementation("io.ktor:ktor-server-netty-jvm") - implementation("io.ktor:ktor-server-data-conversion") - implementation("io.ktor:ktor-client-content-negotiation") - implementation("io.ktor:ktor-client-auth") - implementation("ch.qos.logback:logback-classic:${logbackVersion.get()}") - implementation("io.insert-koin:koin-ktor:${koinVersion.get()}") - implementation("io.insert-koin:koin-logger-slf4j:${koinVersion.get()}") - implementation("io.github.oshai:kotlin-logging-jvm:${kotlinLoggingVersion.get()}") - implementation("org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:${kotlinSerializationVersion.get()}") - implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.2") - implementation("org.postgresql:postgresql:42.7.13") - implementation("com.zaxxer:HikariCP:6.3.0") - implementation("com.rabbitmq:amqp-client:5.25.0") - implementation("com.password4j:password4j:1.8.4") - - // Force version of sub library (for security) - implementation("commons-codec:commons-codec:1.13") - - testImplementation("io.kotest:kotest-extensions-koin:${kotestVersion.get()}") - testImplementation("org.jetbrains.kotlin:kotlin-test-junit:${kotlinVersion.get()}") - testImplementation("io.ktor:ktor-server-test-host-jvm:${ktorVersion.get()}") - testImplementation("io.kotest:kotest-runner-junit5:${kotestVersion.get()}") - testImplementation("io.mockk:mockk:1.14.11") - testImplementation("com.tngtech.archunit:archunit-junit5:1.3.0") + kotlin("multiplatform") version "2.1.21" apply false + kotlin("plugin.serialization") version "2.4.10" apply false + kotlin("plugin.compose") version "2.1.21" apply false + id("com.android.application") version "9.2.0" apply false + id("com.android.library") version "9.2.0" apply false + id("org.jetbrains.compose") version "1.8.2" apply false } diff --git a/composeApp/build.gradle.kts b/composeApp/build.gradle.kts new file mode 100644 index 0000000..66e9b3d --- /dev/null +++ b/composeApp/build.gradle.kts @@ -0,0 +1,135 @@ +import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi +import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + +val kotlinSerializationVersion: Provider = providers.gradleProperty("kotlin_serialization_version") +val kotlinxCoroutinesVersion: Provider = providers.gradleProperty("kotlinx_coroutines_version") +val ktorVersion: Provider = providers.gradleProperty("ktor_version") +val navigationComposeVersion: Provider = providers.gradleProperty("navigation_compose_version") +val androidCompileSdk: Provider = providers.gradleProperty("android_compile_sdk") +val androidTargetSdk: Provider = providers.gradleProperty("android_target_sdk") +val androidMinSdk: Provider = providers.gradleProperty("android_min_sdk") + +plugins { + kotlin("multiplatform") + kotlin("plugin.compose") + kotlin("plugin.serialization") + id("org.jetbrains.compose") + id("com.android.application") +} + +kotlin { + androidTarget { + @OptIn(ExperimentalKotlinGradlePluginApi::class) + compilerOptions { + jvmTarget.set(JvmTarget.JVM_21) + freeCompilerArgs.add("-opt-in=kotlin.uuid.ExperimentalUuidApi") + } + } + + jvm("desktop") { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_21) + freeCompilerArgs.add("-opt-in=kotlin.uuid.ExperimentalUuidApi") + } + } + + @OptIn(ExperimentalWasmDsl::class) + wasmJs { + outputModuleName = "eventDemoApp" + browser { + commonWebpackConfig { + outputFileName = "eventDemoApp.js" + } + } + binaries.executable() + } + + compilerOptions { + freeCompilerArgs.add("-opt-in=kotlin.uuid.ExperimentalUuidApi") + } + + sourceSets { + commonMain.dependencies { + implementation(project(":shared")) + + implementation(compose.runtime) + implementation(compose.foundation) + implementation(compose.material3) + implementation(compose.ui) + implementation(compose.components.resources) + implementation(compose.components.uiToolingPreview) + + implementation("org.jetbrains.androidx.navigation:navigation-compose:${navigationComposeVersion.get()}") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:${kotlinxCoroutinesVersion.get()}") + implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:${kotlinSerializationVersion.get()}") + + implementation("io.ktor:ktor-client-core:${ktorVersion.get()}") + implementation("io.ktor:ktor-client-content-negotiation:${ktorVersion.get()}") + implementation("io.ktor:ktor-client-websockets:${ktorVersion.get()}") + implementation("io.ktor:ktor-serialization-kotlinx-json:${ktorVersion.get()}") + } + + androidMain.dependencies { + implementation("androidx.activity:activity-compose:1.11.0") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:${kotlinxCoroutinesVersion.get()}") + implementation("io.ktor:ktor-client-okhttp:${ktorVersion.get()}") + } + + getByName("desktopMain").dependencies { + implementation(compose.desktop.currentOs) + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-swing:${kotlinxCoroutinesVersion.get()}") + implementation("io.ktor:ktor-client-cio:${ktorVersion.get()}") + } + + wasmJsMain.dependencies { + implementation("io.ktor:ktor-client-js:${ktorVersion.get()}") + } + } +} + +android { + namespace = "io.github.flecomte.eventdemo.app" + compileSdk = androidCompileSdk.get().toInt() + + defaultConfig { + applicationId = "io.github.flecomte.eventdemo.app" + minSdk = androidMinSdk.get().toInt() + targetSdk = androidTargetSdk.get().toInt() + versionCode = 1 + versionName = "1.0" + } + + packaging { + resources { + excludes += "/META-INF/{AL2.0,LGPL2.1}" + } + } + + buildTypes { + getByName("release") { + isMinifyEnabled = false + } + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 + } +} + +compose.desktop { + application { + mainClass = "eventDemo.app.MainKt" + + nativeDistributions { + targetFormats( + org.jetbrains.compose.desktop.application.dsl.TargetFormat.Dmg, + org.jetbrains.compose.desktop.application.dsl.TargetFormat.Msi, + org.jetbrains.compose.desktop.application.dsl.TargetFormat.Deb, + ) + packageName = "EventDemo" + packageVersion = "1.0.0" + } + } +} diff --git a/composeApp/src/androidMain/AndroidManifest.xml b/composeApp/src/androidMain/AndroidManifest.xml new file mode 100644 index 0000000..fe5613e --- /dev/null +++ b/composeApp/src/androidMain/AndroidManifest.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + diff --git a/composeApp/src/androidMain/kotlin/eventDemo/app/MainActivity.kt b/composeApp/src/androidMain/kotlin/eventDemo/app/MainActivity.kt new file mode 100644 index 0000000..9c8de37 --- /dev/null +++ b/composeApp/src/androidMain/kotlin/eventDemo/app/MainActivity.kt @@ -0,0 +1,14 @@ +package eventDemo.app + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent + +class MainActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + App() + } + } +} diff --git a/composeApp/src/commonMain/kotlin/eventDemo/app/App.kt b/composeApp/src/commonMain/kotlin/eventDemo/app/App.kt new file mode 100644 index 0000000..678f03e --- /dev/null +++ b/composeApp/src/commonMain/kotlin/eventDemo/app/App.kt @@ -0,0 +1,154 @@ +package eventDemo.app + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material3.Button +import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import eventDemo.app.network.ApiClient +import eventDemo.shared.game.projection.GameList +import kotlinx.coroutines.launch + +private enum class Screen { LOGIN, GAMES } + +@Composable +fun App() { + MaterialTheme { + Surface(modifier = Modifier.fillMaxSize()) { + val apiClient = remember { ApiClient() } + var screen by remember { mutableStateOf(Screen.LOGIN) } + + when (screen) { + Screen.LOGIN -> LoginScreen(apiClient) { screen = Screen.GAMES } + Screen.GAMES -> GamesScreen(apiClient) { screen = Screen.LOGIN } + } + } + } +} + +@Composable +private fun LoginScreen( + apiClient: ApiClient, + onLoggedIn: () -> Unit, +) { + val scope = rememberCoroutineScope() + var username by remember { mutableStateOf("") } + var password by remember { mutableStateOf("") } + var errorMessage by remember { mutableStateOf(null) } + var isLoading by remember { mutableStateOf(false) } + + Column( + modifier = Modifier.fillMaxSize().padding(24.dp), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Text("EventDemo", style = MaterialTheme.typography.headlineMedium) + OutlinedTextField( + value = username, + onValueChange = { username = it }, + label = { Text("Username") }, + modifier = Modifier.fillMaxWidth().padding(top = 24.dp), + ) + OutlinedTextField( + value = password, + onValueChange = { password = it }, + label = { Text("Password") }, + modifier = Modifier.fillMaxWidth().padding(top = 8.dp), + ) + errorMessage?.let { + Text(it, color = MaterialTheme.colorScheme.error, modifier = Modifier.padding(top = 8.dp)) + } + Button( + onClick = { + errorMessage = null + isLoading = true + scope.launch { + apiClient + .login(username, password) + .onSuccess { onLoggedIn() } + .onFailure { errorMessage = it.message ?: "Login failed" } + isLoading = false + } + }, + enabled = !isLoading && username.isNotBlank() && password.isNotBlank(), + modifier = Modifier.padding(top = 16.dp), + ) { + Text(if (isLoading) "Signing in..." else "Sign in") + } + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +private fun GamesScreen( + apiClient: ApiClient, + onLoggedOut: () -> Unit, +) { + val scope = rememberCoroutineScope() + var games by remember { mutableStateOf>(emptyList()) } + var errorMessage by remember { mutableStateOf(null) } + var isLoading by remember { mutableStateOf(true) } + + fun refresh() { + isLoading = true + scope.launch { + apiClient + .listGames() + .onSuccess { games = it } + .onFailure { errorMessage = it.message ?: "Could not load games" } + isLoading = false + } + } + + remember { refresh() } + + Scaffold( + topBar = { TopAppBar(title = { Text("Games") }) }, + ) { padding -> + Column(modifier = Modifier.fillMaxSize().padding(padding).padding(16.dp)) { + when { + isLoading -> CircularProgressIndicator() + errorMessage != null -> Text(errorMessage ?: "") + games.isEmpty() -> Text("No game yet.") + else -> + LazyColumn { + items(games) { game -> + Text("${game.aggregateId} - ${game.status} - ${game.players.size} player(s)") + } + } + } + Button(onClick = { refresh() }, modifier = Modifier.padding(top = 16.dp)) { + Text("Refresh") + } + Button( + onClick = { + apiClient.logout() + onLoggedOut() + }, + modifier = Modifier.padding(top = 8.dp), + ) { + Text("Sign out") + } + } + } +} diff --git a/composeApp/src/commonMain/kotlin/eventDemo/app/network/ApiClient.kt b/composeApp/src/commonMain/kotlin/eventDemo/app/network/ApiClient.kt new file mode 100644 index 0000000..39ebb51 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/eventDemo/app/network/ApiClient.kt @@ -0,0 +1,63 @@ +package eventDemo.app.network + +import eventDemo.shared.game.projection.GameList +import io.ktor.client.HttpClient +import io.ktor.client.call.body +import io.ktor.client.plugins.contentnegotiation.ContentNegotiation +import io.ktor.client.request.get +import io.ktor.client.request.header +import io.ktor.client.request.parameter +import io.ktor.client.request.post +import io.ktor.http.HttpHeaders +import io.ktor.serialization.kotlinx.json.json +import kotlinx.serialization.json.Json + +/** + * Talks to the Ktor backend over plain HTTP. + * `baseUrl` defaults to the dev Traefik route documented in doc/installation.md. + */ +class ApiClient( + private val baseUrl: String = "http://api.traefik.me", +) { + private var token: String? = null + + private val client = + HttpClient { + install(ContentNegotiation) { + json( + Json { + ignoreUnknownKeys = true + }, + ) + } + } + + val isAuthenticated: Boolean + get() = token != null + + suspend fun login( + username: String, + password: String, + ): Result = + runCatching { + val response: Map = + client + .post("$baseUrl/login/$username") { + parameter("password", password) + }.body() + token = response["token"] ?: error("Missing token in login response") + } + + suspend fun listGames(): Result> = + runCatching { + val currentToken = token ?: error("Not authenticated") + client + .get("$baseUrl/games") { + header(HttpHeaders.Authorization, "Bearer $currentToken") + }.body() + } + + fun logout() { + token = null + } +} diff --git a/composeApp/src/desktopMain/kotlin/eventDemo/app/Main.kt b/composeApp/src/desktopMain/kotlin/eventDemo/app/Main.kt new file mode 100644 index 0000000..7b13297 --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/eventDemo/app/Main.kt @@ -0,0 +1,11 @@ +package eventDemo.app + +import androidx.compose.ui.window.Window +import androidx.compose.ui.window.application + +fun main() = + application { + Window(onCloseRequest = ::exitApplication, title = "EventDemo") { + App() + } + } diff --git a/composeApp/src/wasmJsMain/kotlin/eventDemo/app/Main.kt b/composeApp/src/wasmJsMain/kotlin/eventDemo/app/Main.kt new file mode 100644 index 0000000..8e6a87c --- /dev/null +++ b/composeApp/src/wasmJsMain/kotlin/eventDemo/app/Main.kt @@ -0,0 +1,12 @@ +package eventDemo.app + +import androidx.compose.ui.ExperimentalComposeUiApi +import androidx.compose.ui.window.ComposeViewport +import kotlinx.browser.document + +@OptIn(ExperimentalComposeUiApi::class) +fun main() { + ComposeViewport(document.body!!) { + App() + } +} diff --git a/composeApp/src/wasmJsMain/resources/index.html b/composeApp/src/wasmJsMain/resources/index.html new file mode 100644 index 0000000..5183441 --- /dev/null +++ b/composeApp/src/wasmJsMain/resources/index.html @@ -0,0 +1,17 @@ + + + + + EventDemo + + + + + + diff --git a/docker/Dockerfile b/docker/Dockerfile index 2eef580..c7c0e92 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -2,9 +2,11 @@ FROM gradle:9.6.1-jdk21-alpine AS cache RUN mkdir -p /home/gradle/cache_home ENV GRADLE_USER_HOME=/home/gradle/cache_home -COPY build.gradle.* gradle.properties /home/gradle/app/ +COPY settings.gradle.kts build.gradle.kts gradle.properties /home/gradle/app/ +COPY backend/build.gradle.kts /home/gradle/app/backend/ +COPY shared/build.gradle.kts /home/gradle/app/shared/ WORKDIR /home/gradle/app -RUN gradle build -i -x check +RUN gradle :backend:build -i -x check # Stage 2: Build Application FROM gradle:9.6.1-jdk21-alpine AS build @@ -13,11 +15,11 @@ COPY --chown=gradle:gradle . /home/gradle/src WORKDIR /home/gradle/src # Build the fat JAR, Gradle also supports shadow # and boot JAR by default. -RUN gradle buildFatJar --no-daemon +RUN gradle :backend:buildFatJar --no-daemon # Stage 3: Create the Runtime Image FROM eclipse-temurin:21-jre-alpine AS runtime EXPOSE 8080 RUN mkdir /app -COPY --from=build /home/gradle/src/build/libs/*-all.jar /app/event-demo-all.jar +COPY --from=build /home/gradle/src/backend/build/libs/*-all.jar /app/event-demo-all.jar ENTRYPOINT ["java","-jar","/app/event-demo-all.jar"] \ No newline at end of file diff --git a/docker/DockerfileTest b/docker/DockerfileTest index aae096a..1f2ef19 100644 --- a/docker/DockerfileTest +++ b/docker/DockerfileTest @@ -4,7 +4,11 @@ FROM gradle:9.6.1-jdk21 WORKDIR /app # Copie du wrapper et des fichiers de config en premier pour profiter du cache Docker -COPY build.gradle.kts settings.gradle.kts ./ +COPY build.gradle.kts settings.gradle.kts gradle.properties ./ -# Lance les tests Kotlin -CMD ["gradle", "test", "--no-daemon"] \ No newline at end of file +# Lance les tests Kotlin. +# Scope volontairement limite a :backend et :shared : :composeApp applique le plugin Android +# (com.android.application), qui echoue a la configuration sans SDK Android installe dans +# cette image de test. Ne pas passer a un `gradle test` non scope sans ajouter le SDK Android +# a l'image, ou sans configuration-on-demand garantissant que :composeApp n'est pas evalue. +CMD ["gradle", ":backend:test", ":shared:test", "--no-daemon"] \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 136f432..6f2c680 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,4 +6,23 @@ koin_version=4.2.1 kotlin_logging_version=8.0.4 kotest_version=6.2.2 +compose_multiplatform_version=1.8.2 +agp_version=9.2.0 +kotlinx_coroutines_version=1.10.2 +navigation_compose_version=2.9.2 +android_compile_sdk=36 +android_target_sdk=36 +android_min_sdk=24 + kotlin.code.style=official +org.gradle.jvmargs=-Xmx4g +kotlin.daemon.jvmargs=-Xmx4g +org.gradle.configureondemand=true +android.useAndroidX=true +android.nonTransitiveRClass=true +# AGP 9.x's classic com.android.library/application plugins no longer work together with +# org.jetbrains.kotlin.multiplatform in the same module (they require the newer +# com.android.kotlin.multiplatform.library plugin instead). Until shared/composeApp are migrated +# to that new plugin, this AGP-recommended flag keeps the classic DSL usable. +android.builtInKotlin=false +android.newDsl=false diff --git a/kotlin-js-store/wasm/yarn.lock b/kotlin-js-store/wasm/yarn.lock new file mode 100644 index 0000000..ed04a62 --- /dev/null +++ b/kotlin-js-store/wasm/yarn.lock @@ -0,0 +1,18 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@js-joda/core@3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@js-joda/core/-/core-3.2.0.tgz#3e61e21b7b2b8a6be746df1335cf91d70db2a273" + integrity sha512-PMqgJ0sw5B7FKb2d5bWYIoxjri+QlW/Pys7+Rw82jSH0QN3rB05jZ/VrrsUdh1w4+i2kw9JOejXGq/KhDOX7Kg== + +format-util@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/format-util/-/format-util-1.0.5.tgz#1ffb450c8a03e7bccffe40643180918cc297d271" + integrity sha512-varLbTj0e0yVyRpqQhuWV+8hlePAgaoFRhNFj50BNjEIrw1/DphHSObtqwskVCPWNgzwPoQrZAbfa/SBiicNeg== + +ws@8.20.1: + version "8.20.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.20.1.tgz#91a9ae2b312ccf98e0a85ec499b48cef45ab0ddb" + integrity sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w== diff --git a/settings.gradle.kts b/settings.gradle.kts index c5b7d7f..65d1075 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1 +1,32 @@ +pluginManagement { + repositories { + google { + content { + includeGroupAndSubgroups("androidx") + includeGroupAndSubgroups("com.android") + includeGroupAndSubgroups("com.google") + } + } + mavenCentral() + gradlePluginPortal() + } +} + +dependencyResolutionManagement { + repositories { + google { + content { + includeGroupAndSubgroups("androidx") + includeGroupAndSubgroups("com.android") + includeGroupAndSubgroups("com.google") + } + } + mavenCentral() + } +} + rootProject.name = "event-demo" + +include(":backend") +include(":shared") +include(":composeApp") diff --git a/shared/build.gradle.kts b/shared/build.gradle.kts new file mode 100644 index 0000000..d2f5ade --- /dev/null +++ b/shared/build.gradle.kts @@ -0,0 +1,46 @@ +val kotlinSerializationVersion: Provider = providers.gradleProperty("kotlin_serialization_version") +val androidCompileSdk: Provider = providers.gradleProperty("android_compile_sdk") +val androidMinSdk: Provider = providers.gradleProperty("android_min_sdk") + +plugins { + kotlin("multiplatform") + kotlin("plugin.serialization") + id("com.android.library") +} + +kotlin { + jvm() + + androidTarget { + compilerOptions { + freeCompilerArgs.add("-opt-in=kotlin.uuid.ExperimentalUuidApi") + } + } + + @OptIn(org.jetbrains.kotlin.gradle.ExperimentalWasmDsl::class) + wasmJs { + browser() + } + + compilerOptions { + freeCompilerArgs.add("-opt-in=kotlin.uuid.ExperimentalUuidApi") + } + + sourceSets { + commonMain.dependencies { + implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:${kotlinSerializationVersion.get()}") + } + commonTest.dependencies { + implementation(kotlin("test")) + } + } +} + +android { + namespace = "io.github.flecomte.eventdemo.shared" + compileSdk = androidCompileSdk.get().toInt() + + defaultConfig { + minSdk = androidMinSdk.get().toInt() + } +} diff --git a/shared/src/commonMain/kotlin/eventDemo/shared/command/Command.kt b/shared/src/commonMain/kotlin/eventDemo/shared/command/Command.kt new file mode 100644 index 0000000..4a80e44 --- /dev/null +++ b/shared/src/commonMain/kotlin/eventDemo/shared/command/Command.kt @@ -0,0 +1,17 @@ +package eventDemo.shared.command + +import eventDemo.shared.ids.CommandId + +/** + * Interface to represent a Command. + * + * A command is a request for an action. + * + * Moved to `shared` (deviating slightly from the original plan of leaving it backend-only) + * because [eventDemo.shared.game.command.GameCommand] - a wire type that must live in `shared` + * for multiplatform client reuse - implements it. Since `shared` cannot depend on `backend`, + * this minimal marker interface has to live wherever its implementers live. + */ +interface Command { + val id: CommandId +} diff --git a/src/main/kotlin/eventDemo/contexts/game/domain/game/Card.kt b/shared/src/commonMain/kotlin/eventDemo/shared/game/Card.kt similarity index 85% rename from src/main/kotlin/eventDemo/contexts/game/domain/game/Card.kt rename to shared/src/commonMain/kotlin/eventDemo/shared/game/Card.kt index 4cd3bf1..209f46c 100644 --- a/src/main/kotlin/eventDemo/contexts/game/domain/game/Card.kt +++ b/shared/src/commonMain/kotlin/eventDemo/shared/game/Card.kt @@ -1,16 +1,16 @@ -package eventDemo.contexts.game.domain.game +package eventDemo.shared.game -import eventDemo.libs.serializer.UUIDSerializer +import eventDemo.shared.serializers.UUIDSerializer import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import java.util.UUID +import kotlin.uuid.Uuid /** * A Play card */ @Serializable sealed interface Card { - val id: UUID + val id: Uuid /** * The color of a card @@ -36,7 +36,7 @@ sealed interface Card { val number: Int, override val color: Color, @Serializable(with = UUIDSerializer::class) - override val id: UUID = UUID.randomUUID(), + override val id: Uuid = Uuid.random(), ) : Card, CardWithColor { init { @@ -58,7 +58,7 @@ sealed interface Card { data class ReverseCard( override val color: Color, @Serializable(with = UUIDSerializer::class) - override val id: UUID = UUID.randomUUID(), + override val id: Uuid = Uuid.random(), ) : Special, CardWithColor { override fun toString(): String = @@ -75,7 +75,7 @@ sealed interface Card { data class PassCard( override val color: Color, @Serializable(with = UUIDSerializer::class) - override val id: UUID = UUID.randomUUID(), + override val id: Uuid = Uuid.random(), ) : Special, CardWithColor, PassTurnCard { @@ -91,7 +91,7 @@ sealed interface Card { data class Plus2Card( override val color: Color, @Serializable(with = UUIDSerializer::class) - override val id: UUID = UUID.randomUUID(), + override val id: Uuid = Uuid.random(), ) : Special, CardWithColor, PassTurnCard { @@ -108,7 +108,7 @@ sealed interface Card { @SerialName("Plus4") class Plus4Card( @Serializable(with = UUIDSerializer::class) - override val id: UUID = UUID.randomUUID(), + override val id: Uuid = Uuid.random(), ) : Special, CardWith4Color, PassTurnCard { @@ -123,7 +123,7 @@ sealed interface Card { @SerialName("ChangeColor") class ChangeColorCard( @Serializable(with = UUIDSerializer::class) - override val id: UUID = UUID.randomUUID(), + override val id: Uuid = Uuid.random(), ) : Special, CardWith4Color { override fun toString(): String = diff --git a/src/main/kotlin/eventDemo/contexts/game/domain/game/DiscardPile.kt b/shared/src/commonMain/kotlin/eventDemo/shared/game/DiscardPile.kt similarity index 87% rename from src/main/kotlin/eventDemo/contexts/game/domain/game/DiscardPile.kt rename to shared/src/commonMain/kotlin/eventDemo/shared/game/DiscardPile.kt index 82db786..d3df117 100644 --- a/src/main/kotlin/eventDemo/contexts/game/domain/game/DiscardPile.kt +++ b/shared/src/commonMain/kotlin/eventDemo/shared/game/DiscardPile.kt @@ -1,5 +1,6 @@ -package eventDemo.contexts.game.domain.game +package eventDemo.shared.game +import kotlin.jvm.JvmInline import kotlinx.serialization.Serializable @JvmInline diff --git a/src/main/kotlin/eventDemo/contexts/game/domain/game/DrawPile.kt b/shared/src/commonMain/kotlin/eventDemo/shared/game/DrawPile.kt similarity index 92% rename from src/main/kotlin/eventDemo/contexts/game/domain/game/DrawPile.kt rename to shared/src/commonMain/kotlin/eventDemo/shared/game/DrawPile.kt index 96ca90f..a22ee8f 100644 --- a/src/main/kotlin/eventDemo/contexts/game/domain/game/DrawPile.kt +++ b/shared/src/commonMain/kotlin/eventDemo/shared/game/DrawPile.kt @@ -1,5 +1,6 @@ -package eventDemo.contexts.game.domain.game +package eventDemo.shared.game +import kotlin.jvm.JvmInline import kotlinx.serialization.Serializable @JvmInline diff --git a/src/main/kotlin/eventDemo/contexts/game/domain/game/Player.kt b/shared/src/commonMain/kotlin/eventDemo/shared/game/Player.kt similarity index 71% rename from src/main/kotlin/eventDemo/contexts/game/domain/game/Player.kt rename to shared/src/commonMain/kotlin/eventDemo/shared/game/Player.kt index c99b1d6..0f6cf2e 100644 --- a/src/main/kotlin/eventDemo/contexts/game/domain/game/Player.kt +++ b/shared/src/commonMain/kotlin/eventDemo/shared/game/Player.kt @@ -1,24 +1,24 @@ -package eventDemo.contexts.game.domain.game +package eventDemo.shared.game -import eventDemo.libs.eventSource.AggregateId -import eventDemo.libs.helpers.withReplacedValue -import eventDemo.libs.serializer.UUIDSerializer -import eventDemo.sharedKernel.UserId +import eventDemo.shared.ids.AggregateId +import eventDemo.shared.ids.UserId +import eventDemo.shared.serializers.UUIDSerializer +import kotlin.jvm.JvmInline import kotlinx.serialization.Serializable -import java.util.UUID +import kotlin.uuid.Uuid @Serializable data class Player( val name: String, val userId: UserId, val hand: PlayerHand = PlayerHand(), - val id: PlayerId = PlayerId(UUID.randomUUID()), + val id: PlayerId = PlayerId(Uuid.random()), ) { @JvmInline @Serializable value class PlayerId( @Serializable(with = UUIDSerializer::class) - override val id: UUID = UUID.randomUUID(), + override val id: Uuid = Uuid.random(), ) : AggregateId { override fun toString(): String = id.toString() @@ -60,3 +60,15 @@ class PlayerList( operator fun plus(player: Player): PlayerList = PlayerList(players + player) } + +private inline fun Set.withReplacedValue( + toReplace: V, + transform: (V) -> V, +): Set = + map { + if (it == toReplace) { + transform(it) + } else { + it + } + }.toSet() diff --git a/src/main/kotlin/eventDemo/contexts/game/domain/game/PlayerHand.kt b/shared/src/commonMain/kotlin/eventDemo/shared/game/PlayerHand.kt similarity index 85% rename from src/main/kotlin/eventDemo/contexts/game/domain/game/PlayerHand.kt rename to shared/src/commonMain/kotlin/eventDemo/shared/game/PlayerHand.kt index 7ddf68b..1e6fffc 100644 --- a/src/main/kotlin/eventDemo/contexts/game/domain/game/PlayerHand.kt +++ b/shared/src/commonMain/kotlin/eventDemo/shared/game/PlayerHand.kt @@ -1,5 +1,6 @@ -package eventDemo.contexts.game.domain.game +package eventDemo.shared.game +import kotlin.jvm.JvmInline import kotlinx.serialization.Serializable @Serializable diff --git a/src/main/kotlin/eventDemo/contexts/game/application/command/models/GameCommand.kt b/shared/src/commonMain/kotlin/eventDemo/shared/game/command/GameCommand.kt similarity index 50% rename from src/main/kotlin/eventDemo/contexts/game/application/command/models/GameCommand.kt rename to shared/src/commonMain/kotlin/eventDemo/shared/game/command/GameCommand.kt index 3b7ed9b..fe0c026 100644 --- a/src/main/kotlin/eventDemo/contexts/game/application/command/models/GameCommand.kt +++ b/shared/src/commonMain/kotlin/eventDemo/shared/game/command/GameCommand.kt @@ -1,9 +1,9 @@ -package eventDemo.contexts.game.application.command.models +package eventDemo.shared.game.command -import eventDemo.contexts.game.domain.game.GameId -import eventDemo.contexts.game.infrastructure.persistence.serializers.GameIdSerializer -import eventDemo.libs.command.Command -import eventDemo.sharedKernel.UserId +import eventDemo.shared.command.Command +import eventDemo.shared.ids.GameId +import eventDemo.shared.ids.UserId +import eventDemo.shared.serializers.GameIdSerializer import kotlinx.serialization.Serializable @Serializable diff --git a/src/main/kotlin/eventDemo/contexts/game/application/command/models/JoinTheGameCommand.kt b/shared/src/commonMain/kotlin/eventDemo/shared/game/command/JoinTheGameCommand.kt similarity index 61% rename from src/main/kotlin/eventDemo/contexts/game/application/command/models/JoinTheGameCommand.kt rename to shared/src/commonMain/kotlin/eventDemo/shared/game/command/JoinTheGameCommand.kt index fe94917..c7b6dda 100644 --- a/src/main/kotlin/eventDemo/contexts/game/application/command/models/JoinTheGameCommand.kt +++ b/shared/src/commonMain/kotlin/eventDemo/shared/game/command/JoinTheGameCommand.kt @@ -1,9 +1,9 @@ -package eventDemo.contexts.game.application.command.models +package eventDemo.shared.game.command -import eventDemo.contexts.game.domain.game.GameId -import eventDemo.contexts.game.infrastructure.persistence.serializers.GameIdSerializer -import eventDemo.libs.command.CommandId -import eventDemo.sharedKernel.UserId +import eventDemo.shared.ids.CommandId +import eventDemo.shared.ids.GameId +import eventDemo.shared.ids.UserId +import eventDemo.shared.serializers.GameIdSerializer import kotlinx.serialization.Serializable /** diff --git a/src/main/kotlin/eventDemo/contexts/game/application/command/models/PlayCardCommand.kt b/shared/src/commonMain/kotlin/eventDemo/shared/game/command/PlayCardCommand.kt similarity index 55% rename from src/main/kotlin/eventDemo/contexts/game/application/command/models/PlayCardCommand.kt rename to shared/src/commonMain/kotlin/eventDemo/shared/game/command/PlayCardCommand.kt index 4fc874b..b614e3b 100644 --- a/src/main/kotlin/eventDemo/contexts/game/application/command/models/PlayCardCommand.kt +++ b/shared/src/commonMain/kotlin/eventDemo/shared/game/command/PlayCardCommand.kt @@ -1,12 +1,12 @@ -package eventDemo.contexts.game.application.command.models +package eventDemo.shared.game.command -import eventDemo.contexts.game.domain.game.Card -import eventDemo.contexts.game.domain.game.GameId -import eventDemo.contexts.game.domain.game.Player -import eventDemo.contexts.game.infrastructure.persistence.serializers.GameIdSerializer -import eventDemo.contexts.game.infrastructure.persistence.serializers.PlayerIdSerializer -import eventDemo.libs.command.CommandId -import eventDemo.sharedKernel.UserId +import eventDemo.shared.game.Card +import eventDemo.shared.game.Player +import eventDemo.shared.ids.CommandId +import eventDemo.shared.ids.GameId +import eventDemo.shared.ids.UserId +import eventDemo.shared.serializers.GameIdSerializer +import eventDemo.shared.serializers.PlayerIdSerializer import kotlinx.serialization.Serializable /** diff --git a/src/main/kotlin/eventDemo/contexts/game/application/command/models/ReadyToPlayCommand.kt b/shared/src/commonMain/kotlin/eventDemo/shared/game/command/ReadyToPlayCommand.kt similarity index 54% rename from src/main/kotlin/eventDemo/contexts/game/application/command/models/ReadyToPlayCommand.kt rename to shared/src/commonMain/kotlin/eventDemo/shared/game/command/ReadyToPlayCommand.kt index 143bda9..471d69e 100644 --- a/src/main/kotlin/eventDemo/contexts/game/application/command/models/ReadyToPlayCommand.kt +++ b/shared/src/commonMain/kotlin/eventDemo/shared/game/command/ReadyToPlayCommand.kt @@ -1,11 +1,11 @@ -package eventDemo.contexts.game.application.command.models +package eventDemo.shared.game.command -import eventDemo.contexts.game.domain.game.GameId -import eventDemo.contexts.game.domain.game.Player -import eventDemo.contexts.game.infrastructure.persistence.serializers.GameIdSerializer -import eventDemo.contexts.game.infrastructure.persistence.serializers.PlayerIdSerializer -import eventDemo.libs.command.CommandId -import eventDemo.sharedKernel.UserId +import eventDemo.shared.game.Player +import eventDemo.shared.ids.CommandId +import eventDemo.shared.ids.GameId +import eventDemo.shared.ids.UserId +import eventDemo.shared.serializers.GameIdSerializer +import eventDemo.shared.serializers.PlayerIdSerializer import kotlinx.serialization.Serializable /** diff --git a/src/main/kotlin/eventDemo/contexts/game/application/command/models/TakeCartFromDrawPileCommand.kt b/shared/src/commonMain/kotlin/eventDemo/shared/game/command/TakeCartFromDrawPileCommand.kt similarity index 50% rename from src/main/kotlin/eventDemo/contexts/game/application/command/models/TakeCartFromDrawPileCommand.kt rename to shared/src/commonMain/kotlin/eventDemo/shared/game/command/TakeCartFromDrawPileCommand.kt index ed5b3a5..9fc8006 100644 --- a/src/main/kotlin/eventDemo/contexts/game/application/command/models/TakeCartFromDrawPileCommand.kt +++ b/shared/src/commonMain/kotlin/eventDemo/shared/game/command/TakeCartFromDrawPileCommand.kt @@ -1,15 +1,17 @@ -package eventDemo.contexts.game.application.command.models +package eventDemo.shared.game.command -import eventDemo.contexts.game.domain.game.GameId -import eventDemo.contexts.game.domain.game.Player -import eventDemo.contexts.game.infrastructure.persistence.serializers.GameIdSerializer -import eventDemo.contexts.game.infrastructure.persistence.serializers.PlayerIdSerializer -import eventDemo.libs.command.CommandId -import eventDemo.sharedKernel.UserId +import eventDemo.shared.game.Player +import eventDemo.shared.ids.CommandId +import eventDemo.shared.ids.GameId +import eventDemo.shared.ids.UserId +import eventDemo.shared.serializers.GameIdSerializer +import eventDemo.shared.serializers.PlayerIdSerializer import kotlinx.serialization.Serializable /** - * A command to perform an action to play a new card + * A command to draw card on draw pile. + * + * Is can be triggered when you cannot play any card in your hand. */ @Serializable data class TakeCartFromDrawPileCommand( diff --git a/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/ItsTheTurnOfNotification.kt b/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/ItsTheTurnOfNotification.kt new file mode 100644 index 0000000..fc1ef53 --- /dev/null +++ b/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/ItsTheTurnOfNotification.kt @@ -0,0 +1,13 @@ +package eventDemo.shared.game.notification + +import eventDemo.shared.game.Player +import eventDemo.shared.serializers.UUIDSerializer +import kotlinx.serialization.Serializable +import kotlin.uuid.Uuid + +@Serializable +data class ItsTheTurnOfNotification( + @Serializable(with = UUIDSerializer::class) + override val id: Uuid = Uuid.random(), + val player: Player, +) : Notification diff --git a/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/Notification.kt b/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/Notification.kt new file mode 100644 index 0000000..810229b --- /dev/null +++ b/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/Notification.kt @@ -0,0 +1,11 @@ +package eventDemo.shared.game.notification + +import eventDemo.shared.serializers.UUIDSerializer +import kotlinx.serialization.Serializable +import kotlin.uuid.Uuid + +@Serializable +sealed interface Notification { + @Serializable(with = UUIDSerializer::class) + val id: Uuid +} diff --git a/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/PilesShuffledNotification.kt b/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/PilesShuffledNotification.kt new file mode 100644 index 0000000..47ea0c7 --- /dev/null +++ b/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/PilesShuffledNotification.kt @@ -0,0 +1,11 @@ +package eventDemo.shared.game.notification + +import eventDemo.shared.serializers.UUIDSerializer +import kotlinx.serialization.Serializable +import kotlin.uuid.Uuid + +@Serializable +data class PilesShuffledNotification( + @Serializable(with = UUIDSerializer::class) + override val id: Uuid = Uuid.random(), +) : Notification diff --git a/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/PlayerAsJoinTheGameNotification.kt b/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/PlayerAsJoinTheGameNotification.kt new file mode 100644 index 0000000..cfc0413 --- /dev/null +++ b/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/PlayerAsJoinTheGameNotification.kt @@ -0,0 +1,13 @@ +package eventDemo.shared.game.notification + +import eventDemo.shared.game.Player +import eventDemo.shared.serializers.UUIDSerializer +import kotlinx.serialization.Serializable +import kotlin.uuid.Uuid + +@Serializable +data class PlayerAsJoinTheGameNotification( + @Serializable(with = UUIDSerializer::class) + override val id: Uuid = Uuid.random(), + val player: Player, +) : Notification diff --git a/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/PlayerAsPlayACardNotification.kt b/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/PlayerAsPlayACardNotification.kt new file mode 100644 index 0000000..3b2e956 --- /dev/null +++ b/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/PlayerAsPlayACardNotification.kt @@ -0,0 +1,15 @@ +package eventDemo.shared.game.notification + +import eventDemo.shared.game.Card +import eventDemo.shared.game.Player +import eventDemo.shared.serializers.UUIDSerializer +import kotlinx.serialization.Serializable +import kotlin.uuid.Uuid + +@Serializable +data class PlayerAsPlayACardNotification( + @Serializable(with = UUIDSerializer::class) + override val id: Uuid = Uuid.random(), + val playerId: Player.PlayerId, + val card: Card, +) : Notification diff --git a/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/PlayerHavePassNotification.kt b/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/PlayerHavePassNotification.kt new file mode 100644 index 0000000..01667ce --- /dev/null +++ b/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/PlayerHavePassNotification.kt @@ -0,0 +1,13 @@ +package eventDemo.shared.game.notification + +import eventDemo.shared.game.Player +import eventDemo.shared.serializers.UUIDSerializer +import kotlinx.serialization.Serializable +import kotlin.uuid.Uuid + +@Serializable +data class PlayerHavePassNotification( + @Serializable(with = UUIDSerializer::class) + override val id: Uuid = Uuid.random(), + val playerId: Player.PlayerId, +) : Notification diff --git a/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/PlayerWasReadyNotification.kt b/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/PlayerWasReadyNotification.kt new file mode 100644 index 0000000..2d30c1a --- /dev/null +++ b/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/PlayerWasReadyNotification.kt @@ -0,0 +1,13 @@ +package eventDemo.shared.game.notification + +import eventDemo.shared.game.Player +import eventDemo.shared.serializers.UUIDSerializer +import kotlinx.serialization.Serializable +import kotlin.uuid.Uuid + +@Serializable +data class PlayerWasReadyNotification( + @Serializable(with = UUIDSerializer::class) + override val id: Uuid = Uuid.random(), + val playerId: Player.PlayerId, +) : Notification diff --git a/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/PlayerWinNotification.kt b/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/PlayerWinNotification.kt new file mode 100644 index 0000000..e1fb2cb --- /dev/null +++ b/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/PlayerWinNotification.kt @@ -0,0 +1,13 @@ +package eventDemo.shared.game.notification + +import eventDemo.shared.game.Player +import eventDemo.shared.serializers.UUIDSerializer +import kotlinx.serialization.Serializable +import kotlin.uuid.Uuid + +@Serializable +data class PlayerWinNotification( + @Serializable(with = UUIDSerializer::class) + override val id: Uuid = Uuid.random(), + val playerId: Player.PlayerId, +) : Notification diff --git a/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/TheGameWasStartedNotification.kt b/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/TheGameWasStartedNotification.kt new file mode 100644 index 0000000..644c966 --- /dev/null +++ b/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/TheGameWasStartedNotification.kt @@ -0,0 +1,13 @@ +package eventDemo.shared.game.notification + +import eventDemo.shared.game.Card +import eventDemo.shared.serializers.UUIDSerializer +import kotlinx.serialization.Serializable +import kotlin.uuid.Uuid + +@Serializable +data class TheGameWasStartedNotification( + @Serializable(with = UUIDSerializer::class) + override val id: Uuid = Uuid.random(), + val hand: Set, +) : Notification diff --git a/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/WelcomeToTheGameNotification.kt b/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/WelcomeToTheGameNotification.kt new file mode 100644 index 0000000..38e4908 --- /dev/null +++ b/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/WelcomeToTheGameNotification.kt @@ -0,0 +1,13 @@ +package eventDemo.shared.game.notification + +import eventDemo.shared.game.Player +import eventDemo.shared.serializers.UUIDSerializer +import kotlinx.serialization.Serializable +import kotlin.uuid.Uuid + +@Serializable +data class WelcomeToTheGameNotification( + @Serializable(with = UUIDSerializer::class) + override val id: Uuid = Uuid.random(), + val players: Set, +) : Notification diff --git a/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/YourNewCardNotification.kt b/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/YourNewCardNotification.kt new file mode 100644 index 0000000..a017b96 --- /dev/null +++ b/shared/src/commonMain/kotlin/eventDemo/shared/game/notification/YourNewCardNotification.kt @@ -0,0 +1,13 @@ +package eventDemo.shared.game.notification + +import eventDemo.shared.game.Card +import eventDemo.shared.serializers.UUIDSerializer +import kotlinx.serialization.Serializable +import kotlin.uuid.Uuid + +@Serializable +data class YourNewCardNotification( + @Serializable(with = UUIDSerializer::class) + override val id: Uuid = Uuid.random(), + val cards: Set, +) : Notification diff --git a/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/projections/models/GameList.kt b/shared/src/commonMain/kotlin/eventDemo/shared/game/projection/GameList.kt similarity index 58% rename from src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/projections/models/GameList.kt rename to shared/src/commonMain/kotlin/eventDemo/shared/game/projection/GameList.kt index 8993b0d..2070cc2 100644 --- a/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/projections/models/GameList.kt +++ b/shared/src/commonMain/kotlin/eventDemo/shared/game/projection/GameList.kt @@ -1,11 +1,11 @@ -package eventDemo.contexts.game.infrastructure.persistence.projections.models +package eventDemo.shared.game.projection -import eventDemo.contexts.game.domain.game.GameId -import eventDemo.contexts.game.domain.game.Player +import eventDemo.shared.game.Player +import eventDemo.shared.ids.GameId import kotlinx.serialization.Serializable /** - * This [projection][Projection] is used to list all current games + * This [projection][GameProjection] is used to list all current games */ @Serializable data class GameList( diff --git a/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/projections/models/GameProjection.kt b/shared/src/commonMain/kotlin/eventDemo/shared/game/projection/GameProjection.kt similarity index 53% rename from src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/projections/models/GameProjection.kt rename to shared/src/commonMain/kotlin/eventDemo/shared/game/projection/GameProjection.kt index 99c4f72..de30206 100644 --- a/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/projections/models/GameProjection.kt +++ b/shared/src/commonMain/kotlin/eventDemo/shared/game/projection/GameProjection.kt @@ -1,4 +1,4 @@ -package eventDemo.contexts.game.infrastructure.persistence.projections.models +package eventDemo.shared.game.projection import kotlinx.serialization.Serializable diff --git a/shared/src/commonMain/kotlin/eventDemo/shared/http/HttpErrorBadRequest.kt b/shared/src/commonMain/kotlin/eventDemo/shared/http/HttpErrorBadRequest.kt new file mode 100644 index 0000000..7ac182c --- /dev/null +++ b/shared/src/commonMain/kotlin/eventDemo/shared/http/HttpErrorBadRequest.kt @@ -0,0 +1,19 @@ +package eventDemo.shared.http + +import kotlinx.serialization.Serializable + +@Serializable +class HttpErrorBadRequest( + val title: String = "Bad Request", + val invalidParams: List = emptyList(), +) { + // Hardcoded rather than derived from io.ktor.http.HttpStatusCode.BadRequest, since `shared` + // (multiplatform, no Ktor dependency) cannot depend on the Ktor server APIs backend uses. + val statusCode: Int = 400 + + @Serializable + data class InvalidParam( + val name: String, + val reason: String, + ) +} diff --git a/shared/src/commonMain/kotlin/eventDemo/shared/ids/AggregateId.kt b/shared/src/commonMain/kotlin/eventDemo/shared/ids/AggregateId.kt new file mode 100644 index 0000000..ffc325a --- /dev/null +++ b/shared/src/commonMain/kotlin/eventDemo/shared/ids/AggregateId.kt @@ -0,0 +1,11 @@ +package eventDemo.shared.ids + +import kotlin.uuid.Uuid + +/** + * Represent an ID for one aggregate, and it used in events + * @see eventDemo.libs.eventSource.Event + */ +interface AggregateId { + val id: Uuid +} diff --git a/shared/src/commonMain/kotlin/eventDemo/shared/ids/CommandId.kt b/shared/src/commonMain/kotlin/eventDemo/shared/ids/CommandId.kt new file mode 100644 index 0000000..fb99c0a --- /dev/null +++ b/shared/src/commonMain/kotlin/eventDemo/shared/ids/CommandId.kt @@ -0,0 +1,20 @@ +package eventDemo.shared.ids + +import eventDemo.shared.serializers.CommandIdSerializer +import kotlin.jvm.JvmInline +import kotlinx.serialization.Serializable +import kotlin.uuid.Uuid + +/** + * An ID for the [eventDemo.shared.command.Command] + */ +@JvmInline +@Serializable(with = CommandIdSerializer::class) +value class CommandId( + private val id: Uuid = Uuid.random(), +) { + constructor(id: String) : this(Uuid.parse(id)) + + override fun toString(): String = + id.toString() +} diff --git a/shared/src/commonMain/kotlin/eventDemo/shared/ids/EventId.kt b/shared/src/commonMain/kotlin/eventDemo/shared/ids/EventId.kt new file mode 100644 index 0000000..26d724e --- /dev/null +++ b/shared/src/commonMain/kotlin/eventDemo/shared/ids/EventId.kt @@ -0,0 +1,13 @@ +package eventDemo.shared.ids + +import eventDemo.shared.serializers.UUIDSerializer +import kotlin.jvm.JvmInline +import kotlinx.serialization.Serializable +import kotlin.uuid.Uuid + +@JvmInline +@Serializable +value class EventId( + @Serializable(with = UUIDSerializer::class) + val id: Uuid = Uuid.random(), +) diff --git a/src/main/kotlin/eventDemo/contexts/game/domain/game/GameId.kt b/shared/src/commonMain/kotlin/eventDemo/shared/ids/GameId.kt similarity index 54% rename from src/main/kotlin/eventDemo/contexts/game/domain/game/GameId.kt rename to shared/src/commonMain/kotlin/eventDemo/shared/ids/GameId.kt index 63401b9..42be222 100644 --- a/src/main/kotlin/eventDemo/contexts/game/domain/game/GameId.kt +++ b/shared/src/commonMain/kotlin/eventDemo/shared/ids/GameId.kt @@ -1,9 +1,9 @@ -package eventDemo.contexts.game.domain.game +package eventDemo.shared.ids -import eventDemo.libs.eventSource.AggregateId -import eventDemo.libs.serializer.UUIDSerializer +import eventDemo.shared.serializers.UUIDSerializer +import kotlin.jvm.JvmInline import kotlinx.serialization.Serializable -import java.util.UUID +import kotlin.uuid.Uuid /** * An [AggregateId] for a game. @@ -12,7 +12,7 @@ import java.util.UUID @Serializable value class GameId( @Serializable(with = UUIDSerializer::class) - override val id: UUID = UUID.randomUUID(), + override val id: Uuid = Uuid.random(), ) : AggregateId { override fun toString(): String = id.toString() diff --git a/shared/src/commonMain/kotlin/eventDemo/shared/ids/UserId.kt b/shared/src/commonMain/kotlin/eventDemo/shared/ids/UserId.kt new file mode 100644 index 0000000..cbefaa7 --- /dev/null +++ b/shared/src/commonMain/kotlin/eventDemo/shared/ids/UserId.kt @@ -0,0 +1,13 @@ +package eventDemo.shared.ids + +import eventDemo.shared.serializers.UUIDSerializer +import kotlin.jvm.JvmInline +import kotlinx.serialization.Serializable +import kotlin.uuid.Uuid + +@Serializable +@JvmInline +value class UserId( + @Serializable(with = UUIDSerializer::class) + override val id: Uuid = Uuid.random(), +) : AggregateId diff --git a/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/serializers/CommandIdSerializer.kt b/shared/src/commonMain/kotlin/eventDemo/shared/serializers/CommandIdSerializer.kt similarity index 86% rename from src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/serializers/CommandIdSerializer.kt rename to shared/src/commonMain/kotlin/eventDemo/shared/serializers/CommandIdSerializer.kt index cbe82e9..74e1845 100644 --- a/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/serializers/CommandIdSerializer.kt +++ b/shared/src/commonMain/kotlin/eventDemo/shared/serializers/CommandIdSerializer.kt @@ -1,6 +1,6 @@ -package eventDemo.contexts.game.infrastructure.persistence.serializers +package eventDemo.shared.serializers -import eventDemo.libs.command.CommandId +import eventDemo.shared.ids.CommandId import kotlinx.serialization.KSerializer import kotlinx.serialization.descriptors.PrimitiveKind import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor diff --git a/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/serializers/EventIdSerializer.kt b/shared/src/commonMain/kotlin/eventDemo/shared/serializers/EventIdSerializer.kt similarity index 77% rename from src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/serializers/EventIdSerializer.kt rename to shared/src/commonMain/kotlin/eventDemo/shared/serializers/EventIdSerializer.kt index 87096c8..a9b19ad 100644 --- a/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/serializers/EventIdSerializer.kt +++ b/shared/src/commonMain/kotlin/eventDemo/shared/serializers/EventIdSerializer.kt @@ -1,17 +1,17 @@ -package eventDemo.contexts.game.infrastructure.persistence.serializers +package eventDemo.shared.serializers -import eventDemo.libs.eventSource.EventId +import eventDemo.shared.ids.EventId import kotlinx.serialization.KSerializer import kotlinx.serialization.descriptors.PrimitiveKind import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder -import java.util.UUID +import kotlin.uuid.Uuid object EventIdSerializer : KSerializer { override fun deserialize(decoder: Decoder): EventId = - EventId(UUID.fromString(decoder.decodeString())) + EventId(Uuid.parse(decoder.decodeString())) override fun serialize( encoder: Encoder, diff --git a/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/serializers/GameIdSerializer.kt b/shared/src/commonMain/kotlin/eventDemo/shared/serializers/GameIdSerializer.kt similarity index 76% rename from src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/serializers/GameIdSerializer.kt rename to shared/src/commonMain/kotlin/eventDemo/shared/serializers/GameIdSerializer.kt index 9027285..4b932fc 100644 --- a/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/serializers/GameIdSerializer.kt +++ b/shared/src/commonMain/kotlin/eventDemo/shared/serializers/GameIdSerializer.kt @@ -1,17 +1,17 @@ -package eventDemo.contexts.game.infrastructure.persistence.serializers +package eventDemo.shared.serializers -import eventDemo.contexts.game.domain.game.GameId +import eventDemo.shared.ids.GameId import kotlinx.serialization.KSerializer import kotlinx.serialization.descriptors.PrimitiveKind import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder -import java.util.UUID +import kotlin.uuid.Uuid object GameIdSerializer : KSerializer { override fun deserialize(decoder: Decoder): GameId = - GameId(UUID.fromString(decoder.decodeString())) + GameId(Uuid.parse(decoder.decodeString())) override fun serialize( encoder: Encoder, diff --git a/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/serializers/PlayerIdSerializer.kt b/shared/src/commonMain/kotlin/eventDemo/shared/serializers/PlayerIdSerializer.kt similarity index 76% rename from src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/serializers/PlayerIdSerializer.kt rename to shared/src/commonMain/kotlin/eventDemo/shared/serializers/PlayerIdSerializer.kt index 977a25e..942ce30 100644 --- a/src/main/kotlin/eventDemo/contexts/game/infrastructure/persistence/serializers/PlayerIdSerializer.kt +++ b/shared/src/commonMain/kotlin/eventDemo/shared/serializers/PlayerIdSerializer.kt @@ -1,17 +1,17 @@ -package eventDemo.contexts.game.infrastructure.persistence.serializers +package eventDemo.shared.serializers -import eventDemo.contexts.game.domain.game.Player +import eventDemo.shared.game.Player import kotlinx.serialization.KSerializer import kotlinx.serialization.descriptors.PrimitiveKind import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder -import java.util.UUID +import kotlin.uuid.Uuid object PlayerIdSerializer : KSerializer { override fun deserialize(decoder: Decoder): Player.PlayerId = - Player.PlayerId(UUID.fromString(decoder.decodeString())) + Player.PlayerId(Uuid.parse(decoder.decodeString())) override fun serialize( encoder: Encoder, diff --git a/src/main/kotlin/eventDemo/libs/serializer/UUIDSerializer.kt b/shared/src/commonMain/kotlin/eventDemo/shared/serializers/UUIDSerializer.kt similarity index 70% rename from src/main/kotlin/eventDemo/libs/serializer/UUIDSerializer.kt rename to shared/src/commonMain/kotlin/eventDemo/shared/serializers/UUIDSerializer.kt index 92b186d..382b5d6 100644 --- a/src/main/kotlin/eventDemo/libs/serializer/UUIDSerializer.kt +++ b/shared/src/commonMain/kotlin/eventDemo/shared/serializers/UUIDSerializer.kt @@ -1,4 +1,4 @@ -package eventDemo.libs.serializer +package eventDemo.shared.serializers import kotlinx.serialization.KSerializer import kotlinx.serialization.descriptors.PrimitiveKind @@ -6,15 +6,15 @@ import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder -import java.util.UUID +import kotlin.uuid.Uuid -object UUIDSerializer : KSerializer { - override fun deserialize(decoder: Decoder): UUID = - UUID.fromString(decoder.decodeString()) +object UUIDSerializer : KSerializer { + override fun deserialize(decoder: Decoder): Uuid = + Uuid.parse(decoder.decodeString()) override fun serialize( encoder: Encoder, - value: UUID, + value: Uuid, ) { encoder.encodeString(value.toString()) } diff --git a/src/main/kotlin/eventDemo/contexts/game/application/notification/models/ItsTheTurnOfNotification.kt b/src/main/kotlin/eventDemo/contexts/game/application/notification/models/ItsTheTurnOfNotification.kt deleted file mode 100644 index 76a9e78..0000000 --- a/src/main/kotlin/eventDemo/contexts/game/application/notification/models/ItsTheTurnOfNotification.kt +++ /dev/null @@ -1,13 +0,0 @@ -package eventDemo.contexts.game.application.notification.models - -import eventDemo.contexts.game.domain.game.Player -import eventDemo.libs.serializer.UUIDSerializer -import kotlinx.serialization.Serializable -import java.util.UUID - -@Serializable -data class ItsTheTurnOfNotification( - @Serializable(with = UUIDSerializer::class) - override val id: UUID = UUID.randomUUID(), - val player: Player, -) : Notification diff --git a/src/main/kotlin/eventDemo/contexts/game/application/notification/models/Notification.kt b/src/main/kotlin/eventDemo/contexts/game/application/notification/models/Notification.kt deleted file mode 100644 index b4a4fa0..0000000 --- a/src/main/kotlin/eventDemo/contexts/game/application/notification/models/Notification.kt +++ /dev/null @@ -1,11 +0,0 @@ -package eventDemo.contexts.game.application.notification.models - -import eventDemo.libs.serializer.UUIDSerializer -import kotlinx.serialization.Serializable -import java.util.UUID - -@Serializable -sealed interface Notification { - @Serializable(with = UUIDSerializer::class) - val id: UUID -} diff --git a/src/main/kotlin/eventDemo/contexts/game/application/notification/models/PilesShuffledNotification.kt b/src/main/kotlin/eventDemo/contexts/game/application/notification/models/PilesShuffledNotification.kt deleted file mode 100644 index 90b5e83..0000000 --- a/src/main/kotlin/eventDemo/contexts/game/application/notification/models/PilesShuffledNotification.kt +++ /dev/null @@ -1,11 +0,0 @@ -package eventDemo.contexts.game.application.notification.models - -import eventDemo.libs.serializer.UUIDSerializer -import kotlinx.serialization.Serializable -import java.util.UUID - -@Serializable -data class PilesShuffledNotification( - @Serializable(with = UUIDSerializer::class) - override val id: UUID = UUID.randomUUID(), -) : Notification diff --git a/src/main/kotlin/eventDemo/contexts/game/application/notification/models/PlayerAsJoinTheGameNotification.kt b/src/main/kotlin/eventDemo/contexts/game/application/notification/models/PlayerAsJoinTheGameNotification.kt deleted file mode 100644 index ade9911..0000000 --- a/src/main/kotlin/eventDemo/contexts/game/application/notification/models/PlayerAsJoinTheGameNotification.kt +++ /dev/null @@ -1,13 +0,0 @@ -package eventDemo.contexts.game.application.notification.models - -import eventDemo.contexts.game.domain.game.Player -import eventDemo.libs.serializer.UUIDSerializer -import kotlinx.serialization.Serializable -import java.util.UUID - -@Serializable -data class PlayerAsJoinTheGameNotification( - @Serializable(with = UUIDSerializer::class) - override val id: UUID = UUID.randomUUID(), - val player: Player, -) : Notification diff --git a/src/main/kotlin/eventDemo/contexts/game/application/notification/models/PlayerAsPlayACardNotification.kt b/src/main/kotlin/eventDemo/contexts/game/application/notification/models/PlayerAsPlayACardNotification.kt deleted file mode 100644 index 0d6782e..0000000 --- a/src/main/kotlin/eventDemo/contexts/game/application/notification/models/PlayerAsPlayACardNotification.kt +++ /dev/null @@ -1,15 +0,0 @@ -package eventDemo.contexts.game.application.notification.models - -import eventDemo.contexts.game.domain.game.Card -import eventDemo.contexts.game.domain.game.Player -import eventDemo.libs.serializer.UUIDSerializer -import kotlinx.serialization.Serializable -import java.util.UUID - -@Serializable -data class PlayerAsPlayACardNotification( - @Serializable(with = UUIDSerializer::class) - override val id: UUID = UUID.randomUUID(), - val playerId: Player.PlayerId, - val card: Card, -) : Notification diff --git a/src/main/kotlin/eventDemo/contexts/game/application/notification/models/PlayerHavePassNotification.kt b/src/main/kotlin/eventDemo/contexts/game/application/notification/models/PlayerHavePassNotification.kt deleted file mode 100644 index ac25fa1..0000000 --- a/src/main/kotlin/eventDemo/contexts/game/application/notification/models/PlayerHavePassNotification.kt +++ /dev/null @@ -1,13 +0,0 @@ -package eventDemo.contexts.game.application.notification.models - -import eventDemo.contexts.game.domain.game.Player -import eventDemo.libs.serializer.UUIDSerializer -import kotlinx.serialization.Serializable -import java.util.UUID - -@Serializable -data class PlayerHavePassNotification( - @Serializable(with = UUIDSerializer::class) - override val id: UUID = UUID.randomUUID(), - val playerId: Player.PlayerId, -) : Notification diff --git a/src/main/kotlin/eventDemo/contexts/game/application/notification/models/PlayerWasReadyNotification.kt b/src/main/kotlin/eventDemo/contexts/game/application/notification/models/PlayerWasReadyNotification.kt deleted file mode 100644 index 9eb03e4..0000000 --- a/src/main/kotlin/eventDemo/contexts/game/application/notification/models/PlayerWasReadyNotification.kt +++ /dev/null @@ -1,13 +0,0 @@ -package eventDemo.contexts.game.application.notification.models - -import eventDemo.contexts.game.domain.game.Player -import eventDemo.libs.serializer.UUIDSerializer -import kotlinx.serialization.Serializable -import java.util.UUID - -@Serializable -data class PlayerWasReadyNotification( - @Serializable(with = UUIDSerializer::class) - override val id: UUID = UUID.randomUUID(), - val playerId: Player.PlayerId, -) : Notification diff --git a/src/main/kotlin/eventDemo/contexts/game/application/notification/models/PlayerWinNotification.kt b/src/main/kotlin/eventDemo/contexts/game/application/notification/models/PlayerWinNotification.kt deleted file mode 100644 index 4b04a49..0000000 --- a/src/main/kotlin/eventDemo/contexts/game/application/notification/models/PlayerWinNotification.kt +++ /dev/null @@ -1,13 +0,0 @@ -package eventDemo.contexts.game.application.notification.models - -import eventDemo.contexts.game.domain.game.Player -import eventDemo.libs.serializer.UUIDSerializer -import kotlinx.serialization.Serializable -import java.util.UUID - -@Serializable -data class PlayerWinNotification( - @Serializable(with = UUIDSerializer::class) - override val id: UUID = UUID.randomUUID(), - val playerId: Player.PlayerId, -) : Notification diff --git a/src/main/kotlin/eventDemo/contexts/game/application/notification/models/TheGameWasStartedNotification.kt b/src/main/kotlin/eventDemo/contexts/game/application/notification/models/TheGameWasStartedNotification.kt deleted file mode 100644 index 34e8a9e..0000000 --- a/src/main/kotlin/eventDemo/contexts/game/application/notification/models/TheGameWasStartedNotification.kt +++ /dev/null @@ -1,13 +0,0 @@ -package eventDemo.contexts.game.application.notification.models - -import eventDemo.contexts.game.domain.game.Card -import eventDemo.libs.serializer.UUIDSerializer -import kotlinx.serialization.Serializable -import java.util.UUID - -@Serializable -data class TheGameWasStartedNotification( - @Serializable(with = UUIDSerializer::class) - override val id: UUID = UUID.randomUUID(), - val hand: Set, -) : Notification diff --git a/src/main/kotlin/eventDemo/contexts/game/application/notification/models/WelcomeToTheGameNotification.kt b/src/main/kotlin/eventDemo/contexts/game/application/notification/models/WelcomeToTheGameNotification.kt deleted file mode 100644 index 84ad0eb..0000000 --- a/src/main/kotlin/eventDemo/contexts/game/application/notification/models/WelcomeToTheGameNotification.kt +++ /dev/null @@ -1,13 +0,0 @@ -package eventDemo.contexts.game.application.notification.models - -import eventDemo.contexts.game.domain.game.Player -import eventDemo.libs.serializer.UUIDSerializer -import kotlinx.serialization.Serializable -import java.util.UUID - -@Serializable -data class WelcomeToTheGameNotification( - @Serializable(with = UUIDSerializer::class) - override val id: UUID = UUID.randomUUID(), - val players: Set, -) : Notification diff --git a/src/main/kotlin/eventDemo/contexts/game/application/notification/models/YourNewCardNotification.kt b/src/main/kotlin/eventDemo/contexts/game/application/notification/models/YourNewCardNotification.kt deleted file mode 100644 index 64ad41c..0000000 --- a/src/main/kotlin/eventDemo/contexts/game/application/notification/models/YourNewCardNotification.kt +++ /dev/null @@ -1,13 +0,0 @@ -package eventDemo.contexts.game.application.notification.models - -import eventDemo.contexts.game.domain.game.Card -import eventDemo.libs.serializer.UUIDSerializer -import kotlinx.serialization.Serializable -import java.util.UUID - -@Serializable -data class YourNewCardNotification( - @Serializable(with = UUIDSerializer::class) - override val id: UUID = UUID.randomUUID(), - val cards: Set, -) : Notification diff --git a/src/main/kotlin/eventDemo/libs/command/Command.kt b/src/main/kotlin/eventDemo/libs/command/Command.kt deleted file mode 100644 index 9faba9e..0000000 --- a/src/main/kotlin/eventDemo/libs/command/Command.kt +++ /dev/null @@ -1,28 +0,0 @@ -package eventDemo.libs.command - -import eventDemo.contexts.game.infrastructure.persistence.serializers.CommandIdSerializer -import kotlinx.serialization.Serializable -import java.util.UUID - -/** - * An ID for the [Command] - */ -@JvmInline -@Serializable(with = CommandIdSerializer::class) -value class CommandId( - private val id: UUID = UUID.randomUUID(), -) { - constructor(id: String) : this(UUID.fromString(id)) - - override fun toString(): String = - id.toString() -} - -/** - * Interface to represent a Command. - * - * A command is a request for an action. - */ -interface Command { - val id: CommandId -} diff --git a/src/main/kotlin/eventDemo/libs/eventSource/Event.kt b/src/main/kotlin/eventDemo/libs/eventSource/Event.kt deleted file mode 100644 index 2989a98..0000000 --- a/src/main/kotlin/eventDemo/libs/eventSource/Event.kt +++ /dev/null @@ -1,32 +0,0 @@ -package eventDemo.libs.eventSource - -import eventDemo.libs.serializer.UUIDSerializer -import kotlinx.datetime.Instant -import kotlinx.serialization.Serializable -import java.util.UUID - -/** - * Represent an ID for one aggregate, and it used in events - * @see Event - */ -interface AggregateId { - val id: UUID -} - -/** - * The basic interface for an Event - * @see eventDemo.libs.eventSource.eventStore.EventStream - */ -interface Event { - val eventId: EventId - val aggregateId: ID - val createdAt: Instant - val version: Int -} - -@JvmInline -@Serializable -value class EventId( - @Serializable(with = UUIDSerializer::class) - val id: UUID = UUID.randomUUID(), -) diff --git a/src/main/kotlin/eventDemo/libs/helpers/ReplaceValue.kt b/src/main/kotlin/eventDemo/libs/helpers/ReplaceValue.kt deleted file mode 100644 index 72dd2ed..0000000 --- a/src/main/kotlin/eventDemo/libs/helpers/ReplaceValue.kt +++ /dev/null @@ -1,25 +0,0 @@ -package eventDemo.libs.helpers - -inline fun Map.withReplacedValue( - toReplace: K, - transform: (V) -> V, -): Map = - mapValues { - if (it.key == toReplace) { - transform(it.value) - } else { - it.value - } - } - -inline fun Set.withReplacedValue( - toReplace: V, - transform: (V) -> V, -): Set = - map { - if (it == toReplace) { - transform(it) - } else { - it - } - }.toSet() diff --git a/src/main/kotlin/eventDemo/sharedKernel/UserId.kt b/src/main/kotlin/eventDemo/sharedKernel/UserId.kt deleted file mode 100644 index 7c6a20a..0000000 --- a/src/main/kotlin/eventDemo/sharedKernel/UserId.kt +++ /dev/null @@ -1,13 +0,0 @@ -package eventDemo.sharedKernel - -import eventDemo.libs.eventSource.AggregateId -import eventDemo.libs.serializer.UUIDSerializer -import kotlinx.serialization.Serializable -import java.util.UUID - -@Serializable -@JvmInline -value class UserId( - @Serializable(with = UUIDSerializer::class) - override val id: UUID = UUID.randomUUID(), -) : AggregateId