Filipe: "ich will dass es eine eigene app wird" -- und dann "subdomain
machen jetzt sofort". Name von ihm gewaehlt: crew. (unauffaellig).
Auf einem Ursprung laesst sich genau EINE App installieren (w3c/manifest
Nr. 1180). Derselbe Grund, aus dem der Workspace am 06.09. umgezogen ist.
Getrennt wird ueber den HOSTNAMEN: ein Dienst, eine Datenbank, ein
Verzeichnis wie bisher.
DIE REGEL STEHT AN EINER STELLE
crew-adresse.js beantwortet: Darf diese Rolle auf dieser Adresse
angemeldet sein? Eingehaengt in sitzungLesen() -- durch die Funktion geht
jedes der 26 Fachmodule und jede Seitenschranke. Eine Middleware daneben
kann man in einem neuen Modul vergessen, und ein vergessener Rechteschutz
faellt nicht auf, weil dann alles geht.
crew. nur Modis; jeder andere bekommt 401 wie bei einem Tippfehler
workspace. keine Modis mehr; sie bekommen den Weg zur neuen Adresse
localhost UNVERAENDERT
Die dritte Zeile ist der Kern: Die Regel ist eine AUFZAEHLUNG der drei
echten Adressen, nicht "alles ausser crew". Sonst wuerden sieben andere
Pruefdateien ab sofort messen, dass ein Modi nirgends hereinkommt -- gruen,
weil sie nichts mehr finden.
ZWEI APPS, ZWEI NAMEN
Beide Adressen liefern dieselben HTML-Dateien. Auf crew. wird
/workspace/app.webmanifest serverseitig auf crew.webmanifest umgebogen --
so braucht keine der 30 Seiten eine zweite Zeile, die man bei der 31.
vergisst. "Team Dogi" statt "Creator Workspace", eigenes Zeichen:
derselbe Husky, aber ohne Chili (die gehoert zu Spicy Media, nicht zu
ihnen) und im Modi-Ton #5f8a9f.
tools/crew-symbol.mjs erzeugt die sechs Symbole und bricht ab, wenn sie
sich zu weniger als 10 % vom Workspace-Symbol unterscheiden. Gemessen:
43 bis 53 %.
GEMESSEN
pruef-crew-adresse 74 Pruefungen, 0 Fehler -- mit Gegenprobe: der Modi
bekommt in der Datenbank die Rolle 'manager', danach
MUSS dieselbe Sitzung auf crew. ins Leere laufen
pruef-rollen 245, unveraendert (die Regel ist lokal wirkungslos)
pruef-workspace-umzug 31 Faelle
pruef-zwischenspeicher 21 -- ein Stempel im Haus, jetzt ueber 23 Dateien
Der Server kennt die Adresse damit. DNS und Caddy bleiben Filipes Schritt.
Co-Authored-By: Claude Opus 5 <[email protected]>
127 lines
5.3 KiB
JavaScript
127 lines
5.3 KiB
JavaScript
/* =====================================================================
|
|
workspace-stempel.mjs — Versionsstempel an die Workspace-Dateien.
|
|
|
|
WARUM ES DAS GIBT:
|
|
Cloudflare speichert JS und CSS vier Stunden im Browser -- es
|
|
ueberschreibt damit das "no-cache", das der Server korrekt schickt.
|
|
Nach einem Deploy sah man deshalb bis zu vier Stunden lang die ALTE
|
|
Oberflaeche, obwohl der Server laengst die neue auslieferte. Genau so
|
|
ist es passiert: eine neue Kachel war live, aber nicht sichtbar.
|
|
|
|
Die HTML-Seiten kommen dagegen immer frisch an (no-cache, DYNAMIC).
|
|
Deshalb genuegt es, in der HTML einen Stempel an die Adressen zu
|
|
haengen: Neue Seite -> neue Adresse -> Cloudflare kennt sie nicht ->
|
|
frische Datei. Ohne Cloudflare-Einstellung, ohne Zutun von aussen.
|
|
|
|
Der Stempel ist die Minute des Aufrufs. Er wird bei jedem Lauf neu
|
|
gesetzt, auch wenn schon einer dasteht.
|
|
|
|
AUFRUF: node tools/workspace-stempel.mjs
|
|
Gehoert vor jeden Deploy, der JS oder CSS im Workspace anfasst.
|
|
===================================================================== */
|
|
|
|
import { readdirSync, readFileSync, writeFileSync, existsSync } from "node:fs";
|
|
import { join, dirname } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const HIER = dirname(fileURLToPath(import.meta.url));
|
|
const ORDNER = join(HIER, "..", "workspace");
|
|
|
|
const d = new Date();
|
|
const p = (n) => String(n).padStart(2, "0");
|
|
const STEMPEL = `${d.getFullYear()}${p(d.getMonth() + 1)}${p(d.getDate())}${p(d.getHours())}${p(d.getMinutes())}`;
|
|
|
|
/* Trifft href="assets/..." und src="assets/..." -- mit oder ohne
|
|
vorhandenen Stempel, damit wiederholte Laeufe nicht anhaengen. */
|
|
const MUSTER = /(href|src)="(assets\/(?:css|js)\/[A-Za-z0-9._-]+)(?:\?v=\d+)?"/g;
|
|
|
|
/* ZWEITES MUSTER: DIE APP-SYMBOLE (09.09.2026).
|
|
|
|
Sie stehen mit absolutem Pfad in der Seite (`/assets/img/app-symbole/…`)
|
|
und fielen deshalb durch das Muster oben durch. Der Server gibt Bildern
|
|
einen Tag Haltbarkeit -- ein neu gezeichnetes Symbol war damit bis zu
|
|
24 Stunden lang unsichtbar, obwohl es ausgeliefert wurde. Genau die
|
|
Luecke, die der Stempel eigentlich schliessen soll, nur fuer Bilder
|
|
statt fuer Stilvorlagen.
|
|
|
|
Die Reiter-Kennung und das Apple-Symbol bekommen deshalb denselben
|
|
Stempel wie alles andere. Dass es DERSELBE ist, ist wichtig: Die
|
|
Pruefung `pruef-zwischenspeicher` verlangt genau einen Stempel im
|
|
ganzen Haus, und eine zweite Zahl waere sofort rot. */
|
|
const MUSTER_SYMBOL =
|
|
/(href)="(\/assets\/img\/app-symbole\/[A-Za-z0-9._-]+)(?:\?v=\d+)?"/g;
|
|
|
|
let dateien = 0;
|
|
let stellen = 0;
|
|
|
|
for (const name of readdirSync(ORDNER)) {
|
|
if (!name.endsWith(".html")) continue;
|
|
const pfad = join(ORDNER, name);
|
|
const alt = readFileSync(pfad, "utf8");
|
|
let n = 0;
|
|
const neu = alt
|
|
.replace(MUSTER, (_, was, datei) => {
|
|
n += 1;
|
|
return `${was}="${datei}?v=${STEMPEL}"`;
|
|
})
|
|
.replace(MUSTER_SYMBOL, (_, was, datei) => {
|
|
n += 1;
|
|
return `${was}="${datei}?v=${STEMPEL}"`;
|
|
});
|
|
if (neu !== alt) {
|
|
writeFileSync(pfad, neu);
|
|
dateien += 1;
|
|
stellen += n;
|
|
console.log(` ${name.padEnd(20)} ${n} Verweise`);
|
|
}
|
|
}
|
|
|
|
/* DAS MANIFEST GEHOERT DAZU (09.09.2026).
|
|
|
|
Aus ihm holt sich das Betriebssystem das Symbol der installierten App.
|
|
Ohne Stempel zeigen Android und Windows nach einer Neuzeichnung
|
|
weiter das alte Bild -- die Adresse hat sich ja nicht geaendert, und
|
|
ein einmal installiertes Symbol wird nicht von sich aus nachgeladen.
|
|
Das Manifest selbst wird ohne Haltbarkeit ausgeliefert, kommt also
|
|
frisch an; nur die Adressen darin waren starr.
|
|
|
|
Derselbe Stempel wie in den Seiten -- `pruef-zwischenspeicher`
|
|
verlangt im ganzen Haus genau eine Zahl und wuerde eine zweite sofort
|
|
melden. */
|
|
/* ES SIND ZWEI MANIFESTE (10.09.2026). Seit die Modi-App unter ihrer
|
|
eigenen Adresse laeuft, gibt es neben app.webmanifest auch
|
|
crew.webmanifest -- dasselbe Haus, anderer Name, andere Symbole.
|
|
|
|
ALS LISTE UND NICHT ALS ZWEITER BLOCK: Ein kopierter Block waere beim
|
|
dritten Manifest ein dritter, und irgendwann bleibt einer stehen. Ein
|
|
fehlendes Manifest ist hier ausserdem ein FEHLER und kein
|
|
Ueberspringen -- sonst faellt das Ausbleiben nicht auf. */
|
|
const MANIFESTE = ["app.webmanifest", "crew.webmanifest"];
|
|
const MUSTER_MANIFEST =
|
|
/("src":\s*")(\/assets\/img\/app-symbole\/[A-Za-z0-9._-]+)(?:\?v=\d+)?(")/g;
|
|
for (const name of MANIFESTE) {
|
|
const pfad = join(ORDNER, name);
|
|
if (!existsSync(pfad)) {
|
|
console.error(`FEHLER: ${name} fehlt -- erwartet in ${ORDNER}.`);
|
|
process.exit(1);
|
|
}
|
|
const alt = readFileSync(pfad, "utf8");
|
|
let n = 0;
|
|
const neu = alt.replace(MUSTER_MANIFEST, (_, vor, datei, nach) => {
|
|
n += 1;
|
|
return `${vor}${datei}?v=${STEMPEL}${nach}`;
|
|
});
|
|
/* Findet das Muster nichts, ist das ein FEHLER und kein Achselzucken:
|
|
Dann hat jemand das Manifest umgebaut, und ab da laeuft das Symbol
|
|
still auf dem alten Stand weiter. */
|
|
if (n === 0) {
|
|
console.error(`FEHLER: in ${name} keine Symboladresse gefunden -- Muster pruefen.`);
|
|
process.exit(1);
|
|
}
|
|
if (neu !== alt) { writeFileSync(pfad, neu); dateien += 1; stellen += n; }
|
|
console.log(` ${name.padEnd(20)} ${n} Verweise`);
|
|
}
|
|
|
|
console.log(`\nStempel ${STEMPEL} auf ${stellen} Verweise in ${dateien} Dateien gesetzt.`);
|
|
if (!dateien) console.log("Nichts geaendert -- stimmt das Muster noch?");
|