Commit Graph
38 Commits
Author SHA1 Message Date
ClaudeandClaude Opus 5.5 2659385205 Mitarbeiter nur noch per Label: Kunden-Konten bekommen keinen Team-Zugang
Kunden haben Konten im selben Appwrite-Projekt wie das Ticketsystem. Bisher
galt als Mitarbeiter, wer einen employees-Eintrag hatte - den legte das
Ticketsystem beim Login jedes Kontos automatisch an, und jedes angemeldete
Konto konnte ihn auch selbst anlegen. Damit kam ein Kunde ueber /api/team an
Chats, Kundenansicht, Angebote und Finanzen.

- staffLabels.js: Mitarbeiter = Label "mitarbeiter" oder "admin" (setzt nur
  der Server-Key)
- Team-Eingang (requireStaffJwt) und Portal-Login-Sperre nur noch per Label;
  kein Abgleich ueber employees-Eintrag oder Mail mehr
- Portal-Login: Konto-Abruf gestoert -> 503 fuer alle (fail closed)
- Mitarbeiter anlegen/bearbeiten setzt das Label "mitarbeiter"
- scripts/mitarbeiter-zugang.mjs: --status (markiert employees-Eintraege von
  Kunden), --label, --eintrag-loeschen (nur Eintrag, nie das Konto), --rechte
  (Probelauf, --anwenden mit Sicherung, --zurueck): any/guests/users ->
  label:mitarbeiter + label:admin in Collections, Buckets und bei Dokument-/
  Datei-Sicherheit auch einzelnen Dokumenten und Dateien

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 10:54:09 +00:00
ClaudeandClaude Opus 5.5 334dc1e669 Terminplaner: Schalter, Konfiguration, Schema
Schalter TERMINE_ENABLED (off|pilot|on) mit TERMINE_PILOT_EMAILS, config.termine
und die vier Collection-IDs, Schema der Termine-Collections als reine Daten
(server/services/termine/schema.js), Setup-Skript scripts/termine-setup.mjs mit
--check und schemaKeys() fuer den Appwrite-Nachbau der Tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 08:17:43 +00:00
ClaudeandClaude Opus 5.5 fdf594706d Kundenansicht: Protokoll-Collection customerViewLog mit Schreiben, Lesen und Loeschen nach 12 Monaten
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 19:25:26 +00:00
ClaudeandClaude Opus 5.5 ddb91a9950 Analyse: geprüfte Rechtstexte Fassung 2026-10-02 veröffentlichen (HTML, PDF, Zusatzseiten-Vorlage, Archiv)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 18:50:36 +00:00
ClaudeandClaude Opus 5.5 f401dc14d7 Analyse: Zielgruppen-Bestätigung in Historie, Rücknahme bei Fehler nach Dokument-Update, handelnde Person mit Name und E-Mail
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 18:50:36 +00:00
ClaudeandClaude Opus 5.5 3d05472b25 Analyse: Einwilligungs-Historie, Nachweis beim Einschalten, Sperre ohne Verantwortlichen-Angaben, Textform für Mitarbeiter
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 18:50:36 +00:00
ClaudeandClaude Sonnet 5.5 5ed4fbd188 Finanzen: Setup-Skript mit --iban und strenger Pruefung von --valid-until, Enable-Banking-Variablen in .env.example
M5: --iban speichert iban und ibanMasked (erste und letzte vier Zeichen); --valid-until nur als Datum
oder voller ISO-Zeitpunkt mit Zeitzone, sonst Abbruch.
M16: ENABLE_BANKING_APP_ID und ENABLE_BANKING_KEY_PATH auskommentiert dokumentiert.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-01 15:42:06 +00:00
ClaudeandClaude Sonnet 5.5 75ca8b78c0 Finanzen: Index auf bankTransactions.status, Vormerkungssuche mit Rueckfall
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-01 15:41:54 +00:00
ClaudeandClaude Sonnet 5.5 3dd2fac50b Finanzen: Collections und Setup-Skript mit Sitzungsuebernahme
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-01 15:41:54 +00:00
ClaudeandClaude Sonnet 5.5 37203f00c4 Analyse: Freischalten selbstheilend, Sperre, Retention-Abschaltung
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-01 10:13:28 +00:00
ClaudeandClaude Sonnet 5.5 9e66f55c2c Analyse: Schema, Konfiguration, Client
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-01 10:07:05 +00:00
ClaudeandClaude Sonnet 5.5 3316b562af Preview: Dev-Registrierung nutzt gespeicherten Branch und Stand
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 21:54:01 +00:00
ClaudeandClaude Sonnet 5.5 40a8aad3f9 Preview: Schema-Skript und Runner-Konfiguration
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 21:53:41 +00:00
ClaudeandClaude Opus 5.5 4e8b8f1698 Projektarten: Schema-Skript liest alle Attribute (limit 200)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 18:33:21 +00:00
ClaudeandClaude Sonnet 5.5 85b972f9dc Projektarten: Schema-Skript fuer websiteProjects
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 18:25:28 +00:00
knsoandClaude Opus 5.5 b45108c1de Funktionen: Stripe-Sitzungs-ID bis 128 Zeichen, keine Rohmeldungen beim Bestellen
Live-Fehler: cs_live-Sitzungs-IDs (~66 Zeichen) passten nicht in das Feld
portalFeatures.stripeSessionId (64), die Bestellung brach nach dem Anlegen
der Stripe-Sitzung ab und der Kunde sah die Appwrite-Meldung.
- Setup-Skript: Feld 128 Zeichen, bestehendes Feld wird per ensureStringSize vergroessert
- Fehler von Appwrite oder unerwartete Fehler: Log + verstaendlicher Hinweis

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 17:58:44 +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 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 acc86c267b Skript: 2FA für Mitarbeiter anzeigen, einschalten, abschalten
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 10:32:34 +00:00
ClaudeandClaude Opus 5.5 febac3c2a3 Skripte: Organisation einrichten, Kundenprojekte umziehen
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 10:21:34 +00:00
ClaudeandClaude Sonnet 5.5 9342ba10c8 Löschfristen: Probelauf, Bericht ans Team, Löschen nach drei Jahren
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-29 14:51:50 +00:00
ClaudeandClaude Opus 5.5 662f8d8144 Wechsel: Lastschrift-Fehler nur für den echten Wechsel, Abgleich ohne Webhook, Gutschrift netto, Skript prüft Stripe
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 09:24:02 +00:00
ClaudeandClaude Opus 5.5 188db4b3c1 Wechsel Hosting → Wartung: neuer Abbuchungstag, Gutschrift, 12 neue Monate
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 11:30:21 +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 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 d097704d49 Abo-Spiegel: Produkt und tatsächlicher Preis aus den Stripe-Positionen
Neues Appwrite-Feld subscriptions.productKey (Setup-Skript). Ohne bekannten
Abo-Preis gilt ein Abo weiter als Wartungs-Abo.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 15:31:56 +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 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 7849cb0e64 ENTWURF Vertragsunterlagen v2, Datenschutzerklaerung, Leitfaden Empfehlungsgeber
Noch nicht freigegeben, nicht nach main pushen. Enthaelt amtliche
Muster-Widerrufsbelehrung (Fassung ab 19.06.2026), AVV mit TOM und
Unterauftragsverarbeitern, Stundenkontingent statt Guthaben, Wahl des
Leistungsbeginns, Sperre erst ab 100 EUR, Hetzner-Backup-Formulierung.
Platzhalter: E-Mail-Anbieter und Postfachgroesse.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 13:06:51 +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
knso 3840ecf494 fix 4 2026-05-23 01:18:44 +02:00