Commit Graph
35 Commits
Author SHA1 Message Date
knsoandClaude Opus 5.5 ac7375e889 News: Fotos verkleinern und Metadaten entfernen (sharp)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 16:38:33 +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 16fbb03c13 Stripe: Einmalpreis News-Einrichtung 30 €
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 16:24:21 +00:00
knsoandClaude Opus 5.5 85bee3190c Schema: portalFeatures-Zustände und newsPosts
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 16:24:21 +00:00
ClaudeandClaude Opus 5.5 8acc743cf7 Abo-Bedingungen Fassung 5: Unterstützung in § 4, Fassung 4 archiviert
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 15:26:39 +00:00
ClaudeandClaude Opus 5.5 5b7365b99e Push-Zeitmail: signierter Token für Zeit-Links
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 13:33:39 +00:00
ClaudeandClaude Opus 5.5 d5c70a5bd6 Gesamtprüfung: Zeitlimit für Gitea, Aufräumen ohne Weiterleitung
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 10:21:34 +00:00
ClaudeandClaude Opus 5.5 531ee2a02b Gitea-Client herausgelöst, Konfiguration für Organisation und System-Konto, Test-Nachbauten
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 10:21:34 +00:00
ClaudeandClaude Opus 5.5 e4efdac226 Hosting-Abo: Preis 15 € -> 20 € pro Monat (Vertragsbedingungen v4, Katalog, Leitfaden)
- server/config.js: amountCents 2000, lookup_key webklar_hosting_monatlich_2000
- ensurePrice haengt einen neuen Preis an das vorhandene Stripe-Produkt (metadata.webklar),
  statt ein zweites "WEBklar Hosting-Abo" anzulegen
- abo-bedingungen.html (Uebersicht, Preise, Leistungsbeschreibung) + PDF, Leitfaden + PDF
- Tests auf 20 € umgestellt (399/399)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 16:29:01 +00:00
ClaudeandClaude Opus 5.5 78b4d7b7fe Livegang: Vertragsbedingungen Version 4 und Datenschutzerklärung Stand 30.09.2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 16:03:39 +00:00
ClaudeandClaude Fable 5.1 63d3bb11bf Admin: Reiter E-Mail-Speicher, Abo mit Produkt; Schnittstelle fürs Ticketsystem
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-29 14:37:42 +00:00
ClaudeandClaude Opus 5.5 7df0b72019 Stripe: Testrabatt-Namen, Produktbild, Hosting-Leistungen, Tests für Bestandskunden
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 10:02:03 +00:00
ClaudeandClaude Opus 5.5 e5cc57cefd Stripe: Preise je Produkt, Testrabatt Hosting, Kundenportal „Abo verwalten“, Mindestlaufzeit ab termStartAt
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 09:21:25 +00:00
ClaudeandClaude Opus 5.5 7799d7c4de Vertragsereignisse: Nachweise, Widerrufsfristen, Speicher-Aufgaben
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 08:59:30 +00:00
ClaudeandClaude Fable 5.1 a2c1f0d81c Übernahmegutschrift und Leitfaden: für beide Abos (Entwurf)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-27 20:23:44 +00:00
ClaudeandClaude Opus 5.5 f19187cc16 Vertragsbedingungen Version 4 (Entwurf): Hosting- und Wartungs-Abo, Postfächer, Zusatzspeicher, Wechsel; Fassung 3 archiviert
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 16:17:31 +00:00
ClaudeandClaude Opus 5.5 54defb75c4 Tests: Stripe- und Appwrite-Nachbau im Testprozess
getStripe() nutzt in Tests über STRIPE_API_BASE den Nachbau auf 127.0.0.1;
in Produktion ist der Wert leer und nichts ändert sich.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 15:30:56 +00:00
ClaudeandClaude Opus 5.5 877fde7a6f Abo-Katalog: Wartung, Hosting und Zusatzspeicher als Produkte (noch ohne Verwendung)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 15:29:16 +00:00
ClaudeandClaude Opus 5.5 60baeb3271 Mailversand: Antwortadresse, Absendername WEBklar, nur mit STARTTLS
- SMTP_REPLY_TO (z. B. support@webklar.com) setzt Reply-To auf allen
  Kundenmails, damit Antworten nicht im Versandpostfach (noreply@) landen
- Absendername einheitlich "WEBklar" (Kunden) bzw. "WEBklar Kundenbereich"
  (interne Hinweise) statt "Webklar"/"Webklar Kundenportal"
- requireTLS auf Port 587: der neue Mailserver (Hetzner) nimmt die
  Anmeldung auch unverschluesselt an; ohne STARTTLS wird jetzt nicht gesendet

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 12:12:37 +00:00
ClaudeandClaude Opus 5.5 e54f97144c Abo: Widerrufsfrist nach §§ 187, 188, 193 BGB statt 14 x 24 Stunden
Bisher endete die Frist rechnerisch 14 x 24 h nach Vertragsschluss, und der spaetere
Beginn lag pauschal 15 Tage danach. Gesetzlich beginnt die Frist am Folgetag und endet
um 24 Uhr des 14. Tages; faellt der auf Sa/So/Feiertag, am naechsten Werktag. Beispiel:
Abschluss Sa 26.09. -> Frist bis Mo 12.10., 24 Uhr. Vorher verschwand "Vertrag widerrufen"
schon Sa 10.10. vormittags, und "Beginn nach Ablauf der Frist" buchte am So 11.10. ab.

- server/services/deadlines.js: Fristende und Leistungsbeginn, deutscher Kalender,
  Feiertage aller Bundeslaender (zugunsten des Kunden, § 193 BGB: Erklaerungsort).
- Portal: "Vertrag widerrufen · bis TT.MM." bleibt bis zum echten Fristende sichtbar.
- Beginn nach Ablauf der Frist: Stripe trial_end = 6 Uhr am Tag nach dem spaetesten
  moeglichen Fristende (Checkout gilt hoechstens 24 h). Die Bestellseite zeigt genau
  dieses Datum; hat es sich um Mitternacht verschoben, kommt "Seite neu laden".
- Team-Mail beim Widerruf nennt das Fristende und ob der Widerruf rechtzeitig kam.
- Datumsanzeige im Portal nach deutscher Zeit (auch bei Kunden im Ausland).

Vertragstexte unveraendert (termsVersion bleibt v3).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 18:30:27 +00:00
ClaudeandClaude Opus 5.5 06e9a0fe8d Chat-Anhaenge: Korrekturen aus dem Code-Review
- Kamerafotos in anderen Formaten (z. B. HEIF von Android-Kameras) werden
  wie Dateien angenommen statt abgelehnt
- Dateinamen nach Zeichen kuerzen: ein halbiertes Emoji machte den Anhang
  unabrufbar (encodeURIComponent)
- Endet eine Aufnahme von selbst (Headset getrennt, Anruf), bleibt die
  Sprachnachricht erhalten statt "zu kurz"
- Kamera-App nur auf iOS/iPadOS/Android; Touch-Laptops bekommen die Kamera
  im Browser statt eines Dateidialogs
- Knapp neben dem Chat abgelegte Dateien oeffnet der Browser nicht mehr
  selbst (Portal bliebe sonst stehen); Datei-Felder bleiben Ablagen
- Fehler beim Ausliefern kommt als JSON statt mit dem Dateityp
- Server liest hoechstens 4 Uploads gleichzeitig ein (Speicher), weitere
  warten; abgebrochene Wartende geben ihren Platz frei

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 14:01:17 +00:00
ClaudeandClaude Opus 5.5 35d98da977 Chat: Bilder, Kamerafoto, Dateien und Sprachnachrichten
- Kundenbereich und Admin-Chat: Bueroklammer-Menue (Bild, Kamera, Datei),
  Mikrofon fuer Sprachnachrichten, Vorschau vor dem Senden mit
  Upload-Fortschritt, Einfuegen (Strg+V) und Hineinziehen von Dateien
- Kamera: am Handy/Tablet die Kamera-App, am Rechner die Kamera im Browser
  mit Vorschau, Kamerawechsel und "Nochmal"
- Sprachnachricht: Aufnahme mit Zeit und Pegel, vorher anhoerbar oder
  direkt senden, hoechstens 5 Minuten
- Verlauf: Bilder (einzeln bzw. Raster, Grossansicht), Player fuer
  Sprachnachrichten, Datei-Kacheln mit Download
- Server: jede Datei einzeln roh hochgeladen (max. 25 MB, 10 je Nachricht,
  max. 3 gleichzeitig), Typ aus dem Inhalt, nur erlaubte Endungen, keine
  Programme; Ablage unter upload-data/chat/<Kunde>/ ausserhalb von public/,
  Auslieferung nur mit Login; Bilder, Audio und PDF inline, alles andere
  als Download (nosniff, CSP sandbox)
- Nicht gesendete Anhaenge werden nach 24 Stunden geloescht
- Benachrichtigungs-Mail nennt nur Art und Namen der Anhaenge
- Appwrite: neues Attribut portalMessages.attachments
  (scripts/setup-chat-collection.mjs, vor dem Deploy ausfuehren)
- Datenschutzerklaerung Abschnitt 6 ergaenzt (Stand 26.09.2026), PDF neu

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 14:01:17 +00:00
ClaudeandClaude Opus 5.5 bb2f46e191 Abo: individuelle Angebote (z. B. erste 2 Monate je 25 EUR) mit Stripe-Coupon
- Admin-Tab "Abo-Angebote" und Button "Angebot" in der Kundenliste: Preis, Monate,
  Gueltigkeit, Hinweis fuer den Kunden, interne Notiz, Vorschau vor dem Anlegen
- Je Angebot sofort ein Stripe-Coupon (amount_off, repeating ueber die
  Angebotsmonate, max. 1 Einloesung); danach automatisch wieder Normalpreis
- Kunde ohne Abo: Angebot im Portal, Angebotspreis in der Bestelluebersicht,
  Coupon im Checkout; Angebot schaltet die Bestellung auch ausserhalb der
  Pilotliste frei; Bestellung prueft, dass das angezeigte Angebot noch gilt
- Laufendes Abo: Coupon sofort am Abo fuer die naechsten Abbuchungen
- Testkonten: Testrabatt im Checkout, Angebot per Webhook zusaetzlich am Abo
- Angebot in Abo-Metadaten, Vertragsbestaetigung, Admin-Mail und Abo-Karte
- Zurueckziehen loescht den Coupon; abgelaufene Angebote nicht mehr bestellbar
- Stundenkontingent nach invoice.subtotal: auch voll rabattierte oder per
  Guthaben bezahlte Monate bringen die Stunde, die Probezeit nicht
- setup-abo-collections.mjs: aboOffers, subscriptions.offerId/offerText,
  Attribut-Abfrage mit Limit (sonst Haenger ab 26 Attributen)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 20:32:08 +00:00
ClaudeandClaude Opus 5.5 48b13f4488 Abo: Uebernahmegutschrift fuer beim Altanbieter bezahlte Leistungen
- Kunde (Dashboard, nur mit laufendem Abo): Antrag mit Leistung, Anbieter,
  Domain, Rechnungsbetrag/-zeitraum, Grund, Rechnungsnachweis (PDF/JPG/PNG)
  und E-Mail fuer die Antwort; Eingangsbestaetigung per Mail, Status und
  Antwort auf Rueckfragen im Portal
- Admin-Mail mit Link admin.html?gutschrift=<id> (Login leitet zurueck)
- Admin-Tab "Gutschriften": Kunde und Vertrag, Nachweise, Verlauf,
  automatische Pruefungen (Duplikate per Datei-Hash/Domain, Abo, Zeitraum,
  DNS-Abgleich Nameserver/MX mit Anbieter), Pflicht-Checkliste, Rechner
  (tagesgenau anteilig), Genehmigen/Rueckfrage/Ablehnen mit Kundenmail
- Genehmigte Gutschrift als Stripe-Kundenguthaben (idempotent, Nachbuchen
  bei Stripe-Stoerung)
- Nachweise in upload-data/ (gitignored), Loeschung abgelehnter nach 6 Monaten
- Stundenkontingent auch fuer Monate, die ein Guthaben komplett deckt
  (invoice.total statt amount_paid)
- Datenschutzerklaerung Abschnitt 7 ergaenzt, PDF neu erzeugt
- Collection takeoverCredits in setup-abo-collections.mjs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 19:34:33 +00:00
ClaudeandClaude Opus 5.5 9b563482ff Wartungs-Abo v3: Mindestlaufzeit 12 Monate
- Bedingungen § 8: 12 Monate ab Leistungsbeginn, Kuendigung zum Ende bis
  1 Monat vorher, danach monatlich; Sonderkuendigung bei Geschaeftsaufgabe
  (1 Monat Frist), einvernehmliche Beendigung jederzeit; gilt beidseitig
- Kuendigungslogik computeCancellationDate (Mindestlaufzeit, verpasste
  Frist, Wunschtermin, Geschaeftsaufgabe, Monatsende) + cancelAt gespiegelt
- Stripe-Kundenportal: Kuendigung aus (Stripe kennt keine Mindestlaufzeit)
- Bestellseite, Abo-Karte, Vertragsbestaetigung, Checkout-Text, PDF,
  Leitfaden angepasst; termsVersion 2026-09-25-v3

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 17:59:49 +00:00
ClaudeandClaude Opus 5.5 90e85f5989 Abo: Testkonten zahlen per Rabatt nur 0,50 EUR (ABO_TEST_EMAILS)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 17:09:52 +00:00
ClaudeandClaude Opus 5.5 7237ec729d Stripe-Produkt mit Produktbild; Portal-Konfiguration exportiert
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 14:18:52 +00:00
ClaudeandClaude Opus 5.5 4ab154bfa2 Wartungs-Abo v2: Rechtsrunde umgesetzt
- Bestellseite: Pflichtangaben direkt ueber dem Button, Zahlungsarten,
  Wahl des Leistungsbeginns (sofort / nach Widerrufsfrist via 15 Tage
  Stripe-Probezeit), keine Vorauswahl
- Zustimmungsnachweis: Zeitpunkt, Version, Wahl, IP, Browser in Stripe-
  Metadaten und Appwrite (neue Attribute, Setup-Skript ergaenzt)
- Checkout: Karte + SEPA (Fallback nur Karte), korrigierter Hinweistext
- Vertragsbestaetigung mit PDF der Vertragsunterlagen statt HTML
- Kuendigen/Widerrufen: Formular direkt (keine Zwischenseite), Wunsch-
  termin, Druck/PDF der Bestaetigung, Vorbefuellung bei Login
- Widerrufsbutton im Abo waehrend der Frist, 'beginnt am'-Status
- Pilotbetrieb per ABO_PILOT_EMAILS
- Vertragsbedingungen v2, Datenschutzerklaerung, Kalkulator ohne MwSt
  und mit 100/80 EUR

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 14:10:21 +00:00
ClaudeandClaude Opus 5.5 c0214725c0 Stripe-Produkt: Name, Beschreibung und Abrechnungstext wie im Dashboard
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 13:37:26 +00:00
ClaudeandClaude Opus 5.5 65429aa3ac Wartungs-Abo (50 EUR/Monat) ueber Stripe mit Stundenkonto im Portal
- Bestellung auf der Portal-Startseite: Zusammenfassung, AGB- und
  Vorab-Leistungs-Zustimmung, Button 'Zahlungspflichtig bestellen',
  danach Stripe Checkout (Abo, Kleinunternehmer-Fusszeile)
- Stripe-Webhook /api/abo/webhook spiegelt Abos nach Appwrite
  (subscriptions) und schreibt je bezahlter Rechnung 60 min gut
  (hourCredits, idempotent ueber Invoice-ID, 12 Monate gueltig)
- Stundenkonto: FIFO-Verbrauch aus Worksheets mit countsToPlan,
  15-Minuten-Takt, Mehraufwand separat ausgewiesen
- Stripe-Kundenportal fuer Zahlungsart/Rechnungen/Kuendigung
- Oeffentlicher Kuendigungsbutton (§ 312k) und Widerrufsbutton
  (§ 356a) mit Eingangsbestaetigung per Mail
- Abo-Bedingungen inkl. Leistungsbeschreibung und Widerrufsbelehrung,
  als Anhang der Vertragsbestaetigung

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 12:04:45 +00:00
knsoandClaude Fable 5 d4bd510dcd feat: Kundenportal-Ausbau - Tabs, Projekt-Einblicke, Git-Zeiterfassung, Rechnungen, Chat
Kunden-Dashboard:
- Tab-Navigation: Projekte | Was wurde gemacht | Rechnungen | Chat
- Projekt-Details pro Projekt: letzte Git-Commits (Titel+Beschreibung),
  Projektgroesse, Datei-Uebersicht (Top-Level aggregiert), Ticket-Arbeiten
- Rechnungen: gestylte Liste mit Status-Pillen, Ansehen/Zahlen-Link,
  PDF-Download ueber Server-Proxy (IDOR-geschuetzt)
- Chat mit dem Webklar-Team (Polling, Ungelesen-Badge, viewAs blockiert)

Admin-Dashboard:
- Chat-Tab: Konversationsliste + Thread + Antwortfeld, Ungelesen-Badge

Backend:
- giteaAdmin: getRepoInfo, listRepoCommits, getRepoTreeSummary
- projectInsights: 5-min-Cache, Invalidierung per Gitea-Webhook
- /api/projects/:id/git|files|work mit Ownership-Check (404)
- /api/chat/* (Kunde) + /api/portal-admin/chats/* (Admin), portalMessages-Collection
- mailer: E-Mail-Benachrichtigung an Admins bei Kundennachricht (15-min-Throttle)
- gitWorksheet: dd.mm.yyyy, voller Commit-Body, startTime leer (Zeit-Nachtrag),
  Auto-Webpage-Ticket bei Push auf Projekt ohne Ticket (ensureProjectTicket)
- customerActivity: Git-Push-Eintraege fuer Kunden sichtbar

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 18:01:24 +00:00
knsoandClaude Fable 5 cc57cf887a feat: HTTPS-TLS-Sync nach Deploy, Projekte ohne Subdomain, portalPassword-Feld
- 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>
2026-07-11 16:34:23 +00:00
knsoandClaude Fable 5 cf4b3ce4d1 chore: aktuellen Live-Stand sichern (Admin-API, Services, Auth-Erweiterungen)
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>
2026-07-11 16:24:53 +00:00
knso 8f167a20df tickt db übernahme 2026-05-22 23:51:20 +02:00
knsoandCursor f31727aeb4 Implementiere Kundenportal mit zentraler Appwrite-Anbindung.
Express-Server für Appwrite-Auth, Session, Projekt-Dashboard und Gitea-Webhook; statisches Frontend und Schema-Dokumentation für woms-database.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 23:38:38 +02:00