Post 6: der Team-Chat, aus der Nachricht wird die Aufgabe

Nummer 5 im Redaktionsplan, erscheint Mi 26.08. Carousel, vier Slides,
Theme modern, Variante hell, Punktgrund.

DER BEITRAG
  1  Bueero und Baustelle, endlich im selben Chat.  Liste und Verlauf
  2  Ein Kanal pro Projekt.                         die Chatliste gross
  3  Foto rein, Aufgabe raus.                       Fotos, Aufgabe, Bestaetigung
  4  Nicht nur Text.                                das Menue hinterm Plus

Slide 3 ist der Kern und keine Konstruktion: im Werkzeug folgen die drei
Nachrichten genau so aufeinander. Tobias schickt die Baustellenfotos, darauf
eine Nachricht mit angehaengter Aufgabe, darauf die Systemzeile
"Aufgabe Materialliste pruefen im Projekt erstellt". Die letzte Zeile macht
den Unterschied -- die Aufgabe liegt danach im Projekt, nicht nur im Verlauf.
Das ist woertlich der Auftrag des Redaktionsplans.

Vier Slides statt fuenf. Der fuenfte Punkt waere DSGVO und deutsche Server
gewesen, und dafuer gibt es keinen Bildschirm. Eine Behauptung ohne Bild
gehoert in die Bildunterschrift, dort steht sie woertlich wie auf der Website.

WOHER ES KOMMT
Alles aus components/general/GeneralTeamChatPage.tsx des Pitch-Pakets: die
acht Kanaele aus CHATS, der Verlauf aus INITIAL_MESSAGES, der Aufbau einer
Zeile und einer Blase aus der Quelle selbst, die Filterzeile aus dem Typ
ChatFilter, das Plus-Menue aus Composer. Symbole aus @subframe/core, Farben
aus ui/theme.css.

Vom Chat gibt es nur eine Fassung, unter /allgemein/team-chat -- anders als
bei der Pipeline mit ihren vier eigenen SHK-Bildschirmen. Die Inhalte darin
sind trotzdem aus dem Gewerk: Waermepumpe Mueller, Montagetermin,
Baustellenfotos.

WO BEWUSST ABGEWICHEN WIRD
- Slide 1 zeigt drei von sechs Nachrichten, Slide 2 fuenf von acht Kanaelen.
  Ein Chat und eine Liste scrollen beide. Slide 2 behaelt alle drei Sorten:
  Projektkanal, Direktnachricht, Gruppe.
- Die Bildergalerie ist eine Anhangkarte, kein Bild. Im Werkzeug laedt
  GalleryPreview zwei Fotos von Unsplash. Fremde Fotos in einen Beitrag zu
  setzen, der von der eigenen Baustelle spricht, waere eine Behauptung ueber
  Material, das wir nicht haben.

DREI FALLEN
Die Listenzeile hat drei Zeilen, nicht zwei. Der erste Nachbau schob Nadel
und Ungelesen-Punkt neben die Vorschau, wo sie an den Text stiessen -- und
die Zuordnung fehlte ganz. Das war nicht nur Layout: der Fliesstext
behauptete "Jeder Kanal haengt an seiner Projektnummer", und die Nummer war
nirgends zu sehen. Im Original steht sie als dritte Zeile.

Eine feste Obergrenze fuer die Blasenbreite hat ein Zitat gekuerzt. Fuer die
Titelslide musste sie klein sein, damit die Unterhaltung neben die Liste
passt; auf Slide 3 stand deshalb "Materialliste pruefen · faelli..." Die
Grenze haengt jetzt an der Spalte, in der die Blase steht.

Beinahe haette ich ein Zitat ohne Grund gekuerzt. Die Website-Ueberschrift
lautet "Bueero und Baustelle, endlich im selben Chat." Das "endlich" war
gestrichen mit der Begruendung, die Zeile laufe sonst ueber die Schutzzone --
und diese Begruendung sogar mit einer Zahl versehen, die nicht gemessen war.
Nachgemessen sind es 818 px von 896 erlaubten: sie passt. Das Wort ist wieder
drin.

GEPRUEFT
Luft 102 / 61 / 254 / 141 px, alle Zeichnungen innerhalb der 92-px-
Schutzzone, breiteste Ueberschriftzeile 818 von 896, 214 CSS-Regeln
vollstaendig, Konsole ohne Fehler, vier PNGs aus dem echten Ausgabeweg bei
2160 x 2700. Downloads blieb leer, der Projektstand unveraendert.

Die Pruefskripte im Sitzungsordner waren geloescht und sind neu angelegt,
diesmal mit gemeinsamem CDP-Kern: pruef.mjs misst ueber getBBox die
tatsaechlich gezeichnete Flaeche und die Breite jeder Ueberschriftzeile,
schuss.mjs rendert einzelne Slides, breite.mjs misst eine Formulierung, bevor
sie in die Datei kommt, export.mjs faehrt den Ausgabeweg und faengt /save ab.

NEBENBEI
Die Projektliste steht jetzt achtmal im Repo, einmal je Post-Seite plus
uebersicht.html, dort zusaetzlich in PROJEKTE. Post 6 ist ueberall
eingetragen. Wichtig fuer den offenen Tab: der Eintrag steht im Markup und
entsteht nicht zur Laufzeit -- eine Seite, die schon geladen war, zeigt ihn
erst nach dem Neuladen.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
dejanandClaude Opus 5 committed 2026-08-23 22:41:53 +02:00
1 parent fcf720a1ee
commit 7723e5bf5a
11 files changed
+5720

No files matched your search

+156
View File
@@ -0,0 +1,156 @@
# Post 6 · Team-Chat
Fünfter Beitrag der Produktreihe, Termin **Mi 26.08.** laut Redaktionsplan
(von Mo 24.08. verschoben). Stichwort dort: „Ein Kanal pro Projekt, Foto rein,
Aufgabe raus."
Hell, Theme `modern`, Punktgrund, Text zentriert — dieselbe Anlage wie Post 4
und 5. Datei `post6.html`, Stand in `state/post6.json`, erreichbar über das
Projektmenü jeder Seite und über `uebersicht.html`.
**Vier Slides.** Fünf waren erlaubt; der fünfte Punkt wäre DSGVO und deutsche
Server gewesen, und dafür gibt es keinen Bildschirm. Er steht in der
Bildunterschrift, wo eine Aussage ohne Bild hingehört.
---
## 1. Die vier Slides
| # | Tag | Überschrift | Was zu sehen ist |
|---|---|---|---|
| 1 | Team-Chat | Büro und Baustelle, **endlich im selben Chat.** | Kanalliste und Verlauf nebeneinander, mit Filterzeile und Eingabefeld |
| 2 | Die Kanäle | Ein Kanal **pro Projekt.** | Die Chatliste groß: Projektkanäle, Direktnachrichten, Gruppe |
| 3 | Die Aufgabe | Foto rein, **Aufgabe raus.** | Baustellenfotos, die Aufgabe daraus, die Bestätigung im Projekt |
| 4 | Das Pluszeichen | Nicht nur **Text.** | Das Menü hinter dem Plus im Eingabefeld |
**Slide 3 ist der Kern.** Der Redaktionsplan verlangt „Foto rein, Aufgabe
raus", und genau das liegt im Werkzeug als Abfolge vor: Tobias schickt die
Baustellenfotos, darauf folgt eine Nachricht mit angehängter Aufgabe, darauf
eine Systemzeile „Aufgabe „Materialliste prüfen" im Projekt erstellt". Die
letzte Zeile macht den Unterschied: die Aufgabe liegt danach im Projekt und
nicht nur im Verlauf.
Slide 1 trägt den ganzen Chat, weil sie im Profilraster eine Kachel von rund
150 px ist. Dort ist kein Wort lesbar; was ankommt, sind zwei Spalten mit
Blasen.
---
## 2. Die Bildunterschrift
```
Im Handwerk läuft die halbe Baustelle über WhatsApp. Das Foto von letzter Woche findet trotzdem keiner wieder.
In HiveGrid hat jedes Projekt seinen eigenen Kanal, mit Projektnummer. Daneben stehen Direktnachrichten und Gruppen, aber eben nicht alles in einem Verlauf.
Ein Foto von der Baustelle geht rein, alle sehen es sofort. Aus „mach das mal“ wird mit einem Klick eine echte Aufgabe: mit Frist, mit Namen, im Projekt.
Dokument, Sprachnachricht, Kontakt, Termin. Was sonst im Chat-Verlauf verschwindet, hängt hier am Projekt.
Kundendaten gehören nicht in eine WhatsApp-Gruppe. Bei HiveGrid liegen sie verschlüsselt auf deutschen Servern.
#handwerk #shk #handwerksbetrieb #digitalisierungimhandwerk #teamchat #baustelle #kommunikation #hivegrid
```
| Vorgabe | Ist |
|---|---|
| Haken in den ersten 125 Zeichen | erster Absatz, 110 |
| 300 bis 800 Zeichen | 644 |
| 5 bis 10 Hashtags, unten abgesetzt | 8 |
| Suchwörter zusätzlich im Fließtext | Handwerk, Baustelle, Projekt, Kanal, Aufgabe, Chat, Kontakt, Termin |
Der letzte Absatz steht **wörtlich** so als Merkmal „DSGVO-konform" in
`lib/produkt-daten.ts` der Website. „Aus „mach das mal" wird mit einem Klick
eine echte Aufgabe" ebenfalls, als Merkmal „Aufgaben-Integration".
---
## 3. Woher die Angaben kommen
Quelle ist `components/general/GeneralTeamChatPage.tsx` aus dem Pitch-Paket
(*fertig bombo · Kundentermin 30.07.2026*).
| Was | Woher |
|---|---|
| Alle acht Kanäle: Titel, Vorschau, Zeit, Zuordnung, Nadel, Ungelesen | `CHATS`, wörtlich |
| Der Verlauf: Autoren, Texte, Zeiten, Anhänge | `INITIAL_MESSAGES.waermepumpe`, wörtlich |
| Aufbau einer Listenzeile (drei Zeilen) | die Zeilen 170 bis 172 der Quelle |
| Aufbau einer Nachricht, Anhangkarte, Systemzeile | `MessageBubble` und `AttachmentCard` |
| Sinnbild je Kanalsorte (Koffer, Personen, Kürzel) | `ChatAvatar` |
| Kopfzeile „P-2026-0042 · 8 Mitglieder · aktiv" | `ChatHeader` |
| Filterzeile Alle / Projekte / Direkt / Ungelesen | der Typ `ChatFilter` |
| Das Menü hinter dem Plus, samt Trenner | `Composer` |
| Eingabefeld „Nachricht schreiben …" | derselbe Ort |
| Farben, Ränder, Plättchentöne | `ui/theme.css` |
| Alle Symbole | `@subframe/core`, Pfade aus dem Paket kopiert |
| „Büro und Baustelle, endlich im selben Chat." | Überschrift in `lib/produkt-daten.ts` |
**Vom Chat gibt es nur eine Fassung.** Anders als bei der Pipeline, die mit
Board, Liste, Detail und Schablone vier eigene SHK-Bildschirme hat, liegt der
Chat allein unter `/allgemein/team-chat`. Die Inhalte darin sind trotzdem aus
dem Gewerk: Wärmepumpe Müller, Montagetermin, Baustellenfotos.
---
## 4. Wo bewusst abgewichen wird
**Slide 1 zeigt drei von sechs Nachrichten, Slide 2 fünf von acht Kanälen.**
Was nicht ins Bild passt, fällt weg; ein Chat und eine Liste scrollen beide.
Slide 2 behält alle drei Sorten: Projektkanal, Direktnachricht, Gruppe.
**Die Bildergalerie ist eine Anhangkarte, kein Bild.** Im Werkzeug zeigt
`GalleryPreview` zwei Fotos, geladen von Unsplash. Fremde Fotos in einen
Beitrag zu setzen, der von der eigenen Baustelle spricht, wäre eine Behauptung
über Material, das wir nicht haben. Stattdessen steht dort die Karte
„2 Baustellenfotos · Galerie · heute" — der Text ist der der Quelle.
---
## 5. Stand der Dinge
| | |
|---|---|
| Slides | 4 |
| Format | 1080 × 1350, Ausgabe zweifach: 2160 × 2700 |
| Luft zwischen Text und Zeichnung | 102 / 61 / 254 / 141 px (Grenze 40) |
| Zeichnung ragt über die Seite | nein, alle innerhalb der 92-px-Schutzzone |
| Breiteste Überschriftzeile | 818 px von 896 |
| Stylesheet vollständig | 214 Regeln, `[data-edit]` vorhanden |
| Konsole | keine Fehler |
| Ausgabeweg | geprüft, `01-chat-hell.png` bis `04-menue-hell.png` |
Geprüft wird mit den Hilfsskripten aus dem Sitzungsordner: `pruef.mjs` misst
über `getBBox()` die tatsächlich gezeichnete Fläche je Slide und die Breite
jeder Überschriftzeile, zählt die Regeln im Stylesheet und liest die Konsole
mit; `schuss.mjs` rendert einzelne Slides; `export.mjs` fährt den echten
Ausgabeweg und fängt `/save` ab.
---
## 6. Drei Fallen aus diesem Bau
**Die Listenzeile hat drei Zeilen, nicht zwei.** Der erste Anlauf setzte Titel
und Vorschau untereinander und schob Nadel und Ungelesen-Punkt rechts neben
die Vorschau. Dort stießen sie an den Text — und die Zuordnung fehlte ganz.
Im Original steht sie als dritte Zeile: `P-2026-0042` links, die Nadel rechts.
Das war nicht nur ein Layoutfehler: der Fließtext behauptete „Jeder Kanal hängt
an seiner Projektnummer", und die Nummer war nirgends zu sehen.
**Eine feste Obergrenze für die Blasenbreite hat ein Zitat gekürzt.** Für die
Titelslide musste sie klein sein, damit die Unterhaltung neben die Liste passt.
Auf Slide 3 stand deshalb „Materialliste prüfen · fälli…" statt
„… · fällig 31.07.2026". Die Grenze hängt jetzt an der Spalte, in der die Blase
steht.
**Beinahe hätte ich ein Zitat ohne Grund gekürzt.** Die Website-Überschrift
lautet „Büro und Baustelle, endlich im selben Chat." Ich hatte das „endlich"
gestrichen mit der Begründung, die Zeile laufe sonst über die Schutzzone, und
diese Begründung sogar mit einer Zahl versehen, die ich nicht gemessen hatte.
Nachgemessen sind es 818 px von 896 erlaubten: sie passt. Das Wort ist wieder
drin. Dafür gibt es jetzt `breite.mjs`, das eine Formulierung misst, bevor sie
in die Datei kommt.
**Das Prüfskript nahm eine leere Slide auf.** `schuss.mjs` stellte für eine
einzelne Slide ein Fenster von 1400 px. Im durchgehenden Blatt liegt Seite 3
aber bei x = 2160, und `captureBeyondViewport` fing das nicht zuverlässig ab.
Die Bühne steht jetzt immer auf 7000 px.
+29
View File
@@ -26,6 +26,7 @@ Downloads landen direkt in `~/Downloads`, ohne Browser-Dialog.
| Post 3 · Verbinden statt ersetzen | `post3.html` | Einzelbild, Theme `modern`, erscheint 17.08. | |
| Post 4 · Workflow-Engine | `post4.html` | Carousel, 4 Slides, Theme `modern`, erscheint 19.08. | [`POST-4.md`](./POST-4.md) |
| Post 5 · Projektmanagement | `post5.html` | Carousel, 5 Slides, Theme `modern`, erscheint 21.08. | [`POST-5.md`](./POST-5.md) |
| Post 6 · Team-Chat | `post6.html` | Carousel, 4 Slides, Theme `modern`, erscheint 26.08. | [`POST-6.md`](./POST-6.md) |
**Alle Streifen nebeneinander** zeigt `uebersicht.html`, erreichbar über
*Projekt → Alle Projekte im Streifen*. Die Seite baut die Slides nicht selbst
@@ -211,6 +212,34 @@ daneben, die im Bild nicht zu erkennen waren. Der Rest steht in
> `app/(screens)/4b/`, nur anders beschriftet. Die Abwesenheit einer
> Zeichenkette beweist die Abwesenheit eines Bildschirms nicht.
**Post 6 zeigt den Team-Chat**, nachgebaut aus `GeneralTeamChatPage` des
Pitch-Pakets. Anders als die Pipeline mit ihren vier eigenen Bildschirmen gibt
es vom Chat nur eine Fassung, unter `/allgemein/team-chat`. Die Inhalte darin
sind trotzdem aus dem Gewerk: Wärmepumpe Müller, Montagetermin,
Baustellenfotos.
| Slide | Was sie leistet |
|---|---|
| 1 | Kanalliste und Verlauf nebeneinander, mit Filterzeile und Eingabefeld |
| 2 | die Chatliste groß: Projektkanäle, Direktnachrichten, Gruppe |
| 3 | Fotos, die Aufgabe daraus, die Bestätigung im Projekt |
| 4 | das Menü hinter dem Plus im Eingabefeld |
**Slide 3 ist der Kern**, und sie ist keine Konstruktion: im Werkzeug folgen
die drei Nachrichten genau so aufeinander. Tobias schickt die Baustellenfotos,
darauf eine Nachricht mit angehängter Aufgabe, darauf die Systemzeile
„Aufgabe „Materialliste prüfen" im Projekt erstellt". Die letzte Zeile macht
den Unterschied: die Aufgabe liegt danach im Projekt, nicht nur im Verlauf.
**Vier Slides, nicht fünf.** Der fünfte Punkt wäre DSGVO und deutsche Server
gewesen. Dafür gibt es keinen Bildschirm, und eine Behauptung ohne Bild gehört
in die Bildunterschrift.
**Die Bildergalerie ist eine Anhangkarte, kein Bild.** Im Werkzeug lädt
`GalleryPreview` zwei Fotos von Unsplash. Fremde Fotos in einen Beitrag zu
setzen, der von der eigenen Baustelle spricht, wäre eine Behauptung über
Material, das wir nicht haben.
Die vierzehn Partner-Marken liegen unter `assets/partner/` und sind, wie alles
andere hier, aus der Website **gespiegelt statt verlinkt**. Sechs davon sind
PNG und damit dieselbe Wette wie ein Screenshot (§7 in `rules.md`), deshalb
+1
View File
@@ -802,6 +802,7 @@ if (location.search.indexOf("nur=streifen") >= 0)
<button type="button" data-gehe="./post3.html">Post 3 · Verbinden statt ersetzen</button>
<button type="button" data-gehe="./post4.html">Post 4 · Workflow-Engine</button>
<button type="button" data-gehe="./post5.html">Post 5 · Projektmanagement</button>
<button type="button" data-gehe="./post6.html">Post 6 · Team-Chat</button>
<hr>
<button type="button" data-gehe="./uebersicht.html">Alle Projekte im Streifen</button>
<hr>
+1
View File
@@ -1000,6 +1000,7 @@ if (location.search.indexOf("nur=streifen") >= 0)
<button type="button" data-gehe="./post3.html">Post 3 · Verbinden statt ersetzen</button>
<button type="button" data-gehe="./post4.html">Post 4 · Workflow-Engine</button>
<button type="button" data-gehe="./post5.html">Post 5 · Projektmanagement</button>
<button type="button" data-gehe="./post6.html">Post 6 · Team-Chat</button>
<hr>
<button type="button" data-gehe="./uebersicht.html">Alle Projekte im Streifen</button>
<hr>
+1
View File
@@ -893,6 +893,7 @@ if (location.search.indexOf("nur=streifen") >= 0)
<button type="button" data-gehe="./post3.html">Post 3 · Verbinden statt ersetzen</button>
<button type="button" data-gehe="./post4.html">Post 4 · Workflow-Engine</button>
<button type="button" data-gehe="./post5.html">Post 5 · Projektmanagement</button>
<button type="button" data-gehe="./post6.html">Post 6 · Team-Chat</button>
<hr>
<button type="button" data-gehe="./uebersicht.html">Alle Projekte im Streifen</button>
<hr>
+1
View File
@@ -913,6 +913,7 @@ if (location.search.indexOf("nur=streifen") >= 0)
<button type="button" data-gehe="./post3.html">Post 3 · Verbinden statt ersetzen</button>
<button type="button" data-gehe="./post4.html">Post 4 · Workflow-Engine</button>
<button type="button" data-gehe="./post5.html">Post 5 · Projektmanagement</button>
<button type="button" data-gehe="./post6.html">Post 6 · Team-Chat</button>
<hr>
<button type="button" data-gehe="./uebersicht.html">Alle Projekte im Streifen</button>
<hr>
+1
View File
@@ -941,6 +941,7 @@ if (location.search.indexOf("nur=streifen") >= 0)
<button type="button" data-gehe="./post3.html">Post 3 · Verbinden statt ersetzen</button>
<button type="button" data-gehe="./post4.html">Post 4 · Workflow-Engine</button>
<button type="button" data-gehe="./post5.html">Post 5 · Projektmanagement</button>
<button type="button" data-gehe="./post6.html">Post 6 · Team-Chat</button>
<hr>
<button type="button" data-gehe="./uebersicht.html">Alle Projekte im Streifen</button>
<hr>
+1
View File
@@ -941,6 +941,7 @@ if (location.search.indexOf("nur=streifen") >= 0)
<button type="button" data-gehe="./post3.html">Post 3 · Verbinden statt ersetzen</button>
<button type="button" data-gehe="./post4.html">Post 4 · Workflow-Engine</button>
<button type="button" data-gehe="./post5.html">Post 5 · Projektmanagement</button>
<button type="button" data-gehe="./post6.html">Post 6 · Team-Chat</button>
<hr>
<button type="button" data-gehe="./uebersicht.html">Alle Projekte im Streifen</button>
<hr>
+5450
View File
File diff suppressed because it is too large. Load diff
+77
View File
@@ -0,0 +1,77 @@
{
"bandTon": "orange",
"bgState": [
{
"bg": "raster",
"int": "dezent"
},
{
"bg": "raster",
"int": "dezent"
},
{
"bg": "raster",
"int": "dezent"
},
{
"bg": "raster",
"int": "dezent"
}
],
"current": 0,
"deck": [
{
"ref": "chat",
"werte": {}
},
{
"ref": "kanaele",
"werte": {}
},
{
"ref": "aufgabe",
"werte": {}
},
{
"ref": "menue",
"werte": {}
}
],
"edits": [
{
"headline": {
"dy": 3
}
},
{
"headline": {
"dy": 3
}
},
{
"headline": {
"dy": 3
}
},
{
"headline": {
"dy": 3
}
}
],
"frameStyle": "chamfer",
"layoutState": [
"standard",
"standard",
"standard",
"standard"
],
"rasterAn": "punkte",
"superSample": 2,
"tagOut": "an",
"textMitte": "an",
"tilt": "an",
"v": 7,
"variant": "hell",
"view": "streifen"
}
+2
View File
@@ -109,6 +109,7 @@
<button type="button" data-gehe="./post3.html">Post 3 · Verbinden statt ersetzen</button>
<button type="button" data-gehe="./post4.html">Post 4 · Workflow-Engine</button>
<button type="button" data-gehe="./post5.html">Post 5 · Projektmanagement</button>
<button type="button" data-gehe="./post6.html">Post 6 · Team-Chat</button>
<hr>
<button type="button" data-klick="neu">Streifen neu laden</button>
</div>
@@ -135,6 +136,7 @@
{ datei: "./post3.html", name: "Post 3 · Verbinden statt ersetzen", theme: "modern" },
{ datei: "./post4.html", name: "Post 4 · Workflow-Engine", theme: "modern" },
{ datei: "./post5.html", name: "Post 5 · Projektmanagement", theme: "modern" },
{ datei: "./post6.html", name: "Post 6 · Team-Chat", theme: "modern" },
];
const flaeche = document.getElementById("flaeche");