Skip to content

Commit

Permalink
feat: auto unlock locked tasks after 3 days
Browse files Browse the repository at this point in the history
  • Loading branch information
Anuj-Gupta4 committed Dec 10, 2024
1 parent 9eb6c60 commit 4c3cd0a
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 4 deletions.
16 changes: 12 additions & 4 deletions src/backend/app/db/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"""

import json
from datetime import timedelta
from datetime import datetime, timedelta
from io import BytesIO
from re import sub
from typing import TYPE_CHECKING, Annotated, Optional, Self
Expand Down Expand Up @@ -1366,6 +1366,7 @@ class DbOdkEntities(BaseModel):
status: EntityState
project_id: int
task_id: int
updated_at: Optional[AwareDatetime] = None

@classmethod
async def upsert(
Expand All @@ -1391,7 +1392,7 @@ async def upsert(

sql = """
INSERT INTO public.odk_entities
(entity_id, status, project_id, task_id)
(entity_id, status, project_id, task_id, updated_at)
VALUES
"""

Expand All @@ -1404,20 +1405,27 @@ async def upsert(
f"(%({entity_index}_entity_id)s, "
f"%({entity_index}_status)s, "
f"%({entity_index}_project_id)s, "
f"%({entity_index}_task_id)s)"
f"%({entity_index}_task_id)s, "
f"%({entity_index}_updated_at)s)"
)
data[f"{entity_index}_entity_id"] = entity["id"]
data[f"{entity_index}_status"] = EntityState(int(entity["status"])).name
data[f"{entity_index}_project_id"] = project_id
task_id = entity["task_id"]
data[f"{entity_index}_task_id"] = int(task_id) if task_id else None
data[f"{entity_index}_updated_at"] = (
datetime.fromisoformat(entity["updatedAt"].replace("Z", "+00:00"))
if entity["updatedAt"]
else None
)

sql += (
", ".join(values)
+ """
ON CONFLICT (entity_id) DO UPDATE SET
status = EXCLUDED.status,
task_id = EXCLUDED.task_id
task_id = EXCLUDED.task_id,
updated_at = EXCLUDED.updated_at
RETURNING True;
"""
)
Expand Down
65 changes: 65 additions & 0 deletions src/backend/app/tasks/task_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,68 @@ async def get_task_event_history(
):
"""Get the detailed history for a task."""
return await DbTaskEvent.all(db, task_id=task_id, days=days, comments=comments)


@router.post("/unlock-tasks")
async def trigger_unlock_tasks(db: Annotated[Connection, Depends(db_conn)]):
"""Endpoint to trigger unlock_old_locked_tasks manually."""
await unlock_old_locked_tasks(db)
return {"message": "Old locked tasks unlocked successfully."}


async def unlock_old_locked_tasks(db):
"""Unlock tasks locked for more than 3 days."""
unlock_query = """
WITH svc_user AS (
SELECT id AS svc_user_id, username AS svc_username
FROM users
WHERE username = 'svcfmtm'
),
recent_events AS (
SELECT DISTINCT ON (t.id, t.project_id)
t.id AS task_id,
t.project_id,
MAX(the.created_at) AS last_event_time,
oe.status AS entity_status,
oe.updated_at
FROM tasks t
JOIN task_events the ON t.id = the.task_id
LEFT JOIN odk_entities oe ON t.id = oe.task_id
WHERE the.event IN ('ASSIGN', 'MAP')
GROUP BY t.id, t.project_id, oe.entity_id, oe.status, oe.updated_at
)
INSERT INTO task_events (
event_id,
task_id,
project_id,
event,
user_id,
state,
created_at,
username
)
SELECT
gen_random_uuid(),
re.task_id,
re.project_id,
'MAP'::taskevent,
svc.svc_user_id,
'UNLOCKED_TO_MAP'::mappingstate,
NOW(),
svc.svc_username
FROM recent_events re
CROSS JOIN svc_user svc
WHERE re.last_event_time < NOW() - INTERVAL '3 days'
AND re.updated_at::timestamp < NOW() - INTERVAL '3 days';
"""

async with db.cursor() as cur:
await cur.execute("BEGIN;")
await cur.execute(
"ALTER TABLE task_events DISABLE TRIGGER task_event_state_trigger;"
)
await cur.execute(unlock_query)
await cur.execute(
"ALTER TABLE task_events ENABLE TRIGGER task_event_state_trigger;"
)
await cur.execute("COMMIT;")
22 changes: 22 additions & 0 deletions src/backend/migrations/011-add-date-to-entity.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
-- ## Migration to:
-- * track the last time an entity was updated

-- Start a transaction
BEGIN;

-- Add column 'updated_at' to 'odk_entities' table
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1
FROM information_schema.columns
WHERE table_name='odk_entities' AND column_name='updated_at'
) THEN
ALTER TABLE public.odk_entities
ADD COLUMN updated_at VARCHAR;
END IF;
END $$;


-- Commit the transaction
COMMIT;

0 comments on commit 4c3cd0a

Please sign in to comment.