Skip to content

Conversation

@Devasy
Copy link
Owner

@Devasy Devasy commented Jul 9, 2025

Summary by CodeRabbit

  • New Features

    • Added comprehensive documentation for UI/UX design, user flows, authentication, group, expense, friends, settlement, and navigation screens for the SplitWiser app.
    • Introduced a full Material 3 design system specification and detailed folder structure guidelines.
    • Added OpenAPI specification for the backend API.
    • Implemented a Streamlit-based UI proof of concept supporting user authentication, group management, and expense tracking.
    • Added requirements and setup documentation for the UI POC.
    • Added a test data setup script to automate creation of users, groups, and expenses for realistic testing scenarios.
  • Bug Fixes

    • Not applicable.
  • Chores

    • Removed legacy React Native frontend code, configuration, and documentation files.

Devasy added 4 commits July 2, 2025 21:17
…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.
@Devasy Devasy requested a review from vrajpatelll as a code owner July 9, 2025 11:58
@netlify
Copy link

netlify bot commented Jul 9, 2025

Deploy Preview for splitwizer failed. Why did it fail? →

Name Link
🔨 Latest commit e3e9f92
🔍 Latest deploy log https://app.netlify.com/projects/splitwizer/deploys/6887c5f2c3757d00087688b1

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 9, 2025

Walkthrough

This 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

Files / Groups Change Summary
Documentation
docs/design-system.md, docs/folder-structure.md, docs/frontend-ui-design.md, docs/frontend-user-flow.md, docs/screens/auth-screens.md, docs/screens/expense-creation.md, docs/screens/friends-screens.md, docs/screens/groups-screens.md, docs/screens/main-navigation.md, docs/screens/settlement-screens.md
Added extensive documentation covering design system, folder structure, UI/UX principles, navigation/user flows, and detailed wireframes/specs for all major app screens.
Streamlit UI Proof of Concept
ui-poc/Home.py, ui-poc/pages/Groups.py, ui-poc/pages/Friends.py
Added Streamlit-based UI POC implementing authentication, group/expense management, and friends placeholder, with robust API integration and session handling.
Streamlit UI Support Files
ui-poc/README.md, ui-poc/requirements.txt
Added README and requirements for the Streamlit UI POC.
Backend API Specification
ui-poc/openapi.json
Added a full OpenAPI 3.1.0 specification for the SplitWiser backend API, covering all endpoints and schemas.
Test Data Setup
ui-poc/setup_test_data.py
Added a script to automate creation of realistic test data including users, groups, and expenses via API calls.
React Native Frontend Removal
frontend/App.tsx, frontend/contexts/AuthContext.tsx, frontend/screens/HomeScreen.tsx, frontend/screens/LoginScreen.tsx
Deleted React Native app entry point, authentication context, and main screen components.
React Native Frontend Config and Docs Removal
frontend/README.md, frontend/app.json, frontend/package.json, frontend/tsconfig.json
Deleted React Native frontend configuration and documentation files.

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
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~90 minutes

Suggested labels

documentation, enhancement, backend, level2

Suggested reviewers

  • Devasy23

Poem

In burrows deep, this rabbit writes,
Of docs and flows and UI delights.
Old code is gone, new streams appear—
With Streamlit magic, the path is clear.
Groups and expenses, friends soon to show,
Hop along, SplitWiser, onward you go!
🐇✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch poc/frontend-streamlit

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

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need 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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@codecov
Copy link

codecov bot commented Jul 9, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 85.96%. Comparing base (56dd9dc) to head (e3e9f92).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

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           
Flag Coverage Δ
api 85.96% <ø> (ø)
backend 85.96% <ø> (ø)
python 85.96% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
Authentication System ∅ <ø> (∅)
Expense Management ∅ <ø> (∅)
Group Management ∅ <ø> (∅)
User Management ∅ <ø> (∅)
Backend Core 66.66% <ø> (ø)
Frontend Authentication ∅ <ø> (∅)
Frontend Screens ∅ <ø> (∅)
Frontend Core ∅ <ø> (∅)
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Devasy
Copy link
Owner Author

Devasy commented Jul 9, 2025

@codecovai test

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 requests module is imported but not used in this placeholder page.

-import requests
docs/frontend-user-flow.md (1)

5-15: Trim the code-fence to three back-ticks to comply with MD040

The 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 fences

markdownlint 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 with text

All 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 as text to satisfy markdownlint

Same 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 with statement 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 text as the language identifier.

-```
+```text

Also 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 activity
docs/screens/main-navigation.md (2)

6-6: Add language specifiers to fenced code blocks.

Use text as the language identifier for ASCII wireframes.

-```
+```text

Also 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 picture
ui-poc/Home.py (1)

91-107: Simplify nested context managers.

Multiple nested with statements 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 text as the language identifier for ASCII wireframes.

-```
+```text

Also 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

darkColors stops after the secondary palette and jumps straight to neutral, leaving out tertiary, error, success, shadow, and scrim. 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 sample

The 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

markdownlint flags MD040 because the fenced block lacks a language tag.
Using text (or bash) 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 specification

Same 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
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

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:

  1. Missing global security rules - No default security requirements defined
  2. Empty security operations - Some operations may lack proper security
  3. 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.

Comment on lines +83 to +84
except:
st.sidebar.write("Failed to parse response as JSON")
Copy link
Contributor

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.

st.error("No members selected for splitting the expense.")
st.stop()

equal_split_amount = round(expense_amount / len(selected_member_ids), 2)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

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
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

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.

Suggested change
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)
Copy link
Contributor

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.

Suggested change
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
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

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.

Suggested change
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
Comment on lines 330 to 331
except:
st.write(date_str)
Copy link
Contributor

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.

Suggested change
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')}")
Copy link
Contributor

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.py

Length 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.py

Length 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.py

Length 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.

Suggested change
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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 json module 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_request function 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

📥 Commits

Reviewing files that changed from the base of the PR and between 40d72db and bf01953.

📒 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
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

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.

if 'groups' in data:
return data['groups']
else:
st.error(f"Unexpected response format: 'groups' key not found in response")
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

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.

Suggested change
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")
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

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.

Suggested change
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.

if 'expenses' in data:
return data['expenses']
else:
st.error(f"Unexpected response format: 'expenses' key not found in response")
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

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.

Suggested change
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.

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]")
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

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.

Suggested change
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.

Comment on lines +83 to +84
except:
st.sidebar.write("Failed to parse response as JSON")
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

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.

Suggested change
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)
Copy link
Contributor

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.

Suggested change
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")
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

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.

Comment on lines 276 to 286
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"}
]
)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

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.

Comment on lines 17 to 20
import json
import time
import random
from datetime import datetime, timedelta
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

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.

Suggested change
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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 datetime and json imports are unused and should be removed to clean up the code.

-from datetime import datetime
-import json
ui-poc/pages/Groups.py (8)

4-4: Remove unused import.

The json module 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_request function 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 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.

🧹 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 with statements 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

📥 Commits

Reviewing files that changed from the base of the PR and between b443c88 and 762c45a.

📒 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.

AneeshAhuja31 and others added 2 commits July 28, 2025 23:57
… On reload, the auth persist. Will enhance expense handling flow later. (#83)
Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 json module 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_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")

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 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: 1062-1062

ui-poc/Home.py (1)

1-2: Remove unused imports.

The json and datetime modules are imported but never used in the code.

-import json
-from datetime import datetime
ui-poc/pages/Friends.py (6)

1-1: Remove unused imports.

The json, defaultdict, and datetime modules are imported but never used in the code.

-import json
-from collections import defaultdict
-from datetime import datetime

Also applies to: 3-3, 4-4


86-86: Use the retry wrapper for consistency.

The health check should use make_api_request for 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 in Home.py and Groups.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.py module.

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_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",
🧹 Nitpick comments (3)
ui-poc/pages/Groups.py (1)

256-257: Simplify nested with statements.

Use a single with statement with multiple contexts instead of nested with statements 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 with statements.

Also applies to: 283-284, 382-383

ui-poc/setup_test_data.py (2)

119-124: Use any() 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_URL environment variable.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 762c45a and 607ee6d.

📒 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.py
  • ui-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 with statement with multiple contexts instead of nested with statements 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 with statements. The static analysis hint appears to be a false positive here since the with st.form is not nested inside another with statement 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_balance function 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.

Comment on lines +100 to +113
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
Copy link
Contributor

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 True

Then 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.

@Devasy Devasy self-assigned this Jul 28, 2025
@Devasy Devasy added enhancement New feature or request gssoc25 level3 labels Jul 28, 2025
@github-project-automation github-project-automation bot moved this to Backlog in Splitwiser Jul 28, 2025
@Devasy Devasy moved this from Backlog to In review in Splitwiser Jul 28, 2025
@Devasy Devasy merged commit 7ccca78 into main Jul 28, 2025
35 of 42 checks passed
@github-project-automation github-project-automation bot moved this from In review to Done in Splitwiser Jul 28, 2025
@Devasy Devasy deleted the poc/frontend-streamlit branch July 28, 2025 18:57
@coderabbitai coderabbitai bot mentioned this pull request Aug 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request gssoc25 level3

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants