From 5e90dc256658db4b6046f1c076243b45b490a608 Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Tue, 17 Jun 2025 11:09:55 +0000 Subject: [PATCH 1/2] migrations --- .../migrations/000337_nullable_has_ai_task.down.sql | 4 ++++ .../database/migrations/000337_nullable_has_ai_task.up.sql | 7 +++++++ 2 files changed, 11 insertions(+) create mode 100644 coderd/database/migrations/000337_nullable_has_ai_task.down.sql create mode 100644 coderd/database/migrations/000337_nullable_has_ai_task.up.sql diff --git a/coderd/database/migrations/000337_nullable_has_ai_task.down.sql b/coderd/database/migrations/000337_nullable_has_ai_task.down.sql new file mode 100644 index 0000000000000..54f2f3144acad --- /dev/null +++ b/coderd/database/migrations/000337_nullable_has_ai_task.down.sql @@ -0,0 +1,4 @@ +ALTER TABLE template_versions ALTER COLUMN has_ai_task SET DEFAULT false; +ALTER TABLE template_versions ALTER COLUMN has_ai_task SET NOT NULL; +ALTER TABLE workspace_builds ALTER COLUMN has_ai_task SET DEFAULT false; +ALTER TABLE workspace_builds ALTER COLUMN has_ai_task SET NOT NULL; diff --git a/coderd/database/migrations/000337_nullable_has_ai_task.up.sql b/coderd/database/migrations/000337_nullable_has_ai_task.up.sql new file mode 100644 index 0000000000000..7604124fda902 --- /dev/null +++ b/coderd/database/migrations/000337_nullable_has_ai_task.up.sql @@ -0,0 +1,7 @@ +-- The fields must be nullable because there's a period of time between +-- inserting a row into the database and finishing the "plan" provisioner job +-- when the final value of the field is unknown. +ALTER TABLE template_versions ALTER COLUMN has_ai_task DROP DEFAULT; +ALTER TABLE template_versions ALTER COLUMN has_ai_task DROP NOT NULL; +ALTER TABLE workspace_builds ALTER COLUMN has_ai_task DROP DEFAULT; +ALTER TABLE workspace_builds ALTER COLUMN has_ai_task DROP NOT NULL; From a68a73d7ef94dfdb3b0b6bc8535fc32bdc5dda11 Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Tue, 17 Jun 2025 11:13:08 +0000 Subject: [PATCH 2/2] make gen --- coderd/database/dump.sql | 4 ++-- coderd/database/models.go | 8 ++++---- coderd/database/queries.sql.go | 4 ++-- coderd/templateversions.go | 5 ++++- coderd/wsbuilder/wsbuilder.go | 5 ++++- 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql index cd0a0993e2951..457ba8e65ce5a 100644 --- a/coderd/database/dump.sql +++ b/coderd/database/dump.sql @@ -1555,7 +1555,7 @@ 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 DEFAULT false NOT NULL + has_ai_task boolean ); COMMENT ON COLUMN template_versions.external_auth_providers IS 'IDs of External auth providers for a specific template version'; @@ -2084,7 +2084,7 @@ 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 DEFAULT false NOT NULL, + has_ai_task boolean, ai_tasks_sidebar_app_id uuid ); diff --git a/coderd/database/models.go b/coderd/database/models.go index 0180cd6ac7b7f..c54a218d4b41d 100644 --- a/coderd/database/models.go +++ b/coderd/database/models.go @@ -3358,7 +3358,7 @@ 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 bool `db:"has_ai_task" json:"has_ai_task"` + HasAITask sql.NullBool `db:"has_ai_task" json:"has_ai_task"` CreatedByAvatarURL string `db:"created_by_avatar_url" json:"created_by_avatar_url"` CreatedByUsername string `db:"created_by_username" json:"created_by_username"` CreatedByName string `db:"created_by_name" json:"created_by_name"` @@ -3435,7 +3435,7 @@ 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 bool `db:"has_ai_task" json:"has_ai_task"` + HasAITask sql.NullBool `db:"has_ai_task" json:"has_ai_task"` } type TemplateVersionTerraformValue struct { @@ -3850,7 +3850,7 @@ 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 bool `db:"has_ai_task" json:"has_ai_task"` + HasAITask sql.NullBool `db:"has_ai_task" json:"has_ai_task"` AITasksSidebarAppID uuid.NullUUID `db:"ai_tasks_sidebar_app_id" json:"ai_tasks_sidebar_app_id"` InitiatorByAvatarUrl string `db:"initiator_by_avatar_url" json:"initiator_by_avatar_url"` InitiatorByUsername string `db:"initiator_by_username" json:"initiator_by_username"` @@ -3881,7 +3881,7 @@ 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 bool `db:"has_ai_task" json:"has_ai_task"` + HasAITask sql.NullBool `db:"has_ai_task" json:"has_ai_task"` AITasksSidebarAppID uuid.NullUUID `db:"ai_tasks_sidebar_app_id" json:"ai_tasks_sidebar_app_id"` } diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go index 9a814a5b6dff8..3b44aae2d294f 100644 --- a/coderd/database/queries.sql.go +++ b/coderd/database/queries.sql.go @@ -11828,7 +11828,7 @@ type InsertTemplateVersionParams struct { JobID uuid.UUID `db:"job_id" json:"job_id"` CreatedBy uuid.UUID `db:"created_by" json:"created_by"` SourceExampleID sql.NullString `db:"source_example_id" json:"source_example_id"` - HasAITask bool `db:"has_ai_task" json:"has_ai_task"` + HasAITask sql.NullBool `db:"has_ai_task" json:"has_ai_task"` } func (q *sqlQuerier) InsertTemplateVersion(ctx context.Context, arg InsertTemplateVersionParams) error { @@ -17546,7 +17546,7 @@ type InsertWorkspaceBuildParams struct { MaxDeadline time.Time `db:"max_deadline" json:"max_deadline"` Reason BuildReason `db:"reason" json:"reason"` TemplateVersionPresetID uuid.NullUUID `db:"template_version_preset_id" json:"template_version_preset_id"` - HasAITask bool `db:"has_ai_task" json:"has_ai_task"` + HasAITask sql.NullBool `db:"has_ai_task" json:"has_ai_task"` } func (q *sqlQuerier) InsertWorkspaceBuild(ctx context.Context, arg InsertWorkspaceBuildParams) error { diff --git a/coderd/templateversions.go b/coderd/templateversions.go index 23ce3eaebb4f8..d9f9c3db42dd6 100644 --- a/coderd/templateversions.go +++ b/coderd/templateversions.go @@ -1732,7 +1732,10 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht }, // appease the exhaustruct linter // TODO: set this to whether the template version defines a `coder_ai_task` tf resource - HasAITask: false, + HasAITask: sql.NullBool{ + Bool: false, + Valid: false, + }, }) if err != nil { if database.IsUniqueViolation(err, database.UniqueTemplateVersionsTemplateIDNameKey) { diff --git a/coderd/wsbuilder/wsbuilder.go b/coderd/wsbuilder/wsbuilder.go index 8a6d04272830b..9605df58014de 100644 --- a/coderd/wsbuilder/wsbuilder.go +++ b/coderd/wsbuilder/wsbuilder.go @@ -427,7 +427,10 @@ func (b *Builder) buildTx(authFunc func(action policy.Action, object rbac.Object }, // appease the exhaustruct linter // TODO: set this to whether the build included a `coder_ai_task` tf resource - HasAITask: false, + HasAITask: sql.NullBool{ + Bool: false, + Valid: false, + }, }) if err != nil { code := http.StatusInternalServerError