(snapshot)
| 68 | } |
| 69 | |
| 70 | function summarizeDashboard(snapshot) { |
| 71 | const campaigns = snapshot.campaigns || []; |
| 72 | const fleetSessions = snapshot.fleetSessions || []; |
| 73 | const pending = snapshot.pending || {}; |
| 74 | const artifacts = snapshot.operatorArtifacts || {}; |
| 75 | |
| 76 | return { |
| 77 | planningExists: snapshot.planningExists, |
| 78 | pending: { |
| 79 | docSync: pending.docSync || 0, |
| 80 | mergeReviews: pending.mergeReviews || 0, |
| 81 | intakeItems: pending.intakeItems || 0, |
| 82 | }, |
| 83 | git: { |
| 84 | available: Boolean(snapshot.gitStatus?.available), |
| 85 | dirty: Boolean(snapshot.gitStatus?.dirty), |
| 86 | changedFiles: snapshot.gitStatus?.changedFiles || 0, |
| 87 | sample: snapshot.gitStatus?.sample || [], |
| 88 | }, |
| 89 | campaigns: { |
| 90 | active: countByStatus(campaigns, (campaign) => /^(active|needs-continue)$/i.test(String(campaign.status || ''))), |
| 91 | needsReviewPackage: countByStatus(campaigns, (campaign) => campaign.status === 'needs-review-package'), |
| 92 | needsCompletion: countByStatus(campaigns, (campaign) => campaign.status === 'needs-completion'), |
| 93 | needsArchive: countByStatus(campaigns, (campaign) => campaign.status === 'needs-archive'), |
| 94 | totalVisible: campaigns.length, |
| 95 | }, |
| 96 | fleet: { |
| 97 | active: countByStatus(fleetSessions, (session) => /^(active|needs-continue)$/i.test(String(session.status || ''))), |
| 98 | totalVisible: fleetSessions.length, |
| 99 | }, |
| 100 | problems: { |
| 101 | actionable: snapshot.problemSummary?.actionable || 0, |
| 102 | safetyBlocks: snapshot.problemSummary?.safetyBlocks || 0, |
| 103 | stale: snapshot.problemSummary?.stale || 0, |
| 104 | }, |
| 105 | artifacts: { |
| 106 | nextActionReport: artifacts.nextActionReport || null, |
| 107 | approvalCapsule: artifacts.approvalCapsule || null, |
| 108 | staleCount: [ |
| 109 | artifacts.nextActionReport, |
| 110 | artifacts.approvalCapsule, |
| 111 | ].filter((artifact) => artifact && artifact.stale).length, |
| 112 | }, |
| 113 | }; |
| 114 | } |
| 115 | |
| 116 | function boundaryForDecision(decision) { |
| 117 | const finalAction = decision.final?.nextAction || decision.initial?.nextAction || {}; |
no test coverage detected