Entscheidungen vom 04.10.2026:
- Projekt-Routen (website-projects, preview, gitea, services, analyse)
fuer jeden Mitarbeiter (Label mitarbeiter oder admin); Kunden-,
Mitarbeiter- und Finanz-Verwaltung bleiben nur fuer Admins
- Neue Repos aus der Vorlage werden privat angelegt
- Archivierte Projekte sieht der Kunde nicht mehr: Projektliste,
Projektdetails, Preview-Zugang, Funktionen (Mitarbeiter-Ansicht schon)
- Projektliste des Kunden mit Limit (Appwrite liefert sonst nur 25)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Anlegen uebernimmt keinen alten Eintrag gleichen Namens mehr (Repo in
Gitea geloescht): Platzhalter werden entfernt, ein verknuepftes altes
Projekt blockiert den Namen mit klarer Meldung, bevor ein Repo entsteht;
neue Projekte starten mit archived=false
- archiveRepo aendert Gitea und Dokument unter der Repo-Sperre; der Import
liest den Archiv-Stand vor dem Spiegeln frisch aus Gitea
- Reaktivieren: Preview aus -> synced, Deploy-Fehler -> deploy_failed
statt dauerhaft 'pending'
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Neues Projekt ohne Subdomain: subdomain null statt '' (Unique-Index
subdomain_unique, jedes weitere scheiterte mit "Document with the
requested ID already exists"); ebenso Typ "Internes Projekt"
- Anlegen unter derselben Repo-Sperre wie der Webhook repository/created;
upsertWebsiteProjectByRepo macht aus einem 409 ein Update
- Gitea-Beschreibung = Anzeigename; Art (kind) beim Anlegen aus dem Ticket
- Reaktivieren setzt status zurueck (vorher blieb 'archived' stehen)
- Import: archivierte Repos als archiviert, Archiv-Stand aus Gitea wird
gespiegelt, ein fehlerhaftes Repo bricht den Lauf nicht mehr ab
- Abgleich ueberschreibt Projektnamen nicht mehr
- CORS erlaubt PUT (Preview-Variablen speichern)
- Vorlage zieht beim Zuweisen nie in die Org um
- Erinnerungs-Lauf ueberspringt archivierte Projekte
- kaputte Umlaute (U+FFFD) in drei Fehlermeldungen
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Messdienst: POST /a/admin/sites/:key/off setzt active=0 und offSince einmalig; Portal-Client stopSite.
analyse.js: endAnalyse als gemeinsamer Kern, endAnalyseForCustomer, analyseOnProjectChanged,
analyseDisabled (Sperre/Löschfrist) und täglicher Abgleich runAnalyseReconcile (Projekt/Kunde weg,
Domains nachziehen, K18-Wiederholung, Messdienst für off/disabled, fehlende Entfernen-Tickets nachholen).
Entfernen-Ticket je Abschaltung gekennzeichnet (kein Doppelticket, auch wenn das Speichern der ID scheiterte).
Hooks: Kunde löschen, updateWebsiteProject, withdrawOrder (Wechsel), siteFeatures.disable.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- runDeploy: Repos mit package.json-build-Script ohne index.html werden
automatisch als node_build gebaut (Expo/Vite/React zeigen sonst nur den
Platzhalter); Build-Fehler fallen auf static+Platzhalter zurueck
- deployNodeBuild: npm-ci-Fallback auf npm install, Output-Erkennung
dist/build/out/web-build, maxBuffer+Timeout
- updateWebsiteProject: bestehenden type/index aus .webklar-preview.json
erhalten statt bei jedem Edit auf static zurueckzusetzen
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- runDeploy schreibt Platzhalter-index.html, wenn das Deploy-Verzeichnis
keine index.html enthaelt (leergeraeumtes Repo/Fehlbuild) -> nie mehr
nginx 403 Forbidden, Subdomain bleibt erreichbar.
- deployStatic: Fallback auf Repo-Wurzel bei fehlendem index-Unterordner,
.git wird nicht mehr mit ausgeliefert.
- Webhook: fehlt .webklar-preview.json im Repo, wird die Hosting-Config aus
dem Appwrite-Projektstand rekonstruiert, ins Repo zurueckgeschrieben und
normal deployt (ensureRepoPreviewConfig).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- archiveRepo: fehlt das Gitea-Repo (404), wird nur das Appwrite-Dokument
(ent)archiviert statt hart zu scheitern -> orphaned Projekte lassen sich
aus der Liste entfernen
- Reaktivierungs-Redeploy wird bei fehlendem Repo uebersprungen
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- hasPreview existiert im Live-Schema nicht -> Appwrite lehnte Update ab
- syncPreviewTls muss NACH updateDocument laufen, sonst liest es isPublic
noch im alten Zustand (oeffentlicher Router bekam faelschlich preview-auth)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- previewDeploy.syncPreviewTls(): schreibt Traefik-Router (Host-Regeln) fuer alle
Preview-Subdomains nach preview-hosts.yml, damit Let's Encrypt Zertifikate
ausstellt. Laeuft nach jedem Deploy und beim Serverstart (ersetzt das nie
aufgerufene bash-Script sync-preview-tls.sh).
- createProjectFromTemplate: Subdomain optional. Ohne Subdomain wird nur das
Gitea-Repo angelegt (projectType 'repo', Status 'created'), kein Deploy.
- customerAdmin: Portal-Passwort liegt jetzt im Feld customers.portalPassword
statt als __portalPassword__-Prefix in den Notizen; Legacy-Notizen werden
beim naechsten Update bereinigt. CRM-Stufe (lead/customer) wird beim Setzen
des Portal-Passworts nicht mehr auf 'active' ueberschrieben.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sichert den bisher uncommitteten Produktionsstand des Kundenbereich-Servers,
damit kuenftige Deploys (git reset --hard) nichts mehr verwerfen.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>