diff --git a/coderd/database/dbauthz/dbauthz.go b/coderd/database/dbauthz/dbauthz.go
index 14f7f33c7e4e6..4b281f074c8b6 100644
--- a/coderd/database/dbauthz/dbauthz.go
+++ b/coderd/database/dbauthz/dbauthz.go
@@ -8335,7 +8335,7 @@ func (q *querier) UpdateTemplateVersionExternalAuthProvidersByJobID(ctx context.
}
func (q *querier) UpdateTemplateVersionFlagsByJobID(ctx context.Context, arg database.UpdateTemplateVersionFlagsByJobIDParams) error {
- // An actor is allowed to update the template version ai task and external agent flag if they are authorized to update the template.
+ // An actor is allowed to update the template version external agent flag if they are authorized to update the template.
tv, err := q.db.GetTemplateVersionByJobID(ctx, arg.JobID)
if err != nil {
return err
diff --git a/coderd/database/dbauthz/dbauthz_test.go b/coderd/database/dbauthz/dbauthz_test.go
index 3cd7b3a3faa9e..9f87cfec00850 100644
--- a/coderd/database/dbauthz/dbauthz_test.go
+++ b/coderd/database/dbauthz/dbauthz_test.go
@@ -2906,7 +2906,7 @@ func (s *MethodTestSuite) TestTemplate() {
s.Run("UpdateTemplateVersionFlagsByJobID", s.Mocked(func(dbm *dbmock.MockStore, faker *gofakeit.Faker, check *expects) {
t := testutil.Fake(s.T(), faker, database.Template{})
tv := testutil.Fake(s.T(), faker, database.TemplateVersion{TemplateID: uuid.NullUUID{UUID: t.ID, Valid: true}})
- arg := database.UpdateTemplateVersionFlagsByJobIDParams{JobID: tv.JobID, HasAITask: sql.NullBool{Bool: true, Valid: true}, HasExternalAgent: sql.NullBool{Bool: true, Valid: true}}
+ arg := database.UpdateTemplateVersionFlagsByJobIDParams{JobID: tv.JobID, HasExternalAgent: sql.NullBool{Bool: true, Valid: true}}
dbm.EXPECT().GetTemplateVersionByJobID(gomock.Any(), tv.JobID).Return(tv, nil).AnyTimes()
dbm.EXPECT().GetTemplateByID(gomock.Any(), t.ID).Return(t, nil).AnyTimes()
dbm.EXPECT().UpdateTemplateVersionFlagsByJobID(gomock.Any(), arg).Return(nil).AnyTimes()
@@ -4453,7 +4453,6 @@ func (s *MethodTestSuite) TestWorkspace() {
dbm.EXPECT().UpdateWorkspaceBuildFlagsByID(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
check.Args(database.UpdateWorkspaceBuildFlagsByIDParams{
ID: b.ID,
- HasAITask: sql.NullBool{Bool: true, Valid: true},
HasExternalAgent: sql.NullBool{Bool: true, Valid: true},
UpdatedAt: b.UpdatedAt,
}).Asserts(w, policy.ActionUpdate)
diff --git a/coderd/database/dbfake/dbfake.go b/coderd/database/dbfake/dbfake.go
index d2d0834df662c..1bcd25408a35a 100644
--- a/coderd/database/dbfake/dbfake.go
+++ b/coderd/database/dbfake/dbfake.go
@@ -297,13 +297,6 @@ func (b WorkspaceBuildBuilder) doInTX() WorkspaceResponse {
b.seed.ID = uuid.New()
b.seed.JobID = jobID
- if b.taskAppID != uuid.Nil {
- b.seed.HasAITask = sql.NullBool{
- Bool: true,
- Valid: true,
- }
- }
-
resp := WorkspaceResponse{
AgentToken: b.agentToken,
Agents: make([]database.WorkspaceAgent, 0),
diff --git a/coderd/database/dbgen/dbgen.go b/coderd/database/dbgen/dbgen.go
index ad67930ddfec0..b6a8f82867ce5 100644
--- a/coderd/database/dbgen/dbgen.go
+++ b/coderd/database/dbgen/dbgen.go
@@ -936,7 +936,6 @@ func WorkspaceBuild(t testing.TB, db database.Store, orig database.WorkspaceBuil
buildID := takeFirst(orig.ID, uuid.New())
jobID := takeFirst(orig.JobID, uuid.New())
- hasAITask := takeFirst(orig.HasAITask, sql.NullBool{})
hasExternalAgent := takeFirst(orig.HasExternalAgent, sql.NullBool{})
var build database.WorkspaceBuild
err := db.InTx(func(db database.Store) error {
@@ -971,10 +970,9 @@ func WorkspaceBuild(t testing.TB, db database.Store, orig database.WorkspaceBuil
require.NoError(t, err)
}
- if hasAITask.Valid || hasExternalAgent.Valid {
+ if hasExternalAgent.Valid {
require.NoError(t, db.UpdateWorkspaceBuildFlagsByID(genCtx, database.UpdateWorkspaceBuildFlagsByIDParams{
ID: buildID,
- HasAITask: hasAITask,
HasExternalAgent: hasExternalAgent,
UpdatedAt: dbtime.Now(),
}))
@@ -1592,7 +1590,6 @@ func ExternalAuthLink(t testing.TB, db database.Store, orig database.ExternalAut
func TemplateVersion(t testing.TB, db database.Store, orig database.TemplateVersion) database.TemplateVersion {
var version database.TemplateVersion
- hasAITask := takeFirst(orig.HasAITask, sql.NullBool{})
hasExternalAgent := takeFirst(orig.HasExternalAgent, sql.NullBool{})
jobID := takeFirst(orig.JobID, uuid.New())
err := db.InTx(func(db database.Store) error {
@@ -1614,10 +1611,9 @@ func TemplateVersion(t testing.TB, db database.Store, orig database.TemplateVers
return err
}
- if hasAITask.Valid || hasExternalAgent.Valid {
+ if hasExternalAgent.Valid {
require.NoError(t, db.UpdateTemplateVersionFlagsByJobID(genCtx, database.UpdateTemplateVersionFlagsByJobIDParams{
JobID: jobID,
- HasAITask: hasAITask,
HasExternalAgent: hasExternalAgent,
UpdatedAt: dbtime.Now(),
}))
diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql
index abbfda38e5c9b..d33a18ef14b3f 100644
--- a/coderd/database/dump.sql
+++ b/coderd/database/dump.sql
@@ -334,10 +334,7 @@ CREATE TYPE build_reason AS ENUM (
'cli',
'ssh_connection',
'vscode_connection',
- 'jetbrains_connection',
- 'task_auto_pause',
- 'task_manual_pause',
- 'task_resume'
+ 'jetbrains_connection'
);
CREATE TYPE chat_client_type AS ENUM (
@@ -3189,7 +3186,6 @@ CREATE TABLE workspace_builds (
daily_cost integer DEFAULT 0 NOT NULL,
max_deadline timestamp with time zone DEFAULT '0001-01-01 00:00:00+00'::timestamp with time zone NOT NULL,
template_version_preset_id uuid,
- has_ai_task boolean,
has_external_agent boolean,
notified_autostop_deadline timestamp with time zone DEFAULT '0001-01-01 00:00:00+00'::timestamp with time zone NOT NULL,
CONSTRAINT workspace_builds_deadline_below_max_deadline CHECK ((((deadline <> '0001-01-01 00:00:00+00'::timestamp with time zone) AND (deadline <= max_deadline)) OR (max_deadline = '0001-01-01 00:00:00+00'::timestamp with time zone)))
@@ -3500,7 +3496,6 @@ CREATE TABLE template_versions (
message character varying(1048576) DEFAULT ''::character varying NOT NULL,
archived boolean DEFAULT false NOT NULL,
source_example_id text,
- has_ai_task boolean,
has_external_agent boolean
);
@@ -3522,7 +3517,6 @@ CREATE VIEW template_version_with_user AS
template_versions.message,
template_versions.archived,
template_versions.source_example_id,
- template_versions.has_ai_task,
template_versions.has_external_agent,
COALESCE(visible_users.avatar_url, ''::text) AS created_by_avatar_url,
COALESCE(visible_users.username, ''::text) AS created_by_username,
@@ -4132,7 +4126,6 @@ CREATE VIEW workspace_build_with_user AS
workspace_builds.daily_cost,
workspace_builds.max_deadline,
workspace_builds.template_version_preset_id,
- workspace_builds.has_ai_task,
workspace_builds.has_external_agent,
workspace_builds.notified_autostop_deadline,
COALESCE(visible_users.avatar_url, ''::text) AS initiator_by_avatar_url,
@@ -5019,8 +5012,6 @@ CREATE INDEX idx_telemetry_locks_period_ending_at ON telemetry_locks USING btree
CREATE UNIQUE INDEX idx_template_version_presets_default ON template_version_presets USING btree (template_version_id) WHERE (is_default = true);
-CREATE INDEX idx_template_versions_has_ai_task ON template_versions USING btree (has_ai_task);
-
CREATE UNIQUE INDEX idx_unique_preset_name ON template_version_presets USING btree (name, template_version_id);
CREATE UNIQUE INDEX idx_usage_events_agent_runtime ON usage_events USING btree (event_type, created_at) WHERE (event_type = 'hb_agent_runtime_v1'::text);
diff --git a/coderd/database/migrations/000593_remove_has_ai_task_and_task_build_reasons.down.sql b/coderd/database/migrations/000593_remove_has_ai_task_and_task_build_reasons.down.sql
new file mode 100644
index 0000000000000..d633f79969934
--- /dev/null
+++ b/coderd/database/migrations/000593_remove_has_ai_task_and_task_build_reasons.down.sql
@@ -0,0 +1,91 @@
+-- Drop views before modifying underlying tables and columns.
+DROP VIEW IF EXISTS template_version_with_user;
+DROP VIEW IF EXISTS workspace_build_with_user;
+
+-- Recreate has_ai_task columns and index. The dropped values are not
+-- recoverable, so backfill false to satisfy older migrations that restore
+-- NOT NULL on the way further down.
+ALTER TABLE template_versions ADD COLUMN has_ai_task boolean DEFAULT false;
+ALTER TABLE template_versions ALTER COLUMN has_ai_task DROP DEFAULT;
+CREATE INDEX idx_template_versions_has_ai_task ON template_versions USING btree (has_ai_task);
+ALTER TABLE workspace_builds ADD COLUMN has_ai_task boolean DEFAULT false;
+ALTER TABLE workspace_builds ALTER COLUMN has_ai_task DROP DEFAULT;
+
+-- Recreate build_reason enum with task values.
+ALTER TYPE build_reason RENAME TO build_reason_old;
+
+CREATE TYPE build_reason AS ENUM (
+ 'initiator',
+ 'autostart',
+ 'autostop',
+ 'dormancy',
+ 'failedstop',
+ 'autodelete',
+ 'dashboard',
+ 'cli',
+ 'ssh_connection',
+ 'vscode_connection',
+ 'jetbrains_connection',
+ 'task_auto_pause',
+ 'task_manual_pause',
+ 'task_resume'
+);
+
+ALTER TABLE workspace_builds ALTER COLUMN reason DROP DEFAULT;
+ALTER TABLE workspace_builds ALTER COLUMN reason TYPE build_reason USING (reason::text::build_reason);
+ALTER TABLE workspace_builds ALTER COLUMN reason SET DEFAULT 'initiator'::build_reason;
+
+ALTER TABLE workspace_build_orchestrations ALTER COLUMN child_reason TYPE build_reason USING (child_reason::text::build_reason);
+
+DROP TYPE build_reason_old;
+
+-- Recreate views.
+CREATE VIEW template_version_with_user AS
+ SELECT template_versions.id,
+ template_versions.template_id,
+ template_versions.organization_id,
+ template_versions.created_at,
+ template_versions.updated_at,
+ template_versions.name,
+ template_versions.readme,
+ template_versions.job_id,
+ template_versions.created_by,
+ template_versions.external_auth_providers,
+ template_versions.message,
+ template_versions.archived,
+ template_versions.source_example_id,
+ template_versions.has_ai_task,
+ template_versions.has_external_agent,
+ COALESCE(visible_users.avatar_url, ''::text) AS created_by_avatar_url,
+ COALESCE(visible_users.username, ''::text) AS created_by_username,
+ COALESCE(visible_users.name, ''::text) AS created_by_name
+ FROM (template_versions
+ LEFT JOIN visible_users ON ((template_versions.created_by = visible_users.id)));
+
+COMMENT ON VIEW template_version_with_user IS 'Joins in the username + avatar url of the created by user.';
+
+CREATE VIEW workspace_build_with_user AS
+ SELECT workspace_builds.id,
+ workspace_builds.created_at,
+ workspace_builds.updated_at,
+ workspace_builds.workspace_id,
+ workspace_builds.template_version_id,
+ workspace_builds.build_number,
+ workspace_builds.transition,
+ workspace_builds.initiator_id,
+ workspace_builds.job_id,
+ workspace_builds.deadline,
+ workspace_builds.reason,
+ workspace_builds.daily_cost,
+ workspace_builds.max_deadline,
+ workspace_builds.template_version_preset_id,
+ workspace_builds.has_ai_task,
+ workspace_builds.has_external_agent,
+ workspace_builds.notified_autostop_deadline,
+ COALESCE(visible_users.avatar_url, ''::text) AS initiator_by_avatar_url,
+ COALESCE(visible_users.username, ''::text) AS initiator_by_username,
+ COALESCE(visible_users.name, ''::text) AS initiator_by_name
+ FROM (workspace_builds
+ LEFT JOIN visible_users ON ((workspace_builds.initiator_id = visible_users.id)));
+
+COMMENT ON VIEW workspace_build_with_user IS 'Joins in the username + avatar url of the initiated by user.';
diff --git a/coderd/database/migrations/000593_remove_has_ai_task_and_task_build_reasons.up.sql b/coderd/database/migrations/000593_remove_has_ai_task_and_task_build_reasons.up.sql
new file mode 100644
index 0000000000000..9de1cdfe69510
--- /dev/null
+++ b/coderd/database/migrations/000593_remove_has_ai_task_and_task_build_reasons.up.sql
@@ -0,0 +1,99 @@
+DROP VIEW IF EXISTS template_version_with_user;
+DROP VIEW IF EXISTS workspace_build_with_user;
+
+-- Drop has_ai_task index and columns.
+DROP INDEX IF EXISTS idx_template_versions_has_ai_task;
+ALTER TABLE template_versions DROP COLUMN IF EXISTS has_ai_task;
+ALTER TABLE workspace_builds DROP COLUMN IF EXISTS has_ai_task;
+
+-- Remove task-related build reasons from build_reason enum. Automatic
+-- pauses stay system-attributed; manual pauses and resumes were created by
+-- authenticated user requests, so they keep user attribution as initiator.
+UPDATE workspace_builds
+SET reason = 'autostop'
+WHERE reason::text = 'task_auto_pause';
+
+UPDATE workspace_builds
+SET reason = 'initiator'
+WHERE reason::text IN ('task_manual_pause', 'task_resume');
+
+UPDATE workspace_build_orchestrations
+SET child_reason = 'autostop'
+WHERE child_reason::text = 'task_auto_pause';
+
+UPDATE workspace_build_orchestrations
+SET child_reason = 'initiator'
+WHERE child_reason::text IN ('task_manual_pause', 'task_resume');
+
+ALTER TYPE build_reason RENAME TO build_reason_old;
+
+CREATE TYPE build_reason AS ENUM (
+ 'initiator',
+ 'autostart',
+ 'autostop',
+ 'dormancy',
+ 'failedstop',
+ 'autodelete',
+ 'dashboard',
+ 'cli',
+ 'ssh_connection',
+ 'vscode_connection',
+ 'jetbrains_connection'
+);
+
+ALTER TABLE workspace_builds ALTER COLUMN reason DROP DEFAULT;
+ALTER TABLE workspace_builds ALTER COLUMN reason TYPE build_reason USING (reason::text::build_reason);
+ALTER TABLE workspace_builds ALTER COLUMN reason SET DEFAULT 'initiator'::build_reason;
+
+ALTER TABLE workspace_build_orchestrations ALTER COLUMN child_reason TYPE build_reason USING (child_reason::text::build_reason);
+
+DROP TYPE build_reason_old;
+
+-- Recreate views without task columns.
+CREATE VIEW template_version_with_user AS
+ SELECT template_versions.id,
+ template_versions.template_id,
+ template_versions.organization_id,
+ template_versions.created_at,
+ template_versions.updated_at,
+ template_versions.name,
+ template_versions.readme,
+ template_versions.job_id,
+ template_versions.created_by,
+ template_versions.external_auth_providers,
+ template_versions.message,
+ template_versions.archived,
+ template_versions.source_example_id,
+ template_versions.has_external_agent,
+ COALESCE(visible_users.avatar_url, ''::text) AS created_by_avatar_url,
+ COALESCE(visible_users.username, ''::text) AS created_by_username,
+ COALESCE(visible_users.name, ''::text) AS created_by_name
+ FROM (template_versions
+ LEFT JOIN visible_users ON ((template_versions.created_by = visible_users.id)));
+
+COMMENT ON VIEW template_version_with_user IS 'Joins in the username + avatar url of the created by user.';
+
+CREATE VIEW workspace_build_with_user AS
+ SELECT workspace_builds.id,
+ workspace_builds.created_at,
+ workspace_builds.updated_at,
+ workspace_builds.workspace_id,
+ workspace_builds.template_version_id,
+ workspace_builds.build_number,
+ workspace_builds.transition,
+ workspace_builds.initiator_id,
+ workspace_builds.job_id,
+ workspace_builds.deadline,
+ workspace_builds.reason,
+ workspace_builds.daily_cost,
+ workspace_builds.max_deadline,
+ workspace_builds.template_version_preset_id,
+ workspace_builds.has_external_agent,
+ workspace_builds.notified_autostop_deadline,
+ COALESCE(visible_users.avatar_url, ''::text) AS initiator_by_avatar_url,
+ COALESCE(visible_users.username, ''::text) AS initiator_by_username,
+ COALESCE(visible_users.name, ''::text) AS initiator_by_name
+ FROM (workspace_builds
+ LEFT JOIN visible_users ON ((workspace_builds.initiator_id = visible_users.id)));
+
+COMMENT ON VIEW workspace_build_with_user IS 'Joins in the username + avatar url of the initiated by user.';
diff --git a/coderd/database/migrations/migrate_test.go b/coderd/database/migrations/migrate_test.go
index 9844d8ec4bdbc..19457e9ce9f37 100644
--- a/coderd/database/migrations/migrate_test.go
+++ b/coderd/database/migrations/migrate_test.go
@@ -1190,6 +1190,277 @@ func TestMigration000475AgentsAccessOrgRole(t *testing.T) {
)
}
+func TestMigration000593RemoveHasAITaskAndTaskBuildReasons(t *testing.T) {
+ t.Parallel()
+
+ const migrationVersion = 593
+ sqlDB := testSQLDB(t)
+ next, err := migrations.Stepper(sqlDB)
+ require.NoError(t, err)
+ for {
+ version, more, err := next()
+ require.NoError(t, err)
+ if !more {
+ t.Fatalf("migration %d not found", migrationVersion)
+ }
+ if version == migrationVersion-1 {
+ break
+ }
+ }
+
+ ctx := testutil.Context(t, testutil.WaitLong)
+ now := time.Now().UTC().Truncate(time.Microsecond)
+ orgID, userID, templateID, versionID, templateJobID, workspaceID := uuid.New(), uuid.New(), uuid.New(), uuid.New(), uuid.New(), uuid.New()
+ buildIDs := []uuid.UUID{uuid.New(), uuid.New(), uuid.New(), uuid.New(), uuid.New()}
+ fixtures := []struct {
+ query string
+ args []any
+ }{
+ {
+ "INSERT INTO organizations (id, name, display_name, description, created_at, updated_at, default_org_member_roles) VALUES ($1, $2, '', '', $3, $3, '{}')",
+ []any{orgID, orgID.String(), now},
+ },
+ {
+ "INSERT INTO users (id, username, email, hashed_password, created_at, updated_at) VALUES ($1, $2, $3, '', $4, $4)",
+ []any{userID, userID.String(), userID.String() + "@test.com", now},
+ },
+ {
+ "INSERT INTO provisioner_jobs (id, created_at, updated_at, organization_id, initiator_id, provisioner, storage_method, file_id, type, input) VALUES ($1, $2, $2, $3, $4, 'echo', 'file', $1, 'template_version_import', '{}')",
+ []any{templateJobID, now, orgID, userID},
+ },
+ {
+ "INSERT INTO template_versions (id, organization_id, name, readme, created_at, updated_at, job_id, created_by, has_ai_task) VALUES ($1, $2, 'v1', '', $3, $3, $4, $5, true)",
+ []any{versionID, orgID, now, templateJobID, userID},
+ },
+ {
+ "INSERT INTO templates (id, organization_id, name, created_at, updated_at, provisioner, active_version_id, created_by) VALUES ($1, $2, 'build-reasons', $3, $3, 'echo', $4, $5)",
+ []any{templateID, orgID, now, versionID, userID},
+ },
+ {
+ "UPDATE template_versions SET template_id = $1 WHERE id = $2",
+ []any{templateID, versionID},
+ },
+ {
+ "INSERT INTO workspaces (id, created_at, updated_at, owner_id, organization_id, template_id, name) VALUES ($1, $2, $2, $3, $4, $5, 'build-reasons')",
+ []any{workspaceID, now, userID, orgID, templateID},
+ },
+ }
+ for _, fixture := range fixtures {
+ _, err := sqlDB.ExecContext(ctx, fixture.query, fixture.args...)
+ require.NoError(t, err)
+ }
+ for i, reason := range []string{"task_auto_pause", "task_manual_pause", "task_resume", "initiator", "autostop"} {
+ jobID := uuid.New()
+ _, err = sqlDB.ExecContext(ctx,
+ "INSERT INTO provisioner_jobs (id, created_at, updated_at, organization_id, initiator_id, provisioner, storage_method, file_id, type, input) VALUES ($1, $2, $2, $3, $4, 'echo', 'file', $1, 'workspace_build', '{}')",
+ jobID, now, orgID, userID)
+ require.NoError(t, err)
+ _, err = sqlDB.ExecContext(ctx,
+ "INSERT INTO workspace_builds (id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, job_id, reason, has_ai_task) VALUES ($1, $2, $2, $3, $4, $5, 'start', $6, $7, $8, $9)",
+ buildIDs[i], now, workspaceID, versionID, i+1, userID, jobID, reason, i == 0)
+ require.NoError(t, err)
+ }
+ _, err = sqlDB.ExecContext(ctx,
+ "INSERT INTO workspace_build_orchestrations (id, created_at, updated_at, workspace_id, parent_build_id, child_transition, child_reason) VALUES ($1, $2, $2, $3, $4, 'start', 'task_auto_pause')",
+ uuid.New(), now, workspaceID, buildIDs[0])
+ require.NoError(t, err)
+
+ version, _, err := next()
+ require.NoError(t, err)
+ require.EqualValues(t, migrationVersion, version)
+ var count int
+ var reasons pq.StringArray
+ const reasonsQuery = "SELECT array_agg(reason::text ORDER BY build_number) FROM workspace_builds WHERE workspace_id = $1"
+ wantReasons := pq.StringArray{"autostop", "initiator", "initiator", "initiator", "autostop"}
+ require.NoError(t, sqlDB.QueryRowContext(ctx, reasonsQuery, workspaceID).Scan(&reasons))
+ require.Equal(t, wantReasons, reasons)
+ var childReason string
+ require.NoError(t, sqlDB.QueryRowContext(ctx, "SELECT child_reason FROM workspace_build_orchestrations WHERE workspace_id = $1", workspaceID).Scan(&childReason))
+ require.Equal(t, "autostop", childReason)
+ require.NoError(t, sqlDB.QueryRowContext(ctx, "SELECT count(*) FROM template_version_with_user").Scan(&count))
+ require.Equal(t, 1, count)
+ require.NoError(t, sqlDB.QueryRowContext(ctx, "SELECT count(*) FROM workspace_build_with_user").Scan(&count))
+ require.Equal(t, len(buildIDs), count)
+
+ downSQL, err := os.ReadFile("000593_remove_has_ai_task_and_task_build_reasons.down.sql")
+ require.NoError(t, err)
+ _, err = sqlDB.ExecContext(ctx, string(downSQL))
+ require.NoError(t, err)
+ require.NoError(t, sqlDB.QueryRowContext(ctx, "SELECT count(*) FROM template_versions WHERE has_ai_task IS FALSE").Scan(&count))
+ require.Equal(t, 1, count)
+ require.NoError(t, sqlDB.QueryRowContext(ctx, "SELECT count(*) FROM workspace_builds WHERE has_ai_task IS FALSE").Scan(&count))
+ require.Equal(t, len(buildIDs), count)
+ // The original reasons cannot be recovered after remapping.
+ require.NoError(t, sqlDB.QueryRowContext(ctx, reasonsQuery, workspaceID).Scan(&reasons))
+ require.Equal(t, wantReasons, reasons)
+ require.NoError(t, sqlDB.QueryRowContext(ctx, "SELECT child_reason FROM workspace_build_orchestrations WHERE workspace_id = $1", workspaceID).Scan(&childReason))
+ require.Equal(t, "autostop", childReason)
+
+ upSQL, err := os.ReadFile("000593_remove_has_ai_task_and_task_build_reasons.up.sql")
+ require.NoError(t, err)
+ _, err = sqlDB.ExecContext(ctx, string(upSQL))
+ require.NoError(t, err)
+}
+
+func TestMigration000593TaskBuildReasonRewriteTiming(t *testing.T) {
+ t.Parallel()
+
+ if testing.Short() {
+ t.SkipNow()
+ return
+ }
+
+ // The enum replacement rewrites workspace_builds, risking slow upgrades
+ // on large deployments.
+ const (
+ migrationVersion = 593
+ workspaceCount = 1_000
+ buildCount = 100_000
+ buildsPerWorkspace = buildCount / workspaceCount
+ orchestrationCount = 5_000
+ taskReasonBuilds = 3 * buildCount / 10
+ )
+
+ sqlDB := testSQLDB(t)
+ next, err := migrations.Stepper(sqlDB)
+ require.NoError(t, err)
+ for {
+ version, more, err := next()
+ require.NoError(t, err)
+ if !more {
+ t.Fatalf("migration %d not found", migrationVersion)
+ }
+ if version == migrationVersion-1 {
+ break
+ }
+ }
+
+ ctx := testutil.Context(t, testutil.WaitSuperLong)
+ now := time.Now().UTC().Truncate(time.Microsecond)
+
+ orgID := uuid.New()
+ userID := uuid.New()
+ templateID := uuid.New()
+ templateVersionID := uuid.New()
+ templateJobID := uuid.New()
+
+ // Deterministic IDs let the bulk inserts join rows generated by
+ // generate_series without round-tripping IDs through the test.
+ const (
+ workspaceIDPattern = "('a0000000-0000-4000-8000-' || lpad(%s::text, 12, '0'))::uuid"
+ jobIDPattern = "('b0000000-0000-4000-8000-' || lpad(%s::text, 12, '0'))::uuid"
+ buildIDPattern = "('c0000000-0000-4000-8000-' || lpad(%s::text, 12, '0'))::uuid"
+ )
+
+ fixtures := []struct {
+ query string
+ args []any
+ }{
+ {
+ `INSERT INTO organizations (id, name, display_name, description, created_at, updated_at, default_org_member_roles) VALUES ($1, $2, $3, $4, $5, $6, '{}')`,
+ []any{orgID, "timing-org", "Timing Org", "", now, now},
+ },
+ {
+ `INSERT INTO users (id, username, email, hashed_password, created_at, updated_at, status, rbac_roles, login_type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`,
+ []any{userID, "timinguser", "timing@example.com", []byte{}, now, now, "active", []byte("{}"), "password"},
+ },
+ {
+ `INSERT INTO provisioner_jobs (id, created_at, updated_at, started_at, completed_at, error, organization_id, initiator_id, provisioner, storage_method, file_id, type, input, tags) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)`,
+ []any{templateJobID, now, now, now, now, "", orgID, userID, "terraform", "file", uuid.New(), "template_version_import", []byte("{}"), []byte("{}")},
+ },
+ {
+ `INSERT INTO template_versions (id, organization_id, name, readme, created_at, updated_at, job_id, created_by) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`,
+ []any{templateVersionID, orgID, "v1.0", "", now, now, templateJobID, userID},
+ },
+ {
+ `INSERT INTO templates (id, organization_id, name, created_at, updated_at, provisioner, active_version_id, created_by) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`,
+ []any{templateID, orgID, "timing-template", now, now, "terraform", templateVersionID, userID},
+ },
+ {
+ `UPDATE template_versions SET template_id = $1 WHERE id = $2`,
+ []any{templateID, templateVersionID},
+ },
+ {
+ fmt.Sprintf(`INSERT INTO workspaces (id, created_at, updated_at, owner_id, organization_id, template_id, name, last_used_at)
+ SELECT `+workspaceIDPattern+`, $1, $1, $2, $3, $4, 'timing-ws-' || g, $1
+ FROM generate_series(0, %d) AS g`, "g", workspaceCount-1),
+ []any{now, userID, orgID, templateID},
+ },
+ {
+ fmt.Sprintf(`INSERT INTO provisioner_jobs (id, created_at, updated_at, started_at, completed_at, error, organization_id, initiator_id, provisioner, storage_method, file_id, type, input, tags)
+ SELECT `+jobIDPattern+`, $1, $1, $1, $1, '', $2, $3, 'terraform', 'file', $4, 'workspace_build', '{}'::jsonb, '{}'::jsonb
+ FROM generate_series(0, %d) AS g`, "g", buildCount-1),
+ []any{now, orgID, userID, uuid.New()},
+ },
+ {
+ fmt.Sprintf(`INSERT INTO workspace_builds (id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, job_id, reason, has_ai_task)
+ SELECT `+buildIDPattern+`, $1, $1, `+fmt.Sprintf(workspaceIDPattern, "(g / %d)")+`, $2, (g %% %d) + 1,
+ CASE WHEN g %% 2 = 0 THEN 'start' ELSE 'stop' END::workspace_transition, $3, `+jobIDPattern+`,
+ CASE g %% 10
+ WHEN 0 THEN 'task_auto_pause'
+ WHEN 1 THEN 'task_manual_pause'
+ WHEN 2 THEN 'task_resume'
+ WHEN 3 THEN 'autostart'
+ WHEN 4 THEN 'autostop'
+ ELSE 'initiator'
+ END::build_reason,
+ CASE WHEN g %% 10 < 3 THEN true END
+ FROM generate_series(0, %d) AS g`, "g", buildsPerWorkspace, buildsPerWorkspace, "g", buildCount-1),
+ []any{now, templateVersionID, userID},
+ },
+ {
+ fmt.Sprintf(`INSERT INTO workspace_build_orchestrations (id, created_at, updated_at, workspace_id, parent_build_id, child_transition, child_reason)
+ SELECT ('e0000000-0000-4000-8000-' || lpad(g::text, 12, '0'))::uuid, $1, $1, `+fmt.Sprintf(workspaceIDPattern, "(g * 20 / %d)")+`, `+fmt.Sprintf(buildIDPattern, "(g * 20)")+`, 'start',
+ CASE g %% 3
+ WHEN 0 THEN 'task_auto_pause'
+ WHEN 1 THEN 'task_resume'
+ ELSE 'initiator'
+ END::build_reason
+ FROM generate_series(0, %d) AS g`, buildsPerWorkspace, orchestrationCount-1),
+ []any{now},
+ },
+ }
+ for i, fixture := range fixtures {
+ _, err := sqlDB.ExecContext(ctx, fixture.query, fixture.args...)
+ require.NoErrorf(t, err, "fixture %d", i)
+ }
+
+ countByReason := func(table, column, reason string) int {
+ var n int
+ //nolint:gosec // Test-only query built from constant table/column names.
+ err := sqlDB.QueryRowContext(ctx, fmt.Sprintf("SELECT count(*) FROM %s WHERE %s::text = $1", table, column), reason).Scan(&n)
+ require.NoError(t, err)
+ return n
+ }
+ wantAutostop := countByReason("workspace_builds", "reason", "autostop") + countByReason("workspace_builds", "reason", "task_auto_pause")
+ wantInitiator := countByReason("workspace_builds", "reason", "initiator") + countByReason("workspace_builds", "reason", "task_manual_pause") + countByReason("workspace_builds", "reason", "task_resume")
+ wantChildAutostop := countByReason("workspace_build_orchestrations", "child_reason", "autostop") + countByReason("workspace_build_orchestrations", "child_reason", "task_auto_pause")
+ wantChildInitiator := countByReason("workspace_build_orchestrations", "child_reason", "initiator") + countByReason("workspace_build_orchestrations", "child_reason", "task_resume")
+
+ start := time.Now()
+ version, _, err := next()
+ require.NoError(t, err)
+ require.EqualValues(t, migrationVersion, version)
+ elapsed := time.Since(start)
+ t.Logf("migration %d over %d workspace builds (%d with task reasons) and %d orchestrations took %s", migrationVersion, buildCount, taskReasonBuilds, orchestrationCount, elapsed)
+ // Bound migration time to catch regressions that could prolong upgrade downtime.
+ require.Lessf(t, elapsed, 2*time.Minute, "migration %d took %s at %d workspace builds", migrationVersion, elapsed, buildCount)
+
+ var totalBuilds int
+ err = sqlDB.QueryRowContext(ctx, "SELECT count(*) FROM workspace_builds").Scan(&totalBuilds)
+ require.NoError(t, err)
+ require.Equal(t, buildCount, totalBuilds)
+ require.Equal(t, wantAutostop, countByReason("workspace_builds", "reason", "autostop"))
+ require.Equal(t, wantInitiator, countByReason("workspace_builds", "reason", "initiator"))
+ require.Equal(t, wantChildAutostop, countByReason("workspace_build_orchestrations", "child_reason", "autostop"))
+ require.Equal(t, wantChildInitiator, countByReason("workspace_build_orchestrations", "child_reason", "initiator"))
+
+ var count int
+ err = sqlDB.QueryRowContext(ctx, "SELECT count(*) FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'workspace_builds' AND column_name = 'has_ai_task'").Scan(&count)
+ require.NoError(t, err)
+ require.Zero(t, count)
+}
+
func TestMigration000587RemoveAgentsAccessRole(t *testing.T) {
t.Parallel()
diff --git a/coderd/database/modelqueries.go b/coderd/database/modelqueries.go
index 8345b8bd5a4b3..b0d06b65d5d72 100644
--- a/coderd/database/modelqueries.go
+++ b/coderd/database/modelqueries.go
@@ -145,7 +145,6 @@ func (q *sqlQuerier) GetAuthorizedTemplates(ctx context.Context, arg GetTemplate
arg.FuzzyDisplayName,
pq.Array(arg.IDs),
arg.Deprecated,
- arg.HasAITask,
arg.AgentsAllowed,
arg.AuthorID,
arg.AuthorUsername,
@@ -340,7 +339,6 @@ func (q *sqlQuerier) GetAuthorizedWorkspaces(ctx context.Context, arg GetWorkspa
arg.LastUsedBefore,
arg.LastUsedAfter,
arg.UsingActive,
- arg.HasAITask,
arg.HasExternalAgent,
arg.Shared,
arg.SharedWithUserID,
diff --git a/coderd/database/models.go b/coderd/database/models.go
index b5a1340b353c4..d60a493c22c61 100644
--- a/coderd/database/models.go
+++ b/coderd/database/models.go
@@ -1366,9 +1366,6 @@ const (
BuildReasonSshConnection BuildReason = "ssh_connection"
BuildReasonVscodeConnection BuildReason = "vscode_connection"
BuildReasonJetbrainsConnection BuildReason = "jetbrains_connection"
- BuildReasonTaskAutoPause BuildReason = "task_auto_pause"
- BuildReasonTaskManualPause BuildReason = "task_manual_pause"
- BuildReasonTaskResume BuildReason = "task_resume"
)
func (e *BuildReason) Scan(src interface{}) error {
@@ -1418,10 +1415,7 @@ func (e BuildReason) Valid() bool {
BuildReasonCli,
BuildReasonSshConnection,
BuildReasonVscodeConnection,
- BuildReasonJetbrainsConnection,
- BuildReasonTaskAutoPause,
- BuildReasonTaskManualPause,
- BuildReasonTaskResume:
+ BuildReasonJetbrainsConnection:
return true
}
return false
@@ -1440,9 +1434,6 @@ func AllBuildReasonValues() []BuildReason {
BuildReasonSshConnection,
BuildReasonVscodeConnection,
BuildReasonJetbrainsConnection,
- BuildReasonTaskAutoPause,
- BuildReasonTaskManualPause,
- BuildReasonTaskResume,
}
}
@@ -6214,7 +6205,6 @@ type TemplateVersion struct {
Message string `db:"message" json:"message"`
Archived bool `db:"archived" json:"archived"`
SourceExampleID sql.NullString `db:"source_example_id" json:"source_example_id"`
- HasAITask sql.NullBool `db:"has_ai_task" json:"has_ai_task"`
HasExternalAgent sql.NullBool `db:"has_external_agent" json:"has_external_agent"`
CreatedByAvatarURL string `db:"created_by_avatar_url" json:"created_by_avatar_url"`
CreatedByUsername string `db:"created_by_username" json:"created_by_username"`
@@ -6306,7 +6296,6 @@ type TemplateVersionTable struct {
Message string `db:"message" json:"message"`
Archived bool `db:"archived" json:"archived"`
SourceExampleID sql.NullString `db:"source_example_id" json:"source_example_id"`
- HasAITask sql.NullBool `db:"has_ai_task" json:"has_ai_task"`
HasExternalAgent sql.NullBool `db:"has_external_agent" json:"has_external_agent"`
}
@@ -6840,7 +6829,6 @@ type WorkspaceBuild struct {
DailyCost int32 `db:"daily_cost" json:"daily_cost"`
MaxDeadline time.Time `db:"max_deadline" json:"max_deadline"`
TemplateVersionPresetID uuid.NullUUID `db:"template_version_preset_id" json:"template_version_preset_id"`
- HasAITask sql.NullBool `db:"has_ai_task" json:"has_ai_task"`
HasExternalAgent sql.NullBool `db:"has_external_agent" json:"has_external_agent"`
NotifiedAutostopDeadline time.Time `db:"notified_autostop_deadline" json:"notified_autostop_deadline"`
InitiatorByAvatarUrl string `db:"initiator_by_avatar_url" json:"initiator_by_avatar_url"`
@@ -6897,7 +6885,6 @@ type WorkspaceBuildTable struct {
DailyCost int32 `db:"daily_cost" json:"daily_cost"`
MaxDeadline time.Time `db:"max_deadline" json:"max_deadline"`
TemplateVersionPresetID uuid.NullUUID `db:"template_version_preset_id" json:"template_version_preset_id"`
- HasAITask sql.NullBool `db:"has_ai_task" json:"has_ai_task"`
HasExternalAgent sql.NullBool `db:"has_external_agent" json:"has_external_agent"`
// The autostop deadline value that an autostop reminder notification was last sent for. Used for idempotence: when it equals the build deadline the reminder has already been sent, and it re-arms automatically when the deadline changes.
NotifiedAutostopDeadline time.Time `db:"notified_autostop_deadline" json:"notified_autostop_deadline"`
diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go
index 26d2a934c618f..fe06b407691ee 100644
--- a/coderd/database/queries.sql.go
+++ b/coderd/database/queries.sql.go
@@ -28275,35 +28275,29 @@ WHERE
END
ELSE true
END
- -- Filter by has_ai_task in latest version
- AND CASE
- WHEN $9 :: boolean IS NOT NULL THEN
- tv.has_ai_task = $9 :: boolean
- ELSE true
- END
-- Filter by agents_allowed
AND CASE
- WHEN $10 :: boolean IS NOT NULL THEN
- t.agents_allowed = $10 :: boolean
+ WHEN $9 :: boolean IS NOT NULL THEN
+ t.agents_allowed = $9 :: boolean
ELSE true
END
-- Filter by author_id
AND CASE
- WHEN $11 :: uuid != '00000000-0000-0000-0000-000000000000'::uuid THEN
- t.created_by = $11
+ WHEN $10 :: uuid != '00000000-0000-0000-0000-000000000000'::uuid THEN
+ t.created_by = $10
ELSE true
END
-- Filter by author_username
AND CASE
- WHEN $12 :: text != '' THEN
- t.created_by = (SELECT id FROM users WHERE lower(users.username) = lower($12) AND deleted = false)
+ WHEN $11 :: text != '' THEN
+ t.created_by = (SELECT id FROM users WHERE lower(users.username) = lower($11) AND deleted = false)
ELSE true
END
-- Filter by has_external_agent in latest version
AND CASE
- WHEN $13 :: boolean IS NOT NULL THEN
- tv.has_external_agent = $13 :: boolean
+ WHEN $12 :: boolean IS NOT NULL THEN
+ tv.has_external_agent = $12 :: boolean
ELSE true
END
-- Authorize Filter clause will be injected below in GetAuthorizedTemplates
@@ -28320,7 +28314,6 @@ type GetTemplatesWithFilterParams struct {
FuzzyDisplayName string `db:"fuzzy_display_name" json:"fuzzy_display_name"`
IDs []uuid.UUID `db:"ids" json:"ids"`
Deprecated sql.NullBool `db:"deprecated" json:"deprecated"`
- HasAITask sql.NullBool `db:"has_ai_task" json:"has_ai_task"`
AgentsAllowed sql.NullBool `db:"agents_allowed" json:"agents_allowed"`
AuthorID uuid.UUID `db:"author_id" json:"author_id"`
AuthorUsername string `db:"author_username" json:"author_username"`
@@ -28337,7 +28330,6 @@ func (q *sqlQuerier) GetTemplatesWithFilter(ctx context.Context, arg GetTemplate
arg.FuzzyDisplayName,
pq.Array(arg.IDs),
arg.Deprecated,
- arg.HasAITask,
arg.AgentsAllowed,
arg.AuthorID,
arg.AuthorUsername,
@@ -28848,7 +28840,7 @@ FROM
-- Scope an archive to a single template and ignore already archived template versions
(
SELECT
- id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id, has_ai_task, has_external_agent
+ id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id, has_external_agent
FROM
template_versions
WHERE
@@ -28949,7 +28941,7 @@ func (q *sqlQuerier) ArchiveUnusedTemplateVersions(ctx context.Context, arg Arch
const getPreviousTemplateVersion = `-- name: GetPreviousTemplateVersion :one
SELECT
- id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id, has_ai_task, has_external_agent, created_by_avatar_url, created_by_username, created_by_name
+ id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id, has_external_agent, created_by_avatar_url, created_by_username, created_by_name
FROM
template_version_with_user AS template_versions
WHERE
@@ -28987,7 +28979,6 @@ func (q *sqlQuerier) GetPreviousTemplateVersion(ctx context.Context, arg GetPrev
&i.Message,
&i.Archived,
&i.SourceExampleID,
- &i.HasAITask,
&i.HasExternalAgent,
&i.CreatedByAvatarURL,
&i.CreatedByUsername,
@@ -28998,7 +28989,7 @@ func (q *sqlQuerier) GetPreviousTemplateVersion(ctx context.Context, arg GetPrev
const getTemplateVersionByID = `-- name: GetTemplateVersionByID :one
SELECT
- id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id, has_ai_task, has_external_agent, created_by_avatar_url, created_by_username, created_by_name
+ id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id, has_external_agent, created_by_avatar_url, created_by_username, created_by_name
FROM
template_version_with_user AS template_versions
WHERE
@@ -29022,7 +29013,6 @@ func (q *sqlQuerier) GetTemplateVersionByID(ctx context.Context, id uuid.UUID) (
&i.Message,
&i.Archived,
&i.SourceExampleID,
- &i.HasAITask,
&i.HasExternalAgent,
&i.CreatedByAvatarURL,
&i.CreatedByUsername,
@@ -29033,7 +29023,7 @@ func (q *sqlQuerier) GetTemplateVersionByID(ctx context.Context, id uuid.UUID) (
const getTemplateVersionByJobID = `-- name: GetTemplateVersionByJobID :one
SELECT
- id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id, has_ai_task, has_external_agent, created_by_avatar_url, created_by_username, created_by_name
+ id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id, has_external_agent, created_by_avatar_url, created_by_username, created_by_name
FROM
template_version_with_user AS template_versions
WHERE
@@ -29057,7 +29047,6 @@ func (q *sqlQuerier) GetTemplateVersionByJobID(ctx context.Context, jobID uuid.U
&i.Message,
&i.Archived,
&i.SourceExampleID,
- &i.HasAITask,
&i.HasExternalAgent,
&i.CreatedByAvatarURL,
&i.CreatedByUsername,
@@ -29068,7 +29057,7 @@ func (q *sqlQuerier) GetTemplateVersionByJobID(ctx context.Context, jobID uuid.U
const getTemplateVersionByTemplateIDAndName = `-- name: GetTemplateVersionByTemplateIDAndName :one
SELECT
- id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id, has_ai_task, has_external_agent, created_by_avatar_url, created_by_username, created_by_name
+ id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id, has_external_agent, created_by_avatar_url, created_by_username, created_by_name
FROM
template_version_with_user AS template_versions
WHERE
@@ -29098,7 +29087,6 @@ func (q *sqlQuerier) GetTemplateVersionByTemplateIDAndName(ctx context.Context,
&i.Message,
&i.Archived,
&i.SourceExampleID,
- &i.HasAITask,
&i.HasExternalAgent,
&i.CreatedByAvatarURL,
&i.CreatedByUsername,
@@ -29109,7 +29097,7 @@ func (q *sqlQuerier) GetTemplateVersionByTemplateIDAndName(ctx context.Context,
const getTemplateVersionsByIDs = `-- name: GetTemplateVersionsByIDs :many
SELECT
- id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id, has_ai_task, has_external_agent, created_by_avatar_url, created_by_username, created_by_name
+ id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id, has_external_agent, created_by_avatar_url, created_by_username, created_by_name
FROM
template_version_with_user AS template_versions
WHERE
@@ -29139,7 +29127,6 @@ func (q *sqlQuerier) GetTemplateVersionsByIDs(ctx context.Context, ids []uuid.UU
&i.Message,
&i.Archived,
&i.SourceExampleID,
- &i.HasAITask,
&i.HasExternalAgent,
&i.CreatedByAvatarURL,
&i.CreatedByUsername,
@@ -29160,7 +29147,7 @@ func (q *sqlQuerier) GetTemplateVersionsByIDs(ctx context.Context, ids []uuid.UU
const getTemplateVersionsByTemplateID = `-- name: GetTemplateVersionsByTemplateID :many
SELECT
- id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id, has_ai_task, has_external_agent, created_by_avatar_url, created_by_username, created_by_name
+ id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id, has_external_agent, created_by_avatar_url, created_by_username, created_by_name
FROM
template_version_with_user AS template_versions
WHERE
@@ -29237,7 +29224,6 @@ func (q *sqlQuerier) GetTemplateVersionsByTemplateID(ctx context.Context, arg Ge
&i.Message,
&i.Archived,
&i.SourceExampleID,
- &i.HasAITask,
&i.HasExternalAgent,
&i.CreatedByAvatarURL,
&i.CreatedByUsername,
@@ -29257,7 +29243,7 @@ func (q *sqlQuerier) GetTemplateVersionsByTemplateID(ctx context.Context, arg Ge
}
const getTemplateVersionsCreatedAfter = `-- name: GetTemplateVersionsCreatedAfter :many
-SELECT id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id, has_ai_task, has_external_agent, created_by_avatar_url, created_by_username, created_by_name FROM template_version_with_user AS template_versions WHERE created_at > $1
+SELECT id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id, has_external_agent, created_by_avatar_url, created_by_username, created_by_name FROM template_version_with_user AS template_versions WHERE created_at > $1
`
func (q *sqlQuerier) GetTemplateVersionsCreatedAfter(ctx context.Context, createdAt time.Time) ([]TemplateVersion, error) {
@@ -29283,7 +29269,6 @@ func (q *sqlQuerier) GetTemplateVersionsCreatedAfter(ctx context.Context, create
&i.Message,
&i.Archived,
&i.SourceExampleID,
- &i.HasAITask,
&i.HasExternalAgent,
&i.CreatedByAvatarURL,
&i.CreatedByUsername,
@@ -29450,27 +29435,20 @@ const updateTemplateVersionFlagsByJobID = `-- name: UpdateTemplateVersionFlagsBy
UPDATE
template_versions
SET
- has_ai_task = $2,
- has_external_agent = $3,
- updated_at = $4
+ has_external_agent = $2,
+ updated_at = $3
WHERE
job_id = $1
`
type UpdateTemplateVersionFlagsByJobIDParams struct {
JobID uuid.UUID `db:"job_id" json:"job_id"`
- HasAITask sql.NullBool `db:"has_ai_task" json:"has_ai_task"`
HasExternalAgent sql.NullBool `db:"has_external_agent" json:"has_external_agent"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
}
func (q *sqlQuerier) UpdateTemplateVersionFlagsByJobID(ctx context.Context, arg UpdateTemplateVersionFlagsByJobIDParams) error {
- _, err := q.db.ExecContext(ctx, updateTemplateVersionFlagsByJobID,
- arg.JobID,
- arg.HasAITask,
- arg.HasExternalAgent,
- arg.UpdatedAt,
- )
+ _, err := q.db.ExecContext(ctx, updateTemplateVersionFlagsByJobID, arg.JobID, arg.HasExternalAgent, arg.UpdatedAt)
return err
}
@@ -33990,7 +33968,7 @@ const getAuthenticatedWorkspaceAgentAndBuildByAuthToken = `-- name: GetAuthentic
SELECT
workspaces.id, workspaces.created_at, workspaces.updated_at, workspaces.owner_id, workspaces.organization_id, workspaces.template_id, workspaces.deleted, workspaces.name, workspaces.autostart_schedule, workspaces.ttl, workspaces.last_used_at, workspaces.dormant_at, workspaces.deleting_at, workspaces.automatic_updates, workspaces.favorite, workspaces.next_start_at, workspaces.group_acl, workspaces.user_acl,
workspace_agents.id, workspace_agents.created_at, workspace_agents.updated_at, workspace_agents.name, workspace_agents.first_connected_at, workspace_agents.last_connected_at, workspace_agents.disconnected_at, workspace_agents.resource_id, workspace_agents.auth_token, workspace_agents.auth_instance_id, workspace_agents.architecture, workspace_agents.environment_variables, workspace_agents.operating_system, workspace_agents.instance_metadata, workspace_agents.resource_metadata, workspace_agents.directory, workspace_agents.version, workspace_agents.last_connected_replica_id, workspace_agents.connection_timeout_seconds, workspace_agents.troubleshooting_url, workspace_agents.motd_file, workspace_agents.lifecycle_state, workspace_agents.expanded_directory, workspace_agents.logs_length, workspace_agents.logs_overflowed, workspace_agents.started_at, workspace_agents.ready_at, workspace_agents.subsystems, workspace_agents.display_apps, workspace_agents.api_version, workspace_agents.display_order, workspace_agents.parent_id, workspace_agents.api_key_scope, workspace_agents.deleted,
- workspace_build_with_user.id, workspace_build_with_user.created_at, workspace_build_with_user.updated_at, workspace_build_with_user.workspace_id, workspace_build_with_user.template_version_id, workspace_build_with_user.build_number, workspace_build_with_user.transition, workspace_build_with_user.initiator_id, workspace_build_with_user.job_id, workspace_build_with_user.deadline, workspace_build_with_user.reason, workspace_build_with_user.daily_cost, workspace_build_with_user.max_deadline, workspace_build_with_user.template_version_preset_id, workspace_build_with_user.has_ai_task, workspace_build_with_user.has_external_agent, workspace_build_with_user.notified_autostop_deadline, workspace_build_with_user.initiator_by_avatar_url, workspace_build_with_user.initiator_by_username, workspace_build_with_user.initiator_by_name,
+ workspace_build_with_user.id, workspace_build_with_user.created_at, workspace_build_with_user.updated_at, workspace_build_with_user.workspace_id, workspace_build_with_user.template_version_id, workspace_build_with_user.build_number, workspace_build_with_user.transition, workspace_build_with_user.initiator_id, workspace_build_with_user.job_id, workspace_build_with_user.deadline, workspace_build_with_user.reason, workspace_build_with_user.daily_cost, workspace_build_with_user.max_deadline, workspace_build_with_user.template_version_preset_id, workspace_build_with_user.has_external_agent, workspace_build_with_user.notified_autostop_deadline, workspace_build_with_user.initiator_by_avatar_url, workspace_build_with_user.initiator_by_username, workspace_build_with_user.initiator_by_name,
tasks.id AS task_id
FROM
workspace_agents
@@ -34134,7 +34112,6 @@ func (q *sqlQuerier) GetAuthenticatedWorkspaceAgentAndBuildByAuthToken(ctx conte
&i.WorkspaceBuild.DailyCost,
&i.WorkspaceBuild.MaxDeadline,
&i.WorkspaceBuild.TemplateVersionPresetID,
- &i.WorkspaceBuild.HasAITask,
&i.WorkspaceBuild.HasExternalAgent,
&i.WorkspaceBuild.NotifiedAutostopDeadline,
&i.WorkspaceBuild.InitiatorByAvatarUrl,
@@ -37673,7 +37650,7 @@ func (q *sqlQuerier) InsertWorkspaceBuildParameters(ctx context.Context, arg Ins
}
const getActiveWorkspaceBuildsByTemplateID = `-- name: GetActiveWorkspaceBuildsByTemplateID :many
-SELECT wb.id, wb.created_at, wb.updated_at, wb.workspace_id, wb.template_version_id, wb.build_number, wb.transition, wb.initiator_id, wb.job_id, wb.deadline, wb.reason, wb.daily_cost, wb.max_deadline, wb.template_version_preset_id, wb.has_ai_task, wb.has_external_agent, wb.notified_autostop_deadline, wb.initiator_by_avatar_url, wb.initiator_by_username, wb.initiator_by_name
+SELECT wb.id, wb.created_at, wb.updated_at, wb.workspace_id, wb.template_version_id, wb.build_number, wb.transition, wb.initiator_id, wb.job_id, wb.deadline, wb.reason, wb.daily_cost, wb.max_deadline, wb.template_version_preset_id, wb.has_external_agent, wb.notified_autostop_deadline, wb.initiator_by_avatar_url, wb.initiator_by_username, wb.initiator_by_name
FROM (
SELECT
workspace_id, MAX(build_number) as max_build_number
@@ -37727,7 +37704,6 @@ func (q *sqlQuerier) GetActiveWorkspaceBuildsByTemplateID(ctx context.Context, t
&i.DailyCost,
&i.MaxDeadline,
&i.TemplateVersionPresetID,
- &i.HasAITask,
&i.HasExternalAgent,
&i.NotifiedAutostopDeadline,
&i.InitiatorByAvatarUrl,
@@ -37829,7 +37805,7 @@ func (q *sqlQuerier) GetFailedWorkspaceBuildsByTemplateID(ctx context.Context, a
const getLatestWorkspaceBuildByWorkspaceID = `-- name: GetLatestWorkspaceBuildByWorkspaceID :one
SELECT
- id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, job_id, deadline, reason, daily_cost, max_deadline, template_version_preset_id, has_ai_task, has_external_agent, notified_autostop_deadline, initiator_by_avatar_url, initiator_by_username, initiator_by_name
+ id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, job_id, deadline, reason, daily_cost, max_deadline, template_version_preset_id, has_external_agent, notified_autostop_deadline, initiator_by_avatar_url, initiator_by_username, initiator_by_name
FROM
workspace_build_with_user AS workspace_builds
WHERE
@@ -37858,7 +37834,6 @@ func (q *sqlQuerier) GetLatestWorkspaceBuildByWorkspaceID(ctx context.Context, w
&i.DailyCost,
&i.MaxDeadline,
&i.TemplateVersionPresetID,
- &i.HasAITask,
&i.HasExternalAgent,
&i.NotifiedAutostopDeadline,
&i.InitiatorByAvatarUrl,
@@ -37926,7 +37901,7 @@ func (q *sqlQuerier) GetLatestWorkspaceBuildWithStatusByWorkspaceID(ctx context.
const getLatestWorkspaceBuildsByWorkspaceIDs = `-- name: GetLatestWorkspaceBuildsByWorkspaceIDs :many
SELECT
DISTINCT ON (workspace_id)
- id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, job_id, deadline, reason, daily_cost, max_deadline, template_version_preset_id, has_ai_task, has_external_agent, notified_autostop_deadline, initiator_by_avatar_url, initiator_by_username, initiator_by_name
+ id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, job_id, deadline, reason, daily_cost, max_deadline, template_version_preset_id, has_external_agent, notified_autostop_deadline, initiator_by_avatar_url, initiator_by_username, initiator_by_name
FROM
workspace_build_with_user AS workspace_builds
WHERE
@@ -37959,7 +37934,6 @@ func (q *sqlQuerier) GetLatestWorkspaceBuildsByWorkspaceIDs(ctx context.Context,
&i.DailyCost,
&i.MaxDeadline,
&i.TemplateVersionPresetID,
- &i.HasAITask,
&i.HasExternalAgent,
&i.NotifiedAutostopDeadline,
&i.InitiatorByAvatarUrl,
@@ -37981,7 +37955,7 @@ func (q *sqlQuerier) GetLatestWorkspaceBuildsByWorkspaceIDs(ctx context.Context,
const getWorkspaceBuildByID = `-- name: GetWorkspaceBuildByID :one
SELECT
- id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, job_id, deadline, reason, daily_cost, max_deadline, template_version_preset_id, has_ai_task, has_external_agent, notified_autostop_deadline, initiator_by_avatar_url, initiator_by_username, initiator_by_name
+ id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, job_id, deadline, reason, daily_cost, max_deadline, template_version_preset_id, has_external_agent, notified_autostop_deadline, initiator_by_avatar_url, initiator_by_username, initiator_by_name
FROM
workspace_build_with_user AS workspace_builds
WHERE
@@ -38008,7 +37982,6 @@ func (q *sqlQuerier) GetWorkspaceBuildByID(ctx context.Context, id uuid.UUID) (W
&i.DailyCost,
&i.MaxDeadline,
&i.TemplateVersionPresetID,
- &i.HasAITask,
&i.HasExternalAgent,
&i.NotifiedAutostopDeadline,
&i.InitiatorByAvatarUrl,
@@ -38020,7 +37993,7 @@ func (q *sqlQuerier) GetWorkspaceBuildByID(ctx context.Context, id uuid.UUID) (W
const getWorkspaceBuildByJobID = `-- name: GetWorkspaceBuildByJobID :one
SELECT
- id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, job_id, deadline, reason, daily_cost, max_deadline, template_version_preset_id, has_ai_task, has_external_agent, notified_autostop_deadline, initiator_by_avatar_url, initiator_by_username, initiator_by_name
+ id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, job_id, deadline, reason, daily_cost, max_deadline, template_version_preset_id, has_external_agent, notified_autostop_deadline, initiator_by_avatar_url, initiator_by_username, initiator_by_name
FROM
workspace_build_with_user AS workspace_builds
WHERE
@@ -38047,7 +38020,6 @@ func (q *sqlQuerier) GetWorkspaceBuildByJobID(ctx context.Context, jobID uuid.UU
&i.DailyCost,
&i.MaxDeadline,
&i.TemplateVersionPresetID,
- &i.HasAITask,
&i.HasExternalAgent,
&i.NotifiedAutostopDeadline,
&i.InitiatorByAvatarUrl,
@@ -38059,7 +38031,7 @@ func (q *sqlQuerier) GetWorkspaceBuildByJobID(ctx context.Context, jobID uuid.UU
const getWorkspaceBuildByWorkspaceIDAndBuildNumber = `-- name: GetWorkspaceBuildByWorkspaceIDAndBuildNumber :one
SELECT
- id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, job_id, deadline, reason, daily_cost, max_deadline, template_version_preset_id, has_ai_task, has_external_agent, notified_autostop_deadline, initiator_by_avatar_url, initiator_by_username, initiator_by_name
+ id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, job_id, deadline, reason, daily_cost, max_deadline, template_version_preset_id, has_external_agent, notified_autostop_deadline, initiator_by_avatar_url, initiator_by_username, initiator_by_name
FROM
workspace_build_with_user AS workspace_builds
WHERE
@@ -38090,7 +38062,6 @@ func (q *sqlQuerier) GetWorkspaceBuildByWorkspaceIDAndBuildNumber(ctx context.Co
&i.DailyCost,
&i.MaxDeadline,
&i.TemplateVersionPresetID,
- &i.HasAITask,
&i.HasExternalAgent,
&i.NotifiedAutostopDeadline,
&i.InitiatorByAvatarUrl,
@@ -38267,7 +38238,7 @@ func (q *sqlQuerier) GetWorkspaceBuildStatsByTemplates(ctx context.Context, sinc
const getWorkspaceBuildsByWorkspaceID = `-- name: GetWorkspaceBuildsByWorkspaceID :many
SELECT
- id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, job_id, deadline, reason, daily_cost, max_deadline, template_version_preset_id, has_ai_task, has_external_agent, notified_autostop_deadline, initiator_by_avatar_url, initiator_by_username, initiator_by_name
+ id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, job_id, deadline, reason, daily_cost, max_deadline, template_version_preset_id, has_external_agent, notified_autostop_deadline, initiator_by_avatar_url, initiator_by_username, initiator_by_name
FROM
workspace_build_with_user AS workspace_builds
WHERE
@@ -38337,7 +38308,6 @@ func (q *sqlQuerier) GetWorkspaceBuildsByWorkspaceID(ctx context.Context, arg Ge
&i.DailyCost,
&i.MaxDeadline,
&i.TemplateVersionPresetID,
- &i.HasAITask,
&i.HasExternalAgent,
&i.NotifiedAutostopDeadline,
&i.InitiatorByAvatarUrl,
@@ -38358,7 +38328,7 @@ func (q *sqlQuerier) GetWorkspaceBuildsByWorkspaceID(ctx context.Context, arg Ge
}
const getWorkspaceBuildsCreatedAfter = `-- name: GetWorkspaceBuildsCreatedAfter :many
-SELECT id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, job_id, deadline, reason, daily_cost, max_deadline, template_version_preset_id, has_ai_task, has_external_agent, notified_autostop_deadline, initiator_by_avatar_url, initiator_by_username, initiator_by_name FROM workspace_build_with_user WHERE created_at > $1
+SELECT id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, job_id, deadline, reason, daily_cost, max_deadline, template_version_preset_id, has_external_agent, notified_autostop_deadline, initiator_by_avatar_url, initiator_by_username, initiator_by_name FROM workspace_build_with_user WHERE created_at > $1
`
func (q *sqlQuerier) GetWorkspaceBuildsCreatedAfter(ctx context.Context, createdAt time.Time) ([]WorkspaceBuild, error) {
@@ -38385,7 +38355,6 @@ func (q *sqlQuerier) GetWorkspaceBuildsCreatedAfter(ctx context.Context, created
&i.DailyCost,
&i.MaxDeadline,
&i.TemplateVersionPresetID,
- &i.HasAITask,
&i.HasExternalAgent,
&i.NotifiedAutostopDeadline,
&i.InitiatorByAvatarUrl,
@@ -38522,26 +38491,19 @@ const updateWorkspaceBuildFlagsByID = `-- name: UpdateWorkspaceBuildFlagsByID :e
UPDATE
workspace_builds
SET
- has_ai_task = $1,
- has_external_agent = $2,
- updated_at = $3::timestamptz
-WHERE id = $4::uuid
+ has_external_agent = $1,
+ updated_at = $2::timestamptz
+WHERE id = $3::uuid
`
type UpdateWorkspaceBuildFlagsByIDParams struct {
- HasAITask sql.NullBool `db:"has_ai_task" json:"has_ai_task"`
HasExternalAgent sql.NullBool `db:"has_external_agent" json:"has_external_agent"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
ID uuid.UUID `db:"id" json:"id"`
}
func (q *sqlQuerier) UpdateWorkspaceBuildFlagsByID(ctx context.Context, arg UpdateWorkspaceBuildFlagsByIDParams) error {
- _, err := q.db.ExecContext(ctx, updateWorkspaceBuildFlagsByID,
- arg.HasAITask,
- arg.HasExternalAgent,
- arg.UpdatedAt,
- arg.ID,
- )
+ _, err := q.db.ExecContext(ctx, updateWorkspaceBuildFlagsByID, arg.HasExternalAgent, arg.UpdatedAt, arg.ID)
return err
}
@@ -39808,7 +39770,6 @@ LEFT JOIN LATERAL (
workspace_builds.id,
workspace_builds.transition,
workspace_builds.template_version_id,
- workspace_builds.has_ai_task,
workspace_builds.has_external_agent,
template_versions.name AS template_version_name,
provisioner_jobs.id AS provisioner_job_id,
@@ -40029,43 +39990,28 @@ WHERE
(latest_build.template_version_id = template.active_version_id) = $19 :: boolean
ELSE true
END
- -- Filter by has_ai_task, checks if this is a task workspace.
- AND CASE
- WHEN $20::boolean IS NOT NULL
- THEN $20::boolean = EXISTS (
- SELECT
- 1
- FROM
- tasks
- WHERE
- -- Consider all tasks, deleting a task does not turn the
- -- workspace into a non-task workspace.
- tasks.workspace_id = workspaces.id
- )
- ELSE true
- END
-- Filter by has_external_agent in latest build
AND CASE
- WHEN $21 :: boolean IS NOT NULL THEN
- latest_build.has_external_agent = $21 :: boolean
+ WHEN $20 :: boolean IS NOT NULL THEN
+ latest_build.has_external_agent = $20 :: boolean
ELSE true
END
-- Filter by shared status
AND CASE
- WHEN $22 :: boolean IS NOT NULL THEN
- (workspaces.user_acl != '{}'::jsonb OR workspaces.group_acl != '{}'::jsonb) = $22 :: boolean
+ WHEN $21 :: boolean IS NOT NULL THEN
+ (workspaces.user_acl != '{}'::jsonb OR workspaces.group_acl != '{}'::jsonb) = $21 :: boolean
ELSE true
END
-- Filter by shared_with_user_id
AND CASE
- WHEN $23 :: uuid != '00000000-0000-0000-0000-000000000000'::uuid THEN
- workspaces.user_acl ? ($23 :: uuid) :: text
+ WHEN $22 :: uuid != '00000000-0000-0000-0000-000000000000'::uuid THEN
+ workspaces.user_acl ? ($22 :: uuid) :: text
ELSE true
END
-- Filter by shared_with_group_id
AND CASE
- WHEN $24 :: uuid != '00000000-0000-0000-0000-000000000000'::uuid THEN
- workspaces.group_acl ? ($24 :: uuid) :: text
+ WHEN $23 :: uuid != '00000000-0000-0000-0000-000000000000'::uuid THEN
+ workspaces.group_acl ? ($23 :: uuid) :: text
ELSE true
END
@@ -40078,7 +40024,7 @@ WHERE
filtered_workspaces fw
ORDER BY
-- To ensure that 'favorite' workspaces show up first in the list only for their owner.
- CASE WHEN favorite AND owner_username = (SELECT users.username FROM users WHERE users.id = $25) THEN 0 ELSE 1 END ASC,
+ CASE WHEN favorite AND owner_username = (SELECT users.username FROM users WHERE users.id = $24) THEN 0 ELSE 1 END ASC,
(latest_build_completed_at IS NOT NULL AND
latest_build_canceled_at IS NULL AND
latest_build_error IS NULL AND
@@ -40087,11 +40033,11 @@ WHERE
LOWER(name) ASC
LIMIT
CASE
- WHEN $27 :: integer > 0 THEN
- $27
+ WHEN $26 :: integer > 0 THEN
+ $26
END
OFFSET
- $26
+ $25
), filtered_workspaces_order_with_summary AS (
SELECT
fwo.id, fwo.created_at, fwo.updated_at, fwo.owner_id, fwo.organization_id, fwo.template_id, fwo.deleted, fwo.name, fwo.autostart_schedule, fwo.ttl, fwo.last_used_at, fwo.dormant_at, fwo.deleting_at, fwo.automatic_updates, fwo.favorite, fwo.next_start_at, fwo.group_acl, fwo.user_acl, fwo.owner_avatar_url, fwo.owner_username, fwo.owner_name, fwo.organization_name, fwo.organization_display_name, fwo.organization_icon, fwo.organization_description, fwo.template_name, fwo.template_display_name, fwo.template_icon, fwo.template_description, fwo.task_id, fwo.group_acl_display_info, fwo.user_acl_display_info, fwo.template_version_id, fwo.template_version_name, fwo.latest_build_completed_at, fwo.latest_build_canceled_at, fwo.latest_build_error, fwo.latest_build_transition, fwo.latest_build_status, fwo.latest_build_has_external_agent, fwo.latest_build_provisioner_job_id
@@ -40144,7 +40090,7 @@ WHERE
false, -- latest_build_has_external_agent
'00000000-0000-0000-0000-000000000000'::uuid -- latest_build_provisioner_job_id
WHERE
- $28 :: boolean = true
+ $27 :: boolean = true
), total_count AS (
SELECT
count(*) AS count
@@ -40233,7 +40179,6 @@ type GetWorkspacesParams struct {
LastUsedBefore time.Time `db:"last_used_before" json:"last_used_before"`
LastUsedAfter time.Time `db:"last_used_after" json:"last_used_after"`
UsingActive sql.NullBool `db:"using_active" json:"using_active"`
- HasAITask sql.NullBool `db:"has_ai_task" json:"has_ai_task"`
HasExternalAgent sql.NullBool `db:"has_external_agent" json:"has_external_agent"`
Shared sql.NullBool `db:"shared" json:"shared"`
SharedWithUserID uuid.UUID `db:"shared_with_user_id" json:"shared_with_user_id"`
@@ -40314,7 +40259,6 @@ func (q *sqlQuerier) GetWorkspaces(ctx context.Context, arg GetWorkspacesParams)
arg.LastUsedBefore,
arg.LastUsedAfter,
arg.UsingActive,
- arg.HasAITask,
arg.HasExternalAgent,
arg.Shared,
arg.SharedWithUserID,
diff --git a/coderd/database/queries/templates.sql b/coderd/database/queries/templates.sql
index ba4836086448c..d05c78a61ad3a 100644
--- a/coderd/database/queries/templates.sql
+++ b/coderd/database/queries/templates.sql
@@ -71,12 +71,6 @@ WHERE
END
ELSE true
END
- -- Filter by has_ai_task in latest version
- AND CASE
- WHEN sqlc.narg('has_ai_task') :: boolean IS NOT NULL THEN
- tv.has_ai_task = sqlc.narg('has_ai_task') :: boolean
- ELSE true
- END
-- Filter by agents_allowed
AND CASE
WHEN sqlc.narg('agents_allowed') :: boolean IS NOT NULL THEN
diff --git a/coderd/database/queries/templateversions.sql b/coderd/database/queries/templateversions.sql
index e68383aa0632e..4813c0f83d92c 100644
--- a/coderd/database/queries/templateversions.sql
+++ b/coderd/database/queries/templateversions.sql
@@ -230,8 +230,7 @@ RETURNING template_versions.id;
UPDATE
template_versions
SET
- has_ai_task = $2,
- has_external_agent = $3,
- updated_at = $4
+ has_external_agent = $2,
+ updated_at = $3
WHERE
job_id = $1;
diff --git a/coderd/database/queries/workspacebuilds.sql b/coderd/database/queries/workspacebuilds.sql
index 390ffefab9e01..7afe146d39791 100644
--- a/coderd/database/queries/workspacebuilds.sql
+++ b/coderd/database/queries/workspacebuilds.sql
@@ -252,7 +252,6 @@ ORDER BY
UPDATE
workspace_builds
SET
- has_ai_task = @has_ai_task,
has_external_agent = @has_external_agent,
updated_at = @updated_at::timestamptz
WHERE id = @id::uuid;
diff --git a/coderd/database/queries/workspaces.sql b/coderd/database/queries/workspaces.sql
index 15251b56ca0a8..81d57c167f085 100644
--- a/coderd/database/queries/workspaces.sql
+++ b/coderd/database/queries/workspaces.sql
@@ -130,7 +130,6 @@ LEFT JOIN LATERAL (
workspace_builds.id,
workspace_builds.transition,
workspace_builds.template_version_id,
- workspace_builds.has_ai_task,
workspace_builds.has_external_agent,
template_versions.name AS template_version_name,
provisioner_jobs.id AS provisioner_job_id,
@@ -351,21 +350,6 @@ WHERE
(latest_build.template_version_id = template.active_version_id) = sqlc.narg('using_active') :: boolean
ELSE true
END
- -- Filter by has_ai_task, checks if this is a task workspace.
- AND CASE
- WHEN sqlc.narg('has_ai_task')::boolean IS NOT NULL
- THEN sqlc.narg('has_ai_task')::boolean = EXISTS (
- SELECT
- 1
- FROM
- tasks
- WHERE
- -- Consider all tasks, deleting a task does not turn the
- -- workspace into a non-task workspace.
- tasks.workspace_id = workspaces.id
- )
- ELSE true
- END
-- Filter by has_external_agent in latest build
AND CASE
WHEN sqlc.narg('has_external_agent') :: boolean IS NOT NULL THEN
diff --git a/coderd/provisionerdserver/provisionerdserver.go b/coderd/provisionerdserver/provisionerdserver.go
index 2052edd2c0b63..771b121a6d138 100644
--- a/coderd/provisionerdserver/provisionerdserver.go
+++ b/coderd/provisionerdserver/provisionerdserver.go
@@ -2038,9 +2038,6 @@ func (s *server) completeTemplateImportJob(ctx context.Context, job database.Pro
}
err = db.UpdateTemplateVersionFlagsByJobID(ctx, database.UpdateTemplateVersionFlagsByJobIDParams{
JobID: jobID,
- // Tasks are removed; the has_ai_task column is dropped in a
- // follow-up migration.
- HasAITask: sql.NullBool{Bool: false, Valid: true},
HasExternalAgent: sql.NullBool{
Bool: jobType.TemplateImport.HasExternalAgents,
Valid: true,
@@ -2320,9 +2317,6 @@ func (s *server) completeWorkspaceBuildJob(ctx context.Context, job database.Pro
})
if err := db.UpdateWorkspaceBuildFlagsByID(ctx, database.UpdateWorkspaceBuildFlagsByIDParams{
ID: workspaceBuild.ID,
- // Tasks are removed; the has_ai_task column is dropped in a
- // follow-up migration.
- HasAITask: sql.NullBool{Bool: false, Valid: true},
HasExternalAgent: sql.NullBool{
Bool: hasExternalAgent,
Valid: true,
diff --git a/docs/admin/security/audit-logs.md b/docs/admin/security/audit-logs.md
index c2e4d884b2bfa..8bfca3fe8b4da 100644
--- a/docs/admin/security/audit-logs.md
+++ b/docs/admin/security/audit-logs.md
@@ -45,11 +45,11 @@ We track the following resources:
| PrebuildsSettings
|
| Field | Tracked |
| | id | false |
| reconciliation_paused | true |
|
| RoleSyncSettings
| | Field | Tracked |
| | field | true |
| mapping | true |
|
| Template
write, delete | | Field | Tracked |
| | active_version_id | true |
| activity_bump | true |
| agents_allowed | true |
| allow_user_autostart | true |
| allow_user_autostop | true |
| allow_user_cancel_workspace_jobs | true |
| allow_workspace_renames | true |
| autostart_block_days_of_week | true |
| autostop_requirement_days_of_week | true |
| autostop_requirement_weeks | true |
| cors_behavior | true |
| created_at | false |
| created_by | true |
| created_by_avatar_url | false |
| created_by_name | false |
| created_by_username | false |
| default_ttl | true |
| deleted | false |
| deprecated | true |
| description | true |
| disable_module_cache | true |
| display_name | true |
| failure_ttl | true |
| group_acl | true |
| icon | true |
| id | true |
| max_port_sharing_level | true |
| name | true |
| organization_display_name | false |
| organization_icon | false |
| organization_id | false |
| organization_name | false |
| provisioner | true |
| require_active_version | true |
| time_til_autostop_notify | true |
| time_til_dormant | true |
| time_til_dormant_autodelete | true |
| updated_at | false |
| use_classic_parameter_flow | true |
| user_acl | true |
|
-| TemplateVersion
create, write | | Field | Tracked |
| | archived | true |
| created_at | false |
| created_by | true |
| created_by_avatar_url | false |
| created_by_name | false |
| created_by_username | false |
| external_auth_providers | false |
| has_ai_task | false |
| has_external_agent | false |
| id | true |
| job_id | false |
| message | false |
| name | true |
| organization_id | false |
| readme | true |
| source_example_id | false |
| template_id | true |
| updated_at | false |
|
+| TemplateVersion
create, write | | Field | Tracked |
| | archived | true |
| created_at | false |
| created_by | true |
| created_by_avatar_url | false |
| created_by_name | false |
| created_by_username | false |
| external_auth_providers | false |
| has_external_agent | false |
| id | true |
| job_id | false |
| message | false |
| name | true |
| organization_id | false |
| readme | true |
| source_example_id | false |
| template_id | true |
| updated_at | false |
|
| User
create, write, delete | | Field | Tracked |
| | avatar_url | false |
| chat_spend_limit_micros | true |
| created_at | false |
| deleted | true |
| email | true |
| github_com_user_id | false |
| hashed_one_time_passcode | false |
| hashed_password | true |
| id | true |
| is_service_account | true |
| is_system | true |
| last_seen_at | false |
| login_type | true |
| name | true |
| one_time_passcode_expires_at | true |
| quiet_hours_schedule | true |
| rbac_roles | true |
| status | true |
| updated_at | false |
| username | true |
|
| UserSecret
create, write, delete | | Field | Tracked |
| | created_at | false |
| description | true |
| enabled | true |
| env_name | true |
| file_path | true |
| id | true |
| name | true |
| updated_at | false |
| user_id | true |
| value | true |
| value_key_id | false |
|
| UserSkill
create, write, delete | | Field | Tracked |
| | content | true |
| created_at | false |
| description | true |
| id | true |
| name | true |
| updated_at | false |
| user_id | true |
|
-| WorkspaceBuild
start, stop | | Field | Tracked |
| | build_number | false |
| created_at | false |
| daily_cost | false |
| deadline | false |
| has_ai_task | false |
| has_external_agent | false |
| id | false |
| initiator_by_avatar_url | false |
| initiator_by_name | false |
| initiator_by_username | false |
| initiator_id | false |
| job_id | false |
| max_deadline | false |
| notified_autostop_deadline | false |
| reason | false |
| template_version_id | true |
| template_version_preset_id | false |
| transition | false |
| updated_at | false |
| workspace_id | false |
|
+| WorkspaceBuild
start, stop | | Field | Tracked |
| | build_number | false |
| created_at | false |
| daily_cost | false |
| deadline | false |
| has_external_agent | false |
| id | false |
| initiator_by_avatar_url | false |
| initiator_by_name | false |
| initiator_by_username | false |
| initiator_id | false |
| job_id | false |
| max_deadline | false |
| notified_autostop_deadline | false |
| reason | false |
| template_version_id | true |
| template_version_preset_id | false |
| transition | false |
| updated_at | false |
| workspace_id | false |
|
| WorkspaceProxy
| | Field | Tracked |
| | created_at | true |
| deleted | false |
| derp_enabled | true |
| derp_only | true |
| display_name | true |
| icon | true |
| id | true |
| name | true |
| region_id | true |
| token_hashed_secret | true |
| updated_at | false |
| url | true |
| version | true |
| wildcard_hostname | true |
|
| WorkspaceTable
| | Field | Tracked |
| | automatic_updates | true |
| autostart_schedule | true |
| created_at | false |
| deleted | false |
| deleting_at | true |
| dormant_at | true |
| favorite | true |
| group_acl | true |
| id | true |
| last_used_at | false |
| name | true |
| next_start_at | true |
| organization_id | false |
| owner_id | true |
| template_id | true |
| ttl | true |
| updated_at | false |
| user_acl | true |
|
diff --git a/enterprise/audit/table.go b/enterprise/audit/table.go
index e4339af2507ce..823db47223d5a 100644
--- a/enterprise/audit/table.go
+++ b/enterprise/audit/table.go
@@ -154,7 +154,6 @@ var auditableResourcesTypes = map[any]map[string]Action{
"created_by_name": ActionIgnore,
"archived": ActionTrack,
"source_example_id": ActionIgnore, // Never changes.
- "has_ai_task": ActionIgnore, // Never changes.
"has_external_agent": ActionIgnore, // Never changes.
},
&database.User{}: {
@@ -217,7 +216,6 @@ var auditableResourcesTypes = map[any]map[string]Action{
"initiator_by_username": ActionIgnore,
"initiator_by_name": ActionIgnore,
"template_version_preset_id": ActionIgnore, // Never changes.
- "has_ai_task": ActionIgnore, // Never changes.
"has_external_agent": ActionIgnore, // Never changes.
"notified_autostop_deadline": ActionIgnore, // Updated by the notification system, not by user action.
},