Skip to content

Conversation

@mirena-iud
Copy link

@mirena-iud mirena-iud commented Oct 23, 2025

Description

Fixes administrator soft delete constraint error by adding combined unqiue index. #1523

Breaking changes

None.

Screenshots

None.

Checklist

📌 Always:

  • I have set a clear title
  • My PR is small and contains a single feature
  • I have checked my own PR

👍 Most of the time:

  • I have added or updated test cases
  • I have updated the README if needed

Summary by CodeRabbit

  • Bug Fixes

    • Improved administrator record deletion handling to properly clear status when removing administrators.
  • Chores

    • Enhanced administrator tracking system to distinguish between active and inactive records with refined uniqueness constraints.

@vercel
Copy link

vercel bot commented Oct 23, 2025

Someone is attempting to deploy a commit to the Vendure Team on Vercel.

A member of the Team first needs to authorize it.

@vercel
Copy link

vercel bot commented Oct 23, 2025

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

Project Deployment Preview Updated (UTC)
docs Ready Ready Preview Oct 23, 2025 3:20am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 23, 2025

Walkthrough

Modified the Administrator entity to use a composite unique constraint on emailAddress and isCurrent instead of a unique constraint on emailAddress alone. Updated the soft delete operation to null the isCurrent field alongside deletedAt, enabling email address reuse when an administrator is soft-deleted.

Changes

Cohort / File(s) Summary
Administrator Entity Schema
packages/core/src/entity/administrator/administrator.entity.ts
Added Unique import from TypeORM. Applied @Unique(['emailAddress', 'isCurrent']) class decorator. Removed unique: true constraint from emailAddress column. Introduced new isCurrent boolean column (default true, nullable).
Administrator Service Soft Delete
packages/core/src/service/services/administrator.service.ts
Modified soft delete operation to set both isCurrent to null and deletedAt when soft-deleting an Administrator record.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed The pull request title "fix(core): Administrator soft delete constraint error (#1523)" directly aligns with the primary changes in the changeset. The modifications to the Administrator entity (adding a composite unique constraint on emailAddress and isCurrent, and updating the soft delete operation to clear the isCurrent field) are specifically designed to resolve the soft delete constraint error referenced in the title. The title is concise, follows conventional commit format, includes the issue reference, and clearly communicates the main purpose of the changes to reviewers scanning the commit history.
Description Check ✅ Passed The pull request description follows the required template structure, with all main sections present and completed: the Description section provides a summary linking the fix to the combined unique index and issue #1523, Breaking changes are explicitly stated as "None", Screenshots are noted as "None" (appropriate since not applicable), and all checklist items are addressed. While the description section is brief, it adequately summarizes what was changed and why, and the template does not mandate extensive detail in this section. The author has properly completed all required elements of the template.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@github-actions
Copy link
Contributor

github-actions bot commented Oct 23, 2025

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@sonarqubecloud
Copy link

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

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

⚠️ Outside diff range comments (2)
packages/core/src/service/services/administrator.service.ts (2)

349-352: Critical: Restore logic must also set isCurrent = true.

When restoring a soft-deleted administrator, the code sets deletedAt = null but does NOT restore isCurrent back to true. This is a bug because:

  1. The restored administrator will have deletedAt = null but isCurrent = null
  2. This breaks the intended pattern where active administrators should have isCurrent = true
  3. This could prevent creating new administrators with the same email if the restored one has isCurrent = null

Apply this diff to fix the restore logic:

 } else if (superAdministrator.deletedAt != null) {
     superAdministrator.deletedAt = null;
+    superAdministrator.isCurrent = true;
     await this.connection.rawConnection.getRepository(Administrator).save(superAdministrator);
 }

256-273: Restore operations missing isCurrent restoration.

The soft-delete sets both isCurrent: null and deletedAt, but restore operations at lines 349–350 and 354–356 only restore deletedAt to null, leaving isCurrent as null. This creates an inconsistent state where the administrator appears deleted for uniqueness enforcement (due to the @Unique(['emailAddress', 'isCurrent']) constraint) while deletedAt is cleared.

Update the restore logic to also set isCurrent = true:

} else if (superAdministrator.deletedAt != null) {
    superAdministrator.deletedAt = null;
    superAdministrator.isCurrent = true;
    await this.connection.rawConnection.getRepository(Administrator).save(superAdministrator);
}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 999d3e1 and c0b3acf.

📒 Files selected for processing (2)
  • packages/core/src/entity/administrator/administrator.entity.ts (3 hunks)
  • packages/core/src/service/services/administrator.service.ts (1 hunks)
🔇 Additional comments (3)
packages/core/src/entity/administrator/administrator.entity.ts (1)

2-2: LGTM! Import needed for composite constraint.

The Unique import is correctly added to support the class-level composite unique constraint.

packages/core/src/service/services/administrator.service.ts (2)

264-266: LGTM! Soft delete correctly updates both fields.

The soft delete operation now correctly sets both isCurrent: null and deletedAt, which is essential for the composite unique constraint to allow email address reuse.


354-357: No action required - the review comment is based on incorrect assumptions.

The User entity structure is fundamentally different from Administrator and does not have an isCurrent field or composite unique constraints. User only implements soft-deletion via deletedAt, which is already handled correctly by userService.softDelete(). The restoration logic at lines 354-357 properly handles both entities according to their respective designs: Administrator resets deletedAt, and User resets deletedAt (with no isCurrent to manage).

Likely an incorrect or invalid review comment.

Comment on lines +35 to +36
@Column({ type: 'boolean', default: true, nullable: true })
isCurrent: true | null;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Verify type safety: TypeScript true | null vs SQL boolean.

The TypeScript type is true | null, but the column type is boolean. This mismatch could cause issues:

  • SQL boolean columns can store true, false, or null
  • If the database ever returns false (through direct DB manipulation or ORM behavior), TypeScript will not expect it
  • TypeScript will show type errors when assigning boolean values to this field

Consider using boolean | null for better type safety, and enforce the constraint through validation logic or a database CHECK constraint if you truly want to prevent false values.

If you want to keep the current pattern, add a comment explaining why only true and null are valid values.

+    // isCurrent can only be true (for active administrators) or null (for soft-deleted ones)
+    // This constraint allows multiple soft-deleted administrators with the same email address
     @Column({ type: 'boolean', default: true, nullable: true })
     isCurrent: true | null;
🤖 Prompt for AI Agents
In packages/core/src/entity/administrator/administrator.entity.ts around lines
35-36, the property is declared as TypeScript type `true | null` while the
Column is defined as SQL `boolean`; change the TS type to `boolean | null` to
match the database semantics (allow true, false, or null) or, if you truly
require only true/null, keep `true | null` but add a clear inline comment
explaining the restriction and add application-level validation or a DB CHECK
constraint to prevent false values; ensure any code that sets/reads this field
is updated to the chosen type/validation approach.

@mirena-iud
Copy link
Author

I have read the CLA Document and I hereby sign the CLA

github-actions bot added a commit that referenced this pull request Oct 23, 2025
@mirena-iud
Copy link
Author

recheck

Copy link
Collaborator

@dlhck dlhck left a comment

Choose a reason for hiding this comment

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

I don't think this is the correct approach. We should rather remove the unique constraint on the emailAddress and do the proper exist-checks in the create and update in the administrator.service.ts. Similar to what we have in customer.service.ts

casperiv0 pushed a commit to casperiv0/vendure that referenced this pull request Nov 3, 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