feat: surface Tribe 'needs care' via server cadence check, alert + dashboard widget (#2032)#2061
Merged
Conversation
…shboard widget (#2032) Add a server-side overdue-contact source of truth (getCareSummary / personCadenceStatus in server/services/tribe.js, GET /api/tribe/care), a checkTribeCadence() proactive alert, and a gated TribeCare dashboard widget. Mirrors the Tribe page's client cadence logic. Claude-Session: https://claude.ai/code/session_01DKGYJ2LdM91DRvNKj8Y31B
bf986d5 to
a93b5d3
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #2032
Summary
Tribe already computed who is overdue for contact, but only client-side inside the Tribe page. This surfaces "needs care" where the user looks daily.
personCadenceStatus()+getCareSummary()inserver/services/tribe.jsport the overdue logic fromclient/src/lib/tribe.js(contactStatus), exposed atGET /api/tribe/care(limit-clamped). External people excluded; missing (never-contacted) sorts above dated-overdue, then most-overdue first.checkTribeCadence()added toproactiveAlerts.jsand wired into thePromise.all; emits "N people are overdue for contact" linking to/tribe, quiet when none.TribeCareWidgetregistered inwidgetRegistry.jsx(gate: (s) => !!s.tribeCare?.hasPeople), reads the server summary fromdashboardState(fetched once inDashboard.jsx, no duplicate fetch), lists top-N most-overdue with links to/tribe, shows an "all caught up" state when none overdue, hidden when Tribe has no people. Added to the default "Everything" layout (gated, so silent on installs without a Tribe).No LLM calls — pure data surfacing.
Deferred
Per issue point 1, the Tribe page still derives its own
overdueCount/soonCountfrom the shared client helper rather than the new endpoint (it already loads every person locally, so fetching/tribe/carefor counts it can derive would add a redundant round-trip). Full consolidation of the two mirrored cadence implementations is tracked in #2060.Test plan
server/services/tribe.test.js—personCadenceStatusstates (external/missing/overdue/soon/steady) +getCareSummary(external exclusion, missing-first sort, limit vs. full count, empty tribe). 24 pass.server/routes/tribe.test.js—GET /tribe/carelimit clamp. 16 pass.client/src/components/TribeCareWidget.test.jsx— hidden states, all-caught-up, overdue list + overflow + deep links. 4 pass.server/services/dashboardLayouts.test.js(10) + clientdashboardsuite (6) green.https://claude.ai/code/session_01DKGYJ2LdM91DRvNKj8Y31B