Files
dogfather-universe/server-internal/lib/webdesign-vorlagen.js
T
DogFatherGitandClaude Opus 5 548ec6bc00 Aufgabenlisten und allgemeines Postfach: Datenbank und Vorlagen
Erster von vier Schritten fuer zwei Wuensche vom 22.08.2026:
"wenn sie drauf druecken sollen sie auch sehen was ich schon gemacht habe
von dem was im plan war" und "die kunden sollen mir auch nachrichten
hinterlassen koennen".

DATENBANK (3 neue Tabellen, jetzt 18 insgesamt, Fremdschluessel geprueft)

wd_aufgaben -- die Punkte je Projekt. Drei Entscheidungen darin:
  * "wer_dran" ist eine eigene Spalte, kein Text. Manche Punkte warten
    auf den KUNDEN ("Texte liefern"), und genau die muessen ihm ins Auge
    springen. Ohne diese Unterscheidung liest er die Liste als reinen
    Fortschrittsbericht und uebersieht seinen eigenen Teil -- der
    haeufigste Grund fuer Verzoegerungen ueberhaupt.
  * "nicht_enthalten" bildet ab, was NICHT zum Umfang gehoert. Das ist
    die haeufigste Streitfrage in jedem Projekt ("ich dachte, das ist
    dabei"). Vorher sichtbar aufgeschrieben kostet es nichts, hinterher
    kostet es Geld oder den Kunden.
  * "kategorie" nutzt dieselben vier Abschnitte wie die Farben im Portal.
    Damit bedeutet eine Farbe ueberall dasselbe statt nur huebsch zu sein.

wd_postfach -- Nachrichten OHNE Projektbezug. Bewusst eine EIGENE Tabelle:
wd_nachrichten hat projekt_id als NOT NULL, und SQLite kann das nicht
lockern, ohne die ganze Tabelle zu kopieren -- ein unnoetiges Risiko bei
echten Kundennachrichten. Die neue Tabelle hat ohnehin andere
Anforderungen (Anhaenge, Lesestatus in BEIDE Richtungen, optionaler Bezug
auf eine Aufgabe). Zwei klar getrennte Tabellen sind ehrlicher als eine,
die beides halb kann.

VORLAGEN (56 Punkte ueber 5 Pakete, davon 20 beim Kunden)

Bei jedem Projekt fuenfzehn Punkte von Hand einzutippen fuehrt
zuverlaessig dazu, dass es irgendwann niemand mehr macht -- und dann
steht der Kunde wieder vor der leeren Liste, die der Ausloeser war.

Die Punkte sind in der Sprache formuliert, in der ein KUNDE denkt:
"Aufbau der Seiten festlegen" statt "Informationsarchitektur", "Auf dem
Handy durchtesten" statt "Responsive QA". Er liest diese Liste -- sie
muss ihm etwas sagen, nicht mir.

Die Vorlagen wandern beim ersten Start in die Datenbank und sind ab dann
dort aenderbar. Bereits vorhandene werden NIE ueberschrieben: sonst waeren
von Hand angepasste Vorlagen nach dem naechsten Neustart weg, und niemand
kaeme auf die Idee, dass der Neustart schuld war.

Naechste Schritte: Server-Routen, Verwaltung, Portal.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-22 22:48:39 +02:00

178 lines
10 KiB
JavaScript

/* =====================================================================
webdesign-vorlagen.js — Standard-Aufgabenlisten je Paket
Warum es diese Datei gibt: Bei jedem neuen Projekt fünfzehn Punkte von
Hand einzutippen führt zuverlässig dazu, dass es irgendwann niemand
mehr macht — und dann steht der Kunde wieder vor einer leeren Liste.
Genau die Leere war ja der Auslöser ("wenn sie drauf drücken sollen
sie auch sehen was ich schon gemacht habe von dem was im plan war").
Die Listen stehen hier im Code, wandern beim ersten Start aber in die
Datenbank (wd_aufgaben_vorlagen). Ab dann sind sie dort änderbar. Der
Code ist also nur die Erstbefüllung, nicht die dauerhafte Wahrheit —
sonst müsste man für jede neue Erfahrung einen Deploy machen.
Die Punkte sind bewusst in der Sprache formuliert, in der ein KUNDE
denkt, nicht in Fachsprache. "Aufbau der Seiten festlegen" statt
"Informationsarchitektur", "Auf dem Handy durchtesten" statt
"Responsive QA". Der Kunde liest diese Liste — sie muss ihm etwas
sagen, nicht mir.
wer_dran ist der wichtigste Wert in jeder Zeile: Punkte, die auf den
Kunden warten, springen ihm im Portal farblich ins Auge. Ohne diese
Markierung liest er die Liste als reinen Fortschrittsbericht und
übersieht seinen eigenen Teil — der häufigste Grund für Verzögerungen.
===================================================================== */
import { db } from "../db.js";
import { jetzt, neueId } from "./webdesign-helfer.js";
/* Die vier Kategorien entsprechen exakt den vier Prozessfarben im
Portal: start (blau), gestaltung (lila), umsetzung (grün),
abschluss (gold). Eine Farbe bedeutet damit überall dasselbe. */
const GEMEINSAM_START = [
["Briefing-Gespräch führen", "Ziel, Zielgruppe und Umfang gemeinsam klären.", "start", "dogfather", 10],
["Texte und Bilder zusammenstellen", "Alles, was auf die Seite soll. Lieber früh als vollständig — Lücken klären wir gemeinsam.", "start", "kunde", 20],
["Logo und Farbwünsche liefern", "Falls vorhanden. Wenn nicht, entwerfen wir eine passende Richtung.", "start", "kunde", 30],
["Angebot prüfen und annehmen", "Preis, Umfang und Zeitrahmen schriftlich.", "start", "kunde", 40],
["Anzahlung 30 % überweisen", "Erst danach wird dein Zeitfenster fest reserviert.", "start", "kunde", 50],
];
const GEMEINSAM_ABSCHLUSS = [
["Alles auf Handy und Computer durchtesten", "Jedes Formular, jeder Link, jeder Fehlerfall.", "abschluss", "dogfather", 810],
["Seite selbst durchklicken", "Am besten auf deinem eigenen Handy — du fällst über Dinge, die mir nicht auffallen.", "abschluss", "kunde", 820],
["Rückmeldungen einarbeiten", "Gesammelt, nicht einzeln — das spart beiden Zeit.", "abschluss", "dogfather", 830],
["Freigabe zur Veröffentlichung erteilen", "Ohne dein ausdrückliches Ja geht nichts online.", "abschluss", "kunde", 840],
["Restbetrag begleichen", "Fällig nach der Abnahme, vor der Veröffentlichung.", "abschluss", "kunde", 850],
["Seite live schalten", "Domain, Zertifikat, Suchmaschinen-Grundeinstellungen.", "abschluss", "dogfather", 860],
["Einweisung: Inhalte selbst pflegen", "Damit du nicht für jede Kleinigkeit fragen musst.", "abschluss", "dogfather", 870],
];
export const VORLAGEN = {
onepager: [
...GEMEINSAM_START,
["Aufbau der Seite festlegen", "Welche Abschnitte in welcher Reihenfolge.", "gestaltung", "dogfather", 110],
["Entwurf gestalten", "Farben, Schriften, Bildsprache — du siehst ihn auf Handy und Computer.", "gestaltung", "dogfather", 120],
["Entwurf ansehen und Rückmeldung geben", "Erste von üblicherweise zwei Runden.", "gestaltung", "kunde", 130],
["Entwurf überarbeiten", "", "gestaltung", "dogfather", 140],
["Seite bauen", "Mit deinen echten Inhalten, nicht mit Blindtext.", "umsetzung", "dogfather", 210],
["Kontaktmöglichkeit einrichten", "Formular oder direkte Verlinkung.", "umsetzung", "dogfather", 220],
["Für Suchmaschinen vorbereiten", "Titel, Beschreibung, saubere Überschriften.", "umsetzung", "dogfather", 230],
...GEMEINSAM_ABSCHLUSS,
],
website: [
...GEMEINSAM_START,
["Seitenstruktur festlegen", "Welche Unterseiten es gibt und wie man dorthin kommt.", "gestaltung", "dogfather", 110],
["Entwurf der Startseite", "Die Startseite gibt den Ton für alle anderen vor.", "gestaltung", "dogfather", 120],
["Entwurf ansehen und Rückmeldung geben", "Erste von üblicherweise zwei Runden.", "gestaltung", "kunde", 130],
["Entwurf auf alle Seiten übertragen", "", "gestaltung", "dogfather", 140],
["Zweite Rückmeldung", "Danach wird gebaut.", "gestaltung", "kunde", 150],
["Alle Unterseiten bauen", "", "umsetzung", "dogfather", 210],
["Navigation und Verlinkung", "Kein Weg soll in einer Sackgasse enden.", "umsetzung", "dogfather", 220],
["Formulare einrichten und prüfen", "Anfragen müssen zuverlässig ankommen.", "umsetzung", "dogfather", 230],
["Bilder optimieren", "Damit die Seite auch im Mobilfunk schnell lädt.", "umsetzung", "dogfather", 240],
["Für Suchmaschinen vorbereiten", "Titel, Beschreibungen, Sitemap.", "umsetzung", "dogfather", 250],
["Rechtstexte prüfen lassen", "Impressum und Datenschutz — die endgültige Prüfung gehört zu einer Fachperson.", "umsetzung", "kunde", 260],
...GEMEINSAM_ABSCHLUSS,
],
shop: [
...GEMEINSAM_START,
["Produktdaten liefern", "Bilder, Beschreibungen, Preise, Varianten.", "start", "kunde", 60],
["Zahlungskonto einrichten", "Läuft auf deinen Namen — du bekommst das Geld direkt.", "start", "kunde", 70],
["Aufbau von Shop und Kasse festlegen", "Wie ein Kunde vom Produkt zur Bestellung kommt.", "gestaltung", "dogfather", 110],
["Entwurf gestalten", "Startseite, Produktansicht, Warenkorb.", "gestaltung", "dogfather", 120],
["Entwurf ansehen und Rückmeldung geben", "", "gestaltung", "kunde", 130],
["Shop bauen", "Kategorien, Produkte, Varianten.", "umsetzung", "dogfather", 210],
["Warenkorb und Kasse einrichten", "", "umsetzung", "dogfather", 220],
["Zahlungsarten anbinden und testen", "Mit echten Testbestellungen, nicht nur theoretisch.", "umsetzung", "dogfather", 230],
["Versandregeln festlegen", "Kosten, Zonen, Versandkostenfrei-Grenze.", "umsetzung", "kunde", 240],
["Adminbereich einrichten", "Damit du Artikel selbst anlegen kannst.", "umsetzung", "dogfather", 250],
["Testbestellung durchführen", "Einmal komplett bis zur Bestätigungsmail.", "abschluss", "kunde", 805],
...GEMEINSAM_ABSCHLUSS,
["Einweisung in die Produktpflege", "Artikel anlegen, ändern, ausverkauft setzen.", "abschluss", "dogfather", 880],
],
verwaltung: [
...GEMEINSAM_START,
["Benötigte Auswertungen festlegen", "Was muss am Jahresende herauskommen?", "start", "kunde", 60],
["Rollen und Zugriffe festlegen", "Wer darf was sehen und ändern.", "gestaltung", "dogfather", 110],
["Aufbau der Masken entwerfen", "Belege erfassen soll schnell gehen, nicht schön aussehen.", "gestaltung", "dogfather", 120],
["Entwurf ansehen und Rückmeldung geben", "", "gestaltung", "kunde", 130],
["Anmeldung und Rollen einrichten", "", "umsetzung", "dogfather", 210],
["Erfassung von Belegen bauen", "Mit Foto-Upload vom Handy.", "umsetzung", "dogfather", 220],
["Filter, Suche und Export bauen", "", "umsetzung", "dogfather", 230],
["Sicherungen einrichten und zurückspielen testen", "Eine Sicherung, die nie getestet wurde, ist keine.", "umsetzung", "dogfather", 240],
["Mit echten Belegen testen", "Ein paar Wochen aus der Praxis sagen mehr als jede Theorie.", "abschluss", "kunde", 805],
...GEMEINSAM_ABSCHLUSS,
],
betreuung: [
["Zugänge übergeben und prüfen", "Domain, Hosting, Adminbereich.", "start", "dogfather", 10],
["Sicherungen einrichten", "Regelmäßig und mit geprüfter Wiederherstellung.", "start", "dogfather", 20],
["Überwachung der Erreichbarkeit einrichten", "Damit ein Ausfall auffällt, bevor du ihn bemerkst.", "start", "dogfather", 30],
["Ansprechweg festlegen", "Wie du Änderungswünsche meldest.", "start", "kunde", 40],
["Laufende Sicherheitsaktualisierungen", "Dauerhaft, ohne dass du etwas tun musst.", "umsetzung", "dogfather", 210],
],
};
/* Vorlagen beim ersten Start in die Datenbank schreiben.
Läuft bei jedem Start, tut aber nur beim ersten Mal etwas — sind
bereits Vorlagen für ein Paket vorhanden, wird es übersprungen.
Wichtig: NICHT überschreiben. Sonst wären von Hand angepasste
Vorlagen nach dem nächsten Neustart wieder weg, und niemand käme auf
die Idee, dass der Neustart daran schuld war. */
export function vorlagenSicherstellen() {
const vorhanden = db.prepare(`SELECT COUNT(*) AS n FROM wd_aufgaben_vorlagen`).get().n;
if (vorhanden > 0) return { angelegt: 0, uebersprungen: true };
const einfuegen = db.prepare(
`INSERT INTO wd_aufgaben_vorlagen
(id, paket, titel, beschreibung, kategorie, wer_dran, reihenfolge, aktiv, erstellt_am)
VALUES (?,?,?,?,?,?,?,1,?)`
);
let anzahl = 0;
db.transaction(() => {
for (const [paket, punkte] of Object.entries(VORLAGEN)) {
for (const [titel, beschreibung, kategorie, werDran, reihenfolge] of punkte) {
einfuegen.run(neueId(), paket, titel, beschreibung || null, kategorie, werDran, reihenfolge, jetzt());
anzahl++;
}
}
})();
console.log(`[webdesign] ${anzahl} Aufgaben-Vorlagen angelegt.`);
return { angelegt: anzahl, uebersprungen: false };
}
/* Beim Anlegen eines Projekts die passende Vorlage übernehmen.
Gibt es für das Paket keine, bleibt die Liste leer — das ist besser
als falsche Punkte, die der Kunde dann nicht zuordnen kann. */
export function aufgabenAusVorlage(projektId, kundeId, paket) {
const punkte = db
.prepare(
`SELECT titel, beschreibung, kategorie, wer_dran, reihenfolge
FROM wd_aufgaben_vorlagen WHERE paket = ? AND aktiv = 1 ORDER BY reihenfolge`
)
.all(paket);
if (!punkte.length) return 0;
const einfuegen = db.prepare(
`INSERT INTO wd_aufgaben
(id, projekt_id, kunde_id, titel, beschreibung, kategorie, status, wer_dran, reihenfolge, erstellt_am)
VALUES (?,?,?,?,?,?,'offen',?,?,?)`
);
db.transaction(() => {
for (const p of punkte) {
einfuegen.run(neueId(), projektId, kundeId, p.titel, p.beschreibung,
p.kategorie, p.wer_dran, p.reihenfolge, jetzt());
}
})();
return punkte.length;
}