diff --git a/src/backend/app/projects/project_schemas.py b/src/backend/app/projects/project_schemas.py index 9629cfb0..89f80e98 100644 --- a/src/backend/app/projects/project_schemas.py +++ b/src/backend/app/projects/project_schemas.py @@ -252,10 +252,10 @@ async def one(db: Connection, project_id: uuid.UUID): te.user_id, CASE WHEN te.state = 'REQUEST_FOR_MAPPING' THEN 'request logs' - WHEN te.state = 'LOCKED_FOR_MAPPING' THEN 'ongoing' + WHEN te.state = 'LOCKED_FOR_MAPPING' OR te.state = 'IMAGE_UPLOADED' THEN 'ongoing' WHEN te.state = 'IMAGE_PROCESSED' THEN 'completed' WHEN te.state = 'UNFLYABLE_TASK' THEN 'unflyable task' - ELSE 'UNLOCKED_TO_MAP' + ELSE '' END AS calculated_state FROM task_events te @@ -273,7 +273,7 @@ async def one(db: Connection, project_id: uuid.UUID): ST_YMin(ST_Envelope(t.outline)) AS ymin, ST_XMax(ST_Envelope(t.outline)) AS xmax, ST_YMax(ST_Envelope(t.outline)) AS ymax, - COALESCE(tsc.calculated_state, 'UNLOCKED_TO_MAP') AS state, + COALESCE(tsc.calculated_state) AS state, tsc.user_id, u.name, ST_Area(ST_Transform(t.outline, 3857)) / 1000000 AS task_area @@ -341,7 +341,10 @@ async def all( COUNT(t.id) AS total_task_count, -- Count based on the latest state of tasks - COUNT(CASE WHEN te.state = 'LOCKED_FOR_MAPPING' THEN 1 END) AS ongoing_task_count + COUNT(CASE WHEN te.state = 'LOCKED_FOR_MAPPING' THEN 1 END) AS ongoing_task_count, + + -- Count based on the latest state of tasks + COUNT(CASE WHEN te.state = 'IMAGE_PROCESSED' THEN 1 END) AS completed_task_count FROM projects p LEFT JOIN tasks t ON t.project_id = p.id @@ -526,6 +529,8 @@ class ProjectInfo(BaseModel): tasks: Optional[list[TaskOut]] = [] image_url: Optional[str] = None ongoing_task_count: Optional[int] = 0 + completed_task_count: Optional[int] = 0 + status: Optional[str] = "not-started" @model_validator(mode="after") def set_image_url(cls, values): @@ -537,6 +542,21 @@ def set_image_url(cls, values): values.image_url = get_presigned_url(settings.S3_BUCKET_NAME, image_dir, 5) return values + @model_validator(mode="after") + def calculate_status(cls, values): + """Set the project status based on task counts.""" + ongoing_task_count = values.ongoing_task_count + completed_task_count = values.completed_task_count + + if ongoing_task_count == 0: + values.status = "not-started" + elif ongoing_task_count > 0 and ongoing_task_count != completed_task_count: + values.status = "ongoing" + elif ongoing_task_count == completed_task_count: + values.status = "completed" + + return values + class ProjectOut(BaseModel): """Base project model.""" diff --git a/src/backend/app/tasks/task_schemas.py b/src/backend/app/tasks/task_schemas.py index 6ef0cf94..69ec9bc2 100644 --- a/src/backend/app/tasks/task_schemas.py +++ b/src/backend/app/tasks/task_schemas.py @@ -169,10 +169,10 @@ async def get_tasks_by_user( task_events.updated_at, CASE WHEN task_events.state = 'REQUEST_FOR_MAPPING' THEN 'request logs' - WHEN task_events.state = 'LOCKED_FOR_MAPPING' THEN 'ongoing' + WHEN task_events.state = 'LOCKED_FOR_MAPPING' OR task_events.state = 'IMAGE_UPLOADED' THEN 'ongoing' WHEN task_events.state = 'IMAGE_PROCESSED' THEN 'completed' WHEN task_events.state = 'UNFLYABLE_TASK' THEN 'unflyable task' - ELSE 'UNLOCKED_TO_MAP' + ELSE '' END AS state FROM task_events