diff --git a/CommonCore/SQL/src/de/steamwar/sql/CheckedSchematic.java b/CommonCore/SQL/src/de/steamwar/sql/CheckedSchematic.java
deleted file mode 100644
index 5a0e553c..00000000
--- a/CommonCore/SQL/src/de/steamwar/sql/CheckedSchematic.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * This file is a part of the SteamWar software.
- *
- * Copyright (C) 2025 SteamWar.de-Serverteam
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-package de.steamwar.sql;
-
-import de.steamwar.sql.internal.Field;
-import de.steamwar.sql.internal.SelectStatement;
-import de.steamwar.sql.internal.Statement;
-import de.steamwar.sql.internal.Table;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-import java.sql.Timestamp;
-import java.util.List;
-import java.util.concurrent.CompletableFuture;
-
-@AllArgsConstructor
-public class CheckedSchematic {
-
- private static final Table table = new Table<>(CheckedSchematic.class);
- private static final SelectStatement statusOfNode = new SelectStatement<>(table, "SELECT * FROM CheckedSchematic WHERE NodeId = ? AND DeclineReason != 'Prüfvorgang abgebrochen' ORDER BY EndTime DESC");
- private static final SelectStatement nodeHistory = new SelectStatement<>(table, "SELECT * FROM CheckedSchematic WHERE NodeId = ? AND DeclineReason != '' AND DeclineReason != 'Prüfvorgang abgebrochen' ORDER BY EndTime DESC");
- private static final Statement insert = table.insertAll();
-
- private static final SelectStatement getUnseen = new SelectStatement<>(table, "SELECT * FROM CheckedSchematic WHERE Seen = 0 AND NodeOwner = ? ORDER BY StartTime DESC");
- private static final Statement updateSeen = new Statement("UPDATE CheckedSchematic SET Seen = ? WHERE StartTime = ? AND EndTime = ? AND NodeName = ?");
-
- public static void create(SchematicNode node, int validator, Timestamp startTime, Timestamp endTime, String reason, boolean seen) {
- insert.update(node.getId(), node.getOwner(), node.getName(), validator, startTime, endTime, reason, seen, node.getSchemtype().toDB().substring(1));
- }
-
- public static List getLastDeclinedOfNode(int node) {
- return statusOfNode.listSelect(node);
- }
-
- public static List previousChecks(SchematicNode node) {
- return nodeHistory.listSelect(node.getId());
- }
-
- public static List getUnseen(SteamwarUser owner) {
- return getUnseen.listSelect(owner);
- }
-
- @Field(nullable = true)
- private final Integer nodeId;
- @Field
- private final int nodeOwner;
- @Field
- private final String nodeName;
- @Getter
- @Field
- private final int validator;
- @Getter
- @Field
- private final Timestamp startTime;
- @Getter
- @Field
- private final Timestamp endTime;
- @Getter
- @Field
- private final String declineReason;
- @Getter
- @Field
- private boolean seen;
- @Getter
- @Field
- private final String nodeType;
-
- public int getNode() {
- return nodeId;
- }
-
- public String getSchemName() {
- return nodeName;
- }
-
- public int getSchemOwner() {
- return nodeOwner;
- }
-
- public void setSeen(boolean seen) {
- this.seen = seen;
- updateSeen.update(seen, startTime, endTime, nodeName);
- }
-}
diff --git a/CommonCore/SQL/src/de/steamwar/sql/CheckedSchematic.kt b/CommonCore/SQL/src/de/steamwar/sql/CheckedSchematic.kt
new file mode 100644
index 00000000..3e51d24e
--- /dev/null
+++ b/CommonCore/SQL/src/de/steamwar/sql/CheckedSchematic.kt
@@ -0,0 +1,100 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2025 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.sql
+
+import de.steamwar.sql.internal.useDb
+import org.jetbrains.exposed.v1.core.SortOrder
+import org.jetbrains.exposed.v1.core.and
+import org.jetbrains.exposed.v1.core.dao.id.CompositeID
+import org.jetbrains.exposed.v1.core.dao.id.CompositeIdTable
+import org.jetbrains.exposed.v1.core.dao.id.EntityID
+import org.jetbrains.exposed.v1.core.eq
+import org.jetbrains.exposed.v1.core.neq
+import org.jetbrains.exposed.v1.dao.CompositeEntity
+import org.jetbrains.exposed.v1.dao.CompositeEntityClass
+import org.jetbrains.exposed.v1.javatime.timestamp
+import org.jetbrains.exposed.v1.jdbc.insertIgnore
+import java.sql.Timestamp
+
+object CheckedSchematicTable: CompositeIdTable("CheckedSchematic") {
+ val nodeId = optReference("NodeId", SchematicNodeTable)
+ val nodeOwner = reference("NodeOwner", SteamwarUserTable)
+ val nodeName = varchar("NodeName", 64).entityId()
+ val validator = reference("Validator", SteamwarUserTable)
+ val startTime = timestamp("StartTime").entityId()
+ val endTime = timestamp("EndTime")
+ val declineReason = text("DeclineReason")
+ val seen = bool("Seen")
+ val nodeType = varchar("NodeType", 16)
+
+ init {
+ addIdColumn(nodeOwner)
+ addIdColumn(nodeName)
+ }
+}
+
+class CheckedSchematic(id: EntityID): CompositeEntity(id) {
+ companion object: CompositeEntityClass(CheckedSchematicTable) {
+ @JvmStatic
+ fun create(node: SchematicNode, validator: Int, startTime: Timestamp, endTime: Timestamp, reason: String, seen: Boolean) = useDb {
+ CheckedSchematicTable.insertIgnore {
+ it[this.nodeId] = node.id
+ it[this.nodeOwner] = EntityID(node.owner, SteamwarUserTable)
+ it[this.nodeName] = node.name
+ it[this.validator] = EntityID(validator, SteamwarUserTable)
+ it[this.startTime] = startTime.toInstant()
+ it[this.endTime] = endTime.toInstant()
+ it[this.declineReason] = reason
+ it[this.seen] = seen
+ it[this.nodeType] = node.schemtype.toDB().substring(1)
+ }
+ }
+
+ @JvmStatic
+ fun getLastDeclinedOfNode(node: Int) = useDb {
+ find { (CheckedSchematicTable.nodeId eq node) and (CheckedSchematicTable.declineReason neq "Prüfvorgang abgebrochen") }.orderBy(CheckedSchematicTable.endTime to SortOrder.DESC).toList()
+ }
+
+ @JvmStatic
+ fun previousChecks(node: SchematicNode) = useDb {
+ find { (CheckedSchematicTable.nodeId eq node.id) and (CheckedSchematicTable.declineReason neq "") and (CheckedSchematicTable.declineReason neq "Prüfvorgang abgebrochen") }.orderBy(CheckedSchematicTable.endTime to SortOrder.DESC).toList()
+ }
+
+ @JvmStatic
+ fun getUnseen(owner: SteamwarUser) = useDb {
+ find { (CheckedSchematicTable.nodeOwner eq owner.id) and (CheckedSchematicTable.seen eq false) }.orderBy(CheckedSchematicTable.endTime to SortOrder.DESC).toList()
+ }
+ }
+
+ val node by CheckedSchematicTable.nodeId.transform({ it?.let { EntityID(it, SchematicNodeTable) } }, { it?.value })
+ val schemOwner by CheckedSchematicTable.nodeOwner.transform({ EntityID(it, SteamwarUserTable) }, { it.value })
+ val nodeName by CheckedSchematicTable.nodeName
+ val schemName get() = nodeName.value
+ val validator by CheckedSchematicTable.validator.transform({ EntityID(it, SteamwarUserTable) }, { it.value })
+ val startTimeId by CheckedSchematicTable.startTime
+ val startTime get() = Timestamp.from(startTimeId.value)
+ val endTime by CheckedSchematicTable.endTime.transform({ it.toInstant() }, { Timestamp.from(it) })
+ val declineReason by CheckedSchematicTable.declineReason
+ private var wasSeen by CheckedSchematicTable.seen
+ var seen: Boolean
+ get() = wasSeen
+ set(value) = useDb { wasSeen = value }
+ val nodeType by CheckedSchematicTable.nodeType
+}
\ No newline at end of file