feat(terminology): workplan-first dashboard and retirement backlog (STATE-WP-0069)
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s

Add the ranked legacy-interface backlog (T01), rename dashboard navigation and
user-facing copy to workplan while preserving wire-compat API keys (T02), and
activate the retirement workplan with T01/T02 marked done.
This commit is contained in:
tegwick 2026-07-08 16:08:32 +02:00
parent 4dc69bb8f5
commit b2264d1f06
44 changed files with 382 additions and 253 deletions

View file

@ -3,9 +3,9 @@
*
* Usage:
* import {openEntityModal} from "./components/entity-modal.js";
* row.addEventListener("click", () => openEntityModal(entity, "workstream"));
* row.addEventListener("click", () => openEntityModal(entity, "workplan"));
*
* Supported types: "workstream" | "task" | "ep" | "td"
* Supported types: "workplan" | "task" | "ep" | "td"
*/
const _STYLE_ID = "entity-modal-styles";
@ -216,7 +216,7 @@ function _buildBody(entity, type) {
return _field(label, v);
};
if (type === "workstream") {
if (type === "workplan") {
els.push(
bf("Status", entity.status, _STATUS_STYLE),
tf("Domain", entity.domain ?? entity.topic_title ?? "—"),
@ -261,7 +261,7 @@ function _buildBody(entity, type) {
bf("Status", entity.status, _STATUS_STYLE),
bf("Priority", entity.priority, _PRIORITY_STYLE),
tf("Domain", entity.domain ?? "—"),
tf("Workstream", entity.workstream_title ?? "—"),
tf("Workplan", entity.workstream_title ?? "—"),
tf("Assignee", entity.assignee ?? "—"),
tf("Due", entity.due_date ?? "—"),
);
@ -285,7 +285,7 @@ function _buildBody(entity, type) {
bf("Priority", entity.priority, _PRIORITY_STYLE),
tf("Type", entity.ep_type ?? "—"),
tf("Domain", entity.domain ?? "—"),
tf("Workstream", entity.workstream_title ?? "—"),
tf("Workplan", entity.workstream_title ?? "—"),
tf("Location", entity.location ?? "—"),
);
if (entity.description) {
@ -302,7 +302,7 @@ function _buildBody(entity, type) {
bf("Status", entity.status, _STATUS_STYLE),
tf("Type", entity.debt_type ?? "—"),
tf("Domain", entity.domain ?? "—"),
tf("Workstream", entity.workstream_title ?? "—"),
tf("Workplan", entity.workstream_title ?? "—"),
tf("Location", entity.location ?? "—"),
);
if (entity.description) {
@ -319,8 +319,8 @@ function _buildBody(entity, type) {
/**
* Open a detail modal for the given entity.
* @param {object} entity - The entity data object (workstream, task, ep, or td)
* @param {string} type - One of: "workstream" | "task" | "ep" | "td"
* @param {object} entity - The entity data object (workplan, task, ep, or td)
* @param {string} type - One of: "workplan" | "task" | "ep" | "td"
*/
export function openEntityModal(entity, type) {
_ensureStyles();

View file

@ -99,13 +99,13 @@ export const FIELD_HELP = {
doc: "/docs/tasks",
},
workstream_id: {
label: "Workstream ID",
description: "The workstream this event belongs to; auto-resolved from task if not set directly.",
label: "Workplan ID",
description: "The workplan this event belongs to; auto-resolved from task if not set directly.",
doc: "/docs/workstreams",
},
repo_id: {
label: "Repo ID",
description: "The managed repo this event is attributed to; auto-resolved from workstream.",
description: "The managed repo this event is attributed to; auto-resolved from workplan.",
doc: "/docs/repos",
},
session_id: {
@ -142,14 +142,14 @@ export const FIELD_HELP = {
description: "Timestamp when this token event was recorded (UTC).",
},
// ── Workstream ──────────────────────────────────────────────────────────────
// ── Workplan ──────────────────────────────────────────────────────────────
slug: {
label: "Slug",
description: "URL-safe short identifier for this entity.",
},
title: {
label: "Title",
description: "Human-readable name for this workstream or task.",
description: "Human-readable name for this workplan or task.",
},
status: {
label: "Status",
@ -158,12 +158,12 @@ export const FIELD_HELP = {
},
topic_id: {
label: "Topic ID",
description: "The topic this workstream is grouped under.",
description: "The topic this workplan is grouped under.",
doc: "/docs/reference#topics",
},
repo_goal_id: {
label: "Repo Goal ID",
description: "Optional link to a repo-level strategic goal this workstream advances.",
description: "Optional link to a repo-level strategic goal this workplan advances.",
doc: "/docs/goals",
},

View file

@ -6,7 +6,7 @@
* initImprovementModal({apiBase: "http://127.0.0.1:8000"});
*
* Widget names can be declared explicitly via data attribute:
* <div data-widget-name="Workstreams by Domain"></div>
* <div data-widget-name="Workplans by Domain"></div>
*
* Otherwise the component walks the DOM to infer the nearest section heading.
* Submissions are stored as technical-debt items with debt_type="dashboard-improvement".

View file

@ -80,8 +80,8 @@ export function candidateKeysForWorkplan(item = {}) {
export function buildCandidateIndex(workplanIndex = {}) {
const byCandidate = new Map();
const workstreams = workplanIndex.workstreams ?? {};
for (const [id, item] of Object.entries(workstreams)) {
const workplans = workplanIndex.workplans ?? workplanIndex.workstreams ?? {};
for (const [id, item] of Object.entries(workplans)) {
const resolved = {id, ...item};
byCandidate.set(normalizeCandidate(id), resolved);
for (const key of candidateKeysForWorkplan(item)) {