refactor: Migrate from monolithic to modular architecture
- Restructure project into domain-specific modules (core, masterdata, members, horses, events, infrastructure) - Create shared client components in common-ui module - Implement CI/CD workflows with GitHub Actions - Consolidate documentation in docs directory - Remove deprecated modules and documentation files - Add cleanup and migration scripts for transition - Update README with new project structure and setup instructions
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
alias(libs.plugins.kotlin.serialization)
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(projects.platform.platformDependencies)
|
||||
|
||||
// UUID handling
|
||||
api("com.benasher44:uuid:0.8.2")
|
||||
|
||||
// Serialization
|
||||
api("org.jetbrains.kotlinx:kotlinx-serialization-json")
|
||||
api("org.jetbrains.kotlinx:kotlinx-datetime")
|
||||
|
||||
testImplementation(projects.platform.platformTesting)
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package at.mocode.core.domain.event
|
||||
|
||||
import java.time.Instant
|
||||
import java.util.UUID
|
||||
|
||||
/**
|
||||
* Interface for all domain events in the system.
|
||||
* Domain events represent something that happened in the domain that domain experts care about.
|
||||
*/
|
||||
interface DomainEvent {
|
||||
/**
|
||||
* Unique identifier for this event instance.
|
||||
*/
|
||||
val eventId: UUID
|
||||
|
||||
/**
|
||||
* Timestamp when the event occurred.
|
||||
*/
|
||||
val timestamp: Instant
|
||||
|
||||
/**
|
||||
* Identifier of the aggregate that the event belongs to.
|
||||
*/
|
||||
val aggregateId: UUID
|
||||
|
||||
/**
|
||||
* Version of the aggregate after the event was applied.
|
||||
*/
|
||||
val version: Long
|
||||
}
|
||||
|
||||
/**
|
||||
* Base implementation of the DomainEvent interface.
|
||||
* Provides default implementations for common properties.
|
||||
*/
|
||||
abstract class BaseDomainEvent(
|
||||
override val eventId: UUID = UUID.randomUUID(),
|
||||
override val timestamp: Instant = Instant.now(),
|
||||
override val aggregateId: UUID,
|
||||
override val version: Long
|
||||
) : DomainEvent
|
||||
@@ -0,0 +1,96 @@
|
||||
package at.mocode.core.domain.model
|
||||
|
||||
import at.mocode.core.domain.serialization.KotlinInstantSerializer
|
||||
import at.mocode.core.domain.serialization.UuidSerializer
|
||||
import com.benasher44.uuid.Uuid
|
||||
import kotlinx.datetime.Instant
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Base DTO interface for all data transfer objects
|
||||
*/
|
||||
interface BaseDto
|
||||
|
||||
/**
|
||||
* Base DTO for entities with ID and timestamps
|
||||
*/
|
||||
@Serializable
|
||||
abstract class EntityDto : BaseDto {
|
||||
@Serializable(with = UuidSerializer::class)
|
||||
abstract val id: Uuid
|
||||
|
||||
@Serializable(with = KotlinInstantSerializer::class)
|
||||
abstract val createdAt: Instant
|
||||
|
||||
@Serializable(with = KotlinInstantSerializer::class)
|
||||
abstract val updatedAt: Instant
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard API response wrapper
|
||||
*/
|
||||
@Serializable
|
||||
data class ApiResponse<T>(
|
||||
val success: Boolean,
|
||||
val data: T? = null,
|
||||
val error: ErrorDto? = null,
|
||||
val message: String? = null
|
||||
) : BaseDto {
|
||||
companion object {
|
||||
/**
|
||||
* Creates a successful API response with data
|
||||
*/
|
||||
fun <T> success(data: T, message: String? = null): ApiResponse<T> {
|
||||
return ApiResponse(
|
||||
success = true,
|
||||
data = data,
|
||||
message = message
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an error API response
|
||||
*/
|
||||
fun <T> error(message: String, code: String = "ERROR", details: Map<String, String>? = null): ApiResponse<T> {
|
||||
return ApiResponse(
|
||||
success = false,
|
||||
error = ErrorDto(
|
||||
code = code,
|
||||
message = message,
|
||||
details = details
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Error information DTO
|
||||
*/
|
||||
@Serializable
|
||||
data class ErrorDto(
|
||||
val code: String,
|
||||
val message: String,
|
||||
val details: Map<String, String>? = null
|
||||
) : BaseDto
|
||||
|
||||
/**
|
||||
* Pagination information
|
||||
*/
|
||||
@Serializable
|
||||
data class PaginationDto(
|
||||
val page: Int,
|
||||
val size: Int,
|
||||
val total: Long,
|
||||
val totalPages: Int
|
||||
) : BaseDto
|
||||
|
||||
/**
|
||||
* Paginated response wrapper
|
||||
*/
|
||||
@Serializable
|
||||
data class PagedResponse<T>(
|
||||
val data: List<T>,
|
||||
val pagination: PaginationDto
|
||||
) : BaseDto
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
package at.mocode.core.domain.model
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Data source enumeration - indicates where data originated from
|
||||
*/
|
||||
@Serializable
|
||||
enum class DatenQuelleE { OEPS_ZNS, MANUELL }
|
||||
|
||||
/**
|
||||
* Horse gender enumeration
|
||||
*/
|
||||
@Serializable
|
||||
enum class PferdeGeschlechtE {
|
||||
HENGST, STUTE, WALLACH, UNBEKANNT
|
||||
}
|
||||
|
||||
/**
|
||||
* Person gender enumeration
|
||||
*/
|
||||
@Serializable
|
||||
enum class GeschlechtE { M, W, D, UNBEKANNT }
|
||||
|
||||
/**
|
||||
* Sport discipline enumeration
|
||||
*/
|
||||
@Serializable
|
||||
enum class SparteE { DRESSUR, SPRINGEN, VIELSEITIGKEIT, FAHREN, VOLTIGIEREN, WESTERN, DISTANZ, ISLAND, PFERDESPORT_SPIEL, BASIS, KOMBINIERT, SONSTIGES }
|
||||
|
||||
/**
|
||||
* Venue/place type enumeration
|
||||
*/
|
||||
@Serializable
|
||||
enum class PlatzTypE { AUSTRAGUNG, VORBEREITUNG, LONGIEREN, SONSTIGES }
|
||||
|
||||
/**
|
||||
* User role enumeration for member management
|
||||
*/
|
||||
@Serializable
|
||||
enum class RolleE {
|
||||
ADMIN, // System administrator
|
||||
VEREINS_ADMIN, // Club administrator
|
||||
FUNKTIONAER, // Official/functionary
|
||||
REITER, // Rider
|
||||
TRAINER, // Trainer
|
||||
RICHTER, // Judge
|
||||
TIERARZT, // Veterinarian
|
||||
ZUSCHAUER, // Spectator
|
||||
GAST // Guest
|
||||
}
|
||||
|
||||
/**
|
||||
* Permission enumeration for access control
|
||||
*/
|
||||
@Serializable
|
||||
enum class BerechtigungE {
|
||||
// Person management
|
||||
PERSON_READ,
|
||||
PERSON_CREATE,
|
||||
PERSON_UPDATE,
|
||||
PERSON_DELETE,
|
||||
|
||||
// Club management
|
||||
VEREIN_READ,
|
||||
VEREIN_CREATE,
|
||||
VEREIN_UPDATE,
|
||||
VEREIN_DELETE,
|
||||
|
||||
// Event management
|
||||
VERANSTALTUNG_READ,
|
||||
VERANSTALTUNG_CREATE,
|
||||
VERANSTALTUNG_UPDATE,
|
||||
VERANSTALTUNG_DELETE,
|
||||
|
||||
// Horse management
|
||||
PFERD_READ,
|
||||
PFERD_CREATE,
|
||||
PFERD_UPDATE,
|
||||
PFERD_DELETE,
|
||||
|
||||
// Master data management
|
||||
STAMMDATEN_READ,
|
||||
STAMMDATEN_UPDATE,
|
||||
|
||||
// System administration
|
||||
SYSTEM_ADMIN,
|
||||
BENUTZER_VERWALTEN,
|
||||
ROLLEN_VERWALTEN
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package at.mocode.core.domain.serialization
|
||||
|
||||
import com.benasher44.uuid.Uuid
|
||||
import com.benasher44.uuid.uuidFrom
|
||||
import kotlinx.datetime.Instant
|
||||
import kotlinx.datetime.LocalDate
|
||||
import kotlinx.datetime.LocalDateTime
|
||||
import kotlinx.datetime.LocalTime
|
||||
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
|
||||
|
||||
/**
|
||||
* Serializer for UUID values
|
||||
*/
|
||||
object UuidSerializer : KSerializer<Uuid> {
|
||||
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("UUID", PrimitiveKind.STRING)
|
||||
override fun serialize(encoder: Encoder, value: Uuid) = encoder.encodeString(value.toString())
|
||||
override fun deserialize(decoder: Decoder): Uuid = uuidFrom(decoder.decodeString())
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializer for Instant values
|
||||
*/
|
||||
object KotlinInstantSerializer : KSerializer<Instant> {
|
||||
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Instant", PrimitiveKind.STRING)
|
||||
override fun serialize(encoder: Encoder, value: Instant) = encoder.encodeString(value.toString())
|
||||
override fun deserialize(decoder: Decoder): Instant = Instant.parse(decoder.decodeString())
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializer for LocalDate values
|
||||
*/
|
||||
object KotlinLocalDateSerializer : KSerializer<LocalDate> {
|
||||
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("LocalDate", PrimitiveKind.STRING)
|
||||
override fun serialize(encoder: Encoder, value: LocalDate) = encoder.encodeString(value.toString())
|
||||
override fun deserialize(decoder: Decoder): LocalDate = LocalDate.parse(decoder.decodeString())
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializer for LocalDateTime values
|
||||
*/
|
||||
object KotlinLocalDateTimeSerializer : KSerializer<LocalDateTime> {
|
||||
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("LocalDateTime", PrimitiveKind.STRING)
|
||||
override fun serialize(encoder: Encoder, value: LocalDateTime) = encoder.encodeString(value.toString())
|
||||
override fun deserialize(decoder: Decoder): LocalDateTime = LocalDateTime.parse(decoder.decodeString())
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializer for LocalTime values
|
||||
*/
|
||||
object KotlinLocalTimeSerializer : KSerializer<LocalTime> {
|
||||
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("LocalTime", PrimitiveKind.STRING)
|
||||
override fun serialize(encoder: Encoder, value: LocalTime) = encoder.encodeString(value.toString())
|
||||
override fun deserialize(decoder: Decoder): LocalTime = LocalTime.parse(decoder.decodeString())
|
||||
}
|
||||
Reference in New Issue
Block a user