Skip to content

Commit 3b45a4b

Browse files
committed
fix(review): fix review comments for vrajpatelll30
1 parent d8f44d9 commit 3b45a4b

File tree

6 files changed

+122
-90
lines changed

6 files changed

+122
-90
lines changed

backend/app/auth/schemas.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,40 @@ class EmailSignupRequest(BaseModel):
88
password: str = Field(..., min_length=6)
99
name: str = Field(..., min_length=1)
1010

11+
model_config = {"populate_by_name": True}
12+
1113
class EmailLoginRequest(BaseModel):
1214
email: EmailStr
1315
password: str
1416

17+
model_config = {"populate_by_name": True}
18+
1519
class GoogleLoginRequest(BaseModel):
1620
id_token: str
1721

22+
model_config = {"populate_by_name": True}
23+
1824
class RefreshTokenRequest(BaseModel):
1925
refresh_token: str
2026

27+
model_config = {"populate_by_name": True}
28+
2129
class PasswordResetRequest(BaseModel):
2230
email: EmailStr
2331

32+
model_config = {"populate_by_name": True}
33+
2434
class PasswordResetConfirm(BaseModel):
2535
reset_token: str
2636
new_password: str = Field(..., min_length=6)
2737

38+
model_config = {"populate_by_name": True}
39+
2840
class TokenVerifyRequest(BaseModel):
2941
access_token: str
3042

43+
model_config = {"populate_by_name": True}
44+
3145
# Response Models
3246
class UserResponse(BaseModel):
3347
id: str = Field(alias="_id")
@@ -37,18 +51,21 @@ class UserResponse(BaseModel):
3751
currency: str = "USD"
3852
created_at: datetime
3953

40-
class Config:
41-
populate_by_name = True
54+
model_config = {"populate_by_name": True}
4255

4356
class AuthResponse(BaseModel):
4457
access_token: str
4558
refresh_token: str
4659
user: UserResponse
4760

61+
model_config = {"populate_by_name": True}
62+
4863
class TokenResponse(BaseModel):
4964
access_token: str
5065
refresh_token: Optional[str] = None
5166

67+
model_config = {"populate_by_name": True}
68+
5269
class SuccessResponse(BaseModel):
5370
success: bool = True
5471
message: Optional[str] = None

backend/app/expenses/schemas.py

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ class ExpenseSplit(BaseModel):
1818
amount: float = Field(..., gt=0)
1919
type: SplitType = SplitType.EQUAL
2020

21+
model_config = {"populate_by_name": True}
22+
2123
class ExpenseCreateRequest(BaseModel):
2224
description: str = Field(..., min_length=1, max_length=500)
2325
amount: float = Field(..., gt=0)
@@ -27,13 +29,23 @@ class ExpenseCreateRequest(BaseModel):
2729
receiptUrls: Optional[List[str]] = []
2830

2931
@validator('splits')
30-
def validate_splits_sum(cls, v, values):
31-
if 'amount' in values:
32-
total_split = sum(split.amount for split in v)
33-
if abs(total_split - values['amount']) > 0.01: # Allow small floating point differences
34-
raise ValueError('Split amounts must sum to total expense amount')
32+
def validate_splits_sum(cls, v, values, **kwargs):
33+
# Always validate splits if provided
34+
if v is not None:
35+
# Use the provided amount if present, else try to get from instance (for partial update)
36+
amount = values.get('amount')
37+
if amount is None:
38+
instance = kwargs.get('instance')
39+
if instance is not None:
40+
amount = getattr(instance, 'amount', None)
41+
if amount is not None:
42+
total_split = sum(split.amount for split in v)
43+
if abs(total_split - amount) > 0.01:
44+
raise ValueError('Split amounts must sum to total expense amount')
3545
return v
3646

47+
model_config = {"populate_by_name": True}
48+
3749
class ExpenseUpdateRequest(BaseModel):
3850
description: Optional[str] = Field(None, min_length=1, max_length=500)
3951
amount: Optional[float] = Field(None, gt=0)
@@ -50,9 +62,7 @@ def validate_splits_sum(cls, v, values):
5062
raise ValueError('Split amounts must sum to total expense amount')
5163
return v
5264

53-
class Config:
54-
# Allow validation to work with partial updates
55-
validate_assignment = True
65+
model_config = {"populate_by_name": True, "validate_assignment": True}
5666

5767
class ExpenseComment(BaseModel):
5868
id: str = Field(alias="_id")
@@ -113,38 +123,52 @@ class OptimizedSettlement(BaseModel):
113123
amount: float
114124
consolidatedExpenses: Optional[List[str]] = []
115125

126+
model_config = {"populate_by_name": True}
127+
116128
class GroupSummary(BaseModel):
117129
totalExpenses: float
118130
totalSettlements: int
119131
optimizedSettlements: List[OptimizedSettlement]
120132

133+
model_config = {"populate_by_name": True}
134+
121135
class ExpenseCreateResponse(BaseModel):
122136
expense: ExpenseResponse
123137
settlements: List[Settlement]
124138
groupSummary: GroupSummary
125139

140+
model_config = {"populate_by_name": True}
141+
126142
class ExpenseListResponse(BaseModel):
127143
expenses: List[ExpenseResponse]
128144
pagination: Dict[str, Any]
129145
summary: Dict[str, Any]
130146

147+
model_config = {"populate_by_name": True}
148+
131149
class SettlementCreateRequest(BaseModel):
132150
payer_id: str
133151
payee_id: str
134152
amount: float = Field(..., gt=0)
135153
description: Optional[str] = None
136154
paidAt: Optional[datetime] = None
137155

156+
model_config = {"populate_by_name": True}
157+
138158
class SettlementUpdateRequest(BaseModel):
139159
status: SettlementStatus
140160
paidAt: Optional[datetime] = None
141161

162+
model_config = {"populate_by_name": True}
163+
142164
class SettlementListResponse(BaseModel):
143165
settlements: List[Settlement]
144166
optimizedSettlements: List[OptimizedSettlement]
145167
summary: Dict[str, Any]
146168
pagination: Dict[str, Any]
147169

170+
model_config = {"populate_by_name": True}
171+
148172
class UserBalance(BaseModel):
149173
userId: str
150174
userName: str
@@ -155,12 +179,16 @@ class UserBalance(BaseModel):
155179
pendingSettlements: List[Settlement] = []
156180
recentExpenses: List[Dict[str, Any]] = []
157181

182+
model_config = {"populate_by_name": True}
183+
158184
class FriendBalanceBreakdown(BaseModel):
159185
groupId: str
160186
groupName: str
161187
balance: float
162188
owesYou: bool
163189

190+
model_config = {"populate_by_name": True}
191+
164192
class FriendBalance(BaseModel):
165193
userId: str
166194
userName: str
@@ -170,17 +198,23 @@ class FriendBalance(BaseModel):
170198
breakdown: List[FriendBalanceBreakdown]
171199
lastActivity: datetime
172200

201+
model_config = {"populate_by_name": True}
202+
173203
class FriendsBalanceResponse(BaseModel):
174204
friendsBalance: List[FriendBalance]
175205
summary: Dict[str, Any]
176206

207+
model_config = {"populate_by_name": True}
208+
177209
class BalanceSummaryResponse(BaseModel):
178210
totalOwedToYou: float
179211
totalYouOwe: float
180212
netBalance: float
181213
currency: str = "USD"
182214
groupsSummary: List[Dict[str, Any]]
183215

216+
model_config = {"populate_by_name": True}
217+
184218
class ExpenseAnalytics(BaseModel):
185219
period: str
186220
totalExpenses: float
@@ -190,10 +224,16 @@ class ExpenseAnalytics(BaseModel):
190224
memberContributions: List[Dict[str, Any]]
191225
expenseTrends: List[Dict[str, Any]]
192226

227+
model_config = {"populate_by_name": True}
228+
193229
class AttachmentUploadResponse(BaseModel):
194230
attachment_key: str
195231
url: str
196232

233+
model_config = {"populate_by_name": True}
234+
197235
class OptimizedSettlementsResponse(BaseModel):
198236
optimizedSettlements: List[OptimizedSettlement]
199237
savings: Dict[str, Any]
238+
239+
model_config = {"populate_by_name": True}

backend/app/expenses/service.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
)
99
import asyncio
1010
from collections import defaultdict, deque
11+
import logging
1112

1213
class ExpenseService:
1314
def __init__(self):
@@ -86,8 +87,16 @@ async def _create_settlements_for_expense(self, expense_doc: Dict[str, Any], pay
8687

8788
# Get user names for the settlements
8889
user_ids = [split["userId"] for split in expense_doc["splits"]] + [payer_id]
89-
users = await self.users_collection.find({"_id": {"$in": [ObjectId(uid) for uid in user_ids]}}).to_list(None)
90+
try:
91+
users = await self.users_collection.find({"_id": {"$in": [ObjectId(uid) for uid in user_ids]}}).to_list(None)
92+
except Exception as e:
93+
logging.error(f"Failed to fetch user data for settlements: {e}")
94+
users = []
9095
user_names = {str(user["_id"]): user.get("name", "Unknown") for user in users}
96+
# Ensure all users have names, even if not found in database
97+
for user_id in user_ids:
98+
if user_id not in user_names:
99+
user_names[user_id] = "Unknown User"
91100

92101
for split in expense_doc["splits"]:
93102
settlement_doc = {
@@ -96,8 +105,8 @@ async def _create_settlements_for_expense(self, expense_doc: Dict[str, Any], pay
96105
"groupId": group_id,
97106
"payerId": payer_id,
98107
"payeeId": split["userId"],
99-
"payerName": user_names.get(payer_id, "Unknown"),
100-
"payeeName": user_names.get(split["userId"], "Unknown"),
108+
"payerName": user_names.get(payer_id, "Unknown User"),
109+
"payeeName": user_names.get(split["userId"], "Unknown User"),
101110
"amount": split["amount"],
102111
"status": "completed" if split["userId"] == payer_id else "pending",
103112
"description": f"Share for {expense_doc['description']}",

backend/app/groups/schemas.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,21 @@ class GroupMember(BaseModel):
77
role: str = "member" # "admin" or "member"
88
joinedAt: datetime
99

10+
model_config = {"populate_by_name": True}
11+
1012
class GroupCreateRequest(BaseModel):
1113
name: str = Field(..., min_length=1, max_length=100)
1214
currency: Optional[str] = "USD"
1315
imageUrl: Optional[str] = None
1416

17+
model_config = {"populate_by_name": True}
18+
1519
class GroupUpdateRequest(BaseModel):
1620
name: Optional[str] = Field(None, min_length=1, max_length=100)
1721
imageUrl: Optional[str] = None
1822

23+
model_config = {"populate_by_name": True}
24+
1925
class GroupResponse(BaseModel):
2026
id: str = Field(alias="_id")
2127
name: str
@@ -31,15 +37,23 @@ class GroupResponse(BaseModel):
3137
class GroupListResponse(BaseModel):
3238
groups: List[GroupResponse]
3339

40+
model_config = {"populate_by_name": True}
41+
3442
class JoinGroupRequest(BaseModel):
3543
joinCode: str = Field(..., min_length=1)
3644

45+
model_config = {"populate_by_name": True}
46+
3747
class JoinGroupResponse(BaseModel):
3848
group: GroupResponse
3949

50+
model_config = {"populate_by_name": True}
51+
4052
class MemberRoleUpdateRequest(BaseModel):
4153
role: str = Field(..., pattern="^(admin|member)$")
4254

55+
model_config = {"populate_by_name": True}
56+
4357
class LeaveGroupResponse(BaseModel):
4458
success: bool
4559
message: str

backend/app/user/schemas.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ class UserProfileUpdateRequest(BaseModel):
1818
imageUrl: Optional[str] = None
1919
currency: Optional[str] = None
2020

21+
model_config = {"populate_by_name": True}
22+
2123
class DeleteUserResponse(BaseModel):
2224
success: bool = True
2325
message: Optional[str] = None
26+
27+
model_config = {"populate_by_name": True}

0 commit comments

Comments
 (0)