Skip to content

Commit aba75f3

Browse files
committed
refactor: update task assignment models and repository to streamline data handling and enhance dual-write service integration
1 parent 7219ec5 commit aba75f3

File tree

5 files changed

+92
-72
lines changed

5 files changed

+92
-72
lines changed

todo/migrations/0001_initial_setup.py

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -180,27 +180,19 @@ class Migration(migrations.Migration):
180180
("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
181181
("mongo_id", models.CharField(blank=True, max_length=24, null=True, unique=True)),
182182
("task_mongo_id", models.CharField(max_length=24)),
183-
("user_mongo_id", models.CharField(max_length=24)),
184-
("team_mongo_id", models.CharField(blank=True, max_length=24, null=True)),
183+
("assignee_id", models.CharField(max_length=24)),
185184
(
186-
"status",
185+
"user_type",
187186
models.CharField(
188-
choices=[
189-
("ASSIGNED", "Assigned"),
190-
("IN_PROGRESS", "In Progress"),
191-
("COMPLETED", "Completed"),
192-
("REJECTED", "Rejected"),
193-
],
194-
default="ASSIGNED",
195-
max_length=20,
187+
choices=[("user", "User"), ("team", "Team")],
188+
max_length=10,
196189
),
197190
),
198-
("assigned_at", models.DateTimeField(default=django.utils.timezone.now)),
199-
("started_at", models.DateTimeField(blank=True, null=True)),
200-
("completed_at", models.DateTimeField(blank=True, null=True)),
191+
("team_id", models.CharField(blank=True, max_length=24, null=True)),
192+
("is_active", models.BooleanField(default=True)),
201193
("created_at", models.DateTimeField(default=django.utils.timezone.now)),
202194
("updated_at", models.DateTimeField(blank=True, null=True)),
203-
("assigned_by", models.CharField(max_length=24)),
195+
("created_by", models.CharField(max_length=24)),
204196
("updated_by", models.CharField(blank=True, max_length=24, null=True)),
205197
("last_sync_at", models.DateTimeField(auto_now=True)),
206198
(
@@ -218,12 +210,12 @@ class Migration(migrations.Migration):
218210
"indexes": [
219211
models.Index(fields=["mongo_id"], name="postgres_ta_mongo_i_326fa9_idx"),
220212
models.Index(fields=["task_mongo_id"], name="postgres_ta_task_mo_95ca3b_idx"),
221-
models.Index(fields=["user_mongo_id"], name="postgres_ta_user_mo_d13fa3_idx"),
222-
models.Index(fields=["team_mongo_id"], name="postgres_ta_team_mo_a0605f_idx"),
223-
models.Index(fields=["status"], name="postgres_ta_status_8b9698_idx"),
213+
models.Index(fields=["assignee_id"], name="postgres_ta_assignee_95ca3b_idx"),
214+
models.Index(fields=["user_type"], name="postgres_ta_user_typ_d13fa3_idx"),
215+
models.Index(fields=["team_id"], name="postgres_ta_team_id_a0605f_idx"),
216+
models.Index(fields=["is_active"], name="postgres_ta_is_acti_8b9698_idx"),
224217
models.Index(fields=["sync_status"], name="postgres_ta_sync_st_385c3f_idx"),
225218
],
226-
"unique_together": {("task_mongo_id", "user_mongo_id")},
227219
},
228220
),
229221
migrations.CreateModel(

todo/models/postgres/task_assignment.py

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,19 @@ class PostgresTaskAssignment(models.Model):
1212

1313
# Assignment fields
1414
task_mongo_id = models.CharField(max_length=24) # MongoDB ObjectId as string
15-
user_mongo_id = models.CharField(max_length=24) # MongoDB ObjectId as string
16-
team_mongo_id = models.CharField(max_length=24, null=True, blank=True) # MongoDB ObjectId as string
17-
18-
# Status
19-
STATUS_CHOICES = [
20-
("ASSIGNED", "Assigned"),
21-
("IN_PROGRESS", "In Progress"),
22-
("COMPLETED", "Completed"),
23-
("REJECTED", "Rejected"),
24-
]
25-
26-
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default="ASSIGNED")
15+
assignee_id = models.CharField(max_length=24) # MongoDB ObjectId as string (user or team ID)
16+
user_type = models.CharField(max_length=10, choices=[("user", "User"), ("team", "Team")]) # user or team
17+
team_id = models.CharField(
18+
max_length=24, null=True, blank=True
19+
) # MongoDB ObjectId as string (only for team assignments)
20+
is_active = models.BooleanField(default=True) # Match MongoDB approach
2721

2822
# Timestamps
29-
assigned_at = models.DateTimeField(default=timezone.now)
30-
started_at = models.DateTimeField(null=True, blank=True)
31-
completed_at = models.DateTimeField(null=True, blank=True)
3223
created_at = models.DateTimeField(default=timezone.now)
3324
updated_at = models.DateTimeField(null=True, blank=True)
3425

3526
# References
36-
assigned_by = models.CharField(max_length=24) # MongoDB ObjectId as string
27+
created_by = models.CharField(max_length=24) # MongoDB ObjectId as string
3728
updated_by = models.CharField(max_length=24, null=True, blank=True) # MongoDB ObjectId as string
3829

3930
# Sync metadata
@@ -51,18 +42,18 @@ class PostgresTaskAssignment(models.Model):
5142

5243
class Meta:
5344
db_table = "postgres_task_assignments"
54-
unique_together = ["task_mongo_id", "user_mongo_id"]
5545
indexes = [
5646
models.Index(fields=["mongo_id"]),
5747
models.Index(fields=["task_mongo_id"]),
58-
models.Index(fields=["user_mongo_id"]),
59-
models.Index(fields=["team_mongo_id"]),
60-
models.Index(fields=["status"]),
48+
models.Index(fields=["assignee_id"]),
49+
models.Index(fields=["user_type"]),
50+
models.Index(fields=["team_id"]),
51+
models.Index(fields=["is_active"]),
6152
models.Index(fields=["sync_status"]),
6253
]
6354

6455
def __str__(self):
65-
return f"Task {self.task_mongo_id} assigned to User {self.user_mongo_id}"
56+
return f"Task {self.task_mongo_id} assigned to {self.user_type} {self.assignee_id}"
6657

6758
def save(self, *args, **kwargs):
6859
if not self.pk: # New instance

todo/repositories/task_assignment_repository.py

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,15 @@ def create(cls, task_assignment: TaskAssignmentModel) -> TaskAssignmentModel:
2424

2525
dual_write_service = EnhancedDualWriteService()
2626
task_assignment_data = {
27-
"task_id": str(task_assignment.task_id),
27+
"task_mongo_id": str(task_assignment.task_id),
2828
"assignee_id": str(task_assignment.assignee_id),
2929
"user_type": task_assignment.user_type,
3030
"team_id": str(task_assignment.team_id) if task_assignment.team_id else None,
3131
"is_active": task_assignment.is_active,
32-
"created_by": str(task_assignment.created_by),
33-
"updated_by": str(task_assignment.updated_by) if task_assignment.updated_by else None,
3432
"created_at": task_assignment.created_at,
3533
"updated_at": task_assignment.updated_at,
34+
"created_by": str(task_assignment.created_by),
35+
"updated_by": str(task_assignment.updated_by) if task_assignment.updated_by else None,
3636
}
3737

3838
dual_write_success = dual_write_service.create_document(
@@ -130,6 +130,31 @@ def update_assignment(
130130
},
131131
)
132132

133+
# Sync deactivation to PostgreSQL
134+
if current_assignment:
135+
dual_write_service = EnhancedDualWriteService()
136+
deactivation_data = {
137+
"task_mongo_id": str(current_assignment.task_id),
138+
"assignee_id": str(current_assignment.assignee_id),
139+
"user_type": current_assignment.user_type,
140+
"team_id": str(current_assignment.team_id) if current_assignment.team_id else None,
141+
"is_active": False,
142+
"created_at": current_assignment.created_at,
143+
"updated_at": datetime.now(timezone.utc),
144+
"created_by": str(current_assignment.created_by),
145+
"updated_by": str(user_id),
146+
}
147+
148+
dual_write_success = dual_write_service.update_document(
149+
collection_name="task_assignments", data=deactivation_data, mongo_id=str(current_assignment.id)
150+
)
151+
152+
if not dual_write_success:
153+
import logging
154+
155+
logger = logging.getLogger(__name__)
156+
logger.warning(f"Failed to sync task assignment deactivation {current_assignment.id} to Postgres")
157+
133158
new_assignment = TaskAssignmentModel(
134159
_id=PyObjectId(),
135160
task_id=PyObjectId(task_id),
@@ -181,15 +206,15 @@ def delete_assignment(cls, task_id: str, user_id: str) -> bool:
181206
# Sync to PostgreSQL
182207
dual_write_service = EnhancedDualWriteService()
183208
assignment_data = {
184-
"task_id": str(current_assignment.task_id),
209+
"task_mongo_id": str(current_assignment.task_id),
185210
"assignee_id": str(current_assignment.assignee_id),
186211
"user_type": current_assignment.user_type,
187212
"team_id": str(current_assignment.team_id) if current_assignment.team_id else None,
188213
"is_active": False,
189-
"created_by": str(current_assignment.created_by),
190-
"updated_by": str(user_id),
191214
"created_at": current_assignment.created_at,
192215
"updated_at": datetime.now(timezone.utc),
216+
"created_by": str(current_assignment.created_by),
217+
"updated_by": str(user_id),
193218
}
194219

195220
dual_write_success = dual_write_service.update_document(
@@ -244,15 +269,15 @@ def update_executor(cls, task_id: str, executor_id: str, user_id: str) -> bool:
244269
# Sync to PostgreSQL
245270
dual_write_service = EnhancedDualWriteService()
246271
assignment_data = {
247-
"task_id": str(current_assignment.task_id),
272+
"task_mongo_id": str(current_assignment.task_id),
248273
"assignee_id": str(executor_id),
249274
"user_type": "user",
250275
"team_id": str(current_assignment.team_id) if current_assignment.team_id else None,
251276
"is_active": current_assignment.is_active,
252-
"created_by": str(current_assignment.created_by),
253-
"updated_by": str(user_id),
254277
"created_at": current_assignment.created_at,
255278
"updated_at": datetime.now(timezone.utc),
279+
"created_by": str(current_assignment.created_by),
280+
"updated_by": str(user_id),
256281
}
257282

258283
dual_write_success = dual_write_service.update_document(
@@ -306,15 +331,15 @@ def deactivate_by_task_id(cls, task_id: str, user_id: str) -> bool:
306331
# Sync to PostgreSQL for each assignment
307332
dual_write_service = EnhancedDualWriteService()
308333
assignment_data = {
309-
"task_id": str(active_assignments.task_id),
334+
"task_mongo_id": str(active_assignments.task_id),
310335
"assignee_id": str(active_assignments.assignee_id),
311336
"user_type": active_assignments.user_type,
312337
"team_id": str(active_assignments.team_id) if active_assignments.team_id else None,
313338
"is_active": False,
314-
"created_by": str(active_assignments.created_by),
315-
"updated_by": str(user_id),
316339
"created_at": active_assignments.created_at,
317340
"updated_at": datetime.now(timezone.utc),
341+
"created_by": str(active_assignments.created_by),
342+
"updated_by": str(user_id),
318343
}
319344

320345
dual_write_success = dual_write_service.update_document(

todo/repositories/task_repository.py

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -208,23 +208,31 @@ def create(cls, task: TaskModel) -> TaskModel:
208208
task.createdAt = datetime.now(timezone.utc)
209209
task.updatedAt = None
210210

211+
# Ensure createdAt is properly set
212+
if not task.createdAt:
213+
task.createdAt = datetime.now(timezone.utc)
214+
211215
task_dict = task.model_dump(mode="json", by_alias=True, exclude_none=True)
212216
insert_result = tasks_collection.insert_one(task_dict, session=session)
213217

214218
task.id = insert_result.inserted_id
215219

216220
dual_write_service = EnhancedDualWriteService()
221+
217222
task_data = {
218223
"title": task.title,
219224
"description": task.description,
220225
"priority": task.priority,
221226
"status": task.status,
222-
"display_id": task.displayId,
223-
"created_by": str(task.createdBy),
224-
"updated_by": str(task.updatedBy) if task.updatedBy else None,
225-
"is_deleted": task.isDeleted,
226-
"created_at": task.createdAt,
227-
"updated_at": task.updatedAt,
227+
"displayId": task.displayId,
228+
"isAcknowledged": task.isAcknowledged,
229+
"isDeleted": task.isDeleted,
230+
"startedAt": task.startedAt,
231+
"dueAt": task.dueAt,
232+
"createdAt": task.createdAt or datetime.now(timezone.utc),
233+
"updatedAt": task.updatedAt,
234+
"createdBy": str(task.createdBy),
235+
"updatedBy": str(task.updatedBy) if task.updatedBy else None,
228236
}
229237

230238
dual_write_success = dual_write_service.create_document(
@@ -313,12 +321,15 @@ def update(cls, task_id: str, update_data: dict) -> TaskModel | None:
313321
"description": task_model.description,
314322
"priority": task_model.priority,
315323
"status": task_model.status,
316-
"display_id": task_model.displayId,
317-
"created_by": str(task_model.createdBy),
318-
"updated_by": str(task_model.updatedBy) if task_model.updatedBy else None,
319-
"is_deleted": task_model.isDeleted,
320-
"created_at": task_model.createdAt,
321-
"updated_at": task_model.updatedAt,
324+
"displayId": task_model.displayId,
325+
"isAcknowledged": task_model.isAcknowledged,
326+
"isDeleted": task_model.isDeleted,
327+
"startedAt": task_model.startedAt,
328+
"dueAt": task_model.dueAt,
329+
"createdAt": task_model.createdAt,
330+
"updatedAt": task_model.updatedAt,
331+
"createdBy": str(task_model.createdBy),
332+
"updatedBy": str(task_model.updatedBy) if task_model.updatedBy else None,
322333
}
323334

324335
dual_write_success = dual_write_service.update_document(

todo/services/dual_write_service.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,12 @@ def update_document(self, collection_name: str, mongo_id: str, data: Dict[str, A
115115
labels = postgres_data.pop("labels", []) if collection_name == "tasks" else []
116116

117117
postgres_instance = postgres_model.objects.get(mongo_id=mongo_id)
118+
preserve_fields = {"created_at", "mongo_id"}
119+
118120
for field, value in postgres_data.items():
119-
if hasattr(postgres_instance, field):
121+
if hasattr(postgres_instance, field) and field not in preserve_fields:
120122
setattr(postgres_instance, field, value)
123+
121124
postgres_instance.sync_status = "SYNCED"
122125
postgres_instance.sync_error = None
123126
postgres_instance.save()
@@ -309,15 +312,13 @@ def _transform_task_assignment_data(self, data: Dict[str, Any]) -> Dict[str, Any
309312
"""Transform task assignment data for Postgres."""
310313
return {
311314
"task_mongo_id": str(data.get("task_mongo_id", "")),
312-
"user_mongo_id": str(data.get("user_mongo_id", "")),
313-
"team_mongo_id": str(data.get("team_mongo_id", "")) if data.get("team_mongo_id") else None,
314-
"status": data.get("status", "ASSIGNED"),
315-
"assigned_at": data.get("assigned_at"),
316-
"started_at": data.get("started_at"),
317-
"completed_at": data.get("completed_at"),
315+
"assignee_id": str(data.get("assignee_id", "")),
316+
"user_type": data.get("user_type", "user"),
317+
"team_id": str(data.get("team_id", "")) if data.get("team_id") else None,
318+
"is_active": data.get("is_active", True),
318319
"created_at": data.get("created_at"),
319320
"updated_at": data.get("updated_at"),
320-
"assigned_by": str(data.get("assigned_by", "")),
321+
"created_by": str(data.get("created_by", "")),
321322
"updated_by": str(data.get("updated_by", "")) if data.get("updated_by") else None,
322323
}
323324

0 commit comments

Comments
 (0)