Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

07 - Component Library (Health Module)

Module-specific widgets for the Health surfaces. Authoritative shared components live in 00-shared/03 (AppCard, AppButton, AppBadge, AppSkeleton, AppOfflineBanner, AppBanner, AppSnackbar); this file defines only what the module adds on top. All (proposed).


1. StatusCard

PropertySpec
PurposeOne dependency's availability + optional detail line
Slotsleading StatusDot, title (API, DB, Redis, Storage, Queues), status text (up/down), optional detail line (ping: PONG), optional trailing chip
Statesup (green), down (red), stale (amber + "stale" badge), loading (skeleton)
Semantics`label: ": <up</td></tr> <tr><td>Usage</td><td>S1 card grid; tap target only when <code>down</code> (avoid dead taps)</td></tr> </tbody></table> </div> <pre><code class="language-dart">// lib/features/health/presentation/widgets/status_card.dart StatusCard( title: 'Redis', status: ServiceStatus.up, // up | down | stale detail: 'ping: PONG', // redis-health.indicator.ts:16 onTap: status == ServiceStatus.down ? _openIncident : null, ) </code></pre> <h2 id="2-statusdot"><a class="header" href="#2-statusdot">2. StatusDot</a></h2> <div class="table-wrapper"><table><thead><tr><th>Property</th><th>Spec</th></tr></thead><tbody> <tr><td>Purpose</td><td>10 dp filled circle; color + semantics, never color alone</td></tr> <tr><td>Colors</td><td><code>success</code> green / <code>error</code> red / <code>warning</code> amber (design tokens <code>00-shared/02</code>)</td></tr> <tr><td>a11y</td><td>`Semantics(label: 'up'</td></tr> </tbody></table> </div> <h2 id="3-pendingjobstile"><a class="header" href="#3-pendingjobstile">3. PendingJobsTile</a></h2> <div class="table-wrapper"><table><thead><tr><th>Property</th><th>Spec</th></tr></thead><tbody> <tr><td>Purpose</td><td>Shows BullMQ backlog - the only quantitative signal in the module</td></tr> <tr><td>Data</td><td><code>data.info.bullmq.pendingJobs</code> - array <code>[emails, in-app, webhook-deliver, dlq]</code> (<code>bullmq-health.indicator.ts:27-30</code>)</td></tr> <tr><td>Rendering</td><td><code>emails 3 · in-app 0 · webhook-deliver 8 · dlq 1</code>; dlq count highlighted amber when > 0 (dead-letter backlog is an ops smell)</td></tr> <tr><td>Source note</td><td>counts are <strong>summed per queue</strong> (<code>Object.values(r).reduce</code>, <code>:27-29</code>) - waiting/active/delayed/… collapsed; label must not claim per-state detail</td></tr> </tbody></table> </div> <h2 id="4-lastcheckedlabel"><a class="header" href="#4-lastcheckedlabel">4. LastCheckedLabel</a></h2> <div class="table-wrapper"><table><thead><tr><th>Property</th><th>Spec</th></tr></thead><tbody> <tr><td>Purpose</td><td>"Last checked 12:04:31" - client timestamp of the last 200/503</td></tr> <tr><td>Data</td><td>no server field exists (non-goal, <code>01</code> §5) - local clock only</td></tr> <tr><td>Stale rule</td><td>> 60 s since last success → amber text + "stale" (<code>14</code> QA-4)</td></tr> </tbody></table> </div> <h2 id="5-overallbanner"><a class="header" href="#5-overallbanner">5. OverallBanner</a></h2> <div class="table-wrapper"><table><thead><tr><th>Property</th><th>Spec</th></tr></thead><tbody> <tr><td>Purpose</td><td>One-glance verdict at top of S1</td></tr> <tr><td>Content</td><td>"All systems operational" / "N of 5 degraded — <first down key>" / "All systems degraded"</td></tr> <tr><td>Motion</td><td><code>m-base</code> slide swap; live region announce (<code>00-shared/08</code>)</td></tr> </tbody></table> </div> <h2 id="6-incidentsheet-s2"><a class="header" href="#6-incidentsheet-s2">6. IncidentSheet (S2)</a></h2> <div class="table-wrapper"><table><thead><tr><th>Property</th><th>Spec</th></tr></thead><tbody> <tr><td>Purpose</td><td>Read-only failure detail from cached payload</td></tr> <tr><td>Content</td><td>failed key, monospace <code>SelectableText</code> of <code>data.error.<key></code>, <code>pendingJobs</code> when bullmq, bare-payload notice for redis (<code>redis-health.indicator.ts:17-22</code>)</td></tr> <tr><td>Motion</td><td>bottom sheet per <code>00-shared/03</code></td></tr> </tbody></table> </div> <h2 id="7-not-built-flag-in-code"><a class="header" href="#7-not-built-flag-in-code">7. Not built (flag in code)</a></h2> <ul> <li><strong>History/uptime charts</strong> - endpoint is stateless; no data source <code>(forward-looking)</code>.</li> <li><strong>Threshold config widgets</strong> - no server config surface <code>(proposed)</code> only.</li> </ul> </main> <nav class="nav-wrapper" aria-label="Page navigation"> <!-- Mobile navigation buttons --> <a rel="prev" href="../health/06_Screen_Specifications.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left"> <i class="fa fa-angle-left"></i> </a> <a rel="next prefetch" href="../health/08_Form_Specifications.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right"> <i class="fa fa-angle-right"></i> </a> <div style="clear: both"></div> </nav> </div> </div> <nav class="nav-wide-wrapper" aria-label="Page navigation"> <a rel="prev" href="../health/06_Screen_Specifications.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left"> <i class="fa fa-angle-left"></i> </a> <a rel="next prefetch" href="../health/08_Form_Specifications.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right"> <i class="fa fa-angle-right"></i> </a> </nav> </div> <script> window.playground_copyable = true; </script> <script src="../elasticlunr.min.js"></script> <script src="../mark.min.js"></script> <script src="../searcher.js"></script> <script src="../clipboard.min.js"></script> <script src="../highlight.js"></script> <script src="../book.js"></script> <!-- Custom JS scripts --> <script src="../mermaid.min.js"></script> <script src="../mermaid-init.js"></script> </div> </body> </html>