Die meisten Teams betreiben dafür zwei Systeme. Ein Feedback-Board, auf dem Nutzer Ideen einreichen und abstimmen, und eine öffentliche Roadmap, auf der das Team zeigt, was kommt. Zwei Tools, zwei Datenbanken und dazwischen ein manueller Copy-and-paste-Schritt, der ungefähr in Woche sechs einschläft.
Dann veraltet die Roadmap, die Nutzer merken es, und sie verschwindet still aus der Navigation.
Es sind dieselben Datensätze
Ein Roadmap-Eintrag ist ein Feedback-Beitrag, der angenommen wurde. Mehr verbindet die beiden nicht. Sobald du es so modellierst, fällt das Kopieren weg, denn es gibt nichts zu kopieren.
In Kookee liegen Feedback-Beiträge auf einem Board mit Spalten, die dein Team festlegt: Offen, Geplant, In Arbeit, Ausgeliefert, was eben passt. Das Feedback-Board zeigt alle Spalten. Die Roadmap zeigt dieselben Beiträge, gruppiert nach den Spalten, die du öffentlich machst:
const columns = (await kookee.feedback.getColumns()).filter((column) => column.isVisible);
const { data: posts } = await kookee.feedback.list({ sort: 'top', limit: 100 });
const roadmap = columns.map((column) => ({
...column,
posts: posts.filter((post) => post.columnId === column.id),
}));
Eine Roadmap-API gibt es nicht, weil keine nötig ist. Eine Karte verschiebst du, indem du sie in eine andere Spalte ziehst, und das macht ohnehin die Person, die das Feedback sichtet. In React rendert Roadmap aus @kookee/react/roadmap dieselbe Gruppierung als schreibgeschütztes Board, siehe Eine schreibgeschützte Roadmap mit den React-Komponenten zeigen.
Stimmen fließen in die Priorisierung ein, entscheiden aber nicht
Beiträge haben Stimmen- und Kommentarzahlen, und sort: 'top' und sort: 'trending' holen nach oben, was die Leute gerade beschäftigt:
const top = await kookee.feedback.list({ sort: 'top', category: 'feature', limit: 20 });
Dabei sollte klar sein, was diese Daten bedeuten. Stimmenzahlen zeigen, was deine lautesten, engagiertesten Nutzer wollen. Das ist ein echtes Signal, aber nicht dasselbe wie das, was deine gesamte Nutzerbasis braucht. Nutz es, um Dinge zu finden, von denen du nichts wusstest, nicht um die Roadmap auszulagern. Eine geschlossene Spalte „Abgelehnt“ gibt es genau dafür: damit du öffentlich Nein sagen und es begründen kannst.
Gesammelt wird dort, wo moderiert wird
Einreichen, Abstimmen und Kommentieren passieren auf deinem gehosteten Portal, wo sich Besucher anmelden. Das ist Absicht: eine Person, eine Stimme, und die Moderation deines Teams an einem Ort. Kein Spam über einen geleakten Schlüssel, keine Identität, für die du aus deinem eigenen Backend bürgen musst.
Deine Anwendung liest das Board über die API und stellt es dar, wie du willst: als Roadmap-Seite, als Widget „Meistgewünscht“ auf deiner Preisseite, als Link im Empty State einer Funktion, der zur Diskussion darüber führt. Geschrieben wird auf dem Portal, gelesen überall.
Den Kreis sichtbar schließen
Zwei Details sorgen am meisten dafür, dass sich ein Board lebendig anfühlt.
Kommentare von Projektinhabern und Admins tragen das Flag isOfficial, damit eine Antwort deines Teams anders aussieht als die eines anderen Nutzers. Und getTopContributors() liefert die Leute, deren Beiträge die meisten Stimmen bekommen haben: die Handvoll Menschen, die dir immer wieder die Wahrheit über dein Produkt sagen. Diese Liste ist aus Gründen nützlich, die weit über eine Rangliste hinausgehen.
Der Kreislauf, der ein Board gesund hält, ist kurz: Jemand reicht etwas ein, das Team antwortet öffentlich, die Karte wandert weiter und erscheint auf der Roadmap. Dann wird die Funktion ausgeliefert und landet im Changelog, als ein weiterer kookee.changelog-Eintrag im selben Projekt, hinter demselben API-Schlüssel.