import { config } from '../../config.js' import { berlinDateTime } from '../berlinTime.js' import { getDocument } from '../appwriteAdmin.js' import { createFeatureTicket } from '../ticketAdmin.js' import { ersatzHtml, wochenplanHash } from './ersatz.js' import { ladeZeiten, setzeErsatzHash } from './speicher.js' import { hauptplan } from './zeitlogik.js' /** * Nach dem Abschalten von Oeffnungszeiten live (Spec 4.5): steht in den Platzhaltern der Kundenseite noch eine Ersatz-Tabelle, die * nicht mehr zum aktuellen Wochenplan passt, bekommt das Team ein WOMS-Ticket "Ersatz-Tabelle aktualisieren - " mit dem * aktuellen Ersatz-HTML (gehoert zum enthaltenen Einbau). Ohne Skript zeigt die Seite ab jetzt nur noch diese Tabelle. * * Aufrufer: die Team-Route (disable) und spaeter der Abo-Abgleich (Abo-Ende). Aufruf NACH dem Speichern des Zustands und ausserhalb * jeder Sperre `feature-admin:`: das Ticket legt eine Netzwerkanfrage an, und Sperren sind nicht wiederbetretbar. */ const THEMA = 'Ersatz-Tabelle aktualisieren' /** Text des Tickets: Kopfzeilen wie bei den Einbau-Tickets, Anlass, Aufgabe und das aktuelle Ersatz-HTML des Hauptplans. */ function ticketDetails({ doc, project, daten, haupt, now }) { const projektName = project?.projectName || project?.subdomain || '' const domain = project?.liveDomain || project?.previewUrl || project?.subdomain || '' return [ 'Funktion: zeiten', `Projekt: ${projektName}`, `Domain: ${domain}`, `siteKey: ${doc.siteKey ?? ''}`, '', `Öffnungszeiten live wurde am ${berlinDateTime(now).date} abgeschaltet. Der Wochenplan weicht von der Tabelle ab, die beim Einbau auf die Seite gesetzt wurde (oder der damalige Stand ist nicht bekannt).`, 'Aufgabe: Auf der Kundenseite in jedem Platzhalter
die Tabelle durch die aktuelle ersetzen. Ohne Skript zeigt die Seite nur noch diese Tabelle.', 'Weitere Pläne: WOMS → Funktionen → Ersatz-HTML kopieren.', '', haupt.kurz ? `Ersatz-HTML (Hauptplan ${haupt.kurz}):` : 'Ersatz-HTML (Hauptplan):', ersatzHtml(daten, haupt), ].join('\n') } /** Das Projekt des Dokuments; ein geloeschtes Projekt (404) ist kein Fehler, der Name fehlt dann im Ticket. */ async function ladeProjekt(projectId) { try { return await getDocument(config.collections.websiteProjects, projectId) } catch (err) { if (err?.status === 404) return null throw err } } /** * Pruefen, ob die Ersatz-Tabelle der Seite noch zum Wochenplan passt, und sonst das Ticket anlegen. * Ruling R23: ein leerer oder fehlender gemerkter Hash (ersatzHash) gilt als "unbekannt", also wie geaendert, sobald Zeiten da sind * (schlimmstenfalls ein unnoetiges Ticket). Nach dem Ticket wird der Hash auf den aktuellen Stand gesetzt: er gehoert dann zur Tabelle, * die das Team einsetzt, und ein zweiter Aufruf (Doppelklick, spaeterer Lauf) legt kein zweites Ticket an. Scheitert das Ticket, * bleibt der Hash, und der naechste Aufruf versucht es erneut. * @param {{ $id: string, customerId?: string, projectId?: string, siteKey?: string }} doc portalFeatures-Dokument der Zeiten * (aus disable(): der Stand nach dem Abschalten) * @param {{ now?: Date }} [options] * @returns {Promise<'angelegt'|'aktuell'|'fehler'>} angelegt: Ticket entstanden; aktuell: nichts zu tun (keine Zeiten oder Hash gleich); * fehler: nicht pruefbar oder Ticket nicht angelegt (im Log ohne Kundendaten). Wirft nie. */ export async function nachAbschaltung(doc, { now = new Date() } = {}) { try { if (typeof doc?.$id !== 'string' || doc.$id === '') throw new TypeError('Dokument ohne $id') const gespeichert = await ladeZeiten(doc.$id) const daten = gespeichert?.daten ?? null const haupt = hauptplan(daten) // ohne Zeiten wurde nie eine Tabelle zum Ersetzen vorbereitet if (!haupt) return 'aktuell' const hash = wochenplanHash(daten) if (gespeichert.ersatzHash !== '' && gespeichert.ersatzHash === hash) return 'aktuell' const project = await ladeProjekt(doc.projectId) const projektName = project?.projectName || project?.subdomain || '' await createFeatureTicket({ customerId: doc.customerId, project, featureKey: 'zeiten', siteKey: doc.siteKey, topic: projektName ? `${THEMA} – ${projektName}` : THEMA, details: ticketDetails({ doc, project, daten, haupt, now }), }) // Das Ticket steht; scheitert nur das Merken, entsteht beim naechsten Abschalten ein zweites (Log, kein Fehler) try { await setzeErsatzHash(doc, hash) } catch (err) { console.error(`[zeiten] Ersatz-Hash für Projekt ${doc.projectId} nach dem Ticket nicht gemerkt: ${err?.name ?? 'Fehler'} ${err?.status ?? ''}`.trim()) } return 'angelegt' } catch (err) { // nie Kundendaten ins Log: Art und Statuscode, keine Meldung (Appwrite-Meldungen koennen Feldinhalte nennen) console.error(`[zeiten] Ersatz-Ticket nach dem Abschalten (Projekt ${doc?.projectId ?? '?'}): ${err?.name ?? 'Fehler'} ${err?.status ?? ''} ${err?.type ?? ''}`.replace(/\s+/g, ' ').trim()) return 'fehler' } }