servicewecker.de
Screenshot der Anwendung Servicewecker

Ausgangslage

Ein Heizungsbetrieb hat hunderte Bestandskunden mit wartungspflichtigen Anlagen — und keinen verlässlichen Weg, sie zum nächsten Termin zurückzuholen. Die Nachfassliste liegt im Kopf des Büros oder in einer Excel-Datei, die niemand pflegt. Also bleibt der Sommer leer, obwohl die Aufträge da wären. Große CRM- und ERP-Pakete lösen das nicht: Sie kosten mehr Einrichtung, als das Problem groß ist.

Lösung

Ein Produkt, das nur eine Sache tut. Aus letzter Wartung und Intervall berechnet das System den nächsten Termin und plant daraus eine dreistufige Erinnerungssequenz — gedrosselt auf 25 Mails pro Woche, dienstags bis donnerstags von 9 bis 11 Uhr, nie an bundesweiten Feiertagen. Der Kunde klickt in der gebrandeten Mail auf „Wartung anfragen“ und landet auf einer öffentlichen Mini-Seite ohne Konto; der Betrieb wird sofort benachrichtigt und arbeitet die Anfrage im Posteingang ab. Beim Abschluss plant sich der nächste Zyklus selbst. Die gesamte Terminlogik liegt als reine, datenbankfreie Funktionen im Code — testbar Regel für Regel.

Im Kern

Wellen-Drosselung

25 Erinnerungen pro Woche, festes Sendefenster, keine Feiertage. Wer 400 Kunden importiert, hat morgen nicht 400 Anrufe.

Anfrage ohne Konto

Der Kunde klickt in der Mail und landet auf einer öffentlichen Mini-Seite. Kein Login, keine Hürde — der Betrieb bekommt die Anfrage sofort aufs Handy.

Import aus der Praxis

CSV-Import, der Semikolon, Windows-1252, deutsche Datumsangaben und Excel-Serials versteht — so, wie Handwerkerprogramme wirklich exportieren.

Kunden ohne E-Mail

Anrufliste nach PLZ gruppiert und druckbar, Briefliste mit fertigen Word-Briefen im selben Wortlaut wie die Mail.

GEG-Pflichten benannt

Prüfpflichten nach dem Gebäudeenergiegesetz stehen typisiert mit Paragraph und Quellenstand im Code — das Produkt zitiert die Pflicht, es berät nicht.

Idempotenz als DB-Garantie

Ein Unique-Constraint plus „for update skip locked“: zwei parallel laufende Worker können keine doppelte Erinnerung erzeugen. Getestet, nicht behauptet.

Code-Einblick

src/lib/reminders.ts
// Erster erlaubter Sendezeitpunkt: Wochentag, Feiertag, Uhrzeit — alles Berlin-Zeit
export function nextSendSlot(from: IsoDate, window = DEFAULT_SEND_WINDOW) {
  let candidate = from

  for (let offset = 0; offset < 400; offset += 1) {
    if (window.weekdays.includes(isoWeekday(candidate)) &&   // Di–Do
        !isGermanPublicHoliday(candidate)) {                // nie feiertags
      return { date: candidate, instant: berlinToInstant(candidate, window.startHour) }
    }
    candidate = addDays(candidate, 1)
  }
  throw new Error(`Kein Sendefenster innerhalb eines Jahres ab ${from}`)
}
// Rein, ohne Datenbank — damit jede Regel einzeln testbar bleibt.

Tech-Stack

FrameworkNext.js 16, React 19, TypeScript strict
DatenSupabase self-hosted (Postgres, RLS)
E-MailBrevo (HTTP-API, Zustellereignisse)
PaymentsStripe Subscriptions
TaktWorker-Container, alle 5 Minuten
BetriebDocker Compose, eigener VPS in der EU

Ergebnis

Live unter servicewecker.de: Erinnerungssequenz, Anfragen-Posteingang und Anruf- bzw. Brieflisten laufen im Takt eines eigenen Worker-Containers, die Daten liegen auf einer selbst gehosteten Supabase-Instanz in Deutschland. Zeigt ein bewusst kleines Produkt, das seine Regeln ernst nimmt: reine Domänenlogik, Idempotenz auf Datenbankebene und ein Deployment, das ohne fremde Plattform auskommt.

Ähnliches Projekt geplant?

Ich baue solche Anwendungen als Festpreis-Projekt. Eine kurze Mail mit dem Ziel genügt.

Projekt anfragen