Skip to content

chore: migrate deployment variables to db#816

Merged
adityachoudhari26 merged 2 commits intomainfrom
migrate-deployment-variable
Feb 26, 2026
Merged

chore: migrate deployment variables to db#816
adityachoudhari26 merged 2 commits intomainfrom
migrate-deployment-variable

Conversation

@adityachoudhari26
Copy link
Member

@adityachoudhari26 adityachoudhari26 commented Feb 26, 2026

Summary by CodeRabbit

  • New Features

    • Added deployment variables support, enabling users to define, store, and manage variables scoped to deployments with properties including key, description, and default value.
  • Database

    • Created new deployment_variable table to persistently store deployment-level variables linked to deployments and workspaces.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 26, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 2efa138 and 2247ec5.

📒 Files selected for processing (5)
  • apps/workspace-engine/pkg/db/queries/schema.sql
  • packages/db/drizzle/0151_wooden_tyger_tiger.sql
  • packages/db/drizzle/meta/0151_snapshot.json
  • packages/db/drizzle/meta/_journal.json
  • packages/db/src/schema/deployment-variable.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/db/src/schema/deployment-variable.ts
  • apps/workspace-engine/pkg/db/queries/schema.sql

📝 Walkthrough

Walkthrough

This pull request introduces a new deployment_variable database entity with complete CRUD operations and repository-layer support. It adds database schema definitions in both SQLc (Go) and Drizzle (TypeScript), generates SQLc-based data access functions, implements a repository pattern with DB-backed persistence, and migrates existing in-memory deployment variables to the new database storage during workspace restoration.

Changes

Cohort / File(s) Summary
Database Schema
apps/workspace-engine/pkg/db/queries/schema.sql, packages/db/drizzle/0151_wooden_tyger_tiger.sql, packages/db/drizzle/meta/_journal.json, packages/db/src/schema/deployment-variable.ts, packages/db/src/schema/index.ts
Adds new deployment_variable table with uuid primary key, deployment_id foreign key (ON DELETE CASCADE), text key field, optional description and jsonb default_value columns; includes unique constraint on (deployment_id, key); updates Drizzle migration journal and schema exports.
SQLc Code Generation
apps/workspace-engine/pkg/db/models.go, apps/workspace-engine/pkg/db/deployment_variables.sql.go, apps/workspace-engine/pkg/db/queries/deployment_variables.sql, apps/workspace-engine/pkg/db/sqlc.yaml, packages/db/src/schema/resource-variable.ts
Generates Go CRUD methods (Get, List, Upsert, Delete) for deployment variables; adds DeploymentVariable and UpsertDeploymentVariableParams types; configures sqlc to map default_value column to []byte; minor import reformatting in resource-variable schema.
Repository Layer & Interfaces
apps/workspace-engine/pkg/workspace/store/repository/interfaces.go, apps/workspace-engine/pkg/workspace/store/repository/repo.go, apps/workspace-engine/pkg/workspace/store/repository/db/repo.go, apps/workspace-engine/pkg/workspace/store/repository/db/deploymentvariables/mapper.go, apps/workspace-engine/pkg/workspace/store/repository/db/deploymentvariables/repo.go, apps/workspace-engine/pkg/workspace/store/repository/memory/repo.go
Introduces DeploymentVariableRepo interface with Get, Set, Remove, Items, and GetByDeploymentID methods; implements DB-backed VariableRepo with UUID parsing and OAPI model conversion; adapts in-memory repo to new interface; adds mapper functions for DB↔OAPI transformations.
Store Integration & Migration
apps/workspace-engine/pkg/workspace/store/store.go, apps/workspace-engine/pkg/workspace/store/deployment_variables.go, apps/workspace-engine/pkg/workspace/store/deployments.go, apps/workspace-engine/svc/workspaceconsumer/consumer.go, apps/workspace-engine/test/integration/dbtest.go, apps/workspace-engine/pkg/persistence/integration_test.go
Adds WithDBDeploymentVariables() store option enabling DB persistence; migrates legacy in-memory deployment variables to DB during Store.Restore(); refactors DeploymentVariables field from in-memory to repository abstraction with SetRepo() injector; updates Variables(deploymentId) to use repository query; wires DB store option into consumer and test setup; updates integration test accessor from field to method call.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Poem

🐰 Hopping through schemas with schema so bright,
Variables now persist in the database tonight!
From memory to SQL, a migration so neat,
CRUD operations make deployment complete! 🌿

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 45.45% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'chore: migrate deployment variables to db' accurately describes the primary objective of the changeset, which comprehensively adds database support for deployment variables.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch migrate-deployment-variable

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (4)
apps/workspace-engine/pkg/workspace/store/deployments.go (1)

61-70: Consider logging the error before returning an empty map.

The error from GetByDeploymentID is silently discarded. While returning an empty map is a safe fallback, logging the error would help with debugging if database issues occur.

♻️ Proposed fix to add error logging
 func (e *Deployments) Variables(deploymentId string) map[string]*oapi.DeploymentVariable {
 	dvs, err := e.store.DeploymentVariables.repo.GetByDeploymentID(deploymentId)
 	if err != nil {
+		log.Error("Failed to get deployment variables", "deploymentId", deploymentId, "error", err)
 		return make(map[string]*oapi.DeploymentVariable)
 	}
 	vars := make(map[string]*oapi.DeploymentVariable, len(dvs))
 	for _, dv := range dvs {
 		vars[dv.Key] = dv
 	}
 	return vars
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/workspace-engine/pkg/workspace/store/deployments.go` around lines 61 -
70, The Variables method on Deployments silently swallows errors from
e.store.DeploymentVariables.repo.GetByDeploymentID; before returning the empty
map, log the error so failures are visible. Update Deployments.Variables to call
the component logger (e.logger or e.log if available) or add a logger field to
the Deployments struct and use e.logger.Errorf (or appropriate logging method)
to record the error with context like the deploymentId and the error value, then
continue returning the empty map.
apps/workspace-engine/pkg/workspace/store/repository/db/deploymentvariables/mapper.go (1)

20-25: Silent error handling on JSON unmarshal may hide data issues.

If json.Unmarshal fails, the error is silently swallowed and defaultValue remains nil. This could mask database corruption or schema migration issues. Consider logging at debug/warn level when unmarshal fails.

🔧 Optional: Log unmarshal failures
 	var defaultValue *oapi.LiteralValue
 	if row.DefaultValue != nil {
 		lv := &oapi.LiteralValue{}
-		if err := json.Unmarshal(row.DefaultValue, lv); err == nil {
+		if err := json.Unmarshal(row.DefaultValue, lv); err != nil {
+			// Log but don't fail - treat as missing value
+			log.Debug("failed to unmarshal default_value", "id", row.ID, "error", err)
+		} else {
 			defaultValue = lv
 		}
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/workspace-engine/pkg/workspace/store/repository/db/deploymentvariables/mapper.go`
around lines 20 - 25, The code swallows errors from json.Unmarshal when decoding
row.DefaultValue into lv, which can hide DB/schema issues; update the block in
mapper.go (the json.Unmarshal on row.DefaultValue that sets defaultValue/lv) to
check the err and log a debug or warn with the error and identifying context
(e.g., the row's id/name) instead of ignoring it, preserving the existing
behavior of leaving defaultValue nil on failure.
apps/workspace-engine/pkg/workspace/store/deployment_variables.go (1)

35-41: Unused id parameter in Upsert.

The id parameter is not used in this method - deploymentVariable.Id is used implicitly through repo.Set(). Consider removing it for clarity or documenting why it's kept for interface consistency.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/workspace-engine/pkg/workspace/store/deployment_variables.go` around
lines 35 - 41, The Upsert method on DeploymentVariables has an unused id
parameter; either remove the id parameter from the function signature and update
any interface and callers that reference DeploymentVariables.Upsert, or make the
parameter meaningful by assigning it to the payload before persisting (e.g., set
deploymentVariable.Id = id) and then call d.repo.Set(deploymentVariable) and
d.store.changeset.RecordUpsert(deploymentVariable); also ensure the public
interface/type that declares Upsert is updated consistently.
apps/workspace-engine/pkg/workspace/store/repository/db/deploymentvariables/repo.go (1)

29-32: DB error silently converted to not-found.

When GetDeploymentVariableByID returns an error (e.g., connection issue), it's indistinguishable from "not found" since both return nil, false. This is acceptable for the current interface but could make debugging harder.

🔧 Optional: Log DB errors in Get
 	row, err := db.GetQueries(r.ctx).GetDeploymentVariableByID(r.ctx, uid)
 	if err != nil {
+		if err != pgx.ErrNoRows {
+			log.Warn("Failed to get deployment variable", "id", id, "error", err)
+		}
 		return nil, false
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/workspace-engine/pkg/workspace/store/repository/db/deploymentvariables/repo.go`
around lines 29 - 32, The DB error from
db.GetQueries(r.ctx).GetDeploymentVariableByID is being swallowed into a generic
not-found return; change the error handling so you distinguish real "not found"
from other DB errors: after calling GetDeploymentVariableByID, if errors.Is(err,
sql.ErrNoRows) return nil, false, otherwise log the actual err (e.g. using the
repository logger like r.logger.Errorf or similar) and then return nil, false to
preserve the current API; import errors and database/sql/sql or sql.ErrNoRows as
needed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/workspace-engine/pkg/db/queries/schema.sql`:
- Around line 236-242: Add a foreign-key constraint on
deployment_variable.deployment_id so rows cannot reference a non-existent
deployment: update the CREATE TABLE for deployment_variable (or run an ALTER
TABLE if schema already exists) to add a FOREIGN KEY referencing the deployment
table's primary key (deployment.id) with an appropriate constraint name (e.g.,
fk_deployment_variable_deployment_id) and choose an on-delete policy such as ON
DELETE CASCADE (to remove variables when a deployment is deleted) or ON DELETE
RESTRICT depending on desired behavior.

In `@packages/db/drizzle/0151_motionless_winter_soldier.sql`:
- Around line 1-9: The migration dropped the unique constraint on
(deployment_id, key) causing duplicate keys per deployment; restore it by adding
a UNIQUE constraint or unique index on the deployment_variable table for the
columns (deployment_id, key) (e.g., ADD CONSTRAINT
deployment_variable_deployment_id_key_unique UNIQUE (deployment_id, key)) so
that the Go code in deployments.go (vars[dv.Key] = dv) and the
UpsertDeploymentVariable logic are protected against duplicate keys; ensure the
constraint name is unique and add it either in the CREATE TABLE statement for
deployment_variable or via an ALTER TABLE immediately after creation.

---

Nitpick comments:
In `@apps/workspace-engine/pkg/workspace/store/deployment_variables.go`:
- Around line 35-41: The Upsert method on DeploymentVariables has an unused id
parameter; either remove the id parameter from the function signature and update
any interface and callers that reference DeploymentVariables.Upsert, or make the
parameter meaningful by assigning it to the payload before persisting (e.g., set
deploymentVariable.Id = id) and then call d.repo.Set(deploymentVariable) and
d.store.changeset.RecordUpsert(deploymentVariable); also ensure the public
interface/type that declares Upsert is updated consistently.

In `@apps/workspace-engine/pkg/workspace/store/deployments.go`:
- Around line 61-70: The Variables method on Deployments silently swallows
errors from e.store.DeploymentVariables.repo.GetByDeploymentID; before returning
the empty map, log the error so failures are visible. Update
Deployments.Variables to call the component logger (e.logger or e.log if
available) or add a logger field to the Deployments struct and use
e.logger.Errorf (or appropriate logging method) to record the error with context
like the deploymentId and the error value, then continue returning the empty
map.

In
`@apps/workspace-engine/pkg/workspace/store/repository/db/deploymentvariables/mapper.go`:
- Around line 20-25: The code swallows errors from json.Unmarshal when decoding
row.DefaultValue into lv, which can hide DB/schema issues; update the block in
mapper.go (the json.Unmarshal on row.DefaultValue that sets defaultValue/lv) to
check the err and log a debug or warn with the error and identifying context
(e.g., the row's id/name) instead of ignoring it, preserving the existing
behavior of leaving defaultValue nil on failure.

In
`@apps/workspace-engine/pkg/workspace/store/repository/db/deploymentvariables/repo.go`:
- Around line 29-32: The DB error from
db.GetQueries(r.ctx).GetDeploymentVariableByID is being swallowed into a generic
not-found return; change the error handling so you distinguish real "not found"
from other DB errors: after calling GetDeploymentVariableByID, if errors.Is(err,
sql.ErrNoRows) return nil, false, otherwise log the actual err (e.g. using the
repository logger like r.logger.Errorf or similar) and then return nil, false to
preserve the current API; import errors and database/sql/sql or sql.ErrNoRows as
needed.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between bb0cd45 and 2efa138.

📒 Files selected for processing (23)
  • apps/workspace-engine/pkg/db/deployment_variables.sql.go
  • apps/workspace-engine/pkg/db/models.go
  • apps/workspace-engine/pkg/db/queries/deployment_variables.sql
  • apps/workspace-engine/pkg/db/queries/schema.sql
  • apps/workspace-engine/pkg/db/sqlc.yaml
  • apps/workspace-engine/pkg/persistence/integration_test.go
  • apps/workspace-engine/pkg/workspace/store/deployment_variables.go
  • apps/workspace-engine/pkg/workspace/store/deployments.go
  • apps/workspace-engine/pkg/workspace/store/repository/db/deploymentvariables/mapper.go
  • apps/workspace-engine/pkg/workspace/store/repository/db/deploymentvariables/repo.go
  • apps/workspace-engine/pkg/workspace/store/repository/db/repo.go
  • apps/workspace-engine/pkg/workspace/store/repository/interfaces.go
  • apps/workspace-engine/pkg/workspace/store/repository/memory/repo.go
  • apps/workspace-engine/pkg/workspace/store/repository/repo.go
  • apps/workspace-engine/pkg/workspace/store/store.go
  • apps/workspace-engine/svc/workspaceconsumer/consumer.go
  • apps/workspace-engine/test/integration/dbtest.go
  • packages/db/drizzle/0151_motionless_winter_soldier.sql
  • packages/db/drizzle/meta/0151_snapshot.json
  • packages/db/drizzle/meta/_journal.json
  • packages/db/src/schema/deployment-variable.ts
  • packages/db/src/schema/index.ts
  • packages/db/src/schema/resource-variable.ts

@adityachoudhari26 adityachoudhari26 merged commit 43f7057 into main Feb 26, 2026
11 of 12 checks passed
@adityachoudhari26 adityachoudhari26 deleted the migrate-deployment-variable branch February 26, 2026 03:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant