Bugfixes, Dating angefangen
Some checks failed
Host-Based Deploy (Java 21 Fix) / build-and-run (push) Has been cancelled

This commit is contained in:
2026-04-01 22:06:46 +02:00
parent 912718fc40
commit 87c85b1b17
123 changed files with 28977 additions and 462 deletions

View File

@@ -0,0 +1,66 @@
name: Host-Based Deploy (Java 21 Fix)
on:
push:
branches:
- master
jobs:
build-and-run:
# WICHTIG: Hier nutzen wir das neue Host-Label
runs-on: pve-host
steps:
- name: Checkout Code
run: |
# Debug: Wer ist git.langhei.de?
cat /etc/hosts
ping -c 1 git.langhei.de || echo "Ping failed"
# Sicherstellen, dass wir im richtigen Verzeichnis sind
rm -rf ./* || true
# Versuch über die Domain
git clone http://git.langhei.de/Entwicklung/xxx-sphere-web.git . || \
# FALLBACK: Versuch über die IP direkt, falls DNS im Container hakt
git clone http://192.168.178.93:3000/Entwicklung/xxx-sphere-web.git .
git config --global http.sslVerify false
git checkout master
- name: Build and Deploy (LXC-Safe)
run: |
# 1. Java 21 im Runner-Container installieren
if command -v apt-get >/dev/null; then
apt-get update && apt-get install -y openjdk-21-jdk-headless
elif command -v apk >/dev/null; then
apk add --no-cache openjdk21
fi
# 2. JAVA_HOME setzen
export JAVA_HOME=$(java -XshowSettings:properties -version 2>&1 > /dev/null | grep 'java.home' | awk '{print $3}')
export PATH=$JAVA_HOME/bin:$PATH
# 3. Das JAR-File bauen (Hier brauchen wir noch kein Docker!)
chmod +x gradlew
./gradlew bootJar
# 4. Docker-Socket Berechtigung (für den finalen Build)
chmod 666 /var/run/docker.sock
# 5. Das Image klassisch bauen
# Wir suchen das gebaute JAR und bauen das Image
docker build -t xxx-sphere-web:latest .
# 6. Container starten
# Wir nutzen 'docker-compose' (mit Bindestrich) oder den Standard-Docker-Befehl
if command -v docker-compose >/dev/null; then
docker-compose up -d --force-recreate
else
# Fallback, falls compose fehlt: Alten Container stoppen und neu starten
docker stop xxx-sphere-web || true
docker rm xxx-sphere-web || true
docker run -d --name xxx-sphere-web -p 8080:8080 xxx-sphere-web:latest
fi
- name: Deploy Container
run: |
docker compose up -d --force-recreate

Binary file not shown.

View File

@@ -0,0 +1,218 @@
-- Vorlieben: Kategorien und Items
-- Generiert aus vorlieben_konsolidiert.txt
BEGIN;
-- Kategorien
INSERT INTO vorliebe_kategorie (kategorie_id, name, sort_order) VALUES ('9aff21d1-dc49-48cc-b184-6b034ffc7308', 'Sex & Erotik', 0);
INSERT INTO vorliebe_kategorie (kategorie_id, name, sort_order) VALUES ('88a92d51-33b4-4dad-88a8-5b4f8a0a898a', 'BDSM & Bondage', 10);
INSERT INTO vorliebe_kategorie (kategorie_id, name, sort_order) VALUES ('10ad63de-2ff7-4364-b0d2-9df22bfc200a', 'Rollenspiele & Fantasien', 20);
INSERT INTO vorliebe_kategorie (kategorie_id, name, sort_order) VALUES ('fbfeeabd-31e3-44ee-873a-24d2540c4a0b', 'Körper & Fetische', 30);
INSERT INTO vorliebe_kategorie (kategorie_id, name, sort_order) VALUES ('b45bc99f-6e9e-4a81-af7d-ab858e316b85', 'Fetisch-Kleidung', 40);
INSERT INTO vorliebe_kategorie (kategorie_id, name, sort_order) VALUES ('c2f597bc-ab4c-4819-8eb8-98d324f6dff0', 'Sexspielzeug & Equipment', 50);
INSERT INTO vorliebe_kategorie (kategorie_id, name, sort_order) VALUES ('147066c6-f5be-412f-8516-64e1dffd2389', 'Lifestyle & Beziehungsformen', 60);
INSERT INTO vorliebe_kategorie (kategorie_id, name, sort_order) VALUES ('7879146a-352a-408c-9405-ebc843811fbf', 'Öffentlichkeit & Voyeurismus', 70);
INSERT INTO vorliebe_kategorie (kategorie_id, name, sort_order) VALUES ('56e62741-0f71-49bf-bb67-2c9305cb8bda', 'Digitale Erotik & Medien', 80);
INSERT INTO vorliebe_kategorie (kategorie_id, name, sort_order) VALUES ('ab327fb9-1703-49e7-b64d-0364caf7fa10', 'Sexuelle Orientierung & Identität', 90);
-- Items
-- Sex & Erotik
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('92a5b6bc-2456-4bdc-aca0-44fbfd2caf13', '9aff21d1-dc49-48cc-b184-6b034ffc7308', 'Analsex', 0);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('540de4f3-ec8a-4bdc-b50a-c4ecbbdea83f', '9aff21d1-dc49-48cc-b184-6b034ffc7308', 'Analspiele', 10);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('149b8555-9eed-4dff-b156-6992e03ebf6f', '9aff21d1-dc49-48cc-b184-6b034ffc7308', 'Anonymer Sex', 20);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('1af28eeb-7a98-40b8-81f1-06fee5f5afa2', '9aff21d1-dc49-48cc-b184-6b034ffc7308', 'Blowjob', 30);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('f559d332-2024-4eef-8764-e332044b31be', '9aff21d1-dc49-48cc-b184-6b034ffc7308', 'Cunnilingus', 40);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('d94d1f10-dc67-4765-a1d9-a181a69310f5', '9aff21d1-dc49-48cc-b184-6b034ffc7308', 'Deep Throat', 50);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('b8212dcf-96ee-4898-89ec-d2463bee2cee', '9aff21d1-dc49-48cc-b184-6b034ffc7308', 'Dreier', 60);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('7b20a113-138d-4b11-9c9b-677bbd3a9a19', '9aff21d1-dc49-48cc-b184-6b034ffc7308', 'Facesitting', 70);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('c9b95956-a495-4125-b942-4d3acac3e885', '9aff21d1-dc49-48cc-b184-6b034ffc7308', 'Fingern', 80);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('a0dd81bd-dfaa-4aea-9d60-83b79137c9bb', '9aff21d1-dc49-48cc-b184-6b034ffc7308', 'Gegenseitiges Masturbieren', 90);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('90e4e397-d853-49d2-892c-92d49032f271', '9aff21d1-dc49-48cc-b184-6b034ffc7308', 'Handjob', 100);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('3b5298f2-f324-42c6-9019-f6a04f4a04a2', '9aff21d1-dc49-48cc-b184-6b034ffc7308', 'Haare ziehen', 110);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('7779c097-dc2a-4588-933c-7b1de2d2847e', '9aff21d1-dc49-48cc-b184-6b034ffc7308', 'Küssen', 120);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('46f26b44-fab3-4978-9f1c-830f87b05a14', '9aff21d1-dc49-48cc-b184-6b034ffc7308', 'Kuscheln', 130);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('ddbc0fa3-7560-40a3-87f8-d5f5bbd3b90d', '9aff21d1-dc49-48cc-b184-6b034ffc7308', 'Massagen', 140);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('c95d1667-8a52-435f-b995-bda49d404c86', '9aff21d1-dc49-48cc-b184-6b034ffc7308', 'Normaler Sex', 150);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('77cbe0a7-28ff-4853-a6a5-c5c2a53f8f89', '9aff21d1-dc49-48cc-b184-6b034ffc7308', 'Oralsex', 160);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('4aa82f80-c855-4d2b-bdae-764a594d2324', '9aff21d1-dc49-48cc-b184-6b034ffc7308', 'Pegging', 170);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('132fa3a6-ecd6-4814-9267-30d438a3844c', '9aff21d1-dc49-48cc-b184-6b034ffc7308', 'Prostata Orgasmus', 180);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('c46fc585-6667-47d3-a842-d85b60dc87e2', '9aff21d1-dc49-48cc-b184-6b034ffc7308', 'Quickies', 190);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('421f5bdf-289c-439a-a28e-ef09e4b736f4', '9aff21d1-dc49-48cc-b184-6b034ffc7308', 'Rimming', 200);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('5b7b5fb9-43e2-49d2-9c0c-553a95e2e1ca', '9aff21d1-dc49-48cc-b184-6b034ffc7308', 'Selbstbefriedigung', 210);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('fa31a358-72e8-40ab-8041-20c5975111c8', '9aff21d1-dc49-48cc-b184-6b034ffc7308', 'Sex in der Dusche', 220);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('2063049b-73dc-4f89-8fd4-66a99f9b4533', '9aff21d1-dc49-48cc-b184-6b034ffc7308', 'Slow Sex', 230);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('c70a7f8a-d87d-4905-9d4f-ca295db29e5d', '9aff21d1-dc49-48cc-b184-6b034ffc7308', 'Squirting', 240);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('d381520a-2e73-4c20-bd28-55d3a5d63661', '9aff21d1-dc49-48cc-b184-6b034ffc7308', 'Tantramassage', 250);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('47d61503-459b-44c3-9a6b-99c0ff3e6e70', '9aff21d1-dc49-48cc-b184-6b034ffc7308', 'Vorspiel', 260);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('6c25c492-b44e-43c0-b0c3-029361d0b442', '9aff21d1-dc49-48cc-b184-6b034ffc7308', 'Weibliche Ejakulation', 270);
-- BDSM & Bondage
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('0e54de75-124c-4ca4-baba-370d54b2185e', '88a92d51-33b4-4dad-88a8-5b4f8a0a898a', 'Atemspiele', 0);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('50143e67-5459-4eb3-b959-03cfecd70c22', '88a92d51-33b4-4dad-88a8-5b4f8a0a898a', 'Bondage / Fesseln', 10);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('9ccb79d2-af11-487d-aabd-e5b56ce2bb76', '88a92d51-33b4-4dad-88a8-5b4f8a0a898a', 'Brust/Nippel-Behandlung', 20);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('53eed955-0ccd-45ed-b6ac-266150d4d2ad', '88a92d51-33b4-4dad-88a8-5b4f8a0a898a', 'Disziplin', 30);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('5ef14dcc-ae5a-4d4c-8df2-beb232e86bc0', '88a92d51-33b4-4dad-88a8-5b4f8a0a898a', 'Dominanz & Submission', 40);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('60b7d38e-c4d3-4c3c-86e3-162fdc4c4673', '88a92d51-33b4-4dad-88a8-5b4f8a0a898a', 'Double Penetration', 50);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('cfd64174-b617-4e09-9d85-2d1c37e614c4', '88a92d51-33b4-4dad-88a8-5b4f8a0a898a', 'Edge Play', 60);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('1574f0d3-ddfe-46b2-9817-3398d34c4764', '88a92d51-33b4-4dad-88a8-5b4f8a0a898a', 'Edging', 70);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('7e98f326-fc9f-4990-8aed-b3c64eb423a0', '88a92d51-33b4-4dad-88a8-5b4f8a0a898a', 'Elektrostimulation', 80);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('c5d1fc5f-3968-4f1c-ab9b-bbeb2615d3a4', '88a92d51-33b4-4dad-88a8-5b4f8a0a898a', 'Erniedrigung', 90);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('138b6d05-ef85-41ee-abf9-cc31e449d7b4', '88a92d51-33b4-4dad-88a8-5b4f8a0a898a', 'Feederism', 100);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('e3f06c75-bb97-401c-9276-b6da573cf911', '88a92d51-33b4-4dad-88a8-5b4f8a0a898a', 'Fisting', 110);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('83aae12a-1bc5-4a52-9de6-5c2737c6eb1e', '88a92d51-33b4-4dad-88a8-5b4f8a0a898a', 'Keuschheit', 120);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('75a56056-2bc0-417b-9d19-691f91ff1a3f', '88a92d51-33b4-4dad-88a8-5b4f8a0a898a', 'Knife Play', 130);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('09a582bd-abb5-4a9e-9df7-4b297031b124', '88a92d51-33b4-4dad-88a8-5b4f8a0a898a', 'Masochismus', 140);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('84213212-b83b-463d-a777-f7460c8af4dc', '88a92d51-33b4-4dad-88a8-5b4f8a0a898a', 'Orgasmuskontrolle', 150);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('958a3fae-fef3-457e-b683-3e72d09a177a', '88a92d51-33b4-4dad-88a8-5b4f8a0a898a', 'Post-Orgasmus-Folter', 160);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('1719cb69-a269-45ab-8ada-e40225b743a2', '88a92d51-33b4-4dad-88a8-5b4f8a0a898a', 'Sadismus', 170);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('462a7e7e-b782-41d8-a541-517695eafb27', '88a92d51-33b4-4dad-88a8-5b4f8a0a898a', 'Sensory Deprivation', 180);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('c522b41d-5e64-4b75-a63e-a4fe8d206929', '88a92d51-33b4-4dad-88a8-5b4f8a0a898a', 'Sklaven Erziehung', 190);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('c2be265e-c5e9-4371-a61e-a48163113791', '88a92d51-33b4-4dad-88a8-5b4f8a0a898a', 'Spanking', 200);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('e3759750-ced3-4552-b582-1ddf1f156de7', '88a92d51-33b4-4dad-88a8-5b4f8a0a898a', 'Suspension Bondage', 210);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('2db5d4a4-323b-4e6b-aaab-e066ab0f36b2', '88a92d51-33b4-4dad-88a8-5b4f8a0a898a', 'Trampling', 220);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('d0e0fad7-91e8-4e96-a0de-dc5dae93a636', '88a92d51-33b4-4dad-88a8-5b4f8a0a898a', 'Wachsspiele', 230);
-- Rollenspiele & Fantasien
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('19b8be0f-6eba-4cef-8946-265e336513f9', '10ad63de-2ff7-4364-b0d2-9df22bfc200a', 'Age Play', 0);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('ec00a157-0531-4ff0-978e-1fe3d5a03bc5', '10ad63de-2ff7-4364-b0d2-9df22bfc200a', 'Animal Play / Puppy Play', 10);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('929bf842-e08b-49fb-9998-7e5b31198887', '10ad63de-2ff7-4364-b0d2-9df22bfc200a', 'Caregiver & Little', 20);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('f2144cf1-46e5-426a-87fd-c3f518c2e346', '10ad63de-2ff7-4364-b0d2-9df22bfc200a', 'Cosplay', 30);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('c7cb7bc8-d284-41dd-befa-3076cee682b5', '10ad63de-2ff7-4364-b0d2-9df22bfc200a', 'Dirty Talk', 40);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('d17614cd-84e5-480d-967b-0773caf68f23', '10ad63de-2ff7-4364-b0d2-9df22bfc200a', 'Doktorspiele', 50);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('462d60ab-fc83-4e97-b6a0-cb94d7c1420c', '10ad63de-2ff7-4364-b0d2-9df22bfc200a', 'Escortspiele', 60);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('58ca86b7-ef94-4e98-bdb7-42eaf2044b7f', '10ad63de-2ff7-4364-b0d2-9df22bfc200a', 'Gefangenenrollenspiele', 70);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('eaca0603-e185-4636-ad8d-e9ceec66602f', '10ad63de-2ff7-4364-b0d2-9df22bfc200a', 'Geschlechterrollenspiele', 80);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('8888277b-3926-4e1f-b538-03a3d1c17e0c', '10ad63de-2ff7-4364-b0d2-9df22bfc200a', 'Handwerker - Hausfrau', 90);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('b3fdc7f8-075b-4036-a4c8-de75ad69b315', '10ad63de-2ff7-4364-b0d2-9df22bfc200a', 'Klinik Sex', 100);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('d02a7acf-97a9-48fe-92be-3b5655b33c84', '10ad63de-2ff7-4364-b0d2-9df22bfc200a', 'Rollenspiele', 110);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('f8335c9d-e6d0-4c64-8014-485996485d58', '10ad63de-2ff7-4364-b0d2-9df22bfc200a', 'Vampir Spiele', 120);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('000b4ba3-a4ba-4818-ad1b-74243e6047ef', '10ad63de-2ff7-4364-b0d2-9df22bfc200a', 'Weibliche Dominanz', 130);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('33dbee32-abed-4769-ba9d-5f18c01fade2', '10ad63de-2ff7-4364-b0d2-9df22bfc200a', 'Weiße Erotik', 140);
-- Körper & Fetische
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('d63dcf75-ec08-45da-a90a-59e468991301', 'fbfeeabd-31e3-44ee-873a-24d2540c4a0b', 'Achselfetisch', 0);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('e32f439b-b66e-46f7-9c95-14c5f080be1b', 'fbfeeabd-31e3-44ee-873a-24d2540c4a0b', 'Bauch Fetisch', 10);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('3fc1e022-e5e1-4477-a53a-495420290273', 'fbfeeabd-31e3-44ee-873a-24d2540c4a0b', 'Body Worship', 20);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('bd140557-ce13-40c8-ae0a-58c6e783cd98', 'fbfeeabd-31e3-44ee-873a-24d2540c4a0b', 'Busen Fetisch', 30);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('ad661858-bab9-4381-a482-76fd9a1cc80b', 'fbfeeabd-31e3-44ee-873a-24d2540c4a0b', 'Erotische Laktation', 40);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('bb7a1328-f866-4733-8db6-f4602afb0a4c', 'fbfeeabd-31e3-44ee-873a-24d2540c4a0b', 'Frottage', 50);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('79bb7278-a69b-49b7-ab95-a48b9b4be49f', 'fbfeeabd-31e3-44ee-873a-24d2540c4a0b', 'Fußfetisch', 60);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('6560ac63-c487-41c5-a0fe-614aeac89bd7', 'fbfeeabd-31e3-44ee-873a-24d2540c4a0b', 'Hintern', 70);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('522f259c-54d6-43e4-a9b3-f246499c8ad6', 'fbfeeabd-31e3-44ee-873a-24d2540c4a0b', 'Intimbehaarung', 80);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('f921589d-a5a9-457b-aa2c-17164f48a5e8', 'fbfeeabd-31e3-44ee-873a-24d2540c4a0b', 'Intimrasur', 90);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('2763ce71-fefd-48df-82c5-14991790c958', 'fbfeeabd-31e3-44ee-873a-24d2540c4a0b', 'Kitzelfetisch', 100);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('acbe8c52-96b4-4745-b015-58f7461c9241', 'fbfeeabd-31e3-44ee-873a-24d2540c4a0b', 'Körperbehaarung', 110);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('73e370bd-2387-4e24-b652-3cc20785f13f', 'fbfeeabd-31e3-44ee-873a-24d2540c4a0b', 'Lecken', 120);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('29436044-5bf4-4c9d-b080-b44c9e8f7b25', 'fbfeeabd-31e3-44ee-873a-24d2540c4a0b', 'Mollig', 130);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('eba2cd9e-102b-4705-ac7f-31b6e61ba87a', 'fbfeeabd-31e3-44ee-873a-24d2540c4a0b', 'Natursekt', 140);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('3773603d-ffec-4187-884c-33aa38a6cf84', 'fbfeeabd-31e3-44ee-873a-24d2540c4a0b', 'Nippel', 150);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('f6de705c-4c9a-4c52-9fc5-a0a04431495c', 'fbfeeabd-31e3-44ee-873a-24d2540c4a0b', 'Piercings', 160);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('91e0fb2f-4691-4968-8540-ed1e0ace3314', 'fbfeeabd-31e3-44ee-873a-24d2540c4a0b', 'Rasur Fetisch', 170);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('ba149392-bee9-4931-8af3-b394910eaa03', 'fbfeeabd-31e3-44ee-873a-24d2540c4a0b', 'Schamhaare', 180);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('d2c45d35-032f-4c92-a0d1-e73236ad144a', 'fbfeeabd-31e3-44ee-873a-24d2540c4a0b', 'Spermaspiele', 190);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('88b5a458-9f36-4310-8a8e-be871333ccb9', 'fbfeeabd-31e3-44ee-873a-24d2540c4a0b', 'Spuck-Fetisch', 200);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('bf0fe0ef-043c-4c53-b627-1f8669d87eda', 'fbfeeabd-31e3-44ee-873a-24d2540c4a0b', 'Tattoos', 210);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('4d6819e1-ff06-411e-af4a-97aaaa3af2ec', 'fbfeeabd-31e3-44ee-873a-24d2540c4a0b', 'Titten', 220);
-- Fetisch-Kleidung
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('27438c76-0f40-4418-9c20-57e4fbd12541', 'b45bc99f-6e9e-4a81-af7d-ab858e316b85', 'Dessous', 0);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('090543b3-dc4b-420f-9c88-87aa0b502328', 'b45bc99f-6e9e-4a81-af7d-ab858e316b85', 'Gummi Fetisch', 10);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('a474a0c4-4849-44c7-8011-1e544cb12dde', 'b45bc99f-6e9e-4a81-af7d-ab858e316b85', 'High Heels', 20);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('98b37548-1e32-477b-be9b-01a2c402ca15', 'b45bc99f-6e9e-4a81-af7d-ab858e316b85', 'Kostüme', 30);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('995609d4-8aef-4346-9590-c1c5877c1a6b', 'b45bc99f-6e9e-4a81-af7d-ab858e316b85', 'Korsetts', 40);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('cb316324-0b98-4bd2-baaf-ef459a10073b', 'b45bc99f-6e9e-4a81-af7d-ab858e316b85', 'Lack Fetisch', 50);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('6bb0f818-fdaf-4f3e-9b70-9e54531a4807', 'b45bc99f-6e9e-4a81-af7d-ab858e316b85', 'Latex Fetisch', 60);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('bb37d5b3-f21a-451e-90ba-0187a2ecac0f', 'b45bc99f-6e9e-4a81-af7d-ab858e316b85', 'Leder Fetisch', 70);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('f9471271-6a75-4ee6-b065-3395a8907e5b', 'b45bc99f-6e9e-4a81-af7d-ab858e316b85', 'Masken', 80);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('acfdaa4f-799c-4503-a9cf-2e235fb9eaed', 'b45bc99f-6e9e-4a81-af7d-ab858e316b85', 'Nylons / Strumpfhosen', 90);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('24f91eab-56ba-4d51-a9e4-943d0bb18cb4', 'b45bc99f-6e9e-4a81-af7d-ab858e316b85', 'Sportbekleidung', 100);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('f0fffadc-5966-4def-bb7c-4ed275b92c86', 'b45bc99f-6e9e-4a81-af7d-ab858e316b85', 'Uniform Fetisch', 110);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('f9981d2e-5852-4792-92b1-14b4ec7435ff', 'b45bc99f-6e9e-4a81-af7d-ab858e316b85', 'Unterwäsche', 120);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('07bc4b75-ddf6-4050-895b-ccc766c4c83a', 'b45bc99f-6e9e-4a81-af7d-ab858e316b85', 'Wetlook', 130);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('13a96018-6568-490d-b013-ce012a00d9eb', 'b45bc99f-6e9e-4a81-af7d-ab858e316b85', 'Windelfetisch', 140);
-- Sexspielzeug & Equipment
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('ebb5008e-3495-409a-9251-d720d6adb8fb', 'c2f597bc-ab4c-4819-8eb8-98d324f6dff0', 'Anal-Kette', 0);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('2779f9fe-c748-4128-a5d7-a27bb997ecbc', 'c2f597bc-ab4c-4819-8eb8-98d324f6dff0', 'Analplugs', 10);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('373d227f-4fbb-40e0-978c-7241a55cd4e3', 'c2f597bc-ab4c-4819-8eb8-98d324f6dff0', 'Augenbinde', 20);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('dd8fd4cd-38c4-44af-b812-13f04463aa17', 'c2f597bc-ab4c-4819-8eb8-98d324f6dff0', 'Ben-Wa-Kugeln', 30);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('e9e91d9e-02a0-4842-b855-5689a79e8f7b', 'c2f597bc-ab4c-4819-8eb8-98d324f6dff0', 'Bondage Seil', 40);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('725521b6-a4c2-4ccd-8833-ff7a5a447011', 'c2f597bc-ab4c-4819-8eb8-98d324f6dff0', 'Dildos', 50);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('cafa7d3d-f829-4706-b81c-2c8729895135', 'c2f597bc-ab4c-4819-8eb8-98d324f6dff0', 'Elektrostimulationsstab', 60);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('d4b0993a-f716-4fb7-bd59-1cd1bc1a6eec', 'c2f597bc-ab4c-4819-8eb8-98d324f6dff0', 'Flogger', 70);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('04d6258b-10bc-4493-9780-e9dd34b325aa', 'c2f597bc-ab4c-4819-8eb8-98d324f6dff0', 'Handschellen', 80);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('28641800-64a0-4416-aa43-318c4bd8ae05', 'c2f597bc-ab4c-4819-8eb8-98d324f6dff0', 'Halsband und Leine', 90);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('bd45a6da-d152-4e42-af53-8224811f3718', 'c2f597bc-ab4c-4819-8eb8-98d324f6dff0', 'Keuschheitsgürtel', 100);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('bc0499c1-1669-4a72-a00e-116581294f27', 'c2f597bc-ab4c-4819-8eb8-98d324f6dff0', 'Knebel', 110);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('86716cb5-37de-4aac-a77b-029d0eaca4c1', 'c2f597bc-ab4c-4819-8eb8-98d324f6dff0', 'Massagestab', 120);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('bc5f646a-0959-4a15-8921-23d490822e7b', 'c2f597bc-ab4c-4819-8eb8-98d324f6dff0', 'Nippelklemme', 130);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('c9a23f58-b112-469a-a328-154a5d2c89ab', 'c2f597bc-ab4c-4819-8eb8-98d324f6dff0', 'Penisring', 140);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('62a6e117-1c53-45e7-9e10-7c8571dbd8e7', 'c2f597bc-ab4c-4819-8eb8-98d324f6dff0', 'Peitschen', 150);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('98e07854-448b-43c6-8807-e95722ba3c7d', 'c2f597bc-ab4c-4819-8eb8-98d324f6dff0', 'Sexpuppe', 160);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('4fd8e5a3-b8c5-4c20-9d9a-78228df019be', 'c2f597bc-ab4c-4819-8eb8-98d324f6dff0', 'Spreader Bar', 170);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('953f2387-48ec-4043-8906-2289145de6a0', 'c2f597bc-ab4c-4819-8eb8-98d324f6dff0', 'Umschnalldildo', 180);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('66327aa9-fb5a-4f50-a5eb-d71436df17a7', 'c2f597bc-ab4c-4819-8eb8-98d324f6dff0', 'Vibratoren', 190);
-- Lifestyle & Beziehungsformen
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('fe1f3f77-4226-4725-b80d-acbbf6daf180', '147066c6-f5be-412f-8516-64e1dffd2389', 'Crossdresser', 0);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('afde15ff-db24-48c0-8979-0af452f73036', '147066c6-f5be-412f-8516-64e1dffd2389', 'Cuckold', 10);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('1ee58f61-0b71-4d8a-99e0-61446599af45', '147066c6-f5be-412f-8516-64e1dffd2389', 'Dreier FFM', 20);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('8984e7e2-bd71-4b1a-95aa-5d86874cccff', '147066c6-f5be-412f-8516-64e1dffd2389', 'Dreier MMF', 30);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('fc8d1056-cd4e-4570-b532-47569edbf259', '147066c6-f5be-412f-8516-64e1dffd2389', 'FKK', 40);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('209d557d-8f78-4745-b745-3207cb5ec1ec', '147066c6-f5be-412f-8516-64e1dffd2389', 'Freie Liebe', 50);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('face8ebe-203f-42c6-b6ea-0c903b92edf2', '147066c6-f5be-412f-8516-64e1dffd2389', 'Gangbang', 60);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('63258f31-d07e-4d29-a16b-0f4b933bdad9', '147066c6-f5be-412f-8516-64e1dffd2389', 'Gothic', 70);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('2f9940fe-a99c-40d1-bc0f-0f7ebc88a759', '147066c6-f5be-412f-8516-64e1dffd2389', 'Gruppensex', 80);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('417cb098-95bd-489e-a456-52fb7772992a', '147066c6-f5be-412f-8516-64e1dffd2389', 'Paarsex MFMF', 90);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('298e89b9-f049-4c92-829f-c110fdd57643', '147066c6-f5be-412f-8516-64e1dffd2389', 'Partnertausch', 100);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('c54c0416-90be-4136-b04e-3ce947eeabab', '147066c6-f5be-412f-8516-64e1dffd2389', 'Polyamorie', 110);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('98d85a15-3a7c-47c3-bfbb-59ebbc0bc25d', '147066c6-f5be-412f-8516-64e1dffd2389', 'Swinger', 120);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('f0aa248b-1eb8-49f5-aabb-3dcb1087d43c', '147066c6-f5be-412f-8516-64e1dffd2389', 'Tantra', 130);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('faa09db1-137e-45d6-aca5-2a1419fbd4c6', '147066c6-f5be-412f-8516-64e1dffd2389', 'Wifesharing', 140);
-- Öffentlichkeit & Voyeurismus
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('0ec098d7-fadf-4a37-848b-bf9c2317561e', '7879146a-352a-408c-9405-ebc843811fbf', 'Aktfotografie', 0);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('f3b85a7e-625a-4c6e-87e2-5ef99e9db82b', '7879146a-352a-408c-9405-ebc843811fbf', 'Amateurvideos drehen', 10);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('c80bab40-09f5-49f7-b46d-3b9ecfa73cfe', '7879146a-352a-408c-9405-ebc843811fbf', 'Exhibitionismus', 20);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('975f4cce-b2c0-4680-8206-84a5aa5f8222', '7879146a-352a-408c-9405-ebc843811fbf', 'Lap Dance', 30);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('6fb8dce7-5654-4932-b3e8-c8dea811072c', '7879146a-352a-408c-9405-ebc843811fbf', 'Outdoor / Sex im Freien', 40);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('97c55cee-d86f-44b4-9f91-6d190dd1a003', '7879146a-352a-408c-9405-ebc843811fbf', 'Parkplatzsex', 50);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('cc88d9eb-8dd1-4f32-aa34-a5ee4962fa6f', '7879146a-352a-408c-9405-ebc843811fbf', 'Pornokino', 60);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('c011ebda-a557-4d32-a19d-5dcabd2b1085', '7879146a-352a-408c-9405-ebc843811fbf', 'Sex am Strand', 70);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('b0452d3f-2f28-480a-bbe5-b5633731d5b6', '7879146a-352a-408c-9405-ebc843811fbf', 'Sex im Auto', 80);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('53a73c81-f602-414e-a64a-1308a7713c48', '7879146a-352a-408c-9405-ebc843811fbf', 'Sex im Swingerclub', 90);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('9b274e75-85e0-4ded-86ed-2fa0df8a53b3', '7879146a-352a-408c-9405-ebc843811fbf', 'Sex in der Sauna', 100);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('3da65863-53c3-4c35-935d-427dd6cf45c8', '7879146a-352a-408c-9405-ebc843811fbf', 'Sex in der Umkleide', 110);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('0a552608-311b-4655-ad43-8b654692d381', '7879146a-352a-408c-9405-ebc843811fbf', 'Striptease', 120);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('068f25b4-51cd-48e0-8220-147a55a79341', '7879146a-352a-408c-9405-ebc843811fbf', 'Voyeurismus', 130);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('9a951131-4ba6-4517-b767-a7e6d9aa9721', '7879146a-352a-408c-9405-ebc843811fbf', 'Zuschauen / Zuschauen lassen', 140);
-- Digitale Erotik & Medien
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('ed8752c2-ec71-40c3-a3fb-ad21c2d8cf64', '56e62741-0f71-49bf-bb67-2c9305cb8bda', 'Bildertausch', 0);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('d085f010-ea6b-472b-a589-6c11bad7e4e8', '56e62741-0f71-49bf-bb67-2c9305cb8bda', 'Erotische Chats', 10);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('5242869b-87bc-43a0-bc3f-cd4a978e283c', '56e62741-0f71-49bf-bb67-2c9305cb8bda', 'Erotische Geschichten', 20);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('320a25f8-4758-42d4-a7da-d64e9bc2479b', '56e62741-0f71-49bf-bb67-2c9305cb8bda', 'Filmen / Fotografieren', 30);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('10d59cea-add2-4642-9974-8e4c61f2ea26', '56e62741-0f71-49bf-bb67-2c9305cb8bda', 'Hentai & Anime', 40);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('9804ccfa-84dd-4a02-a753-c588ecb9fdfc', '56e62741-0f71-49bf-bb67-2c9305cb8bda', 'Pornos', 50);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('15b9a156-4cff-45d6-9f48-6a7c2a9cfd7e', '56e62741-0f71-49bf-bb67-2c9305cb8bda', 'Sex Chat', 60);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('d84e58b1-c390-43ae-9bed-3b55793932d4', '56e62741-0f71-49bf-bb67-2c9305cb8bda', 'Sexting', 70);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('f5c73135-3d1a-4f6c-921d-b923aff4ae38', '56e62741-0f71-49bf-bb67-2c9305cb8bda', 'Telefonsex', 80);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('17a7b5e5-0eb4-4e13-bfb4-df7158607103', '56e62741-0f71-49bf-bb67-2c9305cb8bda', 'VR Sex', 90);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('b192219e-ab78-4909-9199-358cc1b8139b', '56e62741-0f71-49bf-bb67-2c9305cb8bda', 'Webcam', 100);
-- Sexuelle Orientierung & Identität
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('c3c34058-ede2-4907-a432-688423bec959', 'ab327fb9-1703-49e7-b64d-0364caf7fa10', 'Asexuell', 0);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('676e9fe2-ac43-419d-a458-ba0607f05507', 'ab327fb9-1703-49e7-b64d-0364caf7fa10', 'Bisexualität', 10);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('6bf86548-0a32-42ab-9d9a-4bfef4994de2', 'ab327fb9-1703-49e7-b64d-0364caf7fa10', 'Cisgender', 20);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('da1350bb-9993-4262-b631-faae8d8ba873', 'ab327fb9-1703-49e7-b64d-0364caf7fa10', 'Heterosexuell', 30);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('aa756c6f-2c00-4c5f-81d7-18e59ff42388', 'ab327fb9-1703-49e7-b64d-0364caf7fa10', 'Homosexuell', 40);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('e5978000-ce7d-444a-9078-7d4ec6ea6588', 'ab327fb9-1703-49e7-b64d-0364caf7fa10', 'Lesbisch', 50);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('6c4943e4-d83b-434a-8d6b-f15c6384cf1e', 'ab327fb9-1703-49e7-b64d-0364caf7fa10', 'Metrosexualität', 60);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('61e2384b-80d1-446a-9477-fee2131ccdd5', 'ab327fb9-1703-49e7-b64d-0364caf7fa10', 'Non-Binary', 70);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('faa9bd98-9099-4e87-94cb-db71aeb2bbe2', 'ab327fb9-1703-49e7-b64d-0364caf7fa10', 'Pansexuell', 80);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('2880b1a8-ed69-4cf5-a308-731f33df84f1', 'ab327fb9-1703-49e7-b64d-0364caf7fa10', 'Queer', 90);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('90261e80-7792-4b83-a943-b991ee291fef', 'ab327fb9-1703-49e7-b64d-0364caf7fa10', 'Sapiosexuell', 100);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('dfbec4c5-3d72-4b18-bc8b-e2f9fa0ad92e', 'ab327fb9-1703-49e7-b64d-0364caf7fa10', 'Trans Mann', 110);
INSERT INTO vorliebe_item (item_id, kategorie_id, name, sort_order) VALUES ('e50fb649-b08a-4094-afec-72b6f7832ad8', 'ab327fb9-1703-49e7-b64d-0364caf7fa10', 'Trans Frau', 120);
COMMIT;

View File

@@ -2416,7 +2416,7 @@ function renderVlListe() {
<span style="font-size:0.72rem;color:var(--color-muted);flex-shrink:0;margin-right:0.5rem;">#${i.sortOrder}</span>
<div class="item-badges" style="flex-shrink:0;">
<button class="btn-item-edit" onclick="editItem('${i.itemId}')">✎</button>
<button class="btn-item-delete" onclick="deleteItem('${i.itemId}','${escAdminHtml(i.name).replace(/'/g,"\\'")}')">✕</button>
<button class="btn-item-delete" onclick="deleteVorliebeItem('${i.itemId}','${escAdminHtml(i.name).replace(/'/g,"\\'")}')">✕</button>
</div>
</div>
</div>`).join('')}</div>`
@@ -2498,13 +2498,14 @@ async function saveKategorie() {
} else { errEl.textContent = 'Fehler beim Speichern.'; }
}
async function deleteKategorie(id, name) {
if (!confirm(`Kategorie "${name}" löschen?`)) return;
const errEl = document.getElementById('vlError');
const r = await fetch(`/admin/vorlieben/kategorien/${id}`, { method: 'DELETE' });
if (r.ok) { await loadVorliebenAdmin(); }
else if (r.status === 409) { errEl.textContent = 'Kategorie enthält noch Vorlieben bitte zuerst alle Vorlieben dieser Kategorie löschen.'; }
else { errEl.textContent = 'Fehler beim Löschen.'; }
function deleteKategorie(id, name) {
openConfirmModal(`Kategorie ${name}" löschen?`, async () => {
const errEl = document.getElementById('vlError');
const r = await fetch(`/admin/vorlieben/kategorien/${id}`, { method: 'DELETE' });
if (r.ok) { await loadVorliebenAdmin(); }
else if (r.status === 409) { errEl.textContent = 'Kategorie enthält noch Vorlieben bitte zuerst alle Vorlieben dieser Kategorie löschen.'; }
else { errEl.textContent = 'Fehler beim Löschen.'; }
});
}
// ── Items CRUD ──
@@ -2554,12 +2555,13 @@ async function saveItem() {
} else { errEl.textContent = 'Fehler beim Speichern.'; }
}
async function deleteItem(id, name) {
if (!confirm(`Vorliebe "${name}" löschen? Alle Nutzerbewertungen werden ebenfalls gelöscht.`)) return;
const errEl = document.getElementById('vlError');
const r = await fetch(`/admin/vorlieben/items/${id}`, { method: 'DELETE' });
if (r.ok) { await loadVorliebenAdmin(); }
else { errEl.textContent = 'Fehler beim Löschen.'; }
function deleteVorliebeItem(id, name) {
openConfirmModal(`Vorliebe ${name}" löschen? Alle Nutzerbewertungen werden ebenfalls gelöscht.`, async () => {
const errEl = document.getElementById('vlError');
const r = await fetch(`/admin/vorlieben/items/${id}`, { method: 'DELETE' });
if (r.ok) { await loadVorliebenAdmin(); }
else { errEl.textContent = 'Fehler beim Löschen.'; }
});
}
// ── Export / Import ──

View File

@@ -444,6 +444,12 @@
</div>
</div>
<!-- Vorlieben (inline, zwischen allgemeinen Angaben und Freunden) -->
<div id="vorliebenSection" style="display:none; margin-top:1rem;">
<div class="section-label">Vorlieben</div>
<div id="vorliebenDisplay"></div>
</div>
<!-- Freunde -->
<div id="friendsSection" style="display:none; margin-top:1rem;">
<div class="section-label">Freunde <span id="friendsCount" style="font-weight:400;color:var(--color-muted);font-size:0.85rem;"></span></div>
@@ -455,11 +461,10 @@
</div>
</div>
<!-- Tabs: Feed | Pinnwand | Vorlieben | Spielhistorie | Keyholder-Angebote -->
<!-- Tabs: Feed | Pinnwand | Spielhistorie | Keyholder-Angebote -->
<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="tabBtnVorlieben" onclick="switchProfilTab('vorlieben', this)" style="display:none;">Vorlieben</button>
<button class="profil-tab-btn" id="tabBtnGameHistory" onclick="switchProfilTab('gamehistory', this)">Spielhistorie</button>
<button class="profil-tab-btn" id="tabBtnKhOffers" onclick="switchProfilTab('khoffers', this)">Keyholder-Angebote</button>
</div>
@@ -480,11 +485,6 @@
<div id="pinnwandList"></div>
</div>
<!-- Vorlieben Tab -->
<div class="profil-tab-panel" id="tab-vorlieben">
<div id="vorliebenDisplay" style="margin-top:0.75rem;"></div>
</div>
<!-- Spielhistorie Tab -->
<div class="profil-tab-panel" id="tab-gamehistory">
<div id="gameHistoryList" style="margin-top:0.75rem;"></div>
@@ -593,6 +593,11 @@
profileData = profile;
allImages = images;
// Profilbesuch tracken (nur fremde Profile, kein Preview-Modus)
if (!isOwnProfile && !previewMode && myUserId) {
fetch('/social/profile-visits/' + targetUserId, { method: 'POST' }).catch(() => {});
}
// ── Preview-Modus: friendStatus simulieren ──
if (previewMode) {
profile.friendStatus = (previewMode === 'FREUND') ? 'FRIEND' : 'NONE';
@@ -716,12 +721,11 @@
const btnFeed = document.getElementById('tabBtnPosts');
const btnPinnwand = document.getElementById('tabBtnPinnwand');
const btnHistory = document.getElementById('tabBtnGameHistory');
const btnVorlieben = document.getElementById('tabBtnVorlieben');
if (!showFeed) { btnFeed.style.display = 'none'; document.getElementById('tab-posts').classList.remove('active'); }
if (!showPinnwand) { btnPinnwand.style.display = 'none'; }
if (!showHistory) { btnHistory.style.display = 'none'; }
if (showVorlieben) { btnVorlieben.style.display = ''; loadVorlieben(); }
if (showVorlieben) { document.getElementById('vorliebenSection').style.display = ''; loadVorlieben(); }
// Ersten sichtbaren Tab aktivieren
if (!showFeed) {
@@ -735,6 +739,7 @@
document.getElementById('tab-gamehistory').classList.add('active');
}
}
}
// ── Vorlieben anzeigen ──

View File

@@ -0,0 +1,32 @@
<!DOCTYPE html>
<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>Dating xXx Sphere</title>
<link rel="stylesheet" href="/css/variables.css">
<link rel="stylesheet" href="/css/style.css">
</head>
<body class="app">
<div class="main">
<div class="content">
<h1>Dating</h1>
<p style="color:var(--color-muted);">Kommt bald.</p>
</div>
</div>
<script src="/js/icons.js"></script>
<script src="/js/sidebar.js"></script>
<script>
fetch('/login/me').then(r => {
if (r.status === 401) window.location.href = '/login.html';
return r.ok ? r.json() : null;
}).then(user => {
if (!user) return;
if (!user.datingAktiv) window.location.href = '/konto/einstellungen.html#sec-dating';
}).catch(() => { window.location.href = '/login.html'; });
</script>
</body>
</html>

View File

@@ -43,14 +43,10 @@
},
];
const homeCls = path === '/userhome.html' ? ' class="active"' : '';
const homeItem = `
<li class="sidebar-mobile-only">
<a href="/userhome.html"${homeCls}><span class="icon">${I('HOME')}</span> Home</a>
</li>`;
// ── Community-Links (immer sichtbar, oberhalb der Spiele) ──
const socialLinks = [
{ href: '/userhome.html', icon: I('HOME') || '⌂', label: 'Home', badgeId: null },
{ href: '/community/feed.html', icon: I('FEED'), label: 'Feed', badgeId: null },
{ href: '/community/freunde.html', icon: I('FRIENDS'), label: 'Freunde', badgeId: 'socialFriendsBadge'},
{ href: '/community/nachrichten.html', icon: I('MESSAGES'), label: 'Nachrichten', badgeId: null },
@@ -64,6 +60,10 @@
return `<li><a href="${href}"${cls}><span class="icon">${icon}</span> ${label}${badge}</a></li>`;
}).join('');
const datingActive = path === '/dating.html';
const datingCls = datingActive ? ' class="active"' : '';
const datingItem = `<li id="navDating"><a href="/konto/einstellungen.html#sec-dating"${datingCls}><span class="icon">${I('DATING') || '♥'}</span> Dating</a></li>`;
const fullHref = path + window.location.search;
const nav = groups.map(({ label, icon, items }) => {
const isOpen = items.some(item => item.href === path || item.href === fullHref);
@@ -105,6 +105,8 @@
<ul>
${socialNav}
<li><hr style="border:none;border-top:1px solid var(--color-secondary);margin:0.4rem 1rem;"></li>
${datingItem}
<li><hr style="border:none;border-top:1px solid var(--color-secondary);margin:0.4rem 1rem;"></li>
${nav}
<li><hr style="border:none;border-top:1px solid var(--color-secondary);margin:0.4rem 1rem;" id="navAdminDivider" style="display:none"></li>
${adminItem}
@@ -204,6 +206,14 @@
}
} catch (_) {}
// Dating-Link
const navDating = document.getElementById('navDating');
if (navDating) {
navDating.querySelector('a').href = user.datingAktiv
? '/dating.html'
: '/konto/einstellungen.html#sec-dating';
}
// Admin-Link
if (user.admin) {
const navAdminLink = document.getElementById('navAdminLink');

View File

@@ -472,6 +472,55 @@
</div>
</div>
<!-- Dating -->
<div class="settings-section" id="sec-dating">
<div class="settings-section-header" onclick="toggleSection('sec-dating')">
<span class="settings-section-title">♥ Dating</span>
<span class="settings-section-arrow"></span>
</div>
<div class="settings-section-body">
<div class="settings-row">
<div class="settings-row-info">
<div class="settings-row-label">Dating aktivieren</div>
<div class="settings-row-desc">Zeige dein Profil im Dating-Bereich. Ein Standort ist erforderlich.</div>
</div>
<label style="display:flex;align-items:center;gap:0.5rem;cursor:pointer;">
<input type="checkbox" id="datingAktiv" style="width:1.1rem;height:1.1rem;accent-color:var(--color-primary);cursor:pointer;" onchange="onDatingToggle()">
</label>
</div>
<div id="datingStadtRow" style="display:none;">
<div class="settings-row" style="flex-wrap:wrap;gap:0.5rem;">
<div class="settings-row-info">
<div class="settings-row-label">Standort (Stadt)</div>
<div class="settings-row-desc">Wird im Dating-Bereich angezeigt.</div>
</div>
</div>
<div style="display:flex;gap:0.5rem;margin-bottom:0.35rem;position:relative;">
<div style="position:relative;flex:1;display:flex;">
<input type="text" id="datingStadt" placeholder="Stadt suchen und auswählen…" autocomplete="off"
style="flex:1;padding:0.55rem 2rem 0.55rem 0.8rem;border:1px solid var(--color-secondary);border-radius:6px;background:var(--color-secondary);color:var(--color-text);font-size:0.95rem;outline:none;"
oninput="onStadtInput()">
<button id="datingStadtClear" onclick="clearStadt()" title="Auswahl aufheben"
style="display:none;position:absolute;right:0.4rem;top:50%;transform:translateY(-50%);
background:none;border:none;color:var(--color-muted);font-size:1.1rem;cursor:pointer;padding:0.1rem 0.3rem;margin:0;line-height:1;">×</button>
</div>
<button onclick="detectLocation()" title="Standort ermitteln"
style="white-space:nowrap;padding:0.55rem 0.9rem;margin:0;font-size:0.85rem;">
⌖ Ermitteln
</button>
<ul id="stadtSuggestions" style="display:none;position:absolute;top:100%;left:0;right:3.5rem;
background:var(--color-card);border:1px solid var(--color-secondary);border-radius:6px;
z-index:100;list-style:none;margin:0.2rem 0 0;padding:0;max-height:200px;overflow-y:auto;"></ul>
</div>
<div id="datingLocMsg" style="font-size:0.82rem;color:var(--color-muted);margin-bottom:0.5rem;"></div>
</div>
<div class="settings-row" style="border-top:1px solid var(--color-secondary);padding-top:0.75rem;margin-top:0.25rem;">
<button onclick="saveDating()" id="saveDatingBtn" style="margin:0;padding:0.55rem 1.25rem;font-size:0.9rem;">Speichern</button>
<span id="datingMsg" style="font-size:0.85rem;"></span>
</div>
</div>
</div>
<!-- Datenschutz -->
<div class="settings-section" id="sec-datenschutz">
<div class="settings-section-header" onclick="toggleSection('sec-datenschutz')">
@@ -1134,8 +1183,152 @@
loadBdsmDefaults();
loadSubscription();
loadTtlockUserConfig();
loadDating();
openSectionFromHash();
// ── Dating ──────────────────────────────────────────────────────────────
async function loadDating() {
const res = await fetch('/login/me');
if (!res.ok) return;
const user = await res.json();
document.getElementById('datingAktiv').checked = !!user.datingAktiv;
if (user.datingStadt) {
const input = document.getElementById('datingStadt');
input.value = user.datingStadt;
input.readOnly = true;
document.getElementById('datingStadtClear').style.display = '';
}
if (user.datingLat != null) _datingLat = user.datingLat;
if (user.datingLon != null) _datingLon = user.datingLon;
document.getElementById('datingStadtRow').style.display = user.datingAktiv ? '' : 'none';
}
function onDatingToggle() {
const aktiv = document.getElementById('datingAktiv').checked;
document.getElementById('datingStadtRow').style.display = aktiv ? '' : 'none';
}
let _stadtSuggestTimer = null;
let _datingLat = null;
let _datingLon = null;
function onStadtInput() {
const q = document.getElementById('datingStadt').value.trim();
_datingLat = null;
_datingLon = null;
document.getElementById('datingStadtClear').style.display = 'none';
clearTimeout(_stadtSuggestTimer);
if (q.length < 2) { hideSuggestions(); return; }
_stadtSuggestTimer = setTimeout(() => fetchStadtSuggestions(q), 300);
}
async function fetchStadtSuggestions(q) {
try {
const url = `https://nominatim.openstreetmap.org/search?q=${encodeURIComponent(q)}&format=json&addressdetails=1&limit=5&featuretype=city`;
const res = await fetch(url, { headers: { 'Accept-Language': 'de' } });
if (!res.ok) return;
const results = await res.json();
const ul = document.getElementById('stadtSuggestions');
if (!results.length) { hideSuggestions(); return; }
ul.innerHTML = results.map(r => {
const city = r.address.city || r.address.town || r.address.village || r.address.county || r.name;
const country = r.address.country || '';
const label = city + (country ? ', ' + country : '');
return `<li style="padding:0.5rem 0.75rem;cursor:pointer;font-size:0.9rem;border-bottom:1px solid var(--color-secondary);"
onmousedown="selectStadt(event, '${label.replace(/'/g, "\\'")}', ${parseFloat(r.lat)}, ${parseFloat(r.lon)})">${label}</li>`;
}).join('');
ul.style.display = '';
} catch (_) { hideSuggestions(); }
}
function selectStadt(e, label, lat, lon) {
e.preventDefault();
const input = document.getElementById('datingStadt');
input.value = label;
input.readOnly = true;
_datingLat = lat;
_datingLon = lon;
document.getElementById('datingStadtClear').style.display = '';
hideSuggestions();
}
function clearStadt() {
const input = document.getElementById('datingStadt');
input.value = '';
input.readOnly = false;
_datingLat = null;
_datingLon = null;
document.getElementById('datingStadtClear').style.display = 'none';
input.focus();
}
function hideSuggestions() {
document.getElementById('stadtSuggestions').style.display = 'none';
}
document.addEventListener('click', e => {
if (!e.target.closest('#datingStadtRow')) hideSuggestions();
});
async function detectLocation() {
const msgEl = document.getElementById('datingLocMsg');
if (!navigator.geolocation) { msgEl.textContent = 'Geolocation nicht unterstützt.'; return; }
msgEl.textContent = 'Standort wird ermittelt…';
navigator.geolocation.getCurrentPosition(async pos => {
try {
const { latitude, longitude } = pos.coords;
const res = await fetch(
`https://nominatim.openstreetmap.org/reverse?lat=${latitude}&lon=${longitude}&format=json&addressdetails=1`,
{ headers: { 'Accept-Language': 'de' } }
);
if (!res.ok) throw new Error();
const data = await res.json();
const city = data.address.city || data.address.town || data.address.village || data.address.county || '';
const country = data.address.country || '';
const input = document.getElementById('datingStadt');
input.value = city + (country ? ', ' + country : '');
input.readOnly = true;
_datingLat = latitude;
_datingLon = longitude;
document.getElementById('datingStadtClear').style.display = '';
msgEl.textContent = '';
} catch (_) { msgEl.textContent = 'Standort konnte nicht ermittelt werden.'; }
}, () => { msgEl.textContent = 'Zugriff auf Standort verweigert.'; });
}
async function saveDating() {
const aktiv = document.getElementById('datingAktiv').checked;
const stadt = document.getElementById('datingStadt').value.trim();
const msgEl = document.getElementById('datingMsg');
if (aktiv && (!stadt || _datingLat == null || _datingLon == null)) {
msgEl.textContent = 'Bitte eine Stadt aus der Liste auswählen oder per GPS ermitteln.';
msgEl.style.color = 'var(--color-primary)';
return;
}
const btn = document.getElementById('saveDatingBtn');
btn.disabled = true;
try {
const res = await fetch('/user/me/dating', {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ datingAktiv: aktiv, datingStadt: stadt || null, datingLat: _datingLat, datingLon: _datingLon })
});
if (res.ok) {
showToast();
msgEl.textContent = '';
} else {
msgEl.textContent = 'Fehler beim Speichern.';
msgEl.style.color = 'var(--color-primary)';
}
} catch (_) {
msgEl.textContent = 'Server nicht erreichbar.';
msgEl.style.color = 'var(--color-primary)';
} finally {
btn.disabled = false;
}
}
// ── TTLock ──────────────────────────────────────────────────────────────
let _ttlPasswordSet = false;

View File

@@ -1,87 +1,159 @@
<!DOCTYPE html>
<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>Home xXx Sphere</title>
<link rel="stylesheet" href="/css/variables.css">
<link rel="stylesheet" href="/css/style.css">
<style>
.game-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 1.25rem;
margin-top: 1.5rem;
}
.game-card {
background: var(--color-secondary);
border: 1px solid var(--color-secondary);
border-radius: 12px;
padding: 1.5rem 1.25rem;
display: flex;
flex-direction: column;
gap: 0.75rem;
}
.game-card-icon { font-size: 2rem; line-height: 1; }
.game-card-title { font-size: 1.1rem; font-weight: 700; margin: 0; }
.game-card-desc { font-size: 0.88rem; color: var(--color-muted); line-height: 1.6; flex: 1; }
.game-card-btn { margin-top: 0.25rem; width: auto; align-self: flex-start; padding: 0.5rem 1.25rem; }
.welcome { font-size: 0.95rem; color: var(--color-muted); margin: 0.25rem 0 0; }
</style>
</head>
<body class="app">
<div class="main">
<div class="content">
<h1 style="margin:0 0 0.15rem;">Home</h1>
<p class="welcome" id="greeting"></p>
<div class="game-grid">
<div class="game-card">
<div class="game-card-icon"></div>
<h2 class="game-card-title">Vanilla Game</h2>
<p class="game-card-desc">
Entdecke spielerische Rollenspiele und Aufgaben in einem entspannten Rahmen.
Ideal für den Einstieg ohne Regeln, nur Spaß zu zweit oder in der Gruppe.
</p>
<a href="/games/vanilla/sessionvanilla.html"><button class="game-card-btn">Neue Session starten</button></a>
</div>
<div class="game-card">
<div class="game-card-icon"></div>
<h2 class="game-card-title">BDSM Game</h2>
<p class="game-card-desc">
Tauche ein in strukturierte Sessions mit Aufgaben, Toys und klaren Rollen.
Definiere Grenzen, vergib Aufgaben und erlebe intensive Momente mit deinem Partner.
</p>
<a href="/games/bdsm/neubdsm.html"><button class="game-card-btn">Neue Session starten</button></a>
</div>
<div class="game-card">
<div class="game-card-icon"></div>
<h2 class="game-card-title">Chastity Game</h2>
<p class="game-card-desc">
Erlebe Keuschheit auf eine neue Art: Kartenbasierte Locks, Keyholder-System,
Community-Abstimmungen und tägliche Verifizierungen machen jedes Lock einzigartig.
</p>
<a href="/games/chastity/neulock.html"><button class="game-card-btn">Neues Lock erstellen</button></a>
</div>
</div>
</div>
</div>
<!DOCTYPE html>
<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>Home xXx Sphere</title>
<link rel="stylesheet" href="/css/variables.css">
<link rel="stylesheet" href="/css/style.css">
<style>
.game-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 1.25rem;
margin-top: 1.5rem;
}
.game-card {
background: var(--color-secondary);
border: 1px solid var(--color-secondary);
border-radius: 12px;
padding: 1.5rem 1.25rem;
display: flex;
flex-direction: column;
gap: 0.75rem;
}
.game-card-icon { font-size: 2rem; line-height: 1; }
.game-card-title { font-size: 1.1rem; font-weight: 700; margin: 0; }
.game-card-desc { font-size: 0.88rem; color: var(--color-muted); line-height: 1.6; flex: 1; }
.game-card-btn { margin-top: 0.25rem; width: auto; align-self: flex-start; padding: 0.5rem 1.25rem; }
.welcome { font-size: 0.95rem; color: var(--color-muted); margin: 0.25rem 0 0; }
.section-label {
font-size: 0.8rem; font-weight: 600; color: var(--color-muted);
text-transform: uppercase; letter-spacing: 0.05em;
margin: 2rem 0 0.75rem;
padding-bottom: 0.5rem;
border-bottom: 1px solid var(--color-secondary);
}
.visitors-strip {
display: flex; flex-wrap: wrap; gap: 0.75rem;
}
.visitor-card {
display: flex; flex-direction: column; align-items: center; gap: 0.3rem;
text-decoration: none; color: var(--color-text);
width: 72px;
}
.visitor-card:hover .visitor-avatar { border-color: var(--color-primary); }
.visitor-avatar {
width: 56px; height: 56px; border-radius: 50%;
background: var(--color-secondary);
border: 2px solid var(--color-secondary);
display: flex; align-items: center; justify-content: center;
font-size: 1.4rem; overflow: hidden; flex-shrink: 0;
transition: border-color 0.15s;
}
.visitor-avatar img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; }
.visitor-name {
font-size: 0.75rem; text-align: center;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
width: 100%;
}
.visitor-time { font-size: 0.68rem; color: var(--color-muted); text-align: center; }
</style>
</head>
<body class="app">
<div class="main">
<div class="content">
<h1 style="margin:0 0 0.15rem;">Home</h1>
<p class="welcome" id="greeting"></p>
<div class="game-grid">
<div class="game-card">
<div class="game-card-icon"></div>
<h2 class="game-card-title">Vanilla Game</h2>
<p class="game-card-desc">
Entdecke spielerische Rollenspiele und Aufgaben in einem entspannten Rahmen.
Ideal für den Einstieg ohne Regeln, nur Spaß zu zweit oder in der Gruppe.
</p>
<a href="/games/vanilla/sessionvanilla.html"><button class="game-card-btn">Neue Session starten</button></a>
</div>
<div class="game-card">
<div class="game-card-icon"></div>
<h2 class="game-card-title">BDSM Game</h2>
<p class="game-card-desc">
Tauche ein in strukturierte Sessions mit Aufgaben, Toys und klaren Rollen.
Definiere Grenzen, vergib Aufgaben und erlebe intensive Momente mit deinem Partner.
</p>
<a href="/games/bdsm/neubdsm.html"><button class="game-card-btn">Neue Session starten</button></a>
</div>
<div class="game-card">
<div class="game-card-icon"></div>
<h2 class="game-card-title">Chastity Game</h2>
<p class="game-card-desc">
Erlebe Keuschheit auf eine neue Art: Kartenbasierte Locks, Keyholder-System,
Community-Abstimmungen und tägliche Verifizierungen machen jedes Lock einzigartig.
</p>
<a href="/games/chastity/neulock.html"><button class="game-card-btn">Neues Lock erstellen</button></a>
</div>
</div>
<!-- Profilbesucher -->
<div id="visitorsSection" style="display:none;">
<div class="section-label">Profilbesucher</div>
<div class="visitors-strip" id="visitorsStrip"></div>
</div>
</div>
</div>
<script src="/js/icons.js"></script>
<script src="/js/sidebar.js"></script>
<script>
fetch('/login/me')
.then(r => {
if (r.status === 401) { window.location.href = '/login.html'; return null; }
return r.json();
})
.then(user => {
if (user) document.getElementById('greeting').textContent = 'Willkommen zurück, ' + user.name + '!';
})
.catch(() => { window.location.href = '/login.html'; });
</script>
</body>
</html>
<script src="/js/sidebar.js"></script>
<script>
fetch('/login/me')
.then(r => {
if (r.status === 401) { window.location.href = '/login.html'; return null; }
return r.json();
})
.then(user => {
if (user) {
document.getElementById('greeting').textContent = 'Willkommen zurück, ' + user.name + '!';
loadVisitors();
}
})
.catch(() => { window.location.href = '/login.html'; });
function relativeTime(isoString) {
const diff = Math.floor((Date.now() - new Date(isoString)) / 1000);
if (diff < 60) return 'gerade eben';
if (diff < 3600) return 'vor ' + Math.floor(diff / 60) + ' Min.';
if (diff < 86400) return 'vor ' + Math.floor(diff / 3600) + ' Std.';
return 'vor ' + Math.floor(diff / 86400) + ' Tag' + (Math.floor(diff / 86400) === 1 ? '' : 'en');
}
async function loadVisitors() {
try {
const res = await fetch('/social/profile-visits/my-visitors');
if (!res.ok) return;
const visitors = await res.json();
if (!visitors.length) return;
const strip = document.getElementById('visitorsStrip');
strip.innerHTML = visitors.map(v => `
<a class="visitor-card" href="/community/benutzer.html?userId=${v.userId}">
<div class="visitor-avatar">
${v.profilePicture
? `<img src="data:image/png;base64,${v.profilePicture}" alt="${v.name}">`
: '◉'}
</div>
<span class="visitor-name">${v.name}</span>
<span class="visitor-time">${relativeTime(v.visitedAt)}</span>
</a>
`).join('');
document.getElementById('visitorsSection').style.display = '';
} catch (_) {}
}
</script>
</body>
</html>

369
bin/main/txt/vorlieben1.txt Normal file
View File

@@ -0,0 +1,369 @@
[Hardcore-Fetisch]
- 24/7
- BDSM Branding
- Double Penetration
- Edge Play
- Elektrostimulation
- Fesselspiele
- Feuerspiele
- Fisting
- Genitalfolter
- Hardcore Sex
- Kastrations-Spiele
- Knife Play
- Predicament Bondage
- Trampling
- Wasser Bondage
[BDSM]
- Abandonment Play
- Angstspiele
- Badezimmerverweigerung
- Bastinado
- BDSM
- Beißen
- Bizarr
- Bondage
- Atemspiele
- Ketten
- Keuschheit
- Defilement
- Disziplin
- Dominanz
- Edging
- Erotisches Wrestling
- Ohrfeigen
- Feederism
- Figging
- Lebendmöbel
- Erniedrigung
- Klistier Fetisch
- Masochismus
- Brust/Nippel-Behandlung
- Orgasmuskontrolle
- Kneifen
- Post-Orgasmus-Folter
- Prostata Melken
- Sadismus
- Kratzen
- Sensory Deprivation
- Sissification
- Small Penis Humilation
- Spanking
- Devot
- Süßer Schmerz
- Suspension Bondage
- Hoden Bondage
- Unterwürfigkeit
- Wachsspiele
- Wedgies
[Körper-Fetisch]
- Achselfetisch
- Augen Fetisch
- Baby Birding Fetisch
- Bauch Fetisch
- Bein Fetisch
- Bauchnabel Fetisch
- Titten
- Rülpsfetisch
- Busen Fetisch
- Hintern
- Beschnitten
- Dacryphilie
- Dicke Männer
- Furz Fetisch
- Frottage
- Fußfetisch
- Haar Fetisch
- Handfetisch
- Kopf-Rasier-Fetisch
- Hygrophilie
- Intimpiercing
- Kitzelfetisch
- Körperbehaarung
- Körpermodifikation
- Schamlippen
- Erotische Laktation
- Lecken
- Lippen Fetisch
- Makrophilie
- Mikropenis
- Body Worship
- Nagelfetisch
- Nippel
- Olfaktophilie
- Pee Desperation
- Periodenblut Fetisch
- Piercings
- Piquerismus
- Mollig
- Rasur Fetisch
- Rauchfetisch
- Rimming
- Schamhaare
- Nies Fetisch
- Sommersprossenfetisch
- Sperma
- Sploshing
- Spuck-Fetisch
- Squirting
- Tattoo Fetisch
- Hoden
- Unbeschnitten
- Adern
- Vore
- Natursekt
[Fetisch-Spiele]
- Wickel-Fetisch
- Age Play
- Animal Play
- Betteln
- Cosplay
- Crossplay
- Dirty Talk
- Doktorspiele
- Escortspiele
- Weibliche Dominanz
- Female Masking
- Furry Sex
- Gefangenenrollenspiele
- Geschlechterrollenspiele
- Handwerker - Hausfrau
- Klinik Sex
- Pegging
- Puppy Play
- Rollenspiele
- Sklaven Erziehung
- Vampir Spiele
- Weiße Erotik
- Werwolf Fetisch
[Exibitionismus und Voyeurismus]
- Aktfotografie
- Amateurvideos drehen
- Exhibitionismus
- Lap Dance
- Striptease
- Voyeurismus
[Außergewöhnliche sexuelle Vorlieben]
- Akzent-Fetisch
- Aquaphilie
- Ballon Fetisch
- Brillen Fetisch
- Clown Fetisch
- Dendrophilie
- Endytophilie
- Hypnose Fetisch
- Futanari
- Hochzeitsring-Fetisch
- Nymphoman
- Paraphilie
- Roboterfetischismus
- Samt-Fetisch
- Sapiosexuell
- Sexsomnia
- Xenophilie
[Fetisch Ausstattung]
- Anal Haken
- Aufblasbarer Knebel
- Augenbinde
- Ball Crusher
- Ball Gag
- Bondage Halsband
- BDSM Pranger
- Bodybag
- Bondage Bett
- Bondage Fesseln
- Bondage Gürtel
- Bondage Handschellen
- Bondage Handschuhe
- Bondage Harness
- Bondage Joch
- Bondage Käfig
- Bondage Maske
- Mundschutz Knebel
- Bondage Seil
- Bondage Schlafsack
- Bondage Tape
- Bondage Trichter
- Brust Binder
- Viehtreiber
- Keuschheitsgürtel
- Halsband und Leine
- Elektrostimulationsstab
- Ellbogenfessel
- Fesselung
- Flogger
- Knebel
- Gasmasken
- Handschellen
- Human Pony Harness
- Humbler
- Mundspreitzer
- Kopfharness
- Masturbations-Maschine
- Medizinische Fesseln
- Monohandschuh
- Muzzle Gag
- Nasen-Haken
- Nadeln
- Paddle
- Penis Knebel
- Plastikfolie
- Posture Collar
- Ring Knebel
- Fickmaschine
- Spreader Bar
- Suspension Cuffs
- Taser
- Vakuumbett
- Vampirhandschuhe
- Peitschen
- Zwangsjacke
[Vanilla Sex und Softcore-Fetisch]
- Analspiele
- Analsex
- Anonymer Sex
- Kuscheln
- Cunnilingus
- Deep Throat
- Dreier
- Facesitting
- Weibliche Ejakulation
- Fingern
- Vorspiel
- Haare ziehen
- Handjob
- Kamasutra
- Poppen
- Küssen
- Massagen
- Selbstbefriedigung
- Multiple Orgasmen
- Gegenseitiges Masturbieren
- Oralsex
- Telefonsex
- Prostata Orgasmus
- Quickies
- Sex auf der Waschmaschine
- Im Bett
- Sex in der Dusche
- Spermaspiele
- Sperma schlucken
- Tantramassage
- Blümchensex
- VR Sex
[Sexspielzeug]
- Anal-Kette
- Analplugs
- Ben-Wa-Kugeln
- Dildos
- Fleshlight
- Klitorispumpe
- Nippelklemme
- Penisring
- Prostata Stimulatoren
- Sex Stuhl
- Sexspielzeug
- Sexpuppe
- Sexschaukel
- Umschnalldildo
- Sybian
- Vibrations-Ei
- Vibratoren
- Massagestab
[Sexuelle Orientierung]
- Metrosexualität
- Asexuell
- Bisexualität
- Cisgender
- Heterosexuell
- Homosexuell
- Intersexualität
- Lesbisch
- Non-Binary
- Pansexuell
- Queer
- Trans Mann
- Trans Frau
[Fetisch-Kleidung]
- Anzug-Fetisch
- BDSM Gimp
- Gürtel
- Korsetts
- Dessous Fetisch
- Elastan Fetisch
- Fetisch Outfits
- Handschuhfetisch
- Gummi Fetisch
- High Heels
- Humpelrock
- Kostüme
- Lack Fetisch
- Latex Fetisch
- Leder Fetisch
- Leggins-Fetisch
- Masken
- Nylon Fetisch
- Pelzfetisch
- PVC Fetisch
- Schuh Fetisch
- Seiden Fetisch
- Socken Fetisch
- Sportbekleidung
- Steampunk
- Strumpfhosen Fetisch
- Unterwäsche-Fetisch
- Uniform Fetisch
- Wetlook
- Windelfetisch
[Kinky Lifestyle]
- Caregiver & Little
- Crossdresser
- Cuckold
- Cuckold Bull
- Erotische Kunst
- Filmen
- Erotische Geschichten
- FFM Dreier
- Freie Liebe
- Gangbang
- Gothic
- Gruppensex
- Hentai & Anime
- MMF Dreier
- FKK
- Partnertausch
- Polyamorie
- Pornos
- Sex Chat
- Sex mit Älteren
- Sex mit Jüngeren
- Sexting
- Swinger
- Tantra
[Sex in der Öffentlichkeit]
- Parkplatzsex
- Pornokino
- Sex am Arbeitsplatz
- Sex am Strand
- Sex auf der Toilette
- Sex im Auto
- Sex im Fahrstuhl
- Sex im Freien
- Sex im Kino
- Sex im Schwimmbad
- Sex im Swingerclub
- Sex im Wasser
- Sex in der Sauna
- Sex in der Umkleide

View File

@@ -0,0 +1,75 @@
[Vergnügen oder Tabu]
- Analsex
- Augen verbinden
- Blowjob
- Cunnilingus
- Fisting
- Handjob
- Harter Sex
- Küssen
- Kuschelsex
- Normaler Sex
- Rimming
- Selbstbefriedigung
- Slow Sex
- Spanking
[Spielarten]
- Bondage, Fesseln
- Dessous
- Fetisch
- Fußerotik
- High Heels
- Kamasutra
- Korsetts & Corsagen
- Lack, Leder & Latex
- Massagen
- Natursekt
- Nylons
- Nymphoman
- Rollenspiele
- SM, BDSM
- Sexspielzeug
- Spermaspiele
- Squirting
- Strapon-Sex
- Tantra
[Körperliche Vorlieben]
- Ältere
- Intimbehaarung
- Intimrasur
- Intimschmuck
- Jüngere
- Körperbehaarung
- Mollig
- Piercings
- Schlank
- Tattoos
[Lustvolle Abenteuer]
- Besondere Orte
- Cuckolding
- Dreier FFM
- Dreier MMF
- Exhibitionismus
- FKK
- Frivoles Ausgehen
- Gangbang
- Gruppensex
- Outdoor
- Paarsex MFMF
- Strip
- Wifesharing
- Zuschauen
- Zuschauen lassen
[Unterhaltung]
- Bildertausch
- Dirty Talk
- Erotische Chats
- Filmen
- Fotografieren
- Pornos
- Telefonsex
- Webcam

View File

@@ -0,0 +1,198 @@
[Sex & Erotik]
- Analsex
- Analspiele
- Anonymer Sex
- Blowjob
- Cunnilingus
- Deep Throat
- Dreier
- Facesitting
- Fingern
- Gegenseitiges Masturbieren
- Handjob
- Haare ziehen
- Küssen
- Kuscheln
- Massagen
- Normaler Sex
- Oralsex
- Pegging
- Prostata Orgasmus
- Quickies
- Rimming
- Selbstbefriedigung
- Sex in der Dusche
- Slow Sex
- Squirting
- Tantramassage
- Vorspiel
- Weibliche Ejakulation
[BDSM & Bondage]
- Atemspiele
- Bondage / Fesseln
- Brust/Nippel-Behandlung
- Disziplin
- Dominanz & Submission
- Double Penetration
- Edge Play
- Edging
- Elektrostimulation
- Erniedrigung
- Feederism
- Fisting
- Keuschheit
- Knife Play
- Masochismus
- Orgasmuskontrolle
- Post-Orgasmus-Folter
- Sadismus
- Sensory Deprivation
- Sklaven Erziehung
- Spanking
- Suspension Bondage
- Trampling
- Wachsspiele
[Rollenspiele & Fantasien]
- Age Play
- Animal Play / Puppy Play
- Caregiver & Little
- Cosplay
- Dirty Talk
- Doktorspiele
- Escortspiele
- Gefangenenrollenspiele
- Geschlechterrollenspiele
- Handwerker - Hausfrau
- Klinik Sex
- Rollenspiele
- Vampir Spiele
- Weibliche Dominanz
- Weiße Erotik
[Körper & Fetische]
- Achselfetisch
- Bauch Fetisch
- Body Worship
- Busen Fetisch
- Erotische Laktation
- Frottage
- Fußfetisch
- Hintern
- Intimbehaarung
- Intimrasur
- Kitzelfetisch
- Körperbehaarung
- Lecken
- Mollig
- Natursekt
- Nippel
- Piercings
- Rasur Fetisch
- Schamhaare
- Spermaspiele
- Spuck-Fetisch
- Tattoos
- Titten
[Fetisch-Kleidung]
- Dessous
- Gummi Fetisch
- High Heels
- Kostüme
- Korsetts
- Lack Fetisch
- Latex Fetisch
- Leder Fetisch
- Masken
- Nylons / Strumpfhosen
- Sportbekleidung
- Uniform Fetisch
- Unterwäsche
- Wetlook
- Windelfetisch
[Sexspielzeug & Equipment]
- Anal-Kette
- Analplugs
- Augenbinde
- Ben-Wa-Kugeln
- Bondage Seil
- Dildos
- Elektrostimulationsstab
- Flogger
- Handschellen
- Halsband und Leine
- Keuschheitsgürtel
- Knebel
- Massagestab
- Nippelklemme
- Penisring
- Peitschen
- Sexpuppe
- Spreader Bar
- Umschnalldildo
- Vibratoren
[Lifestyle & Beziehungsformen]
- Crossdresser
- Cuckold
- Dreier FFM
- Dreier MMF
- FKK
- Freie Liebe
- Gangbang
- Gothic
- Gruppensex
- Paarsex MFMF
- Partnertausch
- Polyamorie
- Swinger
- Tantra
- Wifesharing
[Öffentlichkeit & Voyeurismus]
- Aktfotografie
- Amateurvideos drehen
- Exhibitionismus
- Lap Dance
- Outdoor / Sex im Freien
- Parkplatzsex
- Pornokino
- Sex am Strand
- Sex im Auto
- Sex im Swingerclub
- Sex in der Sauna
- Sex in der Umkleide
- Striptease
- Voyeurismus
- Zuschauen / Zuschauen lassen
[Digitale Erotik & Medien]
- Bildertausch
- Erotische Chats
- Erotische Geschichten
- Filmen / Fotografieren
- Hentai & Anime
- Pornos
- Sex Chat
- Sexting
- Telefonsex
- VR Sex
- Webcam
[Sexuelle Orientierung & Identität]
- Asexuell
- Bisexualität
- Cisgender
- Heterosexuell
- Homosexuell
- Lesbisch
- Metrosexualität
- Non-Binary
- Pansexuell
- Queer
- Sapiosexuell
- Trans Mann
- Trans Frau

View File

@@ -422,7 +422,7 @@ public class AdminController {
@GetMapping("/subscriptions/user/{userId}")
public ResponseEntity<SubscriptionStatusDto> getSubscriptionStatus(
@PathVariable UUID userId, Principal principal) {
@PathVariable("userId") UUID userId, Principal principal) {
requireSuperAdmin(principal);
UserEntity user = userRepository.findById(userId).orElse(null);
if (user == null) return ResponseEntity.notFound().build();

View File

@@ -153,8 +153,8 @@ public class FeedController {
// ── GET /feed/mine ──
@GetMapping("/mine")
public ResponseEntity<FeedPage> getMyFeed(@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size,
public ResponseEntity<FeedPage> getMyFeed(@RequestParam(name = "page", defaultValue = "0") int page,
@RequestParam(name = "size", defaultValue = "10") int size,
Principal principal) {
UUID myId = resolveMyId(principal);
if (myId == null) return ResponseEntity.status(401).build();
@@ -202,8 +202,8 @@ public class FeedController {
// ── GET /feed/public ──
@GetMapping("/public")
public ResponseEntity<FeedPage> getPublicFeed(@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size,
public ResponseEntity<FeedPage> getPublicFeed(@RequestParam(name = "page", defaultValue = "0") int page,
@RequestParam(name = "size", defaultValue = "10") int size,
Principal principal) {
UUID myId = resolveMyId(principal);
if (myId == null) return ResponseEntity.status(401).build();
@@ -221,9 +221,9 @@ public class FeedController {
// ── GET /feed/user/{userId} ──
@GetMapping("/user/{userId}")
public ResponseEntity<FeedPage> getUserPosts(@PathVariable UUID userId,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size,
public ResponseEntity<FeedPage> getUserPosts(@PathVariable("userId") UUID userId,
@RequestParam(name = "page", defaultValue = "0") int page,
@RequestParam(name = "size", defaultValue = "10") int size,
Principal principal) {
UUID myId = resolveMyId(principal);
if (myId == null) return ResponseEntity.status(401).build();
@@ -255,7 +255,7 @@ public class FeedController {
// ── POST /feed/posts/{id}/like ──
@PostMapping("/posts/{id}/like")
public ResponseEntity<Void> toggleLike(@PathVariable UUID id, Principal principal) {
public ResponseEntity<Void> toggleLike(@PathVariable("id") UUID id, Principal principal) {
UUID myId = resolveMyId(principal);
if (myId == null) return ResponseEntity.status(401).build();
if (feedPostRepository.findById(id).isEmpty()) return ResponseEntity.notFound().build();
@@ -267,7 +267,7 @@ public class FeedController {
// ── POST /feed/posts/{id}/vote ──
@PostMapping("/posts/{id}/vote")
public ResponseEntity<Void> vote(@PathVariable UUID id,
public ResponseEntity<Void> vote(@PathVariable("id") UUID id,
@RequestBody VoteRequest req,
Principal principal) {
UUID myId = resolveMyId(principal);
@@ -307,7 +307,7 @@ public class FeedController {
// ── DELETE /feed/posts/{id} ──
@DeleteMapping("/posts/{id}")
public ResponseEntity<Void> deletePost(@PathVariable UUID id, Principal principal) {
public ResponseEntity<Void> deletePost(@PathVariable("id") UUID id, Principal principal) {
UUID myId = resolveMyId(principal);
if (myId == null) return ResponseEntity.status(401).build();

View File

@@ -51,8 +51,8 @@ public class AboController {
@GetMapping("/list")
public ResponseEntity<AufgabenGruppePage> listSubscribed(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "" + DEFAULT_PAGE_SIZE) int size,
@RequestParam(name = "page", defaultValue = "0") int page,
@RequestParam(name = "size", defaultValue = "" + DEFAULT_PAGE_SIZE) int size,
Principal principal) {
UserEntity user = userService.requireUser(principal);
@@ -71,8 +71,8 @@ public class AboController {
@GetMapping("/discover")
public ResponseEntity<AufgabenGruppePage> discover(
@RequestParam(required = false) String name,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "" + DISCOVER_PAGE_SIZE) int size,
@RequestParam(name = "page", defaultValue = "0") int page,
@RequestParam(name = "size", defaultValue = "" + DISCOVER_PAGE_SIZE) int size,
Principal principal) {
UserEntity user = userService.requireUser(principal);
@@ -91,7 +91,7 @@ public class AboController {
// ── Abonnieren ──
@PostMapping("/{gruppenId}")
public ResponseEntity<Void> subscribe(@PathVariable UUID gruppenId, Principal principal) {
public ResponseEntity<Void> subscribe(@PathVariable("gruppenId") UUID gruppenId, Principal principal) {
UserEntity user = userService.requireUser(principal);
AufgabenGruppeEntity gruppe = gruppeRepository.findById(gruppenId).orElse(null);
@@ -113,7 +113,7 @@ public class AboController {
// ── Abonnement kündigen ──
@DeleteMapping("/{gruppenId}")
public ResponseEntity<Void> unsubscribe(@PathVariable UUID gruppenId, Principal principal) {
public ResponseEntity<Void> unsubscribe(@PathVariable("gruppenId") UUID gruppenId, Principal principal) {
UserEntity user = userService.requireUser(principal);
AufgabenGruppeEntity gruppe = gruppeRepository.findById(gruppenId).orElse(null);

View File

@@ -55,7 +55,7 @@ public class AufgabeController {
}
@GetMapping("/{aufgabeId}")
public ResponseEntity<Aufgabe> get(@PathVariable UUID aufgabeId) {
public ResponseEntity<Aufgabe> get(@PathVariable("aufgabeId") UUID aufgabeId) {
return aufgabeRepository.findById(aufgabeId)
.map(entity -> ResponseEntity.ok(entity.toAufgabe()))
.orElse(ResponseEntity.noContent().build());
@@ -84,7 +84,7 @@ public class AufgabeController {
}
@PutMapping("/{aufgabeId}")
public ResponseEntity<Void> update(@PathVariable UUID aufgabeId, @RequestBody Aufgabe aufgabe) {
public ResponseEntity<Void> update(@PathVariable("aufgabeId") UUID aufgabeId, @RequestBody Aufgabe aufgabe) {
if (aufgabe.getKurzText() == null || aufgabe.getText() == null || aufgabe.getLevel() == null) {
return ResponseEntity.badRequest().build();
}

View File

@@ -79,8 +79,8 @@ public class AufgabenGruppeController {
@GetMapping("/list/user")
public ResponseEntity<AufgabenGruppePage> listUser(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "" + DEFAULT_PAGE_SIZE) int size,
@RequestParam(name = "page", defaultValue = "0") int page,
@RequestParam(name = "size", defaultValue = "" + DEFAULT_PAGE_SIZE) int size,
Principal principal) {
UserEntity user = resolveUser(principal);
if (user == null) return ResponseEntity.status(401).build();
@@ -91,8 +91,8 @@ public class AufgabenGruppeController {
@GetMapping("/list/system")
public ResponseEntity<AufgabenGruppePage> listSystem(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "" + DEFAULT_PAGE_SIZE) int size) {
@RequestParam(name = "page", defaultValue = "0") int page,
@RequestParam(name = "size", defaultValue = "" + DEFAULT_PAGE_SIZE) int size) {
Page<AufgabenGruppeEntity> result = gruppeRepository.findByUserIdIsNull(
PageRequest.of(page, size, Sort.by("name")));
return ResponseEntity.ok(toGruppePage(result));
@@ -111,7 +111,7 @@ public class AufgabenGruppeController {
}
@GetMapping("/own")
public ResponseEntity<AufgabenGruppeList> getOwn(@RequestParam UUID userId) {
public ResponseEntity<AufgabenGruppeList> getOwn(@RequestParam("userId") UUID userId) {
AufgabenGruppeList list = new AufgabenGruppeList();
list.setGruppen(gruppeRepository.findByUserId(userId)
.stream().map(AufgabenGruppeEntity::toAufgabenGruppeDisplay).toList());
@@ -119,7 +119,7 @@ public class AufgabenGruppeController {
}
@GetMapping("/{gruppeId}")
public ResponseEntity<AufgabenGruppe> get(@PathVariable UUID gruppeId) {
public ResponseEntity<AufgabenGruppe> get(@PathVariable("gruppeId") UUID gruppeId) {
return gruppeRepository.findById(gruppeId)
.map(entity -> ResponseEntity.ok(entity.toAufgabenGruppe()))
.orElse(ResponseEntity.noContent().build());
@@ -152,7 +152,7 @@ public class AufgabenGruppeController {
// ── Bearbeiten ──
@PutMapping("/{gruppeId}")
public ResponseEntity<Void> update(@PathVariable UUID gruppeId,
public ResponseEntity<Void> update(@PathVariable("gruppeId") UUID gruppeId,
@RequestBody AufgabenGruppe gruppe,
Principal principal) {
if (gruppe.getName() == null || gruppe.getName().isBlank()) {
@@ -180,7 +180,7 @@ public class AufgabenGruppeController {
// ── Kopieren (Systemgruppe → eigene) ──
@PostMapping("/copy/{gruppeId}")
public ResponseEntity<Void> copy(@PathVariable UUID gruppeId, Principal principal) {
public ResponseEntity<Void> copy(@PathVariable("gruppeId") UUID gruppeId, Principal principal) {
UserEntity user = resolveUser(principal);
if (user == null) return ResponseEntity.status(401).build();
try {
@@ -198,7 +198,7 @@ public class AufgabenGruppeController {
// ── Löschen ──
@DeleteMapping("/{gruppeId}")
public ResponseEntity<Void> deleteById(@PathVariable UUID gruppeId, Principal principal) {
public ResponseEntity<Void> deleteById(@PathVariable("gruppeId") UUID gruppeId, Principal principal) {
UserEntity user = resolveUser(principal);
if (user == null) return ResponseEntity.status(401).build();

View File

@@ -104,7 +104,7 @@ public class BdsmEinladungController {
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> cancelEinladung(@PathVariable UUID id, Principal principal) {
public ResponseEntity<Void> cancelEinladung(@PathVariable("id") UUID id, Principal principal) {
UUID userId = currentUserId(principal);
if (userId == null) return ResponseEntity.status(401).build();
BdsmEinladungEntity e = einladungRepository.findById(id).orElse(null);
@@ -116,7 +116,7 @@ public class BdsmEinladungController {
}
@GetMapping
public ResponseEntity<List<Map<String, Object>>> getBySetupId(@RequestParam UUID setupId, Principal principal) {
public ResponseEntity<List<Map<String, Object>>> getBySetupId(@RequestParam("setupId") UUID setupId, Principal principal) {
UUID userId = currentUserId(principal);
if (userId == null) return ResponseEntity.status(401).build();
List<Map<String, Object>> list = einladungRepository.findBySetupId(setupId).stream()
@@ -191,7 +191,7 @@ public class BdsmEinladungController {
}
@PutMapping("/{id}/spielerdaten")
public ResponseEntity<Void> spielerDatenEinreichen(@PathVariable UUID id, @RequestBody SpielerDatenRequest req, Principal principal) {
public ResponseEntity<Void> spielerDatenEinreichen(@PathVariable("id") UUID id, @RequestBody SpielerDatenRequest req, Principal principal) {
UUID userId = currentUserId(principal);
if (userId == null) return ResponseEntity.status(401).build();
BdsmEinladungEntity e = einladungRepository.findById(id).orElse(null);
@@ -204,7 +204,7 @@ public class BdsmEinladungController {
}
@PutMapping("/{id}/antwort")
public ResponseEntity<Void> antwort(@PathVariable UUID id, @RequestBody AntwortRequest req, Principal principal) {
public ResponseEntity<Void> antwort(@PathVariable("id") UUID id, @RequestBody AntwortRequest req, Principal principal) {
UUID userId = currentUserId(principal);
if (userId == null) return ResponseEntity.status(401).build();
BdsmEinladungEntity e = einladungRepository.findById(id).orElse(null);

View File

@@ -97,14 +97,14 @@ public class BdsmGameController {
}
@GetMapping("/{sessionId}")
public ResponseEntity<BdsmGame> getBySessionId(@PathVariable UUID sessionId) {
public ResponseEntity<BdsmGame> getBySessionId(@PathVariable("sessionId") UUID sessionId) {
return sessionRepository.findById(sessionId)
.map(entity -> ResponseEntity.ok(toSession(entity)))
.orElse(ResponseEntity.noContent().build());
}
@GetMapping
public ResponseEntity<BdsmGame> getByUserId(@RequestParam UUID userId) {
public ResponseEntity<BdsmGame> getByUserId(@RequestParam("userId") UUID userId) {
return sessionRepository.findByUserId(userId)
.map(entity -> ResponseEntity.ok(toSession(entity)))
.orElse(ResponseEntity.noContent().build());
@@ -158,7 +158,7 @@ public class BdsmGameController {
}
@PostMapping("/{sessionId}/abgeschlossen")
public ResponseEntity<Void> spielAbgeschlossen(@PathVariable UUID sessionId) {
public ResponseEntity<Void> spielAbgeschlossen(@PathVariable("sessionId") UUID sessionId) {
BdsmGameEntity entity = sessionRepository.findById(sessionId).orElse(null);
if (entity == null) return ResponseEntity.notFound().build();
ORDENTLICH_BEENDET.add(sessionId);
@@ -168,13 +168,13 @@ public class BdsmGameController {
/** Prüft ob eine Session ordentlich (nicht abgebrochen) beendet wurde. */
@GetMapping("/{sessionId}/beendet")
public ResponseEntity<Void> istBeendet(@PathVariable UUID sessionId) {
public ResponseEntity<Void> istBeendet(@PathVariable("sessionId") UUID sessionId) {
if (ORDENTLICH_BEENDET.remove(sessionId)) return ResponseEntity.ok().build();
return ResponseEntity.notFound().build();
}
@DeleteMapping("/{sessionId}/verlassen")
public ResponseEntity<Void> verlasseSpiel(@PathVariable UUID sessionId, Principal principal) {
public ResponseEntity<Void> verlasseSpiel(@PathVariable("sessionId") UUID sessionId, Principal principal) {
UUID userId = userService.requireUser(principal).getUserId();
BdsmGameEntity session = sessionRepository.findById(sessionId).orElse(null);
@@ -200,7 +200,7 @@ public class BdsmGameController {
}
@PostMapping("/{sessionId}/aufgaben")
public ResponseEntity<Void> setAufgaben(@RequestBody AufgabenList list, @PathVariable UUID sessionId) {
public ResponseEntity<Void> setAufgaben(@RequestBody AufgabenList list, @PathVariable("sessionId") UUID sessionId) {
try {
if (list.size() > 1000) {
return ResponseEntity.badRequest().build();
@@ -227,7 +227,7 @@ public class BdsmGameController {
}
@GetMapping("/{sessionId}/aufgaben/next")
public ResponseEntity<AufgabeAnzeige> getNextAufgabe(@PathVariable UUID sessionId) {
public ResponseEntity<AufgabeAnzeige> getNextAufgabe(@PathVariable("sessionId") UUID sessionId) {
try {
BdsmGameEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null || session.getAufgaben() == null) {
@@ -258,7 +258,7 @@ public class BdsmGameController {
}
@PostMapping("/{sessionId}/mitspieler")
public ResponseEntity<Void> addMitspieler(@RequestBody BdsmMitspieler mitspieler, @PathVariable UUID sessionId) {
public ResponseEntity<Void> addMitspieler(@RequestBody BdsmMitspieler mitspieler, @PathVariable("sessionId") UUID sessionId) {
if (mitspieler.getName() == null || mitspieler.getGeschlecht() == null || mitspieler.getRollen() == null
|| mitspieler.getRollen().isEmpty() || mitspieler.getSpieltMit() == null || mitspieler.getSpieltMit().isEmpty()
|| mitspieler.getVerfuegbareWerkzeuge() == null || mitspieler.getVerfuegbareWerkzeuge().isEmpty()) {
@@ -313,7 +313,7 @@ public class BdsmGameController {
}
@GetMapping("/{sessionId}/finisher")
public ResponseEntity<List<AufgabeAnzeige>> getFinisher(@PathVariable UUID sessionId) {
public ResponseEntity<List<AufgabeAnzeige>> getFinisher(@PathVariable("sessionId") UUID sessionId) {
try {
BdsmGameEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null) return ResponseEntity.badRequest().build();
@@ -326,7 +326,7 @@ public class BdsmGameController {
}
@PostMapping("/{sessionId}/backToLevel5")
public ResponseEntity<Void> backToLevel5(@PathVariable UUID sessionId) {
public ResponseEntity<Void> backToLevel5(@PathVariable("sessionId") UUID sessionId) {
try {
BdsmGameEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null) return ResponseEntity.badRequest().build();
@@ -343,7 +343,7 @@ public class BdsmGameController {
}
@GetMapping("/{sessionId}/mitspieler/me")
public ResponseEntity<Map<String, Object>> getMeinMitspieler(@PathVariable UUID sessionId, Principal principal) {
public ResponseEntity<Map<String, Object>> getMeinMitspieler(@PathVariable("sessionId") UUID sessionId, Principal principal) {
UUID userId = userService.requireUser(principal).getUserId();
BdsmGameEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null) return ResponseEntity.notFound().build();
@@ -366,7 +366,7 @@ public class BdsmGameController {
@PostMapping("/{sessionId}/active-task/abschliessen")
public ResponseEntity<AbschliessenResponse> activeTaskAbschliessen(
@PathVariable UUID sessionId, @RequestBody AbschliessenRequest req) {
@PathVariable("sessionId") UUID sessionId, @RequestBody AbschliessenRequest req) {
BdsmGameEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null) return ResponseEntity.notFound().build();
@@ -413,7 +413,7 @@ public class BdsmGameController {
record ActiveTaskResponse(String taskJson, Long elapsedSeconds) {}
@PutMapping("/{sessionId}/active-task")
public ResponseEntity<Void> setActiveTask(@PathVariable UUID sessionId, @RequestBody ActiveTaskRequest req) {
public ResponseEntity<Void> setActiveTask(@PathVariable("sessionId") UUID sessionId, @RequestBody ActiveTaskRequest req) {
BdsmGameEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null) return ResponseEntity.notFound().build();
session.setActiveTaskJson(req.taskJson());
@@ -423,7 +423,7 @@ public class BdsmGameController {
}
@DeleteMapping("/{sessionId}/active-task")
public ResponseEntity<Void> clearActiveTask(@PathVariable UUID sessionId) {
public ResponseEntity<Void> clearActiveTask(@PathVariable("sessionId") UUID sessionId) {
BdsmGameEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null) return ResponseEntity.notFound().build();
session.setActiveTaskJson(null);
@@ -433,7 +433,7 @@ public class BdsmGameController {
}
@GetMapping("/{sessionId}/active-task")
public ResponseEntity<ActiveTaskResponse> getActiveTask(@PathVariable UUID sessionId) {
public ResponseEntity<ActiveTaskResponse> getActiveTask(@PathVariable("sessionId") UUID sessionId) {
BdsmGameEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null) return ResponseEntity.notFound().build();
if (session.getActiveTaskJson() == null) return ResponseEntity.noContent().build();
@@ -446,7 +446,7 @@ public class BdsmGameController {
// ── Keyholder-Angebot: prüft ob am Ende eine VAGINA/PENIS-Sperre vorliegt ──
@GetMapping("/{sessionId}/keyholder-angebot")
public ResponseEntity<Map<String, Object>> keyholderAngebot(@PathVariable UUID sessionId) {
public ResponseEntity<Map<String, Object>> keyholderAngebot(@PathVariable("sessionId") UUID sessionId) {
BdsmGameEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null) return ResponseEntity.notFound().build();
@@ -484,7 +484,7 @@ public class BdsmGameController {
@GetMapping("/{sessionId}/keyholder-locks")
public ResponseEntity<List<Map<String, Object>>> keyholderLocks(
@PathVariable UUID sessionId, @RequestParam UUID keyholderUserId) {
@PathVariable("sessionId") UUID sessionId, @RequestParam("keyholderUserId") UUID keyholderUserId) {
BdsmGameEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null) return ResponseEntity.notFound().build();
@@ -508,7 +508,7 @@ public class BdsmGameController {
@PostMapping("/{sessionId}/zu-chastity")
public ResponseEntity<Map<String, Object>> zuChastity(
@PathVariable UUID sessionId, @RequestBody ZuChastityRequest req) {
@PathVariable("sessionId") UUID sessionId, @RequestBody ZuChastityRequest req) {
try {
CardLockEntity newLock = bdsmGameService.zuChastity(
sessionId, req.lockId(), req.lockeeUserId(), req.keyholderUserId());
@@ -527,7 +527,7 @@ public class BdsmGameController {
/** Gibt zurück welches Werkzeug für einen User durch ein aktives Chastity-Lock blockiert ist. */
@GetMapping("/chastity-constraint")
public ResponseEntity<Map<String, Object>> chastityConstraint(@RequestParam UUID userId) {
public ResponseEntity<Map<String, Object>> chastityConstraint(@RequestParam("userId") UUID userId) {
Map<String, Object> result = new LinkedHashMap<>();
if (!cardlockRepository.existsByLockeeAndStartTimeIsNotNullAndUnlockTimeIsNull(userId)) {
result.put("lockedWerkzeug", null);
@@ -552,7 +552,7 @@ public class BdsmGameController {
// ── Debug-Endpoint: vollständiger Entity-Zustand ──
@GetMapping("/{sessionId}/debug")
public ResponseEntity<Map<String, Object>> debug(@PathVariable UUID sessionId) {
public ResponseEntity<Map<String, Object>> debug(@PathVariable("sessionId") UUID sessionId) {
BdsmGameEntity entity = sessionRepository.findById(sessionId).orElse(null);
if (entity == null) return ResponseEntity.notFound().build();

View File

@@ -39,7 +39,7 @@ public class FavoritController {
}
@GetMapping("/{favoritId}")
public ResponseEntity<Favorit> get(@PathVariable UUID favoritId) {
public ResponseEntity<Favorit> get(@PathVariable("favoritId") UUID favoritId) {
return favoritRepository.findById(favoritId)
.map(entity -> ResponseEntity.ok(entity.toFavorit()))
.orElse(ResponseEntity.noContent().build());

View File

@@ -47,7 +47,7 @@ public class FinisherController {
}
@GetMapping("/{finisherId}")
public ResponseEntity<Finisher> get(@PathVariable UUID finisherId) {
public ResponseEntity<Finisher> get(@PathVariable("finisherId") UUID finisherId) {
return finisherRepository.findById(finisherId)
.map(entity -> ResponseEntity.ok(entity.toFinisher()))
.orElse(ResponseEntity.noContent().build());
@@ -76,7 +76,7 @@ public class FinisherController {
}
@PutMapping("/{finisherId}")
public ResponseEntity<Void> update(@PathVariable UUID finisherId, @RequestBody Finisher finisher) {
public ResponseEntity<Void> update(@PathVariable("finisherId") UUID finisherId, @RequestBody Finisher finisher) {
if (finisher.getKurzText() == null || finisher.getText() == null || finisher.getGeschlecht() == null) {
return ResponseEntity.badRequest().build();
}

View File

@@ -47,7 +47,7 @@ public class SperreController {
}
@GetMapping("/{sperreId}")
public ResponseEntity<Sperre> get(@PathVariable UUID sperreId) {
public ResponseEntity<Sperre> get(@PathVariable("sperreId") UUID sperreId) {
return sperreRepository.findById(sperreId)
.map(entity -> ResponseEntity.ok(entity.toSperre()))
.orElse(ResponseEntity.noContent().build());
@@ -76,7 +76,7 @@ public class SperreController {
}
@PutMapping("/{sperreId}")
public ResponseEntity<Void> update(@PathVariable UUID sperreId, @RequestBody Sperre sperre) {
public ResponseEntity<Void> update(@PathVariable("sperreId") UUID sperreId, @RequestBody Sperre sperre) {
if (sperre.getKurzText() == null || sperre.getText() == null || sperre.getMinutenVon() == null
|| sperre.getSperreFuer() == null || sperre.getSperreFuer().isEmpty()) {
return ResponseEntity.badRequest().build();

View File

@@ -47,7 +47,7 @@ public class StrafeController {
}
@GetMapping("/{strafeId}")
public ResponseEntity<Strafe> get(@PathVariable UUID strafeId) {
public ResponseEntity<Strafe> get(@PathVariable("strafeId") UUID strafeId) {
return strafeRepository.findById(strafeId)
.map(entity -> ResponseEntity.ok(entity.toStrafe()))
.orElse(ResponseEntity.noContent().build());
@@ -75,7 +75,7 @@ public class StrafeController {
}
@PutMapping("/{strafeId}")
public ResponseEntity<Void> update(@PathVariable UUID strafeId, @RequestBody Strafe strafe) {
public ResponseEntity<Void> update(@PathVariable("strafeId") UUID strafeId, @RequestBody Strafe strafe) {
if (strafe.getKurzText() == null || strafe.getText() == null || strafe.getLevel() == null) {
return ResponseEntity.badRequest().build();
}

View File

@@ -61,8 +61,8 @@ public class ToyController {
@GetMapping("/list/user")
public ResponseEntity<ToyPage> listUser(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "" + DEFAULT_PAGE_SIZE) int size,
@RequestParam(name = "page", defaultValue = "0") int page,
@RequestParam(name = "size", defaultValue = "" + DEFAULT_PAGE_SIZE) int size,
Principal principal) {
UserEntity user = userService.requireUser(principal);
Page<ToyEntity> result = toyRepository.findByUserId(
@@ -72,8 +72,8 @@ public class ToyController {
@GetMapping("/list/system")
public ResponseEntity<ToyPage> listSystem(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "" + DEFAULT_PAGE_SIZE) int size) {
@RequestParam(name = "page", defaultValue = "0") int page,
@RequestParam(name = "size", defaultValue = "" + DEFAULT_PAGE_SIZE) int size) {
Page<ToyEntity> result = toyRepository.findByUserIdIsNull(
PageRequest.of(page, size, Sort.by("name")));
return ResponseEntity.ok(toToyPage(result));
@@ -121,7 +121,7 @@ public class ToyController {
}
@GetMapping("/{toyId}")
public ResponseEntity<Toy> get(@PathVariable UUID toyId) {
public ResponseEntity<Toy> get(@PathVariable("toyId") UUID toyId) {
return toyRepository.findById(toyId)
.map(entity -> ResponseEntity.ok(entity.toToy()))
.orElse(ResponseEntity.noContent().build());
@@ -154,7 +154,7 @@ public class ToyController {
}
@PostMapping("/copy/{toyId}")
public ResponseEntity<Void> copy(@PathVariable UUID toyId, Principal principal) {
public ResponseEntity<Void> copy(@PathVariable("toyId") UUID toyId, Principal principal) {
UserEntity user = userService.requireUser(principal);
ToyEntity source = toyRepository.findById(toyId).orElse(null);
if (source == null) {
@@ -180,7 +180,7 @@ public class ToyController {
}
@PutMapping("/{toyId}")
public ResponseEntity<Void> update(@PathVariable UUID toyId, @RequestBody Toy toy, Principal principal) {
public ResponseEntity<Void> update(@PathVariable("toyId") UUID toyId, @RequestBody Toy toy, Principal principal) {
if (toy.getName() == null || toy.getName().isBlank()) {
return ResponseEntity.badRequest().build();
}
@@ -209,7 +209,7 @@ public class ToyController {
}
@DeleteMapping("/{toyId}")
public ResponseEntity<Void> delete(@PathVariable UUID toyId, Principal principal) {
public ResponseEntity<Void> delete(@PathVariable("toyId") UUID toyId, Principal principal) {
UserEntity user = userService.requireUser(principal);
ToyEntity toy = toyRepository.findById(toyId).orElse(null);
if (toy == null) {

View File

@@ -270,7 +270,7 @@ public class CardLockController {
@PostMapping("/cardlock/{lockId}/draw")
@Transactional
public ResponseEntity<Map<String, Object>> drawCard(@PathVariable UUID lockId, Principal principal) {
public ResponseEntity<Map<String, Object>> drawCard(@PathVariable("lockId") UUID lockId, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var lockOpt = cardlockRepository.findById(lockId);
@@ -309,7 +309,7 @@ public class CardLockController {
@PostMapping("/cardlock/{lockId}/hygiene/start")
@Transactional
public ResponseEntity<Map<String, Object>> startHygieneOpening(@PathVariable UUID lockId, Principal principal) {
public ResponseEntity<Map<String, Object>> startHygieneOpening(@PathVariable("lockId") UUID lockId, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var lockOpt = cardlockRepository.findById(lockId);
@@ -326,7 +326,7 @@ public class CardLockController {
@PostMapping("/cardlock/{lockId}/hygiene/end")
@Transactional
public ResponseEntity<Map<String, Object>> endHygieneOpening(@PathVariable UUID lockId, Principal principal) {
public ResponseEntity<Map<String, Object>> endHygieneOpening(@PathVariable("lockId") UUID lockId, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var lockOpt = cardlockRepository.findById(lockId);
@@ -342,7 +342,7 @@ public class CardLockController {
@PostMapping("/cardlock/{lockId}/task/complete")
@Transactional
public ResponseEntity<Void> completeTask(@PathVariable UUID lockId, Principal principal) {
public ResponseEntity<Void> completeTask(@PathVariable("lockId") UUID lockId, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var lockOpt = cardlockRepository.findById(lockId);
@@ -359,7 +359,7 @@ public class CardLockController {
@PostMapping("/cardlock/{lockId}/relock")
@Transactional
public ResponseEntity<Void> relock(@PathVariable UUID lockId, Principal principal) {
public ResponseEntity<Void> relock(@PathVariable("lockId") UUID lockId, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var lockOpt = cardlockRepository.findById(lockId);
@@ -375,7 +375,7 @@ public class CardLockController {
@PostMapping("/cardlock/{lockId}/green/keep")
@Transactional
public ResponseEntity<Void> greenKeep(@PathVariable UUID lockId, Principal principal) {
public ResponseEntity<Void> greenKeep(@PathVariable("lockId") UUID lockId, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var lockOpt = cardlockRepository.findById(lockId);
@@ -409,7 +409,7 @@ public class CardLockController {
}
@GetMapping("/cardlock/{lockId}")
public ResponseEntity<Map<String, Object>> getLock(@PathVariable UUID lockId, Principal principal) {
public ResponseEntity<Map<String, Object>> getLock(@PathVariable("lockId") UUID lockId, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var lockOpt = cardlockRepository.findById(lockId);
@@ -587,7 +587,7 @@ public class CardLockController {
@PostMapping("/cardlock/{lockId}/verification/start")
@Transactional
public ResponseEntity<Map<String, Object>> startVerification(@PathVariable UUID lockId, Principal principal) {
public ResponseEntity<Map<String, Object>> startVerification(@PathVariable("lockId") UUID lockId, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var lockOpt = cardlockRepository.findById(lockId);
@@ -629,7 +629,7 @@ public class CardLockController {
@PostMapping(value = "/cardlock/{lockId}/verification/{verificationId}/complete", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@Transactional
public ResponseEntity<Void> completeVerification(@PathVariable UUID lockId, @PathVariable UUID verificationId,
public ResponseEntity<Void> completeVerification(@PathVariable("lockId") UUID lockId, @PathVariable("verificationId") UUID verificationId,
@RequestParam MultipartFile image, Principal principal) throws IOException {
UUID myId = userService.requireUser(principal).getUserId();
@@ -683,7 +683,7 @@ public class CardLockController {
@DeleteMapping("/cardlock/{lockId}/verification/today")
@Transactional
public ResponseEntity<Void> renewVerification(@PathVariable UUID lockId, Principal principal) {
public ResponseEntity<Void> renewVerification(@PathVariable("lockId") UUID lockId, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var lockOpt = cardlockRepository.findById(lockId);
@@ -852,7 +852,7 @@ public class CardLockController {
}
@GetMapping("/as-keyholder/{lockId}")
public ResponseEntity<Map<String, Object>> getLockAsKeyholder(@PathVariable UUID lockId, Principal principal) {
public ResponseEntity<Map<String, Object>> getLockAsKeyholder(@PathVariable("lockId") UUID lockId, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var lockOpt = cardlockRepository.findById(lockId);
@@ -1009,7 +1009,7 @@ public class CardLockController {
@Transactional
@DeleteMapping("/cardlock/{lockId}")
public ResponseEntity<Void> deleteLock(@PathVariable UUID lockId, Principal principal) {
public ResponseEntity<Void> deleteLock(@PathVariable("lockId") UUID lockId, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var lockOpt = cardlockRepository.findById(lockId);
@@ -1037,7 +1037,7 @@ public class CardLockController {
@PostMapping("/as-keyholder/{lockId}/cards/add")
@Transactional
public ResponseEntity<Void> addCards(@PathVariable UUID lockId, @RequestBody ModifyCardsRequest req,
public ResponseEntity<Void> addCards(@PathVariable("lockId") UUID lockId, @RequestBody ModifyCardsRequest req,
Principal principal) {
var me = userService.requireUser(principal);
UUID myId = me.getUserId();
@@ -1084,7 +1084,7 @@ public class CardLockController {
@PostMapping("/as-keyholder/{lockId}/cards/remove")
@Transactional
public ResponseEntity<Map<String, String>> removeCards(@PathVariable UUID lockId,
public ResponseEntity<Map<String, String>> removeCards(@PathVariable("lockId") UUID lockId,
@RequestBody ModifyCardsRequest req, Principal principal) {
var me = userService.requireUser(principal);
UUID myId = me.getUserId();
@@ -1176,7 +1176,7 @@ public class CardLockController {
@Transactional
@PostMapping("/as-keyholder/{lockId}/assign-task")
public ResponseEntity<?> assignTask(@PathVariable UUID lockId, @RequestBody AssignTaskRequest req,
public ResponseEntity<?> assignTask(@PathVariable("lockId") UUID lockId, @RequestBody AssignTaskRequest req,
Principal principal) {
var me = userService.requireUser(principal);
@@ -1228,7 +1228,7 @@ public class CardLockController {
@Transactional
@PostMapping("/cardlock/{lockId}/assigned-tasks/{taskId}/accept")
public ResponseEntity<?> acceptAssignedTask(@PathVariable UUID lockId, @PathVariable UUID taskId,
public ResponseEntity<?> acceptAssignedTask(@PathVariable("lockId") UUID lockId, @PathVariable("taskId") UUID taskId,
Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
@@ -1287,7 +1287,7 @@ public class CardLockController {
@Transactional
@PostMapping("/cardlock/{lockId}/assigned-tasks/{taskId}/decline")
public ResponseEntity<?> declineAssignedTask(@PathVariable UUID lockId, @PathVariable UUID taskId,
public ResponseEntity<?> declineAssignedTask(@PathVariable("lockId") UUID lockId, @PathVariable("taskId") UUID taskId,
Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
@@ -1320,7 +1320,7 @@ public class CardLockController {
@Transactional
@DeleteMapping("/as-keyholder/{lockId}/assigned-tasks/{taskId}")
public ResponseEntity<?> cancelAssignedTask(@PathVariable UUID lockId, @PathVariable UUID taskId,
public ResponseEntity<?> cancelAssignedTask(@PathVariable("lockId") UUID lockId, @PathVariable("taskId") UUID taskId,
Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
@@ -1347,7 +1347,7 @@ public class CardLockController {
@Transactional
@PostMapping("/as-keyholder/{lockId}/freeze")
public ResponseEntity<?> freezeLock(@PathVariable UUID lockId, @RequestBody FreezeRequest req,
public ResponseEntity<?> freezeLock(@PathVariable("lockId") UUID lockId, @RequestBody FreezeRequest req,
Principal principal) {
var me = userService.requireUser(principal);
UUID myId = me.getUserId();
@@ -1388,7 +1388,7 @@ public class CardLockController {
@Transactional
@DeleteMapping("/as-keyholder/{lockId}/freeze")
public ResponseEntity<?> unfreezeLock(@PathVariable UUID lockId, Principal principal) {
public ResponseEntity<?> unfreezeLock(@PathVariable("lockId") UUID lockId, Principal principal) {
var me = userService.requireUser(principal);
UUID myId = me.getUserId();
@@ -1414,7 +1414,7 @@ public class CardLockController {
@Transactional
@PostMapping("/as-keyholder/{lockId}/request-unlock")
public ResponseEntity<?> requestUnlock(@PathVariable UUID lockId, Principal principal) {
public ResponseEntity<?> requestUnlock(@PathVariable("lockId") UUID lockId, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var lockOpt = cardlockRepository.findById(lockId);
@@ -1436,7 +1436,7 @@ public class CardLockController {
@Transactional
@PostMapping("/cardlock/{lockId}/emergency-unlock")
public ResponseEntity<?> requestEmergencyUnlock(@PathVariable UUID lockId, Principal principal) {
public ResponseEntity<?> requestEmergencyUnlock(@PathVariable("lockId") UUID lockId, Principal principal) {
var me = userService.requireUser(principal);
UUID myId = me.getUserId();

View File

@@ -93,7 +93,7 @@ public class CardlockTemplateController {
}
@PutMapping("/{id}")
public ResponseEntity<Map<String, Object>> update(@PathVariable UUID id,
public ResponseEntity<Map<String, Object>> update(@PathVariable("id") UUID id,
@RequestBody TemplateRequest req,
Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
@@ -114,7 +114,7 @@ public class CardlockTemplateController {
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> delete(@PathVariable UUID id, Principal principal) {
public ResponseEntity<Void> delete(@PathVariable("id") UUID id, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var opt = templateRepository.findById(id);

View File

@@ -26,8 +26,8 @@ public class BaseLockTemplateController {
@GetMapping
public ResponseEntity<Map<String, Object>> list(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "20") int size,
@RequestParam(name = "page", defaultValue = "0") int page,
@RequestParam(name = "size", defaultValue = "20") int size,
Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
@@ -57,7 +57,7 @@ public class BaseLockTemplateController {
}
@GetMapping("/{id}")
public ResponseEntity<Map<String, Object>> getById(@PathVariable UUID id, Principal principal) {
public ResponseEntity<Map<String, Object>> getById(@PathVariable("id") UUID id, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var opt = templateRepository.findById(id);

View File

@@ -48,8 +48,8 @@ public class TemplateExploreController {
@GetMapping("/public")
public ResponseEntity<Map<String, Object>> getPublicTemplates(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size,
@RequestParam(name = "page", defaultValue = "0") int page,
@RequestParam(name = "size", defaultValue = "10") int size,
@RequestParam(defaultValue = "") String q,
Principal principal) {
@@ -80,7 +80,7 @@ public class TemplateExploreController {
@GetMapping("/{id}/public")
public ResponseEntity<Map<String, Object>> getTemplate(
@PathVariable UUID id, Principal principal) {
@PathVariable("id") UUID id, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var tOpt = templateRepository.findById(id);
@@ -131,7 +131,7 @@ public class TemplateExploreController {
@PostMapping("/{id}/subscribe")
@Transactional
public ResponseEntity<Void> subscribe(@PathVariable UUID id, Principal principal) {
public ResponseEntity<Void> subscribe(@PathVariable("id") UUID id, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var tOpt = templateRepository.findById(id);
@@ -157,7 +157,7 @@ public class TemplateExploreController {
@DeleteMapping("/{id}/subscribe")
@Transactional
public ResponseEntity<Void> unsubscribe(@PathVariable UUID id, Principal principal) {
public ResponseEntity<Void> unsubscribe(@PathVariable("id") UUID id, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var subOpt = subscriptionRepository.findByUserIdAndTemplateId(myId, id);
@@ -177,7 +177,7 @@ public class TemplateExploreController {
@PostMapping("/{id}/fork")
@Transactional
public ResponseEntity<Map<String, Object>> fork(@PathVariable UUID id, Principal principal) {
public ResponseEntity<Map<String, Object>> fork(@PathVariable("id") UUID id, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var tOpt = templateRepository.findById(id);
@@ -233,7 +233,7 @@ public class TemplateExploreController {
@PatchMapping("/{id}/publish")
@Transactional
public ResponseEntity<Void> publish(@PathVariable UUID id, Principal principal) {
public ResponseEntity<Void> publish(@PathVariable("id") UUID id, Principal principal) {
var me = userService.requireUser(principal);
var tOpt = templateRepository.findById(id);
@@ -251,7 +251,7 @@ public class TemplateExploreController {
@DeleteMapping("/{id}/publish")
@Transactional
public ResponseEntity<Void> unpublish(@PathVariable UUID id, Principal principal) {
public ResponseEntity<Void> unpublish(@PathVariable("id") UUID id, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var tOpt = templateRepository.findById(id);

View File

@@ -20,7 +20,7 @@ public class CommunityPilloryController {
}
@GetMapping("/{id}")
public ResponseEntity<CommunityPilloryDTO> getPillory(@PathVariable UUID id) {
public ResponseEntity<CommunityPilloryDTO> getPillory(@PathVariable("id") UUID id) {
var pillory = repo.findById(id);
if (pillory.isPresent()) {
return ResponseEntity.ok(pillory.get().toPillory());

View File

@@ -36,7 +36,7 @@ public class CommunityTaskVoteController {
}
@GetMapping("/{displayId}")
public ResponseEntity<CommunityTaskVoteDisplayDTO> getVote(@PathVariable UUID displayId, Principal principal) {
public ResponseEntity<CommunityTaskVoteDisplayDTO> getVote(@PathVariable("displayId") UUID displayId, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var voteOpt = taskVoteRepository.findById(displayId);
@@ -69,7 +69,7 @@ public class CommunityTaskVoteController {
@PostMapping("/{displayId}/vote/{taskIndex}")
@Transactional
public ResponseEntity<Void> castVote(@PathVariable UUID displayId, @PathVariable int taskIndex,
public ResponseEntity<Void> castVote(@PathVariable("displayId") UUID displayId, @PathVariable("taskIndex") int taskIndex,
Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();

View File

@@ -40,7 +40,7 @@ public class CommunityVerificationController {
}
@GetMapping("/{displayId}")
public ResponseEntity<CommunityVerificationDTO> get(@PathVariable UUID displayId, Principal principal) {
public ResponseEntity<CommunityVerificationDTO> get(@PathVariable("displayId") UUID displayId, Principal principal) {
var optional = verificationRepository.findById(displayId);
if (optional.isEmpty()) {
return ResponseEntity.noContent().build();
@@ -81,7 +81,7 @@ public class CommunityVerificationController {
}
@PutMapping("/{displayId}")
public ResponseEntity<Void> update(@PathVariable UUID displayId, @RequestBody CommunityVerificationDTO dto,
public ResponseEntity<Void> update(@PathVariable("displayId") UUID displayId, @RequestBody CommunityVerificationDTO dto,
Principal principal) {
userService.requireUser(principal);
var entity = verificationRepository.findById(displayId).orElse(null);
@@ -99,7 +99,7 @@ public class CommunityVerificationController {
}
@PostMapping("/{verificationId}/vote/")
public ResponseEntity<Void> addVote(@PathVariable UUID verificationId, @RequestBody CommunityVerificationVoteDTO dto,
public ResponseEntity<Void> addVote(@PathVariable("verificationId") UUID verificationId, @RequestBody CommunityVerificationVoteDTO dto,
Principal principal) {
var user = userService.requireUser(principal);
if (!verificationRepository.existsById(verificationId)) return ResponseEntity.notFound().build();

View File

@@ -144,7 +144,7 @@ public class KeyholderOfferController {
@PatchMapping("/{id}")
@Transactional
public ResponseEntity<Map<String, Object>> updateOffer(
@PathVariable UUID id,
@PathVariable("id") UUID id,
@RequestBody CreateOfferRequest req,
Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
@@ -177,7 +177,7 @@ public class KeyholderOfferController {
@DeleteMapping("/{id}")
@Transactional
public ResponseEntity<Void> deleteOffer(@PathVariable UUID id, Principal principal) {
public ResponseEntity<Void> deleteOffer(@PathVariable("id") UUID id, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var offerOpt = offerRepository.findById(id);
@@ -192,7 +192,7 @@ public class KeyholderOfferController {
@GetMapping("/user/{userId}")
public ResponseEntity<List<Map<String, Object>>> getOffersForUser(
@PathVariable UUID userId, Principal principal) {
@PathVariable("userId") UUID userId, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
List<Map<String, Object>> result = offerRepository.findByOffererId(userId).stream()
@@ -231,7 +231,7 @@ public class KeyholderOfferController {
@PostMapping("/{id}/join")
@Transactional
public ResponseEntity<Map<String, Object>> joinOffer(
@PathVariable UUID id,
@PathVariable("id") UUID id,
@RequestBody JoinOfferRequest req,
Principal principal) {

View File

@@ -84,8 +84,8 @@ public class KeyholderTaskChoiceController {
@PostMapping("/{choiceId}/choose/{taskIndex}")
@Transactional
public ResponseEntity<Void> chooseTask(@PathVariable UUID choiceId,
@PathVariable int taskIndex,
public ResponseEntity<Void> chooseTask(@PathVariable("choiceId") UUID choiceId,
@PathVariable("taskIndex") int taskIndex,
@org.springframework.web.bind.annotation.RequestBody(required = false) PenaltyRequest penalty,
Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();

View File

@@ -191,7 +191,7 @@ public class TimeLockController {
@GetMapping("/timelock/{lockId}")
@Transactional
public ResponseEntity<Map<String, Object>> getTimeLock(@PathVariable UUID lockId, Principal principal) {
public ResponseEntity<Map<String, Object>> getTimeLock(@PathVariable("lockId") UUID lockId, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var lockOpt = timeLockRepository.findById(lockId);
@@ -374,7 +374,7 @@ public class TimeLockController {
@PostMapping("/timelock/{lockId}/spin")
@Transactional
public ResponseEntity<Map<String, Object>> spin(@PathVariable UUID lockId, Principal principal) {
public ResponseEntity<Map<String, Object>> spin(@PathVariable("lockId") UUID lockId, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var lockOpt = timeLockRepository.findById(lockId);
@@ -424,7 +424,7 @@ public class TimeLockController {
@PostMapping("/timelock/{lockId}/relock")
@Transactional
public ResponseEntity<Void> relock(@PathVariable UUID lockId, Principal principal) {
public ResponseEntity<Void> relock(@PathVariable("lockId") UUID lockId, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var lockOpt = timeLockRepository.findById(lockId);
@@ -440,7 +440,7 @@ public class TimeLockController {
@PostMapping("/timelock/{lockId}/task/done")
@Transactional
public ResponseEntity<Void> taskDone(@PathVariable UUID lockId, Principal principal) {
public ResponseEntity<Void> taskDone(@PathVariable("lockId") UUID lockId, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var lockOpt = timeLockRepository.findById(lockId);
@@ -462,7 +462,7 @@ public class TimeLockController {
@PostMapping("/timelock/{lockId}/hygiene/start")
@Transactional
public ResponseEntity<Map<String, Object>> startHygiene(@PathVariable UUID lockId, Principal principal) {
public ResponseEntity<Map<String, Object>> startHygiene(@PathVariable("lockId") UUID lockId, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var lockOpt = timeLockRepository.findById(lockId);
@@ -485,7 +485,7 @@ public class TimeLockController {
@PostMapping("/timelock/{lockId}/hygiene/end")
@Transactional
public ResponseEntity<Map<String, Object>> endHygiene(@PathVariable UUID lockId, Principal principal) {
public ResponseEntity<Map<String, Object>> endHygiene(@PathVariable("lockId") UUID lockId, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var lockOpt = timeLockRepository.findById(lockId);
@@ -507,7 +507,7 @@ public class TimeLockController {
@PostMapping("/timelock/{lockId}/verification/start")
@Transactional
public ResponseEntity<Map<String, Object>> startVerification(@PathVariable UUID lockId, Principal principal) {
public ResponseEntity<Map<String, Object>> startVerification(@PathVariable("lockId") UUID lockId, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var lockOpt = timeLockRepository.findById(lockId);
@@ -525,8 +525,8 @@ public class TimeLockController {
consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@Transactional
public ResponseEntity<Void> completeVerification(
@PathVariable UUID lockId,
@PathVariable UUID verificationId,
@PathVariable("lockId") UUID lockId,
@PathVariable("verificationId") UUID verificationId,
@RequestParam MultipartFile image,
Principal principal) throws IOException {
@@ -553,7 +553,7 @@ public class TimeLockController {
@DeleteMapping("/timelock/{lockId}")
@Transactional
public ResponseEntity<Void> endLock(@PathVariable UUID lockId, Principal principal) {
public ResponseEntity<Void> endLock(@PathVariable("lockId") UUID lockId, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var lockOpt = timeLockRepository.findById(lockId);
@@ -594,7 +594,7 @@ public class TimeLockController {
@PatchMapping("/timelock/{lockId}/unlock-time")
@Transactional
public ResponseEntity<Void> setActualUnlockTime(@PathVariable UUID lockId, Principal principal) {
public ResponseEntity<Void> setActualUnlockTime(@PathVariable("lockId") UUID lockId, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var lockOpt = timeLockRepository.findById(lockId);
@@ -644,7 +644,7 @@ public class TimeLockController {
@GetMapping("/timelock/as-keyholder/{lockId}")
public ResponseEntity<Map<String, Object>> getTimeLockAsKeyholder(
@PathVariable UUID lockId, Principal principal) {
@PathVariable("lockId") UUID lockId, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var lockOpt = timeLockRepository.findById(lockId);
@@ -710,7 +710,7 @@ public class TimeLockController {
@PostMapping("/timelock/as-keyholder/{lockId}/request-unlock")
@Transactional
public ResponseEntity<?> requestUnlockAsKeyholder(
@PathVariable UUID lockId, Principal principal) {
@PathVariable("lockId") UUID lockId, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var lockOpt = timeLockRepository.findById(lockId);
@@ -729,7 +729,7 @@ public class TimeLockController {
@PostMapping("/timelock/as-keyholder/{lockId}/freeze")
@Transactional
public ResponseEntity<?> freezeTimeLock(@PathVariable UUID lockId,
public ResponseEntity<?> freezeTimeLock(@PathVariable("lockId") UUID lockId,
@RequestBody FreezeRequest req, Principal principal) {
var me = userService.requireUser(principal);
UUID myId = me.getUserId();
@@ -764,7 +764,7 @@ public class TimeLockController {
@DeleteMapping("/timelock/as-keyholder/{lockId}/freeze")
@Transactional
public ResponseEntity<?> unfreezeTimeLock(@PathVariable UUID lockId, Principal principal) {
public ResponseEntity<?> unfreezeTimeLock(@PathVariable("lockId") UUID lockId, Principal principal) {
var me = userService.requireUser(principal);
UUID myId = me.getUserId();
@@ -790,7 +790,7 @@ public class TimeLockController {
@PostMapping("/timelock/{lockId}/emergency-unlock")
@Transactional
public ResponseEntity<?> requestEmergencyUnlock(@PathVariable UUID lockId, Principal principal) {
public ResponseEntity<?> requestEmergencyUnlock(@PathVariable("lockId") UUID lockId, Principal principal) {
var me = userService.requireUser(principal);
UUID myId = me.getUserId();

View File

@@ -102,7 +102,7 @@ public class TimeLockTemplateController {
}
@PutMapping("/{id}")
public ResponseEntity<Map<String, Object>> update(@PathVariable UUID id,
public ResponseEntity<Map<String, Object>> update(@PathVariable("id") UUID id,
@RequestBody TemplateRequest req,
Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
@@ -121,7 +121,7 @@ public class TimeLockTemplateController {
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> delete(@PathVariable UUID id, Principal principal) {
public ResponseEntity<Void> delete(@PathVariable("id") UUID id, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var opt = templateRepository.findById(id);

View File

@@ -31,7 +31,7 @@ public class GameHistoryController {
@GetMapping
@Transactional(readOnly = true)
public ResponseEntity<List<Map<String, Object>>> get(@RequestParam UUID userId, Principal principal) {
public ResponseEntity<List<Map<String, Object>>> get(@RequestParam("userId") UUID userId, Principal principal) {
userService.requireUser(principal);
var result = gameHistoryRepository.findByParticipantUserId(userId).stream()

View File

@@ -53,8 +53,8 @@ public class VanillaAboController {
@GetMapping("/list")
public ResponseEntity<AufgabenGruppePage> listSubscribed(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "" + DEFAULT_PAGE_SIZE) int size,
@RequestParam(name = "page", defaultValue = "0") int page,
@RequestParam(name = "size", defaultValue = "" + DEFAULT_PAGE_SIZE) int size,
Principal principal) {
UserEntity user = userService.requireUser(principal);
@@ -76,8 +76,8 @@ public class VanillaAboController {
@GetMapping("/discover")
public ResponseEntity<AufgabenGruppePage> discover(
@RequestParam(required = false) String name,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "" + DISCOVER_PAGE_SIZE) int size,
@RequestParam(name = "page", defaultValue = "0") int page,
@RequestParam(name = "size", defaultValue = "" + DISCOVER_PAGE_SIZE) int size,
Principal principal) {
UserEntity user = userService.requireUser(principal);
@@ -104,7 +104,7 @@ public class VanillaAboController {
// ── Abonnieren (nur vanilla-safe) ──
@PostMapping("/{gruppenId}")
public ResponseEntity<Void> subscribe(@PathVariable UUID gruppenId, Principal principal) {
public ResponseEntity<Void> subscribe(@PathVariable("gruppenId") UUID gruppenId, Principal principal) {
UserEntity user = userService.requireUser(principal);
AufgabenGruppeEntity gruppe = gruppeRepository.findById(gruppenId).orElse(null);
@@ -130,7 +130,7 @@ public class VanillaAboController {
// ── Abonnement kündigen ──
@DeleteMapping("/{gruppenId}")
public ResponseEntity<Void> unsubscribe(@PathVariable UUID gruppenId, Principal principal) {
public ResponseEntity<Void> unsubscribe(@PathVariable("gruppenId") UUID gruppenId, Principal principal) {
UserEntity user = userService.requireUser(principal);
AufgabenGruppeEntity gruppe = gruppeRepository.findById(gruppenId).orElse(null);

View File

@@ -55,7 +55,7 @@ public class VanillaAufgabeController {
}
@GetMapping("/{aufgabeId}")
public ResponseEntity<Aufgabe> get(@PathVariable UUID aufgabeId) {
public ResponseEntity<Aufgabe> get(@PathVariable("aufgabeId") UUID aufgabeId) {
return aufgabeRepository.findById(aufgabeId)
.map(entity -> ResponseEntity.ok(entity.toAufgabe()))
.orElse(ResponseEntity.noContent().build());
@@ -84,7 +84,7 @@ public class VanillaAufgabeController {
}
@PutMapping("/{aufgabeId}")
public ResponseEntity<Void> update(@PathVariable UUID aufgabeId, @RequestBody Aufgabe aufgabe) {
public ResponseEntity<Void> update(@PathVariable("aufgabeId") UUID aufgabeId, @RequestBody Aufgabe aufgabe) {
if (aufgabe.getKurzText() == null || aufgabe.getText() == null || aufgabe.getLevel() == null) {
return ResponseEntity.badRequest().build();
}

View File

@@ -79,8 +79,8 @@ public class VanillaAufgabenGruppeController {
@GetMapping("/list/user")
public ResponseEntity<AufgabenGruppePage> listUser(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "" + DEFAULT_PAGE_SIZE) int size,
@RequestParam(name = "page", defaultValue = "0") int page,
@RequestParam(name = "size", defaultValue = "" + DEFAULT_PAGE_SIZE) int size,
Principal principal) {
UserEntity user = resolveUser(principal);
if (user == null) return ResponseEntity.status(401).build();
@@ -100,8 +100,8 @@ public class VanillaAufgabenGruppeController {
@GetMapping("/list/system")
public ResponseEntity<AufgabenGruppePage> listSystem(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "" + DEFAULT_PAGE_SIZE) int size) {
@RequestParam(name = "page", defaultValue = "0") int page,
@RequestParam(name = "size", defaultValue = "" + DEFAULT_PAGE_SIZE) int size) {
Page<AufgabenGruppeEntity> dbPage = gruppeRepository.findSystemGroupsWithContent(
PageRequest.of(page, size, Sort.by("name")));
AufgabenGruppePage r = new AufgabenGruppePage();
@@ -126,7 +126,7 @@ public class VanillaAufgabenGruppeController {
}
@GetMapping("/own")
public ResponseEntity<AufgabenGruppeList> getOwn(@RequestParam UUID userId) {
public ResponseEntity<AufgabenGruppeList> getOwn(@RequestParam("userId") UUID userId) {
AufgabenGruppeList list = new AufgabenGruppeList();
list.setGruppen(gruppeRepository.findByUserId(userId).stream()
.filter(g -> g.getStrafen().isEmpty() && g.getSperren().isEmpty())
@@ -135,7 +135,7 @@ public class VanillaAufgabenGruppeController {
}
@GetMapping("/{gruppeId}")
public ResponseEntity<AufgabenGruppe> get(@PathVariable UUID gruppeId) {
public ResponseEntity<AufgabenGruppe> get(@PathVariable("gruppeId") UUID gruppeId) {
return gruppeRepository.findById(gruppeId)
.filter(g -> g.getStrafen().isEmpty() && g.getSperren().isEmpty())
.map(entity -> ResponseEntity.ok(entity.toAufgabenGruppe()))
@@ -169,7 +169,7 @@ public class VanillaAufgabenGruppeController {
// ── Bearbeiten ──
@PutMapping("/{gruppeId}")
public ResponseEntity<Void> update(@PathVariable UUID gruppeId,
public ResponseEntity<Void> update(@PathVariable("gruppeId") UUID gruppeId,
@RequestBody AufgabenGruppe gruppe,
Principal principal) {
if (gruppe.getName() == null || gruppe.getName().isBlank()) {
@@ -199,7 +199,7 @@ public class VanillaAufgabenGruppeController {
// ── Kopieren (Systemgruppe → eigene) ──
@PostMapping("/copy/{gruppeId}")
public ResponseEntity<Void> copy(@PathVariable UUID gruppeId, Principal principal) {
public ResponseEntity<Void> copy(@PathVariable("gruppeId") UUID gruppeId, Principal principal) {
UserEntity user = resolveUser(principal);
if (user == null) return ResponseEntity.status(401).build();
// Only allow copying vanilla-safe groups
@@ -221,7 +221,7 @@ public class VanillaAufgabenGruppeController {
// ── Löschen ──
@DeleteMapping("/{gruppeId}")
public ResponseEntity<Void> deleteById(@PathVariable UUID gruppeId, Principal principal) {
public ResponseEntity<Void> deleteById(@PathVariable("gruppeId") UUID gruppeId, Principal principal) {
UserEntity user = resolveUser(principal);
if (user == null) return ResponseEntity.status(401).build();

View File

@@ -113,7 +113,7 @@ public class VanillaEinladungController {
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> cancelEinladung(@PathVariable UUID id, Principal principal) {
public ResponseEntity<Void> cancelEinladung(@PathVariable("id") UUID id, Principal principal) {
UUID userId = currentUserId(principal);
if (userId == null) return ResponseEntity.status(401).build();
VanillaEinladungEntity e = einladungRepository.findById(id).orElse(null);
@@ -125,7 +125,7 @@ public class VanillaEinladungController {
}
@GetMapping
public ResponseEntity<List<Map<String, Object>>> getBySetupId(@RequestParam UUID setupId, Principal principal) {
public ResponseEntity<List<Map<String, Object>>> getBySetupId(@RequestParam("setupId") UUID setupId, Principal principal) {
UUID userId = currentUserId(principal);
if (userId == null) return ResponseEntity.status(401).build();
List<Map<String, Object>> list = einladungRepository.findBySetupId(setupId).stream()
@@ -200,7 +200,7 @@ public class VanillaEinladungController {
}
@PutMapping("/{id}/spielerdaten")
public ResponseEntity<Void> spielerDatenEinreichen(@PathVariable UUID id, @RequestBody SpielerDatenRequest req, Principal principal) {
public ResponseEntity<Void> spielerDatenEinreichen(@PathVariable("id") UUID id, @RequestBody SpielerDatenRequest req, Principal principal) {
UUID userId = currentUserId(principal);
if (userId == null) return ResponseEntity.status(401).build();
VanillaEinladungEntity e = einladungRepository.findById(id).orElse(null);
@@ -213,7 +213,7 @@ public class VanillaEinladungController {
}
@PutMapping("/{id}/antwort")
public ResponseEntity<Void> antwort(@PathVariable UUID id, @RequestBody AntwortRequest req, Principal principal) {
public ResponseEntity<Void> antwort(@PathVariable("id") UUID id, @RequestBody AntwortRequest req, Principal principal) {
UUID userId = currentUserId(principal);
if (userId == null) return ResponseEntity.status(401).build();
VanillaEinladungEntity e = einladungRepository.findById(id).orElse(null);

View File

@@ -44,7 +44,7 @@ public class VanillaFavoritController {
}
@GetMapping("/{favoritId}")
public ResponseEntity<Favorit> get(@PathVariable UUID favoritId) {
public ResponseEntity<Favorit> get(@PathVariable("favoritId") UUID favoritId) {
return favoritRepository.findById(favoritId)
.map(entity -> ResponseEntity.ok(entity.toFavorit()))
.orElse(ResponseEntity.noContent().build());

View File

@@ -47,7 +47,7 @@ public class VanillaFinisherController {
}
@GetMapping("/{finisherId}")
public ResponseEntity<Finisher> get(@PathVariable UUID finisherId) {
public ResponseEntity<Finisher> get(@PathVariable("finisherId") UUID finisherId) {
return finisherRepository.findById(finisherId)
.map(entity -> ResponseEntity.ok(entity.toFinisher()))
.orElse(ResponseEntity.noContent().build());
@@ -76,7 +76,7 @@ public class VanillaFinisherController {
}
@PutMapping("/{finisherId}")
public ResponseEntity<Void> update(@PathVariable UUID finisherId, @RequestBody Finisher finisher) {
public ResponseEntity<Void> update(@PathVariable("finisherId") UUID finisherId, @RequestBody Finisher finisher) {
if (finisher.getKurzText() == null || finisher.getText() == null || finisher.getGeschlecht() == null) {
return ResponseEntity.badRequest().build();
}

View File

@@ -78,7 +78,7 @@ public class VanillaGameController {
}
@GetMapping("/{sessionId}")
public ResponseEntity<VanillaGame> getBySessionId(@PathVariable UUID sessionId) {
public ResponseEntity<VanillaGame> getBySessionId(@PathVariable("sessionId") UUID sessionId) {
return sessionRepository.findById(sessionId)
.map(entity -> ResponseEntity.ok(toSession(entity)))
.orElse(ResponseEntity.noContent().build());
@@ -132,7 +132,7 @@ public class VanillaGameController {
}
@PostMapping("/{sessionId}/abgeschlossen")
public ResponseEntity<Void> spielAbgeschlossen(@PathVariable UUID sessionId) {
public ResponseEntity<Void> spielAbgeschlossen(@PathVariable("sessionId") UUID sessionId) {
VanillaGameEntity entity = sessionRepository.findById(sessionId).orElse(null);
if (entity == null) return ResponseEntity.notFound().build();
ORDENTLICH_BEENDET.add(sessionId);
@@ -143,13 +143,13 @@ public class VanillaGameController {
/** Prüft ob eine Session ordentlich (nicht abgebrochen) beendet wurde. */
@GetMapping("/{sessionId}/beendet")
public ResponseEntity<Void> istBeendet(@PathVariable UUID sessionId) {
public ResponseEntity<Void> istBeendet(@PathVariable("sessionId") UUID sessionId) {
if (ORDENTLICH_BEENDET.remove(sessionId)) return ResponseEntity.ok().build();
return ResponseEntity.notFound().build();
}
@DeleteMapping("/{sessionId}/verlassen")
public ResponseEntity<Void> verlasseSpiel(@PathVariable UUID sessionId, Principal principal) {
public ResponseEntity<Void> verlasseSpiel(@PathVariable("sessionId") UUID sessionId, Principal principal) {
UUID userId = userService.requireUser(principal).getUserId();
VanillaGameEntity session = sessionRepository.findById(sessionId).orElse(null);
@@ -174,7 +174,7 @@ public class VanillaGameController {
}
@PostMapping("/{sessionId}/aufgaben")
public ResponseEntity<Void> setAufgaben(@RequestBody AufgabenList list, @PathVariable UUID sessionId) {
public ResponseEntity<Void> setAufgaben(@RequestBody AufgabenList list, @PathVariable("sessionId") UUID sessionId) {
try {
if (list.size() > 1000) {
return ResponseEntity.badRequest().build();
@@ -201,7 +201,7 @@ public class VanillaGameController {
}
@GetMapping("/{sessionId}/aufgaben/next")
public ResponseEntity<VanillaAufgabeAnzeige> getNextAufgabe(@PathVariable UUID sessionId) {
public ResponseEntity<VanillaAufgabeAnzeige> getNextAufgabe(@PathVariable("sessionId") UUID sessionId) {
try {
VanillaGameEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null || session.getAufgaben() == null) {
@@ -229,7 +229,7 @@ public class VanillaGameController {
}
@PostMapping("/{sessionId}/mitspieler")
public ResponseEntity<Void> addMitspieler(@RequestBody VanillaMitspieler mitspieler, @PathVariable UUID sessionId) {
public ResponseEntity<Void> addMitspieler(@RequestBody VanillaMitspieler mitspieler, @PathVariable("sessionId") UUID sessionId) {
if (mitspieler.getName() == null || mitspieler.getVerfuegbareWerkzeuge() == null || mitspieler.getVerfuegbareWerkzeuge().isEmpty()) {
return ResponseEntity.badRequest().build();
}
@@ -253,7 +253,7 @@ public class VanillaGameController {
}
@GetMapping("/{sessionId}/finisher")
public ResponseEntity<List<VanillaAufgabeAnzeige>> getFinisher(@PathVariable UUID sessionId) {
public ResponseEntity<List<VanillaAufgabeAnzeige>> getFinisher(@PathVariable("sessionId") UUID sessionId) {
try {
VanillaGameEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null) return ResponseEntity.badRequest().build();
@@ -266,7 +266,7 @@ public class VanillaGameController {
}
@PostMapping("/{sessionId}/backToLevel5")
public ResponseEntity<Void> backToLevel5(@PathVariable UUID sessionId) {
public ResponseEntity<Void> backToLevel5(@PathVariable("sessionId") UUID sessionId) {
try {
VanillaGameEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null) return ResponseEntity.badRequest().build();
@@ -283,7 +283,7 @@ public class VanillaGameController {
}
@GetMapping("/{sessionId}/mitspieler/me")
public ResponseEntity<Map<String, Object>> getMeinMitspieler(@PathVariable UUID sessionId, Principal principal) {
public ResponseEntity<Map<String, Object>> getMeinMitspieler(@PathVariable("sessionId") UUID sessionId, Principal principal) {
UUID userId = userService.requireUser(principal).getUserId();
VanillaGameEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null) return ResponseEntity.notFound().build();
@@ -305,7 +305,7 @@ public class VanillaGameController {
@PostMapping("/{sessionId}/active-task/abschliessen")
public ResponseEntity<AbschliessenResponse> activeTaskAbschliessen(
@PathVariable UUID sessionId, @RequestBody AbschliessenRequest req) {
@PathVariable("sessionId") UUID sessionId, @RequestBody AbschliessenRequest req) {
VanillaGameEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null) return ResponseEntity.notFound().build();
// Vanilla: keine Sperren/Strafen einfach activeTask löschen
@@ -319,7 +319,7 @@ public class VanillaGameController {
record ActiveTaskResponse(String taskJson, Long elapsedSeconds) {}
@PutMapping("/{sessionId}/active-task")
public ResponseEntity<Void> setActiveTask(@PathVariable UUID sessionId, @RequestBody ActiveTaskRequest req) {
public ResponseEntity<Void> setActiveTask(@PathVariable("sessionId") UUID sessionId, @RequestBody ActiveTaskRequest req) {
VanillaGameEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null) return ResponseEntity.notFound().build();
session.setActiveTaskJson(req.taskJson());
@@ -329,7 +329,7 @@ public class VanillaGameController {
}
@DeleteMapping("/{sessionId}/active-task")
public ResponseEntity<Void> clearActiveTask(@PathVariable UUID sessionId) {
public ResponseEntity<Void> clearActiveTask(@PathVariable("sessionId") UUID sessionId) {
VanillaGameEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null) return ResponseEntity.notFound().build();
session.setActiveTaskJson(null);
@@ -339,7 +339,7 @@ public class VanillaGameController {
}
@GetMapping("/{sessionId}/active-task")
public ResponseEntity<ActiveTaskResponse> getActiveTask(@PathVariable UUID sessionId) {
public ResponseEntity<ActiveTaskResponse> getActiveTask(@PathVariable("sessionId") UUID sessionId) {
VanillaGameEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null) return ResponseEntity.notFound().build();
if (session.getActiveTaskJson() == null) return ResponseEntity.noContent().build();
@@ -352,7 +352,7 @@ public class VanillaGameController {
// ── Debug-Endpoint: vollständiger Entity-Zustand ──
@GetMapping("/{sessionId}/debug")
public ResponseEntity<Map<String, Object>> debug(@PathVariable UUID sessionId) {
public ResponseEntity<Map<String, Object>> debug(@PathVariable("sessionId") UUID sessionId) {
VanillaGameEntity entity = sessionRepository.findById(sessionId).orElse(null);
if (entity == null) return ResponseEntity.notFound().build();

View File

@@ -66,8 +66,8 @@ public class VanillaToyController {
@GetMapping("/list/user")
public ResponseEntity<ToyPage> listUser(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "" + DEFAULT_PAGE_SIZE) int size,
@RequestParam(name = "page", defaultValue = "0") int page,
@RequestParam(name = "size", defaultValue = "" + DEFAULT_PAGE_SIZE) int size,
Principal principal) {
UserEntity user = userService.requireUser(principal);
Page<ToyEntity> result = toyRepository.findByUserId(
@@ -77,8 +77,8 @@ public class VanillaToyController {
@GetMapping("/list/system")
public ResponseEntity<ToyPage> listSystem(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "" + DEFAULT_PAGE_SIZE) int size) {
@RequestParam(name = "page", defaultValue = "0") int page,
@RequestParam(name = "size", defaultValue = "" + DEFAULT_PAGE_SIZE) int size) {
Page<ToyEntity> result = toyRepository.findByUserIdIsNull(
PageRequest.of(page, size, Sort.by("name")));
return ResponseEntity.ok(toToyPage(result));
@@ -144,7 +144,7 @@ public class VanillaToyController {
}
@GetMapping("/{toyId}")
public ResponseEntity<Toy> get(@PathVariable UUID toyId) {
public ResponseEntity<Toy> get(@PathVariable("toyId") UUID toyId) {
return toyRepository.findById(toyId)
.map(entity -> ResponseEntity.ok(entity.toToy()))
.orElse(ResponseEntity.noContent().build());
@@ -177,7 +177,7 @@ public class VanillaToyController {
}
@PostMapping("/copy/{toyId}")
public ResponseEntity<Void> copy(@PathVariable UUID toyId, Principal principal) {
public ResponseEntity<Void> copy(@PathVariable("toyId") UUID toyId, Principal principal) {
UserEntity user = userService.requireUser(principal);
ToyEntity source = toyRepository.findById(toyId).orElse(null);
if (source == null) {
@@ -203,7 +203,7 @@ public class VanillaToyController {
}
@PutMapping("/{toyId}")
public ResponseEntity<Void> update(@PathVariable UUID toyId, @RequestBody Toy toy, Principal principal) {
public ResponseEntity<Void> update(@PathVariable("toyId") UUID toyId, @RequestBody Toy toy, Principal principal) {
if (toy.getName() == null || toy.getName().isBlank()) {
return ResponseEntity.badRequest().build();
}
@@ -232,7 +232,7 @@ public class VanillaToyController {
}
@DeleteMapping("/{toyId}")
public ResponseEntity<Void> delete(@PathVariable UUID toyId, Principal principal) {
public ResponseEntity<Void> delete(@PathVariable("toyId") UUID toyId, Principal principal) {
UserEntity user = userService.requireUser(principal);
ToyEntity toy = toyRepository.findById(toyId).orElse(null);
if (toy == null) {

View File

@@ -113,7 +113,7 @@ public class GruppeController {
// ── GET /gruppe/{id} ──
@GetMapping("/{id}")
public ResponseEntity<GruppeDto> getGruppe(@PathVariable UUID id, Principal principal) {
public ResponseEntity<GruppeDto> getGruppe(@PathVariable("id") UUID id, Principal principal) {
UUID myId = resolveMyId(principal);
if (myId == null) return ResponseEntity.status(401).build();
@@ -155,7 +155,7 @@ public class GruppeController {
// ── PUT /gruppe/{id} ──
@PutMapping("/{id}")
public ResponseEntity<GruppeDto> updateGruppe(@PathVariable UUID id,
public ResponseEntity<GruppeDto> updateGruppe(@PathVariable("id") UUID id,
@RequestBody UpdateGruppeRequest req,
Principal principal) {
UUID myId = resolveMyId(principal);
@@ -180,7 +180,7 @@ public class GruppeController {
// ── DELETE /gruppe/{id} ──
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteGruppe(@PathVariable UUID id, Principal principal) {
public ResponseEntity<Void> deleteGruppe(@PathVariable("id") UUID id, Principal principal) {
UUID myId = resolveMyId(principal);
if (myId == null) return ResponseEntity.status(401).build();
@@ -215,7 +215,7 @@ public class GruppeController {
// ── POST /gruppe/{id}/join ──
@PostMapping("/{id}/join")
public ResponseEntity<Void> join(@PathVariable UUID id,
public ResponseEntity<Void> join(@PathVariable("id") UUID id,
@RequestBody(required = false) JoinRequest req,
Principal principal) {
UUID myId = resolveMyId(principal);
@@ -260,7 +260,7 @@ public class GruppeController {
// ── DELETE /gruppe/{id}/leave ──
@DeleteMapping("/{id}/leave")
public ResponseEntity<Void> leave(@PathVariable UUID id, Principal principal) {
public ResponseEntity<Void> leave(@PathVariable("id") UUID id, Principal principal) {
UUID myId = resolveMyId(principal);
if (myId == null) return ResponseEntity.status(401).build();
@@ -272,7 +272,7 @@ public class GruppeController {
// ── GET /gruppe/{id}/members ──
@GetMapping("/{id}/members")
public ResponseEntity<List<Map<String, Object>>> getMembers(@PathVariable UUID id, Principal principal) {
public ResponseEntity<List<Map<String, Object>>> getMembers(@PathVariable("id") UUID id, Principal principal) {
UUID myId = resolveMyId(principal);
if (myId == null) return ResponseEntity.status(401).build();
if (mitgliedRepository.findFirstByGruppeIdAndUserId(id, myId).isEmpty())
@@ -298,8 +298,8 @@ public class GruppeController {
// ── DELETE /gruppe/{id}/members/{userId} ──
@DeleteMapping("/{id}/members/{userId}")
public ResponseEntity<Void> removeMember(@PathVariable UUID id,
@PathVariable UUID userId,
public ResponseEntity<Void> removeMember(@PathVariable("id") UUID id,
@PathVariable("userId") UUID userId,
Principal principal) {
UUID myId = resolveMyId(principal);
if (myId == null) return ResponseEntity.status(401).build();
@@ -313,8 +313,8 @@ public class GruppeController {
// ── POST /gruppe/{id}/members/{userId}/promote ──
@PostMapping("/{id}/members/{userId}/promote")
public ResponseEntity<Void> promote(@PathVariable UUID id,
@PathVariable UUID userId,
public ResponseEntity<Void> promote(@PathVariable("id") UUID id,
@PathVariable("userId") UUID userId,
Principal principal) {
UUID myId = resolveMyId(principal);
if (myId == null) return ResponseEntity.status(401).build();
@@ -331,7 +331,7 @@ public class GruppeController {
// ── GET /gruppe/{id}/requests ──
@GetMapping("/{id}/requests")
public ResponseEntity<List<BeitrittsanfrageDto>> getRequests(@PathVariable UUID id, Principal principal) {
public ResponseEntity<List<BeitrittsanfrageDto>> getRequests(@PathVariable("id") UUID id, Principal principal) {
UUID myId = resolveMyId(principal);
if (myId == null) return ResponseEntity.status(401).build();
if (!isAdmin(id, myId)) return ResponseEntity.status(403).build();
@@ -353,8 +353,8 @@ public class GruppeController {
// ── POST /gruppe/{id}/requests/{reqId}/approve ──
@PostMapping("/{id}/requests/{reqId}/approve")
public ResponseEntity<Void> approveRequest(@PathVariable UUID id,
@PathVariable UUID reqId,
public ResponseEntity<Void> approveRequest(@PathVariable("id") UUID id,
@PathVariable("reqId") UUID reqId,
Principal principal) {
UUID myId = resolveMyId(principal);
if (myId == null) return ResponseEntity.status(401).build();
@@ -383,8 +383,8 @@ public class GruppeController {
// ── DELETE /gruppe/{id}/requests/{reqId} ──
@DeleteMapping("/{id}/requests/{reqId}")
public ResponseEntity<Void> rejectRequest(@PathVariable UUID id,
@PathVariable UUID reqId,
public ResponseEntity<Void> rejectRequest(@PathVariable("id") UUID id,
@PathVariable("reqId") UUID reqId,
Principal principal) {
UUID myId = resolveMyId(principal);
if (myId == null) return ResponseEntity.status(401).build();
@@ -456,7 +456,7 @@ public class GruppeController {
// ── DELETE /gruppe/{id}/requests/mine (withdraw own request) ──
@DeleteMapping("/{id}/requests/mine")
public ResponseEntity<Void> withdrawRequest(@PathVariable UUID id, Principal principal) {
public ResponseEntity<Void> withdrawRequest(@PathVariable("id") UUID id, Principal principal) {
UUID myId = resolveMyId(principal);
if (myId == null) return ResponseEntity.status(401).build();

View File

@@ -68,8 +68,8 @@ public class GruppenbeitragController {
// ── GET /gruppen/{id}/posts/{postId} ──
@GetMapping("/gruppen/{id}/posts/{postId}")
public ResponseEntity<GruppenbeitragDto> getPost(@PathVariable UUID id,
@PathVariable UUID postId,
public ResponseEntity<GruppenbeitragDto> getPost(@PathVariable("id") UUID id,
@PathVariable("postId") UUID postId,
Principal principal) {
UUID myId = resolveMyId(principal);
if (myId == null) return ResponseEntity.status(401).build();
@@ -83,9 +83,9 @@ public class GruppenbeitragController {
// ── GET /gruppen/{id}/posts ──
@GetMapping("/gruppen/{id}/posts")
public ResponseEntity<PostsPage> getPosts(@PathVariable UUID id,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size,
public ResponseEntity<PostsPage> getPosts(@PathVariable("id") UUID id,
@RequestParam(name = "page", defaultValue = "0") int page,
@RequestParam(name = "size", defaultValue = "10") int size,
Principal principal) {
UUID myId = resolveMyId(principal);
if (myId == null) return ResponseEntity.status(401).build();
@@ -103,7 +103,7 @@ public class GruppenbeitragController {
// ── POST /gruppen/{id}/posts ──
@PostMapping("/gruppen/{id}/posts")
public ResponseEntity<GruppenbeitragDto> createPost(@PathVariable UUID id,
public ResponseEntity<GruppenbeitragDto> createPost(@PathVariable("id") UUID id,
@RequestBody CreateBeitragRequest req,
Principal principal) {
UUID myId = resolveMyId(principal);
@@ -151,8 +151,8 @@ public class GruppenbeitragController {
// ── DELETE /gruppen/{id}/posts/{postId} ──
@DeleteMapping("/gruppen/{id}/posts/{postId}")
public ResponseEntity<Void> deletePost(@PathVariable UUID id,
@PathVariable UUID postId,
public ResponseEntity<Void> deletePost(@PathVariable("id") UUID id,
@PathVariable("postId") UUID postId,
Principal principal) {
UUID myId = resolveMyId(principal);
if (myId == null) return ResponseEntity.status(401).build();
@@ -175,8 +175,8 @@ public class GruppenbeitragController {
// ── POST /gruppen/{id}/posts/{postId}/like ──
@PostMapping("/gruppen/{id}/posts/{postId}/like")
public ResponseEntity<Void> toggleLike(@PathVariable UUID id,
@PathVariable UUID postId,
public ResponseEntity<Void> toggleLike(@PathVariable("id") UUID id,
@PathVariable("postId") UUID postId,
Principal principal) {
UUID myId = resolveMyId(principal);
if (myId == null) return ResponseEntity.status(401).build();
@@ -190,8 +190,8 @@ public class GruppenbeitragController {
// ── POST /gruppen/{id}/posts/{postId}/vote ──
@PostMapping("/gruppen/{id}/posts/{postId}/vote")
public ResponseEntity<Void> vote(@PathVariable UUID id,
@PathVariable UUID postId,
public ResponseEntity<Void> vote(@PathVariable("id") UUID id,
@PathVariable("postId") UUID postId,
@RequestBody VoteRequest req,
Principal principal) {
UUID myId = resolveMyId(principal);
@@ -235,8 +235,8 @@ public class GruppenbeitragController {
// ── POST /gruppen/{id}/posts/{postId}/report ──
@PostMapping("/gruppen/{id}/posts/{postId}/report")
public ResponseEntity<Void> report(@PathVariable UUID id,
@PathVariable UUID postId,
public ResponseEntity<Void> report(@PathVariable("id") UUID id,
@PathVariable("postId") UUID postId,
@RequestBody ReportRequest req,
Principal principal) {
UUID myId = resolveMyId(principal);
@@ -263,7 +263,7 @@ public class GruppenbeitragController {
// ── GET /gruppen/{id}/reports ──
@GetMapping("/gruppen/{id}/reports")
public ResponseEntity<List<BeitragMeldungDto>> getReports(@PathVariable UUID id, Principal principal) {
public ResponseEntity<List<BeitragMeldungDto>> getReports(@PathVariable("id") UUID id, Principal principal) {
UUID myId = resolveMyId(principal);
if (myId == null) return ResponseEntity.status(401).build();
if (mitgliedRepository.findFirstByGruppeIdAndUserId(id, myId)
@@ -288,8 +288,8 @@ public class GruppenbeitragController {
// ── DELETE /gruppen/{id}/reports/{meldungId} ──
@DeleteMapping("/gruppen/{id}/reports/{meldungId}")
public ResponseEntity<Void> dismissReport(@PathVariable UUID id,
@PathVariable UUID meldungId,
public ResponseEntity<Void> dismissReport(@PathVariable("id") UUID id,
@PathVariable("meldungId") UUID meldungId,
Principal principal) {
UUID myId = resolveMyId(principal);
if (myId == null) return ResponseEntity.status(401).build();

View File

@@ -46,7 +46,7 @@ public class KommentarController {
@GetMapping
public ResponseEntity<List<KommentarDto>> getKommentare(
@RequestParam String targetType,
@RequestParam UUID targetId,
@RequestParam("targetId") UUID targetId,
Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
@@ -82,7 +82,7 @@ public class KommentarController {
}
@DeleteMapping("/{kommentarId}")
public ResponseEntity<Void> deleteKommentar(@PathVariable UUID kommentarId, Principal principal) {
public ResponseEntity<Void> deleteKommentar(@PathVariable("kommentarId") UUID kommentarId, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var kOpt = kommentarRepository.findById(kommentarId);
@@ -103,7 +103,7 @@ public class KommentarController {
}
@PostMapping("/{kommentarId}/like")
public ResponseEntity<Void> toggleLike(@PathVariable UUID kommentarId, Principal principal) {
public ResponseEntity<Void> toggleLike(@PathVariable("kommentarId") UUID kommentarId, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
if (kommentarRepository.findById(kommentarId).isEmpty()) return ResponseEntity.notFound().build();

View File

@@ -61,7 +61,7 @@ public class NotificationController {
@Transactional
@PostMapping("/{id}/read")
public ResponseEntity<Void> markOneRead(@PathVariable UUID id, Principal principal) {
public ResponseEntity<Void> markOneRead(@PathVariable("id") UUID id, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
messageRepository.markNotificationAsRead(id, myId, LocalDateTime.now());
return ResponseEntity.noContent().build();

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