feat(phase-36): automatic Tempo time tracking via workflow buttons + fix campaign test management

- Add red_started_at/blue_started_at timing fields to Test model with Alembic migration

- Modify workflow transitions to auto-create integrity-hashed worklogs: Start Execution records red_started_at, Submit to Blue Team stops Red timer and creates worklog then starts Blue timer, Submit for Review stops Blue timer and creates worklog

- Auto-sync worklogs to Tempo when test has a Jira link

- Add LiveTimer component showing real-time elapsed counter during active phases

- Clear timing fields on test reopen

- Fix campaign test management: replace broken navigate-to-tests flow with AddTestToCampaignModal that lets users search and add existing tests directly from the campaign detail page
This commit is contained in:
2026-02-17 16:59:19 +01:00
parent 005a09b42f
commit febf460580
10 changed files with 461 additions and 5 deletions

View File

@@ -89,8 +89,26 @@ def auto_log_test_worklog(
def _calculate_duration(test, activity_type: str) -> int:
"""Estimate duration in seconds based on test timestamps and activity type."""
"""Calculate real duration in seconds from the phase timing fields.
Uses the actual start/end timestamps recorded by the workflow buttons,
so the data cannot be falsified.
"""
from datetime import datetime
now = datetime.utcnow()
if activity_type == "red_team_execution" and test.red_started_at:
delta = now - test.red_started_at
return max(int(delta.total_seconds()), 1)
if activity_type == "blue_team_evaluation" and test.blue_started_at:
delta = now - test.blue_started_at
return max(int(delta.total_seconds()), 1)
# Fallback for legacy activity types
if activity_type == "execution" and test.execution_date and test.created_at:
delta = test.execution_date - test.created_at
return max(int(delta.total_seconds()), 0)
return 3600 # default 1 hour if no timestamps available
return 0