feat(profile): add EnterInviteCodeSheet with keyboard handling#132
Conversation
Downgrades `react` from 19.2.1 to 19.1.0 and `@types/react` from 19.2.7 to 19.1.17 to maintain compatibility with other dependencies. Updates `expo-updates` from 29.0.14 to 29.0.15 for minor improvements. --- updated-dependencies: - dependency-name: react dependency-version: 19.1.0 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: "@types/react" dependency-version: 19.1.17 dependency-type: direct:development update-type: version-update:semver-minor - dependency-name: "expo-updates" dependency-version: 29.0.15 dependency-type: direct:production update-type: version-update:semver-patch ...
Design document for comprehensive navigation overhaul: - iOS 26 Liquid Glass aesthetic (tab bar, headers, sheets) - react-native-bottom-tabs for native iOS/Android tab bars - react-native-keyboard-controller for native keyboard handling - @gorhom/bottom-sheet for all modals (Settings, Tasks, etc.) - Web top navigation bar - Airbnb strict code standards via eslint-config-airbnb-extended
…le.id - Refactored the ProfileScreen component to utilize user.id for various operations, ensuring compliance with RLS policies. - Updated conditions and database interactions to replace profile.id with user.id in invite code handling and notifications. - Enhanced logic to check for user presence alongside profile, improving robustness of the invite code functionality.
Bumps [react-native-screens](https://github.com/software-mansion/react-native-screens) from 4.16.0 to 4.18.0. - [Release notes](https://github.com/software-mansion/react-native-screens/releases) - [Commits](software-mansion/react-native-screens@4.16.0...4.18.0) --- updated-dependencies: - dependency-name: react-native-screens dependency-version: 4.18.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [@react-native-community/datetimepicker](https://github.com/react-native-datetimepicker/datetimepicker) from 8.4.4 to 8.5.1. - [Release notes](https://github.com/react-native-datetimepicker/datetimepicker/releases) - [Changelog](https://github.com/react-native-datetimepicker/datetimepicker/blob/master/CHANGELOG.md) - [Commits](react-native-datetimepicker/datetimepicker@v8.4.4...v8.5.1) --- updated-dependencies: - dependency-name: "@react-native-community/datetimepicker" dependency-version: 8.5.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…#127) Bumps [@react-navigation/bottom-tabs](https://github.com/react-navigation/react-navigation/tree/HEAD/packages/bottom-tabs) from 7.8.11 to 7.8.12. - [Release notes](https://github.com/react-navigation/react-navigation/releases) - [Changelog](https://github.com/react-navigation/react-navigation/blob/@react-navigation/[email protected]/packages/bottom-tabs/CHANGELOG.md) - [Commits](https://github.com/react-navigation/react-navigation/commits/@react-navigation/[email protected]/packages/bottom-tabs) --- updated-dependencies: - dependency-name: "@react-navigation/bottom-tabs" dependency-version: 7.8.12 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [react-native-svg](https://github.com/react-native-community/react-native-svg) from 15.12.1 to 15.15.1. - [Release notes](https://github.com/react-native-community/react-native-svg/releases) - [Commits](software-mansion/react-native-svg@v15.12.1...v15.15.1) --- updated-dependencies: - dependency-name: react-native-svg dependency-version: 15.15.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [react](https://github.com/facebook/react/tree/HEAD/packages/react) and [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react). These dependencies needed to be updated together. Updates `react` from 19.1.0 to 19.2.1 - [Release notes](https://github.com/facebook/react/releases) - [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md) - [Commits](https://github.com/facebook/react/commits/v19.2.1/packages/react) Updates `@types/react` from 19.1.17 to 19.2.7 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react) --- updated-dependencies: - dependency-name: react dependency-version: 19.2.1 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: "@types/react" dependency-version: 19.2.7 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…lows - Added a new section for Test-Driven Development (TDD) outlining the required cycle and workflow. - Included detailed guidelines on what requires tests and common anti-patterns to avoid in TDD. - Expanded the verification checklist for UI changes, emphasizing the importance of visual verification. - Documented Jest configuration and mock strategies for testing, along with performance testing guidelines. - Updated the commit workflow to emphasize atomic commits and the use of Conventional Commits. - Enhanced the documentation for advanced Expo configuration and Firebase integration. - Added comprehensive notes on ESLint and Prettier configurations, including pre-commit hooks. - Improved clarity and structure throughout the document for better developer experience.
…failures - Introduced a new section detailing guidelines for pushing changes, including verification steps to ensure a clean working state. - Added a list of scenarios when pushing should be avoided, such as failing tests or uncommitted changes. - Documented procedures for handling push failures, including rebase conflict resolution and the importance of avoiding force pushes on main branches. - Emphasized the critical nature of visual verification before committing UI changes.
Resolve conflicts: - Remove AnimatedBottomNav.tsx (replaced by native liquid glass tabs in main) - Regenerate pnpm-lock.yaml
- Create new EnterInviteCodeSheet component for sponsor invite code entry - Use GlassBottomSheet with interactive keyboard behavior - Add BottomSheetTextInput for proper keyboard handling in bottom sheets - Refactor profile.tsx to use sheet-based invite code entry - Add keyboard behavior props to GlassBottomSheet (keyboardBehavior, keyboardBlurBehavior) - Update LogSlipUpSheet with same keyboard improvements - Add comprehensive tests for EnterInviteCodeSheet - Update profile tests to reflect sheet-based architecture
|
Warning Rate limit exceeded@BillChirico has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 18 minutes and 21 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (4)
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. 📝 WalkthroughWalkthroughAdds a new EnterInviteCodeSheet component with imperative present/dismiss API and validation, moves profile invite flow into the sheet and updates useAuth to include Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant Profile as ProfileScreen
participant Sheet as EnterInviteCodeSheet
participant UI as GlassBottomSheet
participant Auth as useAuth / joinWithInviteCode
participant API as Backend/API
User->>Profile: tap "Enter Invite Code"
Profile->>Sheet: inviteCodeSheetRef.present()
Sheet->>UI: render GlassBottomSheet (keyboardBehavior/keyboardBlurBehavior)
User->>Sheet: enter code & submit
Sheet->>Auth: onSubmit -> joinWithInviteCode(code)
Auth->>API: verify / join invite
API-->>Auth: success / error
alt success
Auth-->>Sheet: resolve
Sheet->>Sheet: dismiss(), reset state
Sheet->>Profile: optionally refreshProfile / notify
else error
Auth-->>Sheet: throw error
Sheet->>User: display specific or generic error
end
Suggested labels
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
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 |
|
Claude encountered an error —— View job I'll analyze this and get back to you. |
There was a problem hiding this comment.
Pull request overview
This PR introduces a new bottom sheet component for entering sponsor invite codes with improved keyboard handling, replacing the previous inline input approach. The changes enhance the user experience on iOS by providing proper keyboard interaction and a more polished UI flow.
Key changes:
- New
EnterInviteCodeSheetcomponent with comprehensive input validation and loading states - Enhanced
GlassBottomSheetwith configurable keyboard behavior props - Refactored profile screen to use sheet-based invite code entry instead of inline input
Reviewed changes
Copilot reviewed 10 out of 11 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
package.json |
Downgraded react-native-keyboard-controller to v1.18.5 |
components/sheets/LogSlipUpSheet.tsx |
Updated to use BottomSheetTextInput and adjusted keyboard behavior settings |
components/sheets/EnterInviteCodeSheet.tsx |
New component for invite code entry with validation and keyboard handling |
components/GlassBottomSheet.tsx |
Added keyboardBlurBehavior prop for iOS keyboard dismissal behavior |
app/(tabs)/profile.tsx |
Refactored to use EnterInviteCodeSheet instead of inline input |
__tests__/components/sheets/LogSlipUpSheet.test.tsx |
Added mock for BottomSheetTextInput |
__tests__/components/sheets/EnterInviteCodeSheet.test.tsx |
New comprehensive test suite with 29 tests |
__tests__/app/profile.test.tsx |
Updated tests to reflect sheet-based invite code entry |
__tests__/app/profile.keyboard-avoidance.test.tsx |
Updated keyboard avoidance tests for sheet-based approach |
CLAUDE.md |
Added extensive TDD workflow documentation and testing guidelines |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #132 +/- ##
==========================================
+ Coverage 81.43% 81.57% +0.14%
==========================================
Files 52 53 +1
Lines 3776 3789 +13
Branches 1373 1369 -4
==========================================
+ Hits 3075 3091 +16
+ Misses 679 676 -3
Partials 22 22 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
__tests__/app/profile.test.tsx (1)
1358-1427: Nice added coverage for invite generation errors, sponsee stats, and relationship failuresThe new blocks around “Generate Invite Code Error”, “sponsee task statistics”, and relationship fetch/disconnect error handling add valuable coverage for previously fragile paths (DB insert failures, aggregate task stats, and thrown errors from
supabase.from). Tests assert that the UI remains stable and appropriate alerts/derived values are shown.Given how often
supabase.from.mockImplementationpatterns are repeated across describes and test files, consider extracting small helpers (e.g.,mockRelationshipsQuery,mockTaskStatsQuery,mockInviteInsertError) into a shared test module to reduce duplication and keep the setup logic consistent.Also applies to: 1429-1529, 1531-1559, 1593-1683
app/(tabs)/profile.tsx (1)
1055-1096: Remove unused style definitions.These styles (
inviteInputContainer,inviteInput,inviteSubmitButton,inviteSubmitText,inviteCancelButton,inviteCancelText) were used by the old inline invite code input UI that has been replaced byEnterInviteCodeSheet. They are now dead code.actionButtonText: { fontSize: 16, fontFamily: theme.fontRegular, fontWeight: '600', color: theme.text, marginLeft: 12, }, - inviteInputContainer: { - backgroundColor: theme.card, - padding: 16, - borderRadius: 12, - shadowColor: theme.black, - shadowOffset: { width: 0, height: 2 }, - shadowOpacity: 0.1, - shadowRadius: 8, - elevation: 3, - }, - inviteInput: { - backgroundColor: theme.borderLight, - borderRadius: 8, - padding: 12, - fontSize: 16, - fontFamily: theme.fontRegular, - marginBottom: 12, - color: theme.text, - }, - inviteSubmitButton: { - backgroundColor: theme.primary, - borderRadius: 8, - padding: 12, - alignItems: 'center', - marginBottom: 8, - }, - inviteSubmitText: { - fontSize: 16, - fontFamily: theme.fontRegular, - fontWeight: '600', - color: theme.white, - }, - inviteCancelButton: { - padding: 12, - alignItems: 'center', - }, - inviteCancelText: { - fontSize: 16, - fontFamily: theme.fontRegular, - fontWeight: '600', - color: theme.textSecondary, - }, loadingContainer: {
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (10)
CLAUDE.md(9 hunks)__tests__/app/profile.keyboard-avoidance.test.tsx(4 hunks)__tests__/app/profile.test.tsx(13 hunks)__tests__/components/sheets/EnterInviteCodeSheet.test.tsx(1 hunks)__tests__/components/sheets/LogSlipUpSheet.test.tsx(1 hunks)app/(tabs)/profile.tsx(12 hunks)components/GlassBottomSheet.tsx(3 hunks)components/sheets/EnterInviteCodeSheet.tsx(1 hunks)components/sheets/LogSlipUpSheet.tsx(3 hunks)package.json(1 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: All database operations must use typed client fromtypes/database.ts(source of truth)
Use ErrorBoundary component for graceful failure handling
All imports must use@/path alias (configured in tsconfig.json)
File organization order: imports → types → constants → helpers → main logic → exports with required section comments
JSDoc/TSDoc documentation is mandatory for all exported functions and components
Use mount status tracking with useRef to prevent closure issues in async operations
**/*.{ts,tsx}: Runpnpm typecheckto verify TypeScript types before committing
Write tests for any new or modified code, including happy path, edge cases, and error handling
Every exported function, hook, and component MUST have JSDoc/TSDoc comments that work with IntelliSense
Preferinterfacefor defining object shapes in TypeScript
Use strict mode in TypeScript (strict: truein tsconfig); avoidanytype, useunknownwith type guards instead
Use database types fromtypes/database.tsas the source of truth
Use Supabase client with typed database schema (types/database.ts); all data models derive from database types
Use platform-aware storage: SecureStore (native) / localStorage (web)
Session tokens are stored securely (SecureStore on native, localStorage on web)
Tasks flow unidirectionally from sponsor → sponsee within a relationship
Files:
__tests__/components/sheets/LogSlipUpSheet.test.tsxcomponents/GlassBottomSheet.tsxcomponents/sheets/EnterInviteCodeSheet.tsxcomponents/sheets/LogSlipUpSheet.tsx__tests__/components/sheets/EnterInviteCodeSheet.test.tsx__tests__/app/profile.test.tsx__tests__/app/profile.keyboard-avoidance.test.tsxapp/(tabs)/profile.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx}: NEVER use console.log/error/warn directly - use logger fromlib/logger.ts
All logs are automatically sent to Sentry as breadcrumbs with categorized metadata using LogCategory enum
Logger reserved keys (error_message, error_stack, error_name) must be avoided in metadata
Boolean variables must use is/has/should prefix (isLoading, hasSlipUps)
**/*.{ts,tsx,js,jsx}: Runpnpm lintto check for code quality issues using ESLint before committing
Use camelCase for function and variable names
Use PascalCase for component and type/interface names
Use SCREAMING_SNAKE_CASE for constants
Use 'is', 'has', or 'should' prefix for boolean variables (e.g.,isLoading,hasSlipUps)
Use 'handle' prefix for event handlers (e.g.,handlePress,handleSubmit)
Name async functions with verbs describing the action (e.g.,fetchTasks,updateProfile)
Always use@/path alias for all local imports
Remove unused imports before committing
Always pass Error objects tologger.error()for stack traces and include contextual metadata
Validate and sanitize all user inputs
Use universal logger (lib/logger.ts) for centralized, structured logging with categorization viaLogCategoryenum
Five log levels available:logger.error(),logger.warn(),logger.info(),logger.debug(),logger.trace()
Organize files logically with sections: imports, types, constants, helper functions, component, styles
Files:
__tests__/components/sheets/LogSlipUpSheet.test.tsxcomponents/GlassBottomSheet.tsxcomponents/sheets/EnterInviteCodeSheet.tsxcomponents/sheets/LogSlipUpSheet.tsx__tests__/components/sheets/EnterInviteCodeSheet.test.tsx__tests__/app/profile.test.tsx__tests__/app/profile.keyboard-avoidance.test.tsxapp/(tabs)/profile.tsx
**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.test.{ts,tsx}: UserenderWithProvidersfrom test-utils to wrap components with AuthContext/ThemeContext in tests
Test mocks must include platform detection (defaults to iOS) and timezone handling
Files:
__tests__/components/sheets/LogSlipUpSheet.test.tsx__tests__/components/sheets/EnterInviteCodeSheet.test.tsx__tests__/app/profile.test.tsx__tests__/app/profile.keyboard-avoidance.test.tsx
**/*.{ts,tsx,js,jsx,json,css}
📄 CodeRabbit inference engine (CLAUDE.md)
Run
pnpm formatto ensure consistent code formatting before committing
Files:
__tests__/components/sheets/LogSlipUpSheet.test.tsxcomponents/GlassBottomSheet.tsxcomponents/sheets/EnterInviteCodeSheet.tsxpackage.jsoncomponents/sheets/LogSlipUpSheet.tsx__tests__/components/sheets/EnterInviteCodeSheet.test.tsx__tests__/app/profile.test.tsx__tests__/app/profile.keyboard-avoidance.test.tsxapp/(tabs)/profile.tsx
**/__tests__/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/__tests__/**/*.test.{ts,tsx}: Runpnpm testto verify all tests pass and coverage stays above 80% before committing
Place test files in__tests__/directory mirroring the source structure (e.g.,app/(tabs)/profile.tsx→__tests__/app/profile.test.tsx)
Use Jest with React Native Testing Library for testing; mock Supabase client for database operations
All tests must use descriptive test names and be independent; group related tests withdescribe()blocks
Clean up mocks inbeforeEach()orafterEach()blocks in tests
Test behavior, not implementation details
Wrap test components with AuthContext, ThemeContext; mock Supabase client for database operations
Use MSW (Mock Service Worker) for API mocking in tests
Add regression tests for bug fixes that would have caught the bug
Update tests when modifying existing code; add new tests for new behavior
UserenderWithProvidershelper function to wrap test components with required contexts
Mock navigation with expo-router mocks in tests
Files:
__tests__/components/sheets/LogSlipUpSheet.test.tsx__tests__/components/sheets/EnterInviteCodeSheet.test.tsx__tests__/app/profile.test.tsx__tests__/app/profile.keyboard-avoidance.test.tsx
!(lib/logger.ts|lib/sentry.ts|jest.setup.js)
📄 CodeRabbit inference engine (CLAUDE.md)
Use ESLint no-console rule; never use console.log/error/warn directly - use the universal logger instead (exceptions: logger.ts, sentry.ts, jest.setup.js)
Files:
__tests__/components/sheets/LogSlipUpSheet.test.tsxcomponents/GlassBottomSheet.tsxcomponents/sheets/EnterInviteCodeSheet.tsxpackage.jsoncomponents/sheets/LogSlipUpSheet.tsx__tests__/components/sheets/EnterInviteCodeSheet.test.tsxCLAUDE.md__tests__/app/profile.test.tsx__tests__/app/profile.keyboard-avoidance.test.tsxapp/(tabs)/profile.tsx
**/components/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/components/**/*.{ts,tsx}: Use functional components with hooks (no class components) in React/React Native
Use StyleSheet.create() for component styles instead of inline style objects
Define Props interfaces inline or export if shared; use StyleSheet.create() for component styles
Files:
__tests__/components/sheets/LogSlipUpSheet.test.tsxcomponents/GlassBottomSheet.tsxcomponents/sheets/EnterInviteCodeSheet.tsxcomponents/sheets/LogSlipUpSheet.tsx__tests__/components/sheets/EnterInviteCodeSheet.test.tsx
🧠 Learnings (60)
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Test behavior, not implementation details
Applied to files:
__tests__/components/sheets/LogSlipUpSheet.test.tsx__tests__/components/sheets/EnterInviteCodeSheet.test.tsx__tests__/app/profile.test.tsx__tests__/app/profile.keyboard-avoidance.test.tsx
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to **/*.test.{ts,tsx} : Test mocks must include platform detection (defaults to iOS) and timezone handling
Applied to files:
__tests__/components/sheets/LogSlipUpSheet.test.tsx__tests__/components/sheets/EnterInviteCodeSheet.test.tsxCLAUDE.md__tests__/app/profile.test.tsx__tests__/app/profile.keyboard-avoidance.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Update tests when modifying existing code; add new tests for new behavior
Applied to files:
__tests__/components/sheets/LogSlipUpSheet.test.tsx__tests__/components/sheets/EnterInviteCodeSheet.test.tsxCLAUDE.md__tests__/app/profile.test.tsx__tests__/app/profile.keyboard-avoidance.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Use Jest with React Native Testing Library for testing; mock Supabase client for database operations
Applied to files:
__tests__/components/sheets/LogSlipUpSheet.test.tsx__tests__/components/sheets/EnterInviteCodeSheet.test.tsxCLAUDE.md__tests__/app/profile.test.tsx__tests__/app/profile.keyboard-avoidance.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Add regression tests for bug fixes that would have caught the bug
Applied to files:
__tests__/components/sheets/LogSlipUpSheet.test.tsx__tests__/components/sheets/EnterInviteCodeSheet.test.tsx__tests__/app/profile.test.tsx__tests__/app/profile.keyboard-avoidance.test.tsx
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to tests/**/*.{ts,tsx} : Add comprehensive test coverage for components, hooks, utilities, and API routes in tests/ directory
Applied to files:
__tests__/components/sheets/LogSlipUpSheet.test.tsx__tests__/components/sheets/EnterInviteCodeSheet.test.tsx__tests__/app/profile.test.tsx__tests__/app/profile.keyboard-avoidance.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Wrap test components with AuthContext, ThemeContext; mock Supabase client for database operations
Applied to files:
__tests__/components/sheets/LogSlipUpSheet.test.tsx__tests__/components/sheets/EnterInviteCodeSheet.test.tsxCLAUDE.md__tests__/app/profile.test.tsx__tests__/app/profile.keyboard-avoidance.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/components/**/*.{ts,tsx} : Define Props interfaces inline or export if shared; use StyleSheet.create() for component styles
Applied to files:
__tests__/components/sheets/LogSlipUpSheet.test.tsxcomponents/sheets/EnterInviteCodeSheet.tsxcomponents/sheets/LogSlipUpSheet.tsxCLAUDE.md__tests__/app/profile.test.tsx__tests__/app/profile.keyboard-avoidance.test.tsxapp/(tabs)/profile.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Mock navigation with expo-router mocks in tests
Applied to files:
__tests__/components/sheets/LogSlipUpSheet.test.tsxCLAUDE.md__tests__/app/profile.test.tsx__tests__/app/profile.keyboard-avoidance.test.tsx
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to jest.setup.js : AsyncStorage and SecureStore must be mocked to prevent actual storage during tests
Applied to files:
__tests__/components/sheets/LogSlipUpSheet.test.tsxCLAUDE.md__tests__/app/profile.test.tsx__tests__/app/profile.keyboard-avoidance.test.tsx
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to jest.setup.ts : Initialize testing-library/jest-dom and mocks in jest.setup.ts for unit test setup
Applied to files:
__tests__/components/sheets/LogSlipUpSheet.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Use `renderWithProviders` helper function to wrap test components with required contexts
Applied to files:
__tests__/components/sheets/LogSlipUpSheet.test.tsx__tests__/components/sheets/EnterInviteCodeSheet.test.tsx__tests__/app/profile.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Use MSW (Mock Service Worker) for API mocking in tests
Applied to files:
__tests__/components/sheets/LogSlipUpSheet.test.tsx__tests__/app/profile.test.tsx__tests__/app/profile.keyboard-avoidance.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/components/**/*.{ts,tsx} : Use functional components with hooks (no class components) in React/React Native
Applied to files:
components/sheets/EnterInviteCodeSheet.tsxcomponents/sheets/LogSlipUpSheet.tsxCLAUDE.md__tests__/app/profile.test.tsx__tests__/app/profile.keyboard-avoidance.test.tsxapp/(tabs)/profile.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx} : Write tests for any new or modified code, including happy path, edge cases, and error handling
Applied to files:
__tests__/components/sheets/EnterInviteCodeSheet.test.tsxCLAUDE.md__tests__/app/profile.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : All tests must use descriptive test names and be independent; group related tests with `describe()` blocks
Applied to files:
__tests__/components/sheets/EnterInviteCodeSheet.test.tsx__tests__/app/profile.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Run `pnpm test` to verify all tests pass and coverage stays above 80% before committing
Applied to files:
__tests__/components/sheets/EnterInviteCodeSheet.test.tsxCLAUDE.md
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to src/**/*.{ts,tsx} : Run pnpm test to ensure all unit tests pass after any file changes
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Use `pnpm format && pnpm lint && pnpm typecheck && pnpm build:web && pnpm test` validation workflow before committing
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Run complete validation workflow: `pnpm format && pnpm lint && pnpm typecheck && pnpm build:web && pnpm test` before committing
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-02T00:08:12.192Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T00:08:12.192Z
Learning: After changing any files, run validation workflow: `pnpm format && pnpm typecheck && pnpm lint && pnpm test && pnpm build`. All checks must pass before committing.
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to src/**/*.{ts,tsx,js,jsx} : Run pnpm lint to check for code quality issues including type-aware linting after any file changes
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-02T00:08:12.192Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T00:08:12.192Z
Learning: Applies to tests/**/*.{ts,tsx,js} : Use Jest for unit tests located in `tests/` directory
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to src/**/*.{ts,tsx,js,jsx,css} : Run pnpm build to verify production build passes after any file changes
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to src/**/*.{ts,tsx,js,jsx,css,json,md} : Run pnpm format to ensure consistent code formatting after any file changes
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Run `pnpm lint` to check for code quality issues using ESLint before committing
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx} : Run `pnpm typecheck` to verify TypeScript types before committing
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx,js,jsx,json,css} : Run `pnpm format` to ensure consistent code formatting before committing
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Do NOT skip validation checks to save time - all validation checks must pass before changes are considered complete
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to jest.setup.js : Supabase client must be mocked with chainable query builder in jest.setup.js
Applied to files:
CLAUDE.md__tests__/app/profile.test.tsx
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to {jest.config.ts,jest.setup.ts,tests/**/*.{ts,tsx}} : Use Jest with Testing Library for unit tests located in tests/ directory with configuration via jest.config.ts and setup via jest.setup.ts
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Clean up mocks in `beforeEach()` or `afterEach()` blocks in tests
Applied to files:
CLAUDE.md__tests__/app/profile.test.tsx__tests__/app/profile.keyboard-avoidance.test.tsx
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to **/*.test.{ts,tsx} : Use `renderWithProviders` from test-utils to wrap components with AuthContext/ThemeContext in tests
Applied to files:
CLAUDE.md__tests__/app/profile.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx} : Use Supabase client with typed database schema (`types/database.ts`); all data models derive from database types
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to .env* : Use `EXPO_PUBLIC_*` prefix for environment variables available in client-side code; other vars are build-time only
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx} : Use strict mode in TypeScript (`strict: true` in tsconfig); avoid `any` type, use `unknown` with type guards instead
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-02T00:08:12.192Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T00:08:12.192Z
Learning: Applies to **/*.{ts,tsx} : Use strict TypeScript mode with explicit types for public APIs
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx} : Use database types from `types/database.ts` as the source of truth
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to tsconfig.json : Enable strict TypeScript mode in project configuration
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use 'handle' prefix for event handlers (e.g., `handlePress`, `handleSubmit`)
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to **/*.{ts,tsx} : All database operations must use typed client from `types/database.ts` (source of truth)
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Name async functions with verbs describing the action (e.g., `fetchTasks`, `updateProfile`)
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use PascalCase for component and type/interface names
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/components/**/*.{ts,tsx} : Use StyleSheet.create() for component styles instead of inline style objects
Applied to files:
CLAUDE.mdapp/(tabs)/profile.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Organize files logically with sections: imports, types, constants, helper functions, component, styles
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/hooks/**/*.{ts,tsx} : Extract reusable logic into custom hooks
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to **/*.{ts,tsx} : File organization order: imports → types → constants → helpers → main logic → exports with required section comments
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Use Conventional Branch naming format: `<type>/<description>` (e.g., feat/user-authentication, fix/login-validation-error)
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx} : Tasks flow unidirectionally from sponsor → sponsee within a relationship
Applied to files:
__tests__/app/profile.test.tsx
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to src/app/page.tsx : Use Promise.allSettled in src/app/page.tsx to tolerate partial content loading failures and log issues via reportError
Applied to files:
__tests__/app/profile.test.tsx
📚 Learning: 2025-12-02T00:08:12.192Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T00:08:12.192Z
Learning: Applies to src/app/page.tsx : Homepage must use `Promise.allSettled()` for data fetching to tolerate partial content loading failures
Applied to files:
__tests__/app/profile.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to app/_layout.tsx : Authentication flow in root layout must route users: unauthenticated → /login, authenticated without profile → /onboarding, fully onboarded → /(tabs)
Applied to files:
app/(tabs)/profile.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Use Context API for global state (AuthContext, ThemeContext) wrapping the entire app in `app/_layout.tsx`; do not use Redux/Zustand
Applied to files:
app/(tabs)/profile.tsx
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to {app/_layout.tsx,**/*context*.{ts,tsx}} : Use Context API only (no Redux/Zustand) - contexts must wrap entire app in root layout
Applied to files:
app/(tabs)/profile.tsx
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to src/components/**/*.{ts,tsx} : Use framer-motion for motion and animation effects in navigation, hero, products, about, mentorship, and blog section components
Applied to files:
app/(tabs)/profile.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to app/_layout.tsx : Routing uses Expo Router v6 with typed routes (file-based routing in `app/`) and authentication flow enforced in root layout (`app/_layout.tsx`)
Applied to files:
app/(tabs)/profile.tsx
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to app/_layout.tsx : Root layout (`app/_layout.tsx`) must enforce auth routing: no user → `/login`, user without profile → `/onboarding`, complete profile → `/(tabs)`
Applied to files:
app/(tabs)/profile.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to contexts/AuthContext.tsx : AuthContext must provide: `user`, `session`, `profile`, `loading`, and auth methods
Applied to files:
app/(tabs)/profile.tsx
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to **/*auth*context*.{ts,tsx} : AuthContext must provide: user, session, profile, loading, auth methods
Applied to files:
app/(tabs)/profile.tsx
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Invite codes must connect sponsors to sponsees without requiring email exchange
Applied to files:
app/(tabs)/profile.tsx
🧬 Code graph analysis (5)
__tests__/components/sheets/LogSlipUpSheet.test.tsx (1)
jest.setup.js (11)
React(3-3)React(176-176)React(241-241)React(365-365)React(376-376)React(405-405)React(413-413)React(427-427)React(435-435)ScrollView(10-10)TextInput(7-7)
components/sheets/EnterInviteCodeSheet.tsx (2)
contexts/ThemeContext.tsx (1)
ThemeColors(8-36)components/GlassBottomSheet.tsx (1)
GlassBottomSheetRef(48-65)
__tests__/components/sheets/EnterInviteCodeSheet.test.tsx (3)
jest.setup.js (2)
ScrollView(10-10)TextInput(7-7)components/sheets/EnterInviteCodeSheet.tsx (1)
EnterInviteCodeSheetRef(36-46)components/ErrorBoundary.tsx (1)
render(48-54)
__tests__/app/profile.test.tsx (2)
app/(tabs)/profile.tsx (1)
ProfileScreen(166-882)lib/supabase.ts (1)
supabase(78-87)
__tests__/app/profile.keyboard-avoidance.test.tsx (1)
app/(tabs)/profile.tsx (1)
ProfileScreen(166-882)
🪛 LanguageTool
CLAUDE.md
[uncategorized] ~741-~741: The official name of this software platform is spelled with a capital “H”.
Context: ... or edit 4. Daily Codebase Review (.github/workflows/daily-codebase-review.yml): ...
(GITHUB)
🪛 markdownlint-cli2 (0.18.1)
CLAUDE.md
402-402: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Unit Tests
- GitHub Check: Build for Web
- GitHub Check: auto-label
- GitHub Check: Cursor Bugbot
- GitHub Check: claude-review
🔇 Additional comments (24)
package.json (1)
76-76: Confirm intentional downgrade ofreact-native-keyboard-controllerThe version change to
"react-native-keyboard-controller": "^1.18.5"looks deliberate to align with the new keyboard behavior pattern, but it’s a downgrade from the previously noted version. Please double‑check that 1.18.5 is the intended target and is fully compatible with React Native 0.81.5 and your current keyboard handling usage.components/sheets/LogSlipUpSheet.tsx (1)
21-21: Bottom sheet keyboard handling and text input integration look solidUsing
BottomSheetScrollView/BottomSheetTextInputpluskeyboardBehavior="interactive"andkeyboardBlurBehavior="restore"with the expanded['50%', '90%']snap points is consistent with Gorhom’s expected patterns and should improve iOS keyboard UX while keeping behavior explicit. Notes wiring (value/onChangeText, placeholder, multiline, alignment) mirrors the priorTextInputusage.Also applies to: 298-302, 383-392
components/GlassBottomSheet.tsx (1)
105-117: NewkeyboardBlurBehaviorprop is cleanly wired and backwards‑compatibleExposing
keyboardBlurBehavior?: 'none' | 'restore'with a default of'none'preserves existing behavior while giving sheets (e.g., invite/slip‑up flows) fine‑grained control over iOS keyboard dismissal. Forwarding it directly toBottomSheetModalkeeps the wrapper thin and consistent.Please just confirm your
@gorhom/bottom-sheetversion indeed supports thekeyboardBlurBehaviorprop as typed here.Also applies to: 153-162, 281-281
__tests__/app/profile.keyboard-avoidance.test.tsx (1)
186-205: Keyboard-avoidance tests correctly isolate sheet behavior behind mocksExtending the lucide and
@gorhom/bottom-sheetmocks (includingBottomSheetTextInput) plus mockingEnterInviteCodeSheetlets this file focus purely on ProfileScreen’s keyboard/structure concerns. The “Enter Invite Code” test now verifies the button is present and pressable, while detailed sheet behavior is covered inEnterInviteCodeSheet.test.tsx, which keeps responsibilities nicely separated.Also applies to: 335-362, 440-449
__tests__/app/profile.test.tsx (1)
325-352: Profile tests now correctly delegate invite code behavior toEnterInviteCodeSheetUpdating the lucide and Gorhom mocks and introducing a mock
EnterInviteCodeSheetwhile narrowing the Profile tests to “button exists and is clickable” is a good split of concerns: ProfileScreen verifies wiring (button, sheet presence), and the detailed validation/submission flows live inEnterInviteCodeSheet.test.tsx. The inline comments documenting this delegation make the intent clear for future readers.Also applies to: 506-527, 599-608, 677-687, 848-848, 1333-1354
components/sheets/EnterInviteCodeSheet.tsx (7)
1-16: LGTM!Imports are well-organized using the
@/path alias as required. All necessary React hooks, React Native components, and external dependencies are properly imported.
22-71: LGTM!Well-documented interfaces with proper JSDoc examples. The ref API follows the established pattern from
GlassBottomSheetRef, and props are appropriately typed with optionalonClosecallback.
104-122: LGTM!Correctly implements mount status tracking with
useRefto prevent state updates after unmount, following the coding guidelines for async operations. State variables use appropriateisprefix for boolean (isSubmitting).
127-133: LGTM!The imperative API correctly resets form state before presenting, ensuring a clean slate each time the sheet opens.
167-197: LGTM!The
handleSubmitfunction correctly:
- Guards against double submission with
isSubmittingcheck- Validates input length before proceeding
- Uses mount guards in async code paths
- Handles errors gracefully with user-friendly fallback message
306-410: LGTM!Styles are properly created using
StyleSheet.create()as per coding guidelines, with comprehensive theme integration and good organization.
293-294: LGTM!Good practice setting
displayNamefor better debugging experience in React DevTools.app/(tabs)/profile.tsx (12)
36-38: LGTM!Import of
EnterInviteCodeSheetand its ref type follows the@/path alias convention.
174-174: LGTM!The ref is correctly typed with
EnterInviteCodeSheetRefand follows the established pattern for other sheet refs in this component.
315-327: LGTM on JSDoc and function signature refactor.Good documentation for the refactored function. The parameter-based approach allows the sheet to handle input while the profile screen handles the business logic.
366-368: Correct use ofuser.idfor self-connection check.Using
user.id(auth UID) instead ofprofile.idensures the check aligns with the RLS policy constraints wheresponsee_id = auth.uid().
400-411: Correct RLS alignment forinvite_codes.used_by.The comment on lines 400-401 correctly documents that the RLS
WITH CHECKclause requiresused_by = auth.uid(). Usinguser.idsatisfies this constraint.
438-446: Error re-throw pattern enables sheet error display.The catch block correctly re-throws errors (preserving the original message if available) so the
EnterInviteCodeSheetcan display them to users. This is cleaner than the previous alert-based approach.
614-619: LGTM!Simple handler following the
handleprefix naming convention with appropriate JSDoc documentation.
624-634: LGTM!
KeyboardAwareScrollViewprovides better keyboard handling for the profile screen, with appropriate configuration for tap handling and scroll indicators.
757-772: LGTM!The UI correctly provides invite code entry via the sheet for both new users (no sponsor) and existing users (additional sponsor). This replaces the previous inline input approach for better keyboard UX.
12-14: TheScrollViewimport is still needed. It's used as a type annotation for thescrollViewRefon line 175 (const scrollViewRef = useRef<ScrollView>(null)), so the import should be retained.Likely an incorrect or invalid review comment.
167-167:useAuthhook correctly returns theuserproperty.The
AuthContextTypeinterface definesuser: User | null, and theuseAuthhook properly retrieves it fromAuthContext. This aligns with RLS policy compliance wheresponsee_id = auth.uid()is matched against the user's auth ID.
382-398: RLS policy correctly enforced forsponsee_id.The code correctly uses
user.idforsponsee_id, which satisfies the RLS policy constraintsponsee_id = auth.uid(). This ensures users can only create relationships for themselves, maintaining critical security alignment. The comment documenting this requirement is accurate and necessary.
Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com> Signed-off-by: Bill Chirico <[email protected]>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 10 out of 11 changed files in this pull request and generated 3 comments.
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Note Docstrings generation - SKIPPED All docstrings were kept as they were. No new docstrings were generated. |
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
CLAUDE.md(9 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
!(lib/logger.ts|lib/sentry.ts|jest.setup.js)
📄 CodeRabbit inference engine (CLAUDE.md)
Use ESLint no-console rule; never use console.log/error/warn directly - use the universal logger instead (exceptions: logger.ts, sentry.ts, jest.setup.js)
Files:
CLAUDE.md
🧠 Learnings (43)
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Run `pnpm test` to verify all tests pass and coverage stays above 80% before committing
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-02T00:08:12.192Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T00:08:12.192Z
Learning: After changing any files, run validation workflow: `pnpm format && pnpm typecheck && pnpm lint && pnpm test && pnpm build`. All checks must pass before committing.
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Update tests when modifying existing code; add new tests for new behavior
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to src/**/*.{ts,tsx} : Run pnpm test to ensure all unit tests pass after any file changes
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Do NOT commit or push changes - allow the user to do this manually
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Do NOT skip validation checks to save time; all checks must pass before committing
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Use `pnpm format && pnpm lint && pnpm typecheck && pnpm build:web && pnpm test` validation workflow before committing
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Run complete validation workflow: `pnpm format && pnpm lint && pnpm typecheck && pnpm build:web && pnpm test` before committing
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to src/**/*.{ts,tsx,js,jsx} : Run pnpm lint to check for code quality issues including type-aware linting after any file changes
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-02T00:08:12.192Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T00:08:12.192Z
Learning: Applies to tests/**/*.{ts,tsx,js} : Use Jest for unit tests located in `tests/` directory
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to src/**/*.{ts,tsx,js,jsx,css} : Run pnpm build to verify production build passes after any file changes
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to src/**/*.{ts,tsx,js,jsx,css,json,md} : Run pnpm format to ensure consistent code formatting after any file changes
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Run `pnpm lint` to check for code quality issues using ESLint before committing
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx} : Write tests for any new or modified code, including happy path, edge cases, and error handling
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx} : Run `pnpm typecheck` to verify TypeScript types before committing
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx,js,jsx,json,css} : Run `pnpm format` to ensure consistent code formatting before committing
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Do NOT skip validation checks to save time - all validation checks must pass before changes are considered complete
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Use Jest with React Native Testing Library for testing; mock Supabase client for database operations
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Wrap test components with AuthContext, ThemeContext; mock Supabase client for database operations
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to jest.setup.js : Supabase client must be mocked with chainable query builder in jest.setup.js
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to {jest.config.ts,jest.setup.ts,tests/**/*.{ts,tsx}} : Use Jest with Testing Library for unit tests located in tests/ directory with configuration via jest.config.ts and setup via jest.setup.ts
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to jest.setup.js : AsyncStorage and SecureStore must be mocked to prevent actual storage during tests
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Clean up mocks in `beforeEach()` or `afterEach()` blocks in tests
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to **/*.test.{ts,tsx} : Test mocks must include platform detection (defaults to iOS) and timezone handling
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Mock navigation with expo-router mocks in tests
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to **/*.test.{ts,tsx} : Use `renderWithProviders` from test-utils to wrap components with AuthContext/ThemeContext in tests
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx} : Use Supabase client with typed database schema (`types/database.ts`); all data models derive from database types
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to .env* : Use `EXPO_PUBLIC_*` prefix for environment variables available in client-side code; other vars are build-time only
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx} : Use strict mode in TypeScript (`strict: true` in tsconfig); avoid `any` type, use `unknown` with type guards instead
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-02T00:08:12.192Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T00:08:12.192Z
Learning: Applies to **/*.{ts,tsx} : Use strict TypeScript mode with explicit types for public APIs
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx} : Use database types from `types/database.ts` as the source of truth
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to tsconfig.json : Enable strict TypeScript mode in project configuration
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use 'handle' prefix for event handlers (e.g., `handlePress`, `handleSubmit`)
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to **/*.{ts,tsx} : All database operations must use typed client from `types/database.ts` (source of truth)
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Name async functions with verbs describing the action (e.g., `fetchTasks`, `updateProfile`)
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use PascalCase for component and type/interface names
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/components/**/*.{ts,tsx} : Define Props interfaces inline or export if shared; use StyleSheet.create() for component styles
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/components/**/*.{ts,tsx} : Use StyleSheet.create() for component styles instead of inline style objects
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/components/**/*.{ts,tsx} : Use functional components with hooks (no class components) in React/React Native
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Organize files logically with sections: imports, types, constants, helper functions, component, styles
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/hooks/**/*.{ts,tsx} : Extract reusable logic into custom hooks
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to **/*.{ts,tsx} : File organization order: imports → types → constants → helpers → main logic → exports with required section comments
Applied to files:
CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Use Conventional Branch naming format: `<type>/<description>` (e.g., feat/user-authentication, fix/login-validation-error)
Applied to files:
CLAUDE.md
🪛 LanguageTool
CLAUDE.md
[uncategorized] ~741-~741: The official name of this software platform is spelled with a capital “H”.
Context: ... or edit 4. Daily Codebase Review (.github/workflows/daily-codebase-review.yml): ...
(GITHUB)
🪛 markdownlint-cli2 (0.18.1)
CLAUDE.md
402-402: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🔇 Additional comments (7)
CLAUDE.md (7)
32-32: Approve: CI test command documentationThe addition of
pnpm test:ciappropriately documents the CI testing mode and complements the existing testing command documentation.
71-123: Approve: Comprehensive TDD workflow documentationThe new TDD section effectively establishes RED/GREEN/REFACTOR expectations with clear workflow steps, practical examples, and an anti-patterns table. This strengthens the testing culture documented in the project guidelines and aligns with the PR's emphasis on test-driven development.
137-161: Approve: Commit workflow documentationThe new atomic commit workflow with Conventional Commits examples is clear and practical. Using immediate commits for each completed task followed by a single push is sound guidance for multi-task sessions.
163-200: Approve: Pushing guidelines and force-push warningThe pushing guidelines are thorough, including a strong warning against force-pushing to main/develop, proper rebase guidance, and clear decision criteria for when to push. This provides necessary safeguards for collaborative development.
201-262: Approve: Visual verification and API testing guidanceThe expanded visual verification section with Chrome DevTools MCP workflows, comprehensive checklists, and network/API verification guidance provides solid guardrails for catching runtime issues before committing. The practical examples and severity classifications enhance developer confidence.
264-399: Approve: Error handling, performance, and form validation guidanceThe console error severity table, performance testing workflow, and extensive form validation edge cases (email, password, text, date fields) demonstrate thorough QA mindset. The authentication flows section appropriately addresses the app's auth-guarded routes.
1005-1069: Approve: TypeScript, ESLint, and Prettier configuration documentationThe expanded TypeScript configuration section, ESLint setup with clear no-console exceptions, Prettier settings table, and pre-commit hooks documentation provide developers with comprehensive guidance. The branch naming and commit message conventions are well-detailed with practical examples.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 14 changed files in this pull request and generated 3 comments.
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const EnterInviteCodeSheet = forwardRef<EnterInviteCodeSheetRef, EnterInviteCodeSheetProps>( | ||
| ({ theme, onSubmit, onClose }, ref) => { |
There was a problem hiding this comment.
The component documentation states that onClose is optional with @optional, but the parameter is not marked as optional in the actual interface definition (line 70). The documentation and implementation should align - either mark the parameter as onClose?: () => void in the props interface or remove the @optional tag from the JSDoc.
| // Mock document for web platform tests (keyboard event handling) | ||
| global.document = { | ||
| addEventListener: jest.fn(), | ||
| removeEventListener: jest.fn(), | ||
| }; |
There was a problem hiding this comment.
The document mock only includes addEventListener and removeEventListener, but web environments may require additional document properties or methods. Consider using a more complete mock object or using jsdom for web-specific tests to avoid potential issues with code that accesses other document properties.
| onClose={() => { | ||
| // Sheet dismissed without submitting | ||
| }} |
There was a problem hiding this comment.
The onClose callback is an empty function with only a comment. If no action is needed on close, consider either removing this prop (since it's optional) or implementing meaningful cleanup logic. Empty callbacks with only comments suggest incomplete implementation.
| onClose={() => { | |
| // Sheet dismissed without submitting | |
| }} |
Extend the minimal document mock with commonly used properties and methods to prevent errors when code accesses document APIs beyond addEventListener/removeEventListener. Includes mocks for: - DOM queries (getElementById, querySelector, etc.) - Element creation (createElement, createTextNode) - Document properties (body, head, documentElement) - Document state (readyState, visibilityState, hidden)
…eSheet The onClose prop is optional and no cleanup is needed when the sheet is dismissed without submitting, so remove the empty callback.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 14 changed files in this pull request and generated 1 comment.
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // On Android with display="default", the native dialog auto-closes | ||
| // on OK/Cancel press. We must hide the picker component to prevent | ||
| // it from reopening. On iOS, display="default" also shows a dialog. | ||
| // | ||
| // IMPORTANT: Update the date BEFORE hiding the picker to ensure | ||
| // the state update completes before the component unmounts. | ||
| if (date) { | ||
| setSlipUpDate(date); | ||
| } | ||
| setShowDatePicker(false); |
There was a problem hiding this comment.
The comment mentions that the date update order is important to prevent state updates after unmount, but the logic always calls setShowDatePicker(false) regardless of whether date is defined. Consider clarifying that the unconditional call is intentional because the native dialog auto-closes on both OK and Cancel, and the order only matters when date is defined (OK pressed).
…deSheet The mounted state tracking pattern is an anti-pattern in React 18+. React's automatic batching handles cleanup appropriately when components unmount during async operations, making manual mount tracking unnecessary.
Removed misleading reference to unmount timing. The comment now accurately describes that the native dialog auto-closes on OK/Cancel and we always hide the picker to sync React state with the native UI.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 14 changed files in this pull request and generated 7 comments.
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "expo-device": "^8.0.10", | ||
| "expo-font": "~14.0.10", | ||
| "expo-glass-effect": "~0.1.8", | ||
| "expo-haptics": "~15.0.8", | ||
| "expo-image": "~3.0.11", |
There was a problem hiding this comment.
The removal of expo-haptics at line 57 is not documented in the PR description or commit message. If haptics are no longer needed, ensure that all references to expo-haptics in the codebase have been removed to avoid runtime errors.
| // When date is defined (OK pressed), update it before hiding. | ||
| if (date) { | ||
| setSlipUpDate(date); | ||
| } | ||
| setShowDatePicker(false); |
There was a problem hiding this comment.
The order of operations has been reversed from the original code. Previously, setShowDatePicker(false) was called first, then the date was conditionally updated. Now the date is updated before hiding the picker. This change means the picker UI will show the updated date briefly before closing, which could cause a visual flash. The original order was correct for avoiding this flash.
| // When date is defined (OK pressed), update it before hiding. | |
| if (date) { | |
| setSlipUpDate(date); | |
| } | |
| setShowDatePicker(false); | |
| // Hide the picker first to avoid a visual flash, then update the date if needed. | |
| setShowDatePicker(false); | |
| if (date) { | |
| setSlipUpDate(date); | |
| } |
| {/* Android: Use native date picker dialog (has its own OK/Cancel buttons) */} | ||
| {Platform.OS === 'android' && showSobrietyDatePicker && ( | ||
| <DateTimePicker | ||
| value={selectedSobrietyDate} | ||
| mode="date" | ||
| display="default" | ||
| onChange={(event, date) => { | ||
| // Always hide picker on Android since dialog auto-closes | ||
| setShowSobrietyDatePicker(false); | ||
| // Only update if user pressed OK (date is defined) | ||
| if (date) { | ||
| updateSobrietyDate(date); | ||
| } | ||
| }} | ||
| maximumDate={maximumDate} | ||
| /> | ||
| )} |
There was a problem hiding this comment.
The Android date picker logic differs from the iOS implementation in the modal above (lines 819-853). The iOS version uses a separate 'Done' button, while Android updates immediately on selection. This inconsistency may confuse users switching platforms. Consider documenting this platform difference or unifying the behavior.
| it('shows generic error when onSubmit throws non-Error', async () => { | ||
| mockOnSubmit.mockRejectedValueOnce('Something went wrong'); | ||
| renderSheet(); | ||
|
|
||
| const input = screen.getByPlaceholderText('Enter 8-character code'); | ||
| fireEvent.changeText(input, 'ABC12345'); | ||
|
|
||
| fireEvent.press(screen.getByTestId('connect-button')); | ||
|
|
||
| await waitFor(() => { | ||
| expect(screen.getByText('Failed to connect. Please try again.')).toBeTruthy(); | ||
| }); | ||
| }); |
There was a problem hiding this comment.
This test verifies error handling for non-Error rejections, but the actual component code at line 179 uses err instanceof Error ? err.message : 'Failed to connect. Please try again.'. The test should also verify that the isSubmitting state is properly reset after an error, as this affects the UI state.
| }); | ||
| }); | ||
| }); | ||
| // Note: Invite Code Validation and Invalid tests are now covered in EnterInviteCodeSheet.test.tsx |
There was a problem hiding this comment.
Multiple test sections have been removed and replaced with notes pointing to EnterInviteCodeSheet.test.tsx. However, the integration between the profile screen and the sheet (e.g., the joinWithInviteCode callback) is not tested in the new sheet tests. Consider adding integration tests that verify the profile screen properly calls the sheet and handles its callbacks.
| pnpm test # Run all Jest tests | ||
| pnpm test:watch # Run tests in watch mode | ||
| pnpm test -- --coverage # Run tests with coverage report (80% minimum required) | ||
| pnpm test:ci # Run tests with coverage in CI mode (used by GitHub Actions) |
There was a problem hiding this comment.
The pnpm test:ci command is documented here but does not appear in the package.json scripts. This documentation is misleading as the command will not work. Either add the script to package.json or remove this line from the documentation.
| pnpm test:ci # Run tests with coverage in CI mode (used by GitHub Actions) |
Co-authored-by: Copilot <[email protected]> Signed-off-by: Bill Chirico <[email protected]>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 14 changed files in this pull request and generated 2 comments.
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| // Extend global for TypeScript | ||
| declare global { | ||
| var __backHandlerListeners: (() => boolean)[] | undefined; |
There was a problem hiding this comment.
Using var in a TypeScript global declaration is unconventional. While this works for global declarations, consider using const or let for consistency with modern JavaScript practices, or explicitly document why var is required for global scope hoisting.
| var __backHandlerListeners: (() => boolean)[] | undefined; | |
| let __backHandlerListeners: (() => boolean)[] | undefined; |
Clarify why iOS and Android date pickers have different UX: - iOS: Spinner picker needs explicit "Update" button (no clear confirmation point) - Android: Native dialog has OK/Cancel, confirming immediately matches platform conventions This intentional difference follows each platform's design guidelines.
Co-authored-by: Copilot <[email protected]> Signed-off-by: Bill Chirico <[email protected]>
- Add functional mock for EnterInviteCodeSheet that captures onSubmit prop - Add integration tests verifying profile passes joinWithInviteCode to sheet - Add tests for sheet button presentation on Enter Invite Code click - Add tests for joinWithInviteCode success flow with Alert verification - Add tests for all error cases (invalid, expired, used, self-connect, duplicate, profile fetch fail, relationship creation fail) - Add onSubmit callback tests in EnterInviteCodeSheet test suite - Test async onSubmit resolution and rejection handling - Test retry after failure behavior - Test code capitalization before submission
…deSheet Both error handling tests now verify that the submit button becomes enabled again after an error, ensuring proper UI state recovery.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 14 changed files in this pull request and generated 8 comments.
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (1)
package.json:1
- The removal of
expo-hapticspackage should be accompanied by verification that no code references this dependency. Search the codebase for any imports or usage ofexpo-hapticsto ensure this removal is safe.
{
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const sanitized = text.replace(/[^a-zA-Z0-9]/g, '').toUpperCase(); | ||
| setInviteCode(sanitized); | ||
| setError(null); | ||
| }, []); |
There was a problem hiding this comment.
The handleChangeText function has an empty dependency array but calls setInviteCode and setError. While this works because setState functions are stable, it's better practice to include them in the dependency array for clarity and to avoid potential issues if the implementation changes.
| }, []); | |
| }, [setInviteCode, setError]); |
| value={inviteCode} | ||
| onChangeText={handleChangeText} | ||
| placeholder="Enter 8-character code" | ||
| placeholderTextColor={theme.textTertiary} |
There was a problem hiding this comment.
The autoCapitalize="characters" prop is redundant since handleChangeText already forces uppercase via .toUpperCase(). The input sanitization in handleChangeText takes precedence, so this prop has no effect. Consider removing it or documenting that it serves as a hint for mobile keyboards even though the value is enforced programmatically.
| placeholderTextColor={theme.textTertiary} | |
| placeholderTextColor={theme.textTertiary} | |
| // Hint for mobile keyboards to show uppercase, actual value is enforced via handleChangeText |
| // Only add BackHandler listener on Android platform when sheet is open | ||
| if (Platform.OS !== 'android' || !isOpen) return; | ||
|
|
||
| const subscription = BackHandler.addEventListener('hardwareBackPress', () => { | ||
| // Dismiss the sheet and return true to indicate event was handled | ||
| bottomSheetRef.current?.dismiss(); | ||
| return true; | ||
| }); | ||
|
|
||
| return () => subscription.remove(); |
There was a problem hiding this comment.
The early return condition !isOpen means the effect cleanup function is never executed when the sheet closes, since the effect doesn't run when isOpen is false. This is correct behavior, but the cleanup in line 200 (return () => subscription.remove()) will only run when the component unmounts or when dependencies change while isOpen is true. Consider documenting this behavior or restructuring to make the lifecycle clearer.
| // Only add BackHandler listener on Android platform when sheet is open | |
| if (Platform.OS !== 'android' || !isOpen) return; | |
| const subscription = BackHandler.addEventListener('hardwareBackPress', () => { | |
| // Dismiss the sheet and return true to indicate event was handled | |
| bottomSheetRef.current?.dismiss(); | |
| return true; | |
| }); | |
| return () => subscription.remove(); | |
| // Only add BackHandler listener on Android platform | |
| if (Platform.OS !== 'android') return; | |
| let subscription: { remove: () => void } | null = null; | |
| if (isOpen) { | |
| subscription = BackHandler.addEventListener('hardwareBackPress', () => { | |
| // Dismiss the sheet and return true to indicate event was handled | |
| bottomSheetRef.current?.dismiss(); | |
| return true; | |
| }); | |
| } | |
| return () => { | |
| if (subscription) { | |
| subscription.remove(); | |
| } | |
| }; |
| @@ -163,17 +164,15 @@ function SponsorDaysDisplay({ | |||
| * @returns A React element representing the profile screen | |||
| */ | |||
| export default function ProfileScreen() { | |||
There was a problem hiding this comment.
The addition of user destructuring from useAuth() is used throughout the refactored invite code flow. However, there's inconsistency in the codebase: some operations use profile.id while others now use user.id. This is correct per RLS policies (as documented in comments), but it may be confusing. Consider adding a comment at the destructuring site explaining when to use user.id vs profile.id.
| export default function ProfileScreen() { | |
| export default function ProfileScreen() { | |
| // NOTE: Both `user` and `profile` are destructured from useAuth(). | |
| // Use `user.id` for authentication/authorization (RLS policies), and `profile.id` for profile-related data. | |
| // See RLS documentation/comments for details. Be careful to use the correct ID in each context. |
| {/* iOS: Custom modal with spinner picker requires explicit "Update" button | ||
| because the spinner UI allows continuous scrolling without clear confirmation. | ||
| This matches iOS platform conventions for date selection. */} | ||
| {Platform.OS === 'ios' && showSobrietyDatePicker && ( |
There was a problem hiding this comment.
The platform-specific date picker implementations (iOS modal with Update button vs Android native dialog) are well-commented, but they duplicate logic for handling date selection. Consider extracting the date update logic into a shared handler to reduce duplication between lines 838 and 868.
| it('sanitizes input to alphanumeric only', () => { | ||
| renderSheet(); | ||
| const input = screen.getByPlaceholderText('Enter 8-character code'); | ||
|
|
||
| fireEvent.changeText(input, 'ABC-123!@#'); | ||
|
|
||
| expect(input.props.value).toBe('ABC123'); | ||
| }); |
There was a problem hiding this comment.
The test verifies that special characters are stripped, but it doesn't test what happens when the input contains only special characters (e.g., '!!!!'). Consider adding a test case for this edge case to ensure the component handles it gracefully.
| pnpm test # Run all Jest tests | ||
| pnpm test:watch # Run tests in watch mode | ||
| pnpm test -- --coverage # Run tests with coverage report (80% minimum required) | ||
| pnpm test:ci # Run tests with coverage in CI mode (used by GitHub Actions) |
There was a problem hiding this comment.
The new pnpm test:ci command is documented but it's unclear if this command actually exists in package.json. Verify that the command is defined in the scripts section of package.json, or update this documentation if it's a planned addition.
| pnpm test:ci # Run tests with coverage in CI mode (used by GitHub Actions) | |
| pnpm test:ci # (Planned addition) Will run tests with coverage in CI mode (used by GitHub Actions) |
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (3)
components/sheets/LogSlipUpSheet.tsx (2)
298-298: Verify UX on smaller devices with increased sheet height.The snap point increased from 70% to 90%, which significantly expands the sheet's coverage. Ensure this doesn't negatively impact visibility and usability on smaller devices like iPhone SE.
371-377: Verify date picker update order doesn't cause visual flash.The updated logic now sets
slipUpDatebefore hiding the picker, which reverses the previous order. A past review comment (lines 373-377) noted that hiding the picker first avoids a visual flash when the updated date briefly renders before the picker closes.The new comment states the order only matters when
dateis defined, but the visual flash concern may still apply. Please verify this change was intentional and test on physical devices to ensure no UI flickering occurs.app/(tabs)/profile.tsx (1)
366-367: Consider clarifying redundant ID checks.The condition checks both
user.idandprofile.idfor self-sponsorship prevention. Since these should always match (user.id from auth, profile.id from database), consider either:
- Documenting why both checks are needed (if there's an edge case where they differ)
- Simplifying to
user.idonly if they're guaranteed identicalThe current defensive approach is safe but may be unnecessarily cautious.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (5)
__tests__/components/GlassBottomSheet.test.tsx(4 hunks)app/(tabs)/profile.tsx(14 hunks)components/sheets/EnterInviteCodeSheet.tsx(1 hunks)components/sheets/LogSlipUpSheet.tsx(4 hunks)jest.setup.js(2 hunks)
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: All database operations must use typed client fromtypes/database.ts(source of truth)
Use ErrorBoundary component for graceful failure handling
All imports must use@/path alias (configured in tsconfig.json)
File organization order: imports → types → constants → helpers → main logic → exports with required section comments
JSDoc/TSDoc documentation is mandatory for all exported functions and components
Use mount status tracking with useRef to prevent closure issues in async operations
**/*.{ts,tsx}: Runpnpm typecheckto verify TypeScript types before committing
Write tests for any new or modified code, including happy path, edge cases, and error handling
Every exported function, hook, and component MUST have JSDoc/TSDoc comments that work with IntelliSense
Preferinterfacefor defining object shapes in TypeScript
Use strict mode in TypeScript (strict: truein tsconfig); avoidanytype, useunknownwith type guards instead
Use database types fromtypes/database.tsas the source of truth
Use Supabase client with typed database schema (types/database.ts); all data models derive from database types
Use platform-aware storage: SecureStore (native) / localStorage (web)
Session tokens are stored securely (SecureStore on native, localStorage on web)
Tasks flow unidirectionally from sponsor → sponsee within a relationship
Files:
__tests__/components/GlassBottomSheet.test.tsxcomponents/sheets/LogSlipUpSheet.tsxcomponents/sheets/EnterInviteCodeSheet.tsxapp/(tabs)/profile.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx}: NEVER use console.log/error/warn directly - use logger fromlib/logger.ts
All logs are automatically sent to Sentry as breadcrumbs with categorized metadata using LogCategory enum
Logger reserved keys (error_message, error_stack, error_name) must be avoided in metadata
Boolean variables must use is/has/should prefix (isLoading, hasSlipUps)
**/*.{ts,tsx,js,jsx}: Runpnpm lintto check for code quality issues using ESLint before committing
Use camelCase for function and variable names
Use PascalCase for component and type/interface names
Use SCREAMING_SNAKE_CASE for constants
Use 'is', 'has', or 'should' prefix for boolean variables (e.g.,isLoading,hasSlipUps)
Use 'handle' prefix for event handlers (e.g.,handlePress,handleSubmit)
Name async functions with verbs describing the action (e.g.,fetchTasks,updateProfile)
Always use@/path alias for all local imports
Remove unused imports before committing
Always pass Error objects tologger.error()for stack traces and include contextual metadata
Validate and sanitize all user inputs
Use universal logger (lib/logger.ts) for centralized, structured logging with categorization viaLogCategoryenum
Five log levels available:logger.error(),logger.warn(),logger.info(),logger.debug(),logger.trace()
Organize files logically with sections: imports, types, constants, helper functions, component, styles
Files:
__tests__/components/GlassBottomSheet.test.tsxcomponents/sheets/LogSlipUpSheet.tsxcomponents/sheets/EnterInviteCodeSheet.tsxjest.setup.jsapp/(tabs)/profile.tsx
**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.test.{ts,tsx}: UserenderWithProvidersfrom test-utils to wrap components with AuthContext/ThemeContext in tests
Test mocks must include platform detection (defaults to iOS) and timezone handling
Files:
__tests__/components/GlassBottomSheet.test.tsx
**/*.{ts,tsx,js,jsx,json,css}
📄 CodeRabbit inference engine (CLAUDE.md)
Run
pnpm formatto ensure consistent code formatting before committing
Files:
__tests__/components/GlassBottomSheet.test.tsxcomponents/sheets/LogSlipUpSheet.tsxcomponents/sheets/EnterInviteCodeSheet.tsxjest.setup.jsapp/(tabs)/profile.tsx
**/__tests__/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/__tests__/**/*.test.{ts,tsx}: Runpnpm testto verify all tests pass and coverage stays above 80% before committing
Place test files in__tests__/directory mirroring the source structure (e.g.,app/(tabs)/profile.tsx→__tests__/app/profile.test.tsx)
Use Jest with React Native Testing Library for testing; mock Supabase client for database operations
All tests must use descriptive test names and be independent; group related tests withdescribe()blocks
Clean up mocks inbeforeEach()orafterEach()blocks in tests
Test behavior, not implementation details
Wrap test components with AuthContext, ThemeContext; mock Supabase client for database operations
Use MSW (Mock Service Worker) for API mocking in tests
Add regression tests for bug fixes that would have caught the bug
Update tests when modifying existing code; add new tests for new behavior
UserenderWithProvidershelper function to wrap test components with required contexts
Mock navigation with expo-router mocks in tests
Files:
__tests__/components/GlassBottomSheet.test.tsx
!(lib/logger.ts|lib/sentry.ts|jest.setup.js)
📄 CodeRabbit inference engine (CLAUDE.md)
Use ESLint no-console rule; never use console.log/error/warn directly - use the universal logger instead (exceptions: logger.ts, sentry.ts, jest.setup.js)
Files:
__tests__/components/GlassBottomSheet.test.tsxcomponents/sheets/LogSlipUpSheet.tsxcomponents/sheets/EnterInviteCodeSheet.tsxjest.setup.jsapp/(tabs)/profile.tsx
**/components/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/components/**/*.{ts,tsx}: Use functional components with hooks (no class components) in React/React Native
Use StyleSheet.create() for component styles instead of inline style objects
Define Props interfaces inline or export if shared; use StyleSheet.create() for component styles
Files:
__tests__/components/GlassBottomSheet.test.tsxcomponents/sheets/LogSlipUpSheet.tsxcomponents/sheets/EnterInviteCodeSheet.tsx
{lib/logger.ts,lib/sentry.ts,jest.setup.js}
📄 CodeRabbit inference engine (AGENTS.md)
Console.log/error/warn are only permitted in logger.ts, sentry.ts, and jest.setup.js
Files:
jest.setup.js
jest.setup.js
📄 CodeRabbit inference engine (AGENTS.md)
jest.setup.js: Supabase client must be mocked with chainable query builder in jest.setup.js
AsyncStorage and SecureStore must be mocked to prevent actual storage during tests
Files:
jest.setup.js
🧠 Learnings (34)
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to **/*.test.{ts,tsx} : Test mocks must include platform detection (defaults to iOS) and timezone handling
Applied to files:
__tests__/components/GlassBottomSheet.test.tsxjest.setup.js
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Test behavior, not implementation details
Applied to files:
__tests__/components/GlassBottomSheet.test.tsx
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to tests/**/*.{ts,tsx} : Add comprehensive test coverage for components, hooks, utilities, and API routes in tests/ directory
Applied to files:
__tests__/components/GlassBottomSheet.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Update tests when modifying existing code; add new tests for new behavior
Applied to files:
__tests__/components/GlassBottomSheet.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Add regression tests for bug fixes that would have caught the bug
Applied to files:
__tests__/components/GlassBottomSheet.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Clean up mocks in `beforeEach()` or `afterEach()` blocks in tests
Applied to files:
__tests__/components/GlassBottomSheet.test.tsxjest.setup.js
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Wrap test components with AuthContext, ThemeContext; mock Supabase client for database operations
Applied to files:
__tests__/components/GlassBottomSheet.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Mock navigation with expo-router mocks in tests
Applied to files:
__tests__/components/GlassBottomSheet.test.tsxjest.setup.js
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Use Jest with React Native Testing Library for testing; mock Supabase client for database operations
Applied to files:
__tests__/components/GlassBottomSheet.test.tsxjest.setup.js
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Use MSW (Mock Service Worker) for API mocking in tests
Applied to files:
__tests__/components/GlassBottomSheet.test.tsxjest.setup.js
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Run `pnpm test` to verify all tests pass and coverage stays above 80% before committing
Applied to files:
__tests__/components/GlassBottomSheet.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx} : Write tests for any new or modified code, including happy path, edge cases, and error handling
Applied to files:
__tests__/components/GlassBottomSheet.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : All tests must use descriptive test names and be independent; group related tests with `describe()` blocks
Applied to files:
__tests__/components/GlassBottomSheet.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx} : Use strict mode in TypeScript (`strict: true` in tsconfig); avoid `any` type, use `unknown` with type guards instead
Applied to files:
__tests__/components/GlassBottomSheet.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Use `renderWithProviders` helper function to wrap test components with required contexts
Applied to files:
__tests__/components/GlassBottomSheet.test.tsx
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to **/*.test.{ts,tsx} : Use `renderWithProviders` from test-utils to wrap components with AuthContext/ThemeContext in tests
Applied to files:
__tests__/components/GlassBottomSheet.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/components/**/*.{ts,tsx} : Define Props interfaces inline or export if shared; use StyleSheet.create() for component styles
Applied to files:
__tests__/components/GlassBottomSheet.test.tsxcomponents/sheets/LogSlipUpSheet.tsxcomponents/sheets/EnterInviteCodeSheet.tsxapp/(tabs)/profile.tsx
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to jest.setup.ts : Initialize testing-library/jest-dom and mocks in jest.setup.ts for unit test setup
Applied to files:
__tests__/components/GlassBottomSheet.test.tsxjest.setup.js
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to jest.setup.js : AsyncStorage and SecureStore must be mocked to prevent actual storage during tests
Applied to files:
__tests__/components/GlassBottomSheet.test.tsxjest.setup.js
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/components/**/*.{ts,tsx} : Use functional components with hooks (no class components) in React/React Native
Applied to files:
components/sheets/LogSlipUpSheet.tsxcomponents/sheets/EnterInviteCodeSheet.tsxapp/(tabs)/profile.tsx
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to **/*.{ts,tsx} : Use mount status tracking with useRef to prevent closure issues in async operations
Applied to files:
components/sheets/EnterInviteCodeSheet.tsx
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to **/*.{ts,tsx} : JSDoc/TSDoc documentation is mandatory for all exported functions and components
Applied to files:
components/sheets/EnterInviteCodeSheet.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to app/_layout.tsx : Authentication flow in root layout must route users: unauthenticated → /login, authenticated without profile → /onboarding, fully onboarded → /(tabs)
Applied to files:
app/(tabs)/profile.tsx
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Invite codes must connect sponsors to sponsees without requiring email exchange
Applied to files:
app/(tabs)/profile.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: No role field in database `profiles` table; role is contextual based on relationship (sponsor_id vs sponsee_id)
Applied to files:
app/(tabs)/profile.tsx
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to app/_layout.tsx : Root layout (`app/_layout.tsx`) must enforce auth routing: no user → `/login`, user without profile → `/onboarding`, complete profile → `/(tabs)`
Applied to files:
app/(tabs)/profile.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Use Supabase RLS policies for data access control
Applied to files:
app/(tabs)/profile.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Use Context API for global state (AuthContext, ThemeContext) wrapping the entire app in `app/_layout.tsx`; do not use Redux/Zustand
Applied to files:
app/(tabs)/profile.tsx
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to {app/_layout.tsx,**/*context*.{ts,tsx}} : Use Context API only (no Redux/Zustand) - contexts must wrap entire app in root layout
Applied to files:
app/(tabs)/profile.tsx
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to src/components/**/*.{ts,tsx} : Use framer-motion for motion and animation effects in navigation, hero, products, about, mentorship, and blog section components
Applied to files:
app/(tabs)/profile.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/components/**/*.{ts,tsx} : Use StyleSheet.create() for component styles instead of inline style objects
Applied to files:
app/(tabs)/profile.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to app/_layout.tsx : Routing uses Expo Router v6 with typed routes (file-based routing in `app/`) and authentication flow enforced in root layout (`app/_layout.tsx`)
Applied to files:
app/(tabs)/profile.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to contexts/AuthContext.tsx : AuthContext must provide: `user`, `session`, `profile`, `loading`, and auth methods
Applied to files:
app/(tabs)/profile.tsx
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to **/*auth*context*.{ts,tsx} : AuthContext must provide: user, session, profile, loading, auth methods
Applied to files:
app/(tabs)/profile.tsx
🧬 Code graph analysis (3)
__tests__/components/GlassBottomSheet.test.tsx (2)
components/GlassBottomSheet.tsx (1)
GlassBottomSheetRef(48-65)__tests__/test-utils.tsx (1)
renderWithProviders(59-64)
components/sheets/EnterInviteCodeSheet.tsx (2)
contexts/ThemeContext.tsx (1)
ThemeColors(8-36)components/GlassBottomSheet.tsx (1)
GlassBottomSheetRef(48-65)
app/(tabs)/profile.tsx (5)
contexts/AuthContext.tsx (1)
useAuth(50-56)contexts/ThemeContext.tsx (1)
useTheme(112-118)hooks/useTabBarPadding.ts (1)
useTabBarPadding(58-69)components/SettingsSheet.tsx (1)
SettingsSheetRef(75-85)components/sheets/EnterInviteCodeSheet.tsx (1)
EnterInviteCodeSheetRef(29-39)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Build for Web
- GitHub Check: Unit Tests
- GitHub Check: claude-review
- GitHub Check: Cursor Bugbot
🔇 Additional comments (19)
components/sheets/LogSlipUpSheet.tsx (3)
21-21: LGTM! Correct component for bottom sheet context.The switch to
BottomSheetTextInputensures proper keyboard integration with the bottom sheet modal.
300-301: Enhanced keyboard behavior improves UX.The change to
keyboardBehavior="interactive"enables smoother keyboard-driven scrolling, andkeyboardBlurBehavior="restore"ensures the sheet returns to its original position when the keyboard dismisses. These align with the PR's keyboard handling improvements.
388-398: LGTM! Consistent bottom sheet text input usage.The switch to
BottomSheetTextInputfor the notes field maintains consistency with bottom sheet best practices and ensures proper keyboard behavior.__tests__/components/GlassBottomSheet.test.tsx (4)
10-13: Global declaration correctly usesvar.The
varkeyword is appropriate here for TypeScript global augmentation. Unlike regular code wherelet/constare preferred, global declarations requirevarfor proper hoisting and scope. The past comment suggestingletwould not work for this use case.
95-128: Well-structured BackHandler test utilities.The helper functions provide a clean abstraction over the global mock with proper LIFO ordering that matches Android's real BackHandler behavior. The JSDoc documentation clearly explains each function's purpose.
142-143: Proper test cleanup prevents state leakage.Clearing BackHandler listeners in
afterEachfollows testing best practices and prevents state pollution between test cases.Based on learnings, test cleanup in afterEach blocks is a coding guideline requirement.
382-487: Comprehensive Android back button test coverage.This test suite thoroughly covers:
- Listener registration on sheet presentation
- Back button dismissal behavior
- Listener cleanup on dismissal
- Platform-specific behavior (Android vs iOS/web)
The tests properly use
act()for imperative actions and follow React Testing Library best practices by testing behavior rather than implementation details.Based on learnings, tests should be behavior-focused and use descriptive names with proper cleanup.
jest.setup.js (2)
131-154: BackHandler mock enables Android behavior testing.The mock correctly:
- Stores listeners in
global.__backHandlerListenersfor test access- Returns a remover object with
remove()matching React Native's API- Allows tests to simulate hardware back button presses
This integrates seamlessly with the test utilities added to GlassBottomSheet.test.tsx.
164-212: Comprehensive document mock for web compatibility.The manual document mock provides essential DOM APIs (event handling, queries, element creation) for tests without requiring jsdom. The comment correctly explains why jsdom isn't used (Jest's node environment configuration), which addresses the past review concern about conflicting guidance.
components/sheets/EnterInviteCodeSheet.tsx (5)
1-96: Well-structured component with comprehensive documentation.The component follows coding guidelines:
- Proper file organization (imports → types → component)
- JSDoc documentation for all exported interfaces
- Props interface properly defines
onCloseas optional (line 63)Based on learnings, JSDoc/TSDoc documentation is mandatory for all exported functions and components.
102-108: Ref-based submission tracking correctly implements onClose contract.The
didSubmitSuccessfullyRefsuccessfully addresses the past comment about the onClose contract violation. By tracking successful submissions, the component ensuresonCloseis only called when dismissed without submitting, as documented.
150-155: Correct useCallback dependencies for state setters.The empty dependency array is correct. React guarantees that
setInviteCodeandsetErrorhave stable identities and don't need to be included in the dependency array. This is idiomatic React and won't cause stale closures.
157-183: Robust submission handling with proper guards and error handling.The implementation correctly:
- Prevents double submissions with guard check
- Validates input before submission
- Tracks successful submission for proper onClose behavior
- Provides user-friendly error messages
- Resets loading state in finally block
The absence of unmount guards is correct for React 18+, where AbortController or automatic cleanup is preferred over manual isMountedRef patterns.
231-244: Accessible text input with proper test hooks.The input field correctly implements:
testID="invite-code-input"for testing (addresses past review comment)accessibilityLabelfor screen readers- Character validation with auto-capitalization
- No
autoFocus(avoiding accessibility concerns from past comments)app/(tabs)/profile.tsx (5)
14-14: LGTM! Proper integration of new keyboard and sheet components.The additions correctly:
- Import
KeyboardAwareScrollViewfor enhanced keyboard handling- Import
EnterInviteCodeSheetand its ref type- Access
userfromuseAuthfor RLS policy compliance- Declare
inviteCodeSheetReffor imperative sheet controlAll imports use the
@/path alias per coding guidelines.Also applies to: 36-38, 167-167, 174-174
315-447: Well-refactored invite code handler with improved error flow.The refactored function correctly:
- Accepts
inviteCodeas a parameter for sheet-based flow- Throws errors for the sheet to display (lines 443-445)
- Uses
user.idfor RLS policy compliance (lines 382, 401, 404, 419, 422)- Validates invite code thoroughly before creating relationship
The error handling pattern aligns well with the EnterInviteCodeSheet's error display mechanism.
624-634: Enhanced keyboard handling with KeyboardAwareScrollView.The switch to
KeyboardAwareScrollViewfromreact-native-keyboard-controllerprovides:
- Smooth keyboard-aware scrolling
- Proper tap handling with
keyboardShouldPersistTaps="handled"- Integration with the new sheet-based flows
This aligns with the PR's objective to improve keyboard behavior across the app.
857-873: Platform-appropriate date picker patterns with clear documentation.The comments effectively explain the platform differences:
- iOS: Custom modal with spinner requires explicit "Update" button (lines 818-820)
- Android: Native dialog with built-in OK/Cancel provides immediate confirmation (lines 857-859)
This documentation addresses the past review concern about platform inconsistency and follows each platform's conventions.
892-898: Properly conditional sheet rendering prevents unnecessary mounting.The sheet is only rendered when both
profileanduserexist, which:
- Prevents mounting before authentication/profile is loaded
- Matches the pattern used for
LogSlipUpSheet(lines 879-889)- Addresses the past review comment requesting conditional rendering
The
onSubmitcallback correctly wires to the refactoredjoinWithInviteCodefunction.
| throw new Error('You are already connected to this sponsor'); | ||
| } | ||
|
|
||
| // Use user.id for sponsee_id to satisfy RLS policy: sponsee_id = auth.uid() |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Consider consolidating redundant RLS policy comments.
Lines 382 and 401 both explain the same RLS constraint requiring auth.uid(). Consider consolidating these into a single, more detailed comment that could reference the specific RLS policy or migration file, or have the second comment reference the first.
Example for line 401:
- // Use user.id (auth.uid()) instead of profile.id to satisfy RLS policy
- // The WITH CHECK clause requires: used_by = auth.uid()
+ // Use user.id to satisfy RLS policy (see comment on line 382)Also applies to: 401-401
🤖 Prompt for AI Agents
In app/(tabs)/profile.tsx around lines 382 and 401 there are duplicate comments
explaining the same RLS constraint (sponsee_id = auth.uid()); consolidate them
by keeping a single, slightly more detailed comment (e.g., at the first
occurrence) that references the exact RLS policy name or migration file and
remove the redundant second comment or replace it with a short pointer like "see
comment above (line 382)" so the codebase has one authoritative explanation.
- Add handleSobrietyDateConfirm callback to reduce duplication between iOS and Android date pickers - Wrap updateSobrietyDate in useCallback for stable dependency - Both iOS modal buttons and Android native dialog now use the same handler - Handler accepts undefined to cancel, or Date to confirm and update
Add test to verify validateDisplayName correctly rejects input containing only special characters (e.g., '!!!!', '@#$%', '****').
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 15 changed files in this pull request and generated 4 comments.
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (1)
package.json:1
- The package
expo-hapticshas been removed, but there's no mention in the PR description about why this dependency was removed or if haptic feedback functionality was used elsewhere in the codebase. If this package was in use, ensure haptic feedback calls have been removed or replaced.
{
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Mock document for web platform tests (keyboard event handling, DOM access, etc.) | ||
| // This provides a more complete mock to avoid errors when code accesses document properties. | ||
| // Note: Jest is configured to use the 'node' environment (see CLAUDE.md), so jsdom is not available. | ||
| // This manual mock provides basic document functionality for compatibility in tests. |
There was a problem hiding this comment.
The comment states 'Jest is configured to use the node environment (see CLAUDE.md)' but the reason for mocking document in a Node environment is unclear. If this mock is for web platform code paths, consider clarifying which components or code paths require DOM access in tests despite using the Node environment.
| // Mock document for web platform tests (keyboard event handling, DOM access, etc.) | |
| // This provides a more complete mock to avoid errors when code accesses document properties. | |
| // Note: Jest is configured to use the 'node' environment (see CLAUDE.md), so jsdom is not available. | |
| // This manual mock provides basic document functionality for compatibility in tests. | |
| // Mock document for web platform code paths that require DOM access in tests. | |
| // Specifically, this mock is needed for: | |
| // - Keyboard event handling logic in src/platform/web/KeyboardManager.js | |
| // - Web-specific code in src/platform/web/ and tests in __tests__/web/ | |
| // Note: Jest is configured to use the 'node' environment (see CLAUDE.md), so jsdom is not available. | |
| // This manual mock provides basic document functionality for compatibility in these tests. |
| // Dismiss the sheet and return true to indicate event was handled | ||
| bottomSheetRef.current?.dismiss(); | ||
| return true; | ||
| }); | ||
|
|
||
| return () => subscription.remove(); | ||
| }, [isOpen]); |
There was a problem hiding this comment.
The BackHandler listener always returns true, preventing any parent components from handling the back press. Consider if there are scenarios where the sheet should not consume the back press (e.g., if enablePanDownToClose is false, or if there's unsaved form data that needs confirmation).
| // Dismiss the sheet and return true to indicate event was handled | |
| bottomSheetRef.current?.dismiss(); | |
| return true; | |
| }); | |
| return () => subscription.remove(); | |
| }, [isOpen]); | |
| // Only handle back press if sheet is dismissible | |
| if (enablePanDownToClose) { | |
| bottomSheetRef.current?.dismiss(); | |
| return true; | |
| } | |
| // Allow event to propagate if not dismissible | |
| return false; | |
| }); | |
| return () => subscription.remove(); | |
| }, [isOpen, enablePanDownToClose]); |
| <KeyboardAwareScrollView | ||
| ref={scrollViewRef} | ||
| style={[styles.keyboardAvoidingContainer, { backgroundColor: theme.background }]} | ||
| contentContainerStyle={{ | ||
| paddingBottom: scrollPadding, | ||
| flexGrow: 1, | ||
| backgroundColor: theme.background, | ||
| }} | ||
| keyboardShouldPersistTaps="handled" | ||
| showsVerticalScrollIndicator={true} | ||
| > |
There was a problem hiding this comment.
The backgroundColor: theme.background is duplicated in both style and contentContainerStyle. This is likely unnecessary—the background color on style should be sufficient. Consider removing the duplicate to simplify the code.
| it('rejects input containing only special characters', () => { | ||
| expect(validateDisplayName('!!!!')).toBe( | ||
| 'Display name can only contain letters, spaces, periods, and hyphens' | ||
| ); | ||
| expect(validateDisplayName('@#$%')).toBe( | ||
| 'Display name can only contain letters, spaces, periods, and hyphens' | ||
| ); | ||
| expect(validateDisplayName('****')).toBe( | ||
| 'Display name can only contain letters, spaces, periods, and hyphens' | ||
| ); | ||
| }); |
There was a problem hiding this comment.
The test validates that special characters are rejected, but the expected error message mentions 'letters, spaces, periods, and hyphens'. Ensure this matches the actual validation logic in the validateDisplayName function. If the function allows additional characters (like numbers), update the test's expected message accordingly.
| onChange={(event, date) => handleSobrietyDateConfirm(date)} | ||
| maximumDate={maximumDate} | ||
| /> | ||
| )} |
There was a problem hiding this comment.
Bug: Android DateTimePicker may update date on dismiss
The Android DateTimePicker's onChange handler passes the date directly to handleSobrietyDateConfirm on line 882. On Android, when the user presses "Cancel" in the date picker dialog, onChange is still called but date may be the currently selected date (not undefined) depending on the DateTimePicker version. The current logic only checks if (date) which could cause the date to be updated even when the user cancels. This differs from the iOS behavior which only calls updateSobrietyDate when the user explicitly presses the "Update" button.
Summary
EnterInviteCodeSheetcomponent for sponsor invite code entry with proper keyboard handlingkeyboardBehavior,keyboardBlurBehavior) toGlassBottomSheetfor interactive keyboard scrollingLogSlipUpSheetwith same keyboard improvementsChanges
components/sheets/EnterInviteCodeSheet.tsx- Bottom sheet for entering sponsor invite codes with 8-character validation, auto-capitalization, and loading stateskeyboardBehaviorandkeyboardBlurBehaviorprops for configurable keyboard handlingEnterInviteCodeSheetcovering rendering, validation, submission, and dismissalTest plan
Note
Introduces a new EnterInviteCodeSheet and refactors profile to use it, while enhancing GlassBottomSheet keyboard/back behavior and updating related sheets, tests, and docs.
components/sheets/EnterInviteCodeSheet.tsx): New bottom sheet for sponsor codes with 8-char validation, loading, and imperative API.app/(tabs)/profile.tsx): Replaces inline invite input with sheet; updatesjoinWithInviteCode(usesuser.id, throws errors for sheet to display); switches toKeyboardAwareScrollView; refines sobriety date pickers.components/GlassBottomSheet.tsx): AddskeyboardBehavior/keyboardBlurBehavior; Android BackHandler integration; web Escape key handling; unified backdrop.components/sheets/LogSlipUpSheet.tsx): UsesBottomSheetTextInput; adopts new keyboard props; tweaks date picker dismissal.EnterInviteCodeSheet; expandsGlassBottomSheet(incl. Android back button); updatesprofiletests and adds keyboard-avoidance suite; extendsjest.setup.jswith BackHandler and document mocks; augments validation edge-case tests.CLAUDE.md(TDD/CI/testing guidance); addsdocs/plans/2025-12-11-toast-notifications-design.md.react-native-keyboard-controllerto^1.18.5; lockfile updates.Written by Cursor Bugbot for commit f5ad9c1. This will update automatically on new commits. Configure here.
Important
Adds
EnterInviteCodeSheetfor sponsor invite codes, enhancesGlassBottomSheetkeyboard handling, refactorsprofile.tsx, updatesLogSlipUpSheet, and expands tests.EnterInviteCodeSheet.tsx: Bottom sheet for entering sponsor invite codes with 8-character validation, auto-capitalization, and loading states.GlassBottomSheet.tsx: AddskeyboardBehaviorandkeyboardBlurBehaviorprops for improved keyboard handling.profile.tsx: Replaces inline invite code input withEnterInviteCodeSheetfor better keyboard UX on iOS.LogSlipUpSheet.tsx: Adopts new keyboard props and improves date picker handling.EnterInviteCodeSheetcovering rendering, validation, submission, and dismissal.This description was created by
for f5ad9c1. You can customize this summary. It will automatically update as commits are pushed.