diff --git a/CLAUDE.md b/CLAUDE.md index 858c656..31cb2f3 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,4 +1,4 @@ -# Arbeitsweise in diesem Projekt +c# Arbeitsweise in diesem Projekt ## Prüfen statt raten diff --git a/server/src/routes/freigabe.ts b/server/src/routes/freigabe.ts index a8706a6..b5b6d2b 100644 --- a/server/src/routes/freigabe.ts +++ b/server/src/routes/freigabe.ts @@ -35,6 +35,13 @@ export function neuerSchluessel(): string { return Array.from(roh, (b) => ZEICHEN[b % ZEICHEN.length]).join('') } +/** Wieviele Dateien liegen unter diesem Ordner -- die WAHRE Zahl. + * + * Dieselbe Bedingung wie die Liste darunter, nur ohne Grenze. Zwei Abfragen + * statt einer, weil `zeilen.length` nach einem `LIMIT` eben nicht die Anzahl + * ist, sondern die Anzahl der geholten Zeilen. */ +const GEZAEHLT = `SELECT COUNT(*) AS n FROM media WHERE path LIKE ? ESCAPE '\\'` + /** Die Liste eines freigegebenen Ordners. * * OHNE ANMELDUNG, und deshalb wird hier genau abgemessen, was hinausgeht: @@ -56,12 +63,32 @@ freigabeRoutes.get('/:schluessel', (c) => { ) const maskiert = eintrag.ordner.replace(/[\\%_]/g, (z) => `\\${z}`) + // WIEVIELE ES WIRKLICH SIND -- getrennt gezaehlt, nicht aus der Liste + // abgeleitet. + // + // GEMESSEN am 22.08.2026: der Ordner "items" enthaelt 3685 Dateien, die + // Freigabeseite meldete 2000. Der Grund stand eine Zeile weiter unten -- + // `LIMIT 2000` -- und `anzahl: zeilen.length` machte aus der Kappung eine + // Aussage: die Seite behauptete eine Vollstaendigkeit, die sie nicht hatte. + // + // Genau der Fall aus CLAUDE.md: eine Auskunft, die nicht alles sehen kann, + // meldet nicht die halbe Zahl als ganze, sondern sagt, dass sie kappt. + const gesamt = ( + db + .prepare(GEZAEHLT) + .get(`${maskiert}/%`) as { n: number } + ).n + + // Die Grenze bleibt -- eine Freigabe auf einen Ordner mit 200000 Dateien + // soll den Dienst nicht in die Knie zwingen. Sie ist nur nicht mehr + // stillschweigend: was darueber liegt, wird unten benannt. + const GRENZE = 20000 const zeilen = db .prepare( `SELECT path, size, mime, dauer FROM media - WHERE path LIKE ? ESCAPE '\\' ORDER BY path COLLATE NOCASE LIMIT 2000`, + WHERE path LIKE ? ESCAPE '\\' ORDER BY path COLLATE NOCASE LIMIT ?`, ) - .all(`${maskiert}/%`) as Pick[] + .all(`${maskiert}/%`, GRENZE) as Pick[] return c.json({ // Auch hier der Name aus derselben Einstellung -- die Freigabeseite ist @@ -72,7 +99,11 @@ freigabeRoutes.get('/:schluessel', (c) => { // Der Praefix, den die Oberflaeche abschneidet -- damit dort // "adder.webp" steht und nicht "vehicles/adder.webp". Wer den ganzen // Pfad sehen will, sieht ihn in der Adresse. - anzahl: zeilen.length, + // Die WIRKLICHE Zahl, nicht die der ausgelieferten Zeilen. + anzahl: gesamt, + // Und wieviele davon hier stehen. Sind beide gleich, ist die Liste + // vollstaendig; sonst weiss die Oberflaeche, dass sie es sagen muss. + gezeigt: zeilen.length, items: zeilen.map((r) => ({ name: r.path.slice(eintrag.ordner.length + 1), size: r.size,