Index: detekt-rules/src/main/kotlin/de/hype/bingonet/server/detektrules/ExposedRuleSetProvider.kt
===================================================================
diff --git a/detekt-rules/src/main/kotlin/de/hype/bingonet/server/detektrules/ExposedRuleSetProvider.kt b/detekt-rules/src/main/kotlin/de/hype/bingonet/server/detektrules/ExposedRuleSetProvider.kt
new file mode 100644
--- /dev/null	(revision df29a77f0ff346f2726e082a8b6d5d6f602132ba)
+++ b/detekt-rules/src/main/kotlin/de/hype/bingonet/server/detektrules/ExposedRuleSetProvider.kt	(revision df29a77f0ff346f2726e082a8b6d5d6f602132ba)
@@ -0,0 +1,11 @@
+package de.hype.bingonet.server.detektrules
+
+import io.gitlab.arturbosch.detekt.api.Config
+import io.gitlab.arturbosch.detekt.api.RuleSet
+import io.gitlab.arturbosch.detekt.api.RuleSetProvider
+
+class ExposedRuleSetProvider : RuleSetProvider {
+    override val ruleSetId = "exposed"
+    override fun instance(config: Config) =
+        RuleSet(ruleSetId, listOf(ExposedTransactionRule(config)))
+}
Index: detekt-rules/src/main/kotlin/de/hype/bingonet/server/detektrules/ExposedTransactionRule.kt
===================================================================
diff --git a/detekt-rules/src/main/kotlin/de/hype/bingonet/server/detektrules/ExposedTransactionRule.kt b/detekt-rules/src/main/kotlin/de/hype/bingonet/server/detektrules/ExposedTransactionRule.kt
new file mode 100644
--- /dev/null	(revision df29a77f0ff346f2726e082a8b6d5d6f602132ba)
+++ b/detekt-rules/src/main/kotlin/de/hype/bingonet/server/detektrules/ExposedTransactionRule.kt	(revision df29a77f0ff346f2726e082a8b6d5d6f602132ba)
@@ -0,0 +1,56 @@
+package de.hype.bingonet.server.detektrules
+
+import io.gitlab.arturbosch.detekt.api.*
+import org.jetbrains.kotlin.com.intellij.psi.PsiElement
+import org.jetbrains.kotlin.lexer.KtTokens
+import org.jetbrains.kotlin.psi.KtBinaryExpression
+import org.jetbrains.kotlin.psi.KtCallExpression
+
+class ExposedTransactionRule(config: Config) : Rule(config) {
+    override val issue = Issue(
+        id = "ExposedTransaction",
+        severity = Severity.Defect,
+        description = "Exposed database operations must be wrapped in transaction {}",
+        debt = Debt.TWENTY_MINS
+    )
+
+    private val methods = setOf("insert", "update", "delete", "select", "find", "flush")
+
+    override fun visitCallExpression(expression: KtCallExpression) {
+        if (expression.calleeExpression?.text in methods && !inTransaction(expression)) {
+            report(
+                CodeSmell(
+                    issue,
+                    Entity.from(expression),
+                    "Exposed call `${expression.text}` is not inside a transaction"
+                )
+            )
+        }
+        super.visitCallExpression(expression)
+    }
+
+    override fun visitBinaryExpression(expression: KtBinaryExpression) {
+        if (expression.operationToken == KtTokens.EQ &&
+            expression.left?.text?.contains('.') == true &&
+            !inTransaction(expression)
+        ) {
+            report(
+                CodeSmell(
+                    issue,
+                    Entity.from(expression),
+                    "DAO property assignment `${expression.text}` not inside transaction"
+                )
+            )
+        }
+        super.visitBinaryExpression(expression)
+    }
+
+    private fun inTransaction(el: PsiElement): Boolean {
+        var cur = el.parent
+        while (cur != null) {
+            if (cur is KtCallExpression && cur.calleeExpression?.text == "transaction") return true
+            cur = cur.parent
+        }
+        return false
+    }
+}
Index: detekt-rules/build.gradle.kts
===================================================================
diff --git a/detekt-rules/build.gradle.kts b/detekt-rules/build.gradle.kts
new file mode 100644
--- /dev/null	(revision df29a77f0ff346f2726e082a8b6d5d6f602132ba)
+++ b/detekt-rules/build.gradle.kts	(revision df29a77f0ff346f2726e082a8b6d5d6f602132ba)
@@ -0,0 +1,11 @@
+plugins {
+    kotlin("jvm")
+    idea
+    `java-library`
+    java
+}
+
+dependencies {
+    compileOnly("io.gitlab.arturbosch.detekt:detekt-api:1.23.8")
+    implementation("org.jetbrains.kotlin:kotlin-compiler-embeddable:1.9.0")
+}
Index: gradle/libs.versions.toml
===================================================================
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
new file mode 100644
--- /dev/null	(revision 49ba6acd2ac17c3aa9561c3453f4fa19cf5c967d)
+++ b/gradle/libs.versions.toml	(revision 49ba6acd2ac17c3aa9561c3453f4fa19cf5c967d)
@@ -0,0 +1,10 @@
+[versions]
+kotlin = "${kotlinVersion}"
+ksp = "${kspVersion}"
+detekt = "1.23.8"
+
+[plugins]
+kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
+kotlin-kapt = { id = "org.jetbrains.kotlin.kapt", version.ref = "kotlin" }
+ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
+detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" }
Index: build.gradle.kts
===================================================================
diff --git a/build.gradle.kts b/build.gradle.kts
new file mode 100644
--- /dev/null	(revision 49ba6acd2ac17c3aa9561c3453f4fa19cf5c967d)
+++ b/build.gradle.kts	(revision 49ba6acd2ac17c3aa9561c3453f4fa19cf5c967d)
@@ -0,0 +1,53 @@
+plugins {
+    kotlin("jvm")
+    java
+    idea
+    alias(libs.plugins.detekt)
+}
+
+repositories {
+    mavenCentral()
+    gradlePluginPortal()
+}
+
+subprojects {
+    repositories {
+        mavenCentral()
+    }
+
+    apply(plugin = "io.gitlab.arturbosch.detekt")
+
+    dependencies {
+        detektPlugins(project(":detekt-rules"))
+    }
+
+    detekt {
+        toolVersion = "1.23.8"
+        config.setFrom(files(rootProject.file("detekt.yml")))
+        buildUponDefaultConfig = true
+        parallel = false
+        debug = true
+        input.from("src/main/kotlin", "src/main/java")
+    }
+
+    tasks.withType<io.gitlab.arturbosch.detekt.Detekt> {
+        jvmTarget = "21"
+        reports {
+            html.required.set(true)
+        }
+    }
+
+    plugins.withId("org.jetbrains.kotlin.jvm") {
+        kotlin {
+            jvmToolchain(21)
+            compilerOptions {
+                freeCompilerArgs.addAll(
+                    listOf(
+                        "-Xmulti-dollar-interpolation",
+                    )
+                )
+            }
+        }
+
+    }
+}
Index: detekt.yml
===================================================================
diff --git a/detekt.yml b/detekt.yml
new file mode 100644
--- /dev/null	(revision 49ba6acd2ac17c3aa9561c3453f4fa19cf5c967d)
+++ b/detekt.yml	(revision 49ba6acd2ac17c3aa9561c3453f4fa19cf5c967d)
@@ -0,0 +1,797 @@
+build:
+  maxIssues: 0
+  excludeCorrectable: false
+  weights:
+  # complexity: 2
+  # LongParameterList: 1
+  # style: 1
+  # comments: 1
+
+config:
+  validation: true
+  warningsAsErrors: false
+  checkExhaustiveness: false
+  # when writing own rules with new properties, exclude the property path e.g.: 'my_rule_set,.*>.*>[my_property]'
+  excludes: ''
+
+processors:
+  active: true
+  exclude:
+    - 'DetektProgressListener'
+  # - 'KtFileCountProcessor'
+  # - 'PackageCountProcessor'
+  # - 'ClassCountProcessor'
+  # - 'FunctionCountProcessor'
+  # - 'PropertyCountProcessor'
+  # - 'ProjectComplexityProcessor'
+  # - 'ProjectCognitiveComplexityProcessor'
+  # - 'ProjectLLOCProcessor'
+  # - 'ProjectCLOCProcessor'
+  # - 'ProjectLOCProcessor'
+  # - 'ProjectSLOCProcessor'
+  # - 'LicenseHeaderLoaderExtension'
+
+console-reports:
+  active: true
+  exclude:
+    - 'ProjectStatisticsReport'
+    - 'ComplexityReport'
+    - 'NotificationReport'
+    - 'FindingsReport'
+    - 'FileBasedFindingsReport'
+  #  - 'LiteFindingsReport'
+
+output-reports:
+  active: true
+  exclude:
+    - 'TxtOutputReport'
+  # - 'XmlOutputReport'
+    - 'HtmlOutputReport'
+  # - 'MdOutputReport'
+  # - 'SarifOutputReport'
+
+comments:
+  active: true
+  AbsentOrWrongFileLicense:
+    active: false
+    licenseTemplateFile: 'license.template'
+    licenseTemplateIsRegex: false
+  CommentOverPrivateFunction:
+    active: false
+  CommentOverPrivateProperty:
+    active: false
+  DeprecatedBlockTag:
+    active: false
+  EndOfSentenceFormat:
+    active: false
+    endOfSentenceFormat: '([.?!][ \t\n\r\f<])|([.?!:]$)'
+  KDocReferencesNonPublicProperty:
+    active: false
+    excludes: [ '**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**' ]
+  OutdatedDocumentation:
+    active: false
+    matchTypeParameters: true
+    matchDeclarationsOrder: true
+    allowParamOnConstructorProperties: false
+  UndocumentedPublicClass:
+    active: false
+    excludes: [ '**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**' ]
+    searchInNestedClass: true
+    searchInInnerClass: true
+    searchInInnerObject: true
+    searchInInnerInterface: true
+    searchInProtectedClass: false
+    ignoreDefaultCompanionObject: false
+  UndocumentedPublicFunction:
+    active: false
+    excludes: [ '**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**' ]
+    searchProtectedFunction: false
+  UndocumentedPublicProperty:
+    active: false
+    excludes: [ '**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**' ]
+    searchProtectedProperty: false
+
+complexity:
+  active: false
+  CognitiveComplexMethod:
+    active: false
+    threshold: 15
+  ComplexCondition:
+    active: true
+    threshold: 4
+  ComplexInterface:
+    active: false
+    threshold: 10
+    includeStaticDeclarations: false
+    includePrivateDeclarations: false
+    ignoreOverloaded: false
+  CyclomaticComplexMethod:
+    active: true
+    threshold: 15
+    ignoreSingleWhenExpression: false
+    ignoreSimpleWhenEntries: false
+    ignoreNestingFunctions: false
+    nestingFunctions:
+      - 'also'
+      - 'apply'
+      - 'forEach'
+      - 'isNotNull'
+      - 'ifNull'
+      - 'let'
+      - 'run'
+      - 'use'
+      - 'with'
+  LabeledExpression:
+    active: false
+    ignoredLabels: [ ]
+  LargeClass:
+    active: true
+    threshold: 600
+  LongMethod:
+    active: true
+    threshold: 60
+  LongParameterList:
+    active: true
+    functionThreshold: 6
+    constructorThreshold: 7
+    ignoreDefaultParameters: false
+    ignoreDataClasses: true
+    ignoreAnnotatedParameter: [ ]
+  MethodOverloading:
+    active: false
+    threshold: 6
+  NamedArguments:
+    active: false
+    threshold: 3
+    ignoreArgumentsMatchingNames: false
+  NestedBlockDepth:
+    active: true
+    threshold: 4
+  NestedScopeFunctions:
+    active: false
+    threshold: 1
+    functions:
+      - 'kotlin.apply'
+      - 'kotlin.run'
+      - 'kotlin.with'
+      - 'kotlin.let'
+      - 'kotlin.also'
+  ReplaceSafeCallChainWithRun:
+    active: false
+  StringLiteralDuplication:
+    active: false
+    excludes: [ '**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**' ]
+    threshold: 3
+    ignoreAnnotation: true
+    excludeStringsWithLessThan5Characters: true
+    ignoreStringsRegex: '$^'
+  TooManyFunctions:
+    active: true
+    excludes: [ '**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**' ]
+    thresholdInFiles: 11
+    thresholdInClasses: 11
+    thresholdInInterfaces: 11
+    thresholdInObjects: 11
+    thresholdInEnums: 11
+    ignoreDeprecated: false
+    ignorePrivate: false
+    ignoreOverridden: false
+    ignoreAnnotatedFunctions: [ ]
+
+coroutines:
+  active: true
+  GlobalCoroutineUsage:
+    active: false
+  InjectDispatcher:
+    active: true
+    dispatcherNames:
+      - 'IO'
+      - 'Default'
+      - 'Unconfined'
+  RedundantSuspendModifier:
+    active: true
+  SleepInsteadOfDelay:
+    active: true
+  SuspendFunSwallowedCancellation:
+    active: false
+  SuspendFunWithCoroutineScopeReceiver:
+    active: false
+  SuspendFunWithFlowReturnType:
+    active: true
+
+empty-blocks:
+  active: false
+  EmptyCatchBlock:
+    active: true
+    allowedExceptionNameRegex: '_|(ignore|expected).*'
+  EmptyClassBlock:
+    active: true
+  EmptyDefaultConstructor:
+    active: true
+  EmptyDoWhileBlock:
+    active: true
+  EmptyElseBlock:
+    active: true
+  EmptyFinallyBlock:
+    active: true
+  EmptyForBlock:
+    active: true
+  EmptyFunctionBlock:
+    active: true
+    ignoreOverridden: false
+  EmptyIfBlock:
+    active: true
+  EmptyInitBlock:
+    active: true
+  EmptyKtFile:
+    active: true
+  EmptySecondaryConstructor:
+    active: true
+  EmptyTryBlock:
+    active: true
+  EmptyWhenBlock:
+    active: true
+  EmptyWhileBlock:
+    active: true
+
+exceptions:
+  active: true
+  ExceptionRaisedInUnexpectedLocation:
+    active: false
+    methodNames:
+      - 'equals'
+      - 'finalize'
+      - 'hashCode'
+      - 'toString'
+  InstanceOfCheckForException:
+    active: false
+    excludes: [ '**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**' ]
+  NotImplementedDeclaration:
+    active: false
+  ObjectExtendsThrowable:
+    active: false
+  PrintStackTrace:
+    active: false
+  RethrowCaughtException:
+    active: false
+  ReturnFromFinally:
+    active: false
+    ignoreLabeled: false
+  SwallowedException:
+    active: false
+    ignoredExceptionTypes:
+      - 'InterruptedException'
+      - 'MalformedURLException'
+      - 'NumberFormatException'
+      - 'ParseException'
+    allowedExceptionNameRegex: 'e|t|_|(ignore|expected).*'
+  ThrowingExceptionFromFinally:
+    active: false
+  ThrowingExceptionInMain:
+    active: false
+  ThrowingExceptionsWithoutMessageOrCause:
+    active: true
+    excludes: [ '**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**' ]
+    exceptions:
+      - 'ArrayIndexOutOfBoundsException'
+      - 'Exception'
+      - 'IllegalArgumentException'
+      - 'IllegalMonitorStateException'
+      - 'IllegalStateException'
+      - 'IndexOutOfBoundsException'
+      - 'NullPointerException'
+      - 'RuntimeException'
+      - 'Throwable'
+  ThrowingNewInstanceOfSameException:
+    active: false
+  TooGenericExceptionCaught:
+    active: false
+    excludes: [ '**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**' ]
+    exceptionNames:
+      - 'ArrayIndexOutOfBoundsException'
+      - 'Error'
+      - 'Exception'
+      - 'IllegalMonitorStateException'
+      - 'IndexOutOfBoundsException'
+      - 'NullPointerException'
+      - 'RuntimeException'
+      - 'Throwable'
+    allowedExceptionNameRegex: '_|(ignore|expected).*'
+  TooGenericExceptionThrown:
+    active: false
+    exceptionNames:
+      - 'Error'
+      - 'Exception'
+      - 'RuntimeException'
+      - 'Throwable'
+
+naming:
+  active: false
+  BooleanPropertyNaming:
+    active: false
+    allowedPattern: '^(is|has|are)'
+  ClassNaming:
+    active: true
+    classPattern: '[A-Z][a-zA-Z0-9]*'
+  ConstructorParameterNaming:
+    active: true
+    parameterPattern: '[a-z][A-Za-z0-9]*'
+    privateParameterPattern: '[a-z][A-Za-z0-9]*'
+    excludeClassPattern: '$^'
+  EnumNaming:
+    active: true
+    enumEntryPattern: '[A-Z][_a-zA-Z0-9]*'
+  ForbiddenClassName:
+    active: false
+    forbiddenName: [ ]
+  FunctionMaxLength:
+    active: false
+    maximumFunctionNameLength: 30
+  FunctionMinLength:
+    active: false
+    minimumFunctionNameLength: 3
+  FunctionNaming:
+    active: true
+    excludes: [ '**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**' ]
+    functionPattern: '[a-z][a-zA-Z0-9]*'
+    excludeClassPattern: '$^'
+  FunctionParameterNaming:
+    active: true
+    parameterPattern: '[a-z][A-Za-z0-9]*'
+    excludeClassPattern: '$^'
+  InvalidPackageDeclaration:
+    active: true
+    rootPackage: ''
+    requireRootInDeclaration: false
+  LambdaParameterNaming:
+    active: false
+    parameterPattern: '[a-z][A-Za-z0-9]*|_'
+  MatchingDeclarationName:
+    active: true
+    mustBeFirst: true
+    multiplatformTargets:
+      - 'ios'
+      - 'android'
+      - 'js'
+      - 'jvm'
+      - 'native'
+      - 'iosArm64'
+      - 'iosX64'
+      - 'macosX64'
+      - 'mingwX64'
+      - 'linuxX64'
+  MemberNameEqualsClassName:
+    active: true
+    ignoreOverridden: true
+  NoNameShadowing:
+    active: true
+  NonBooleanPropertyPrefixedWithIs:
+    active: false
+  ObjectPropertyNaming:
+    active: true
+    constantPattern: '[A-Za-z][_A-Za-z0-9]*'
+    propertyPattern: '[A-Za-z][_A-Za-z0-9]*'
+    privatePropertyPattern: '(_)?[A-Za-z][_A-Za-z0-9]*'
+  PackageNaming:
+    active: true
+    packagePattern: '[a-z]+(\.[a-z][A-Za-z0-9]*)*'
+  TopLevelPropertyNaming:
+    active: true
+    constantPattern: '[A-Z][_A-Z0-9]*'
+    propertyPattern: '[A-Za-z][_A-Za-z0-9]*'
+    privatePropertyPattern: '_?[A-Za-z][_A-Za-z0-9]*'
+  VariableMaxLength:
+    active: false
+    maximumVariableNameLength: 64
+  VariableMinLength:
+    active: false
+    minimumVariableNameLength: 1
+  VariableNaming:
+    active: true
+    variablePattern: '[a-z][A-Za-z0-9]*'
+    privateVariablePattern: '(_)?[a-z][A-Za-z0-9]*'
+    excludeClassPattern: '$^'
+
+performance:
+  active: true
+  ArrayPrimitive:
+    active: true
+  CouldBeSequence:
+    active: false
+    threshold: 3
+  ForEachOnRange:
+    active: true
+    excludes: [ '**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**' ]
+  SpreadOperator:
+    active: false
+    excludes: [ '**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**' ]
+  UnnecessaryPartOfBinaryExpression:
+    active: false
+  UnnecessaryTemporaryInstantiation:
+    active: true
+
+potential-bugs:
+  active: true
+  AvoidReferentialEquality:
+    active: true
+    forbiddenTypePatterns:
+      - 'kotlin.String'
+  CastNullableToNonNullableType:
+    active: false
+  CastToNullableType:
+    active: false
+  Deprecation:
+    active: false
+  DontDowncastCollectionTypes:
+    active: false
+  DoubleMutabilityForCollection:
+    active: true
+    mutableTypes:
+      - 'kotlin.collections.MutableList'
+      - 'kotlin.collections.MutableMap'
+      - 'kotlin.collections.MutableSet'
+      - 'java.util.ArrayList'
+      - 'java.util.LinkedHashSet'
+      - 'java.util.HashSet'
+      - 'java.util.LinkedHashMap'
+      - 'java.util.HashMap'
+  ElseCaseInsteadOfExhaustiveWhen:
+    active: false
+    ignoredSubjectTypes: [ ]
+  EqualsAlwaysReturnsTrueOrFalse:
+    active: true
+  EqualsWithHashCodeExist:
+    active: true
+  ExitOutsideMain:
+    active: false
+  ExplicitGarbageCollectionCall:
+    active: true
+  HasPlatformType:
+    active: true
+  IgnoredReturnValue:
+    active: true
+    restrictToConfig: true
+    returnValueAnnotations:
+      - 'CheckResult'
+      - '*.CheckResult'
+      - 'CheckReturnValue'
+      - '*.CheckReturnValue'
+    ignoreReturnValueAnnotations:
+      - 'CanIgnoreReturnValue'
+      - '*.CanIgnoreReturnValue'
+    returnValueTypes:
+      - 'kotlin.sequences.Sequence'
+      - 'kotlinx.coroutines.flow.*Flow'
+      - 'java.util.stream.*Stream'
+    ignoreFunctionCall: [ ]
+  ImplicitDefaultLocale:
+    active: false
+  ImplicitUnitReturnType:
+    active: false
+    allowExplicitReturnType: true
+  InvalidRange:
+    active: true
+  IteratorHasNextCallsNextMethod:
+    active: true
+  IteratorNotThrowingNoSuchElementException:
+    active: true
+  LateinitUsage:
+    active: false
+    excludes: [ '**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**' ]
+    ignoreOnClassesPattern: ''
+  MapGetWithNotNullAssertionOperator:
+    active: true
+  MissingPackageDeclaration:
+    active: false
+    excludes: [ '**/*.kts' ]
+  NullCheckOnMutableProperty:
+    active: false
+  NullableToStringCall:
+    active: false
+  PropertyUsedBeforeDeclaration:
+    active: false
+  UnconditionalJumpStatementInLoop:
+    active: false
+  UnnecessaryNotNullCheck:
+    active: false
+  UnnecessaryNotNullOperator:
+    active: true
+  UnnecessarySafeCall:
+    active: true
+  UnreachableCatchBlock:
+    active: true
+  UnreachableCode:
+    active: true
+  UnsafeCallOnNullableType:
+    active: true
+    excludes: [ '**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**' ]
+  UnsafeCast:
+    active: true
+  UnusedUnaryOperator:
+    active: true
+  UselessPostfixExpression:
+    active: true
+  WrongEqualsTypeParameter:
+    active: true
+
+style:
+  active: false
+  AlsoCouldBeApply:
+    active: false
+  BracesOnIfStatements:
+    active: false
+    singleLine: 'never'
+    multiLine: 'always'
+  BracesOnWhenStatements:
+    active: false
+    singleLine: 'necessary'
+    multiLine: 'consistent'
+  CanBeNonNullable:
+    active: false
+  CascadingCallWrapping:
+    active: false
+    includeElvis: true
+  ClassOrdering:
+    active: false
+  CollapsibleIfStatements:
+    active: false
+  DataClassContainsFunctions:
+    active: false
+    conversionFunctionPrefix:
+      - 'to'
+    allowOperators: false
+  DataClassShouldBeImmutable:
+    active: false
+  DestructuringDeclarationWithTooManyEntries:
+    active: true
+    maxDestructuringEntries: 3
+  DoubleNegativeLambda:
+    active: false
+    negativeFunctions:
+      - reason: 'Use `takeIf` instead.'
+        value: 'takeUnless'
+      - reason: 'Use `all` instead.'
+        value: 'none'
+    negativeFunctionNameParts:
+      - 'not'
+      - 'non'
+  EqualsNullCall:
+    active: true
+  EqualsOnSignatureLine:
+    active: false
+  ExplicitCollectionElementAccessMethod:
+    active: false
+  ExplicitItLambdaParameter:
+    active: true
+  ExpressionBodySyntax:
+    active: false
+    includeLineWrapping: false
+  ForbiddenAnnotation:
+    active: false
+    annotations:
+      - reason: 'it is a java annotation. Use `Suppress` instead.'
+        value: 'java.lang.SuppressWarnings'
+      - reason: 'it is a java annotation. Use `kotlin.Deprecated` instead.'
+        value: 'java.lang.Deprecated'
+      - reason: 'it is a java annotation. Use `kotlin.annotation.MustBeDocumented` instead.'
+        value: 'java.lang.annotation.Documented'
+      - reason: 'it is a java annotation. Use `kotlin.annotation.Target` instead.'
+        value: 'java.lang.annotation.Target'
+      - reason: 'it is a java annotation. Use `kotlin.annotation.Retention` instead.'
+        value: 'java.lang.annotation.Retention'
+      - reason: 'it is a java annotation. Use `kotlin.annotation.Repeatable` instead.'
+        value: 'java.lang.annotation.Repeatable'
+      - reason: 'Kotlin does not support @Inherited annotation, see https://youtrack.jetbrains.com/issue/KT-22265'
+        value: 'java.lang.annotation.Inherited'
+  ForbiddenComment:
+    active: true
+    comments:
+      - reason: 'Forbidden FIXME todo marker in comment, please fix the problem.'
+        value: 'FIXME:'
+      - reason: 'Forbidden STOPSHIP todo marker in comment, please address the problem before shipping the code.'
+        value: 'STOPSHIP:'
+      - reason: 'Forbidden TODO todo marker in comment, please do the changes.'
+        value: 'TODO:'
+    allowedPatterns: ''
+  ForbiddenImport:
+    active: false
+    imports: [ ]
+    forbiddenPatterns: ''
+  ForbiddenMethodCall:
+    active: false
+    methods:
+      - reason: 'print does not allow you to configure the output stream. Use a logger instead.'
+        value: 'kotlin.io.print'
+      - reason: 'println does not allow you to configure the output stream. Use a logger instead.'
+        value: 'kotlin.io.println'
+  ForbiddenSuppress:
+    active: false
+    rules: [ ]
+  ForbiddenVoid:
+    active: true
+    ignoreOverridden: false
+    ignoreUsageInGenerics: false
+  FunctionOnlyReturningConstant:
+    active: true
+    ignoreOverridableFunction: true
+    ignoreActualFunction: true
+    excludedFunctions: [ ]
+  LoopWithTooManyJumpStatements:
+    active: true
+    maxJumpCount: 1
+  MagicNumber:
+    active: true
+    excludes: [ '**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.kts' ]
+    ignoreNumbers:
+      - '-1'
+      - '0'
+      - '1'
+      - '2'
+    ignoreHashCodeFunction: true
+    ignorePropertyDeclaration: false
+    ignoreLocalVariableDeclaration: false
+    ignoreConstantDeclaration: true
+    ignoreCompanionObjectPropertyDeclaration: true
+    ignoreAnnotation: false
+    ignoreNamedArgument: true
+    ignoreEnums: false
+    ignoreRanges: false
+    ignoreExtensionFunctions: true
+  MandatoryBracesLoops:
+    active: false
+  MaxChainedCallsOnSameLine:
+    active: false
+    maxChainedCalls: 5
+  MaxLineLength:
+    active: true
+    maxLineLength: 120
+    excludePackageStatements: true
+    excludeImportStatements: true
+    excludeCommentStatements: false
+    excludeRawStrings: true
+  MayBeConst:
+    active: true
+  ModifierOrder:
+    active: true
+  MultilineLambdaItParameter:
+    active: false
+  MultilineRawStringIndentation:
+    active: false
+    indentSize: 4
+    trimmingMethods:
+      - 'trimIndent'
+      - 'trimMargin'
+  NestedClassesVisibility:
+    active: true
+  NewLineAtEndOfFile:
+    active: true
+  NoTabs:
+    active: false
+  NullableBooleanCheck:
+    active: false
+  ObjectLiteralToLambda:
+    active: true
+  OptionalAbstractKeyword:
+    active: true
+  OptionalUnit:
+    active: false
+  PreferToOverPairSyntax:
+    active: false
+  ProtectedMemberInFinalClass:
+    active: true
+  RedundantExplicitType:
+    active: false
+  RedundantHigherOrderMapUsage:
+    active: true
+  RedundantVisibilityModifierRule:
+    active: false
+  ReturnCount:
+    active: true
+    max: 2
+    excludedFunctions:
+      - 'equals'
+    excludeLabeled: false
+    excludeReturnFromLambda: true
+    excludeGuardClauses: false
+  SafeCast:
+    active: true
+  SerialVersionUIDInSerializableClass:
+    active: true
+  SpacingBetweenPackageAndImports:
+    active: false
+  StringShouldBeRawString:
+    active: false
+    maxEscapedCharacterCount: 2
+    ignoredCharacters: [ ]
+  ThrowsCount:
+    active: true
+    max: 2
+    excludeGuardClauses: false
+  TrailingWhitespace:
+    active: false
+  TrimMultilineRawString:
+    active: false
+    trimmingMethods:
+      - 'trimIndent'
+      - 'trimMargin'
+  UnderscoresInNumericLiterals:
+    active: false
+    acceptableLength: 4
+    allowNonStandardGrouping: false
+  UnnecessaryAbstractClass:
+    active: true
+  UnnecessaryAnnotationUseSiteTarget:
+    active: false
+  UnnecessaryApply:
+    active: true
+  UnnecessaryBackticks:
+    active: false
+  UnnecessaryBracesAroundTrailingLambda:
+    active: false
+  UnnecessaryFilter:
+    active: true
+  UnnecessaryInheritance:
+    active: true
+  UnnecessaryInnerClass:
+    active: false
+  UnnecessaryLet:
+    active: false
+  UnnecessaryParentheses:
+    active: false
+    allowForUnclearPrecedence: false
+  UntilInsteadOfRangeTo:
+    active: false
+  UnusedImports:
+    active: false
+  UnusedParameter:
+    active: true
+    allowedNames: 'ignored|expected'
+  UnusedPrivateClass:
+    active: true
+  UnusedPrivateMember:
+    active: true
+    allowedNames: ''
+  UnusedPrivateProperty:
+    active: true
+    allowedNames: '_|ignored|expected|serialVersionUID'
+  UseAnyOrNoneInsteadOfFind:
+    active: true
+  UseArrayLiteralsInAnnotations:
+    active: true
+  UseCheckNotNull:
+    active: true
+  UseCheckOrError:
+    active: true
+  UseDataClass:
+    active: false
+    allowVars: false
+  UseEmptyCounterpart:
+    active: false
+  UseIfEmptyOrIfBlank:
+    active: false
+  UseIfInsteadOfWhen:
+    active: false
+    ignoreWhenContainingVariableDeclaration: false
+  UseIsNullOrEmpty:
+    active: true
+  UseLet:
+    active: false
+  UseOrEmpty:
+    active: true
+  UseRequire:
+    active: true
+  UseRequireNotNull:
+    active: true
+  UseSumOfInsteadOfFlatMapSize:
+    active: false
+  UselessCallOnNotNull:
+    active: true
+  UtilityClassWithPublicConstructor:
+    active: true
+  VarCouldBeVal:
+    active: true
+    ignoreLateinitVar: false
+  WildcardImport:
+    active: true
+    excludeImports:
+      - 'java.util.*'
Index: gradle.properties
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>ISO-8859-1
===================================================================
diff --git a/gradle.properties b/gradle.properties
--- a/gradle.properties	(revision 3412d717fb463b9a39505ed8204a4c532a7b253d)
+++ b/gradle.properties	(revision 49ba6acd2ac17c3aa9561c3453f4fa19cf5c967d)
@@ -1,4 +1,7 @@
 kotlin.code.style=official
 kotlin.daemon.jvmargs=-Xmx4g
 org.gradle.jvmargs=-Xmx4g
-ksp.allow.all.target.configuration=true
\ No newline at end of file
+ksp.allow.all.target.configuration=true
+kotlinVersion=2.0.21
+kspVersion=2.0.21-1.0.27
+detektVersion=1.23.8
\ No newline at end of file
Index: settings.gradle.kts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/settings.gradle.kts b/settings.gradle.kts
--- a/settings.gradle.kts	(revision 6a5c23c0c9ed945217e78f94d72330934d5949b7)
+++ b/settings.gradle.kts	(revision 49ba6acd2ac17c3aa9561c3453f4fa19cf5c967d)
@@ -3,11 +3,13 @@
         mavenCentral()
         gradlePluginPortal()
     }
-
     plugins {
-        kotlin("jvm") version "latest.release"
-        kotlin("kapt") version "latest.release"
-        id("com.google.devtools.ksp") version "latest.release"
+        val kotlinVersion: String by settings
+        val kspVersion: String by settings
+
+        kotlin("jvm") version kotlinVersion
+        kotlin("kapt") version kotlinVersion
+        id("com.google.devtools.ksp") version kspVersion
     }
 }
 
@@ -16,6 +18,4 @@
 }
 
 rootProject.name = "BingoNet-Server"
-include("annotation-proccessor")
-include("shared-annotation-proccessor")
-include("main")
+include("annotation-proccessor", "shared-annotation-proccessor", "main", "detekt-rules")
Index: annotation-proccessor/build.gradle.kts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/annotation-proccessor/build.gradle.kts b/annotation-proccessor/build.gradle.kts
--- a/annotation-proccessor/build.gradle.kts	(revision 6a5c23c0c9ed945217e78f94d72330934d5949b7)
+++ b/annotation-proccessor/build.gradle.kts	(revision 3412d717fb463b9a39505ed8204a4c532a7b253d)
@@ -1,5 +1,3 @@
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
-
 plugins {
     kotlin("jvm")
     kotlin("kapt")
@@ -30,7 +28,7 @@
     implementation(project(":shared-annotation-proccessor"))
     testImplementation(kotlin("test"))
     implementation(kotlin("stdlib"))
-    //implementation("org.apache.logging.log4j:log4j-Core.INSTANCE:2.20.0")
+    // implementation("org.apache.logging.log4j:log4j-Core.INSTANCE:2.20.0")
     implementation("com.google.code.gson:gson")
     implementation("com.mysql:mysql-connector-j")
 //    implementation("io.github.JDA-Fork:JDA:82d7ab90d6")
@@ -73,15 +71,15 @@
 //    implementation("moe.nea:neurepoparser:latest.release")
     val exposedVersion = "latest.release"
 
-    implementation("org.jetbrains.exposed:exposed-core:${exposedVersion}")
-    implementation("org.jetbrains.exposed:exposed-crypt:${exposedVersion}")
-    implementation("org.jetbrains.exposed:exposed-dao:${exposedVersion}")
-    implementation("org.jetbrains.exposed:exposed-jdbc:${exposedVersion}")
-    implementation("org.jetbrains.exposed:exposed-kotlin-datetime:${exposedVersion}")
-    implementation("org.jetbrains.exposed:exposed-json:${exposedVersion}")
-    implementation("org.jetbrains.exposed:exposed-money:${exposedVersion}")
-    implementation("org.jetbrains.exposed:exposed-spring-boot-starter:${exposedVersion}")
-    implementation("org.jetbrains.exposed:exposed-migration:${exposedVersion}")
+    implementation("org.jetbrains.exposed:exposed-core:$exposedVersion")
+    implementation("org.jetbrains.exposed:exposed-crypt:$exposedVersion")
+    implementation("org.jetbrains.exposed:exposed-dao:$exposedVersion")
+    implementation("org.jetbrains.exposed:exposed-jdbc:$exposedVersion")
+    implementation("org.jetbrains.exposed:exposed-kotlin-datetime:$exposedVersion")
+    implementation("org.jetbrains.exposed:exposed-json:$exposedVersion")
+    implementation("org.jetbrains.exposed:exposed-money:$exposedVersion")
+    implementation("org.jetbrains.exposed:exposed-spring-boot-starter:$exposedVersion")
+    implementation("org.jetbrains.exposed:exposed-migration:$exposedVersion")
 }
 
 application {
@@ -95,7 +93,20 @@
 tasks.withType<JavaCompile> {
     options.compilerArgs.add("-AprojectDir=${project.projectDir}")
 }
-val compileKotlin: KotlinCompile by tasks
-compileKotlin.compilerOptions {
-    freeCompilerArgs.set(listOf("-Xmulti-dollar-interpolation"))
-}
\ No newline at end of file
+
+// 1) Gemeinsame Kotlin‑Compiler‑Optionen
+kotlin {
+    jvmToolchain(21)
+    compilerOptions {
+        freeCompilerArgs.addAll(
+            listOf(
+                "-Xmulti-dollar-interpolation",
+            )
+        )
+    }
+}
+
+// Dein vorhandener Java‑Annotation‑Processor‑Hook bleibt unverändert:
+tasks.withType<JavaCompile> {
+    options.compilerArgs.add("-AprojectDir=${project.projectDir}")
+}
Index: main/src/main/kotlin/de/hype/bingonet/data/tables/punishment/DisciplinaryActionTables.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/src/main/kotlin/de/hype/bingonet/data/tables/punishment/DisciplinaryActionTables.kt b/main/src/main/kotlin/de/hype/bingonet/data/tables/punishment/DisciplinaryActionTables.kt
--- a/main/src/main/kotlin/de/hype/bingonet/data/tables/punishment/DisciplinaryActionTables.kt	(revision 3412d717fb463b9a39505ed8204a4c532a7b253d)
+++ b/main/src/main/kotlin/de/hype/bingonet/data/tables/punishment/DisciplinaryActionTables.kt	(revision 49ba6acd2ac17c3aa9561c3453f4fa19cf5c967d)
@@ -771,7 +771,6 @@
         user: BBUser,
         type: AppealType,
         message: String,
-        //TODO change over to proofDTO List. (Requires Website Adaptation ig)
         appealProof: List<String>
     ): Appeal {
         val appeal = Appeal.new(this, user, type)
@@ -1109,7 +1108,7 @@
         extraMessage: String?,
         mutliplier: Double
     ) {
-        //TODO
+        TODO("Not yet implemented")
     }
 }
 
Index: main/src/main/kotlin/de/hype/bingonet/data/tables/services/ServiceEntities.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/src/main/kotlin/de/hype/bingonet/data/tables/services/ServiceEntities.kt b/main/src/main/kotlin/de/hype/bingonet/data/tables/services/ServiceEntities.kt
--- a/main/src/main/kotlin/de/hype/bingonet/data/tables/services/ServiceEntities.kt	(revision 3412d717fb463b9a39505ed8204a4c532a7b253d)
+++ b/main/src/main/kotlin/de/hype/bingonet/data/tables/services/ServiceEntities.kt	(revision 49ba6acd2ac17c3aa9561c3453f4fa19cf5c967d)
@@ -187,7 +187,6 @@
             return fullParticipants.toList().subListTo(_queueLimit + 1).toSet()
         }
 
-    //TODO ISSUE: the participants etc change live possible during start? make them persistent?
     var description by Services.description
 
     var title by Services.title
Index: main/src/main/kotlin/de/hype/bingonet/shared/constants/Collections.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/src/main/kotlin/de/hype/bingonet/shared/constants/Collections.kt b/main/src/main/kotlin/de/hype/bingonet/shared/constants/Collections.kt
--- a/main/src/main/kotlin/de/hype/bingonet/shared/constants/Collections.kt	(revision 3412d717fb463b9a39505ed8204a4c532a7b253d)
+++ b/main/src/main/kotlin/de/hype/bingonet/shared/constants/Collections.kt	(revision 49ba6acd2ac17c3aa9561c3453f4fa19cf5c967d)
@@ -63,7 +63,7 @@
         ;
 
 
-        override val tierCount: IntArray = intArrayOf(*tiers)
+        override val tierCount: IntArray = tiers
     }
 
     enum class Mining(override val id: String, override val minionID: String?, vararg tiers: Int) : Collections {
@@ -168,7 +168,7 @@
         Netherrack("NETHERRACK", null, 50, 250, 500, 1000, 5000),
         ;
 
-        override val tierCount: IntArray = intArrayOf(*tiers)
+        override val tierCount: IntArray = tiers
     }
 
     enum class Combat(override val id: String, override val minionID: String?, vararg tiers: Int) : Collections {
@@ -185,7 +185,7 @@
         String("STRING", "SPIDER_GENERATOR_1", 50, 100, 250, 1000, 2500, 5000, 10000, 25000, 50000),
         ;
 
-        override val tierCount: IntArray = intArrayOf(*tiers)
+        override val tierCount: IntArray = tiers
     }
 
     enum class Foraging(override val id: String, override val minionID: String?, vararg tiers: Int) : Collections {
@@ -197,7 +197,7 @@
         Dark_Oak_Wood("LOG_2:1", "DARK_OAK_GENERATOR_1", 50, 100, 250, 1000, 2000, 5000, 10000, 15000, 25000),
         ;
 
-        override val tierCount: IntArray = intArrayOf(*tiers)
+        override val tierCount: IntArray = tiers
     }
 
     enum class Fishing(override val id: String, override val minionID: String?, vararg tiers: Int) : Collections {
@@ -212,7 +212,7 @@
         Clay("CLAY_BALL", "CLAY_GENERATOR_1", 50, 100, 250, 1000, 1500, 2500),
         Sponge("SPONGE", "FISHING_GENERATOR_1", 20, 40, 100, 200, 400, 800, 1500, 2500, 4000);
 
-        override val tierCount: IntArray = intArrayOf(*tiers)
+        override val tierCount: IntArray = tiers
 
     }
 
@@ -225,7 +225,7 @@
         Half_Eaten_Carrot("HALF_EATEN_CARROT", 1, 400, 1000, 3500),
         ;
 
-        override val tierCount: IntArray = intArrayOf(*tiers)
+        override val tierCount: IntArray = tiers
 
         override val minionID: String? = null
     }
Index: shared-annotation-proccessor/src/main/kotlin/de/hype/bingonet/shared/compilation/sbenums/minions/MinionRepoManager.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/shared-annotation-proccessor/src/main/kotlin/de/hype/bingonet/shared/compilation/sbenums/minions/MinionRepoManager.kt b/shared-annotation-proccessor/src/main/kotlin/de/hype/bingonet/shared/compilation/sbenums/minions/MinionRepoManager.kt
--- a/shared-annotation-proccessor/src/main/kotlin/de/hype/bingonet/shared/compilation/sbenums/minions/MinionRepoManager.kt	(revision 3412d717fb463b9a39505ed8204a4c532a7b253d)
+++ b/shared-annotation-proccessor/src/main/kotlin/de/hype/bingonet/shared/compilation/sbenums/minions/MinionRepoManager.kt	(revision 49ba6acd2ac17c3aa9561c3453f4fa19cf5c967d)
@@ -79,6 +79,7 @@
     }
 
     val minionTypes: MutableMap<String, MinionType> by lazy {
+        println(System.getProperties())
         val file = File(NeuRepoManager.LOCAL_PATH.toFile(), "constants/minions.json")
         val json = file.readText()
         val jsonObject = JsonParser.parseString(json).asJsonObject
diff --git a/detekt-rules/src/main/resources/META-INF/services/io.gitlab.arturbosch.detekt.api.RuleSetProvider b/detekt-rules/src/main/resources/META-INF/services/io.gitlab.arturbosch.detekt.api.RuleSetProvider
new file mode 100644
index 0000000000000000000000000000000000000000..316de661760a6abecb9722cb97b16382844b551d
GIT binary patch
literal 60
zc$`Z~)yt?XNYzWq%uCPDOD)kWPAw`+Ez(O#ElJHTDJsoLE!K0bD9A5PO$h>Wf>TQZ
Nit@`cQ&Nk#xB$mY7Wx1H

