Skip to content

Conversation

@kingston
Copy link
Collaborator

@kingston kingston commented Aug 19, 2025

Summary by CodeRabbit

  • New Features

    • Standardized model names for Auth and Storage (User, UserAccount, UserRole, UserSession, File).
    • Automatic model configuration; manual model selection removed.
  • Refactor

    • Plugin schemas and generators simplified to rely on fixed model names.
    • Model merger now shows a clear "Models Up to Date" alert when no changes are needed.
  • UI

    • Removed model-selection controls from Auth and Storage editors; streamlined forms.
  • Tests / Chores

    • Unified Vitest/Playwright/e2e config updates and switched debug to pnpm.
    • Added changeset documenting the standardization.

@vercel
Copy link

vercel bot commented Aug 19, 2025

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

Project Deployment Preview Comments Updated (UTC)
baseplate-project-builder-web Ready Ready Preview Comment Aug 19, 2025 8:53pm

@changeset-bot
Copy link

changeset-bot bot commented Aug 19, 2025

🦋 Changeset detected

Latest commit: 1434a37

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

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

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

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

@coderabbitai
Copy link

coderabbitai bot commented Aug 19, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

Standardizes model names across auth and storage plugins via plugin-specific constants, removes configurable modelRefs from schemas/UI/generators, adds ModelUtils name-based lookups, updates the model-merger to use sibling names, and simplifies compile hooks and test/tooling config.

Changes

Cohort / File(s) Summary
Tooling & test configs
.cursor/rules/dev-commands.mdc, .vscode/launch.json, vitest.config.js, scripts/run-vitest.js, packages/tools/vitest.config.node.js, packages/tools/vitest.config.react.js, packages/project-builder-cli/playwright.config.ts, packages/project-builder-cli/tsconfig.e2e.json, knip.config.js
Normalize frontmatter, switch VS Code/Vitest to pnpm, remove legacy run-vitest.js, change Vitest to projects/watch=false and adjust roots/excludes, move Playwright tests to ./e2e and TS e2e include, adjust knip globs.
Model utilities & merger UI
packages/project-builder-lib/src/definition/model/model-utils.ts, .../tools/model-merger/model-merger.ts, .../web/components/model-merger-result-alert.tsx, .../plugins/spec/auth-model-config-spec.ts
Add ModelUtils.byName/byNameOrThrow; model-merger serializes relation.modelRef using sibling name mapping and resolves current models by name; ModelMergerResultAlert always renders ("Models Up to Date"); auth model-getter type updated.
Auth model-name constants
plugins/plugin-auth/src/*/constants/model-names.ts (auth0, local-auth, placeholder-auth)
Add AUTH0_MODELS, LOCAL_AUTH_MODELS, PLACEHOLDER_AUTH_MODELS constants with fixed model name mappings (User, UserAccount, UserRole, UserSession).
Auth0 plugin changes
plugins/plugin-auth/src/auth0/core/common.ts, .../core/components/auth0-definition-editor.tsx, .../core/node.ts, .../core/schema/models.ts, .../core/schema/plugin-definition.ts, .../generators/fastify/auth0-module/auth0-module.generator.ts
Remove modelRefs from schema/UI; use AUTH0_MODELS and ModelUtils.byNameOrThrow; simplify generators/descriptor (drop userModelName) and compile hook signatures; models derived from AUTH0_MODELS.
Local-auth plugin changes
plugins/plugin-auth/src/local-auth/** (admin/web.ts, core/common.ts, core/components/local-auth-definition-editor.tsx, core/generators/**, core/node.ts, core/schema/models.ts, core/schema/plugin-definition.ts)
Replace dynamic modelRefs with LOCAL_AUTH_MODELS across editors, gating, generators, schema, and compile wiring; drop per-descriptor model-name parameters; editors compute and apply models automatically.
Placeholder-auth plugin changes
plugins/plugin-auth/src/placeholder-auth/** (core/common.ts, core/components/placeholder-auth-definition-editor.tsx, core/schema/models.ts, core/schema/plugin-definition.ts)
Switch to PLACEHOLDER_AUTH_MODELS and by-name lookups; remove modelRefs from schema/UI; simplify createAuthModels signature and types.
Storage plugin changes
plugins/plugin-storage/src/storage/constants/model-names.ts, .../core/components/storage-definition-editor.tsx, .../core/node.ts, .../core/schema/models.ts, .../core/schema/plugin-definition.ts, .../generators/fastify/storage-module/storage-module.generator.ts, .../generators/react/upload-components/upload-components.generator.ts, .../transformers/**/*.ts(x)
Add STORAGE_MODELS; remove modelRefs/fileModel fields from schemas, editors, and generator descriptors; generators and transformers now reference STORAGE_MODELS.file; createStorageModels returns Record keyed by STORAGE_MODELS.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User as Editor UI
  participant Editor as Plugin Definition Editor
  participant Lib as Project Builder Lib (ModelUtils, Merger)
  participant Def as Project Definition

  User->>Editor: Open plugin editor / submit changes
  Editor->>Editor: Load fixed MODEL constants (e.g., LOCAL_AUTH_MODELS)
  Editor->>Lib: compute desiredModels via create*Models(authDef)
  Editor->>Lib: createModelMergerResults({ desiredModels, targetNames: MODEL constants })
  Lib->>Def: Resolve current models by name (ModelUtils.byName/byNameOrThrow)
  Lib->>Lib: Serialize relations using sibling name mapping
  Lib-->>Editor: Pending changes (or "Models Up to Date")
  User->>Editor: Apply changes
  Editor->>Lib: createAndApplyModelMergerResults(MODEL constants, desiredModels)
  Lib->>Def: Apply model diffs
  Lib-->>Editor: Success
  Editor-->>User: Show success
Loading
sequenceDiagram
  autonumber
  participant Compiler as App Compiler
  participant Plugin as Plugin Node Entry
  participant Gen as Generators

  Compiler->>Plugin: compile()
  Plugin->>Gen: invoke generators (no model name args)
  Gen->>Gen: use MODEL constants (AUTH0_MODELS/LOCAL_AUTH_MODELS/STORAGE_MODELS)
  Gen-->>Plugin: build artifacts referencing constants
  Plugin-->>Compiler: register outputs
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.


📜 Recent review details

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

💡 Knowledge Base configuration:

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

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 8883688 and 1434a37.

📒 Files selected for processing (1)
  • knip.config.js (2 hunks)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch kingston/eng-832-standardize-data-model-names-for-auth-and-storage-plugins

🪧 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.
    • 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.
  • 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 the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

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

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

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.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • 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.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

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

⚠️ Outside diff range comments (1)
plugins/plugin-auth/src/local-auth/core/components/local-auth-definition-editor.tsx (1)

152-157: Typo in user-facing copy: “INTIIAL_” should be “INITIAL_

This is visible to users; please fix both occurrences.

-                    add a seed script to create the initial user provided a
-                    .seed.env exists with the INTIIAL_USER_EMAIL and
-                    INTIIAL_USER_PASSWORD variables.
+                    add a seed script to create the initial user provided a
+                    .seed.env exists with the INITIAL_USER_EMAIL and
+                    INITIAL_USER_PASSWORD variables.
♻️ Duplicate comments (3)
plugins/plugin-storage/src/storage/core/components/storage-definition-editor.tsx (1)

99-103: Same as above: verify apply step expects name-based map

createAndApplyModelMergerResults should also accept the name-keyed STORAGE_MODELS map consistently with the “results” path. Confirm both APIs are in sync.

Use the script in the previous comment; it also checks both result and apply functions.

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

9-9: Path alias note duplicated

The import uses '#src/'. See earlier comment about verifying the repo’s preferred alias and tsconfig paths before changing to '@src/'.

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

8-8: Path alias note duplicated

The import uses '#src/'. See earlier comment about verifying the repo’s preferred alias and tsconfig paths.

🧹 Nitpick comments (20)
packages/project-builder-cli/tsconfig.e2e.json (1)

12-12: Nit: Narrow the include glob to TypeScript files for faster editor/typecheck performance
Functionally OK as-is. If you want to trim the TS program for faster typecheck/IDE responsiveness, consider scoping the include to .ts files.

Apply:

-  "include": ["e2e/**/*", "playwright.config.ts"]
+  "include": ["e2e/**/*.ts", "playwright.config.ts"]
.cursor/rules/dev-commands.mdc (2)

2-3: Frontmatter fields are empty; populate them to avoid parser/tooling surprises
If your rules loader expects non-empty description/globs, leaving them blank can be brittle. Suggest giving them sensible defaults.

Apply:

-description:
-globs:
+description: Developer commands cheat sheet
+globs:
+  - "**/*"

26-26: Clarify wording on where to run commands
Minor copy edit for precision.

Apply:

-Note: Make sure to run the commands in the sub-packages if only modifying files in that package.
+Note: If you modify files in a specific package, run these commands from that package directory.
plugins/plugin-auth/src/auth0/constants/model-names.ts (1)

1-3: Export typed unions for Auth0 models & confirm ESM imports

To improve ergonomics and consistency, export key/value unions from AUTH0_MODELS:

 export const AUTH0_MODELS = {
   user: 'User',
 } as const;

+export type Auth0ModelKey = keyof typeof AUTH0_MODELS;
+export type Auth0ModelName = (typeof AUTH0_MODELS)[Auth0ModelKey];

All TS imports of model-names already include the .js extension—ESM specifiers are compliant.

plugins/plugin-auth/src/placeholder-auth/constants/model-names.ts (1)

1-3: Export handy key/name types for stronger typing across consumers

These make model-merger APIs, lookups, and UI props safer and self-documenting.

Apply:

 export const PLACEHOLDER_AUTH_MODELS = {
   user: 'User',
 } as const;
+
+export type PlaceholderAuthModelKey = keyof typeof PLACEHOLDER_AUTH_MODELS;
+export type PlaceholderAuthModelName =
+  typeof PLACEHOLDER_AUTH_MODELS[PlaceholderAuthModelKey];
plugins/plugin-storage/src/storage/constants/model-names.ts (1)

1-6: Export key/name types to improve DX and prevent typos

Helps when constraining inputs to union types and shaping Record<keyof …> mappings.

Apply:

 export const STORAGE_MODELS = {
   /**
    * Model name for the file model that represents a file in the storage system.
    */
   file: 'File',
 } as const;
+
+export type StorageModelKey = keyof typeof STORAGE_MODELS;
+export type StorageModelName = typeof STORAGE_MODELS[StorageModelKey];
plugins/plugin-auth/src/local-auth/constants/model-names.ts (1)

1-18: Export union types for keys and names to strengthen APIs

These types will simplify definition helpers, schema builders, and UI components keyed by these constants.

Apply:

 export const LOCAL_AUTH_MODELS = {
   /**
    * Model name for the user model that represents a user in the local auth system.
    */
   user: 'User',
   /**
    * Model name for the user account model that represents a user account in the local auth system, e.g. email / password.
    */
   userAccount: 'UserAccount',
   /**
    * Model name for the user role model that represents a user role in the local auth system.
    */
   userRole: 'UserRole',
   /**
    * Model name for the user session model that represents a user session in the local auth system.
    */
   userSession: 'UserSession',
 } as const;
+
+export type LocalAuthModelKey = keyof typeof LOCAL_AUTH_MODELS;
+export type LocalAuthModelName = typeof LOCAL_AUTH_MODELS[LocalAuthModelKey];
.vscode/launch.json (1)

11-12: Optional: be explicit about the root config to avoid edge-case resolution issues

In some monorepos, being explicit helps when debugging from nested folders or with multi-project configs.

Apply:

-      "runtimeArgs": ["vitest", "${relativeFile}", "--testTimeout", "0"],
+      "runtimeArgs": ["vitest", "-c", "vitest.config.js", "${relativeFile}", "--testTimeout", "0"],
plugins/plugin-storage/src/storage/core/components/storage-definition-editor.tsx (1)

144-150: RHF integration and CSS prefixing look correct; nit on copy

Using control is correct and all utility classes are storage-prefixed. Minor copy nit: the section description still mentions “file models,” but the file-model selector UI is removed.

Apply this diff to update the description:

-                Configure your storage settings, file models, and S3 adapters.
+                Configure your storage settings and S3 adapters.
packages/project-builder-lib/src/definition/model/model-utils.ts (1)

28-44: New by-name lookups are clear and useful; add tiny DX polish and tests

The helpers are straightforward and align with the PR direction. Two small improvements:

  • Error message polish: quote the name to aid debugging in logs.
  • Add unit tests for byName/byNameOrThrow to prevent regressions.

Apply this diff for the error message:

-    throw new Error(`Could not find model with name ${name}`);
+    throw new Error(`Could not find model with name "${name}"`);

If you want, I can scaffold tests under packages/project-builder-lib with cases for present/absent models and edge names.

plugins/plugin-storage/src/generators/react/upload-components/upload-components.generator.ts (2)

20-20: Minor: accept and ignore descriptor param for consistency.

createGenerator always calls buildTasks(validatedDescriptor). While TS will accept a zero-arg function here, explicitly accepting but ignoring the param improves readability and avoids potential variance edge cases.

Apply this diff:

-  buildTasks: () => ({
+  buildTasks: (_descriptor) => ({

48-48: capitalize likely redundant; consider removing dependency.

STORAGE_MODELS.file is 'File' already. The extra inflection import and call are unnecessary.

Apply this diff here (you can then remove the inflection import):

-                  TPL_FILE_TYPE: capitalize(STORAGE_MODELS.file),
+                  TPL_FILE_TYPE: STORAGE_MODELS.file,
packages/project-builder-lib/src/tools/model-merger/model-merger.ts (3)

126-126: Naming nit: clarify map intent (id -> name).

Minor readability tweak: rename siblingModelIds to siblingModelIdToName (and update usage) to convey the mapping direction at a glance.

Apply:

-  const siblingModelIds = new Map(siblingModels.map((m) => [m.id, m.name]));
+  const siblingModelIdToName = new Map(siblingModels.map((m) => [m.id, m.name]));
@@
-  const modelFromId = (id: string): string =>
-    siblingModelIds.get(id) ?? definitionContainer.nameFromId(id);
+  const modelFromId = (id: string): string =>
+    siblingModelIdToName.get(id) ?? definitionContainer.nameFromId(id);

Also applies to: 147-149


415-416: Avoid by-name lookup with empty string.

When current[key] is undefined, calling byName(definition, '') is unnecessary. Guard it and pass undefined to createModelMergerResult instead.

Apply:

-        : ModelUtils.byName(definitionContainer.definition, current[key] ?? ''),
+        : current[key]
+          ? ModelUtils.byName(definitionContainer.definition, current[key]!)
+          : undefined,

121-190: Add tests for sibling-name resolution in modelRef during (de)serialization.

Given the new sibling model name resolution, add unit tests that:

  • Verify serializeModelMergerModelInput converts relation.modelRef IDs to sibling names when the sibling is provided.
  • Verify deserializeModelMergerModelInput maps those names back to IDs via the provided resolvers.

I can draft focused tests around these scenarios. Want me to open a follow-up and provide a test suite scaffold?

.changeset/standardize-model-names.md (1)

20-21: Grammar nit in Improvements section.

Apply:

-- Enhanced ModelMergerResultAlert to show "Models Up to Date" instead of null when no changes needed
+- Enhanced ModelMergerResultAlert to show "Models Up to Date" instead of null when no changes are needed
plugins/plugin-auth/src/auth0/core/schema/plugin-definition.ts (1)

6-8: Add schema strictness and optional output type alias

I ran the grep search for Auth0PluginDefinition and InferOutput<typeof createAuth0PluginDefinitionSchema> and found no remaining references—so it’s safe to proceed.

File: plugins/plugin-auth/src/auth0/core/schema/plugin-definition.ts

Suggested changes (optional):

-export const createAuth0PluginDefinitionSchema = definitionSchema((_) =>
-  z.object({}),
-);
+export const createAuth0PluginDefinitionSchema = definitionSchema((_) =>
+  z.object({}).strict(),
+);
 export type Auth0PluginDefinitionInput = def.InferInput<
   typeof createAuth0PluginDefinitionSchema
 >;

+// Optional: preserve symmetry with an output type alias
+export type Auth0PluginDefinition = def.InferOutput<
+  typeof createAuth0PluginDefinitionSchema
+>;
plugins/plugin-auth/src/local-auth/core/schema/models.ts (1)

56-61: Minor: GraphQL fields omit 'name' despite it being present on the model.

If exposing name is intended in the admin UI or API, consider adding it to the objectType fields. Otherwise, ignore.

       graphql: {
         objectType: {
           enabled: true,
-          fields: ['id', 'email'],
+          fields: ['id', 'email', 'name'],
         },
       },
plugins/plugin-storage/src/storage/transformers/web.ts (1)

67-83: Avoid creating a transformer with an empty adapterRef

If no S3 adapters are configured, adapterRef becomes an empty string. Prefer a clear error to prevent generating an invalid transformer.

Apply this change to fail fast with a helpful message:

         const storageDefinition = PluginUtils.configByKeyOrThrow(
           definition,
           pluginKey,
         ) as StoragePluginDefinition;
+        if (!storageDefinition.s3Adapters?.length) {
+          throw new Error(
+            'No S3 adapters configured. Please add an S3 adapter in the Storage plugin before creating a file transformer.',
+          );
+        }
         return {
           id: modelTransformerEntityType.generateNewId(),
           type: 'file' as const,
           fileRelationRef: fileRelationIds[0],
           category: {
             name: constantCase(relation.foreignRelationName),
             maxFileSizeMb: 20,
             authorize: {
               uploadRoles: ['user'],
             },
-            adapterRef: storageDefinition.s3Adapters[0]?.id ?? '',
+            adapterRef: storageDefinition.s3Adapters[0].id,
           },
         };
plugins/plugin-auth/src/local-auth/core/components/local-auth-definition-editor.tsx (1)

93-98: DRY: compute desiredModels once and reuse

You call createAuthModels(authDefinition) twice (for preview and apply). Hoist it into a memo and reuse.

Apply this:

   const pendingModelChanges = useMemo(() => {
-    const desiredModels = createAuthModels(authDefinition);
+    const desiredModels = createAuthModels(authDefinition);
 
     return createModelMergerResults(
       LOCAL_AUTH_MODELS,
       desiredModels,
       definitionContainer,
     );
   }, [definitionContainer, authDefinition]);

And add a memoized desiredModels, then reuse it in onSubmit:

@@
-  const pendingModelChanges = useMemo(() => {
-    const desiredModels = createAuthModels(authDefinition);
+  const desiredModels = useMemo(
+    () => createAuthModels(authDefinition),
+    [authDefinition],
+  );
+  const pendingModelChanges = useMemo(() => {
     return createModelMergerResults(
       LOCAL_AUTH_MODELS,
-      desiredModels,
+      desiredModels,
       definitionContainer,
     );
-  }, [definitionContainer, authDefinition]);
+  }, [definitionContainer, desiredModels]);
@@
-        createAndApplyModelMergerResults(
+        createAndApplyModelMergerResults(
           draftConfig,
           LOCAL_AUTH_MODELS,
-          createAuthModels(authDefinition),
+          desiredModels,
           definitionContainer,
         );

Comment on lines +2 to +4
'@baseplate-dev/plugin-auth': patch
'@baseplate-dev/plugin-storage': patch
'@baseplate-dev/project-builder-lib': patch
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Semver level conflicts with documented “Breaking Changes.”

The changeset declares breaking changes but marks all packages as patch. If these packages are ≥1.0.0, a major bump is required. Even for 0.x, removing config is typically at least a minor bump. Recommend updating to major for all three packages.

Apply:

-'@baseplate-dev/plugin-auth': patch
-'@baseplate-dev/plugin-storage': patch
-'@baseplate-dev/project-builder-lib': patch
+'@baseplate-dev/plugin-auth': major
+'@baseplate-dev/plugin-storage': major
+'@baseplate-dev/project-builder-lib': major

If you intend a different policy for pre-1.0, please clarify in the repo docs and adjust these levels accordingly.

📝 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
'@baseplate-dev/plugin-auth': patch
'@baseplate-dev/plugin-storage': patch
'@baseplate-dev/project-builder-lib': patch
'@baseplate-dev/plugin-auth': major
'@baseplate-dev/plugin-storage': major
'@baseplate-dev/project-builder-lib': major
🤖 Prompt for AI Agents
In .changeset/standardize-model-names.md around lines 2 to 4, the changeset
marks three packages as "patch" even though the changes are breaking (removing
config) and therefore require higher semver bumps; update the changeset to use
"major" for '@baseplate-dev/plugin-auth', '@baseplate-dev/plugin-storage', and
'@baseplate-dev/project-builder-lib' (or change them to "minor" if your repo
policy for 0.x requires that instead), and if you intentionally follow a pre-1.0
policy that treats such changes as patch, add/update the repository's
release/semver documentation to state that policy and adjust the changeset to
reflect that documented policy.

@@ -1,16 +1,15 @@
import type { ModelConfig } from '#src/schema/index.js';
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Confirm path alias convention (#src vs @src).

Coding guidelines specify @src/ for tsconfig path aliases, while this file (and others) use #src/. If #src/ is the repo-standard, consider updating the guideline; if not, plan a follow-up to normalize aliases.

Run this to audit alias usage across the repo:


🏁 Script executed:

#!/bin/bash
# Inspect usage of "#src/" vs "@src/" imports across TS/TSX files.
rg -nP --type=ts --type=tsx -C2 "from ['\"]#src/" || true
rg -nP --type=ts --type=tsx -C2 "from ['\"]@src/" || true

Length of output: 177


To accurately audit alias usage, let’s re-run the search across all .ts and .tsx files without relying on --type.


🏁 Script executed:

#!/bin/bash
# Search for "#src/" imports in TS/TSX files
rg -nP "from ['\"]#src/" -g '*.ts' -g '*.tsx' || true

# Search for "@src/" imports in TS/TSX files
rg -nP "from ['\"]@src/" -g '*.ts' -g '*.tsx' || true

Length of output: 144264


Standardize path alias to #src/

The repository overwhelmingly uses #src/ as its TypeScript path alias—update our coding guidelines to reflect this and replace the few remaining @src/ imports:

• plugins/plugin-auth/src/local-auth/core/generators/auth-hooks/templates/src/hooks/use-session.ts:7
• packages/core-generators/src/renderers/typescript/imports/ts-morph-operations.unit.test.ts:512
• packages/core-generators/src/renderers/typescript/extractor/apply-simple-replacements.unit.test.ts:149

🤖 Prompt for AI Agents
In packages/project-builder-lib/src/plugins/spec/auth-model-config-spec.ts
around line 1, the import path alias uses @src/ instead of the project-standard
#src/; update the import to use the #src/ alias and scan/replace the other
listed files
(plugins/plugin-auth/src/local-auth/core/generators/auth-hooks/templates/src/hooks/use-session.ts
line ~7,
packages/core-generators/src/renderers/typescript/imports/ts-morph-operations.unit.test.ts
line ~512, and
packages/core-generators/src/renderers/typescript/extractor/apply-simple-replacements.unit.test.ts
line ~149) to replace any remaining @src/ imports with #src/, and update the
coding guidelines/docs to state #src/ as the canonical TypeScript path alias.

) as LocalAuthPluginDefinition;
return modelId === pluginDefinition.modelRefs.user;
},
isAvailableForModel: (_, modelId) => modelId === LOCAL_AUTH_MODELS.user,
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Confirm isAvailableForModel receives a model name, not an ID.

Comparing modelId to 'User' assumes the callback’s second arg is the model name. If it’s an entity ID, this check will silently fail.

If it does accept names, you can DRY the predicate:

 import { LOCAL_AUTH_MODELS } from '#src/local-auth/constants/model-names.js';
+const isUserModel = (_: unknown, modelId: string) =>
+  modelId === LOCAL_AUTH_MODELS.user;

 ...
-      isAvailableForModel: (_, modelId) => modelId === LOCAL_AUTH_MODELS.user,
+      isAvailableForModel: isUserModel,
 ...
-      isAvailableForModel: (_, modelId) => modelId === LOCAL_AUTH_MODELS.user,
+      isAvailableForModel: isUserModel,
 ...
-      isAvailableForModel: (_, modelId) => modelId === LOCAL_AUTH_MODELS.user,
+      isAvailableForModel: isUserModel,

Also applies to: 28-28, 36-36


🏁 Script executed:

#!/bin/bash
# Find the type signature for isAvailableForModel in action/column web configs
rg -nP -C5 '\bisAvailableForModel\s*:\s*\(' packages
rg -nP -C5 'register(Action|Column)WebConfig\(' packages
rg -nP -C5 'AdminCrud(Action|Column).*Config' packages

Length of output: 44634


I’d like to confirm the actual values and types before updating the comment.


🏁 Script executed:

#!/bin/bash
set -e
echo "=== web.ts around isAvailableForModel ==="
sed -n '1,200p' plugins/plugin-auth/src/local-auth/admin/web.ts
echo
echo "=== LOCAL_AUTH_MODELS constants ==="
sed -n '1,200p' plugins/plugin-auth/src/local-auth/constants/model-names.js

Length of output: 1824


I need to locate and inspect the LOCAL_AUTH_MODELS definition. Let’s search for the constants file and its export:


🏁 Script executed:

#!/bin/bash
set -e
echo "🔍 Finding model-names file:"
find plugins/plugin-auth -type f -name "*model-names*"

echo
echo "🔍 Grepping for LOCAL_AUTH_MODELS export:"
rg -n "LOCAL_AUTH_MODELS" -C3 plugins/plugin-auth

Length of output: 17800


To confirm the actual model identifier strings, let’s inspect the LOCAL_AUTH_MODELS definitions:


🏁 Script executed:

#!/bin/bash
set -e
echo "=== LOCAL_AUTH_MODELS (local-auth) ==="
sed -n '1,200p' plugins/plugin-auth/src/local-auth/constants/model-names.ts

Length of output: 767


Fix model availability check: compare model name, not model ID

The isAvailableForModel callback’s second argument is the model’s definition ID, not its name. Comparing modelId directly to LOCAL_AUTH_MODELS.user ('User') will always fail, so none of these configs will ever become available.

Please update the predicates to look up the model by its ID and then compare its .model.name. For example, in plugins/plugin-auth/src/local-auth/admin/web.ts:

• Define a helper above your configs:

import type { ProjectDefinition } from '@baseplate-dev/project-builder-lib';
import { LOCAL_AUTH_MODELS } from '#src/local-auth/constants/model-names.js';

const isUserModel = (definition: ProjectDefinition, modelId: string) =>
  definition.models.find((m) => m.id === modelId)?.model.name === LOCAL_AUTH_MODELS.user;

• Then apply it to each registration:

adminCrudActionWeb.registerActionWebConfig({
  pluginKey,
  name: 'manage-roles',
  label: 'Manage Roles',
- isAvailableForModel: (_, modelId) => modelId === LOCAL_AUTH_MODELS.user,
+ isAvailableForModel: isUserModel,
  getNewAction: () => ({ type: 'manage-roles', position: 'dropdown' }),
});

adminCrudActionWeb.registerActionWebConfig({
  pluginKey,
  name: 'reset-password',
  label: 'Reset Password',
- isAvailableForModel: (_, modelId) => modelId === LOCAL_AUTH_MODELS.user,
+ isAvailableForModel: isUserModel,
  getNewAction: () => ({ type: 'reset-password', position: 'dropdown' }),
});

adminCrudColumnWeb.registerColumnWebConfig({
  pluginKey,
  name: 'roles',
  label: 'Roles',
- isAvailableForModel: (_, modelId) => modelId === LOCAL_AUTH_MODELS.user,
+ isAvailableForModel: isUserModel,
  getNewColumn: () => ({ type: 'roles', label: 'Roles' }),
});

Locations to update:

  • plugins/plugin-auth/src/local-auth/admin/web.ts: lines 20, 28, 36
🤖 Prompt for AI Agents
In plugins/plugin-auth/src/local-auth/admin/web.ts around lines 20, 28 and 36,
the isAvailableForModel callbacks compare the incoming modelId to
LOCAL_AUTH_MODELS.user (a model name) which always fails; add a helper that
accepts the ProjectDefinition and modelId, finds the model by id and compares
its .model.name to LOCAL_AUTH_MODELS.user, import the ProjectDefinition type and
LOCAL_AUTH_MODELS constant, then replace the three predicates to call that
helper (e.g. isUserModel(definition, modelId)) so availability is determined by
the model's name instead of its id.

generatorFileUrl: import.meta.url,
descriptorSchema,
buildTasks: ({ adminRoles, userModelName }) => ({
buildTasks: ({ adminRoles }) => ({
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Descriptor change: remove userModelName usage across generators/templates

buildTasks no longer accepts userModelName. Ensure no remaining references exist in generators, descriptors, or template variables.

Run:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Search for previous descriptor field 'userModelName' usages:"
rg -nP -C2 '\buserModelName\b' plugins/plugin-auth

echo
echo "Search template variables that might still assume a dynamic user model name:"
rg -nP -C2 'TPL_.*USER.*MODEL|userModelName' plugins/plugin-auth

Length of output: 16889


Remove all lingering userModelName references

We still see userModelName used in several generators and the admin node files. Please remove the userModelName field from the descriptor schemas, update the buildTasks signatures, and adjust any template variables accordingly:

• plugins/plugin-auth/src/local-auth/admin/node.ts
– lines 41 and 59: const userModelName = … and passing userModelName into the action generators

• plugins/plugin-auth/src/local-auth/admin/generators/admin-crud-manage-roles-action/admin-crud-manage-roles-action.generator.ts
– line 18: descriptorSchema includes userModelName: z.string()
– line 32: buildTasks: ({ …, userModelName, … })
– line 139: TPL_USER_ROW_FRAGMENT: ${userModelName}Row``

• plugins/plugin-auth/src/local-auth/admin/generators/admin-crud-reset-password-action/admin-crud-reset-password-action.generator.ts
– line 18: descriptorSchema includes userModelName: z.string()
– line 29: buildTasks: ({ …, userModelName })
– line 123: TPL_USER_ROW_FRAGMENT: ${userModelName}Row``

After removal, ensure that any hardcoded or derived row‐fragment names are updated in the templates so they no longer rely on a dynamic userModelName.

🤖 Prompt for AI Agents
In
plugins/plugin-auth/src/local-auth/core/generators/auth-email-password/auth-email-password.generator.ts
around line 26 and the related admin files listed, remove all references to
userModelName: delete the userModelName field from descriptorSchema definitions,
update buildTasks signatures to stop accepting/using userModelName, remove the
const userModelName and stop passing it from
plugins/plugin-auth/src/local-auth/admin/node.ts (lines ~41 and ~59), and change
template variables (e.g. TPL_USER_ROW_FRAGMENT) to a fixed, hardcoded fragment
name (choose a single consistent name like "UserRow") so templates no longer
depend on a dynamic userModelName. Ensure no remaining imports or usages
reference userModelName and run tests to verify templates and generators
compile.

@kingston kingston merged commit f450b7f into main Aug 19, 2025
8 of 9 checks passed
@kingston kingston deleted the kingston/eng-832-standardize-data-model-names-for-auth-and-storage-plugins branch August 19, 2025 20:55
@github-actions github-actions bot mentioned this pull request Aug 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants