diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index eb8c66fd..f0e2b565 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -63,6 +63,9 @@ protobuf-kotlin = { module = "com.google.protobuf:protobuf-kotlin", version.ref protobuf-java = { module = "com.google.protobuf:protobuf-java", version.ref = "protobuf" } koin-core = { module = "io.insert-koin:koin-core", version.ref = "koin" } postgresql-driver = { module = "org.postgresql:postgresql", version.require = "42.6.0" } +kotlin-scripting-common = { module = "org.jetbrains.kotlin:kotlin-scripting-common", version.ref = "kotlin" } +kotlin-scripting-dependencies = { module = "org.jetbrains.kotlin:kotlin-scripting-dependencies", version.ref = "kotlin" } +kotlin-scripting-maven = { module = "org.jetbrains.kotlin:kotlin-scripting-dependencies-maven", version.ref = "kotlin" } [plugins] kotlinx-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } diff --git a/infrastructure/configuration-api/build.gradle.kts b/infrastructure/configuration-api/build.gradle.kts new file mode 100644 index 00000000..91fd03fb --- /dev/null +++ b/infrastructure/configuration-api/build.gradle.kts @@ -0,0 +1,11 @@ +plugins { + alias(libs.plugins.kotlin.jvm) +} + +kotlin { + explicitApi() +} + +dependencies { + implementation(libs.kotlin.scripting.common) +} \ No newline at end of file diff --git a/infrastructure/configuration-api/src/main/kotlin/io/timemates/backend/configuration/ConfigurationScript.kt b/infrastructure/configuration-api/src/main/kotlin/io/timemates/backend/configuration/ConfigurationScript.kt new file mode 100644 index 00000000..c4b12450 --- /dev/null +++ b/infrastructure/configuration-api/src/main/kotlin/io/timemates/backend/configuration/ConfigurationScript.kt @@ -0,0 +1,16 @@ +package io.timemates.backend.configuration + +import kotlin.script.experimental.annotations.KotlinScript +import kotlin.script.experimental.api.ScriptCompilationConfiguration +import kotlin.script.experimental.api.implicitReceivers + +@KotlinScript( + displayName = "TimeMates configuration", + fileExtension = ".tmc", + compilationConfiguration = ConfigurationScriptCompilationSettings::class, +) +public abstract class ConfigurationScript + +public object ConfigurationScriptCompilationSettings : ScriptCompilationConfiguration({ + implicitReceivers(TimeMatesConfigurationScope::class) +}) \ No newline at end of file diff --git a/infrastructure/configuration-api/src/main/kotlin/io/timemates/backend/configuration/TimeMatesConfigurationScope.kt b/infrastructure/configuration-api/src/main/kotlin/io/timemates/backend/configuration/TimeMatesConfigurationScope.kt new file mode 100644 index 00000000..2167cdfe --- /dev/null +++ b/infrastructure/configuration-api/src/main/kotlin/io/timemates/backend/configuration/TimeMatesConfigurationScope.kt @@ -0,0 +1,74 @@ +package io.timemates.backend.configuration + +import io.timemates.backend.configuration.annotations.TimeMatesDsl +import io.timemates.backend.configuration.database.DatabaseConfigurationScope +import io.timemates.backend.configuration.files.FilesConfigurationScope +import io.timemates.backend.configuration.mailer.MailerConfigurationScope +import io.timemates.backend.configuration.settings.TimeMatesSettingsScope + +/** + * This interface represents the configuration scope for TimeMates. + * It provides methods to configure the mailer, database, files, and settings. + * + * @since 1.0 + */ + +@TimeMatesDsl +public interface TimeMatesConfigurationScope { + + /** + * Configures the mailer using the specified block. + * + * ```kotlin + * mailer { + * // Configure mailer settings here + * } + * ``` + * + * @param block the block of code to configure the mailer + * @since 1.0 + */ + public fun mailer(block: MailerConfigurationScope.() -> Unit) + + /** + * Configures the database using the specified block. + * + * ```kotlin + * database { + * // Configure database settings here + * } + * ``` + * + * @param block the block of code to configure the database + * @since 1.0 + */ + public fun database(block: DatabaseConfigurationScope.() -> Unit) + + /** + * Configures the files using the specified block. + * + * ```kotlin + * files { + * // Configure file system settings here + * } + * ``` + * + * @param block the block of code to configure the files + * @since 1.0 + */ + public fun files(block: FilesConfigurationScope.() -> Unit) + + /** + * Configures the settings using the specified block. + * + * ```kotlin + * settings { + * // Configure TimeMates settings here + * } + * ``` + * + * @param block the block of code to configure the settings + * @since 1.0 + */ + public fun settings(block: TimeMatesSettingsScope.() -> Unit) +} diff --git a/infrastructure/configuration-api/src/main/kotlin/io/timemates/backend/configuration/annotations/TimeMatesDsl.kt b/infrastructure/configuration-api/src/main/kotlin/io/timemates/backend/configuration/annotations/TimeMatesDsl.kt new file mode 100644 index 00000000..5017f63d --- /dev/null +++ b/infrastructure/configuration-api/src/main/kotlin/io/timemates/backend/configuration/annotations/TimeMatesDsl.kt @@ -0,0 +1,4 @@ +package io.timemates.backend.configuration.annotations + +@DslMarker +public annotation class TimeMatesDsl \ No newline at end of file diff --git a/infrastructure/configuration-api/src/main/kotlin/io/timemates/backend/configuration/database/DatabaseConfigurationScope.kt b/infrastructure/configuration-api/src/main/kotlin/io/timemates/backend/configuration/database/DatabaseConfigurationScope.kt new file mode 100644 index 00000000..81ac0300 --- /dev/null +++ b/infrastructure/configuration-api/src/main/kotlin/io/timemates/backend/configuration/database/DatabaseConfigurationScope.kt @@ -0,0 +1,71 @@ +package io.timemates.backend.configuration.database + +import io.timemates.backend.configuration.annotations.TimeMatesDsl + +/** + * This interface represents the configuration scope for a database. + * It provides methods for configuring the database connection. + * + * @since 1.0 + */ +@TimeMatesDsl +public interface DatabaseConfigurationScope { + + /** + * Configures the database to use the in-memory H2 implementation. + * This method sets up the database connection for in-memory usage. + * + * ```kotlin + * inMemory() + * ``` + * + * @since 1.0 + */ + public fun inMemory() + + /** + * Configures the database connection to use PostgreSQL with the provided settings. + * This method sets up the database connection for PostgreSQL usage. + * + * ```kotlin + * postgresql { + * url = "jdbc:postgresql://localhost:5432/mydb" + * user = "username" + * password = "password" + * } + * ``` + * + * @param block the block of code to configure the PostgreSQL settings + * @since 1.0 + */ + public fun postgresql(block: PostgresqlScope.() -> Unit) + + /** + * This interface represents the configuration scope for the PostgreSQL settings. + * + * @since 1.0 + */ + @TimeMatesDsl + public interface PostgresqlScope { + /** + * The URL of the PostgreSQL database. + * + * @since 1.0 + */ + public var url: String + + /** + * The username for the PostgreSQL database. + * + * @since 1.0 + */ + public var user: String + + /** + * The password for the PostgreSQL database. + * + * @since 1.0 + */ + public var password: String + } +} \ No newline at end of file diff --git a/infrastructure/configuration-api/src/main/kotlin/io/timemates/backend/configuration/files/FilesConfigurationScope.kt b/infrastructure/configuration-api/src/main/kotlin/io/timemates/backend/configuration/files/FilesConfigurationScope.kt new file mode 100644 index 00000000..39bf6dc1 --- /dev/null +++ b/infrastructure/configuration-api/src/main/kotlin/io/timemates/backend/configuration/files/FilesConfigurationScope.kt @@ -0,0 +1,49 @@ +package io.timemates.backend.configuration.files + +import io.timemates.backend.configuration.annotations.TimeMatesDsl +import java.nio.file.Path + +/** + * This interface represents the configuration scope for handling files. + * It provides methods for configuring the file system settings. + * + * @since 1.0 + */ +@TimeMatesDsl +public interface FilesConfigurationScope { + + /** + * Configures the file system to use local files with the provided settings. + * This method sets up the local file system configuration. + * + * ```kotlin + * localFiles { + * imagesPath(Path.of(URI("/path/to/images"))) + * } + * ``` + * + * @param block the block of code to configure the file system settings + * @since 1.0 + */ + public fun localFiles(block: FileSystemScope.() -> Unit) + + /** + * This interface represents the configuration scope for the file system settings. + * + * @since 1.0 + */ + @TimeMatesDsl + public interface FileSystemScope { + /** + * Sets the path for storing images in the file system. + * + * ```kotlin + * imagesPath(Path.of(URI("/path/to/images"))) + * ``` + * + * @param path the path where images will be stored + * @since 1.0 + */ + public fun imagesPath(path: Path) + } +} diff --git a/infrastructure/configuration-api/src/main/kotlin/io/timemates/backend/configuration/mailer/MailerConfigurationScope.kt b/infrastructure/configuration-api/src/main/kotlin/io/timemates/backend/configuration/mailer/MailerConfigurationScope.kt new file mode 100644 index 00000000..de46b21f --- /dev/null +++ b/infrastructure/configuration-api/src/main/kotlin/io/timemates/backend/configuration/mailer/MailerConfigurationScope.kt @@ -0,0 +1,130 @@ +package io.timemates.backend.configuration.mailer + +import io.timemates.backend.configuration.annotations.TimeMatesDsl + +/** + * This interface represents the configuration scope for a mailer. + * It provides methods for configuring the mailer and SMTP settings. + * + * @since 1.0 + */ +@TimeMatesDsl +public interface MailerConfigurationScope { + + /** + * Configures the mailer with the provided settings using the specified block. + * Only one implementation is allowed. + * + * ```kotlin + * mailerSend { + * apiKey = "your-api-key" + * sender = "sender@example.com" + * confirmationTemplateId = "template-id" + * supportEmail = "support@example.com" + * } + * ``` + * + * @param block the block of code to configure the mailer + * @since 1.0 + */ + public fun mailerSend(block: MailerSendScope.() -> Unit) + + /** + * Configures the SMTP settings for the mailer using the specified block. + * Only one implementation is allowed. + * + * ```kotlin + * smtp { + * host = "smtp.example.com" + * port = 587 + * user = "smtp-user" + * password = "smtp-password" + * confirmationSender = "noreply@example.com" + * } + * ``` + * + * @param block the block of code to configure the SMTP settings + * @since 1.0 + */ + public fun smtp(block: MailerSendScope.() -> Unit) + + /** + * This interface represents the configuration scope for the mailer send settings. + * + * [API Reference](https://developers.mailersend.com/api/v1/email.html#send-an-email) + * @since 1.0 + */ + @TimeMatesDsl + public interface MailerSendScope { + /** + * The API key for the mailer. + * + * @since 1.0 + */ + public var apiKey: String + + /** + * The sender's email address. + * + * @since 1.0 + */ + public var sender: String + + /** + * The ID of the confirmation template. + * + * @since 1.0 + */ + public var confirmationTemplateId: String + + /** + * The support email address. + * + * @since 1.0 + */ + public var supportEmail: String + } + + /** + * This interface represents the configuration scope for the SMTP settings. + * + * @since 1.0 + */ + @TimeMatesDsl + public interface SmtpScope { + /** + * The SMTP host address. + * + * @since 1.0 + */ + public var host: String + + /** + * The SMTP port number. + * + * @since 1.0 + */ + public var port: Int + + /** + * The SMTP user. + * + * @since 1.0 + */ + public var user: Int + + /** + * The SMTP password. + * + * @since 1.0 + */ + public var password: String + + /** + * The sender's email address for confirmation emails. + * + * @since 1.0 + */ + public var confirmationSender: String + } +} \ No newline at end of file diff --git a/infrastructure/configuration-api/src/main/kotlin/io/timemates/backend/configuration/settings/TimeMatesSettingsScope.kt b/infrastructure/configuration-api/src/main/kotlin/io/timemates/backend/configuration/settings/TimeMatesSettingsScope.kt new file mode 100644 index 00000000..b4dd6623 --- /dev/null +++ b/infrastructure/configuration-api/src/main/kotlin/io/timemates/backend/configuration/settings/TimeMatesSettingsScope.kt @@ -0,0 +1,28 @@ +package io.timemates.backend.configuration.settings + +import io.timemates.backend.configuration.annotations.TimeMatesDsl +import io.timemates.backend.configuration.settings.users.UsersFeaturesScope + +/** + * This interface represents the configuration scope for TimeMates settings. + * It provides a method to configure user features. + * + * @since 1.0 + */ +@TimeMatesDsl +public interface TimeMatesSettingsScope { + + /** + * Configures user features using the specified block. + * + * ```kotlin + * users { + * canRegister = true + * } + * ``` + * + * @param block the block of code to configure user features + * @since 1.0 + */ + public fun users(block: UsersFeaturesScope.() -> Unit) +} diff --git a/infrastructure/configuration-api/src/main/kotlin/io/timemates/backend/configuration/settings/users/UsersFeaturesScope.kt b/infrastructure/configuration-api/src/main/kotlin/io/timemates/backend/configuration/settings/users/UsersFeaturesScope.kt new file mode 100644 index 00000000..c345f1ee --- /dev/null +++ b/infrastructure/configuration-api/src/main/kotlin/io/timemates/backend/configuration/settings/users/UsersFeaturesScope.kt @@ -0,0 +1,27 @@ +package io.timemates.backend.configuration.settings.users + +import io.timemates.backend.configuration.annotations.TimeMatesDsl + +/** + * This interface represents the configuration scope for user features. + * It provides a property to control whether new users can register or not. + * + * @since 1.0 + */ +@TimeMatesDsl +public interface UsersFeaturesScope { + + /** + * Determines whether new users can register or not. + * Set this property to `true` to allow registration, or `false` to disable it. + * + * ```kotlin + * canRegister = true + * ``` + * + * `true` by default + * + * @since 1.0 + */ + public var canRegister: Boolean +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 9d91ceb4..5b2de695 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -40,6 +40,7 @@ include(":domain", ":data") include( ":infrastructure:services", ":infrastructure:application", + ":infrastructure:configuration-api", )