Skip to content

feat: Add support for indexes on tables, mirroring the existing unique constraints implementation#830

Merged
kingston merged 1 commit into
mainfrom
kingston/eng-891-add-support-for-indexes-on-tables
Mar 14, 2026
Merged

feat: Add support for indexes on tables, mirroring the existing unique constraints implementation#830
kingston merged 1 commit into
mainfrom
kingston/eng-891-add-support-for-indexes-on-tables

Conversation

@kingston

@kingston kingston commented Mar 14, 2026

Copy link
Copy Markdown
Collaborator

…e constraints implementation

Summary by CodeRabbit

Release Notes

  • New Features
    • Added table index management with support for creating, editing, and deleting indexes
    • Field badges now display which indexes include each field
    • New dedicated section in model editor for managing all table indexes

@changeset-bot

changeset-bot Bot commented Mar 14, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: bba6a2b

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

This PR includes changesets to release 23 packages
Name Type
@baseplate-dev/project-builder-lib Patch
@baseplate-dev/fastify-generators Patch
@baseplate-dev/project-builder-server Patch
@baseplate-dev/project-builder-web Patch
@baseplate-dev/create-project Patch
@baseplate-dev/project-builder-cli Patch
@baseplate-dev/project-builder-common Patch
@baseplate-dev/project-builder-dev Patch
@baseplate-dev/plugin-auth Patch
@baseplate-dev/plugin-email Patch
@baseplate-dev/plugin-observability Patch
@baseplate-dev/plugin-payments Patch
@baseplate-dev/plugin-queue Patch
@baseplate-dev/plugin-rate-limit Patch
@baseplate-dev/plugin-storage Patch
@baseplate-dev/project-builder-test Patch
@baseplate-dev/code-morph Patch
@baseplate-dev/core-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

coderabbitai Bot commented Mar 14, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This pull request introduces model index support across the Baseplate project builder. It adds a new Prisma model index generator, extends the model schema to include an indexes array, creates a new entity type for model indexes, implements backend support to generate Prisma indexes, and provides a complete UI layer for creating and editing model indexes.

Changes

Cohort / File(s) Summary
Changeset
.changeset/add-model-indexes.md
Declares patch version bumps across four packages with description of index support feature addition.
Prisma Model Index Generator
packages/fastify-generators/src/generators/prisma/prisma-model-index/prisma-model-index.generator.ts
Updated descriptor schema from string array to objects with name property; added getInstanceName computation; changed Prisma attribute name from "index" to "@@index"; adjusted args to extract field names from objects.
Schema and Types
packages/project-builder-lib/src/schema/models/models.ts, packages/project-builder-lib/src/schema/models/types.ts
Introduced createModelIndexSchema with field references and name resolver; exported ModelIndexConfig and ModelIndexConfigInput types; added modelIndexEntityType; extended model configuration with indexes array field.
Backend Compiler
packages/project-builder-server/src/compiler/backend/models.ts
Imported prismaModelIndexGenerator and integrated index generation into buildModel to map model.model.indexes through the generator.
Web UI Components
packages/project-builder-web/src/routes/data/models/edit.$key/-components/fields/model-field-badges.tsx, packages/project-builder-web/src/routes/data/models/edit.$key/-components/fields/indexes/model-index-badge.tsx, packages/project-builder-web/src/routes/data/models/edit.$key/-components/fields/indexes/model-index-dialog.tsx, packages/project-builder-web/src/routes/data/models/edit.$key/-components/fields/indexes/model-index-form.tsx
Added ModelFieldIndexBadge component showing index references; created ModelIndexDialog for index editing with title and description; implemented ModelIndexForm with field selection, validation, creation, update, and deletion logic using react-hook-form and zod schema.
Field Form and Page Integration
packages/project-builder-web/src/routes/data/models/edit.$key/-components/fields/model-field-form.tsx, packages/project-builder-web/src/routes/data/models/edit.$key/-components/model-indexes-section.tsx, packages/project-builder-web/src/routes/data/models/edit.$key/index.tsx
Enhanced field form with index management (Add Index action, dialog integration, field removal validation); introduced ModelIndexesSection component for list-level index management with Edit/Delete actions; integrated ModelIndexesSection into main Model edit page.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant UI as Web UI
    participant Form as React Hook Form
    participant Schema as Zod Schema
    participant Model as Model State

    User->>UI: Opens Model Index Dialog
    UI->>Form: Initialize with existing/empty index
    User->>UI: Selects fields from available model fields
    UI->>Schema: Validate field selection (min 1)
    Schema-->>Form: Validation result
    
    alt Create New Index
        User->>UI: Click Save
        Form->>Schema: Validate and normalize
        Schema-->>Form: Valid index object with generated ID
        Form->>Model: Append new index to model.indexes
    else Edit Existing Index
        User->>UI: Click Save
        Form->>Schema: Validate and normalize
        Schema-->>Form: Valid index object with existing ID
        Form->>Model: Replace existing index in model.indexes
    end
    
    Model-->>UI: Update badges and sections
    User->>UI: Sees updated index count in badges
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding index support mirroring unique constraints. It is specific, concise, and clearly describes the primary feature being added.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch kingston/eng-891-add-support-for-indexes-on-tables
📝 Coding Plan
  • Generate coding plan for human review comments

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

❤️ Share

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

@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.

🧹 Nitpick comments (3)
packages/project-builder-web/src/routes/data/models/edit.$key/-components/fields/badges/model-field-badges.tsx (1)

40-47: Variable shadowing: idx shadows the component prop.

The filter callback parameter idx shadows the component's idx prop. Consider renaming to avoid confusion:

♻️ Suggested rename for clarity
   const indexes = useWatch({
     control,
     name: 'model.indexes',
     compute: (idxs) =>
       idxs
-        ?.filter((idx) => idx.fields.some((f) => f.fieldRef === field.id))
-        .map((idx) => idx.id) ?? [],
+        ?.filter((index) => index.fields.some((f) => f.fieldRef === field.id))
+        .map((index) => index.id) ?? [],
   });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/project-builder-web/src/routes/data/models/edit`.$key/-components/fields/badges/model-field-badges.tsx
around lines 40 - 47, The compute callback for useWatch is shadowing the
component prop idx; rename the callback parameter used in the filter/map
(currently "idx") to something unique like "index" or "modelIndex" to avoid
confusion with the component prop "idx"; update both the filter and map
callbacks to use the new name (e.g., index.fields.some(...); .map((index) =>
index.id)) while keeping references to control, name: 'model.indexes', compute
and field.id unchanged.
packages/project-builder-web/src/routes/data/models/edit.$key/-components/fields/model-field-form.tsx (1)

66-68: Variable shadowing: idx shadows the component prop.

Similar to the unique constraints filter pattern, the callback parameter idx shadows the component's idx prop (line 45):

♻️ Suggested rename for consistency
-  const ownIndexes = indexes.filter((idx) =>
-    idx.fields.some((f) => f.fieldRef === watchedField.id),
+  const ownIndexes = indexes.filter((index) =>
+    index.fields.some((f) => f.fieldRef === watchedField.id),
   );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/project-builder-web/src/routes/data/models/edit`.$key/-components/fields/model-field-form.tsx
around lines 66 - 68, The callback parameter `idx` in the filter used to compute
`ownIndexes` shadows the component prop `idx`; rename the callback parameter
(for example to `index` or `idxItem`) in the expression that uses
`indexes.filter((...) => ...)` so it no longer conflicts with the prop, and
update any references inside that callback (e.g., `index.fields.some((f) =>
f.fieldRef === watchedField.id)`) to match the new name for consistency with the
unique constraints filter pattern and to avoid shadowing the `idx` prop.
packages/project-builder-web/src/routes/data/models/edit.$key/-components/fields/indexes/model-index-form.tsx (1)

61-64: Consider adding a confirmation step before deleting an index.

The delete action immediately removes the index without user confirmation. While this is consistent with the dialog context (user can cancel the dialog), adding a brief confirmation could prevent accidental deletions.

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

In
`@packages/project-builder-web/src/routes/data/models/edit`.$key/-components/fields/indexes/model-index-form.tsx
around lines 61 - 64, onDelete currently removes the index immediately (it calls
onModelChange with modelValue.filter(...)) — add a confirmation step before
performing the deletion: prompt the user (using the app’s existing confirm/Modal
utility or fallback to window.confirm) asking to confirm deletion of the index
referenced by indexId (or include index label if available), and only call
onModelChange(modelValue.filter((idx) => idx.id !== indexId)) and
onSubmitSuccess() when the user confirms; if they cancel, do nothing. Use the
onDelete function in model-index-form.tsx as the insertion point and preserve
existing calls to onModelChange and onSubmitSuccess.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@packages/project-builder-web/src/routes/data/models/edit`.$key/-components/fields/badges/model-field-badges.tsx:
- Around line 40-47: The compute callback for useWatch is shadowing the
component prop idx; rename the callback parameter used in the filter/map
(currently "idx") to something unique like "index" or "modelIndex" to avoid
confusion with the component prop "idx"; update both the filter and map
callbacks to use the new name (e.g., index.fields.some(...); .map((index) =>
index.id)) while keeping references to control, name: 'model.indexes', compute
and field.id unchanged.

In
`@packages/project-builder-web/src/routes/data/models/edit`.$key/-components/fields/indexes/model-index-form.tsx:
- Around line 61-64: onDelete currently removes the index immediately (it calls
onModelChange with modelValue.filter(...)) — add a confirmation step before
performing the deletion: prompt the user (using the app’s existing confirm/Modal
utility or fallback to window.confirm) asking to confirm deletion of the index
referenced by indexId (or include index label if available), and only call
onModelChange(modelValue.filter((idx) => idx.id !== indexId)) and
onSubmitSuccess() when the user confirms; if they cancel, do nothing. Use the
onDelete function in model-index-form.tsx as the insertion point and preserve
existing calls to onModelChange and onSubmitSuccess.

In
`@packages/project-builder-web/src/routes/data/models/edit`.$key/-components/fields/model-field-form.tsx:
- Around line 66-68: The callback parameter `idx` in the filter used to compute
`ownIndexes` shadows the component prop `idx`; rename the callback parameter
(for example to `index` or `idxItem`) in the expression that uses
`indexes.filter((...) => ...)` so it no longer conflicts with the prop, and
update any references inside that callback (e.g., `index.fields.some((f) =>
f.fieldRef === watchedField.id)`) to match the new name for consistency with the
unique constraints filter pattern and to avoid shadowing the `idx` prop.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2127a744-14c5-4f5f-b22f-b06023c64744

📥 Commits

Reviewing files that changed from the base of the PR and between 28517d6 and bba6a2b.

📒 Files selected for processing (12)
  • .changeset/add-model-indexes.md
  • packages/fastify-generators/src/generators/prisma/prisma-model-index/prisma-model-index.generator.ts
  • packages/project-builder-lib/src/schema/models/models.ts
  • packages/project-builder-lib/src/schema/models/types.ts
  • packages/project-builder-server/src/compiler/backend/models.ts
  • packages/project-builder-web/src/routes/data/models/edit.$key/-components/fields/badges/model-field-badges.tsx
  • packages/project-builder-web/src/routes/data/models/edit.$key/-components/fields/indexes/model-index-badge.tsx
  • packages/project-builder-web/src/routes/data/models/edit.$key/-components/fields/indexes/model-index-dialog.tsx
  • packages/project-builder-web/src/routes/data/models/edit.$key/-components/fields/indexes/model-index-form.tsx
  • packages/project-builder-web/src/routes/data/models/edit.$key/-components/fields/model-field-form.tsx
  • packages/project-builder-web/src/routes/data/models/edit.$key/-components/model-indexes-section.tsx
  • packages/project-builder-web/src/routes/data/models/edit.$key/index.tsx

@kingston kingston merged commit c175429 into main Mar 14, 2026
11 checks passed
@kingston kingston deleted the kingston/eng-891-add-support-for-indexes-on-tables branch March 14, 2026 13:58
@github-actions github-actions Bot mentioned this pull request Mar 14, 2026
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