Die Uhr laeuft erst, wenn die Anzahlung da ist
Bisher begann der Liefertermin mit der Annahme. Das ist unfair in beide Richtungen: Wer zehn Tage bis zur Zahlung braucht, verbraucht zehn Tage der zugesagten Zeit, ohne dass ein Handschlag Arbeit passiert waere -- und ich stehe am Ende als der da, der seinen Termin reisst. Ein Projekt hat jetzt drei Abschnitte statt zwei: 1. angenommen, wartet auf Anzahlung -> Uhr steht 2. Anzahlung da -> Uhr laeuft, Termin ab HEUTE neu 3. uebergeben oder abgebrochen -> Uhr steht wieder Der Zahlungseingang loest alles Weitere von selbst aus: Uhr starten, Termin neu rechnen, Status von briefing auf design, 'wer ist am Zug' auf mich, Benachrichtigung in der Verwaltung. Der bei der Annahme genannte Termin bleibt als termin_geplant_am erhalten, und die Meldung nennt BEIDE -- so sieht man, dass sich etwas verschoben hat, ohne nachrechnen zu muessen. Eingehaengt an der Stelle, an der beide Wege zusammenlaufen (PayPals Meldung UND das Vermerken von Hand). Nur am Webhook haenge sich die Seite verschieden verhalten, je nachdem WIE das Geld ankam -- eine von Hand verbuchte Zahlung startete die Uhr nie. Zwei Grundsaetze fuer die Automatik: Sie setzt Dinge in Gang, nimmt aber nie eine Entscheidung zurueck, die ein Mensch getroffen hat (ein von Hand pausiertes Projekt wird nicht kommentarlos wieder gestartet). Und jeder Schritt hinterlaesst eine Spur im Verlauf UND als Meldung -- eine Automatik, die stillschweigend arbeitet, ist kein Helfer, sondern ein Raetsel. ABBRECHEN Ein angenommener Auftrag bleibt abbrechbar: Der Kunde zahlt nicht, meldet sich nicht, springt ab. Vorschau und Ausfuehrung sind getrennt -- die Seite rechnet aus dem Aufgabenfortschritt vor, wie viel Leistung erbracht wurde, und schlaegt daraus einen Erstattungsbetrag vor. Der Betrag ist ein VORSCHLAG: Ob im Einzelfall mehr oder weniger angemessen ist, haengt an Dingen, die keine Tabelle kennt. Offene Rechnungen werden storniert (eine Zahlungsaufforderung ohne Gegenleistung), bezahlte bleiben unangetastet, und die Rueckzahlung loest die Seite bewusst NICHT selbst aus -- PayPal-Rueckzahlungen sind nicht umkehrbar. BENACHRICHTIGUNGEN Eigene Tabelle statt im Verlauf: Der Verlauf haelt fest, WAS geschehen ist -- vollstaendig, zum Nachschlagen. Eine Benachrichtigung ist ein Anstupsen, das gelesen und weggelegt wird. Beides in einer Tabelle hiesse: entweder ein Verlauf voller Rauschen oder Meldungen, die man nicht wegklicken kann. Wegklicken markiert nur als gelesen, loescht nichts. Dazu die Liste der Projekte, die seit ueber einer Woche auf ihre Anzahlung warten. Sie stehen in keiner anderen Zahl, weil ihre Uhr nie zu laufen begann -- ohne diesen Hinweis vergisst man sie. Geprueft: 44 gegen eine echte Datenbank. Darunter der Kern -- die Annahme wird zehn Tage zurueckdatiert, und der Termin muss danach trotzdem volle 20 Werktage entfernt liegen. Beim Bauen des Tests selbst ein Fehler gefunden: Die erste Fassung datierte nur die Annahme zurueck, nicht den damals errechneten Termin, und bildete damit genau den Fall nicht ab, um den es geht. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
-- =====================================================================
|
||||
-- Die Uhr läuft erst, wenn die Anzahlung da ist
|
||||
--
|
||||
-- WARUM DAS EIN EIGENER ZUSTAND IST
|
||||
--
|
||||
-- Bisher begann der Liefertermin mit der Annahme. Das ist unfair in
|
||||
-- beide Richtungen: Wer zehn Tage bis zur Zahlung braucht, verbraucht
|
||||
-- zehn Tage der zugesagten Zeit, ohne dass ein Handschlag Arbeit
|
||||
-- passiert wäre — und ich stehe am Ende als der da, der seinen Termin
|
||||
-- reisst.
|
||||
--
|
||||
-- Deshalb hat ein Projekt jetzt drei Abschnitte statt zwei:
|
||||
-- 1. angenommen, wartet auf Anzahlung → Uhr steht
|
||||
-- 2. Anzahlung da → Uhr läuft, Termin ab HEUTE
|
||||
-- 3. übergeben oder abgebrochen → Uhr steht wieder
|
||||
--
|
||||
-- `termin_am` wird beim Zahlungseingang NEU berechnet. Es wäre bequemer,
|
||||
-- den bei der Annahme errechneten Termin stehenzulassen — aber dann wäre
|
||||
-- die Zusage falsch, sobald jemand eine Woche mit der Zahlung wartet.
|
||||
-- Der bei der Annahme genannte Termin bleibt als `termin_geplant_am`
|
||||
-- erhalten, damit man sieht, was ursprünglich in Aussicht stand.
|
||||
-- =====================================================================
|
||||
|
||||
ALTER TABLE wd_projekte ADD COLUMN uhr_start_am TEXT;
|
||||
ALTER TABLE wd_projekte ADD COLUMN termin_geplant_am TEXT;
|
||||
|
||||
-- ---------------------------------------------------------------------
|
||||
-- Abbruch
|
||||
--
|
||||
-- Ein angenommener Auftrag muss abbrechbar bleiben: Der Kunde zahlt
|
||||
-- nicht, meldet sich nicht mehr, oder springt selbst ab. Ohne diesen
|
||||
-- Weg bliebe das Projekt für immer offen in der Liste stehen und
|
||||
-- verfälschte jede Zahl im Cockpit.
|
||||
--
|
||||
-- Der Erstattungsbetrag wird festgehalten, nicht nur die Entscheidung:
|
||||
-- Bei einem Streit zählt, WAS erstattet wurde und WARUM — und der
|
||||
-- Fortschritt zum Zeitpunkt des Abbruchs ist die Begründung dafür.
|
||||
-- ---------------------------------------------------------------------
|
||||
ALTER TABLE wd_projekte ADD COLUMN abbruch_am TEXT;
|
||||
ALTER TABLE wd_projekte ADD COLUMN abbruch_grund TEXT;
|
||||
ALTER TABLE wd_projekte ADD COLUMN abbruch_wer TEXT; -- kunde | dogfather
|
||||
ALTER TABLE wd_projekte ADD COLUMN abbruch_erstattung_cent INTEGER;
|
||||
ALTER TABLE wd_projekte ADD COLUMN abbruch_fortschritt INTEGER; -- Prozent bei Abbruch
|
||||
|
||||
-- =====================================================================
|
||||
-- Benachrichtigungen für die Verwaltung
|
||||
--
|
||||
-- WARUM EINE EIGENE TABELLE UND NICHT DER VERLAUF
|
||||
--
|
||||
-- `wd_verlauf` gibt es schon, aber er hat einen anderen Zweck: Er hält
|
||||
-- fest, WAS geschehen ist — vollständig, für später, zum Nachschlagen.
|
||||
-- Eine Benachrichtigung ist etwas anderes: Sie ist ein Anstupsen, das
|
||||
-- gelesen und dann weggelegt wird.
|
||||
--
|
||||
-- Beides in eine Tabelle zu werfen hiesse: Entweder man markiert jeden
|
||||
-- Verlaufseintrag als gelesen (dann ist der Verlauf voller Rauschen),
|
||||
-- oder man kann Benachrichtigungen nicht wegklicken (dann sammeln sie
|
||||
-- sich, bis niemand mehr hinsieht). Getrennt kann jedes für sich das
|
||||
-- Richtige tun.
|
||||
-- =====================================================================
|
||||
CREATE TABLE IF NOT EXISTS wd_meldungen (
|
||||
id TEXT PRIMARY KEY,
|
||||
art TEXT NOT NULL, -- anzahlung_da | restzahlung_da | zusage | widerruf | zahlung_faellig
|
||||
titel TEXT NOT NULL,
|
||||
text TEXT,
|
||||
-- Wohin man springt, wenn man draufdrückt. Eine Benachrichtigung, die
|
||||
-- nur meldet und nicht hinführt, erzeugt Arbeit statt sie abzunehmen.
|
||||
ziel TEXT, -- projekte | zahlungen | anfragen | postfach
|
||||
ziel_id TEXT,
|
||||
dringend INTEGER NOT NULL DEFAULT 0,
|
||||
gelesen INTEGER NOT NULL DEFAULT 0,
|
||||
gelesen_am TEXT,
|
||||
erstellt_am TEXT NOT NULL
|
||||
);
|
||||
|
||||
-- Ungelesene zuerst, neueste oben: genau die Reihenfolge, in der sie
|
||||
-- gelesen werden. Ohne Index wird das bei jedem Laden der Übersicht neu
|
||||
-- sortiert.
|
||||
CREATE INDEX IF NOT EXISTS idx_wd_meldungen_offen
|
||||
ON wd_meldungen (gelesen, erstellt_am DESC);
|
||||
Reference in New Issue
Block a user