Skip to content

[codex] Show no-data sleep states - #1222

Merged
Asherlc merged 3 commits into
mainfrom
Asherlc/mobile-missing-sleep-data
Jun 2, 2026
Merged

Asherlc merged 3 commits into
mainfrom
Asherlc/mobile-missing-sleep-data

Conversation

@Asherlc

@Asherlc Asherlc commented Jun 2, 2026 •

Copy link
Copy Markdown
Owner

Stops the mobile dashboard from showing fabricated sleep recommendation numbers when no sleep rows exist.
The server now returns null sleep-need data instead of defaulting to an 8-hour baseline, and the mobile dashboard renders explicit no-data sleep states.
This prevents users from seeing misleading Last Night or Sleep Coach values before previous-night sleep data has synced.
Validated with focused server/mobile tests, server typecheck, and Biome on touched files.


Summary by cubic

Stop showing default 8h sleep recommendations when no sleep data exists. The server now returns null sleepNeed, and the mobile dashboard shows clear no‑data states in Last Night and Sleep Coach to avoid misleading values before sync.

  • Bug Fixes

    • Server returns null sleepNeed when no sleep baseline rows exist (no 8h fallback).
    • Mobile: Last Night card shows “No sleep data”; Sleep Coach shows “No sleep data” when sleepNeed is null, or “Need last night’s sleep…” when a recommendation can’t be made; breakdown only appears when a recommendation is available.
    • Tests updated to cover these no‑data states on server and mobile.
  • Refactors

    • Added Zod output schemas and router .output() typing for mobileDashboard, sleepNeed (including recentNights), and anomalies.

Written for commit e46115f. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Bug Fixes
    • Enhanced handling of missing sleep data—the app now displays a "No sleep data" message when previous night's sleep information is unavailable, rather than showing default or misleading values. Sleep recommendations also properly reflect when baseline data is missing.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @Asherlc, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@coderabbitai

coderabbitai Bot commented Jun 2, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR makes sleepNeed nullable at the server API level when no baseline sleep data exists, and refactors the mobile dashboard UI to display "No sleep data" fallback messages instead of default values. Backend and frontend tests validate the updated contract and rendering behavior.

Changes

Missing sleep data handling

Layer / File(s) Summary
Server sleepNeed nullability
packages/server/src/routers/mobile-dashboard.ts, packages/server/src/routers/mobile-dashboard.test.ts
sleepNeedResult now conditionally returns null when sleepBaselineRows is empty, replacing prior behavior of always constructing a SleepNeedResult object. Server test assertion for the "no sleep rows" case updated from expecting a computed sleep-need object to null.
Mobile UI refactor for missing sleep data
packages/mobile/app/(tabs)/index.tsx, packages/mobile/app/(tabs)/index.test.tsx
"Last Night" section renders when not loading, showing either the sleep bar (when lastNight exists) or "No sleep data" placeholder. "Sleep Coach" section added explicit sleepNeed == null state alongside existing recommendable and non-recommendable branches. New noDataText style supports both "no data" fallback messages. Test case added to validate "No sleep data" and recommendation messaging when previous-night sleep is missing.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Suggested labels

area/mobile, area/server, type/bug

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed Title uses imperative mood, is 33 characters (under 70), includes [codex] area prefix, and has no trailing punctuation.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Asherlc
Asherlc marked this pull request as ready for review June 2, 2026 18:02
Copilot AI review requested due to automatic review settings June 2, 2026 18:02
@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@surmado-code-review

surmado-code-review Bot commented Jun 2, 2026 •

Copy link
Copy Markdown

Automated Checks (advisory, non-blocking)

✅ All checks passed.


Surmado Code Review — Free tier limit reached

You've used all 10 free reviews this month. Deterministic checks (secrets, model strings) still ran above.

Upgrade to the Paid plan for 100 reviews/month + $15 per additional 100: https://app.surmado.com/checkout?plan=pr_review_starter

Or wait until your next monthly window for 10 more free reviews.


Surmado Code Review (v1.2-mt)

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions

github-actions Bot commented Jun 2, 2026 •

Copy link
Copy Markdown
Contributor

Storybook previews for 4c407584 are ready:

This comment updates automatically on each PR push.

@github-actions

github-actions Bot commented Jun 2, 2026 •

Copy link
Copy Markdown
Contributor

Mobile Preview

Scan to open on device:

QR code for dofek://preview/pr-1222

Channel pr-1222
Deep Link dofek://preview/pr-1222
Commit 4c40758

To test on device:

  1. Build and install the preview client: PREVIEW_CHANNEL=pr-1222 npx expo prebuild --clean -p ios
  2. Or tap deep link on an existing preview build: dofek://preview/pr-1222

Each PR gets its own channel. Build a preview client with PREVIEW_CHANNEL=pr-{N} to test.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/server/src/routers/mobile-dashboard.test.ts (1)

405-422: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Isolate the no-sleep-row contract in this case.

This setup also removes metrics and load data, so the sleepNeed === null assertion can pass as part of a broader empty-dashboard state. Keep at least one metric row present and only drop sleep rows here so the test proves the new server contract instead of unrelated null/zero fallbacks.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/server/src/routers/mobile-dashboard.test.ts` around lines 405 - 422,
The test "does not return default sleep coach numbers when no sleep rows exist"
currently mocks execute to return three empty arrays which removes metrics and
load data too; instead mock execute so only sleep-related queries return empty
arrays while ensuring at least one metric row is returned (e.g., make one
execute.mockResolvedValueOnce([...metricRow...]) for the metrics query) so that
createCaller/caller.dashboard still has metrics but no sleep rows; update the
sequence of execute.mockResolvedValueOnce calls in the test to return a metric
row for the metrics query and empty arrays only for sleep queries so the
assertion about sleepNeed === null isolates the no-sleep-row contract.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/mobile/app/`(tabs)/index.test.tsx:
- Around line 193-217: Update the test to exercise the new no-data branch by
setting mockDashboardData.sleepNeed = null (instead of a populated object) so
the TodayScreen import in index.test.tsx renders the fallback state; then
replace the negative assertions for removed UI ("Baseline need", "8h 0m") with
positive assertions that verify the new fallback messaging (e.g., the no-data
text already asserted like "Need last night's sleep for recommendation" or any
explicit fallback element). Ensure you modify the mockDashboardData object used
by the test and keep the TodayScreen render/assert flow intact.

In `@packages/server/src/routers/mobile-dashboard.ts`:
- Around line 370-380: The router's dashboard procedure must declare an explicit
tRPC .output(...) Zod schema for MobileDashboardResult so runtime responses
enforce sleepNeed: null when appropriate; update the dashboard procedure (in
packages/server/src/routers/mobile-dashboard.ts) to call
.output(z.object({...})) matching MobileDashboardResult's fields and make
sleepNeed z.nullable(...) (or z.union([z.object({ baselineMinutes: z.number(),
strainDebtMinutes: z.number(), accumulatedDebtMinutes: z.number(),
totalNeedMinutes: z.number(), recentNights: z.array(z.any()) /* refine element
schema as needed */, canRecommend: z.boolean() }), z.null()])) so the nullable
sleepNeed produced by the sleepNeedResult code path is validated at the router
boundary.

---

Outside diff comments:
In `@packages/server/src/routers/mobile-dashboard.test.ts`:
- Around line 405-422: The test "does not return default sleep coach numbers
when no sleep rows exist" currently mocks execute to return three empty arrays
which removes metrics and load data too; instead mock execute so only
sleep-related queries return empty arrays while ensuring at least one metric row
is returned (e.g., make one execute.mockResolvedValueOnce([...metricRow...]) for
the metrics query) so that createCaller/caller.dashboard still has metrics but
no sleep rows; update the sequence of execute.mockResolvedValueOnce calls in the
test to return a metric row for the metrics query and empty arrays only for
sleep queries so the assertion about sleepNeed === null isolates the
no-sleep-row contract.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: d479b6e5-2510-4997-bee6-19a065e9ca68

📥 Commits

Reviewing files that changed from the base of the PR and between 02e39a1 and 0a399a4.

📒 Files selected for processing (4)
  • packages/mobile/app/(tabs)/index.test.tsx
  • packages/mobile/app/(tabs)/index.tsx
  • packages/server/src/routers/mobile-dashboard.test.ts
  • packages/server/src/routers/mobile-dashboard.ts

Comment thread packages/mobile/app/(tabs)/index.test.tsx Outdated
Comment thread packages/server/src/routers/mobile-dashboard.ts
@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Review app deployment was skipped for PR #1222.

Hetzner could not allocate the configured review app server type in the configured location. This is provider capacity/placement availability, not a code failure in this PR.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 4 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Auto-approved: This change prevents the mobile dashboard from showing a default 8‑hour sleep recommendation when no sleep data exists, replacing it with clear no‑data states; the logic is straightforward, the blast radius is limited, and both server and mobile tests validate the new behavior.

Re-trigger cubic

Asherlc added 2 commits June 2, 2026 11:55
…g-sleep-data

# Conflicts:
#	packages/server/src/routers/mobile-dashboard.ts

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 issues found across 2 files (changes from recent commits).

Requires human review: This change modifies core business logic in a critical user-facing feature by removing a default sleep baseline and adding null-state handling, which carries risk of regression and requires human review to ensure correctness and data integrity.

Re-trigger cubic

@Asherlc
Asherlc merged commit 8e14911 into main Jun 2, 2026
66 checks passed
@Asherlc
Asherlc deleted the Asherlc/mobile-missing-sleep-data branch June 2, 2026 19:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants