Skip to content

Conversation

@kingston
Copy link
Collaborator

@kingston kingston commented Dec 22, 2025

Summary by CodeRabbit

  • Bug Fixes
    • Enabling a new plugin via the web config editor now correctly sets the plugin's migration/config schema version; updating existing plugins preserves their prior schema version.

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link

vercel bot commented Dec 22, 2025

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

Project Deployment Review Updated (UTC)
baseplate-project-builder-web Ready Ready Preview, Comment Dec 22, 2025 8:41am

@changeset-bot
Copy link

changeset-bot bot commented Dec 22, 2025

🦋 Changeset detected

Latest commit: 243c531

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 18 packages
Name Type
@baseplate-dev/project-builder-lib Patch
@baseplate-dev/project-builder-cli Patch
@baseplate-dev/project-builder-common Patch
@baseplate-dev/project-builder-server Patch
@baseplate-dev/project-builder-test Patch
@baseplate-dev/project-builder-web Patch
@baseplate-dev/plugin-auth Patch
@baseplate-dev/plugin-queue Patch
@baseplate-dev/plugin-storage Patch
@baseplate-dev/create-project Patch
@baseplate-dev/code-morph Patch
@baseplate-dev/core-generators Patch
@baseplate-dev/fastify-generators Patch
@baseplate-dev/react-generators Patch
@baseplate-dev/sync Patch
@baseplate-dev/tools Patch
@baseplate-dev/ui-components Patch
@baseplate-dev/utils Patch

Not sure what this means? Click here to learn what changesets are.

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

@coderabbitai
Copy link

coderabbitai bot commented Dec 22, 2025

Walkthrough

This PR fixes a bug where plugin config migration versions were not set correctly when enabling new plugins via the web config editor. The main change updates the setPluginConfig function signature to accept a ProjectDefinitionContainer instead of PluginImplementationStore, enabling proper migration version calculation for newly added plugins by constructing a temporary plugin store with the new plugin included.

Changes

Cohort / File(s) Summary
Changeset
.changeset/fix-plugin-config-migration-version.md
Added a patch changeset entry documenting the fix and version bump.
Plugin config core
packages/project-builder-lib/src/definition/plugins/plugin-utils.ts
Changed setPluginConfig signature to accept ProjectDefinitionContainer. Detects new plugins and, when adding, builds a temporary plugin implementation store (including the new plugin) to compute the correct last migration version before inserting plugin entry; preserves prior update path for existing plugins.
Plugin utils tests
packages/project-builder-lib/src/definition/plugins/plugin-utils.unit.test.ts, packages/project-builder-lib/src/plugins/plugins.test-utils.ts
Tests updated to use a test container helper (createTestContainerWithAvailablePlugins) that populates parserContext.pluginStore.availablePlugins; removed createTestPluginImplementationStore export. Added/modified tests to assert config schema version behavior for new vs existing plugins.
Model merger
packages/project-builder-lib/src/tools/model-merger/model-merger.ts
Model resolution in applyModelMergerDiff now tries ModelUtils.byName first, then falls back to byIdOrThrow; error message for missing fields expanded to include parent model name.
Call sites — pass container
Web & Plugins UI
packages/project-builder-web/src/routes/plugins/-components/plugin-card.tsx, plugins/plugin-auth/.../auth-definition-editor.tsx, plugins/plugin-auth/.../auth0-definition-editor.tsx, plugins/plugin-auth/.../local-auth-definition-editor.tsx, plugins/plugin-auth/.../placeholder-auth-definition-editor.tsx, plugins/plugin-queue/.../pg-boss-definition-editor.tsx, plugins/plugin-queue/.../queue-definition-editor.tsx, plugins/plugin-storage/.../storage-definition-editor.tsx
Updated PluginUtils.setPluginConfig call sites to pass the full definitionContainer (instead of definitionContainer.pluginStore). In storage editor, also pass updatedData (form-derived) instead of raw data.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Review the new-plugin detection and temporary plugin-store construction in setPluginConfig for edge cases (e.g., plugins without migrations, conflicting IDs/names).
  • Verify tests: ensure test container setup correctly registers migrations and that removed test util isn't referenced elsewhere.
  • Confirm all UI call sites were updated consistently and that updatedData usage in storage editor has correct shape.
  • Check model-merger name-first lookup for correctness and that error message change is acceptable.

Possibly related PRs

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.69% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately and specifically describes the main change: fixing the plugin config migration version not being set correctly when enabling a new plugin via web config editor.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch kingston/eng-933-cannot-find-model-by-id-for-user-when-enabling-storage

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • 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 52ddcbe and 243c531.

📒 Files selected for processing (1)
  • packages/project-builder-lib/src/plugins/plugins.test-utils.ts
💤 Files with no reviewable changes (1)
  • packages/project-builder-lib/src/plugins/plugins.test-utils.ts
⏰ 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). (5)
  • GitHub Check: Verify Sync (todo-with-auth0)
  • GitHub Check: Verify Sync (blog-with-auth)
  • GitHub Check: Test E2E
  • GitHub Check: Lint
  • GitHub Check: test

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

@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: 0

🧹 Nitpick comments (2)
packages/project-builder-lib/src/tools/model-merger/model-merger.ts (2)

460-469: Consider adding a comment to clarify the two-step lookup pattern.

The change from direct byIdOrThrow lookup to byName ?? byIdOrThrow makes the resolution more flexible by accepting both names and IDs. This is useful since the resolver function may receive either format after the serialization/deserialization cycle. However, the code would benefit from a brief comment explaining this.

Additionally, the improved error message on line 466 that includes ${model.name} is clearer than using the potentially ambiguous modelId parameter.

Optional: Add clarifying comment
      },
      (modelId, fieldName) => {
        const siblingModel = siblingModels.find(
          (m) => m.id === modelId || m.name === modelId,
        );
        if (siblingModel) {
          const field = siblingModel.model.fields.find(
            (f) => f.name === fieldName,
          );
          if (!field) {
            throw new Error(
              `Field ${fieldName} not found in sibling model ${modelId}`,
            );
          }
          return field.id;
        }
+       // modelId may be either a name (from desired state) or an ID (from current state)
+       // Try name-based lookup first, then fall back to ID-based lookup
        const model =
          ModelUtils.byName(definitionContainer.definition, modelId) ??
          ModelUtils.byIdOrThrow(definitionContainer.definition, modelId);
        const field = model.model.fields.find((f) => f.name === fieldName);
        if (!field) {
          throw new Error(
            `Field ${fieldName} not found in model ${model.name}`,
          );
        }
        return field.id;
      },

512-516: Consistent two-step lookup pattern; consider adding a clarifying comment.

Similar to the earlier change, this implements the same defensive two-step lookup pattern (byName ?? byIdOrThrow) for modelRef resolution, and explicitly returns the resolved model.id. This ensures consistency and handles both name and ID references robustly.

The same suggestion applies here: a brief comment explaining why both lookups are necessary would improve maintainability.

Optional: Add clarifying comment
      (modelRef) => {
        const siblingModel = siblingModels.find(
          (m) => m.id === modelRef || m.name === modelRef,
        );
        if (siblingModel) {
          return siblingModel.id;
        }

+       // modelRef may be either a name or an ID after serialization/deserialization
+       // Try name-based lookup first, then fall back to ID-based lookup
        const model =
          ModelUtils.byName(definitionContainer.definition, modelRef) ??
          ModelUtils.byIdOrThrow(definitionContainer.definition, modelRef);
        return model.id;
      },
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • 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 0851584 and 52ddcbe.

📒 Files selected for processing (12)
  • .changeset/fix-plugin-config-migration-version.md
  • packages/project-builder-lib/src/definition/plugins/plugin-utils.ts
  • packages/project-builder-lib/src/definition/plugins/plugin-utils.unit.test.ts
  • packages/project-builder-lib/src/tools/model-merger/model-merger.ts
  • packages/project-builder-web/src/routes/plugins/-components/plugin-card.tsx
  • plugins/plugin-auth/src/auth/core/components/auth-definition-editor.tsx
  • plugins/plugin-auth/src/auth0/core/components/auth0-definition-editor.tsx
  • plugins/plugin-auth/src/local-auth/core/components/local-auth-definition-editor.tsx
  • plugins/plugin-auth/src/placeholder-auth/core/components/placeholder-auth-definition-editor.tsx
  • plugins/plugin-queue/src/pg-boss/core/components/pg-boss-definition-editor.tsx
  • plugins/plugin-queue/src/queue/core/components/queue-definition-editor.tsx
  • plugins/plugin-storage/src/storage/core/components/storage-definition-editor.tsx
🧰 Additional context used
📓 Path-based instructions (8)
plugins/**/plugin-*/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (plugins/CLAUDE.md)

All CSS classes used in className attributes within plugin components MUST be prefixed with the plugin name (e.g., auth:, storage:) to avoid style conflicts between plugins and the main application

Files:

  • plugins/plugin-storage/src/storage/core/components/storage-definition-editor.tsx
  • plugins/plugin-auth/src/placeholder-auth/core/components/placeholder-auth-definition-editor.tsx
  • plugins/plugin-auth/src/auth/core/components/auth-definition-editor.tsx
  • plugins/plugin-auth/src/auth0/core/components/auth0-definition-editor.tsx
  • plugins/plugin-queue/src/pg-boss/core/components/pg-boss-definition-editor.tsx
  • plugins/plugin-auth/src/local-auth/core/components/local-auth-definition-editor.tsx
  • plugins/plugin-queue/src/queue/core/components/queue-definition-editor.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/code-style.mdc)

**/*.{ts,tsx}: Use TypeScript with strict type checking enabled
Always include return types on top-level functions including React components (React.ReactElement)
Include absolute paths in import statements via tsconfig paths (@src/ is the alias for src/)
If a particular interface or type is not exported, change the file so it is exported
If caught on a typing loop where forcing the any type is necessary, do not iterate too much - leave the typing as broken and let the user fix it

If target code is not easily testable, refactor it to be more testable (e.g., export types or functions)

**/*.{ts,tsx}: Import components from '@baseplate-dev/ui-components' package for UI development (e.g., Button, Input, Card, Dialog, etc.)
Use form components with React Hook Form controller variants (InputField, TextareaField, SelectField, CheckboxField, SwitchField, ComboboxField, MultiComboboxField, ColorPickerField, DatePickerField, DateTimePickerField)
Use SidebarLayout, Card, Breadcrumb, NavigationMenu, and NavigationTabs components for consistent layout structure from @baseplate-dev/ui-components
Use Dialog, ConfirmDialog, and useConfirmDialog from @baseplate-dev/ui-components for modal dialogs and confirmation interactions
Always use compareStrings from @baseplate-dev/utils instead of String.prototype.localeCompare() for code generation, file sorting, and internal data structures
If a particular interface or type is not exported, modify the file to export it
Use TsCodeFragment for composable code pieces and TsCodeUtils for manipulating fragments when generating TypeScript code
Create generators using createGenerator with configuration via descriptor schema (Zod), organizing into one or more tasks created with createGeneratorTask
Tasks should have run (initialization) and build (code generation) phases, export and consume providers, and may be organized into phases for ordered execution
Use provider scopes to control visibility and prevent collisions be...

Files:

  • plugins/plugin-storage/src/storage/core/components/storage-definition-editor.tsx
  • packages/project-builder-lib/src/tools/model-merger/model-merger.ts
  • packages/project-builder-lib/src/definition/plugins/plugin-utils.unit.test.ts
  • plugins/plugin-auth/src/placeholder-auth/core/components/placeholder-auth-definition-editor.tsx
  • plugins/plugin-auth/src/auth/core/components/auth-definition-editor.tsx
  • plugins/plugin-auth/src/auth0/core/components/auth0-definition-editor.tsx
  • plugins/plugin-queue/src/pg-boss/core/components/pg-boss-definition-editor.tsx
  • plugins/plugin-auth/src/local-auth/core/components/local-auth-definition-editor.tsx
  • packages/project-builder-lib/src/definition/plugins/plugin-utils.ts
  • plugins/plugin-queue/src/queue/core/components/queue-definition-editor.tsx
  • packages/project-builder-web/src/routes/plugins/-components/plugin-card.tsx
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/code-style.mdc)

**/*.{ts,tsx,js}: Node 16 module resolution - include file extensions in imports (.js)
Sort imports by group: external libs first, then local imports
Use camelCase for variables/functions, PascalCase for types/classes
Order functions such that functions are placed below the variables/functions they use
Prefer using nullish coalescing operator (??) instead of logical or (||), enforced via ESLint rule
Prefer barrel exports e.g. export * from './foo.js' instead of individual named exports
Use console.info/warn/error instead of console.log

Files:

  • plugins/plugin-storage/src/storage/core/components/storage-definition-editor.tsx
  • packages/project-builder-lib/src/tools/model-merger/model-merger.ts
  • packages/project-builder-lib/src/definition/plugins/plugin-utils.unit.test.ts
  • plugins/plugin-auth/src/placeholder-auth/core/components/placeholder-auth-definition-editor.tsx
  • plugins/plugin-auth/src/auth/core/components/auth-definition-editor.tsx
  • plugins/plugin-auth/src/auth0/core/components/auth0-definition-editor.tsx
  • plugins/plugin-queue/src/pg-boss/core/components/pg-boss-definition-editor.tsx
  • plugins/plugin-auth/src/local-auth/core/components/local-auth-definition-editor.tsx
  • packages/project-builder-lib/src/definition/plugins/plugin-utils.ts
  • plugins/plugin-queue/src/queue/core/components/queue-definition-editor.tsx
  • packages/project-builder-web/src/routes/plugins/-components/plugin-card.tsx
.changeset/*.md

📄 CodeRabbit inference engine (AGENTS.md)

Add a new Changeset in the .changeset/ directory for new features or changes, with format 'package-name': patch and description of the feature or change

Files:

  • .changeset/fix-plugin-config-migration-version.md
**/*.{unit.test.ts,int.test.ts}

📄 CodeRabbit inference engine (.cursor/rules/code-style.mdc)

**/*.{unit.test.ts,int.test.ts}: Unit tests must use .unit.test.ts suffix, integration tests must use .int.test.ts suffix
Always import vitest globals explicitly (describe, it, expect)

Files:

  • packages/project-builder-lib/src/definition/plugins/plugin-utils.unit.test.ts
**/*.{unit,int}.test.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/testing.mdc)

**/*.{unit,int}.test.{ts,tsx}: Use descriptive test names that explain what is being tested
Structure tests with Arrange-Act-Assert: clear setup, execution, and verification phases
Always mock external API calls and file system operations
Each test should be independent and not rely on other tests
Leverage TypeScript for type-safe mocking in tests
Focus on testing public methods and behaviors, not implementation details
Each test should verify one specific behavior
Extract repeated logic into helper functions to reduce duplication
Test broad behavior and common edge cases intelligently to avoid slowing down CI with excessive tests
For file system operations in tests, use memfs and mock node:fs and node:fs/promises
When using globby with mocked fs, pass the mocked fs adapter to the globby call

Files:

  • packages/project-builder-lib/src/definition/plugins/plugin-utils.unit.test.ts
**/*.unit.test.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/testing.mdc)

Unit tests are colocated with source files using .unit.test.ts suffix

Files:

  • packages/project-builder-lib/src/definition/plugins/plugin-utils.unit.test.ts
packages/project-builder-web/**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/ui-rules.mdc)

In plugins, prefix all Tailwind classes with the plugin name (e.g., auth-, storage-)

Files:

  • packages/project-builder-web/src/routes/plugins/-components/plugin-card.tsx
🧠 Learnings (10)
📚 Learning: 2025-11-25T22:46:20.505Z
Learnt from: CR
Repo: halfdomelabs/baseplate PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T22:46:20.505Z
Learning: Applies to .changeset/*.md : Add a new Changeset in the `.changeset/` directory for new features or changes, with format `'package-name': patch` and description of the feature or change

Applied to files:

  • .changeset/fix-plugin-config-migration-version.md
📚 Learning: 2025-11-24T19:45:19.136Z
Learnt from: CR
Repo: halfdomelabs/baseplate PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:45:19.136Z
Learning: Applies to **/*.{unit,int}.test.{ts,tsx} : Leverage TypeScript for type-safe mocking in tests

Applied to files:

  • packages/project-builder-lib/src/definition/plugins/plugin-utils.unit.test.ts
📚 Learning: 2025-11-24T19:44:46.506Z
Learnt from: CR
Repo: halfdomelabs/baseplate PR: 0
File: examples/todo-with-auth0/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:44:46.506Z
Learning: Applies to examples/todo-with-auth0/**/*.{unit,int}.test.ts : Import test functions explicitly from 'vitest' instead of using globals. Example: `import { describe, expect, it } from 'vitest';`

Applied to files:

  • packages/project-builder-lib/src/definition/plugins/plugin-utils.unit.test.ts
📚 Learning: 2025-11-24T19:45:19.136Z
Learnt from: CR
Repo: halfdomelabs/baseplate PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:45:19.136Z
Learning: Applies to **/*.{unit,int}.test.{ts,tsx} : Test broad behavior and common edge cases intelligently to avoid slowing down CI with excessive tests

Applied to files:

  • packages/project-builder-lib/src/definition/plugins/plugin-utils.unit.test.ts
📚 Learning: 2025-11-24T19:44:33.994Z
Learnt from: CR
Repo: halfdomelabs/baseplate PR: 0
File: examples/blog-with-auth/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:44:33.994Z
Learning: Applies to examples/blog-with-auth/**/*.test.ts : Import test functions explicitly from 'vitest' instead of relying on globals (e.g., `import { describe, expect, it } from 'vitest';`)

Applied to files:

  • packages/project-builder-lib/src/definition/plugins/plugin-utils.unit.test.ts
📚 Learning: 2025-11-24T19:45:01.582Z
Learnt from: CR
Repo: halfdomelabs/baseplate PR: 0
File: .cursor/rules/code-style.mdc:0-0
Timestamp: 2025-11-24T19:45:01.582Z
Learning: Applies to **/*.{unit.test.ts,int.test.ts} : Always import vitest globals explicitly (describe, it, expect)

Applied to files:

  • packages/project-builder-lib/src/definition/plugins/plugin-utils.unit.test.ts
📚 Learning: 2025-04-23T06:44:30.952Z
Learnt from: kingston
Repo: halfdomelabs/baseplate PR: 510
File: packages/project-builder-server/src/sync/conflict-file-monitor.test.ts:19-24
Timestamp: 2025-04-23T06:44:30.952Z
Learning: In the project-builder-server test suite, Vitest automocks for 'node:fs' and 'node:fs/promises' are already configured to use memfs without needing explicit implementation replacement in each test file.

Applied to files:

  • packages/project-builder-lib/src/definition/plugins/plugin-utils.unit.test.ts
📚 Learning: 2025-11-24T19:45:19.136Z
Learnt from: CR
Repo: halfdomelabs/baseplate PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:45:19.136Z
Learning: Applies to **/*.{unit,int}.test.{ts,tsx} : Extract repeated logic into helper functions to reduce duplication

Applied to files:

  • packages/project-builder-lib/src/definition/plugins/plugin-utils.unit.test.ts
📚 Learning: 2025-11-24T19:45:27.654Z
Learnt from: CR
Repo: halfdomelabs/baseplate PR: 0
File: .cursor/rules/ui-rules.mdc:0-0
Timestamp: 2025-11-24T19:45:27.654Z
Learning: Applies to packages/project-builder-web/**/*.tsx : In plugins, prefix all Tailwind classes with the plugin name (e.g., `auth-`, `storage-`)

Applied to files:

  • packages/project-builder-lib/src/definition/plugins/plugin-utils.ts
  • packages/project-builder-web/src/routes/plugins/-components/plugin-card.tsx
📚 Learning: 2025-11-24T19:45:27.654Z
Learnt from: CR
Repo: halfdomelabs/baseplate PR: 0
File: .cursor/rules/ui-rules.mdc:0-0
Timestamp: 2025-11-24T19:45:27.654Z
Learning: Applies to +(*.tsx|packages/project-builder-web/**/*.tsx|packages/ui-components/**/*.tsx) : Use ShadCN-based components from `baseplate-dev/ui-components` instead of creating custom components

Applied to files:

  • packages/project-builder-web/src/routes/plugins/-components/plugin-card.tsx
🧬 Code graph analysis (3)
packages/project-builder-lib/src/tools/model-merger/model-merger.ts (1)
packages/project-builder-lib/src/definition/model/model-utils.ts (1)
  • ModelUtils (107-119)
packages/project-builder-lib/src/definition/plugins/plugin-utils.unit.test.ts (4)
packages/project-builder-lib/src/plugins/plugins.test-utils.ts (2)
  • createTestPluginMetadata (16-35)
  • createTestMigration (68-80)
packages/project-builder-lib/src/plugins/spec/config-spec.ts (2)
  • PluginConfigMigration (12-26)
  • PluginConfigSpec (31-43)
packages/project-builder-lib/src/schema/plugins/definition.ts (1)
  • BasePluginDefinition (17-17)
packages/project-builder-lib/src/definition/project-definition-container.test-utils.ts (1)
  • createTestProjectDefinitionContainer (43-72)
packages/project-builder-web/src/routes/plugins/-components/plugin-card.tsx (1)
packages/project-builder-lib/src/definition/plugins/plugin-utils.ts (1)
  • PluginUtils (135-142)
⏰ 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). (5)
  • GitHub Check: Verify Sync (blog-with-auth)
  • GitHub Check: Verify Sync (todo-with-auth0)
  • GitHub Check: Test E2E
  • GitHub Check: test
  • GitHub Check: Lint
🔇 Additional comments (16)
plugins/plugin-auth/src/local-auth/core/components/local-auth-definition-editor.tsx (1)

99-104: LGTM! Correctly updated to pass the full container.

The change from definitionContainer.pluginStore to definitionContainer aligns with the updated setPluginConfig signature, enabling proper migration version calculation for newly enabled plugins.

plugins/plugin-queue/src/pg-boss/core/components/pg-boss-definition-editor.tsx (1)

65-70: LGTM! Correctly updated to pass the full container.

The change aligns with the updated setPluginConfig signature.

plugins/plugin-auth/src/placeholder-auth/core/components/placeholder-auth-definition-editor.tsx (1)

90-95: LGTM! Correctly updated to pass the full container.

The change aligns with the updated setPluginConfig signature.

.changeset/fix-plugin-config-migration-version.md (1)

1-5: LGTM! Changeset follows proper format.

The patch version bump and description accurately reflect the bug fix being implemented.

plugins/plugin-queue/src/queue/core/components/queue-definition-editor.tsx (1)

106-111: LGTM! Correctly updated to pass the full container.

The change aligns with the updated setPluginConfig signature.

plugins/plugin-auth/src/auth/core/components/auth-definition-editor.tsx (1)

117-125: LGTM! Correctly updated to pass the full container.

The change aligns with the updated setPluginConfig signature.

packages/project-builder-web/src/routes/plugins/-components/plugin-card.tsx (1)

62-75: LGTM! This is where the bug fix takes effect.

By passing definitionContainer instead of implementations, the setPluginConfig function can now construct a temporary plugin store internally that includes the new plugin, enabling it to correctly calculate and set the migration version for newly enabled plugins.

The implementations variable created earlier (lines 49-53) is still appropriately used for the webConfig lookup.

plugins/plugin-auth/src/auth0/core/components/auth0-definition-editor.tsx (1)

90-95: LGTM! Correctly updated to pass the full container.

The change aligns with the updated setPluginConfig signature.

plugins/plugin-storage/src/storage/core/components/storage-definition-editor.tsx (1)

103-108: LGTM! Correct alignment with refactored API.

The update correctly passes updatedData (with the transformed featureRef) and the full definitionContainer to match the new setPluginConfig signature. This enables proper migration version calculation for newly enabled plugins.

packages/project-builder-lib/src/definition/plugins/plugin-utils.unit.test.ts (4)

21-62: Well-structured test helper for container-based plugin testing.

The helper function properly simulates plugin initialization by registering migrations during module initialization, which matches the actual plugin system behavior. This enables accurate testing of migration version calculation.


65-102: LGTM! Correctly tests new plugin migration version.

This test verifies the core fix: when adding a new plugin with migrations, configSchemaVersion is properly set to the latest migration version (2 in this case).


104-138: LGTM! Properly tests edge case of plugin without migrations.

This test correctly verifies that when adding a plugin with no migrations, configSchemaVersion is set to undefined as expected.


140-193: LGTM! Validates schema version preservation for existing plugins.

This test correctly verifies that updating an existing plugin's config preserves the original configSchemaVersion, ensuring backward compatibility and preventing unintended version changes.

packages/project-builder-lib/src/definition/plugins/plugin-utils.ts (3)

1-15: LGTM! Import changes correctly support the refactored API.

The imports properly reflect the signature change from PluginImplementationStore to ProjectDefinitionContainer, and add the necessary createPluginImplementationStoreWithNewPlugins utility for temporary store creation.


55-60: LGTM! Signature change enables proper migration version calculation.

Accepting ProjectDefinitionContainer instead of PluginImplementationStore provides access to both the plugin store and definition, enabling creation of a temporary implementation store that includes the new plugin for proper migration registration.


63-96: Excellent fix! Properly handles migration version for new plugins.

The implementation correctly differentiates between adding a new plugin and updating an existing one:

  • New plugin path (lines 65-90): Creates a temporary PluginImplementationStore that includes the new plugin, allowing its migrations to be registered and the correct lastMigrationVersion to be retrieved. This solves the core issue in the PR.

  • Existing plugin path (lines 91-96): Preserves all existing fields including configSchemaVersion, ensuring backward compatibility.

The logic is clean, well-commented, and directly addresses the bug described in the PR objectives.

@kingston kingston merged commit 6828918 into main Dec 22, 2025
13 checks passed
@kingston kingston deleted the kingston/eng-933-cannot-find-model-by-id-for-user-when-enabling-storage branch December 22, 2025 08:46
@github-actions github-actions bot mentioned this pull request Dec 19, 2025
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.

2 participants