feat(taiga): Ticket-Stand im Knoten-Fenster — gelesen, nie geschrieben (D91-Nachtrag 6, SPEC §9)
Wo eine Ref steht und ein `&taiga.<slug>` gilt, zeigt das Knoten-Fenster
Betreff, Status und Zuständigen des Tickets; Taigas Statusname steht neben
der Statusbox der Notation (`In progress → [~]`).
- Proxy: zwei benannte Lese-Endpunkte (`GET /taiga/userstories/{ref}` und
`…/tasks/{ref}`, je `?slug=`) — das Präfix der Ref trägt den Typ, Taiga
hat getrennte `by_ref`-Endpunkte. Erst `/projects/by_slug`, dann `by_ref`
(eine Ref ist nur je Projekt eindeutig); der Slug wird kodiert angehängt.
- Die Abbildung Status → Statusbox liegt im Editor (`mapTaigaStatus`,
headless): Statuscodes sind Notation, das Backend parst sie nicht (D14).
Unbekannte Namen bleiben unabgebildet — Raten hieße, dem Knoten eine
Aussage zu geben, die niemand gemacht hat.
- Geholt wird erst nach 400 ms Verweilen und je Ticket einmal je Sitzung
(↻ holt neu); ohne Anmeldung gar nicht — der Knopf meldet erst an.
- Nichts wird geschrieben: kein Text, keine Statusbox (das bleibt
`#trk.write`).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
e58f71bf90
commit
842e89795a
@@ -19,6 +19,11 @@ reverse.
|
||||
|
||||
## 2026-08-27
|
||||
|
||||
- The node window shows the state of a ticket now: subject, status and assignee, read from Taiga through the backend proxy
|
||||
- Taiga's status is shown next to the notation's own box (`In progress → [~]`) — a column name outside the five known ones stays unmapped and is shown as text
|
||||
- Reading a ticket never changes the plan: no status is written back, and the text stays untouched
|
||||
- The state is fetched once per ticket and session, and only when the node window stays open for a moment — a ↻ button fetches again
|
||||
- Without being logged in nothing is fetched: the window offers a "fetch state" button that asks for the login first
|
||||
- Ctrl+click a ticket ref like `#US-123` — in the text or on its node — opens the ticket in Taiga's web UI; the node window carries an open button, which is the way on touch
|
||||
- The backend names the Taiga web address now (`WERKBAUM_TAIGA_WEB_URL`, reported by `/api/v1/info`) — without it, creating tickets still works and opening is simply absent
|
||||
- A ticket ref like `#US-123` in a node title no longer breaks across two lines at its hyphen
|
||||
|
||||
@@ -8123,3 +8123,90 @@ gestapelten Prüfskript setzte der Sprung aus dem Vor-Schritt die Auswahl
|
||||
asynchron neu und ließ den Tastaturweg scheinbar die falsche URL öffnen —
|
||||
isoliert wiederholt stimmt sie; dieselbe Zustandsvermischung wie beim
|
||||
Nachtrag-4-Bau.
|
||||
|
||||
**Nachtrag 6 — Ticket-Stand im Knoten-Fenster: gelesen, nie geschrieben
|
||||
(2026-08-27).** `#trk.resolve` gebaut: Wo eine Ref steht und ein
|
||||
`&taiga.<slug>` gilt, zeigt das Fenster Betreff, Status und Zuständigen des
|
||||
Tickets (SPEC §9). Die Entscheidungen:
|
||||
|
||||
**Zwei benannte Lese-Endpunkte statt eines mit Typ-Parameter** —
|
||||
`GET /taiga/userstories/{ref}` und `GET /taiga/tasks/{ref}`, je mit `?slug=`.
|
||||
Das Präfix der Ref **trägt** den Typ (D91-Nachtrag 2), und Taiga hat für die
|
||||
beiden Typen getrennte `by_ref`-Endpunkte; ein Enum-Parameter hätte dieselbe
|
||||
Verzweigung nur einen Schritt später gemacht — und passt schlecht zu den
|
||||
vorhandenen Namen (`/taiga/userstories` POST legt an, GET liest).
|
||||
|
||||
**Zwei Umläufe, nicht einer auf Verdacht.** Eine Ref ist nur **je Projekt**
|
||||
eindeutig, `by_ref` filtert über die Projekt-**Id**. Der Proxy fragt deshalb
|
||||
erst `/projects/by_slug`, dann `by_ref`. Der eine gesparte Umlauf über
|
||||
`?project__slug=` wäre eine Wette auf eine Filter-Eigenheit gewesen, die
|
||||
niemand hier gemessen hat — die beiden genommenen Endpunkte sind
|
||||
dokumentiert. **Der Slug wird kodiert** in die Anfrage gesetzt: Er kommt vom
|
||||
Client, und ein `&` darin hängte sonst einen weiteren Filter an (die kleine
|
||||
Schwester der SSRF-Falle, wegen der die Basis-URL Server-Konfiguration ist).
|
||||
|
||||
**Die Abbildung Taiga-Status → Statusbox liegt im FRONTEND**, obwohl
|
||||
`backend/CLAUDE.md` sie unter „Taiga-Mapping" führt: Die Statuscodes sind
|
||||
Notations-Vokabular (SPEC §4), und das Backend parst die Notation nicht
|
||||
(D14). Der Proxy reicht den **Namen** durch (`status_extra_info.name`), der
|
||||
Editor bildet ab — headless in `taiga.js`, damit die Regel eine Zusicherung
|
||||
hat. Vorgabe wie dort notiert: „New" `[ ]`, „In progress" `[~]`, „Ready for
|
||||
test" `[/]`, „Done" `[x]`, „Archived" `[^]`; Groß-/Kleinschreibung und
|
||||
Leerraum egal. **Unbekannte Namen bleiben unabgebildet** und stehen nur als
|
||||
Text — Taiga-Workflows sind je Projekt frei benannt, und Raten wäre hier
|
||||
besonders teuer: Der Knoten bekäme eine Statusaussage, die niemand gemacht
|
||||
hat. Die in der Roadmap versprochene **Konfigurierbarkeit** ist damit
|
||||
ausdrücklich noch offen; der Plan-Knoten `#trk.resolve.map` steht deshalb auf
|
||||
`[/]`, nicht auf `[x]`.
|
||||
|
||||
**Gezeigt wird beides: Taigas Name UND die Box** (`In progress → [~]`). Die
|
||||
Abbildung ist die Aussage — nur die Box zu zeigen verlöre, woher sie kommt,
|
||||
nur den Namen zu zeigen verlöre den Bezug zur Notation.
|
||||
|
||||
**Gelesen, nie geschrieben.** Kein Zeichen wandert in den Text, keine
|
||||
Statusbox ändert sich. Das Zurückschreiben ist ein eigener Knoten
|
||||
(`#trk.write`) und braucht eigene Entscheidungen (wer gewinnt bei
|
||||
Abweichung?). Wo Ticket und Knoten auseinanderlaufen, sieht man es jetzt —
|
||||
die Frage stellt das Fenster, beantworten muss sie ein Mensch.
|
||||
|
||||
**Zwei Sparsamkeiten gegenüber der fremden Instanz.** Das Fenster öffnet beim
|
||||
**Überfahren** (D57) und beim Tabben — ein Abruf je gestreiftem Knoten wäre
|
||||
unhöflich. Also: geholt wird erst, wenn es **400 ms** stehen bleibt, und je
|
||||
Ticket **einmal je Sitzung** (Cache); ein ↻-Knopf holt neu. Ohne Anmeldung
|
||||
wird **gar nicht** automatisch geholt — dort steht der Knopf „Stand holen",
|
||||
und der meldet bei Bedarf an: Ein Klick ist die ausdrückliche Absicht, ein
|
||||
Zeiger über einem Knoten nicht.
|
||||
|
||||
**Der Anmelde-Dialog darf das Fenster nicht zumachen.** Er gehört zu einer
|
||||
Aktion **aus** dem Fenster; schlösse der `pointerdown`-Wächter es (D52), fiele
|
||||
die Antwort ins Leere und man müsste den Knoten erneut aufsuchen. Ausgenommen
|
||||
ist deshalb `.tabmodal-overlay` — die Anlage-Aktion (D91-Nachtrag 4) schließt
|
||||
das Fenster weiterhin selbst, dort ist es gewollt.
|
||||
|
||||
**Ohne Slug geschieht still nichts**, wie beim Öffnen (D91-Nachtrag 5) und
|
||||
beim Abhängigkeits-Sprung (D67); ein Fehler dagegen steht als Zeile im
|
||||
Fenster — ein Abruf, den jemand angefordert hat, darf nicht stumm scheitern.
|
||||
Nicht im Grafikexport und nicht im Druck: Das Fenster ist Bedienhilfe.
|
||||
|
||||
**Nachgemessen** Ende-zu-Ende im Browser gegen das lokal laufende Backend mit
|
||||
Taiga-Stub: Ohne Sitzung steht „Stand holen" und **kein** Abruf geht hinaus;
|
||||
der Knopf meldet an (Dialog, Fenster bleibt offen) und zeigt danach
|
||||
`In progress → [~]` mit Taigas eigenem Betreff und „Zuständig: Anna
|
||||
Beispiel"; die Task zeigt `Ready for test → [/]`; ein Knoten ohne Ref zeigt
|
||||
unverändert die Anlage-Knöpfe, eine Ref **ohne** Projekt-Zuordnung gar
|
||||
nichts. Im Mitschnitt des Stubs: genau **zwei** Anfragen je Ticket
|
||||
(`by_slug` + `by_ref`), **keine** beim kurzen Streifen eines Knotens,
|
||||
**keine** beim zweiten Ansehen (Cache), und genau eine neue Runde auf ↻.
|
||||
Die Farben der Box stammen aus §4 (gemessen: `#FADDE4`/`#D897A8` für
|
||||
`arbeit`). Backend: 5 neue Client-Tests (zweistufiger Weg, eigener
|
||||
Task-Endpunkt, fehlendes `extra_info` → leer statt geraten, 404 ohne zweiten
|
||||
Umlauf, kodierter Slug) und 2 Ende-zu-Ende-Tests; Frontend 585 Tests
|
||||
(9 neue). Gegenproben: Kodierung entfernt → genau die eine danach benannte
|
||||
Zusicherung fällt, Normalisierung des Statusnamens entfernt → genau die drei.
|
||||
|
||||
**Werkzeuggrenze, benannt:** Die Browser-Fläche wurde in dieser Sitzung nicht
|
||||
dargestellt (keine Frames, keine Screenshots, `getBoundingClientRect()`
|
||||
durchweg 0) — geprüft ist deshalb über Ereignisse und **berechnete** Stile,
|
||||
nicht am Bild. Dieselbe Sorte Grenze wie D57 (`focus()` ohne Fensterfokus
|
||||
feuert keine Fokus-Ereignisse): Der Tastaturweg musste synthetisch angestoßen
|
||||
werden.
|
||||
|
||||
@@ -489,6 +489,30 @@ durch eine echte Linie abgesetzt. Siehe D57.
|
||||
|
||||
Siehe D52.
|
||||
|
||||
**Ticket-Stand im Knoten-Fenster (§11).** Trägt die Zeile eine
|
||||
Ticket-Referenz (`#US-123` / `#T-1234`) und ist ihr Teilbaum per
|
||||
`&taiga.<slug>` (§1) einem Projekt zugeordnet, holt das Fenster den Stand des
|
||||
Tickets und zeigt ihn über dem Öffnen-Knopf: **Betreff**, **Status** und, wenn
|
||||
es einen gibt, den **Zuständigen**.
|
||||
|
||||
- Der Taiga-Status wird auf die Statusbox der Notation (§4) abgebildet und
|
||||
**neben** seinem eigenen Namen gezeigt (`In progress → [~]`): „New“ `[ ]`,
|
||||
„In progress“ `[~]`, „Ready for test“ `[/]`, „Done“ `[x]`, „Archived“ `[^]`;
|
||||
Groß-/Kleinschreibung und Leerraum sind egal. Ein Name außerhalb dieser
|
||||
Liste bleibt **unabgebildet** und steht nur als Text — geraten wird nicht.
|
||||
- **Gelesen, nie geschrieben.** Der Notationstext bleibt unangetastet; die
|
||||
Statusbox des Knotens ändert sich nicht, und die Abbildung sagt nichts über
|
||||
Fortschritt (§4) oder Kosten (§5). Das Zurückschreiben ist reserviert (§11).
|
||||
- Geholt wird erst, wenn das Fenster **kurz stehen bleibt** (nicht im
|
||||
Vorüberfahren), und je Ticket **einmal je Sitzung** — ein ↻-Knopf im Fenster
|
||||
holt neu. Ohne Anmeldung an der Instanz, ohne Projekt-Zuordnung oder ohne
|
||||
konfiguriertes Backend geschieht still nichts; ein Fehler steht als Zeile im
|
||||
Fenster.
|
||||
- Reine Bedienhilfe wie das Fenster selbst: nicht im Grafikexport, nicht im
|
||||
Druck.
|
||||
|
||||
Siehe D91-Nachtrag 6.
|
||||
|
||||
**Die Knotenfarbe zeigt den effektiven Status (§4)**, nicht den intrinsischen —
|
||||
das Diagramm beantwortet „wie weit ist das wirklich?“. Wo der eigene Status
|
||||
**weiter** ist als der effektive (der Knoten wird von Abhängigkeiten
|
||||
@@ -1360,6 +1384,9 @@ wird sie von selbst die ID. Erstreckt sich ein Plan über **mehrere**
|
||||
Taiga-Projekte, benennt das Schlagwort `&taiga.<slug>` (unten) das Projekt
|
||||
je Teilbaum — eine Ref wird gegen das Projekt des nächsten Vorfahren mit so
|
||||
einem Tag aufgelöst. Siehe D91-Nachträge 2 und 3.
|
||||
Der **Stand** eines so bezeichneten Tickets (Betreff, Status, Zuständiger)
|
||||
wird im Knoten-Fenster gezeigt (§9) — gelesen, nie geschrieben; das
|
||||
**Zurückschreiben** des Status bleibt reserviert (unten).
|
||||
Freie Schlagworte liegen **nicht** mehr auf `#` — siehe `&tag` unten; damit
|
||||
ist die frühere Dreifach-Rolle von `#` aufgelöst (D34).
|
||||
|
||||
|
||||
@@ -201,9 +201,9 @@
|
||||
| [?] #idea.drift.js: Run the one JS parser inside the IDE (M)
|
||||
- [~] #trk: Tracker integration (XL) %% exactly one of these, hence =
|
||||
= [~] #trk.taiga: Taiga (XL) https://taiga.io
|
||||
- [ ] #trk.resolve: Resolve "#US-123" over the REST API (M)
|
||||
- [ ] #trk.resolve.read: Read title, link and status (S)
|
||||
- [ ] #trk.resolve.map: Map the workflow onto the states (S)
|
||||
- [/] #trk.resolve: Resolve "#US-123" over the REST API (M)
|
||||
- [x] #trk.resolve.read: Read title, link and status (S)
|
||||
- [/] #trk.resolve.map: Map the workflow onto the states (S)
|
||||
- [?] #trk.write: Write the status back (M) :#trk.resolve
|
||||
- [^] #trk.create: Create tickets from nodes (XL)
|
||||
- [^] #trk.create.proxy: Backend proxy with named endpoints (M)
|
||||
@@ -1149,11 +1149,13 @@
|
||||
state. Read-only, and already useful on its own.
|
||||
|
||||
#trk.resolve.read
|
||||
Fetching the ticket and showing what it says.
|
||||
Fetching the ticket and showing what it says: subject, status and assignee
|
||||
in the node window, read through the backend proxy.
|
||||
|
||||
#trk.resolve.map
|
||||
Translating the tracker's workflow onto the eight states of the notation.
|
||||
Configurable, because no two projects use the same column names.
|
||||
The default five are mapped, an unknown column name stays unmapped and is
|
||||
shown as plain text; making the mapping configurable is still open.
|
||||
|
||||
#trk.write
|
||||
The other direction: change a status in the plan and the ticket follows.
|
||||
|
||||
Reference in New Issue
Block a user