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); + } + }