Files
tutti/packages/agent/store-sqlite/migrations_entity_invariants.go
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

84 lines
4.6 KiB
Go

package storesqlite
import (
"context"
"fmt"
)
func (s *Store) applyWorkspaceAgentEntityInvariantsV1(ctx context.Context) error {
applied, err := s.hasMigration(ctx, schemaMigrationWorkspaceAgentEntityInvariantsV1)
if err != nil || applied {
return err
}
tx, err := s.db.BeginTx(ctx, nil)
if err != nil {
return fmt.Errorf("begin workspace agent entity invariants v1: %w", err)
}
defer func() { _ = tx.Rollback() }()
if _, err := tx.ExecContext(ctx, `
CREATE TRIGGER workspace_agent_sessions_validate_insert
BEFORE INSERT ON workspace_agent_sessions BEGIN
SELECT CASE WHEN length(trim(NEW.workspace_id)) = 0 OR length(trim(NEW.agent_session_id)) = 0
OR NOT json_valid(NEW.settings_json) OR json_type(NEW.settings_json) != 'object'
OR NEW.message_version < 0 OR NEW.last_event_at_unix_ms < 0 OR NEW.started_at_unix_ms < 0
OR NEW.ended_at_unix_ms < 0 OR NEW.pinned_at_unix_ms < 0 OR NEW.deleted_at_unix_ms < 0
OR NEW.created_at_unix_ms < 0 OR NEW.updated_at_unix_ms < 0
THEN RAISE(ABORT, 'invalid workspace agent session entity') END;
END;
CREATE TRIGGER workspace_agent_sessions_validate_update
BEFORE UPDATE ON workspace_agent_sessions BEGIN
SELECT CASE WHEN length(trim(NEW.workspace_id)) = 0 OR length(trim(NEW.agent_session_id)) = 0
OR NOT json_valid(NEW.settings_json) OR json_type(NEW.settings_json) != 'object'
OR NEW.message_version < 0 OR NEW.last_event_at_unix_ms < 0 OR NEW.started_at_unix_ms < 0
OR NEW.ended_at_unix_ms < 0 OR NEW.pinned_at_unix_ms < 0 OR NEW.deleted_at_unix_ms < 0
OR NEW.created_at_unix_ms < 0 OR NEW.updated_at_unix_ms < 0
THEN RAISE(ABORT, 'invalid workspace agent session entity') END;
END;
CREATE TRIGGER workspace_agent_turns_validate_insert
BEFORE INSERT ON workspace_agent_turns BEGIN
SELECT CASE WHEN length(trim(NEW.workspace_id)) = 0 OR length(trim(NEW.agent_session_id)) = 0 OR length(trim(NEW.turn_id)) = 0
OR NEW.started_at_unix_ms < 0 OR NEW.created_at_unix_ms < 0 OR NEW.updated_at_unix_ms < 0
OR (NEW.settled_at_unix_ms IS NOT NULL AND NEW.settled_at_unix_ms < 0)
OR (NEW.error_json IS NOT NULL AND NOT json_valid(NEW.error_json))
OR (NEW.file_changes_json IS NOT NULL AND NOT json_valid(NEW.file_changes_json))
OR (NEW.completed_command_json IS NOT NULL AND NOT json_valid(NEW.completed_command_json))
OR (NEW.phase = 'settled' AND (NEW.outcome IS NULL OR NEW.settled_at_unix_ms IS NULL))
OR (NEW.phase != 'settled' AND (NEW.outcome IS NOT NULL OR NEW.settled_at_unix_ms IS NOT NULL))
THEN RAISE(ABORT, 'invalid workspace agent turn entity') END;
END;
CREATE TRIGGER workspace_agent_turns_validate_update
BEFORE UPDATE ON workspace_agent_turns BEGIN
SELECT CASE WHEN NEW.started_at_unix_ms < 0 OR NEW.created_at_unix_ms < 0 OR NEW.updated_at_unix_ms < 0
OR (NEW.settled_at_unix_ms IS NOT NULL AND NEW.settled_at_unix_ms < 0)
OR (NEW.error_json IS NOT NULL AND NOT json_valid(NEW.error_json))
OR (NEW.file_changes_json IS NOT NULL AND NOT json_valid(NEW.file_changes_json))
OR (NEW.completed_command_json IS NOT NULL AND NOT json_valid(NEW.completed_command_json))
OR (NEW.phase = 'settled' AND (NEW.outcome IS NULL OR NEW.settled_at_unix_ms IS NULL))
OR (NEW.phase != 'settled' AND (NEW.outcome IS NOT NULL OR NEW.settled_at_unix_ms IS NOT NULL))
THEN RAISE(ABORT, 'invalid workspace agent turn entity') END;
END;
CREATE TRIGGER workspace_agent_interactions_validate_insert
BEFORE INSERT ON workspace_agent_interactions BEGIN
SELECT CASE WHEN NOT json_valid(NEW.input_json) OR json_type(NEW.input_json) != 'object'
OR NOT json_valid(NEW.output_json) OR json_type(NEW.output_json) != 'object'
OR NOT json_valid(NEW.metadata_json) OR json_type(NEW.metadata_json) != 'object'
OR NEW.created_at_unix_ms < 0 OR NEW.updated_at_unix_ms < NEW.created_at_unix_ms
THEN RAISE(ABORT, 'invalid workspace agent interaction entity') END;
END;
CREATE TRIGGER workspace_agent_interactions_validate_update
BEFORE UPDATE ON workspace_agent_interactions BEGIN
SELECT CASE WHEN NOT json_valid(NEW.input_json) OR json_type(NEW.input_json) != 'object'
OR NOT json_valid(NEW.output_json) OR json_type(NEW.output_json) != 'object'
OR NOT json_valid(NEW.metadata_json) OR json_type(NEW.metadata_json) != 'object'
OR NEW.created_at_unix_ms < 0 OR NEW.updated_at_unix_ms < NEW.created_at_unix_ms
THEN RAISE(ABORT, 'invalid workspace agent interaction entity') END;
END;
`); err != nil {
return fmt.Errorf("migrate workspace agent entity invariants v1: %w", err)
}
if err := recordMigrationTx(ctx, tx, schemaMigrationWorkspaceAgentEntityInvariantsV1); err != nil {
return err
}
return tx.Commit()
}