Der Einzel-Import kennt den dritten Ausgang jetzt auch
Nach dem Umbau von heute Nachmittag habe ich nachgesehen, WER
tagAusZelle() sonst noch ruft -- und genau dort die naechste Luecke
gefunden, bevor sie jemanden getroffen hat.
DIE FUNKTION HAT SEIT HEUTE DREI AUSGAENGE (Tag, Zeitraum, Grund).
Gekannt hat den dritten nur der Backstage-Weg. Im Einzel-Import stand
weiterhin `gelesen.tag` -- bei einem Zeitraum `undefined`:
VORSCHAU: `undefined > heute` ist false, die Zeile faellt durch
und landet mit `tag: undefined` in der Liste.
SCHREIBWEG: `if (!tag)` greift, die Zeile wird still uebersprungen.
Die Vorschau haette also eine Zeile versprochen, die danach nirgends
steht. Zwei Aussagen ueber dieselbe Datei, die einander widersprechen,
und beide sehen fuer sich plausibel aus -- das ist der Unterschied, den
niemand bemerkt.
Das ist an diesem Tag die FUENFTE Wiederholung derselben Sache: eine
Regel, mehrere Aufrufer, und einer kennt sie nicht. Ein dritter Ausgang
taugt nur, wenn ihn ALLE Aufrufer kennen.
Jetzt legt auch der Einzel-Import einen Zeitraum in leistung_zeitraum
ab -- dieselbe Tabelle, dieselbe Regel, dieselbe Anzeige. Und die
Dauer-Einheit gilt dort ebenfalls; sie fehlte in der Vorschau noch.
DIE MELDUNG SAGT JETZT, WAS ANGEKOMMEN IST: "1 Zeitraum uebernommen"
statt "1 Tage uebernommen". Bei einer Backstage-Ausgabe ueber zwei
Wochen haette man sie sonst in der Tagesliste gesucht und nicht
gefunden.
pruef-backstage-import 106 -> 118. Die Pruefung, auf die es ankommt,
vergleicht VORSCHAU UND ERGEBNIS: Was die Vorschau verspricht, muss
danach dastehen -- genau die Aussage, die vorher falsch gewesen waere.
Dazu, dass in der Vorschau die Spanne steht und kein leerer Tag, und
die Gegenprobe, dass eine echte Tagesdatei weiterhin als Tage durchgeht.
ZWEI EIGENE FEHLER DABEI: Ich habe `.length` auf eine Zahl angewendet
(`fehlerhaft` ist eine Anzahl, keine Liste) -- immer `undefined`, immer
rot. Und zum zweiten Mal heute den Absolutwert gemessen, wo die
Veraenderung gehoert: Lumi hatte aus einem frueheren Teil der Pruefung
schon eine Tageszeile in derselben Spanne.
Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -1244,15 +1244,52 @@ leistungRouter.post("/workspace/api/leistung/:creatorId/import/vorschau", gleich
|
||||
const fehlerhaft = [];
|
||||
for (let i = 1; i < zeilen.length; i++) {
|
||||
const z = zeilen[i];
|
||||
/* DER DRITTE AUSGANG MUSS HIER GENAUSO ANKOMMEN wie im
|
||||
Backstage-Weg (14.09.2026).
|
||||
|
||||
Als tagAusZelle() den Zeitraum bekam, stand hier weiterhin
|
||||
nur `gelesen.tag`. Bei einem Zeitraum war der `undefined`,
|
||||
der Vergleich mit heute wurde still falsch, und die Zeile
|
||||
landete mit `tag: undefined` in der Vorschau -- waehrend der
|
||||
Schreibweg daneben sie kommentarlos uebersprang. Vorschau
|
||||
und Ergebnis haetten sich widersprochen, und das ist der
|
||||
Unterschied, den niemand bemerkt.
|
||||
|
||||
Ein dritter Ausgang taugt nur, wenn ihn ALLE Aufrufer
|
||||
kennen. Das ist an diesem Tag die fuenfte Wiederholung
|
||||
derselben Sache -- gefunden, bevor sie jemanden getroffen
|
||||
hat, weil ich nach dem Umbau nachgesehen habe, wer die
|
||||
Funktion sonst noch ruft. */
|
||||
const gelesen = tagAusZelle(z[zu.tag]);
|
||||
if (gelesen.fehler) { fehlerhaft.push({ zeile: i + 1, grund: gelesen.fehler }); continue; }
|
||||
|
||||
if (gelesen.zeitraum) {
|
||||
const { von, bis } = gelesen.zeitraum;
|
||||
if (bis > tagVor(0)) {
|
||||
fehlerhaft.push({ zeile: i + 1, grund: `${bis} liegt in der Zukunft` });
|
||||
continue;
|
||||
}
|
||||
const wertez = { von, bis, tage: tageImZeitraum(von, bis) };
|
||||
for (const [feld, spalte] of Object.entries(zu)) {
|
||||
if (feld === "tag" || spalte === undefined) continue;
|
||||
wertez[feld] = feld === "dauer_min" ? dauerLesen(z[spalte]) : zahlLesen(z[spalte]);
|
||||
}
|
||||
const daz = db().prepare(
|
||||
"SELECT 1 FROM leistung_zeitraum WHERE creator_id = ? AND von = ? AND bis = ?")
|
||||
.get(creatorId, von, bis);
|
||||
(daz ? ersetzt : neu).push(wertez);
|
||||
continue;
|
||||
}
|
||||
|
||||
const tag = gelesen.tag;
|
||||
if (tag > tagVor(0)) { fehlerhaft.push({ zeile: i + 1, grund: `${tag} liegt in der Zukunft` }); continue; }
|
||||
|
||||
const werte = { tag };
|
||||
for (const [feld, spalte] of Object.entries(zu)) {
|
||||
if (feld === "tag" || spalte === undefined) continue;
|
||||
werte[feld] = zahlLesen(z[spalte]);
|
||||
/* Die Dauer hat eine Einheit, die uebrigen Felder nicht --
|
||||
dieselbe Unterscheidung wie im Backstage-Weg. */
|
||||
werte[feld] = feld === "dauer_min" ? dauerLesen(z[spalte]) : zahlLesen(z[spalte]);
|
||||
}
|
||||
const vorhanden = db().prepare(
|
||||
"SELECT 1 FROM leistung WHERE creator_id = ? AND tag = ?").get(creatorId, tag);
|
||||
@@ -1301,15 +1338,41 @@ leistungRouter.post("/workspace/api/leistung/:creatorId/import", gleicheHerkunft
|
||||
(SELECT notiz FROM leistung WHERE creator_id = ? AND tag = ?),
|
||||
?,?, 'import')`);
|
||||
|
||||
let geschrieben = 0, uebersprungen = 0;
|
||||
/* Der zweite Weg, wie im Backstage-Import: Ein Zeitraum geht in
|
||||
seine eigene Tabelle. */
|
||||
const spanneSchreiben = d.prepare(`
|
||||
INSERT OR REPLACE INTO leistung_zeitraum
|
||||
(creator_id, von, bis, tage, diamanten, dauer_min, gueltige_tage,
|
||||
zuschauer_avg, zuschauer_max, verweildauer_s, schenker, follower_neu,
|
||||
erfasst, erfasst_von)
|
||||
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)`);
|
||||
|
||||
let geschrieben = 0, uebersprungen = 0, spannen = 0;
|
||||
d.exec("BEGIN");
|
||||
try {
|
||||
for (let i = 1; i < zeilen.length; i++) {
|
||||
const z = zeilen[i];
|
||||
/* Dieselbe Regel wie in der Vorschau -- sonst zeigt die
|
||||
Vorschau etwas anderes an, als geschrieben wird. Genau das
|
||||
ist der Unterschied, den niemand bemerkt. */
|
||||
ist der Unterschied, den niemand bemerkt.
|
||||
|
||||
UND DERSELBE DRITTE AUSGANG: Ohne diesen Zweig wuerde ein
|
||||
Zeitraum hier still uebersprungen, waehrend die Vorschau
|
||||
ihn zaehlt. */
|
||||
const gelesen = tagAusZelle(z[zu.tag]);
|
||||
const wz = (feld) => (zu[feld] === undefined ? null
|
||||
: (feld === "dauer_min" ? dauerLesen(z[zu[feld]]) : zahlLesen(z[zu[feld]])));
|
||||
if (gelesen.zeitraum) {
|
||||
const { von, bis } = gelesen.zeitraum;
|
||||
if (bis > tagVor(0)) { uebersprungen++; continue; }
|
||||
spanneSchreiben.run(creatorId, von, bis, tageImZeitraum(von, bis),
|
||||
wz("diamanten"), wz("dauer_min"), wz("gueltige_tage"),
|
||||
wz("zuschauer_avg"), wz("zuschauer_max"), wz("verweildauer_s"),
|
||||
wz("schenker"), wz("follower_neu"),
|
||||
jetzt(), req.person.id);
|
||||
spannen++;
|
||||
continue;
|
||||
}
|
||||
const tag = gelesen.tag;
|
||||
if (!tag || tag > tagVor(0)) { uebersprungen++; continue; }
|
||||
const w = (feld) => (zu[feld] === undefined ? null : zahlLesen(z[zu[feld]]));
|
||||
@@ -1338,7 +1401,7 @@ leistungRouter.post("/workspace/api/leistung/:creatorId/import", gleicheHerkunft
|
||||
personId: req.person.id, rolle: req.person.rolle, ip: echteIp(req),
|
||||
detail: `Creator #${creatorId}: ${geschrieben} Tage`,
|
||||
});
|
||||
res.json({ ok: true, geschrieben, uebersprungen });
|
||||
res.json({ ok: true, geschrieben, zeitraeume: spannen, uebersprungen });
|
||||
} catch (fehler) {
|
||||
console.error("[leistung] Import:", fehler?.message);
|
||||
res.status(503).json({ fehler: "nicht_verfuegbar" });
|
||||
|
||||
Reference in New Issue
Block a user