feat(api): Logo-Endpunkte, Fehlercodes und gemeinsame Helfer
- common.js (aus app.js herausgelöst, Verhalten gleich): MSG, HttpError, Prüfungen, Rechte-Strings, Melder-Hash,
Bildmaße und die Dateiprüfungen checkFileExists/checkFileOwnership. Neu: die Logo-Texte in MSG, codeFor,
likeRowPermissions. app.js exportiert weiter alles wie bisher.
- Fehlerantworten sind jetzt {error, code}: code = MSG-Schlüssel des Textes, dynamische Prüftexte badRequest,
Appwrite-Fehler unavailable (502) bzw. internal (500).
- logos.js: POST /api/logos/hochladen, /herz, /melden, /loeschen und /api/admin/logo-sichtbarkeit nach dem Vorbild der
Karten-Endpunkte (Datei prüfen, Zeile anlegen, Datei auf read("any") festlegen, sonst Rücknahme; likeCount und
reportCount immer aus countRows; ein gemeinsames Rate-Limit für Karten- und Logo-Meldungen).
- appwrite.js: countRows. fake-appwrite.js: Tabellen logos, logo_likes, logo_reports mit Spaltenlängen, Bucket
logo-images und total in den Listen-Antworten.
- Tests: logos.test.js (59), code-Fälle und MSG-Eindeutigkeit in app.test.js (+7), countRows in appwrite.test.js (+2);
alle 111 bisherigen Tests unverändert grün (179 gesamt).
- Doku: api/README.md (Endpunkte, Fehlercodes, Logo-Regeln), deploy/README.md (Betrieb kopiert fünf Dateien).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
88abc2061d
commit
dc5de99611
10 files changed
+2181
-286
No files matched your search
+17
-2
@@ -7,6 +7,8 @@
|
||||
* getRow(table, id) Zeile oder null (404 row_not_found)
|
||||
* listRows(table, queries) Array von Zeilen; queries = JSON-Strings (queryEqual, queryLimit, queryCursorAfter);
|
||||
* eine Antwort ohne `rows`-Array ist ein Fehler (kein stilles [])
|
||||
* countRows(table, queries) Anzahl aller Treffer (`total` einer Abfrage mit limit(1), ohne eigenes limit
|
||||
* in `queries`); eine Antwort ohne gültiges `total` ist ein Fehler
|
||||
* createRow(table, rowId, data, permissions) doppelte ID -> AppwriteError mit status 409
|
||||
* updateRow(table, id, data, permissions?) Rechte nur ändern, wenn übergeben
|
||||
* deleteRow(table, id) true, false bei 404 row_not_found (wiederholbar)
|
||||
@@ -74,6 +76,10 @@ function createAppwrite({ endpoint, project, key, fetchImpl = globalThis.fetch,
|
||||
const base = endpoint.replace(/\/+$/, '');
|
||||
const rowsPath = (table) => `/tablesdb/${segment(database)}/tables/${segment(table)}/rows`;
|
||||
const filePath = (bucket, id) => `/storage/buckets/${segment(bucket)}/files/${segment(id)}`;
|
||||
const rowsUrl = (table, queries) => {
|
||||
const search = queries.map((query) => `queries[]=${encodeURIComponent(query)}`).join('&');
|
||||
return `${rowsPath(table)}${search === '' ? '' : `?${search}`}`;
|
||||
};
|
||||
|
||||
/** Liest höchstens `limit` Bytes vom Anfang der Antwort und bricht den Rest ab (Dateien können 5 MiB groß sein). */
|
||||
async function readHead(response, limit) {
|
||||
@@ -145,14 +151,23 @@ function createAppwrite({ endpoint, project, key, fetchImpl = globalThis.fetch,
|
||||
},
|
||||
|
||||
async listRows(table, queries = []) {
|
||||
const search = queries.map((query) => `queries[]=${encodeURIComponent(query)}`).join('&');
|
||||
const result = await send('GET', `${rowsPath(table)}${search === '' ? '' : `?${search}`}`);
|
||||
const result = await send('GET', rowsUrl(table, queries));
|
||||
if (!result.body || !Array.isArray(result.body.rows)) {
|
||||
throw new AppwriteError(502, 'invalid_response', 'Unerwartete Antwort von Appwrite');
|
||||
}
|
||||
return result.body.rows;
|
||||
},
|
||||
|
||||
/** Zählt die Treffer einer Abfrage über `total` (Appwrite zählt bis 5000): es wird höchstens eine Zeile übertragen. */
|
||||
async countRows(table, queries = []) {
|
||||
const result = await send('GET', rowsUrl(table, [...queries, queryLimit(1)]));
|
||||
const total = result.body && result.body.total;
|
||||
if (!Number.isInteger(total) || total < 0) {
|
||||
throw new AppwriteError(502, 'invalid_response', 'Unerwartete Antwort von Appwrite');
|
||||
}
|
||||
return total;
|
||||
},
|
||||
|
||||
async createRow(table, rowId, data, permissions) {
|
||||
const result = await send('POST', rowsPath(table), { body: { rowId, data, permissions } });
|
||||
return result.body;
|
||||
|
||||
Reference in new issue
Block a user