Complete workplan state model cleanup

This commit is contained in:
2026-05-18 01:31:36 +02:00
parent 98b2cb6484
commit d6522a9a40
42 changed files with 789 additions and 310 deletions

View File

@@ -131,8 +131,12 @@ function _ensureStyles() {
/* ── Style maps ──────────────────────────────────────────────────────────── */
const _STATUS_STYLE = {
proposed: "background:#fef3c7;color:#92400e",
ready: "background:#e0f2fe;color:#075985",
active: "background:#d4edda;color:#155724",
blocked: "background:#f8d7da;color:#721c24",
backlog: "background:#f1f5f9;color:#64748b",
finished: "background:#cce5ff;color:#004085",
completed: "background:#cce5ff;color:#004085",
archived: "background:#e2e3e5;color:#383d41",
open: "background:#dbeafe;color:#1e40af",

View File

@@ -0,0 +1,45 @@
export const WORKSTREAM_STATUSES = [
"proposed",
"ready",
"active",
"blocked",
"backlog",
"finished",
"archived",
];
export const OPEN_WORKSTREAM_STATUSES = ["ready", "active", "blocked"];
export const CLOSED_WORKSTREAM_STATUSES = ["finished", "archived"];
export const LEGACY_STATUS_ALIASES = {
todo: "ready",
done: "finished",
completed: "finished",
accepted: "finished",
};
export function normalizeWorkstreamStatus(status) {
const value = String(status ?? "").trim().toLowerCase();
return LEGACY_STATUS_ALIASES[value] ?? value;
}
export function isClosedWorkstream(status) {
return CLOSED_WORKSTREAM_STATUSES.includes(normalizeWorkstreamStatus(status));
}
export function isOpenWorkstream(status) {
return OPEN_WORKSTREAM_STATUSES.includes(normalizeWorkstreamStatus(status));
}
export function isStalledWorkstream(w, staleDays = 7) {
const staleAt = new Date(Date.now() - staleDays * 24 * 60 * 60 * 1000);
const openTasks = (w.todo ?? 0) + (w.in_progress ?? 0) + (w.blocked ?? 0);
return ["active", "blocked"].includes(normalizeWorkstreamStatus(w.status))
&& new Date(w.updated_at) < staleAt
&& (w.done ?? 0) > 0
&& openTasks > 0;
}
export function needsReviewWorkstream(w) {
return Array.isArray(w.health_labels) && w.health_labels.includes("needs_review");
}