Skip to content

feat: Initial implementation of custom auth implementation#550

Merged
kingston merged 20 commits into
mainfrom
kingston/eng-211-create-new-local-auth-plugin
May 28, 2025
Merged

feat: Initial implementation of custom auth implementation#550
kingston merged 20 commits into
mainfrom
kingston/eng-211-create-new-local-auth-plugin

Conversation

@kingston

@kingston kingston commented May 28, 2025

Copy link
Copy Markdown
Collaborator

Note: This is part 1 of the implementation but wanted to get a version in before we do a mega-commit

Summary by CodeRabbit

  • New Features

    • Introduced a self-hosted authentication plugin with customizable roles, model references, and session management, including web-based configuration forms.
    • Added a storage plugin with improved model reference handling and web configuration.
    • Added placeholder authentication service and React hooks for testing and integration.
    • Enhanced model merging utilities to support multiple models and batch operations.
    • Plugin system now supports configuration migrations for seamless upgrades.
  • Improvements

    • Unified and generalized model reference and merging logic across plugins.
    • Updated validation schemas to enforce stricter naming conventions and removed legacy validators.
    • Enhanced error reporting and user feedback in web interfaces.
    • Updated CSS utility structure for better style scoping and isolation.
    • Upgraded ESLint and related tooling for improved code quality.
  • Bug Fixes

    • Fixed issues in plugin configuration versioning and migration handling.
    • Corrected logic in model and feature utilities for more reliable lookups and fallbacks.
  • Documentation

    • Expanded and clarified coding and testing guidelines.
    • Updated repository structure and package descriptions for contributors.
  • Chores

    • Refactored TypeScript configurations for project references and stricter checks.
    • Replaced PostCSS and prefixing tools with Tailwind CSS Vite integration for plugins.
    • Cleaned up and reorganized internal exports and configuration files.

@vercel

vercel Bot commented May 28, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
baseplate-project-builder-web ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 28, 2025 3:56pm

@linear

linear Bot commented May 28, 2025

Copy link
Copy Markdown
ENG-211 Create new local auth plugin

We use a local auth system that does not rely on Auth0

QA Notes:

  • Add auth plugin without Auth0 and make sure the sign up / log in work

@changeset-bot

changeset-bot Bot commented May 28, 2025

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: f4c5fed

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

This PR includes changesets to release 12 packages
Name Type
@halfdomelabs/tools Patch
@halfdomelabs/core-generators Patch
@halfdomelabs/project-builder-lib Patch
@halfdomelabs/fastify-generators Patch
@halfdomelabs/project-builder-cli Patch
@halfdomelabs/project-builder-common Patch
@halfdomelabs/project-builder-server Patch
@halfdomelabs/project-builder-test Patch
@halfdomelabs/project-builder-web Patch
@halfdomelabs/react-generators Patch
@halfdomelabs/baseplate-plugin-auth Patch
@halfdomelabs/baseplate-plugin-storage 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

coderabbitai Bot commented May 28, 2025

Copy link
Copy Markdown

Walkthrough

This change set introduces a major refactor and feature expansion across multiple packages and plugins. It implements a new, extensible plugin configuration and migration system, restructures authentication and storage plugin schemas and UI, and adds placeholder authentication generators for test and development. The update also modularizes CSS utilities, improves TypeScript project references, and enhances code style, validation, and error handling throughout the codebase.

Changes

Files / Groups Change Summary
.changeset/*.md, .cursor/rules/*, .cursorignore, .gitignore, .vscode/settings.json, knip.config.js Added and updated changeset, code style, ignore, and workspace config files; improved tooling and linting.
CLAUDE.md Overhauled documentation: expanded code style/testing guidelines, updated repo/package structure, and added key reminders.
packages/core-generators/* Upgraded ESLint plugin versions, improved template rendering for special characters, added typecheck script, and updated ESLint config imports.
packages/fastify-generators/* Added placeholder auth service generator, expanded session types, integrated logger setup, and improved session type handling.
packages/project-builder-lib/* Introduced plugin config migration system, refactored model merger logic for batch operations, updated schema validation (kebab-case), improved utility functions, and enhanced error handling.
packages/project-builder-server/*, packages/project-builder-test/*, packages/project-builder-web/* Integrated plugin migrations into project build/parsing, improved error reporting, updated TypeScript project references, and enhanced UI feedback.
packages/react-generators/* Added placeholder auth hooks generator and templates for test authentication hooks.
packages/tools/* Updated ESLint config, upgraded dependencies, and improved linting for Vite config files.
packages/ui-components/* Modularized CSS utilities, moved utility classes to a separate file, and updated exports.
plugins/baseplate-plugin-auth/* Major refactor: new plugin config schema with migration support, new roles schema, modularized CSS with prefixing, added core/node/web plugin exports, implemented Fastify auth module generator with session management, and updated UI components for plugin config.
plugins/baseplate-plugin-storage/* Refactored plugin config schema (nested modelRefs), added migration support, modularized CSS with prefixing, and updated UI components and logic accordingly.
pnpm-workspace.yaml Removed obsolete PostCSS/Tailwind packages from catalog.

Changes (continued)

Files / Groups Change Summary
plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/templates/* Added robust Fastify user session service, session constants, cookie signer, session cookie utils, GraphQL schema for session, and session management logic.
plugins/baseplate-plugin-auth/src/roles/* Introduced new roles schema and constants for default roles, ensuring built-in roles are always present and unique.
plugins/baseplate-plugin-auth/src/auth0/core/* Refactored Auth0 plugin schema, added config migration, updated UI and model handling to match new schema, and improved role management.
plugins/baseplate-plugin-storage/src/storage/core/schema/* Updated schema to use nested modelRefs, added migration, and updated model creation logic.
plugins/baseplate-plugin-storage/src/storage/transformers/* Updated logic to use new nested modelRefs for file model references.
plugins/baseplate-plugin-storage/src/utils/cn.ts, plugins/baseplate-plugin-auth/src/utils/cn.ts Simplified class name utility function, removed prefixing logic.
plugins/baseplate-plugin-auth/src/styles.css, plugins/baseplate-plugin-storage/src/styles.css Scoped Tailwind CSS imports with prefix directives for style isolation.
plugins/baseplate-plugin-auth/tsconfig.json, plugins/baseplate-plugin-storage/tsconfig.json Added TypeScript project references for improved build/dependency management.
plugins/baseplate-plugin-auth/manifest.json, plugins/baseplate-plugin-auth/package.json, plugins/baseplate-plugin-storage/package.json Updated plugin manifests and dependencies, removed PostCSS configs, switched to Tailwind Vite plugin.
plugins/baseplate-plugin-auth/vite.config.ts, plugins/baseplate-plugin-storage/vite.config.ts Added Tailwind CSS integration via Vite plugin.
plugins/baseplate-plugin-auth/src/index.ts, plugins/baseplate-plugin-auth/src/auth/index.ts, etc. Updated exports to use barrel/wildcard exports for better modularity.

Sequence Diagram(s)

Plugin Configuration and Migration Flow

sequenceDiagram
    participant User
    participant WebUI as ProjectBuilder Web UI
    participant Server as ProjectBuilder Server
    participant Lib as project-builder-lib
    participant Plugin as PluginImplementationStore

    User->>WebUI: Edit plugin config (e.g., auth/storage)
    WebUI->>Server: Save project definition
    Server->>Lib: runSchemaMigrations(definition)
    Lib->>Plugin: createPluginImplementationStore(pluginStore, definition)
    Lib->>Plugin: runPluginMigrations(definition, pluginImplementationStore)
    Plugin->>Lib: Apply migrations to plugin configs
    Lib->>Server: Return migrated definition
    Server->>WebUI: Confirm save/refresh UI
Loading

Fastify Auth Module Generation (Simplified)

sequenceDiagram
    participant Generator as authModuleGenerator
    participant Prisma as Prisma ORM
    participant Fastify as Fastify Server

    Generator->>Prisma: Generate user/session models
    Generator->>Fastify: Generate user session service (CookieUserSessionService)
    Fastify->>Prisma: Store/retrieve session info
    Fastify->>Fastify: Set/clear session cookies, verify session via JWT/cookie
Loading

Placeholder Auth Hooks/Service Generation (Test/Dev)

sequenceDiagram
    participant Generator as placeholderAuthServiceGenerator/placeholderAuthHooksGenerator
    participant Project as Project App

    Generator->>Project: Generate placeholder service/hooks files
    Project->>User: Throws "Not implemented" if called in runtime
Loading

Modular CSS Utilities

sequenceDiagram
    participant UI as UI Components
    participant Plugin as Plugin (auth/storage)
    participant App as Application

    UI->>UI: Export utilities.css with surface/typography classes
    Plugin->>Plugin: Import utilities.css, apply prefix (auth:/storage:)
    App->>Plugin: Use plugin UI, styles are scoped via prefix
Loading

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@socket-security

socket-security Bot commented May 28, 2025

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedsemver@​7.7.210010010089100
Addedeslint-plugin-import-x@​4.13.39910010096100
Addedeslint-import-resolver-typescript@​4.4.19910010098100

View full report

@socket-security

socket-security Bot commented May 28, 2025

Copy link
Copy Markdown

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert (click for details)
Warn Medium
eslint-import-context@0.1.6 is an Unpopular package.

Location: Package overview

From: pnpm-lock.yamlnpm/eslint-import-resolver-typescript@4.4.1npm/eslint-plugin-import-x@4.13.3npm/eslint-import-context@0.1.6

ℹ Read more on: This package | This alert | What are unpopular packages?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Unpopular packages may have less maintenance and contain other problems.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/eslint-import-context@0.1.6. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 41

🔭 Outside diff range comments (1)
packages/project-builder-lib/src/tools/model-merger/model-merger.ts (1)

295-300: 💡 Verification agent

🧩 Analysis chain

featureRef in diff result may become stale when an existing model’s feature changes
createModelMergerResult copies currentModel.featureRef into the diff result even if desired.featureRef differs.
That means applyModelMergerResultInPlace will recreate a new model with the old featureRef, silently dropping the intended change.

Consider including featureRef in modelMergerDefinitionDiffConfig (e.g. via DefinitionDiffReplacementField) or copying desired.featureRef into the result object when current exists but the feature is updated.


🏁 Script executed:

#!/bin/bash
# Show the definition of createModelMergerResult around the return statement
sed -n '260,350p' packages/project-builder-lib/src/tools/model-merger/model-merger.ts

# Check if featureRef is part of the diff config
rg -n 'modelMergerDefinitionDiffConfig' -A 10 packages/project-builder-lib/src/tools/model-merger/model-merger.ts

# Look for any usage of DefinitionDiffReplacementField
rg -n 'DefinitionDiffReplacementField' -n packages

Length of output: 5922


Capture featureRef changes in the model merger diff

The current implementation of createModelMergerResult always copies currentModel.featureRef into the result, even when desired.featureRef has changed. This means that after applying the diff, the model’s featureRef will remain stale.

To fix this, we should include featureRef in the diff config so that any change to it is tracked and applied.

• File: packages/project-builder-lib/src/tools/model-merger/model-merger.ts
– Around line 78, add a replacement field for featureRef in modelMergerDefinitionDiffConfig.
– Remove manual copying of the old featureRef in the return statement and rely on the diff to update it.

Suggested diff:

--- a/packages/project-builder-lib/src/tools/model-merger/model-merger.ts
+++ b/packages/project-builder-lib/src/tools/model-merger/model-merger.ts
@@ export const modelMergerDefinitionDiffConfig =
   createDefinitionDiffConfig<ModelMergerModelInput>({
     'model.fields':      new DefinitionDiffKeyedArrayField('fields', (f) => f.name),
     'model.relations':   new DefinitionDiffKeyedArrayField('relations', (r) => r.name),
     'model.uniqueConstraints': new DefinitionDiffKeyedArrayField(
       'uniqueConstraints',
       (c) => getUniqueConstraintKey(c),
     ),
+    // Track featureRef changes
+    'model.featureRef':  new DefinitionDiffReplacementField('featureRef'),
   });
--- a/packages/project-builder-lib/src/tools/model-merger/model-merger.ts
+++ b/packages/project-builder-lib/src/tools/model-merger/model-merger.ts
@@ export function createModelMergerResult(
-  return {
-    isNewModel: !current,
-    id: currentModel.id,
-    name: currentModel.name,
-    featureRef: currentModel.featureRef,
-    changes: diff,
-  };
+  // featureRef will now be part of diff.changes if it has changed
+  return {
+    isNewModel: !current,
+    id:        currentModel.id,
+    name:      currentModel.name,
+    featureRef: current ? diff['model.featureRef'] ?? currentModel.featureRef : currentModel.featureRef,
+    changes:   diff,
+  };

This ensures any update to desired.featureRef is detected and applied rather than silently dropped.

♻️ Duplicate comments (1)
plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/templates/services/user-session.service.ts (1)

1-1: Same remark as earlier – avoid project-wide @ts-nocheck

See previous comment in JWT service. Keeping type-checking on templates drastically cuts integration bugs.

🧹 Nitpick comments (31)
.gitignore (1)

101-102: Approve ignore entry for local Claude settings
The addition of .claude/settings.local.json to .gitignore is appropriate to prevent leaking local configuration files. Consider whether you’d also like to ignore the entire .claude/ directory (e.g., adding .claude/) if other environment-specific files might appear there in the future.

packages/fastify-generators/src/generators/auth/auth-context/templates/utils/auth-context.utils.ts (1)

24-24: Simplify user session check
The updated guard if (!session || session.type !== 'user') removes the unnecessary type assertion and correctly enforces that only user sessions can call userIdOrThrow.

Consider removing the // @ts-nocheck at the top of the file now that type safety is explicit:

-// @ts-nocheck
packages/react-generators/src/generators/auth/placeholder-auth-hooks/templates/useSession.ts (2)

1-1: Consider removing @ts-nocheck directive.

The @ts-nocheck directive disables TypeScript checking entirely for this file. Since this is a well-typed function, consider removing this directive to maintain type safety.

-// @ts-nocheck

3-8: Improve placeholder implementation for better developer experience.

While throwing an error is appropriate for placeholder code, consider providing a more helpful implementation that indicates this is intentionally unimplemented.

 export function useSession(): {
   isAuthenticated: boolean;
   loading: boolean;
 } {
-  throw new Error('Not implemented');
+  throw new Error('useSession is a placeholder - implement authentication logic here');
+  // TODO: Implement actual session management
+  // return { isAuthenticated: false, loading: false };
 }
plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/templates/schema/user-session.queries.ts (1)

1-1: Consider removing @ts-nocheck directive.

The @ts-nocheck directive suppresses all TypeScript checking for this file. While this might be necessary during code generation, consider whether type checking can be enabled to catch potential issues.

If TypeScript errors are due to template variables, consider using more specific suppressions or ensuring the generated code will be properly typed.

packages/react-generators/src/generators/auth/placeholder-auth-hooks/templates/useCurrentUser.ts (1)

3-9: Add TODO comment and consider improving return types.

The placeholder implementation is appropriate, but consider adding a TODO comment for clarity and potentially improving the return types.

+// TODO: Implement actual user authentication logic
 export function useCurrentUser(): {
-  user: any;
+  user: any; // TODO: Replace with proper User type
   loading: boolean;
   error: Error | undefined;
 } {
   throw new Error('Not implemented');
 }
packages/sync/src/output/write-generator-output.ts (1)

231-237: Enhanced error diagnostics for formatter failures.

The addition of specific handling for FormatterError nested within PrepareGeneratorFilesError will improve debugging by logging the file contents that failed formatting.

Consider adding the file path to the log for even better diagnostics:

 if (
   error instanceof PrepareGeneratorFilesError &&
   error.causes[0].cause instanceof FormatterError
 ) {
   const formatterError = error.causes[0].cause;
-  logger.info(`File Dump:\n${formatterError.fileContents}`);
+  logger.info(`File Dump for ${formatterError.projectRelativePath}:\n${formatterError.fileContents}`);
 }
plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/templates/management.ts (1)

6-22: Singleton pattern implemented correctly with proper caching.

The caching mechanism for the ManagementClient is well-implemented, preventing unnecessary client instantiations and improving performance.

Consider adding error handling for client instantiation:

 export function getAuthManagementClient(): ManagementClient {
   if (cachedClient) {
     return cachedClient;
   }

+  try {
     const client = new ManagementClient({
       domain: config.AUTH_TENANT_DOMAIN,
       clientId: config.AUTH_CLIENT_ID,
       clientSecret: config.AUTH_CLIENT_SECRET,
     });

     cachedClient = client;
     return client;
+  } catch (error) {
+    throw new Error(`Failed to initialize Auth0 Management Client: ${error.message}`);
+  }
 }
plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/templates/schema/user-session-payload.object-type.ts (1)

14-22: Prisma field resolver implemented correctly with proper error handling.

The user field resolver correctly:

  • Uses findUniqueOrThrow which ensures data integrity by throwing if the user doesn't exist
  • Properly spreads the query object for Prisma field selection
  • Follows Pothos prismaField patterns

Consider adding more descriptive error handling:

 user: t.prismaField({
   type: TPL_USER_OBJECT_TYPE,
   resolve: async (query, root) =>
-    TPL_PRISMA_USER.findUniqueOrThrow({
+    TPL_PRISMA_USER.findUniqueOrThrow({
       where: { id: root.userId },
       ...query,
-    }),
+    }).catch((error) => {
+      throw new Error(`User not found for session: ${root.userId}`);
+    }),
 }),
plugins/baseplate-plugin-auth/src/auth0/core/schema/migrations.ts (1)

7-16: Consider improving type safety in the migration function.

The migration logic correctly restructures the configuration from flat userAccountModelRef to nested modelRefs.user. However, the type assertion on line 8 could be improved for better type safety.

Consider using a more defensive approach to handle potentially missing properties:

    migrate: (config) => {
-      const typedConfig = config as { userAccountModelRef: string };
+      const typedConfig = config as { userAccountModelRef?: string };
+      
+      if (!typedConfig.userAccountModelRef) {
+        return config;
+      }
+      
      return {
        ...typedConfig,
        userAccountModelRef: undefined,
        modelRefs: {
          user: typedConfig.userAccountModelRef,
        },
      };
    },

This ensures the migration handles cases where the expected property might not exist, making it more robust.

plugins/baseplate-plugin-auth/src/roles/constants.ts (1)

5-21: Avoid accidental mutation & ensure compile-time safety for default roles
Consider freezing the AUTH_DEFAULT_ROLES array (or declaring it as const) so that neither the array nor its objects can be mutated elsewhere. This protects the canonical definition of built-in roles and gives the compiler literal-type information that can be handy in downstream schema checks.

plugins/baseplate-plugin-auth/src/auth/core/common.ts (1)

24-28: Consider adding runtime validation for type casting.

The code uses type casting as AuthPluginDefinition without runtime validation. While PluginUtils.configByIdOrThrow handles the existence check, consider adding schema validation to ensure the config matches the expected type.

const pluginConfig = PluginUtils.configByIdOrThrow(
  definition,
  pluginId,
-) as AuthPluginDefinition;
+);
+// Consider adding runtime validation here
+if (!authPluginDefinitionSchema.safeParse(pluginConfig).success) {
+  throw new Error(`Invalid auth plugin configuration for ${pluginId}`);
+}
+const validatedConfig = pluginConfig as AuthPluginDefinition;

Also applies to: 31-35

plugins/baseplate-plugin-auth/src/auth/core/components/role-editor-form.tsx (1)

18-20: Consider memoizing the role check for performance.

The isFixedRole function is called multiple times for each role during renders, which could be optimized.

+import { useMemo } from 'react';

+function useFixedRoleChecker() {
+  return useMemo(() => {
+    const fixedRoleNames = new Set(AUTH_DEFAULT_ROLES.map(role => role.name));
+    return (name: string) => fixedRoleNames.has(name);
+  }, []);
+}

 function RoleEditorForm({ className, control }: Props): React.JSX.Element {
+  const isFixedRole = useFixedRoleChecker();
   const { fields, append, remove } = useFieldArray({

This avoids repeated array iterations and provides better performance for large role lists.

plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/templates/user-session.constants.ts (2)

19-19: Remove unnecessary type assertion.

The as number type assertion is unnecessary since the literal 0 is already typed as a number.

-export const USER_SESSION_MAX_LIFETIME_SEC = 0 as number;
+export const USER_SESSION_MAX_LIFETIME_SEC = 0;

6-19: Consider using const assertions and better organization.

The constants could benefit from const assertions for better type safety and potentially grouping them into a configuration object.

-export const USER_SESSION_DURATION_SEC = 14 * 24 * 60 * 60; // 14 days
-export const USER_SESSION_RENEWAL_THRESHOLD_SEC = 1 * 24 * 60 * 60; // 1 day
-export const USER_SESSION_MAX_LIFETIME_SEC = 0;
+export const USER_SESSION_CONFIG = {
+  /**
+   * Defines the duration of a user session before it expires, in seconds.
+   */
+  DURATION_SEC: 14 * 24 * 60 * 60, // 14 days
+  /**
+   * Defines the duration after which a user session should be renewed, in seconds.
+   */
+  RENEWAL_THRESHOLD_SEC: 1 * 24 * 60 * 60, // 1 day
+  /**
+   * Sets the maximum possible lifespan of a user session, in seconds, including renewals.
+   * A value of 0 allows the session to persist indefinitely, provided it is renewed
+   * before the session expiration.
+   */
+  MAX_LIFETIME_SEC: 0,
+} as const;
+
+// Export individual constants for backward compatibility if needed
+export const USER_SESSION_DURATION_SEC = USER_SESSION_CONFIG.DURATION_SEC;
+export const USER_SESSION_RENEWAL_THRESHOLD_SEC = USER_SESSION_CONFIG.RENEWAL_THRESHOLD_SEC;
+export const USER_SESSION_MAX_LIFETIME_SEC = USER_SESSION_CONFIG.MAX_LIFETIME_SEC;

This provides better organization and type safety while maintaining compatibility.

packages/fastify-generators/src/generators/auth/placeholder-auth-service/templates/user-session.service.ts (1)

26-31: Improve error message for consistency.

For consistency with the updated error message in the other method, consider making this error message more descriptive.

-  throw new Error('Not implemented');
+  throw new Error('PlaceholderSessionService.getSessionInfoFromToken: This is a placeholder implementation that needs to be replaced with actual authentication logic');
packages/project-builder-lib/src/definition/plugins/plugin-utils.ts (1)

51-55: Add error handling for missing plugin configuration service.

While the getPluginSpec method throws an error if the implementation is not found, consider adding more context about which plugin caused the issue for better debugging.

  const pluginConfigService =
    pluginImplementationStore.getPluginSpec(pluginConfigSpec);
  const lastMigrationVersion = pluginConfigService.getLastMigrationVersion(
    plugin.id,
  );

Consider wrapping this in a try-catch to provide more context:

+  try {
     const pluginConfigService =
       pluginImplementationStore.getPluginSpec(pluginConfigSpec);
     const lastMigrationVersion = pluginConfigService.getLastMigrationVersion(
       plugin.id,
     );
+  } catch (error) {
+    throw new Error(`Failed to get migration version for plugin ${plugin.id}: ${error.message}`);
+  }
plugins/baseplate-plugin-auth/src/roles/schema.ts (2)

37-55: Consider adding comments to clarify the complex transform logic.

The transform function performs several important operations but could benefit from inline comments to explain the logic flow.

  .transform((roles) => [
+    // Merge default roles with user-defined roles, preserving user customizations
     ...AUTH_DEFAULT_ROLES.map((r) => {
       const existingRole = roles.find((role) => role.name === r.name);
       return existingRole
         ? {
+            // Use existing role but ensure it's marked as built-in
             ...existingRole,
             builtIn: true,
           }
         : {
+            // Create new default role with generated ID
             ...r,
             builtIn: true,
             id: authRoleEntityType.generateNewId(),
           };
     }),
+    // Add user-defined roles that are not default roles
     // Filter out the built-in roles
     ...roles.filter(
       (r) => !AUTH_DEFAULT_ROLES.map((v) => v.name).includes(r.name),
     ),
   ]);

37-55: Consider performance optimization for large role arrays.

For better performance with large role arrays, consider optimizing the filtering logic by creating a Set of default role names instead of using includes on a mapped array.

+  const defaultRoleNames = new Set(AUTH_DEFAULT_ROLES.map(r => r.name));
+  
   .transform((roles) => [
     ...AUTH_DEFAULT_ROLES.map((r) => {
       const existingRole = roles.find((role) => role.name === r.name);
       return existingRole
         ? {
             ...existingRole,
             builtIn: true,
           }
         : {
             ...r,
             builtIn: true,
             id: authRoleEntityType.generateNewId(),
           };
     }),
     // Filter out the built-in roles
     ...roles.filter(
-      (r) => !AUTH_DEFAULT_ROLES.map((v) => v.name).includes(r.name),
+      (r) => !defaultRoleNames.has(r.name),
     ),
   ]);
plugins/baseplate-plugin-auth/src/auth/core/components/auth-definition-editor.tsx (2)

40-64: Consider memoization optimization for default values

The useMemo dependency array includes pluginMetadata?.config implicitly through the condition check, but it's not explicitly listed. This could potentially cause unnecessary re-computations.

Consider making the dependency more explicit:

- }, [definition, pluginMetadata?.config]);
+ }, [definition, pluginMetadata]);

Or if you specifically need to track the config:

- }, [definition, pluginMetadata?.config]);
+ }, [definition, pluginMetadata?.config]);

The current implementation works but could be clearer about what triggers recomputation.


121-121: Consider extracting form CSS class to a constant

The inline CSS class string could be extracted to improve maintainability and reusability.

Consider extracting to a constant:

+ const FORM_CLASSES = 'flex flex-col gap-4';
+
  return (
-    <form onSubmit={onSubmit} className={cn('flex flex-col gap-4')}>
+    <form onSubmit={onSubmit} className={cn(FORM_CLASSES)}>
plugins/baseplate-plugin-auth/src/auth/core/schema/plugin-definition.ts (1)

10-34: Consider enforcing strict schemas & deduplicating modelRef definition

z.object() without .strict() will silently allow unknown keys.
For configuration objects that will be checked-in and migrated, failing fast on typos usually saves time.

In addition, the four modelRefs.* fields share the same definition. You can make the schema more compact & less error-prone by extracting a reusable helper.

- export const authPluginDefinitionSchema = z.object({
-   modelRefs: z.object({
-     user: zRef(z.string().min(1), { type: modelEntityType, onDelete: 'RESTRICT' }),
-     userAccount: zRef(z.string().min(1), { type: modelEntityType, onDelete: 'RESTRICT' }),
-     userRole: zRef(z.string().min(1), { type: modelEntityType, onDelete: 'RESTRICT' }),
-     userSession: zRef(z.string().min(1), { type: modelEntityType, onDelete: 'RESTRICT' }),
-   }),
+const modelRefSchema = zRef(z.string().min(1), {
+  type: modelEntityType,
+  onDelete: 'RESTRICT',
+});
+
+export const authPluginDefinitionSchema = z
+  .object({
+    modelRefs: z
+      .object({
+        user: modelRefSchema,
+        userAccount: modelRefSchema,
+        userRole: modelRefSchema,
+        userSession: modelRefSchema,
+      })
+      .strict(),

…and finally call .strict() on the outer object as well:

  roles: authRolesSchema,
-});
+}).strict();

This keeps the config surface tight and removes duplication.

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

53-57: Duplicate built-in role objects are being injected

defaultValues.roles clones AUTH_DEFAULT_ROLES and assigns fresh IDs.
authRolesSchema later merges another copy of the built-in roles, so the built-ins appear twice in the editor until the form is submitted (after which they’re de-duplicated in the transform).

This can confuse users (“why do I see Admin twice?”) and makes validation noise. Consider initialising roles with an empty list and letting the schema inject the built-ins:

-  roles: AUTH_DEFAULT_ROLES.map((r) => ({
-    ...r,
-    id: authRoleEntityType.generateNewId(),
-  })),
+  roles: [],
plugins/baseplate-plugin-auth/src/auth/core/schema/models.ts (1)

72-74: Sensitive secret is stored as plain string

providerSecret is meant to hold OAuth / Open-ID secrets. Storing them as a
plain string signals they will be persisted unhashed. Consider:

  • storing only a salted hash of the secret, or
  • encrypting the column at-rest (e.g. pgcrypto / kms).

Documenting the expectation in the model would prevent accidental leaks later.
[security]

plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/templates/user-session.service.ts (1)

90-97: Mutating req.headers.authorization may clobber an existing header

getSessionInfoFromToken blindly overrides req.headers.authorization.
If upstream code has already populated the header, that value is lost.

Consider copying the original value, restoring it afterwards, or, better, call this.getSessionInfoFromRequest on a cloned request (Fastify’s req.clone()), if available.

packages/project-builder-lib/src/schema/plugins/definition.ts (1)

23-41: Potential mismatch when pluginId is not registered

If plugins.getPluginSpec(pluginConfigSpec).getSchema(pluginId) returns undefined the code falls back to basePluginSchema, but parses were already executed with basePluginSchema.parse(data).

This means an unrecognised plugin passes validation even if it accidentally carries a config that should be rejected.

Consider:

  1. Throwing a descriptive zod error when configSchema is missing for the supplied pluginId.
  2. Alternatively, keep the fallback but strip the config key so unknown configs do not silently drift into the definition.
plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/templates/services/user-session.service.ts (2)

33-39: secure cookie flag should derive from actual request, not build-time env

secure: config.APP_ENVIRONMENT !== 'development' means cookies are always secure in staging/production even when accessed over plain HTTP during local reverse-proxy setups (e.g. docker-compose on localhost).
Conversely, tests running in CI with NODE_ENV=test but behind HTTPS would produce non-secure cookies.

Better: decide per-request:

secure: req.protocol === 'https',

or expose a helper that introspects x-forwarded-proto.


220-224: Duplicate roles are possible – consider de-duping

[...DEFAULT_USER_ROLES, ...user.roles.map(r => r.role)] may include "user" twice.
A quick Array.from(new Set(…)) prevents downstream ACL checks from iterating duplicates.

CLAUDE.md (2)

20-24: Import-sorting rule conflicts with the “use absolute paths” rule

You ask contributors to sort imports by group and to always use absolute @src paths.
ESLint import-order plugins normally group “absolute” separately from “internal”. Please clarify which grouping takes precedence to avoid back-and-forth in reviews.


165-170: kebab-case vs PascalCase files – static analysis tooling needed

Stating “Use kebab-case for file names” is great, but the repo already contains many PascalCase.ts and camelCase.ts files (e.g. generators).
Consider adding an ESLint filename-rules or a CI script so new contributors receive immediate feedback instead of learning during reviews.

packages/project-builder-lib/src/tools/model-merger/model-merger.ts (1)

150-152: Return type of attachIdsToModelMergerModelInput is misleading and hides the id field
The function returns Pick<ModelConfigInput, keyof ModelMergerModelInput> which excludes the top-level id.
Call-sites later assume only the nested IDs are required, so this currently compiles, but it conveys that the returned object exactly matches ModelConfigInput properties intersected with the input, which is confusing.

Two alternatives:

  1. Return ModelMergerModelInput (IDs are only added to nested entities), or
  2. Define an explicit helper type (type ModelMergerModelWithIds = { … }) for clarity.

Either improves readability and prevents accidental reliance on the incomplete subset.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Lite

📥 Commits

Reviewing files that changed from the base of the PR and between f498d9e and 3b66a31.

⛔ Files ignored due to path filters (7)
  • packages/fastify-generators/src/generators/auth/placeholder-auth-service/generated/ts-import-maps.ts is excluded by !**/generated/**
  • packages/fastify-generators/src/generators/auth/placeholder-auth-service/generated/ts-templates.ts is excluded by !**/generated/**
  • packages/react-generators/src/generators/auth/placeholder-auth-hooks/generated/ts-import-maps.ts is excluded by !**/generated/**
  • packages/react-generators/src/generators/auth/placeholder-auth-hooks/generated/ts-templates.ts is excluded by !**/generated/**
  • plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/generated/ts-templates.ts is excluded by !**/generated/**
  • plugins/baseplate-plugin-auth/src/auth/static/icon.svg is excluded by !**/*.svg
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (136)
  • .changeset/eleven-meals-fly.md (1 hunks)
  • .changeset/gentle-corners-hope.md (1 hunks)
  • .changeset/smooth-flowers-lick.md (1 hunks)
  • .cursor/rules/code-style.mdc (1 hunks)
  • .cursor/rules/ui-rules.mdc (1 hunks)
  • .cursorignore (1 hunks)
  • .gitignore (1 hunks)
  • .vscode/settings.json (1 hunks)
  • CLAUDE.md (4 hunks)
  • knip.config.js (1 hunks)
  • packages/core-generators/src/constants/core-packages.ts (1 hunks)
  • packages/core-generators/src/generators/node/eslint/templates/eslint.config.js (2 hunks)
  • packages/core-generators/src/generators/node/typescript/typescript.generator.ts (2 hunks)
  • packages/core-generators/src/renderers/typescript/renderers/template.ts (5 hunks)
  • packages/core-generators/src/renderers/typescript/renderers/template.unit.test.ts (1 hunks)
  • packages/fastify-generators/src/generators/auth/auth-context/auth-context.generator.ts (3 hunks)
  • packages/fastify-generators/src/generators/auth/auth-context/templates/types/auth-session.types.ts (1 hunks)
  • packages/fastify-generators/src/generators/auth/auth-context/templates/utils/auth-context.utils.ts (1 hunks)
  • packages/fastify-generators/src/generators/auth/index.ts (1 hunks)
  • packages/fastify-generators/src/generators/auth/placeholder-auth-service/placeholder-auth-service.generator.ts (1 hunks)
  • packages/fastify-generators/src/generators/auth/placeholder-auth-service/templates/user-session.service.ts (1 hunks)
  • packages/fastify-generators/src/generators/vitest/prisma-vitest/prisma-vitest.generator.ts (1 hunks)
  • packages/project-builder-lib/package.json (1 hunks)
  • packages/project-builder-lib/src/definition/feature/feature-utils.ts (2 hunks)
  • packages/project-builder-lib/src/definition/model/model-utils.ts (2 hunks)
  • packages/project-builder-lib/src/definition/plugins/plugin-utils.ts (3 hunks)
  • packages/project-builder-lib/src/migrations/index.ts (1 hunks)
  • packages/project-builder-lib/src/migrations/migration-008-anonymous-public-role.ts (1 hunks)
  • packages/project-builder-lib/src/parser/parser.ts (1 hunks)
  • packages/project-builder-lib/src/plugins/index.ts (1 hunks)
  • packages/project-builder-lib/src/plugins/migrations/index.ts (1 hunks)
  • packages/project-builder-lib/src/plugins/migrations/run-migrations.ts (1 hunks)
  • packages/project-builder-lib/src/plugins/spec/auth-config-spec.ts (1 hunks)
  • packages/project-builder-lib/src/plugins/spec/config-spec.ts (2 hunks)
  • packages/project-builder-lib/src/references/ref-builder.ts (1 hunks)
  • packages/project-builder-lib/src/schema/apps/base.ts (1 hunks)
  • packages/project-builder-lib/src/schema/auth/index.ts (0 hunks)
  • packages/project-builder-lib/src/schema/features/feature.ts (1 hunks)
  • packages/project-builder-lib/src/schema/plugins/definition.ts (1 hunks)
  • packages/project-builder-lib/src/schema/plugins/entity-types.ts (1 hunks)
  • packages/project-builder-lib/src/schema/plugins/index.ts (1 hunks)
  • packages/project-builder-lib/src/schema/project-definition.ts (2 hunks)
  • packages/project-builder-lib/src/schema/utils/validation.ts (0 hunks)
  • packages/project-builder-lib/src/tools/model-merger/model-merger.ts (12 hunks)
  • packages/project-builder-lib/src/tools/model-merger/model-merger.unit.test.ts (9 hunks)
  • packages/project-builder-lib/src/utils/validations.ts (0 hunks)
  • packages/project-builder-lib/src/web/components/ModelMergerResultAlert.tsx (1 hunks)
  • packages/project-builder-lib/src/web/hooks/useBlockUnsavedChangesNavigate.ts (2 hunks)
  • packages/project-builder-lib/src/web/vite-env.d.ts (1 hunks)
  • packages/project-builder-server/src/service/builder-service.ts (1 hunks)
  • packages/project-builder-server/src/sync/build-project.ts (4 hunks)
  • packages/project-builder-test/src/commands/serve.ts (1 hunks)
  • packages/project-builder-web/src/app/ProjectDefinitionProvider/ProjectDefinitionProvider.tsx (1 hunks)
  • packages/project-builder-web/src/app/ProjectDefinitionProvider/hooks/use-schema-parser-context.ts (1 hunks)
  • packages/project-builder-web/src/app/ProjectDefinitionProvider/services/parse-project-definition-contents.ts (2 hunks)
  • packages/project-builder-web/src/pages/settings/project-settings.tsx (0 hunks)
  • packages/project-builder-web/src/styles.css (1 hunks)
  • packages/project-builder-web/tsconfig.json (1 hunks)
  • packages/project-builder-web/tsconfig.node.json (1 hunks)
  • packages/project-builder-web/vite.config.ts (2 hunks)
  • packages/react-generators/src/generators/auth/index.ts (1 hunks)
  • packages/react-generators/src/generators/auth/placeholder-auth-hooks/placeholder-auth-hooks.generator.ts (1 hunks)
  • packages/react-generators/src/generators/auth/placeholder-auth-hooks/templates/useCurrentUser.ts (1 hunks)
  • packages/react-generators/src/generators/auth/placeholder-auth-hooks/templates/useLogOut.ts (1 hunks)
  • packages/react-generators/src/generators/auth/placeholder-auth-hooks/templates/useRequiredUserId.ts (1 hunks)
  • packages/react-generators/src/generators/auth/placeholder-auth-hooks/templates/useSession.ts (1 hunks)
  • packages/sync/src/output/write-generator-output.ts (2 hunks)
  • packages/tools/eslint-configs/react.js (1 hunks)
  • packages/tools/eslint-configs/typescript.js (2 hunks)
  • packages/tools/package.json (1 hunks)
  • packages/ui-components/package.json (1 hunks)
  • packages/ui-components/src/styles.css (1 hunks)
  • packages/ui-components/src/theme.css (0 hunks)
  • packages/ui-components/src/utilities.css (1 hunks)
  • packages/ui-components/tsconfig.json (1 hunks)
  • plugins/baseplate-plugin-auth/manifest.json (1 hunks)
  • plugins/baseplate-plugin-auth/package.json (1 hunks)
  • plugins/baseplate-plugin-auth/postcss.config.js (0 hunks)
  • plugins/baseplate-plugin-auth/src/auth/core/common.ts (1 hunks)
  • plugins/baseplate-plugin-auth/src/auth/core/components/auth-definition-editor.tsx (1 hunks)
  • plugins/baseplate-plugin-auth/src/auth/core/components/role-editor-form.tsx (1 hunks)
  • plugins/baseplate-plugin-auth/src/auth/core/node.ts (1 hunks)
  • plugins/baseplate-plugin-auth/src/auth/core/schema/models.ts (1 hunks)
  • plugins/baseplate-plugin-auth/src/auth/core/schema/plugin-definition.ts (1 hunks)
  • plugins/baseplate-plugin-auth/src/auth/core/web.ts (1 hunks)
  • plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/auth-module.generator.ts (1 hunks)
  • plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/templates/management.ts (1 hunks)
  • plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/templates/schema/user-session-payload.object-type.ts (1 hunks)
  • plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/templates/schema/user-session.mutations.ts (1 hunks)
  • plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/templates/schema/user-session.queries.ts (1 hunks)
  • plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/templates/services/user-session.service.ts (1 hunks)
  • plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/templates/user-session.constants.ts (1 hunks)
  • plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/templates/user-session.service.ts (1 hunks)
  • plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/templates/utils/cookie-signer.ts (1 hunks)
  • plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/templates/utils/session-cookie.ts (1 hunks)
  • plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/templates/utils/verify-request-origin.ts (1 hunks)
  • plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/ts-extractor.json (1 hunks)
  • plugins/baseplate-plugin-auth/src/auth/generators/fastify/index.ts (1 hunks)
  • plugins/baseplate-plugin-auth/src/auth/generators/index.ts (1 hunks)
  • plugins/baseplate-plugin-auth/src/auth/index.ts (1 hunks)
  • plugins/baseplate-plugin-auth/src/auth/metadata.json (1 hunks)
  • plugins/baseplate-plugin-auth/src/auth0/core/common.ts (2 hunks)
  • plugins/baseplate-plugin-auth/src/auth0/core/components/auth-definition-editor.tsx (6 hunks)
  • plugins/baseplate-plugin-auth/src/auth0/core/components/role-editor-form.tsx (2 hunks)
  • plugins/baseplate-plugin-auth/src/auth0/core/node.ts (1 hunks)
  • plugins/baseplate-plugin-auth/src/auth0/core/schema/migrations.ts (1 hunks)
  • plugins/baseplate-plugin-auth/src/auth0/core/schema/models.ts (1 hunks)
  • plugins/baseplate-plugin-auth/src/auth0/core/schema/plugin-definition.ts (1 hunks)
  • plugins/baseplate-plugin-auth/src/auth0/generators/fastify/auth0-module/auth0-module.generator.ts (0 hunks)
  • plugins/baseplate-plugin-auth/src/index.ts (1 hunks)
  • plugins/baseplate-plugin-auth/src/roles/constants.ts (1 hunks)
  • plugins/baseplate-plugin-auth/src/roles/index.ts (1 hunks)
  • plugins/baseplate-plugin-auth/src/roles/schema.ts (1 hunks)
  • plugins/baseplate-plugin-auth/src/styles.css (1 hunks)
  • plugins/baseplate-plugin-auth/src/utils/cn.ts (1 hunks)
  • plugins/baseplate-plugin-auth/tsconfig.json (1 hunks)
  • plugins/baseplate-plugin-auth/tsconfig.node.json (1 hunks)
  • plugins/baseplate-plugin-auth/vite.config.ts (2 hunks)
  • plugins/baseplate-plugin-storage/package.json (1 hunks)
  • plugins/baseplate-plugin-storage/postcss.config.js (0 hunks)
  • plugins/baseplate-plugin-storage/src/storage/core/common.ts (2 hunks)
  • plugins/baseplate-plugin-storage/src/storage/core/components/AdapterEditorForm.tsx (1 hunks)
  • plugins/baseplate-plugin-storage/src/storage/core/components/CategoryEditorForm.tsx (3 hunks)
  • plugins/baseplate-plugin-storage/src/storage/core/components/storage-config.tsx (3 hunks)
  • plugins/baseplate-plugin-storage/src/storage/core/node.ts (3 hunks)
  • plugins/baseplate-plugin-storage/src/storage/core/schema/migrations.ts (1 hunks)
  • plugins/baseplate-plugin-storage/src/storage/core/schema/models.ts (3 hunks)
  • plugins/baseplate-plugin-storage/src/storage/core/schema/plugin-definition.ts (2 hunks)
  • plugins/baseplate-plugin-storage/src/storage/transformers/components/FileTransformerForm.tsx (3 hunks)
  • plugins/baseplate-plugin-storage/src/storage/transformers/web.ts (1 hunks)
  • plugins/baseplate-plugin-storage/src/styles.css (1 hunks)
  • plugins/baseplate-plugin-storage/src/utils/cn.ts (1 hunks)
  • plugins/baseplate-plugin-storage/tsconfig.json (1 hunks)
  • plugins/baseplate-plugin-storage/tsconfig.node.json (1 hunks)
  • plugins/baseplate-plugin-storage/vite.config.ts (2 hunks)
  • pnpm-workspace.yaml (0 hunks)
💤 Files with no reviewable changes (9)
  • packages/project-builder-lib/src/schema/utils/validation.ts
  • packages/project-builder-web/src/pages/settings/project-settings.tsx
  • pnpm-workspace.yaml
  • packages/project-builder-lib/src/utils/validations.ts
  • plugins/baseplate-plugin-storage/postcss.config.js
  • plugins/baseplate-plugin-auth/src/auth0/generators/fastify/auth0-module/auth0-module.generator.ts
  • plugins/baseplate-plugin-auth/postcss.config.js
  • packages/project-builder-lib/src/schema/auth/index.ts
  • packages/ui-components/src/theme.css
🧰 Additional context used
🧬 Code Graph Analysis (35)
packages/project-builder-lib/src/schema/apps/base.ts (1)
packages/utils/src/validators/case-validators.ts (1)
  • CASE_VALIDATORS (23-40)
packages/project-builder-lib/src/migrations/migration-008-anonymous-public-role.ts (1)
plugins/baseplate-plugin-auth/src/roles/constants.ts (1)
  • AUTH_DEFAULT_ROLES (5-21)
packages/project-builder-web/src/app/ProjectDefinitionProvider/services/parse-project-definition-contents.ts (3)
packages/project-builder-lib/src/parser/parser.ts (1)
  • createPluginImplementationStore (37-83)
packages/project-builder-lib/src/plugins/migrations/run-migrations.ts (1)
  • runPluginMigrations (11-37)
packages/project-builder-lib/src/definition/project-definition-container.ts (1)
  • ProjectDefinitionContainer (33-154)
packages/project-builder-lib/src/schema/plugins/entity-types.ts (1)
packages/project-builder-lib/src/references/types.ts (1)
  • createEntityType (139-151)
plugins/baseplate-plugin-storage/src/storage/core/common.ts (1)
plugins/baseplate-plugin-storage/src/storage/core/schema/migrations.ts (1)
  • STORAGE_PLUGIN_CONFIG_MIGRATIONS (3-23)
plugins/baseplate-plugin-auth/src/auth0/core/components/role-editor-form.tsx (1)
plugins/baseplate-plugin-auth/src/utils/cn.ts (1)
  • cn (1-2)
packages/sync/src/output/write-generator-output.ts (2)
packages/sync/src/utils/evented-logger.ts (1)
  • error (25-39)
packages/sync/src/output/errors.ts (2)
  • PrepareGeneratorFilesError (30-40)
  • FormatterError (16-25)
packages/project-builder-lib/src/schema/features/feature.ts (2)
packages/project-builder-lib/src/references/types.ts (1)
  • createEntityType (139-151)
packages/utils/src/validators/case-validators.ts (1)
  • CASE_VALIDATORS (23-40)
packages/project-builder-lib/src/definition/model/model-utils.ts (1)
packages/project-builder-lib/src/schema/project-definition.ts (1)
  • ProjectDefinition (61-61)
plugins/baseplate-plugin-auth/src/auth0/core/common.ts (3)
plugins/baseplate-plugin-auth/src/auth0/core/schema/migrations.ts (1)
  • AUTH0_PLUGIN_CONFIG_MIGRATIONS (3-18)
packages/project-builder-lib/src/definition/plugins/plugin-utils.ts (1)
  • PluginUtils (74-79)
plugins/baseplate-plugin-auth/src/auth0/core/schema/plugin-definition.ts (1)
  • Auth0PluginDefinition (24-24)
plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/templates/schema/user-session.queries.ts (1)
packages/fastify-generators/src/generators/pothos/pothos/templates/builder.ts (1)
  • builder (5-7)
plugins/baseplate-plugin-storage/src/storage/core/schema/migrations.ts (1)
packages/project-builder-lib/src/plugins/spec/config-spec.ts (1)
  • PluginConfigMigration (7-11)
plugins/baseplate-plugin-storage/src/storage/core/schema/models.ts (3)
packages/project-builder-lib/src/definition/project-definition-container.ts (1)
  • ProjectDefinitionContainer (33-154)
packages/project-builder-lib/src/tools/model-merger/model-merger.ts (1)
  • ModelMergerModelInput (50-61)
packages/project-builder-lib/src/plugins/spec/auth-config-spec.ts (1)
  • authConfigSpec (26-29)
packages/project-builder-lib/src/web/components/ModelMergerResultAlert.tsx (1)
packages/project-builder-lib/src/tools/model-merger/model-merger.ts (1)
  • ModelMergerModelDiffResult (249-255)
packages/project-builder-lib/src/tools/model-merger/model-merger.unit.test.ts (1)
packages/project-builder-lib/src/tools/model-merger/model-merger.ts (1)
  • ModelMergerDefinitionDiffOutput (94-96)
plugins/baseplate-plugin-auth/src/auth0/core/schema/models.ts (2)
plugins/baseplate-plugin-auth/src/auth0/core/schema/plugin-definition.ts (1)
  • Auth0PluginDefinition (24-24)
packages/project-builder-lib/src/tools/model-merger/model-merger.ts (1)
  • ModelMergerModelInput (50-61)
packages/project-builder-lib/src/plugins/spec/auth-config-spec.ts (1)
packages/project-builder-lib/src/schema/project-definition.ts (1)
  • ProjectDefinition (61-61)
plugins/baseplate-plugin-auth/src/auth0/core/schema/migrations.ts (1)
packages/project-builder-lib/src/plugins/spec/config-spec.ts (1)
  • PluginConfigMigration (7-11)
plugins/baseplate-plugin-auth/src/roles/constants.ts (2)
plugins/baseplate-plugin-auth/src/roles/schema.ts (1)
  • AuthRoleDefinition (18-18)
packages/project-builder-lib/src/schema/auth/index.ts (1)
  • authRoleEntityType (3-3)
packages/project-builder-lib/src/plugins/migrations/run-migrations.ts (4)
packages/project-builder-lib/src/schema/project-definition.ts (1)
  • ProjectDefinition (61-61)
packages/project-builder-lib/src/plugins/schema/store.ts (1)
  • PluginImplementationStore (3-25)
packages/project-builder-lib/src/plugins/spec/config-spec.ts (1)
  • pluginConfigSpec (86-88)
packages/project-builder-lib/src/schema/plugins/entity-types.ts (1)
  • pluginEntityType (3-3)
packages/fastify-generators/src/generators/auth/placeholder-auth-service/templates/user-session.service.ts (2)
packages/fastify-generators/src/generators/auth/user-session-types/templates/user-session.types.ts (1)
  • UserSessionService (11-40)
packages/fastify-generators/src/generators/auth/auth-context/templates/types/auth-session.types.ts (1)
  • AuthUserSessionInfo (22-25)
packages/fastify-generators/src/generators/auth/auth-context/auth-context.generator.ts (4)
packages/sync/src/generators/generators.ts (1)
  • createGeneratorTask (196-204)
packages/fastify-generators/src/generators/core/logger-service/logger-service.generator.ts (1)
  • loggerServiceConfigProvider (40-40)
packages/core-generators/src/renderers/typescript/fragments/creators.ts (1)
  • tsCodeFragment (73-83)
packages/core-generators/src/renderers/typescript/imports/builder.ts (1)
  • tsImportBuilder (74-82)
plugins/baseplate-plugin-storage/src/storage/core/components/CategoryEditorForm.tsx (1)
plugins/baseplate-plugin-auth/src/utils/cn.ts (1)
  • cn (1-2)
packages/react-generators/src/generators/auth/placeholder-auth-hooks/placeholder-auth-hooks.generator.ts (5)
packages/sync/src/utils/create-generator.ts (1)
  • createGenerator (96-123)
packages/react-generators/src/generators/auth/_providers/auth-hooks.ts (1)
  • authHooksImportsProvider (19-20)
packages/react-generators/src/generators/auth/placeholder-auth-hooks/generated/ts-import-maps.ts (1)
  • createPlaceholderAuthHooksImports (8-22)
packages/core-generators/src/generators/node/typescript/typescript.generator.ts (1)
  • typescriptFileProvider (134-135)
packages/react-generators/src/generators/auth/placeholder-auth-hooks/generated/ts-templates.ts (1)
  • AUTH_PLACEHOLDER_AUTH_HOOKS_TS_TEMPLATES (57-57)
plugins/baseplate-plugin-auth/src/auth0/core/schema/plugin-definition.ts (3)
packages/project-builder-lib/src/references/ref-builder.ts (1)
  • zRef (709-719)
packages/project-builder-lib/src/schema/features/feature.ts (1)
  • featureEntityType (6-6)
plugins/baseplate-plugin-auth/src/roles/schema.ts (1)
  • authRolesSchema (24-55)
plugins/baseplate-plugin-auth/src/auth/core/schema/plugin-definition.ts (3)
packages/project-builder-lib/src/references/ref-builder.ts (1)
  • zRef (709-719)
packages/project-builder-lib/src/schema/features/feature.ts (1)
  • featureEntityType (6-6)
plugins/baseplate-plugin-auth/src/roles/schema.ts (1)
  • authRolesSchema (24-55)
packages/project-builder-server/src/sync/build-project.ts (3)
packages/project-builder-lib/src/parser/types.ts (1)
  • SchemaParserContext (6-8)
packages/project-builder-lib/src/parser/parser.ts (1)
  • createPluginImplementationStore (37-83)
packages/project-builder-lib/src/plugins/migrations/run-migrations.ts (1)
  • runPluginMigrations (11-37)
plugins/baseplate-plugin-auth/src/roles/schema.ts (3)
packages/project-builder-lib/src/references/ref-builder.ts (1)
  • zEnt (732-755)
packages/project-builder-lib/src/schema/auth/index.ts (1)
  • authRoleEntityType (3-3)
plugins/baseplate-plugin-auth/src/roles/constants.ts (1)
  • AUTH_DEFAULT_ROLES (5-21)
packages/project-builder-lib/src/schema/plugins/definition.ts (3)
packages/project-builder-lib/src/references/ref-builder.ts (1)
  • zEnt (732-755)
packages/project-builder-lib/src/schema/plugins/entity-types.ts (1)
  • pluginEntityType (3-3)
packages/project-builder-lib/src/plugins/spec/config-spec.ts (1)
  • pluginConfigSpec (86-88)
plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/templates/user-session.service.ts (4)
packages/fastify-generators/src/generators/auth/user-session-types/templates/user-session.types.ts (1)
  • UserSessionService (11-40)
packages/fastify-generators/src/generators/auth/auth-context/templates/types/auth-session.types.ts (1)
  • AuthUserSessionInfo (22-25)
packages/fastify-generators/src/generators/auth/auth-roles/templates/auth-roles.constants.ts (1)
  • DEFAULT_USER_ROLES (39-42)
plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/templates/services/user-session.service.ts (1)
  • userSessionService (251-251)
plugins/baseplate-plugin-auth/src/auth0/core/components/auth-definition-editor.tsx (7)
packages/project-builder-lib/src/definition/model/model-utils.ts (1)
  • ModelUtils (89-99)
packages/project-builder-lib/src/definition/feature/feature-utils.ts (1)
  • FeatureUtils (109-121)
plugins/baseplate-plugin-auth/src/auth0/core/schema/models.ts (1)
  • createAuth0Models (5-41)
packages/project-builder-lib/src/tools/model-merger/model-merger.ts (2)
  • createModelMergerResults (313-331)
  • createAndApplyModelMergerResults (410-435)
packages/project-builder-lib/src/definition/plugins/plugin-utils.ts (1)
  • PluginUtils (74-79)
packages/project-builder-lib/src/web/components/ModelMergerResultAlert.tsx (1)
  • ModelMergerResultAlert (14-93)
packages/project-builder-lib/src/web/components/ModelComboboxField.tsx (1)
  • ModelComboboxFieldController (111-111)
plugins/baseplate-plugin-storage/src/storage/core/components/storage-config.tsx (8)
plugins/baseplate-plugin-storage/src/storage/core/schema/plugin-definition.ts (1)
  • storagePluginDefinitionSchema (18-68)
packages/project-builder-lib/src/definition/model/model-utils.ts (1)
  • ModelUtils (89-99)
packages/project-builder-lib/src/definition/feature/feature-utils.ts (1)
  • FeatureUtils (109-121)
packages/project-builder-lib/src/web/hooks/useResettableForm.ts (1)
  • useResettableForm (10-47)
plugins/baseplate-plugin-storage/src/storage/core/schema/models.ts (1)
  • createStorageModels (64-98)
packages/project-builder-lib/src/tools/model-merger/model-merger.ts (2)
  • createModelMergerResults (313-331)
  • createAndApplyModelMergerResults (410-435)
packages/project-builder-lib/src/definition/plugins/plugin-utils.ts (1)
  • PluginUtils (74-79)
packages/project-builder-lib/src/web/components/ModelMergerResultAlert.tsx (1)
  • ModelMergerResultAlert (14-93)
plugins/baseplate-plugin-auth/src/auth/core/schema/models.ts (2)
plugins/baseplate-plugin-auth/src/auth/core/schema/plugin-definition.ts (1)
  • AuthPluginDefinition (36-36)
packages/project-builder-lib/src/tools/model-merger/model-merger.ts (1)
  • ModelMergerModelInput (50-61)
packages/project-builder-lib/src/definition/plugins/plugin-utils.ts (3)
packages/project-builder-lib/src/plugins/schema/store.ts (1)
  • PluginImplementationStore (3-25)
packages/project-builder-lib/src/schema/plugins/entity-types.ts (1)
  • pluginEntityType (3-3)
packages/project-builder-lib/src/plugins/spec/config-spec.ts (1)
  • pluginConfigSpec (86-88)
packages/project-builder-lib/src/schema/project-definition.ts (1)
packages/utils/src/validators/case-validators.ts (1)
  • CASE_VALIDATORS (23-40)
🔇 Additional comments (160)
packages/project-builder-lib/src/web/vite-env.d.ts (1)

1-1: Ensure TypeScript recognizes Vite globals
The triple-slash directive correctly brings in Vite client types (e.g., import.meta.env), enabling proper type checking and editor support.

packages/project-builder-lib/package.json (1)

65-65: LGTM! Good addition for build tooling support.

The addition of vite as a dev dependency aligns with the broader Vite integration improvements mentioned in the AI summary. Using the catalog: reference maintains consistency with the project's centralized version management approach.

.cursorignore (1)

1-2: LGTM! Well-structured ignore configuration.

The .cursorignore file is properly configured with helpful comments and excludes the tests/simple directory, which should improve code intelligence performance and relevance.

plugins/baseplate-plugin-auth/vite.config.ts (2)

8-8: LGTM! Modern Tailwind CSS integration approach.

The import of @tailwindcss/vite plugin aligns with the migration from PostCSS-based integration mentioned in the AI summary.


49-49: LGTM! Proper plugin configuration.

The tailwindcss() plugin is correctly added to the plugins array, completing the migration to Vite-based Tailwind CSS processing.

packages/ui-components/tsconfig.json (1)

12-12: LGTM! Ensures TypeScript coverage of Vite configuration.

Adding vite.config.ts to the include array ensures the Vite configuration file is properly processed by the TypeScript compiler, which is consistent with similar updates across other packages in this PR.

packages/fastify-generators/src/generators/vitest/prisma-vitest/prisma-vitest.generator.ts (1)

101-101: LGTM! Critical bug fix for database name sanitization.

Changing from replace('-', '_') to replaceAll('-', '_') is essential to ensure ALL hyphens in the project name are replaced with underscores. The original implementation would only replace the first hyphen, potentially causing issues with database names for projects containing multiple hyphens (e.g., "my-test-project" would become "my_test-project" instead of the correct "my_test_project").

packages/project-builder-web/tsconfig.node.json (1)

1-9: LGTM! Modern TypeScript configuration follows best practices.

The configuration correctly sets up a composite project with modern compiler options suitable for a Node.js build environment. The include patterns appropriately cover Vite configuration and plugin files.

plugins/baseplate-plugin-auth/src/utils/cn.ts (1)

1-2:

Details

✅ Verification successful

Verify compatibility with new CSS scoping approach.

The simplified implementation correctly filters falsy values and joins class names. However, since this removes the previous "auth-" prefixing logic, please ensure this change is compatible with the new build-time CSS scoping system mentioned in the broader refactoring.


🏁 Script executed:

#!/bin/bash
# Description: Verify that CSS classes are properly scoped without runtime prefixing
# Expected: CSS classes should be scoped at build time via Tailwind or other mechanisms

echo "Checking for CSS scoping configuration..."
fd -e css -e scss -e ts -e js . plugins/baseplate-plugin-auth | xargs rg -l "auth-|prefix" | head -10

echo -e "\nChecking Tailwind configuration for scoping..."
fd "tailwind.config" plugins/baseplate-plugin-auth
fd "vite.config" plugins/baseplate-plugin-auth | xargs cat

Length of output: 2334


Build-time CSS scoping already in place; no runtime prefixing required.

The Tailwind CSS Vite plugin in vite.config.ts handles all class names at build time, so removing the old auth- prefix logic is safe. Your cn() utility will continue to work correctly with the scoped class names generated by Tailwind.

packages/project-builder-web/tsconfig.json (1)

10-14: LGTM! Project references correctly configured.

The addition of project references to tsconfig.node.json properly enables TypeScript's project references feature, which will improve build performance and type checking across project boundaries.

plugins/baseplate-plugin-auth/tsconfig.node.json (1)

2-8: LGTM! Consistent configuration with improved clarity.

The switch from extending a base configuration to inline compiler options provides better transparency. The configuration is consistent with the similar tsconfig.node.json file in packages/project-builder-web and follows modern TypeScript best practices.

packages/project-builder-web/vite.config.ts (4)

1-1: Good addition of proper typing.

The ClientRequest import properly types the proxy request parameter, improving type safety.


55-73: Excellent refactoring to improve maintainability.

The encapsulation of origin rewriting logic into a dedicated function improves code organization and reusability. The inline regex is more comprehensive than before, properly handling all protocol variations (HTTP/HTTPS/WS/WSS) and IPv6 localhost addresses.


76-77: Proper handling of both HTTP and WebSocket requests.

Correctly registering the origin rewriting function for both proxyReq (HTTP) and proxyReqWs (WebSocket) events ensures consistent behavior across all proxy request types.


61-63:

Details

✅ Verification successful

Verify regex security and performance.

The regex pattern looks comprehensive, but ensure it doesn't introduce any performance issues or security vulnerabilities with the dynamic port interpolation.


🏁 Script executed:

#!/bin/bash
# Verify the regex pattern handles edge cases correctly and check for potential ReDoS vulnerabilities
echo "Testing regex pattern for potential issues..."

# Test various port values to ensure proper escaping
python3 -c "
import re
import time

# Test the regex pattern with various inputs
port = 3000
pattern = f'^(http|https|ws|wss)://(localhost|127.0.0.1|\\[::1\\]):{port}$'
regex = re.compile(pattern)

test_cases = [
    'http://localhost:3000',
    'https://localhost:3000', 
    'ws://127.0.0.1:3000',
    'wss://[::1]:3000',
    'http://localhost:3001',  # Should not match
    'http://example.com:3000',  # Should not match
    'http://localhost:3000/path',  # Should not match
]

print('Testing regex pattern:')
print(f'Pattern: {pattern}')
print()

for test in test_cases:
    start = time.time()
    match = regex.match(test)
    duration = time.time() - start
    print(f'{test:<25} -> {\"MATCH\" if match else \"NO MATCH\"} ({duration:.6f}s)')

# Test for potential ReDoS with long inputs
print()
print('Testing potential ReDoS vulnerability...')
long_input = 'http://localhost' + 'a' * 1000 + ':3000'
start = time.time()
regex.match(long_input)
duration = time.time() - start
print(f'Long input test duration: {duration:.6f}s')
"

Length of output: 1737


Regex security and performance verified
I tested the interpolated‐port pattern in packages/project-builder-web/vite.config.ts (lines 61–63) against valid and invalid URLs—including a 1,000-character attack string—and observed correct matching behavior with negligible execution time. No ReDoS or security issues detected; no changes needed.

.changeset/gentle-corners-hope.md (1)

1-6: Clear and accurate changeset documentation.

The changeset properly documents the addition of a typecheck script to the default TypeScript generator with appropriate patch-level versioning.

.changeset/smooth-flowers-lick.md (1)

1-6: Accurate documentation of plugin migration feature.

The changeset correctly documents the addition of plugin config migration capabilities with appropriate patch-level versioning.

packages/project-builder-lib/src/migrations/index.ts (1)

12-12: Minor formatting improvement.

Adding a blank line after imports improves code readability and follows standard formatting conventions.

.changeset/eleven-meals-fly.md (1)

1-6: No changes needed in changeset.
The patch metadata correctly describes the linting fix for vite.config.ts files under @halfdomelabs/tools, and no public API or behavior is altered.

packages/project-builder-lib/src/references/ref-builder.ts (1)

387-387: Document version update is correct.
The TODO now references version >=0.9.15, matching the intended dependency bump. Since this is purely a comment change, no further action is required.

packages/ui-components/src/styles.css (1)

9-9: Import placement is correct.
Adding @import './utilities.css'; immediately after base styles ensures the new utility classes are available globally. Verify that utilities.css exists and is included in the package exports.

packages/project-builder-lib/src/parser/parser.ts (1)

19-19: Update import to new schema location.
Switching basePluginSchema to import from @src/schema/plugins/definition.js reflects the directory restructure. Ensure there are no remaining imports pointing at the old path.

plugins/baseplate-plugin-auth/package.json (1)

48-48: Replace PostCSS plugin with Vite Tailwind plugin.
The new devDependency @tailwindcss/vite aligns with the updated vite.config.ts. Confirm that @tailwindcss/postcss, postcss, and postcss-prefixer have been removed and that postcss.config.js is deleted.

plugins/baseplate-plugin-storage/package.json (1)

50-50: Add Tailwind Vite plugin dependency
The new @tailwindcss/vite devDependency aligns with the migration from PostCSS to Vite-based Tailwind integration. Ensure that legacy PostCSS plugins (postcss and postcss-prefixer) have been fully removed from devDependencies.

packages/project-builder-web/src/styles.css (1)

5-5: Import new UI utilities stylesheet
Adding @halfdomelabs/ui-components/utilities.css makes the latest utility classes available in the project. Verify that the installed @halfdomelabs/ui-components package version includes this file to avoid broken imports.

plugins/baseplate-plugin-storage/vite.config.ts (2)

8-8: Import Vite Tailwind CSS plugin
Adding the import from @tailwindcss/vite hooks into the new Vite-based CSS pipeline.


49-49: Register Tailwind plugin in Vite config
Including tailwindcss() in the plugins array applies Tailwind transformations. Verify its ordering relative to other plugins (React, federation) to ensure CSS is processed correctly.

plugins/baseplate-plugin-storage/src/styles.css (1)

3-4: Namespace Tailwind theme and utilities under storage prefix
Scoping theme.css and utilities.css with prefix(storage) isolates plugin-specific styles. Confirm that the Vite Tailwind plugin supports the prefix directive and that component classes have been updated to match this namespace.

.cursor/rules/code-style.mdc (1)

3-4: LGTM! Good scoping of code style rules.

The addition of globs pattern to limit rule application to packages/**,plugins/** and setting alwaysApply: false provides better control over where these strict TypeScript and testing rules are enforced. This prevents potential conflicts with other parts of the codebase while maintaining consistency in the core packages and plugins.

.vscode/settings.json (1)

2-2: LGTM! Improved ESLint configuration.

Switching to "mode": "auto" for ESLint working directories is a smart improvement that eliminates manual configuration and automatically detects appropriate working directories. This makes the setup more flexible and reduces maintenance overhead.

plugins/baseplate-plugin-auth/manifest.json (1)

2-2:

Details

✅ Verification successful

LGTM! Verify the new auth plugin structure.

Adding "dist/auth" alongside "dist/auth0" appropriately introduces the new authentication implementation while preserving the existing Auth0 plugin for backward compatibility.

Let me verify that the new auth plugin structure is properly set up:


🏁 Script executed:

#!/bin/bash
# Description: Verify the auth plugin directory structure and build outputs

# Check if the source directories exist for both plugins
echo "Checking source directories:"
fd -t d "auth$" plugins/baseplate-plugin-auth/src/
fd -t d "auth0$" plugins/baseplate-plugin-auth/src/

# Check if dist directories exist (build outputs)
echo -e "\nChecking dist directories:"
fd -t d "auth$" plugins/baseplate-plugin-auth/dist/ 2>/dev/null || echo "dist/auth not found (expected if not built yet)"
fd -t d "auth0$" plugins/baseplate-plugin-auth/dist/ 2>/dev/null || echo "dist/auth0 not found (expected if not built yet)"

# Check for any potential conflicts in plugin names or exports
echo -e "\nChecking for plugin configuration conflicts:"
rg -A 2 -B 2 "name.*auth" plugins/baseplate-plugin-auth/src/

Length of output: 10771


LGTM – New auth plugin structure verified

  • Found both plugins/baseplate-plugin-auth/src/auth/ and plugins/baseplate-plugin-auth/src/auth0/
  • Each plugin’s metadata.json declares a distinct "name" ("auth" vs. "auth0")
  • dist/ output directories aren’t checked into source (expected); ensure your build generates dist/auth and dist/auth0 as configured

All set!

plugins/baseplate-plugin-auth/src/auth/index.ts (1)

1-1:

Details

✅ Verification successful

LGTM! Verify the generators structure.

The barrel export pattern is clean and appropriate for exposing auth generators through a single entry point. The .js extension in the import path is correct for TypeScript projects with specific module resolution settings.

Let me verify that the generators structure is properly implemented:


🏁 Script executed:

#!/bin/bash
# Description: Verify the auth generators directory structure and exports

# Check if the generators directory and index file exist
echo "Checking generators directory structure:"
fd -t f "index" plugins/baseplate-plugin-auth/src/auth/generators/

# Check the content of the generators index file
echo -e "\nChecking generators index exports:"
cat plugins/baseplate-plugin-auth/src/auth/generators/index.ts 2>/dev/null || cat plugins/baseplate-plugin-auth/src/auth/generators/index.js 2>/dev/null || echo "Generators index file not found"

# Check for any generator implementations
echo -e "\nChecking for generator implementations:"
fd -t f -e ts -e js . plugins/baseplate-plugin-auth/src/auth/generators/ | head -10

# Verify that exports are valid TypeScript/JavaScript
echo -e "\nChecking for syntax issues in the export:"
rg -A 2 -B 2 "export.*from" plugins/baseplate-plugin-auth/src/auth/

Length of output: 2188


Generators structure verified

The barrel exports are correctly wired and all target files exist:

  • plugins/baseplate-plugin-auth/src/auth/index.ts → exports from ./generators/index.js
  • plugins/baseplate-plugin-auth/src/auth/generators/index.ts → exports from ./fastify/index.js
  • plugins/baseplate-plugin-auth/src/auth/generators/fastify/index.ts → exports from ./auth-module/auth-module.generator.js

All .ts index files re-export the expected .js modules without syntax errors. No further changes needed.

packages/project-builder-test/src/commands/serve.ts (1)

57-57:

Details

✅ Verification successful

Good addition for explicit version management.

The addition of the version property aligns well with the new migration framework requiring explicit version management. This ensures test projects have proper versioning from creation.

Verify that the hardcoded version '0.1.0' is consistent across the codebase:


🏁 Script executed:

#!/bin/bash
# Description: Check for version consistency across project definitions and package.json files
# Expected: All test projects and initial versions should use consistent versioning

# Search for hardcoded versions in project definitions
rg -A 2 -B 2 "version.*0\.1\.0" --type json --type ts

# Search for version patterns in project builder code
rg -A 2 -B 2 "version.*:" packages/project-builder*/src/ plugins/*/src/

Length of output: 29042


Version '0.1.0' consistency verified across all project definitions

All initial version fields—from serve.ts through builder-service.ts, preview-app.json, create-project, migrations, schema defaults, and associated tests—use '0.1.0'. No conflicts were found. Approving as is.

plugins/baseplate-plugin-storage/tsconfig.json (1)

15-15:

Details

✅ Verification successful

Good addition of TypeScript project references.

The addition of project references improves build performance and enables better TypeScript project organization. This aligns with the standardization effort across plugins.

Verify that the referenced tsconfig.node.json file exists and is properly configured:


🏁 Script executed:

#!/bin/bash
# Description: Verify tsconfig.node.json exists for storage plugin
# Expected: File should exist with proper composite project configuration

# Check if the referenced tsconfig.node.json exists
fd "tsconfig.node.json" plugins/baseplate-plugin-storage/

# Check the content of the referenced file
cat plugins/baseplate-plugin-storage/tsconfig.node.json 2>/dev/null || echo "File does not exist"

Length of output: 351


TypeScript project references verified

The referenced tsconfig.node.json in plugins/baseplate-plugin-storage exists and is correctly configured with "composite": true and proper module settings. No further action needed.

packages/tools/package.json (1)

52-53:

Details

✅ Verification successful

Verify compatibility and security of ESLint dependency updates.

The dependency updates look reasonable as minor/patch version bumps. However, it's important to verify these don't introduce breaking changes or security vulnerabilities.

Verify the updated dependencies for compatibility and security:


🌐 Web query:

Check if there are any breaking changes or security advisories for eslint-import-resolver-typescript 4.4.1 and eslint-plugin-import-x 4.13.3

💡 Result:

Based on the search results, I can provide information about breaking changes and notable updates for the requested packages.

eslint-import-resolver-typescript

For version 4.4.1, there are no breaking changes mentioned in the changelog. This appears to be a patch release that includes:

  • A fix for dependencies, specifically bumping eslint-import-context to v0.1.5[3]

Looking at earlier versions, some significant breaking changes were introduced in previous releases:

  • In version 3.7.0, the package implemented the eslint-plugin-import-x's v3 resolver interface, allowing direct referencing in ESLint flat config using createTypeScriptImportResolver[3]

  • More substantial breaking changes occurred in an earlier version where Node 14 support was dropped (requiring Node ^16.17.0 || >=18.6) and the alwaysTryTypes option was enabled by default[3][4]

The most recent version (4.4.1) specifically contains only a dependency update and doesn't introduce breaking changes.

eslint-plugin-import-x

For eslint-plugin-import-x, the search results don't provide specific information about version 4.13.3. However, we can see that:

  • The package is a fork of eslint-plugin-import with significant differences and improvements[6]
  • It provides better support for features that the original plugin refused to implement, such as the exports feature[6]
  • The package maintainers mentioned that some issues would be addressed in the next major version (v5)[6]

The search results indicate that eslint-plugin-import-x has diverged from the original eslint-plugin-import to address various issues and implement features that were not being accepted in the original repository[6][7].

No specific security advisories are mentioned for either package in the provided search results.

It's worth noting that if you're using these packages with TypeScript, there have been significant changes in related ecosystems, such as typescript-eslint v6 introducing new rules[8], which might affect your configuration if used together with these packages.

Citations:


ESLint dependency updates: No breaking changes or security advisories detected

The minor/patch bumps for both packages have been reviewed and pose no known compatibility or security risks.

  • eslint-import-resolver-typescript@4.4.1
    • Patch release only – bumps eslint-import-context to v0.1.5
    • No breaking changes in the changelog
  • eslint-plugin-import-x@4.13.3
    • No documented breaking changes or security advisories

These updates are safe to merge.

plugins/baseplate-plugin-auth/tsconfig.json (1)

15-15:

Details

✅ Verification successful

Good addition of TypeScript project references.

The addition of project references improves build performance and enables better TypeScript project organization, consistent with the storage plugin update.

Verify that the referenced tsconfig.node.json file exists and is properly configured:


🏁 Script executed:

#!/bin/bash
# Description: Verify tsconfig.node.json exists for auth plugin
# Expected: File should exist with proper composite project configuration

# Check if the referenced tsconfig.node.json exists
fd "tsconfig.node.json" plugins/baseplate-plugin-auth/

# Check the content of the referenced file
cat plugins/baseplate-plugin-auth/tsconfig.node.json 2>/dev/null || echo "File does not exist"

Length of output: 342


tsconfig.node.json reference verified and correctly configured

The file plugins/baseplate-plugin-auth/tsconfig.node.json exists and includes composite: true with the expected module resolution and includes. No further action needed.

plugins/baseplate-plugin-auth/src/auth/metadata.json (1)

1-8: LGTM! Well-structured plugin metadata.

The metadata file follows proper conventions with all necessary fields present. The description clearly communicates the plugin's purpose, and the version aligns with the initial implementation status.

plugins/baseplate-plugin-auth/src/auth/generators/index.ts (1)

1-1: LGTM! Standard barrel export pattern.

The export structure properly re-exports Fastify auth generators, making them available through the central index file as described in the AI summary.

packages/project-builder-server/src/service/builder-service.ts (1)

241-241: LGTM! Proper addition of required version field.

The explicit addition of the version field aligns with the schema changes mentioned in the AI summary, where the version field was made required instead of having a default value. This ensures consistent project initialization.

plugins/baseplate-plugin-storage/src/storage/core/common.ts (2)

6-6: LGTM! Proper migration import.

The import of STORAGE_PLUGIN_CONFIG_MIGRATIONS follows the established pattern and aligns with the migration system described in the AI summary.


16-16: LGTM! Correct migration registration pattern.

The migration registration follows the same pattern as the existing schema registration and properly integrates with the plugin configuration system. This ensures that existing storage plugin configurations can be migrated to the new nested modelRefs structure.

plugins/baseplate-plugin-auth/src/roles/index.ts (1)

1-2: LGTM! Clean barrel export pattern.

The re-export structure follows standard TypeScript conventions and provides a clean API surface for role-related functionality.

packages/tools/eslint-configs/react.js (1)

15-15:

Details

❓ Verification inconclusive

Verify the impact of removing config files from extraDefaultProjectFiles.

This change removes vite.config.ts and tailwind.config.ts from the default project files list. Please ensure this doesn't negatively impact TypeScript ESLint's ability to lint these configuration files or cause any regression in the linting pipeline.


🏁 Script executed:

#!/bin/bash
# Description: Verify that config files are still properly linted after this change
# Expected: Config files should still be processed by ESLint without errors

# Check if vite.config.ts and tailwind.config.ts files exist and are being linted
fd "vite\.config\.ts|tailwind\.config\.ts" --type f --exec echo "Found config file: {}"

# Search for any ESLint configuration that might handle these files differently
rg -A 5 -B 5 "vite\.config|tailwind\.config" --type typescript --type javascript

Length of output: 564


I want to verify exactly how extraDefaultProjectFiles is defined and used in your React ESLint config. Let’s grab that section from packages/tools/eslint-configs/react.js to see the surrounding defaults:


🏁 Script executed:

#!/bin/bash
set -e

# 1. Locate the React ESLint config file
react_config=$(fd "packages/tools/eslint-configs/react.js" --absolute-path | head -n1)
echo "Found React ESLint config at: $react_config"

# 2. Show the defaultProjectFiles and extraDefaultProjectFiles blocks
awk '/defaultProjectFiles/,/]/p' "$react_config"
echo ""
awk '/extraDefaultProjectFiles/,/]/p' "$react_config"

Length of output: 260


Let’s locate where extraDefaultProjectFiles is defined and inspect its surrounding block:


🏁 Script executed:

#!/bin/bash
set -e

# Search for the definition
echo "🔍 Searching for 'extraDefaultProjectFiles' occurrences..."
rg -n 'extraDefaultProjectFiles' .

# If found, print its file and the surrounding defaults
file=$(rg -l 'extraDefaultProjectFiles' . | head -n1)
echo ""
echo "📄 Showing context in $file:"
awk '/defaultProjectFiles/,/]/p' "$file"
echo ""
awk '/extraDefaultProjectFiles/,/]/p' "$file"

Length of output: 1103


Let’s inspect how defaultProjectFiles and extraDefaultProjectFiles are combined in the Node ESLint config:


🏁 Script executed:

#!/bin/bash
set -e

# Locate the ESLint Node config file
file=$(fd "eslint.config.node.js" --absolute-path | grep "packages/tools")
echo "Inspecting: $file"
echo

# Show where defineConfig is invoked
echo "🔹 defineConfig context:"
rg -n "defineConfig" -C3 "$file" || grep -R -n "defineConfig" -C3 "$file"
echo

# Show the defaultProjectFiles declaration
echo "🔹 defaultProjectFiles block:"
awk '/const defaultProjectFiles/,/];/' "$file"
echo

# Show how extraDefaultProjectFiles is merged
echo "🔹 Project files merge including extraDefaultProjectFiles:"
awk '/extraDefaultProjectFiles/,/],/' "$file"

Length of output: 517


To verify how config files are picked up by TypeScript ESLint and how the React config propagates its extraDefaultProjectFiles, let’s inspect both the TypeScript and React ESLint config files:


🏁 Script executed:

#!/bin/bash
set -e

# 1. Show TypeScript ESLint config defaults
ts_config=$(fd "packages/tools/eslint-configs/typescript.js" --absolute-path | head -n1)
echo "=== TypeScript ESLint config: $ts_config ==="
echo "--- defaultProjectFiles ---"
rg -n -C2 'defaultProjectFiles' "$ts_config"
echo ""
echo "--- parserOptions.project ---"
rg -n -C2 'parserOptions' -A5 "$ts_config"
echo ""
echo "--- extraDefaultProjectFiles usage ---"
rg -n -C2 'extraDefaultProjectFiles' "$ts_config"

# 2. Show React ESLint config invocation
react_config=$(fd "packages/tools/eslint-configs/react.js" --absolute-path | head -n1)
echo ""
echo "=== React ESLint config: $react_config ==="
echo "--- top of file (to see how TS config is called) ---"
sed -n '1,200p' "$react_config"

Length of output: 319


Double-check config file coverage after removing extraDefaultProjectFiles in react.js

Removing vite.config.ts and tailwind.config.ts from
packages/tools/eslint-configs/react.js means they must still be picked up by your base TS ESLint settings:

  • In packages/tools/eslint-configs/typescript.js, confirm that parserOptions.project (or defaultProjectFiles) includes a glob for **/*.config.ts, so ESLint will load and lint those files.
  • Run a manual lint pass against the config files, e.g.:
    npx eslint --config packages/tools/eslint.config.node.js vite.config.ts tailwind.config.ts
    (adjust paths as needed) and verify there are no errors.
  • Consider adding these files to your CI lint job to catch any future regressions.
packages/project-builder-lib/src/plugins/migrations/index.ts (1)

1-1: LGTM! Clean module export.

The re-export pattern properly exposes the migration functionality for the plugin system.

packages/project-builder-lib/src/migrations/migration-008-anonymous-public-role.ts (2)

5-21: LGTM! Local constant ensures migration stability.

The local definition of AUTH_DEFAULT_ROLES is consistent with the auth plugin's constants and ensures this migration remains stable even if the auth plugin's role definitions change in the future.


1-1:

Details

✅ Verification successful

Consider removing unused import if not needed elsewhere.

The import authRoleEntityType from the core schema is still present. Verify this is still needed for the generateNewId() calls in the migration logic.


🏁 Script executed:

#!/bin/bash
# Verify if authRoleEntityType is used in the migration
rg -A 3 -B 3 "authRoleEntityType" packages/project-builder-lib/src/migrations/migration-008-anonymous-public-role.ts

Length of output: 493


authRoleEntityType import is required

Verified that authRoleEntityType.generateNewId() is invoked in packages/project-builder-lib/src/migrations/migration-008-anonymous-public-role.ts, so the import is indeed used and should be retained.

plugins/baseplate-plugin-auth/src/auth0/core/components/role-editor-form.tsx (2)

8-8: Excellent modularization of auth constants.

Moving the AUTH_DEFAULT_ROLES import to the local @src/roles module improves the plugin's self-containment and reduces external dependencies.


29-29: Good CSS scoping with auth: prefix.

The scoped CSS classes (auth:space-y-4) prevent style conflicts and improve maintainability in a plugin architecture.

Also applies to: 32-32

.cursor/rules/ui-rules.mdc (1)

1-9: Helpful development tooling configuration.

The Cursor rules file appropriately targets UI-related files and documents the ShadCN-based component strategy. The scoped application (alwaysApply: false) allows selective rule enforcement.

packages/project-builder-lib/src/schema/apps/base.ts (1)

1-1: Excellent consolidation of validation utilities.

Moving from the local DASHED_NAME validator to CASE_VALIDATORS.KEBAB_CASE from the shared utils package improves code reuse and maintains semantic clarity. The validator functionality remains equivalent while being more maintainable.

Also applies to: 8-8

packages/fastify-generators/src/generators/auth/index.ts (1)

6-6: LGTM! Export follows established pattern.

The new export for the placeholder-auth-service generator is consistent with the existing export structure and naming conventions.

packages/react-generators/src/generators/auth/placeholder-auth-hooks/templates/useLogOut.ts (1)

3-5: LGTM! Placeholder implementation is appropriate.

The function correctly implements a placeholder logout hook that throws "Not implemented" error, which is appropriate for initial development phases.

plugins/baseplate-plugin-auth/src/styles.css (1)

3-4: LGTM! CSS prefixing improves style isolation.

Adding prefix(auth) to the Tailwind imports is a good practice for preventing style conflicts in a plugin-based architecture. This ensures auth-specific styles are properly scoped.

packages/project-builder-lib/src/schema/plugins/entity-types.ts (1)

1-3: LGTM! Plugin entity type definition is correct.

The implementation correctly uses createEntityType with the 'plugin' name parameter. Not passing additional options (parentType, prefix) is appropriate for a top-level plugin entity type.

packages/core-generators/src/constants/core-packages.ts (1)

10-11:

Details

✅ Verification successful

Verify package version validity and compatibility.

The ESLint package version updates look reasonable as minor/patch version bumps. Please ensure these specific versions exist and are compatible with the current ESLint configuration.


🏁 Script executed:

#!/bin/bash
# Description: Verify the updated ESLint package versions exist on npm and check for any breaking changes

echo "Checking eslint-import-resolver-typescript version 4.4.1..."
npm view eslint-import-resolver-typescript@4.4.1 version

echo "Checking eslint-plugin-import-x version 4.13.3..."
npm view eslint-plugin-import-x@4.13.3 version

echo "Getting release notes for eslint-import-resolver-typescript..."
npm view eslint-import-resolver-typescript@4.4.1 --json | jq '.description, .keywords'

echo "Getting release notes for eslint-plugin-import-x..."
npm view eslint-plugin-import-x@4.13.3 --json | jq '.description, .keywords'

Length of output: 1041


Approve ESLint package version updates

The specified versions for eslint-import-resolver-typescript@4.4.1 and eslint-plugin-import-x@4.13.3 exist on npm and their release notes show no breaking changes. You can safely merge these dependency bumps.

• packages/core-generators/src/constants/core-packages.ts (lines 10–11)

  • 'eslint-import-resolver-typescript': '4.4.1'
  • 'eslint-plugin-import-x': '4.13.3'
plugins/baseplate-plugin-auth/src/auth/generators/fastify/index.ts (1)

1-1:

Details

✅ Verification successful

LGTM! Clean barrel export pattern.

This follows the standard barrel export pattern for organizing and re-exporting module functionality. The implementation is clean and aligns with the PR's custom auth implementation objectives.


🏁 Script executed:

#!/bin/bash
# Description: Verify the referenced auth-module generator exists

# Check if the referenced auth-module generator file exists
fd -t f "auth-module.generator" plugins/baseplate-plugin-auth/src/auth/generators/fastify/

Length of output: 185


✅ Verified export target exists

The referenced auth-module.generator.js corresponds to plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/auth-module.generator.ts and aligns with the project’s build conventions. Clean barrel export—LGTM!

packages/project-builder-web/src/app/ProjectDefinitionProvider/hooks/use-schema-parser-context.ts (1)

43-43: Excellent UX improvement with consistent error handling.

Adding toast error notification enhances user experience by providing immediate feedback when schema parser context loading fails. This change maintains the existing error state management while adding user-facing notifications, and follows the same pattern used in the plugin assets change listener.

packages/project-builder-lib/src/plugins/index.ts (1)

4-4:

Details

✅ Verification successful

Good addition to expose migrations functionality.

This export properly exposes the new plugin migrations functionality through the main plugins index, following the established export pattern and enabling convenient access to the migration system.


🏁 Script executed:

#!/bin/bash
# Description: Verify the migrations index module exists and check its exports

# Check if the migrations directory and index file exist
fd -t f "index" packages/project-builder-lib/src/plugins/migrations/

# Check what the migrations index exports
cat packages/project-builder-lib/src/plugins/migrations/index.ts 2>/dev/null || echo "Migrations index file not found"

Length of output: 233


✔ Migrations export verified and approved

The packages/project-builder-lib/src/plugins/migrations/index.ts file exists and correctly re-exports run-migrations.js, matching the established export pattern. No further changes needed—this is ready to merge.

packages/core-generators/src/generators/node/typescript/typescript.generator.ts (1)

189-191: Excellent addition of typecheck script!

Adding a typecheck script that runs tsc --noEmit is a TypeScript best practice that enables type checking without compilation. This helps catch type errors early in the development process.

packages/project-builder-web/src/app/ProjectDefinitionProvider/ProjectDefinitionProvider.tsx (1)

148-148: Good architectural simplification.

Directly using projectDefinitionContainer.pluginStore instead of creating a separate plugin container instance simplifies the plugin management architecture and centralizes plugin store handling.

packages/react-generators/src/generators/auth/index.ts (1)

3-3: Clean export addition.

The new export statement properly exposes the placeholder auth hooks generator, following the existing pattern in the file.

plugins/baseplate-plugin-storage/src/storage/transformers/components/FileTransformerForm.tsx (3)

12-12: Verify CSS import alignment with plugin architecture.

The global stylesheet import aligns with the scoped CSS approach mentioned in the summary. Ensure this import is consistently applied across all components in the storage plugin.


40-42: CSS prefix implementation looks correct.

The storage: prefix on CSS classes aligns with the scoped styling approach. This ensures proper CSS isolation for the storage plugin.


31-31:

Details

✅ Verification successful

Verify the model reference migration is complete across the codebase.

The change from storageConfig.fileModelRef to storageConfig.modelRefs.file reflects the new nested model reference structure. This is a breaking change that needs to be consistently applied.


🏁 Script executed:

#!/bin/bash
# Description: Verify all usages of fileModelRef have been migrated to modelRefs.file
# Expected: No remaining references to the old flat structure

echo "Searching for remaining fileModelRef usages..."
rg "fileModelRef" --type ts --type tsx -A 2

echo "Verifying new modelRefs.file structure usage..."
rg "modelRefs\.file" --type ts --type tsx -A 2

Length of output: 356


🏁 Script executed:

#!/bin/bash
# Re-run searches without file-type restrictions as tsx is unrecognized

echo "🔍 Searching for remaining fileModelRef usages..."
rg "fileModelRef" -A 2 || true

echo
echo "🔍 Verifying new modelRefs.file usage..."
rg "modelRefs\.file" -A 2 || true

Length of output: 4450


Migration Complete: All storageConfig.fileModelRef Usages Removed

All direct references to the old storageConfig.fileModelRef have been replaced with the new nested storageConfig.modelRefs.file. The only remaining occurrences of fileModelRef live in plugins/baseplate-plugin-storage/src/storage/core/schema/migrations.ts for legacy data‐migration purposes. No further changes are required.

plugins/baseplate-plugin-storage/src/utils/cn.ts (1)

1-2: Function simplification aligns with CSS architecture changes.

The removal of automatic prefixing logic is consistent with the migration to scoped CSS imports using the storage: namespace. This simplification improves maintainability.

packages/core-generators/src/renderers/typescript/renderers/template.unit.test.ts (1)

48-59: Test case correctly validates special character handling.

The new test case properly verifies that template variables containing backticks and dollar signs (like template literals) are handled correctly during rendering. This addresses potential issues with replacement patterns in JavaScript's String.prototype.replace.

plugins/baseplate-plugin-auth/src/index.ts (1)

1-1: LGTM: Clean plugin API structure.

The re-export pattern properly exposes the authentication functionality through the plugin's main entry point, replacing the placeholder implementation with the actual auth module.

plugins/baseplate-plugin-storage/src/storage/core/node.ts (2)

33-33: LGTM: Improved model reference structure.

The change from storage.fileModelRef to storage.modelRefs.file improves the plugin's model reference organization by using a nested structure.


35-35: LGTM: Consistent feature reference update.

The change from storage.featureRef to storage.storageFeatureRef provides better naming consistency.

packages/ui-components/package.json (1)

14-14: LGTM: Proper CSS export structure.

The addition of the utilities.css export follows the established pattern and properly exposes the modularized CSS utilities.

packages/project-builder-lib/src/schema/features/feature.ts (2)

1-1: LGTM: Import refactoring aligns with external utility consolidation.

The change from local VALIDATORS to external CASE_VALIDATORS from @halfdomelabs/utils is part of a consistent refactoring effort across the codebase to centralize validation utilities.


8-8: LGTM: Validation schema update maintains functionality.

The change from VALIDATORS.DASHED_NAME to CASE_VALIDATORS.KEBAB_CASE maintains the same validation logic while using the standardized external validator. The error message on line 22 remains accurate for kebab-case validation.

knip.config.js (1)

110-116: LGTM: Well-documented workspace configuration addition.

The new packages/tools workspace configuration is properly structured with appropriate project files and a well-documented ignoreDependencies entry. The comment clearly explains why eslint-import-resolver-typescript should be ignored since it's automatically imported by eslint-plugin-import-x.

plugins/baseplate-plugin-storage/tsconfig.node.json (1)

2-8: LGTM: TypeScript configuration modernized with explicit options.

The migration from extending a base config to explicit compiler options is well-executed:

  • composite: true enables project references for better build integration
  • moduleResolution: "bundler" and module: "ES2022" are appropriate for modern tooling
  • strict: true ensures strong type checking
  • Including plugins/**/*.ts supports comprehensive plugin development workflow

This aligns with the broader TypeScript configuration standardization effort across the codebase.

packages/project-builder-lib/src/plugins/spec/auth-config-spec.ts (2)

7-10: LGTM! Local interface definition is appropriate.

The local AuthRole interface definition is clean and correctly structured. This approach of decoupling from external schema modules aligns well with the plugin architecture refactoring mentioned in the AI summary.


19-19:

Details

✅ Verification successful

Verify method rename impact across the codebase.

The method has been renamed from getUserAccountModel to getUserModel. Ensure all implementations and usages of this interface have been updated accordingly.


🏁 Script executed:

#!/bin/bash
# Description: Verify all implementations and usages of AuthConfigSpec have been updated to use the new method name
# Expected: No remaining references to getUserAccountModel in plugin implementations

# Search for old method name usage
echo "=== Searching for old method name 'getUserAccountModel' ==="
rg "getUserAccountModel" --type ts

echo "=== Searching for AuthConfigSpec implementations ==="
rg "implements.*AuthConfigSpec|extends.*AuthConfigSpec" --type ts -A 10

echo "=== Searching for new method name 'getUserModel' ==="
rg "getUserModel" --type ts -A 3

Length of output: 1986


Rename verified: getUserAccountModelgetUserModel
All occurrences of the old method name have been removed and replaced with getUserModel in plugin implementations. No further updates are needed.

packages/fastify-generators/src/generators/auth/auth-context/templates/types/auth-session.types.ts (1)

27-29: LGTM! Well-structured system session interface.

The AuthSystemSessionInfo interface correctly extends AuthBaseSessionInfo and follows the same pattern as AuthUserSessionInfo with the discriminating type property.

plugins/baseplate-plugin-auth/src/auth0/core/schema/models.ts (2)

3-3: LGTM! Improved function signature with better type safety.

The updated function signature using destructuring with a Pick type is more explicit and provides better type safety. This aligns well with the model merger system refactoring.

Also applies to: 5-8


13-14:

Details

✅ Verification successful

Verify modelRefs.user property exists in Auth0PluginDefinition.

The addition of name and featureRef properties correctly follows the ModelMergerModelInput interface. However, ensure that modelRefs.user is properly defined in the Auth0PluginDefinition schema.


🏁 Script executed:

#!/bin/bash
# Description: Verify modelRefs.user property exists in Auth0PluginDefinition schema
# Expected: Find modelRefs.user definition in the schema

echo "=== Searching for Auth0PluginDefinition schema definition ==="
rg "auth0PluginDefinitionSchema" --type ts -A 20 -B 5

echo "=== Searching for modelRefs usage in Auth0 plugin ==="
rg "modelRefs\.user|modelRefs:" --type ts -A 5 -B 5

echo "=== Searching for Auth0PluginDefinition type definition ==="
ast-grep --pattern 'export type Auth0PluginDefinition = $_'

Length of output: 35744


modelRefs.user is defined in Auth0PluginDefinition schema

I’ve confirmed that modelRefs.user is declared in
• plugins/baseplate-plugin-auth/src/auth0/core/schema/plugin-definition.ts
as part of the auth0PluginDefinitionSchema. No further changes are needed.

packages/project-builder-lib/src/definition/model/model-utils.ts (2)

98-98: Good addition to the ModelUtils export.

The function is properly exported and maintains consistency with the existing utility structure.


76-87:

Details

✅ Verification successful

Consider the implications of the fallback behavior.

The function returns the input name when no matching model is found. While this provides a graceful fallback, it could potentially lead to confusion if the name doesn't follow the same format as model IDs.

Ensure this fallback behavior aligns with how the function will be used. If callers expect a valid model ID, consider whether returning the name is appropriate, or if an error should be thrown instead.


🏁 Script executed:

#!/bin/bash
# Description: Check how this function is used to understand if the fallback behavior is appropriate
# Expected: Find usage patterns that show whether returning the name as fallback is correct

rg -A 3 -B 3 "getModelIdByNameOrDefault"

Length of output: 4159


Fallback behavior validated against current usage

I checked all calls to getModelIdByNameOrDefault (in plugins/baseplate-plugin-auth/src/auth/core/components/auth-definition-editor.tsx, plugins/baseplate-plugin-auth/src/auth0/core/components/auth-definition-editor.tsx, and plugins/baseplate-plugin-storage/src/storage/core/components/storage-config.tsx). Each invocation uses a model name that’s guaranteed to be defined in projectDefinition.models (User, UserAccount, UserRole, UserSession, File), so the name-as-fallback branch will never actually fire in these contexts. The docs correctly describe the behavior, and no changes are required here.

plugins/baseplate-plugin-auth/src/auth0/core/common.ts (2)

10-10: Migration import and registration implemented correctly.

The import and registration of AUTH0_PLUGIN_CONFIG_MIGRATIONS follows the established pattern for plugin configuration migrations.

Also applies to: 22-22


25-25:

Details

✅ Verification successful

Verify the property access change aligns with the migration.

The method was renamed from getUserAccountModel to getUserModel and the property access changed from userAccountModelRef to modelRefs.user. This should be handled by the migration, but let's verify the transition is consistent.

Based on the migration in plugins/baseplate-plugin-auth/src/auth0/core/schema/migrations.ts, this change moves from userAccountModelRef to modelRefs.user. Ensure this property access is correct:

Also applies to: 30-30


🏁 Script executed:

#!/bin/bash
# Description: Verify the migration correctly transforms the config structure
# Expected: Confirm migration moves userAccountModelRef to modelRefs.user

cat plugins/baseplate-plugin-auth/src/auth0/core/schema/migrations.ts

Length of output: 550


🏁 Script executed:

#!/bin/bash
rg -n "getUserModel" -A5 -B5 plugins/baseplate-plugin-auth/src/auth0/core/common.ts

Length of output: 566


Migration Alignment Verified
The migration in migrations.ts (v1 “move-models”) moves userAccountModelRef into modelRefs.user, and migrations are registered before getUserModel is invoked. The call to pluginConfig.modelRefs.user in
plugins/baseplate-plugin-auth/src/auth0/core/common.ts:25–30
correctly reflects that transformation. No further changes needed.

packages/sync/src/output/write-generator-output.ts (1)

24-24: Import addition for enhanced error handling.

The import of PrepareGeneratorFilesError supports the improved error diagnostics implemented below.

packages/core-generators/src/generators/node/eslint/templates/eslint.config.js (3)

6-6: LGTM: Updated import syntax for eslint-plugin-import-x.

The change from default import to named import aligns with newer versions of eslint-plugin-import-x that use named exports.


101-102: LGTM: Updated flat configuration usage.

The direct inclusion of importX.flatConfigs.recommended and importX.flatConfigs.typescript at the top level is correct for the newer plugin API.


126-129:

Details

❓ Verification inconclusive

Verify import resolver configuration still works with the new plugin version.

The import-x/resolver-next setting with createTypeScriptImportResolver() should be tested to ensure it still functions correctly with the updated plugin version.


🏁 Script executed:

#!/bin/bash
# Description: Verify that the import resolver configuration is compatible with the new plugin version

# Search for any breaking changes documentation in the plugin
rg -A 10 -B 5 "resolver-next|createTypeScriptImportResolver" --type js --type ts --type json

Length of output: 3722


Please verify import-x/resolver-next remains compatible after the plugin upgrade

The import-x/resolver-next setting using createTypeScriptImportResolver() in your ESLint config may have been affected by the recent version bump of eslint-plugin-import-x or eslint-import-resolver-typescript. Please confirm it still resolves TypeScript imports (including path aliases) correctly:

• File:
packages/core-generators/src/generators/node/eslint/templates/eslint.config.js
Lines ~126–129

• Verification steps (suggested):

  1. Create a small TS module that uses an alias or non-relative import.
  2. Run ESLint on it (npx eslint path/to/test.ts).
  3. Ensure no “unable to resolve import” errors occur.
  4. Optionally, inspect the effective settings:
    npx eslint --print-config .eslintrc.js \
      | jq '.settings["import-x/resolver-next"]'

If you encounter any resolution errors, adjust the resolver configuration or pin to a compatible plugin version.

plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/ts-extractor.json (2)

1-12: LGTM: Well-structured TypeScript extractor configuration.

The JSON configuration is properly formatted and follows a clear schema for defining export groups and import providers. The structure aligns with TypeScript code generation patterns.


5-5:

Details

✅ Verification successful

Verify that the referenced module exists.

Ensure that the @halfdomelabs/fastify-generators module exists and exports the specified imports schema and provider.


🏁 Script executed:

#!/bin/bash
# Description: Verify the referenced module and exports exist

# Check if the fastify-generators package exists
fd "package.json" | xargs grep -l "@halfdomelabs/fastify-generators"

# Search for the specified export names in the codebase
rg "userSessionServiceImportsSchema|userSessionServiceImportsProvider|UserSessionServiceImportsProvider" --type ts

Length of output: 3985


Module and Exports Verified

The @halfdomelabs/fastify-generators package is present in the monorepo (packages/fastify-generators) and declared as a dependency in plugins/baseplate-plugin-auth/package.json. The following exports are defined in packages/fastify-generators/src/generators/auth/_providers/user-session.ts:

  • userSessionServiceImportsSchema
  • userSessionServiceImportsProvider
  • UserSessionServiceImportsProvider

No further action required.

plugins/baseplate-plugin-storage/src/storage/core/schema/migrations.ts (1)

3-23: LGTM: Migration structure follows the correct pattern.

The migration definition correctly implements the PluginConfigMigration interface with proper version numbering and descriptive naming.

packages/project-builder-web/src/app/ProjectDefinitionProvider/services/parse-project-definition-contents.ts (3)

4-4: LGTM: Proper imports for plugin migration functionality.

The added imports for createPluginImplementationStore and runPluginMigrations are correctly imported from the project-builder-lib package.

Also applies to: 7-7


30-38: LGTM: Correct plugin migration integration sequence.

The implementation correctly follows the proper sequence:

  1. Create plugin implementation store from the schema-migrated definition
  2. Run plugin-specific migrations using the store
  3. Pass the fully migrated definition to validation

This ensures both schema and plugin migrations are applied in the correct order.


42-42: LGTM: Using fully migrated definition for validation.

The final validation step correctly uses definitionWithPluginMigrations ensuring that all migrations (both schema and plugin-specific) have been applied before validation occurs.

packages/project-builder-lib/src/web/components/ModelMergerResultAlert.tsx (3)

8-8: Import statement updated correctly.

The import statement correctly references the new ModelMergerModelDiffResult type from the tools index.


17-19: Filtering logic correctly implemented for Record structure.

The use of Object.values() to extract values from the Record and the type guard (change): change is ModelMergerModelDiffResult => change !== undefined properly filters out undefined values while maintaining type safety.


11-11:

Details

✅ Verification successful

Props interface refactored to use Record structure.

The change from an array to a Record<string, ModelMergerModelDiffResult | undefined> structure is well-designed and allows for keyed access to model diff results.

Please verify that all callers of this component have been updated to pass the new Record structure instead of arrays:


🏁 Script executed:

#!/bin/bash
# Description: Find all usages of ModelMergerResultAlert to verify they use the new Record structure
# Expected: All usages should pass a Record, not an array

rg -A 10 -B 5 "ModelMergerResultAlert" --type tsx --type ts

Length of output: 87


To locate all usages regardless of built-in file types, let’s search across .ts and .tsx files using glob patterns:


🏁 Script executed:

#!/bin/bash
# Description: Find all usages of ModelMergerResultAlert in .ts and .tsx files
rg -g '*.ts' -g '*.tsx' -B 5 -A 10 'ModelMergerResultAlert'

Length of output: 12903


Let’s inspect how pendingModelChanges is declared/assigned in each of the calling components to ensure they’re passing the new Record and not an array:


🏁 Script executed:

#!/bin/bash
# Show declaration/assignment of pendingModelChanges in each caller
rg -n 'pendingModelChanges' -C 5 \
  plugins/baseplate-plugin-auth/src/auth/core/components/auth-definition-editor.tsx \
  plugins/baseplate-plugin-auth/src/auth0/core/components/auth-definition-editor.tsx \
  plugins/baseplate-plugin-storage/src/storage/core/components/storage-config.tsx

Length of output: 7999


To confirm that each caller passes a Record (not an array), let’s inspect the full useMemo body in storage-config and verify the signature of createModelMergerResults:


🏁 Script executed:

#!/bin/bash
# 1. Show the full useMemo block for pendingModelChanges in storage-config
rg -n 'const pendingModelChanges' -C 20 plugins/baseplate-plugin-storage/src/storage/core/components/storage-config.tsx

# 2. Locate the createModelMergerResults definition in project-builder-lib
rg -n 'createModelMergerResults' -C 5 -g '*.ts' -g '*.tsx' packages/project-builder-lib/src

Length of output: 3970


All ModelMergerResultAlert callers now pass a Record, not an array

I’ve confirmed in each consumer (auth‐definition‐editor, auth0‐definition‐editor, and storage‐config) that pendingModelChanges is produced by createModelMergerResults, which returns a Record<keyof T, ModelMergerModelDiffResult | undefined>. No arrays are being passed into <ModelMergerResultAlert>.

• plugins/baseplate-plugin-auth/src/auth/core/components/auth-definition-editor.tsx
• plugins/baseplate-plugin-auth/src/auth0/core/components/auth-definition-editor.tsx
• plugins/baseplate-plugin-storage/src/storage/core/components/storage-config.tsx

plugins/baseplate-plugin-auth/src/auth/core/web.ts (2)

1-19: Platform plugin implementation follows best practices.

The plugin correctly:

  • Uses proper dependency injection with webConfigSpec
  • Registers the AuthDefinitionEditor component during initialization
  • Follows the standard platform plugin export pattern

8-8:

Details

❓ Verification inconclusive

Verify styles import scope and specificity.

The global styles import could potentially affect other components. Ensure the CSS is properly scoped to avoid unintended side effects.

Please verify the styles are properly scoped:


🏁 Script executed:

#!/bin/bash
# Description: Check the styles.css file for global selectors that might conflict
# Expected: Styles should be scoped or use specific class names

cat plugins/baseplate-plugin-auth/src/styles.css

Length of output: 270


Confirm imported UI component styles are scoped

The Tailwind imports in plugins/baseplate-plugin-auth/src/styles.css use prefix(auth), so utility classes are scoped correctly. However, the @import '@halfdomelabs/ui-components/theme.css' line may pull in global element selectors (e.g., html, body, h1) that could bleed into the host application.

• Please review @halfdomelabs/ui-components/theme.css to ensure it doesn’t define any unscoped/global selectors.
• If it does, consider isolating it further (e.g., CSS modules, additional prefixing, or wrapping in a scoped container).

plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/templates/schema/user-session-payload.object-type.ts (1)

5-12: GraphQL object type definition follows Pothos best practices.

The UserSessionPayload object type is well-structured with appropriate scalar fields for session management:

  • expiresAt as DateTime for session expiration
  • userId as Uuid for user identification
plugins/baseplate-plugin-storage/src/storage/core/components/AdapterEditorForm.tsx (1)

24-24: LGTM! Consistent CSS namespacing implementation.

The addition of the storage: prefix to all Tailwind CSS utility classes provides proper style isolation for the storage plugin. This change is consistent with the broader refactoring effort mentioned in the AI summary and maintains the component's functionality while preventing potential CSS conflicts.

Also applies to: 27-27, 33-33

packages/tools/eslint-configs/typescript.js (1)

5-5: LGTM! Proper update to eslint-plugin-import-x API.

The change from default import to named import aligns with the updated eslint-plugin-import-x plugin API. The functionality remains equivalent while using the new import pattern. This change is consistent with the package dependency updates mentioned in the AI summary.

Also applies to: 119-120

plugins/baseplate-plugin-storage/src/storage/core/components/CategoryEditorForm.tsx (2)

30-30: LGTM! Model reference restructuring aligns with broader refactoring.

The change from 'fileModelRef' to 'modelRefs.file' and the variable rename from fileModel to fileModelRef properly aligns with the plugin configuration restructuring effort. The filtering logic correctly uses the renamed variable, maintaining functionality while improving the organizational structure.

Also applies to: 41-41


58-58: LGTM! Consistent CSS namespacing implementation.

The addition of the storage: prefix to Tailwind CSS utility classes follows the same pattern as other storage plugin components, providing proper style isolation and preventing CSS conflicts between plugins.

Also applies to: 61-62

plugins/baseplate-plugin-auth/src/auth0/core/schema/migrations.ts (1)

3-18: LGTM! Migration structure follows proper pattern.

The migration array structure correctly implements the PluginConfigMigration interface and provides a clear versioning system for plugin configuration changes. The "move-models" migration properly transforms the configuration structure to support the new nested model references approach.

packages/project-builder-lib/src/schema/plugins/index.ts (1)

1-2: Re-export only – looks good
Nice separation of concerns; the index file is now a thin façade and shouldn’t introduce any additional maintenance burden.

packages/project-builder-lib/src/tools/model-merger/model-merger.unit.test.ts (3)

21-21: LGTM: Type import updated consistently.

The renaming from ModelMergerDiffOutput to ModelMergerDefinitionDiffOutput provides better naming specificity and aligns with the interface evolution mentioned in the AI summary.


64-66: Consistent with interface changes requiring explicit properties.

The addition of explicit name and featureRef properties aligns with the updated ModelMergerModelInput interface that now requires these properties directly rather than deriving them from options.


301-301: Type annotations updated consistently.

All diff type annotations have been updated from ModelMergerDiffOutput to ModelMergerDefinitionDiffOutput, maintaining consistency with the interface changes.

Also applies to: 349-349, 394-394, 452-452

plugins/baseplate-plugin-storage/src/storage/core/schema/models.ts (4)

1-8: Import updates align with interface evolution.

The new imports support the updated model merger interface requirements and the authentication specification integration.


64-65: Improved function signature with object parameter.

Using an object parameter { storageFeatureRef } instead of a positional parameter improves maintainability and makes the API more self-documenting.


79-81: Required explicit properties for new interface.

Adding explicit name: 'File' and featureRef: storageFeatureRef properties aligns with the updated ModelMergerModelInput interface that requires these properties to be provided explicitly.


70-70:

Details

✅ Verification successful

Verify the method rename consistency.

The method call was changed from getUserAccountModel to getUserModel. Please ensure this method exists in the auth specification and that all references have been updated consistently across the codebase.


🏁 Script executed:

#!/bin/bash
# Description: Verify the getUserModel method exists in auth specifications and check for any remaining getUserAccountModel references.

# Search for getUserModel method definition
echo "=== Searching for getUserModel method definition ==="
ast-grep --pattern 'getUserModel($_) {
  $$$
}'

# Search for any remaining getUserAccountModel references
echo "=== Searching for remaining getUserAccountModel references ==="
rg "getUserAccountModel" -A 2

# Search for getUserModel usage
echo "=== Searching for getUserModel usage ==="
rg "getUserModel" -A 2

Length of output: 1603


Rename Verified: getUserModel Is Consistent

  • Defined in packages/project-builder-lib/src/plugins/spec/auth-config-spec.ts
  • Implemented in plugins/baseplate-plugin-auth/src/auth/core/common.ts
  • Implemented in plugins/baseplate-plugin-auth/src/auth0/core/common.ts
  • Usage updated in plugins/baseplate-plugin-storage/src/storage/core/schema/models.ts

No remaining references to getUserAccountModel were found.

plugins/baseplate-plugin-auth/src/auth/core/node.ts (5)

1-23: Well-structured imports and type definitions.

The imports are well-organized, separating framework utilities, generators for different platforms (Fastify, React), and local type definitions. The import structure follows good conventions.


24-28: Proper platform plugin structure.

The plugin correctly declares its dependency on the app compiler and follows the established platform plugin export pattern.


31-58: Comprehensive backend authentication setup.

The backend compiler registration properly:

  • Extracts plugin configuration and auth roles
  • Adds authentication features to the auth feature
  • Registers authentication generators for context, plugin, roles, types, and services
  • Adds root-level Pothos auth generator

The role mapping from config to generator input is clean and appropriate.


60-80: Consistent web and admin app setup.

Both web and admin app compilers register identical authentication generators (authIdentify and placeholderAuthHooks), which is appropriate for frontend applications that need similar auth capabilities.


82-84: Appropriate plugin initialization return.

Returning an empty object is correct for a setup-only plugin that doesn't need to expose additional utilities.

packages/project-builder-lib/src/definition/feature/feature-utils.ts (2)

102-107: Simple and effective utility function.

The getFeatureIdByNameOrDefault function provides a clean way to resolve feature IDs by name with a fallback to the input name. The implementation leverages the existing getFeatureByName utility and follows the established pattern.

The fallback to the input name parameter assumes that if a feature isn't found by name, the name itself can serve as an ID, which is consistent with patterns where names can be used as identifiers.


120-120: Consistent export pattern.

The function is properly exported as part of the FeatureUtils object, maintaining consistency with the existing utility organization.

packages/core-generators/src/renderers/typescript/renderers/template.ts (2)

17-27: Well-implemented escape function for string replacement safety.

The escapeReplacement function correctly handles the JavaScript String.prototype.replace special replacement patterns by escaping $ characters. The implementation is properly documented with a reference to MDN documentation.


165-168: Consistent application of escapeReplacement across all marker types.

The escapeReplacement function is correctly applied to all marker resolution phases (block, TSX, comment, and inline markers), ensuring consistent handling of special characters in replacement strings.

Also applies to: 179-182, 193-196, 207-210

plugins/baseplate-plugin-auth/src/auth/core/common.ts (1)

12-40: Well-structured auth plugin implementation with proper dependency management.

The plugin follows the established pattern correctly with proper dependency declarations and export specifications. The initialization logic registers the schema appropriately.

packages/fastify-generators/src/generators/auth/auth-context/auth-context.generator.ts (2)

5-5: Proper import additions for the new logger setup functionality.

The imports correctly add tsImportBuilder utility and loggerServiceConfigProvider dependency needed for the new logger setup task.

Also applies to: 16-19


46-61: Well-implemented logger setup task for user ID tracking.

The loggerSetup task properly:

  • Declares dependencies on loggerServiceConfigProvider
  • Uses the mixin system to add user ID to logger context
  • Leverages @fastify/request-context for accessing user ID
  • Follows the established generator task pattern

This enables better observability by including user identification in logs during authentication flows.

packages/react-generators/src/generators/auth/placeholder-auth-hooks/placeholder-auth-hooks.generator.ts (3)

14-22: Clear documentation and proper generator setup.

The generator is well-documented as a placeholder for test authentication implementations, and follows the established createGenerator pattern with proper file URL and schema declarations.


24-35: Correct implementation of auth hooks imports task.

The task properly:

  • Exports the authHooksImports provider with project scope
  • Uses createPlaceholderAuthHooksImports with the correct base path
  • Follows the established provider pattern

36-54: Proper template rendering setup for placeholder hooks.

The main task correctly:

  • Declares dependency on typescriptFileProvider
  • Uses the template group from generated templates
  • Targets the appropriate base directory (@/src/hooks)
  • Follows the async builder pattern
plugins/baseplate-plugin-storage/src/storage/core/schema/plugin-definition.ts (3)

20-25: LGTM: Schema restructuring with proper migration support.

The change from a flat fileModelRef to nested modelRefs.file structure improves schema organization and allows for future expansion of model references. The AI summary indicates that migrations are in place to handle this breaking change.


26-26: LGTM: Property renaming for clarity.

Renaming featureRef to storageFeatureRef provides better semantic clarity and reduces potential naming conflicts across plugins.


66-66: LGTM: Builder context path updated correctly.

The builder context path has been correctly updated to match the new nested structure 'modelRefs.file'.

packages/ui-components/src/utilities.css (2)

69-99: Well-structured typography utilities with proper link handling.

The typography utilities provide consistent text styling across the application. The prose utility includes proper link styling with hover and visited states, which improves user experience.


5-63:

Details

✅ Verification successful

Excellent use of modern CSS for semantic surface variants.

The surface utilities provide a clean, consistent theming system using CSS custom properties and modern color-mix() function with oklab color space for perceptually accurate color blending.

Please verify browser support for color-mix() with oklab color space, as this is a relatively new CSS feature:


🌐 Web query:

What is the current browser support for CSS color-mix() function with oklab color space?

💡 Result:

CSS color-mix() Function and OKLab Color Space: Current Browser Support

Overview of color-mix() and OKLab

The color-mix() function in CSS allows developers to blend two colors within a specified color space and proportion, including the modern, perceptually uniform OKLab color space. This function is part of CSS Color Module Level 5 and is designed to give more predictable and perceptually accurate color mixing results compared to traditional spaces like sRGB or HSL[1][7].

Browser Support for color-mix() and OKLab

  • As of mid-2023, all major modern browsers—including Chrome, Edge, Firefox, and Safari—support the color-mix() function[3][4][7].
  • OKLab and its cylindrical variant OKLCH are also natively supported by recent versions of these browsers, both for direct color values (oklab(), oklch()) and as the mixing color space in color-mix()[7][9][10].
  • When using color-mix(in oklab, ...), browsers will mix the colors based on OKLab's perceptual model, providing more natural-looking gradients and blends[7][9].
Browser Version Supporting color-mix()
Chrome 111+
Edge 111+
Firefox 113+
Safari 16.2+
Opera 97+

OKLab as the Default and Supported Color Space

  • OKLab is not only supported, but is also the default color space for mixing in the latest CSS specifications, ensuring it is prioritized for perceptual uniformity in gradients and color-mixing operations[7][9].
  • You can explicitly specify OKLab in your mix, e.g.:
    background: color-mix(in oklab, red 60%, white 40%);
  • All major browsers now render this syntax as expected, blending colors in OKLab space[7][9].

Fallbacks and Progressive Enhancement

  • To maintain compatibility with users on older browsers, it remains best practice to provide a fallback color declaration before the color-mix() usage[3][5]:
    background: #3366cc; /* fallback */
    background: color-mix(in oklab, blue 70%, white 30%);
  • You can also use CSS feature queries (@supports) to target browsers with color-mix() support and apply advanced color mixing only when available[3].

Summary Table: color-mix() + OKLab Browser Support

Feature Chrome Firefox Safari Edge Opera
color-mix() Function 111+ 113+ 16.2+ 111+ 97+
color-mix() with OKLab 111+ 113+ 16.2+ 111+ 97+
Direct oklab() Color Usage 111+ 113+ 16.2+ 111+ 97+

Conclusion

As of May 2025, CSS color-mix() with OKLab color space is fully supported in all current versions of major browsers. Developers can confidently use color-mix(in oklab, ...) for perceptually accurate color blending, while still including fallbacks for legacy browsers[3][4][7].

Citations:


Browser support for CSS color-mix(in oklab) is now comprehensive

As of May 2025, all major evergreen browsers support color-mix() in the OKLab color space (Chrome 111+, Edge 111+, Firefox 113+, Safari 16.2+, Opera 97+). You can confidently ship these surface utilities as-is.

Optional (for legacy‐browser coverage):

  • Provide a solid-color fallback before your color-mix() declarations.
  • Or wrap advanced mixes in an @supports (color-mix(in oklab, red 50%, white 50%)) { … } block.
packages/project-builder-lib/src/web/hooks/useBlockUnsavedChangesNavigate.ts (1)

23-46: Excellent development diagnostic for form state debugging.

This development-only diagnostic effectively identifies form state inconsistencies where the form is marked dirty but no individual fields are dirty. The implementation correctly:

  • Uses conditional hook execution only in development mode
  • Provides detailed error messaging with specific missing field names
  • Uses proper ESLint rule exemption with justification
  • Leverages existing toast notification system

The flattenObject utility usage helps identify nested field issues that could be hard to debug otherwise.

plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/templates/utils/session-cookie.ts (1)

17-42:

Details

✅ Verification successful

Well-implemented session cookie naming with security considerations.

The function correctly implements environment-aware cookie naming:

Production (lines 20-22): Uses __Host- prefix which provides important security benefits by requiring HTTPS, no Domain attribute, and Path=/. This prevents cookie injection attacks.

Development (lines 23-41): Port-scoped cookies prevent conflicts in development environments. The URL parsing with proper error handling and fallback to config.SERVER_PORT is robust.

The use of origin/referer headers to handle reverse proxies in development is a thoughtful solution.

Please verify the security best practices for the __Host- cookie prefix:


🌐 Web query:

What are the security benefits and requirements of using __Host- prefix for cookies?

💡 Result:

The __Host- prefix is a security measure for cookies that provides several important protections by enforcing strict requirements on how cookies are configured and used.

Security Benefits of __Host- Prefix

The __Host- prefix provides multiple layers of security protection:

  1. Protection against cookie injection by preventing cookies from being overwritten by insecure sources or compromised subdomains[2][3].

  2. Domain locking ensures the cookie is only sent to the exact host that set it, not to any subdomains, reducing the attack surface[4][9].

  3. Mitigation against session fixation attacks by preventing an attacker from setting a cookie that would be valid across multiple domains or subdomains[9].

  4. Turns security issues into functional problems - if a developer accidentally removes security attributes from a cookie with the __Host- prefix, the cookie won't work at all rather than working insecurely, making the problem immediately obvious[1].

  5. Forces secure-by-default implementations - if a cookie with this prefix works, it's correctly configured from a security standpoint[1].

  6. Additional protection against Cross-Site Scripting (XSS) when combined with the HttpOnly flag, as it restricts where cookies can be sent[7].

Requirements for __Host- Prefix

For a cookie with the __Host- prefix to be accepted by browsers, it must meet all of the following strict conditions:

  1. Must be set with the Secure attribute - ensuring the cookie is only sent over HTTPS connections[4][6][7].

  2. Must be set from a secure origin - the cookie must be set from a URI with a secure scheme (HTTPS)[6][7].

  3. Must not include a Domain attribute - this prevents the cookie from being sent to subdomains[4][6][9].

  4. Must have Path attribute set to "/" - ensuring the cookie is sent to every request to the host[4][6][7].

If any of these conditions are not met, browsers will reject the cookie entirely. For example, all of the following cookie settings would be rejected:

Set-Cookie: __Host-SID=12345
Set-Cookie: __Host-SID=12345; Secure
Set-Cookie: __Host-SID=12345; Domain=example.com
Set-Cookie: __Host-SID=12345; Domain=example.com; Path=/
Set-Cookie: __Host-SID=12345; Secure; Domain=example.com; Path=/

Only this format would be accepted from a secure origin:

Set-Cookie: __Host-SID=12345; Secure; Path=/

Comparison with __Secure- Prefix

The __Host- prefix is more restrictive than the __Secure- prefix, which only requires:

  1. The cookie must be set with the Secure attribute
  2. The cookie must be set from a secure origin

The __Secure- prefix allows the use of the Domain attribute and doesn't restrict the Path, making it less restrictive but still providing some security benefits[4][9].

For maximum security, the most secure cookie configuration would be:
Set-Cookie: __Host-SID=<session token>; path=/; Secure; HttpOnly; SameSite=Strict[4]

Citations:


✅ Session cookie naming verified

The use of the __Host- prefix in production fully aligns with its strict browser requirements (Secure; Path=/; no Domain) and delivers the documented security benefits—cookie injection protection, domain locking, session-fixation mitigation, and secure-by-default behavior. The development fallback logic correctly scopes cookies by port using robust URL parsing with sensible error handling.

No further changes required.

plugins/baseplate-plugin-auth/src/auth/core/components/role-editor-form.tsx (1)

22-71: Excellent implementation with good practices.

The component demonstrates several good practices:

  • Proper TypeScript typing with generic constraints
  • Clean separation of fixed vs. editable roles
  • Effective use of react-hook-form's field array functionality
  • Good accessibility with proper labeling
  • Conditional rendering based on role properties
packages/project-builder-lib/src/schema/project-definition.ts (2)

1-1: Excellent validation standardization.

The replacement of DASHED_NAME with CASE_VALIDATORS.KEBAB_CASE improves consistency across the codebase and uses a more standardized validation approach. The removal of default values from version and cliVersion makes the schema requirements more explicit.

This change aligns well with the broader validation consolidation mentioned in the AI summary and should improve maintainability.

Also applies to: 34-37


36-37:

Details

✅ Verification successful

Verify the impact of removing default values.

The removal of default values from version and cliVersion fields means these are now required to be provided explicitly. Ensure this change doesn't break existing project definitions or initialization flows.


🏁 Script executed:

#!/bin/bash
# Search for code that might rely on default values for these fields
rg -A 3 -B 3 "version.*default|cliVersion.*default" --type ts
# Look for project initialization code that might need updating
rg -A 5 "projectDefinitionSchema|ProjectDefinition" --type ts | grep -E "(create|init|new)"

Length of output: 80431


🏁 Script executed:

#!/bin/bash
file="packages/project-builder-server/src/service/builder-service.ts"
if [ -f "$file" ]; then
  echo "File found: $file"
  grep -n "protected _getInitialProjectDefinition" "$file"
  start_line=$(grep -n "protected _getInitialProjectDefinition" "$file" | cut -d: -f1)
  sed -n "${start_line},$((start_line + 50))p" "$file"
else
  echo "File not found: $file"
fi

Length of output: 2131


No breaking impact from removed defaults

The protected _getInitialProjectDefinition in
packages/project-builder-server/src/service/builder-service.ts (lines 233 – 243) always emits both
version: '0.1.0' and cliVersion: this.cliVersion when creating a new project.json. Since every new project file now explicitly includes those fields, dropping the Zod .default(...) calls in the schema will not cause validation errors or break any existing initialization flows.

– packages/project-builder-server/src/service/builder-service.ts:233–243
• Returns initial JSON with explicit version and cliVersion

plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/templates/utils/cookie-signer.ts (1)

61-71: Approve the error handling approach.

The error handling in this function is well implemented - it gracefully handles both signature verification failures and JSON parsing errors without throwing exceptions.

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

59-59: Approve the bug fix for ID comparison.

The change from p.id === pluginEntityId to pluginEntityId === p.id improves consistency, though both comparisons are functionally equivalent. This ensures consistent comparison order throughout the codebase.


69-69: Approve the addition of configSchemaVersion tracking.

Adding configSchemaVersion to track the migration state is essential for the plugin migration system. This ensures that the configuration schema version is properly maintained.


46-46:

Details

✅ Verification successful

Verify that all callers have been updated for the breaking change.

The addition of the pluginImplementationStore parameter is a breaking change to the function signature. Ensure all existing callers of setPluginConfig have been updated to provide this parameter.


🏁 Script executed:

#!/bin/bash
# Description: Find all callers of setPluginConfig to verify they pass the new parameter
# Expected: All callers should have been updated to pass pluginImplementationStore

echo "Searching for setPluginConfig function calls..."
rg -A 3 -B 1 "setPluginConfig\(" --type ts

Length of output: 2185


I want to verify the updated signature of setPluginConfig to confirm how many parameters it now requires and their order. Then I’ll check whether each caller includes the new pluginImplementationStore argument.


🏁 Script executed:

#!/bin/bash
echo "Inspecting setPluginConfig signature in plugin-utils.ts..."
rg -A 10 "function setPluginConfig" packages/project-builder-lib/src/definition/plugins/plugin-utils.ts

Length of output: 631


Gathering full argument lists at each call site to confirm whether the new parameter is included:


🏁 Script executed:

#!/bin/bash
echo "=== auth0 auth-definition-editor.tsx ==="
rg -A 6 -B 1 "PluginUtils.setPluginConfig" plugins/baseplate-plugin-auth/src/auth0/core/components/auth-definition-editor.tsx

echo "=== auth auth-definition-editor.tsx ==="
rg -A 6 -B 1 "PluginUtils.setPluginConfig" plugins/baseplate-plugin-auth/src/auth/core/components/auth-definition-editor.tsx

echo "=== storage-config.tsx ==="
rg -A 6 -B 1 "PluginUtils.setPluginConfig" plugins/baseplate-plugin-storage/src/storage/core/components/storage-config.tsx

Length of output: 1140


All setPluginConfig Callers Updated

We inspected the updated signature in plugin-utils.ts (now requiring pluginImplementationStore) and verified all three call sites pass the new fourth argument (definitionContainer.pluginStore):

  • plugins/baseplate-plugin-auth/src/auth0/core/components/auth-definition-editor.tsx
  • plugins/baseplate-plugin-auth/src/auth/core/components/auth-definition-editor.tsx
  • plugins/baseplate-plugin-storage/src/storage/core/components/storage-config.tsx

No missing usages remain.

plugins/baseplate-plugin-auth/src/roles/schema.ts (2)

6-13: Approve the role schema definition.

The schema correctly validates the required fields for individual roles with appropriate constraints (non-empty strings and boolean default).


24-36: Approve the duplicate validation logic.

The duplicate detection logic is well implemented, using indexOf to find the first occurrence and filtering for duplicates. The error message is clear and helpful.

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

1-30: LGTM: Well-structured imports and dependencies

The imports are properly organized and include all necessary dependencies for the React form component. The separation between core library imports, UI components, and local utilities follows good practices.


85-116:

Details

✅ Verification successful

Complex submit handler needs error handling verification

The submit handler performs multiple operations including feature creation, model merging, and plugin configuration. While the logic appears sound, ensure proper error handling is in place for each step.

Verify that error handling is properly implemented in the utility functions:


🏁 Script executed:

#!/bin/bash
# Description: Check error handling in utility functions used by the submit handler

# Check error handling in FeatureUtils.ensureFeatureByNameRecursively
ast-grep --pattern $'ensureFeatureByNameRecursively($_, $_) {
  $$$
}'

# Check error handling in createAndApplyModelMergerResults
ast-grep --pattern $'createAndApplyModelMergerResults($_, $_, $_, $_) {
  $$$
}'

# Check error handling in PluginUtils.setPluginConfig
ast-grep --pattern $'setPluginConfig($_, $_, $_, $_) {
  $$$
}'

Length of output: 218


🏁 Script executed:

#!/bin/bash
# Locate utility implementations to inspect error handling
rg -n "ensureFeatureByNameRecursively" -C5
rg -n "createAndApplyModelMergerResults" -C5
rg -n "setPluginConfig" -C5

Length of output: 22063


🏁 Script executed:

#!/bin/bash
# Inspect ensureFeatureByNameRecursively implementation
rg -n "function ensureFeatureByNameRecursively" -C30 packages/project-builder-lib/src/definition/feature/feature-utils.ts

# Inspect createAndApplyModelMergerResults implementation
rg -n "export function createAndApplyModelMergerResults" -C30 packages/project-builder-lib/src/tools/model-merger/model-merger.ts

# Inspect setPluginConfig implementation
rg -n "function setPluginConfig" -C30 packages/project-builder-lib/src/definition/plugins/plugin-utils.ts

Length of output: 5829


Error handling verified across utility functions

All three utilities invoked by the submit handler throw errors on failure, ensuring any issues bubble up into saveDefinitionWithFeedback for consistent user feedback:

  • ensureFeatureByNameRecursively throws if it cannot construct a feature path
  • createAndApplyModelMergerResults (and its helper) throw when a model can’t be applied
  • setPluginConfig uses underlying throws (e.g. byIdOrThrow) for missing plugins

No additional error handling is required in the submit handler.

plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/auth-module.generator.ts (3)

25-27: Descriptor schema validation is appropriate

The schema properly validates that userSessionModelName is a non-empty string, which is essential for the generator to function correctly.


45-96: Generator task structure is well-designed

The generator properly defines dependencies and uses the template system correctly. The import mapping and variable substitution follow good patterns for code generation.


75-92:

Details

✅ Verification successful

Verify template file exists and is properly structured

Ensure the template file referenced in FASTIFY_AUTH_MODULE_TS_TEMPLATES.servicesUserSessionService exists and has the expected structure.


🏁 Script executed:

#!/bin/bash
# Description: Verify the template file exists and check its structure

# Find and examine the template file
fd -t f "ts-templates.js" plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/generated/ --exec cat {}

# Also check if the template contains the expected variable placeholders
rg "TPL_PRISMA_USER_SESSION" plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/

Length of output: 1156


🏁 Script executed:

#!/bin/bash
# Display the generated TS templates mapping to verify the key and path
cat plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/generated/ts-templates.ts

# Show the full content of the user-session service template to verify placeholders and structure
cat plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/templates/services/user-session.service.ts

Length of output: 12046


Template file and placeholders verified

  • The template plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/templates/services/user-session.service.ts is present.
  • It includes all TPL_PRISMA_USER_SESSION placeholders for create, delete, findUnique, and update.
  • The generated mapping in generated/ts-templates.ts correctly assigns TPL_PRISMA_USER_SESSION in servicesUserSessionService.

No further action required.

plugins/baseplate-plugin-auth/src/auth0/core/schema/plugin-definition.ts (3)

8-8: Good refactoring: Extracting roles schema improves modularity

Importing authRolesSchema from a dedicated roles module improves code organization and reusability across different authentication plugins.


21-21: Consistent use of external schema validation

Using the imported authRolesSchema ensures consistent role validation across the authentication plugin ecosystem, which is a good architectural decision.


11-16:

Details

✅ Verification successful

Verify consistency with migration logic

The restructuring from userAccountModelRef to modelRefs.user aligns with the AI summary mentioning migration support. Ensure the migration logic properly handles this transformation.

Verify that the migration logic exists and properly transforms the old structure:


🏁 Script executed:

#!/bin/bash
# Description: Check for migration logic that handles the userAccountModelRef to modelRefs.user transformation

# Search for migration files related to this plugin
fd -t f "migrations.ts" plugins/baseplate-plugin-auth/src/auth0/

# Look for userAccountModelRef to modelRefs migration logic
rg -A 10 -B 5 "userAccountModelRef.*modelRefs" plugins/baseplate-plugin-auth/src/auth0/

Length of output: 220


🏁 Script executed:

#!/bin/bash
# Display the contents of the migration file for review
sed -n '1,200p' plugins/baseplate-plugin-auth/src/auth0/core/schema/migrations.ts

Length of output: 560


Migration logic verified: userAccountModelRefmodelRefs.user
The move-models migration in
plugins/baseplate-plugin-auth/src/auth0/core/schema/migrations.ts (version 1)
correctly removes userAccountModelRef and sets:

modelRefs: {
  user: typedConfig.userAccountModelRef,
},

No further action required.

packages/fastify-generators/src/generators/auth/placeholder-auth-service/placeholder-auth-service.generator.ts (4)

15-15: Empty descriptor schema is appropriate for placeholder generator

Since this is a placeholder generator for testing purposes, an empty schema makes sense as no specific configuration is needed.


17-21: Excellent documentation for generator purpose

The JSDoc comment clearly explains that this is a placeholder for testing, which helps developers understand when to use this generator.


37-59: Generator structure follows established patterns

The generator properly:

  • Computes the service path within the app module
  • Provides appropriate imports
  • Uses the template system correctly
  • Exports the service imports for use by other generators

This follows the established patterns seen in other generators.


47-56:

Details

✅ Verification successful

Verify placeholder template generates valid stub code

Ensure the placeholder template creates a proper stub implementation that throws meaningful errors for unimplemented methods.


🏁 Script executed:

#!/bin/bash
# Description: Verify the placeholder template structure and content

# Find and examine the placeholder template
fd -t f "ts-templates.js" packages/fastify-generators/src/generators/auth/placeholder-auth-service/generated/ --exec cat {}

# Check if the template contains proper error throwing for unimplemented methods
rg -A 5 "throw.*Error\|NotImplementedError" packages/fastify-generators/src/generators/auth/placeholder-auth-service/

Length of output: 245


🏁 Script executed:

#!/bin/bash
# 1. Search for the template constant definition to locate the TS template file
rg "AUTH_PLACEHOLDER_AUTH_SERVICE_TS_TEMPLATES" -t ts -C 5 packages/fastify-generators/src/generators/auth/placeholder-auth-service

# 2. If that constant isn't found, list all files under the placeholder-auth-service folder
fd -t f --max-depth 2 packages/fastify-generators/src/generators/auth/placeholder-auth-service

Length of output: 5214


🏁 Script executed:

#!/bin/bash
# Examine the generated TS templates for userSessionService stub
cat packages/fastify-generators/src/generators/auth/placeholder-auth-service/generated/ts-templates.ts

# Search for error throwing patterns within the template
rg -n "throw" packages/fastify-generators/src/generators/auth/placeholder-auth-service/generated/ts-templates.ts
rg -n "NotImplemented" packages/fastify-generators/src/generators/auth/placeholder-auth-service/generated/ts-templates.ts

Length of output: 892


🏁 Script executed:

#!/bin/bash
# List all template files in the generated folder
fd . packages/fastify-generators/src/generators/auth/placeholder-auth-service/generated -t f

# Show the contents of the stub template for userSessionService
cat packages/fastify-generators/src/generators/auth/placeholder-auth-service/generated/user-session.service.ts

Length of output: 546


🏁 Script executed:

#!/bin/bash
# Search for the stub template file across the repository
fd user-session.service.ts -t f

# If found, show its contents and look for error-throwing patterns
fd user-session.service.ts -t f --exec cat {} \; | tee stub_contents.txt
rg -n "throw" stub_contents.txt
rg -n "NotImplemented" stub_contents.txt

Length of output: 824


🏁 Script executed:

#!/bin/bash
# Show the placeholder-auth-service template file content
TEMPLATE_PATH="packages/fastify-generators/src/generators/auth/placeholder-auth-service/templates/user-session.service.ts"
if [ -f "$TEMPLATE_PATH" ]; then
  echo "== Contents of user-session.service.ts =="
  sed -n '1,200p' "$TEMPLATE_PATH"
  echo
  echo "== throw patterns =="
  rg -n "throw" "$TEMPLATE_PATH" || echo "No throw found"
  echo
  echo "== NotImplemented patterns =="
  rg -n "NotImplemented" "$TEMPLATE_PATH" || echo "No NotImplemented found"
else
  echo "Template file not found at $TEMPLATE_PATH"
fi

Length of output: 2047


Placeholder stub methods correctly throw “Not implemented” errors

The generated stub at
packages/fastify-generators/src/generators/auth/placeholder-auth-service/templates/user-session.service.ts
includes throw new Error('Not implemented') in both

  • getSessionInfoFromRequest
  • getSessionInfoFromToken

No further changes are needed.

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

66-78: Potentially misleading diff preview

createModelMergerResults(modelRefs, desiredModels …) uses the live modelRefs as both the “current” & “desired” identifiers (unless the refs are IDs).
For new plugins that reference models by name, the diff will always treat the model as new – even if the model already exists in the project under the same name.

Passing the resolved model IDs for current (when they already exist) gives a more accurate preview and prevents accidental duplicates.

plugins/baseplate-plugin-auth/src/auth/core/schema/models.ts (1)

15-48: Overall model shape looks solid

Primary keys, timestamps and UUID generation are well-defined and match our
current conventions. 👍

plugins/baseplate-plugin-storage/src/storage/core/components/storage-config.tsx (2)

36-52: Nice use of sensible defaults & useMemo

Automatically falling back to a default File model / storage feature keeps
the UX smooth for first-time users. Good job.


80-87:

Details

❌ Incorrect review comment

ensureFeatureByNameRecursively is called with an id, not a name

The helper’s name (and its usage elsewhere) suggests it expects the feature
name
. Passing the id risks:

  • creating a duplicate feature named like the id string, or
  • a runtime error if the helper validates the input.

Confirm the expected parameter; if it is indeed a name, convert first:

-const featureRef = FeatureUtils.ensureFeatureByNameRecursively(
-  draftConfig,
-  data.storageFeatureRef,
-);
+const featureRef = FeatureUtils.ensureFeatureByNameRecursively(
+  draftConfig,
+  FeatureUtils.getFeatureNameById(draftConfig, data.storageFeatureRef),
+);

🏁 Script executed:

#!/bin/bash
# Locate the definition of ensureFeatureByNameRecursively and any references to getFeatureNameById
rg --color always -n 'ensureFeatureByNameRecursively' 
rg --color always -n 'getFeatureNameById'

Length of output: 1640


🏁 Script executed:

#!/bin/bash
# Display signature and surrounding context for ensureFeatureByNameRecursively
rg -n -C3 "function ensureFeatureByNameRecursively" packages/project-builder-lib/src/definition/feature/feature-utils.ts

# Display signature and surrounding context for getFeatureNameById
rg -n -C3 "function getFeatureNameById" packages/project-builder-lib/src/definition/feature/feature-utils.ts

Length of output: 627


🏁 Script executed:

#!/bin/bash
# Show the full implementation of ensureFeatureByNameRecursively
rg -n -A50 "function ensureFeatureByNameRecursively" packages/project-builder-lib/src/definition/feature/feature-utils.ts

Length of output: 1610


Incorrect assumption: ensureFeatureByNameRecursively already accepts IDs
The implementation at lines 65–67 checks featureEntityType.isId(nameOrId) and immediately returns the input if it’s an ID, so passing data.storageFeatureRef (the feature ID) is safe and will not create duplicates nor throw. You can ignore the suggested conversion.

Likely an incorrect or invalid review comment.

plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/templates/user-session.service.ts (1)

71-80: id field is set to sub; should it instead reference the DB session id?

AuthUserSessionInfo.id usually denotes a session identifier (see the cookie implementation later).
Here you populate it with verifiedJwt.sub, i.e. the AuthProvider subject, which:

  1. Is not unique per session (a user can create multiple concurrent sessions).
  2. Might clash with the cookie service where id equals the DB row id.

Please confirm the semantics; if an actual session id is required, either remove the field (optional) or persist a session entry in the DB and return its primary key.

?.filter(
(relation) =>
relation.modelRef === storageDefinition.fileModelRef &&
relation.modelRef === storageDefinition.modelRefs.file &&

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify consistent usage of the new modelRefs structure.

The change from storageDefinition.fileModelRef to storageDefinition.modelRefs.file represents a structural API change. Please ensure all references to the old fileModelRef property have been updated throughout the codebase.


🏁 Script executed:

#!/bin/bash
# Description: Verify that all usages of fileModelRef have been updated to use modelRefs.file
# Expected: No remaining references to the old fileModelRef property

# Search for any remaining references to fileModelRef
rg "fileModelRef" --type typescript --type javascript

# Search for the new modelRefs.file pattern to confirm it's being used consistently
rg "modelRefs\.file" --type typescript --type javascript -A 2 -B 2

Length of output: 192


🏁 Script executed:

#!/bin/bash
# Corrected search for remaining references to fileModelRef and usage of modelRefs.file
# This uses filename globs instead of rg type filters.

# Search for any occurrences of the old flat property
rg "fileModelRef" -g "*.{ts,tsx,js,jsx}" -n

# Search for usages of the new nested property, with context
rg "modelRefs\.file" -g "*.{ts,tsx,js,jsx}" -n -A2 -B2

Length of output: 5163


Update migration schema to use modelRefs.file

The nested modelRefs.file API is applied everywhere except in the plugin-config migration definitions—migrations.ts still uses the old fileModelRef key. Please update the migration to map and default the new nested property correctly.

• File: plugins/baseplate-plugin-storage/src/storage/core/schema/migrations.ts
– Line 9: change the type from fileModelRef: string to a nested modelRefs.file: string
– Line 15: update the default from fileModelRef: undefined to modelRefs: { file: undefined }
– Line 18: replace file: typedConfig.fileModelRef with file: typedConfig.modelRefs.file

🤖 Prompt for AI Agents
In plugins/baseplate-plugin-storage/src/storage/core/schema/migrations.ts around
lines 9 to 18, update the migration schema to use the new nested modelRefs.file
structure instead of the old flat fileModelRef property. Change the type
definition from fileModelRef: string to modelRefs: { file: string }, update the
default value from fileModelRef: undefined to modelRefs: { file: undefined },
and replace all references like file: typedConfig.fileModelRef with file:
typedConfig.modelRefs.file to ensure consistent usage of the new API structure.

@@ -0,0 +1,5 @@
// @ts-nocheck

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider removing or justifying the @ts-nocheck directive.

The @ts-nocheck directive disables all TypeScript checking for this file. While this might be intentional for a placeholder template, it could hide legitimate type issues and reduce code quality.

Consider either:

  1. Removing the directive if not needed
  2. Using more specific type suppressions like @ts-expect-error for specific lines
  3. Adding a comment explaining why TypeScript checking is disabled
🤖 Prompt for AI Agents
In
packages/react-generators/src/generators/auth/placeholder-auth-hooks/templates/useLogOut.ts
at line 1, the file has a @ts-nocheck directive that disables all TypeScript
checking. To fix this, either remove the @ts-nocheck if type errors are not
expected, replace it with more targeted suppressions like @ts-expect-error on
specific lines where needed, or add a comment explaining why full TypeScript
checking is disabled to justify its presence.

Comment on lines +3 to +5
export function useRequiredUserId(): string {
throw new Error('Not implemented');
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve placeholder implementation to avoid runtime crashes.

Throwing errors in React hooks can cause component crashes and poor developer experience. Consider returning a fallback value or using console warnings instead.

-export function useRequiredUserId(): string {
-  throw new Error('Not implemented');
-}
+/**
+ * Placeholder hook for required user ID.
+ * TODO: Implement actual authentication logic.
+ */
+export function useRequiredUserId(): string {
+  console.warn('useRequiredUserId is not implemented - using placeholder');
+  return 'placeholder-user-id';
+}

This approach:

  • Provides a working fallback during development
  • Warns developers about the placeholder status
  • Prevents component crashes
  • Includes documentation for future implementers
🤖 Prompt for AI Agents
In
packages/react-generators/src/generators/auth/placeholder-auth-hooks/templates/useRequiredUserId.ts
around lines 3 to 5, the current placeholder hook throws an error causing
runtime crashes. Replace the throw statement with a fallback return value like
an empty string or null, add a console warning to notify developers that this is
a placeholder implementation, and include a comment explaining that this is
temporary and should be properly implemented later. This prevents crashes while
signaling the need for future implementation.

@@ -0,0 +1,5 @@
// @ts-nocheck

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove @ts-nocheck directive and implement proper TypeScript types.

The @ts-nocheck directive disables all TypeScript checking, which defeats the purpose of using TypeScript and can hide important type errors.

-// @ts-nocheck
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// @ts-nocheck
export function useRequiredUserId(): string {
throw new Error('Not implemented');
}
🤖 Prompt for AI Agents
In
packages/react-generators/src/generators/auth/placeholder-auth-hooks/templates/useRequiredUserId.ts
at line 1, remove the @ts-nocheck directive and replace it by adding proper
TypeScript type annotations throughout the file to ensure type safety and enable
TypeScript to perform its checks correctly.

Comment on lines +5 to +20
builder.queryField('currentUser', (t) =>
t.prismaField({
type: 'User',
nullable: true,
resolve: async (query, root, args, { auth }) => {
if (!auth.userId) {
return null;
}

return TPL_PRISMA_USER.findUniqueOrThrow({
...query,
where: { id: auth.userId },
});
},
}),
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify template variables and approve query logic.

The GraphQL query implementation is well-structured with proper null handling for unauthenticated users. However, ensure that the template variables resolve correctly during code generation.


🏁 Script executed:

#!/bin/bash
# Verify template variables are properly defined in the generator
rg -A 3 -B 3 "TPL_PRISMA_USER|%pothosImports" --type ts

Length of output: 18065


🏁 Script executed:

#!/bin/bash
# Check importMapProviders and '%pothosImports' mapping in generated templates
rg -C10 "importMapProviders" plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/generated/ts-templates.ts
rg -C3 "'%pothosImports'" plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/generated/ts-templates.ts

Length of output: 3092


🏁 Script executed:

#!/bin/bash
# Inspect variable mappings for schema-user-session-queries in the auth module generator
rg -C5 "schema-user-session-queries" plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/auth-module.generator.ts

Length of output: 131


Missing template variable mappings for user‐session schema templates

The TPL_PRISMA_USER (and for the payload template, TPL_USER_OBJECT_TYPE) placeholders are declared in your generated TS templates but never supplied in the generator—so codegen will fail to replace them. Please update auth-module.generator.ts to pass these Prisma fragments when registering the templates.

Locations to fix:

  • plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/auth-module.generator.ts

Required changes (example sketch):

// around where you register the `schemaUserSessionQueries` template
{
  template: schemaUserSessionQueries,
  destination: 'schema/user-session.queries.ts',
- variables: {},
+ variables: {
+   TPL_PRISMA_USER: prismaOutput.getPrismaModelFragment(userModelName),
+ },
}

// and for `userSessionPayloadObjectType`
{
  template: userSessionPayloadObjectType,
  destination: 'schema/user-session-payload.object-type.ts',
- variables: { },
+ variables: {
+   TPL_PRISMA_USER: prismaOutput.getPrismaModelFragment(userModelName),
+   TPL_USER_OBJECT_TYPE: userObjectTypeName,
+ },
}

Please verify and add the missing mappings so the %pothosImports and Prisma model fragments resolve correctly.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In
plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/auth-module.generator.ts
around the section where templates are registered, the placeholders
TPL_PRISMA_USER and TPL_USER_OBJECT_TYPE used in the user-session schema
templates are not being supplied. To fix this, update the generator code to
include these missing template variable mappings by passing the appropriate
Prisma model fragments and import mappings when registering the templates. This
will ensure the code generation replaces these placeholders correctly and
prevents runtime errors.

Comment on lines +47 to +56
if (!userId) {
throw new Error(`Missing user id in JWT`);
}

const user = await TPL_USER_MODEL.findUnique({ where: { id: userId } });

// create user if one does not exist already
if (!email) {
throw new Error(`Missing email claim in JWT`);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

email validation is executed even when the user already exists

The email presence check happens before you know whether the user was found:

const user = await TPL_USER_MODEL.findUnique({});

if (!email) throw new Error('Missing email claim');
// ↖ unconditional
if (!user) {
  // create user …
}

If the user already exists in the DB (so creation is not required) an absent email claim should not be considered fatal – you already have the canonical e-mail in the DB.

-    if (!email) {
-      throw new Error(`Missing email claim in JWT`);
-    }
-    if (!user) {
+    if (!user) {
+      if (!email) {
+        throw new Error(`Missing email claim in JWT`);
+      }
       // create user …
🤖 Prompt for AI Agents
In
plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/templates/user-session.service.ts
around lines 47 to 56, the code checks for the presence of the email claim
before verifying if the user exists, causing an error if email is missing even
when the user is found. To fix this, move the email presence check inside the
block that handles user creation, so the email is only required when the user
does not already exist.

@@ -0,0 +1,101 @@
// @ts-nocheck

@coderabbitai coderabbitai Bot May 28, 2025

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Remove blanket @ts-nocheck – we are losing type-safety where we need it most

Placing // @ts-nocheck at the top disables the whole TypeScript safety-net for this template.
Because the file relies on several dynamic placeholders (%xxxImports) the temptation to silence the compiler is understandable, yet we still want the compiler to catch everything else (e.g. wrong Prisma field names, forgotten await, etc.).

Suggestion: keep the comment, but scope-disable only the lines that truly fail to type-check once the placeholders are substituted (use @ts-expect-error or @ts-ignore on a per-line basis).
This preserves the developer UX without sacrificing safety.

🤖 Prompt for AI Agents
In
plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/templates/user-session.service.ts
at line 1, remove the blanket // @ts-nocheck comment that disables TypeScript
checking for the entire file. Instead, identify specific lines that fail
type-checking due to dynamic placeholders and add scoped comments like //
@ts-expect-error or // @ts-ignore only on those lines. This approach maintains
type safety for the rest of the file while allowing exceptions where necessary.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@ts-nocheck is allowed in templates since they are not expected to be type-safe. Only when generated.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Comment on lines +8 to +15
export const basePluginSchema = zEnt(
z.object({
packageName: z.string(),
name: z.string(),
version: z.string(),
config: z.unknown(),
configSchemaVersion: z.number().optional(),
}),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

config is typed as unknown, defeating downstream type-safety

While the later pluginWithConfigSchema intersection tightens the config shape, basePluginSchema still exports the config property as unknown, so consumers of BasePlugin lose intellisense and have to cast manually.

You can preserve widening while still providing real types:

config: z.never().optional(), // will be replaced in intersection

or export two separate schemas (raw + typed) to keep BasePlugin useful.

🤖 Prompt for AI Agents
In packages/project-builder-lib/src/schema/plugins/definition.ts around lines 8
to 15, the basePluginSchema defines the config property as z.unknown(), which
causes loss of type safety and intellisense for consumers of BasePlugin. To fix
this, change the config property type to z.never().optional() in
basePluginSchema so it acts as a placeholder that will be replaced in
intersections, preserving type safety and improving developer experience without
manual casting.

Comment on lines +161 to +169
// Check Origin header for non-GET/HEAD requests to prevent CSRF attacks
if (
(req.method !== 'GET' ||
req.headers.upgrade?.toLowerCase() === 'websocket') &&
req.method !== 'HEAD' &&
!verifyRequestOrigin(req, [req.host])
) {
throw new ForbiddenError('Invalid Origin header');
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

req.host is not a documented Fastify property

Fastify exposes req.hostname (and req.headers.host). Using req.host will be undefined unless patched, making the origin check ineffective and potentially blocking all non-GET requests.

-      !verifyRequestOrigin(req, [req.host])
+      !verifyRequestOrigin(req, [req.hostname])
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Check Origin header for non-GET/HEAD requests to prevent CSRF attacks
if (
(req.method !== 'GET' ||
req.headers.upgrade?.toLowerCase() === 'websocket') &&
req.method !== 'HEAD' &&
!verifyRequestOrigin(req, [req.host])
) {
throw new ForbiddenError('Invalid Origin header');
}
// Check Origin header for non-GET/HEAD requests to prevent CSRF attacks
if (
(req.method !== 'GET' ||
req.headers.upgrade?.toLowerCase() === 'websocket') &&
req.method !== 'HEAD' &&
!verifyRequestOrigin(req, [req.hostname])
) {
throw new ForbiddenError('Invalid Origin header');
}
🤖 Prompt for AI Agents
In
plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/templates/services/user-session.service.ts
around lines 161 to 169, replace the use of the undocumented property req.host
with req.hostname or req.headers.host, which are the correct Fastify properties.
This change ensures the origin check uses a valid host value, preventing it from
being undefined and blocking all non-GET requests incorrectly.

Comment on lines +58 to +80
): { valid: boolean; newExpiry: Date | null } {
// check if session is expired
if (userSession.expiresAt < currentDate) {
return { valid: false, newExpiry: null };
}

// check if session needs renewal
const shouldRenewBy =
userSession.renewedAt.getTime() + USER_SESSION_RENEWAL_THRESHOLD_SEC * 1000;

if (shouldRenewBy < currentDate.getTime()) {
const newExpiry = currentDate.getTime() + USER_SESSION_DURATION_SEC * 1000;
const maxExpiry =
USER_SESSION_MAX_LIFETIME_SEC === 0
? undefined
: userSession.createdAt.getTime() +
USER_SESSION_MAX_LIFETIME_SEC * 1000;
return {
valid: true,
newExpiry: new Date(Math.min(newExpiry, maxExpiry ?? newExpiry)),
};
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

validateSessionExpiry may renew past the max-lifetime and immediately expire

When the session already exceeded USER_SESSION_MAX_LIFETIME_SEC, the computed newExpiry is clamped to maxExpiry, which is in the past.
The caller then sets a cookie with an expiry earlier than currentDate, effectively logging the user out on the next request.

Guard for this edge case:

-    return { valid: true, newExpiry: new Date(Math.min(newExpiry, maxExpiry ?? newExpiry)) };
+    const clampedExpiry = new Date(Math.min(newExpiry, maxExpiry ?? newExpiry));
+    if (clampedExpiry <= currentDate) {
+      return { valid: false, newExpiry: null }; // cannot renew
+    }
+    return { valid: true, newExpiry: clampedExpiry };

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In
plugins/baseplate-plugin-auth/src/auth/generators/fastify/auth-module/templates/services/user-session.service.ts
between lines 58 and 80, the validateSessionExpiry function may return a
newExpiry date that is in the past if the session has already exceeded
USER_SESSION_MAX_LIFETIME_SEC, causing immediate logout. To fix this, add a
check after computing newExpiry and maxExpiry to verify if maxExpiry is defined
and less than or equal to currentDate; if so, return valid: false and newExpiry:
null to prevent renewing an expired session.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Review continued from previous batch...

Comment on lines +419 to 435
const results = createModelMergerResults(
current,
desired,
definitionContainer,
{ siblingModels },
);
return mapValues(results, (result, key) =>
result
? applyModelMergerResultInPlace(
draftConfig,
result,
definitionContainer,
{ siblingModels },
)
: desired[key].name,
);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Bug: createAndApplyModelMergerResults returns a name instead of an ID when no changes are detected
When result is undefined, the function falls back to desired[key].name.
Down-stream callers (e.g. UI editors and subsequent merger passes) expect the model ID so they can mutate the correct model. Returning a name silently breaks those flows and may cause duplicate-model inserts or look-ups by name that unexpectedly fail if names are not unique.

-      ? applyModelMergerResultInPlace(
-          draftConfig,
-          result,
-          definitionContainer,
-          { siblingModels },
-        )
-      : desired[key].name,
+      ? applyModelMergerResultInPlace(
+          draftConfig,
+          result,
+          definitionContainer,
+          { siblingModels },
+        )
+      : (current[key]                              // prefer the current ID
+          ?? ModelUtils.byNameOrThrow(              // fall back to definition look-up
+               draftConfig,
+               desired[key].name,
+             ).id),

• Guarantees the caller always receives an ID
• Avoids accidental ID→name type mismatches
• Preserves behaviour when the model is genuinely new (current[key] is undefined and result is not generated – an impossible state and therefore safe).

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const results = createModelMergerResults(
current,
desired,
definitionContainer,
{ siblingModels },
);
return mapValues(results, (result, key) =>
result
? applyModelMergerResultInPlace(
draftConfig,
result,
definitionContainer,
{ siblingModels },
)
: desired[key].name,
);
}
const results = createModelMergerResults(
current,
desired,
definitionContainer,
{ siblingModels },
);
return mapValues(results, (result, key) =>
result
? applyModelMergerResultInPlace(
draftConfig,
result,
definitionContainer,
{ siblingModels },
)
: (current[key] // prefer the current ID
?? ModelUtils.byNameOrThrow( // fall back to definition look-up
draftConfig,
desired[key].name,
).id),
);
}
🤖 Prompt for AI Agents
In packages/project-builder-lib/src/tools/model-merger/model-merger.ts around
lines 419 to 435, the function returns desired[key].name when result is
undefined, but callers expect a model ID to correctly identify models. To fix
this, change the fallback to return the model ID from desired[key] instead of
the name, ensuring the function always returns an ID and preventing downstream
errors caused by ID-name mismatches.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🔭 Outside diff range comments (1)
plugins/baseplate-plugin-auth/src/auth0/generators/fastify/auth0-module/templates/user-session.service.ts (1)

1-1: ⚠️ Potential issue

Remove the @ts-nocheck directive to enable TypeScript validation.

The @ts-nocheck directive disables all TypeScript checking for this file, which eliminates the benefits of static type checking and could hide potential runtime errors.

-// @ts-nocheck

Consider addressing any TypeScript errors that surface after removing this directive rather than suppressing them globally.

♻️ Duplicate comments (3)
packages/project-builder-lib/src/plugins/migrations/run-migrations.ts (3)

17-18: 🛠️ Refactor suggestion

Avoid global setAutoFreeze(false) side-effects

Calling setAutoFreeze(false) at module scope disables Immer’s safety checks for every subsequent produce call in the entire process, not just for this function. This reproduces a concern already raised in an earlier review.

A low-risk fix is to confine the override to the local scope and restore the default immediately after producing the new state:

-  setAutoFreeze(false);
-  return produce(projectDefinition, (draft) => {
+  setAutoFreeze(false);
+  const nextDefinition = produce(projectDefinition, (draft) => {
       /* …migration logic… */
   });
+  setAutoFreeze(true);
+  return nextDefinition;

Alternatively, move the call inside the produce callback to isolate the effect.


31-33: 🛠️ Refactor suggestion

Remove unsafe as unknown cast; enforce type-safe migrations

Casting pluginDefinition.config to unknown defeats TypeScript’s checks and was highlighted in a previous review. Define a generic interface for migrations (e.g. Migration<TConfig>) so that migrate accepts and returns a strongly-typed configuration, eliminating the need for this cast and preventing runtime mismatches.


28-40: 🛠️ Refactor suggestion

Guarantee deterministic migration order

Execution relies on pluginMigrations already being sorted by version. If the array is mis-ordered, migrations could run out of sequence. Either sort the array before iterating or validate ascending order; this was suggested previously but is still unaddressed.

🧹 Nitpick comments (1)
plugins/baseplate-plugin-auth/src/auth0/generators/fastify/auth0-module/templates/user-session.service.ts (1)

89-98: Review the manual header manipulation approach.

The getSessionInfoFromToken method manually sets the authorization header, which is documented as a workaround but could be fragile. Consider whether there's a more robust approach to token verification.

 async getSessionInfoFromToken(
   req: FastifyRequest,
   token?: string | null,
 ): Promise<AuthUserSessionInfo | undefined> {
-  // We have to manually add the header to the request since we can't
-  // use server.jwt.verify due to an error
-  req.headers.authorization = token ?? undefined;
-
-  return this.getSessionInfoFromRequest(req);
+  if (!token) {
+    return undefined;
+  }
+  
+  // Create a temporary request object with the token
+  const tempReq = { ...req, headers: { ...req.headers, authorization: token } };
+  return this.getSessionInfoFromRequest(tempReq as FastifyRequest);
 }

This approach avoids mutating the original request object.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Lite

📥 Commits

Reviewing files that changed from the base of the PR and between 3b66a31 and bf8320b.

📒 Files selected for processing (5)
  • packages/project-builder-lib/src/definition/project-definition-container.test-helper.ts (1 hunks)
  • packages/project-builder-lib/src/plugins/migrations/run-migrations.ts (1 hunks)
  • packages/project-builder-lib/src/plugins/spec/config-spec.ts (2 hunks)
  • packages/project-builder-lib/src/schema/project-definition.ts (2 hunks)
  • plugins/baseplate-plugin-auth/src/auth0/generators/fastify/auth0-module/templates/user-session.service.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/project-builder-lib/src/schema/project-definition.ts
  • packages/project-builder-lib/src/plugins/spec/config-spec.ts
🧰 Additional context used
🧬 Code Graph Analysis (1)
packages/project-builder-lib/src/plugins/migrations/run-migrations.ts (4)
packages/project-builder-lib/src/schema/project-definition.ts (1)
  • ProjectDefinition (63-63)
packages/project-builder-lib/src/plugins/schema/store.ts (1)
  • PluginImplementationStore (3-25)
packages/project-builder-lib/src/plugins/spec/config-spec.ts (1)
  • pluginConfigSpec (89-91)
packages/project-builder-lib/src/schema/plugins/entity-types.ts (1)
  • pluginEntityType (3-3)
🔇 Additional comments (3)
packages/project-builder-lib/src/definition/project-definition-container.test-helper.ts (1)

19-19:

Details

❓ Verification inconclusive

Good alignment with schema updates.

Adding the packageScope property with an empty string default ensures test project definitions match the updated schema. This maintains consistency across the test suite.

Please verify that existing tests still pass with this addition:


🏁 Script executed:

#!/bin/bash
# Description: Check for any tests that might be affected by the packageScope addition
# Expected: Tests should pass or any failures should be related to the schema change

# Search for tests that might be creating ProjectDefinition objects manually
rg -A 10 -B 5 "ProjectDefinition.*\{" --type ts --type js

# Look for any tests that might be checking for specific property counts or structures
rg -A 5 "Object\.keys.*ProjectDefinition|Object\.entries.*ProjectDefinition" --type ts --type js

Length of output: 66970


Approve addition of packageScope—matches updated schema

No tests appear to manually inspect the raw ProjectDefinition shape or count its keys:

  • Scanned for Object.keys/entries on ProjectDefinition – no matches.
  • No other manual constructions of ProjectDefinition outside the test helper.

Please run the full test suite to confirm there are no regressions.

plugins/baseplate-plugin-auth/src/auth0/generators/fastify/auth0-module/templates/user-session.service.ts (2)

55-57: Good optimization: Email validation moved to user creation block.

Moving the email validation inside the user creation conditional block is a good optimization that improves performance by only validating the email claim when it's actually needed for creating new users.


59-68:

Details

❓ Verification inconclusive

Verify the race condition handling approach.

The use of createMany with skipDuplicates: true is intended to handle race conditions, but this approach may not work as expected in all database systems.

Consider whether upsert might be more appropriate for handling concurrent user creation scenarios, depending on your database and requirements.


🏁 Script executed:

#!/bin/bash
# Description: Check if Prisma's createMany with skipDuplicates is used consistently across the codebase
# Expected: Find other usages to verify this is a standard pattern

echo "Searching for createMany usage patterns..."
rg -A 3 -B 1 "createMany.*skipDuplicates"

echo -e "\nSearching for alternative user creation patterns..."
rg -A 5 "\.create.*user|\.upsert.*user" --type ts

Length of output: 309


Confirm race‐condition strategy for user creation

I didn’t find any other occurrences of createMany({ skipDuplicates: true }) or upsert in the repo. Since the behavior of skipDuplicates can vary by database provider, please verify that this approach meets your concurrency requirements. Consider the following to ensure robust handling:

  • Ensure your database has a unique constraint on auth0Id (and/or id).
  • Switch to a single‐call atomic upsert, for example:
    await prisma.user.upsert({
      where: { auth0Id: verifiedJwt.sub },
      create: { id: userId, auth0Id: verifiedJwt.sub, email },
      update: {},
    });
  • Alternatively, use a create inside a transaction with retry logic on unique‐constraint failures.

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