Neue Funktion: Supporter-Abstimmungen (Verwaltung + DogiCrew-Bereich)
Naechste "Ausbaustufe" aus Dogfather_VanVan_Supporter_Abo.odt Abschnitt 20 (siehe Supporter-Abo-System.md), auf Nutzerwunsch "perfektioniere meine Verwaltungsseite": Dogi/VanVan koennen in verwaltung.html eine Frage mit 2-6 Antwortoptionen auf Deutsch erstellen, automatische Uebersetzung beim Speichern (gleiches Muster wie "Event des Jahres"). Jede aktive DogiCrew- Person sieht die Abstimmung in ihrem Supporter-Bereich, stimmt genau einmal ab (UNIQUE-Constraint in der DB, nicht nur Anwendungslogik), sieht danach die Live-Ergebnisse. Admin-Seite zeigt Ergebnisbalken live, kann schliessen/ wiedereroeffnen/loeschen. - Neue Migration 0005_supporter_polls.sql (supporter_polls, supporter_poll_votes), neue Berechtigung POLLS_MANAGE. - server-internal/routes/polls.js: 30 End-to-End-Tests gegen eine Fake-DB bestanden (better-sqlite3 laesst sich lokal nicht kompilieren). - verwaltung.html: neue "Abstimmungen"-Kiste im bestehenden vw-overview-box-Stil (violett/pink Ergebnisbalken). - supporter.html: neue "Aktuelle Abstimmung"-Karte im bestehenden Gold-Look, Optionen -> Stimme -> Ergebnisbalken, alle 5 Sprachen. Backend-Teil (server-internal/, cloudflare-worker/migrations/) noch ohne Deploy-Zugriff -- Dogi muss ihn manuell auf dogiintern ausrollen. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -64,6 +64,9 @@ import {
|
||||
listSupporters, getSupporterDetail, updatePremium, listCollections, upsertCollection, getAdminOverview,
|
||||
} from "./routes/supporter-admin.js";
|
||||
import { getEventsPublic, saveEvent, uploadEventImage } from "./routes/events.js";
|
||||
import {
|
||||
createPoll, listPolls, closePoll, reopenPoll, deletePoll, getActivePollPublic, voteOnPoll,
|
||||
} from "./routes/polls.js";
|
||||
|
||||
initDb();
|
||||
|
||||
@@ -219,6 +222,13 @@ app.post("/admin/supporter/premium/update", requireTeamSession, withSession(upda
|
||||
app.post("/admin/supporter/collections/list", requireTeamSession, withSession(listCollections));
|
||||
app.post("/admin/supporter/collections/upsert", requireTeamSession, withSession(upsertCollection));
|
||||
|
||||
// Supporter-Abstimmungen (20.08.2026)
|
||||
app.post("/admin/polls/list", requireTeamSession, withSession(listPolls));
|
||||
app.post("/admin/polls/create", requireTeamSession, withSession(createPoll));
|
||||
app.post("/admin/polls/close", requireTeamSession, withSession(closePoll));
|
||||
app.post("/admin/polls/reopen", requireTeamSession, withSession(reopenPoll));
|
||||
app.post("/admin/polls/delete", requireTeamSession, withSession(deletePoll));
|
||||
|
||||
/* ---------- Öffentlicher Supporter-Bereich (eigene Session, requireSupporterAuth) ---------- */
|
||||
|
||||
app.post("/supporter/logout", requireSupporterAuth, wrap(logoutSupporter));
|
||||
@@ -231,6 +241,8 @@ app.post("/supporter/delete-account", requireSupporterAuth, withSupporter(delete
|
||||
app.post("/supporter/paypal/start", requireSupporterAuth, withSupporter(startPaypalSubscription));
|
||||
app.post("/supporter/paypal/confirm", requireSupporterAuth, withSupporter(confirmPaypalSubscription));
|
||||
app.post("/supporter/paypal/cancel", requireSupporterAuth, withSupporter(cancelPaypalSubscription));
|
||||
app.post("/supporter/polls/active", requireSupporterAuth, withSupporter(getActivePollPublic));
|
||||
app.post("/supporter/polls/vote", requireSupporterAuth, withSupporter(voteOnPoll));
|
||||
|
||||
app.use((req, res) => json(res, { ok: false, error: "Not found." }, 404));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user