refactor(robot): streamline execution insertion logic in tests

- Replaced direct database insertion with a structured approach using ExecutionStore for better maintainability.
- Updated time parsing logic to handle both timezone-aware and local time formats, improving robustness.
- Enhanced the insertWatcherExec function to utilize the new execution record structure, ensuring consistency in execution data handling.
This commit is contained in:
Max 2026-03-23 18:42:57 +08:00
parent ce19e9bdb7
commit c5bc1fe1c0
2 changed files with 32 additions and 25 deletions

View file

@ -920,18 +920,18 @@ func (s *ExecutionStore) parseTime(v interface{}) *time.Time {
case *time.Time: case *time.Time:
return t return t
case string: case string:
// Try parsing common time formats // Formats that include timezone info — use time.Parse (respects embedded tz)
formats := []string{ for _, format := range []string{time.RFC3339, time.RFC3339Nano} {
time.RFC3339,
time.RFC3339Nano,
"2006-01-02 15:04:05",
"2006-01-02T15:04:05Z",
}
for _, format := range formats {
if parsed, err := time.Parse(format, t); err == nil { if parsed, err := time.Parse(format, t); err == nil {
return &parsed return &parsed
} }
} }
// Formats without timezone — treat as local time
for _, format := range []string{"2006-01-02 15:04:05", "2006-01-02T15:04:05Z"} {
if parsed, err := time.ParseInLocation(format, t, time.Local); err == nil {
return &parsed
}
}
} }
return nil return nil
} }

View file

@ -11,6 +11,8 @@ import (
"github.com/yaoapp/xun/capsule" "github.com/yaoapp/xun/capsule"
"github.com/yaoapp/yao/agent/robot/api" "github.com/yaoapp/yao/agent/robot/api"
"github.com/yaoapp/yao/agent/robot/manager" "github.com/yaoapp/yao/agent/robot/manager"
"github.com/yaoapp/yao/agent/robot/store"
"github.com/yaoapp/yao/agent/robot/types"
"github.com/yaoapp/yao/agent/testutils" "github.com/yaoapp/yao/agent/testutils"
"github.com/yaoapp/yao/monitor" "github.com/yaoapp/yao/monitor"
@ -213,27 +215,32 @@ func findWatcher(t *testing.T, name string) monitor.Watcher {
func insertWatcherExec(t *testing.T, execID, memberID, teamID, status string, startTime *time.Time, updatedAt *time.Time) { func insertWatcherExec(t *testing.T, execID, memberID, teamID, status string, startTime *time.Time, updatedAt *time.Time) {
t.Helper() t.Helper()
mod := model.Select("__yao.agent.execution") ctx := context.Background()
tableName := mod.MetaData.Table.Name execStore := store.NewExecutionStore()
qb := capsule.Query()
data := map[string]interface{}{ record := &store.ExecutionRecord{
"execution_id": execID, ExecutionID: execID,
"member_id": memberID, MemberID: memberID,
"team_id": teamID, TeamID: teamID,
"trigger_type": "clock", TriggerType: types.TriggerClock,
"status": status, Status: types.ExecStatus(status),
"phase": "run", Phase: types.PhaseRun,
} StartTime: startTime,
if startTime != nil {
data["start_time"] = *startTime
}
if updatedAt != nil {
data["updated_at"] = *updatedAt
} }
err := qb.Table(tableName).Insert([]map[string]interface{}{data}) err := execStore.Save(ctx, record)
require.NoError(t, err, "insert execution %s", execID) require.NoError(t, err, "insert execution %s", execID)
if updatedAt != nil {
mod := model.Select("__yao.agent.execution")
require.NotNil(t, mod)
tableName := mod.MetaData.Table.Name
qb := capsule.Query()
_, err := qb.Table(tableName).
Where("execution_id", execID).
Update(map[string]interface{}{"updated_at": updatedAt.Format("2006-01-02 15:04:05")})
require.NoError(t, err, "update updated_at for %s", execID)
}
} }
func insertWatcherRobot(t *testing.T, memberID, teamID string) { func insertWatcherRobot(t *testing.T, memberID, teamID string) {