Skip to content

Commit 33492dd

Browse files
committed
fix: korbit suggestion
1 parent ae1370a commit 33492dd

File tree

6 files changed

+76
-29
lines changed

6 files changed

+76
-29
lines changed

todo/constants/messages.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Application Messages
22
class AppMessages:
33
TASK_CREATED = "Task created successfully"
4+
TEAM_CREATED = "Team created successfully"
45
GOOGLE_LOGIN_SUCCESS = "Successfully logged in with Google"
56
GOOGLE_LOGOUT_SUCCESS = "Successfully logged out"
67
TOKEN_REFRESHED = "Access token refreshed successfully"

todo/dto/responses/create_team_response.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44

55
class CreateTeamResponse(BaseModel):
66
team: TeamDTO
7-
message: str = "Team created successfully"
7+
message: str

todo/dto/team_dto.py

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,42 @@
1-
from pydantic import BaseModel
1+
from pydantic import BaseModel, validator
22
from typing import List, Optional
33
from datetime import datetime
4+
from todo.repositories.user_repository import UserRepository
45

56

67
class CreateTeamDTO(BaseModel):
78
name: str
89
description: Optional[str] = None
9-
member_ids: List[str] = []
10+
member_ids: Optional[List[str]] = None
1011
poc_id: str
1112

13+
@validator('member_ids')
14+
def validate_member_ids(cls, value):
15+
"""Validate that all member IDs exist in the database."""
16+
if value is None:
17+
return value
18+
19+
invalid_ids = []
20+
for member_id in value:
21+
user = UserRepository.get_by_id(member_id)
22+
if not user:
23+
invalid_ids.append(member_id)
24+
25+
if invalid_ids:
26+
raise ValueError(f'Invalid member IDs: {invalid_ids}')
27+
return value
28+
29+
@validator('poc_id')
30+
def validate_poc_id(cls, value):
31+
"""Validate that the POC ID exists in the database."""
32+
if value is None:
33+
return value
34+
35+
user = UserRepository.get_by_id(value)
36+
if not user:
37+
raise ValueError(f'Invalid POC ID: {value}')
38+
return value
39+
1240

1341
class TeamDTO(BaseModel):
1442
id: str

todo/models/team.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from pydantic import Field
1+
from pydantic import Field, validator
22
from typing import ClassVar
33
from datetime import datetime, timezone
44

@@ -13,7 +13,7 @@ class TeamModel(Document):
1313

1414
collection_name: ClassVar[str] = "teams"
1515

16-
name: str
16+
name: str = Field(..., min_length=1, max_length=100)
1717
description: str | None = None
1818
poc_id: PyObjectId
1919
created_by: PyObjectId
@@ -22,13 +22,22 @@ class TeamModel(Document):
2222
updated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
2323
is_deleted: bool = False
2424

25+
@validator('created_by', 'updated_by')
26+
def validate_user_id(cls, v):
27+
"""Validate that the user ID is a valid ObjectId format."""
28+
if v is None:
29+
raise ValueError('User ID cannot be None')
30+
if not PyObjectId.is_valid(v):
31+
raise ValueError(f'Invalid user ID format: {v}')
32+
return v
33+
2534

2635
class UserTeamDetailsModel(Document):
2736
"""
2837
Model for user-team relationships.
2938
"""
3039

31-
collection_name: ClassVar[str] = "userTeamDetails"
40+
collection_name: ClassVar[str] = "user_team_details"
3241

3342
user_id: PyObjectId
3443
team_id: PyObjectId
@@ -38,3 +47,12 @@ class UserTeamDetailsModel(Document):
3847
updated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
3948
created_by: PyObjectId
4049
updated_by: PyObjectId
50+
51+
@validator('user_id', 'team_id', 'created_by', 'updated_by')
52+
def validate_object_ids(cls, v):
53+
"""Validate that the ObjectId fields are in valid format."""
54+
if v is None:
55+
raise ValueError('ObjectId cannot be None')
56+
if not PyObjectId.is_valid(v):
57+
raise ValueError(f'Invalid ObjectId format: {v}')
58+
return v

todo/services/team_service.py

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from todo.models.common.pyobjectid import PyObjectId
55
from todo.repositories.team_repository import TeamRepository, UserTeamDetailsRepository
66
from todo.repositories.user_repository import UserRepository
7+
from todo.constants.messages import AppMessages
78

89

910
class TeamService:
@@ -13,18 +14,8 @@ def create_team(cls, dto: CreateTeamDTO, created_by_user_id: str) -> CreateTeamR
1314
Create a new team with members and POC.
1415
"""
1516
try:
16-
# Validate that all member IDs exist
17-
if dto.member_ids:
18-
for user_id in dto.member_ids:
19-
user = UserRepository.get_by_id(user_id)
20-
if not user:
21-
raise ValueError(f"User with ID {user_id} not found")
22-
23-
# Validate POC exists if provided
24-
if dto.poc_id:
25-
poc_user = UserRepository.get_by_id(dto.poc_id)
26-
if not poc_user:
27-
raise ValueError(f"POC user with ID {dto.poc_id} not found")
17+
# Member IDs and POC ID validation is handled at DTO level
18+
member_ids = dto.member_ids or []
2819

2920
# Create team
3021
team = TeamModel(
@@ -41,8 +32,8 @@ def create_team(cls, dto: CreateTeamDTO, created_by_user_id: str) -> CreateTeamR
4132
user_teams = []
4233

4334
# Add members to the team
44-
if dto.member_ids:
45-
for user_id in dto.member_ids:
35+
if member_ids:
36+
for user_id in member_ids:
4637
user_team = UserTeamDetailsModel(
4738
user_id=PyObjectId(user_id),
4839
team_id=created_team.id,
@@ -53,7 +44,7 @@ def create_team(cls, dto: CreateTeamDTO, created_by_user_id: str) -> CreateTeamR
5344
user_teams.append(user_team)
5445

5546
# Add POC if not already in member_ids
56-
if dto.poc_id and dto.poc_id not in dto.member_ids:
47+
if dto.poc_id and dto.poc_id not in member_ids:
5748
poc_user_team = UserTeamDetailsModel(
5849
user_id=PyObjectId(dto.poc_id),
5950
team_id=created_team.id,
@@ -64,7 +55,7 @@ def create_team(cls, dto: CreateTeamDTO, created_by_user_id: str) -> CreateTeamR
6455
user_teams.append(poc_user_team)
6556

6657
# Add creator if not already in member_ids
67-
if created_by_user_id not in dto.member_ids:
58+
if created_by_user_id not in member_ids:
6859
creator_user_team = UserTeamDetailsModel(
6960
user_id=PyObjectId(created_by_user_id),
7061
team_id=created_team.id,
@@ -90,7 +81,7 @@ def create_team(cls, dto: CreateTeamDTO, created_by_user_id: str) -> CreateTeamR
9081
updated_at=created_team.updated_at,
9182
)
9283

93-
return CreateTeamResponse(team=team_dto)
84+
return CreateTeamResponse(team=team_dto, message=AppMessages.TEAM_CREATED)
9485

9586
except Exception as e:
9687
raise ValueError(str(e))

todo/utils/google_jwt_utils.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import jwt
2+
import logging
23
from datetime import datetime, timedelta, timezone
34
from django.conf import settings
45

@@ -10,6 +11,8 @@
1011

1112
from todo.constants.messages import AuthErrorMessages
1213

14+
logger = logging.getLogger(__name__)
15+
1316

1417
def generate_google_access_token(user_data: dict) -> str:
1518
try:
@@ -34,7 +37,8 @@ def generate_google_access_token(user_data: dict) -> str:
3437
return token
3538

3639
except Exception as e:
37-
raise GoogleTokenInvalidError(f"Token generation failed: {str(e)}")
40+
logger.error(f"Token generation failed: {str(e)}") # Log the detailed error internally
41+
raise GoogleTokenInvalidError(AuthErrorMessages.GOOGLE_TOKEN_INVALID) # Return generic message to client
3842

3943

4044
def generate_google_refresh_token(user_data: dict) -> str:
@@ -59,7 +63,8 @@ def generate_google_refresh_token(user_data: dict) -> str:
5963
return token
6064

6165
except Exception as e:
62-
raise GoogleTokenInvalidError(f"Refresh token generation failed: {str(e)}")
66+
logger.error(f"Refresh token generation failed: {str(e)}") # Log the detailed error internally
67+
raise GoogleTokenInvalidError(AuthErrorMessages.GOOGLE_TOKEN_INVALID) # Return generic message to client
6368

6469

6570
def validate_google_access_token(token: str) -> dict:
@@ -76,9 +81,11 @@ def validate_google_access_token(token: str) -> dict:
7681
except jwt.ExpiredSignatureError:
7782
raise GoogleTokenExpiredError()
7883
except jwt.InvalidTokenError as e:
79-
raise GoogleTokenInvalidError(f"Invalid token: {str(e)}")
84+
logger.error(f"Invalid token: {str(e)}") # Log the detailed error internally
85+
raise GoogleTokenInvalidError(AuthErrorMessages.GOOGLE_TOKEN_INVALID) # Return generic message to client
8086
except Exception as e:
81-
raise GoogleTokenInvalidError(f"Token validation failed: {str(e)}")
87+
logger.error(f"Token validation failed: {str(e)}") # Log the detailed error internally
88+
raise GoogleTokenInvalidError(AuthErrorMessages.GOOGLE_TOKEN_INVALID) # Return generic message to client
8289

8390

8491
def validate_google_refresh_token(token: str) -> dict:
@@ -94,9 +101,11 @@ def validate_google_refresh_token(token: str) -> dict:
94101
except jwt.ExpiredSignatureError:
95102
raise GoogleRefreshTokenExpiredError()
96103
except jwt.InvalidTokenError as e:
97-
raise GoogleTokenInvalidError(f"Invalid refresh token: {str(e)}")
104+
logger.error(f"Invalid refresh token: {str(e)}") # Log the detailed error internally
105+
raise GoogleTokenInvalidError(AuthErrorMessages.GOOGLE_TOKEN_INVALID) # Return generic message to client
98106
except Exception as e:
99-
raise GoogleTokenInvalidError(f"Refresh token validation failed: {str(e)}")
107+
logger.error(f"Refresh token validation failed: {str(e)}") # Log the detailed error internally
108+
raise GoogleTokenInvalidError(AuthErrorMessages.GOOGLE_TOKEN_INVALID) # Return generic message to client
100109

101110

102111
def generate_google_token_pair(user_data: dict) -> dict:

0 commit comments

Comments
 (0)