-
Notifications
You must be signed in to change notification settings - Fork 24
API documentation #149
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
API documentation #149
Conversation
WalkthroughAdds comprehensive API documentation under docs/api: overview, authentication, users, groups, expenses, settlements, and runnable examples (cURL and Postman). All are docs-only changes; no code or public API declarations were modified. A minor formatting anomaly is present in the cURL examples file. Changes
Sequence Diagram(s)sequenceDiagram
actor Client
participant Auth as Auth Service
participant DB as DB (users/refresh_tokens/password_resets)
Client->>Auth: POST /auth/signup or /auth/login
Auth->>DB: Create/Verify user, store refresh token
DB-->>Auth: User/Token records
Auth-->>Client: access_token (15m) + refresh_token (30d)
Client->>Auth: POST /auth/refresh (with refresh_token)
Auth->>DB: Validate & rotate refresh token
Auth-->>Client: New access_token + rotated refresh_token
sequenceDiagram
actor User
participant API as Expenses API
participant Settle as Settlements Engine
participant DB as DB
User->>API: POST /groups/{group_id}/expenses
API->>DB: Persist expense
API->>Settle: Compute settlements (auto)
Settle-->>API: Settlements
API->>DB: Persist settlements
API-->>User: Expense + settlements + group summary
User->>API: POST /groups/{group_id}/settlements/optimize?algorithm=advanced
API->>Settle: Optimize debts (normal/advanced)
Settle-->>API: Optimized plan + savings
API-->>User: Optimized settlements
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. ✨ Finishing Touches🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
🧹 Nitpick comments (25)
docs/api/README.md (2)
22-24: Specify language on fenced code block to satisfy markdownlint and improve readabilityAdd a language hint (http or bash) to the Authorization header example.
- ``` + ```http Authorization: Bearer <your_access_token> ```
19-19: Minor phrasing cleanupReplace “with the exception of” with “except for” for conciseness.
-All API endpoints (with the exception of sign-up and login) are protected and require a valid **JSON Web Token (JWT)** to be included in the request. +All API endpoints (except for sign-up and login) are protected and require a valid **JSON Web Token (JWT)** to be included in the request.docs/api/users.md (3)
11-12: Show full endpoint paths for claritySince the section states endpoints are prefixed with /users, render the headings with full paths to reduce ambiguity.
-### **`GET /me`** +### **`GET /users/me`** @@ -### **`PATCH /me`** +### **`PATCH /users/me`** @@ -### **`DELETE /me`** +### **`DELETE /users/me`**Also applies to: 31-33, 61-63
62-73: Align deletion semantics and response messageThe text says “scheduled for deletion” but the server-side logic says “permanently deleted (hard delete)”. Pick one. If it’s hard delete, reflect that in the description and response message.
-### **`DELETE /me`** -Schedules the currently authenticated user's account for deletion. +### **`DELETE /users/me`** +Permanently deletes the currently authenticated user's account (hard delete). @@ - *(Note: In a production system, this might be a "soft delete" where the user is marked as inactive, but the current implementation is a "hard delete".)* + *(Note: In a production system, this might be a "soft delete" where the user is marked as inactive. The current implementation is a "hard delete".)* @@ - "message": "User account scheduled for deletion." + "message": "User account deleted successfully."
1-10: Consider documenting balance-summary and friends-balance endpoints referenced by the frontendfrontend/api/groups.js (lines 25-29) calls /users/me/balance-summary and /users/me/friends-balance, which aren’t covered here. Either add them to this doc or create a “Balances” doc and link it from README.
If you confirm the endpoint shapes, I can draft the missing sections with sample requests/responses.
docs/api/examples/postman_collection.json (2)
15-25: Add Content-Type header for raw JSON requestsExplicitly set Content-Type: application/json for requests with a raw JSON body. Postman often infers this, but making it explicit improves portability and avoids edge cases.
Example (apply similarly to all requests with "body.mode": "raw"):
"request": { "method": "POST", - "header": [], + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], "body": {Also applies to: 41-53, 69-81, 97-108, 149-159, 197-209, 241-252, 291-302, 342-354
194-285: Add missing “List Group Members” request to the Groups folderThe docs expose GET /groups/{groupId}/members, and the frontend uses it. Consider adding it to this collection for completeness.
Example item JSON to add under the “Groups” folder:
{ "name": "List Group Members", "request": { "method": "GET", "header": [], "url": { "raw": "{{baseUrl}}/groups/{{groupId}}/members", "host": ["{{baseUrl}}"], "path": ["groups", "{{groupId}}", "members"] } }, "response": [] }docs/api/authentication.md (6)
4-7: Tighten intro wording and fix spacingMinor edits for clarity and formatting.
-The Authentication Service in Splitwiser handles secure user registration, login, and session management using JWT (JSON Web Tokens) with refresh token rotation for enhanced security. It supports multiple authentication providers, including email/password and Google OAuth.This documentation is based on the backend implementation in `/backend/app/auth`. +The Authentication Service in Splitwiser handles secure user registration, login, and session management using JWT (JSON Web Tokens) with refresh token rotation for enhanced security. It supports multiple authentication providers, including email/password and Google OAuth. This documentation is based on the backend implementation in `/backend/app/auth`.
35-41: Polish dependencies list and phrasingClean up punctuation and wording.
-The auth module relies on: -- `fastapi.security`: For OAuth2PasswordBearer . -- `pydantic`: For request/response schemas model.(pydantic model) -- `jose`: For JWT encoding/decoding. -- `passlib`: For password hashing. -- `MongoDB driver`: (e.g.,`pymongo`) for user storage. +The auth module relies on: +- `fastapi.security`: OAuth2PasswordBearer +- `pydantic`: Request/response schema models +- `python-jose`: JWT encoding/decoding +- `passlib[bcrypt]`: Password hashing +- `pymongo`: MongoDB client for user and token storage
76-83: Heading spacing and typos (“4.API Endpoints”, “AuthResponse contains…”)Fix heading spacing and typos.
-## 4.API Endpoints +## 4. API Endpoints @@ -**Responses** (`AuthResponse`): -- Note: AuthResponse conatin another pydhantic model : `UserResponse` +**Responses** (`AuthResponse`): +- Note: `AuthResponse` contains a nested `UserResponse` model
98-114: Normalize timestamp casing in public API examplesElsewhere (users doc) you present createdAt/updatedAt in camelCase. Consider using camelCase here too for consistency across public responses.
- "created_at": "2025-08-12T18:49:48.000Z" + "createdAt": "2025-08-12T18:49:48.000Z"If you decide on snake_case for public responses, please reflect that consistently across all docs and align the backend serializers accordingly.
206-241: Minor grammar and clarity tweaks in password reset sectionsA few sentences are duplicated or awkwardly phrased. Recommend a quick copy edit pass; example fixes below.
-**Description**: Initiates the password reset process for a user.Initiates a password reset process by sending a reset link to the provided email address. +**Description**: Initiates the password reset process by sending a reset link to the provided email address (if the account exists). @@ -- 400 Unauthorized: Invalid or expired refresh token. +- 400 Bad Request: Invalid or expired reset token.
51-63: Complete Python example imports to avoid confusionThe example references Field and datetime without imports. Optional improvement for completeness:
from pydantic import BaseModel, EmailStr, Field from typing import Optional from datetime import datetimedocs/api/groups.md (3)
28-33: Show full endpoint paths with /groups prefixHeadings like “POST /” can be ambiguous. Since this section states the prefix, render paths fully as /groups..., e.g., POST /groups, GET /groups, GET /groups/{group_id}, etc.
-### **`POST /`** +### **`POST /groups`** @@ -### **`GET /`** +### **`GET /groups`** @@ -### **`GET /{group_id}`** +### **`GET /groups/{group_id}`** @@ -### **`PATCH /{group_id}`** +### **`PATCH /groups/{group_id}`** @@ -### **`DELETE /{group_id}`** +### **`DELETE /groups/{group_id}`** @@ -### **`POST /join`** +### **`POST /groups/join`** @@ -### **`POST /{group_id}/leave`** +### **`POST /groups/{group_id}/leave`** @@ -### **`GET /{group_id}/members`** +### **`GET /groups/{group_id}/members`** @@ -### **`PATCH /{group_id}/members/{member_id}`** +### **`PATCH /groups/{group_id}/members/{member_id}`** @@ -### **`DELETE /{group_id}/members/{member_id}`** +### **`DELETE /groups/{group_id}/members/{member_id}`**Also applies to: 60-66, 74-83, 84-96, 97-108, 114-127, 135-151, 152-166, 168-181, 182-198
46-58: Confirm response ID field name matches backendDocs show "id", but backend/app/groups/service.py:transform_group_document currently returns "_id". Please verify what the public response should be and align either the docs or the transformer accordingly (prefer “id” for public API).
If you opt for “id”, I can propose a backend patch to map
_id->idin the transformer and adjust consumers.
60-73: Consider pagination for listing groupsIf the number of groups can be large, document optional pagination/query params (e.g., page, limit) and default ordering.
docs/api/examples/curl_examples.md (3)
9-17: Add REFRESH_TOKEN to prerequisites for consistencyRefresh example uses a literal token. Define and reuse a REFRESH_TOKEN env var like ACCESS_TOKEN for consistency and to avoid hardcoding.
Apply this diff:
export API_URL="http://localhost:8000" export ACCESS_TOKEN="your_jwt_access_token_here" +export REFRESH_TOKEN="your_jwt_refresh_token_here" export GROUP_ID="your_group_id_here" export EXPENSE_ID="your_expense_id_here" export SETTLEMENT_ID="your_settlement_id_here" export MEMBER_ID="a_group_member_id_here"
42-49: Use REFRESH_TOKEN env var in the refresh exampleUse the newly defined REFRESH_TOKEN for the refresh call.
Apply this diff:
curl -X POST "$API_URL/auth/refresh" \ -H "Content-Type: application/json" \ -d '{ - "refresh_token": "your_refresh_token_here" + "refresh_token": "'"$REFRESH_TOKEN"'" }'
81-102: Optional: Improve curl ergonomics for DXConsider adding options to make failures and outputs clearer:
- -sS for silent with errors
- -f to fail on HTTP errors (non-2xx)
- -H "Accept: application/json" where relevant
This reduces noisy output and surfaces HTTP failures in scripts.
Also applies to: 118-121, 123-127, 139-143, 145-149, 153-169, 171-175, 177-185, 189-200, 202-206, 208-216, 218-221
docs/api/settlements.md (3)
21-27: Normalize spacing and list indentation in “Advanced” algorithm sectionThere are extra spaces (“for the entire group.”) and list indentation doesn’t pass markdownlint (MD007). Normalize spacing and indent sub-items with 2 spaces.
Apply this diff:
-* **Advanced (`algorithm=advanced`)**: A more powerful graph-based algorithm that minimizes the total number of transactions for the entire group. - * **Logic**: - 1. It calculates the net balance of every member (total paid - total owed). - 2. It separates all members into two lists: "debtors" (who owe money) and "creditors" (who are owed money). - 3. Using a two-pointer approach, it matches the person who owes the most with the person who is owed the most, creating a single payment to clear as much debt as possible. - 4. This process continues until all debts are consolidated into the fewest possible transactions. +* **Advanced (`algorithm=advanced`)**: A more powerful graph-based algorithm that minimizes the total number of transactions for the entire group. + - Logic: + 1. It calculates the net balance of every member (total paid - total owed). + 2. It separates all members into two lists: "debtors" (who owe money) and "creditors" (who are owed money). + 3. Using a two-pointer approach, it matches the person who owes the most with the person who is owed the most, creating a single payment to clear as much debt as possible. + 4. This process continues until all debts are consolidated into the fewest possible transactions.
57-61: Fix list indentation for query parameters (markdownlint MD007)Indent bullets by 2 spaces under the section header to satisfy MD007.
Apply this diff:
* **Query Parameters**: - * `status`: Optional filter for settlement status (e.g., "pending"). - * `page` & `limit`: For paginating through the list of raw settlements. - * `algorithm`: The settlement algorithm to use (`normal` or `advanced`). + - `status`: Optional filter for settlement status (e.g., "pending"). + - `page` & `limit`: For paginating through the list of raw settlements. + - `algorithm`: The settlement algorithm to use (`normal` or `advanced`).
116-118: Fix list indentation under “Optimize” endpoint (markdownlint MD007)Indent bullets by 2 spaces under the section header.
Apply this diff:
* **Query Parameters**: - * `algorithm`: `normal` or `advanced` (default). + - `algorithm`: `normal` or `advanced` (default).docs/api/expenses.md (3)
5-6: Fix italics and link to Settlements documentationClose the italics and link the document name to the local Settlements doc.
Apply this diff:
-*For details on how debts are calculated, simplified, and paid, please see the **Settlements.md** +_For details on how debts are calculated, simplified, and paid, please see [Settlements](./settlements.md)._
86-89: Tighten wording (style)Trim “originally created” redundancy.
Apply this diff:
- 1. Verifies that the user attempting the update is the one who originally created the expense. + 1. Verifies that the user attempting the update is the one who created the expense.
124-127: Expand attachments endpoint with minimal request/response shape (optional)Consider adding request fields (e.g., multipart/form-data with file and optional metadata) and a sample response for completeness. This mirrors the detail level of other endpoints.
I can draft a concise request/response example aligned with your current attachments handler if you confirm the expected fields (file field name, optional tags/description).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (8)
docs/api/README.md(1 hunks)docs/api/authentication.md(1 hunks)docs/api/examples/curl_examples.md(1 hunks)docs/api/examples/postman_collection.json(1 hunks)docs/api/expenses.md(1 hunks)docs/api/groups.md(1 hunks)docs/api/settlements.md(1 hunks)docs/api/users.md(1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-07-26T09:41:01.332Z
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/**/*.py : JWT authentication with refresh token rotation must be implemented in the backend.
Applied to files:
docs/api/authentication.md
📚 Learning: 2025-07-26T09:41:01.332Z
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/security.py : To troubleshoot authentication issues, check JWT token handling in app/auth/security.py.
Applied to files:
docs/api/authentication.md
📚 Learning: 2025-07-26T09:41:01.332Z
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.
Applied to files:
docs/api/settlements.md
🧬 Code Graph Analysis (5)
docs/api/expenses.md (3)
backend/app/expenses/service.py (2)
create_expense(41-115)get_friends_balance_summary(955-1094)backend/app/expenses/schemas.py (5)
GroupSummary(134-137)ExpenseCreateResponse(140-143)Settlement(108-122)BalanceSummaryResponse(205-210)ExpenseResponse(89-105)frontend/utils/balanceCalculator.js (2)
expense(82-132)group(175-195)
docs/api/users.md (2)
frontend/api/groups.js (2)
apiClient(26-27)apiClient(29-30)frontend/api/auth.js (1)
userData(11-11)
docs/api/groups.md (2)
frontend/api/groups.js (4)
groupId(5-6)groupId(35-36)groupId(15-16)groupId(43-44)backend/app/groups/service.py (1)
transform_group_document(103-122)
docs/api/authentication.md (1)
backend/app/auth/service.py (1)
AuthService(72-573)
docs/api/settlements.md (7)
backend/app/expenses/schemas.py (2)
Settlement(108-122)OptimizedSettlement(125-131)frontend/screens/GroupSettingsScreen.js (1)
settlementsRes(166-193)frontend/api/groups.js (1)
groupId(5-6)frontend/screens/HomeScreen.js (1)
groupId(33-67)backend/app/expenses/routes.py (1)
get_group_settlements(236-290)backend/app/expenses/service.py (3)
create_manual_settlement(624-671)update_settlement_status(793-820)_create_settlements_for_expense(117-155)backend/tests/expenses/test_expense_service.py (1)
test_calculate_optimized_settlements_advanced(185-255)
🪛 LanguageTool
docs/api/README.md
[style] ~19-~19: Consider using “except” or “except for”
Context: ... Authentication All API endpoints (with the exception of sign-up and login) are protected and re...
(WITH_THE_EXCEPTION_OF)
docs/api/expenses.md
[grammar] ~13-~13: There might be a mistake here.
Context: ...and how the cost is split among members. * When an expense is created, the system a...
(QB_NEW_EN)
[grammar] ~19-~19: There might be a mistake here.
Context: ... permissions, and retrieve user details. * settlements: This collection is used to record the ...
(QB_NEW_EN)
[grammar] ~65-~65: There might be a mistake here.
Context: ...* page, limit, from, to, tags. * Response (ExpenseListResponse): ...
(QB_NEW_EN)
[style] ~86-~86: This phrase is redundant. Consider writing “created”.
Context: ...er attempting the update is the one who originally created the expense. 2. Creates a history ...
(ORIGINALLY_CREATED)
docs/api/groups.md
[grammar] ~21-~21: There might be a mistake here.
Context: ...emails to display in group member lists. * settlements: Queried to perform safety checks, spec...
(QB_NEW_EN)
docs/api/authentication.md
[grammar] ~23-~23: There might be a mistake here.
Context: ...tication provider (email or google). 2. refresh_tokens: Tracks all active refresh tokens. Each...
(QB_NEW_EN)
[grammar] ~35-~35: There might be a mistake here.
Context: ...Dependencies The auth module relies on: - fastapi.security: For OAuth2PasswordBearer . - `pydantic...
(QB_NEW_EN)
[grammar] ~38-~38: There might be a mistake here.
Context: ...el) - jose: For JWT encoding/decoding. - passlib: For password hashing. - `MongoDB drive...
(QB_NEW_EN)
[grammar] ~40-~40: There might be a mistake here.
Context: ...word hashing. - MongoDB driver: (e.g.,pymongo) for user storage. --- ## 3. Data Mod...
(QB_NEW_EN)
[grammar] ~46-~46: There might be a mistake here.
Context: ...chemas ### User Model (in schemas.py) Represents a user in the database: ### ...
(QB_NEW_EN)
[grammar] ~83-~83: There might be a mistake here.
Context: ...s and user information. Parameters: - Request Body (JSON): - email: string...
(QB_NEW_EN)
[grammar] ~84-~84: There might be a mistake here.
Context: ... Parameters: - Request Body (JSON): - email: string (required, valid email) - `pa...
(QB_NEW_EN)
[grammar] ~85-~85: There might be a mistake here.
Context: ... email: string (required, valid email) - password: string (required) - name : string ...
(QB_NEW_EN)
[grammar] ~98-~98: There might be a mistake here.
Context: ...1 } ``` Responses (AuthResponse): - Note: AuthResponse conatin another pydha...
(QB_NEW_EN)
[grammar] ~123-~123: There might be a mistake here.
Context: ...and adds a new session. Parameters: - Request Body (JSON): - email: string...
(QB_NEW_EN)
[grammar] ~124-~124: There might be a mistake here.
Context: ... Parameters: - Request Body (JSON): - email: string (required) - password: stri...
(QB_NEW_EN)
[grammar] ~125-~125: There might be a mistake here.
Context: ...y (JSON): - email: string (required) - password: string (required) Request Example...
(QB_NEW_EN)
[grammar] ~128-~128: There might be a mistake here.
Context: ... string (required) Request Example: * Request Body (EmailLoginRequest): ...
(QB_NEW_EN)
[grammar] ~145-~145: There might be a mistake here.
Context: ...nd issue OAuth ID token Parameters: - Request Body (JSON): - `GoogleLoginReq...
(QB_NEW_EN)
[grammar] ~146-~146: There might be a mistake here.
Context: ... Parameters: - Request Body (JSON): - GoogleLoginRequest: string (required, Google ID token) *...
(QB_NEW_EN)
[grammar] ~164-~164: There might be a mistake here.
Context: ...nd updates the session. Parameters: - Request Body (JSON): - `RefreshTokenRe...
(QB_NEW_EN)
[grammar] ~165-~165: There might be a mistake here.
Context: ... Parameters: - Request Body (JSON): - RefreshTokenRequest: string (required) * Request Body ...
(QB_NEW_EN)
[grammar] ~175-~175: There might be a mistake here.
Context: ... * **Response** (`TokenResponse`): - 200 OK: New tokens issued. json ...
(QB_NEW_EN)
[grammar] ~245-~245: There might be a mistake here.
Context: ...ates, creates/hashes, and issues tokens. 2. Protected Routes: Use `Depends(get_cur...
(QB_NEW_EN)
[grammar] ~248-~248: There might be a mistake here.
Context: ...fresh token. 4. Rotation: On refresh, new refresh token is issued, old one in...
(QB_NEW_EN)
[grammar] ~248-~248: There might be a mistake here.
Context: ...sh token is issued, old one invalidated. 5. Google OAuth: Client gets Google token...
(QB_NEW_EN)
[grammar] ~249-~249: There might be a mistake here.
Context: ...token, sends to server. Server verifies with Google API, links to user. ## Error Co...
(QB_NEW_EN)
[grammar] ~249-~249: There might be a mistake here.
Context: ... Server verifies with Google API, links to user. ## Error Codes - 400: Bad reque...
(QB_NEW_EN)
[grammar] ~262-~262: There might be a mistake here.
Context: ...gin**: POST /auth/login/email → Tokens. - Google Sign-In: Integrate with Google ...
(QB_NEW_EN)
[grammar] ~263-~263: There might be a mistake here.
Context: ...le Sign-In**: Integrate with Google SDK on frontend, send token to /auth/google/lo...
(QB_NEW_EN)
[grammar] ~263-~263: There might be a mistake here.
Context: ...ntend, send token to /auth/google/login. - Session Refresh: When access token exp...
(QB_NEW_EN)
[grammar] ~264-~264: There might be a mistake here.
Context: ...th/google/login. - Session Refresh: When access token expires, use refresh token...
(QB_NEW_EN)
[grammar] ~264-~264: There might be a mistake here.
Context: ...n Refresh**: When access token expires, use refresh token to get new pair. ## Secu...
(QB_NEW_EN)
[grammar] ~264-~264: There might be a mistake here.
Context: ...ess token expires, use refresh token to get new pair. ## Security Considerations ...
(QB_NEW_EN)
docs/api/settlements.md
[grammar] ~21-~21: There might be a mistake here.
Context: ... transactions for the entire group. * Logic: 1. It calculates the n...
(QB_NEW_EN)
[grammar] ~59-~59: There might be a mistake here.
Context: ...ing through the list of raw settlements. * algorithm: The settlement algorithm to use (`norm...
(QB_NEW_EN)
🪛 markdownlint-cli2 (0.17.2)
docs/api/README.md
22-22: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
docs/api/settlements.md
22-22: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
58-58: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
59-59: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
60-60: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
117-117: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
🔇 Additional comments (5)
docs/api/README.md (1)
35-49: All referenced docs exist — no broken links foundVerified the files linked from docs/api/README.md (lines 35–49); all referenced paths are present.
- docs/api/authentication.md — OK
- docs/api/users.md — OK
- docs/api/groups.md — OK
- docs/api/expenses.md — OK
- docs/api/settlements.md — OK
- docs/api/examples/curl_examples.md — OK
- docs/api/examples/postman_collection.json — OK
docs/api/examples/postman_collection.json (1)
392-401: Confirm collection-level Bearer auth inheritanceCollection auth is set to Bearer with {{accessToken}}. Ensure all folders/requests inherit auth (Postman setting) and none override it unintentionally.
docs/api/authentication.md (2)
142-156: Inconsistent Google login pathThis section documents POST /login/google, while “Common Use Cases” references /auth/google/login. Please standardize on a single route (likely POST /auth/login/google).
Proposed fix in “Common Use Cases”:
-- **Google Sign-In**: Integrate with Google SDK on frontend, send token to /auth/google/login. +- **Google Sign-In**: Integrate with Google SDK on frontend, send token to /auth/login/google.Also applies to: 262-265
161-183: Refresh endpoint response shape verified — docs are correctThe /refresh route returns both access_token and refresh_token; no docs change required.
- backend/app/auth/routes.py — @router.post("/refresh", response_model=TokenResponse) returns TokenResponse(access_token=access_token, refresh_token=new_refresh_token)
- backend/app/auth/schemas.py — class TokenResponse(access_token: str, refresh_token: Optional[str] = None)
docs/api/expenses.md (1)
43-49: Docs: keep per-split "type" — backend supports itExpenseSplit in the backend includes a per-split
typefield (defaulting toSplitType.EQUAL), so removingtypefrom the docs is incorrect. Either keep thetypefields in the example or add a short note that the per-splittypeis optional and defaults to"equal".Files to note:
- backend/app/expenses/schemas.py —
ExpenseSplitdefinestype: SplitType = SplitType.EQUAL(andExpenseCreateRequestalso hassplitType).- docs/api/expenses.md — sample shown at lines ~43–49.
Suggested docs change (add clarification rather than removing fields):
"splits": [ - { "userId": "user_id_1", "amount": 50.25, "type": "equal" }, - { "userId": "user_id_2", "amount": 100.50, "type": "unequal" } + { "userId": "user_id_1", "amount": 50.25, "type": "equal" }, + { "userId": "user_id_2", "amount": 100.50, "type": "unequal" } ], "splitType": "unequal", + +Note: Each split may include an optional "type" field (`"equal" | "unequal" | "percentage"`). It defaults to `"equal"` if omitted.Likely an incorrect or invalid review comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🔭 Outside diff range comments (1)
docs/api/groups.md (1)
193-200: Remove stray trailing line breaking Markdown renderingA dangling “200” appears after the last code block. It should be removed.
- - -200 +
♻️ Duplicate comments (3)
docs/api/authentication.md (1)
185-204: Token verify doc now matches implementation (no token minting)Thanks for correcting the description to only verify and return user info.
docs/api/groups.md (1)
41-45: JSON example URLs are now plain strings (good fix)Thanks for replacing Markdown link syntax with plain URL strings in JSON examples.
docs/api/settlements.md (1)
11-11: Payer/payee semantics now align with backend behaviorThis clarification matches service logic for auto-generated and manual settlements.
🧹 Nitpick comments (8)
docs/api/authentication.md (6)
4-4: Fix punctuation: add missing space after period"Google OAuth.This" should be "Google OAuth. This".
Apply this diff:
-... Google OAuth.This documentation is based on the backend implementation in `/backend/app/auth`. +... Google OAuth. This documentation is based on the backend implementation in `/backend/app/auth`.
35-41: Tighten dependency bullets and fix minor wording
- Remove stray spaces before periods.
- Clarify wording around Pydantic and MongoDB driver.
Apply this diff:
-- `fastapi.security`: For OAuth2PasswordBearer . -- `pydantic`: For request/response schemas model.(pydantic model) +- `fastapi.security`: For OAuth2PasswordBearer. +- `pydantic`: For request/response schema models. - `jose`: For JWT encoding/decoding. - `passlib`: For password hashing. -- `MongoDB driver`: (e.g.,`pymongo`) for user storage. +- `MongoDB driver` (e.g., `pymongo`): For user storage.
53-63: Complete the Python example importsThe snippet uses Field and datetime but doesn't import them.
Apply this diff:
-from pydantic import BaseModel, EmailStr +from pydantic import BaseModel, EmailStr, Field +from datetime import datetime
76-79: Heading formatting: add space after section numberUse "4. API Endpoints" for readability and consistency.
-## 4.API Endpoints +## 4. API Endpoints
98-100: Fix typos in note about nested modelCorrect “conatin” and “pydhantic”.
-- Note: AuthResponse conatin another pydhantic model : `UserResponse` +- Note: AuthResponse contains another Pydantic model: `UserResponse`
206-214: Deduplicate and clarify password reset request descriptionThere’s a repeated sentence and missing space.
-**Description**: Initiates the password reset process for a user.Initiates a password reset process by sending a reset link to the provided email address. +**Description**: Initiates the password reset process by sending a reset link to the provided email address.docs/api/groups.md (1)
60-72: Optional: Clarify base path in endpoint headingsYou note “All endpoints are prefixed with /groups,” but the headings use "POST /". Consider showing full paths to avoid ambiguity.
-### **`POST /`** +### **`POST /groups`**Apply similarly for GET/PATCH/DELETE sections if preferred.
docs/api/settlements.md (1)
21-23: Trim excessive spacing in proseThere are multiple spaces before “entire group.” Keep single spaces.
-* **Advanced (`algorithm=advanced`)**: A more powerful graph-based algorithm that minimizes the total number of transactions for the entire group. +* **Advanced (`algorithm=advanced`)**: A more powerful graph-based algorithm that minimizes the total number of transactions for the entire group.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (5)
docs/api/authentication.md(1 hunks)docs/api/examples/curl_examples.md(1 hunks)docs/api/groups.md(1 hunks)docs/api/settlements.md(1 hunks)docs/api/users.md(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- docs/api/examples/curl_examples.md
- docs/api/users.md
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-07-26T09:41:01.332Z
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/**/*.py : JWT authentication with refresh token rotation must be implemented in the backend.
Applied to files:
docs/api/authentication.md
📚 Learning: 2025-07-26T09:41:01.332Z
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/security.py : To troubleshoot authentication issues, check JWT token handling in app/auth/security.py.
Applied to files:
docs/api/authentication.md
📚 Learning: 2025-07-26T09:41:01.332Z
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.
Applied to files:
docs/api/settlements.md
🧬 Code Graph Analysis (3)
docs/api/authentication.md (1)
backend/app/auth/service.py (1)
AuthService(72-573)
docs/api/groups.md (2)
backend/tests/groups/test_groups_service.py (1)
TestGroupService(9-742)backend/app/groups/service.py (2)
GroupService(12-474)transform_group_document(103-122)
docs/api/settlements.md (8)
backend/app/expenses/schemas.py (2)
Settlement(108-122)OptimizedSettlement(125-131)frontend/screens/GroupSettingsScreen.js (1)
settlementsRes(166-193)frontend/api/groups.js (1)
groupId(5-6)backend/app/expenses/service.py (2)
create_manual_settlement(624-671)_create_settlements_for_expense(117-155)backend/app/expenses/routes.py (1)
get_group_settlements(236-290)frontend/screens/HomeScreen.js (1)
groupId(33-67)backend/tests/expenses/test_expense_service.py (1)
test_calculate_optimized_settlements_advanced(185-255)backend/tests/expenses/test_expense_routes.py (1)
test_optimized_settlements_endpoint(127-153)
🪛 LanguageTool
docs/api/authentication.md
[grammar] ~23-~23: There might be a mistake here.
Context: ...tication provider (email or google). 2. refresh_tokens: Tracks all active refresh tokens. Each...
(QB_NEW_EN)
[grammar] ~35-~35: There might be a mistake here.
Context: ...Dependencies The auth module relies on: - fastapi.security: For OAuth2PasswordBearer . - `pydantic...
(QB_NEW_EN)
[grammar] ~38-~38: There might be a mistake here.
Context: ...el) - jose: For JWT encoding/decoding. - passlib: For password hashing. - `MongoDB drive...
(QB_NEW_EN)
[grammar] ~40-~40: There might be a mistake here.
Context: ...word hashing. - MongoDB driver: (e.g.,pymongo) for user storage. --- ## 3. Data Mod...
(QB_NEW_EN)
[grammar] ~46-~46: There might be a mistake here.
Context: ...chemas ### User Model (in schemas.py) Represents a user in the database: ### ...
(QB_NEW_EN)
[grammar] ~83-~83: There might be a mistake here.
Context: ...s and user information. Parameters: - Request Body (JSON): - email: string...
(QB_NEW_EN)
[grammar] ~84-~84: There might be a mistake here.
Context: ... Parameters: - Request Body (JSON): - email: string (required, valid email) - `pa...
(QB_NEW_EN)
[grammar] ~85-~85: There might be a mistake here.
Context: ... email: string (required, valid email) - password: string (required) - name : string ...
(QB_NEW_EN)
[grammar] ~98-~98: There might be a mistake here.
Context: ...1 } ``` Responses (AuthResponse): - Note: AuthResponse conatin another pydha...
(QB_NEW_EN)
[grammar] ~123-~123: There might be a mistake here.
Context: ...and adds a new session. Parameters: - Request Body (JSON): - email: string...
(QB_NEW_EN)
[grammar] ~124-~124: There might be a mistake here.
Context: ... Parameters: - Request Body (JSON): - email: string (required) - password: stri...
(QB_NEW_EN)
[grammar] ~125-~125: There might be a mistake here.
Context: ...y (JSON): - email: string (required) - password: string (required) Request Example...
(QB_NEW_EN)
[grammar] ~128-~128: There might be a mistake here.
Context: ... string (required) Request Example: * Request Body (EmailLoginRequest): ...
(QB_NEW_EN)
[grammar] ~145-~145: There might be a mistake here.
Context: ...nd issue OAuth ID token Parameters: - Request Body (JSON): - `GoogleLoginReq...
(QB_NEW_EN)
[grammar] ~146-~146: There might be a mistake here.
Context: ... Parameters: - Request Body (JSON): - GoogleLoginRequest: string (required, Google ID token) *...
(QB_NEW_EN)
[grammar] ~164-~164: There might be a mistake here.
Context: ...nd updates the session. Parameters: - Request Body (JSON): - `RefreshTokenRe...
(QB_NEW_EN)
[grammar] ~165-~165: There might be a mistake here.
Context: ... Parameters: - Request Body (JSON): - RefreshTokenRequest: string (required) * Request Body ...
(QB_NEW_EN)
[grammar] ~175-~175: There might be a mistake here.
Context: ... * **Response** (`TokenResponse`): - 200 OK: New tokens issued. json ...
(QB_NEW_EN)
[grammar] ~244-~244: There might be a mistake here.
Context: ...ates, creates/hashes, and issues tokens. 2. Protected Routes: Use `Depends(get_cur...
(QB_NEW_EN)
[grammar] ~247-~247: There might be a mistake here.
Context: ...fresh token. 4. Rotation: On refresh, new refresh token is issued, old one in...
(QB_NEW_EN)
[grammar] ~247-~247: There might be a mistake here.
Context: ...sh token is issued, old one invalidated. 5. Google OAuth: Client gets Google token...
(QB_NEW_EN)
[grammar] ~248-~248: There might be a mistake here.
Context: ...token, sends to server. Server verifies with Google API, links to user. ## Error Co...
(QB_NEW_EN)
[grammar] ~248-~248: There might be a mistake here.
Context: ... Server verifies with Google API, links to user. ## Error Codes - 400: Bad reque...
(QB_NEW_EN)
[grammar] ~261-~261: There might be a mistake here.
Context: ...gin**: POST /auth/login/email → Tokens. - Google Sign-In: Integrate with Google ...
(QB_NEW_EN)
[grammar] ~262-~262: There might be a mistake here.
Context: ...le Sign-In**: Integrate with Google SDK on frontend, send token to /auth/google/lo...
(QB_NEW_EN)
[grammar] ~262-~262: There might be a mistake here.
Context: ...ntend, send token to /auth/google/login. - Session Refresh: When access token exp...
(QB_NEW_EN)
[grammar] ~263-~263: There might be a mistake here.
Context: ...th/google/login. - Session Refresh: When access token expires, use refresh token...
(QB_NEW_EN)
[grammar] ~263-~263: There might be a mistake here.
Context: ...n Refresh**: When access token expires, use refresh token to get new pair. ## Secu...
(QB_NEW_EN)
[grammar] ~263-~263: There might be a mistake here.
Context: ...ess token expires, use refresh token to get new pair. ## Security Considerations ...
(QB_NEW_EN)
docs/api/groups.md
[grammar] ~21-~21: There might be a mistake here.
Context: ...emails to display in group member lists. * settlements: Queried to perform safety checks, spec...
(QB_NEW_EN)
docs/api/settlements.md
[grammar] ~21-~21: There might be a mistake here.
Context: ... transactions for the entire group. * Logic: 1. It calculates the n...
(QB_NEW_EN)
[grammar] ~59-~59: There might be a mistake here.
Context: ...ing through the list of raw settlements. * algorithm: The settlement algorithm to use (`norm...
(QB_NEW_EN)
🪛 markdownlint-cli2 (0.17.2)
docs/api/authentication.md
36-36: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
37-37: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
38-38: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
39-39: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
40-40: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
67-67: Multiple headings with the same content
(MD024, no-duplicate-heading)
84-84: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
85-85: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
86-86: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
87-87: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
99-99: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
100-100: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
115-115: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
116-116: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
124-124: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
125-125: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
126-126: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
139-139: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
146-146: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
147-147: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
158-158: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
165-165: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
166-166: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
176-176: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
183-183: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
239-239: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
252-252: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
253-253: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
254-254: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
255-255: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
256-256: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
260-260: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
261-261: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
262-262: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
263-263: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
267-267: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
268-268: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: preview
🔇 Additional comments (4)
docs/api/authentication.md (2)
262-264: Fix Google login path in Common Use CasesEarlier you document the endpoint as POST /login/google (under /auth prefix). Align the example path.
-- **Google Sign-In**: Integrate with Google SDK on frontend, send token to /auth/google/login. +- **Google Sign-In**: Integrate with Google SDK on frontend, send the token to /auth/login/google.If the actual route is different in backend/app/auth/routes.py, update both places for consistency.
161-183: Refresh endpoint returns both access and refresh tokens — confirmedThe implementation rotates the refresh token in the service and the /refresh route builds a new access token and returns both tokens.
- backend/app/auth/service.py — async def refresh_access_token(...) rotates the refresh token and returns the new refresh token.
- backend/app/auth/routes.py — POST /refresh calls the service, creates access_token (create_access_token(...)) and returns TokenResponse(access_token=access_token, refresh_token=new_refresh_token).
docs/api/groups.md (1)
16-16: Verified: join code is case-insensitiveGenerator emits only uppercase alphanumeric codes and the join flow normalizes input to uppercase before lookup, so the docs are accurate.
- backend/app/groups/service.py: generate_join_code() uses string.ascii_uppercase + string.digits (produces uppercase codes).
- backend/app/groups/service.py: join_group_by_code() looks up db.groups.find_one({"joinCode": join_code.upper()}) (uppercases input).
docs/api/settlements.md (1)
118-137: Confirmed — optimize endpoint returns "savings"; docs example is accurateVerified the POST /groups/{group_id}/settlements/optimize handler constructs and returns a savings object (originalTransactions, optimizedTransactions, reductionPercentage). No doc change required.
Files inspected:
- backend/app/expenses/routes.py — return OptimizedSettlementsResponse with savings dict (around lines 379–386).
- backend/app/expenses/schemas.py — OptimizedSettlementsResponse defines savings: Dict[str, Any] (around line 230).
- backend/app/expenses/service.py — calculate_optimized_settlements produces optimized_settlements used in the response (implementation and calls around lines 360–364, 480–622).
docs/api/authentication.md
Outdated
| **Description**: Handles Google OAuth login. Validates the Google token, creates or logs in the user based on Google ID, and issue OAuth ID token | ||
|
|
||
| **Parameters**: | ||
| - Request Body (JSON): | ||
| - `GoogleLoginRequest`: string (required, Google ID token) | ||
|
|
||
|
|
||
| * **Request Body** (`GoogleLoginRequest`): | ||
| ```json | ||
| { | ||
| "id_token": "google_id_token_from_client" | ||
| } | ||
| ``` | ||
| * **Response** (`AuthResponse`): The response format is identical to the sign-up endpoint. | ||
|
|
||
| - 500 If Google authentication fails. | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Google login description incorrectly implies issuing a Google token
Backend verifies a Google ID token and returns your app’s tokens; it does not issue a new Google OAuth token.
-**Description**: Handles Google OAuth login. Validates the Google token, creates or logs in the user based on Google ID, and issue OAuth ID token
+**Description**: Handles Google OAuth login. Validates the Google ID token, creates or logs in the user, and returns Splitwiser access and refresh tokens. It does not issue a Google OAuth token.📝 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.
| **Description**: Handles Google OAuth login. Validates the Google token, creates or logs in the user based on Google ID, and issue OAuth ID token | |
| **Parameters**: | |
| - Request Body (JSON): | |
| - `GoogleLoginRequest`: string (required, Google ID token) | |
| * **Request Body** (`GoogleLoginRequest`): | |
| ```json | |
| { | |
| "id_token": "google_id_token_from_client" | |
| } | |
| ``` | |
| * **Response** (`AuthResponse`): The response format is identical to the sign-up endpoint. | |
| - 500 If Google authentication fails. | |
| **Description**: Handles Google OAuth login. Validates the Google ID token, creates or logs in the user, and returns Splitwiser access and refresh tokens. It does not issue a Google OAuth token. | |
| **Parameters**: | |
| - Request Body (JSON): | |
| - `GoogleLoginRequest`: string (required, Google ID token) | |
| * **Request Body** (`GoogleLoginRequest`): |
🧰 Tools
🪛 LanguageTool
[grammar] ~145-~145: There might be a mistake here.
Context: ...nd issue OAuth ID token Parameters: - Request Body (JSON): - `GoogleLoginReq...
(QB_NEW_EN)
[grammar] ~146-~146: There might be a mistake here.
Context: ... Parameters: - Request Body (JSON): - GoogleLoginRequest: string (required, Google ID token) *...
(QB_NEW_EN)
🪛 markdownlint-cli2 (0.17.2)
146-146: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
147-147: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
158-158: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
🤖 Prompt for AI Agents
In docs/api/authentication.md around lines 143 to 159, the Google login
description wrongly implies the backend issues a Google OAuth token; update the
text to state the backend verifies the Google ID token and returns the
application’s own authentication tokens (e.g., JWT or session token) instead of
issuing a new Google token, adjust any wording like “issue OAuth ID token” to
“issue application auth token” and ensure the Request/Response section clearly
explains the client sends a Google ID token and receives the app’s AuthResponse.
| * **Response** (`GroupResponse`): | ||
| ```json | ||
| { | ||
| "id": "group_id_string", | ||
| "name": "Trip to the Mountains", | ||
| "currency": "EUR", | ||
| "joinCode": "UNIQUE_JOIN_CODE", | ||
| "createdBy": "user_id_of_creator", | ||
| "createdAt": "2025-08-14T12:00:00Z", | ||
| "imageUrl": "https://example.com/mountains.png", | ||
| "members": [ /* ... list of GroupMemberWithDetails ... */ ] | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Response field name should match backend: use "_id" not "id"
GroupService.transform_group_document returns "_id" (string). Docs currently show "id".
- "id": "group_id_string",
+ "_id": "group_id_string",Reference: backend/app/groups/service.py transform_group_document returns {"_id": group_id, ...}.
📝 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.
| * **Response** (`GroupResponse`): | |
| ```json | |
| { | |
| "id": "group_id_string", | |
| "name": "Trip to the Mountains", | |
| "currency": "EUR", | |
| "joinCode": "UNIQUE_JOIN_CODE", | |
| "createdBy": "user_id_of_creator", | |
| "createdAt": "2025-08-14T12:00:00Z", | |
| "imageUrl": "https://example.com/mountains.png", | |
| "members": [ /* ... list of GroupMemberWithDetails ... */ ] | |
| } | |
| * **Response** (`GroupResponse`): |
🤖 Prompt for AI Agents
In docs/api/groups.md around lines 46 to 57, the example response uses "id"
while the backend returns "_id"; update the JSON example and any accompanying
text to use "_id" instead of "id" so it matches
GroupService.transform_group_document (i.e., replace "id": "group_id_string"
with "_id": "group_id_string" and ensure any references in that section refer to
"_id").
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (14)
docs/api/authentication.md (11)
4-4: Fix punctuation/spacing in overview sentenceThere’s a missing space after the period.
Apply this diff:
-The Authentication Service in Splitwiser handles secure user registration, login, and session management using JWT (JSON Web Tokens) with refresh token rotation for enhanced security. It supports multiple authentication providers, including email/password and Google OAuth.This documentation is based on the backend implementation in `/backend/app/auth`. +The Authentication Service in Splitwiser handles secure user registration, login, and session management using JWT (JSON Web Tokens) with refresh token rotation for enhanced security. It supports multiple authentication providers, including email/password and Google OAuth. This documentation is based on the backend implementation in `/backend/app/auth`.
35-41: Tighten dependency wording and minor grammarClarify phrasing, fix spacing/punctuation.
Apply this diff:
-The auth module relies on: -- `fastapi.security`: For OAuth2PasswordBearer . -- `pydantic`: For request/response schemas model.(pydantic model) -- `jose`: For JWT encoding/decoding. -- `passlib`: For password hashing. -- `MongoDB driver`: (e.g.,`pymongo`) for user storage. +The auth module relies on: +* `fastapi.security`: OAuth2PasswordBearer (access-token extraction on protected routes). +* `pydantic`: Request/response schema models. +* `python-jose`: JWT encoding/decoding. +* `passlib[bcrypt]`: Password hashing. +* MongoDB driver (e.g., `pymongo`) for user storage.
51-63: Complete the User model example (missing imports) and tidy commentsThe snippet uses Field and datetime but doesn’t import them.
Apply this diff:
-```python - -from pydantic import BaseModel, EmailStr -from typing import Optional - -class User(BaseModel): - id: str = Field(alias="_id") - email: EmailStr #EmailStr to check the syntax of email - name: str - imageUrl: Optional[str] = None #Optional field - currency: str = "USD" - created_at: datetime -``` +```python +from datetime import datetime +from typing import Optional +from pydantic import BaseModel, EmailStr, Field + +class User(BaseModel): + id: str = Field(alias="_id") + email: EmailStr # validates email syntax + name: str + imageUrl: Optional[str] = None + currency: str = "USD" + created_at: datetime +```
69-73: Import BaseModel for TokenData exampleAdd the missing import for clarity/consistency.
Apply this diff:
-```python -class TokenData(BaseModel): +```python +from pydantic import BaseModel + +class TokenData(BaseModel): sub: str # The user's ID--- `76-76`: **Heading spacing** Add a space after the section number. Apply this diff: ```diff -## 4.API Endpoints +## 4. API Endpoints
89-96: Use valid JSON in examples or mark as JSONCJSON does not support comments; either remove inline comments or mark the block as jsonc. Recommend removing comments to keep examples copy-pastable.
Apply this diff (remove comments in the signup example; apply similarly to other JSON examples that contain comments):
-**Request BODY** (`EmailSignupRequest`): -```json +**Request Body** (`EmailSignupRequest`): +```json { - "email": "user@example.com", - "password": "a-strong-password", // min_length: 6 - "name": "John Doe" // min_length: 1 + "email": "user@example.com", + "password": "a-strong-password", + "name": "John Doe" }--- `98-100`: **Fix typos in response description** Correct spelling/grammar for clarity. Apply this diff: ```diff -**Responses** (`AuthResponse`): -- Note: AuthResponse conatin another pydhantic model : `UserResponse` +**Responses** (`AuthResponse`): +* Note: AuthResponse contains another Pydantic model: `UserResponse`
138-140: Add standard auth failure status codes for email loginUnsuccessful login attempts should document 401 Unauthorized; keep 500 for truly unexpected failures.
Apply this diff:
-Error : -- 500 if authentication fails due to an unexpected error +Errors: +* 401 Unauthorized: Invalid email or password. +* 422 Unprocessable Entity: Validation error. +* 500 Internal Server Error: Unexpected failure.
142-158: Google login: document 401 for invalid Google ID token and clarify 500Align response codes with typical failure modes.
Apply this diff:
* **Response** (`AuthResponse`): The response format is identical to the sign-up endpoint. - -- 500 If Google authentication fails. +* 401 Unauthorized: Invalid or expired Google ID token. +* 500 Internal Server Error: Unexpected failure during Google token verification.
205-207: Remove duplicated sentence in password reset request descriptionThere’s a repeated phrase.
Apply this diff:
-**Description**: Initiates the password reset process for a user.Initiates a password reset process by sending a reset link to the provided email address. +**Description**: Initiates a password reset by sending a reset link to the provided email address.
226-231: Use valid JSON in password reset confirm exampleRemove comments to keep it valid JSON (or mark as jsonc).
Apply this diff:
```json { - "reset_token": "the_token_from_the_reset_email", - "new_password": "a_new_strong_password" // min_length: 6 + "reset_token": "the_token_from_the_reset_email", + "new_password": "a_new_strong_password" }</blockquote></details> <details> <summary>docs/api/settlements.md (3)</summary><blockquote> `21-21`: **Remove extra spaces in sentence** Minor formatting nit. Apply this diff: ```diff -* **Advanced (`algorithm=advanced`)**: A more powerful graph-based algorithm that minimizes the total number of transactions for the entire group. +* **Advanced (`algorithm=advanced`)**: A more powerful graph-based algorithm that minimizes the total number of transactions for the entire group.
53-70: Document status codes for GET /settlementsBackend may return 404 for group not found and 500 for failures. Add explicit status codes to set expectations.
Apply this diff:
* **Response** (`SettlementListResponse`): @@ } ``` +* **Status Codes**: + * 200 OK + * 404 Not Found: Group not found or user not a member + * 500 Internal Server Error: Failed to fetch settlements
112-118: Clarify request body and default algorithm for optimize endpointDocument that the request body is empty and the default algorithm is “advanced” (per routes).
Apply this diff:
### **`POST /settlements/optimize`** Calculates and returns the most efficient way to settle all debts in a group. * **Query Parameters**: - * `algorithm`: `normal` or `advanced` (default). + * `algorithm`: `normal` or `advanced` (default: `advanced`). +* **Request Body**: none
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
docs/api/authentication.md(1 hunks)docs/api/settlements.md(1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-07-26T09:41:01.332Z
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/**/*.py : JWT authentication with refresh token rotation must be implemented in the backend.
Applied to files:
docs/api/authentication.md
📚 Learning: 2025-07-26T09:41:01.332Z
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/security.py : To troubleshoot authentication issues, check JWT token handling in app/auth/security.py.
Applied to files:
docs/api/authentication.md
📚 Learning: 2025-07-26T09:41:01.332Z
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.
Applied to files:
docs/api/settlements.md
🧬 Code Graph Analysis (1)
docs/api/settlements.md (7)
backend/app/expenses/schemas.py (2)
Settlement(108-122)OptimizedSettlement(125-131)frontend/screens/GroupSettingsScreen.js (1)
settlementsRes(166-193)frontend/api/groups.js (1)
groupId(5-6)backend/app/expenses/service.py (2)
create_manual_settlement(624-671)_create_settlements_for_expense(117-155)backend/app/expenses/routes.py (1)
get_group_settlements(236-290)frontend/screens/HomeScreen.js (1)
groupId(33-67)backend/tests/expenses/test_expense_routes.py (1)
test_optimized_settlements_endpoint(127-153)
🪛 LanguageTool
docs/api/authentication.md
[grammar] ~23-~23: There might be a mistake here.
Context: ...tication provider (email or google). 2. refresh_tokens: Tracks all active refresh tokens. Each...
(QB_NEW_EN)
[grammar] ~35-~35: There might be a mistake here.
Context: ...Dependencies The auth module relies on: - fastapi.security: For OAuth2PasswordBearer . - `pydantic...
(QB_NEW_EN)
[grammar] ~38-~38: There might be a mistake here.
Context: ...el) - jose: For JWT encoding/decoding. - passlib: For password hashing. - `MongoDB drive...
(QB_NEW_EN)
[grammar] ~40-~40: There might be a mistake here.
Context: ...word hashing. - MongoDB driver: (e.g.,pymongo) for user storage. --- ## 3. Data Mod...
(QB_NEW_EN)
[grammar] ~46-~46: There might be a mistake here.
Context: ...chemas ### User Model (in schemas.py) Represents a user in the database: ### ...
(QB_NEW_EN)
[grammar] ~83-~83: There might be a mistake here.
Context: ...s and user information. Parameters: - Request Body (JSON): - email: string...
(QB_NEW_EN)
[grammar] ~84-~84: There might be a mistake here.
Context: ... Parameters: - Request Body (JSON): - email: string (required, valid email) - `pa...
(QB_NEW_EN)
[grammar] ~85-~85: There might be a mistake here.
Context: ... email: string (required, valid email) - password: string (required) - name : string ...
(QB_NEW_EN)
[grammar] ~98-~98: There might be a mistake here.
Context: ...1 } ``` Responses (AuthResponse): - Note: AuthResponse conatin another pydha...
(QB_NEW_EN)
[grammar] ~123-~123: There might be a mistake here.
Context: ...and adds a new session. Parameters: - Request Body (JSON): - email: string...
(QB_NEW_EN)
[grammar] ~124-~124: There might be a mistake here.
Context: ... Parameters: - Request Body (JSON): - email: string (required) - password: stri...
(QB_NEW_EN)
[grammar] ~125-~125: There might be a mistake here.
Context: ...y (JSON): - email: string (required) - password: string (required) Request Example...
(QB_NEW_EN)
[grammar] ~128-~128: There might be a mistake here.
Context: ... string (required) Request Example: * Request Body (EmailLoginRequest): ...
(QB_NEW_EN)
[grammar] ~145-~145: There might be a mistake here.
Context: ...ss and refresh tokens. Parameters: - Request Body (JSON): - `GoogleLoginReq...
(QB_NEW_EN)
[grammar] ~146-~146: There might be a mistake here.
Context: ... Parameters: - Request Body (JSON): - GoogleLoginRequest: string (required, Google ID token) *...
(QB_NEW_EN)
[grammar] ~164-~164: There might be a mistake here.
Context: ...nd updates the session. Parameters: - Request Body (JSON): - `RefreshTokenRe...
(QB_NEW_EN)
[grammar] ~165-~165: There might be a mistake here.
Context: ... Parameters: - Request Body (JSON): - RefreshTokenRequest: string (required) * Request Body ...
(QB_NEW_EN)
[grammar] ~175-~175: There might be a mistake here.
Context: ... * **Response** (`TokenResponse`): - 200 OK: New tokens issued. json ...
(QB_NEW_EN)
[grammar] ~244-~244: There might be a mistake here.
Context: ...ates, creates/hashes, and issues tokens. 2. Protected Routes: Use `Depends(get_cur...
(QB_NEW_EN)
[grammar] ~247-~247: There might be a mistake here.
Context: ...fresh token. 4. Rotation: On refresh, new refresh token is issued, old one in...
(QB_NEW_EN)
[grammar] ~247-~247: There might be a mistake here.
Context: ...sh token is issued, old one invalidated. 5. Google OAuth: Client gets Google token...
(QB_NEW_EN)
[grammar] ~248-~248: There might be a mistake here.
Context: ...token, sends to server. Server verifies with Google API, links to user. ## Error Co...
(QB_NEW_EN)
[grammar] ~248-~248: There might be a mistake here.
Context: ... Server verifies with Google API, links to user. ## Error Codes - 400: Bad reque...
(QB_NEW_EN)
[grammar] ~261-~261: There might be a mistake here.
Context: ...gin**: POST /auth/login/email → Tokens. - Google Sign-In: Integrate with Google ...
(QB_NEW_EN)
[grammar] ~262-~262: There might be a mistake here.
Context: ...ntend, send token to /auth/google/login. - Session Refresh: When access token exp...
(QB_NEW_EN)
[grammar] ~263-~263: There might be a mistake here.
Context: ...th/google/login. - Session Refresh: When access token expires, use refresh token...
(QB_NEW_EN)
[grammar] ~263-~263: There might be a mistake here.
Context: ...n Refresh**: When access token expires, use refresh token to get new pair. ## Secu...
(QB_NEW_EN)
[grammar] ~263-~263: There might be a mistake here.
Context: ...ess token expires, use refresh token to get new pair. ## Security Considerations ...
(QB_NEW_EN)
docs/api/settlements.md
[grammar] ~21-~21: There might be a mistake here.
Context: ... transactions for the entire group. * Logic: 1. It calculates the n...
(QB_NEW_EN)
[grammar] ~59-~59: There might be a mistake here.
Context: ...ing through the list of raw settlements. * algorithm: The settlement algorithm to use (`norm...
(QB_NEW_EN)
🪛 markdownlint-cli2 (0.17.2)
docs/api/settlements.md
36-36: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
37-37: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
38-38: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
39-39: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
40-40: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
67-67: Multiple headings with the same content
(MD024, no-duplicate-heading)
84-84: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
85-85: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
86-86: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
87-87: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
99-99: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
100-100: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
115-115: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
116-116: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
124-124: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
125-125: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
126-126: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
🔇 Additional comments (3)
docs/api/authentication.md (1)
185-204: LGTM: /token/verify description now accurateThe docs correctly state that the endpoint only verifies the access token and returns user info; it does not mint new tokens.
docs/api/settlements.md (2)
11-15: LGTM: Payer/payee semantics are now explicit and match backendThe clarified creditor/debtor mapping aligns with service implementations for auto-generated and manual settlements.
114-137: LGTM: Optimize response shape matches backend and frontend usageThe fields (fromUserId/toUserId/amount/consolidatedExpenses) align with service and consumers.
| email: EmailStr #EmailStr to check the syntax of email | ||
| name: str | ||
| imageUrl: Optional[str] = None #Optional field | ||
| currency: str = "USD" | ||
| created_at: datetime | ||
| ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Verify field naming consistency (snake_case vs camelCase)
Users in this doc use created_at (snake_case) while other resources (e.g., settlements) use createdAt (camelCase). Please verify what the backend actually returns for user payloads and align docs consistently.
Run this script to check user schema/response conventions in the backend:
Also applies to: 111-112, 200-202
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Search for user response models/serializers ==="
rg -n -C2 -S -g '!**/node_modules/**' -P '\b(created_at|createdAt)\b' backend/app | sed -n '1,200p'
echo
echo "=== Look for Pydantic schemas for users ==="
rg -n -C2 -S -P 'class\s+User\w*\s*\(BaseModel\)' backend/app | sed -n '1,200p'
echo
echo "=== Inspect routes returning user payloads ==="
rg -n -C3 -S -P 'return\s+.*(user|UserResponse|AuthResponse)' backend/app | sed -n '1,200p'Length of output: 17782
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== docs/api/authentication.md (lines 1-160) ==="
sed -n '1,160p' docs/api/authentication.md || true
echo
echo "=== backend/app/user/service.py (full) ==="
sed -n '1,240p' backend/app/user/service.py || true
echo
echo "=== backend/app/user/schemas.py (full) ==="
sed -n '1,200p' backend/app/user/schemas.py || true
echo
echo "=== backend/app/auth/schemas.py (full) ==="
sed -n '1,240p' backend/app/auth/schemas.py || true
echo
echo "=== backend/app/auth/routes.py (full) ==="
sed -n '1,320p' backend/app/auth/routes.py || true
echo
echo "=== backend/app/user/routes.py (full) ==="
sed -n '1,200p' backend/app/user/routes.py || trueLength of output: 23496
Fix: unify user timestamp field casing (createdAt vs created_at)
Verified: the codebase is inconsistent — user endpoints return camelCase timestamps, while auth responses use snake_case and the docs currently show snake_case. Please standardize.
Findings (verified):
- backend/app/user/service.py — transform_user_document returns "createdAt" / "updatedAt" (camelCase).
- backend/app/user/schemas.py — UserProfileResponse uses createdAt / updatedAt (camelCase).
- backend/app/user/routes.py — GET /users/me uses UserProfileResponse (so returns camelCase).
- backend/app/auth/schemas.py — UserResponse defines created_at (snake_case) and is used by auth endpoints (backend/app/auth/routes.py).
- docs/api/authentication.md — example User model shows created_at (snake_case).
Recommended minimal fixes:
-
Prefer camelCase (createdAt) to match most existing resources (groups/expenses/etc.). Update auth schema to expose camelCase while accepting current DB field:
-
Change in backend/app/auth/schemas.py:
Before
class UserResponse(BaseModel): id: str = Field(alias="_id") email: str name: str imageUrl: Optional[str] = None currency: str = "USD" created_at: datetime model_config = ConfigDict(populate_by_name=True)
After
class UserResponse(BaseModel): id: str = Field(alias="_id") email: str name: str imageUrl: Optional[str] = None currency: str = "USD" createdAt: datetime = Field(alias="created_at") model_config = ConfigDict(populate_by_name=True)
This accepts the DB key created_at but exposes createdAt in API responses, keeping backwards-safe population and aligning with other resources.
-
-
Update docs/api/authentication.md examples to use createdAt / updatedAt (camelCase).
-
Optional: consider normalizing service code to consistently return the same shape (e.g., reuse user_service.transform_user_document in auth flows) to avoid future drift.
Files to update:
- backend/app/auth/schemas.py (change field and alias)
- docs/api/authentication.md (update example usage)
- (optional) backend/app/auth/service.py and backend/app/auth/routes.py — verify they pass through user dicts consistently (no extra mapping needed once schema change is applied).
🤖 Prompt for AI Agents
In docs/api/authentication.md around lines 58 to 63, the docs and auth schema
use snake_case created_at while the rest of the API uses camelCase createdAt;
update backend/app/auth/schemas.py to expose createdAt by adding a Field alias
for the DB key (accept created_at but return createdAt) and ensure model config
allows population by name, then update docs/api/authentication.md examples to
use createdAt/updatedAt; optionally verify backend/app/auth/service.py and
backend/app/auth/routes.py pass through the user dict unchanged so the new
schema alias works without further mapping.
| Manually records a payment settlement between two users. This is for tracking payments made outside the app. | ||
|
|
||
| * **Server-Side Logic**: | ||
| 1. Verifies the current user is a member of the group. | ||
| 2. Creates a new settlement document in the `settlements` collection with a status of `completed`. | ||
| * **Request Body** (`SettlementCreateRequest`): | ||
| ```json | ||
| { | ||
| "payer_id": "user_id_1", | ||
| "payee_id": "user_id_2", | ||
| "amount": 25.00, | ||
| "description": "Paid back for coffee", | ||
| "paidAt": "2025-08-14T10:00:00Z" | ||
| } | ||
| ``` | ||
| * **Response** (`Settlement`): Returns the newly created `completed` settlement object. | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Consider documenting 201 Created for manual settlement creation
POST typically returns 201 on success; confirm backend behavior and document it. Also add common errors (403 not a member, 422 validation).
Apply this diff if verified:
-* **Response** (`Settlement`): Returns the newly created `completed` settlement object.
+* **Response** (`Settlement`): Returns the newly created `completed` settlement object.
+* **Status Codes**:
+ * 201 Created
+ * 403 Forbidden: Group not found or user not a member
+ * 422 Unprocessable Entity: Validation error
+ * 500 Internal Server Error: Failed to create settlementRun this script to confirm the route’s declared status_code and error handling:
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Find settlements route definitions ==="
rg -n -C3 -S -P '@router\.(post|patch|delete|get)\(.*settlements' backend/app | sed -n '1,200p'
echo
echo "=== Search for create_manual_settlement usage in routes ==="
rg -n -C3 -S -P 'create_manual_settlement' backend/app | sed -n '1,200p'Length of output: 3812
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Find model SettlementCreateRequest ==="
rg -n --hidden -S "SettlementCreateRequest" || true
echo
echo "=== Show route around manual settlement (routes.py:200-240) ==="
sed -n '200,240p' backend/app/expenses/routes.py || true
echo
echo "=== Show nearby lines where 'Failed to record settlement' appears (routes.py:228-236) ==="
sed -n '228,238p' backend/app/expenses/routes.py || true
echo
echo "=== Show create_manual_settlement service implementation (service.py:600-660) ==="
sed -n '600,660p' backend/app/expenses/service.py || true
echo
echo "=== Search for HTTPException with 403/422/500 in expenses paths ==="
rg -n --hidden -S "HTTPException\\(status_code=403|HTTPException\\(status_code=422|HTTPException\\(status_code=500" backend/app || true
echo
echo "=== Search for explicit status_code=201 on settlements routes ==="
rg -n --hidden -S "status_code=201|status_code\\s*=\\s*201" backend/app || trueLength of output: 57149
Document POST /groups/{group_id}/settlements response codes (add 201, 400, 403, 422, 500)
Verified: the route explicitly returns 201 on success and can return 400, 403, 422, and 500 — please update docs accordingly.
- Location evidence:
- backend/app/expenses/routes.py — @router.post("/settlements", ..., status_code=status.HTTP_201_CREATED) and the handler catches ValueError -> HTTPException(status_code=400) and Exception -> HTTPException(status_code=500) (manually_record_payment, ~lines 200–240).
- backend/app/expenses/service.py — create_manual_settlement raises HTTPException(status_code=403, ...) when group not found / user not a member (~lines 624–660).
- backend/app/expenses/schemas.py — SettlementCreateRequest model (validation -> 422).
- ui-poc/openapi.json — OpenAPI shows 201 and 422 for this endpoint.
Apply this diff to docs/api/settlements.md:
-* **Response** (`Settlement`): Returns the newly created `completed` settlement object.
+* **Response** (`Settlement`): Returns the newly created `completed` settlement object.
+* **Status Codes**:
+ * 201 Created
+ * 400 Bad Request: Semantic/validation error (ValueError)
+ * 403 Forbidden: Group not found or user not a member
+ * 422 Unprocessable Entity: Request body validation error
+ * 500 Internal Server Error: Failed to record settlement📝 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.
| Manually records a payment settlement between two users. This is for tracking payments made outside the app. | |
| * **Server-Side Logic**: | |
| 1. Verifies the current user is a member of the group. | |
| 2. Creates a new settlement document in the `settlements` collection with a status of `completed`. | |
| * **Request Body** (`SettlementCreateRequest`): | |
| ```json | |
| { | |
| "payer_id": "user_id_1", | |
| "payee_id": "user_id_2", | |
| "amount": 25.00, | |
| "description": "Paid back for coffee", | |
| "paidAt": "2025-08-14T10:00:00Z" | |
| } | |
| ``` | |
| * **Response** (`Settlement`): Returns the newly created `completed` settlement object. | |
| Manually records a payment settlement between two users. This is for tracking payments made outside the app. | |
| * **Server-Side Logic**: | |
| 1. Verifies the current user is a member of the group. | |
| 2. Creates a new settlement document in the `settlements` collection with a status of `completed`. | |
| * **Request Body** (`SettlementCreateRequest`): |
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
36-36: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
37-37: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
38-38: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
39-39: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
40-40: Unordered list style
Expected: asterisk; Actual: dash
(MD004, ul-style)
🤖 Prompt for AI Agents
In docs/api/settlements.md around lines 36 to 52, the POST
/groups/{group_id}/settlements documentation only lists success but not all
possible response codes; update the endpoint's response codes to include 201
(created), 400 (bad request for ValueError), 403 (forbidden when group not found
or user not a member), 422 (validation error from SettlementCreateRequest), and
500 (internal server error) and add a short parenthetical reason for each code
so the docs match the backend behavior.
fixes issue #57
Summary by CodeRabbit