--- title: Technical Debt --- ```js const API = "http://127.0.0.1:8000"; const POLL = 15_000; ``` ```js const tdState = (async function*() { while (true) { let data = [], ok = false; try { const [rt, rw, rto] = await Promise.all([ fetch(`${API}/technical-debt/`), fetch(`${API}/workstreams/`), fetch(`${API}/topics/`), ]); ok = rt.ok && rw.ok && rto.ok; if (ok) { const [tdList, wsList, topicList] = await Promise.all([rt.json(), rw.json(), rto.json()]); const topicMap = Object.fromEntries(topicList.map(t => [t.id, t])); const wsMap = Object.fromEntries(wsList.map(w => [w.id, { ...w, domain: topicMap[w.topic_id]?.domain_slug ?? "unknown", }])); data = tdList.map(t => ({ ...t, workstream_title: wsMap[t.workstream_id]?.title ?? null, })).sort((a, b) => { const sv = {critical: 0, high: 1, medium: 2, low: 3}; const st = {open: 0, in_progress: 1, deferred: 2, resolved: 3, wont_fix: 4}; const sd = (st[a.status] ?? 9) - (st[b.status] ?? 9); return sd !== 0 ? sd : (sv[a.severity] ?? 9) - (sv[b.severity] ?? 9); }); } } catch {} yield {data, ok, ts: new Date()}; await new Promise(res => setTimeout(res, POLL)); } })(); ``` ```js const data = tdState.data ?? []; const _ok = tdState.ok ?? false; const _ts = tdState.ts; ``` ```js import {MultiSelect} from "./components/multiselect.js"; const STATUSES = ["open", "in_progress", "resolved", "deferred", "wont_fix"]; const SEVERITIES = ["critical", "high", "medium", "low"]; const _domainsResp = await fetch(`${API}/domains/?status=active`).catch(() => null); const DOMAINS = _domainsResp?.ok ? (await _domainsResp.json()).map(d => d.slug) : ["custodian", "railiance", "markitect", "coulomb_social", "personhood", "foerster_capabilities"]; const DEBT_TYPES = ["design", "implementation", "test", "docs", "dependencies", "performance", "security", "other"]; const _filtersForm = Inputs.form( { status: MultiSelect(STATUSES, {label: "Status", placeholder: "All statuses"}), severity: MultiSelect(SEVERITIES, {label: "Severity", placeholder: "All severities"}), domain: MultiSelect(DOMAINS, {label: "Domain", placeholder: "All domains"}), debt_type: MultiSelect(DEBT_TYPES, {label: "Type", placeholder: "All types"}), }, { template: ({status, severity, domain, debt_type}) => html`
${status}${severity}${domain}${debt_type}
`, } ); ``` ```js const filters = Generators.input(_filtersForm); ``` ```js const filtered = data.filter(t => (filters.status.length === 0 || filters.status.includes(t.status)) && (filters.severity.length === 0 || filters.severity.includes(t.severity)) && (filters.domain.length === 0 || filters.domain.includes(t.domain)) && (filters.debt_type.length === 0 || filters.debt_type.includes(t.debt_type)) ); ``` # Technical Debt ```js import {injectTocTop} from "./components/toc-sidebar.js"; import {withDocHelp} from "./components/doc-overlay.js"; import {openEntityModal} from "./components/entity-modal.js"; // ── KPI sidebar ─────────────────────────────────────────────────────────────── const _open = data.filter(t => t.status === "open" || t.status === "in_progress"); const _critical = data.filter(t => t.severity === "critical" && t.status === "open"); const _high = data.filter(t => t.severity === "high" && t.status === "open"); const _resolved = data.filter(t => t.status === "resolved"); const _total = data.filter(t => t.status !== "wont_fix").length; const _resolvedPct = _total > 0 ? Math.round(_resolved.length / _total * 100) : 0; const _kpiBox = html`
Tech Debt
open
${_open.length}
critical
${_critical.length}
high
${_high.length}
resolved
${_resolved.length}
${_resolvedPct}% of total
`; // ── Live indicator ───────────────────────────────────────────────────────────── const _liveEl = html`
${_ok ? `Live · updated ${_ts?.toLocaleTimeString()}` : html`Offline — run: make api`}
`; withDocHelp(_liveEl, "/docs/live-data"); injectTocTop("td-kpi-box", _kpiBox); injectTocTop("live-indicator", _liveEl); const _h1 = document.querySelector("#observablehq-main h1"); if (_h1) _h1.style.position = "relative"; ``` ## By Type & Severity ```js import * as Plot from "npm:@observablehq/plot"; const SEVERITY_COLOR = {critical: "#dc2626", high: "#ea580c", medium: "#3b82f6", low: "#94a3b8"}; const TYPE_COLOR = { design: "#8b5cf6", implementation: "#3b82f6", test: "#f59e0b", docs: "#10b981", dependencies: "#6366f1", performance: "#ec4899", security: "#dc2626", other: "#94a3b8", }; const bySeverity = SEVERITIES .map(s => ({severity: s, count: filtered.filter(t => t.severity === s && t.status !== "resolved" && t.status !== "wont_fix").length})) .filter(d => d.count > 0); const byType = DEBT_TYPES .map(t => ({type: t, count: filtered.filter(d => d.debt_type === t).length})) .filter(d => d.count > 0); if (filtered.length === 0) { display(html`

No technical debt items match the current filter.

`); } else { display(html`
${bySeverity.length > 0 ? Plot.plot({ marks: [ Plot.barX(bySeverity, {y: "severity", x: "count", fill: d => SEVERITY_COLOR[d.severity] ?? "#94a3b8", tip: true}), Plot.ruleX([0]), ], marginLeft: 80, width: 300, title: "Open by severity", }) : ""} ${byType.length > 0 ? Plot.plot({ marks: [ Plot.barX(byType, {y: "type", x: "count", fill: d => TYPE_COLOR[d.type] ?? "#94a3b8", tip: true}), Plot.ruleX([0]), ], marginLeft: 110, width: 360, title: "By type", }) : ""}
`); } ``` ## Critical & High ```js const _urgent = filtered.filter(t => (t.severity === "critical" || t.severity === "high") && t.status === "open"); if (_urgent.length === 0) { display(html`

No critical or high severity open items in current filter. ✓

`); } else { display(html`
${_urgent.map(t => html`
openEntityModal(t, "td")} title="Click to view full details">
${t.td_id ? html`${t.td_id}` : ""} ${t.severity} ${t.debt_type} ${t.domain} ${t.workstream_title ? html`${t.workstream_title}` : ""}
${t.title}
${t.description ? html`
${t.description.slice(0, 220)}${t.description.length > 220 ? " …" : ""}
` : ""} ${t.location ? html`
${t.location}
` : ""}
`)}
`); } ``` ## All Technical Debt ```js display(_filtersForm); display(html`

${filtered.length} items shown.

`); display(html`
${filtered.map(t => html`
openEntityModal(t, "td")} title="Click to view full details">
${t.td_id ? html`${t.td_id}` : ""} ${t.severity} ${t.debt_type} ${t.status.replace("_", " ")} ${t.domain} ${t.workstream_title ? html`${t.workstream_title}` : ""}
${t.title}
${t.description ? html`
${t.description.slice(0, 220)}${t.description.length > 220 ? " …" : ""}
` : ""} ${t.location ? html`
${t.location}
` : ""}
`)}
`); ```