2.8 KiB
2.8 KiB
Daily Zone Check-in Integration
Purpose
Campus staff log a daily self-regulation "Emotional Zone" (blue/green/yellow/red).
The same state drives three surfaces: the dashboard check-in card, the
/zones-of-regulation page (reminder banner + card), and a notification-dropdown
nudge when an eligible user has not checked in today.
Backend contract
/api/zone_checkins requires explicit ZONE_CHECKIN. This personal workflow
permission is not implied by globalAccess. The client never computes the date;
"today" is the campus-local date computed server-side from campuses.timezone.
GET /today→{ date, zone, isCheckedInToday }POST /{ data: { zone } }→ record today's zone (upsert)DELETE /today→ clear today's zoneGET /?from=&to=→ history{ rows: [{ date, zone }], count }
Frontend Structure
- API/types:
shared/api/zoneCheckins.ts,shared/types/zoneCheckins.ts - Business:
business/zone-checkin/hooks.ts(useTodayZoneCheckIn,useZoneCheckInHistory),business/zone-checkin/selectors.ts(canZoneCheckIn,shouldNudgeZoneCheckIn) - Components:
components/zone-checkin/ZoneCheckInCard.tsx(shared card),ZoneCheckInReminder.tsx(banner),ZoneCheckInSection.tsx(page section)
Behavior
- Eligibility/nudge gating requires the effective
ZONE_CHECKINpermission. Seed data grants it only to the campus staff workflow audience (director,office_manager,teacher,support_staff), but custom permissions can extend or remove it per user. Global/full-access leadership users do not see self-state nudges unless they receive explicitZONE_CHECKIN. - Dashboard: the card is wired through
useDashboardPage(which exposesshowZoneCheckIn+needsZoneCheckIn) with an optimistic shell value for snappy selection. - Zones page:
ZoneCheckInSectionis self-contained (useTodayZoneCheckIn) and renders above the regulation content. - Notifications:
business/top-barderives a single unread notification fromshouldNudgeZoneCheckIn(buildTopBarNotifications) — there is no backend notifications store. The notification carries anhref(APP_ROUTE_PATHS.zones); clicking it navigates to/zones-of-regulation(a react-routerLink) and closes the dropdown. useTodayZoneCheckInis disabled for users withoutZONE_CHECKIN. Itserrorsurfaces only save/clear failures; non-eligible users should not trigger the/todayrequest.
Tests
business/zone-checkin/selectors.test.ts(eligibility + nudge),business/top-bar/selectors.test.ts(notification builder + zoneshref).- Seeded e2e:
frontend/tests/e2e/zone-checkins.seeded.e2e.ts(record / read-back / clear today, invalid-zone rejection, external-role lockout).
Verification
npm run typecheck,npm run lint,npm run testpass.