fix(community): nur bei eindeutigem Ausgang aufräumen, Tag- und Kurzsuche, kleine Härtungen
- publish.ts: bei Fehlern der API werden die hochgeladenen Dateien nur bei eindeutiger Ablehnung (4xx außer 408/429, JWT-Fehler vor der Anfrage) gelöscht; bei offenem Ausgang (Netzfehler, Zeitlimit, 5xx, 429, Antwort ohne id) bleiben sie liegen, damit keine öffentliche Zeile auf gelöschte Bilder zeigt - api.ts: ApiError.definitive und isDefinitiveFailure, Zeitlimit 15 s, gleichzeitige createJWT werden geteilt - gallery.ts: Tag-Filter (contains auf tags), Kurzsuche unter 3 Zeichen per contains, loadGalleryImage prüft die Datei-ID - geometry.ts: PREVIEW_WIDTH/PREVIEW_QUALITY an einer Stelle (Editor und Veröffentlichen) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
89c86fd578
commit
ae73dc4a0b
8 files changed
+449
-48
No files matched your search
@@ -3,16 +3,14 @@
|
||||
import { ID, Permission, Role } from 'appwrite';
|
||||
import { IDS, storage } from '../account/appwrite';
|
||||
import { cardsService, requireUserId, toUploadFile, type SavedCard } from '../account/cards';
|
||||
import { CARD_W } from '../card/geometry';
|
||||
import { CARD_W, PREVIEW_QUALITY, PREVIEW_WIDTH } from '../card/geometry';
|
||||
import { clampCrop } from '../card/crop';
|
||||
import { exportCard, loadCardAssets } from '../card/render';
|
||||
import { decodeImage } from '../editor/upload';
|
||||
import { publishCard, type PublishInput } from './api';
|
||||
import { isDefinitiveFailure, publishCard, type PublishInput } from './api';
|
||||
|
||||
/** Der Galerie-Bucket nimmt Dateien bis 5 MiB an (wie der Server prüft). */
|
||||
export const PNG_MAX_BYTES = 5_242_880;
|
||||
const PREVIEW_WIDTH = 480;
|
||||
const PREVIEW_QUALITY = 0.85;
|
||||
const TOO_LARGE = 'Das Kartenbild ist zu groß für die Galerie (max. 5 MB).';
|
||||
const NOT_RENDERED = 'Das Kartenbild konnte nicht erzeugt werden.';
|
||||
const GALLERY_TYPES = ['image/png', 'image/webp'];
|
||||
@@ -80,8 +78,15 @@ async function deleteQuietly(deps: PublishDeps, fileIds: string[]): Promise<void
|
||||
|
||||
/**
|
||||
* Veröffentlicht die Karte: Bild laden, rendern, PNG und Vorschau in den Galerie-Bucket laden, API rufen.
|
||||
* Schlägt nach dem ersten Upload etwas fehl (zweiter Upload, API, auch 409), werden die in diesem Versuch
|
||||
* hochgeladenen Dateien (und nur diese) gelöscht und der Fehler weitergeworfen.
|
||||
*
|
||||
* Aufräumen (nur die zwei Dateien dieses Versuchs, nie etwas anderes):
|
||||
* - Scheitert ein Upload, ist noch nichts veröffentlicht: der erste Upload wird gelöscht.
|
||||
* - Scheitert die API eindeutig (4xx außer 408/429, auch 409, oder schon der JWT-Abruf), wurde nichts angelegt:
|
||||
* beide Dateien werden gelöscht.
|
||||
* - Bleibt der Ausgang offen (Netzfehler, Zeitlimit, 5xx, 408, 429, Antwort ohne `id`), kann die API die Zeile schon
|
||||
* angelegt haben. Dann bleiben die Dateien liegen: sonst zeigte eine öffentliche Karte auf gelöschte Bilder.
|
||||
* (Ein Waisen-Upload ist harmlos: unverlinkt, mit Zufalls-ID, vom Nutzer jederzeit löschbar.)
|
||||
* Der Fehler wird in jedem Fall weitergeworfen.
|
||||
*/
|
||||
export async function publishSavedCard(
|
||||
card: SavedCard,
|
||||
@@ -105,6 +110,13 @@ export async function publishSavedCard(
|
||||
try {
|
||||
uploaded.push((await deps.createFile(imageFile, permissions)).$id);
|
||||
uploaded.push((await deps.createFile(previewFile, permissions)).$id);
|
||||
} catch (err) {
|
||||
// Die API wurde noch nicht gerufen: es gibt keine Zeile, die auf die Dateien zeigen könnte.
|
||||
await deleteQuietly(deps, uploaded);
|
||||
throw err;
|
||||
}
|
||||
|
||||
try {
|
||||
return await deps.publishCard({
|
||||
title: form.title.trim(),
|
||||
issuer: form.issuer.trim(),
|
||||
@@ -115,7 +127,7 @@ export async function publishSavedCard(
|
||||
sourceCardId: card.id,
|
||||
});
|
||||
} catch (err) {
|
||||
await deleteQuietly(deps, uploaded);
|
||||
if (isDefinitiveFailure(err)) await deleteQuietly(deps, uploaded);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user