import { config } from '../../config.js' import { deleteDocument, listDocuments, Query } from '../appwriteAdmin.js' import { loescheAlleBilder } from './bilder.js' /** * Alle Daten EINES Shops loeschen (Plan 2026-10-05-webshop.md, J3): Bestellungen, Artikel, Widerrufe, das Archiv der bestaetigten Rechtstexte, Artikelbilder und zuletzt das * shopConfig-Dokument. Gemeinsamer Baustein des Tagesjobs (Shop seit 90 Tagen abgeschaltet, jobs.js) und der Loeschfristen * (retention.js, Kunde faellig). Bewusst ohne Import von bestellungen.js/Stripe: retention.js darf nichts Schweres nachladen. * Das Stripe-Konto gehoert dem Haendler und wird nie angefasst. * * Seitenweise (100 je Abfrage, immer die erste Seite neu, denn gelesene Dokumente sind danach weg). Am Deckel endet der Lauf * (vollstaendig: false), der naechste setzt fort. Ein Fehler beim Loeschen wirft (sonst wuerde dieselbe Seite endlos neu gelesen). */ const SEITE = 100 const GRUPPEN = [ ['shopOrders', 'bestellungen'], ['shopProducts', 'artikel'], ['shopWiderrufe', 'widerrufe'], ['shopRechtstexteArchiv', 'archiv'], ] /** * @param {{ shopId: string, siteKey?: string, deckel?: number, nochGueltig?: () => Promise }} opt * deckel: hoechstens so viele Dokumente (Bestellungen + Artikel + Widerrufe + Archiv); nochGueltig wird vor jeder Seite gefragt (false = abbrechen) * @returns {Promise<{ bestellungen: number, artikel: number, widerrufe: number, archiv: number, geloescht: number, konfig: boolean, vollstaendig: boolean, abgebrochen: boolean }>} * vollstaendig = alle Dokumente, Bilder und das shopConfig-Dokument sind weg */ export async function loescheShopDaten({ shopId, siteKey, deckel = Number.POSITIVE_INFINITY, nochGueltig = async () => true }) { if (typeof shopId !== 'string' || shopId === '') throw new TypeError('loescheShopDaten: shopId fehlt') const erg = { bestellungen: 0, artikel: 0, widerrufe: 0, archiv: 0, geloescht: 0, konfig: false, vollstaendig: false, abgebrochen: false } for (const [name, feld] of GRUPPEN) { const sammlung = config.collections[name] for (;;) { if (!(await nochGueltig())) return { ...erg, abgebrochen: true } const rest = deckel - erg.geloescht if (rest <= 0) return erg const seite = await listDocuments(sammlung, [Query.equal('shopId', shopId), Query.limit(Math.min(SEITE, rest))]) if (seite.length === 0) break for (const doc of seite) { try { await deleteDocument(sammlung, doc.$id) } catch (err) { if (err?.status !== 404) throw err } erg[feld] += 1 erg.geloescht += 1 } } } if (!(await nochGueltig())) return { ...erg, abgebrochen: true } if (siteKey) await loescheAlleBilder(siteKey) try { await deleteDocument(config.collections.shopConfig, shopId) erg.konfig = true } catch (err) { if (err?.status !== 404) throw err } erg.vollstaendig = true return erg }