refactor(workflow): delegate start_execution to TestEntity
Replace manual state+field mutation with entity.start_execution() and apply_to(), keeping audit logging and notifications at the service layer.
This commit is contained in:
@@ -111,15 +111,33 @@ def start_execution(db: Session, test: Test, user: User) -> Test:
|
|||||||
"""Move from ``draft`` → ``red_executing``.
|
"""Move from ``draft`` → ``red_executing``.
|
||||||
|
|
||||||
Typically called by a **red_tech** when they begin the attack.
|
Typically called by a **red_tech** when they begin the attack.
|
||||||
Starts the Red Team timer by recording ``red_started_at``.
|
Delegates to :meth:`TestEntity.start_execution` which handles the
|
||||||
|
state transition and sets ``execution_date`` / ``red_started_at``.
|
||||||
"""
|
"""
|
||||||
now = datetime.utcnow()
|
entity = TestEntity.from_orm(test)
|
||||||
test = transition_state(
|
entity.start_execution()
|
||||||
db, test, TestState.red_executing, user,
|
entity.apply_to(test)
|
||||||
action_name="start_execution",
|
db.flush()
|
||||||
|
|
||||||
|
log_action(
|
||||||
|
db,
|
||||||
|
user_id=user.id,
|
||||||
|
action="start_execution",
|
||||||
|
entity_type="test",
|
||||||
|
entity_id=test.id,
|
||||||
|
details={
|
||||||
|
"previous_state": "draft",
|
||||||
|
"new_state": test.state.value,
|
||||||
|
"test_name": test.name,
|
||||||
|
"technique_id": str(test.technique_id),
|
||||||
|
},
|
||||||
)
|
)
|
||||||
test.execution_date = now
|
|
||||||
test.red_started_at = now
|
try:
|
||||||
|
notify_test_state_change(db, test, test.state.value)
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning("Notification failed for test %s: %s", test.id, e, exc_info=True)
|
||||||
|
|
||||||
return test
|
return test
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user