Skip to content

chore: Make workspace slug not null after migrate#3916

Merged
chronark merged 13 commits intomainfrom
workspace-slug-not-null
Sep 9, 2025
Merged

chore: Make workspace slug not null after migrate#3916
chronark merged 13 commits intomainfrom
workspace-slug-not-null

Conversation

@MichaelUnkey
Copy link
Collaborator

@MichaelUnkey MichaelUnkey commented Sep 4, 2025

What does this PR do?

Fixes # (issue)

If there is not an issue for this, please create one first. This is used to tracking purposes and also helps use understand why this PR exists

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • Chore (refactoring code, technical debt, workflow improvements)
  • Enhancement (small improvements)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How should this be tested?

  • Changes make sense. Tests pass. Nothing breaks

Checklist

Required

  • Filled out the "How to test" section in this PR
  • Read Contributing Guide
  • Self-reviewed my own code
  • Commented on my code in hard-to-understand areas
  • Ran pnpm build
  • Ran pnpm fmt
  • Checked for warnings, there are none
  • Removed all console.logs
  • Merged the latest changes from main onto my branch with git pull origin main
  • My changes don't cause any responsiveness issues

Appreciated

  • If a UI change was made: Added a screen recording or screenshots to this PR
  • Updated the Unkey Docs if changes were necessary

Summary by CodeRabbit

  • New Features

    • Automatically creates a Personal Workspace if none exists, assigning a unique slug.
  • Chores

    • Made workspace slugs required and persisted everywhere (DB, inserts, generated queries).
  • UI/Content

    • Email migration component now uses sensible default names/placeholders when fields are omitted.
  • Tests

    • Updated tests and seed data to include workspace slugs and improved header-copy handling in one test.

@changeset-bot
Copy link

changeset-bot bot commented Sep 4, 2025

⚠️ No Changeset found

Latest commit: 7c3a94f

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 4, 2025

Warning

Rate limit exceeded

@chronark has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 8 minutes and 13 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 7d1145b and 7c3a94f.

📒 Files selected for processing (1)
  • deployment/04-seed-workspace.sql (1 hunks)
📝 Walkthrough

Walkthrough

Make workspaces.slug non-nullable across DB and generated types, thread a required slug through inserts and tests, auto-generate a slug for dashboard personal workspace creation, and add runtime defaults to an email component's props.

Changes

Cohort / File(s) Summary
DB schema & generated SQLC types
go/pkg/db/schema.sql, go/pkg/db/queries/workspace_insert.sql, go/pkg/db/workspace_insert.sql_generated.go, go/pkg/db/querier_generated.go, go/pkg/db/models_generated.go, go/pkg/db/bulk_workspace_insert.sql.go
Add slug column to workspace INSERTs and SELECTs, make workspaces.slug NOT NULL in schema, and convert generated types/params to include a non-null Slug string (InsertWorkspaceParams, Workspace).
DB TS schema
internal/db/src/schema/workspaces.ts
Make slug column .notNull().unique() in the TS schema.
Seed & test helpers
go/pkg/testutil/seed/seed.go, go/pkg/db/retry_test.go, other tests under go/apps/api/...
Populate Slug in workspace insert calls used by tests and seed helpers (replace nullable usage with explicit Slug values).
API tests (JS/TS)
apps/api/src/routes/v1_keys_getVerifications.security.test.ts, other updated tests under apps/api/...
Update test fixtures to supply slug (replace inline random UUIDs with named variables where applied).
Dashboard: gateway-new personal workspace creation
apps/dashboard/app/(app)/gateway-new/page.tsx
Generate and set slug when auto-creating a Personal Workspace (uses personal-workspace-${randomInt(100000)}) prior to quotas insertion and redirect.
Email component defaults
internal/resend/emails/api_v1_migration.tsx
Change component to destructured props with runtime defaults: username = "User", workspaceName = "Your Workspace", deprecatedEndpoints = [].

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant Dashboard
  participant DB

  User->>Dashboard: GET /gateway-new
  Dashboard->>DB: Find workspace by org
  alt no workspace found
    Dashboard->>DB: Insert workspace { name: "Personal Workspace", slug: "personal-workspace-<rand>" }
    Dashboard->>DB: Insert quotas for workspace
    Dashboard-->>User: Redirect to new workspace page
  else workspace exists
    Dashboard-->>User: Redirect to existing workspace page
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • perkinsjr
  • mcstepp
  • imeyer

Pre-merge checks (1 passed, 2 warnings)

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The description’s “What does this PR do?” section remains unfilled boilerplate with no actual summary of changes, lacks a valid issue reference, motivation, context, or dependencies, and the testing section provides only a high-level assertion rather than concrete reproduction steps. Please replace the placeholder text with a clear summary of the slug non-null migration and its rationale, reference the correct issue number (or create one), list any dependencies or related work, and provide specific, step-by-step testing instructions or commands to verify the changes.
Docstring Coverage ⚠️ Warning Docstring coverage is 10.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Title Check ✅ Passed The title succinctly describes the primary change of making the workspace slug non-null post-migration, follows conventional commit styling, and clearly conveys the main intent without extraneous detail.
✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch workspace-slug-not-null

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.

@vercel
Copy link

vercel bot commented Sep 4, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
dashboard Ignored Ignored Preview Sep 9, 2025 7:03am
engineering Ignored Ignored Preview Sep 9, 2025 7:03am

@github-actions
Copy link
Contributor

github-actions bot commented Sep 4, 2025

Thank you for following the naming conventions for pull request titles! 🙏

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: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/dashboard/app/(app)/gateway-new/page.tsx (1)

27-42: Race on upsert + fragile slug entropy; handle duplicates and widen suffix space

  • TOCTOU: Two concurrent requests can both see no workspace and then one insert fails on orgId (UNIQUE) or slug (UNIQUE). Wrap insert in try/catch and refetch, or use an idempotent upsert.
  • Collisions: randomInt(100000) gives only 1e5 possibilities; at scale this risks hitting UNIQUE(slug). Use a wider suffix (e.g., fixed-length base36) and/or retry on duplicate.

Apply this minimal, defensive change:

@@
   if (!ws) {
     const id = newId("workspace");
-    await db.insert(schema.workspaces).values({
-      id,
-      name: "Personal Workspace",
-      slug: `personal-workspace-${randomInt(100000)}`,
-      orgId,
-      betaFeatures: {},
-      features: {},
-    });
+    // 8-char base36 suffix (~2.8e12 space), total slug length << 64
+    const suffix = randomInt(36 ** 8).toString(36).padStart(8, "0");
+    const slug = `personal-workspace-${suffix}`;
+    try {
+      await db.insert(schema.workspaces).values({
+        id,
+        name: "Personal Workspace",
+        slug,
+        orgId,
+        betaFeatures: {},
+        features: {},
+      });
+    } catch (e: any) {
+      // Ignore duplicate errors (orgId/slug) from a concurrent creator.
+      if (e?.code !== "ER_DUP_ENTRY" && e?.errno !== 1062) throw e;
+    }
 
-    await db.insert(schema.quotas).values({
-      workspaceId: id,
-      ...freeTierQuotas,
-    });
+    // Ensure quotas exist; refetch actual workspace id if our insert lost the race.
+    const current = await db.query.workspaces.findFirst({
+      where: (table, { eq, isNull, and }) => and(eq(table.orgId, orgId), isNull(table.deletedAtM)),
+    });
+    if (current) {
+      try {
+        await db.insert(schema.quotas).values({
+          workspaceId: current.id,
+          ...freeTierQuotas,
+        });
+      } catch (e: any) {
+        // Ignore duplicate if quotas already created in the competing request.
+        if (e?.code !== "ER_DUP_ENTRY" && e?.errno !== 1062) throw e;
+      }
+    }
   }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between f4183e2 and 22f3a0a.

📒 Files selected for processing (3)
  • apps/api/src/routes/v1_keys_getVerifications.security.test.ts (1 hunks)
  • apps/dashboard/app/(app)/gateway-new/page.tsx (2 hunks)
  • internal/db/src/schema/workspaces.ts (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Test Go API Local / Test
  • GitHub Check: Test API / API Test Local
  • GitHub Check: Test Packages / Test
  • GitHub Check: Build / Build
🔇 Additional comments (2)
apps/dashboard/app/(app)/gateway-new/page.tsx (1)

11-11: Import is fine for server runtime

randomInt from node:crypto is OK in this server-only route. No issues.

apps/api/src/routes/v1_keys_getVerifications.security.test.ts (1)

78-90: Cap test-generated slug to schema limit

  • In apps/api/src/routes/v1_keys_getVerifications.security.test.ts, append .slice(0, 64) after the regex chain to match the workspace.slug (varchar(64)) limit and avoid brittle failures:
-      .replace(/^-|-$/g, ""),
+      .replace(/^-|-$/g, "")
+      .slice(0, 64),
  • Optionally extract a shared slugify util (e.g., utils/slug.ts) for reuse in tests and client code to keep slug logic consistent.
  • Verify the workspace.slug column is defined as varchar(64) in your DB migrations/schema.

@chronark chronark requested a review from imeyer as a code owner September 9, 2025 06:22
@vercel vercel bot temporarily deployed to Preview – engineering September 9, 2025 06:28 Inactive
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/dashboard/app/(app)/gateway-new/page.tsx (1)

27-42: Harden the “upsert” against races and make it idempotent.

Current check-then-insert can race on concurrent gateway.new hits (unique orgId/slug). Either use DB upsert or catch-and-ignore duplicate key.

Minimal, driver-agnostic approach:

-    await db.insert(schema.workspaces).values({
+    try {
+      await db.insert(schema.workspaces).values({
         id,
         name: "Personal Workspace",
         slug: `personal-workspace-${randomUUID().slice(0, 8)}`,
         orgId,
         betaFeatures: {},
         features: {},
-    });
+      });
+    } catch (e: any) {
+      // MySQL: 1062 ER_DUP_ENTRY; ignore races on orgId/slug
+      if (e?.code !== "ER_DUP_ENTRY" && e?.errno !== 1062) throw e;
+    }
@@
-    await db.insert(schema.quotas).values({
+    try {
+      await db.insert(schema.quotas).values({
         workspaceId: id,
         ...freeTierQuotas,
-    });
+      });
+    } catch (e: any) {
+      if (e?.code !== "ER_DUP_ENTRY" && e?.errno !== 1062) throw e;
+    }
♻️ Duplicate comments (1)
go/pkg/db/schema.sql (1)

185-185: Migration safety: backfill before enforcing NOT NULL.

Ensure a two-step rollout:

  • Backfill all NULL slugs with a de-duped, <=64 value (in batches to avoid locks).
  • Then ALTER COLUMN to NOT NULL (online DDL) and keep UNIQUE(slug).

If any seed/test writers still omit slug, the migration will fail. Refer to the earlier verification agent’s repository-wide scan; rerun it after the latest changes.

I can open a thorough tracking issue (Summary/Impact/Repro/AC/Validation/References) per imeyer’s preference—say the word and I’ll draft it.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 740961a and 3ed8d1f.

📒 Files selected for processing (4)
  • apps/api/src/routes/v1_keys_getVerifications.security.test.ts (1 hunks)
  • apps/dashboard/app/(app)/gateway-new/page.tsx (2 hunks)
  • go/pkg/db/schema.sql (1 hunks)
  • internal/db/src/schema/workspaces.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: imeyer
PR: unkeyed/unkey#3755
File: .github/workflows/runbook-freshness-check.yaml:157-173
Timestamp: 2025-08-08T14:59:52.283Z
Learning: Repo unkeyed/unkey: When a CI/workflow fix is deferred, imeyer prefers a thorough GitHub issue be opened with sections (Summary, Impact, Where, Repro, Observed vs Expected, Acceptance Criteria, Validation Plan, Out of Scope, References) and assigned to imeyer, including backlinks to the originating PR and comment.
Learnt from: imeyer
PR: unkeyed/unkey#3755
File: .github/workflows/job_detect_changes.yaml:111-114
Timestamp: 2025-08-08T16:10:00.224Z
Learning: Repo: unkeyed/unkey — When imeyer writes “make me an issue” on a PR thread, automatically open a thorough GitHub issue (Summary, Impact, Where, Repro, Observed vs Expected, Acceptance Criteria, Validation Plan, Out of Scope, References), include backlinks to the PR and comment, and assign to imeyer.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Test API / API Test Local
🔇 Additional comments (1)
apps/api/src/routes/v1_keys_getVerifications.security.test.ts (1)

78-84: LGTM: test aligned to NOT NULL slug.

Using a UUID for both name and slug satisfies length and uniqueness constraints for the fixture.

@vercel vercel bot temporarily deployed to Preview – dashboard September 9, 2025 06:32 Inactive
@Flo4604
Copy link
Member

Flo4604 commented Sep 9, 2025

Tests are currently failing and the changes also have to be done for the go schema and any place where the go code inserts workspaces

Copy link
Collaborator

chronark commented Sep 9, 2025

yeah fixed it already

Copy link
Member

Flo4604 commented Sep 9, 2025

👌

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: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
internal/resend/emails/api_v1_migration.tsx (2)

26-28: Fix Tailwind class typo (“text-semibold” → “font-semibold”).

Ensures the heading actually renders semibold.

-      <Heading className="font-sans text-3xl text-semibold text-center">
+      <Heading className="font-sans text-3xl font-semibold text-center">

37-39: Avoid hard-coding the EOL date; centralize/configure it.

Move the date to a shared constant or env so updates don’t require code edits.

Example:

// top-level or shared config
const API_V1_EOL_DISPLAY = "January 1, 2026";
...
<Text className="font-semibold text-red-600">
  Important: <span className="font-mono">api.unkey.dev/v1</span> will be discontinued on {API_V1_EOL_DISPLAY}.
</Text>
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3ed8d1f and 9685417.

📒 Files selected for processing (1)
  • internal/resend/emails/api_v1_migration.tsx (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Test API / API Test Local
  • GitHub Check: Test Go API Local / Test
  • GitHub Check: Test Packages / Test

@vercel vercel bot temporarily deployed to Preview – dashboard September 9, 2025 06:44 Inactive
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: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (7)
go/apps/api/routes/v2_identities_list_identities/200_test.go (1)

54-87: Compile-time bug: cannot range over int (totalIdentities)

for i := range totalIdentities is invalid; use a classic for loop.

- const totalIdentities = 15
- var externalIDs []string
- for i := range totalIdentities {
+ const totalIdentities = 15
+ var externalIDs []string
+ for i := 0; i < totalIdentities; i++ {

Optionally preallocate for fewer allocs:

- var externalIDs []string
+ externalIDs := make([]string, 0, totalIdentities)
go/apps/api/routes/v2_identities_list_identities/400_test.go (1)

82-114: Use testutil.CallRaw for malformed JSON test
The test builds a raw http.Request with invalid JSON but then calls CallRoute, which re-marshals a valid struct—so the malformed body is never sent. Replace the CallRoute invocation with:

res := testutil.CallRaw[openapi.BadRequestErrorResponse](h, req)

to exercise the JSON parse error.

go/pkg/testutil/seed/seed.go (2)

49-55: Optional: derive a readable slug from the name for seed data.

Using uid.New("slug") is fine; for debuggability you could slugify the name (lowercase, hyphenated). Example:

name := uid.New("test_name")
slug := strings.ToLower(strings.ReplaceAll(name, " ", "-"))
params := db.InsertWorkspaceParams{
  ID: uid.New("test_ws"),
  OrgID: uid.New("test_org"),
  Name: name,
  Slug: slug,
  CreatedAt: time.Now().UnixMilli(),
}

Remember to import "strings".


430-433: Bug: incorrect assertions validate WorkspaceID instead of Name/Slug.

These checks won’t catch empty Name/Slug. Fix as below.

- require.NoError(s.t, assert.NotEmpty(req.WorkspaceID, "Permission Name must be set"))
- require.NoError(s.t, assert.NotEmpty(req.WorkspaceID, "Permission Slug must be set"))
+ require.NoError(s.t, assert.NotEmpty(req.Name, "Permission Name must be set"))
+ require.NoError(s.t, assert.NotEmpty(req.Slug, "Permission Slug must be set"))
go/pkg/db/models_generated.go (1)

770-776: Include Slug in all InsertWorkspaceParams literals
Tests and seed data (e.g., go/pkg/testutil/seed/seed.go, go/pkg/db/retry_test.go, and various apps/api/routes/* tests) must set the new non-nullable Slug field.

go/pkg/db/queries/workspace_insert.sql (1)

20-23: Tier literal casing could diverge from code enums.

Insert uses 'Free' while WorkspacesPlan constants appear lower-case ('free'). Aligning avoids surprises in comparisons.

-    'Free',
+    'free',
go/pkg/db/querier_generated.go (1)

1186-1210: Add missing backfill migration for slug
No migration was found that populates slug on existing workspaces—add an UPDATE workspaces SET slug=… (e.g. derived from name) before enforcing NOT NULL.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9685417 and 7d1145b.

📒 Files selected for processing (14)
  • go/apps/api/routes/v2_identities_list_identities/200_test.go (1 hunks)
  • go/apps/api/routes/v2_identities_list_identities/400_test.go (2 hunks)
  • go/apps/api/routes/v2_identities_list_identities/cross_workspace_test.go (1 hunks)
  • go/apps/api/routes/v2_keys_add_permissions/404_test.go (1 hunks)
  • go/apps/api/routes/v2_keys_remove_permissions/403_test.go (1 hunks)
  • go/apps/api/routes/v2_keys_remove_permissions/404_test.go (2 hunks)
  • go/apps/api/routes/v2_keys_set_roles/404_test.go (2 hunks)
  • go/pkg/db/bulk_workspace_insert.sql.go (3 hunks)
  • go/pkg/db/models_generated.go (1 hunks)
  • go/pkg/db/querier_generated.go (2 hunks)
  • go/pkg/db/queries/workspace_insert.sql (2 hunks)
  • go/pkg/db/retry_test.go (1 hunks)
  • go/pkg/db/workspace_insert.sql_generated.go (6 hunks)
  • go/pkg/testutil/seed/seed.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
go/pkg/testutil/seed/seed.go (1)
go/pkg/uid/uid.go (1)
  • New (97-127)
go/apps/api/routes/v2_keys_remove_permissions/403_test.go (1)
go/pkg/testutil/seed/seed.go (1)
  • New (39-46)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Build / Build
  • GitHub Check: Test Packages / Test
  • GitHub Check: Test API / API Test Local
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (14)
go/apps/api/routes/v2_keys_set_roles/404_test.go (1)

151-157: Slug added to InsertWorkspace — LGTM

Supplying Slug is required post-migration; using uid.New("slug") avoids uniqueness collisions in parallel tests.
Unable to automatically verify all InsertWorkspaceParams initializations include a Slug field due to environment limitations—please manually confirm no instances remain missing a Slug field.

go/apps/api/routes/v2_keys_add_permissions/404_test.go (1)

80-86: Populate slug on workspace insert — looks correct

Matches the NOT NULL schema. No further action.

go/apps/api/routes/v2_identities_list_identities/200_test.go (1)

292-298: Slug added to single-workspace setup — OK

Consistent with new schema requirements.

go/apps/api/routes/v2_keys_remove_permissions/403_test.go (1)

112-119: Slug supplied on other workspace insert — good

Aligns tests with NOT NULL slug constraint.

go/apps/api/routes/v2_identities_list_identities/cross_workspace_test.go (1)

45-52: Slug passed on workspace insert: looks good.

Providing Slug in InsertWorkspaceParams unblocks the NOT NULL constraint and keeps this test self-contained.

go/pkg/db/retry_test.go (1)

142-149: Populate slug in integration setup: good catch.

Including Slug in InsertWorkspaceParams aligns the test with the new schema and generated types.

go/apps/api/routes/v2_keys_remove_permissions/404_test.go (1)

114-124: Added slug on workspace inserts in tests: all set.

Both inserts now satisfy the NOT NULL slug constraint.

Also applies to: 186-196

go/pkg/db/queries/workspace_insert.sql (1)

2-9: Remove migration/backfill verification—slug already exists as NOT NULL with a UNIQUE constraint.

Likely an incorrect or invalid review comment.

go/pkg/db/bulk_workspace_insert.sql.go (3)

11-13: Bulk insert column list updated: good.

Slug added to the column list; matches generated single-row insert.


24-25: Values placeholder count matches column count.

Now five positional args before literals — correct.


32-37: Args collection includes Slug in correct order.

Order aligns with VALUES tuple. Looks good.

go/pkg/db/workspace_insert.sql_generated.go (2)

39-45: InsertWorkspaceParams adds Slug: good.

Public API now enforces the invariant at compile-time.


73-80: Parameter binding order correct.

Slug is passed between Name and CreatedAt consistently with the SQL.

go/pkg/db/querier_generated.go (1)

1186-1210: Slug added to InsertWorkspace: looks correct.

Column list and VALUES placeholders now include slug; counts align; constants remain unchanged. No issues on the generated side.

@chronark chronark merged commit c6c7206 into main Sep 9, 2025
17 checks passed
@chronark chronark deleted the workspace-slug-not-null branch September 9, 2025 07:15
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.

3 participants