diff --git a/src/backend/app/migrations/versions/e23c05f21542_change_task_events_state.py b/src/backend/app/migrations/versions/e23c05f21542_change_task_events_state.py new file mode 100644 index 00000000..8106412d --- /dev/null +++ b/src/backend/app/migrations/versions/e23c05f21542_change_task_events_state.py @@ -0,0 +1,130 @@ +"""change task events state + +Revision ID: e23c05f21542 +Revises: 8ae4e43a7011 +Create Date: 2024-12-06 08:00:16.223517 + +""" + +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision: str = "e23c05f21542" +down_revision: Union[str, None] = "8ae4e43a7011" +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + +old_state_enum = sa.Enum( + "REQUEST_FOR_MAPPING", + "UNLOCKED_TO_MAP", + "LOCKED_FOR_MAPPING", + "UNLOCKED_TO_VALIDATE", + "LOCKED_FOR_VALIDATION", + "UNLOCKED_DONE", + "UNFLYABLE_TASK", + "IMAGE_UPLOADED", + "IMAGE_PROCESSED", + "IMAGE_PROCESSING_FAILED", + name="state", +) + +new_state_enum = sa.Enum( + "REQUEST_FOR_MAPPING", + "UNLOCKED_TO_MAP", + "LOCKED_FOR_MAPPING", + "UNLOCKED_TO_VALIDATE", + "LOCKED_FOR_VALIDATION", + "UNLOCKED_DONE", + "UNFLYABLE_TASK", + "IMAGE_UPLOADED", + "IMAGE_PROCESSING_FAILED", + "IMAGE_PROCESSING_STARTED", + "IMAGE_PROCESSING_FINISHED", + name="state_new", +) + + +def upgrade(): + # Step 1: Create the new enum type + new_state_enum.create(op.get_bind()) + + # Step 2: Add a new column with the new enum type + op.add_column("task_events", sa.Column("new_state", new_state_enum, nullable=True)) + + # Step 3: Populate the new state column with the transformed data + op.execute( + """ + UPDATE task_events + SET new_state = + CASE + WHEN state = 'IMAGE_PROCESSED' THEN 'IMAGE_PROCESSING_FINISHED' + ELSE state::text + END::state_new + """ + ) + + # Step 4: Drop the old state column + op.drop_column("task_events", "state") + + # Step 5: Rename the new_state column to state + op.alter_column("task_events", "new_state", new_column_name="state") + + # Step 6: Drop the old enum type + op.execute("DROP TYPE state;") + + # Step 7: Rename the new enum type to state + op.execute("ALTER TYPE state_new RENAME TO state;") + + ## then add the image processing started state to all the image uploaded file + op.execute(""" + WITH added_image_processing_started AS ( + SELECT gen_random_uuid() AS event_id, + task_id, + project_id, + user_id, + created_at + INTERVAL '10 seconds' AS created_at, + comment, + updated_at + INTERVAL '10 seconds' AS updated_at, + 'IMAGE_PROCESSING_STARTED'::state AS state + FROM task_events WHERE state = 'IMAGE_UPLOADED' + ) + INSERT INTO task_events (event_id, task_id, project_id, user_id, created_at, comment, updated_at, state) + SELECT event_id, task_id, project_id, user_id, created_at, comment, updated_at, state + FROM added_image_processing_started; + """) + + +def downgrade(): + op.execute("DELETE from task_events WHERE state = 'IMAGE_PROCESSING_STARTED';") + # Step 1: Rename the new enum type back to the old name + op.execute("ALTER TYPE state RENAME TO state_new;") + + # Step 2: Create the old enum type again (assuming you have the definition of the old enum type) + # You would need to define the old state enum type here, e.g.: + old_state_enum.create(op.get_bind()) + + # Step 3: Add the old state column with the old enum type + op.add_column("task_events", sa.Column("state_old", old_state_enum, nullable=True)) + + # Step 4: Populate the old state column with the transformed data + op.execute( + """ + UPDATE task_events + SET state_old = + CASE + WHEN state = 'IMAGE_PROCESSING_FINISHED' THEN 'IMAGE_PROCESSED' + ELSE state::text + END::state + """ + ) + + # Step 5: Drop the new_state column + op.drop_column("task_events", "state") + op.alter_column("task_events", "state_old", new_column_name="state") + + # Step 6: Drop the new enum type + op.execute("DROP TYPE state_new;") diff --git a/src/backend/app/models/enums.py b/src/backend/app/models/enums.py index d15f5b94..6d22d16e 100644 --- a/src/backend/app/models/enums.py +++ b/src/backend/app/models/enums.py @@ -155,8 +155,9 @@ class State(int, Enum): UNLOCKED_DONE = 4 UNFLYABLE_TASK = 5 IMAGE_UPLOADED = 6 - IMAGE_PROCESSED = 7 - IMAGE_PROCESSING_FAILED = 8 + IMAGE_PROCESSING_FAILED = 7 + IMAGE_PROCESSING_STARTED = 8 + IMAGE_PROCESSING_FINISHED = 9 class EventType(str, Enum): diff --git a/src/backend/app/projects/image_processing.py b/src/backend/app/projects/image_processing.py index d51b0e20..39ef0599 100644 --- a/src/backend/app/projects/image_processing.py +++ b/src/backend/app/projects/image_processing.py @@ -190,7 +190,7 @@ def process_images_from_s3(self, bucket_name, name=None, options=[], webhook=Non self.user_id, "Task completed.", State.IMAGE_UPLOADED, - State.IMAGE_PROCESSED, + State.IMAGE_PROCESSING_FINISHED, timestamp(), ) return task @@ -305,11 +305,11 @@ async def download_and_upload_assets_from_odm_to_s3( user_id=user_id, comment=comment, initial_state=current_state, - final_state=State.IMAGE_PROCESSED, + final_state=State.IMAGE_PROCESSING_FINISHED, updated_at=timestamp(), ) log.info( - f"Task {dtm_task_id} state updated to IMAGE_PROCESSED in the database." + f"Task {dtm_task_id} state updated to IMAGE_PROCESSING_FINISHED in the database." ) except Exception as e: diff --git a/src/backend/app/projects/project_logic.py b/src/backend/app/projects/project_logic.py index 5d5db371..d08f06e2 100644 --- a/src/backend/app/projects/project_logic.py +++ b/src/backend/app/projects/project_logic.py @@ -34,7 +34,7 @@ async def get_centroids(db: Connection): ST_AsGeoJSON(p.centroid)::jsonb AS centroid, COUNT(t.id) AS total_task_count, COUNT(CASE WHEN te.state IN ('LOCKED_FOR_MAPPING', 'REQUEST_FOR_MAPPING', 'IMAGE_UPLOADED', 'UNFLYABLE_TASK') THEN 1 END) AS ongoing_task_count, - COUNT(CASE WHEN te.state = 'IMAGE_PROCESSED' THEN 1 END) AS completed_task_count + COUNT(CASE WHEN te.state = 'IMAGE_PROCESSING_FINISHED' THEN 1 END) AS completed_task_count FROM projects p LEFT JOIN diff --git a/src/backend/app/projects/project_schemas.py b/src/backend/app/projects/project_schemas.py index e9bc01d5..02297c2e 100644 --- a/src/backend/app/projects/project_schemas.py +++ b/src/backend/app/projects/project_schemas.py @@ -369,7 +369,7 @@ async def all( COUNT(CASE WHEN te.state IN ('LOCKED_FOR_MAPPING', 'REQUEST_FOR_MAPPING', 'IMAGE_UPLOADED', 'UNFLYABLE_TASK') 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 + COUNT(CASE WHEN te.state = 'IMAGE_PROCESSING_FINISHED' THEN 1 END) AS completed_task_count FROM projects p LEFT JOIN tasks t ON t.project_id = p.id diff --git a/src/backend/app/tasks/task_logic.py b/src/backend/app/tasks/task_logic.py index 0d3fa7c7..c82cd5dc 100644 --- a/src/backend/app/tasks/task_logic.py +++ b/src/backend/app/tasks/task_logic.py @@ -19,7 +19,7 @@ async def get_task_stats(db: Connection, user_data: AuthUser): SELECT COUNT(CASE WHEN te.state = 'REQUEST_FOR_MAPPING' THEN 1 END) AS request_logs, COUNT(CASE WHEN te.state IN ('LOCKED_FOR_MAPPING', 'IMAGE_UPLOADED', 'IMAGE_PROCESSING_FAILED') THEN 1 END) AS ongoing_tasks, - COUNT(CASE WHEN te.state = 'IMAGE_PROCESSED' THEN 1 END) AS completed_tasks, + COUNT(CASE WHEN te.state = 'IMAGE_PROCESSING_FINISHED' THEN 1 END) AS completed_tasks, COUNT(CASE WHEN te.state = 'UNFLYABLE_TASK' THEN 1 END) AS unflyable_tasks FROM (