From fab545db71e92b3e759639865abd3f40c4c6bccf Mon Sep 17 00:00:00 2001 From: Dogfather Date: Thu, 8 Oct 2026 09:33:40 +0200 Subject: [PATCH] Spenden: der Glanz wird nach RANG verteilt, nicht nach Betrag Nachtrag zum Umbau von vorhin -- gefunden, als ich nach dem Ausliefern in die echte Datenbank gesehen habe: 100 Danke 5 500 Starke Runde 15 2000 Starke Runde 45 5000 Rudel-Legende 0 <- die hoechste, und als Einzige aus Die erste Nachruestung fuellte `glanz_minuten` nur dort, wo noch die WERKSGRENZE steht (100/500/2000 Cent). Das war vorsichtig gemeint: Wer seine Leiter umgebaut hat, soll nicht ploetzlich einen Glanz bekommen, den er nie eingestellt hat. Auf dem echten Server war es die falsche Vorsicht -- dort stehen vier Stufen, und die oberste bekam nichts. Ein Glanz, der mit der Hoehe waechst und ausgerechnet bei der hoechsten Stufe aufhoert, sieht nicht nach Vorsicht aus, sondern nach einem Fehler. Also nach RANG statt nach Betrag: unterste Stufe 5 Minuten, oberste 45, dazwischen verteilt und auf Fuenferschritte gerundet. Dieselbe Idee wie bei den Muenzen -- nicht die Zahl abschreiben, sondern die Reihenfolge lesen. Eine Leiter mit sechs Stufen rechnet damit genauso richtig wie eine mit drei. ES PASSIERT GENAU EINMAL und nur bei Stufen, die noch auf 0 stehen. Wer spaeter bewusst eine Null einstellt, behaelt sie -- der Merker ist dann laengst gesetzt. Geprueft an einer frischen Datenbank mit genau dieser Leiter (vier Stufen, oberste bei 5000): 5 / 20 / 30 / 45. Und mit Gegenprobe, dass eine bewusst gesetzte Null stehen bleibt -- ohne sie bewiese der Lauf nur, dass irgendetwas gefuellt wird. pruef-spenden 215 -> 218 (0 Fehler), pruef-reaktion 478 (0). Co-Authored-By: Claude Opus 5 --- server/pruef-spenden.mjs | 59 +++++++++++++++++++++++++++++++++ server/spenden-tabellen.js | 68 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+) diff --git a/server/pruef-spenden.mjs b/server/pruef-spenden.mjs index 01f28cfe..a3c46cc7 100644 --- a/server/pruef-spenden.mjs +++ b/server/pruef-spenden.mjs @@ -1404,6 +1404,65 @@ melde("=== 12. Platz und Spender-Glanz ==="); }); ok(grenze.code === 400 && grenze.j?.fehler === "glanz_unklar", `und 9999 Minuten sind zu viel (${grenze.code}/${grenze.j?.fehler})`); + + /* ==== DER GLANZ WIRD NACH RANG VERTEILT, NICHT NACH BETRAG ===== + (08.10.2026, nach einem Fund auf dem echten Server) + + Die erste Nachruestung fuellte nur Stufen mit der WERKSGRENZE + (100/500/2000 Cent). Auf dem Server stehen vier Stufen, und die + oberste liegt bei 5000 -- sie bekam als EINZIGE nichts, waehrend + eine mittlere 45 Minuten bekam. Ein Glanz, der mit der Hoehe + waechst und bei der hoechsten Stufe aufhoert, sieht nicht nach + Vorsicht aus, sondern nach einem Fehler. + + Geprueft wird an einer eigenen, frischen Datenbank -- die + laufende hat ihren Merker laengst gesetzt, und ein Lauf gegen + sie bewiese nur, dass nichts mehr passiert. */ + { + const { DatabaseSync: DBM } = await import("node:sqlite"); + const { mkdtempSync: neuerOrdner, rmSync: wegDamit } = await import("node:fs"); + const { tmpdir: tmp2 } = await import("node:os"); + const { spendenTabellen } = await import("./spenden-tabellen.js"); + + const ordner3 = neuerOrdner(join(tmp2(), "glanz-")); + const d3 = new DBM(join(ordner3, "probe.db")); + d3.exec(`CREATE TABLE einstellungen (schluessel TEXT PRIMARY KEY, + wert TEXT NOT NULL, geaendert TEXT, von INTEGER); + CREATE TABLE personen (id INTEGER PRIMARY KEY);`); + spendenTabellen(d3); + + /* Eine Leiter wie auf dem Server: vier Stufen, die oberste weit + oberhalb der Werksgrenze -- und alle vier ohne Glanz, so wie + sie nach dem ersten Nachruesten dastuenden. */ + d3.exec("DELETE FROM einstellungen WHERE schluessel = 'spenden_glanz_verteilt'"); + d3.exec("UPDATE spenden_stufen SET glanz_minuten = 0"); + d3.prepare(`INSERT INTO spenden_stufen + (ab_cent, name, vorlage, farbe, dauer_ms, groesse, glanz_minuten, geaendert) + VALUES (5000,'Rudel-Legende','dogen','#e0a13a',11000,1.45,0,'')`).run(); + spendenTabellen(d3); + + const nachher = d3.prepare("SELECT ab_cent, glanz_minuten FROM spenden_stufen" + + " ORDER BY ab_cent").all(); + const werte = nachher.map((z) => z.glanz_minuten); + ok(werte.length === 4 && werte.every((w) => w > 0), + `alle vier Stufen bekommen Glanz (${werte.join(" / ")} Minuten)`); + ok(werte[3] > werte[0] && werte[3] >= werte[2] && werte[2] >= werte[1], + "und er waechst mit dem Rang -- die hoechste Stufe am laengsten"); + + /* ==== DIE GEGENPROBE: EINE BEWUSSTE NULL BLEIBT ============ + Ohne sie bewiese das Obige nur, dass irgendetwas gefuellt + wird -- und beim naechsten Neustart stuende die Null, die + jemand ausdruecklich gesetzt hat, wieder auf 20. */ + d3.exec("UPDATE spenden_stufen SET glanz_minuten = 0 WHERE ab_cent = 100"); + spendenTabellen(d3); + const nochmal = d3.prepare("SELECT glanz_minuten FROM spenden_stufen" + + " WHERE ab_cent = 100").get(); + ok(nochmal?.glanz_minuten === 0, + `Gegenprobe: eine bewusst gesetzte Null bleibt (${nochmal?.glanz_minuten})`); + + d3.close(); + wegDamit(ordner3, { recursive: true, force: true }); + } } melde(""); diff --git a/server/spenden-tabellen.js b/server/spenden-tabellen.js index 07aa438d..29ca956b 100644 --- a/server/spenden-tabellen.js +++ b/server/spenden-tabellen.js @@ -390,6 +390,11 @@ export const GLANZ_MAX_MINUTEN = 180; einen Wert, den jemand verschieben kann. Was zu einer Stufe gehört, steht an der Stufe. */ +/** Unter welchem Namen steht, dass der Glanz einmal an die ganze + * Leiter verteilt wurde. Die Begründung steht bei der Verteilung + * selbst. */ +export const GLANZ_VERTEILT = "spenden_glanz_verteilt"; + /** Wo die Spendenkarte im Bild steht. */ export const PLATZ_NAME = "spenden_platz"; export const PLAETZE = ["mitte", "rand"]; @@ -627,4 +632,67 @@ export function spendenTabellen(d) { console.error("[spenden] Muenzen verteilen:", fehler?.message); } + /* ==== DEN GLANZ EINMAL AN DIE GANZE LEITER VERTEILEN =========== + (08.10.2026, noch am selben Abend nachgetragen) + + Die Nachruestung darueber fuellt `glanz_minuten` nur dort, wo + noch die WERKSGRENZE steht (100, 500, 2000 Cent). Das war + vorsichtig gemeint: Wer seine Leiter umgebaut hat, soll nicht + ploetzlich einen Glanz bekommen, den er nie eingestellt hat. + + AUF DEM ECHTEN SERVER WAR DAS DIE FALSCHE VORSICHT. Dort stehen + vier Stufen, und die OBERSTE liegt bei 5000 Cent -- sie bekam + also nichts, waehrend eine mittlere 45 Minuten bekam. Gemessen + nach dem Ausliefern: + + 100 Danke 5 + 500 Starke Runde 15 + 2000 Starke Runde 45 + 5000 Rudel-Legende 0 <- die hoechste, und als Einzige aus + + Ein Glanz, der mit der Hoehe waechst und bei der hoechsten + Stufe aufhoert, sieht nicht nach Vorsicht aus, sondern nach + einem Fehler. + + ALSO NACH RANG STATT NACH BETRAG. Die unterste Stufe bekommt 5 + Minuten, die oberste 45, dazwischen wird verteilt und auf + Fuenferschritte gerundet. Das ist dieselbe Idee wie bei den + Muenzen: nicht die Zahl abschreiben, sondern die REIHENFOLGE + lesen -- eine Leiter mit sechs Stufen rechnet damit genauso + richtig wie eine mit drei. + + ES PASSIERT GENAU EINMAL, und nur bei Stufen, die noch auf 0 + stehen. Wer spaeter bewusst eine Null einstellt, behaelt sie: + Der Merker ist dann laengst gesetzt. Eine Einstellung, die sich + gegen den Benutzer durchsetzt, wird abgeschafft -- und dann ist + auch die gute Absicht dahinter weg. */ + try { + const schon = d.prepare("SELECT wert FROM einstellungen WHERE schluessel = ?") + .get(GLANZ_VERTEILT); + if (!schon) { + const leiter = d.prepare("SELECT id, glanz_minuten FROM spenden_stufen" + + " ORDER BY ab_cent").all(); + const n = leiter.length; + let gesetzt = 0; + if (n > 0) { + const setz = d.prepare("UPDATE spenden_stufen SET glanz_minuten = ? WHERE id = ?"); + leiter.forEach((s, i) => { + if (Number(s.glanz_minuten) > 0) return; + /* Bei genau einer Stufe gibt es kein Oben und Unten -- + dann die Mitte. */ + const roh = n === 1 ? 15 : 5 + ((45 - 5) * i) / (n - 1); + setz.run(Math.round(roh / 5) * 5, s.id); + gesetzt += 1; + }); + } + d.prepare(`INSERT OR REPLACE INTO einstellungen (schluessel, wert, geaendert) + VALUES (?,?,?)`).run(GLANZ_VERTEILT, "ja", new Date().toISOString()); + if (gesetzt) console.log(`[spenden] Glanz an ${gesetzt} Stufen verteilt.`); + } + } catch (fehler) { + /* Ein fehlender Glanz ist ein Schoenheitsfehler, kein Grund, den + Start abzubrechen. */ + console.error("[spenden] Glanz verteilen:", fehler?.message); + } + }