Commit Graph
36 Commits
Author SHA1 Message Date
ClaudeandClaude Opus 5.5 1b7aa9ebe3 Shop Review B I-8: Aktivierung des Webshops durch das Team nur mit Zustimmung in Textform
AVV Webshop, Vorbemerkung Abs. 2: Das Team darf den Webshop ohne Online-Bestellung
nur einschalten, wenn der Kunde vorher in Textform zugestimmt hat. Die Textform-Aktivierung
gilt jetzt wie beim Terminplaner auch fuer 'shop' (Modus on, Pilotadressen ausgenommen,
shopTextformNoetig): Nachweis in featureConsents mit Fassung (config.shop.fassung), Datum,
Weg, Mitarbeiter und dem Wortlaut der Erklaerungen der Bestelltexte, K16 mit
Leistungsbeschreibung und AVV als PDF. GET /api/team/funktionen/:kunde liefert zusaetzlich
shop { textformNoetig, avvVersion, links }.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 09:44:11 +00:00
ClaudeandClaude Opus 5.5 309c98d531 Shop Review A M10: Kontext-Cache des Shops beim Abschalten leeren
disable (und damit disableCustomerFeatures bei Kundenloeschung) leert fuer die Funktion shop den Kontext-Cache dieses siteKeys, per dynamischem Import und best effort.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 09:38:58 +00:00
ClaudeandClaude Opus 5.5 af63b69ec1 Merge origin/main in feature/terminplaner-tp2 (Analyse-Cockpit, Subdomain-Sperre, Projekte)
Konflikte: funktionen.js folgt der Aufteilung aus main (fn-util.js, analyse.js); der Link
'Zu Verträge' der Analyse-Seite kommt jetzt auch in analyse.js aus vertraege-link.js.
Checkout und Team-Ansicht übernehmen assertOwnProject(..., { forNewOrder: true }) und
includeArchived aus main. Test-Pins der absoluten Importe nachgezogen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 07:11:58 +00:00
ClaudeandClaude Sonnet 5.5 2fc48df915 TP2 Abschlussprüfung: Löschung (IP/Browser auf portalFeatures, Erstattungsspur, K22-Datum)
- markOrdered speichert IP und Browser der Bestellung nicht mehr am Funktionsdokument (nur im Nachweis featureConsents, dort mit
  Löschfrist); Altwerte werden bei einer neuen Bestellung geleert
- Aufbewahrungslauf (retention): consentIp, consentUserAgent, consentText, consentAt werden an allen Funktionsdokumenten eines fälligen
  Kunden geleert, auch an abgeschalteten; Fehlschlag hält den Kunden wie die übrigen abhängigen Daten
- Einmal-Skript scripts/feature-consent-felder-leeren.mjs (Standard Probelauf, --apply leert nur, wo featureConsents die Angabe trägt)
- 30-Tage-Reset (jobs.js): auch eine bezahlte Einrichtung mit Grund abo_ende_vor_einrichtung und noch nicht gemeldetem T19 wird nicht
  zurückgesetzt, solange zahlungMeldung nicht gemeldet ist (die Spur der Erstattung bleibt)
- K22: enddatum ist das Abo-Ende (lage.endedAt), sonst der Tag des Abschaltens; loeschdatum bleibt 30 Tage nach dem Abschalten

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-05 06:26:33 +00:00
ClaudeandClaude Sonnet 5.5 b974b3a3ec TP2 Abschlussprüfung: Zahlung/Team (Wiederzustellung, K16-Warnung, Sperrschlüssel)
- adoptPaidSession übernimmt ein erneut zugestelltes checkout.session.completed nicht mehr, wenn das Dokument nach 30 Tagen zurückgesetzt wurde
  (off, purchaseStatus zurueckgesetzt, gleiche Sitzung): kein Setup, kein Ticket, keine K15/T16
- meldeFreigeschaltet liefert true/false; die Staff-Aktivierung in Textform vermerkt eine nicht gesendete K16 mit Unterlagen in adminNote und
  antwortet mit warnung: true
- disable() nutzt die Sperre feature-activate:<id> statt feature-disable:<id> (Freischaltung und Abschalten überholen sich nicht)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-05 06:18:34 +00:00
ClaudeandClaude Sonnet 5.5 bade4edb74 Terminplaner: Staff-Aktivierung nur mit Zustimmung in Textform (Modus on), Portal
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-05 04:44:44 +00:00
ClaudeandClaude Sonnet 5.5 90098726b9 Rechtstexte und K15: Prüfbefunde F5–F8 (AVV genauer, PDF-Prüfsumme, Unterlagen der vereinbarten Fassung)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-05 03:42:27 +00:00
ClaudeandClaude Sonnet 5.5 2c059cb3d6 Funktionen: Vertragsunterlagen als K15-Anhang, Belehrung vor dem Bestellknopf
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-05 03:20:56 +00:00
ClaudeandClaude Sonnet 5.5 f830698dc3 Funktionen: Freischalten nach Abnahme und Ticket nachlegen (Team)
Neue Team-Aktionen abnahme (Freischalten ohne Ticket-Schliessung, K16
einmal, unter feature-activate:<id> mit Haken freischaltHindernis) und
ticket (Ticket nachlegen: Zahlung bei Stripe pruefen und Webhook-Weg,
geloeschtes Ticket ersetzen, vorhandenes unberuehrt). Ticketanlage aus
markPaid in legeTicketAn herausgeloest.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-05 01:08:03 +00:00
ClaudeandClaude Sonnet 5.5 8fe14c2fe6 Funktionen: Freischalt-Hindernisse und Freigabe-Mail ausgelagert
freischaltHindernis (Abo zuerst, dann Einstellung; Abo-Lesefehler = abo_unbekannt)
und meldeFreigeschaltet (K16, Fehler geloggt, mit attachments) in
termine/freischaltung.js. Der Standardhaken freischaltbar fuer termine
delegiert an freischaltHindernis, runActivation an meldeFreigeschaltet.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-05 00:56:35 +00:00
ClaudeandClaude Sonnet 5.5 2db3eca357 Terminplaner: Kurzfassung der Einbauanleitung fuer das Einrichtungs-Ticket, T16-Gesundheitsblock
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-05 00:45:56 +00:00
ClaudeandClaude Sonnet 5.5 c5009da570 Abo-Ende: Sofortpfad beim Widerruf des Wechsels, Team-Aktivierung nur mit laufendem Abo
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 18:19:48 +00:00
ClaudeandClaude Opus 5.5 4fc4c70b7d Archiv/Rechte: Review-Punkte
- archiviertes Projekt bleibt unter Funktionen sichtbar, solange dort eine
  Funktion bestellt/eingerichtet/aktiv ist (z. B. Terminbuchungen)
- auf archivierten Projekten nichts neu bestellen oder einschalten
- Projekttyp Vorlage nur fuer Admins; repo-readme nur fuer bekannte Projekte

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 15:11:54 +00:00
ClaudeandClaude Opus 5.5 3156bb790a Projekte: alle Mitarbeiter, private Repos, Archiv fuer Kunden ausgeblendet
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>
2026-10-04 15:02:02 +00:00
ClaudeandClaude Sonnet 5.5 eae6eee03c Terminplaner TP2 E2: Nachbesserung 1 (Löschdatum nur für den Terminplaner)
Ruling R105: featureView setzt loeschungAm nur für featureKey 'termine' (der
30-Tage-Löschlauf löscht nur Terminplaner-Daten); disabledReason und disabledAt
bleiben für alle Funktionen. Test: News ohne Löschdatum, Zeitfenster-Prüfung
entfernt, Teamroute-Ansicht pinnt loeschungAm für den Terminplaner.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 14:02:57 +00:00
ClaudeandClaude Sonnet 5.5 35c9800856 Abschaltgrund und Loeschfrist in der Funktionsansicht (featureView, frist.js)
featureView liefert zusaetzlich disabledReason, disabledAt und loeschungAm (Berliner
Tag, 30 Tage nach disabledAt); alle drei nur im Zustand disabled, sonst null.
Neu termine/frist.js mit LOESCHFRIST_TAGE, loeschzeit und loeschTag (nur zeit.js/util.js).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 13:58:06 +00:00
ClaudeandClaude Sonnet 5.5 f57dad73ca Freischaltung ueber das Register mit Pruefung von Einstellung und Abo
activateClosedTickets oeffnet jetzt alle Funktionen mit ticketFreischaltung im Register
(ticketFreischaltungKeys) statt fest news und fragt unter der Sperre feature-activate:<id>
nach dem frischen Lesen den Haken freischaltbar(doc). Der Standard fuer termine verlangt eine
gespeicherte Einstellung und ein laufendes Wartungs-Abo. false oder Fehler (z. B. Abo nicht
lesbar) lassen das Dokument in setup: Log und genau ein adminNote-Eintrag "Freischaltung
wartet: <Grund>", keine Mail. News bleibt unveraendert.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 13:35:57 +00:00
ClaudeandClaude Sonnet 5.5 f4754f573a Zahlungseingang in jedem Zustand: nie Geld ohne Spur, nie doppelt (T16/T19)
onFeaturePaid wertet den Fall aus markPaid aus. Trifft die Zahlung eine Funktion, die
schon freigeschaltet, in Einrichtung oder abgeschaltet ist, geht nur eine Team-Meldung
raus (T16 Block bereits_aktiv, bei Abo-Ende vor der Einrichtung T19), kein Ticket und
keine K15. Beide Meldungen laufen genau einmal je Dokument: unter feature-meldung:<id>
frisch lesen, Marker zahlungMeldung gemeldet erst nach gesendeter Mail. Scheitert der
Versand, wirft onFeaturePaid (Webhook 500), Stripe wiederholt und der naechste Versuch
sendet genau einmal.

meldeErstattung ist die einzige Stelle fuer T19 (Zahlung nach dem Abo-Ende und spaeter
die Meldung des Abo-Abgleichs), wirft nie. Bei Funktionen mit Wartungs-Abo-Pflicht
zeigt T16 nach der Verbuchung den Block kein_abo, wenn das Abo nicht mehr laeuft; ein
Lesefehler laesst den Block aus und blockiert nichts. customerOf und projectName sind
exportiert.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 13:25:26 +00:00
ClaudeandClaude Sonnet 5.5 468df49812 Zahlungseingang: markPaid meldet den Fall und merkt ihn im Dokument
markPaid liefert jetzt { doc, created, fall }. Trifft eine Zahlung ein Dokument, das nicht
mehr auf die Bezahlung wartet (active, disabled, setup mit Ticket), wird sie einmalig
verbucht (purchaseStatus paid, unlockedByPurchase, Rechnung, Notiz) und der noch zu
meldende Fall im eigenen Feld zahlungMeldung vermerkt (bereits_aktiv | abgeschaltet |
abo_ende), in einem einzigen Schreibzugriff. Ein Folgeereignis bucht nichts doppelt und
liefert den Fall erneut, bis zahlungMeldung auf gemeldet steht. ordered und fortsetzbares
setup laufen wie bisher, off bleibt unveraendert (Uebernahme ueber adoptPaidSession).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 13:13:42 +00:00
ClaudeandClaude Sonnet 5.5 992d7358fa Mail T16 je Funktion, neue Vorlage T19 Erstattung faellig
T16 (Funktion bestellt) nennt die Funktion aus dem Register statt fest
"News-Pinnwand": neue Platzhalter funktion, zustand, anleitung_url und
gesundheit_text, neue Bloecke kein_abo, bereits_aktiv, anleitung (Knopf
"Im Ticketsystem oeffnen" zur Einbauanleitung) und gesundheit. teamNotice
und unmatchedNotice fuellen funktion aus featureConfig (ohne bekannten
Schluessel "Funktion"); die neuen Bloecke kein_abo, bereits_aktiv und
gesundheit bleiben aus, bis B10a und D4 sie fuellen. Die News-Mails
bleiben woertlich (HTML, Text und Betreff byte-gleich).

T19 (Erstattung faellig, Team-Hinweis) ist neu: volle Erstattung von
Hand in Stripe, Bloecke zahlung_nach_ende, ticket_offen und rechnung.
Gesendet wird sie spaeter ueber meldeErstattung (B10b).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 13:06:39 +00:00
ClaudeandClaude Sonnet 5.5 e200efb7e5 Mails K15/K16 je Funktion (News-Wortlaut eingefroren)
K15 (Bestellung eingegangen) und K16 (Funktion bereit) tragen den Wortlaut der
Funktion als Platzhalter (funktion, funktion_gen/akk/nom/pron/dein, preis_hinweis,
danach, bereit, knopf, portal_url) statt fest News-Pinnwand. siteFeatures baut die
Werte mit bestellMail/bereitMail aus dem Register-Eintrag (mails.*, setupEstimate,
returnHash) und dem Katalogpreis je feature.product. K15 geht ohne Anhaenge raus.
Die News-Mails bleiben Zeichen fuer Zeichen gleich (Test featureMails friert
Betreff und Text ein).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 12:56:45 +00:00
ClaudeandClaude Sonnet 5.5 9dd0244537 Funktions-Ticket: Text aus dem Register, Laengendeckel, Notfall-Details und gezielte Wiederholung
markPaid holt Betreff und Details des Einrichtungs-Tickets aus dem Register (ticketTexte), createFeatureTicket
bleibt die einzige Stelle, die das Ticket anlegt. Betreff auf 128, Details auf 7000 Zeichen gekuerzt (surrogatsicher,
Schnitt an der Zeilengrenze, einheitliche Schlusszeile). Wirft die Details-Funktion oder liefert sie keinen Text,
gelten die Notfall-Details (Kopfzeilen und Verweis ins WOMS). Nach einem 400 bei langen Details gibt es genau einen
zweiten Versuch mit den Notfall-Details und derselben woid; 5xx, Netzfehler und kurze Details werden ohne
Wiederholung weitergereicht. Stub termine/ticketDetails.js bis Task D4.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 12:48:02 +00:00
ClaudeandClaude Sonnet 5.5 7fcb268644 Checkout je Funktion: Zustimmungsnachweis vor der Weiterleitung, Zustaende aus dem Register
Rest der Route POST /api/funktionen/:key/checkout unter der Sperre feature-order:<Kunde>:<Projekt>:
Zustand aus dem Register (setup/active, disabled, ordered mit offener Sitzung, "Zahlung fortsetzen"),
Stripe-Sitzung mit der Zeit des Klicks, Zustimmungsnachweis (Serverfassungen und -texte) vor markOrdered
und vor der URL. Standard-Haken belehrung mit BELEHRUNG_PLATZHALTER fuer den Terminplaner.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 12:38:50 +00:00
ClaudeandClaude Sonnet 5.5 786df1230e Zustimmungsnachweis je Funktion (featureConsents) und Fristanker aus dem Klick
server/services/featureConsents.js speichert und liest den Nachweis zur Bestellung
einer Funktion (nur anfuegen, sieben Exporte): speichereZustimmung (Texte und Fassungen
als JSON, SHA-256 ueber die Texte, vollstaendig oder gar nicht), letzteZustimmung,
zustimmungFuerSitzung (leere Sitzung fragt nicht ab), leseZustimmung, texteHash,
zustimmungsfassungen und nachweisTexte (Haken, Belehrung, Knopf aus dem Register).
paidFeatureOrders liefert featureKey und vertragAt (Klick der bezahlten Sitzung, sonst
consentAt, sonst orderedAt; Lesefehler faellt mit Log auf orderedAt zurueck); der Widerruf
einer Funktion rechnet die Frist aus vertragAt. Eine spaetere, unbezahlte Zustimmung
verschiebt den Anker nicht.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 12:05:12 +00:00
ClaudeandClaude Sonnet 5.5 c584d220c8 Funktionen: Register config.features mit News- und Termine-Eintrag
config.features (news, termine) als reine Daten in config.js, config.ustHinweis,
config.funktionen als Alias mit Gettern auf features.news. Neu featureRegistry.js
(featureConfig, featureKeys, featureHaken mit Ueberschreib-Regel, oeffentlicheAnsicht);
FEATURE_KEYS, FEATURE_LABELS und DISABLED_MESSAGE in siteFeatures.js kommen aus dem
Register, Werte unveraendert.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 11:48:06 +00:00
ClaudeandClaude Sonnet 5.5 aaed273b62 Funktionen: disable() idempotent, disabledReason, Schema-Skript feature-setup
disable() laeuft unter einer Sperre je Dokument und aendert ein schon
abgeschaltetes Dokument nicht mehr (disabledAt als Beginn der 30-Tage-Frist,
Grund und Notiz bleiben); nur Altbestand ohne disabledAt bekommt dieses Feld.
Neu: DISABLED_REASONS und der Parameter reason (Vorgabe team, unbekannt = 400),
disableCustomerFeatures reicht ihn durch, die Kundenloeschung nutzt
kunde_geloescht. activate() leert zusaetzlich disabledReason und aboEndeMailAt
und laesst zahlungMeldung unberuehrt.

scripts/feature-setup.mjs legt portalFeatures.disabledReason, aboEndeMailAt und
zahlungMeldung idempotent an (--check meldet Luecken mit Exit 1);
schemaKeys('portalFeatures') zieht die Schluessel mit.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 11:33:17 +00:00
ClaudeandClaude Sonnet 5.5 9e8fd33713 Funktionen: Terminplaner als zweite Funktion (Team-Route, Kundenansicht)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-03 08:17:43 +00:00
ClaudeandClaude Opus 5.5 78170567b4 Analyse: alle Beendigungswege schalten den Messdienst ab (Kunde/Projekt weg, Domain, Löschfrist, Widerruf Wechsel)
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>
2026-10-01 18:50:36 +00:00
ClaudeandClaude Sonnet 5.5 f4c8b291d7 Analyse: Routen fuer Portal und WOMS
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-01 10:19:37 +00:00
ClaudeandClaude Sonnet 5.5 f0eee196ed Analyse: Freischalten, Abschalten, Abo-Pruefung
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-01 10:10:39 +00:00
knsoandClaude Opus 5.5 4b7f73abba Funktionen/News: Schlussdurchgang (Webhook-Retry, Checkout-Sitzung, Rechnungslink, Widerruf Funktion, UI- und Rechtstext-Korrekturen)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 17:38:15 +00:00
knsoandClaude Opus 5.5 6dac6aa073 Admin: News je Projekt aktivieren und abschalten
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 16:56:41 +00:00
knsoandClaude Opus 5.5 8374a570aa Funktionen: Bestellung serialisiert, Sitzung nachtragen, Freischaltung einmalig
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 16:35:59 +00:00
knsoandClaude Opus 5.5 0cc35bf1a5 Funktionen: Buchung per Stripe, Webhook, Mails und Freischalt-Job
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 16:33:48 +00:00
knsoandClaude Opus 5.5 770cbe32b7 Funktionen: Bestellschutz, serialisiertes markPaid, idx_session
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 16:29:12 +00:00
knsoandClaude Opus 5.5 4b1df8fbfa Funktionen: Zustände, Ticket beim Kauf, Freischaltung bei geschlossenem Ticket
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 16:27:27 +00:00