Epic 10: Planning & Weekly Queue (Stories 10.1–10.5)#36
Conversation
Story 9.1: Context assembly service — assembles hive context from inspection history, seasonal phase, region, telemetry with freshness timestamps and missing source flagging Story 9.2: Confidence penalty system — adjusts recommendation confidence based on stale/missing data sources, downgrades confidence type appropriately (HIGH→MODERATE→LOW→INSUFFICIENT_DATA) Story 9.3: Conservative defaults — generates safe fallback recommendations when data is insufficient, season-aware (winter: food stores, spring: swarm prep) Story 9.4: Degraded mode — confidence floor at 0.1, INSUFFICIENT_DATA capped at 0.5, configurable staleness thresholds (weather 24h, flora 7d) Story 9.5: Skill mismatch detection — detects sustained behavioral patterns (5+ signals in 14-day window) suggesting misconfigured skill level, returns gentle suggestion message 14 new Go tests covering all service methods. All tests passing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Reorder confidence type downgrade to use else-if chain, preventing MODERATE from being immediately overwritten by LOW when penalty is in the 0.2-0.3 range. Most severe condition (missing sources) now checked first. - Give conservative default recommendation a proper ID instead of empty string, and handle NewRecommendation error explicitly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Story 10.1: Happy Context Homepage — personalized greeting, weather/bloom/ seasonal context cards, two primary CTAs (Start Plan, View Apiaries) Story 10.2: Weekly Action Queue — apiary accordion sections, task rows with priority, overdue highlighting with URGENT badge and catch-up guidance, required materials checklist Story 10.3: Task Actions — Did It (positive), Not now (dismiss) with TanStack Query mutations and cache invalidation Story 10.4-10.5: GraphQL operations for seasonal calendar and dynamic priority updates scaffolded 6 new homepage tests, 323 total passing. Lint clean. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
|
There was a problem hiding this comment.
Pull request overview
Implements the mobile UI + client-side plumbing for Epic 10’s planning surfaces (homepage context cards + weekly plan queue), including new GraphQL operations, React Query hooks, updated tab screens, and tests.
Changes:
- Added planning GraphQL documents plus React Query hooks for weekly queue and task actions.
- Replaced placeholder Home/Plan tab screens with a “Happy Context” homepage and a weekly plan queue UI.
- Updated navigation tests and added dedicated homepage tests.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| apps/mobile/src/services/graphql/planning.ts | Adds GraphQL queries/mutations for weekly queue, homepage context, task actions, and seasonal calendar. |
| apps/mobile/src/features/planning/hooks/use-weekly-queue.ts | Adds React Query hooks for fetching the weekly queue and mutating task status. |
| apps/mobile/app/(tabs)/plan/index.tsx | Implements Weekly Plan screen UI (materials checklist, apiary accordion, task action buttons). |
| apps/mobile/app/(tabs)/index.tsx | Implements homepage greeting + context card UI + primary navigation CTAs. |
| apps/mobile/tests/navigation.test.tsx | Updates screen stub expectations and adds mocks for new planning/auth dependencies. |
| apps/mobile/tests/homepage.test.tsx | Adds tests for homepage greeting, cards, and CTA navigation. |
| _bmad-output/implementation-artifacts/sprint-status.yaml | Updates sprint status tracking for Epic 10 items. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| export const DEFER_TASK_MUTATION = gql` | ||
| mutation DeferTask($id: UUID!, $reason: String, $newDueDate: DateTime!) { | ||
| deferTask(id: $id, reason: $reason, newDueDate: $newDueDate) { | ||
| id | ||
| status | ||
| dueDate | ||
| } | ||
| } | ||
| `; |
There was a problem hiding this comment.
DEFER_TASK_MUTATION does not match the current schema. Server schema defines deferTask(id: UUID!, input: DeferTaskInput) where DeferTaskInput only contains reason (no newDueDate), but this mutation passes reason/newDueDate as top-level args and requires newDueDate. Update the mutation to the schema shape (or update the schema/resolvers if newDueDate is intended).
| key={task.id} | ||
| task={task} | ||
| onComplete={() => completeTask.mutateAsync(task.id)} | ||
| onDismiss={() => dismissTask.mutateAsync({ id: task.id })} | ||
| /> |
There was a problem hiding this comment.
mutateAsync(...) is called from button handlers without await/catch. If the mutation rejects (network/server error), this can surface as an unhandled promise rejection and the UI won’t show feedback. Prefer using mutate with an onError handler, or wrap mutateAsync in void ...catch(...) and surface an error state/toast.
| export default function PlanScreen() { | ||
| const { data: queues, isLoading, refetch, isRefetching } = useWeeklyQueue(); | ||
|
|
||
| if (isLoading) { | ||
| return ( | ||
| <View className="flex-1 bg-background-0 justify-center items-center"> | ||
| <Text size="md" className="text-typography-500">Loading your plan...</Text> | ||
| </View> | ||
| ); | ||
| } | ||
|
|
||
| return ( | ||
| <ScrollView | ||
| className="flex-1 bg-background-50" | ||
| contentContainerClassName="px-4 pt-6 pb-12" | ||
| refreshControl={<RefreshControl refreshing={isRefetching} onRefresh={refetch} />} | ||
| > | ||
| <Heading size="2xl" className="mb-4">This Week's Plan</Heading> | ||
|
|
||
| {queues && <MaterialsChecklist queues={queues} />} | ||
|
|
||
| {(!queues || queues.length === 0) ? ( | ||
| <View className="items-center py-12"> | ||
| <Ionicons name="checkmark-done-circle-outline" size={48} color={ICON_COLORS.muted} /> | ||
| <Text size="md" className="text-typography-400 mt-4 text-center"> | ||
| All caught up! No actions planned this week. | ||
| </Text> | ||
| </View> |
There was a problem hiding this comment.
The empty-state branch (!queues || queues.length === 0) will also run when the query errors (React Query sets data to undefined on error once isLoading is false). That would show “All caught up!” even though loading failed. Consider handling isError/error from useWeeklyQueue() and rendering a retry/error message distinct from the genuine empty state.
Review — fix requested (cycle 1/3)The automated review identified the following issues. Please address each one: Findings to fix
Additional tasks
The review cascade will automatically re-review after new commits are pushed. |
|
@claude Please address all open review comments on this PR from CodeRabbit and Copilot. |
|
Claude finished @don-petry's task in 5m 58s —— View job Addressing Review CommentsAll open Copilot and don-petry review findings addressed in commit Todo List
What was fixed
|
- planning.ts: replace weeklyQueue/homepageContext/dismissTask (non-existent
schema fields) with tasks(status: PENDING), fix DEFER_TASK_MUTATION to use
DeferTaskInput, remove DISMISS_TASK_MUTATION, keep SEASONAL_CALENDAR_QUERY
with scaffolding comment
- use-weekly-queue.ts: add groupByApiary helper to transform flat tasks into
ApiaryQueue[]; fix QueueTask types (priority → TaskPriority enum, dueDate →
string|null); fix useDeferTask variables ({id, input:{reason}}); remove
useDismissTask (no backend mutation exists)
- plan/index.tsx: switch to useDeferTask for "Not now"; use mutate+onError
instead of bare mutateAsync to prevent unhandled promise rejections; handle
isError state distinctly from empty state; stable React keys for materials
- index.tsx: replace "Loading..." stubs with honest static placeholders
- navigation.test.tsx: update mock from useDismissTask to useDeferTask
- use-weekly-queue.test.ts: 9 tests for groupByApiary pure function covering
grouping, field mapping, nullability, priority variants, and ordering
Co-authored-by: Don Petry <don-petry@users.noreply.github.com>
…clean AssembleContext stub - ApplyConfidencePenalty: guard HIGH→LOW downgrade so INSUFFICIENT_DATA and other non-standard types are never upgraded; reorder INSUFFICIENT_DATA cap before universal floor with inline invariant comments (Copilot + cycle-1 review) - AssembleContext: remove unconditional stub that marked all three sources as missing on every call, making HIGH/MODERATE confidence unreachable; return clean context — integration hooks documented in godoc (cycle-1 major) - GenerateConservativeDefault: return (*domain.Recommendation, error) instead of silently swallowing the error and returning nil (Copilot + cycle-1 minor) - Tests: update AssembleContext test for corrected stub behavior; add INSUFFICIENT_DATA-not-upgraded-to-LOW test; update GenerateConservativeDefault tests to handle error return (Copilot) - sonar-project.properties: add sonar.go.coverage.reportPaths so SonarCloud picks up the coverage.out emitted by the CI Go job (cycle-1 major) Co-authored-by: Don Petry <don-petry@users.noreply.github.com>
Review — fix requested (cycle 2/3)The automated review identified the following issues. Please address each one: Findings to fix[Findings would be inserted here] Additional tasks
The review cascade will automatically re-review after new commits are pushed. |
4 similar comments
Review — fix requested (cycle 2/3)The automated review identified the following issues. Please address each one: Findings to fix[Findings would be inserted here] Additional tasks
The review cascade will automatically re-review after new commits are pushed. |
Review — fix requested (cycle 2/3)The automated review identified the following issues. Please address each one: Findings to fix[Findings would be inserted here] Additional tasks
The review cascade will automatically re-review after new commits are pushed. |
Review — fix requested (cycle 2/3)The automated review identified the following issues. Please address each one: Findings to fix[Findings would be inserted here] Additional tasks
The review cascade will automatically re-review after new commits are pushed. |
Review — fix requested (cycle 2/3)The automated review identified the following issues. Please address each one: Findings to fix[Findings would be inserted here] Additional tasks
The review cascade will automatically re-review after new commits are pushed. |
Review — fix requested (cycle 2/3)The automated review identified the following issues. Please address each one: Findings to fix[Findings would be inserted here] Additional tasks
The review cascade will automatically re-review after new commits are pushed. |
Review — fix requested (cycle 2/3)The automated review identified the following issues. Please address each one: Findings to fix[Findings would be inserted here] Additional tasks
The review cascade will automatically re-review after new commits are pushed. |
* Epic 11 + 12: Media Pipeline & Notifications (Stories 11.1–11.5, 12.1–12.5)
Epic 11 — Voice Capture & Media Processing:
- Signed URL config with 15-min expiry and environment-aware bucket naming
- STT worker with 90% confidence threshold and review flagging
- Vision AI worker with 70% confidence threshold and inconclusive detection
- Acoustic analysis worker for queenright/agitation/swarm signals
- Embedding worker generating 768-dim vectors (Vertex AI Embedding 2.0)
- All workers validate media type, return structured results
Epic 12 — Notifications & Alerts:
- Notification dispatcher with validation and FCM integration point
- Suppression logic: global toggle, quiet hours (supports overnight spans)
- High-priority notifications bypass all suppression
- Escalation engine: 2h for high priority, 24h for normal, never for low
- Notification GraphQL operations for center UI, read tracking, preferences
27 new Go tests (media: 14, notification: 13). All passing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Enhance CI pipeline: timeouts, failure artifacts, helper scripts, docs
CI pipeline improvements per Test Architect review:
- Add timeout-minutes to all jobs (15min tests, 20min mobile build)
- Add test failure artifact upload (TS coverage + test-results, 14d retention)
- Add Go test timeout flag (-timeout=5m unit, -timeout=10m integration)
- Upload Go coverage on always() instead of only on success
- Fix format:check to use pnpm -w (workspace root command)
Helper scripts:
- scripts/ci-local.sh — run full CI locally (--skip-go, --skip-ts flags)
- scripts/test-changed.sh — run tests only for changed packages
Documentation:
- docs/ci.md — pipeline guide, quality gates, secrets checklist, troubleshooting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix web platform crash: block native-only modules in Metro resolver
The app crashed on web with 'Cannot use import.meta outside a module'
because Metro resolved @react-native-firebase/* and react-native-mmkv
for the web platform. These are native-only modules.
Fix:
- metro.config.js: Add resolveRequest that returns empty modules for
@react-native-firebase/* and react-native-mmkv on web platform
- mmkv-storage.web.ts: Add localStorage fallback for web (platform
extension ensures correct module is loaded per platform)
The app already uses platform extensions (.web.ts / .native.ts) for
auth services — this fix ensures the bundler respects those boundaries.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Add e2e smoke tests for web platform after import.meta fix
Three e2e test suites for Playwright:
- app-loads.spec.ts: verifies app loads without crash, renders auth/
onboarding screen, no critical console errors
- onboarding-flow.spec.ts: verifies onboarding navigation doesn't crash
- web-compatibility.spec.ts: asserts no import.meta errors, no native
module leaks, no Gluestack hydration errors
These tests specifically guard against the web platform crash that was
caused by native-only modules leaking into the Metro web bundle.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix review findings: parseHour validation, escalation boundary, stub confidence, E2E waits, TS coverage
- notification.go: parseHour now validates range [0,23] and returns error
for non-numeric or out-of-range input instead of silently returning 0
- notification.go: ShouldSuppress treats invalid quiet-hour config as
"no quiet hours" (errStart/errEnd check) rather than discarding errors
- notification.go: ShouldEscalate uses >= for 2h/24h thresholds so
notifications escalate at exactly the threshold, not only after it
- media.go: STTWorker.Process uses minConfidence as stub placeholder and
derives NeedsReview via ShouldFlagForReview instead of hardcoding true
- media.go: VisionWorker.Analyze uses 1.0 as stub placeholder confidence
and derives IsInconclusive via IsInconclusive() instead of hardcoding true
- notification_test.go: add tests for non-numeric/out-of-range quiet hours
and boundary conditions at exactly 2h (high) / 24h (normal)
- tests/e2e: replace page.waitForTimeout() with page.waitForLoadState('networkidle')
to eliminate timing-based flakiness in CI
- Add notification.test.ts and mmkv-storage.web.test.ts to satisfy
SonarCloud ≥80% coverage gate on new TypeScript files
Co-authored-by: Don Petry <don-petry@users.noreply.github.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Don Petry <don-petry@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
|
CI Failure: SonarCloud Code AnalysisStep: SonarCloud Code Analysis (external quality gate) SonarCloud triggered a quality gate failure on this PR. The PR adds Suggested fix: Open the SonarCloud dashboard for this PR, identify which quality gate condition failed (coverage below threshold, new bugs, or code smells), then either add tests to cover the flagged uncovered code or adjust the |
CI Failure: SonarCloud Code AnalysisStep: SonarCloud Quality Gate This PR adds ~1943 lines of new code while introducing Suggested fix: Add unit tests for the |
Dev-Lead — fix-bot-comment (applied)Changes committed and pushed. |
CI Failure: SonarCloud Code AnalysisStep: SonarCloud Quality Gate This PR adds Suggested fix: Add unit tests targeting the new Epic 10 components ( |
Dev-Lead — fix-bot-comment (applied)Changes committed and pushed. |
CI Failure: SonarCloud Code AnalysisStep: SonarCloud Scan The Quality Gate failed on two conditions: 0.0% Coverage on New Code (required ≥ 80%) and C Security Rating on New Code (required ≥ A). The coverage is 0.0% because this PR adds Suggested fix: Add |
Dev-Lead — fix-bot-comment (applied)Changes committed and pushed. |
|
Dev-Lead Fix CI — failedPR: #36 | SHA: |




Summary
Stacked on #35 (Epic 9).
Test plan
🤖 Generated with Claude Code