Filipe: "mach doch bitte so dass man alle dateien hoch laden könne auch
excel dateien. gib gas und krieg das hin."
server/workspace-xlsx.js liest .xlsx mit Bordmitteln: Eine .xlsx ist ein
ZIP mit XML darin, und Node kann beides (`zlib.inflateRawSync`). Kein
zusaetzliches Paket fuer eine Datei mit neun Zeilen.
GEMESSEN AN ZWEI ECHTEN BACKSTAGE-AUSGABEN vom 11. und 12.09.2026, die
auf dem Rechner lagen -- nicht an der Dokumentation. Sie haben mir an
drei Stellen widersprochen, und JEDE davon waere sonst ein stiller
Fehler geworden:
1. DER ZEITRAUM. In "Datenzeitraum" steht `2026-09-01 ~ 2026-09-11`.
`datumLesen` griff sich davon den ersten Tag -- elf Tage Diamanten
waeren auf den 1. September gebucht worden. Die Zahl steht da, sie
ist gross, sie sieht richtig aus, und niemand kann spaeter sagen,
dass elf Tage darin stecken. Neu: `zeitraumLesen`; eine Zeile mit
einem Zeitraum ueber mehrere Tage wird abgelehnt UND begruendet
("Stell in Backstage den Zeitraum auf EINEN Tag"). Ein Zeitraum von
einem Tag geht durch.
2. DIE EINHEIT. "LIVE-Dauer" enthaelt `86Std. 10Min. 52Sek.`.
`zahlLesen` ergab daraus `null` -- die Dauer fiel weg. Bei einem
anderen Trennzeichen waere es schlimmer gewesen: 86 statt 5171,
Faktor 60 daneben und plausibel. Neu: `dauerLesen`, versteht die
deutsche und englische Schreibweise, die Uhrzeitform und weiterhin
die blosse Zahl.
3. DIE DATUMSSPALTE. `/datum|date|tag|day/i` erklaerte "Tage seit dem
Beitritt" zur Datumsspalte (Wert "65") und traf in der
Leistungstabelle "Gueltige LIVE-Gehen-Tage" genauso. Jetzt nur noch
als ganzes Wort, dafuer mit "zeitraum" -- Backstages Spalte wurde
bisher nur zufaellig gefunden, weil in "Daten" die Silbe "date"
steckt.
Gefunden hat das keine Ueberlegung, sondern der ganze Weg einmal mit
der echten Datei durchlaufen.
WEITER GEBAUT:
- Titelzeilen werden uebersprungen: "Creator:innen verwalten" hat in
Zeile 1 nur "Exportiert am :…", die Ueberschriften stehen darunter.
Die Regel misst (drei gefuellte Felder UND halb so breit wie die
breiteste Zeile), statt eine feste Zahl zu nehmen.
- Fehlende Zellen verschieben nichts: Eine leere Zelle steht in der
Datei gar nicht; wer der Reihe nach liest, verrutscht ab dort jede
Spalte, und die Zeile sieht voll aus.
- Datums-Seriennummern werden nur umgerechnet, wenn das FORMAT es sagt
(sonst stuende 46271 in der Vorschau). Der Nullpunkt ist an zwei
nachschlagbaren Werten festgenagelt.
- Der Backstage-Dialog nimmt die Datei jetzt AUCH -- dort gehoert sie
hin, denn Filipes Ausgabe enthaelt alle Creator auf einmal. Sie fuellt
das Einfuegefeld; ab da laeuft derselbe Weg wie beim Einfuegen. Keine
zweite Fassung derselben Regeln.
- Die alte .xls (BIFF, kein ZIP) wird erkannt und bekommt einen Weg
gezeigt, statt "ging nicht" zu sagen.
NEU: pruef-xlsx.mjs (60) -- baut seine Dateien selbst (ZIP-Schreiber in
helfer-xlsx-bauen.mjs), damit keine Creator-Daten ins Repo wandern und
auch Faelle pruefbar sind, die es als Datei nicht gibt: kaputtes
Verzeichnis, fehlendes Blatt, abgeschnittene Datei. Jeder davon mit
Gegenprobe, dass die heile Datei durchgeht.
pruef-backstage-import 77 -> 82, dabei zwei Pruefungen GEDREHT: Die
.xlsx bekommt keine Absage mehr, sondern eine Vorschau.
DREI EIGENE FEHLER DABEI, alle von einer Messung gefunden:
- Ich hielt Seriennummer 46264 fuer den 06.09.; es ist der 30.08. Der
Code hatte recht. Deshalb stehen jetzt zwei nachschlagbare Anker drin.
- Eine Zeile war gruen, weil mein Muster den SPALTENNAMEN
"Datenzeitraum" traf statt der Begruendung. Jetzt wird auf den Text
der Ablehnung geprueft.
- Beim Umbau habe ich pruef-backstage-import beschaedigt (ein
Suchtreffer weiter oben als gemeint) und aus Git zurueckgeholt.
Co-Authored-By: Claude Opus 5 <[email protected]>
195 lines
9.1 KiB
HTML
195 lines
9.1 KiB
HTML
<!doctype html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||
<title>Bereich · Spicy & Dogi</title>
|
||
<meta name="robots" content="noindex, nofollow" />
|
||
<link rel="manifest" href="/workspace/app.webmanifest" />
|
||
<!-- Die Farbe der Fensterleiste, wenn der Workspace als App laeuft.
|
||
Stand auf #0674b9 (kraeftiges Blau) und stach damit als einziger
|
||
heller Balken ueber einer durchweg dunklen Seite. Jetzt derselbe
|
||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||
eine Flaeche sind statt zweier. -->
|
||
<meta name="theme-color" content="#06090f" />
|
||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609141135" />
|
||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609141135" />
|
||
<link rel="stylesheet" href="assets/css/gate.css?v=202609141135" />
|
||
<link rel="stylesheet" href="assets/css/start.css?v=202609141135" />
|
||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609141135" />
|
||
<link rel="stylesheet" href="assets/css/bereich.css?v=202609141135" />
|
||
<link rel="stylesheet" href="assets/css/module.css?v=202609141135" />
|
||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||
ohne Umfaerben im Browser, ohne Flackern. -->
|
||
<link rel="stylesheet" href="assets/css/haus.css?v=202609141135" />
|
||
</head>
|
||
|
||
<body class="start">
|
||
|
||
<!-- Der Schleier ueber der Buehne (Casper und HasiDog in den unteren
|
||
Ecken, siehe start.css). Ein eigenes Element statt eines dritten
|
||
Pseudo-Elements -- body hat nur ::before und ::after. -->
|
||
<div class="schleier" aria-hidden="true"></div>
|
||
|
||
<header class="kopfleiste">
|
||
<button type="button" class="zurueck-knopf" id="zurueck" hidden>
|
||
<svg class="zurueck-knopf__pfeil" viewBox="0 0 24 24" aria-hidden="true">
|
||
<path d="M14.5 5.5 8 12l6.5 6.5" />
|
||
</svg>
|
||
<span class="zurueck-knopf__text">Zurück</span>
|
||
</button>
|
||
<!-- Der innere span.marke__text fehlte hier als einziger Seite. Damit
|
||
griffen weder die Überlauf-Kürzung noch der Rang im Schriftzug --
|
||
aufgefallen erst, als die Seitenprüfung die Marke auf allen
|
||
dreizehn Seiten nachgesehen hat. -->
|
||
<p class="marke"><span class="marke__text"><a class="zurueck" href="start.html">Creator Workspace</a> ·
|
||
<span id="marke-bereich">…</span></span></p>
|
||
<div class="kopfleiste__rechts">
|
||
<span class="wer" id="wer">…</span>
|
||
<button type="button" class="abmelden" id="abmelden">Abmelden</button>
|
||
</div>
|
||
</header>
|
||
|
||
<main class="inhalt inhalt--breit">
|
||
|
||
<section class="kopf-zeile">
|
||
<div>
|
||
<p class="marke" id="ober">Betreuung</p>
|
||
<h1 class="titel" id="titel">…</h1>
|
||
<p class="unterzeile" id="unterzeile"></p>
|
||
</div>
|
||
<button type="button" class="knopf knopf--klein" id="neu-oeffnen">Neuer Eintrag</button>
|
||
</section>
|
||
|
||
<form class="neu" id="neu" hidden>
|
||
<div class="neu__raster">
|
||
<div>
|
||
<label class="feld-schild" for="f-art">Art</label>
|
||
<select id="f-art"></select>
|
||
</div>
|
||
<div>
|
||
<label class="feld-schild" for="f-datum" id="schild-datum">Datum</label>
|
||
<input id="f-datum" type="date" />
|
||
</div>
|
||
<!-- Nur bei Agentur-Events: das Ende des Zeitraums. Der Beginn ist
|
||
das Feld darueber -- ein zweites Datumsfeld daneben liest sich
|
||
als Spanne, ein Feld "Zeitraum" mit Text darin nicht. -->
|
||
<div id="feld-ende" hidden>
|
||
<label class="feld-schild" for="f-ende">Bis</label>
|
||
<input id="f-ende" type="date" />
|
||
</div>
|
||
<!-- Was DogFather dafuer tun muesste. Nur in Bereichen, die das
|
||
Feld kennen (siehe BEREICHE.angebote) -- sonst bleibt es
|
||
verborgen und wird auch nicht mitgeschickt. -->
|
||
<div id="feld-einsatz" hidden>
|
||
<label class="feld-schild" for="f-einsatz" id="einsatz-schild">Einsatz</label>
|
||
<input id="f-einsatz" type="text" maxlength="300"
|
||
placeholder="z. B. Termin ansagen und den Gast einladen" />
|
||
</div>
|
||
<!-- FÜRS TEAM ODER NUR AN DOGFATHER (10.09.2026, Kapitel 5).
|
||
Steht nur dort, wo der Bereich es vorsieht -- der Server sagt
|
||
das über `einstellung.vertraulich`, nicht diese Datei.
|
||
Es ist ein Schalter mit zwei Zuständen und keine Auswahlliste:
|
||
Es gibt genau zwei Antworten, und eine davon ist der
|
||
Normalfall. -->
|
||
<div id="feld-vertraulich" hidden>
|
||
<label class="feld-schild" for="f-vertraulich">Wer darf das lesen?</label>
|
||
<label class="vertraulich-zeile">
|
||
<input type="checkbox" id="f-vertraulich" />
|
||
<span>
|
||
<strong>Nur DogFather</strong>
|
||
<em>Sonst liest es das ganze Team – auch die rechte Hand.</em>
|
||
</span>
|
||
</label>
|
||
</div>
|
||
|
||
<div id="feld-dringlich" hidden>
|
||
<label class="feld-schild" for="f-dringlich" id="dringlich-schild">Dringlichkeit</label>
|
||
<select id="f-dringlich">
|
||
<option value="hoch">hoch</option>
|
||
<option value="mittel" selected>mittel</option>
|
||
<option value="niedrig">niedrig</option>
|
||
</select>
|
||
</div>
|
||
<div id="feld-bewertung" hidden>
|
||
<label class="feld-schild" for="f-bewertung" id="bewertung-schild">Bewertung (1–5)</label>
|
||
<select id="f-bewertung">
|
||
<option value="">—</option>
|
||
<option value="1">1 – schwach</option>
|
||
<option value="2">2</option>
|
||
<option value="3">3 – solide</option>
|
||
<option value="4">4</option>
|
||
<option value="5">5 – stark</option>
|
||
</select>
|
||
</div>
|
||
<div id="feld-creator" hidden>
|
||
<label class="feld-schild" for="f-creator" id="schild-creator">Creator</label>
|
||
<select id="f-creator"><option value="">—</option></select>
|
||
<p class="feld-hinweis" id="hinweis-creator" hidden></p>
|
||
</div>
|
||
</div>
|
||
<div class="neu__zeile">
|
||
<label class="feld-schild" for="f-titel" id="schild-titel">Überschrift</label>
|
||
<input id="f-titel" maxlength="160" required />
|
||
</div>
|
||
<div class="neu__zeile">
|
||
<label class="feld-schild" for="f-text" id="schild-text">Text <span class="leise">(optional)</span></label>
|
||
<textarea id="f-text" rows="4" maxlength="6000"></textarea>
|
||
</div>
|
||
<!-- ==== Nur bei Agentur-Events ====================================
|
||
Zwei Felder, die den Unterschied zwischen einem Aufruf und einer
|
||
Aktion ausmachen, an der jemand teilnehmen kann: WAS ist zu tun
|
||
(und was springt dabei heraus) und WAS GILT dabei. Beides stand
|
||
bisher irgendwo im Fliesstext oder gar nicht -- und jede
|
||
Rueckfrage dazu kostet eine Nachricht. -->
|
||
<div class="neu__zeile" id="feld-aufgaben" hidden>
|
||
<label class="feld-schild" for="f-aufgaben">Aufgaben
|
||
<span class="leise">– womit sammelt man Punkte, was gibt es zu gewinnen</span></label>
|
||
<textarea id="f-aufgaben" rows="5" maxlength="6000"
|
||
placeholder="z. B. · 1 Punkt je Live-Stunde · 3 Punkte je neuem Abo · Platz 1 gewinnt …"></textarea>
|
||
</div>
|
||
<div class="neu__zeile" id="feld-regeln" hidden>
|
||
<label class="feld-schild" for="f-regeln">Regeln
|
||
<span class="leise">– was zählt, was nicht, bis wann</span></label>
|
||
<textarea id="f-regeln" rows="5" maxlength="6000"
|
||
placeholder="z. B. · Nur Streams auf dem eigenen Konto · Punkte zählen bis 23:59 am letzten Tag"></textarea>
|
||
</div>
|
||
<p class="fehler" id="neu-fehler" role="alert" aria-live="polite"></p>
|
||
<div class="neu__knoepfe">
|
||
<button type="submit" class="knopf knopf--klein" id="neu-speichern">Eintragen</button>
|
||
<button type="button" class="abmelden" id="neu-abbrechen">Abbrechen</button>
|
||
</div>
|
||
</form>
|
||
|
||
<p class="fehler" id="fehler" role="alert" aria-live="polite"></p>
|
||
|
||
<div class="filter" id="filter"></div>
|
||
|
||
<!-- Fertige Punkte zum Uebernehmen -- nur in Bereichen, fuer die es
|
||
welche gibt (derzeit LIVE-Analyse). -->
|
||
<!-- Unterweisungen mit beidseitiger Bestaetigung. Nur im Bereich
|
||
"Schutz & Regeln" -- dort gehoeren Richtlinien hin. -->
|
||
<div id="schulung" hidden></div>
|
||
|
||
<div id="vorlagen" hidden></div>
|
||
|
||
<div id="liste" aria-busy="true"><p class="leise">Einträge werden geladen …</p></div>
|
||
|
||
</main>
|
||
|
||
<script src="assets/js/wahl.js?v=202609141135" defer></script>
|
||
<script src="assets/js/bereiche.js?v=202609141135" defer></script>
|
||
<script src="assets/js/kopf.js?v=202609141135" defer></script>
|
||
<script src="assets/js/glocke.js?v=202609141135" defer></script>
|
||
<script src="assets/js/checkliste.js?v=202609141135" defer></script>
|
||
<script src="assets/js/ampel.js?v=202609141135" defer></script>
|
||
<script src="assets/js/schulung.js?v=202609141135" defer></script>
|
||
<script src="assets/js/vorlagen.js?v=202609141135" defer></script>
|
||
<script src="assets/js/bereich.js?v=202609141135" defer></script>
|
||
</body>
|
||
</html>
|