Files
TimeTracker/logs/app.jsonl
Dries Peeters 54ec5fe4b2 feat: Add bulk task operations and CSV export across all entities
Implements comprehensive bulk operations and export functionality for tasks,
clients, and projects with consistent UI/UX across all three entities.

Features Added:
- Bulk task operations (delete, status change, assignment, move to project)
- Multi-select checkboxes with "select all" functionality
- CSV export for tasks, clients, and projects
- Export respects current filters and permissions
- Modal dialogs for bulk operation confirmation

Bug Fixes:
- Fixed bulk delete not working due to dialog submission issue
- Fixed dropdown menus being cut off in short tables (z-index and overflow)
- Fixed projects export attempting to access .name on string property

Technical Details:
- Backend: Added 5 new routes (tasks bulk ops, 3 export routes)
- Frontend: Updated task/client/project list templates with consistent UI
- Tests: Added 23 comprehensive tests for bulk operations
- Changed table overflow from overflow-x-auto to overflow-visible
- Added z-50 to all dropdown menus for proper layering

Routes Added:
- POST /tasks/bulk-delete
- POST /tasks/bulk-status
- POST /tasks/bulk-assign
- POST /tasks/bulk-move-project
- GET /tasks/export
- GET /clients/export
- GET /projects/export

Files Changed:
- app/routes/tasks.py (+103 lines)
- app/routes/clients.py (+73 lines)
- app/routes/projects.py (+95 lines)
- app/templates/tasks/list.html (major refactor)
- app/templates/clients/list.html (+export, overflow fix)
- app/templates/projects/list.html (+export fix, overflow fix)
- tests/test_bulk_task_operations.py (NEW, 23 tests)
- docs/BULK_TASK_OPERATIONS.md (NEW)
- BULK_TASK_OPERATIONS_IMPLEMENTATION.md (NEW)
- BUGFIXES_BULK_OPERATIONS.md (NEW)
- BUGFIXES_CONSISTENCY_AND_EXPORT.md (NEW)

Breaking Changes: None
Migration Required: None
2025-10-30 10:06:13 +01:00

117 lines
28 KiB
JSON

{"asctime": "2025-10-20 13:22:52,815", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "request_id": "40313990-3329-433e-9f7f-7ad0202d77ef", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-20 13:34:55,797", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "request_id": "1fbe6ee8-69dc-4262-9a26-453af24c0fea", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-20 13:35:27,047", "levelname": "INFO", "name": "timetracker", "message": "timer.started", "request_id": "df68bf19-97c5-45de-b5f3-fb0ee3f7f429", "event": "timer.started", "user_id": 1, "project_id": 4, "task_id": 2, "description": ""}
{"asctime": "2025-10-20 13:35:47,153", "levelname": "INFO", "name": "timetracker", "message": "timer.stopped", "request_id": "2f5027c5-7204-40ed-b3ce-8878c9b4e0f1", "event": "timer.stopped", "user_id": 1, "time_entry_id": 8, "project_id": 4, "task_id": 2, "duration_seconds": 0}
{"asctime": "2025-10-20 13:37:48,958", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "request_id": "20538739-454b-4aa0-a395-64b1ebc3b294", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-20 13:37:55,671", "levelname": "INFO", "name": "timetracker", "message": "timer.started", "request_id": "2eb5f561-0420-48ca-964f-25397184369d", "event": "timer.started", "user_id": 1, "project_id": 4, "task_id": 2, "description": ""}
{"asctime": "2025-10-20 13:38:03,573", "levelname": "INFO", "name": "timetracker", "message": "timer.stopped", "request_id": "7c23039a-69a5-4896-bb72-7cc0e084bb32", "event": "timer.stopped", "user_id": 1, "time_entry_id": 9, "project_id": 4, "task_id": 2, "duration_seconds": 0}
{"asctime": "2025-10-20 14:19:26,750", "levelname": "INFO", "name": "timetracker", "message": "setup.completed", "request_id": "11ca8b85-d7a2-467e-9e41-a6f953f3303c", "event": "setup.completed", "telemetry_enabled": true}
{"asctime": "2025-10-20 14:19:29,777", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "request_id": "0635621f-2e2a-4b52-8dc4-5652aaef17eb", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-20 14:28:36,797", "levelname": "INFO", "name": "timetracker", "message": "setup.completed", "request_id": "3f7216f5-b11c-4b6b-ac52-e387ef638224", "event": "setup.completed", "telemetry_enabled": true}
{"asctime": "2025-10-20 14:28:40,804", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "request_id": "70a538d8-e7b9-4b18-ac1a-857a87f8f0fa", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-20 14:30:09,546", "levelname": "INFO", "name": "timetracker", "message": "auth.logout", "request_id": "f80073a2-aee6-4928-b9cf-44d6ace690b0", "event": "auth.logout", "user_id": 1}
{"asctime": "2025-10-20 14:34:19,473", "levelname": "INFO", "name": "timetracker", "message": "setup.completed", "request_id": "86ac6b57-806a-45a5-abf1-781ea6b4ca4b", "event": "setup.completed", "telemetry_enabled": true}
{"asctime": "2025-10-20 14:34:22,253", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "request_id": "0dcfc3dd-1efa-4c6d-b403-26c187656674", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-20 20:08:21,420", "levelname": "INFO", "name": "timetracker", "message": "setup.completed", "request_id": "bea1cf53-11ed-4851-bce4-e3528c47d42b", "event": "setup.completed", "telemetry_enabled": false}
{"asctime": "2025-10-20 20:08:23,876", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "request_id": "f0167eaa-0f9d-4c6e-af3b-f35e0cd6f63b", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-20 20:09:56,566", "levelname": "INFO", "name": "timetracker", "message": "setup.completed", "request_id": "7fc7c326-29db-49a7-a80b-0515f427fe3c", "event": "setup.completed", "telemetry_enabled": false}
{"asctime": "2025-10-20 20:09:59,301", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "request_id": "78bf6b25-412f-4bee-8d67-ded5b4fee86a", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-20 20:15:47,262", "levelname": "INFO", "name": "timetracker", "message": "setup.completed", "request_id": "3828246e-f2fa-47cd-84fc-f322da1cc216", "event": "setup.completed", "telemetry_enabled": false}
{"asctime": "2025-10-20 20:15:49,953", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "request_id": "9b9b16ff-5e6c-4cd7-bbde-54162d1a929b", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-20 20:40:12,247", "levelname": "INFO", "name": "timetracker", "message": "setup.completed", "request_id": "13c49d26-2c81-4644-9f2d-f6a117bcea7f", "event": "setup.completed", "telemetry_enabled": false}
{"asctime": "2025-10-20 20:40:19,162", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "request_id": "cdd831f4-40fe-430c-af5e-123affba5069", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-20 20:40:42,782", "levelname": "INFO", "name": "timetracker", "message": "project.created", "request_id": "86e686d1-750c-4599-8009-1ae8284b9576", "event": "project.created", "user_id": 1, "project_id": 8, "project_name": "fezfjsvvjkldfjl", "has_client": true}
{"asctime": "2025-10-20 20:43:44,701", "levelname": "INFO", "name": "timetracker", "message": "setup.completed", "request_id": "17a2f9be-8851-4caf-9129-43643cda15ce", "event": "setup.completed", "telemetry_enabled": true}
{"asctime": "2025-10-20 20:43:50,049", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "request_id": "b2e3a7e8-828a-4aec-8efa-f27d5728f164", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-21 13:09:39,323", "levelname": "INFO", "name": "timetracker", "message": "setup.completed", "request_id": "0e1915f5-507f-4c48-a46c-58e427cae277", "event": "setup.completed", "telemetry_enabled": true}
{"asctime": "2025-10-21 13:09:42,053", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "request_id": "a0ca4577-e58d-4e83-860f-4dc2631ad1a5", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-21 13:17:58,706", "levelname": "INFO", "name": "timetracker", "message": "setup.completed", "request_id": "bf613ab0-889d-412c-9146-4ec376496ee1", "event": "setup.completed", "telemetry_enabled": true}
{"asctime": "2025-10-21 13:18:01,044", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "request_id": "66357edf-7158-4fa3-97c7-258e36e04335", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-21 13:18:33,803", "levelname": "INFO", "name": "timetracker", "message": "task.created", "request_id": "011cfd1d-43c8-4bf1-93c0-225c062180cb", "event": "task.created", "user_id": 1, "task_id": 1, "project_id": 1, "priority": "medium"}
{"asctime": "2025-10-21 16:02:08,457", "levelname": "INFO", "name": "timetracker", "message": "setup.completed", "request_id": "48d537a1-0ed1-452e-bbdc-030e83af940c", "event": "setup.completed", "telemetry_enabled": true}
{"asctime": "2025-10-21 16:02:11,272", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "request_id": "9f445ef0-b6e6-4631-8bc5-c40c5689a501", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-21 16:02:32,456", "levelname": "INFO", "name": "timetracker", "message": "report.viewed", "request_id": "d1de7948-78b1-4b74-b534-e342fe7f7830", "event": "report.viewed", "user_id": 1, "report_type": "summary"}
{"asctime": "2025-10-21 16:02:59,857", "levelname": "INFO", "name": "timetracker", "message": "task.updated", "request_id": "090070f8-6a79-4eaa-bb07-805cdf525ce7", "event": "task.updated", "user_id": 1, "task_id": 1, "project_id": 1}
{"asctime": "2025-10-22 11:20:05,729", "levelname": "INFO", "name": "timetracker", "message": "auth.logout", "taskName": null, "request_id": "423f12e2-cbd5-4322-ac98-8fd0411537c7", "event": "auth.logout", "user_id": 1}
{"asctime": "2025-10-23 20:14:11,146", "levelname": "INFO", "name": "timetracker", "message": "timer.duplicated", "taskName": null, "request_id": "41ca6146-be8b-4f30-8871-c71d5e7f3964", "event": "timer.duplicated", "user_id": 1, "time_entry_id": 1, "project_id": 1, "task_id": 1}
{"asctime": "2025-10-23 20:14:38,417", "levelname": "INFO", "name": "timetracker", "message": "timer.duplicated", "taskName": null, "request_id": "341f2437-0a7d-47be-8d1f-847e43afb795", "event": "timer.duplicated", "user_id": 1, "time_entry_id": 1, "project_id": 1, "task_id": 1}
{"asctime": "2025-10-23 20:14:44,498", "levelname": "INFO", "name": "timetracker", "message": "timer.duplicated", "taskName": null, "request_id": "d5a8050e-8c63-475f-81d4-918b435484c8", "event": "timer.duplicated", "user_id": 1, "time_entry_id": 1, "project_id": 1, "task_id": 1}
{"asctime": "2025-10-23 20:14:47,275", "levelname": "INFO", "name": "timetracker", "message": "timer.duplicated", "taskName": null, "request_id": "f952bc7a-9a24-4dc1-bd99-94ea89620509", "event": "timer.duplicated", "user_id": 1, "time_entry_id": 1, "project_id": 1, "task_id": 1}
{"asctime": "2025-10-23 20:14:50,441", "levelname": "INFO", "name": "timetracker", "message": "timer.duplicated", "taskName": null, "request_id": "a19dcddb-edbb-4eae-a555-5518c9920270", "event": "timer.duplicated", "user_id": 1, "time_entry_id": 1, "project_id": 1, "task_id": 1}
{"asctime": "2025-10-23 20:14:52,833", "levelname": "INFO", "name": "timetracker", "message": "timer.duplicated", "taskName": null, "request_id": "3f067faf-5b6e-4a38-a6ab-4c1c56f4e8ee", "event": "timer.duplicated", "user_id": 1, "time_entry_id": 1, "project_id": 1, "task_id": 1}
{"asctime": "2025-10-23 20:14:55,273", "levelname": "INFO", "name": "timetracker", "message": "timer.duplicated", "taskName": null, "request_id": "1dd13ace-dc08-46e4-ad29-e936ec0dc0c4", "event": "timer.duplicated", "user_id": 1, "time_entry_id": 1, "project_id": 1, "task_id": 1}
{"asctime": "2025-10-23 20:14:57,404", "levelname": "INFO", "name": "timetracker", "message": "timer.duplicated", "taskName": null, "request_id": "843c6026-c8bc-4017-8efd-e3701820e770", "event": "timer.duplicated", "user_id": 1, "time_entry_id": 1, "project_id": 1, "task_id": 1}
{"asctime": "2025-10-23 20:14:59,557", "levelname": "INFO", "name": "timetracker", "message": "timer.duplicated", "taskName": null, "request_id": "f6d9f096-b75c-42b7-ab34-0f304b4fe8e1", "event": "timer.duplicated", "user_id": 1, "time_entry_id": 1, "project_id": 1, "task_id": null}
{"asctime": "2025-10-23 20:15:02,124", "levelname": "INFO", "name": "timetracker", "message": "timer.duplicated", "taskName": null, "request_id": "a3f968ed-22f2-4640-8837-858f4dceee29", "event": "timer.duplicated", "user_id": 1, "time_entry_id": 1, "project_id": 1, "task_id": 1}
{"asctime": "2025-10-23 20:15:31,256", "levelname": "INFO", "name": "timetracker", "message": "timer.duplicated", "taskName": null, "request_id": "f6e15de1-a45b-4410-8a6d-97ba22b6e8ee", "event": "timer.duplicated", "user_id": 1, "time_entry_id": 1, "project_id": 1, "task_id": null}
{"asctime": "2025-10-23 20:15:34,551", "levelname": "INFO", "name": "timetracker", "message": "timer.duplicated", "taskName": null, "request_id": "aa0cc94b-2b44-4f55-b67a-8bfa46a710c3", "event": "timer.duplicated", "user_id": 1, "time_entry_id": 1, "project_id": 1, "task_id": null}
{"asctime": "2025-10-23 20:15:38,205", "levelname": "INFO", "name": "timetracker", "message": "timer.duplicated", "taskName": null, "request_id": "13a0d587-b837-4935-923b-9f67e6e16ad9", "event": "timer.duplicated", "user_id": 1, "time_entry_id": 1, "project_id": 1, "task_id": null}
{"asctime": "2025-10-23 20:16:34,068", "levelname": "INFO", "name": "timetracker", "message": "timer.duplicated", "taskName": null, "request_id": "155b554f-bacb-4d62-ac2a-c855bbb1cd16", "event": "timer.duplicated", "user_id": 1, "time_entry_id": 1, "project_id": 1, "task_id": null}
{"asctime": "2025-10-23 20:17:19,067", "levelname": "INFO", "name": "timetracker", "message": "timer.duplicated", "taskName": null, "request_id": "7524a209-ecd6-46c3-ac78-364e3b0d1200", "event": "timer.duplicated", "user_id": 1, "time_entry_id": 1, "project_id": 1, "task_id": 1}
{"asctime": "2025-10-23 20:17:30,734", "levelname": "INFO", "name": "timetracker", "message": "timer.duplicated", "taskName": null, "request_id": "92b6622a-9a07-452f-bae2-051991c9d5a1", "event": "timer.duplicated", "user_id": 1, "time_entry_id": 1, "project_id": 1, "task_id": 1}
{"asctime": "2025-10-23 20:17:33,519", "levelname": "INFO", "name": "timetracker", "message": "timer.duplicated", "taskName": null, "request_id": "bfc93896-8e26-45c9-90ab-2a2b157ec049", "event": "timer.duplicated", "user_id": 1, "time_entry_id": 1, "project_id": 1, "task_id": 1}
{"asctime": "2025-10-23 20:17:36,372", "levelname": "INFO", "name": "timetracker", "message": "timer.duplicated", "taskName": null, "request_id": "7bcd2cf4-e995-472c-82cf-c05d96fd73d3", "event": "timer.duplicated", "user_id": 1, "time_entry_id": 1, "project_id": 1, "task_id": 1}
{"asctime": "2025-10-23 20:17:38,981", "levelname": "INFO", "name": "timetracker", "message": "timer.duplicated", "taskName": null, "request_id": "3defa21b-a5cb-4c11-9e19-e724072c935e", "event": "timer.duplicated", "user_id": 1, "time_entry_id": 1, "project_id": 1, "task_id": 1}
{"asctime": "2025-10-23 20:17:42,472", "levelname": "INFO", "name": "timetracker", "message": "timer.duplicated", "taskName": null, "request_id": "2ebf2373-995a-4405-b26e-d1920b81ce7b", "event": "timer.duplicated", "user_id": 1, "time_entry_id": 1, "project_id": 1, "task_id": 1}
{"asctime": "2025-10-23 20:17:45,275", "levelname": "INFO", "name": "timetracker", "message": "timer.duplicated", "taskName": null, "request_id": "ecb62be2-d32b-4b97-be86-e756d6983179", "event": "timer.duplicated", "user_id": 1, "time_entry_id": 1, "project_id": 1, "task_id": 1}
{"asctime": "2025-10-23 20:17:47,268", "levelname": "INFO", "name": "timetracker", "message": "timer.duplicated", "taskName": null, "request_id": "7fc96faf-2f9e-4ded-979a-7427fdb3dc12", "event": "timer.duplicated", "user_id": 1, "time_entry_id": 1, "project_id": 1, "task_id": null}
{"asctime": "2025-10-23 20:17:49,790", "levelname": "INFO", "name": "timetracker", "message": "timer.duplicated", "taskName": null, "request_id": "18bae198-0f48-42e9-bca0-175ac06efa00", "event": "timer.duplicated", "user_id": 1, "time_entry_id": 1, "project_id": 1, "task_id": 1}
{"asctime": "2025-10-23 20:17:56,945", "levelname": "INFO", "name": "timetracker", "message": "timer.duplicated", "taskName": null, "request_id": "7e740e81-a356-4222-84fb-6b545efee48f", "event": "timer.duplicated", "user_id": 1, "time_entry_id": 1, "project_id": 1, "task_id": null}
{"asctime": "2025-10-23 20:18:13,808", "levelname": "INFO", "name": "timetracker", "message": "timer.duplicated", "taskName": null, "request_id": "01a0cac0-5466-4e22-8f05-46352eeafb55", "event": "timer.duplicated", "user_id": 1, "time_entry_id": 1, "project_id": 1, "task_id": null}
{"asctime": "2025-10-23 20:18:15,922", "levelname": "INFO", "name": "timetracker", "message": "timer.duplicated", "taskName": null, "request_id": "5762bce5-cb10-4b59-a16d-aa40af773ec5", "event": "timer.duplicated", "user_id": 1, "time_entry_id": 1, "project_id": 1, "task_id": null}
{"asctime": "2025-10-23 20:18:18,704", "levelname": "INFO", "name": "timetracker", "message": "timer.duplicated", "taskName": null, "request_id": "c19ff3aa-1113-4e2c-81ad-72abf5cbc736", "event": "timer.duplicated", "user_id": 1, "time_entry_id": 1, "project_id": 1, "task_id": null}
{"asctime": "2025-10-23 20:43:18,241", "levelname": "INFO", "name": "timetracker", "message": "project.favorited", "taskName": null, "request_id": "d87e4ea4-4219-4edb-99d4-81829e4c157d", "event": "project.favorited", "user_id": 1, "project_id": 1}
{"asctime": "2025-10-23 20:43:20,050", "levelname": "INFO", "name": "timetracker", "message": "project.unfavorited", "taskName": null, "request_id": "8a0369d4-a457-4bee-bbe9-a21ef7f00056", "event": "project.unfavorited", "user_id": 1, "project_id": 1}
{"asctime": "2025-10-23 20:44:25,411", "levelname": "INFO", "name": "timetracker", "message": "project.favorited", "taskName": null, "request_id": "a64b6ad2-badd-4879-bdc7-ae8b0e94fe3d", "event": "project.favorited", "user_id": 1, "project_id": 1}
{"asctime": "2025-10-23 20:44:26,386", "levelname": "INFO", "name": "timetracker", "message": "project.unfavorited", "taskName": null, "request_id": "73d9bd58-61e5-431d-9963-6a57e2b63e61", "event": "project.unfavorited", "user_id": 1, "project_id": 1}
{"asctime": "2025-10-27 15:08:28,401", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "taskName": null, "request_id": "566a134d-117b-43fa-a925-b6a25ae8d9f1", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-27 15:08:29,748", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "taskName": null, "request_id": "e09e20ad-66d8-487c-8fab-69e3f687ac72", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-27 15:08:32,269", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "taskName": null, "request_id": "1db2a23c-c59a-40a1-af9f-f2e69bdfc31e", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-27 15:08:34,725", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "taskName": null, "request_id": "1f8f31b2-2684-4268-a14e-973c7ef03fd2", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-27 15:08:36,149", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "taskName": null, "request_id": "cd7595eb-7d01-4373-aae8-14a9a7c00c4f", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-27 15:08:37,568", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "taskName": null, "request_id": "7f8df4b5-d127-403d-b63e-abaad630c06c", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-27 15:08:39,004", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "taskName": null, "request_id": "50e3a7d8-6db9-4767-9b67-fe68e8eb7c8b", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-27 15:08:40,402", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "taskName": null, "request_id": "78030e9f-cf8d-49e5-9cf8-2dc494fc5656", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-27 15:08:41,824", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "taskName": null, "request_id": "edb7c4a1-a37c-4511-9b61-a8042b938313", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-27 15:08:42,987", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "taskName": null, "request_id": "f4332d2c-b2d1-44cb-b94e-6db75b391c27", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-27 15:08:44,079", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "taskName": null, "request_id": "9f9363eb-1cf9-49f5-bcc6-5515530dd02b", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-27 15:08:45,257", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "taskName": null, "request_id": "320d0cec-8db8-40fd-ad14-24fd29ceb85f", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-27 15:08:46,337", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "taskName": null, "request_id": "8f4c4b8b-fd9c-44b0-95da-22c3ff2764bd", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-27 15:08:47,703", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "taskName": null, "request_id": "052de3e0-c98c-4c31-aee2-e7114a24a4d2", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-27 15:08:48,763", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "taskName": null, "request_id": "5107623c-ea3d-4461-b5e3-8dd9c6053778", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-27 15:08:49,950", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "taskName": null, "request_id": "10b6b5bf-d27a-4fcb-8ae8-5b66c6eb237a", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-27 15:08:56,665", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "taskName": null, "request_id": "bb84b1ee-60a1-4040-9977-c0b24759b2cf", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-27 15:08:57,821", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "taskName": null, "request_id": "bb244600-1eb2-4538-ac1c-4dc4e0ce444c", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-27 15:08:58,965", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "taskName": null, "request_id": "83bda093-6e6c-4744-8c90-5fb7ea3f9c84", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-27 15:09:02,194", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "taskName": null, "request_id": "fca17491-6c73-40c8-b36b-e02b48934493", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-27 15:09:03,259", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "taskName": null, "request_id": "253718af-c020-476a-a41f-0b4b93011644", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-27 15:09:05,332", "levelname": "INFO", "name": "timetracker", "message": "auth.login", "taskName": null, "request_id": "507e45da-62b4-49c2-8430-ce293ccb61f3", "event": "auth.login", "user_id": 1, "auth_method": "local"}
{"asctime": "2025-10-29 08:54:54,842", "levelname": "INFO", "name": "timetracker", "message": "project.favorited", "taskName": null, "request_id": "df528552-5d52-4840-a3f1-b7b0856461b9", "event": "project.favorited", "user_id": 1, "project_id": 1}
{"asctime": "2025-10-29 08:54:55,974", "levelname": "INFO", "name": "timetracker", "message": "project.unfavorited", "taskName": null, "request_id": "41bbaefb-287f-4bf0-9e38-01da740cf548", "event": "project.unfavorited", "user_id": 1, "project_id": 1}
{"asctime": "2025-10-29 08:55:37,589", "levelname": "INFO", "name": "timetracker", "message": "project.archived", "taskName": null, "request_id": "bb66bbbc-bc45-4154-a1ad-b632fc04494c", "event": "project.archived", "user_id": 1, "project_id": 1, "reason": "Project completed successfully"}
{"asctime": "2025-10-29 08:55:39,880", "levelname": "INFO", "name": "timetracker", "message": "project.archived", "taskName": null, "request_id": "84cb06e3-e26f-40b5-942c-cfe35cb73fca", "event": "project.archived", "user_id": 1, "project_id": 1, "reason": null}
{"asctime": "2025-10-29 08:55:41,442", "levelname": "INFO", "name": "timetracker", "message": "project.unarchived", "taskName": null, "request_id": "68c1b2bf-b7f0-4554-9bd4-f8a60396c687", "event": "project.unarchived", "user_id": 1, "project_id": 1}
{"asctime": "2025-10-29 08:55:43,167", "levelname": "INFO", "name": "timetracker", "message": "project.status_changed_archived", "taskName": null, "request_id": "8336746f-195c-4f18-a128-6e4a0b548695", "event": "project.status_changed_archived", "user_id": 1, "project_id": 1}
{"asctime": "2025-10-29 08:55:43,173", "levelname": "INFO", "name": "timetracker", "message": "project.status_changed_archived", "taskName": null, "request_id": "8336746f-195c-4f18-a128-6e4a0b548695", "event": "project.status_changed_archived", "user_id": 1, "project_id": 2}
{"asctime": "2025-10-29 08:55:52,925", "levelname": "INFO", "name": "timetracker", "message": "project.archived", "taskName": null, "request_id": "65a474e8-6415-48f4-a7c3-c0492cfee88a", "event": "project.archived", "user_id": 1, "project_id": 1, "reason": "Project completed"}
{"asctime": "2025-10-29 08:55:54,112", "levelname": "INFO", "name": "timetracker", "message": "project.unarchived", "taskName": null, "request_id": "89b64b10-55c3-4e01-adfe-af96c1419fc6", "event": "project.unarchived", "user_id": 1, "project_id": 1}
{"asctime": "2025-10-29 08:55:59,266", "levelname": "INFO", "name": "timetracker", "message": "project.archived", "taskName": null, "request_id": "98b2916b-c41e-4412-be72-0e6ced617314", "event": "project.archived", "user_id": 1, "project_id": 1, "reason": "Complete smoke test"}
{"asctime": "2025-10-29 08:55:59,351", "levelname": "INFO", "name": "timetracker", "message": "project.unarchived", "taskName": null, "request_id": "2beada5f-3fa1-4fef-ab8e-27b45f02384a", "event": "project.unarchived", "user_id": 1, "project_id": 1}
{"asctime": "2025-10-29 08:57:06,857", "levelname": "INFO", "name": "timetracker", "message": "project.deactivated", "taskName": null, "request_id": "37e8671d-3392-4989-aabd-8f3470e0e832", "event": "project.deactivated", "user_id": 1, "project_id": 1}
{"asctime": "2025-10-29 08:57:07,928", "levelname": "INFO", "name": "timetracker", "message": "project.activated", "taskName": null, "request_id": "14a50afd-54b7-419c-8cf1-c12ad3a1be16", "event": "project.activated", "user_id": 1, "project_id": 1}
{"asctime": "2025-10-29 08:57:21,949", "levelname": "INFO", "name": "timetracker", "message": "task.updated", "taskName": null, "request_id": "b91eb6e3-4229-4e57-a38c-a50a0d8d4fc8", "event": "task.updated", "user_id": 1, "task_id": 1, "project_id": 2}
{"asctime": "2025-10-29 08:57:25,166", "levelname": "INFO", "name": "timetracker", "message": "timer.duplicated", "taskName": null, "request_id": "bb3a4bdf-773c-4a92-85bb-fd93b838e50c", "event": "timer.duplicated", "user_id": 1, "time_entry_id": 1, "project_id": 1, "task_id": 1}
{"asctime": "2025-10-29 08:57:26,120", "levelname": "INFO", "name": "timetracker", "message": "timer.duplicated", "taskName": null, "request_id": "e1f0e4ad-5de0-40cc-9630-20fc944ed3b7", "event": "timer.duplicated", "user_id": 1, "time_entry_id": 1, "project_id": 1, "task_id": null}
{"asctime": "2025-10-30 09:33:51,285", "levelname": "INFO", "name": "timetracker", "message": "task.deleted", "taskName": null, "request_id": "984166af-7388-44a3-93a4-c8c18d8daad5", "event": "task.deleted", "user_id": 1, "task_id": 1, "project_id": 1}
{"asctime": "2025-10-30 09:33:51,306", "levelname": "INFO", "name": "timetracker", "message": "task.deleted", "taskName": null, "request_id": "984166af-7388-44a3-93a4-c8c18d8daad5", "event": "task.deleted", "user_id": 1, "task_id": 2, "project_id": 1}
{"asctime": "2025-10-30 09:33:51,317", "levelname": "INFO", "name": "timetracker", "message": "task.deleted", "taskName": null, "request_id": "984166af-7388-44a3-93a4-c8c18d8daad5", "event": "task.deleted", "user_id": 1, "task_id": 3, "project_id": 1}
{"asctime": "2025-10-30 09:34:44,871", "levelname": "INFO", "name": "timetracker", "message": "task.deleted", "taskName": null, "request_id": "48672a3c-55a2-4875-a6f1-4d465bfc9a33", "event": "task.deleted", "user_id": 1, "task_id": 1, "project_id": 1}
{"asctime": "2025-10-30 09:34:44,892", "levelname": "INFO", "name": "timetracker", "message": "task.deleted", "taskName": null, "request_id": "48672a3c-55a2-4875-a6f1-4d465bfc9a33", "event": "task.deleted", "user_id": 1, "task_id": 2, "project_id": 1}
{"asctime": "2025-10-30 09:34:44,892", "levelname": "INFO", "name": "timetracker", "message": "task.deleted", "taskName": null, "request_id": "48672a3c-55a2-4875-a6f1-4d465bfc9a33", "event": "task.deleted", "user_id": 1, "task_id": 3, "project_id": 1}
{"asctime": "2025-10-30 09:43:59,793", "levelname": "INFO", "name": "timetracker", "message": "task.deleted", "taskName": null, "request_id": "f6bf169b-cc3b-497d-acaa-334ff0c15cee", "event": "task.deleted", "user_id": 1, "task_id": 1, "project_id": 1}
{"asctime": "2025-10-30 09:43:59,817", "levelname": "INFO", "name": "timetracker", "message": "task.deleted", "taskName": null, "request_id": "f6bf169b-cc3b-497d-acaa-334ff0c15cee", "event": "task.deleted", "user_id": 1, "task_id": 2, "project_id": 1}
{"asctime": "2025-10-30 09:43:59,821", "levelname": "INFO", "name": "timetracker", "message": "task.deleted", "taskName": null, "request_id": "f6bf169b-cc3b-497d-acaa-334ff0c15cee", "event": "task.deleted", "user_id": 1, "task_id": 3, "project_id": 1}
{"asctime": "2025-10-30 09:45:46,439", "levelname": "INFO", "name": "timetracker", "message": "task.deleted", "taskName": null, "request_id": "87a0ad0f-3147-49be-850a-048e28fe9887", "event": "task.deleted", "user_id": 1, "task_id": 1, "project_id": 1}
{"asctime": "2025-10-30 09:45:46,455", "levelname": "INFO", "name": "timetracker", "message": "task.deleted", "taskName": null, "request_id": "87a0ad0f-3147-49be-850a-048e28fe9887", "event": "task.deleted", "user_id": 1, "task_id": 2, "project_id": 1}
{"asctime": "2025-10-30 09:45:46,461", "levelname": "INFO", "name": "timetracker", "message": "task.deleted", "taskName": null, "request_id": "87a0ad0f-3147-49be-850a-048e28fe9887", "event": "task.deleted", "user_id": 1, "task_id": 3, "project_id": 1}