-
Notifications
You must be signed in to change notification settings - Fork 24
feat(groups): enhance expense splitting options with detailed methods and UI improvements #49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…een, and TypeScript configuration files
…Settlement screens - Introduced Friends Screens documentation including Friends List, Friend Detail, Add Friend, Friend Search Results. - Added Groups Screens documentation covering Groups List, Group Details, Group Management, Join Group. - Created Main Navigation documentation detailing Home Screen, Notifications Screen, Profile Menu, Activity Detail Screen. - Developed Settlement Screens documentation featuring Settlement Summary, Optimized Settlement, Record Payment, Payment Confirmation, Payment History.
- Created Friends.py page with placeholder for future features. - Developed Groups.py page with functionalities to join, create, and manage groups. - Implemented API request handling with retry logic. - Added debug mode for troubleshooting API interactions. - Included session state management for user authentication and group selection. - Updated requirements.txt to include necessary packages for the project.
… and UI improvements
❌ Deploy Preview for splitwizer failed. Why did it fail? →
|
WalkthroughThis update introduces a comprehensive suite of documentation files specifying the UI/UX, navigation flows, design system, architecture, and screen-level wireframes for the SplitWiser app. Simultaneously, a new Streamlit-based UI proof of concept is added with user authentication, group management, and expense tracking, alongside a detailed OpenAPI schema for the backend. The original React Native frontend codebase and configuration are removed. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant StreamlitUI as Streamlit UI
participant BackendAPI as Backend API
User->>StreamlitUI: Open app
alt Not authenticated
StreamlitUI->>User: Show login/signup form
User->>StreamlitUI: Submit credentials
StreamlitUI->>BackendAPI: POST /auth/login or /auth/signup
BackendAPI-->>StreamlitUI: Return tokens/user info
StreamlitUI->>User: Store session, reload UI
end
alt Authenticated
StreamlitUI->>User: Show Groups tab
User->>StreamlitUI: Create/join/select group
StreamlitUI->>BackendAPI: GET/POST group endpoints
BackendAPI-->>StreamlitUI: Group data
User->>StreamlitUI: Add expense
StreamlitUI->>BackendAPI: POST /groups/{id}/expenses
BackendAPI-->>StreamlitUI: Expense data
StreamlitUI->>User: Update group/expense list
end
User->>StreamlitUI: Logout
StreamlitUI->>User: Clear session, reload UI
Estimated code review effort🎯 4 (Complex) | ⏱️ ~90 minutes Suggested labels
Suggested reviewers
Poem
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. ✨ Finishing Touches
🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #49 +/- ##
=======================================
Coverage 85.96% 85.96%
=======================================
Files 28 28
Lines 3306 3306
Branches 189 189
=======================================
Hits 2842 2842
Misses 464 464
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
|
@codecovai test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 11
🧹 Nitpick comments (21)
ui-poc/README.md (1)
18-19: Add language specification to code blocks for better rendering.The code blocks should specify the shell language for proper syntax highlighting and better documentation rendering.
- ``` - pip install -r requirements.txt - ``` + ```bash + pip install -r requirements.txt + ``` - ``` - streamlit run Home.py - ``` + ```bash + streamlit run Home.py + ```Also applies to: 23-24
ui-poc/pages/Friends.py (1)
2-2: Remove unused import.The
requestsmodule is imported but not used in this placeholder page.-import requestsdocs/frontend-user-flow.md (1)
5-15: Trim the code-fence to three back-ticks to comply with MD040The PlantUML block is already annotated with
plantuml, but markdownlint still flags it because the opening fence is four back-ticks instead of three. Dropping one back-tick silences the warning without affecting rendering.-```` +```plantuml @startuml ... @enduml -```` +```docs/screens/auth-screens.md (1)
5-34: Add a language identifier (text) to ASCII-art fencesmarkdownlint MD040 complains about code blocks without a language tag.
Annotate the block as plain text:-``` +```text ┌─────────────────────────────┐ │ │ ... └─────────────────────────────┘ -``` +```Apply the same change to every ASCII sketch in this document to eliminate linter noise.
docs/screens/expense-creation.md (1)
5-42: Tag the wireframe fence withtextAll monocle-box wireframes trigger MD040 for missing language. Prefix the opening fence with
text:-``` +```text ┌─────────────────────────────┐ ... └─────────────────────────────┘ -``` +```Replicate for the other four wireframe blocks (lines 91-127, 167-204, 245-279, 324-359).
docs/screens/friends-screens.md (1)
6-40: Mark ASCII diagrams astextto satisfy markdownlintSame MD040 issue here. Prefix the fence:
-``` +```text ┌─────────────────────────────┐ │ SplitWiser [🔔] [👤] │ ... └─────────────────────────────┘ -``` +```Please update the remaining three diagrams (lines 84-123, 176-214, 263-300) as well.
ui-poc/pages/Groups.py (4)
52-52: Remove unnecessary f-string prefixes.These strings don't contain any placeholders, so the f-prefix is not needed.
- st.error(f"API Connection: Offline") + st.error("API Connection: Offline")- st.error(f"Unexpected response format: 'groups' key not found in response") + st.error("Unexpected response format: 'groups' key not found in response")- st.error(f"Unexpected response format: 'expenses' key not found in response") + st.error("Unexpected response format: 'expenses' key not found in response")Also applies to: 92-92, 171-171
349-395: Consider extracting member selection logic to reduce complexity.The member selection logic with checkboxes is quite complex and could be extracted into a helper function for better maintainability.
Would you like me to help refactor this into a reusable component that handles member selection with select/deselect all functionality?
197-221: Simplify nested context managers.You can combine multiple context managers into a single
withstatement for cleaner code.-with st.expander("Join a Group", expanded=False): - with st.form("join_group_form_page", clear_on_submit=True): +with st.expander("Join a Group", expanded=False), \ + st.form("join_group_form_page", clear_on_submit=True):Also applies to: 298-299
631-646: Consider extracting expense data construction logic.The expense data construction logic is complex and could be extracted into a separate function for better testability and maintainability.
def create_expense_data(description, amount, splits, split_type, payer_id, tags=None): """Create expense data dictionary with validation.""" return { "description": description, "amount": amount, "splits": splits, "splitType": split_type, "paidBy": payer_id, "tags": tags or [] }docs/screens/groups-screens.md (2)
6-6: Add language specifiers to fenced code blocks.Fenced code blocks should specify a language for better syntax highlighting. Since these are ASCII wireframes, use
textas the language identifier.-``` +```textAlso applies to: 69-69, 154-154, 231-231
53-53: Add missing comma in list.There's a missing comma between "member count" and "last activity".
-- **Group Cards**: Simple elevated cards with group name, member count, last activity +- **Group Cards**: Simple elevated cards with group name, member count, and last activitydocs/screens/main-navigation.md (2)
6-6: Add language specifiers to fenced code blocks.Use
textas the language identifier for ASCII wireframes.-``` +```textAlso applies to: 98-98, 149-149, 200-200
191-191: Add missing comma in list.Missing comma in the list of profile attributes.
-- **Edit Profile**: Change name, email, profile picture +- **Edit Profile**: Change name, email, and profile pictureui-poc/Home.py (1)
91-107: Simplify nested context managers.Multiple nested
withstatements can be combined for cleaner code.For example:
-with login_tab: - with st.form("login_form", clear_on_submit=False): +with login_tab, st.form("login_form", clear_on_submit=False):Also applies to: 109-128, 142-162, 164-187, 250-303
docs/screens/settlement-screens.md (2)
6-6: Add language specifiers to fenced code blocks.Use
textas the language identifier for ASCII wireframes.-``` +```textAlso applies to: 96-96, 183-183, 268-268, 352-352
436-437: Add missing period at end of sentence.The last sentence is missing a period.
-- Access dispute resolution for incorrect payments +- Access dispute resolution for incorrect payments.docs/design-system.md (2)
82-94: Incomplete dark-mode palette may cause downstream theme gaps
darkColorsstops after thesecondarypalette and jumps straight toneutral, leaving outtertiary,error,success,shadow, andscrim. Consumers following this spec will have to guess those values or fall back to light-mode tokens, defeating the purpose of a deterministic design system.Consider completing the snippet or adding a note such as:
... secondaryContainer: '#4A4458', onSecondaryContainer: '#E8DEF8', }, - // ... additional dark mode colors + tertiary: { /* … */ }, + error: { /* … */ }, + success: { /* … */ }, + shadow: '#000000', + scrim: '#000000',
590-596: Typography overrides missing from the dark-theme sampleThe light-theme example merges
...typography, but the dark-theme snippet omits this, which implies typography reverts to the Paper default when switching schemes. If that’s unintentional, mirror the merge logic to avoid style drift.const darkTheme = { ...MD3DarkTheme, colors: { ...MD3DarkTheme.colors, ...darkColors, // Custom dark colors }, + fonts: { + ...MD3DarkTheme.fonts, + ...typography, + }, };docs/folder-structure.md (2)
8-336: Add language identifier to large tree diagram code block
markdownlintflags MD040 because the fenced block lacks a language tag.
Usingtext(orbash) improves syntax highlighting and avoids lint noise.-``` +/```text /app ├── navigation/ # Central navigation config (React Navigation) ... └── .env # Environment variables
371-402: Second fenced block also missing language specificationSame MD040 issue for the navigation-structure diagram.
-``` +/```text App ├── AuthNavigator (Stack) ... └── SettleUpScreen</blockquote></details> </blockquote></details> <details> <summary>📜 Review details</summary> **Configuration used: CodeRabbit UI** **Review profile: CHILL** **Plan: Pro** <details> <summary>📥 Commits</summary> Reviewing files that changed from the base of the PR and between f652ef384b51d7bdcce6dc654c95d2cd35ec80b1 and 40d72db54f51e6a989da830a1cdc158f7ba6cb69. </details> <details> <summary>⛔ Files ignored due to path filters (2)</summary> * `docs/Group-Screen-Flow.png` is excluded by `!**/*.png` * `frontend/package-lock.json` is excluded by `!**/package-lock.json` </details> <details> <summary>📒 Files selected for processing (24)</summary> * `docs/design-system.md` (1 hunks) * `docs/folder-structure.md` (1 hunks) * `docs/frontend-ui-design.md` (1 hunks) * `docs/frontend-user-flow.md` (1 hunks) * `docs/screens/auth-screens.md` (1 hunks) * `docs/screens/expense-creation.md` (1 hunks) * `docs/screens/friends-screens.md` (1 hunks) * `docs/screens/groups-screens.md` (1 hunks) * `docs/screens/main-navigation.md` (1 hunks) * `docs/screens/settlement-screens.md` (1 hunks) * `frontend/App.tsx` (0 hunks) * `frontend/README.md` (0 hunks) * `frontend/app.json` (0 hunks) * `frontend/contexts/AuthContext.tsx` (0 hunks) * `frontend/package.json` (0 hunks) * `frontend/screens/HomeScreen.tsx` (0 hunks) * `frontend/screens/LoginScreen.tsx` (0 hunks) * `frontend/tsconfig.json` (0 hunks) * `ui-poc/Home.py` (1 hunks) * `ui-poc/README.md` (1 hunks) * `ui-poc/openapi.json` (1 hunks) * `ui-poc/pages/Friends.py` (1 hunks) * `ui-poc/pages/Groups.py` (1 hunks) * `ui-poc/requirements.txt` (1 hunks) </details> <details> <summary>💤 Files with no reviewable changes (8)</summary> * frontend/tsconfig.json * frontend/README.md * frontend/app.json * frontend/App.tsx * frontend/package.json * frontend/screens/HomeScreen.tsx * frontend/screens/LoginScreen.tsx * frontend/contexts/AuthContext.tsx </details> <details> <summary>🧰 Additional context used</summary> <details> <summary>🪛 LanguageTool</summary> <details> <summary>ui-poc/README.md</summary> [grammar] ~1-~1: Use correct spacing Context: # Splitwiser UI POC This is a proof of concept UI for the S... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~3-~3: Use hyphens correctly Context: # Splitwiser UI POC This is a proof of concept UI for the Splitwiser applica... (QB_NEW_EN_OTHER_ERROR_IDS_29) --- [grammar] ~3-~3: There might be a problem here. Context: ...tication, group management, and expense tracking. ## Features - Login and Registration - Group Manageme... (QB_NEW_EN_MERGED_MATCH) --- [grammar] ~9-~9: There might be a mistake here. Context: ...tion - Group Management: - Create new groups - Join existing groups - View group... (QB_NEW_EN_OTHER) --- [grammar] ~10-~10: There might be a mistake here. Context: ... - Create new groups - Join existing groups - View group details - Add expenses... (QB_NEW_EN_OTHER) --- [grammar] ~11-~11: There might be a mistake here. Context: ... - Join existing groups - View group details - Add expenses to groups - Friends Ma... (QB_NEW_EN_OTHER) --- [grammar] ~12-~12: There might be a mistake here. Context: ... View group details - Add expenses to groups - Friends Management (Coming Soon) ## ... (QB_NEW_EN_OTHER) --- [grammar] ~13-~13: Use correct spacing Context: ... to groups - Friends Management (Coming Soon) ## Setup and Installation 1. Install the ... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~15-~15: Use correct spacing Context: ... Management (Coming Soon) ## Setup and Installation 1. Install the required dependencies: `... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~17-~17: Use correct spacing Context: ...d Installation 1. Install the required dependencies: ``` pip install -r requirements.txt ``` 2. Run the application: ``` streamli... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~22-~22: Use correct spacing Context: ... -r requirements.txt ``` 2. Run the application: ``` streamlit run Home.py ``` ## API Connection This UI connects to the... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~27-~27: Use correct spacing Context: ... streamlit run Home.py ``` ## API Connection This UI connects to the Splitwiser back... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~29-~29: There might be a mistake here. Context: ... to the Splitwiser backend API deployed at: `https://splitwiser-production.up.railway.app/` ## Session State Management The applicati... (QB_NEW_EN_OTHER) --- [grammar] ~32-~32: Use correct spacing Context: ...tion.up.railway.app/` ## Session State Management The application uses Streamlit's sessio... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~34-~34: Use correct spacing Context: ...rent views. Key session state variables include: - `access_token`: User's authentication token - `user_i... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~40-~40: There might be a problem here. Context: ...the currently selected group for detail view ## Structure - `Home.py`: Main application file with login/sign... (QB_NEW_EN_MERGED_MATCH) </details> <details> <summary>docs/frontend-user-flow.md</summary> [grammar] ~1-~1: Use correct spacing Context: # SplitWiser: User Flow & Navigation ## App User Flow Diagram ```plantuml @sta... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~3-~3: Use correct spacing Context: ...ser Flow & Navigation ## App User Flow Diagram ```plantuml @startuml skinparam backgroundColor white skinparam DefaultFontName "Roboto" skinparam DefaultFontSize 12 skinparam ArrowColor #6200EE skinparam ActivityBorderColor #6200EE skinparam ActivityBackgroundColor #E8DEF8 skinparam ActivityDiamondBackgroundColor #E8DEF8 skinparam ActivityDiamondBorderColor #6200EE title SplitWiser App User Flow (*) --> "Login Screen" "Login Screen" --> "Authenticate" : Login/Google Sign In "Authenticate" --> "Main Navigation" "Main Navigation" -right-> "Home Tab" "Main Navigation" -down-> "Groups Tab" "Main Navigation" -left-> "Friends Tab" "Home Tab" --> "Recent Activity Feed" "Home Tab" --> "Overall Balance" "Home Tab" --> "Analytics Charts" "Home Tab" -right-> "Notification Center" : Tap Notification Icon "Groups Tab" --> "Group List" "Group List" --> "Create Group" : + Button "Group List" --> "Join Group" : Join Button "Group List" --> "Group Detail" : Tap Group "Group Detail" --> "Group Header" : Group name & members "Group Detail" --> "Settlement Summary" : Balances owed/to receive "Group Detail" --> "Expense Feed" : Chronological list "Group Detail" --> "Add Expense" : FAB "Add Expense" --> "Basic Info Screen" : Step 1 "Basic Info Screen" --> "Payment Selection" : Step 2 "Payment Selection" --> "Split Options Screen" : Step 3 "Split Options Screen" --> "Equal Split" : Toggle option "Split Options Screen" --> "Unequal Split" : Toggle option "Equal Split" --> "Member Selection" "Unequal Split" --> "Split Method Selection" "Split Method Selection" --> "By Shares" "Split Method Selection" --> "By Percentages" "Split Method Selection" --> "By Exact Values" "Member Selection" --> "Save Expense" "By Shares" --> "Save Expense" "By Percentages" --> "Save Expense" "By Exact Values" --> "Save Expense" "Save Expense" --> "Group Detail" "Friends Tab" --> "Friend List" "Friend List" --> "Friend Detail" : Tap Friend "Friend Detail" --> "Settle Up" : Settlement flow "Settle Up" --> "Payment Method" "Payment Method" --> "Record Payment" "Record Payment" --> "Friend Detail" "Group Detail" --> "Expense Detail" : Tap Expense "Expense Detail" --> "Edit Expense" : Edit (creator only) "Expense Detail" --> "Delete Expense" : Delete (creator only) @enduml ``` ## Detailed User Journeys ### 1. Authenti... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~74-~74: Use correct spacing Context: ...or only) @enduml ``` ## Detailed User Journeys ### 1. Authentication Journey #### New Use... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~76-~76: Use correct spacing Context: ...ed User Journeys ### 1. Authentication Journey #### New User Registration 1. **Landing** → ... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~79-~79: There might be a mistake here. Context: ...anding** → User opens app for the first time 2. **Welcome Screen** → Brief app intro... (QB_NEW_EN_OTHER) --- [grammar] ~80-~80: There might be a mistake here. Context: ... → Brief app introduction with continue button 3. **Sign Up** → Email, password, confi... (QB_NEW_EN_OTHER) --- [grammar] ~81-~81: Insert the missing word Context: ...continue button 3. **Sign Up** → Email, password, confirm password fields 4. **Email Veri... (QB_NEW_EN_OTHER_ERROR_IDS_32) --- [grammar] ~81-~81: There might be a mistake here. Context: ...p** → Email, password, confirm password fields 4. **Email Verification** → Verify emai... (QB_NEW_EN_OTHER) --- [grammar] ~82-~82: There might be a mistake here. Context: ...rification** → Verify email address (if required) 5. **Onboarding** → 3-4 screens explain... (QB_NEW_EN_OTHER) --- [grammar] ~83-~83: There might be a mistake here. Context: ...boarding** → 3-4 screens explaining key features 6. **Profile Setup** → Name, profile pi... (QB_NEW_EN_OTHER) --- [grammar] ~84-~84: Insert the missing word Context: ...es 6. **Profile Setup** → Name, profile picture, currency preference 7. **Main App** → R... (QB_NEW_EN_OTHER_ERROR_IDS_32) --- [grammar] ~84-~84: There might be a mistake here. Context: ...tup** → Name, profile picture, currency preference 7. **Main App** → Redirect to home scre... (QB_NEW_EN_OTHER) --- [grammar] ~85-~85: There might be a mistake here. Context: ...ence 7. **Main App** → Redirect to home screen #### Existing User Login 1. **Login Screen**... (QB_NEW_EN_OTHER) --- [grammar] ~90-~90: Use correct spacing Context: ...p** → Direct to home screen with recent activity #### Password Recovery 1. **Login Screen** →... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~97-~97: Use correct spacing Context: ...5. **Login** → Return to login with new credentials ### 2. Group Management Journey #### Creat... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~99-~99: Use correct spacing Context: ...ew credentials ### 2. Group Management Journey #### Creating a Group 1. **Groups List** → T... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~102-~102: There might be a mistake here. Context: ...up 1. **Groups List** → Tap "Create new group" 2. **Group Details** → Name, descripti... (QB_NEW_EN_OTHER) --- [grammar] ~104-~104: There might be a mistake here. Context: ... 3. **Add Members** → Search and invite friends/contacts 4. **Invitation Method** → Email, phone... (QB_NEW_EN_OTHER) --- [grammar] ~106-~106: There might be a mistake here. Context: ...reated** → Navigate to new group detail screen 6. **First Expense** → Optional prompt ... (QB_NEW_EN_OTHER) --- [grammar] ~107-~107: Use correct spacing Context: ...xpense** → Optional prompt to add first expense #### Joining a Group 1. **Groups List** → Ta... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~110-~110: Use articles correctly Context: ...## Joining a Group 1. **Groups List** → Tap "Join Group" button 2. **Join Method** ... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~110-~110: There might be a mistake here. Context: ...p 1. **Groups List** → Tap "Join Group" button 2. **Join Method** → Choose from QR sca... (QB_NEW_EN_OTHER) --- [grammar] ~111-~111: There might be a mistake here. Context: ... → Choose from QR scan, invite code, or link 3. **Group Preview** → Show group detai... (QB_NEW_EN_OTHER) --- [grammar] ~112-~112: There might be a mistake here. Context: ...p Preview** → Show group details before joining 4. **Confirm Join** → Accept invitation... (QB_NEW_EN_OTHER) --- [grammar] ~113-~113: There might be a mistake here. Context: ...re joining 4. **Confirm Join** → Accept invitation 5. **Group Detail** → Navigate to joine... (QB_NEW_EN_OTHER) --- [grammar] ~114-~114: There might be a mistake here. Context: .... **Group Detail** → Navigate to joined group #### Group Settings 1. **Group Detail** → Ta... (QB_NEW_EN_OTHER) --- [grammar] ~117-~117: There might be a mistake here. Context: ...ings 1. **Group Detail** → Tap settings icon 2. **Group Settings** → Edit name, desc... (QB_NEW_EN_OTHER) --- [grammar] ~118-~118: There might be a mistake here. Context: ...up Settings** → Edit name, description, image 3. **Manage Members** → Add/remove memb... (QB_NEW_EN_OTHER) --- [grammar] ~119-~119: There might be a mistake here. Context: ... Members** → Add/remove members, change permissions 4. **Leave Group** → Option to leave (w... (QB_NEW_EN_OTHER) --- [grammar] ~120-~120: There might be a mistake here. Context: ...**Leave Group** → Option to leave (with confirmation) 5. **Archive Group** → Archive complete... (QB_NEW_EN_OTHER) --- [grammar] ~121-~121: There might be a mistake here. Context: .... **Archive Group** → Archive completed groups ### 3. Expense Creation Journey #### Compl... (QB_NEW_EN_OTHER) --- [grammar] ~123-~123: Use correct spacing Context: ...mpleted groups ### 3. Expense Creation Journey #### Complete Expense Flow 1. **Group Detail... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~128-~128: There might be a mistake here. Context: ... Info** - Enter amount with currency formatting - Add description (required) - Se... (QB_NEW_EN_OTHER) --- [grammar] ~129-~129: There might be a mistake here. Context: ...urrency formatting - Add description (required) - Select category from dropdown -... (QB_NEW_EN_OTHER) --- [grammar] ~130-~130: There might be a mistake here. Context: ...on (required) - Select category from dropdown - Optional: Capture receipt photo ... (QB_NEW_EN_OTHER) --- [grammar] ~131-~131: There might be a mistake here. Context: ...dropdown - Optional: Capture receipt photo - Tap "Next" 3. **Step 2: Payment S... (QB_NEW_EN_OTHER) --- [grammar] ~132-~132: There might be a problem here. Context: ...ptional: Capture receipt photo - Tap "Next" 3. **Step 2: Payment Selection** - Choose... (QB_NEW_EN_MERGED_MATCH) --- [grammar] ~140-~140: There might be a problem here. Context: ...e total matches expense amount - Tap "Next" 4. **Step 3: Split Options** - **Equal Sp... (QB_NEW_EN_MERGED_MATCH) --- [grammar] ~144-~144: There might be a mistake here. Context: ...**: - Select members to include in split - Real-time calculation of per-per... (QB_NEW_EN_OTHER) --- [grammar] ~145-~145: There might be a mistake here. Context: ... - Real-time calculation of per-person amount - **Unequal Split**: - Choose m... (QB_NEW_EN_OTHER) --- [grammar] ~147-~147: There might be a mistake here. Context: ...e method: Shares, Percentages, or Exact Amounts - Enter values for each person ... (QB_NEW_EN_OTHER) --- [grammar] ~148-~148: There might be a mistake here. Context: ...ct Amounts - Enter values for each person - Real-time validation and calcula... (QB_NEW_EN_OTHER) --- [grammar] ~149-~149: There might be a mistake here. Context: ... person - Real-time validation and calculation - Tap "Save" 5. **Confirmation** → ... (QB_NEW_EN_OTHER) --- [grammar] ~150-~150: There might be a problem here. Context: ...ime validation and calculation - Tap "Save" 5. **Confirmation** → Brief success message ... (QB_NEW_EN_MERGED_MATCH) --- [grammar] ~153-~153: Use correct spacing Context: ...Group** → Updated expense feed with new entry ### 4. Settlement Journey #### Viewing Set... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~155-~155: Use correct spacing Context: ... feed with new entry ### 4. Settlement Journey #### Viewing Settlement Summary 1. **Group D... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~162-~162: Use correct spacing Context: ...s exist) - Balance amount with color coding #### Optimized Settlement Flow 1. **Group De... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~165-~165: There might be a mistake here. Context: ... Flow 1. **Group Detail** → Tap "Settle Up" 2. **Optimized View** → Algorithm show... (QB_NEW_EN_OTHER) --- [grammar] ~166-~166: There might be a mistake here. Context: ... → Algorithm shows minimum transactions needed 3. **Settlement List** → Each required ... (QB_NEW_EN_OTHER) --- [grammar] ~167-~167: There might be a mistake here. Context: ...st** → Each required payment with clear direction 4. **Record Payments** → Bulk action to... (QB_NEW_EN_OTHER) --- [grammar] ~168-~168: There might be a mistake here. Context: ... Payments** → Bulk action to record all payments 5. **Individual Recording** → Option to... (QB_NEW_EN_OTHER) --- [grammar] ~169-~169: There might be a mistake here. Context: ...Recording** → Option to record payments separately #### Individual Settlement 1. **Friend Detai... (QB_NEW_EN_OTHER) --- [grammar] ~172-~172: There might be a mistake here. Context: ...ment 1. **Friend Detail** → Tap "Settle Up" 2. **Payment Amount** → Pre-filled wi... (QB_NEW_EN_OTHER) --- [grammar] ~177-~177: Use correct spacing Context: ... Payment** → Update balances across all groups ### 5. Friends Management Journey #### Add... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~179-~179: Use correct spacing Context: ...s all groups ### 5. Friends Management Journey #### Adding Friends 1. **Friends List** → Ta... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~182-~182: There might be a mistake here. Context: ... Friends 1. **Friends List** → Tap "Add friend" 2. **Search Methods**: - Search by ... (QB_NEW_EN_OTHER) --- [grammar] ~184-~184: There might be a mistake here. Context: ..." 2. **Search Methods**: - Search by email/phone - Import from contacts - QR code ... (QB_NEW_EN_OTHER) --- [grammar] ~185-~185: There might be a mistake here. Context: ... Search by email/phone - Import from contacts - QR code scan - Share invite lin... (QB_NEW_EN_OTHER) --- [grammar] ~186-~186: There might be a mistake here. Context: ... - Import from contacts - QR code scan - Share invite link 3. **Send Invita... (QB_NEW_EN_OTHER) --- [grammar] ~187-~187: There might be a mistake here. Context: ...cts - QR code scan - Share invite link 3. **Send Invitation** → Friend receive... (QB_NEW_EN_OTHER) --- [grammar] ~188-~188: There might be a mistake here. Context: .... **Send Invitation** → Friend receives notification 4. **Acceptance** → Friend appears in f... (QB_NEW_EN_OTHER) --- [grammar] ~189-~189: There might be a mistake here. Context: ...cceptance** → Friend appears in friends list #### Friend Interaction 1. **Friends List** ... (QB_NEW_EN_OTHER) --- [grammar] ~192-~192: There might be a mistake here. Context: ... List** → View all friends with balance indicators 2. **Friend Detail** → Tap on specific ... (QB_NEW_EN_OTHER) --- [grammar] ~193-~193: There might be a problem here. Context: ...ndicators 2. **Friend Detail** → Tap on specific friend 3. **Shared History** → View shared gro... (QB_NEW_EN_MERGED_MATCH) --- [grammar] ~194-~194: There might be a mistake here. Context: ...ared History** → View shared groups and transactions 4. **Direct Settlement** → Settle balan... (QB_NEW_EN_OTHER) --- [grammar] ~195-~195: There might be a mistake here. Context: ...ttlement** → Settle balances across all groups 5. **Transaction Filter** → Filter by g... (QB_NEW_EN_OTHER) --- [grammar] ~196-~196: There might be a mistake here. Context: ...tion Filter** → Filter by group or date range ### 6. Home Dashboard Journey #### Daily U... (QB_NEW_EN_OTHER) --- [grammar] ~198-~198: Use correct spacing Context: ...up or date range ### 6. Home Dashboard Journey #### Daily Usage 1. **App Launch** → Home sc... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~206-~206: Use correct spacing Context: ...s notifications - Navigate to active groups #### Analytics Review 1. **Home Screen** → S... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~209-~209: There might be a mistake here. Context: .... **Home Screen** → Scroll to analytics section 2. **Monthly Summary** → Spending break... (QB_NEW_EN_OTHER) --- [grammar] ~210-~210: There might be a mistake here. Context: ...nthly Summary** → Spending breakdown by category 3. **Trend Analysis** → Compare spendin... (QB_NEW_EN_OTHER) --- [grammar] ~211-~211: There might be a mistake here. Context: ...alysis** → Compare spending across time periods 4. **Group Insights** → Most active gro... (QB_NEW_EN_OTHER) --- [grammar] ~212-~212: There might be a mistake here. Context: ...hts** → Most active groups and frequent expenses ## Navigation Patterns ### Bottom Tab Nav... (QB_NEW_EN_OTHER) --- [grammar] ~214-~214: Use correct spacing Context: ...ps and frequent expenses ## Navigation Patterns ### Bottom Tab Navigation - **Home**: Dashb... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~219-~219: Use correct spacing Context: ...s**: Friends list, individual balances, settlements ### Modal Presentations - **Expense Creatio... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~225-~225: Use correct spacing Context: ...le Actions**: Modal for profile-related actions ### Stack Navigation - Each tab maintains i... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~228-~228: There might be a mistake here. Context: ...- Each tab maintains its own navigation stack - Deep linking support for shared expen... (QB_NEW_EN_OTHER) --- [grammar] ~229-~229: There might be a mistake here. Context: ...g support for shared expenses and group invites - Proper back navigation with state pre... (QB_NEW_EN_OTHER) --- [grammar] ~230-~230: There might be a mistake here. Context: ...tes - Proper back navigation with state preservation ## Error Handling & Edge Cases ### Networ... (QB_NEW_EN_OTHER) --- [grammar] ~232-~232: Use correct spacing Context: ... preservation ## Error Handling & Edge Cases ### Network Issues - Offline mode with loca... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~237-~237: Use correct spacing Context: ...ion restored - Clear indication of sync status ### Form Validation - Real-time validation ... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~242-~242: Use correct spacing Context: ... error messages - Prevention of invalid submissions ### Permission Handling - Camera access for... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~247-~247: Use correct spacing Context: ...itations - Notification permissions for updates ### Conflict Resolution - Handle concurrent... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~250-~250: There might be a mistake here. Context: ...Resolution - Handle concurrent edits to expenses - Clear indication of outdated data - A... (QB_NEW_EN_OTHER) --- [grammar] ~251-~251: There might be a mistake here. Context: ...expenses - Clear indication of outdated data - Automatic refresh when conflicts dete... (QB_NEW_EN_OTHER) --- [grammar] ~252-~252: There might be a mistake here. Context: ...data - Automatic refresh when conflicts detected ## Accessibility Considerations ### Scree... (QB_NEW_EN_OTHER) --- [grammar] ~254-~254: Use correct spacing Context: ...en conflicts detected ## Accessibility Considerations ### Screen Reader Support - Semantic labels... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~259-~259: Use correct spacing Context: ...hierarchy - Descriptive button and link text ### Visual Accessibility - High contrast mo... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~264-~264: Use hyphens correctly Context: ...pport - Large text size compatibility - Color-blind friendly design ### Motor Accessibility... (QB_NEW_EN_OTHER_ERROR_IDS_29) --- [grammar] ~264-~264: Use correct spacing Context: ...ze compatibility - Color-blind friendly design ### Motor Accessibility - Minimum touch tar... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~269-~269: Use correct spacing Context: ...ternative input methods - Voice control compatibility This user flow ensures a smooth, intuit... (QB_NEW_EN_OTHER_ERROR_IDS_5) </details> <details> <summary>docs/frontend-ui-design.md</summary> [grammar] ~1-~1: Use correct spacing Context: # SplitWiser: Mobile App Frontend UI Design ## Overview SplitWiser is a React Native +... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~4-~4: Use correct spacing Context: ...ptimization with minimal user interface complexity. ## Technology Stack - **Framework**: React... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~11-~11: Use correct spacing Context: ...v6 - **Design System**: Material Design 3 ## Documentation Structure This frontend d... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~14-~14: Use correct spacing Context: ...ed across multiple documents for better maintainability: - **[User Flow & Navigation](./frontend-user... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~26-~26: Use correct spacing Context: ...e + Expo project organization ## Quick Reference ### Key UX Principles 1. **Progressive Disc... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~29-~29: There might be a mistake here. Context: ... Show only relevant information at each step 2. **Smart Defaults**: Pre-fill common ... (QB_NEW_EN_OTHER) --- [grammar] ~30-~30: There might be a mistake here. Context: ... Defaults**: Pre-fill common values and selections 3. **Real-time Feedback**: Show calcula... (QB_NEW_EN_OTHER) --- [grammar] ~31-~31: There might be a mistake here. Context: ...ck**: Show calculations and validations immediately 4. **Error Prevention**: Validate input... (QB_NEW_EN_OTHER) --- [grammar] ~32-~32: There might be a mistake here. Context: ...tion**: Validate inputs before allowing progression 5. **Consistent Interactions**: Use sam... (QB_NEW_EN_OTHER) --- [grammar] ~33-~33: Use articles correctly Context: ...ion 5. **Consistent Interactions**: Use same patterns across similar features 6. **A... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~33-~33: There might be a mistake here. Context: ...ons**: Use same patterns across similar features 6. **Accessibility First**: Support scr... (QB_NEW_EN_OTHER) --- [grammar] ~34-~34: There might be a mistake here. Context: ...rst**: Support screen readers and large text 7. **Offline Support**: Cache data and ... (QB_NEW_EN_OTHER) --- [grammar] ~35-~35: There might be a problem here. Context: ...ine Support**: Cache data and sync when connection restored ### Navigation Structure - **Bottom Navigat... (QB_NEW_EN_MERGED_MATCH) --- [grammar] ~37-~37: Use colons correctly Context: ...hen connection restored ### Navigation Structure - **Bottom Navigation**: Home, Groups, ... (QB_NEW_EN_OTHER_ERROR_IDS_30) --- [grammar] ~41-~41: Use correct spacing Context: ...*: Material motion patterns with smooth animations ### Implementation Notes - Use `react-nativ... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~44-~44: There might be a mistake here. Context: ...`react-native-paper` v5+ for Material 3 components - Implement dynamic color theming based... (QB_NEW_EN_OTHER) --- [grammar] ~45-~45: There might be a mistake here. Context: ...t dynamic color theming based on system preferences - Follow Material 3 guidelines for spac... (QB_NEW_EN_OTHER) --- [grammar] ~46-~46: There might be a mistake here. Context: ... guidelines for spacing, elevation, and typography - Support both light and dark modes wit... (QB_NEW_EN_OTHER) --- [grammar] ~47-~47: There might be a mistake here. Context: ...oth light and dark modes with automatic switching - Ensure accessibility compliance with ... (QB_NEW_EN_OTHER) --- [grammar] ~48-~48: Use a period to end declarative sentences Context: ...ance with screen readers and large text support (QB_NEW_EN_OTHER_ERROR_IDS_25) </details> <details> <summary>docs/screens/friends-screens.md</summary> [grammar] ~1-~1: Use correct spacing Context: # Friends Screens ## Friends List Screen ### Wireframe Sket... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~3-~3: Use correct spacing Context: # Friends Screens ## Friends List Screen ### Wireframe Sketch ``` ┌─────────────────... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~5-~5: Use correct spacing Context: ... ## Friends List Screen ### Wireframe Sketch ``` ┌─────────────────────────────┐ │ SplitWiser [🔔] [👤] │ │─────────────────────────────│ │ │ │ Your Friends │ │ │ │ ┌─────────────────────┐ │ │ │ 👤 Alex │ │ │ │ You owe: $25 │ │ │ │ 3 groups together │ │ │ │ [>] │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ 👤 Sarah │ │ │ │ Owes you: $45 │ │ │ │ 2 groups together │ │ │ │ [>] │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ 👤 Mike │ │ │ │ All settled up │ │ │ │ 1 group together │ │ │ │ [>] │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ + ADD FRIEND │ │ │ └─────────────────────┘ │ │ │ │ [HOME] [GROUPS] [FRIENDS] │ └─────────────────────────────┘ ``` ### Description List of user's friends with... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~43-~43: Use correct spacing Context: ...oup count with quick access to detailed view. ### Key Features - Friend cards with balanc... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~47-~47: Use periods with abbreviations Context: ... - Color-coded balance indicators (owed vs owes) - Quick balance overview across a... (QB_NEW_EN_OTHER_ERROR_IDS_34) --- [grammar] ~51-~51: Use correct spacing Context: ... capabilities - Overall friends balance summary ### Component Breakdown #### Friend Cards ... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~53-~53: Use correct spacing Context: ... friends balance summary ### Component Breakdown #### Friend Cards - **Avatar**: Profile pict... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~60-~60: Use correct spacing Context: ...*Navigation Arrow**: Tap to view friend details #### Balance Indicators - **You Owe**: Red t... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~66-~66: Use correct spacing Context: ...**Amount**: Precise balance amount with currency #### Add Friend Section - **Add Button**: Pr... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~72-~72: Use correct spacing Context: ...**QR Code**: Share personal QR for easy adding ### Interactions - Tap friend card to view ... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~75-~75: There might be a mistake here. Context: ...Tap friend card to view detailed friend profile - Swipe friend card for quick actions (... (QB_NEW_EN_OTHER) --- [grammar] ~76-~76: There might be a mistake here. Context: ...card for quick actions (settle up, send reminder) - Pull-to-refresh to update all friend ... (QB_NEW_EN_OTHER) --- [grammar] ~77-~77: There might be a mistake here. Context: ... - Pull-to-refresh to update all friend balances - Search friends by name or filter by b... (QB_NEW_EN_OTHER) --- [grammar] ~78-~78: There might be a mistake here. Context: ...ch friends by name or filter by balance status ## Friend Detail Screen ### Wireframe Ske... (QB_NEW_EN_OTHER) --- [grammar] ~80-~80: Use correct spacing Context: ...ter by balance status ## Friend Detail Screen ### Wireframe Sketch ``` ┌─────────────────... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~82-~82: Use correct spacing Context: ... ## Friend Detail Screen ### Wireframe Sketch ``` ┌─────────────────────────────┐ │ ← Alex [⋮] │ │─────────────────────────────│ │ │ │ ┌─────────────────────┐ │ │ │ 👤 Alex │ │ │ │ alex@email.com │ │ │ │ │ │ │ │ Overall Balance │ │ │ │ You owe: $25 │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ SETTLE UP │ │ │ └─────────────────────┘ │ │ │ │ Shared Groups (3) │ │ ┌─────────────────────┐ │ │ │ 🏠 Roommates │ │ │ │ You owe: $15 │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ ✈️ Weekend Trip │ │ │ │ You owe: $10 │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ 🍽️ Dinner Club │ │ │ │ All settled │ │ │ └─────────────────────┘ │ │ │ │ Recent Activity │ │ ┌─────────────────────┐ │ │ │ Dinner - $60 │ │ │ │ Alex paid • 2 days │ │ │ └─────────────────────┘ │ │ │ └─────────────────────────────┘ ``` ### Description Detailed view of a specific... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~126-~126: Use articles correctly Context: ...ivity, and settlement options. Provides comprehensive overview of financial relationship. ##... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~126-~126: There might be a problem here. Context: ...ons. Provides comprehensive overview of financial relationship. ### Key Features - Friend profile informati... (QB_NEW_EN_MERGED_MATCH) --- [grammar] ~134-~134: Use correct spacing Context: ...payments - Direct messaging and contact options ### Component Breakdown #### Friend Profil... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~136-~136: Use correct spacing Context: ...ging and contact options ### Component Breakdown #### Friend Profile Card - **Profile Picture... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~142-~142: Use correct spacing Context: ...*Quick Actions**: Message, call, settle up #### Settle Up Button - **Primary Action**: ... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~147-~147: Use correct spacing Context: ...d Settlement**: For complex multi-group balances #### Shared Groups Section - **Group Cards**... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~152-~152: Use correct spacing Context: ...ce Breakdown**: Clear per-group balance display #### Recent Activity - **Activity Feed**: Re... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~157-~157: Use correct spacing Context: ...*Navigation**: Tap to view full expense details #### Profile Actions Menu - **Edit Friend**:... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~160-~160: There might be a mistake here. Context: ...Modify friend's display name or contact info - **Send Reminder**: Gentle payment rem... (QB_NEW_EN_OTHER) --- [grammar] ~161-~161: There might be a mistake here. Context: ...end Reminder**: Gentle payment reminder notifications - **Block/Remove**: Remove friend relat... (QB_NEW_EN_OTHER) --- [grammar] ~162-~162: There might be a mistake here. Context: ...move**: Remove friend relationship with confirmation - **Export History**: Download shared e... (QB_NEW_EN_OTHER) --- [grammar] ~163-~163: There might be a mistake here. Context: ...port History**: Download shared expense history ### Interactions - Tap shared group to navi... (QB_NEW_EN_OTHER) --- [grammar] ~166-~166: There might be a mistake here. Context: ...- Tap shared group to navigate to group details - Tap recent activity to view expense d... (QB_NEW_EN_OTHER) --- [grammar] ~167-~167: There might be a mistake here. Context: ...s - Tap recent activity to view expense details - Settle up with payment method selecti... (QB_NEW_EN_OTHER) --- [grammar] ~168-~168: There might be a mistake here. Context: ...details - Settle up with payment method selection - Contact friend through integrated com... (QB_NEW_EN_OTHER) --- [grammar] ~169-~169: There might be a mistake here. Context: ...ion - Contact friend through integrated communication - Access profile management options ##... (QB_NEW_EN_OTHER) --- [grammar] ~170-~170: There might be a mistake here. Context: ...mmunication - Access profile management options ## Add Friend Screen ### Wireframe Sketch... (QB_NEW_EN_OTHER) --- [grammar] ~172-~172: Use correct spacing Context: ...ofile management options ## Add Friend Screen ### Wireframe Sketch ``` ┌─────────────────... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~174-~174: Use correct spacing Context: ...ns ## Add Friend Screen ### Wireframe Sketch ``` ┌─────────────────────────────┐ │ ← Add Friend │ │─────────────────────────────│ │ │ │ Add a Friend │ │ │ │ Find by email or phone │ │ ┌─────────────────────┐ │ │ │ [alex@email.com___] │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ SEND INVITE │ │ │ └─────────────────────┘ │ │ │ │ or │ │ │ │ ┌─────────────────────┐ │ │ │ IMPORT CONTACTS │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ SHARE QR CODE │ │ │ └─────────────────────┘ │ │ │ │ Your QR Code │ │ ┌─────────────────────┐ │ │ │ ████████████████ │ │ │ │ ██ ██ ██ ██ │ │ │ │ ██████████████████ │ │ │ │ ██ ██ ██ ██ │ │ │ │ ████████████████ │ │ │ └─────────────────────┘ │ │ │ │ Share this code so friends │ │ can add you easily! │ │ │ └─────────────────────────────┘ ``` ### Description Screen for adding new frien... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~217-~217: Use correct spacing Context: ...ltiple convenient ways to expand friend network. ### Key Features - Email/phone number searc... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~224-~224: Use correct spacing Context: ...atus updates - Multiple contact methods support ### Component Breakdown #### Manual Additi... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~226-~226: Use correct spacing Context: ... contact methods support ### Component Breakdown #### Manual Addition - **Search Field**: Ema... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~232-~232: Use correct spacing Context: ...Tracking**: Pending, accepted, declined invitations #### Contact Import - **Permission Request**... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~238-~238: Use correct spacing Context: ...ering**: Show only contacts not already friends #### QR Code Sharing - **Personal QR**: User... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~244-~244: Use correct spacing Context: ...**Scanner**: Option to scan friend's QR code #### Invitation Management - **Sent Invites*... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~250-~250: Use correct spacing Context: ... **Privacy Controls**: Who can find/add user ### Interactions - Search contacts with rea... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~253-~253: There might be a mistake here. Context: ...ctions - Search contacts with real-time filtering - Select multiple contacts for bulk inv... (QB_NEW_EN_OTHER) --- [grammar] ~254-~254: There might be a mistake here. Context: ...ing - Select multiple contacts for bulk invitations - Share QR code through various platfor... (QB_NEW_EN_OTHER) --- [grammar] ~255-~255: Make sure to use plural and singular nouns correctly Context: ...ontacts for bulk invitations - Share QR code through various platforms - Accept/decl... (QB_NEW_EN_OTHER_ERROR_IDS_10) --- [grammar] ~255-~255: There might be a mistake here. Context: ...tations - Share QR code through various platforms - Accept/decline incoming friend reques... (QB_NEW_EN_OTHER) --- [grammar] ~256-~256: There might be a mistake here. Context: ...tforms - Accept/decline incoming friend requests - Resend or cancel pending invitations ... (QB_NEW_EN_OTHER) --- [grammar] ~257-~257: There might be a mistake here. Context: ...end requests - Resend or cancel pending invitations ## Friend Search Results ### Wireframe Sk... (QB_NEW_EN_OTHER) --- [grammar] ~259-~259: Use correct spacing Context: ...l pending invitations ## Friend Search Results ### Wireframe Sketch ``` ┌─────────────────... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~261-~261: Use correct spacing Context: ...## Friend Search Results ### Wireframe Sketch ``` ┌─────────────────────────────┐ │ ← Search Results │ │─────────────────────────────│ │ │ │ Results for "alex@email" │ │ │ │ ┌─────────────────────┐ │ │ │ 👤 Alex Johnson │ │ │ │ alex@email.com │ │ │ │ 2 mutual friends │ │ │ │ [ADD] │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ 👤 Alex Smith │ │ │ │ alexsmith@email.com │ │ │ │ No mutual friends │ │ │ │ [ADD] │ │ │ └─────────────────────┘ │ │ │ │ People you may know │ │ │ │ ┌─────────────────────┐ │ │ │ 👤 Sarah Williams │ │ │ │ From your contacts │ │ │ │ 5 mutual friends │ │ │ │ [ADD] │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ 👤 Mike Chen │ │ │ │ Friend of Alex │ │ │ │ 1 mutual friend │ │ │ │ [ADD] │ │ │ └─────────────────────┘ │ │ │ └─────────────────────────────┘ ``` ### Description Search results screen showi... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~303-~303: Use correct spacing Context: ... on mutual connections and contact list matches. ### Key Features - Search results based on ... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~310-~310: Use correct spacing Context: ... - Add friend functionality with status tracking ### Component Breakdown #### Search Result... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~312-~312: Use correct spacing Context: ...ity with status tracking ### Component Breakdown #### Search Results - **User Cards**: Profil... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~324-~324: Use correct spacing Context: ... **Geographic Proximity**: Nearby users (optional) #### Privacy Considerations - **Search Visib... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~327-~327: Use the right verb tense Context: ...rch Visibility**: User privacy settings respect - **Contact Permissions**: Appropriate ... (QB_NEW_EN_OTHER_ERROR_IDS_13) --- [grammar] ~329-~329: Use correct spacing Context: ...Suggestion Opt-out**: User control over discoverability ### Interactions - Send friend requests wit... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~332-~332: There might be a mistake here. Context: ... Send friend requests with personalized messages - View mutual friends for verification ... (QB_NEW_EN_OTHER) --- [grammar] ~333-~333: There might be a mistake here. Context: ...ized messages - View mutual friends for verification - Filter suggestions by connection type... (QB_NEW_EN_OTHER) --- [grammar] ~334-~334: There might be a mistake here. Context: ...tion - Filter suggestions by connection type - Block or hide specific suggestions - ... (QB_NEW_EN_OTHER) --- [grammar] ~335-~335: There might be a mistake here. Context: ...onnection type - Block or hide specific suggestions - Access user profiles (if public) befo... (QB_NEW_EN_OTHER) --- [grammar] ~336-~336: Use a period to end declarative sentences Context: ...Access user profiles (if public) before adding (QB_NEW_EN_OTHER_ERROR_IDS_25) </details> <details> <summary>docs/screens/auth-screens.md</summary> [grammar] ~1-~1: Use correct spacing Context: # Authentication Screens ## Login Screen ### Wireframe Sketch ``` ... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~3-~3: Use correct spacing Context: # Authentication Screens ## Login Screen ### Wireframe Sketch ``` ┌─────────────────... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~5-~5: Use correct spacing Context: ...Screens ## Login Screen ### Wireframe Sketch ``` ┌─────────────────────────────┐ │ │ │ [ Logo/Icon ] │ │ │ │ Welcome to SplitWiser │ │ │ │ ┌─────────────────────┐ │ │ │ Email Address │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ Password │ │ │ └─────────────────────┘ │ │ │ │ [ ] Remember me │ │ │ │ ┌─────────────────────┐ │ │ │ LOG IN │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ CONTINUE WITH GOOGLE│ │ │ └─────────────────────┘ │ │ │ │ New user? [Sign up] │ │ │ └─────────────────────────────┘ ``` ### Description Clean login interface with ... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~37-~37: Use correct spacing Context: ...erial 3 filled text fields and elevated buttons. ### Key Features - Material 3 filled text i... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~45-~45: Use correct spacing Context: ... - Form validation with real-time error display ### Component Breakdown - **Logo**: App bra... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~55-~55: Use correct spacing Context: ...- **Sign Up Link**: Text button for new users ### Interactions - Form validation on field... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~62-~62: There might be a problem here. Context: ...ccessibility support with screen reader labels ## Sign Up Screen ### Wireframe Sketch ``` ┌───... (QB_NEW_EN_MERGED_MATCH) --- [grammar] ~64-~64: Use correct spacing Context: ...t with screen reader labels ## Sign Up Screen ### Wireframe Sketch ``` ┌─────────────────... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~66-~66: There might be a problem here. Context: ...abels ## Sign Up Screen ### Wireframe Sketch ``` ┌─────────────────────────────┐ │ │ │ [ Logo/Icon ] │ │ │ │ Sign Up │ │ │ │ ┌─────────────────────┐ │ │ │ Email │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ Password │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ Confirm Password │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ SIGN UP │ │ │ └─────────────────────┘ │ │ │ │ Already have an account? │ │ [Log in] │ │ │ └─────────────────────────────┘ ``` ### Description Registration form with email, password,... (QB_NEW_EN_MERGED_MATCH) --- [grammar] ~97-~97: Use articles correctly Context: ..., and confirm password fields. Includes primary sign-up button and login redirect for e... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~97-~97: Use correct spacing Context: ...eedback for password strength and email format. ### Key Features - Three-step form validati... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~104-~104: Use correct spacing Context: ... screen - Consistent styling with login screen ### Component Breakdown - **Logo**: Same ap... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~113-~113: Use correct spacing Context: ...*Login Link**: Text button for existing users ### Validation Rules - **Email**: Valid ema... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~116-~116: There might be a mistake here. Context: ...n Rules - **Email**: Valid email format required - **Password**: Minimum 8 characters, m... (QB_NEW_EN_OTHER) --- [grammar] ~117-~117: There might be a mistake here. Context: ...inimum 8 characters, mix of letters and numbers - **Confirm Password**: Must match pass... (QB_NEW_EN_OTHER) --- [grammar] ~118-~118: There might be a mistake here. Context: ...m Password**: Must match password field exactly - Real-time validation feedback with co... (QB_NEW_EN_OTHER) --- [grammar] ~119-~119: There might be a mistake here. Context: ...me validation feedback with color-coded indicators ## Forgot Password Screen ### Wireframe S... (QB_NEW_EN_OTHER) --- [grammar] ~121-~121: Use correct spacing Context: ...or-coded indicators ## Forgot Password Screen ### Wireframe Sketch ``` ┌─────────────────... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~123-~123: There might be a problem here. Context: ...# Forgot Password Screen ### Wireframe Sketch ``` ┌─────────────────────────────┐ │ ← │ │ │ │ [ Logo/Icon ] │ │ │ │ Forgot Password? │ │ │ │ Enter your email address │ │ and we'll send you a link │ │ to reset your password. │ │ │ │ ┌─────────────────────┐ │ │ │ Email Address │ │ │ └─────────────────────┘ │ │ │ │ │ │ ┌─────────────────────┐ │ │ │ SEND RESET LINK │ │ │ └─────────────────────┘ │ │ │ │ │ │ Remember your password? │ │ [Back to Login] │ │ │ └─────────────────────────────┘ ``` ### Description Password reset interface with clear ins... (QB_NEW_EN_MERGED_MATCH) --- [grammar] ~153-~153: Use correct spacing Context: ...des back navigation and return to login option. ### Key Features - Clear explanation of the... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~159-~159: Use correct spacing Context: ...tion message - Back navigation to login screen ## Onboarding Screens ### Onboarding Scre... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~161-~161: Use correct spacing Context: ...vigation to login screen ## Onboarding Screens ### Onboarding Screen 1: Welcome ``` ┌─────... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~163-~163: Use correct spacing Context: ...rding Screens ### Onboarding Screen 1: Welcome ``` ┌─────────────────────────────┐ │ │ │ [Illustration] │ │ │ │ Welcome to SplitWiser │ │ │ │ Split expenses with friends │ │ and settle up easily with │ │ optimized payment flows. │ │ │ │ │ │ │ │ │ │ │ │ ○ ○ ○ │ │ │ │ [NEXT] │ │ │ └─────────────────────────────┘ ``` ### Onboarding Screen 2: Groups ``` ┌──────... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~186-~186: Use correct spacing Context: ...────────┘ ``` ### Onboarding Screen 2: Groups ``` ┌─────────────────────────────┐ │ │ │ [Illustration] │ │ │ │ Create Groups │ │ │ │ Organize expenses by trip, │ │ roommates, or any group. │ │ Track who owes what. │ │ │ │ │ │ │ │ │ │ │ │ ○ ● ○ │ │ │ │ [SKIP] [NEXT] │ │ │ └─────────────────────────────┘ ``` ### Onboarding Screen 3: Smart Splits ``` ┌... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~209-~209: Use correct spacing Context: ...──┘ ``` ### Onboarding Screen 3: Smart Splits ``` ┌─────────────────────────────┐ │ │ │ [Illustration] │ │ │ │ Smart Splitting │ │ │ │ Split equally, by shares, │ │ percentages, or exact │ │ amounts. We do the math. │ │ │ │ │ │ │ │ │ │ │ │ ○ ○ ● │ │ │ │ [SKIP] [GET STARTED] │ │ │ └─────────────────────────────┘ ``` ### Onboarding Features - Swipeable screens... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~237-~237: Use correct spacing Context: ...nsistent button styling with Material 3 design ### Navigation Flow 1. **Welcome** → Next →... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~242-~242: Use correct spacing Context: .... **Smart Splits** → Get Started → Main App All onboarding screens support: - Smoot... (QB_NEW_EN_OTHER_ERROR_IDS_5) </details> <details> <summary>docs/screens/expense-creation.md</summary> [grammar] ~1-~1: Use correct spacing Context: # Expense Creation Screens ## Expense Creation - Basic Details ### W... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [typographical] ~3-~3: To join two clauses or set off examples, consider using an em dash. Context: # Expense Creation Screens ## Expense Creation - Basic Details ### Wireframe Sketch ``` ... (QB_NEW_EN_DASH_RULE_EM) --- [grammar] ~3-~3: Use correct spacing Context: ...on Screens ## Expense Creation - Basic Details ### Wireframe Sketch ``` ┌─────────────────... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~5-~5: Use correct spacing Context: ...Creation - Basic Details ### Wireframe Sketch ``` ┌─────────────────────────────┐ │ ← Add Expense [✓] │ │─────────────────────────────│ │ │ │ ●○○○ │ │ │ │ What was this expense for? │ │ │ │ ┌─────────────────────┐ │ │ │ Description │ │ │ │ [Dinner at restaurant] │ │ └─────────────────────┘ │ │ │ │ How much did it cost? │ │ │ │ ┌─────────────────────┐ │ │ │ $ [85.50________] │ │ │ └─────────────────────┘ │ │ │ │ Category │ │ ┌─────────────────────┐ │ │ │ 🍽️ Food & Dining ▼ │ │ │ └─────────────────────┘ │ │ │ │ Date │ │ ┌─────────────────────┐ │ │ │ 📅 Today ▼ │ │ │ └─────────────────────┘ │ │ │ │ │ │ ┌─────────────────────┐ │ │ │ NEXT │ │ │ └─────────────────────┘ │ │ │ └─────────────────────────────┘ ``` ### Description First step of expense creat... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~45-~45: Use correct spacing Context: ...quired fields without overwhelming step numbers. ### Key Features - Progress indicator showi... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~53-~53: Use correct spacing Context: ...today) - Form validation with real-time feedback ### Component Breakdown #### Progress Indi... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~55-~55: Use correct spacing Context: ... with real-time feedback ### Component Breakdown #### Progress Indicator - **Progress Dots**:... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~66-~66: Use correct spacing Context: ...s - **Date**: Date picker with calendar interface #### Categories - 🍽️ Food & Dining - 🚗 Tra... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~80-~80: Use correct spacing Context: ...Education - 💼 Business - 🎁 Gifts - 🔧 Other ### Interactions - Real-time amount formatt... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~86-~86: Use correct spacing Context: ... preventing progression with incomplete data ## Expense Creation - Select Payers ### W... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [typographical] ~88-~88: To join two clauses or set off examples, consider using an em dash. Context: ...ession with incomplete data ## Expense Creation - Select Payers ### Wireframe Sketch ``` ... (QB_NEW_EN_DASH_RULE_EM) --- [grammar] ~88-~88: Use correct spacing Context: ...lete data ## Expense Creation - Select Payers ### Wireframe Sketch ``` ┌─────────────────... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~90-~90: There might be a problem here. Context: ...Creation - Select Payers ### Wireframe Sketch ``` ┌─────────────────────────────┐ │ ← Add Expense [✓] │ │─────────────────────────────│ │ │ │ ●●○○ │ │ │ │ Who paid for this? │ │ │ │ ○ Single payer │ │ ● Multiple payers │ │ │ │ Select payers: │ │ │ │ ┌─────────────────────┐ │ │ │ ☑️ You $45.00 │ │ │ │ [_____________] │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ ☑️ Alex $40.50 │ │ │ │ [_____________] │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ ☐ Sam $0.00 │ │ │ │ [_____________] │ │ │ └─────────────────────┘ │ │ │ │ Total paid: $85.50 │ │ │ │ ┌─────────────────────┐ │ │ │ NEXT │ │ │ └─────────────────────┘ │ │ │ └─────────────────────────────┘ ``` ### Description Second step allowing selection of who p... (QB_NEW_EN_MERGED_MATCH) --- [grammar] ~130-~130: Use correct spacing Context: ...ch payer. Progress shown with clean dot indicators. ### Key Features - Radio buttons for single... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~133-~133: Use periods with abbreviations Context: ...Key Features - Radio buttons for single vs multiple payers - Member checkboxes wit... (QB_NEW_EN_OTHER_ERROR_IDS_34) --- [grammar] ~137-~137: Use correct spacing Context: ...es - Clear visual feedback for selected payers ### Component Breakdown #### Payment Mode ... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~139-~139: Use correct spacing Context: ...back for selected payers ### Component Breakdown #### Payment Mode Selection - **Single Payer... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~144-~144: Use correct spacing Context: ...**: Radio buttons with automatic amount adjustment #### Payer Selection - **Member List**: All ... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~150-~150: Use correct spacing Context: ...*: Auto-calculate amounts when toggling modes #### Validation - **Total Match**: Paid amou... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~153-~153: There might be a mistake here. Context: ...atch**: Paid amounts must equal expense total - **Positive Amounts**: All individual ... (QB_NEW_EN_OTHER) --- [grammar] ~154-~154: There might be a mistake here. Context: ...ounts**: All individual amounts must be positive - **At Least One**: Minimum one payer m... (QB_NEW_EN_OTHER) --- [grammar] ~155-~155: There might be a problem here. Context: ...l amounts must be positive - **At Least One**: Minimum one payer must be selected ### Interac... (QB_NEW_EN_MERGED_MATCH) --- [grammar] ~155-~155: There might be a mistake here. Context: ... Least One**: Minimum one payer must be selected ### Interactions - Toggle between single/mu... (QB_NEW_EN_OTHER) --- [grammar] ~158-~158: There might be a mistake here. Context: ... - Toggle between single/multiple payer modes - Check/uncheck members with automatic ... (QB_NEW_EN_OTHER) --- [grammar] ~159-~159: There might be a mistake here. Context: ...k/uncheck members with automatic amount calculations - Manual amount adjustment with real-ti... (QB_NEW_EN_OTHER) --- [grammar] ~160-~160: There might be a mistake here. Context: ... amount adjustment with real-time total updates - Visual indicators for validation erro... (QB_NEW_EN_OTHER) --- [grammar] ~161-~161: There might be a mistake here. Context: ...ates - Visual indicators for validation errors ## Expense Creation - Split Method ### Wi... (QB_NEW_EN_OTHER) --- [typographical] ~163-~163: To join two clauses or set off examples, consider using an em dash. Context: ...ators for validation errors ## Expense Creation - Split Method ### Wireframe Sketch ``` ┌... (QB_NEW_EN_DASH_RULE_EM) --- [grammar] ~163-~163: Use correct spacing Context: ...ion errors ## Expense Creation - Split Method ### Wireframe Sketch ``` ┌─────────────────... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~165-~165: Use correct spacing Context: ... Creation - Split Method ### Wireframe Sketch ``` ┌─────────────────────────────┐ │ ← Add Expense [✓] │ │─────────────────────────────│ │ │ │ ●●●○ │ │ │ │ How should this be split? │ │ │ │ ○ Equal split │ │ ● Custom amounts │ │ ○ Percentage split │ │ ○ By shares │ │ │ │ Split details: │ │ │ │ ┌─────────────────────┐ │ │ │ 👤 You $30.00 │ │ │ │ [_____________] │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ 👤 Alex $25.50 │ │ │ │ [_____________] │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ 👤 Sam $30.00 │ │ │ │ [_____________] │ │ │ └─────────────────────┘ │ │ │ │ Total: $85.50 │ │ │ │ ┌─────────────────────┐ │ │ │ NEXT │ │ │ └─────────────────────┘ │ │ │ └─────────────────────────────┘ ``` ### Description Third step for defining how... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~207-~207: Use modal and auxiliary verbs correctly Context: ...h real-time calculation and validation. Progress shown with clean visual indicators. ##... (QB_NEW_EN_OTHER_ERROR_IDS_24) --- [grammar] ~207-~207: Use correct spacing Context: ...ation. Progress shown with clean visual indicators. ### Key Features - Four split methods: equa... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~214-~214: Use correct spacing Context: ...tions - Clear visual feedback for split amounts ### Component Breakdown #### Split Methods... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~216-~216: Use correct spacing Context: ...edback for split amounts ### Component Breakdown #### Split Methods - **Equal Split**: Divide... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~219-~219: Use articles correctly Context: ...Split Methods - **Equal Split**: Divide total amount equally among selected members -... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~219-~219: There might be a mistake here. Context: ...ide total amount equally among selected members - **Custom Amounts**: Manually specify ... (QB_NEW_EN_OTHER) --- [grammar] ~220-~220: There might be a mistake here. Context: ...Manually specify exact amounts for each person - **Percentage Split**: Define percenta... (QB_NEW_EN_OTHER) --- [grammar] ~221-~221: Use articles correctly Context: ...h person - **Percentage Split**: Define percentage share for each member - **By Shares**: ... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~221-~221: There might be a mistake here. Context: ...lit**: Define percentage share for each member - **By Shares**: Assign shares/units to... (QB_NEW_EN_OTHER) --- [grammar] ~222-~222: There might be a mistake here. Context: ...s/units to each member for proportional split #### Split Interface (varies by method) - **... (QB_NEW_EN_OTHER) --- [grammar] ~228-~228: Use correct spacing Context: ...*: Share count inputs with proportional calculation #### Member Selection - **Include/Exclude**:... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~231-~231: There might be a mistake here. Context: ...Exclude**: Toggle members in/out of the split - **Visual Indicators**: Clear distinct... (QB_NEW_EN_OTHER) --- [grammar] ~232-~232: There might be a mistake here. Context: ...r distinction between included/excluded members - **Smart Defaults**: Include all group... (QB_NEW_EN_OTHER) --- [grammar] ~233-~233: There might be a mistake here. Context: ...efaults**: Include all group members by default ### Interactions - Switch between split met... (QB_NEW_EN_OTHER) --- [grammar] ~236-~236: There might be a mistake here. Context: ...ch between split methods with automatic recalculation - Include/exclude members from the spli... (QB_NEW_EN_OTHER) --- [grammar] ~237-~237: There might be a mistake here. Context: ...tion - Include/exclude members from the split - Real-time validation and error feedba... (QB_NEW_EN_OTHER) --- [grammar] ~238-~238: There might be a mistake here. Context: ... split - Real-time validation and error feedback - Auto-calculation based on selected me... (QB_NEW_EN_OTHER) --- [grammar] ~239-~239: There might be a mistake here. Context: ...ck - Auto-calculation based on selected method ## Expense Creation - Review & Submit ###... (QB_NEW_EN_OTHER) --- [typographical] ~241-~241: To join two clauses or set off examples, consider using an em dash. Context: ...on based on selected method ## Expense Creation - Review & Submit ### Wireframe Sketch ``... (QB_NEW_EN_DASH_RULE_EM) --- [grammar] ~241-~241: Use correct spacing Context: ... method ## Expense Creation - Review & Submit ### Wireframe Sketch ``` ┌─────────────────... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~243-~243: There might be a problem here. Context: ...eation - Review & Submit ### Wireframe Sketch ``` ┌─────────────────────────────┐ │ ← Add Expense [✓] │ │─────────────────────────────│ │ │ │ ●●●● │ │ │ │ Review your expense │ │ │ │ ┌─────────────────────┐ │ │ │ 🍽️ Dinner at restaurant │ │ │ $85.50 • Today │ │ │ │ │ │ │ │ Paid by: │ │ │ │ • You: $45.00 │ │ │ │ • Alex: $40.50 │ │ │ │ │ │ │ │ Split between: │ │ │ │ • You: $30.00 │ │ │ │ • Alex: $25.50 │ │ │ │ • Sam: $30.00 │ │ │ └─────────────────────┘ │ │ │ │ Net amounts: │ │ ┌─────────────────────┐ │ │ │ You lent: $15.00 │ │ │ │ Alex owes: $14.00 │ │ │ │ Sam owes: $30.00 │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ CREATE EXPENSE │ │ │ └─────────────────────┘ │ │ │ └─────────────────────────────┘ ``` ### Description Final review step showing complete expe... (QB_NEW_EN_MERGED_MATCH) --- [grammar] ~282-~282: Use correct spacing Context: ...r. All progress dots filled to indicate completion. ### Key Features - Complete expense summary... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~290-~290: Use correct spacing Context: ... state - Option to go back and edit any step ### Component Breakdown #### Expense Summa... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~292-~292: Use correct spacing Context: ...o back and edit any step ### Component Breakdown #### Expense Summary Card - **Description**:... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~297-~297: Use correct spacing Context: ...*: Elevated card with clear information hierarchy #### Payment Details - **Payers List**: Who ... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~302-~302: Use periods with abbreviations Context: ...inction**: Different styling for payers vs split participants #### Split Breakdow... (QB_NEW_EN_OTHER_ERROR_IDS_34) --- [grammar] ~302-~302: Use correct spacing Context: ...: Different styling for payers vs split participants #### Split Breakdown - **Participant List**:... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~304-~304: Use colons correctly Context: ...ayers vs split participants #### Split Breakdown - **Participant List**: Each person's s... (QB_NEW_EN_OTHER_ERROR_IDS_30) --- [grammar] ~306-~306: Use articles correctly Context: ...e - **Split Method**: Indication of how split was calculated - **Total Validation**: ... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~307-~307: Use correct spacing Context: ...tion**: Confirmation that splits add up correctly #### Net Amounts - **Balance Changes**: What... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~312-~312: Use correct spacing Context: ...at**: Clear, scannable format for quick review ### Interactions - Tap any section to go ba... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~315-~315: There might be a mistake here. Context: ...ctions - Tap any section to go back and edit - Create expense with loading state and... (QB_NEW_EN_OTHER) --- [grammar] ~316-~316: Use articles correctly Context: ...ny section to go back and edit - Create expense with loading state and success feedback... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~316-~316: There might be a mistake here. Context: ... expense with loading state and success feedback - Error handling for network issues - S... (QB_NEW_EN_OTHER) --- [grammar] ~317-~317: There might be a mistake here. Context: ...s feedback - Error handling for network issues - Success navigation to group details w... (QB_NEW_EN_OTHER) --- [grammar] ~318-~318: There might be a mistake here. Context: ...ation to group details with new expense highlighted ## Receipt Upload (Optional Feature) ### ... (QB_NEW_EN_OTHER) --- [grammar] ~320-~320: Use correct spacing Context: ...ighlighted ## Receipt Upload (Optional Feature) ### Wireframe Sketch ``` ┌─────────────────... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~322-~322: Use correct spacing Context: ...pload (Optional Feature) ### Wireframe Sketch ``` ┌─────────────────────────────┐ │ ← Add Receipt │ │─────────────────────────────│ │ │ │ Add Receipt (Optional) │ │ │ │ ┌─────────────────────┐ │ │ │ │ │ │ │ 📷 TAKE PHOTO │ │ │ │ │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ │ │ │ │ 📁 CHOOSE FROM │ │ │ │ GALLERY │ │ │ │ │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ [Receipt Preview] │ │ │ │ │ │ │ │ ┌─────────────┐ │ │ │ │ │ Receipt │ │ │ │ │ │ Image │ │ │ │ │ └─────────────┘ │ │ │ │ │ │ │ │ [🗑️] [✓] │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ DONE │ │ │ └─────────────────────┘ │ │ │ └─────────────────────────────┘ ``` ### Description Optional receipt attachment... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~362-~362: Use correct spacing Context: ...ture and gallery selection with preview functionality. ### Key Features - Camera integration for i... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~369-~369: Use correct spacing Context: ...nt detection - Optional attachment (can skip) ### Component Breakdown #### Capture Optio... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~371-~371: Use correct spacing Context: ...al attachment (can skip) ### Component Breakdown #### Capture Options - **Camera Button**: Di... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~376-~376: Use correct spacing Context: ... Handling**: Appropriate camera/storage permissions #### Image Processing - **Preview Screen**: ... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~382-~382: Use correct spacing Context: ...*Compression**: Optimize image size for storage ### Interactions - Camera interface with st... (QB_NEW_EN_OTHER_ERROR_IDS_5) </details> <details> <summary>docs/screens/groups-screens.md</summary> [grammar] ~1-~1: Use correct spacing Context: # Groups Screens ## Groups List Screen ### Wireframe Sketc... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~3-~3: Use correct spacing Context: # Groups Screens ## Groups List Screen ### Wireframe Sketch ``` ┌─────────────────... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~5-~5: There might be a problem here. Context: ...s ## Groups List Screen ### Wireframe Sketch ``` ┌─────────────────────────────┐ │ Groups [�] [➕] │ │─────────────────────────────│ │ │ │ ┌─────────────────────┐ │ │ │ Weekend Trip │ │ │ │ 5 members │ │ │ │ Last activity: Today│ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ Apartment │ │ │ │ 3 members │ │ │ │ Last activity: 2d ago│ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ Book Club │ │ │ │ 8 members │ │ │ │ Last activity: 1w ago│ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ Create new group │ │ │ └─────────────────────┘ │ │ │ │ │ │ │ │ │ │ │ │ [HOME] [GROUPS] [FRIENDS] │ └─────────────────────────────┘ ``` ### Description Clean groups list with simplified group... (QB_NEW_EN_MERGED_MATCH) --- [grammar] ~42-~42: Use correct spacing Context: ... clutter by focusing on essential group information. ### Key Features - Clean group cards with m... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~50-~50: Use correct spacing Context: ...Recent activity tracking without visual clutter ### Component Breakdown - **Group Cards**: ... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~53-~53: Insert the missing word Context: ... elevated cards with group name, member count, last activity - **Search Icon**: Top-ri... (QB_NEW_EN_OTHER_ERROR_IDS_32) --- [grammar] ~57-~57: There might be a problem here. Context: ...yout**: Removes balance information for cleaner interface ### Interactions - Tap group card to naviga... (QB_NEW_EN_MERGED_MATCH) --- [grammar] ~60-~60: Use articles correctly Context: ...eaner interface ### Interactions - Tap group card to navigate to group details - Tap... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~60-~60: There might be a mistake here. Context: ...s - Tap group card to navigate to group details - Tap search icon to open group search ... (QB_NEW_EN_OTHER) --- [grammar] ~61-~61: Use articles correctly Context: ...card to navigate to group details - Tap search icon to open group search functionality... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~61-~61: There might be a mistake here. Context: ... - Tap search icon to open group search functionality - Tap plus icon for group creation or j... (QB_NEW_EN_OTHER) --- [grammar] ~62-~62: Use articles correctly Context: ...o open group search functionality - Tap plus icon for group creation or joining opti... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~62-~62: There might be a mistake here. Context: ...plus icon for group creation or joining options - Pull-to-refresh to update group infor... (QB_NEW_EN_OTHER) --- [grammar] ~63-~63: There might be a mistake here. Context: ...tions - Pull-to-refresh to update group information - Long press for quick group management... (QB_NEW_EN_OTHER) --- [grammar] ~64-~64: There might be a mistake here. Context: ...- Long press for quick group management options ## Group Details Screen ### Wireframe Ske... (QB_NEW_EN_OTHER) --- [grammar] ~66-~66: Use correct spacing Context: ...up management options ## Group Details Screen ### Wireframe Sketch ``` ┌─────────────────... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~68-~68: Use correct spacing Context: ... ## Group Details Screen ### Wireframe Sketch ``` ┌─────────────────────────────┐ │ ← Weekend Trip │ │─────────────────────────────│ │ Weekend Trip │ │ 5 members • Created Jun 25 │ │ │ │ ┌─────────────────────┐ │ │ │ You are owed $125 │ │ │ │ [SETTLE UP] │ │ │ └─────────────────────┘ │ │ │ │ EXPENSES │ │ │ │ Today │ │ ┌─────────────────────┐ │ │ │ Dinner │ │ │ │ $85 • You paid │ │ │ │ Split equally (4) │ │ │ └─────────────────────┘ │ │ │ │ Yesterday │ │ ┌─────────────────────┐ │ │ │ Hotel │ │ │ │ $350 • John paid │ │ │ │ Split unequally │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ Gas │ │ │ │ $45 • Sarah paid │ │ │ │ Split equally (3) │ │ │ └─────────────────────┘ │ │ │ │ [+] │ └─────────────────────────────┘ ``` ### Description Clean group details view fo... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~108-~108: Use hyphens correctly Context: ...ation. Shows group balance summary with settle up option and expense history organized ... (QB_NEW_EN_OTHER_ERROR_IDS_29) --- [grammar] ~108-~108: Use articles correctly Context: ...nse history organized by date. Features floating action button for adding new expenses. ... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~108-~108: Use correct spacing Context: ...s floating action button for adding new expenses. ### Key Features - Clean header with group ... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~112-~112: Use hyphens correctly Context: ...adata - Simplified balance summary with settle up action - Chronologically organized ex... (QB_NEW_EN_OTHER_ERROR_IDS_29) --- [grammar] ~117-~117: Use correct spacing Context: ...treamlined interface focused on expense tracking ### Component Breakdown #### Header Sectio... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~119-~119: Use correct spacing Context: ...used on expense tracking ### Component Breakdown #### Header Section - **Back Button**: Navig... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~125-~125: Use correct spacing Context: ...- **Creation Date**: When the group was created #### Balance Summary Card - **Personal Balan... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~130-~130: Use correct spacing Context: ...**: Minimal card with essential balance info #### Expenses Section - **Section Header**: ... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~136-~136: Use correct spacing Context: ...mation**: Shows how expense was divided (equally/unequally) #### Floating Action Button - **Add Expense*... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~141-~141: Use correct spacing Context: ...lean Design**: Simple plus icon without text ### Interactions - Tap back button to retur... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~144-~144: Use articles correctly Context: ...on without text ### Interactions - Tap back button to return to groups list - Tap s... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~144-~144: There might be a problem here. Context: ...ractions - Tap back button to return to groups list - Tap settle up button to initiate sett... (QB_NEW_EN_MERGED_MATCH) --- [grammar] ~145-~145: Use articles correctly Context: ...k button to return to groups list - Tap settle up button to initiate settlement proces... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~145-~145: There might be a mistake here. Context: ...settle up button to initiate settlement process - Tap expense cards to view detailed br... (QB_NEW_EN_OTHER) --- [grammar] ~146-~146: Use articles correctly Context: ...on to initiate settlement process - Tap expense cards to view detailed breakdown and ed... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~146-~146: Use articles correctly Context: ...ent process - Tap expense cards to view detailed breakdown and edit options - FAB to sta... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~146-~146: There might be a mistake here. Context: ...rds to view detailed breakdown and edit options - FAB to start expense creation flow - ... (QB_NEW_EN_OTHER) --- [grammar] ~147-~147: Use articles correctly Context: ...eakdown and edit options - FAB to start expense creation flow - Pull-to-refresh for lat... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~147-~147: There might be a mistake here. Context: ...options - FAB to start expense creation flow - Pull-to-refresh for latest expense da... (QB_NEW_EN_OTHER) --- [grammar] ~148-~148: Use articles correctly Context: ...nse creation flow - Pull-to-refresh for latest expense data - Long press expense for q... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~148-~148: There might be a mistake here. Context: ...ow - Pull-to-refresh for latest expense data - Long press expense for quick actions ... (QB_NEW_EN_OTHER) --- [grammar] ~149-~149: Use articles correctly Context: ...sh for latest expense data - Long press expense for quick actions (edit, delete) ## Gr... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~149-~149: There might be a mistake here. Context: ... press expense for quick actions (edit, delete) ## Group Management Screen ### Wireframe ... (QB_NEW_EN_OTHER) --- [grammar] ~151-~151: Use correct spacing Context: ...ons (edit, delete) ## Group Management Screen ### Wireframe Sketch ``` ┌─────────────────... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~153-~153: Use correct spacing Context: ... Group Management Screen ### Wireframe Sketch ``` ┌─────────────────────────────┐ │ ← Group Settings │ │─────────────────────────────│ │ │ │ Group Details │ │ ┌─────────────────────┐ │ │ │ Group Name │ │ │ │ [Roommates_______] │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ Description │ │ │ │ [Shared expenses__] │ │ │ └─────────────────────┘ │ │ │ │ Members │ │ ┌─────────────────────┐ │ │ │ 👤 You (Admin) │ │ │ │ 👤 Alex [Remove] │ │ │ │ 👤 Sam [Remove] │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ + INVITE MEMBER │ │ │ └─────────────────────┘ │ │ │ │ Group Actions │ │ ┌─────────────────────┐ │ │ │ Share Group Link │ │ │ │ Export Expenses │ │ │ │ Settle All Debts │ │ │ │ Delete Group │ │ │ └─────────────────────┘ │ │ │ └─────────────────────────────┘ ``` ### Description Group administration interf... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~193-~193: Use correct spacing Context: ...ssible to group admins with appropriate permissions. ### Key Features - Editable group name and ... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~200-~200: Use correct spacing Context: ...ttle, delete) - Permission-based access control ### Component Breakdown #### Group Details... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~202-~202: Use correct spacing Context: ...ion-based access control ### Component Breakdown #### Group Details Section - **Name Field**:... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~207-~207: Use correct spacing Context: ...**: Selectable emoji or image for group identification #### Members Management - **Member List**: C... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~213-~213: Use correct spacing Context: ...e Button**: Generate invite links or QR codes #### Group Actions - **Share Link**: Generat... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~216-~216: There might be a mistake here. Context: ...*Share Link**: Generate shareable group invitation - **Export Data**: Download expense his... (QB_NEW_EN_OTHER) --- [grammar] ~217-~217: There might be a mistake here. Context: ...ort Data**: Download expense history as CSV/PDF - **Settle All**: Initiate group-wide s... (QB_NEW_EN_OTHER) --- [grammar] ~218-~218: There might be a mistake here. Context: ...e All**: Initiate group-wide settlement process - **Delete Group**: Permanently remove ... (QB_NEW_EN_OTHER) --- [grammar] ~219-~219: There might be a mistake here. Context: ...Group**: Permanently remove group (with confirmation) ### Interactions - Edit group name and desc... (QB_NEW_EN_OTHER) --- [grammar] ~222-~222: There might be a mistake here. Context: ...oup name and description with real-time saving - Remove members with confirmation dial... (QB_NEW_EN_OTHER) --- [grammar] ~223-~223: There might be a mistake here. Context: ...ving - Remove members with confirmation dialog - Generate and share invite links - Exp... (QB_NEW_EN_OTHER) --- [grammar] ~224-~224: There might be a mistake here. Context: ...tion dialog - Generate and share invite links - Export expense data in multiple forma... (QB_NEW_EN_OTHER) --- [grammar] ~225-~225: There might be a mistake here. Context: ...links - Export expense data in multiple formats - Delete group with multi-step confirma... (QB_NEW_EN_OTHER) --- [grammar] ~226-~226: There might be a mistake here. Context: ... formats - Delete group with multi-step confirmation ## Join Group Screen ### Wireframe Sketch... (QB_NEW_EN_OTHER) --- [grammar] ~228-~228: Use correct spacing Context: ... multi-step confirmation ## Join Group Screen ### Wireframe Sketch ``` ┌─────────────────... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~230-~230: There might be a problem here. Context: ...on ## Join Group Screen ### Wireframe Sketch ``` ┌─────────────────────────────┐ │ ← Join Group │ │─────────────────────────────│ │ │ │ Join a Group │ │ │ │ Enter Group Code │ │ ┌─────────────────────┐ │ │ │ [ABC123_________] │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ JOIN GROUP │ │ │ └─────────────────────┘ │ │ │ │ or │ │ │ │ ┌─────────────────────┐ │ │ │ SCAN QR CODE │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ [QR Camera Preview] │ │ │ │ │ │ │ │ ┌─────────────┐ │ │ │ │ │ [ ] │ │ │ │ │ └─────────────┘ │ │ │ │ │ │ │ └─────────────────────┘ │ │ │ │ Point camera at QR code │ │ │ └─────────────────────────────┘ ``` ### Description Screen for joining existing groups thro... (QB_NEW_EN_MERGED_MATCH) --- [grammar] ~268-~268: Use correct spacing Context: ...hods with clear instructions and visual feedback. ### Key Features - Text input for manual gr... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~275-~275: Use correct spacing Context: ...n joining - Clear instructions for both methods ### Component Breakdown #### Group Code In... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~277-~277: Use correct spacing Context: ...uctions for both methods ### Component Breakdown #### Group Code Input - **Text Field**: 6-ch... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~282-~282: Use correct spacing Context: ...- **Validation**: Real-time code format checking #### QR Scanner - **Camera Preview**: Live c... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~288-~288: Use correct spacing Context: ...l Controls**: Flashlight toggle, camera switch #### Instructions - **Helper Text**: Clear g... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~293-~293: Use correct spacing Context: ...tes**: Confirmation of successful group joining ### Interactions - Type or paste group code... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~296-~296: There might be a mistake here. Context: ...actions - Type or paste group code with auto-formatting - Camera permission request for QR scan... (QB_NEW_EN_OTHER) --- [grammar] ~297-~297: There might be a mistake here. Context: ...ting - Camera permission request for QR scanning - Automatic navigation to group details... (QB_NEW_EN_OTHER) --- [grammar] ~298-~298: There might be a mistake here. Context: ...gation to group details upon successful join - Error handling for invalid codes or n... (QB_NEW_EN_OTHER) --- [grammar] ~299-~299: Use a period to end declarative sentences Context: ...r handling for invalid codes or network issues (QB_NEW_EN_OTHER_ERROR_IDS_25) </details> <details> <summary>docs/screens/settlement-screens.md</summary> [grammar] ~1-~1: Use correct spacing Context: # Settlement Screens ## Settlement Summary Screen ### Wirefram... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~3-~3: Use correct spacing Context: ...ttlement Screens ## Settlement Summary Screen ### Wireframe Sketch ``` ┌─────────────────... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~5-~5: Use correct spacing Context: ...ettlement Summary Screen ### Wireframe Sketch ``` ┌─────────────────────────────┐ │ ← Settle Up │ │─────────────────────────────│ │ │ │ Settlement Summary │ │ │ │ ┌─────────────────────┐ │ │ │ Total to settle: │ │ │ │ $247.50 │ │ │ │ │ │ │ │ Across 3 groups │ │ │ └─────────────────────┘ │ │ │ │ Your balances: │ │ │ │ ┌─────────────────────┐ │ │ │ 🏠 Roommates │ │ │ │ You owe: $45.00 │ │ │ │ to Alex, Sam │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ ✈️ Weekend Trip │ │ │ │ You owe: $125.50 │ │ │ │ to Alex │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ 🍽️ Dinner Club │ │ │ │ You're owed: $77.00 │ │ │ │ from Mike, Sarah │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ OPTIMIZE PAYMENTS │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ SETTLE INDIVIDUAL │ │ │ └─────────────────────┘ │ │ │ └─────────────────────────────┘ ``` ### Description Overview of all outstanding... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~52-~52: Use correct spacing Context: ...l amounts and provides clear settlement pathways. ### Key Features - Total settlement amount ... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~60-~60: Use correct spacing Context: ...ual settlement choices - Payment method integration ### Component Breakdown #### Settlement Ov... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~62-~62: Use correct spacing Context: ...yment method integration ### Component Breakdown #### Settlement Overview Card - **Total Amou... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~68-~68: Use correct spacing Context: ...y**: Clear emphasis on total settlement amount #### Group Balance Cards - **Group Identity*... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~74-~74: Use correct spacing Context: ... Options**: Quick settle for individual groups #### Settlement Options - **Optimize Payment... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~76-~76: Use colons correctly Context: ... for individual groups #### Settlement Options - **Optimize Payments**: Algorithm-base... (QB_NEW_EN_OTHER_ERROR_IDS_30) --- [grammar] ~80-~80: Use correct spacing Context: ...ods**: Integration with various payment platforms #### Action Buttons - **Primary Actions**: P... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~85-~85: Use correct spacing Context: ...t Suggestions**: Recommended settlement strategies ### Interactions - Tap group cards to see d... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~88-~88: Make sure to use plural and singular nouns correctly Context: ...tions - Tap group cards to see detailed breakdown - Choose between optimized or individual s... (QB_NEW_EN_OTHER_ERROR_IDS_10) --- [grammar] ~89-~89: There might be a mistake here. Context: ... Choose between optimized or individual settlements - Select payment methods and amounts - ... (QB_NEW_EN_OTHER) --- [grammar] ~90-~90: There might be a mistake here. Context: ...ettlements - Select payment methods and amounts - Confirm settlements with secure payme... (QB_NEW_EN_OTHER) --- [grammar] ~91-~91: There might be a mistake here. Context: ...Confirm settlements with secure payment flow ## Optimized Settlement Screen ### Wirefr... (QB_NEW_EN_OTHER) --- [grammar] ~93-~93: Use correct spacing Context: ...e payment flow ## Optimized Settlement Screen ### Wireframe Sketch ``` ┌─────────────────... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~95-~95: There might be a problem here. Context: ...imized Settlement Screen ### Wireframe Sketch ``` ┌─────────────────────────────┐ │ ← Optimized Settlement │ │─────────────────────────────│ │ │ │ Recommended Payments │ │ │ │ ┌─────────────────────┐ │ │ │ Instead of 6 payments │ │ │ Make only 2 payments │ │ │ Save time & effort! ✨ │ │ └─────────────────────┘ │ │ │ │ Payment Plan: │ │ │ │ ┌─────────────────────┐ │ │ │ 1. Pay Alex │ │ │ │ $93.50 │ │ │ │ [💳 Pay Now] │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ 2. Pay Sam │ │ │ │ $77.00 │ │ │ │ [💳 Pay Now] │ │ │ └─────────────────────┘ │ │ │ │ This will settle: │ │ • Roommates group │ │ • Weekend Trip group │ │ • Your portion in Dinner │ │ │ │ ┌─────────────────────┐ │ │ │ Mike owes you $45 │ │ │ │ [Send Reminder] │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ EXECUTE PLAN │ │ │ └─────────────────────┘ │ │ │ └─────────────────────────────┘ ``` ### Description Algorithmic settlement optimization sho... (QB_NEW_EN_MERGED_MATCH) --- [grammar] ~141-~141: Use correct spacing Context: ... plan with clear benefits and execution options. ### Key Features - Debt optimization algori... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~149-~149: Use correct spacing Context: ...alance tracking - Settlement efficiency metrics ### Component Breakdown #### Optimization ... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~151-~151: Use correct spacing Context: ...ement efficiency metrics ### Component Breakdown #### Optimization Summary - **Transaction Re... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~154-~154: There might be a mistake here. Context: ... Reduction**: Show savings in number of payments - **Efficiency Metrics**: Time and effo... (QB_NEW_EN_OTHER) --- [grammar] ~155-~155: There might be a mistake here. Context: ...ency Metrics**: Time and effort savings visualization - **Algorithm Explanation**: Simple exp... (QB_NEW_EN_OTHER) --- [grammar] ~156-~156: There might be a mistake here. Context: ...n**: Simple explanation of optimization benefits #### Payment Plan - **Sequential Steps**: Nu... (QB_NEW_EN_OTHER) --- [grammar] ~162-~162: Use correct spacing Context: ...s**: Individual action buttons for each payment #### Settlement Coverage - **Affected Groups... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~167-~167: Use correct spacing Context: ...tatus**: Track progress through payment plan #### Outstanding Items - **Money Owed to Use... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~172-~172: There might be a problem here. Context: ...meline**: When user can expect incoming payments ### Interactions - Execute individual payments in recomm... (QB_NEW_EN_MERGED_MATCH) --- [grammar] ~175-~175: There might be a problem here. Context: ...ctions - Execute individual payments in recommended order - Skip or defer specific payments while... (QB_NEW_EN_MERGED_MATCH) --- [grammar] ~176-~176: There might be a mistake here. Context: ...fer specific payments while maintaining optimization - Send reminders for amounts owed to us... (QB_NEW_EN_OTHER) --- [grammar] ~177-~177: Use articles correctly Context: ...on - Send reminders for amounts owed to user - View detailed explanation of optimizatio... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~178-~178: Use articles correctly Context: ...minders for amounts owed to user - View detailed explanation of optimization algorithm ... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~178-~178: There might be a problem here. Context: ... to user - View detailed explanation of optimization algorithm ## Record Payment Screen ### Wireframe Sk... (QB_NEW_EN_MERGED_MATCH) --- [grammar] ~180-~180: Use correct spacing Context: ...timization algorithm ## Record Payment Screen ### Wireframe Sketch ``` ┌─────────────────... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~182-~182: Use correct spacing Context: ...## Record Payment Screen ### Wireframe Sketch ``` ┌─────────────────────────────┐ │ ← Record Payment │ │─────────────────────────────│ │ │ │ Payment to Alex │ │ │ │ ┌─────────────────────┐ │ │ │ Amount │ │ │ │ $ [93.50_______] │ │ │ └─────────────────────┘ │ │ │ │ Payment method │ │ ┌─────────────────────┐ │ │ │ ○ Cash │ │ │ │ ● Venmo │ │ │ │ ○ PayPal │ │ │ │ ○ Bank Transfer │ │ │ │ ○ Other │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ Payment details │ │ │ │ [Reference/note___] │ │ │ └─────────────────────┘ │ │ │ │ This payment settles: │ │ • Roommates: $45.00 │ │ • Weekend Trip: $48.50 │ │ │ │ ┌─────────────────────┐ │ │ │ ☑️ Mark as paid │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ RECORD PAYMENT │ │ │ └─────────────────────┘ │ │ │ └─────────────────────────────┘ ``` ### Description Screen for recording comple... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~225-~225: Use correct spacing Context: ...tomatic balance updates across relevant groups. ### Key Features - Editable payment amount ... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~233-~233: Use correct spacing Context: ...nt platforms - Confirmation and receipt generation ### Component Breakdown #### Payment Detai... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~235-~235: Use correct spacing Context: ...n and receipt generation ### Component Breakdown #### Payment Details - **Amount Field**: Pre... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~240-~240: Use correct spacing Context: ...**: Appropriate currency formatting and validation #### Payment Methods - **Cash**: Manual trac... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~246-~246: Use correct spacing Context: ...er**: Custom payment method with manual tracking #### Payment Reference - **Notes Field**: Op... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~251-~251: Use correct spacing Context: ...oad**: Optional receipt or confirmation attachment #### Settlement Preview - **Affected Balance... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~254-~254: There might be a mistake here. Context: ...es**: Show which group balances will be updated - **Remaining Balances**: Calculate rem... (QB_NEW_EN_OTHER) --- [grammar] ~255-~255: There might be a mistake here. Context: ...es**: Calculate remaining amounts after payment - **Confirmation**: Clear summary befor... (QB_NEW_EN_OTHER) --- [grammar] ~256-~256: There might be a mistake here. Context: ...tion**: Clear summary before finalizing payment ### Interactions - Adjust payment amount wh... (QB_NEW_EN_OTHER) --- [grammar] ~259-~259: There might be a mistake here. Context: ...ent amount while maintaining settlement logic - Select payment method with appropriat... (QB_NEW_EN_OTHER) --- [grammar] ~260-~260: There might be a mistake here. Context: ...ent method with appropriate integration flow - Add payment notes and references - Co... (QB_NEW_EN_OTHER) --- [grammar] ~261-~261: There might be a mistake here. Context: ...ntegration flow - Add payment notes and references - Confirm payment with automatic balanc... (QB_NEW_EN_OTHER) --- [grammar] ~262-~262: There might be a mistake here. Context: ... Confirm payment with automatic balance updates - Generate and share payment confirmati... (QB_NEW_EN_OTHER) --- [grammar] ~263-~263: There might be a mistake here. Context: ...ce updates - Generate and share payment confirmation ## Payment Confirmation Screen ### Wirefr... (QB_NEW_EN_OTHER) --- [grammar] ~265-~265: Use correct spacing Context: ...t confirmation ## Payment Confirmation Screen ### Wireframe Sketch ``` ┌─────────────────... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~267-~267: Use correct spacing Context: ...ment Confirmation Screen ### Wireframe Sketch ``` ┌─────────────────────────────┐ │ ← Payment Confirmed │ │─────────────────────────────│ │ │ │ ✅ │ │ │ │ Payment Successful! │ │ │ │ ┌─────────────────────┐ │ │ │ Payment Details │ │ │ │ │ │ │ │ To: Alex │ │ │ │ Amount: $93.50 │ │ │ │ Method: Venmo │ │ │ │ Date: Today, 2:15pm │ │ │ │ Ref: VM-123456789 │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ Balances Updated │ │ │ │ │ │ │ │ 🏠 Roommates: $0 │ │ │ │ ✈️ Weekend: $0 │ │ │ │ │ │ │ │ New total owed: $0 │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ SHARE RECEIPT │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ DONE │ │ │ └─────────────────────┘ │ │ │ └─────────────────────────────┘ ``` ### Description Confirmation screen showing... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~308-~308: Use correct spacing Context: ... balances, and options to share payment confirmation. ### Key Features - Success confirmation wit... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~316-~316: Use correct spacing Context: ... back to main screens - Payment history integration ### Component Breakdown #### Success Indic... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~318-~318: Use correct spacing Context: ...ment history integration ### Component Breakdown #### Success Indicator - **Visual Confirmati... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~323-~323: Use correct spacing Context: ...k**: Encouraging message for successful transaction #### Payment Summary - **Transaction Details... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~329-~329: Use correct spacing Context: ...**Timestamp**: Exact payment processing time #### Balance Updates - **Before/After**: Cle... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~335-~335: Use correct spacing Context: ...t Status**: Indication of fully settled relationships #### Action Options - **Share Receipt**: Sen... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~338-~338: There might be a mistake here. Context: ...: Send payment confirmation to relevant parties - **Save to Files**: Export payment con... (QB_NEW_EN_OTHER) --- [grammar] ~339-~339: There might be a mistake here. Context: ...iles**: Export payment confirmation for records - **Return Home**: Navigate back to mai... (QB_NEW_EN_OTHER) --- [grammar] ~340-~340: There might be a mistake here. Context: ...eturn Home**: Navigate back to main app screens - **View History**: Access to complete ... (QB_NEW_EN_OTHER) --- [grammar] ~341-~341: There might be a mistake here. Context: ...w History**: Access to complete payment history ### Interactions - Share payment confirmati... (QB_NEW_EN_OTHER) --- [grammar] ~344-~344: There might be a mistake here. Context: ...re payment confirmation through various channels - Save payment details for personal rec... (QB_NEW_EN_OTHER) --- [grammar] ~345-~345: There might be a mistake here. Context: ...els - Save payment details for personal records - Navigate to updated group or friend d... (QB_NEW_EN_OTHER) --- [grammar] ~346-~346: There might be a mistake here. Context: ...s - Navigate to updated group or friend details - Access payment history and analytics ... (QB_NEW_EN_OTHER) --- [grammar] ~347-~347: There might be a mistake here. Context: ...nd details - Access payment history and analytics ## Payment History Screen ### Wireframe S... (QB_NEW_EN_OTHER) --- [grammar] ~349-~349: Use correct spacing Context: ...story and analytics ## Payment History Screen ### Wireframe Sketch ``` ┌─────────────────... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~351-~351: Use correct spacing Context: ...# Payment History Screen ### Wireframe Sketch ``` ┌─────────────────────────────┐ │ ← Payment History │ │─────────────────────────────│ │ │ │ Your Payment History │ │ │ │ Filter: [All ▼] [Dec ▼] │ │ │ │ ┌─────────────────────┐ │ │ │ Dec 15 - Paid Alex │ │ │ │ $93.50 via Venmo │ │ │ │ Settled 2 groups │ │ │ │ [📄] │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ Dec 12 - From Sarah │ │ │ │ $45.00 via PayPal │ │ │ │ Dinner Club payment │ │ │ │ [📄] │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ Dec 10 - Paid Mike │ │ │ │ $30.00 Cash │ │ │ │ Weekend trip │ │ │ │ [📄] │ │ │ └─────────────────────┘ │ │ │ │ Monthly Total │ │ Paid: $123.50 │ │ Received: $45.00 │ │ │ │ ┌─────────────────────┐ │ │ │ EXPORT HISTORY │ │ │ └─────────────────────┘ │ │ │ └─────────────────────────────┘ ``` ### Description Comprehensive payment histo... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~394-~394: Use correct spacing Context: ...s detailed record keeping for financial tracking. ### Key Features - Chronological payment hi... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~398-~398: Use periods with abbreviations Context: ...ry - Payment direction indicators (paid vs received) - Payment method tracking - G... (QB_NEW_EN_OTHER_ERROR_IDS_34) --- [grammar] ~402-~402: Use correct spacing Context: ...Export functionality for tax/accounting purposes ### Component Breakdown #### Filter Contro... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~404-~404: Use correct spacing Context: ... tax/accounting purposes ### Component Breakdown #### Filter Controls - **Payment Type**: All... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~410-~410: Use correct spacing Context: ... - **Group/Person**: Filter by specific relationships #### Payment History Items - **Transaction D... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~417-~417: Use correct spacing Context: ...eipt Access**: Link to detailed payment confirmations #### Summary Statistics - **Period Totals**:... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~429-~429: Use correct spacing Context: ...eports**: Filtered exports for specific needs ### Interactions - Filter and search paymen... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~432-~432: There might be a mistake here. Context: ...r and search payment history by various criteria - Tap payment items to view detailed re... (QB_NEW_EN_OTHER) --- [grammar] ~433-~433: There might be a mistake here. Context: ...ia - Tap payment items to view detailed receipts - Export payment data in multiple forma... (QB_NEW_EN_OTHER) --- [grammar] ~434-~434: There might be a mistake here. Context: ...eipts - Export payment data in multiple formats - View payment trends and analytics - A... (QB_NEW_EN_OTHER) --- [grammar] ~435-~435: There might be a mistake here. Context: ...tiple formats - View payment trends and analytics - Access dispute resolution for incorre... (QB_NEW_EN_OTHER) --- [grammar] ~436-~436: Use a period to end declarative sentences Context: ...Access dispute resolution for incorrect payments (QB_NEW_EN_OTHER_ERROR_IDS_25) </details> <details> <summary>docs/folder-structure.md</summary> [grammar] ~1-~1: Use correct spacing Context: # React Native + Expo Folder Structure ## Overview This document outlines the rec... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~4-~4: Use correct spacing Context: ...lability using a **feature-based domain architecture**. ## 📁 Complete Folder Structure ``` /app ... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~6-~6: Use correct spacing Context: ... architecture**. ## 📁 Complete Folder Structure ``` /app ├── navigation/ # Central navigation config (React Navigation) │ ├── AppNavigator.tsx # Main app navigation container │ ├── AuthNavigator.tsx # Authentication flow navigation │ ├── MainTabNavigator.tsx # Bottom tab navigation │ ├── GroupsNavigator.tsx # Groups stack navigation │ ├── ExpenseNavigator.tsx # Expense creation flow navigation │ └── types.ts # Navigation type definitions │ ├── screens/ # Screen components grouped by feature │ ├── Auth/ │ │ ├── LoginScreen.tsx │ │ ├── SignupScreen.tsx │ │ ├── ForgotPasswordScreen.tsx │ │ └── OnboardingScreen.tsx │ │ │ ├── Home/ │ │ ├── HomeScreen.tsx │ │ ├── NotificationsScreen.tsx │ │ └── ActivityDetailScreen.tsx │ │ │ ├── Groups/ │ │ ├── GroupsListScreen.tsx │ │ ├── GroupDetailsScreen.tsx │ │ ├── CreateGroupScreen.tsx │ │ ├── JoinGroupScreen.tsx │ │ ├── GroupSettingsScreen.tsx │ │ └── GroupMembersScreen.tsx │ │ │ ├── Expenses/ │ │ ├── AddExpenseStep1Screen.tsx # Basic info (amount, description, category) │ │ ├── AddExpenseStep2Screen.tsx # Payment selection (who paid) │ │ ├── AddExpenseStep3Screen.tsx # Split options (equal/unequal) │ │ ├── ExpenseDetailScreen.tsx │ │ ├── ExpenseHistoryScreen.tsx │ │ └── EditExpenseScreen.tsx │ │ │ ├── Friends/ │ │ ├── FriendsScreen.tsx │ │ ├── FriendDetailScreen.tsx │ │ ├── AddFriendScreen.tsx │ │ └── FriendRequestsScreen.tsx │ │ │ ├── Settlements/ │ │ ├── SettlementsScreen.tsx │ │ ├── OptimizedSettlementsScreen.tsx │ │ ├── SettleUpScreen.tsx │ │ ├── PaymentMethodScreen.tsx │ │ └── PaymentConfirmationScreen.tsx │ │ │ └── Settings/ │ ├── ProfileScreen.tsx │ ├── PreferencesScreen.tsx │ ├── PaymentMethodsScreen.tsx │ └── SecurityScreen.tsx │ ├── components/ # Reusable UI components │ ├── common/ # Generic Material 3 components │ │ ├── Button/ │ │ │ ├── Button.tsx │ │ │ ├── Button.styles.ts │ │ │ └── Button.types.ts │ │ │ │ │ ├── Card/ │ │ │ ├── Card.tsx │ │ │ └── Card.styles.ts │ │ │ │ │ ├── TextField/ │ │ │ ├── TextField.tsx │ │ │ ├── TextField.styles.ts │ │ │ └── TextField.types.ts │ │ │ │ │ ├── RadioGroup/ │ │ ├── Checkbox/ │ │ ├── Avatar/ │ │ ├── Badge/ │ │ ├── Chip/ │ │ ├── Snackbar/ │ │ ├── Modal/ │ │ └── LoadingSpinner/ │ │ │ ├── layout/ # Layout components │ │ ├── AppBar/ │ │ │ ├── AppBar.tsx │ │ │ └── AppBar.styles.ts │ │ │ │ │ ├── BottomNavigation/ │ │ │ ├── BottomNavigation.tsx │ │ │ └── BottomNavigation.styles.ts │ │ │ │ │ ├── Screen/ │ │ │ ├── Screen.tsx # Base screen wrapper with common layout │ │ │ └── Screen.styles.ts │ │ │ │ │ ├── FloatingActionButton/ │ │ ├── Container/ │ │ └── SafeAreaWrapper/ │ │ │ └── feature/ # Feature-specific components │ ├── expenses/ │ │ ├── ExpenseCard/ │ │ │ ├── ExpenseCard.tsx │ │ │ ├── ExpenseCard.styles.ts │ │ │ └── ExpenseCard.types.ts │ │ │ │ │ ├── ExpenseForm/ │ │ ├── ExpenseList/ │ │ ├── SplitOptions/ │ │ │ ├── EqualSplit.tsx │ │ │ ├── UnequalSplit.tsx │ │ │ ├── SharesSplit.tsx │ │ │ ├── PercentageSplit.tsx │ │ │ └── ExactAmountSplit.tsx │ │ │ │ │ ├── CategorySelector/ │ │ ├── ReceiptCapture/ │ │ └── PaymentSelector/ │ │ │ ├── groups/ │ │ ├── GroupCard/ │ │ ├── GroupList/ │ │ ├── GroupHeader/ │ │ ├── GroupSummary/ │ │ ├── MemberList/ │ │ └── InviteMember/ │ │ │ ├── friends/ │ │ ├── FriendCard/ │ │ ├── FriendList/ │ │ ├── BalanceIndicator/ │ │ └── FriendSearch/ │ │ │ ├── settlements/ │ │ ├── SettlementCard/ │ │ ├── OptimizedSettlementList/ │ │ ├── PaymentMethodSelector/ │ │ ├── BalanceSummary/ │ │ └── DebtVisualization/ │ │ │ └── analytics/ │ ├── SpendingChart/ │ ├── MonthlyChart/ │ └── CategoryBreakdown/ │ ├── services/ # API service calls and business logic │ ├── api/ │ │ ├── client.ts # Base API client configuration │ │ ├── interceptors.ts # Request/response interceptors │ │ └── endpoints.ts # API endpoint constants │ │ │ ├── auth/ │ │ ├── authService.ts # Authentication API calls │ │ ├── googleAuth.ts # Google Sign-in integration │ │ └── tokenService.ts # Token management │ │ │ ├── groups/ │ │ ├── groupService.ts # Group CRUD operations │ │ ├── memberService.ts # Group member management │ │ └── inviteService.ts # Group invitation handling │ │ │ ├── expenses/ │ │ ├── expenseService.ts # Expense CRUD operations │ │ ├── splitService.ts # Split calculation logic │ │ └── receiptService.ts # Receipt processing │ │ │ ├── settlements/ │ │ ├── settlementService.ts # Settlement calculations │ │ ├── optimizationService.ts # Debt optimization algorithms │ │ └── paymentService.ts # Payment recording │ │ │ ├── users/ │ │ ├── userService.ts # User profile management │ │ └── friendsService.ts # Friends management │ │ │ └── notifications/ │ ├── notificationService.ts │ ├── pushNotifications.ts │ └── emailService.ts │ ├── hooks/ # Reusable custom hooks │ ├── auth/ │ │ ├── useAuth.ts # Authentication state and methods │ │ ├── useGoogleAuth.ts # Google Sign-in hook │ │ └── useTokenRefresh.ts # Automatic token refresh │ │ │ ├── data/ │ │ ├── useGroups.ts # Groups data fetching and management │ │ ├── useExpenses.ts # Expenses data operations │ │ ├── useFriends.ts # Friends data management │ │ ├── useSettlements.ts # Settlement calculations │ │ └── useNotifications.ts # Notifications management │ │ │ ├── ui/ │ │ ├── useTheme.ts # Theme switching and customization │ │ ├── useModal.ts # Modal state management │ │ ├── useSnackbar.ts # Snackbar notifications │ │ └── useKeyboard.ts # Keyboard handling │ │ │ └── utils/ │ ├── useDebounce.ts # Debounced values │ ├── useLocalStorage.ts # Local storage operations │ ├── useNetworkStatus.ts # Network connectivity │ └── usePermissions.ts # Device permissions │ ├── store/ # Global state management │ ├── slices/ # Redux Toolkit slices │ │ ├── authSlice.ts # User authentication state │ │ ├── groupSlice.ts # Groups data state │ │ ├── expenseSlice.ts # Expenses state │ │ ├── friendSlice.ts # Friends data state │ │ ├── settlementSlice.ts # Settlement calculations state │ │ ├── uiSlice.ts # UI state (modals, loading, etc.) │ │ └── notificationSlice.ts # Notifications state │ │ │ ├── middleware/ │ │ ├── authMiddleware.ts # Authentication middleware │ │ ├── apiMiddleware.ts # API call middleware │ │ └── persistMiddleware.ts # Data persistence middleware │ │ │ ├── selectors/ │ │ ├── authSelectors.ts # Authentication selectors │ │ ├── groupSelectors.ts # Group data selectors │ │ └── expenseSelectors.ts # Expense data selectors │ │ │ ├── hooks.ts # Typed Redux hooks │ ├── store.ts # Redux store configuration │ └── types.ts # Redux state type definitions │ ├── assets/ # Static assets │ ├── fonts/ # Custom fonts │ │ ├── Roboto-Regular.ttf │ │ ├── Roboto-Medium.ttf │ │ └── Roboto-Bold.ttf │ │ │ ├── images/ # Static images │ │ ├── logo/ │ │ ├── icons/ │ │ ├── illustrations/ │ │ └── placeholders/ │ │ │ ├── lottie/ # Animation files │ │ ├── loading.json │ │ ├── success.json │ │ └── empty-state.json │ │ │ └── audio/ # Sound files │ ├── notification.mp3 │ └── success.mp3 │ ├── constants/ # App constants and configuration │ ├── theme/ │ │ ├── colors.ts # Material 3 color palette │ │ ├── typography.ts # Typography scale and styles │ │ ├── spacing.ts # Spacing system │ │ ├── shadows.ts # Elevation and shadow styles │ │ └── theme.ts # Main theme configuration │ │ │ ├── api.ts # API endpoints and configuration │ ├── categories.ts # Expense categories │ ├── currencies.ts # Supported currencies │ ├── dimensions.ts # Screen dimensions and breakpoints │ └── validation.ts # Validation rules and messages │ ├── utils/ # Utility functions and helpers │ ├── formatters/ │ │ ├── currency.ts # Currency formatting │ │ ├── date.ts # Date formatting │ │ ├── number.ts # Number formatting │ │ └── text.ts # Text manipulation │ │ │ ├── validators/ │ │ ├── email.ts # Email validation │ │ ├── password.ts # Password validation │ │ ├── amount.ts # Amount validation │ │ └── forms.ts # Form validation schemas │ │ │ ├── calculations/ │ │ ├── splitCalculator.ts # Expense split calculations │ │ ├── balanceCalculator.ts # Balance calculations │ │ ├── settlementOptimizer.ts # Settlement optimization │ │ └── analytics.ts # Analytics calculations │ │ │ ├── storage/ │ │ ├── asyncStorage.ts # AsyncStorage helpers │ │ ├── secureStorage.ts # Secure storage for sensitive data │ │ └── cache.ts # Caching utilities │ │ │ ├── permissions/ │ │ ├── camera.ts # Camera permissions │ │ ├── notifications.ts # Notification permissions │ │ └── contacts.ts # Contacts permissions │ │ │ └── helpers/ │ ├── deviceInfo.ts # Device information utilities │ ├── network.ts # Network utilities │ ├── deepLinking.ts # Deep linking handlers │ └── errorHandling.ts # Error handling utilities │ ├── types/ # TypeScript type definitions │ ├── api.ts # API response types │ ├── entities.ts # Business entity types │ ├── navigation.ts # Navigation parameter types │ ├── forms.ts # Form data types │ └── common.ts # Common shared types │ ├── config/ # App configuration │ ├── env.ts # Environment configuration │ ├── firebase.ts # Firebase configuration │ ├── analytics.ts # Analytics configuration │ └── notifications.ts # Push notifications configuration │ ├── __tests__/ # Test files │ ├── components/ # Component tests │ ├── screens/ # Screen tests │ ├── hooks/ # Hook tests │ ├── services/ # Service tests │ ├── utils/ # Utility tests │ └── __mocks__/ # Mock files │ ├── App.tsx # Root application component ├── index.js # Entry point ├── app.json # Expo configuration ├── package.json # Dependencies and scripts ├── tsconfig.json # TypeScript configuration ├── babel.config.js # Babel configuration ├── metro.config.js # Metro bundler configuration └── .env # Environment variables ``` ## 🎯 Key Architecture Principles ### 1. ... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~338-~338: Use correct spacing Context: ...t variables ``` ## 🎯 Key Architecture Principles ### 1. Feature-Based Organization - Screens... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~341-~341: There might be a mistake here. Context: ... and logic for each feature are grouped together - Easier to locate and maintain related... (QB_NEW_EN_OTHER) --- [grammar] ~342-~342: There might be a mistake here. Context: ...- Easier to locate and maintain related code - Supports team collaboration with clea... (QB_NEW_EN_OTHER) --- [grammar] ~343-~343: There might be a mistake here. Context: ...team collaboration with clear ownership boundaries ### 2. Separation of Concerns - **Screens**... (QB_NEW_EN_OTHER) --- [grammar] ~351-~351: Use correct spacing Context: ...agement - **Utils**: Pure functions and helpers ### 3. Material 3 Compliance - Theme system... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~356-~356: Use correct spacing Context: ...nsistent spacing, typography, and color usage ### 4. TypeScript First - Comprehensive typ... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~361-~361: Use correct spacing Context: ...- Strongly typed API responses and form data ### 5. Testing Strategy - Collocated test f... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~367-~367: Use correct spacing Context: ...Library - E2E testing for critical user flows ## 📱 Screen Organization ### Navigation ... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~369-~369: Use correct spacing Context: ...g for critical user flows ## 📱 Screen Organization ### Navigation Structure ``` App ├── AuthNa... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~371-~371: Use correct spacing Context: ... 📱 Screen Organization ### Navigation Structure ``` App ├── AuthNavigator (Stack) │ ├── LoginScreen │ ├── SignupScreen │ └── OnboardingScreen │ └── MainTabNavigator (Bottom Tabs) ├── HomeTab (Stack) │ ├── HomeScreen │ ├── NotificationsScreen │ └── ActivityDetailScreen │ ├── GroupsTab (Stack) │ ├── GroupsListScreen │ ├── GroupDetailsScreen │ ├── CreateGroupScreen │ ├── JoinGroupScreen │ └── ExpenseFlow (Modal Stack) │ ├── AddExpenseStep1Screen │ ├── AddExpenseStep2Screen │ └── AddExpenseStep3Screen │ └── FriendsTab (Stack) ├── FriendsScreen ├── FriendDetailScreen └── SettlementFlow (Modal Stack) ├── SettlementsScreen ├── OptimizedSettlementsScreen └── SettleUpScreen ``` ## 🔧 Development Workflow ### Component ... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~404-~404: Use correct spacing Context: ...─ SettleUpScreen ``` ## 🔧 Development Workflow ### Component Development 1. Create compone... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~407-~407: Use articles correctly Context: ...ow ### Component Development 1. Create component folder with TypeScript file 2. Define p... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~407-~407: There might be a problem here. Context: ...lopment 1. Create component folder with TypeScript file 2. Define props interface in `.types.ts... (QB_NEW_EN_MERGED_MATCH) --- [grammar] ~408-~408: Use articles correctly Context: ...t folder with TypeScript file 2. Define props interface in `.types.ts` file 3. Implem... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~408-~408: Use articles correctly Context: ...peScript file 2. Define props interface in `.types.ts` file 3. Implement styles in... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~408-~408: There might be a mistake here. Context: .... Define props interface in `.types.ts` file 3. Implement styles in `.styles.ts` fil... (QB_NEW_EN_OTHER) --- [grammar] ~409-~409: Use articles correctly Context: ...in `.types.ts` file 3. Implement styles in `.styles.ts` file 4. Add component test... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~409-~409: There might be a mistake here. Context: ...ile 3. Implement styles in `.styles.ts` file 4. Add component tests in `__tests__` f... (QB_NEW_EN_OTHER) --- [grammar] ~410-~410: Use articles correctly Context: ....styles.ts` file 4. Add component tests in `__tests__` folder 5. Export from index... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~410-~410: There might be a mistake here. Context: ...e 4. Add component tests in `__tests__` folder 5. Export from index file for clean imp... (QB_NEW_EN_OTHER) --- [grammar] ~411-~411: Use articles correctly Context: ...ts in `__tests__` folder 5. Export from index file for clean imports ### Screen Deve... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~411-~411: There might be a mistake here. Context: ...der 5. Export from index file for clean imports ### Screen Development 1. Create screen com... (QB_NEW_EN_OTHER) --- [grammar] ~414-~414: Use articles correctly Context: ...ports ### Screen Development 1. Create screen component in appropriate feature folder... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~414-~414: Use articles correctly Context: ...velopment 1. Create screen component in appropriate feature folder 2. Implement navigation ... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~414-~414: There might be a mistake here. Context: ...screen component in appropriate feature folder 2. Implement navigation types for param... (QB_NEW_EN_OTHER) --- [grammar] ~415-~415: There might be a mistake here. Context: ...older 2. Implement navigation types for parameters 3. Connect to global state via hooks 4.... (QB_NEW_EN_OTHER) --- [grammar] ~416-~416: There might be a mistake here. Context: ...rameters 3. Connect to global state via hooks 4. Add business logic via custom hooks ... (QB_NEW_EN_OTHER) --- [grammar] ~417-~417: There might be a mistake here. Context: ... hooks 4. Add business logic via custom hooks 5. Style with Material 3 theme system ... (QB_NEW_EN_OTHER) --- [grammar] ~418-~418: Use articles correctly Context: ...ss logic via custom hooks 5. Style with Material 3 theme system ### State Management 1.... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~418-~418: There might be a mistake here. Context: ...om hooks 5. Style with Material 3 theme system ### State Management 1. Define entity types... (QB_NEW_EN_OTHER) --- [grammar] ~421-~421: Use articles correctly Context: ...State Management 1. Define entity types in `types/` folder 2. Create Redux slice w... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~421-~421: There might be a mistake here. Context: ...ment 1. Define entity types in `types/` folder 2. Create Redux slice with actions and ... (QB_NEW_EN_OTHER) --- [grammar] ~422-~422: Use articles correctly Context: ...tity types in `types/` folder 2. Create Redux slice with actions and reducers 3. Impl... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~422-~422: There might be a mistake here. Context: ... 2. Create Redux slice with actions and reducers 3. Implement selectors for derived stat... (QB_NEW_EN_OTHER) --- [grammar] ~423-~423: There might be a mistake here. Context: ...cers 3. Implement selectors for derived state 4. Create custom hooks for component in... (QB_NEW_EN_OTHER) --- [grammar] ~424-~424: There might be a mistake here. Context: ...te 4. Create custom hooks for component integration 5. Add middleware for side effects ## ... (QB_NEW_EN_OTHER) --- [grammar] ~425-~425: There might be a mistake here. Context: ... integration 5. Add middleware for side effects ## 🚀 Performance Considerations ### Code... (QB_NEW_EN_OTHER) --- [grammar] ~427-~427: Use correct spacing Context: ...are for side effects ## 🚀 Performance Considerations ### Code Splitting - Lazy load screens usin... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~430-~430: There might be a mistake here. Context: ...litting - Lazy load screens using React Navigation - Split large components into smaller c... (QB_NEW_EN_OTHER) --- [grammar] ~431-~431: There might be a mistake here. Context: ...n - Split large components into smaller chunks - Use dynamic imports for heavy librari... (QB_NEW_EN_OTHER) --- [grammar] ~432-~432: There might be a mistake here. Context: ... chunks - Use dynamic imports for heavy libraries ### Optimization Strategies - Implement Fla... (QB_NEW_EN_OTHER) --- [grammar] ~435-~435: There might be a mistake here. Context: ...ies - Implement FlatList for large data sets - Use React.memo for expensive componen... (QB_NEW_EN_OTHER) --- [grammar] ~436-~436: There might be a mistake here. Context: ...ata sets - Use React.memo for expensive components - Optimize image loading with progressi... (QB_NEW_EN_OTHER) --- [grammar] ~437-~437: There might be a mistake here. Context: ...Optimize image loading with progressive enhancement - Cache API responses with React Query ... (QB_NEW_EN_OTHER) --- [grammar] ~438-~438: There might be a mistake here. Context: ...cement - Cache API responses with React Query ### Bundle Management - Minimize app bundle... (QB_NEW_EN_OTHER) --- [grammar] ~441-~441: There might be a mistake here. Context: ...nt - Minimize app bundle size with tree shaking - Use Hermes JavaScript engine for bett... (QB_NEW_EN_OTHER) --- [grammar] ~442-~442: Use articles correctly Context: ...app bundle size with tree shaking - Use Hermes JavaScript engine for better performanc... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~442-~442: There might be a mistake here. Context: ...Use Hermes JavaScript engine for better performance - Implement over-the-air updates with E... (QB_NEW_EN_OTHER) --- [grammar] ~443-~443: There might be a mistake here. Context: ...mplement over-the-air updates with Expo Updates This folder structure ensures maintaina... (QB_NEW_EN_OTHER) --- [grammar] ~445-~445: There might be a mistake here. Context: ... Updates This folder structure ensures maintainability, scalability, and follows React Native best practice... (QB_NEW_EN_OTHER) </details> <details> <summary>docs/screens/main-navigation.md</summary> [grammar] ~1-~1: Use correct spacing Context: # Main Navigation & Home Screen ## Home Screen ### Wireframe Sketch ``` ┌... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~3-~3: Use correct spacing Context: ... Main Navigation & Home Screen ## Home Screen ### Wireframe Sketch ``` ┌─────────────────... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~5-~5: Use correct spacing Context: ...e Screen ## Home Screen ### Wireframe Sketch ``` ┌─────────────────────────────┐ │ SplitWiser [🔔] [👤] │ │─────────────────────────────│ │ │ │ Overall Balance │ │ ┌─────────────────────┐ │ │ │ You are owed: $125 │ │ │ └─────────────────────┘ │ │ │ │ Recent Activity │ │ ┌─────────────────────┐ │ │ │ Dinner with Alex │ │ │ │ You paid: $60 │ │ │ │ You lent: $30 │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ Weekend Trip │ │ │ │ Alex paid: $45 │ │ │ │ You owe: $15 │ │ │ └─────────────────────┘ │ │ │ │ Monthly Summary │ │ [Chart visualization] │ │ │ │ │ │ [HOME] [GROUPS] [FRIENDS] │ └─────────────────────────────┘ ``` ### Description Dashboard showing overall b... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~38-~38: Use articles correctly Context: ...ly spending analytics. Top bar includes notification bell icon and profile avatar. Bottom na... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~38-~38: Use articles correctly Context: ...bar includes notification bell icon and profile avatar. Bottom navigation with three ma... (QB_NEW_EN_OTHER_ERROR_IDS_11) --- [grammar] ~38-~38: Use correct spacing Context: ...atar. Bottom navigation with three main tabs. ### Key Features - App bar with notificatio... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~46-~46: Use correct spacing Context: ...l-to-refresh functionality for updating data ### Component Breakdown #### App Bar - **T... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~48-~48: Use correct spacing Context: ...nality for updating data ### Component Breakdown #### App Bar - **Title**: "SplitWiser" using... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~54-~54: Use correct spacing Context: ...Background**: Surface color with subtle elevation #### Overall Balance Card - **Card Type**: E... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~60-~60: Use correct spacing Context: ...on**: Tappable to view detailed balance breakdown #### Recent Activity Section - **Section Hea... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~68-~68: Use correct spacing Context: ...information (`bodySmall`) - Timestamp (`labelSmall`) #### Monthly Summary - **Chart Component**: ... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~74-~74: Use correct spacing Context: ...gories**: Spending breakdown by expense categories #### Bottom Navigation - **Tabs**: Home, Gro... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~80-~80: Use correct spacing Context: ...ort**: Notification badges on tabs when relevant ### Interactions - **Pull to Refresh**: Swi... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~83-~83: There might be a mistake here. Context: ...to Refresh**: Swipe down to refresh all data - **Card Taps**: Navigate to detailed v... (QB_NEW_EN_OTHER) --- [grammar] ~84-~84: There might be a mistake here. Context: ...a - **Card Taps**: Navigate to detailed views - **Notification Tap**: Open notificati... (QB_NEW_EN_OTHER) --- [grammar] ~85-~85: There might be a problem here. Context: ...iled views - **Notification Tap**: Open notifications screen - **Profile Tap**: Open profile/setting... (QB_NEW_EN_MERGED_MATCH) --- [grammar] ~86-~86: There might be a problem here. Context: ...ications screen - **Profile Tap**: Open profile/settings menu - **Chart Interaction**: Tap chart segm... (QB_NEW_EN_MERGED_MATCH) --- [grammar] ~87-~87: There might be a mistake here. Context: ...t Interaction**: Tap chart segments for details ### Data States - **Loading State**: Skelet... (QB_NEW_EN_OTHER) --- [grammar] ~93-~93: Use correct spacing Context: ...*Offline State**: Cached data with sync indicator ## Notifications Screen ### Wireframe Ske... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~95-~95: Use correct spacing Context: ...a with sync indicator ## Notifications Screen ### Wireframe Sketch ``` ┌─────────────────... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~97-~97: There might be a problem here. Context: ... ## Notifications Screen ### Wireframe Sketch ``` ┌─────────────────────────────┐ │ ← Notifications │ │─────────────────────────────│ │ │ │ Today │ │ ┌─────────────────────┐ │ │ │ 🔔 Alex added expense │ │ │ │ "Dinner" - $45 │ │ │ │ Weekend Trip • 2h ago │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ 💰 Sarah settled up │ │ │ │ Paid you $25 │ │ │ │ Apartment • 4h ago │ │ │ └─────────────────────┘ │ │ │ │ Yesterday │ │ ┌─────────────────────┐ │ │ │ 👥 New group invite │ │ │ │ "Book Club" │ │ │ │ From John • 1d ago │ │ │ └─────────────────────┘ │ │ │ │ │ │ [Mark all as read] │ │ │ └─────────────────────────────┘ ``` ### Description Chronologically organized notifications... (QB_NEW_EN_MERGED_MATCH) --- [grammar] ~130-~130: Use correct spacing Context: ...h clear visual hierarchy and actionable items. ### Key Features - Grouped by date sections... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~135-~135: Use hyphens correctly Context: ...on types with appropriate icons - Clear call-to-action for each notification - Mark as ... (QB_NEW_EN_OTHER_ERROR_IDS_29) --- [grammar] ~137-~137: Use correct spacing Context: ...unctionality - Deep linking to relevant screens ### Notification Types - **Expense Added**:... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~144-~144: Use correct spacing Context: ...nce changes - **Reminder**: Payment due reminders ## Profile Menu ### Wireframe Sketch ``` ... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~146-~146: Use correct spacing Context: ...er**: Payment due reminders ## Profile Menu ### Wireframe Sketch ``` ┌─────────────────... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~148-~148: Use correct spacing Context: ...minders ## Profile Menu ### Wireframe Sketch ``` ┌─────────────────────────────┐ │ ← Profile │ │─────────────────────────────│ │ │ │ [Large Avatar] │ │ John Doe │ │ john.doe@email.com │ │ │ │ ┌─────────────────────┐ │ │ │ 📝 Edit Profile │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ 💳 Payment Methods │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ ⚙️ Settings │ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ 🌙 Dark Mode │ ⚬ │ │ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ │ │ │ 🚪 Log Out │ │ │ └─────────────────────┘ │ │ │ └─────────────────────────────┘ ``` ### Description User profile management wit... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~182-~182: Use correct spacing Context: ...management with key account actions and preferences. ### Key Features - Large profile picture wi... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~188-~188: Use correct spacing Context: ... mode toggle - Clear logout option with confirmation ### Menu Options - **Edit Profile**: Change... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~191-~191: Insert the missing word Context: ...ptions - **Edit Profile**: Change name, email, profile picture - **Payment Methods**: ... (QB_NEW_EN_OTHER_ERROR_IDS_32) --- [grammar] ~191-~191: There might be a mistake here. Context: ... Profile**: Change name, email, profile picture - **Payment Methods**: Manage linked pa... (QB_NEW_EN_OTHER) --- [grammar] ~192-~192: There might be a mistake here. Context: ...ayment Methods**: Manage linked payment accounts - **Settings**: App preferences and pri... (QB_NEW_EN_OTHER) --- [grammar] ~193-~193: There might be a mistake here. Context: ...Settings**: App preferences and privacy settings - **Dark Mode**: Toggle between light a... (QB_NEW_EN_OTHER) --- [grammar] ~194-~194: There might be a mistake here. Context: ...k Mode**: Toggle between light and dark themes - **Log Out**: Sign out with confirmati... (QB_NEW_EN_OTHER) --- [grammar] ~195-~195: There might be a mistake here. Context: ...**Log Out**: Sign out with confirmation dialog ## Activity Detail Screen ### Wireframe S... (QB_NEW_EN_OTHER) --- [grammar] ~197-~197: Use correct spacing Context: ...confirmation dialog ## Activity Detail Screen ### Wireframe Sketch ``` ┌─────────────────... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~199-~199: Use correct spacing Context: ...# Activity Detail Screen ### Wireframe Sketch ``` ┌─────────────────────────────┐ │ ← Activity Details │ │─────────────────────────────│ │ │ │ Dinner at Luigi's │ │ $85.50 • Food │ │ June 28, 2024 • 7:30 PM │ │ │ │ ┌─────────────────────┐ │ │ │ Paid by: You │ │ │ │ Split: Equally (4) │ │ │ │ Group: Weekend Trip │ │ │ └─────────────────────┘ │ │ │ │ Split Details │ │ ┌─────────────────────┐ │ │ │ You $21.38 │ │ │ │ Alex $21.38 │ │ │ │ Sarah $21.37 │ │ │ │ John $21.37 │ │ │ └─────────────────────┘ │ │ │ │ [ Receipt Image ] │ │ │ │ │ │ [EDIT] [DELETE] │ │ │ └─────────────────────────────┘ ``` ### Description Detailed view of a single e... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~232-~232: Use correct spacing Context: ... showing all participants, amounts, and metadata. ### Key Features - Complete expense informa... (QB_NEW_EN_OTHER_ERROR_IDS_5) --- [grammar] ~239-~239: Use correct spacing Context: ...for expense creator - Group context and navigation This home navigation structure provides... (QB_NEW_EN_OTHER_ERROR_IDS_5) </details> </details> <details> <summary>🪛 markdownlint-cli2 (0.17.2)</summary> <details> <summary>ui-poc/README.md</summary> 18-18: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 23-23: Fenced code blocks should have a language specified (MD040, fenced-code-language) </details> <details> <summary>docs/screens/friends-screens.md</summary> 6-6: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 83-83: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 175-175: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 262-262: Fenced code blocks should have a language specified (MD040, fenced-code-language) </details> <details> <summary>docs/screens/auth-screens.md</summary> 6-6: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 67-67: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 124-124: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 164-164: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 187-187: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 210-210: Fenced code blocks should have a language specified (MD040, fenced-code-language) </details> <details> <summary>docs/screens/expense-creation.md</summary> 6-6: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 91-91: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 166-166: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 244-244: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 323-323: Fenced code blocks should have a language specified (MD040, fenced-code-language) </details> <details> <summary>docs/screens/groups-screens.md</summary> 6-6: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 69-69: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 154-154: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 231-231: Fenced code blocks should have a language specified (MD040, fenced-code-language) </details> <details> <summary>docs/screens/settlement-screens.md</summary> 6-6: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 96-96: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 183-183: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 268-268: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 352-352: Fenced code blocks should have a language specified (MD040, fenced-code-language) </details> <details> <summary>docs/folder-structure.md</summary> 8-8: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 372-372: Fenced code blocks should have a language specified (MD040, fenced-code-language) </details> <details> <summary>docs/screens/main-navigation.md</summary> 6-6: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 98-98: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 149-149: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 200-200: Fenced code blocks should have a language specified (MD040, fenced-code-language) </details> </details> <details> <summary>🪛 Ruff (0.11.9)</summary> <details> <summary>ui-poc/pages/Friends.py</summary> 2-2: `requests` imported but unused Remove unused import: `requests` (F401) </details> <details> <summary>ui-poc/pages/Groups.py</summary> 4-4: `json` imported but unused Remove unused import: `json` (F401) --- 52-52: f-string without any placeholders Remove extraneous `f` prefix (F541) --- 83-83: Do not use bare `except` (E722) --- 92-92: f-string without any placeholders Remove extraneous `f` prefix (F541) --- 100-100: Do not use bare `except` (E722) --- 125-125: Do not use bare `except` (E722) --- 137-137: Do not use bare `except` (E722) --- 162-162: Do not use bare `except` (E722) --- 171-171: f-string without any placeholders Remove extraneous `f` prefix (F541) --- 181-181: Do not use bare `except` (E722) --- 197-198: Use a single `with` statement with multiple contexts instead of nested `with` statements (SIM117) --- 220-221: Use a single `with` statement with multiple contexts instead of nested `with` statements (SIM117) --- 298-299: Use a single `with` statement with multiple contexts instead of nested `with` statements (SIM117) --- 683-683: Do not use bare `except` (E722) </details> <details> <summary>ui-poc/Home.py</summary> 4-4: `json` imported but unused Remove unused import: `json` (F401) --- 91-92: Use a single `with` statement with multiple contexts instead of nested `with` statements Combine `with` statements (SIM117) --- 109-110: Use a single `with` statement with multiple contexts instead of nested `with` statements (SIM117) --- 142-143: Use a single `with` statement with multiple contexts instead of nested `with` statements (SIM117) --- 164-165: Use a single `with` statement with multiple contexts instead of nested `with` statements (SIM117) --- 250-251: Use a single `with` statement with multiple contexts instead of nested `with` statements (SIM117) --- 255-255: Local variable `expense_date` is assigned to but never used Remove assignment to unused variable `expense_date` (F841) --- 330-330: Do not use bare `except` (E722) </details> </details> <details> <summary>🪛 Checkov (3.2.334)</summary> <details> <summary>ui-poc/openapi.json</summary> [HIGH] 1: Ensure that the global security field has rules defined (CKV_OPENAPI_4) --- [HIGH] 1: Ensure that security operations is not empty. (CKV_OPENAPI_5) --- [MEDIUM] 1: Ensure that arrays have a maximum number of items (CKV_OPENAPI_21) </details> </details> </details> <details> <summary>🔇 Additional comments (4)</summary><blockquote> <details> <summary>ui-poc/requirements.txt (1)</summary> `1-4`: **LGTM! Requirements are appropriate for the Streamlit UI POC.** The dependency versions and constraints are well-chosen: - Streamlit >=1.24.0 ensures recent features and security fixes - Requests >=2.31.0 provides reliable HTTP client functionality - Python-dateutil >=2.8.2 handles date parsing needs </details> <details> <summary>ui-poc/README.md (1)</summary> `1-47`: **Excellent comprehensive documentation for the UI POC.** The README provides thorough coverage of features, setup instructions, API connection details, and session state management. This will be very helpful for developers working with the POC. </details> <details> <summary>ui-poc/pages/Friends.py (1)</summary> `9-12`: **Good authentication check pattern.** The authentication check using session state is consistent with the overall POC architecture and provides appropriate user feedback. </details> <details> <summary>docs/frontend-ui-design.md (1)</summary> `1-49`: **Excellent comprehensive frontend design documentation.** This documentation provides thorough coverage of the technology stack, UX principles, navigation structure, and implementation notes. The organization across multiple documents and the Material 3 design system approach are well-structured for maintainability. </details> </blockquote></details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
| @@ -0,0 +1 @@ | |||
| {"openapi":"3.1.0","info":{"title":"Splitwiser API","description":"Backend API for Splitwiser expense tracking application","version":"1.0.0"},"paths":{"/{path}":{"options":{"summary":"Options Handler","description":"Handle all OPTIONS requests","operationId":"options_handler__path__options","parameters":[{"name":"path","in":"path","required":true,"schema":{"type":"string","title":"Path"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/health":{"get":{"summary":"Health Check","description":"Returns the health status of the Splitwiser API service.\n\nThis endpoint can be used for health checks and monitoring.","operationId":"health_check_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/auth/signup/email":{"post":{"tags":["Authentication"],"summary":"Signup With Email","description":"Registers a new user using email, password, and name, and returns authentication tokens and user information.\n\nArgs:\n request: Contains the user's email, password, and name for registration.\n\nReturns:\n An AuthResponse with access token, refresh token, and user details.\n\nRaises:\n HTTPException: If registration fails or an unexpected error occurs.","operationId":"signup_with_email_auth_signup_email_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailSignupRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/login/email":{"post":{"tags":["Authentication"],"summary":"Login With Email","description":"Authenticates a user using email and password credentials.\n\nOn successful authentication, returns an access token, refresh token, and user information. Raises an HTTP 500 error if authentication fails due to an unexpected error.","operationId":"login_with_email_auth_login_email_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailLoginRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/login/google":{"post":{"tags":["Authentication"],"summary":"Login With Google","description":"Authenticates or registers a user using a Google OAuth ID token.\n\nOn success, returns an access token, refresh token, and user information. Raises an HTTP 500 error if Google authentication fails.","operationId":"login_with_google_auth_login_google_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoogleLoginRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/refresh":{"post":{"tags":["Authentication"],"summary":"Refresh Token","description":"Refreshes JWT tokens using a valid refresh token.\n\nValidates the provided refresh token, issues a new access token and refresh token if valid, and returns them. Raises a 401 error if the refresh token is invalid or revoked.\n \nReturns:\n A TokenResponse containing the new access and refresh tokens.","operationId":"refresh_token_auth_refresh_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshTokenRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/token/verify":{"post":{"tags":["Authentication"],"summary":"Verify Token","description":"Verifies an access token and returns the associated user information.\n\nRaises:\n HTTPException: If the token is invalid or expired, returns a 401 Unauthorized error.","operationId":"verify_token_auth_token_verify_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenVerifyRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/password/reset/request":{"post":{"tags":["Authentication"],"summary":"Request Password Reset","description":"Initiates a password reset process by sending a reset link to the provided email address.\n\nReturns:\n SuccessResponse: Indicates whether the password reset email was sent if the email exists.","operationId":"request_password_reset_auth_password_reset_request_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/password/reset/confirm":{"post":{"tags":["Authentication"],"summary":"Confirm Password Reset","description":"Resets a user's password using a valid password reset token.\n\nArgs:\n request: Contains the password reset token and the new password.\n\nReturns:\n SuccessResponse indicating the password has been reset successfully.\n\nRaises:\n HTTPException: If the reset token is invalid or an error occurs during the reset process.","operationId":"confirm_password_reset_auth_password_reset_confirm_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetConfirm"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/users/me":{"get":{"tags":["User"],"summary":"Get Current User Profile","operationId":"get_current_user_profile_users_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProfileResponse"}}}}},"security":[{"OAuth2PasswordBearer":[]}]},"delete":{"tags":["User"],"summary":"Delete User Account","operationId":"delete_user_account_users_me_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteUserResponse"}}}}},"security":[{"OAuth2PasswordBearer":[]}]},"patch":{"tags":["User"],"summary":"Update User Profile","operationId":"update_user_profile_users_me_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProfileUpdateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Update User Profile Users Me Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/groups":{"get":{"tags":["Groups"],"summary":"List User Groups","description":"List all groups the current user belongs to","operationId":"list_user_groups_groups_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GroupListResponse"}}}}},"security":[{"OAuth2PasswordBearer":[]}]},"post":{"tags":["Groups"],"summary":"Create Group","description":"Create a new group","operationId":"create_group_groups_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GroupCreateRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GroupResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/groups/{group_id}":{"get":{"tags":["Groups"],"summary":"Get Group Details","description":"Get group details including members","operationId":"get_group_details_groups__group_id__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GroupResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["Groups"],"summary":"Update Group Metadata","description":"Update group metadata (admin only)","operationId":"update_group_metadata_groups__group_id__patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GroupUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GroupResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Groups"],"summary":"Delete Group","description":"Delete a group (admin only)","operationId":"delete_group_groups__group_id__delete","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteGroupResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/groups/join":{"post":{"tags":["Groups"],"summary":"Join Group By Code","description":"Join a group using a join code","operationId":"join_group_by_code_groups_join_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JoinGroupRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JoinGroupResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/groups/{group_id}/leave":{"post":{"tags":["Groups"],"summary":"Leave Group","description":"Leave a group (only if no outstanding balances)","operationId":"leave_group_groups__group_id__leave_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeaveGroupResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/groups/{group_id}/members":{"get":{"tags":["Groups"],"summary":"Get Group Members","description":"Get list of group members with detailed user information","operationId":"get_group_members_groups__group_id__members_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GroupMemberWithDetails"},"title":"Response Get Group Members Groups Group Id Members Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/groups/{group_id}/members/{member_id}":{"patch":{"tags":["Groups"],"summary":"Update Member Role","description":"Change member role (admin only)","operationId":"update_member_role_groups__group_id__members__member_id__patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}},{"name":"member_id","in":"path","required":true,"schema":{"type":"string","title":"Member Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberRoleUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"},"title":"Response Update Member Role Groups Group Id Members Member Id Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Groups"],"summary":"Remove Group Member","description":"Remove a member from the group (admin only)","operationId":"remove_group_member_groups__group_id__members__member_id__delete","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}},{"name":"member_id","in":"path","required":true,"schema":{"type":"string","title":"Member Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveMemberResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/groups/{group_id}/expenses":{"post":{"tags":["Expenses"],"summary":"Create Expense","description":"Create a new expense within a group","operationId":"create_expense_groups__group_id__expenses_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExpenseCreateRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExpenseCreateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Expenses"],"summary":"List Group Expenses","description":"List all expenses for a group with pagination and filtering","operationId":"list_group_expenses_groups__group_id__expenses_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}},{"name":"from","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"From"}},{"name":"to","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"To"}},{"name":"tags","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tags"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExpenseListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/groups/{group_id}/expenses/{expense_id}":{"get":{"tags":["Expenses"],"summary":"Get Single Expense","description":"Retrieve details for a single expense","operationId":"get_single_expense_groups__group_id__expenses__expense_id__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}},{"name":"expense_id","in":"path","required":true,"schema":{"type":"string","title":"Expense Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["Expenses"],"summary":"Update Expense","description":"Update an existing expense","operationId":"update_expense_groups__group_id__expenses__expense_id__patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}},{"name":"expense_id","in":"path","required":true,"schema":{"type":"string","title":"Expense Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExpenseUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExpenseResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Expenses"],"summary":"Delete Expense","description":"Delete an expense","operationId":"delete_expense_groups__group_id__expenses__expense_id__delete","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}},{"name":"expense_id","in":"path","required":true,"schema":{"type":"string","title":"Expense Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/groups/{group_id}/expenses/{expense_id}/attachments":{"post":{"tags":["Expenses"],"summary":"Upload Attachment For Expense","description":"Upload attachment for an expense","operationId":"upload_attachment_for_expense_groups__group_id__expenses__expense_id__attachments_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}},{"name":"expense_id","in":"path","required":true,"schema":{"type":"string","title":"Expense Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_attachment_for_expense_groups__group_id__expenses__expense_id__attachments_post"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttachmentUploadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/groups/{group_id}/expenses/{expense_id}/attachments/{key}":{"get":{"tags":["Expenses"],"summary":"Get Attachment","description":"Get/download an attachment","operationId":"get_attachment_groups__group_id__expenses__expense_id__attachments__key__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}},{"name":"expense_id","in":"path","required":true,"schema":{"type":"string","title":"Expense Id"}},{"name":"key","in":"path","required":true,"schema":{"type":"string","title":"Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/groups/{group_id}/settlements":{"post":{"tags":["Expenses"],"summary":"Manually Record Payment","description":"Manually record a payment settlement between users in a group","operationId":"manually_record_payment_groups__group_id__settlements_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SettlementCreateRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Settlement"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Expenses"],"summary":"Get Group Settlements","description":"Retrieve pending and optimized settlements for a group","operationId":"get_group_settlements_groups__group_id__settlements_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}},{"name":"algorithm","in":"query","required":false,"schema":{"type":"string","description":"Settlement algorithm: 'normal' or 'advanced'","default":"advanced","title":"Algorithm"},"description":"Settlement algorithm: 'normal' or 'advanced'"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SettlementListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/groups/{group_id}/settlements/{settlement_id}":{"get":{"tags":["Expenses"],"summary":"Get Single Settlement","description":"Retrieve details for a single settlement","operationId":"get_single_settlement_groups__group_id__settlements__settlement_id__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}},{"name":"settlement_id","in":"path","required":true,"schema":{"type":"string","title":"Settlement Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Settlement"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["Expenses"],"summary":"Mark Settlement As Paid","description":"Mark a settlement as paid","operationId":"mark_settlement_as_paid_groups__group_id__settlements__settlement_id__patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}},{"name":"settlement_id","in":"path","required":true,"schema":{"type":"string","title":"Settlement Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SettlementUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Settlement"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Expenses"],"summary":"Delete Settlement","description":"Delete/undo a recorded settlement","operationId":"delete_settlement_groups__group_id__settlements__settlement_id__delete","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}},{"name":"settlement_id","in":"path","required":true,"schema":{"type":"string","title":"Settlement Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/groups/{group_id}/settlements/optimize":{"post":{"tags":["Expenses"],"summary":"Calculate Optimized Settlements","description":"Calculate and return optimized (simplified) settlements for a group","operationId":"calculate_optimized_settlements_groups__group_id__settlements_optimize_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}},{"name":"algorithm","in":"query","required":false,"schema":{"type":"string","description":"Settlement algorithm: 'normal' or 'advanced'","default":"advanced","title":"Algorithm"},"description":"Settlement algorithm: 'normal' or 'advanced'"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OptimizedSettlementsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/groups/{group_id}/users/{user_id}/balance":{"get":{"tags":["Expenses"],"summary":"Get User Balance In Specific Group","description":"Get a specific user's balance within a particular group","operationId":"get_user_balance_in_specific_group_groups__group_id__users__user_id__balance_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserBalance"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/groups/{group_id}/analytics":{"get":{"tags":["Expenses"],"summary":"Group Expense Analytics","description":"Provide expense analytics for a group","operationId":"group_expense_analytics_groups__group_id__analytics_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}},{"name":"period","in":"query","required":false,"schema":{"type":"string","description":"Analytics period: 'week', 'month', 'year'","default":"month","title":"Period"},"description":"Analytics period: 'week', 'month', 'year'"},{"name":"year","in":"query","required":true,"schema":{"type":"integer","title":"Year"}},{"name":"month","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Month"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExpenseAnalytics"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/groups/{group_id}/expenses/{expense_id}/debug":{"get":{"tags":["Expenses"],"summary":"Debug Expense","description":"Debug endpoint to check expense details and user permissions","operationId":"debug_expense_groups__group_id__expenses__expense_id__debug_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}},{"name":"expense_id","in":"path","required":true,"schema":{"type":"string","title":"Expense Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/users/me/friends-balance":{"get":{"tags":["User Balance"],"summary":"Get Cross Group Friend Balances","description":"Retrieve the current user's aggregated balances with all friends","operationId":"get_cross_group_friend_balances_users_me_friends_balance_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FriendsBalanceResponse"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/users/me/balance-summary":{"get":{"tags":["User Balance"],"summary":"Get Overall User Balance Summary","description":"Retrieve an overall balance summary for the current user","operationId":"get_overall_user_balance_summary_users_me_balance_summary_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BalanceSummaryResponse"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}}},"components":{"schemas":{"AttachmentUploadResponse":{"properties":{"attachment_key":{"type":"string","title":"Attachment Key"},"url":{"type":"string","title":"Url"}},"type":"object","required":["attachment_key","url"],"title":"AttachmentUploadResponse"},"AuthResponse":{"properties":{"access_token":{"type":"string","title":"Access Token"},"refresh_token":{"type":"string","title":"Refresh Token"},"user":{"$ref":"#/components/schemas/UserResponse"}},"type":"object","required":["access_token","refresh_token","user"],"title":"AuthResponse"},"BalanceSummaryResponse":{"properties":{"totalOwedToYou":{"type":"number","title":"Totalowedtoyou"},"totalYouOwe":{"type":"number","title":"Totalyouowe"},"netBalance":{"type":"number","title":"Netbalance"},"currency":{"type":"string","title":"Currency","default":"USD"},"groupsSummary":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Groupssummary"}},"type":"object","required":["totalOwedToYou","totalYouOwe","netBalance","groupsSummary"],"title":"BalanceSummaryResponse"},"Body_upload_attachment_for_expense_groups__group_id__expenses__expense_id__attachments_post":{"properties":{"file":{"type":"string","format":"binary","title":"File"}},"type":"object","required":["file"],"title":"Body_upload_attachment_for_expense_groups__group_id__expenses__expense_id__attachments_post"},"DeleteGroupResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"message":{"type":"string","title":"Message"}},"type":"object","required":["success","message"],"title":"DeleteGroupResponse"},"DeleteUserResponse":{"properties":{"success":{"type":"boolean","title":"Success","default":true},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"}},"type":"object","title":"DeleteUserResponse"},"EmailLoginRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"password":{"type":"string","title":"Password"}},"type":"object","required":["email","password"],"title":"EmailLoginRequest"},"EmailSignupRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"password":{"type":"string","minLength":6,"title":"Password"},"name":{"type":"string","minLength":1,"title":"Name"}},"type":"object","required":["email","password","name"],"title":"EmailSignupRequest"},"ExpenseAnalytics":{"properties":{"period":{"type":"string","title":"Period"},"totalExpenses":{"type":"number","title":"Totalexpenses"},"expenseCount":{"type":"integer","title":"Expensecount"},"avgExpenseAmount":{"type":"number","title":"Avgexpenseamount"},"topCategories":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Topcategories"},"memberContributions":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Membercontributions"},"expenseTrends":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Expensetrends"}},"type":"object","required":["period","totalExpenses","expenseCount","avgExpenseAmount","topCategories","memberContributions","expenseTrends"],"title":"ExpenseAnalytics"},"ExpenseComment":{"properties":{"_id":{"type":"string","title":"Id"},"userId":{"type":"string","title":"Userid"},"userName":{"type":"string","title":"Username"},"content":{"type":"string","title":"Content"},"createdAt":{"type":"string","format":"date-time","title":"Createdat"}},"type":"object","required":["_id","userId","userName","content","createdAt"],"title":"ExpenseComment"},"ExpenseCreateRequest":{"properties":{"description":{"type":"string","maxLength":500,"minLength":1,"title":"Description"},"amount":{"type":"number","exclusiveMinimum":0.0,"title":"Amount"},"splits":{"items":{"$ref":"#/components/schemas/ExpenseSplit"},"type":"array","title":"Splits"},"splitType":{"$ref":"#/components/schemas/SplitType","default":"equal"},"tags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tags","default":[]},"receiptUrls":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Receipturls","default":[]}},"type":"object","required":["description","amount","splits"],"title":"ExpenseCreateRequest"},"ExpenseCreateResponse":{"properties":{"expense":{"$ref":"#/components/schemas/ExpenseResponse"},"settlements":{"items":{"$ref":"#/components/schemas/Settlement"},"type":"array","title":"Settlements"},"groupSummary":{"$ref":"#/components/schemas/GroupSummary"}},"type":"object","required":["expense","settlements","groupSummary"],"title":"ExpenseCreateResponse"},"ExpenseHistoryEntry":{"properties":{"_id":{"type":"string","title":"Id"},"userId":{"type":"string","title":"Userid"},"userName":{"type":"string","title":"Username"},"beforeData":{"additionalProperties":true,"type":"object","title":"Beforedata"},"editedAt":{"type":"string","format":"date-time","title":"Editedat"}},"type":"object","required":["_id","userId","userName","beforeData","editedAt"],"title":"ExpenseHistoryEntry"},"ExpenseListResponse":{"properties":{"expenses":{"items":{"$ref":"#/components/schemas/ExpenseResponse"},"type":"array","title":"Expenses"},"pagination":{"additionalProperties":true,"type":"object","title":"Pagination"},"summary":{"additionalProperties":true,"type":"object","title":"Summary"}},"type":"object","required":["expenses","pagination","summary"],"title":"ExpenseListResponse"},"ExpenseResponse":{"properties":{"_id":{"type":"string","title":"Id"},"groupId":{"type":"string","title":"Groupid"},"createdBy":{"type":"string","title":"Createdby"},"description":{"type":"string","title":"Description"},"amount":{"type":"number","title":"Amount"},"splits":{"items":{"$ref":"#/components/schemas/ExpenseSplit"},"type":"array","title":"Splits"},"splitType":{"$ref":"#/components/schemas/SplitType"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags","default":[]},"receiptUrls":{"items":{"type":"string"},"type":"array","title":"Receipturls","default":[]},"comments":{"anyOf":[{"items":{"$ref":"#/components/schemas/ExpenseComment"},"type":"array"},{"type":"null"}],"title":"Comments","default":[]},"history":{"anyOf":[{"items":{"$ref":"#/components/schemas/ExpenseHistoryEntry"},"type":"array"},{"type":"null"}],"title":"History","default":[]},"createdAt":{"type":"string","format":"date-time","title":"Createdat"},"updatedAt":{"type":"string","format":"date-time","title":"Updatedat"}},"type":"object","required":["_id","groupId","createdBy","description","amount","splits","splitType","createdAt","updatedAt"],"title":"ExpenseResponse"},"ExpenseSplit":{"properties":{"userId":{"type":"string","title":"Userid"},"amount":{"type":"number","exclusiveMinimum":0.0,"title":"Amount"},"type":{"$ref":"#/components/schemas/SplitType","default":"equal"}},"type":"object","required":["userId","amount"],"title":"ExpenseSplit"},"ExpenseUpdateRequest":{"properties":{"description":{"anyOf":[{"type":"string","maxLength":500,"minLength":1},{"type":"null"}],"title":"Description"},"amount":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"null"}],"title":"Amount"},"splits":{"anyOf":[{"items":{"$ref":"#/components/schemas/ExpenseSplit"},"type":"array"},{"type":"null"}],"title":"Splits"},"tags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tags"},"receiptUrls":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Receipturls"}},"type":"object","title":"ExpenseUpdateRequest"},"FriendBalance":{"properties":{"userId":{"type":"string","title":"Userid"},"userName":{"type":"string","title":"Username"},"userImageUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Userimageurl"},"netBalance":{"type":"number","title":"Netbalance"},"owesYou":{"type":"boolean","title":"Owesyou"},"breakdown":{"items":{"$ref":"#/components/schemas/FriendBalanceBreakdown"},"type":"array","title":"Breakdown"},"lastActivity":{"type":"string","format":"date-time","title":"Lastactivity"}},"type":"object","required":["userId","userName","netBalance","owesYou","breakdown","lastActivity"],"title":"FriendBalance"},"FriendBalanceBreakdown":{"properties":{"groupId":{"type":"string","title":"Groupid"},"groupName":{"type":"string","title":"Groupname"},"balance":{"type":"number","title":"Balance"},"owesYou":{"type":"boolean","title":"Owesyou"}},"type":"object","required":["groupId","groupName","balance","owesYou"],"title":"FriendBalanceBreakdown"},"FriendsBalanceResponse":{"properties":{"friendsBalance":{"items":{"$ref":"#/components/schemas/FriendBalance"},"type":"array","title":"Friendsbalance"},"summary":{"additionalProperties":true,"type":"object","title":"Summary"}},"type":"object","required":["friendsBalance","summary"],"title":"FriendsBalanceResponse"},"GoogleLoginRequest":{"properties":{"id_token":{"type":"string","title":"Id Token"}},"type":"object","required":["id_token"],"title":"GoogleLoginRequest"},"GroupCreateRequest":{"properties":{"name":{"type":"string","maxLength":100,"minLength":1,"title":"Name"},"currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Currency","default":"USD"},"imageUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Imageurl"}},"type":"object","required":["name"],"title":"GroupCreateRequest"},"GroupListResponse":{"properties":{"groups":{"items":{"$ref":"#/components/schemas/GroupResponse"},"type":"array","title":"Groups"}},"type":"object","required":["groups"],"title":"GroupListResponse"},"GroupMemberWithDetails":{"properties":{"userId":{"type":"string","title":"Userid"},"role":{"type":"string","title":"Role","default":"member"},"joinedAt":{"type":"string","format":"date-time","title":"Joinedat"},"user":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"User"}},"type":"object","required":["userId","joinedAt"],"title":"GroupMemberWithDetails"},"GroupResponse":{"properties":{"_id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"currency":{"type":"string","title":"Currency"},"joinCode":{"type":"string","title":"Joincode"},"createdBy":{"type":"string","title":"Createdby"},"createdAt":{"type":"string","format":"date-time","title":"Createdat"},"imageUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Imageurl"},"members":{"anyOf":[{"items":{"$ref":"#/components/schemas/GroupMemberWithDetails"},"type":"array"},{"type":"null"}],"title":"Members","default":[]}},"type":"object","required":["_id","name","currency","joinCode","createdBy","createdAt"],"title":"GroupResponse"},"GroupSummary":{"properties":{"totalExpenses":{"type":"number","title":"Totalexpenses"},"totalSettlements":{"type":"integer","title":"Totalsettlements"},"optimizedSettlements":{"items":{"$ref":"#/components/schemas/OptimizedSettlement"},"type":"array","title":"Optimizedsettlements"}},"type":"object","required":["totalExpenses","totalSettlements","optimizedSettlements"],"title":"GroupSummary"},"GroupUpdateRequest":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":100,"minLength":1},{"type":"null"}],"title":"Name"},"imageUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Imageurl"}},"type":"object","title":"GroupUpdateRequest"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"JoinGroupRequest":{"properties":{"joinCode":{"type":"string","minLength":1,"title":"Joincode"}},"type":"object","required":["joinCode"],"title":"JoinGroupRequest"},"JoinGroupResponse":{"properties":{"group":{"$ref":"#/components/schemas/GroupResponse"}},"type":"object","required":["group"],"title":"JoinGroupResponse"},"LeaveGroupResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"message":{"type":"string","title":"Message"}},"type":"object","required":["success","message"],"title":"LeaveGroupResponse"},"MemberRoleUpdateRequest":{"properties":{"role":{"type":"string","pattern":"^(admin|member)$","title":"Role"}},"type":"object","required":["role"],"title":"MemberRoleUpdateRequest"},"OptimizedSettlement":{"properties":{"fromUserId":{"type":"string","title":"Fromuserid"},"toUserId":{"type":"string","title":"Touserid"},"fromUserName":{"type":"string","title":"Fromusername"},"toUserName":{"type":"string","title":"Tousername"},"amount":{"type":"number","title":"Amount"},"consolidatedExpenses":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Consolidatedexpenses","default":[]}},"type":"object","required":["fromUserId","toUserId","fromUserName","toUserName","amount"],"title":"OptimizedSettlement"},"OptimizedSettlementsResponse":{"properties":{"optimizedSettlements":{"items":{"$ref":"#/components/schemas/OptimizedSettlement"},"type":"array","title":"Optimizedsettlements"},"savings":{"additionalProperties":true,"type":"object","title":"Savings"}},"type":"object","required":["optimizedSettlements","savings"],"title":"OptimizedSettlementsResponse"},"PasswordResetConfirm":{"properties":{"reset_token":{"type":"string","title":"Reset Token"},"new_password":{"type":"string","minLength":6,"title":"New Password"}},"type":"object","required":["reset_token","new_password"],"title":"PasswordResetConfirm"},"PasswordResetRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"}},"type":"object","required":["email"],"title":"PasswordResetRequest"},"RefreshTokenRequest":{"properties":{"refresh_token":{"type":"string","title":"Refresh Token"}},"type":"object","required":["refresh_token"],"title":"RefreshTokenRequest"},"RemoveMemberResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"message":{"type":"string","title":"Message"}},"type":"object","required":["success","message"],"title":"RemoveMemberResponse"},"Settlement":{"properties":{"_id":{"type":"string","title":"Id"},"expenseId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expenseid"},"groupId":{"type":"string","title":"Groupid"},"payerId":{"type":"string","title":"Payerid"},"payeeId":{"type":"string","title":"Payeeid"},"payerName":{"type":"string","title":"Payername"},"payeeName":{"type":"string","title":"Payeename"},"amount":{"type":"number","title":"Amount"},"status":{"$ref":"#/components/schemas/SettlementStatus"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"paidAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Paidat"},"createdAt":{"type":"string","format":"date-time","title":"Createdat"}},"type":"object","required":["_id","groupId","payerId","payeeId","payerName","payeeName","amount","status","createdAt"],"title":"Settlement"},"SettlementCreateRequest":{"properties":{"payer_id":{"type":"string","title":"Payer Id"},"payee_id":{"type":"string","title":"Payee Id"},"amount":{"type":"number","exclusiveMinimum":0.0,"title":"Amount"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"paidAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Paidat"}},"type":"object","required":["payer_id","payee_id","amount"],"title":"SettlementCreateRequest"},"SettlementListResponse":{"properties":{"settlements":{"items":{"$ref":"#/components/schemas/Settlement"},"type":"array","title":"Settlements"},"optimizedSettlements":{"items":{"$ref":"#/components/schemas/OptimizedSettlement"},"type":"array","title":"Optimizedsettlements"},"summary":{"additionalProperties":true,"type":"object","title":"Summary"},"pagination":{"additionalProperties":true,"type":"object","title":"Pagination"}},"type":"object","required":["settlements","optimizedSettlements","summary","pagination"],"title":"SettlementListResponse"},"SettlementStatus":{"type":"string","enum":["pending","completed","cancelled"],"title":"SettlementStatus"},"SettlementUpdateRequest":{"properties":{"status":{"$ref":"#/components/schemas/SettlementStatus"},"paidAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Paidat"}},"type":"object","required":["status"],"title":"SettlementUpdateRequest"},"SplitType":{"type":"string","enum":["equal","unequal","percentage"],"title":"SplitType"},"SuccessResponse":{"properties":{"success":{"type":"boolean","title":"Success","default":true},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"}},"type":"object","title":"SuccessResponse"},"TokenResponse":{"properties":{"access_token":{"type":"string","title":"Access Token"},"refresh_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Refresh Token"}},"type":"object","required":["access_token"],"title":"TokenResponse"},"TokenVerifyRequest":{"properties":{"access_token":{"type":"string","title":"Access Token"}},"type":"object","required":["access_token"],"title":"TokenVerifyRequest"},"UserBalance":{"properties":{"userId":{"type":"string","title":"Userid"},"userName":{"type":"string","title":"Username"},"totalPaid":{"type":"number","title":"Totalpaid"},"totalOwed":{"type":"number","title":"Totalowed"},"netBalance":{"type":"number","title":"Netbalance"},"owesYou":{"type":"boolean","title":"Owesyou"},"pendingSettlements":{"items":{"$ref":"#/components/schemas/Settlement"},"type":"array","title":"Pendingsettlements","default":[]},"recentExpenses":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Recentexpenses","default":[]}},"type":"object","required":["userId","userName","totalPaid","totalOwed","netBalance","owesYou"],"title":"UserBalance"},"UserProfileResponse":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"email":{"type":"string","format":"email","title":"Email"},"imageUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Imageurl"},"currency":{"type":"string","title":"Currency","default":"USD"},"createdAt":{"type":"string","format":"date-time","title":"Createdat"},"updatedAt":{"type":"string","format":"date-time","title":"Updatedat"}},"type":"object","required":["id","name","email","createdAt","updatedAt"],"title":"UserProfileResponse"},"UserProfileUpdateRequest":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"imageUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Imageurl"},"currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Currency"}},"type":"object","title":"UserProfileUpdateRequest"},"UserResponse":{"properties":{"_id":{"type":"string","title":"Id"},"email":{"type":"string","title":"Email"},"name":{"type":"string","title":"Name"},"avatar":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar"},"currency":{"type":"string","title":"Currency","default":"USD"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["_id","email","name","created_at"],"title":"UserResponse"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"securitySchemes":{"OAuth2PasswordBearer":{"type":"oauth2","flows":{"password":{"scopes":{},"tokenUrl":"/auth/token"}}}}}} No newline at end of file | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical: Format the OpenAPI specification for readability and maintainability.
The entire OpenAPI specification is compressed into a single line, making it extremely difficult to read, review, and maintain. This severely impacts code quality and collaborative development.
Please format the JSON with proper indentation:
-{"openapi":"3.1.0","info":{"title":"Splitwiser API"...
+{
+ "openapi": "3.1.0",
+ "info": {
+ "title": "Splitwiser API",
+ "description": "Backend API for Splitwiser expense tracking application",
+ "version": "1.0.0"
+ },
+ "paths": {
+ ...
+ }
+}Committable suggestion skipped: line range outside the PR's diff.
🧰 Tools
🪛 Checkov (3.2.334)
[HIGH] 1: Ensure that the global security field has rules defined
(CKV_OPENAPI_4)
[HIGH] 1: Ensure that security operations is not empty.
(CKV_OPENAPI_5)
[MEDIUM] 1: Ensure that arrays have a maximum number of items
(CKV_OPENAPI_21)
🤖 Prompt for AI Agents
In ui-poc/openapi.json at line 1, the entire OpenAPI specification is compressed
into a single line, which makes it very hard to read and maintain. Reformat the
JSON content by pretty-printing it with proper indentation and line breaks to
improve readability and maintainability. Use a JSON formatter or editor to apply
consistent indentation throughout the file.
💡 Verification agent
🧩 Analysis chain
Address security configuration issues identified by static analysis.
The OpenAPI specification has security configuration gaps that should be addressed:
- Missing global security rules - No default security requirements defined
- Empty security operations - Some operations may lack proper security
- Missing array limits - Arrays without maximum item constraints could lead to DoS attacks
Please add global security requirements and validate array limits. Here's a verification script to check security configuration:
🏁 Script executed:
#!/bin/bash
# Description: Analyze OpenAPI security configuration
# Expected: Find security issues and suggest improvements
# Check for global security definition
echo "Checking for global security configuration..."
cat ui-poc/openapi.json | jq -r 'if .security then "Global security found" else "No global security defined" end'
# Check for security schemes
echo "Checking security schemes..."
cat ui-poc/openapi.json | jq -r '.components.securitySchemes // "No security schemes found"'
# Check for operations without security
echo "Checking operations without security..."
cat ui-poc/openapi.json | jq -r '.paths | to_entries[] | select(.value | to_entries[] | .value.security == null) | .key'Length of output: 943
Enforce global security and harden array schemas
The OpenAPI spec currently has no root‐level security, many operations lack explicit security declarations, and arrays have no maxItems limits (DoS risk).
Required changes in ui-poc/openapi.json:
• Add a global security block at the top level:
{
"openapi": "3.1.0",
"info": { … },
+ "security": [
+ { "OAuth2PasswordBearer": [] }
+ ],
"paths": { … }
}• For public endpoints, explicitly override security to an empty array:
/security: []– /health
– /auth/signup/email
– /auth/login/email
– /auth/login/google
– /auth/refresh
– /auth/token/verify
– /auth/password/reset/request
– /auth/password/reset/confirm
• Ensure every other operation includes:
security:
- OAuth2PasswordBearer: []• Audit all type: array schemas under components.schemas and add sensible maxItems bounds. Examples:
– ExpenseCreateRequest.properties.splits → "maxItems": 50
– ExpenseResponse.properties.tags → "maxItems": 20
– FriendsBalanceResponse.properties.friendsBalance → "maxItems": 100"
Operations missing any security block:
• /{path}
• /health
• /auth/signup/email
• /auth/login/email
• /auth/login/google
• /auth/refresh
• /auth/token/verify
• /auth/password/reset/request
• /auth/password/reset/confirm
Please update accordingly to enforce consistent authentication rules and prevent unbounded arrays.
🧰 Tools
🪛 Checkov (3.2.334)
[HIGH] 1: Ensure that the global security field has rules defined
(CKV_OPENAPI_4)
[HIGH] 1: Ensure that security operations is not empty.
(CKV_OPENAPI_5)
[MEDIUM] 1: Ensure that arrays have a maximum number of items
(CKV_OPENAPI_21)
🤖 Prompt for AI Agents
In ui-poc/openapi.json at the root level, add a global security block requiring
OAuth2PasswordBearer for all operations by default. For the listed public
endpoints (/health, /auth/signup/email, /auth/login/email, /auth/login/google,
/auth/refresh, /auth/token/verify, /auth/password/reset/request,
/auth/password/reset/confirm), explicitly override security with an empty array
to allow unauthenticated access. For all other operations, ensure the security
block includes OAuth2PasswordBearer. Additionally, audit all array schemas under
components.schemas and add appropriate maxItems limits to prevent DoS risks,
such as maxItems: 50 for ExpenseCreateRequest.properties.splits, maxItems: 20
for ExpenseResponse.properties.tags, and maxItems: 100 for
FriendsBalanceResponse.properties.friendsBalance.
| except: | ||
| st.sidebar.write("Failed to parse response as JSON") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Replace bare except clauses with specific exception handling.
Bare except clauses can hide important errors and make debugging difficult. Consider catching specific exceptions or at least Exception.
For example, replace:
except:
st.sidebar.write("Failed to parse response as JSON")With:
except (json.JSONDecodeError, ValueError) as e:
st.sidebar.write(f"Failed to parse response as JSON: {e}")Also applies to: 100-101, 125-126, 137-138, 162-163, 181-182, 683-684
🧰 Tools
🪛 Ruff (0.11.9)
83-83: Do not use bare except
(E722)
🤖 Prompt for AI Agents
In ui-poc/pages/Groups.py at lines 83-84, replace the bare except clause with
specific exception handling by catching json.JSONDecodeError and ValueError
exceptions. Update the except block to capture the exception as a variable and
include its message in the sidebar output for better debugging. Apply the same
change to lines 100-101, 125-126, 137-138, 162-163, 181-182, and 683-684 to
ensure consistent and clear error handling throughout the file.
ui-poc/pages/Groups.py
Outdated
| st.error("No members selected for splitting the expense.") | ||
| st.stop() | ||
|
|
||
| equal_split_amount = round(expense_amount / len(selected_member_ids), 2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential precision issue with equal split calculation.
When dividing the expense amount equally, rounding to 2 decimal places might cause the total to not exactly match the original amount due to rounding errors.
Consider adjusting the last split to account for any rounding difference:
equal_split_amount = round(expense_amount / len(selected_member_ids), 2)
total_assigned = equal_split_amount * (len(selected_member_ids) - 1)
last_split_amount = round(expense_amount - total_assigned, 2)🤖 Prompt for AI Agents
In ui-poc/pages/Groups.py at line 573, the current equal split calculation
rounds each share to 2 decimals, which can cause the total to differ from the
original expense amount due to rounding errors. To fix this, calculate the equal
split amount for all but the last member, then assign the last member the
remainder by subtracting the total assigned from the original amount, ensuring
the sum matches exactly. Implement this by computing the equal split amount,
multiplying it by the count minus one, and then setting the last split amount as
the difference rounded to 2 decimals.
| import streamlit as st | ||
| import requests | ||
| from datetime import datetime | ||
| import json |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove unused import.
The json module is imported but never used in the code.
-import json📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| import json |
🧰 Tools
🪛 Ruff (0.11.9)
4-4: json imported but unused
Remove unused import: json
(F401)
🤖 Prompt for AI Agents
In ui-poc/pages/Groups.py at line 4, the json module is imported but not used
anywhere in the file. Remove the line importing json to clean up the code and
avoid unnecessary imports.
|
|
||
| # Connection status check | ||
| try: | ||
| status_response = requests.get(f"{API_URL}/health", timeout=3) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Use the retry wrapper for consistency.
The health check API call should use the make_api_request function for consistency and to benefit from retry logic.
- status_response = requests.get(f"{API_URL}/health", timeout=3)
+ status_response = make_api_request('get', f"{API_URL}/health")📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| status_response = requests.get(f"{API_URL}/health", timeout=3) | |
| status_response = make_api_request('get', f"{API_URL}/health") |
🤖 Prompt for AI Agents
In ui-poc/pages/Groups.py at line 46, replace the direct requests.get call to
the health check API with the make_api_request function to ensure consistent
usage and apply the retry logic. Modify the code to call make_api_request with
the appropriate URL and parameters instead of using requests.get directly.
| import streamlit as st | ||
| import requests | ||
| from datetime import datetime | ||
| import json |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove unused import.
The json module is imported but never used.
-import json📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| import json |
🧰 Tools
🪛 Ruff (0.11.9)
4-4: json imported but unused
Remove unused import: json
(F401)
🤖 Prompt for AI Agents
In ui-poc/Home.py at line 4, the json module is imported but not used anywhere
in the file. Remove the import statement for json to clean up unused imports and
improve code clarity.
ui-poc/Home.py
Outdated
| except: | ||
| st.write(date_str) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Replace bare except with specific exception handling.
Catch specific exceptions to avoid hiding important errors.
-except:
- st.write(date_str)
+except (ValueError, TypeError) as e:
+ st.write(date_str)
+ if st.session_state.get('debug_mode'):
+ st.caption(f"Date parsing error: {e}")📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| except: | |
| st.write(date_str) | |
| except (ValueError, TypeError) as e: | |
| st.write(date_str) | |
| if st.session_state.get('debug_mode'): | |
| st.caption(f"Date parsing error: {e}") |
🧰 Tools
🪛 Ruff (0.11.9)
330-330: Do not use bare except
(E722)
🤖 Prompt for AI Agents
In ui-poc/Home.py around lines 330 to 331, replace the bare except clause with
handling for specific exceptions that might be raised in the try block. Identify
the likely exceptions (e.g., ValueError, TypeError) and catch only those to
avoid suppressing unexpected errors. This will make error handling clearer and
prevent hiding important issues.
ui-poc/Home.py
Outdated
|
|
||
| # Get payer info | ||
| payer_id = expense.get('createdBy') | ||
| st.caption(f"Paid by: {next((m.get('user', {}).get('name', 'Unknown') for m in members if m.get('userId') == payer_id), 'Unknown')}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Variable 'members' might not be defined.
The variable members is used here but might not be defined if the previous API call to fetch members failed.
Consider initializing members at the beginning of the expenses section or checking if it exists:
# At the beginning of the expenses section
members = [] # Initialize empty list
# Or check before use
payer_name = next((m.get('user', {}).get('name', 'Unknown')
for m in members if m.get('userId') == payer_id), 'Unknown') if 'members' in locals() else 'Unknown'🏁 Script executed:
#!/bin/bash
# Check if members is properly initialized before use
ast-grep --pattern 'members = $_' ui-poc/Home.pyLength of output: 204
🏁 Script executed:
#!/bin/bash
# Show context around all usages of 'members' in ui-poc/Home.py
rg -n 'members' -B3 -A3 ui-poc/Home.pyLength of output: 2829
🏁 Script executed:
#!/bin/bash
# Show how existing expenses are iterated and where 'members' is referenced
rg -n 'for expense in' -C5 ui-poc/Home.py
# Show the block from the initial members fetch through the expenses display
sed -n '200,380p' ui-poc/Home.pyLength of output: 9037
Initialize and guard members before use to prevent NameError
The members list is only set when the API returns a 200, so in failure paths it remains undefined and causes a crash when rendering expenses. Please add a default initialization and/or fallback assignment in both the “Members” expander and before referencing it in the “Expenses” section.
• File: ui-poc/Home.py
– Lines ~236–245 (Group Members expander)
– Lines ~332–336 (Group Expenses expander)
Proposed changes:
--- a/ui-poc/Home.py
+++ a/ui-poc/Home.py
@@ with st.expander("Members", expanded=True):
- try:
+ # Initialize members to a safe default
+ members = []
+ try:
headers = {"Authorization": f"Bearer {st.session_state.access_token}"}
response = requests.get(
f"{API_URL}/groups/{group.get('_id')}/members",
@@
if response.status_code == 200:
- members = response.json()
+ members = response.json()
else:
st.error("Failed to fetch group members.")
@@ with st.expander("Expenses", expanded=True):
- # Get payer info
- payer_id = expense.get('createdBy')
- st.caption(f"Paid by: {next((m.get('user', {}).get('name', 'Unknown') for m in members if m.get('userId') == payer_id), 'Unknown')}")
+ # Ensure members is defined before lookup
+ if 'members' not in locals():
+ members = []
+ payer_id = expense.get('createdBy')
+ payer_name = next(
+ (m.get("user", {}).get("name", "Unknown") for m in members if m.get("userId") == payer_id),
+ "Unknown"
+ )
+ st.caption(f"Paid by: {payer_name}")These changes guarantee members is always defined and avoids runtime errors when the initial fetch fails.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| st.caption(f"Paid by: {next((m.get('user', {}).get('name', 'Unknown') for m in members if m.get('userId') == payer_id), 'Unknown')}") | |
| # … earlier in the file … | |
| with st.expander("Members", expanded=True): | |
| # Initialize members to a safe default | |
| members = [] | |
| try: | |
| headers = {"Authorization": f"Bearer {st.session_state.access_token}"} | |
| response = requests.get( | |
| f"{API_URL}/groups/{group.get('_id')}/members", | |
| headers=headers | |
| ) | |
| if response.status_code == 200: | |
| members = response.json() | |
| else: | |
| st.error("Failed to fetch group members.") | |
| except Exception as e: | |
| st.error(f"Error fetching members: {e}") | |
| # … other UI code … | |
| with st.expander("Expenses", expanded=True): | |
| for expense in expenses: | |
| # Ensure members is defined before lookup | |
| if 'members' not in locals(): | |
| members = [] | |
| payer_id = expense.get("createdBy") | |
| payer_name = next( | |
| (m.get("user", {}).get("name", "Unknown") for m in members if m.get("userId") == payer_id), | |
| "Unknown" | |
| ) | |
| st.caption(f"Paid by: {payer_name}") | |
| # … rest of your expense rendering … |
🤖 Prompt for AI Agents
In ui-poc/Home.py around lines 236 to 245 and 332 to 336, the variable members
is only assigned when the API call succeeds, causing a NameError if the call
fails. To fix this, initialize members as an empty list before the API call in
the Members expander and ensure it is defined or assigned a fallback empty list
before it is used in the Expenses expander. This guarantees members is always
defined and prevents runtime crashes.
…or better user experience
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 14
♻️ Duplicate comments (5)
ui-poc/pages/Groups.py (5)
4-4: Remove unused import.The
jsonmodule is imported but never used in the code.
32-32: Remove unreachable code.This return statement can never be reached since the while loop either returns a response or raises an exception.
46-46: Use the retry wrapper for consistency.The health check API call should use the
make_api_requestfunction for consistency and to benefit from retry logic.
83-84: Replace bare except clauses with specific exception handling.Bare except clauses can hide important errors and make debugging difficult. Consider catching specific exceptions or at least
Exception.
573-573: Potential precision issue with equal split calculation.When dividing the expense amount equally, rounding to 2 decimal places might cause the total to not exactly match the original amount due to rounding errors.
🧹 Nitpick comments (2)
ui-poc/pages/Groups.py (1)
197-198: Combine nested with statements.For better readability, combine the nested with statements into a single one.
-with st.expander("Join a Group", expanded=False): - with st.form("join_group_form_page", clear_on_submit=True): +with st.expander("Join a Group", expanded=False), st.form("join_group_form_page", clear_on_submit=True):ui-poc/setup_test_data.py (1)
121-124: Simplify using any() function.The loop can be replaced with a more concise and Pythonic approach.
- for expense in expenses: - if expense.get('description') == description: - return True - return False + return any(expense.get('description') == description for expense in expenses)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
ui-poc/pages/Friends.py(1 hunks)ui-poc/pages/Groups.py(1 hunks)ui-poc/setup_test_data.py(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
ui-poc/pages/Friends.py (1)
ui-poc/pages/Groups.py (4)
make_api_request(11-32)fetch_user_groups(68-107)fetch_group_members(110-144)fetch_group_expenses(147-188)
ui-poc/pages/Groups.py (1)
ui-poc/pages/Friends.py (4)
make_api_request(12-33)fetch_user_groups(69-99)fetch_group_members(102-118)fetch_group_expenses(121-141)
🪛 Ruff (0.11.9)
ui-poc/pages/Friends.py
3-3: datetime.datetime imported but unused
Remove unused import: datetime.datetime
(F401)
4-4: json imported but unused
Remove unused import: json
(F401)
6-6: collections.defaultdict imported but unused
Remove unused import: collections.defaultdict
(F401)
53-53: f-string without any placeholders
Remove extraneous f prefix
(F541)
83-83: Do not use bare except
(E722)
92-92: f-string without any placeholders
Remove extraneous f prefix
(F541)
174-174: Local variable current_user_paid is assigned to but never used
Remove assignment to unused variable current_user_paid
(F841)
175-175: Local variable friend_paid is assigned to but never used
Remove assignment to unused variable friend_paid
(F841)
ui-poc/setup_test_data.py
17-17: json imported but unused
Remove unused import: json
(F401)
19-19: random imported but unused
Remove unused import: random
(F401)
20-20: datetime.datetime imported but unused
Remove unused import
(F401)
20-20: datetime.timedelta imported but unused
Remove unused import
(F401)
121-124: Use return any(expense.get('description') == description for expense in expenses) instead of for loop
Replace with return any(expense.get('description') == description for expense in expenses)
(SIM110)
215-215: f-string without any placeholders
Remove extraneous f prefix
(F541)
233-233: f-string without any placeholders
Remove extraneous f prefix
(F541)
251-251: f-string without any placeholders
Remove extraneous f prefix
(F541)
ui-poc/pages/Groups.py
4-4: json imported but unused
Remove unused import: json
(F401)
52-52: f-string without any placeholders
Remove extraneous f prefix
(F541)
83-83: Do not use bare except
(E722)
92-92: f-string without any placeholders
Remove extraneous f prefix
(F541)
100-100: Do not use bare except
(E722)
125-125: Do not use bare except
(E722)
137-137: Do not use bare except
(E722)
162-162: Do not use bare except
(E722)
171-171: f-string without any placeholders
Remove extraneous f prefix
(F541)
181-181: Do not use bare except
(E722)
197-198: Use a single with statement with multiple contexts instead of nested with statements
(SIM117)
220-221: Use a single with statement with multiple contexts instead of nested with statements
(SIM117)
298-299: Use a single with statement with multiple contexts instead of nested with statements
(SIM117)
686-686: Do not use bare except
(E722)
721-721: f-string without any placeholders
Remove extraneous f prefix
(F541)
| "amount": expense_amount, | ||
| "splits": splits, | ||
| "splitType": split_type, | ||
| "paidBy": payer_id, # Add the payer ID |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure consistent payer identification.
The expense creation uses paidBy field with the selected payer ID, but when displaying expenses, the code uses createdBy field to identify the payer. This inconsistency could lead to incorrect balance calculations.
Verify that the backend API correctly handles the paidBy field and returns it in the expense response. If the API uses a different field name for the payer, update the display logic accordingly:
- payer_id = expense.get('createdBy')
+ payer_id = expense.get('paidBy', expense.get('createdBy'))Also applies to: 690-690
🤖 Prompt for AI Agents
In ui-poc/pages/Groups.py at lines 637 and 690, the code uses the "paidBy" field
to set the payer ID when creating an expense, but the display logic uses
"createdBy" to identify the payer, causing inconsistency. Confirm the backend
API's field name for the payer in the expense response; if it returns "paidBy,"
update the display logic to use "paidBy" instead of "createdBy" to ensure
consistent payer identification and correct balance calculations.
ui-poc/pages/Groups.py
Outdated
| if 'groups' in data: | ||
| return data['groups'] | ||
| else: | ||
| st.error(f"Unexpected response format: 'groups' key not found in response") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove extraneous f-string prefix.
The error message doesn't use any placeholders.
- st.error(f"Unexpected response format: 'groups' key not found in response")
+ st.error("Unexpected response format: 'groups' key not found in response")📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| st.error(f"Unexpected response format: 'groups' key not found in response") | |
| st.error("Unexpected response format: 'groups' key not found in response") |
🧰 Tools
🪛 Ruff (0.11.9)
92-92: f-string without any placeholders
Remove extraneous f prefix
(F541)
🤖 Prompt for AI Agents
In ui-poc/pages/Groups.py at line 92, remove the unnecessary f-string prefix
from the error message since it contains no placeholders. Change the line to use
a regular string literal instead of an f-string.
| else: | ||
| st.error(f"API Connection: Error (Status {status_response.status_code})") | ||
| except Exception as e: | ||
| st.error(f"API Connection: Offline") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove extraneous f-string prefix.
The error message doesn't use any placeholders, so the f-string prefix is unnecessary.
- st.error(f"API Connection: Offline")
+ st.error("API Connection: Offline")📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| st.error(f"API Connection: Offline") | |
| st.error("API Connection: Offline") |
🧰 Tools
🪛 Ruff (0.11.9)
52-52: f-string without any placeholders
Remove extraneous f prefix
(F541)
🤖 Prompt for AI Agents
In ui-poc/pages/Groups.py at line 52, remove the unnecessary f-string prefix
from the error message since it contains no placeholders. Change the line from
using f-string syntax to a regular string literal for clarity and simplicity.
ui-poc/pages/Groups.py
Outdated
| if 'expenses' in data: | ||
| return data['expenses'] | ||
| else: | ||
| st.error(f"Unexpected response format: 'expenses' key not found in response") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove extraneous f-string prefix.
The error message doesn't use any placeholders.
- st.error(f"Unexpected response format: 'expenses' key not found in response")
+ st.error("Unexpected response format: 'expenses' key not found in response")📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| st.error(f"Unexpected response format: 'expenses' key not found in response") | |
| st.error("Unexpected response format: 'expenses' key not found in response") |
🧰 Tools
🪛 Ruff (0.11.9)
171-171: f-string without any placeholders
Remove extraneous f prefix
(F541)
🤖 Prompt for AI Agents
In ui-poc/pages/Groups.py at line 171, remove the unnecessary f-string prefix
from the st.error call since the error message contains no placeholders. Change
the line to use a regular string literal instead of an f-string.
ui-poc/pages/Groups.py
Outdated
| else: | ||
| # User is not included in the expense (grey) | ||
| st.markdown(f":gray[Paid by: {payer_name}]") | ||
| st.markdown(f":gray[You are not included in this expense]") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove extraneous f-string prefix.
The message doesn't use any placeholders.
- st.markdown(f":gray[You are not included in this expense]")
+ st.markdown(":gray[You are not included in this expense]")📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| st.markdown(f":gray[You are not included in this expense]") | |
| st.markdown(":gray[You are not included in this expense]") |
🧰 Tools
🪛 Ruff (0.11.9)
721-721: f-string without any placeholders
Remove extraneous f prefix
(F541)
🤖 Prompt for AI Agents
In ui-poc/pages/Groups.py at line 721, remove the unnecessary f-string prefix
from the st.markdown call since the string does not contain any placeholders.
Replace the f-string with a regular string literal to clean up the code.
| except: | ||
| st.sidebar.write("Failed to parse response as JSON") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace bare except with specific exception handling.
Catch specific exceptions for better error handling and debugging.
- except:
+ except (json.JSONDecodeError, ValueError) as e:
- st.sidebar.write("Failed to parse response as JSON")
+ st.sidebar.write(f"Failed to parse response as JSON: {e}")📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| except: | |
| st.sidebar.write("Failed to parse response as JSON") | |
| except (json.JSONDecodeError, ValueError) as e: | |
| st.sidebar.write(f"Failed to parse response as JSON: {e}") |
🧰 Tools
🪛 Ruff (0.11.9)
83-83: Do not use bare except
(E722)
🤖 Prompt for AI Agents
In ui-poc/pages/Friends.py around lines 83 to 84, replace the bare except clause
with specific exception handling by catching the exact exceptions that can occur
during JSON parsing, such as json.JSONDecodeError or ValueError. This improves
error handling clarity and debugging by avoiding catching unrelated exceptions.
|
|
||
| # Connection status check | ||
| try: | ||
| status_response = requests.get(f"{API_URL}/health", timeout=3) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Use the retry wrapper for consistency.
The health check should use make_api_request for consistency with other API calls.
- status_response = requests.get(f"{API_URL}/health", timeout=3)
+ status_response = make_api_request('get', f"{API_URL}/health")📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| status_response = requests.get(f"{API_URL}/health", timeout=3) | |
| status_response = make_api_request('get', f"{API_URL}/health") |
🤖 Prompt for AI Agents
In ui-poc/pages/Friends.py at line 47, replace the direct requests.get call for
the health check with the make_api_request function to maintain consistency with
other API calls. This involves calling make_api_request with the appropriate URL
and parameters instead of using requests.get directly.
| # Group 1: House Share (Alice, Bob, Charlie) | ||
| house_group = self.find_group_by_name(existing_groups, "House Share") | ||
| if house_group: | ||
| print(f"✅ Group 'House Share' already exists") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove extraneous f-string prefixes.
These strings don't use any placeholders.
- print(f"✅ Group 'House Share' already exists")
+ print("✅ Group 'House Share' already exists")
...
- print(f"✅ Group 'Trip to Goa' already exists")
+ print("✅ Group 'Trip to Goa' already exists")
...
- print(f"✅ Group 'Office Lunch Group' already exists")
+ print("✅ Group 'Office Lunch Group' already exists")Also applies to: 233-233, 251-251
🧰 Tools
🪛 Ruff (0.11.9)
215-215: f-string without any placeholders
Remove extraneous f prefix
(F541)
🤖 Prompt for AI Agents
In ui-poc/setup_test_data.py at lines 215, 233, and 251, remove the unnecessary
f-string prefixes from print statements that do not contain any placeholders.
Replace the f-strings with regular string literals to clean up the code.
| self.create_expense( | ||
| self.users["Alice Johnson"]["access_token"], | ||
| group_id, | ||
| "Monthly Rent - March", | ||
| 45000.0, | ||
| [ | ||
| {"userId": alice_id, "amount": 15000.0, "type": "equal"}, | ||
| {"userId": bob_id, "amount": 15000.0, "type": "equal"}, | ||
| {"userId": charlie_id, "amount": 15000.0, "type": "equal"} | ||
| ] | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use create_expense_if_not_exists to prevent duplicates.
The setup functions use create_expense directly instead of create_expense_if_not_exists, which could create duplicate expenses on repeated runs of the script.
Replace all calls to self.create_expense with self.create_expense_if_not_exists throughout the setup functions. For example:
- self.create_expense(
+ self.create_expense_if_not_exists(
self.users["Alice Johnson"]["access_token"],
group_id,
"Monthly Rent - March",Also applies to: 289-301, 304-315, 318-329, 332-343
🤖 Prompt for AI Agents
In ui-poc/setup_test_data.py around lines 276 to 286 and also in lines 289-301,
304-315, 318-329, and 332-343, replace all calls to self.create_expense with
self.create_expense_if_not_exists to avoid creating duplicate expenses when the
setup script is run multiple times. This change ensures that expenses are only
created if they do not already exist.
| import json | ||
| import time | ||
| import random | ||
| from datetime import datetime, timedelta |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove unused imports.
These modules are imported but never used in the code.
import requests
-import json
import time
-import random
-from datetime import datetime, timedelta
from typing import Dict, List, Any📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| import json | |
| import time | |
| import random | |
| from datetime import datetime, timedelta | |
| import requests | |
| import time | |
| from typing import Dict, List, Any |
🧰 Tools
🪛 Ruff (0.11.9)
17-17: json imported but unused
Remove unused import: json
(F401)
19-19: random imported but unused
Remove unused import: random
(F401)
20-20: datetime.datetime imported but unused
Remove unused import
(F401)
20-20: datetime.timedelta imported but unused
Remove unused import
(F401)
🤖 Prompt for AI Agents
In ui-poc/setup_test_data.py around lines 17 to 20, the imports for time,
random, datetime, and timedelta are not used anywhere in the code. Remove these
unused imports to clean up the code and avoid unnecessary dependencies.
…mized calculations and debug information
… improve error handling
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (9)
ui-poc/Home.py (1)
3-4: Remove unused imports.Both
datetimeandjsonimports are unused and should be removed to clean up the code.-from datetime import datetime -import jsonui-poc/pages/Groups.py (8)
4-4: Remove unused import.The
jsonmodule is imported but not used anywhere in the file.
32-32: Remove unreachable code.This return statement can never be reached since the while loop either returns a response or raises an exception.
46-46: Use the retry wrapper for consistency.The health check API call should use the
make_api_requestfunction for consistency and to benefit from retry logic.
52-52: Remove extraneous f-string prefix.The error message doesn't use any placeholders, so the f-string prefix is unnecessary.
83-84: Replace bare except clauses with specific exception handling.Bare except clauses can hide important errors and make debugging difficult. Consider catching specific exceptions.
92-92: Remove extraneous f-string prefix.The error message doesn't use any placeholders.
604-604: Potential precision issue with equal split calculation.When dividing the expense amount equally, rounding to 2 decimal places might cause the total to not exactly match the original amount due to rounding errors.
668-668: Ensure consistent payer identification.The expense creation uses
paidByfield with the selected payer ID, but when displaying expenses, the code usescreatedByfield to identify the payer. This inconsistency could lead to incorrect balance calculations.
🧹 Nitpick comments (2)
ui-poc/Home.py (1)
91-92: Combine nested with statements for cleaner code.- with login_tab: - with st.form("login_form", clear_on_submit=False): + with login_tab, st.form("login_form", clear_on_submit=False):Also applies to lines 109-110 for the signup form.
ui-poc/pages/Groups.py (1)
220-221: Combine nested with statements for consistency.Multiple locations in the file use nested
withstatements that can be combined for cleaner code.-with st.expander("Join a Group", expanded=False): - with st.form("join_group_form_page", clear_on_submit=True): +with st.expander("Join a Group", expanded=False), st.form("join_group_form_page", clear_on_submit=True):Also applies to lines 243-244 and 329-330.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
ui-poc/Home.py(1 hunks)ui-poc/pages/Groups.py(1 hunks)
🪛 Ruff (0.12.2)
ui-poc/Home.py
3-3: datetime.datetime imported but unused
Remove unused import: datetime.datetime
(F401)
4-4: json imported but unused
Remove unused import: json
(F401)
91-92: Use a single with statement with multiple contexts instead of nested with statements
Combine with statements
(SIM117)
109-110: Use a single with statement with multiple contexts instead of nested with statements
(SIM117)
ui-poc/pages/Groups.py
4-4: json imported but unused
Remove unused import: json
(F401)
52-52: f-string without any placeholders
Remove extraneous f prefix
(F541)
83-83: Do not use bare except
(E722)
92-92: f-string without any placeholders
Remove extraneous f prefix
(F541)
100-100: Do not use bare except
(E722)
125-125: Do not use bare except
(E722)
137-137: Do not use bare except
(E722)
220-221: Use a single with statement with multiple contexts instead of nested with statements
(SIM117)
243-244: Use a single with statement with multiple contexts instead of nested with statements
(SIM117)
329-330: Use a single with statement with multiple contexts instead of nested with statements
(SIM117)
884-884: Do not use bare except
(E722)
919-919: f-string without any placeholders
Remove extraneous f prefix
(F541)
🧰 Additional context used
🪛 Ruff (0.12.2)
ui-poc/Home.py
3-3: datetime.datetime imported but unused
Remove unused import: datetime.datetime
(F401)
4-4: json imported but unused
Remove unused import: json
(F401)
91-92: Use a single with statement with multiple contexts instead of nested with statements
Combine with statements
(SIM117)
109-110: Use a single with statement with multiple contexts instead of nested with statements
(SIM117)
ui-poc/pages/Groups.py
4-4: json imported but unused
Remove unused import: json
(F401)
52-52: f-string without any placeholders
Remove extraneous f prefix
(F541)
83-83: Do not use bare except
(E722)
92-92: f-string without any placeholders
Remove extraneous f prefix
(F541)
100-100: Do not use bare except
(E722)
125-125: Do not use bare except
(E722)
137-137: Do not use bare except
(E722)
220-221: Use a single with statement with multiple contexts instead of nested with statements
(SIM117)
243-244: Use a single with statement with multiple contexts instead of nested with statements
(SIM117)
329-330: Use a single with statement with multiple contexts instead of nested with statements
(SIM117)
884-884: Do not use bare except
(E722)
919-919: f-string without any placeholders
Remove extraneous f prefix
(F541)
🔇 Additional comments (4)
ui-poc/Home.py (3)
25-63: Authentication functions are well-implemented.The login, signup, and logout functions follow good patterns with proper error handling and clear return values.
130-196: Dashboard implementation looks solid.Good use of columns, proper error handling, and user-friendly features like limiting displayed groups and providing navigation options.
197-200: Good documentation of architectural refactoring.Clear indication that functionality has been moved to a dedicated page maintains code clarity.
ui-poc/pages/Groups.py (1)
1-933: Well-implemented comprehensive groups management interface.This file provides a feature-rich groups management system with excellent user experience considerations. The implementation includes proper session state management, comprehensive split methods, and good visual feedback for users.
… On reload, the auth persist. Will enhance expense handling flow later. (#83)
for more information, see https://pre-commit.ci
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (18)
ui-poc/pages/Groups.py (8)
1-1: Remove unused import.The
jsonmodule is imported but never used in the code.-import json
70-70: Remove unreachable code.This return statement is unreachable since the while loop either returns a response or raises an exception.
- return None # This shouldn't be reached, but added for safety
85-85: Use the retry wrapper for consistency.The health check API call should use the
make_api_requestfunction for consistency and to benefit from retry logic.- status_response = requests.get(f"{API_URL}/health", timeout=3) + status_response = make_api_request('get', f"{API_URL}/health")
92-92: Remove extraneous f-string prefix.The error message doesn't use any placeholders, so the f-string prefix is unnecessary.
- st.error(f"API Connection: Offline") + st.error("API Connection: Offline")
116-117: Replace bare except clauses with specific exception handling.Bare except clauses can hide important errors and make debugging difficult. Consider catching specific exceptions.
- except: - st.sidebar.write("Failed to parse response as JSON") + except (json.JSONDecodeError, ValueError) as e: + st.sidebar.write(f"Failed to parse response as JSON: {e}")Apply the same pattern to other bare except clauses in the file.
Also applies to: 135-135, 159-159, 1058-1058
126-126: Remove extraneous f-string prefixes.These error messages don't use any placeholders, so the f-string prefixes are unnecessary.
- st.error(f"Unexpected response format: 'groups' key not found in response") + st.error("Unexpected response format: 'groups' key not found in response")Apply the same fix to other similar lines.
Also applies to: 171-171, 1114-1114
644-645: Potential precision issue with equal split calculation.When dividing the expense amount equally, rounding to 2 decimal places might cause the total to not exactly match the original amount due to rounding errors.
Consider adjusting the last split to account for any rounding difference:
equal_split_amount = round(expense_amount / len(selected_member_ids), 2) total_assigned = equal_split_amount * (len(selected_member_ids) - 1) last_split_amount = round(expense_amount - total_assigned, 2)
233-233: Ensure consistent payer identification.The expense creation uses
paidByfield with the selected payer ID, but when displaying expenses, the code usescreatedByfield to identify the payer. This inconsistency could lead to incorrect balance calculations.Verify that the backend API correctly handles the
paidByfield and returns it in the expense response. If the API uses a different field name for the payer, update the display logic accordingly:- payer_id = expense.get('createdBy') + payer_id = expense.get('paidBy', expense.get('createdBy'))Also applies to: 1062-1062
ui-poc/Home.py (1)
1-2: Remove unused imports.The
jsonanddatetimemodules are imported but never used in the code.-import json -from datetime import datetimeui-poc/pages/Friends.py (6)
1-1: Remove unused imports.The
json,defaultdict, anddatetimemodules are imported but never used in the code.-import json -from collections import defaultdict -from datetime import datetimeAlso applies to: 3-3, 4-4
86-86: Use the retry wrapper for consistency.The health check should use
make_api_requestfor consistency with other API calls and to benefit from retry logic.- status_response = requests.get(f"{API_URL}/health", timeout=3) + status_response = make_api_request('get', f"{API_URL}/health")
93-93: Remove extraneous f-string prefixes.These error messages don't use any placeholders, so the f-string prefixes are unnecessary.
- st.error(f"API Connection: Offline") + st.error("API Connection: Offline")Apply the same fix to the other similar line.
Also applies to: 126-126
116-117: Replace bare except with specific exception handling.Catch specific exceptions for better error handling and debugging.
- except: - st.sidebar.write("Failed to parse response as JSON") + except (json.JSONDecodeError, ValueError) as e: + st.sidebar.write(f"Failed to parse response as JSON: {e}")
218-221: Remove unused variables.These variables are assigned but never used in the calculation logic.
- current_user_paid = ( - total_amount if payer_id == current_user_id else 0 - ) - friend_paid = total_amount if payer_id == friend_user_id else 0
21-34: Consider extracting duplicate code.The
check_cookies()function is identical to the one inHome.pyandGroups.py. This represents code duplication that should be refactored into a shared utility.Refer to the suggestion in Home.py review for creating a shared
ui-poc/utils/auth.pymodule.ui-poc/setup_test_data.py (3)
16-20: Remove unused imports.These modules are imported but never used in the code.
import requests -import json -import random import time -from datetime import datetime, timedelta from typing import Any, Dict, List
254-254: Remove extraneous f-string prefixes.These strings don't use any placeholders.
- print(f"✅ Group 'House Share' already exists") + print("✅ Group 'House Share' already exists")Also applies to lines 282 and 310.
346-609: Use create_expense_if_not_exists to prevent duplicates.The setup functions use
create_expensedirectly instead ofcreate_expense_if_not_exists, which could create duplicate expenses on repeated runs of the script.Replace all calls to
self.create_expensewithself.create_expense_if_not_existsthroughout the setup functions. For example:- self.create_expense( + self.create_expense_if_not_exists( self.users["Alice Johnson"]["access_token"], group_id, "Monthly Rent - March",
🧹 Nitpick comments (3)
ui-poc/pages/Groups.py (1)
256-257: Simplify nested with statements.Use a single
withstatement with multiple contexts instead of nestedwithstatements for better readability.-with st.expander("Join a Group", expanded=False): - with st.form("join_group_form_page", clear_on_submit=True): +with st.expander("Join a Group", expanded=False), \ + st.form("join_group_form_page", clear_on_submit=True):Apply the same simplification to other nested
withstatements.Also applies to: 283-284, 382-383
ui-poc/setup_test_data.py (2)
119-124: Useany()function for cleaner code.The current for loop can be replaced with a more Pythonic approach using the
any()function.def expense_exists(self, expenses: List[Dict], description: str) -> bool: """Check if an expense with the given description already exists""" - for expense in expenses: - if expense.get("description") == description: - return True - return False + return any(expense.get("description") == description for expense in expenses)
25-25: Make API URL configurable for different environments.The hardcoded production URL limits flexibility for testing against different environments.
+import os + # API Configuration -API_URL = "https://splitwiser-production.up.railway.app" +API_URL = os.getenv("SPLITWISER_API_URL", "https://splitwiser-production.up.railway.app")This allows developers to test against local or staging environments by setting the
SPLITWISER_API_URLenvironment variable.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
ui-poc/Home.py(1 hunks)ui-poc/pages/Friends.py(1 hunks)ui-poc/pages/Groups.py(1 hunks)ui-poc/requirements.txt(1 hunks)ui-poc/setup_test_data.py(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- ui-poc/requirements.txt
🧰 Additional context used
📓 Path-based instructions (4)
ui-poc/pages/*.py
📄 CodeRabbit Inference Engine (.github/copilot-instructions.md)
ui-poc/pages/*.py: Frontend POC application pages must be placed in ui-poc/pages/ as individual Python files.
When adding a new UI component, modify or add files in /ui-poc/pages/.
Files:
ui-poc/pages/Friends.pyui-poc/pages/Groups.py
ui-poc/pages/Groups.py
📄 CodeRabbit Inference Engine (.github/copilot-instructions.md)
API calls from the frontend should use retry logic as demonstrated in Groups.py.
Files:
ui-poc/pages/Groups.py
ui-poc/Home.py
📄 CodeRabbit Inference Engine (.github/copilot-instructions.md)
ui-poc/Home.py: Frontend POC must be implemented using Streamlit, with the entry point in ui-poc/Home.py.
Streamlit session state must be used to manage user sessions in the frontend, as shown in Home.py.
Files:
ui-poc/Home.py
ui-poc/setup_test_data.py
📄 CodeRabbit Inference Engine (.github/copilot-instructions.md)
Test data for the frontend must be generated using ui-poc/setup_test_data.py.
Files:
ui-poc/setup_test_data.py
🧠 Learnings (5)
📓 Common learnings
Learnt from: CR
PR: Devasy23/splitwiser#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-26T09:41:01.332Z
Learning: Applies to backend/app/expenses/**/*.py : Support for different expense split types (equal, unequal, percentage-based) must be implemented in the expense tracking logic.
Learnt from: CR
PR: Devasy23/splitwiser#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-26T09:41:01.332Z
Learning: Applies to ui-poc/Home.py : Frontend POC must be implemented using Streamlit, with the entry point in ui-poc/Home.py.
Learnt from: CR
PR: Devasy23/splitwiser#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-26T09:41:01.332Z
Learning: Applies to backend/app/{auth,user,groups,expenses}/**/*.py : Backend services should be modular, with authentication and user registration in app/auth/, user profile management in app/user/, group management in app/groups/, and expense tracking in app/expenses/.
Learnt from: CR
PR: Devasy23/splitwiser#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-26T09:41:01.332Z
Learning: Applies to ui-poc/pages/*.py : When adding a new UI component, modify or add files in /ui-poc/pages/.
ui-poc/pages/Friends.py (5)
Learnt from: CR
PR: Devasy23/splitwiser#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-26T09:41:01.332Z
Learning: Applies to ui-poc/Home.py : Streamlit session state must be used to manage user sessions in the frontend, as shown in Home.py.
Learnt from: CR
PR: Devasy23/splitwiser#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-26T09:41:01.332Z
Learning: Applies to ui-poc/Home.py : Frontend POC must be implemented using Streamlit, with the entry point in ui-poc/Home.py.
Learnt from: CR
PR: Devasy23/splitwiser#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-26T09:41:01.332Z
Learning: Applies to ui-poc/pages/Groups.py : API calls from the frontend should use retry logic as demonstrated in Groups.py.
Learnt from: CR
PR: Devasy23/splitwiser#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-26T09:41:01.332Z
Learning: Applies to ui-poc/pages/*.py : When adding a new UI component, modify or add files in /ui-poc/pages/.
Learnt from: CR
PR: Devasy23/splitwiser#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-26T09:41:01.332Z
Learning: Applies to backend/app/expenses/**/*.py : Settlements must track debt resolution between users in the expense tracking logic.
ui-poc/pages/Groups.py (7)
Learnt from: CR
PR: Devasy23/splitwiser#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-26T09:41:01.332Z
Learning: Applies to ui-poc/pages/Groups.py : API calls from the frontend should use retry logic as demonstrated in Groups.py.
Learnt from: CR
PR: Devasy23/splitwiser#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-26T09:41:01.332Z
Learning: Applies to ui-poc/Home.py : Streamlit session state must be used to manage user sessions in the frontend, as shown in Home.py.
Learnt from: CR
PR: Devasy23/splitwiser#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-26T09:41:01.332Z
Learning: Applies to backend/app/expenses/**/*.py : Settlements must track debt resolution between users in the expense tracking logic.
Learnt from: CR
PR: Devasy23/splitwiser#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-26T09:41:01.332Z
Learning: Applies to backend/app/{auth,user,groups,expenses}/**/*.py : Backend services should be modular, with authentication and user registration in app/auth/, user profile management in app/user/, group management in app/groups/, and expense tracking in app/expenses/.
Learnt from: CR
PR: Devasy23/splitwiser#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-26T09:41:01.332Z
Learning: Applies to ui-poc/Home.py : Frontend POC must be implemented using Streamlit, with the entry point in ui-poc/Home.py.
Learnt from: CR
PR: Devasy23/splitwiser#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-26T09:41:01.332Z
Learning: Applies to backend/app/expenses/**/*.py : Support for different expense split types (equal, unequal, percentage-based) must be implemented in the expense tracking logic.
Learnt from: CR
PR: Devasy23/splitwiser#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-26T09:41:01.332Z
Learning: Applies to ui-poc/pages/*.py : When adding a new UI component, modify or add files in /ui-poc/pages/.
ui-poc/Home.py (8)
Learnt from: CR
PR: Devasy23/splitwiser#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-26T09:41:01.332Z
Learning: Applies to ui-poc/Home.py : Frontend POC must be implemented using Streamlit, with the entry point in ui-poc/Home.py.
Learnt from: CR
PR: Devasy23/splitwiser#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-26T09:41:01.332Z
Learning: Applies to ui-poc/Home.py : Streamlit session state must be used to manage user sessions in the frontend, as shown in Home.py.
Learnt from: CR
PR: Devasy23/splitwiser#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-26T09:41:01.332Z
Learning: Applies to ui-poc/pages/*.py : When adding a new UI component, modify or add files in /ui-poc/pages/.
Learnt from: CR
PR: Devasy23/splitwiser#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-26T09:41:01.332Z
Learning: Applies to ui-poc/pages/*.py : Frontend POC application pages must be placed in ui-poc/pages/ as individual Python files.
Learnt from: CR
PR: Devasy23/splitwiser#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-26T09:41:01.332Z
Learning: Applies to backend/app/{auth,user,groups,expenses}/**/*.py : Backend services should be modular, with authentication and user registration in app/auth/, user profile management in app/user/, group management in app/groups/, and expense tracking in app/expenses/.
Learnt from: CR
PR: Devasy23/splitwiser#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-26T09:41:01.332Z
Learning: Applies to ui-poc/pages/Groups.py : API calls from the frontend should use retry logic as demonstrated in Groups.py.
Learnt from: CR
PR: Devasy23/splitwiser#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-26T09:41:01.332Z
Learning: Applies to backend/app/expenses/**/*.py : Support for different expense split types (equal, unequal, percentage-based) must be implemented in the expense tracking logic.
Learnt from: CR
PR: Devasy23/splitwiser#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-26T09:41:01.332Z
Learning: Applies to backend/app/expenses/**/*.py : Settlements must track debt resolution between users in the expense tracking logic.
ui-poc/setup_test_data.py (3)
Learnt from: CR
PR: Devasy23/splitwiser#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-26T09:41:01.332Z
Learning: Applies to ui-poc/setup_test_data.py : Test data for the frontend must be generated using ui-poc/setup_test_data.py.
Learnt from: CR
PR: Devasy23/splitwiser#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-26T09:41:01.332Z
Learning: Applies to backend/app/expenses/**/*.py : Support for different expense split types (equal, unequal, percentage-based) must be implemented in the expense tracking logic.
Learnt from: CR
PR: Devasy23/splitwiser#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-26T09:41:01.332Z
Learning: Applies to backend/app/expenses/**/*.py : Settlements must track debt resolution between users in the expense tracking logic.
🧬 Code Graph Analysis (2)
ui-poc/pages/Friends.py (6)
ui-poc/Home.py (1)
check_cookies(100-113)ui-poc/pages/Groups.py (5)
check_cookies(20-33)make_api_request(45-70)fetch_user_groups(104-142)fetch_group_members(146-178)fetch_group_expenses(182-200)backend/app/expenses/service.py (1)
get_friends_balance_summary(799-917)backend/app/expenses/schemas.py (3)
FriendBalance(168-175)FriendsBalanceResponse(177-179)FriendBalanceBreakdown(162-166)backend/tests/expenses/test_expense_service.py (2)
test_get_friends_balance_summary_success(1215-1360)test_get_friends_balance_summary_no_friends_or_groups(1364-1396)backend/app/expenses/routes.py (1)
get_cross_group_friend_balances(318-326)
ui-poc/Home.py (3)
ui-poc/pages/Friends.py (1)
check_cookies(21-34)ui-poc/pages/Groups.py (1)
check_cookies(20-33)ui-poc/setup_test_data.py (1)
main(669-672)
🪛 Ruff (0.12.2)
ui-poc/pages/Friends.py
1-1: json imported but unused
Remove unused import: json
(F401)
3-3: collections.defaultdict imported but unused
Remove unused import: collections.defaultdict
(F401)
4-4: datetime.datetime imported but unused
Remove unused import: datetime.datetime
(F401)
93-93: f-string without any placeholders
Remove extraneous f prefix
(F541)
116-116: Do not use bare except
(E722)
126-126: f-string without any placeholders
Remove extraneous f prefix
(F541)
218-218: Local variable current_user_paid is assigned to but never used
Remove assignment to unused variable current_user_paid
(F841)
221-221: Local variable friend_paid is assigned to but never used
Remove assignment to unused variable friend_paid
(F841)
ui-poc/pages/Groups.py
1-1: json imported but unused
Remove unused import: json
(F401)
92-92: f-string without any placeholders
Remove extraneous f prefix
(F541)
116-116: Do not use bare except
(E722)
126-126: f-string without any placeholders
Remove extraneous f prefix
(F541)
135-135: Do not use bare except
(E722)
159-159: Do not use bare except
(E722)
171-171: Do not use bare except
(E722)
256-257: Use a single with statement with multiple contexts instead of nested with statements
(SIM117)
283-284: Use a single with statement with multiple contexts instead of nested with statements
(SIM117)
382-383: Use a single with statement with multiple contexts instead of nested with statements
(SIM117)
1058-1058: Do not use bare except
(E722)
1114-1114: f-string without any placeholders
Remove extraneous f prefix
(F541)
ui-poc/Home.py
1-1: json imported but unused
Remove unused import: json
(F401)
2-2: datetime.datetime imported but unused
Remove unused import: datetime.datetime
(F401)
144-145: Use a single with statement with multiple contexts instead of nested with statements
Combine with statements
(SIM117)
163-164: Use a single with statement with multiple contexts instead of nested with statements
Combine with statements
(SIM117)
ui-poc/setup_test_data.py
16-16: json imported but unused
Remove unused import: json
(F401)
17-17: random imported but unused
Remove unused import: random
(F401)
19-19: datetime.datetime imported but unused
Remove unused import
(F401)
19-19: datetime.timedelta imported but unused
Remove unused import
(F401)
121-124: Use return any(expense.get("description") == description for expense in expenses) instead of for loop
Replace with return any(expense.get("description") == description for expense in expenses)
(SIM110)
254-254: f-string without any placeholders
Remove extraneous f prefix
(F541)
282-282: f-string without any placeholders
Remove extraneous f prefix
(F541)
310-310: f-string without any placeholders
Remove extraneous f prefix
(F541)
🔇 Additional comments (6)
ui-poc/Home.py (3)
144-145: Simplify nested with statements.Use a single
withstatement with multiple contexts instead of nestedwithstatements for better readability.- with st.form("login_form", clear_on_submit=False): + with st.form("login_form", clear_on_submit=False):Wait, this is already using single
withstatements. The static analysis hint appears to be a false positive here since thewith st.formis not nested inside anotherwithstatement at the same indentation level.Also applies to: 163-164
36-66: LGTM! Well-structured authentication flow.The login function properly handles API responses, stores authentication data in both session state and cookies, and provides appropriate error handling. The implementation follows the expected authentication pattern for the application.
188-261: LGTM! Comprehensive dashboard implementation.The main dashboard effectively provides quick navigation to other pages, displays recent activity with user groups, and includes helpful getting started tips. The error handling and user feedback are well implemented.
ui-poc/pages/Friends.py (2)
177-235: LGTM! Well-implemented balance calculation logic.The
calculate_friend_balancefunction correctly computes net balances between users across shared groups by:
- Identifying shared groups between users
- Processing expenses where both users have splits
- Calculating the net effect based on who paid and who owes
- Returning both the balance and list of shared groups
The logic properly handles the case where one user pays for another's share, contributing to accurate balance tracking.
296-355: LGTM! Intuitive friends list display.The friends list implementation provides a clear overview with:
- Summary metrics showing total friends and amounts owed/owing
- Sorted display by balance magnitude to highlight significant debts/credits
- Color-coded balance indicators (green for owed, red for owing)
- Detailed view navigation with session state management
The UI effectively communicates financial relationships and provides good user experience.
ui-poc/setup_test_data.py (1)
1-677: Excellent implementation of comprehensive test data setup.This script effectively implements the coding guideline requirement for test data generation and provides realistic scenarios covering:
- Multiple users with proper authentication
- Various group configurations and memberships
- Comprehensive expense scenarios with equal, unequal, and percentage splits
- Good error handling and duplicate prevention logic
- Realistic test cases that align with the expense splitting requirements
The implementation supports the Streamlit-based UI POC by creating meaningful test data that demonstrates the application's core functionality.
| def check_cookies(): | ||
| access_token = cookies.get("access_token") | ||
| user_id = cookies.get("user_id") | ||
| username = cookies.get("username") | ||
|
|
||
| if access_token == "" or not access_token: | ||
| st.session_state.access_token = None | ||
| st.session_state.user_id = None | ||
| st.session_state.username = None | ||
| return False | ||
| st.session_state.access_token = access_token | ||
| st.session_state.user_id = user_id | ||
| st.session_state.username = username | ||
| return True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider extracting duplicate cookie check logic.
The check_cookies() function is identical across Home.py, Groups.py, and Friends.py. Consider extracting this common functionality to a shared utility module to reduce code duplication.
Create a new file ui-poc/utils/auth.py:
import streamlit as st
from streamlit_cookies_manager import EncryptedCookieManager
def check_cookies(cookies: EncryptedCookieManager) -> bool:
access_token = cookies.get("access_token")
user_id = cookies.get("user_id")
username = cookies.get("username")
if access_token == "" or not access_token:
st.session_state.access_token = None
st.session_state.user_id = None
st.session_state.username = None
return False
st.session_state.access_token = access_token
st.session_state.user_id = user_id
st.session_state.username = username
return TrueThen import and use it in all three files.
🤖 Prompt for AI Agents
In ui-poc/Home.py lines 100 to 113, the check_cookies() function duplicates
logic found in Groups.py and Friends.py. To fix this, extract the check_cookies
function into a new shared utility module at ui-poc/utils/auth.py with the same
implementation, then update Home.py, Groups.py, and Friends.py to import and
call this shared function instead of defining it locally. This reduces code
duplication and centralizes cookie checking logic.
…c/frontend-streamlit
Summary by CodeRabbit
New Features
Bug Fixes
Chores