Termine-Outbox: notEqual mit genau einem Wert (Appwrite 1.8.1), nachrangige Mails kommen wieder dran
Auf der echten Appwrite 1.8.1 lehnt notEqual mit Liste die Abfrage ab (HTTP 400
general_query_invalid, "NotEqual queries require exactly one value"). Die Klasse normal der
Mail-Warteschlange schickte immer eine Liste, jeder Lauf warf dort, und die nachrangige Klasse
(G05, K20, K21) kam nie dran.
- appwriteAdmin: Query.notEqual nimmt genau einen Wert (eine Liste wirft einen TypeError, der
keinerVon nennt); neu keinerVon(attribute, werte) = je Wert ein notEqual (Appwrite schneidet
sie); dokumenteUrl() baut die Listen-URL ohne Netz, mit derselben Serialisierung wie die Anfrage.
- outbox: klassenFilter liefert fuer jede Klasse eine Liste von Abfragen (normal = sechs notEqual
auf art), die Ausschlussliste ist keinerVon('featureId', ...). AUSSCHLUSS_MAX 90 -> 30 (der nginx
antwortet in dieser Abfrageform ab 46 Funktions-IDs mit 414); der Kommentar "100 Werte je Abfrage"
entfaellt.
- Nachbau (appwriteMock): notEqual mit Liste oder ohne Wert => 400 wie Appwrite; ein Dokument mit
Feld null oder ohne Feld passt nicht zu notEqual (SQL-Semantik).
- Tests: Query-Helfer, keinerVon, dokumenteUrl, Nachbau (400, null), ein Lauf bedient alle drei
Klassen, Ausschlussliste hoechstens 30 und URL unter 6000 Zeichen im schlimmsten Fall.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
af63b69ec1
commit
2c7cd26532
5 files changed
+196
-39
No files matched your search
@@ -8,6 +8,18 @@ function buildQueries(queries = []) {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* URL einer Anfrage: Pfad plus eine `queries[]` je Abfrage (JSON, URL-kodiert). Die einzige Stelle, die sie baut (adminFetch und
|
||||
* dokumenteUrl), damit die Laenge, die der nginx vor Appwrite zaehlt (siehe AUSSCHLUSS_MAX in termine/outbox.js), pruefbar bleibt.
|
||||
*/
|
||||
function buildUrl(path, queries = []) {
|
||||
const url = new URL(`${config.appwrite.endpoint}${path}`)
|
||||
for (const q of buildQueries(queries)) {
|
||||
url.searchParams.append('queries[]', q)
|
||||
}
|
||||
return url
|
||||
}
|
||||
|
||||
function adminHeaders() {
|
||||
return {
|
||||
'Content-Type': 'application/json',
|
||||
@@ -33,10 +45,7 @@ async function adminFetch(path, { method = 'GET', body, queries = [], raw = fals
|
||||
throw error
|
||||
}
|
||||
|
||||
const url = new URL(`${config.appwrite.endpoint}${path}`)
|
||||
for (const q of buildQueries(queries)) {
|
||||
url.searchParams.append('queries[]', q)
|
||||
}
|
||||
const url = buildUrl(path, queries)
|
||||
|
||||
const useRawBody = raw || path.startsWith('/users')
|
||||
const requestBody = formatRequestBody(body, method, { raw: useRawBody })
|
||||
@@ -93,12 +102,30 @@ export const Query = {
|
||||
orderAsc: (attribute) => ({ method: 'orderAsc', attribute }),
|
||||
/** Nur diese Felder zurueckgeben (die $-Felder wie $id liefert Appwrite immer mit) */
|
||||
select: (attributes) => ({ method: 'select', values: attributes }),
|
||||
/** Ein Wert oder eine Liste: kein Dokument mit einem der Werte ("keiner von") */
|
||||
notEqual: (attribute, value) => ({
|
||||
method: 'notEqual',
|
||||
attribute,
|
||||
values: Array.isArray(value) ? value : [value],
|
||||
}),
|
||||
/**
|
||||
* Kein Dokument mit diesem Wert. Genau EIN Wert: Appwrite 1.8.1 lehnt eine Liste ab (HTTP 400 general_query_invalid
|
||||
* "NotEqual queries require exactly one value.", gemessen 2026-10-05, M1). Fuer mehrere Werte keinerVon(attribute, werte).
|
||||
* Zwei Eigenheiten der echten Datenbank, die auch der Nachbau der Tests hat: mehrere notEqual in einer Anfrage werden
|
||||
* geschnitten (M2, bis 40 getestet), und ein Dokument, dessen Feld null ist oder fehlt, passt NICHT zu notEqual, SQL-Semantik
|
||||
* (M3): nur verwenden, wenn das Feld an jedem Dokument gesetzt ist.
|
||||
*/
|
||||
notEqual: (attribute, value) => {
|
||||
if (Array.isArray(value)) throw new TypeError(`Query.notEqual('${attribute}') nimmt genau einen Wert (Appwrite lehnt eine Liste ab); fuer mehrere keinerVon('${attribute}', werte) benutzen`)
|
||||
return { method: 'notEqual', attribute, values: [value] }
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* "Keiner von diesen Werten": je Wert eine notEqual-Abfrage mit genau einem Wert; Appwrite schneidet sie (M2). Ohne Werte
|
||||
* keine Abfrage (leeres Array). Jede Abfrage steht als eigenes queries[] in der URL, die Zahl der Werte also begrenzen
|
||||
* (M4: der nginx vor Appwrite antwortet mit 414, in der Abfrage der Mail-Warteschlange ab 46 Werten); fuer M1 bis M3
|
||||
* siehe Query.notEqual.
|
||||
* @param {string} attribute
|
||||
* @param {Iterable<string|number|boolean>} werte
|
||||
* @returns {object[]}
|
||||
*/
|
||||
export function keinerVon(attribute, werte) {
|
||||
return [...(werte ?? [])].map((wert) => Query.notEqual(attribute, wert))
|
||||
}
|
||||
|
||||
export const ID = {
|
||||
@@ -109,6 +136,11 @@ function collectionPath(collectionId) {
|
||||
return `/databases/${config.appwrite.databaseId}/collections/${collectionId}/documents`
|
||||
}
|
||||
|
||||
/** Die URL der Listenabfrage einer Collection (ohne Netz), so wie listDocuments sie sendet: fuer Tests der URL-Laenge. */
|
||||
export function dokumenteUrl(collectionId, queries = []) {
|
||||
return buildUrl(collectionPath(collectionId), queries).toString()
|
||||
}
|
||||
|
||||
export async function getUserById(userId) {
|
||||
return adminFetch(`/users/${userId}`)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user