Umbau zu SCS

This commit is contained in:
stefan
2025-07-17 15:17:31 +02:00
parent 67c52f7381
commit 029b0c86bc
255 changed files with 6458 additions and 26663 deletions
+68
View File
@@ -0,0 +1,68 @@
plugins {
alias(libs.plugins.kotlin.multiplatform)
alias(libs.plugins.kotlin.serialization)
}
kotlin {
jvm()
js(IR) {
browser {
commonWebpackConfig {
outputFileName = "event-management.js"
}
@OptIn(org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalDistributionDsl::class)
distribution {
outputDirectory = layout.buildDirectory.dir("dist")
}
}
binaries.executable()
// NPM dependencies
useCommonJs()
nodejs {
testTask {
useMocha {
timeout = "10s"
}
}
}
}
sourceSets {
commonMain.dependencies {
implementation(project(":shared-kernel"))
implementation(libs.kotlinx.coroutines.core)
implementation(libs.kotlinx.serialization.json)
implementation(libs.kotlinx.datetime)
implementation(libs.uuid)
}
commonTest.dependencies {
implementation(libs.kotlin.test)
implementation(libs.kotlinx.coroutines.test)
}
jvmMain.dependencies {
implementation(libs.exposed.core)
implementation(libs.exposed.dao)
implementation(libs.exposed.jdbc)
implementation(libs.exposed.kotlinDatetime)
implementation(libs.ktor.server.core)
implementation(libs.ktor.server.contentNegotiation)
implementation(libs.ktor.server.serializationKotlinxJson)
}
jsMain.dependencies {
// Kotlin React dependencies with explicit versions
implementation("org.jetbrains.kotlin-wrappers:kotlin-react:${libs.versions.kotlinWrappers.get()}")
implementation("org.jetbrains.kotlin-wrappers:kotlin-emotion:${libs.versions.kotlinWrappers.get()}")
// NPM dependencies
implementation(npm("react", "18.2.0"))
implementation(npm("react-dom", "18.2.0"))
implementation(npm("react-to-web-component", "2.0.2"))
}
}
}
@@ -0,0 +1,15 @@
package at.mocode.events
/**
* Simple Event Management class for testing KMP configuration
*/
class EventManagement {
fun createEvent(name: String): String {
return "Event created: $name"
}
}
fun main() {
val eventManager = EventManagement()
println(eventManager.createEvent("Test Event"))
}
@@ -0,0 +1,132 @@
package at.mocode.events.domain.model
import at.mocode.enums.SparteE
import at.mocode.serializers.KotlinInstantSerializer
import at.mocode.serializers.KotlinLocalDateSerializer
import at.mocode.serializers.UuidSerializer
import com.benasher44.uuid.Uuid
import com.benasher44.uuid.uuid4
import kotlinx.datetime.Clock
import kotlinx.datetime.Instant
import kotlinx.datetime.LocalDate
import kotlinx.datetime.TimeZone
import kotlinx.serialization.Serializable
/**
* Domain model representing an event/competition in the event management system.
*
* This entity represents a sporting event that can contain multiple tournaments
* and competitions. It serves as the main aggregate root for event planning.
*
* @property veranstaltungId Unique internal identifier for this event (UUID).
* @property name Name of the event.
* @property beschreibung Description of the event.
* @property startDatum Start date of the event.
* @property endDatum End date of the event.
* @property ort Location where the event takes place.
* @property veranstalterVereinId ID of the organizing club/association.
* @property sparten List of sport disciplines included in this event.
* @property istAktiv Whether the event is currently active.
* @property istOeffentlich Whether the event is public.
* @property maxTeilnehmer Maximum number of participants (optional).
* @property anmeldeschluss Registration deadline.
* @property createdAt Timestamp when this record was created.
* @property updatedAt Timestamp when this record was last updated.
*/
@Serializable
data class Veranstaltung(
@Serializable(with = UuidSerializer::class)
val veranstaltungId: Uuid = uuid4(),
// Basic Information
var name: String,
var beschreibung: String? = null,
// Dates
@Serializable(with = KotlinLocalDateSerializer::class)
var startDatum: LocalDate,
@Serializable(with = KotlinLocalDateSerializer::class)
var endDatum: LocalDate,
// Location and Organization
var ort: String,
@Serializable(with = UuidSerializer::class)
var veranstalterVereinId: Uuid,
// Event Details
var sparten: List<SparteE> = emptyList(),
var istAktiv: Boolean = true,
var istOeffentlich: Boolean = true,
var maxTeilnehmer: Int? = null,
@Serializable(with = KotlinLocalDateSerializer::class)
var anmeldeschluss: LocalDate? = null,
// Audit Fields
@Serializable(with = KotlinInstantSerializer::class)
val createdAt: Instant = Clock.System.now(),
@Serializable(with = KotlinInstantSerializer::class)
var updatedAt: Instant = Clock.System.now()
) {
/**
* Checks if the event is currently accepting registrations.
*/
fun isRegistrationOpen(): Boolean {
// Simplified implementation - can be enhanced with proper date comparison
return istAktiv && anmeldeschluss != null
}
/**
* Returns the duration of the event in days.
*/
fun getDurationInDays(): Int {
return (endDatum.toEpochDays() - startDatum.toEpochDays()).toInt() + 1
}
/**
* Checks if the event spans multiple days.
*/
fun isMultiDay(): Boolean {
return startDatum != endDatum
}
/**
* Validates that the event data is consistent.
*/
fun validate(): List<String> {
val errors = mutableListOf<String>()
if (name.isBlank()) {
errors.add("Event name is required")
}
if (ort.isBlank()) {
errors.add("Event location is required")
}
if (endDatum < startDatum) {
errors.add("End date cannot be before start date")
}
anmeldeschluss?.let { deadline ->
if (deadline > startDatum) {
errors.add("Registration deadline cannot be after event start date")
}
}
maxTeilnehmer?.let { max ->
if (max <= 0) {
errors.add("Maximum participants must be positive")
}
}
return errors
}
/**
* Creates a copy of this event with updated timestamp.
*/
fun withUpdatedTimestamp(): Veranstaltung {
return this.copy(updatedAt = Clock.System.now())
}
}
@@ -0,0 +1,51 @@
package at.mocode.events.ui
import at.mocode.events.domain.model.Veranstaltung
/**
* Simple JS-specific utility functions for event management UI
*/
object EventUIUtils {
/**
* Formats an event for display in the browser
*/
fun formatEventForDisplay(event: Veranstaltung): String {
return buildString {
append("Event: ${event.name}")
append(" | Location: ${event.ort}")
append(" | From: ${event.startDatum} to: ${event.endDatum}")
if (event.beschreibung != null) {
append(" | Description: ${event.beschreibung}")
}
if (event.sparten.isNotEmpty()) {
append(" | Sports: ${event.sparten.joinToString(", ") { it.name }}")
}
}
}
/**
* Creates a simple HTML representation of an event
*/
fun createEventHtml(event: Veranstaltung): String {
return """
<div class="event-card">
<h3>${event.name}</h3>
<p><strong>Location:</strong> ${event.ort}</p>
<p><strong>Date:</strong> ${event.startDatum} - ${event.endDatum}</p>
${if (event.beschreibung != null) "<p><strong>Description:</strong> ${event.beschreibung}</p>" else ""}
${if (event.sparten.isNotEmpty())
"<p><strong>Sports:</strong> ${event.sparten.joinToString(", ") { it.name }}</p>"
else ""}
</div>
""".trimIndent()
}
}
/**
* Main entry point for the JS application
*/
fun main() {
console.log("Event Management JS module loaded successfully!")
console.log("React dependencies are available for UI development")
}