9.1 KiB
Projektarten, Zuordnungs-Ablauf und Bereich „Services“ – Design
Stand: 2026-09-30 · Status: vom Nutzer im Chat freigegeben (Abschnitte 1–3), Spec zur Durchsicht
Gesamtvorhaben in drei Teilprojekten, nacheinander: jedes wird gebaut, geht live und wird vom Nutzer live getestet, bevor das nächste beginnt.
- Projektarten + Services (diese Spec)
- Preview 2.0 (statisch / Build / Dev-Server bei Bedarf, Build ohne Portal-Geheimnisse) – eigene Spec
- Funktion „Website-Analyse“ (Einwilligung, eigene Auswertung, Heatmap, Rechtstexte) – eigene Spec
Recherchen dazu: /root/reports/analyse-funktion-2026-09-30/ (projekttypen-preview.md, technik-analyse-heatmap.md,
recht-tracking-deutschland.md).
Ziel
Jedes Repo hat eine Art (Website, Web-App, …). Egal ob es in Gitea oder im WOMS angelegt wird, wird die anlegende Person durch einen Ablauf geführt, bis Art, Kunde und Ticket feststehen. Es entstehen keine leeren Tickets und keine verwaisten Kunden-Repos. Im WOMS zeigt ein Bereich „Services“ unsere Leistungsarten, was je Art möglich ist und welche Projekte welche Art haben.
Entscheidungen (vom Nutzer)
| # | Entscheidung |
|---|---|
| P1 | Arten: Website, Web-App, App, Migration/Umzug, Automation/Skript, Sonstiges. Landingpage und Shop laufen als Website; Wartung ist ein Abo, keine Art; Template bleibt eigene Markierung. |
| P2 | Bestehende Repos bekommen keine automatische Art; sie stehen auf „Art fehlt“, bis jemand sie von Hand setzt. |
| P3 | Gitea bleibt erlaubt. Wer ein Repo in Gitea anlegt, bekommt eine Mail (Muster Push-Zeitmail) mit Link in den Zuordnungs-Ablauf. |
| P4 | Der Ablauf gilt auch für den Mail-Link, mit WOMS-Login (inkl. 2FA). |
| P5 | Ablauf: Art → Für einen Kunden? → Kunde → Ticket (vorhandenes oder neu) → Abschließen. Ein neues Ticket entsteht erst beim Abschließen. |
| P6 | Bereich „Services“ = Variante B: Katalog + Projektlisten je Art. Funktionen werden nur am Projekt geschaltet. |
| P7 | Jetzt nur das Gerüst und als Funktion „Website-Analyse“ (Status In Entwicklung). Weitere Funktionen fragt Claude am Ende ab. |
1. Datenmodell und Erkennung
websiteProjects – neue Attribute (Schema-Skript scripts/projektarten-setup.mjs, idempotent, Muster
portal-setup.mjs):
kind(string 20, optional):website|webapp|app|migration|automation|other; leer = Art fehltforCustomer(boolean, optional; leer = noch nicht beantwortet)kindSetBy(string 64),kindSetAt(ISO-String)createdByGitea(string 64): Gitea-Login der anlegenden Person (für die Mail)assignMailSentAt,assignReminderSentAt(ISO-Strings)
projectType (preview/website/template/repo) bleibt unverändert und regelt weiter nur das Hosting.
Katalog server/services/projectKinds.js (einzige Quelle der Wahrheit):
KINDS = [
{ key: 'website', label: 'Website', preview: 'yes', features: ['analyse'], description: '…' },
{ key: 'webapp', label: 'Web-App', preview: 'possible', features: [], … },
{ key: 'app', label: 'App', preview: 'no', … },
{ key: 'migration', label: 'Migration/Umzug', preview: 'no', ticketType: 'Migration', … },
{ key: 'automation', label: 'Automation/Skript', preview: 'no', … },
{ key: 'other', label: 'Sonstiges', preview: 'no', … },
]
FEATURES = { analyse: { label: 'Website-Analyse', status: 'in_development' } }
Ausgeliefert über GET /api/admin/services (Admin-JWT wie die anderen WOMS-Aufrufe). WOMS hat keine eigene Kopie.
Erkennung neuer Repos
- Org-Webhook WEBklar (Hook 112) bekommt zusätzlich das Ereignis
repository(created). Der Handler inserver/routes/webhook/gitea.jslegt das Projekt-Dokument an (upsertWebsiteProjectByRepo), setztcreatedByGitea = sender.loginund stößt die Mail an.deletedwird ignoriert (Verhalten wie heute). - Job alle 10 Minuten in
server/index.js:importNewRepos()(dieselbe Funktion wie „Suche neue Repos“) findet Repos in persönlichen Konten.createdByGitea= Repo-Owner (bei Org-Repos ohne Hook-Ereignis leer ⇒ keine Mail, erscheint nur in „Art fehlt“). - Nur neu angelegte Projekt-Dokumente lösen eine Mail aus (Dokument in diesem Lauf erzeugt und
Repo
created_atjünger als 24 h). Beim ersten Lauf nach dem Livegang entsteht so keine Mail-Welle. - Empfänger = Mitarbeiter, dessen Kürzel/Anzeigename zum Gitea-Login passt (
findEmployeeForPusherauspushTimeMail.jswiederverwenden). Kein Treffer ⇒ keine Mail, Log-Zeile. - Mail (neue Staff-Vorlage T16 „Neues Repo zuordnen“, Stil wie T15): Repo-Name, Gitea-Link, wer, wann,
Knopf „Jetzt zuordnen“ ⇒
https://ticket.webklar.com/projects/zuordnen/<projektId>. - Erinnerung: 1× nach 24 h, falls
kindnoch leer (derselbe 10-Minuten-Job). Danach nichts mehr.
2. Zuordnungs-Ablauf (WOMS)
Route /projects/zuordnen/:id (ProtectedRoute, also WOMS-Login + 2FA). Kopf: Repo-Name, Gitea-Link,
angelegt von/am. Schritte mit „Zurück“/„Weiter“:
- Was ist das? sechs Knöpfe aus dem Katalog.
- Für einen Kunden? Ja / Nein (internes Projekt ⇒ weiter zu 5).
- Welcher Kunde? Suche über Kunden; „Neuer Kunde“ öffnet das vorhandene Kunden-Formular und kehrt mit dem neuen Kunden zurück.
- Welches Ticket? offene Tickets (Status ≠ Closed/Cancelled) dieses Kunden, oder „Neues Ticket anlegen“
mit vorausgefüllten, änderbaren Feldern: Thema „ – “, Ticket-Art
Migrationbei Art Migration sonstWebpage, Angefragt von = Ansprechpartner des Kunden, Start heute, Details = Repo-Link. - Zusammenfassung + „Abschließen“. Bei Art Website mit Kunde: Preview-Schalter an, Subdomain-Vorschlag aus dem Repo-Namen (änderbar, Prüfung wie heute).
Abschließen = ein Aufruf POST /api/admin/website-projects/:id/zuordnen
{ kind, forCustomer, customerId?, ticketId? | newTicket?, preview?: { subdomain } }. Der Server:
- prüft Eingaben (Art aus Katalog, Kunde existiert, Ticket gehört zum Kunden und ist offen);
- legt ggf. das Ticket an (neue Funktion
createTicketForProjectinticketAdmin.js, Felder wie das WOMS-Formular); - ruft
assignProject(projectId, { customerId, ticketId })(Umzug in die Org, Pushes nachtragen); - setzt
kind,forCustomer,kindSetBy(Mitarbeiter aus dem JWT),kindSetAt; - bei Website + Preview:
updateWebsiteProject(id, { subdomain, projectType: 'preview' }). Scheitert Schritt 3 nach einem neu angelegten Ticket, wird das Ticket wieder gelöscht (kein leeres Ticket). Antwort{ ticketId }⇒ WOMS springt ins Ticket.
Weitere Einstiege:
- WOMS „Neues Repo anlegen“ (Projekte): nach Name/Vorlage direkt weiter in diesen Ablauf.
- Ticket ⇒ „Projekt zuweisen“: Kunde/Ticket bekannt; fehlt die Art, fragt ein kleiner Dialog nur Schritt 1.
- Bereits zugeordnet (
kindgesetzt) ⇒ Seite zeigt „Bereits erledigt von am “ mit Link zum Ticket; Art bleibt dort änderbar.
3. Bereich „Services“ (WOMS)
Menüpunkt „Services“ neben „Projekte“, Route /services. Daten: GET /api/admin/services liefert
Katalog + Projekte gruppiert nach kind (Repo, Kunde, Ticket, Preview-URL, Funktionszustände).
- Eine Karte je Art: Name, Beschreibung, Anzahl, mögliche Funktionen mit Status (Website-Analyse: In Entwicklung), Projekte dieser Art als Liste (Klick ⇒ Ticket bzw. Projekt).
- Karte „Art fehlt“: alle Repos ohne
kind, je mit Knopf „Zuordnen“ ⇒ Ablauf aus Abschnitt 2. - Kein Umschalten hier. Umschalten der Funktionen kommt mit Teilprojekt 3 am Projekt (Ticket ⇒ Projekte).
- Kundenportal: Tab „Funktionen“ zeigt dem Kunden nur Funktionen, die laut Katalog zur Art seines Projekts passen (Anbindung an die Funktionen-Spec, sobald diese live ist).
Fehlerfälle
- Gitea-Login ohne passenden Mitarbeiter ⇒ keine Mail, Projekt steht in „Art fehlt“.
- SMTP-Fehler ⇒
assignMailSentAtbleibt leer, nächster Job-Lauf versucht es erneut (höchstens 3 Versuche). - Zwei Personen schließen gleichzeitig ab ⇒ zweiter Aufruf bekommt 409 „bereits zugeordnet“.
- Appwrite nicht erreichbar ⇒ Job überspringt den Lauf, keine Teil-Zustände.
Tests
- Unit (Portal,
node --test): Katalog, Eingabeprüfung, Mail-Auswahl „nur neue Repos“, Erinnerung, Rückbau des Tickets bei Fehler, 409 bei Doppel-Abschluss. - WOMS (vitest): Schritt-Logik des Ablaufs, Vorbelegung des neuen Tickets.
- Playwright gegen Fixture-Daten: Ablauf komplett (intern, Kunde + vorhandenes Ticket, Kunde + neues Ticket), Services-Seite.
- Live-Test mit dem Nutzer: Repo in Gitea anlegen ⇒ Mail ⇒ Ablauf ⇒ Ticket/Preview prüfen; danach aufräumen.
Livegang (je Schritt mit OK des Nutzers)
L1 Schema-Skript · L2 Portal pushen (main) · L3 Hook 112 um repository erweitern · L4 WOMS pushen (test) ·
L5 Live-Test mit dem Nutzer · danach erst Teilprojekt 2.
Nicht Teil dieser Spec
Preview-Modi/Dev-Server (Teilprojekt 2), Analyse und deren Rechtstexte (Teilprojekt 3), weitere Funktionen
im Katalog (werden am Ende beim Nutzer abgefragt), Umbenennen/Abschaffen von projectType.