Weiter am Chastity Game gebastelt

This commit is contained in:
2026-03-17 23:01:14 +01:00
parent aafc203407
commit d22b87a79b
234 changed files with 3465 additions and 12528 deletions

View File

@@ -9,4 +9,34 @@ Verknüpfung der Spiele, wenn das Finish eines aus dem Bereich Chastity ist, wir
Wenn ein Lock für einen User existiert, wird er ohne entsprechend Penis/Vagina zu dem Spiel erstellt.
Ich kann Spieler einladen zu spielen, dann kriegt die Person eine E-Mail und muss bestätigen, dass es diese PErson ist, sie wird dann ins spiel übernommen
-- Falls fall mit Chastity auftritt wird die Spielpartnerin als Keyholder eingetragen, diese Person darf entscheiden, was für ein Lock das wird.
-- Falls fall mit Chastity auftritt wird die Spielpartnerin als Keyholder eingetragen, diese Person darf entscheiden, was für ein Lock das wird.
Hier ein paar Ideen für neue Kartentypen:
Bestrafungskarten
- Straf-Karte Lockee muss eine vorher definierte Strafe erfüllen (ähnlich Task, aber negativer konnotiert)
- Extra-Rot Fügt sofort 2-3 rote Karten hinzu, kein Ziehen möglich
Belohnungskarten
- Bonus-Grün LatestOpeningTime wird auf jetzt gesetzt (sofortige Öffnungsmöglichkeit), aber nur kurz gültig (z.B. 30 Minuten Fenster)
- Karten entfernen Lockee darf eine bestimmte Anzahl roter Karten aus dem Deck entfernen
Ereigniskarten
- Würfel-Karte Zufällige Aktion: 1-2 = Freeze, 3-4 = Nichts, 5-6 = Grüne Karte
- Umkehr-Karte Die nächste Karte hat den umgekehrten Effekt (Rot → Grün, Freeze → Beschleunigung)
- Überraschungs-Karte Community, Keyholder oder Zufalls-Task, je nachdem was gerade konfiguriert ist
Zeitkarten
- Verlängerungs-Karte Verschiebt die latestOpeningtime nach hinten (nur bei Keyholder-Locks sinnvoll)
- Countdown-Karte Setzt einen Timer; wenn die Lockee innerhalb der Zeit eine Aufgabe erledigt, wird eine grüne Karte freigeschaltet
- Hygiene-Skip Nächste Hygiene-Öffnung wird übersprungen/gezählt ohne tatsächliche Öffnung
Soziale Karten
- Verifizierungs-Karte Erzwingt sofort eine Verifikations-Session
- Keyholder-Wahl Keyholder entscheidet frei was passiert (Freitext-Eingabe möglich)
- Community-Entscheid Community stimmt nicht über eine Aufgabe ab, sondern darüber was als nächstes passiert (z.B. Freeze vs. Aufgabe)
Die interessantesten wären wohl Würfel und Countdown, da sie mehr Spannung erzeugen ohne den Ablauf zu sehr zu unterbrechen.

View File

@@ -1,8 +1,13 @@
package de.oaa.xxx.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
public class Aufgabe {
private UUID aufgabeId;
@@ -15,34 +20,4 @@ public class Aufgabe {
private List<Werkzeug> benoetigtAktiv;
private List<Werkzeug> benoetigtPassiv;
private List<Toy> benoetigteToys;
public UUID getAufgabeId() { return aufgabeId; }
public void setAufgabeId(UUID aufgabeId) { this.aufgabeId = aufgabeId; }
public String getKurzText() { return kurzText; }
public void setKurzText(String kurzText) { this.kurzText = kurzText; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
public Integer getLevel() { return level; }
public void setLevel(Integer level) { this.level = level; }
public Integer getSekundenVon() { return sekundenVon; }
public void setSekundenVon(Integer sekundenVon) { this.sekundenVon = sekundenVon; }
public Integer getSekundenBis() { return sekundenBis; }
public void setSekundenBis(Integer sekundenBis) { this.sekundenBis = sekundenBis; }
public UUID getGruppeId() { return gruppeId; }
public void setGruppeId(UUID gruppeId) { this.gruppeId = gruppeId; }
public List<Werkzeug> getBenoetigtAktiv() { return benoetigtAktiv; }
public void setBenoetigtAktiv(List<Werkzeug> benoetigtAktiv) { this.benoetigtAktiv = benoetigtAktiv; }
public List<Werkzeug> getBenoetigtPassiv() { return benoetigtPassiv; }
public void setBenoetigtPassiv(List<Werkzeug> benoetigtPassiv) { this.benoetigtPassiv = benoetigtPassiv; }
public List<Toy> getBenoetigteToys() { return benoetigteToys; }
public void setBenoetigteToys(List<Toy> benoetigteToys) { this.benoetigteToys = benoetigteToys; }
}

View File

@@ -1,8 +1,13 @@
package de.oaa.xxx.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
public class AufgabenGruppe {
private UUID gruppenId;
@@ -18,43 +23,4 @@ public class AufgabenGruppe {
private String bild;
private long subscriberCount;
private boolean subscribed;
public UUID getGruppenId() { return gruppenId; }
public void setGruppenId(UUID gruppenId) { this.gruppenId = gruppenId; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getBeschreibung() { return beschreibung; }
public void setBeschreibung(String beschreibung) { this.beschreibung = beschreibung; }
public String getVon() { return von; }
public void setVon(String von) { this.von = von; }
public UUID getUserId() { return userId; }
public void setUserId(UUID userId) { this.userId = userId; }
public boolean isPrivateGruppe() { return privateGruppe; }
public void setPrivateGruppe(boolean privateGruppe) { this.privateGruppe = privateGruppe; }
public List<Aufgabe> getAufgaben() { return aufgaben; }
public void setAufgaben(List<Aufgabe> aufgaben) { this.aufgaben = aufgaben; }
public List<Strafe> getStrafen() { return strafen; }
public void setStrafen(List<Strafe> strafen) { this.strafen = strafen; }
public List<Sperre> getSperren() { return sperren; }
public void setSperren(List<Sperre> sperren) { this.sperren = sperren; }
public List<Finisher> getFinisher() { return finisher; }
public void setFinisher(List<Finisher> finisher) { this.finisher = finisher; }
public String getBild() { return bild; }
public void setBild(String bild) { this.bild = bild; }
public long getSubscriberCount() { return subscriberCount; }
public void setSubscriberCount(long subscriberCount) { this.subscriberCount = subscriberCount; }
public boolean isSubscribed() { return subscribed; }
public void setSubscribed(boolean subscribed) { this.subscribed = subscribed; }
}

View File

@@ -1,7 +1,12 @@
package de.oaa.xxx.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.UUID;
@Getter
@Setter
public class AufgabenGruppeDisplay {
private UUID gruppenId;
@@ -11,25 +16,4 @@ public class AufgabenGruppeDisplay {
private boolean privateGruppe;
private String bild;
private String von;
public UUID getGruppenId() { return gruppenId; }
public void setGruppenId(UUID gruppenId) { this.gruppenId = gruppenId; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getBeschreibung() { return beschreibung; }
public void setBeschreibung(String beschreibung) { this.beschreibung = beschreibung; }
public UUID getUserId() { return userId; }
public void setUserId(UUID userId) { this.userId = userId; }
public boolean isPrivateGruppe() { return privateGruppe; }
public void setPrivateGruppe(boolean privateGruppe) { this.privateGruppe = privateGruppe; }
public String getBild() { return bild; }
public void setBild(String bild) { this.bild = bild; }
public String getVon() { return von; }
public void setVon(String von) { this.von = von; }
}

View File

@@ -1,11 +1,13 @@
package de.oaa.xxx.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class AufgabenGruppeList {
private List<AufgabenGruppeDisplay> gruppen;
public List<AufgabenGruppeDisplay> getGruppen() { return gruppen; }
public void setGruppen(List<AufgabenGruppeDisplay> gruppen) { this.gruppen = gruppen; }
}

View File

@@ -1,23 +1,16 @@
package de.oaa.xxx.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class AufgabenGruppePage {
private List<AufgabenGruppe> content;
private int currentPage;
private int totalPages;
private long totalElements;
public List<AufgabenGruppe> getContent() { return content; }
public void setContent(List<AufgabenGruppe> content) { this.content = content; }
public int getCurrentPage() { return currentPage; }
public void setCurrentPage(int currentPage) { this.currentPage = currentPage; }
public int getTotalPages() { return totalPages; }
public void setTotalPages(int totalPages) { this.totalPages = totalPages; }
public long getTotalElements() { return totalElements; }
public void setTotalElements(long totalElements) { this.totalElements = totalElements; }
}

View File

@@ -1,19 +1,15 @@
package de.oaa.xxx.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.UUID;
@Getter
@Setter
public class Favorit {
private UUID favoritId;
private UUID userId;
private UUID aufgabenGruppeId;
public UUID getFavoritId() { return favoritId; }
public void setFavoritId(UUID favoritId) { this.favoritId = favoritId; }
public UUID getUserId() { return userId; }
public void setUserId(UUID userId) { this.userId = userId; }
public UUID getAufgabenGruppeId() { return aufgabenGruppeId; }
public void setAufgabenGruppeId(UUID aufgabenGruppeId) { this.aufgabenGruppeId = aufgabenGruppeId; }
}

View File

@@ -1,11 +1,13 @@
package de.oaa.xxx.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class FavoritList {
private List<Favorit> favoriten;
public List<Favorit> getFavoriten() { return favoriten; }
public void setFavoriten(List<Favorit> favoriten) { this.favoriten = favoriten; }
}

View File

@@ -1,10 +1,14 @@
package de.oaa.xxx.aufgaben;
import de.oaa.xxx.session.GeschlechtEnum;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
public class Finisher {
private UUID finisherId;
@@ -16,30 +20,6 @@ public class Finisher {
private List<Toy> benoetigteToys;
private UUID gruppeId;
public UUID getFinisherId() { return finisherId; }
public void setFinisherId(UUID finisherId) { this.finisherId = finisherId; }
public String getKurzText() { return kurzText; }
public void setKurzText(String kurzText) { this.kurzText = kurzText; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
public GeschlechtEnum getGeschlecht() { return geschlecht; }
public void setGeschlecht(GeschlechtEnum geschlecht) { this.geschlecht = geschlecht; }
public List<Werkzeug> getBenoetigtAktiv() { return benoetigtAktiv; }
public void setBenoetigtAktiv(List<Werkzeug> benoetigtAktiv) { this.benoetigtAktiv = benoetigtAktiv; }
public List<Werkzeug> getBenoetigtPassiv() { return benoetigtPassiv; }
public void setBenoetigtPassiv(List<Werkzeug> benoetigtPassiv) { this.benoetigtPassiv = benoetigtPassiv; }
public List<Toy> getBenoetigteToys() { return benoetigteToys; }
public void setBenoetigteToys(List<Toy> benoetigteToys) { this.benoetigteToys = benoetigteToys; }
public UUID getGruppeId() { return gruppeId; }
public void setGruppeId(UUID gruppeId) { this.gruppeId = gruppeId; }
@Override
public String toString() {
return "Finisher[id=" + finisherId + ", kurzText=" + kurzText + ", geschlecht=" + geschlecht + ", gruppeId=" + gruppeId + "]";

View File

@@ -1,8 +1,13 @@
package de.oaa.xxx.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
public class Sperre {
private UUID sperreId;
@@ -14,31 +19,4 @@ public class Sperre {
private Integer minutenVon;
private Integer minutenBis;
private List<Toy> benoetigteToys;
public UUID getSperreId() { return sperreId; }
public void setSperreId(UUID sperreId) { this.sperreId = sperreId; }
public String getKurzText() { return kurzText; }
public void setKurzText(String kurzText) { this.kurzText = kurzText; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
public String getReleaseText() { return releaseText; }
public void setReleaseText(String releaseText) { this.releaseText = releaseText; }
public UUID getGruppeId() { return gruppeId; }
public void setGruppeId(UUID gruppeId) { this.gruppeId = gruppeId; }
public List<Werkzeug> getSperreFuer() { return sperreFuer; }
public void setSperreFuer(List<Werkzeug> sperreFuer) { this.sperreFuer = sperreFuer; }
public Integer getMinutenVon() { return minutenVon; }
public void setMinutenVon(Integer minutenVon) { this.minutenVon = minutenVon; }
public Integer getMinutenBis() { return minutenBis; }
public void setMinutenBis(Integer minutenBis) { this.minutenBis = minutenBis; }
public List<Toy> getBenoetigteToys() { return benoetigteToys; }
public void setBenoetigteToys(List<Toy> benoetigteToys) { this.benoetigteToys = benoetigteToys; }
}

View File

@@ -1,8 +1,13 @@
package de.oaa.xxx.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
public class Strafe {
private UUID strafeId;
@@ -15,34 +20,4 @@ public class Strafe {
private List<Werkzeug> benoetigtAktiv;
private List<Werkzeug> benoetigtPassiv;
private List<Toy> benoetigteToys;
public UUID getStrafeId() { return strafeId; }
public void setStrafeId(UUID strafeId) { this.strafeId = strafeId; }
public Integer getLevel() { return level; }
public void setLevel(Integer level) { this.level = level; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
public String getKurzText() { return kurzText; }
public void setKurzText(String kurzText) { this.kurzText = kurzText; }
public Integer getSekundenVon() { return sekundenVon; }
public void setSekundenVon(Integer sekundenVon) { this.sekundenVon = sekundenVon; }
public Integer getSekundenBis() { return sekundenBis; }
public void setSekundenBis(Integer sekundenBis) { this.sekundenBis = sekundenBis; }
public UUID getGruppeId() { return gruppeId; }
public void setGruppeId(UUID gruppeId) { this.gruppeId = gruppeId; }
public List<Werkzeug> getBenoetigtAktiv() { return benoetigtAktiv; }
public void setBenoetigtAktiv(List<Werkzeug> benoetigtAktiv) { this.benoetigtAktiv = benoetigtAktiv; }
public List<Werkzeug> getBenoetigtPassiv() { return benoetigtPassiv; }
public void setBenoetigtPassiv(List<Werkzeug> benoetigtPassiv) { this.benoetigtPassiv = benoetigtPassiv; }
public List<Toy> getBenoetigteToys() { return benoetigteToys; }
public void setBenoetigteToys(List<Toy> benoetigteToys) { this.benoetigteToys = benoetigteToys; }
}

View File

@@ -1,7 +1,12 @@
package de.oaa.xxx.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.UUID;
@Getter
@Setter
public class Toy {
private UUID toyId;
@@ -9,19 +14,4 @@ public class Toy {
private String beschreibung;
private UUID userId;
private String bild;
public UUID getToyId() { return toyId; }
public void setToyId(UUID toyId) { this.toyId = toyId; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getBeschreibung() { return beschreibung; }
public void setBeschreibung(String beschreibung) { this.beschreibung = beschreibung; }
public UUID getUserId() { return userId; }
public void setUserId(UUID userId) { this.userId = userId; }
public String getBild() { return bild; }
public void setBild(String bild) { this.bild = bild; }
}

View File

@@ -1,15 +1,14 @@
package de.oaa.xxx.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class ToyList {
private List<Toy> systemToys;
private List<Toy> userToys;
public List<Toy> getSystemToys() { return systemToys; }
public void setSystemToys(List<Toy> systemToys) { this.systemToys = systemToys; }
public List<Toy> getUserToys() { return userToys; }
public void setUserToys(List<Toy> userToys) { this.userToys = userToys; }
}

View File

@@ -1,23 +1,16 @@
package de.oaa.xxx.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class ToyPage {
private List<Toy> content;
private int currentPage;
private int totalPages;
private long totalElements;
public List<Toy> getContent() { return content; }
public void setContent(List<Toy> content) { this.content = content; }
public int getCurrentPage() { return currentPage; }
public void setCurrentPage(int currentPage) { this.currentPage = currentPage; }
public int getTotalPages() { return totalPages; }
public void setTotalPages(int totalPages) { this.totalPages = totalPages; }
public long getTotalElements() { return totalElements; }
public void setTotalElements(long totalElements) { this.totalElements = totalElements; }
}

View File

@@ -15,11 +15,15 @@ import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "aufgabe")
public class AufgabeEntity {
@@ -54,36 +58,6 @@ public class AufgabeEntity {
@JoinTable(name = "aufgabeToy", joinColumns = {@JoinColumn(name = "aufgabeId")}, inverseJoinColumns = {@JoinColumn(name = "toyId")})
private List<ToyEntity> benoetigteToys;
public UUID getAufgabeId() { return aufgabeId; }
public void setAufgabeId(UUID aufgabeId) { this.aufgabeId = aufgabeId; }
public String getKurzText() { return kurzText; }
public void setKurzText(String kurzText) { this.kurzText = kurzText; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
public Integer getLevel() { return level; }
public void setLevel(Integer level) { this.level = level; }
public Integer getSekundenVon() { return sekundenVon; }
public void setSekundenVon(Integer sekundenVon) { this.sekundenVon = sekundenVon; }
public Integer getSekundenBis() { return sekundenBis; }
public void setSekundenBis(Integer sekundenBis) { this.sekundenBis = sekundenBis; }
public AufgabenGruppeEntity getAufgabenGruppe() { return aufgabenGruppe; }
public void setAufgabenGruppe(AufgabenGruppeEntity aufgabenGruppe) { this.aufgabenGruppe = aufgabenGruppe; }
public List<Werkzeug> getBenoetigtAktiv() { return benoetigtAktiv; }
public void setBenoetigtAktiv(List<Werkzeug> benoetigtAktiv) { this.benoetigtAktiv = benoetigtAktiv; }
public List<Werkzeug> getBenoetigtPassiv() { return benoetigtPassiv; }
public void setBenoetigtPassiv(List<Werkzeug> benoetigtPassiv) { this.benoetigtPassiv = benoetigtPassiv; }
public List<ToyEntity> getBenoetigteToys() { return benoetigteToys; }
public void setBenoetigteToys(List<ToyEntity> benoetigteToys) { this.benoetigteToys = benoetigteToys; }
@Override
public String toString() {
return "AufgabeEntity[id=" + aufgabeId + ", kurzText=" + kurzText + ", level=" + level

View File

@@ -8,11 +8,15 @@ import jakarta.persistence.Id;
import jakarta.persistence.Lob;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.util.Base64;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "aufgabenGruppe")
public class AufgabenGruppeEntity {
@@ -42,39 +46,6 @@ public class AufgabenGruppeEntity {
@OneToMany(mappedBy = "aufgabenGruppe")
private List<FinisherEntity> finisher;
public UUID getGruppenId() { return gruppenId; }
public void setGruppenId(UUID gruppenId) { this.gruppenId = gruppenId; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getBeschreibung() { return beschreibung; }
public void setBeschreibung(String beschreibung) { this.beschreibung = beschreibung; }
public UUID getUserId() { return userId; }
public void setUserId(UUID userId) { this.userId = userId; }
public boolean isPrivateGruppe() { return privateGruppe; }
public void setPrivateGruppe(boolean privateGruppe) { this.privateGruppe = privateGruppe; }
public byte[] getBild() { return bild; }
public void setBild(byte[] bild) { this.bild = bild; }
public String getVon() { return von; }
public void setVon(String von) { this.von = von; }
public List<AufgabeEntity> getAufgaben() { return aufgaben; }
public void setAufgaben(List<AufgabeEntity> aufgaben) { this.aufgaben = aufgaben; }
public List<StrafeEntity> getStrafen() { return strafen; }
public void setStrafen(List<StrafeEntity> strafen) { this.strafen = strafen; }
public List<SperreEntity> getSperren() { return sperren; }
public void setSperren(List<SperreEntity> sperren) { this.sperren = sperren; }
public List<FinisherEntity> getFinisher() { return finisher; }
public void setFinisher(List<FinisherEntity> finisher) { this.finisher = finisher; }
@Override
public String toString() {
return "AufgabenGruppeEntity[gruppenId=" + gruppenId + ", name=" + name + ", userId=" + userId

View File

@@ -5,9 +5,13 @@ import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "favorit")
public class FavoritEntity {
@@ -20,15 +24,6 @@ public class FavoritEntity {
@Column
private UUID aufgabenGruppeId;
public UUID getFavoritId() { return favoritId; }
public void setFavoritId(UUID favoritId) { this.favoritId = favoritId; }
public UUID getUserId() { return userId; }
public void setUserId(UUID userId) { this.userId = userId; }
public UUID getAufgabenGruppeId() { return aufgabenGruppeId; }
public void setAufgabenGruppeId(UUID aufgabenGruppeId) { this.aufgabenGruppeId = aufgabenGruppeId; }
@Override
public String toString() {
return "FavoritEntity[favoritId=" + favoritId + ", userId=" + userId + ", gruppeId=" + aufgabenGruppeId + "]";

View File

@@ -16,11 +16,15 @@ import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "finisher")
public class FinisherEntity {
@@ -52,30 +56,6 @@ public class FinisherEntity {
@JoinTable(name = "finisherToy", joinColumns = {@JoinColumn(name = "finisherId")}, inverseJoinColumns = {@JoinColumn(name = "toyId")})
private List<ToyEntity> benoetigteToys;
public UUID getFinisherId() { return finisherId; }
public void setFinisherId(UUID finisherId) { this.finisherId = finisherId; }
public String getKurzText() { return kurzText; }
public void setKurzText(String kurzText) { this.kurzText = kurzText; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
public GeschlechtEnum getGeschlecht() { return geschlecht; }
public void setGeschlecht(GeschlechtEnum geschlecht) { this.geschlecht = geschlecht; }
public AufgabenGruppeEntity getAufgabenGruppe() { return aufgabenGruppe; }
public void setAufgabenGruppe(AufgabenGruppeEntity aufgabenGruppe) { this.aufgabenGruppe = aufgabenGruppe; }
public List<Werkzeug> getBenoetigtAktiv() { return benoetigtAktiv; }
public void setBenoetigtAktiv(List<Werkzeug> benoetigtAktiv) { this.benoetigtAktiv = benoetigtAktiv; }
public List<Werkzeug> getBenoetigtPassiv() { return benoetigtPassiv; }
public void setBenoetigtPassiv(List<Werkzeug> benoetigtPassiv) { this.benoetigtPassiv = benoetigtPassiv; }
public List<ToyEntity> getBenoetigteToys() { return benoetigteToys; }
public void setBenoetigteToys(List<ToyEntity> benoetigteToys) { this.benoetigteToys = benoetigteToys; }
@Override
public String toString() {
return "FinisherEntity[id=" + finisherId + ", kurzText=" + kurzText + ", geschlecht=" + geschlecht + "]";

View File

@@ -6,9 +6,13 @@ import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "gruppen_abo")
public class GruppenAboEntity {
@@ -24,15 +28,6 @@ public class GruppenAboEntity {
@JoinColumn(name = "gruppenId")
private AufgabenGruppeEntity aufgabenGruppe;
public UUID getAboId() { return aboId; }
public void setAboId(UUID aboId) { this.aboId = aboId; }
public UUID getUserId() { return userId; }
public void setUserId(UUID userId) { this.userId = userId; }
public AufgabenGruppeEntity getAufgabenGruppe() { return aufgabenGruppe; }
public void setAufgabenGruppe(AufgabenGruppeEntity aufgabenGruppe) { this.aufgabenGruppe = aufgabenGruppe; }
@Override
public String toString() {
return "GruppenAboEntity[aboId=" + aboId + ", userId=" + userId

View File

@@ -15,11 +15,15 @@ import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "sperre")
public class SperreEntity {
@@ -49,33 +53,6 @@ public class SperreEntity {
@JoinTable(name = "sperreToy", joinColumns = {@JoinColumn(name = "sperreId")}, inverseJoinColumns = {@JoinColumn(name = "toyId")})
private List<ToyEntity> benoetigteToys;
public UUID getSperreId() { return sperreId; }
public void setSperreId(UUID sperreId) { this.sperreId = sperreId; }
public String getKurzText() { return kurzText; }
public void setKurzText(String kurzText) { this.kurzText = kurzText; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
public String getReleaseText() { return releaseText; }
public void setReleaseText(String releaseText) { this.releaseText = releaseText; }
public AufgabenGruppeEntity getAufgabenGruppe() { return aufgabenGruppe; }
public void setAufgabenGruppe(AufgabenGruppeEntity aufgabenGruppe) { this.aufgabenGruppe = aufgabenGruppe; }
public List<Werkzeug> getSperreFuer() { return sperreFuer; }
public void setSperreFuer(List<Werkzeug> sperreFuer) { this.sperreFuer = sperreFuer; }
public Integer getMinutenVon() { return minutenVon; }
public void setMinutenVon(Integer minutenVon) { this.minutenVon = minutenVon; }
public Integer getMinutenBis() { return minutenBis; }
public void setMinutenBis(Integer minutenBis) { this.minutenBis = minutenBis; }
public List<ToyEntity> getBenoetigteToys() { return benoetigteToys; }
public void setBenoetigteToys(List<ToyEntity> benoetigteToys) { this.benoetigteToys = benoetigteToys; }
@Override
public String toString() {
return "SperreEntity[id=" + sperreId + ", kurzText=" + kurzText

View File

@@ -15,11 +15,15 @@ import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "strafe")
public class StrafeEntity {
@@ -54,36 +58,6 @@ public class StrafeEntity {
@JoinTable(name = "strafeToy", joinColumns = {@JoinColumn(name = "strafeId")}, inverseJoinColumns = {@JoinColumn(name = "toyId")})
private List<ToyEntity> benoetigteToys;
public UUID getStrafeId() { return strafeId; }
public void setStrafeId(UUID strafeId) { this.strafeId = strafeId; }
public String getKurzText() { return kurzText; }
public void setKurzText(String kurzText) { this.kurzText = kurzText; }
public Integer getLevel() { return level; }
public void setLevel(Integer level) { this.level = level; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
public Integer getSekundenVon() { return sekundenVon; }
public void setSekundenVon(Integer sekundenVon) { this.sekundenVon = sekundenVon; }
public Integer getSekundenBis() { return sekundenBis; }
public void setSekundenBis(Integer sekundenBis) { this.sekundenBis = sekundenBis; }
public AufgabenGruppeEntity getAufgabenGruppe() { return aufgabenGruppe; }
public void setAufgabenGruppe(AufgabenGruppeEntity aufgabenGruppe) { this.aufgabenGruppe = aufgabenGruppe; }
public List<Werkzeug> getBenoetigtAktiv() { return benoetigtAktiv; }
public void setBenoetigtAktiv(List<Werkzeug> benoetigtAktiv) { this.benoetigtAktiv = benoetigtAktiv; }
public List<Werkzeug> getBenoetigtPassiv() { return benoetigtPassiv; }
public void setBenoetigtPassiv(List<Werkzeug> benoetigtPassiv) { this.benoetigtPassiv = benoetigtPassiv; }
public List<ToyEntity> getBenoetigteToys() { return benoetigteToys; }
public void setBenoetigteToys(List<ToyEntity> benoetigteToys) { this.benoetigteToys = benoetigteToys; }
@Override
public String toString() {
return "StrafeEntity[id=" + strafeId + ", kurzText=" + kurzText + ", level=" + level

View File

@@ -6,10 +6,14 @@ import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Lob;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.util.Base64;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "toy")
public class ToyEntity {
@@ -27,21 +31,6 @@ public class ToyEntity {
@Column(columnDefinition = "BLOB")
private byte[] bild;
public UUID getToyId() { return toyId; }
public void setToyId(UUID toyId) { this.toyId = toyId; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getBeschreibung() { return beschreibung; }
public void setBeschreibung(String beschreibung) { this.beschreibung = beschreibung; }
public UUID getUserId() { return userId; }
public void setUserId(UUID userId) { this.userId = userId; }
public byte[] getBild() { return bild; }
public void setBild(byte[] bild) { this.bild = bild; }
@Override
public String toString() {
return "ToyEntity[toyId=" + toyId + ", name=" + name + ", userId=" + userId + "]";

View File

@@ -10,7 +10,6 @@ import org.springframework.security.config.annotation.web.configurers.AbstractHt
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
@Configuration
@EnableWebSecurity
@@ -23,7 +22,7 @@ public class SecurityConfig {
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable)
.sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
@@ -32,65 +31,66 @@ public class SecurityConfig {
response.sendRedirect("/login.html")))
.authorizeHttpRequests(auth -> auth
.dispatcherTypeMatchers(DispatcherType.ASYNC, DispatcherType.ERROR).permitAll()
.requestMatchers(AntPathRequestMatcher.antMatcher("/")).permitAll()
.requestMatchers(AntPathRequestMatcher.antMatcher("/error")).permitAll()
.requestMatchers(AntPathRequestMatcher.antMatcher("/userhome.html")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/toys.html")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/aufgaben.html")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/entdecken.html")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/profile.html")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/infovanilla.html")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/infobdsm.html")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/infochastity.html")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/sessionvanilla.html")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/sessionbdsm.html")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/sessionchastity.html")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/neulock.html")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/activelock.html")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/sessionbdsmtasks.html")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/sessionbdsmtoys.html")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/sessionbdsmingame.html")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/personen-suchen.html")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/freunde.html")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/nachrichten.html")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/benutzer.html")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/gruppen.html")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/gruppe.html")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/feed.html")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/communityvotes.html")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/keyholder.html")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/meine-locks.html")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/unlock-history.html")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/einladungen.html")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/joinlock.html")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/benachrichtigungen.html")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/gruppen/**")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/feed/**")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/notifications/**")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/events/**")).authenticated()
.requestMatchers(AntPathRequestMatcher.antMatcher("/*.html")).permitAll()
.requestMatchers(AntPathRequestMatcher.antMatcher("/css/**")).permitAll()
.requestMatchers(AntPathRequestMatcher.antMatcher("/js/**")).permitAll()
.requestMatchers(AntPathRequestMatcher.antMatcher("/images/**")).permitAll()
.requestMatchers(AntPathRequestMatcher.antMatcher("/favicon.ico")).permitAll()
.requestMatchers(AntPathRequestMatcher.antMatcher("/audio/**")).permitAll()
.requestMatchers(AntPathRequestMatcher.antMatcher("/*.png")).permitAll()
.requestMatchers(AntPathRequestMatcher.antMatcher("/*.jpg")).permitAll()
.requestMatchers(AntPathRequestMatcher.antMatcher("/*.svg")).permitAll()
.requestMatchers(AntPathRequestMatcher.antMatcher("/*.webp")).permitAll()
.requestMatchers(AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/login")).permitAll()
.requestMatchers(AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/login/publickey")).permitAll()
.requestMatchers(AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/login/logout")).permitAll()
.requestMatchers(AntPathRequestMatcher.antMatcher(HttpMethod.POST, "/user")).permitAll()
.requestMatchers(AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/registration")).permitAll()
.requestMatchers(AntPathRequestMatcher.antMatcher(HttpMethod.POST, "/registration")).permitAll()
.requestMatchers(AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/activation")).permitAll()
.requestMatchers(AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/activation/**")).permitAll()
.requestMatchers(AntPathRequestMatcher.antMatcher(HttpMethod.POST, "/password-reset/request")).permitAll()
.requestMatchers(AntPathRequestMatcher.antMatcher(HttpMethod.POST, "/password-reset/confirm")).permitAll()
.requestMatchers(AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/email-change/**")).permitAll()
.requestMatchers(AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/keyholder/invitation/**")).permitAll()
.requestMatchers(AntPathRequestMatcher.antMatcher(HttpMethod.POST, "/filler")).permitAll()
.requestMatchers("/").permitAll()
.requestMatchers("/error").permitAll()
.requestMatchers("/userhome.html").authenticated()
.requestMatchers("/toys.html").authenticated()
.requestMatchers("/aufgaben.html").authenticated()
.requestMatchers("/entdecken.html").authenticated()
.requestMatchers("/profile.html").authenticated()
.requestMatchers("/infovanilla.html").authenticated()
.requestMatchers("/infobdsm.html").authenticated()
.requestMatchers("/infochastity.html").authenticated()
.requestMatchers("/sessionvanilla.html").authenticated()
.requestMatchers("/sessionbdsm.html").authenticated()
.requestMatchers("/sessionchastity.html").authenticated()
.requestMatchers("/neulock.html").authenticated()
.requestMatchers("/activelock.html").authenticated()
.requestMatchers("/sessionbdsmtasks.html").authenticated()
.requestMatchers("/sessionbdsmtoys.html").authenticated()
.requestMatchers("/sessionbdsmingame.html").authenticated()
.requestMatchers("/personen-suchen.html").authenticated()
.requestMatchers("/freunde.html").authenticated()
.requestMatchers("/nachrichten.html").authenticated()
.requestMatchers("/benutzer.html").authenticated()
.requestMatchers("/gruppen.html").authenticated()
.requestMatchers("/gruppe.html").authenticated()
.requestMatchers("/feed.html").authenticated()
.requestMatchers("/communityvotes.html").authenticated()
.requestMatchers("/keyholder.html").authenticated()
.requestMatchers("/meine-locks.html").authenticated()
.requestMatchers("/unlock-history.html").authenticated()
.requestMatchers("/einladungen.html").authenticated()
.requestMatchers("/joinlock.html").authenticated()
.requestMatchers("/benachrichtigungen.html").authenticated()
.requestMatchers("/gruppen/**").authenticated()
.requestMatchers("/feed/**").authenticated()
.requestMatchers("/notifications/**").authenticated()
.requestMatchers("/events/**").authenticated()
.requestMatchers("/*.html").permitAll()
.requestMatchers("/css/**").permitAll()
.requestMatchers("/js/**").permitAll()
.requestMatchers("/images/**").permitAll()
.requestMatchers("/img/**").permitAll()
.requestMatchers("/favicon.ico").permitAll()
.requestMatchers("/audio/**").permitAll()
.requestMatchers("/*.png").permitAll()
.requestMatchers("/*.jpg").permitAll()
.requestMatchers("/*.svg").permitAll()
.requestMatchers("/*.webp").permitAll()
.requestMatchers(HttpMethod.GET, "/login").permitAll()
.requestMatchers(HttpMethod.GET, "/login/publickey").permitAll()
.requestMatchers(HttpMethod.GET, "/login/logout").permitAll()
.requestMatchers(HttpMethod.POST, "/user").permitAll()
.requestMatchers(HttpMethod.GET, "/registration").permitAll()
.requestMatchers(HttpMethod.POST, "/registration").permitAll()
.requestMatchers(HttpMethod.GET, "/activation").permitAll()
.requestMatchers(HttpMethod.GET, "/activation/**").permitAll()
.requestMatchers(HttpMethod.POST, "/password-reset/request").permitAll()
.requestMatchers(HttpMethod.POST, "/password-reset/confirm").permitAll()
.requestMatchers(HttpMethod.GET, "/email-change/**").permitAll()
.requestMatchers(HttpMethod.GET, "/keyholder/invitation/**").permitAll()
.requestMatchers(HttpMethod.POST, "/filler").permitAll()
.anyRequest().authenticated()
)
.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);

View File

@@ -4,10 +4,14 @@ import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "email_change")
public class EmailChangeEntity {
@@ -25,18 +29,6 @@ public class EmailChangeEntity {
@Column
private LocalDateTime createdAt;
public UUID getTokenId() { return tokenId; }
public void setTokenId(UUID tokenId) { this.tokenId = tokenId; }
public String getUserEmail() { return userEmail; }
public void setUserEmail(String userEmail) { this.userEmail = userEmail; }
public String getNewEmail() { return newEmail; }
public void setNewEmail(String newEmail) { this.newEmail = newEmail; }
public LocalDateTime getCreatedAt() { return createdAt; }
public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
@Override
public String toString() {
return "EmailChangeEntity[tokenId=" + tokenId + ", userEmail=" + userEmail + ", newEmail=" + newEmail + ", createdAt=" + createdAt + "]";

View File

@@ -3,10 +3,15 @@ package de.oaa.xxx.feed.entity;
import de.oaa.xxx.config.StringListConverter;
import de.oaa.xxx.gruppe.BeitragTyp;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "feed_post")
public class FeedPostEntity {
@@ -37,28 +42,4 @@ public class FeedPostEntity {
@Column(nullable = false)
private LocalDateTime createdAt;
public UUID getPostId() { return postId; }
public void setPostId(UUID postId) { this.postId = postId; }
public UUID getAuthorId() { return authorId; }
public void setAuthorId(UUID authorId) { this.authorId = authorId; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
public List<String> getBilder() { return bilder; }
public void setBilder(List<String> bilder) { this.bilder = bilder; }
public BeitragTyp getBeitragTyp() { return beitragTyp; }
public void setBeitragTyp(BeitragTyp beitragTyp) { this.beitragTyp = beitragTyp; }
public Boolean getMultiChoice() { return multiChoice; }
public void setMultiChoice(Boolean multiChoice) { this.multiChoice = multiChoice; }
public boolean isPublic() { return isPublic; }
public void setPublic(boolean aPublic) { isPublic = aPublic; }
public LocalDateTime getCreatedAt() { return createdAt; }
public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
}

View File

@@ -1,9 +1,14 @@
package de.oaa.xxx.feed.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "feed_post_like", uniqueConstraints = {
@UniqueConstraint(columnNames = {"postId", "userId"})
@@ -22,16 +27,4 @@ public class FeedPostLikeEntity {
@Column(nullable = false)
private LocalDateTime likedAt;
public UUID getLikeId() { return likeId; }
public void setLikeId(UUID likeId) { this.likeId = likeId; }
public UUID getPostId() { return postId; }
public void setPostId(UUID postId) { this.postId = postId; }
public UUID getUserId() { return userId; }
public void setUserId(UUID userId) { this.userId = userId; }
public LocalDateTime getLikedAt() { return likedAt; }
public void setLikedAt(LocalDateTime likedAt) { this.likedAt = likedAt; }
}

View File

@@ -1,8 +1,13 @@
package de.oaa.xxx.feed.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "feed_post_option")
public class FeedPostOptionEntity {
@@ -19,16 +24,4 @@ public class FeedPostOptionEntity {
@Column(nullable = false)
private int reihenfolge;
public UUID getOptionId() { return optionId; }
public void setOptionId(UUID optionId) { this.optionId = optionId; }
public UUID getPostId() { return postId; }
public void setPostId(UUID postId) { this.postId = postId; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
public int getReihenfolge() { return reihenfolge; }
public void setReihenfolge(int reihenfolge) { this.reihenfolge = reihenfolge; }
}

View File

@@ -1,8 +1,13 @@
package de.oaa.xxx.feed.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "feed_post_vote")
public class FeedPostVoteEntity {
@@ -19,16 +24,4 @@ public class FeedPostVoteEntity {
@Column(nullable = false)
private UUID userId;
public UUID getStimmeId() { return stimmeId; }
public void setStimmeId(UUID stimmeId) { this.stimmeId = stimmeId; }
public UUID getOptionId() { return optionId; }
public void setOptionId(UUID optionId) { this.optionId = optionId; }
public UUID getPostId() { return postId; }
public void setPostId(UUID postId) { this.postId = postId; }
public UUID getUserId() { return userId; }
public void setUserId(UUID userId) { this.userId = userId; }
}

View File

@@ -1,9 +1,14 @@
package de.oaa.xxx.games.chastity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "keyholder_invitation")
public class KeyholderInvitationEntity {
@@ -11,6 +16,7 @@ public class KeyholderInvitationEntity {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
@Column
@Setter(lombok.AccessLevel.NONE)
private UUID id;
@Column(nullable = false)
@@ -27,21 +33,4 @@ public class KeyholderInvitationEntity {
@Column(nullable = false)
private LocalDateTime createdAt;
public UUID getId() { return id; }
public UUID getLockId() { return lockId; }
public void setLockId(UUID lockId) { this.lockId = lockId; }
public UUID getKeyholderUserId() { return keyholderUserId; }
public void setKeyholderUserId(UUID keyholderUserId) { this.keyholderUserId = keyholderUserId; }
public UUID getLockeeUserId() { return lockeeUserId; }
public void setLockeeUserId(UUID lockeeUserId) { this.lockeeUserId = lockeeUserId; }
public String getToken() { return token; }
public void setToken(String token) { this.token = token; }
public LocalDateTime getCreatedAt() { return createdAt; }
public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
}

View File

@@ -1,9 +1,14 @@
package de.oaa.xxx.games.chastity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "lockee_invitation")
public class LockeeInvitationEntity {
@@ -11,6 +16,7 @@ public class LockeeInvitationEntity {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
@Column
@Setter(lombok.AccessLevel.NONE)
private UUID invitationId;
@Column(nullable = false)
@@ -30,24 +36,4 @@ public class LockeeInvitationEntity {
@Column(nullable = false)
private boolean detailsVisible = true;
public UUID getInvitationId() { return invitationId; }
public UUID getLockId() { return lockId; }
public void setLockId(UUID lockId) { this.lockId = lockId; }
public UUID getLockeeUserId() { return lockeeUserId; }
public void setLockeeUserId(UUID lockeeUserId) { this.lockeeUserId = lockeeUserId; }
public UUID getKeyholderUserId() { return keyholderUserId; }
public void setKeyholderUserId(UUID keyholderUserId) { this.keyholderUserId = keyholderUserId; }
public String getToken() { return token; }
public void setToken(String token) { this.token = token; }
public LocalDateTime getCreatedAt() { return createdAt; }
public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
public boolean isDetailsVisible() { return detailsVisible; }
public void setDetailsVisible(boolean detailsVisible) { this.detailsVisible = detailsVisible; }
}

View File

@@ -41,6 +41,7 @@ import de.oaa.xxx.games.chastity.KeyholderInvitationEntity;
import de.oaa.xxx.games.chastity.KeyholderInvitationRepository;
import de.oaa.xxx.games.chastity.LockeeInvitationEntity;
import de.oaa.xxx.games.chastity.LockeeInvitationRepository;
import de.oaa.xxx.games.chastity.history.LockHistoryRepository;
import de.oaa.xxx.games.chastity.tasks.AssignedTaskEntity;
import de.oaa.xxx.games.chastity.tasks.AssignedTaskRepository;
import de.oaa.xxx.games.chastity.tasks.Task;
@@ -70,6 +71,8 @@ public class CardLockController {
private final KeyholderTaskChoiceRepository keyholderTaskChoiceRepository;
private final CommunityTaskVoteRepository communityTaskVoteRepository;
private final UnlockCodeHistoryRepository unlockCodeHistoryRepository;
private final UnlockCodeHistoryService unlockCodeHistoryService;
private final LockHistoryRepository lockHistoryRepository;
private final SseService sseService;
@Value("${app.base-url:http://localhost:8080}")
@@ -88,6 +91,8 @@ public class CardLockController {
KeyholderTaskChoiceRepository keyholderTaskChoiceRepository,
CommunityTaskVoteRepository communityTaskVoteRepository,
UnlockCodeHistoryRepository unlockCodeHistoryRepository,
UnlockCodeHistoryService unlockCodeHistoryService,
LockHistoryRepository lockHistoryRepository,
SseService sseService) {
this.cardlockRepository = cardlockRepository;
this.cardLockRepository = cardLockRepository;
@@ -102,6 +107,8 @@ public class CardLockController {
this.keyholderTaskChoiceRepository = keyholderTaskChoiceRepository;
this.communityTaskVoteRepository = communityTaskVoteRepository;
this.unlockCodeHistoryRepository = unlockCodeHistoryRepository;
this.unlockCodeHistoryService = unlockCodeHistoryService;
this.lockHistoryRepository = lockHistoryRepository;
this.sseService = sseService;
}
@@ -275,7 +282,7 @@ public class CardLockController {
var l = lockOpt.get();
if (!l.getLockee().equals(myId)) return ResponseEntity.status(403).build();
CardLockService service = new CardLockService(l, verificationRepository, verificationVoteRepository, cardLockRepository);
CardLockService service = new CardLockService(l, verificationRepository, verificationVoteRepository, cardLockRepository, lockHistoryRepository, userRepository);
CardDTO dto = service.getNextCard();
if (dto == null) return ResponseEntity.status(409).body(Map.of("error", "Keine Karte verfügbar"));
@@ -315,7 +322,7 @@ public class CardLockController {
// Grüne Karte → Entsperrcode-Historie speichern
if (dto.unlockCode() != null && !dto.unlockCode().isBlank()) {
saveUnlockCodeHistory(myId, l.getLockId(), l.getName(), dto.unlockCode(), "GREEN_CARD");
unlockCodeHistoryService.save(myId, l.getLockId(), l.getName(), dto.unlockCode(), "GREEN_CARD");
}
return ResponseEntity.ok(result);
@@ -336,7 +343,7 @@ public class CardLockController {
l.setHygineOpeningtime(LocalDateTime.now());
cardlockRepository.save(l);
saveUnlockCodeHistory(myId, l.getLockId(), l.getName(), l.getUnlockCode(), "HYGIENE_OPEN");
unlockCodeHistoryService.save(myId, l.getLockId(), l.getName(), l.getUnlockCode(), "HYGIENE_OPEN");
return ResponseEntity.ok(Map.of(
"unlockCode", l.getUnlockCode(),
@@ -393,7 +400,7 @@ public class CardLockController {
l.setUnlockCode(newCode);
cardlockRepository.save(l);
saveUnlockCodeHistory(myId, l.getLockId(), l.getName(), newCode, "HYGIENE_CLOSE");
unlockCodeHistoryService.save(myId, l.getLockId(), l.getName(), newCode, "HYGIENE_CLOSE");
return ResponseEntity.ok(Map.of("newUnlockCode", newCode));
}
@@ -410,7 +417,7 @@ public class CardLockController {
var l = lockOpt.get();
if (!l.getLockee().equals(myId)) return ResponseEntity.status(403).build();
CardLockService service = new CardLockService(l, verificationRepository, verificationVoteRepository, cardLockRepository);
CardLockService service = new CardLockService(l, verificationRepository, verificationVoteRepository, cardLockRepository, lockHistoryRepository, userRepository);
service.clearTask();
return ResponseEntity.noContent().build();
}
@@ -427,7 +434,7 @@ public class CardLockController {
var l = lockOpt.get();
if (!l.getLockee().equals(myId)) return ResponseEntity.status(403).build();
CardLockService service = new CardLockService(l, verificationRepository, verificationVoteRepository, cardLockRepository);
CardLockService service = new CardLockService(l, verificationRepository, verificationVoteRepository, cardLockRepository, lockHistoryRepository, userRepository);
service.putBackGreen();
return ResponseEntity.noContent().build();
}
@@ -603,7 +610,10 @@ public class CardLockController {
result.put("keyholderRequestedUnlock", l.isKeyholderRequestedUnlock());
if (l.isKeyholderRequestedUnlock()) {
result.put("unlockCode", l.getUnlockCode() != null ? l.getUnlockCode() : "");
saveUnlockCodeHistory(myId, l.getLockId(), l.getName(), l.getUnlockCode(), "KEYHOLDER_UNLOCK");
// Notfall-Freigaben werden nicht in der Historie gespeichert
if (l.getEmergencyUnlockRequestedAt() == null) {
unlockCodeHistoryService.save(myId, l.getLockId(), l.getName(), l.getUnlockCode(), "KEYHOLDER_UNLOCK");
}
}
result.put("testLock", l.isTestLock());
@@ -662,7 +672,7 @@ public class CardLockController {
public ResponseEntity<Void> completeVerification(
@PathVariable UUID lockId,
@PathVariable UUID verificationId,
@RequestParam("image") MultipartFile image,
@RequestParam MultipartFile image,
Principal principal) throws IOException {
var meOpt = userRepository.findByEmail(principal.getName());
if (meOpt.isEmpty()) return ResponseEntity.status(401).build();
@@ -679,6 +689,15 @@ public class CardLockController {
v.setImage(scaleImage(image.getBytes(), 1024));
verificationRepository.save(v);
var lock = lockOpt.get();
if (lock.getKeyholder() != null) {
var lockee = meOpt.get();
sendMessage(myId, lock.getKeyholder(),
"📸 " + lockee.getName() + " hat eine Verifikation eingereicht.",
"/keyholder.html");
}
return ResponseEntity.noContent().build();
}
@@ -1046,7 +1065,12 @@ public class CardLockController {
var lockOpt = cardlockRepository.findById(lockId);
if (lockOpt.isEmpty()) return ResponseEntity.notFound().build();
if (!lockOpt.get().getLockee().equals(myId)) return ResponseEntity.status(403).build();
var l = lockOpt.get();
if (!l.getLockee().equals(myId)) return ResponseEntity.status(403).build();
// Entsperrung protokollieren (History + XP) gültig nur wenn Keyholder vorhanden und kein Auto-Notfall
CardLockService service = new CardLockService(l, verificationRepository, verificationVoteRepository, cardLockRepository, lockHistoryRepository, userRepository);
service.unlock(l.getUnlockCode());
var verifications = verificationRepository.findByLockId(lockId);
verifications.forEach(v -> verificationVoteRepository.deleteAllByVerificationId(v.getVerficationId()));
@@ -1212,30 +1236,6 @@ public class CardLockController {
sseService.push(receiverId, "NOTIFICATION", java.util.Map.of("unreadCount", unread, "text", text));
}
// ── Entsperrcode-Historie ──────────────────────────────────────────────────
private void saveUnlockCodeHistory(UUID userId, UUID lockId, String lockName, String unlockCode, String source) {
if (unlockCode == null || unlockCode.isBlank()) return;
// Deduplizierung: gleicher Code+Quelle+Lock bereits gespeichert → überspringen
if (unlockCodeHistoryRepository.existsByLockIdAndSourceAndUnlockCode(lockId, source, unlockCode)) return;
UnlockCodeHistoryEntity entry = new UnlockCodeHistoryEntity();
entry.setUserId(userId);
entry.setLockId(lockId);
entry.setLockName(lockName != null && !lockName.isBlank() ? lockName : "Unbenanntes Lock");
entry.setUnlockCode(unlockCode);
entry.setSource(source);
entry.setReceivedAt(LocalDateTime.now());
unlockCodeHistoryRepository.save(entry);
// Nur die letzten 10 behalten
long count = unlockCodeHistoryRepository.countByUserId(userId);
if (count > 10) {
var oldest = unlockCodeHistoryRepository.findByUserIdOrderByReceivedAtAsc(userId);
for (int i = 0; i < count - 10; i++) {
unlockCodeHistoryRepository.delete(oldest.get(i));
}
}
}
@GetMapping("/cardlock/unlock-history")
public ResponseEntity<List<Map<String, Object>>> getUnlockHistory(Principal principal) {
var meOpt = userRepository.findByEmail(principal.getName());

View File

@@ -13,7 +13,11 @@ import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Entity
@Table(name = "card_lock")
public class CardLockEntity {
@@ -102,224 +106,5 @@ public class CardLockEntity {
@Column(nullable = false)
private String taskCardMode = "RANDOM";
public UUID getLockId() {
return lockId;
}
public void setLockId(UUID lockId) {
this.lockId = lockId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public UUID getLockee() {
return lockee;
}
public void setLockee(UUID lockee) {
this.lockee = lockee;
}
public UUID getKeyholder() {
return keyholder;
}
public void setKeyholder(UUID keyholder) {
this.keyholder = keyholder;
}
public List<CardEnum> getInitialCards() {
return initialCards;
}
public void setInitialCards(List<CardEnum> initialCards) {
this.initialCards = initialCards;
}
public Integer getPickEveryMinute() {
return pickEveryMinute;
}
public void setPickEveryMinute(Integer pickEveryMinute) {
this.pickEveryMinute = pickEveryMinute;
}
public boolean isAccumulatePicks() {
return accumulatePicks;
}
public void setAccumulatePicks(boolean accumulatePicks) {
this.accumulatePicks = accumulatePicks;
}
public boolean isShowRemainingCards() {
return showRemainingCards;
}
public void setShowRemainingCards(boolean showRemainingCards) {
this.showRemainingCards = showRemainingCards;
}
public LocalDateTime getLatestOpeningtime() {
return latestOpeningtime;
}
public void setLatestOpeningtime(LocalDateTime latestOpeningtime) {
this.latestOpeningtime = latestOpeningtime;
}
public LocalDateTime getFrozenUntill() {
return frozenUntill;
}
public void setFrozenUntill(LocalDateTime frozenUntill) {
this.frozenUntill = frozenUntill;
}
public Integer getHygineOpeningDurationMinutes() {
return hygineOpeningDurationMinutes;
}
public void setHygineOpeningDurationMinutes(Integer hygineOpeningDurationMinutes) {
this.hygineOpeningDurationMinutes = hygineOpeningDurationMinutes;
}
public Integer getHygineOpeningEveryMinites() {
return hygineOpeningEveryMinites;
}
public void setHygineOpeningEveryMinites(Integer hygineOpeningEveryMinites) {
this.hygineOpeningEveryMinites = hygineOpeningEveryMinites;
}
public LocalDateTime getStartTime() {
return startTime;
}
public void setStartTime(LocalDateTime startTime) {
this.startTime = startTime;
}
public LocalDateTime getNextCardIn() {
return nextCardIn;
}
public void setNextCardIn(LocalDateTime nextCardIn) {
this.nextCardIn = nextCardIn;
}
public Integer getOpenPicks() {
return openPicks;
}
public void setOpenPicks(Integer openPicks) {
this.openPicks = openPicks;
}
public List<CardEnum> getAvailableCards() {
return availableCards;
}
public void setAvailableCards(List<CardEnum> availableCards) {
this.availableCards = availableCards;
}
public LocalDateTime getLastHygineOpening() {
return lastHygineOpening;
}
public void setLastHygineOpening(LocalDateTime lastHygineOpening) {
this.lastHygineOpening = lastHygineOpening;
}
public LocalDateTime getHygineOpeningtime() {
return hygineOpeningtime;
}
public void setHygineOpeningtime(LocalDateTime hygineOpeningtime) {
this.hygineOpeningtime = hygineOpeningtime;
}
public LocalDateTime getUnlockTime() {
return unlockTime;
}
public void setUnlockTime(LocalDateTime unlockTime) {
this.unlockTime = unlockTime;
}
public List<Task> getTasks() {
return tasks;
}
public void setTasks(List<Task> tasks) {
this.tasks = tasks;
}
public String getCurrentTask() { return currentTask; }
public void setCurrentTask(String currentTask) { this.currentTask = currentTask; }
public String getCurrentTaskDescription() { return currentTaskDescription; }
public void setCurrentTaskDescription(String d) { this.currentTaskDescription = d; }
public LocalDateTime getTaskFrozenUntil() { return taskFrozenUntil; }
public void setTaskFrozenUntil(LocalDateTime t) { this.taskFrozenUntil = t; }
public List<Task> getTasksInQueue() {
return tasksInQueue;
}
public void setTasksInQueue(List<Task> tasksInQueue) {
this.tasksInQueue = tasksInQueue;
}
public boolean isRequiresVerification() {
return requiresVerification;
}
public void setRequiresVerification(boolean requiresVerification) {
this.requiresVerification = requiresVerification;
}
public boolean isTestLock() {
return testLock;
}
public void setTestLock(boolean testLock) {
this.testLock = testLock;
}
public String getUnlockCode() {
return unlockCode;
}
public void setUnlockCode(String unlockCode) {
this.unlockCode = unlockCode;
}
public Integer getUnlockCodeLines() {
return unlockCodeLines;
}
public void setUnlockCodeLines(Integer unlockCodeLines) {
this.unlockCodeLines = unlockCodeLines;
}
public String getTaskCardMode() { return taskCardMode != null ? taskCardMode : "RANDOM"; }
public void setTaskCardMode(String taskCardMode) { this.taskCardMode = taskCardMode; }
public boolean isKeyholderRequestedUnlock() { return keyholderRequestedUnlock; }
public void setKeyholderRequestedUnlock(boolean v) { this.keyholderRequestedUnlock = v; }
public java.time.LocalDateTime getEmergencyUnlockRequestedAt() { return emergencyUnlockRequestedAt; }
public void setEmergencyUnlockRequestedAt(java.time.LocalDateTime t) { this.emergencyUnlockRequestedAt = t; }
public boolean isEmergencyAutoUnlocked() { return emergencyAutoUnlocked; }
public void setEmergencyAutoUnlocked(boolean v) { this.emergencyAutoUnlocked = v; }
}

View File

@@ -11,12 +11,16 @@ import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.oaa.xxx.games.chastity.LockType;
import de.oaa.xxx.games.chastity.ProcessLock;
import de.oaa.xxx.games.chastity.history.LockHistoryEntity;
import de.oaa.xxx.games.chastity.history.LockHistoryRepository;
import de.oaa.xxx.games.chastity.tasks.Task;
import de.oaa.xxx.games.chastity.verification.VerificationEntity;
import de.oaa.xxx.games.chastity.verification.VerificationRepository;
import de.oaa.xxx.games.chastity.verification.VerificationVoteEntity;
import de.oaa.xxx.games.chastity.verification.VerificationVoteRepository;
import de.oaa.xxx.user.UserRepository;
public class CardLockService extends ProcessLock {
@@ -25,21 +29,25 @@ public class CardLockService extends ProcessLock {
private VerificationRepository verificationRepository;
private VerificationVoteRepository verificationVoteRepository;
private CardLockRepository cardLockRepository;
private LockHistoryRepository lockHistoryRepository;
private UserRepository userRepository;
public CardLockService(CardLockEntity lock, VerificationRepository verificationRepository, VerificationVoteRepository verificationVoteRepository, CardLockRepository cardLockRepository) {
this.lock = lock;
public CardLockService(CardLockEntity lock, VerificationRepository verificationRepository, VerificationVoteRepository verificationVoteRepository, CardLockRepository cardLockRepository, LockHistoryRepository lockHistoryRepository, UserRepository userRepository) {
this.lock = lock;
this.verificationRepository = verificationRepository;
this.verificationVoteRepository = verificationVoteRepository;
this.cardLockRepository = cardLockRepository;
this.lockHistoryRepository = lockHistoryRepository;
this.userRepository = userRepository;
}
public CardDTO getNextCard() {
LOGGER.debug("New Card requested by user {}", lock.getLockee());
CardDTO card = null;
if (lock.getLatestOpeningtime() != null && lock.getLatestOpeningtime().isAfter(LocalDateTime.now())) {
if (lock.isKeyholderRequestedUnlock() || (lock.getLatestOpeningtime() != null && lock.getLatestOpeningtime().isAfter(LocalDateTime.now()))) {
card = getGreenCard();
} else if (lock.isAccumulatePicks()) {
if (lock.getNextCardIn().isAfter(LocalDateTime.now())) {
if (lock.getNextCardIn().isBefore(LocalDateTime.now())) {
lock.setOpenPicks(lock.getOpenPicks() == null ? 1 : lock.getOpenPicks() + 1);
}
if (lock.getOpenPicks() != null && lock.getOpenPicks() > 0) {
@@ -117,15 +125,51 @@ public class CardLockService extends ProcessLock {
}
if (valid) {
}
// XP berechnen
// Lock löschen
lock.setUnlockTime(LocalDateTime.now());
LOGGER.debug("Unlocked at {}", lock.getUnlockTime());
cardLockRepository.save(lock);
if (valid) {
long durationMinutes = Duration.between(lock.getStartTime(), lock.getUnlockTime()).toMinutes();
// Eintrag für den Lockee
LockHistoryEntity lockeeEntry = new LockHistoryEntity();
lockeeEntry.setUserId(lock.getLockee());
lockeeEntry.setLockedBy(lock.getKeyholder());
lockeeEntry.setLockName(lock.getName());
lockeeEntry.setStartTime(lock.getStartTime());
lockeeEntry.setEndTime(lock.getUnlockTime());
lockeeEntry.setType(LockType.CARD);
lockeeEntry.setDurationMinutes(durationMinutes);
lockeeEntry.setRole("LOCKEE");
lockHistoryRepository.save(lockeeEntry);
// Eintrag für die Keyholderin
if (lock.getKeyholder() != null) {
LockHistoryEntity khEntry = new LockHistoryEntity();
khEntry.setUserId(lock.getKeyholder());
khEntry.setLockedBy(lock.getLockee());
khEntry.setLockName(lock.getName());
khEntry.setStartTime(lock.getStartTime());
khEntry.setEndTime(lock.getUnlockTime());
khEntry.setType(LockType.CARD);
khEntry.setDurationMinutes(durationMinutes);
khEntry.setRole("KEYHOLDER");
lockHistoryRepository.save(khEntry);
}
int minutes = (int) durationMinutes;
userRepository.findById(lock.getLockee()).ifPresent(u -> {
u.setLockeeXp(u.getLockeeXp() + minutes);
userRepository.save(u);
});
if (lock.getKeyholder() != null) {
userRepository.findById(lock.getKeyholder()).ifPresent(u -> {
u.setKeyholderXp(u.getKeyholderXp() + minutes);
userRepository.save(u);
});
}
}
}
public void putBackGreen() {

View File

@@ -3,11 +3,15 @@ package de.oaa.xxx.games.chastity.cardlock;
import de.oaa.xxx.games.chastity.tasks.Task;
import de.oaa.xxx.games.chastity.tasks.TaskListConverter;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "cardlock_template")
public class CardlockTemplateEntity {
@@ -56,42 +60,5 @@ public class CardlockTemplateEntity {
@Column(nullable = false)
private String taskCardMode = "RANDOM";
public UUID getTemplateId() { return templateId; }
public void setTemplateId(UUID templateId) { this.templateId = templateId; }
public UUID getOwner() { return owner; }
public void setOwner(UUID owner) { this.owner = owner; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public Map<String, Integer> getCardCountsMin() { return cardCountsMin; }
public void setCardCountsMin(Map<String, Integer> cardCountsMin) { this.cardCountsMin = cardCountsMin; }
public Map<String, Integer> getCardCountsMax() { return cardCountsMax; }
public void setCardCountsMax(Map<String, Integer> cardCountsMax) { this.cardCountsMax = cardCountsMax; }
public Integer getPickEveryMinute() { return pickEveryMinute; }
public void setPickEveryMinute(Integer pickEveryMinute) { this.pickEveryMinute = pickEveryMinute; }
public boolean isAccumulatePicks() { return accumulatePicks; }
public void setAccumulatePicks(boolean accumulatePicks) { this.accumulatePicks = accumulatePicks; }
public boolean isShowRemainingCards() { return showRemainingCards; }
public void setShowRemainingCards(boolean showRemainingCards) { this.showRemainingCards = showRemainingCards; }
public Integer getHygineOpeningDurationMinutes() { return hygineOpeningDurationMinutes; }
public void setHygineOpeningDurationMinutes(Integer hygineOpeningDurationMinutes) { this.hygineOpeningDurationMinutes = hygineOpeningDurationMinutes; }
public Integer getHygineOpeningEveryMinites() { return hygineOpeningEveryMinites; }
public void setHygineOpeningEveryMinites(Integer hygineOpeningEveryMinites) { this.hygineOpeningEveryMinites = hygineOpeningEveryMinites; }
public List<Task> getTasks() { return tasks; }
public void setTasks(List<Task> tasks) { this.tasks = tasks; }
public boolean isRequiresVerification() { return requiresVerification; }
public void setRequiresVerification(boolean requiresVerification) { this.requiresVerification = requiresVerification; }
public String getTaskCardMode() { return taskCardMode != null ? taskCardMode : "RANDOM"; }
public void setTaskCardMode(String taskCardMode) { this.taskCardMode = taskCardMode; }
}

View File

@@ -1,9 +1,14 @@
package de.oaa.xxx.games.chastity.cardlock;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "community_task_vote")
public class CommunityTaskVoteEntity {
@@ -32,25 +37,4 @@ public class CommunityTaskVoteEntity {
/** null until completed */
@Column
private Integer winningTaskIndex;
public UUID getVoteSessionId() { return voteSessionId; }
public void setVoteSessionId(UUID id) { this.voteSessionId = id; }
public UUID getLockId() { return lockId; }
public void setLockId(UUID lockId) { this.lockId = lockId; }
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
public LocalDateTime getCreatedAt() { return createdAt; }
public void setCreatedAt(LocalDateTime t) { this.createdAt = t; }
public LocalDateTime getExpiresAt() { return expiresAt; }
public void setExpiresAt(LocalDateTime t) { this.expiresAt = t; }
public boolean isTestLock() { return testLock; }
public void setTestLock(boolean testLock) { this.testLock = testLock; }
public Integer getWinningTaskIndex() { return winningTaskIndex; }
public void setWinningTaskIndex(Integer i) { this.winningTaskIndex = i; }
}

View File

@@ -1,8 +1,13 @@
package de.oaa.xxx.games.chastity.cardlock;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "community_task_vote_entry",
uniqueConstraints = @UniqueConstraint(columnNames = {"voteSessionId", "voterUserId"}))
@@ -20,16 +25,4 @@ public class CommunityTaskVoteEntryEntity {
@Column(nullable = false)
private int taskIndex;
public UUID getEntryId() { return entryId; }
public void setEntryId(UUID entryId) { this.entryId = entryId; }
public UUID getVoteSessionId() { return voteSessionId; }
public void setVoteSessionId(UUID id) { this.voteSessionId = id; }
public UUID getVoterUserId() { return voterUserId; }
public void setVoterUserId(UUID id) { this.voterUserId = id; }
public int getTaskIndex() { return taskIndex; }
public void setTaskIndex(int taskIndex) { this.taskIndex = taskIndex; }
}

View File

@@ -1,9 +1,14 @@
package de.oaa.xxx.games.chastity.cardlock;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "hygiene_violation")
public class HygieneViolationEntity {
@@ -29,25 +34,4 @@ public class HygieneViolationEntity {
@Column(nullable = false)
private boolean notifiedKeyholder = false;
public UUID getId() { return id; }
public void setId(UUID id) { this.id = id; }
public UUID getLockId() { return lockId; }
public void setLockId(UUID lockId) { this.lockId = lockId; }
public UUID getLockeeId() { return lockeeId; }
public void setLockeeId(UUID lockeeId) { this.lockeeId = lockeeId; }
public UUID getKeyholderUserId() { return keyholderUserId; }
public void setKeyholderUserId(UUID keyholderUserId) { this.keyholderUserId = keyholderUserId; }
public LocalDateTime getViolationTime() { return violationTime; }
public void setViolationTime(LocalDateTime violationTime){ this.violationTime = violationTime; }
public long getOvertimeMinutes() { return overtimeMinutes; }
public void setOvertimeMinutes(long overtimeMinutes) { this.overtimeMinutes = overtimeMinutes; }
public boolean isNotifiedKeyholder() { return notifiedKeyholder; }
public void setNotifiedKeyholder(boolean notifiedKeyholder){ this.notifiedKeyholder = notifiedKeyholder; }
}

View File

@@ -1,9 +1,14 @@
package de.oaa.xxx.games.chastity.cardlock;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "keyholder_task_choice")
public class KeyholderTaskChoiceEntity {
@@ -21,16 +26,4 @@ public class KeyholderTaskChoiceEntity {
@Column(nullable = false)
private LocalDateTime createdAt;
public UUID getChoiceId() { return choiceId; }
public void setChoiceId(UUID choiceId) { this.choiceId = choiceId; }
public UUID getLockId() { return lockId; }
public void setLockId(UUID lockId) { this.lockId = lockId; }
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
public LocalDateTime getCreatedAt() { return createdAt; }
public void setCreatedAt(LocalDateTime t) { this.createdAt = t; }
}

View File

@@ -168,14 +168,18 @@ public class TaskCardController {
.stream().filter(e -> myId.equals(e.getVoterUserId()))
.map(CommunityTaskVoteEntryEntity::getTaskIndex).findFirst().orElse(null);
boolean isOwnLock = lock.getLockee().equals(myId);
Map<String, Object> m = new LinkedHashMap<>();
m.put("voteSessionId", vote.getVoteSessionId().toString());
m.put("lockId", lock.getLockId().toString());
m.put("lockeeName", lockee != null ? lockee.getName() : "");
m.put("createdAt", vote.getCreatedAt().toString());
m.put("expiresAt", vote.getExpiresAt().toString());
m.put("tasks", taskList);
m.put("voteCounts", voteCounts);
m.put("myVote", myVote);
m.put("myVote", isOwnLock ? "own" : myVote);
m.put("isOwnLock", isOwnLock);
result.add(m);
}
return ResponseEntity.ok(result);
@@ -201,6 +205,8 @@ public class TaskCardController {
if (lockOpt.isEmpty()) return ResponseEntity.notFound().build();
var lock = lockOpt.get();
if (lock.getLockee().equals(myId)) return ResponseEntity.status(403).build();
if (lock.getTasks() == null || taskIndex < 0 || taskIndex >= lock.getTasks().size())
return ResponseEntity.badRequest().build();

View File

@@ -1,15 +1,21 @@
package de.oaa.xxx.games.chastity.cardlock;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "unlock_code_history")
public class UnlockCodeHistoryEntity {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
@Setter(lombok.AccessLevel.NONE)
private UUID id;
@Column(nullable = false)
@@ -30,18 +36,4 @@ public class UnlockCodeHistoryEntity {
@Column(nullable = false)
private LocalDateTime receivedAt;
public UUID getId() { return id; }
public UUID getUserId() { return userId; }
public void setUserId(UUID userId) { this.userId = userId; }
public UUID getLockId() { return lockId; }
public void setLockId(UUID lockId) { this.lockId = lockId; }
public String getLockName() { return lockName; }
public void setLockName(String lockName) { this.lockName = lockName; }
public String getUnlockCode() { return unlockCode; }
public void setUnlockCode(String unlockCode) { this.unlockCode = unlockCode; }
public String getSource() { return source; }
public void setSource(String source) { this.source = source; }
public LocalDateTime getReceivedAt() { return receivedAt; }
public void setReceivedAt(LocalDateTime receivedAt) { this.receivedAt = receivedAt; }
}

View File

@@ -0,0 +1,52 @@
package de.oaa.xxx.games.chastity.cardlock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.UUID;
@Service
public class UnlockCodeHistoryService {
private static final Logger LOGGER = LoggerFactory.getLogger(UnlockCodeHistoryService.class);
private final UnlockCodeHistoryRepository unlockCodeHistoryRepository;
public UnlockCodeHistoryService(UnlockCodeHistoryRepository unlockCodeHistoryRepository) {
this.unlockCodeHistoryRepository = unlockCodeHistoryRepository;
}
/**
* Speichert einen Entsperrcode-Eintrag in einer eigenen Transaktion,
* damit ein Fehler hier die aufrufende Transaktion nicht zurückrollt.
*/
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void save(UUID userId, UUID lockId, String lockName, String unlockCode, String source) {
if (unlockCode == null || unlockCode.isBlank()) return;
try {
if (unlockCodeHistoryRepository.existsByLockIdAndSourceAndUnlockCode(lockId, source, unlockCode)) return;
UnlockCodeHistoryEntity entry = new UnlockCodeHistoryEntity();
entry.setUserId(userId);
entry.setLockId(lockId);
entry.setLockName(lockName != null && !lockName.isBlank() ? lockName : "Unbenanntes Lock");
entry.setUnlockCode(unlockCode);
entry.setSource(source);
entry.setReceivedAt(LocalDateTime.now());
unlockCodeHistoryRepository.save(entry);
// Nur die letzten 10 behalten
long count = unlockCodeHistoryRepository.countByUserId(userId);
if (count > 10) {
var oldest = unlockCodeHistoryRepository.findByUserIdOrderByReceivedAtAsc(userId);
for (int i = 0; i < count - 10; i++) {
unlockCodeHistoryRepository.delete(oldest.get(i));
}
}
} catch (Exception e) {
LOGGER.warn("Entsperrcode-Historie konnte nicht gespeichert werden (lockId={}, source={}): {}", lockId, source, e.getMessage());
}
}
}

View File

@@ -1,35 +1,57 @@
package de.oaa.xxx.games.chastity.history;
import java.security.Principal;
import java.util.List;
import java.util.UUID;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import de.oaa.xxx.user.UserRepository;
@RestController
@RequestMapping("/lockhistory")
public class LockHistoryController {
private UserRepository userRepository;
private LockHistoryRepository lockHistoryRepository;
public LockHistoryController(UserRepository userRepository, LockHistoryRepository lockHistoryRepository) {
this.userRepository = userRepository;
this.lockHistoryRepository = lockHistoryRepository;
}
@GetMapping
public ResponseEntity<List<LockHistoryDTO>> get(@RequestParam UUID userId, Principal principal) {
var meOpt = userRepository.findByEmail(principal.getName());
if (meOpt.isEmpty())
return ResponseEntity.status(401).build();
return ResponseEntity.ok(lockHistoryRepository.findByUserIdOrderByEndTimeDesc(userId).stream()
.map(entity -> entity.toLockHistory()).toList());
}
}
package de.oaa.xxx.games.chastity.history;
import de.oaa.xxx.user.UserRepository;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.security.Principal;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@RestController
@RequestMapping("/lockhistory")
public class LockHistoryController {
private final UserRepository userRepository;
private final LockHistoryRepository lockHistoryRepository;
public LockHistoryController(UserRepository userRepository, LockHistoryRepository lockHistoryRepository) {
this.userRepository = userRepository;
this.lockHistoryRepository = lockHistoryRepository;
}
@GetMapping
public ResponseEntity<List<Map<String, Object>>> get(@RequestParam UUID userId, Principal principal) {
var meOpt = userRepository.findByEmail(principal.getName());
if (meOpt.isEmpty()) return ResponseEntity.status(401).build();
var result = lockHistoryRepository.findByUserIdOrderByEndTimeDesc(userId).stream()
.map(e -> {
Map<String, Object> item = new LinkedHashMap<>();
item.put("role", e.getRole());
item.put("lockName", e.getLockName() != null ? e.getLockName() : "");
item.put("startTime", e.getStartTime().toString());
item.put("unlockTime", e.getEndTime().toString());
item.put("durationMinutes", e.getDurationMinutes());
if (e.getLockedBy() != null) {
userRepository.findById(e.getLockedBy()).ifPresent(u -> {
if ("LOCKEE".equals(e.getRole())) {
item.put("keyholderName", u.getName());
} else {
item.put("lockeeName", u.getName());
}
if (u.getProfilePicture() != null) {
item.put("partnerPic", u.getProfilePicture());
}
});
}
return item;
}).toList();
return ResponseEntity.ok(result);
}
}

View File

@@ -5,7 +5,7 @@ import java.util.UUID;
import de.oaa.xxx.games.chastity.LockType;
public record LockHistoryDTO (UUID historyId, UUID userId, LocalDateTime startTime, LocalDateTime endTime, LockType type, UUID lockedBy) {
public record LockHistoryDTO (UUID historyId, UUID userId, LocalDateTime startTime, LocalDateTime endTime, LockType type, UUID lockedBy, String lockName, long durationMinutes, String role) {
}

View File

@@ -12,7 +12,11 @@ import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Entity
@Table(name = "lock_history")
public class LockHistoryEntity {
@@ -33,55 +37,17 @@ public class LockHistoryEntity {
@Column
private UUID lockedBy;
public UUID getHistoryId() {
return historyId;
}
@Column
private String lockName;
public void setHistoryId(UUID historyId) {
this.historyId = historyId;
}
@Column(nullable = false, columnDefinition = "BIGINT DEFAULT 0")
private long durationMinutes;
public UUID getUserId() {
return userId;
}
public void setUserId(UUID userId) {
this.userId = userId;
}
public LocalDateTime getStartTime() {
return startTime;
}
public void setStartTime(LocalDateTime startTime) {
this.startTime = startTime;
}
public LocalDateTime getEndTime() {
return endTime;
}
public void setEndTime(LocalDateTime endTime) {
this.endTime = endTime;
}
public LockType getType() {
return type;
}
public void setType(LockType type) {
this.type = type;
}
public UUID getLockedBy() {
return lockedBy;
}
public void setLockedBy(UUID lockedBy) {
this.lockedBy = lockedBy;
}
// LOCKEE oder KEYHOLDER
@Column(nullable = false, length = 20)
private String role;
public LockHistoryDTO toLockHistory() {
return new LockHistoryDTO(historyId, userId, startTime, endTime, type, lockedBy);
return new LockHistoryDTO(historyId, userId, startTime, endTime, type, lockedBy, lockName, durationMinutes, role);
}
}

View File

@@ -1,9 +1,14 @@
package de.oaa.xxx.games.chastity.tasks;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "assigned_task")
public class AssignedTaskEntity {
@@ -44,37 +49,4 @@ public class AssignedTaskEntity {
/** PENDING | ACCEPTED | DECLINED | EXPIRED */
@Column(nullable = false)
private String status = "PENDING";
public UUID getTaskId() { return taskId; }
public void setTaskId(UUID taskId) { this.taskId = taskId; }
public UUID getLockId() { return lockId; }
public void setLockId(UUID lockId) { this.lockId = lockId; }
public String getTaskTitle() { return taskTitle; }
public void setTaskTitle(String taskTitle) { this.taskTitle = taskTitle; }
public String getTaskDescription() { return taskDescription; }
public void setTaskDescription(String d) { this.taskDescription = d; }
public String getTaskText() { return taskText; }
public void setTaskText(String taskText) { this.taskText = taskText; }
public Integer getTaskMinutes() { return taskMinutes; }
public void setTaskMinutes(Integer m) { this.taskMinutes = m; }
public LocalDateTime getAssignedAt() { return assignedAt; }
public void setAssignedAt(LocalDateTime t) { this.assignedAt = t; }
public LocalDateTime getAcceptDeadline() { return acceptDeadline; }
public void setAcceptDeadline(LocalDateTime t) { this.acceptDeadline = t; }
public Integer getPenaltyFreezeMinutes() { return penaltyFreezeMinutes; }
public void setPenaltyFreezeMinutes(Integer m) { this.penaltyFreezeMinutes = m; }
public Integer getPenaltyRedCards() { return penaltyRedCards; }
public void setPenaltyRedCards(Integer n) { this.penaltyRedCards = n; }
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
}

View File

@@ -1,5 +1,10 @@
package de.oaa.xxx.games.chastity.tasks;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class Task {
private String title;
@@ -9,18 +14,6 @@ public class Task {
/** @deprecated Backward-Compat alte Einträge ohne title/description. Nur lesen, nicht setzen. */
private String text;
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public String getDescription() { return description; }
public void setDescription(String description) { this.description = description; }
public Integer getMinutes() { return minutes; }
public void setMinutes(Integer minutes) { this.minutes = minutes; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
/** Gibt den anzeigbaren Titel zurück fällt auf altes text-Feld zurück. */
public String resolveTitle() {
if (title != null && !title.isBlank()) return title;

View File

@@ -1,7 +1,6 @@
package de.oaa.xxx.games.chastity.verification;
import java.security.Principal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Base64;
import java.util.HashMap;
@@ -60,8 +59,8 @@ public class VerificationController {
@GetMapping("/")
public ResponseEntity<List<VerificationDTO>> getAll(
@RequestParam(value = "page", defaultValue = "1") int page,
@RequestParam(value = "size", defaultValue = "10") int size) {
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "10") int size) {
var paging = PageRequest.of(page, size, Sort.by("verificationTime").descending());
Page<VerificationEntity> result = verificationRepository.findAllByImageIsNotNull(paging);
return ResponseEntity.ok(result.stream().map(VerificationEntity::toVerification).toList());
@@ -106,11 +105,11 @@ public class VerificationController {
if (user == null) return ResponseEntity.status(401).build();
UUID myId = user.getUserId();
LocalDateTime todayStart = LocalDate.now().atStartOfDay();
LocalDateTime todayEnd = todayStart.plusDays(1);
LocalDateTime since = LocalDateTime.now().minusHours(24);
LocalDateTime until = LocalDateTime.now();
var paging = PageRequest.of(page, 10, Sort.by("verificationTime").descending());
Page<VerificationEntity> result = verificationRepository
.findByKeyholderIsNullAndVerificationTimeBetweenAndImageIsNotNull(todayStart, todayEnd, paging);
.findByKeyholderIsNullAndVerificationTimeBetweenAndImageIsNotNull(since, until, paging);
List<Map<String, Object>> items = result.getContent().stream().map(v -> {
var votes = verificationVoteRepository.findAllByVerificationId(v.getVerficationId());

View File

@@ -8,7 +8,11 @@ import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Entity
@Table(name = "verification")
public class VerificationEntity {
@@ -29,54 +33,6 @@ public class VerificationEntity {
@Column
private UUID keyholder;
public UUID getVerficationId() {
return verficationId;
}
public void setVerficationId(UUID verficationId) {
this.verficationId = verficationId;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public LocalDateTime getVerificationTime() {
return verificationTime;
}
public void setVerificationTime(LocalDateTime verificationTime) {
this.verificationTime = verificationTime;
}
public byte[] getImage() {
return image;
}
public void setImage(byte[] image) {
this.image = image;
}
public UUID getLockId() {
return lockId;
}
public void setLockId(UUID lockId) {
this.lockId = lockId;
}
public UUID getLockeeId() {
return lockeeId;
}
public void setLockeeId(UUID lockeeId) {
this.lockeeId = lockeeId;
}
public UUID getKeyholderId() {
return keyholder;
}

View File

@@ -6,7 +6,11 @@ import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Entity
@Table(name="verification_vote")
public class VerificationVoteEntity {
@@ -20,32 +24,7 @@ public class VerificationVoteEntity {
private UUID userId;
@Column(nullable = false)
private boolean upvote;
public UUID getVoteId() {
return voteId;
}
public void setVoteId(UUID voteId) {
this.voteId = voteId;
}
public UUID getVerificationId() {
return verificationId;
}
public void setVerificationId(UUID verificationId) {
this.verificationId = verificationId;
}
public UUID getUserId() {
return userId;
}
public void setUserId(UUID userId) {
this.userId = userId;
}
public boolean isUpvote() {
return upvote;
}
public void setUpvote(boolean upvote) {
this.upvote = upvote;
}
public VerificationVoteDTO toVerificationVote() {
return new VerificationVoteDTO(voteId, userId, upvote);
}

View File

@@ -1,9 +1,14 @@
package de.oaa.xxx.gruppe.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "beitrag_meldung",
uniqueConstraints = @UniqueConstraint(columnNames = {"beitragId", "melderId"}))
@@ -24,19 +29,4 @@ public class BeitragMeldungEntity {
@Column(nullable = false)
private LocalDateTime gemeldetAt;
public UUID getMeldungId() { return meldungId; }
public void setMeldungId(UUID meldungId) { this.meldungId = meldungId; }
public UUID getBeitragId() { return beitragId; }
public void setBeitragId(UUID beitragId) { this.beitragId = beitragId; }
public UUID getMelderId() { return melderId; }
public void setMelderId(UUID melderId) { this.melderId = melderId; }
public String getGrund() { return grund; }
public void setGrund(String grund) { this.grund = grund; }
public LocalDateTime getGemeldetAt() { return gemeldetAt; }
public void setGemeldetAt(LocalDateTime gemeldetAt) { this.gemeldetAt = gemeldetAt; }
}

View File

@@ -2,9 +2,14 @@ package de.oaa.xxx.gruppe.entity;
import de.oaa.xxx.gruppe.AnfrageStatus;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "beitrittsanfrage")
public class BeitrittsanfrageEntity {
@@ -28,22 +33,4 @@ public class BeitrittsanfrageEntity {
@Enumerated(EnumType.STRING)
@Column(nullable = false, length = 15)
private AnfrageStatus status;
public UUID getAnfrageId() { return anfrageId; }
public void setAnfrageId(UUID anfrageId) { this.anfrageId = anfrageId; }
public UUID getGruppeId() { return gruppeId; }
public void setGruppeId(UUID gruppeId) { this.gruppeId = gruppeId; }
public UUID getUserId() { return userId; }
public void setUserId(UUID userId) { this.userId = userId; }
public String getNachricht() { return nachricht; }
public void setNachricht(String nachricht) { this.nachricht = nachricht; }
public LocalDateTime getAngefragtAt() { return angefragtAt; }
public void setAngefragtAt(LocalDateTime angefragtAt) { this.angefragtAt = angefragtAt; }
public AnfrageStatus getStatus() { return status; }
public void setStatus(AnfrageStatus status) { this.status = status; }
}

View File

@@ -1,9 +1,14 @@
package de.oaa.xxx.gruppe.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "gruppe")
public class GruppeEntity {
@@ -29,25 +34,4 @@ public class GruppeEntity {
@Column(nullable = false)
private UUID createdByUserId;
public UUID getGruppeId() { return gruppeId; }
public void setGruppeId(UUID gruppeId) { this.gruppeId = gruppeId; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getBeschreibung() { return beschreibung; }
public void setBeschreibung(String beschreibung) { this.beschreibung = beschreibung; }
public String getBild() { return bild; }
public void setBild(String bild) { this.bild = bild; }
public boolean isPrivate() { return isPrivate; }
public void setPrivate(boolean aPrivate) { isPrivate = aPrivate; }
public LocalDateTime getCreatedAt() { return createdAt; }
public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
public UUID getCreatedByUserId() { return createdByUserId; }
public void setCreatedByUserId(UUID createdByUserId) { this.createdByUserId = createdByUserId; }
}

View File

@@ -3,10 +3,15 @@ package de.oaa.xxx.gruppe.entity;
import de.oaa.xxx.config.StringListConverter;
import de.oaa.xxx.gruppe.BeitragTyp;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "gruppe_beitrag")
public class GruppenbeitragEntity {
@@ -37,28 +42,4 @@ public class GruppenbeitragEntity {
@Column(nullable = false)
private LocalDateTime createdAt;
public UUID getBeitragId() { return beitragId; }
public void setBeitragId(UUID beitragId) { this.beitragId = beitragId; }
public UUID getGruppeId() { return gruppeId; }
public void setGruppeId(UUID gruppeId) { this.gruppeId = gruppeId; }
public UUID getAuthorId() { return authorId; }
public void setAuthorId(UUID authorId) { this.authorId = authorId; }
public BeitragTyp getBeitragTyp() { return beitragTyp; }
public void setBeitragTyp(BeitragTyp beitragTyp) { this.beitragTyp = beitragTyp; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
public Boolean getMultiChoice() { return multiChoice; }
public void setMultiChoice(Boolean multiChoice) { this.multiChoice = multiChoice; }
public List<String> getBilder() { return bilder; }
public void setBilder(List<String> bilder) { this.bilder = bilder; }
public LocalDateTime getCreatedAt() { return createdAt; }
public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
}

View File

@@ -1,9 +1,14 @@
package de.oaa.xxx.gruppe.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "gruppe_beitrag_like",
uniqueConstraints = @UniqueConstraint(columnNames = {"beitragId", "userId"}))
@@ -21,16 +26,4 @@ public class GruppenbeitragLikeEntity {
@Column(nullable = false)
private LocalDateTime likedAt;
public UUID getLikeId() { return likeId; }
public void setLikeId(UUID likeId) { this.likeId = likeId; }
public UUID getBeitragId() { return beitragId; }
public void setBeitragId(UUID beitragId) { this.beitragId = beitragId; }
public UUID getUserId() { return userId; }
public void setUserId(UUID userId) { this.userId = userId; }
public LocalDateTime getLikedAt() { return likedAt; }
public void setLikedAt(LocalDateTime likedAt) { this.likedAt = likedAt; }
}

View File

@@ -2,9 +2,14 @@ package de.oaa.xxx.gruppe.entity;
import de.oaa.xxx.gruppe.GruppenRolle;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "gruppe_mitglied",
uniqueConstraints = @UniqueConstraint(columnNames = {"gruppeId", "userId"}))
@@ -26,19 +31,4 @@ public class GruppenmitgliedEntity {
@Column(nullable = false)
private LocalDateTime joinedAt;
public UUID getMitgliedId() { return mitgliedId; }
public void setMitgliedId(UUID mitgliedId) { this.mitgliedId = mitgliedId; }
public UUID getGruppeId() { return gruppeId; }
public void setGruppeId(UUID gruppeId) { this.gruppeId = gruppeId; }
public UUID getUserId() { return userId; }
public void setUserId(UUID userId) { this.userId = userId; }
public GruppenRolle getRolle() { return rolle; }
public void setRolle(GruppenRolle rolle) { this.rolle = rolle; }
public LocalDateTime getJoinedAt() { return joinedAt; }
public void setJoinedAt(LocalDateTime joinedAt) { this.joinedAt = joinedAt; }
}

View File

@@ -1,8 +1,13 @@
package de.oaa.xxx.gruppe.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "umfrage_option")
public class UmfrageOptionEntity {
@@ -19,16 +24,4 @@ public class UmfrageOptionEntity {
@Column(nullable = false)
private int reihenfolge;
public UUID getOptionId() { return optionId; }
public void setOptionId(UUID optionId) { this.optionId = optionId; }
public UUID getBeitragId() { return beitragId; }
public void setBeitragId(UUID beitragId) { this.beitragId = beitragId; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
public int getReihenfolge() { return reihenfolge; }
public void setReihenfolge(int reihenfolge) { this.reihenfolge = reihenfolge; }
}

View File

@@ -1,8 +1,13 @@
package de.oaa.xxx.gruppe.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "umfrage_stimme",
uniqueConstraints = @UniqueConstraint(columnNames = {"optionId", "userId"}))
@@ -20,16 +25,4 @@ public class UmfrageStimmeEntity {
@Column(nullable = false)
private UUID userId;
public UUID getStimmeId() { return stimmeId; }
public void setStimmeId(UUID stimmeId) { this.stimmeId = stimmeId; }
public UUID getOptionId() { return optionId; }
public void setOptionId(UUID optionId) { this.optionId = optionId; }
public UUID getBeitragId() { return beitragId; }
public void setBeitragId(UUID beitragId) { this.beitragId = beitragId; }
public UUID getUserId() { return userId; }
public void setUserId(UUID userId) { this.userId = userId; }
}

View File

@@ -1,17 +1,13 @@
package de.oaa.xxx.mail;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class Email {
private String emailAdresse;
private String titel;
private String text;
public String getEmailAdresse() { return emailAdresse; }
public void setEmailAdresse(String emailAdresse) { this.emailAdresse = emailAdresse; }
public String getTitel() { return titel; }
public void setTitel(String titel) { this.titel = titel; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
}

View File

@@ -4,10 +4,14 @@ import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "password_reset")
public class PasswordResetEntity {
@@ -22,15 +26,6 @@ public class PasswordResetEntity {
@Column
private LocalDateTime createdAt;
public UUID getTokenId() { return tokenId; }
public void setTokenId(UUID tokenId) { this.tokenId = tokenId; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public LocalDateTime getCreatedAt() { return createdAt; }
public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
@Override
public String toString() {
return "PasswordResetEntity[tokenId=" + tokenId + ", email=" + email + ", createdAt=" + createdAt + "]";

View File

@@ -1,7 +1,12 @@
package de.oaa.xxx.registration;
import lombok.Getter;
import lombok.Setter;
import java.util.UUID;
@Getter
@Setter
public class Registration {
private UUID id;
@@ -9,18 +14,6 @@ public class Registration {
private String email;
private String passwordHash;
public UUID getId() { return id; }
public void setId(UUID id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public String getPasswordHash() { return passwordHash; }
public void setPasswordHash(String passwordHash) { this.passwordHash = passwordHash; }
@Override
public String toString() {
return "Registration [id=" + id + ", name=" + name + ", email=" + email + "]";

View File

@@ -4,9 +4,13 @@ import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "registration")
public class RegistrationEntity {
@@ -23,21 +27,6 @@ public class RegistrationEntity {
@Column
private Boolean activated;
public UUID getRegistrationId() { return registrationId; }
public void setRegistrationId(UUID registrationId) { this.registrationId = registrationId; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public Boolean getActivated() { return activated; }
public void setActivated(Boolean activated) { this.activated = activated; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
@Override
public String toString() {
return "RegistrationEntity [registrationId=" + registrationId + ", name=" + name + ", email=" + email + "]";

View File

@@ -1,9 +1,14 @@
package de.oaa.xxx.session;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
public class AktiveSperre {
private UUID aktiveSperreId;
@@ -14,27 +19,6 @@ public class AktiveSperre {
private List<Werkzeug> fuer;
private String releaseText;
public UUID getAktiveSperreId() { return aktiveSperreId; }
public void setAktiveSperreId(UUID aktiveSperreId) { this.aktiveSperreId = aktiveSperreId; }
public Mitspieler getMitspieler() { return mitspieler; }
public void setMitspieler(Mitspieler mitspieler) { this.mitspieler = mitspieler; }
public Integer getMinuten() { return minuten; }
public void setMinuten(Integer minuten) { this.minuten = minuten; }
public LocalDateTime getStartzeit() { return startzeit; }
public void setStartzeit(LocalDateTime startzeit) { this.startzeit = startzeit; }
public LocalDateTime getEndzeit() { return endzeit; }
public void setEndzeit(LocalDateTime endzeit) { this.endzeit = endzeit; }
public List<Werkzeug> getFuer() { return fuer; }
public void setFuer(List<Werkzeug> fuer) { this.fuer = fuer; }
public String getReleaseText() { return releaseText; }
public void setReleaseText(String releaseText) { this.releaseText = releaseText; }
@Override
public String toString() {
return "AktiveSperre[id=" + aktiveSperreId + ", mitspieler=" + (mitspieler != null ? mitspieler.getName() : null)

View File

@@ -1,5 +1,10 @@
package de.oaa.xxx.session;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class AufgabeAnzeige {
private String nameAktiverMitspieler;
@@ -8,21 +13,6 @@ public class AufgabeAnzeige {
private Callback callback;
private Integer level;
public String getNameAktiverMitspieler() { return nameAktiverMitspieler; }
public void setNameAktiverMitspieler(String nameAktiverMitspieler) { this.nameAktiverMitspieler = nameAktiverMitspieler; }
public String getAufgabeText() { return aufgabeText; }
public void setAufgabeText(String aufgabeText) { this.aufgabeText = aufgabeText; }
public Integer getTimer() { return timer; }
public void setTimer(Integer timer) { this.timer = timer; }
public Callback getCallback() { return callback; }
public void setCallback(Callback callback) { this.callback = callback; }
public Integer getLevel() { return level; }
public void setLevel(Integer level) { this.level = level; }
@Override
public String toString() {
return "AufgabeAnzeige[mitspieler=" + nameAktiverMitspieler + ", level=" + level + ", timer=" + timer

View File

@@ -1,8 +1,13 @@
package de.oaa.xxx.session;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
public class Mitspieler {
private UUID id;
@@ -12,24 +17,6 @@ public class Mitspieler {
private List<RolleEnum> rollen;
private List<Werkzeug> verfuegbareWerkzeuge;
public UUID getId() { return id; }
public void setId(UUID id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public GeschlechtEnum getGeschlecht() { return geschlecht; }
public void setGeschlecht(GeschlechtEnum geschlecht) { this.geschlecht = geschlecht; }
public List<GeschlechtEnum> getSpieltMit() { return spieltMit; }
public void setSpieltMit(List<GeschlechtEnum> spieltMit) { this.spieltMit = spieltMit; }
public List<RolleEnum> getRollen() { return rollen; }
public void setRollen(List<RolleEnum> rollen) { this.rollen = rollen; }
public List<Werkzeug> getVerfuegbareWerkzeuge() { return verfuegbareWerkzeuge; }
public void setVerfuegbareWerkzeuge(List<Werkzeug> verfuegbareWerkzeuge) { this.verfuegbareWerkzeuge = verfuegbareWerkzeuge; }
public boolean isVerfuegbar(Werkzeug werkzeug) {
return verfuegbareWerkzeuge.contains(werkzeug);
}

View File

@@ -1,8 +1,13 @@
package de.oaa.xxx.session;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.UUID;
@Getter
@Setter
public class Session {
private UUID sessionId;
@@ -16,36 +21,6 @@ public class Session {
private LocalDateTime startZeit;
private LocalDateTime letzteAktivitaet;
public UUID getSessionId() { return sessionId; }
public void setSessionId(UUID sessionId) { this.sessionId = sessionId; }
public UUID getUserId() { return userId; }
public void setUserId(UUID userId) { this.userId = userId; }
public Integer getWahrscheinlichkeitSperre() { return wahrscheinlichkeitSperre; }
public void setWahrscheinlichkeitSperre(Integer wahrscheinlichkeitSperre) { this.wahrscheinlichkeitSperre = wahrscheinlichkeitSperre; }
public Integer getWahrscheinlichkeitStrafe() { return wahrscheinlichkeitStrafe; }
public void setWahrscheinlichkeitStrafe(Integer wahrscheinlichkeitStrafe) { this.wahrscheinlichkeitStrafe = wahrscheinlichkeitStrafe; }
public Integer getAufgabenProLevel() { return aufgabenProLevel; }
public void setAufgabenProLevel(Integer aufgabenProLevel) { this.aufgabenProLevel = aufgabenProLevel; }
public Double getZeitfaktorZeitstrafen() { return zeitfaktorZeitstrafen; }
public void setZeitfaktorZeitstrafen(Double zeitfaktorZeitstrafen) { this.zeitfaktorZeitstrafen = zeitfaktorZeitstrafen; }
public Integer getLevel() { return level; }
public void setLevel(Integer level) { this.level = level; }
public Integer getAufgabenAufAktuellemLevel() { return aufgabenAufAktuellemLevel; }
public void setAufgabenAufAktuellemLevel(Integer aufgabenAufAktuellemLevel) { this.aufgabenAufAktuellemLevel = aufgabenAufAktuellemLevel; }
public LocalDateTime getStartZeit() { return startZeit; }
public void setStartZeit(LocalDateTime startZeit) { this.startZeit = startZeit; }
public LocalDateTime getLetzteAktivitaet() { return letzteAktivitaet; }
public void setLetzteAktivitaet(LocalDateTime letzteAktivitaet) { this.letzteAktivitaet = letzteAktivitaet; }
@Override
public String toString() {
return "Session[sessionId=" + sessionId + ", userId=" + userId

View File

@@ -2,10 +2,14 @@ package de.oaa.xxx.session.aufgaben;
import de.oaa.xxx.session.Mitspieler;
import de.oaa.xxx.session.Werkzeug;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
public class Aufgabe {
private UUID aufgabeId;
@@ -18,33 +22,6 @@ public class Aufgabe {
private List<Werkzeug> benoetigtAktiv;
private List<Werkzeug> benoetigtPassiv;
public UUID getAufgabeId() { return aufgabeId; }
public void setAufgabeId(UUID aufgabeId) { this.aufgabeId = aufgabeId; }
public String getKurzText() { return kurzText; }
public void setKurzText(String kurzText) { this.kurzText = kurzText; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
public Integer getLevel() { return level; }
public void setLevel(Integer level) { this.level = level; }
public Integer getSekundenVon() { return sekundenVon; }
public void setSekundenVon(Integer sekundenVon) { this.sekundenVon = sekundenVon; }
public Integer getSekundenBis() { return sekundenBis; }
public void setSekundenBis(Integer sekundenBis) { this.sekundenBis = sekundenBis; }
public UUID getGruppeId() { return gruppeId; }
public void setGruppeId(UUID gruppeId) { this.gruppeId = gruppeId; }
public List<Werkzeug> getBenoetigtAktiv() { return benoetigtAktiv; }
public void setBenoetigtAktiv(List<Werkzeug> benoetigtAktiv) { this.benoetigtAktiv = benoetigtAktiv; }
public List<Werkzeug> getBenoetigtPassiv() { return benoetigtPassiv; }
public void setBenoetigtPassiv(List<Werkzeug> benoetigtPassiv) { this.benoetigtPassiv = benoetigtPassiv; }
@Override
public String toString() {
return "Aufgabe[id=" + aufgabeId + ", kurzText=" + kurzText + ", level=" + level

View File

@@ -1,7 +1,12 @@
package de.oaa.xxx.session.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class AufgabenList {
private List<Aufgabe> aufgaben;
@@ -9,18 +14,6 @@ public class AufgabenList {
private List<Strafe> strafen;
private List<Finisher> finisher;
public List<Aufgabe> getAufgaben() { return aufgaben; }
public void setAufgaben(List<Aufgabe> aufgaben) { this.aufgaben = aufgaben; }
public List<Sperre> getSperren() { return sperren; }
public void setSperren(List<Sperre> sperren) { this.sperren = sperren; }
public List<Strafe> getStrafen() { return strafen; }
public void setStrafen(List<Strafe> strafen) { this.strafen = strafen; }
public List<Finisher> getFinisher() { return finisher; }
public void setFinisher(List<Finisher> finisher) { this.finisher = finisher; }
public int size() {
int size = 0;
if (aufgaben != null) size += aufgaben.size();

View File

@@ -1,13 +1,17 @@
package de.oaa.xxx.session.aufgaben;
import de.oaa.xxx.session.GeschlechtEnum;
import de.oaa.xxx.session.Werkzeug;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.UUID;
import de.oaa.xxx.session.GeschlechtEnum;
import de.oaa.xxx.session.Werkzeug;
@Getter
@Setter
public class Finisher {
private UUID finisherId;
private String kurzText;
private String text;
@@ -15,24 +19,6 @@ public class Finisher {
private List<Werkzeug> benoetigtAktiv;
private List<Werkzeug> benoetigtPassiv;
public UUID getFinisherId() { return finisherId; }
public void setFinisherId(UUID finisherId) { this.finisherId = finisherId; }
public String getKurzText() { return kurzText; }
public void setKurzText(String kurzText) { this.kurzText = kurzText; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
public GeschlechtEnum getGeschlecht() { return geschlecht; }
public void setGeschlecht(GeschlechtEnum geschlecht) { this.geschlecht = geschlecht; }
public List<Werkzeug> getBenoetigtAktiv() { return benoetigtAktiv; }
public void setBenoetigtAktiv(List<Werkzeug> benoetigtAktiv) { this.benoetigtAktiv = benoetigtAktiv; }
public List<Werkzeug> getBenoetigtPassiv() { return benoetigtPassiv; }
public void setBenoetigtPassiv(List<Werkzeug> benoetigtPassiv) { this.benoetigtPassiv = benoetigtPassiv; }
@Override
public String toString() {
return "Finisher[id=" + finisherId + ", kurzText=" + kurzText + ", geschlecht=" + geschlecht + "]";

View File

@@ -2,10 +2,14 @@ package de.oaa.xxx.session.aufgaben;
import de.oaa.xxx.session.Mitspieler;
import de.oaa.xxx.session.Werkzeug;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
public class Sperre {
private UUID sperreId;
@@ -17,30 +21,6 @@ public class Sperre {
private Integer minutenVon;
private Integer minutenBis;
public UUID getSperreId() { return sperreId; }
public void setSperreId(UUID sperreId) { this.sperreId = sperreId; }
public String getKurzText() { return kurzText; }
public void setKurzText(String kurzText) { this.kurzText = kurzText; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
public String getReleaseText() { return releaseText; }
public void setReleaseText(String releaseText) { this.releaseText = releaseText; }
public UUID getGruppeId() { return gruppeId; }
public void setGruppeId(UUID gruppeId) { this.gruppeId = gruppeId; }
public List<Werkzeug> getSperreFuer() { return sperreFuer; }
public void setSperreFuer(List<Werkzeug> sperreFuer) { this.sperreFuer = sperreFuer; }
public Integer getMinutenVon() { return minutenVon; }
public void setMinutenVon(Integer minutenVon) { this.minutenVon = minutenVon; }
public Integer getMinutenBis() { return minutenBis; }
public void setMinutenBis(Integer minutenBis) { this.minutenBis = minutenBis; }
@Override
public String toString() {
return "Sperre[id=" + sperreId + ", kurzText=" + kurzText

View File

@@ -2,10 +2,14 @@ package de.oaa.xxx.session.aufgaben;
import de.oaa.xxx.session.Mitspieler;
import de.oaa.xxx.session.Werkzeug;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
public class Strafe {
private UUID strafeId;
@@ -18,33 +22,6 @@ public class Strafe {
private List<Werkzeug> benoetigtAktiv;
private List<Werkzeug> benoetigtPassiv;
public UUID getStrafeId() { return strafeId; }
public void setStrafeId(UUID strafeId) { this.strafeId = strafeId; }
public Integer getLevel() { return level; }
public void setLevel(Integer level) { this.level = level; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
public String getKurzText() { return kurzText; }
public void setKurzText(String kurzText) { this.kurzText = kurzText; }
public Integer getSekundenVon() { return sekundenVon; }
public void setSekundenVon(Integer sekundenVon) { this.sekundenVon = sekundenVon; }
public Integer getSekundenBis() { return sekundenBis; }
public void setSekundenBis(Integer sekundenBis) { this.sekundenBis = sekundenBis; }
public UUID getGruppeId() { return gruppeId; }
public void setGruppeId(UUID gruppeId) { this.gruppeId = gruppeId; }
public List<Werkzeug> getBenoetigtAktiv() { return benoetigtAktiv; }
public void setBenoetigtAktiv(List<Werkzeug> benoetigtAktiv) { this.benoetigtAktiv = benoetigtAktiv; }
public List<Werkzeug> getBenoetigtPassiv() { return benoetigtPassiv; }
public void setBenoetigtPassiv(List<Werkzeug> benoetigtPassiv) { this.benoetigtPassiv = benoetigtPassiv; }
public boolean isAufgabePassend(int level, Mitspieler aktiv, Mitspieler passiv) {
if (level != this.level && level - 1 != this.level) {
return false;

View File

@@ -14,6 +14,8 @@ import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.ArrayList;
@@ -21,6 +23,8 @@ import java.util.List;
import java.util.Optional;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "aktiveSperre")
public class AktiveSperreEntity {
@@ -48,30 +52,6 @@ public class AktiveSperreEntity {
@JoinColumn(name = "sessionId", nullable = false)
private SessionEntity session;
public UUID getAktiveSperreId() { return aktiveSperreId; }
public void setAktiveSperreId(UUID aktiveSperreId) { this.aktiveSperreId = aktiveSperreId; }
public MitspielerEntity getMitspieler() { return mitspieler; }
public void setMitspieler(MitspielerEntity mitspieler) { this.mitspieler = mitspieler; }
public Integer getMinuten() { return minuten; }
public void setMinuten(Integer minuten) { this.minuten = minuten; }
public LocalDateTime getStartzeit() { return startzeit; }
public void setStartzeit(LocalDateTime startzeit) { this.startzeit = startzeit; }
public LocalDateTime getEndzeit() { return endzeit; }
public void setEndzeit(LocalDateTime endzeit) { this.endzeit = endzeit; }
public List<Werkzeug> getFuer() { return fuer; }
public void setFuer(List<Werkzeug> fuer) { this.fuer = fuer; }
public String getReleaseText() { return releaseText; }
public void setReleaseText(String releaseText) { this.releaseText = releaseText; }
public SessionEntity getSession() { return session; }
public void setSession(SessionEntity session) { this.session = session; }
public AktiveSperre toSperre(List<Mitspieler> mitspielerList) {
AktiveSperre sperre = new AktiveSperre();
sperre.setAktiveSperreId(aktiveSperreId);

View File

@@ -16,11 +16,15 @@ import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "mitspieler")
public class MitspielerEntity {
@@ -54,30 +58,6 @@ public class MitspielerEntity {
@OneToMany(mappedBy = "mitspieler", fetch = FetchType.EAGER)
private List<AktiveSperreEntity> aktiveSperren = new ArrayList<>();
public UUID getMitspielerId() { return mitspielerId; }
public void setMitspielerId(UUID mitspielerId) { this.mitspielerId = mitspielerId; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public GeschlechtEnum getGeschlecht() { return geschlecht; }
public void setGeschlecht(GeschlechtEnum geschlecht) { this.geschlecht = geschlecht; }
public List<Werkzeug> getWerkzeuge() { return werkzeuge; }
public void setWerkzeuge(List<Werkzeug> werkzeuge) { this.werkzeuge = werkzeuge; }
public List<GeschlechtEnum> getSpieltMit() { return spieltMit; }
public void setSpieltMit(List<GeschlechtEnum> spieltMit) { this.spieltMit = spieltMit; }
public List<RolleEnum> getRollen() { return rollen; }
public void setRollen(List<RolleEnum> rollen) { this.rollen = rollen; }
public SessionEntity getSession() { return session; }
public void setSession(SessionEntity session) { this.session = session; }
public List<AktiveSperreEntity> getAktiveSperren() { return aktiveSperren; }
public void setAktiveSperren(List<AktiveSperreEntity> aktiveSperren) { this.aktiveSperren = aktiveSperren; }
@Override
public String toString() {
return "MitspielerEntity[mitspielerId=" + mitspielerId + ", name=" + name

View File

@@ -6,12 +6,16 @@ import jakarta.persistence.FetchType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "session")
public class SessionEntity {
@@ -44,45 +48,6 @@ public class SessionEntity {
@Column
private Double zeitfaktorZeitstrafen;
public UUID getSessionId() { return sessionId; }
public void setSessionId(UUID sessionId) { this.sessionId = sessionId; }
public UUID getUserId() { return userId; }
public void setUserId(UUID userId) { this.userId = userId; }
public LocalDateTime getStartZeit() { return startZeit; }
public void setStartZeit(LocalDateTime startZeit) { this.startZeit = startZeit; }
public LocalDateTime getLetzteAktivitaet() { return letzteAktivitaet; }
public void setLetzteAktivitaet(LocalDateTime letzteAktivitaet) { this.letzteAktivitaet = letzteAktivitaet; }
public List<MitspielerEntity> getMitspieler() { return mitspieler; }
public void setMitspieler(List<MitspielerEntity> mitspieler) { this.mitspieler = mitspieler; }
public List<AktiveSperreEntity> getAktiveSperren() { return aktiveSperren; }
public void setAktiveSperren(List<AktiveSperreEntity> aktiveSperren) { this.aktiveSperren = aktiveSperren; }
public Integer getWahrscheinlichkeitSperre() { return wahrscheinlichkeitSperre; }
public void setWahrscheinlichkeitSperre(Integer wahrscheinlichkeitSperre) { this.wahrscheinlichkeitSperre = wahrscheinlichkeitSperre; }
public Integer getWahrscheinlichkeitStrafe() { return wahrscheinlichkeitStrafe; }
public void setWahrscheinlichkeitStrafe(Integer wahrscheinlichkeitStrafe) { this.wahrscheinlichkeitStrafe = wahrscheinlichkeitStrafe; }
public Integer getAufgabenProLevel() { return aufgabenProLevel; }
public void setAufgabenProLevel(Integer aufgabenProLevel) { this.aufgabenProLevel = aufgabenProLevel; }
public Integer getLevel() { return level; }
public void setLevel(Integer level) { this.level = level; }
public Integer getAufgabenAufAktuellemLevel() { return aufgabenAufAktuellemLevel; }
public void setAufgabenAufAktuellemLevel(Integer aufgabenAufAktuellemLevel) { this.aufgabenAufAktuellemLevel = aufgabenAufAktuellemLevel; }
public String getAufgaben() { return aufgaben; }
public void setAufgaben(String aufgaben) { this.aufgaben = aufgaben; }
public Double getZeitfaktorZeitstrafen() { return zeitfaktorZeitstrafen; }
public void setZeitfaktorZeitstrafen(Double zeitfaktorZeitstrafen) { this.zeitfaktorZeitstrafen = zeitfaktorZeitstrafen; }
@Override
public String toString() {
return "SessionEntity[sessionId=" + sessionId + ", userId=" + userId

View File

@@ -62,7 +62,7 @@ public class KommentarController {
if (request.text() == null || request.text().isBlank()) return ResponseEntity.badRequest().build();
if (request.text().length() > 500) return ResponseEntity.badRequest().build();
if (!List.of("PINNWAND", "IMAGE", "KOMMENTAR", "GROUP_POST").contains(request.targetType())) {
if (!List.of("PINNWAND", "IMAGE", "KOMMENTAR", "GROUP_POST", "FEED_POST").contains(request.targetType())) {
return ResponseEntity.badRequest().build();
}

View File

@@ -313,7 +313,8 @@ public class SocialController {
}
return new UserProfile(user.getUserId(), user.getName(), user.getProfilePicture(), user.getProfilePictureHq(),
status, user.getAlter(), user.getGroesse(), user.getGewicht(),
user.getGeschlecht(), user.getNeigung(), user.getBeziehungsstatus(), user.getBeschreibung());
user.getGeschlecht(), user.getNeigung(), user.getBeziehungsstatus(), user.getBeschreibung(),
user.getLockeeXp(), user.getKeyholderXp());
}
private MessageDto toMessageDto(MessageEntity m) {

View File

@@ -1,27 +1,29 @@
package de.oaa.xxx.social.dto;
import de.oaa.xxx.user.Beziehungsstatus;
import de.oaa.xxx.user.Geschlecht;
import de.oaa.xxx.user.Neigung;
import java.util.UUID;
public record UserProfile(
UUID userId,
String name,
String profilePicture,
String profilePictureHq,
String friendStatus,
Integer alter,
Integer groesse,
Integer gewicht,
Geschlecht geschlecht,
Neigung neigung,
Beziehungsstatus beziehungsstatus,
String beschreibung
) {
/** Compact constructor for contexts where profile details are not needed (friend list etc.) */
public UserProfile(UUID userId, String name, String profilePicture, String profilePictureHq, String friendStatus) {
this(userId, name, profilePicture, profilePictureHq, friendStatus, null, null, null, null, null, null, null);
}
}
package de.oaa.xxx.social.dto;
import de.oaa.xxx.user.Beziehungsstatus;
import de.oaa.xxx.user.Geschlecht;
import de.oaa.xxx.user.Neigung;
import java.util.UUID;
public record UserProfile(
UUID userId,
String name,
String profilePicture,
String profilePictureHq,
String friendStatus,
Integer alter,
Integer groesse,
Integer gewicht,
Geschlecht geschlecht,
Neigung neigung,
Beziehungsstatus beziehungsstatus,
String beschreibung,
int lockeeXp,
int keyholderXp
) {
/** Compact constructor for contexts where profile details are not needed (friend list etc.) */
public UserProfile(UUID userId, String name, String profilePicture, String profilePictureHq, String friendStatus) {
this(userId, name, profilePicture, profilePictureHq, friendStatus, null, null, null, null, null, null, null, 0, 0);
}
}

View File

@@ -1,9 +1,14 @@
package de.oaa.xxx.social.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "friendship")
public class FriendshipEntity {
@@ -26,19 +31,4 @@ public class FriendshipEntity {
@Column(nullable = false)
private LocalDateTime createdAt;
public UUID getFriendshipId() { return friendshipId; }
public void setFriendshipId(UUID friendshipId) { this.friendshipId = friendshipId; }
public UUID getSenderId() { return senderId; }
public void setSenderId(UUID senderId) { this.senderId = senderId; }
public UUID getReceiverId() { return receiverId; }
public void setReceiverId(UUID receiverId) { this.receiverId = receiverId; }
public Status getStatus() { return status; }
public void setStatus(Status status) { this.status = status; }
public LocalDateTime getCreatedAt() { return createdAt; }
public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
}

View File

@@ -1,9 +1,14 @@
package de.oaa.xxx.social.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "kommentar")
public class KommentarEntity {
@@ -27,22 +32,4 @@ public class KommentarEntity {
@Column(nullable = false)
private LocalDateTime createdAt;
public UUID getKommentarId() { return kommentarId; }
public void setKommentarId(UUID kommentarId) { this.kommentarId = kommentarId; }
public UUID getAuthorId() { return authorId; }
public void setAuthorId(UUID authorId) { this.authorId = authorId; }
public String getTargetType() { return targetType; }
public void setTargetType(String targetType) { this.targetType = targetType; }
public UUID getTargetId() { return targetId; }
public void setTargetId(UUID targetId) { this.targetId = targetId; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
public LocalDateTime getCreatedAt() { return createdAt; }
public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
}

View File

@@ -1,9 +1,14 @@
package de.oaa.xxx.social.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "kommentar_like")
public class KommentarLikeEntity {
@@ -20,16 +25,4 @@ public class KommentarLikeEntity {
@Column(nullable = false)
private LocalDateTime likedAt;
public UUID getLikeId() { return likeId; }
public void setLikeId(UUID likeId) { this.likeId = likeId; }
public UUID getKommentarId() { return kommentarId; }
public void setKommentarId(UUID kommentarId) { this.kommentarId = kommentarId; }
public UUID getUserId() { return userId; }
public void setUserId(UUID userId) { this.userId = userId; }
public LocalDateTime getLikedAt() { return likedAt; }
public void setLikedAt(LocalDateTime likedAt) { this.likedAt = likedAt; }
}

View File

@@ -1,9 +1,14 @@
package de.oaa.xxx.social.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "message")
public class MessageEntity {
@@ -32,28 +37,4 @@ public class MessageEntity {
@Column(length = 500)
private String targetUrl;
public UUID getMessageId() { return messageId; }
public void setMessageId(UUID messageId) { this.messageId = messageId; }
public UUID getSenderId() { return senderId; }
public void setSenderId(UUID senderId) { this.senderId = senderId; }
public UUID getReceiverId() { return receiverId; }
public void setReceiverId(UUID receiverId) { this.receiverId = receiverId; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
public LocalDateTime getSentAt() { return sentAt; }
public void setSentAt(LocalDateTime sentAt) { this.sentAt = sentAt; }
public LocalDateTime getReadAt() { return readAt; }
public void setReadAt(LocalDateTime readAt) { this.readAt = readAt; }
public boolean isSystemMessage() { return systemMessage; }
public void setSystemMessage(boolean systemMessage) { this.systemMessage = systemMessage; }
public String getTargetUrl() { return targetUrl; }
public void setTargetUrl(String targetUrl) { this.targetUrl = targetUrl; }
}

View File

@@ -1,9 +1,14 @@
package de.oaa.xxx.social.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "pinnwand_eintrag")
public class PinnwandEintragEntity {
@@ -23,19 +28,4 @@ public class PinnwandEintragEntity {
@Column(nullable = false)
private LocalDateTime createdAt;
public UUID getEintragId() { return eintragId; }
public void setEintragId(UUID eintragId) { this.eintragId = eintragId; }
public UUID getProfilUserId() { return profilUserId; }
public void setProfilUserId(UUID profilUserId) { this.profilUserId = profilUserId; }
public UUID getAuthorId() { return authorId; }
public void setAuthorId(UUID authorId) { this.authorId = authorId; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
public LocalDateTime getCreatedAt() { return createdAt; }
public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
}

View File

@@ -1,9 +1,14 @@
package de.oaa.xxx.social.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "pinnwand_like")
public class PinnwandLikeEntity {
@@ -20,16 +25,4 @@ public class PinnwandLikeEntity {
@Column(nullable = false)
private LocalDateTime likedAt;
public UUID getLikeId() { return likeId; }
public void setLikeId(UUID likeId) { this.likeId = likeId; }
public UUID getEintragId() { return eintragId; }
public void setEintragId(UUID eintragId) { this.eintragId = eintragId; }
public UUID getUserId() { return userId; }
public void setUserId(UUID userId) { this.userId = userId; }
public LocalDateTime getLikedAt() { return likedAt; }
public void setLikedAt(LocalDateTime likedAt) { this.likedAt = likedAt; }
}

View File

@@ -1,9 +1,14 @@
package de.oaa.xxx.social.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "profile_image")
public class ProfileImageEntity {
@@ -20,16 +25,4 @@ public class ProfileImageEntity {
@Column(nullable = false)
private LocalDateTime uploadedAt;
public UUID getImageId() { return imageId; }
public void setImageId(UUID imageId) { this.imageId = imageId; }
public UUID getUserId() { return userId; }
public void setUserId(UUID userId) { this.userId = userId; }
public String getImageData() { return imageData; }
public void setImageData(String imageData) { this.imageData = imageData; }
public LocalDateTime getUploadedAt() { return uploadedAt; }
public void setUploadedAt(LocalDateTime uploadedAt) { this.uploadedAt = uploadedAt; }
}

View File

@@ -1,9 +1,14 @@
package de.oaa.xxx.social.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "profile_image_like")
public class ProfileImageLikeEntity {
@@ -20,16 +25,4 @@ public class ProfileImageLikeEntity {
@Column(nullable = false)
private LocalDateTime likedAt;
public UUID getLikeId() { return likeId; }
public void setLikeId(UUID likeId) { this.likeId = likeId; }
public UUID getImageId() { return imageId; }
public void setImageId(UUID imageId) { this.imageId = imageId; }
public UUID getUserId() { return userId; }
public void setUserId(UUID userId) { this.userId = userId; }
public LocalDateTime getLikedAt() { return likedAt; }
public void setLikedAt(LocalDateTime likedAt) { this.likedAt = likedAt; }
}

View File

@@ -1,7 +1,12 @@
package de.oaa.xxx.user;
import lombok.Getter;
import lombok.Setter;
import java.util.UUID;
@Getter
@Setter
public class Registration {
private UUID id;
@@ -9,18 +14,6 @@ public class Registration {
private String email;
private String passwordHash;
public UUID getId() { return id; }
public void setId(UUID id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public String getPasswordHash() { return passwordHash; }
public void setPasswordHash(String passwordHash) { this.passwordHash = passwordHash; }
@Override
public String toString() {
return "Registration [id=" + id + ", name=" + name + ", email=" + email + "]";

View File

@@ -1,7 +1,12 @@
package de.oaa.xxx.user;
import lombok.Getter;
import lombok.Setter;
import java.util.UUID;
@Getter
@Setter
public class User {
private UUID userId;
@@ -17,42 +22,6 @@ public class User {
private Beziehungsstatus beziehungsstatus;
private String beschreibung;
public UUID getUserId() { return userId; }
public void setUserId(UUID userId) { this.userId = userId; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
public String getProfilePicture() { return profilePicture; }
public void setProfilePicture(String profilePicture) { this.profilePicture = profilePicture; }
public Integer getAlter() { return alter; }
public void setAlter(Integer alter) { this.alter = alter; }
public Integer getGroesse() { return groesse; }
public void setGroesse(Integer groesse) { this.groesse = groesse; }
public Integer getGewicht() { return gewicht; }
public void setGewicht(Integer gewicht) { this.gewicht = gewicht; }
public Geschlecht getGeschlecht() { return geschlecht; }
public void setGeschlecht(Geschlecht geschlecht) { this.geschlecht = geschlecht; }
public Neigung getNeigung() { return neigung; }
public void setNeigung(Neigung neigung) { this.neigung = neigung; }
public Beziehungsstatus getBeziehungsstatus() { return beziehungsstatus; }
public void setBeziehungsstatus(Beziehungsstatus beziehungsstatus) { this.beziehungsstatus = beziehungsstatus; }
public String getBeschreibung() { return beschreibung; }
public void setBeschreibung(String beschreibung) { this.beschreibung = beschreibung; }
@Override
public String toString() {
return "User[userId=" + userId + ", name=" + name + ", email=" + email + "]";

View File

@@ -1,9 +1,13 @@
package de.oaa.xxx.user;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "user")
public class UserEntity {
@@ -48,44 +52,11 @@ public class UserEntity {
@Column(columnDefinition = "TEXT")
private String beschreibung;
public UUID getUserId() { return userId; }
public void setUserId(UUID userId) { this.userId = userId; }
@Column(nullable = false, columnDefinition = "INT DEFAULT 0")
private int lockeeXp;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
public String getProfilePicture() { return profilePicture; }
public void setProfilePicture(String profilePicture) { this.profilePicture = profilePicture; }
public String getProfilePictureHq() { return profilePictureHq; }
public void setProfilePictureHq(String profilePictureHq) { this.profilePictureHq = profilePictureHq; }
public Integer getAlter() { return alter; }
public void setAlter(Integer alter) { this.alter = alter; }
public Integer getGroesse() { return groesse; }
public void setGroesse(Integer groesse) { this.groesse = groesse; }
public Integer getGewicht() { return gewicht; }
public void setGewicht(Integer gewicht) { this.gewicht = gewicht; }
public Geschlecht getGeschlecht() { return geschlecht; }
public void setGeschlecht(Geschlecht geschlecht) { this.geschlecht = geschlecht; }
public Neigung getNeigung() { return neigung; }
public void setNeigung(Neigung neigung) { this.neigung = neigung; }
public Beziehungsstatus getBeziehungsstatus() { return beziehungsstatus; }
public void setBeziehungsstatus(Beziehungsstatus beziehungsstatus) { this.beziehungsstatus = beziehungsstatus; }
public String getBeschreibung() { return beschreibung; }
public void setBeschreibung(String beschreibung) { this.beschreibung = beschreibung; }
@Column(nullable = false, columnDefinition = "INT DEFAULT 0")
private int keyholderXp;
@Override
public String toString() {

View File

@@ -1,7 +1,8 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta charset="UTF-8">
<link rel="icon" href="/img/icon.png" type="image/png">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>XXX The Game Aktivierung</title>
<link rel="stylesheet" href="/css/variables.css">

View File

@@ -2,6 +2,7 @@
<html lang="de">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/img/icon.png" type="image/png">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Chastity Game XXX The Game</title>
<link rel="stylesheet" href="/css/variables.css">
@@ -825,9 +826,11 @@
document.getElementById('drawnCardImg').alt = def.name;
inner.classList.add('flipped');
setTimeout(() => {
const khName = _currentLock && _currentLock.keyholderName ? _currentLock.keyholderName : 'Deine Keyholderin';
const khName = _currentLock && _currentLock.keyholderName ? _currentLock.keyholderName : null;
document.getElementById('drawCardName').textContent = def.name;
document.getElementById('drawCardDesc').textContent = `🔑 ${khName} hat das Lock freigegeben.`;
document.getElementById('drawCardDesc').textContent = khName
? `🔑 ${khName} hat das Lock freigegeben.`
: '🔓 Das Lock wird freigegeben.';
document.getElementById('drawGreenText').style.display = 'none';
info.classList.add('visible');
actions.style.display = '';
@@ -846,9 +849,11 @@
if (lock.testLock) {
area.innerHTML = `<button class="btn-lock-beenden" onclick="lockBeendenFragen()">🔓 Lock beenden</button>`;
} else if (lock.emergencyUnlockRequested) {
const khName = lock.keyholderName || 'Deine Keyholderin';
const emergencyMsg = lock.keyholderName
? `⏳ Notfall-Entsperrung angefordert ${lock.keyholderName} wurde benachrichtigt.`
: `⏳ Notfall-Entsperrung angefordert Das Lock öffnet sich automatisch.`;
area.innerHTML = `<div style="font-size:0.85rem;color:var(--color-muted);padding:0.5rem 0.75rem;border:1px solid rgba(231,76,60,0.3);border-radius:8px;background:rgba(231,76,60,0.06);">
⏳ Notfall-Entsperrung angefordert ${khName} wurde benachrichtigt.
${emergencyMsg}
</div>`;
} else {
area.innerHTML = `<button onclick="openEmergencyModal()"
@@ -859,13 +864,16 @@
}
function openEmergencyModal() {
const khName = _currentLock && _currentLock.keyholderName ? _currentLock.keyholderName : 'Deine Keyholderin';
const hasKH = _currentLock && _currentLock.keyholderName;
const khName = hasKH ? _currentLock.keyholderName : null;
const text = hasKH
? `Im Notfall kannst du eine sofortige Freigabe anfordern.<br>
<strong style="color:var(--color-text);">${khName}</strong> wird benachrichtigt und hat <strong>1 Stunde</strong> Zeit zu reagieren.
Reagiert ${khName} nicht, öffnet sich das Lock automatisch.`
: `Im Notfall kannst du eine sofortige Freigabe anfordern.<br>
Da kein Keyholder zugewiesen ist, öffnet sich das Lock <strong>sofort</strong>.`;
document.getElementById('emergencyModalContent').innerHTML = `
<p style="font-size:0.88rem;color:var(--color-muted);line-height:1.5;margin:0 0 0.5rem;">
Im Notfall kannst du eine sofortige Freigabe anfordern.<br>
<strong style="color:var(--color-text);">${khName}</strong> wird benachrichtigt und hat <strong>1 Stunde</strong> Zeit zu reagieren.
Reagiert ${khName} nicht, öffnet sich das Lock automatisch.
</p>`;
<p style="font-size:0.88rem;color:var(--color-muted);line-height:1.5;margin:0 0 0.5rem;">${text}</p>`;
document.getElementById('emergencyModalActions').style.display = '';
document.getElementById('emergencyModal').classList.add('open');
}
@@ -879,10 +887,13 @@
try {
const res = await fetch('/keyholder/cardlock/' + lockId + '/emergency-unlock', { method: 'POST' });
if (res.ok || res.status === 204) {
const khName2 = _currentLock && _currentLock.keyholderName ? _currentLock.keyholderName : 'Deine Keyholderin';
const hasKH2 = _currentLock && _currentLock.keyholderName;
const successText = hasKH2
? `✅ Notfall-Anfrage wurde gesendet. ${_currentLock.keyholderName} wurde benachrichtigt.`
: `✅ Notfall-Freigabe wurde ausgelöst. Das Lock öffnet sich jetzt.`;
document.getElementById('emergencyModalContent').innerHTML = `
<p style="font-size:0.88rem;color:#2ecc71;line-height:1.5;margin:0;">
✅ Notfall-Anfrage wurde gesendet. ${khName2} wurde benachrichtigt.
${successText}
</p>`;
setTimeout(() => { closeEmergencyModal(); loadLock(); }, 2000);
}
@@ -1126,8 +1137,10 @@
if (lock.openPicks > 0) {
overlay.style.display = 'none';
panel.classList.add('drawable');
enableCardClick();
if (!lock.keyholderRequestedUnlock) {
panel.classList.add('drawable');
enableCardClick();
}
return;
}
@@ -1141,8 +1154,10 @@
const diff = target - Date.now();
if (diff <= 0) {
overlay.style.display = 'none';
panel.classList.add('drawable');
enableCardClick();
if (!lock.keyholderRequestedUnlock) {
panel.classList.add('drawable');
enableCardClick();
}
clearInterval(tickInterval); tickInterval = null;
return;
}

View File

@@ -1,7 +1,8 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta charset="UTF-8">
<link rel="icon" href="/img/icon.png" type="image/png">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Aufgaben XXX The Game</title>
<link rel="stylesheet" href="/css/variables.css">

View File

@@ -1,7 +1,8 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta charset="UTF-8">
<link rel="icon" href="/img/icon.png" type="image/png">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Benachrichtigungen XXX The Game</title>
<link rel="stylesheet" href="/css/variables.css">

View File

@@ -2,6 +2,7 @@
<html lang="de">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/img/icon.png" type="image/png">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Profil XXX The Game</title>
<link rel="stylesheet" href="/css/variables.css">
@@ -405,10 +406,11 @@
</div>
</div>
<!-- Tabs: Feed | Pinnwand -->
<!-- Tabs: Feed | Pinnwand | Lock-Historie -->
<div class="profil-tabs" style="margin-top:1.25rem;">
<button class="profil-tab-btn active" id="tabBtnPosts" onclick="switchProfilTab('posts', this)">Feed</button>
<button class="profil-tab-btn" id="tabBtnPinnwand" onclick="switchProfilTab('pinnwand', this)">Pinnwand</button>
<button class="profil-tab-btn" id="tabBtnLockHistory" onclick="switchProfilTab('lockhistory', this); loadLockHistory()">Lock-Historie</button>
</div>
<!-- Feed Tab (vorausgewählt) -->
@@ -427,6 +429,12 @@
<div id="pinnwandList"></div>
</div>
<!-- Lock-Historie Tab -->
<div class="profil-tab-panel" id="tab-lockhistory">
<div id="lockHistoryList" style="margin-top:0.75rem;"></div>
<p id="lockHistoryEmpty" style="color:var(--color-muted);font-size:0.9rem;display:none;">Keine abgeschlossenen Locks vorhanden.</p>
</div>
</div>
</div>
</div>
@@ -566,6 +574,8 @@
if (profile.geschlecht) addTag('Geschlecht', GESCHLECHT_LABEL[profile.geschlecht] || profile.geschlecht);
if (profile.neigung) addTag('Neigung', NEIGUNG_LABEL[profile.neigung] || profile.neigung);
if (profile.beziehungsstatus) addTag('Beziehung', BEZIEHUNG_LABEL[profile.beziehungsstatus] || profile.beziehungsstatus);
if (profile.lockeeXp > 0) addTag('🔒 Lockee XP', profile.lockeeXp + ' XP');
if (profile.keyholderXp > 0) addTag('🔑 Keyholder XP', profile.keyholderXp + ' XP');
// Action buttons
const actions = document.getElementById('profileActions');
@@ -767,6 +777,52 @@
</div>`;
}
// ── Lock-Historie ──
let lockHistoryLoaded = false;
async function loadLockHistory() {
if (lockHistoryLoaded) return;
lockHistoryLoaded = true;
const list = document.getElementById('lockHistoryList');
const empty = document.getElementById('lockHistoryEmpty');
list.innerHTML = '<p style="color:var(--color-muted);font-size:0.85rem;">Lädt…</p>';
try {
const res = await fetch('/lockhistory?userId=' + targetUserId);
if (!res.ok) { list.innerHTML = ''; return; }
const entries = await res.json();
list.innerHTML = '';
if (entries.length === 0) { empty.style.display = ''; return; }
list.innerHTML = entries.map(e => {
const icon = e.role === 'KEYHOLDER' ? '🔑' : '🔒';
const partner = e.role === 'KEYHOLDER'
? (e.lockeeName ? `<span style="color:var(--color-muted);font-size:0.78rem;">Lockee: ${esc(e.lockeeName)}</span>` : '')
: (e.keyholderName ? `<span style="color:var(--color-muted);font-size:0.78rem;">Keyholder: ${esc(e.keyholderName)}</span>` : '<span style="color:var(--color-muted);font-size:0.78rem;">Self-Lock</span>');
const days = Math.floor(e.durationMinutes / 1440);
const hours = Math.floor((e.durationMinutes % 1440) / 60);
const mins = e.durationMinutes % 60;
const dur = days > 0
? `${days}d ${hours}h ${mins}min`
: hours > 0 ? `${hours}h ${mins}min` : `${mins}min`;
const avatar = e.partnerPic
? `<img src="data:image/jpeg;base64,${e.partnerPic}" style="width:40px;height:40px;border-radius:50%;object-fit:cover;display:block;">`
: `<div style="width:40px;height:40px;border-radius:50%;background:var(--color-secondary);display:flex;align-items:center;justify-content:center;font-size:1.1rem;">👤</div>`;
return `<div style="display:flex;align-items:center;gap:0.75rem;padding:0.65rem 0;border-bottom:1px solid var(--color-secondary);">
<div style="position:relative;width:40px;height:40px;flex-shrink:0;">
${avatar}
<span style="position:absolute;top:-3px;left:-3px;font-size:1.4rem;line-height:1;">${icon}</span>
</div>
<div style="flex:1;min-width:0;">
<div style="font-weight:600;font-size:0.92rem;">${esc(e.lockName) || 'Unbenanntes Lock'}</div>
<div style="display:flex;gap:1rem;flex-wrap:wrap;margin-top:0.15rem;">
${partner}
<span style="color:var(--color-muted);font-size:0.78rem;">⏱ ${dur}</span>
<span style="color:var(--color-muted);font-size:0.78rem;">${fmtDate(e.unlockTime)}</span>
</div>
</div>
</div>`;
}).join('');
} catch(e) { list.innerHTML = ''; }
}
async function postPinnwand() {
const ta = document.getElementById('pinnwandText');
const text = ta.value.trim();

View File

@@ -2,6 +2,7 @@
<html lang="de">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/img/icon.png" type="image/png">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Community Votes XXX The Game</title>
<link rel="stylesheet" href="/css/variables.css">
@@ -18,21 +19,21 @@
margin-bottom: 1.5rem;
}
.vote-grid {
/* ── Unified feed ── */
#feed {
display: flex;
flex-direction: column;
gap: 1rem;
}
/* ── Verifikations-Karte ── */
.vote-card {
background: var(--color-card);
border: 1px solid var(--color-secondary);
border-radius: 10px;
overflow: hidden;
}
.vote-card-media {
position: relative;
}
.vote-card-media { position: relative; }
.vote-card-img {
width: 100%;
max-height: 420px;
@@ -64,15 +65,8 @@
gap: 1rem;
flex-wrap: wrap;
}
.vote-meta {
font-size: 0.8rem;
color: var(--color-muted);
}
.vote-actions {
display: flex;
align-items: center;
gap: 0.75rem;
}
.vote-meta { font-size: 0.8rem; color: var(--color-muted); }
.vote-actions { display: flex; align-items: center; gap: 0.75rem; }
.vote-btn {
display: flex;
align-items: center;
@@ -93,63 +87,29 @@
color: var(--color-primary);
background: none;
}
.vote-btn.voted-up {
border-color: #2ecc71;
color: #2ecc71;
background: rgba(46,204,113,0.08);
}
.vote-btn.voted-down {
border-color: #e74c3c;
color: #e74c3c;
background: rgba(231,76,60,0.08);
}
.vote-btn:disabled {
opacity: 0.55;
cursor: not-allowed;
pointer-events: none;
}
.vote-count {
font-weight: 600;
font-size: 0.88rem;
}
.vote-btn.voted-up { border-color: #2ecc71; color: #2ecc71; background: rgba(46,204,113,0.08); }
.vote-btn.voted-down { border-color: #e74c3c; color: #e74c3c; background: rgba(231,76,60,0.08); }
.vote-btn:disabled { opacity: 0.55; cursor: not-allowed; pointer-events: none; }
.vote-count { font-weight: 600; font-size: 0.88rem; }
/* Task Vote Section */
.task-vote-section {
margin-bottom: 2rem;
}
.task-vote-section-title {
font-size: 1rem;
font-weight: 700;
margin-bottom: 0.75rem;
color: var(--color-primary);
}
/* ── Aufgaben-Abstimmungs-Karte ── */
.task-vote-card {
background: var(--color-card);
border: 1px solid rgba(52,152,219,0.35);
border-radius: 10px;
padding: 0.85rem 1rem;
margin-bottom: 0.75rem;
}
.task-vote-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 0.5rem;
flex-wrap: wrap;
gap: 0.4rem;
}
.task-vote-lockee {
font-weight: 600;
font-size: 0.92rem;
}
.task-vote-expires {
font-size: 0.78rem;
color: var(--color-muted);
}
.task-vote-options {
display: flex;
flex-direction: column;
gap: 0.35rem;
margin-top: 0.5rem;
}
.task-vote-lockee { font-weight: 600; font-size: 0.92rem; }
.task-vote-expires { font-size: 0.78rem; color: var(--color-muted); }
.task-vote-options { display: flex; flex-direction: column; gap: 0.35rem; margin-top: 0.5rem; }
.task-vote-btn {
display: flex;
justify-content: space-between;
@@ -174,9 +134,7 @@
border-color: var(--color-primary);
background: rgba(52,152,219,0.18);
}
.task-vote-btn:disabled {
cursor: default;
}
.task-vote-btn:disabled { cursor: default; }
.task-vote-count {
font-size: 0.78rem;
color: var(--color-muted);
@@ -184,6 +142,13 @@
margin-left: 0.5rem;
flex-shrink: 0;
}
.task-vote-own-hint {
font-size: 0.78rem;
color: var(--color-muted);
font-style: italic;
margin-top: 0.4rem;
text-align: center;
}
.empty-hint {
color: var(--color-muted);
@@ -207,18 +172,9 @@
<div class="page-title">Community Votes</div>
<div class="page-subtitle">Verifikationen &amp; Aufgaben-Abstimmungen</div>
<!-- Aktive Aufgaben-Abstimmungen -->
<div class="task-vote-section" id="taskVoteSection" style="display:none;">
<div class="task-vote-section-title">🃏 Aufgaben-Abstimmungen</div>
<div id="taskVoteList"></div>
</div>
<div class="page-title" style="font-size:1rem;margin-bottom:0.25rem;">Verifikationen</div>
<div class="page-subtitle" style="margin-bottom:0.75rem;">Stimme ab, ob die Verifikation gültig ist</div>
<div class="vote-grid" id="voteGrid"></div>
<div id="feed"></div>
<div class="load-spinner" id="loadSpinner" style="display:none;">Lädt…</div>
<div class="empty-hint" id="emptyHint" style="display:none;">Heute gibt es noch keine Verifikationen ohne Keyholder.</div>
<div class="empty-hint" id="emptyHint" style="display:none;">Noch keine Community-Abstimmungen vorhanden.</div>
<div class="sentinel" id="sentinel"></div>
</div>
@@ -227,8 +183,6 @@
<script src="/js/sidebar.js"></script>
<script src="/js/social-sidebar.js"></script>
<script>
// ── Aufgaben-Abstimmungen ──────────────────────────────────────────────────
function esc(s) {
return String(s || '').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
}
@@ -237,64 +191,59 @@
return new Date(isoStr).toLocaleString('de-DE', {day:'2-digit',month:'2-digit',year:'numeric',hour:'2-digit',minute:'2-digit'});
}
async function loadTaskVotes() {
try {
const res = await fetch('/task-card/community/votes');
if (!res.ok) return;
const votes = await res.json();
const section = document.getElementById('taskVoteSection');
const list = document.getElementById('taskVoteList');
list.innerHTML = '';
if (votes.length === 0) {
section.style.display = 'none';
return;
}
section.style.display = '';
votes.forEach(vote => {
const card = document.createElement('div');
card.className = 'task-vote-card';
card.dataset.voteSessionId = vote.voteSessionId;
// ── Task vote card builder ─────────────────────────────────────────────────
let optionsHtml = '';
(vote.tasks || []).forEach((t, i) => {
const count = (vote.voteCounts || [])[i] || 0;
const isMyVote = vote.myVote === i;
const alreadyVoted = vote.myVote !== null && vote.myVote !== undefined;
const desc = t.description ? `<div style="font-size:0.75rem;color:var(--color-muted);margin-top:0.1rem;">${esc(t.description)}</div>` : '';
const mins = t.minutes > 0 ? ` <span style="font-size:0.75rem;color:var(--color-muted);">⏱ ${t.minutes} Min.</span>` : '';
optionsHtml += `<button class="task-vote-btn ${isMyVote ? 'my-vote' : ''}"
id="tvbtn-${vote.voteSessionId}-${i}"
${alreadyVoted ? 'disabled' : ''}
onclick="castTaskVote('${vote.voteSessionId}', ${i})">
<div style="flex:1;min-width:0;">
<div style="font-weight:600;">${esc(t.title)}${mins}</div>
${desc}
</div>
<span class="task-vote-count" id="tvcount-${vote.voteSessionId}-${i}">${count} Stimme${count !== 1 ? 'n' : ''}</span>
</button>`;
});
function buildTaskVoteCard(vote) {
const isOwn = vote.isOwnLock;
const alreadyVoted = vote.myVote !== null && vote.myVote !== undefined;
card.innerHTML = `
<div class="task-vote-header">
<span class="task-vote-lockee">🔒 ${esc(vote.lockeeName)}</span>
<span class="task-vote-expires">Endet: ${fmtDateTime(vote.expiresAt)}</span>
</div>
<div class="task-vote-options">${optionsHtml}</div>`;
list.appendChild(card);
});
} catch(e) { console.error(e); }
let optionsHtml = '';
(vote.tasks || []).forEach((t, i) => {
const count = (vote.voteCounts || [])[i] || 0;
const isMyVote = vote.myVote === i;
const desc = t.description
? `<div style="font-size:0.75rem;color:var(--color-muted);margin-top:0.1rem;">${esc(t.description)}</div>`
: '';
const mins = t.minutes > 0
? ` <span style="font-size:0.75rem;color:var(--color-muted);">⏱ ${t.minutes} Min.</span>`
: '';
optionsHtml += `<button class="task-vote-btn ${isMyVote ? 'my-vote' : ''}"
id="tvbtn-${vote.voteSessionId}-${i}"
${(alreadyVoted || isOwn) ? 'disabled' : ''}
onclick="castTaskVote('${vote.voteSessionId}', ${i})">
<div style="flex:1;min-width:0;">
<div style="font-weight:600;">${esc(t.title)}${mins}</div>
${desc}
</div>
<span class="task-vote-count" id="tvcount-${vote.voteSessionId}-${i}">${count} Stimme${count !== 1 ? 'n' : ''}</span>
</button>`;
});
const ownHint = isOwn
? `<div class="task-vote-own-hint">Das ist dein eigenes Lock du kannst hier nicht abstimmen.</div>`
: '';
const card = document.createElement('div');
card.className = 'task-vote-card';
card.dataset.ts = vote.createdAt;
card.innerHTML = `
<div class="task-vote-header">
<span class="task-vote-lockee">🃏 ${esc(vote.lockeeName)}</span>
<span class="task-vote-expires">Endet: ${fmtDateTime(vote.expiresAt)}</span>
</div>
<div class="task-vote-options">${optionsHtml}</div>
${ownHint}`;
return card;
}
async function castTaskVote(voteSessionId, taskIndex) {
// Disable all buttons for this vote immediately
document.querySelectorAll(`[id^="tvbtn-${voteSessionId}-"]`).forEach(btn => btn.disabled = true);
const res = await fetch(`/task-card/community/votes/${voteSessionId}/vote/${taskIndex}`, { method: 'POST' });
if (res.ok || res.status === 204) {
const countEl = document.getElementById(`tvcount-${voteSessionId}-${taskIndex}`);
if (countEl) {
const current = parseInt(countEl.textContent) || 0;
const next = current + 1;
const next = (parseInt(countEl.textContent) || 0) + 1;
countEl.textContent = `${next} Stimme${next !== 1 ? 'n' : ''}`;
}
const btn = document.getElementById(`tvbtn-${voteSessionId}-${taskIndex}`);
@@ -302,43 +251,33 @@
}
}
// ── Verifikations-Votes ───────────────────────────────────────────────────
// ── Verification card builder ──────────────────────────────────────────────
let page = 0;
let loading = false;
let exhausted = false;
function fmtTime(isoStr) {
const d = new Date(isoStr);
return d.toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit' });
}
function buildCard(item) {
const isOwn = item.myVote === 'own';
const voted = isOwn || (item.myVote !== null && item.myVote !== undefined);
const votedUp = !isOwn && item.myVote === true;
const votedDn = !isOwn && item.myVote === false;
function buildVerCard(item) {
const isOwn = item.myVote === 'own';
const voted = isOwn || (item.myVote !== null && item.myVote !== undefined);
const votedUp = !isOwn && item.myVote === true;
const votedDn = !isOwn && item.myVote === false;
const card = document.createElement('div');
card.className = 'vote-card';
card.dataset.id = item.verificationId;
card.dataset.ts = item.verificationTime;
card.innerHTML = `
<div class="vote-card-media">
<img class="vote-card-img" src="data:image/jpeg;base64,${item.image}" alt="Verifikationsbild">
<div class="vote-card-code">${item.code}</div>
<div class="vote-card-code">${esc(item.code)}</div>
</div>
<div class="vote-card-body">
<div class="vote-meta">Erstellt um ${fmtTime(item.verificationTime)}</div>
<div class="vote-meta">Verifikation · ${fmtDateTime(item.verificationTime)}</div>
<div class="vote-actions">
<button class="vote-btn ${votedUp ? 'voted-up' : ''}" id="up-${item.verificationId}"
${voted ? 'disabled' : ''}
onclick="castVote('${item.verificationId}', true)">
onclick="castVerVote('${item.verificationId}', true)">
👍 <span class="vote-count" id="upcount-${item.verificationId}">${item.upvotes}</span>
</button>
<button class="vote-btn ${votedDn ? 'voted-down' : ''}" id="dn-${item.verificationId}"
${voted ? 'disabled' : ''}
onclick="castVote('${item.verificationId}', false)">
onclick="castVerVote('${item.verificationId}', false)">
👎 <span class="vote-count" id="dncount-${item.verificationId}">${item.downvotes}</span>
</button>
</div>
@@ -346,35 +285,7 @@
return card;
}
async function loadPage() {
if (loading || exhausted) return;
loading = true;
document.getElementById('loadSpinner').style.display = '';
const res = await fetch('/verification/community?page=' + page);
document.getElementById('loadSpinner').style.display = 'none';
loading = false;
if (!res.ok) return;
const items = await res.json();
const grid = document.getElementById('voteGrid');
if (items.length === 0 && page === 0) {
document.getElementById('emptyHint').style.display = '';
exhausted = true;
return;
}
items.forEach(item => grid.appendChild(buildCard(item)));
if (items.length < 10 || (items.length > 0 && !items[items.length - 1].hasMore)) {
exhausted = true;
} else {
page++;
}
}
async function castVote(verificationId, upvote) {
async function castVerVote(verificationId, upvote) {
const upBtn = document.getElementById('up-' + verificationId);
const dnBtn = document.getElementById('dn-' + verificationId);
upBtn.disabled = true;
@@ -385,24 +296,120 @@
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ upvote })
});
if (res.ok || res.status === 202) {
const countEl = document.getElementById(upvote ? 'upcount-' + verificationId : 'dncount-' + verificationId);
countEl.textContent = parseInt(countEl.textContent) + 1;
(upvote ? upBtn : dnBtn).classList.add(upvote ? 'voted-up' : 'voted-down');
} else {
// Doppelter Vote oder Fehler Buttons trotzdem disabled lassen
}
}
// Infinite Scroll via IntersectionObserver
// ── Unified feed ──────────────────────────────────────────────────────────
// Strategy: task votes are loaded once (small set); verifications are paginated.
// When each verification page loads, we interleave the pending task votes that
// belong chronologically before the oldest verification on this page.
let verPage = 0;
let verExhausted = false;
let loading = false;
// Task votes sorted newest-first; items are removed as they get placed in feed
let pendingTaskVotes = [];
let taskVotesLoaded = false;
let totalRendered = 0;
function getTs(isoStr) { return new Date(isoStr).getTime(); }
// Append cards to feed in the correct order.
// `items` must already be sorted newest-first.
function appendItems(items) {
const feed = document.getElementById('feed');
items.forEach(card => feed.appendChild(card));
totalRendered += items.length;
}
// Merge verItems (sorted newest-first) with the front of pendingTaskVotes
// (also sorted newest-first). Only consume task votes that are >= cutoffMs
// so that older task votes wait for later verification pages.
// Pass cutoffMs = -Infinity to flush all remaining task votes.
function mergeWithTaskVotes(verItems, cutoffMs) {
const result = [];
let vIdx = 0;
while (vIdx < verItems.length || (pendingTaskVotes.length > 0 && getTs(pendingTaskVotes[0].createdAt) >= cutoffMs)) {
const verTs = vIdx < verItems.length ? getTs(verItems[vIdx].verificationTime) : -Infinity;
const tvTs = pendingTaskVotes.length > 0 && getTs(pendingTaskVotes[0].createdAt) >= cutoffMs
? getTs(pendingTaskVotes[0].createdAt)
: -Infinity;
if (tvTs >= verTs) {
result.push(buildTaskVoteCard(pendingTaskVotes.shift()));
} else if (vIdx < verItems.length) {
result.push(buildVerCard(verItems[vIdx++]));
} else {
break;
}
}
// Remaining verifications (task votes exhausted or below cutoff)
while (vIdx < verItems.length) {
result.push(buildVerCard(verItems[vIdx++]));
}
return result;
}
async function loadMore() {
if (loading || verExhausted) return;
loading = true;
document.getElementById('loadSpinner').style.display = '';
// Load task votes on first call
if (!taskVotesLoaded) {
try {
const r = await fetch('/task-card/community/votes');
if (r.ok) {
const votes = await r.json();
pendingTaskVotes = votes.sort((a, b) => getTs(b.createdAt) - getTs(a.createdAt));
}
} catch(e) {}
taskVotesLoaded = true;
}
let verItems = [];
try {
const r = await fetch('/verification/community?page=' + verPage);
if (r.ok) verItems = await r.json();
} catch(e) {}
document.getElementById('loadSpinner').style.display = 'none';
loading = false;
let batch;
if (verItems.length === 0) {
verExhausted = true;
batch = mergeWithTaskVotes([], -Infinity);
} else {
const oldestVerTs = getTs(verItems[verItems.length - 1].verificationTime);
if (verItems.length < 10) {
verExhausted = true;
// Last page: flush all remaining task votes too
batch = mergeWithTaskVotes(verItems, -Infinity);
} else {
verPage++;
// Only include task votes newer than the oldest item in this page
batch = mergeWithTaskVotes(verItems, oldestVerTs);
}
}
if (batch.length > 0) appendItems(batch);
if (totalRendered === 0 && verExhausted) {
document.getElementById('emptyHint').style.display = '';
}
}
const observer = new IntersectionObserver(entries => {
if (entries[0].isIntersecting) loadPage();
if (entries[0].isIntersecting) loadMore();
}, { rootMargin: '200px' });
observer.observe(document.getElementById('sentinel'));
loadTaskVotes();
loadPage();
loadMore();
</script>
</body>
</html>

View File

@@ -197,23 +197,54 @@ body.app {
transition: transform 0.25s ease;
}
.sidebar-icon-area {
display: flex;
justify-content: center;
padding: 1.25rem 1.25rem 0.75rem;
.sidebar-logo-area {
padding: 1rem 1rem 0.5rem;
flex-shrink: 0;
}
.sidebar-icon-area a { display: block; line-height: 0; }
.sidebar-logo-area a { display: block; line-height: 0; }
.sidebar-icon-area img {
width: 64px;
height: 64px;
.sidebar-logo-area img {
width: 100%;
height: auto;
object-fit: contain;
transition: transform 0.2s;
display: block;
}
.sidebar-icon-area img:hover { transform: scale(1.1); }
.sidebar-desktop-profile { flex-shrink: 0; padding: 0.25rem 0; }
.sidebar-desktop-profile a {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 0.55rem 1.25rem;
color: var(--color-text);
text-decoration: none;
font-size: 0.9rem;
font-weight: 600;
border-left: 3px solid transparent;
transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.sidebar-desktop-profile a:hover {
background: var(--color-secondary);
color: var(--color-primary);
border-left-color: var(--color-primary);
}
.sidebar-desktop-profile .icon { font-size: 1rem; width: 1.2rem; text-align: center; flex-shrink: 0; }
.social-sidebar-logo-area {
padding: 1rem 1rem 0.5rem;
flex-shrink: 0;
}
.social-sidebar-logo-area img {
width: 100%;
height: auto;
object-fit: contain;
display: block;
}
.sidebar-mobile-only { display: none; }
@@ -316,7 +347,8 @@ body.app {
}
.sidebar.open { transform: translateX(0); box-shadow: -4px 0 20px rgba(0, 0, 0, 0.5); }
.sidebar-icon-area { display: none; }
.sidebar-logo-area { display: none; }
.sidebar-desktop-profile { display: none; }
.main {
border-radius: 0;
@@ -346,7 +378,7 @@ body.app {
overflow-y: auto;
}
.social-sidebar ul { list-style: none; padding: 0.5rem 0; }
.social-sidebar ul { list-style: none; padding: 0.5rem 0; display: flex; flex-direction: column; flex: 1; }
.social-sidebar ul li a {
display: flex;

View File

@@ -2,6 +2,7 @@
<html lang="de">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/img/icon.png" type="image/png">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Einladungen XXX The Game</title>
<link rel="stylesheet" href="/css/variables.css">

View File

@@ -1,7 +1,8 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta charset="UTF-8">
<link rel="icon" href="/img/icon.png" type="image/png">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Entdecken XXX The Game</title>
<link rel="stylesheet" href="/css/variables.css">

View File

@@ -1,7 +1,8 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta charset="UTF-8">
<link rel="icon" href="/img/icon.png" type="image/png">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Feed XXX The Game</title>
<link rel="stylesheet" href="/css/variables.css">

View File

@@ -1,7 +1,8 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta charset="UTF-8">
<link rel="icon" href="/img/icon.png" type="image/png">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>xXx Games Passwort vergessen</title>
<link rel="stylesheet" href="/css/variables.css">

View File

@@ -1,7 +1,8 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta charset="UTF-8">
<link rel="icon" href="/img/icon.png" type="image/png">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Freunde XXX The Game</title>
<link rel="stylesheet" href="/css/variables.css">

View File

@@ -1,7 +1,8 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta charset="UTF-8">
<link rel="icon" href="/img/icon.png" type="image/png">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Gruppe XXX The Game</title>
<link rel="stylesheet" href="/css/variables.css">

Some files were not shown because too many files have changed in this diff Show More