fix: do not limit users when self-hosting - #225

Merged
KMKoushik merged 1 commit into
mainfrom
km/2025-09-11-team-limit-self-hosted
Sep 10, 2025
Merged

fix: do not limit users when self-hosting#225
KMKoushik merged 1 commit into
mainfrom
km/2025-09-11-team-limit-self-hosted

Conversation

@KMKoushik

@KMKoushikKMKoushik commented Sep 10, 2025

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • Refactor
    • Standardized how team member limits are validated during invite creation, ensuring consistent enforcement across the app.
    • Maintains current behavior and error messages when limits are reached; no changes to workflows or permissions.
    • Improves reliability and prepares the system for easier future updates to limit policies.
    • No user action required; this change is behind-the-scenes and does not affect existing teams or invitations.

@vercel

vercelBot commented Sep 10, 2025

Copy link
Copy Markdown

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

ProjectDeploymentPreviewCommentsUpdated (UTC)
unsend-marketingReadyReadyPreviewCommentSep 10, 2025 7:45pm

@coderabbitai

coderabbitaiBot commented Sep 10, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

The team invite member-limit check in apps/web/src/server/service/team-service.ts was refactored to delegate to LimitService. The previous logic that computed limits using PLAN_LIMITS and member counts was removed. In createTeamInvite, a single call to LimitService.checkTeamMemberLimit(teamId) now determines if the limit is reached and throws the same UnsendApiError when exceeded. Imports were updated to remove PLAN_LIMITS and add LimitService. No exported/public entity signatures were changed.

Possibly related PRs

  • block sending emails on limits #216: Also modifies team invite member-limit logic in team-service.ts, altering LimitService usage versus PLAN_LIMITS and introducing caching/notification adjustments.

Pre-merge checks (2 passed, 1 warning)

❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Title Check⚠️ WarningThe current title implies that self-hosted deployments will no longer enforce user limits, yet the diff chiefly centralizes the team member limit logic by migrating from a static PLAN_LIMITS calculation to a call into LimitService, without explicitly exposing any self-hosting conditional in the code shown, making the title misleading relative to the actual changes.Consider renaming the PR to directly reflect the code change—such as “refactor: delegate team member limit check to LimitService”—or, if bypassing limits for self-hosting is indeed implemented here, ensure the title and summary explicitly reference that behavior.
✅ Passed checks (2 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage✅ PassedNo functions found in the changes. Docstring coverage check skipped.

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
pre_merge_checks:
custom_checks:
- name: "Undocumented Breaking Changes"mode: "warning"instructions: | Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch km/2025-09-11-team-limit-self-hosted

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

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying usesend with Cloudflare Pages Cloudflare Pages

Latest commit:7b3bd10
Status: ✅ Deploy successful!
Preview URL:https://323032aa.usesend.pages.dev
Branch Preview URL:https://km-2025-09-11-team-limit-sel.usesend.pages.dev

View logs

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

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

⚠️ Outside diff range comments (1)
apps/web/src/server/service/team-service.ts (1)

165-171: Re-validate team member limit in invite acceptance
In apps/web/src/server/api/routers/invitiation.ts (at the ctx.db.teamUser.create call around line 60), invoke LimitService.checkTeamMemberLimit(invite.teamId) and throw if isLimitReached before creating the teamUser to prevent a TOCTOU race.

🧹 Nitpick comments (1)
apps/web/src/server/service/team-service.ts (1)

9-10: Use ~/ alias for LimitService import to match apps/web conventions.

Follow the repo guideline for src imports in apps/web.

Apply:

-import { LimitService } from "./limit-service";+import { LimitService } from "~/server/service/limit-service";
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cd40de0 and 7b3bd10.

📒 Files selected for processing (1)
  • apps/web/src/server/service/team-service.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{js,jsx,ts,tsx}

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

Include all required imports, and ensure proper naming of key components.

Files:

  • apps/web/src/server/service/team-service.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use 2-space indentation in TypeScript code (enforced by Prettier)
Use semicolons in TypeScript code (enforced by Prettier)
Do not use dynamic imports

Files:

  • apps/web/src/server/service/team-service.ts
**/*.{ts,tsx,md}

📄 CodeRabbit inference engine (AGENTS.md)

Format code with Prettier 3 via pnpm format for TypeScript and Markdown files

Files:

  • apps/web/src/server/service/team-service.ts
apps/web/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

In apps/web, use the / alias for src imports (e.g., import { x } from "/utils/x")

Files:

  • apps/web/src/server/service/team-service.ts
🧠 Learnings (1)
📚 Learning: 2025-09-10T12:33:42.627Z
Learnt from: KMKoushik
PR: usesend/useSend#224
File: apps/web/src/server/public-api/api/emails/get-email.ts:63-74
Timestamp: 2025-09-10T12:33:42.627Z
Learning: In the useSend project, Prisma's findUnique method works with composite where clauses including id, teamId, and optional domainId fields in apps/web/src/server/public-api/api/emails/get-email.ts

Applied to files:

  • apps/web/src/server/service/team-service.ts
🧬 Code graph analysis (1)
apps/web/src/server/service/team-service.ts (1)
apps/web/src/server/service/limit-service.ts (1)
  • LimitService (14-241)
🔇 Additional comments (1)
apps/web/src/server/service/team-service.ts (1)

165-166: LGTM: centralized limit check correctly skips self-hosted.

Delegating to LimitService honors the cloud-only gating and aligns with “do not limit users when self-hosting.”

@KMKoushik
KMKoushik merged commit 0167d13 into mainSep 10, 2025
6 checks passed
@KMKoushik
KMKoushik deleted the km/2025-09-11-team-limit-self-hosted branch September 10, 2025 19:52
Sign up for freeto 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

@KMKoushik
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

fix: do not limit users when self-hosting - #225

Merged
KMKoushik merged 1 commit into
mainfrom
km/2025-09-11-team-limit-self-hosted
Sep 10, 2025
Merged

fix: do not limit users when self-hosting#225
KMKoushik merged 1 commit into
mainfrom
km/2025-09-11-team-limit-self-hosted

Conversation

@KMKoushik

@KMKoushikKMKoushik commented Sep 10, 2025

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • Refactor
    • Standardized how team member limits are validated during invite creation, ensuring consistent enforcement across the app.
    • Maintains current behavior and error messages when limits are reached; no changes to workflows or permissions.
    • Improves reliability and prepares the system for easier future updates to limit policies.
    • No user action required; this change is behind-the-scenes and does not affect existing teams or invitations.

@vercel

vercelBot commented Sep 10, 2025

Copy link
Copy Markdown

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

ProjectDeploymentPreviewCommentsUpdated (UTC)
unsend-marketingReadyReadyPreviewCommentSep 10, 2025 7:45pm

@coderabbitai

coderabbitaiBot commented Sep 10, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

The team invite member-limit check in apps/web/src/server/service/team-service.ts was refactored to delegate to LimitService. The previous logic that computed limits using PLAN_LIMITS and member counts was removed. In createTeamInvite, a single call to LimitService.checkTeamMemberLimit(teamId) now determines if the limit is reached and throws the same UnsendApiError when exceeded. Imports were updated to remove PLAN_LIMITS and add LimitService. No exported/public entity signatures were changed.

Possibly related PRs

  • block sending emails on limits #216: Also modifies team invite member-limit logic in team-service.ts, altering LimitService usage versus PLAN_LIMITS and introducing caching/notification adjustments.

Pre-merge checks (2 passed, 1 warning)

❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Title Check⚠️ WarningThe current title implies that self-hosted deployments will no longer enforce user limits, yet the diff chiefly centralizes the team member limit logic by migrating from a static PLAN_LIMITS calculation to a call into LimitService, without explicitly exposing any self-hosting conditional in the code shown, making the title misleading relative to the actual changes.Consider renaming the PR to directly reflect the code change—such as “refactor: delegate team member limit check to LimitService”—or, if bypassing limits for self-hosting is indeed implemented here, ensure the title and summary explicitly reference that behavior.
✅ Passed checks (2 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage✅ PassedNo functions found in the changes. Docstring coverage check skipped.

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
pre_merge_checks:
custom_checks:
- name: "Undocumented Breaking Changes"mode: "warning"instructions: | Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch km/2025-09-11-team-limit-self-hosted

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

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying usesend with Cloudflare Pages Cloudflare Pages

Latest commit:7b3bd10
Status: ✅ Deploy successful!
Preview URL:https://323032aa.usesend.pages.dev
Branch Preview URL:https://km-2025-09-11-team-limit-sel.usesend.pages.dev

View logs

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

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

⚠️ Outside diff range comments (1)
apps/web/src/server/service/team-service.ts (1)

165-171: Re-validate team member limit in invite acceptance
In apps/web/src/server/api/routers/invitiation.ts (at the ctx.db.teamUser.create call around line 60), invoke LimitService.checkTeamMemberLimit(invite.teamId) and throw if isLimitReached before creating the teamUser to prevent a TOCTOU race.

🧹 Nitpick comments (1)
apps/web/src/server/service/team-service.ts (1)

9-10: Use ~/ alias for LimitService import to match apps/web conventions.

Follow the repo guideline for src imports in apps/web.

Apply:

-import { LimitService } from "./limit-service";+import { LimitService } from "~/server/service/limit-service";
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cd40de0 and 7b3bd10.

📒 Files selected for processing (1)
  • apps/web/src/server/service/team-service.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{js,jsx,ts,tsx}

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

Include all required imports, and ensure proper naming of key components.

Files:

  • apps/web/src/server/service/team-service.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use 2-space indentation in TypeScript code (enforced by Prettier)
Use semicolons in TypeScript code (enforced by Prettier)
Do not use dynamic imports

Files:

  • apps/web/src/server/service/team-service.ts
**/*.{ts,tsx,md}

📄 CodeRabbit inference engine (AGENTS.md)

Format code with Prettier 3 via pnpm format for TypeScript and Markdown files

Files:

  • apps/web/src/server/service/team-service.ts
apps/web/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

In apps/web, use the / alias for src imports (e.g., import { x } from "/utils/x")

Files:

  • apps/web/src/server/service/team-service.ts
🧠 Learnings (1)
📚 Learning: 2025-09-10T12:33:42.627Z
Learnt from: KMKoushik
PR: usesend/useSend#224
File: apps/web/src/server/public-api/api/emails/get-email.ts:63-74
Timestamp: 2025-09-10T12:33:42.627Z
Learning: In the useSend project, Prisma's findUnique method works with composite where clauses including id, teamId, and optional domainId fields in apps/web/src/server/public-api/api/emails/get-email.ts

Applied to files:

  • apps/web/src/server/service/team-service.ts
🧬 Code graph analysis (1)
apps/web/src/server/service/team-service.ts (1)
apps/web/src/server/service/limit-service.ts (1)
  • LimitService (14-241)
🔇 Additional comments (1)
apps/web/src/server/service/team-service.ts (1)

165-166: LGTM: centralized limit check correctly skips self-hosted.

Delegating to LimitService honors the cloud-only gating and aligns with “do not limit users when self-hosting.”

@KMKoushik
KMKoushik merged commit 0167d13 into mainSep 10, 2025
6 checks passed
@KMKoushik
KMKoushik deleted the km/2025-09-11-team-limit-self-hosted branch September 10, 2025 19:52
Sign up for freeto 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

@KMKoushik
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: do not limit users when self-hosting - #225

Merged
KMKoushik merged 1 commit into
mainfrom
km/2025-09-11-team-limit-self-hosted
Sep 10, 2025
Merged

fix: do not limit users when self-hosting#225
KMKoushik merged 1 commit into
mainfrom
km/2025-09-11-team-limit-self-hosted

Conversation

@KMKoushik

@KMKoushikKMKoushik commented Sep 10, 2025

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • Refactor
    • Standardized how team member limits are validated during invite creation, ensuring consistent enforcement across the app.
    • Maintains current behavior and error messages when limits are reached; no changes to workflows or permissions.
    • Improves reliability and prepares the system for easier future updates to limit policies.
    • No user action required; this change is behind-the-scenes and does not affect existing teams or invitations.

@vercel

vercelBot commented Sep 10, 2025

Copy link
Copy Markdown

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

ProjectDeploymentPreviewCommentsUpdated (UTC)
unsend-marketingReadyReadyPreviewCommentSep 10, 2025 7:45pm

@coderabbitai

coderabbitaiBot commented Sep 10, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

The team invite member-limit check in apps/web/src/server/service/team-service.ts was refactored to delegate to LimitService. The previous logic that computed limits using PLAN_LIMITS and member counts was removed. In createTeamInvite, a single call to LimitService.checkTeamMemberLimit(teamId) now determines if the limit is reached and throws the same UnsendApiError when exceeded. Imports were updated to remove PLAN_LIMITS and add LimitService. No exported/public entity signatures were changed.

Possibly related PRs

  • block sending emails on limits #216: Also modifies team invite member-limit logic in team-service.ts, altering LimitService usage versus PLAN_LIMITS and introducing caching/notification adjustments.

Pre-merge checks (2 passed, 1 warning)

❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Title Check⚠️ WarningThe current title implies that self-hosted deployments will no longer enforce user limits, yet the diff chiefly centralizes the team member limit logic by migrating from a static PLAN_LIMITS calculation to a call into LimitService, without explicitly exposing any self-hosting conditional in the code shown, making the title misleading relative to the actual changes.Consider renaming the PR to directly reflect the code change—such as “refactor: delegate team member limit check to LimitService”—or, if bypassing limits for self-hosting is indeed implemented here, ensure the title and summary explicitly reference that behavior.
✅ Passed checks (2 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage✅ PassedNo functions found in the changes. Docstring coverage check skipped.

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
pre_merge_checks:
custom_checks:
- name: "Undocumented Breaking Changes"mode: "warning"instructions: | Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch km/2025-09-11-team-limit-self-hosted

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

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying usesend with Cloudflare Pages Cloudflare Pages

Latest commit:7b3bd10
Status: ✅ Deploy successful!
Preview URL:https://323032aa.usesend.pages.dev
Branch Preview URL:https://km-2025-09-11-team-limit-sel.usesend.pages.dev

View logs

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

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

⚠️ Outside diff range comments (1)
apps/web/src/server/service/team-service.ts (1)

165-171: Re-validate team member limit in invite acceptance
In apps/web/src/server/api/routers/invitiation.ts (at the ctx.db.teamUser.create call around line 60), invoke LimitService.checkTeamMemberLimit(invite.teamId) and throw if isLimitReached before creating the teamUser to prevent a TOCTOU race.

🧹 Nitpick comments (1)
apps/web/src/server/service/team-service.ts (1)

9-10: Use ~/ alias for LimitService import to match apps/web conventions.

Follow the repo guideline for src imports in apps/web.

Apply:

-import { LimitService } from "./limit-service";+import { LimitService } from "~/server/service/limit-service";
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cd40de0 and 7b3bd10.

📒 Files selected for processing (1)
  • apps/web/src/server/service/team-service.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{js,jsx,ts,tsx}

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

Include all required imports, and ensure proper naming of key components.

Files:

  • apps/web/src/server/service/team-service.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use 2-space indentation in TypeScript code (enforced by Prettier)
Use semicolons in TypeScript code (enforced by Prettier)
Do not use dynamic imports

Files:

  • apps/web/src/server/service/team-service.ts
**/*.{ts,tsx,md}

📄 CodeRabbit inference engine (AGENTS.md)

Format code with Prettier 3 via pnpm format for TypeScript and Markdown files

Files:

  • apps/web/src/server/service/team-service.ts
apps/web/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

In apps/web, use the / alias for src imports (e.g., import { x } from "/utils/x")

Files:

  • apps/web/src/server/service/team-service.ts
🧠 Learnings (1)
📚 Learning: 2025-09-10T12:33:42.627Z
Learnt from: KMKoushik
PR: usesend/useSend#224
File: apps/web/src/server/public-api/api/emails/get-email.ts:63-74
Timestamp: 2025-09-10T12:33:42.627Z
Learning: In the useSend project, Prisma's findUnique method works with composite where clauses including id, teamId, and optional domainId fields in apps/web/src/server/public-api/api/emails/get-email.ts

Applied to files:

  • apps/web/src/server/service/team-service.ts
🧬 Code graph analysis (1)
apps/web/src/server/service/team-service.ts (1)
apps/web/src/server/service/limit-service.ts (1)
  • LimitService (14-241)
🔇 Additional comments (1)
apps/web/src/server/service/team-service.ts (1)

165-166: LGTM: centralized limit check correctly skips self-hosted.

Delegating to LimitService honors the cloud-only gating and aligns with “do not limit users when self-hosting.”

@KMKoushik
KMKoushik merged commit 0167d13 into mainSep 10, 2025
6 checks passed
@KMKoushik
KMKoushik deleted the km/2025-09-11-team-limit-self-hosted branch September 10, 2025 19:52
Sign up for freeto 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

@KMKoushik
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: do not limit users when self-hosting - #225

Merged
KMKoushik merged 1 commit into
mainfrom
km/2025-09-11-team-limit-self-hosted
Sep 10, 2025
Merged

fix: do not limit users when self-hosting#225
KMKoushik merged 1 commit into
mainfrom
km/2025-09-11-team-limit-self-hosted

Conversation

@KMKoushik

@KMKoushikKMKoushik commented Sep 10, 2025

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • Refactor
    • Standardized how team member limits are validated during invite creation, ensuring consistent enforcement across the app.
    • Maintains current behavior and error messages when limits are reached; no changes to workflows or permissions.
    • Improves reliability and prepares the system for easier future updates to limit policies.
    • No user action required; this change is behind-the-scenes and does not affect existing teams or invitations.

@vercel

vercelBot commented Sep 10, 2025

Copy link
Copy Markdown

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

ProjectDeploymentPreviewCommentsUpdated (UTC)
unsend-marketingReadyReadyPreviewCommentSep 10, 2025 7:45pm

@coderabbitai

coderabbitaiBot commented Sep 10, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

The team invite member-limit check in apps/web/src/server/service/team-service.ts was refactored to delegate to LimitService. The previous logic that computed limits using PLAN_LIMITS and member counts was removed. In createTeamInvite, a single call to LimitService.checkTeamMemberLimit(teamId) now determines if the limit is reached and throws the same UnsendApiError when exceeded. Imports were updated to remove PLAN_LIMITS and add LimitService. No exported/public entity signatures were changed.

Possibly related PRs

  • block sending emails on limits #216: Also modifies team invite member-limit logic in team-service.ts, altering LimitService usage versus PLAN_LIMITS and introducing caching/notification adjustments.

Pre-merge checks (2 passed, 1 warning)

❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Title Check⚠️ WarningThe current title implies that self-hosted deployments will no longer enforce user limits, yet the diff chiefly centralizes the team member limit logic by migrating from a static PLAN_LIMITS calculation to a call into LimitService, without explicitly exposing any self-hosting conditional in the code shown, making the title misleading relative to the actual changes.Consider renaming the PR to directly reflect the code change—such as “refactor: delegate team member limit check to LimitService”—or, if bypassing limits for self-hosting is indeed implemented here, ensure the title and summary explicitly reference that behavior.
✅ Passed checks (2 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage✅ PassedNo functions found in the changes. Docstring coverage check skipped.

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
pre_merge_checks:
custom_checks:
- name: "Undocumented Breaking Changes"mode: "warning"instructions: | Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch km/2025-09-11-team-limit-self-hosted

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

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying usesend with Cloudflare Pages Cloudflare Pages

Latest commit:7b3bd10
Status: ✅ Deploy successful!
Preview URL:https://323032aa.usesend.pages.dev
Branch Preview URL:https://km-2025-09-11-team-limit-sel.usesend.pages.dev

View logs

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

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

⚠️ Outside diff range comments (1)
apps/web/src/server/service/team-service.ts (1)

165-171: Re-validate team member limit in invite acceptance
In apps/web/src/server/api/routers/invitiation.ts (at the ctx.db.teamUser.create call around line 60), invoke LimitService.checkTeamMemberLimit(invite.teamId) and throw if isLimitReached before creating the teamUser to prevent a TOCTOU race.

🧹 Nitpick comments (1)
apps/web/src/server/service/team-service.ts (1)

9-10: Use ~/ alias for LimitService import to match apps/web conventions.

Follow the repo guideline for src imports in apps/web.

Apply:

-import { LimitService } from "./limit-service";+import { LimitService } from "~/server/service/limit-service";
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cd40de0 and 7b3bd10.

📒 Files selected for processing (1)
  • apps/web/src/server/service/team-service.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{js,jsx,ts,tsx}

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

Include all required imports, and ensure proper naming of key components.

Files:

  • apps/web/src/server/service/team-service.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use 2-space indentation in TypeScript code (enforced by Prettier)
Use semicolons in TypeScript code (enforced by Prettier)
Do not use dynamic imports

Files:

  • apps/web/src/server/service/team-service.ts
**/*.{ts,tsx,md}

📄 CodeRabbit inference engine (AGENTS.md)

Format code with Prettier 3 via pnpm format for TypeScript and Markdown files

Files:

  • apps/web/src/server/service/team-service.ts
apps/web/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

In apps/web, use the / alias for src imports (e.g., import { x } from "/utils/x")

Files:

  • apps/web/src/server/service/team-service.ts
🧠 Learnings (1)
📚 Learning: 2025-09-10T12:33:42.627Z
Learnt from: KMKoushik
PR: usesend/useSend#224
File: apps/web/src/server/public-api/api/emails/get-email.ts:63-74
Timestamp: 2025-09-10T12:33:42.627Z
Learning: In the useSend project, Prisma's findUnique method works with composite where clauses including id, teamId, and optional domainId fields in apps/web/src/server/public-api/api/emails/get-email.ts

Applied to files:

  • apps/web/src/server/service/team-service.ts
🧬 Code graph analysis (1)
apps/web/src/server/service/team-service.ts (1)
apps/web/src/server/service/limit-service.ts (1)
  • LimitService (14-241)
🔇 Additional comments (1)
apps/web/src/server/service/team-service.ts (1)

165-166: LGTM: centralized limit check correctly skips self-hosted.

Delegating to LimitService honors the cloud-only gating and aligns with “do not limit users when self-hosting.”

@KMKoushik
KMKoushik merged commit 0167d13 into mainSep 10, 2025
6 checks passed
@KMKoushik
KMKoushik deleted the km/2025-09-11-team-limit-self-hosted branch September 10, 2025 19:52
Sign up for freeto 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

@KMKoushik
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

fix: do not limit users when self-hosting - #225

Merged
KMKoushik merged 1 commit into
mainfrom
km/2025-09-11-team-limit-self-hosted
Sep 10, 2025
Merged

fix: do not limit users when self-hosting#225
KMKoushik merged 1 commit into
mainfrom
km/2025-09-11-team-limit-self-hosted

Conversation

@KMKoushik

@KMKoushikKMKoushik commented Sep 10, 2025

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • Refactor
    • Standardized how team member limits are validated during invite creation, ensuring consistent enforcement across the app.
    • Maintains current behavior and error messages when limits are reached; no changes to workflows or permissions.
    • Improves reliability and prepares the system for easier future updates to limit policies.
    • No user action required; this change is behind-the-scenes and does not affect existing teams or invitations.

@vercel

vercelBot commented Sep 10, 2025

Copy link
Copy Markdown

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

ProjectDeploymentPreviewCommentsUpdated (UTC)
unsend-marketingReadyReadyPreviewCommentSep 10, 2025 7:45pm

@coderabbitai

coderabbitaiBot commented Sep 10, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

The team invite member-limit check in apps/web/src/server/service/team-service.ts was refactored to delegate to LimitService. The previous logic that computed limits using PLAN_LIMITS and member counts was removed. In createTeamInvite, a single call to LimitService.checkTeamMemberLimit(teamId) now determines if the limit is reached and throws the same UnsendApiError when exceeded. Imports were updated to remove PLAN_LIMITS and add LimitService. No exported/public entity signatures were changed.

Possibly related PRs

  • block sending emails on limits #216: Also modifies team invite member-limit logic in team-service.ts, altering LimitService usage versus PLAN_LIMITS and introducing caching/notification adjustments.

Pre-merge checks (2 passed, 1 warning)

❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Title Check⚠️ WarningThe current title implies that self-hosted deployments will no longer enforce user limits, yet the diff chiefly centralizes the team member limit logic by migrating from a static PLAN_LIMITS calculation to a call into LimitService, without explicitly exposing any self-hosting conditional in the code shown, making the title misleading relative to the actual changes.Consider renaming the PR to directly reflect the code change—such as “refactor: delegate team member limit check to LimitService”—or, if bypassing limits for self-hosting is indeed implemented here, ensure the title and summary explicitly reference that behavior.
✅ Passed checks (2 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage✅ PassedNo functions found in the changes. Docstring coverage check skipped.

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
pre_merge_checks:
custom_checks:
- name: "Undocumented Breaking Changes"mode: "warning"instructions: | Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch km/2025-09-11-team-limit-self-hosted

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

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying usesend with Cloudflare Pages Cloudflare Pages

Latest commit:7b3bd10
Status: ✅ Deploy successful!
Preview URL:https://323032aa.usesend.pages.dev
Branch Preview URL:https://km-2025-09-11-team-limit-sel.usesend.pages.dev

View logs

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

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

⚠️ Outside diff range comments (1)
apps/web/src/server/service/team-service.ts (1)

165-171: Re-validate team member limit in invite acceptance
In apps/web/src/server/api/routers/invitiation.ts (at the ctx.db.teamUser.create call around line 60), invoke LimitService.checkTeamMemberLimit(invite.teamId) and throw if isLimitReached before creating the teamUser to prevent a TOCTOU race.

🧹 Nitpick comments (1)
apps/web/src/server/service/team-service.ts (1)

9-10: Use ~/ alias for LimitService import to match apps/web conventions.

Follow the repo guideline for src imports in apps/web.

Apply:

-import { LimitService } from "./limit-service";+import { LimitService } from "~/server/service/limit-service";
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cd40de0 and 7b3bd10.

📒 Files selected for processing (1)
  • apps/web/src/server/service/team-service.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{js,jsx,ts,tsx}

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

Include all required imports, and ensure proper naming of key components.

Files:

  • apps/web/src/server/service/team-service.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use 2-space indentation in TypeScript code (enforced by Prettier)
Use semicolons in TypeScript code (enforced by Prettier)
Do not use dynamic imports

Files:

  • apps/web/src/server/service/team-service.ts
**/*.{ts,tsx,md}

📄 CodeRabbit inference engine (AGENTS.md)

Format code with Prettier 3 via pnpm format for TypeScript and Markdown files

Files:

  • apps/web/src/server/service/team-service.ts
apps/web/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

In apps/web, use the / alias for src imports (e.g., import { x } from "/utils/x")

Files:

  • apps/web/src/server/service/team-service.ts
🧠 Learnings (1)
📚 Learning: 2025-09-10T12:33:42.627Z
Learnt from: KMKoushik
PR: usesend/useSend#224
File: apps/web/src/server/public-api/api/emails/get-email.ts:63-74
Timestamp: 2025-09-10T12:33:42.627Z
Learning: In the useSend project, Prisma's findUnique method works with composite where clauses including id, teamId, and optional domainId fields in apps/web/src/server/public-api/api/emails/get-email.ts

Applied to files:

  • apps/web/src/server/service/team-service.ts
🧬 Code graph analysis (1)
apps/web/src/server/service/team-service.ts (1)
apps/web/src/server/service/limit-service.ts (1)
  • LimitService (14-241)
🔇 Additional comments (1)
apps/web/src/server/service/team-service.ts (1)

165-166: LGTM: centralized limit check correctly skips self-hosted.

Delegating to LimitService honors the cloud-only gating and aligns with “do not limit users when self-hosting.”

@KMKoushik
KMKoushik merged commit 0167d13 into mainSep 10, 2025
6 checks passed
@KMKoushik
KMKoushik deleted the km/2025-09-11-team-limit-self-hosted branch September 10, 2025 19:52
Sign up for freeto 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

@KMKoushik
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: do not limit users when self-hosting - #225

Merged
KMKoushik merged 1 commit into
mainfrom
km/2025-09-11-team-limit-self-hosted
Sep 10, 2025
Merged

fix: do not limit users when self-hosting#225
KMKoushik merged 1 commit into
mainfrom
km/2025-09-11-team-limit-self-hosted

Conversation

@KMKoushik

@KMKoushikKMKoushik commented Sep 10, 2025

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • Refactor
    • Standardized how team member limits are validated during invite creation, ensuring consistent enforcement across the app.
    • Maintains current behavior and error messages when limits are reached; no changes to workflows or permissions.
    • Improves reliability and prepares the system for easier future updates to limit policies.
    • No user action required; this change is behind-the-scenes and does not affect existing teams or invitations.

@vercel

vercelBot commented Sep 10, 2025

Copy link
Copy Markdown

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

ProjectDeploymentPreviewCommentsUpdated (UTC)
unsend-marketingReadyReadyPreviewCommentSep 10, 2025 7:45pm

@coderabbitai

coderabbitaiBot commented Sep 10, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

The team invite member-limit check in apps/web/src/server/service/team-service.ts was refactored to delegate to LimitService. The previous logic that computed limits using PLAN_LIMITS and member counts was removed. In createTeamInvite, a single call to LimitService.checkTeamMemberLimit(teamId) now determines if the limit is reached and throws the same UnsendApiError when exceeded. Imports were updated to remove PLAN_LIMITS and add LimitService. No exported/public entity signatures were changed.

Possibly related PRs

  • block sending emails on limits #216: Also modifies team invite member-limit logic in team-service.ts, altering LimitService usage versus PLAN_LIMITS and introducing caching/notification adjustments.

Pre-merge checks (2 passed, 1 warning)

❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Title Check⚠️ WarningThe current title implies that self-hosted deployments will no longer enforce user limits, yet the diff chiefly centralizes the team member limit logic by migrating from a static PLAN_LIMITS calculation to a call into LimitService, without explicitly exposing any self-hosting conditional in the code shown, making the title misleading relative to the actual changes.Consider renaming the PR to directly reflect the code change—such as “refactor: delegate team member limit check to LimitService”—or, if bypassing limits for self-hosting is indeed implemented here, ensure the title and summary explicitly reference that behavior.
✅ Passed checks (2 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage✅ PassedNo functions found in the changes. Docstring coverage check skipped.

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
pre_merge_checks:
custom_checks:
- name: "Undocumented Breaking Changes"mode: "warning"instructions: | Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch km/2025-09-11-team-limit-self-hosted

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

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying usesend with Cloudflare Pages Cloudflare Pages

Latest commit:7b3bd10
Status: ✅ Deploy successful!
Preview URL:https://323032aa.usesend.pages.dev
Branch Preview URL:https://km-2025-09-11-team-limit-sel.usesend.pages.dev

View logs

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

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

⚠️ Outside diff range comments (1)
apps/web/src/server/service/team-service.ts (1)

165-171: Re-validate team member limit in invite acceptance
In apps/web/src/server/api/routers/invitiation.ts (at the ctx.db.teamUser.create call around line 60), invoke LimitService.checkTeamMemberLimit(invite.teamId) and throw if isLimitReached before creating the teamUser to prevent a TOCTOU race.

🧹 Nitpick comments (1)
apps/web/src/server/service/team-service.ts (1)

9-10: Use ~/ alias for LimitService import to match apps/web conventions.

Follow the repo guideline for src imports in apps/web.

Apply:

-import { LimitService } from "./limit-service";+import { LimitService } from "~/server/service/limit-service";
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cd40de0 and 7b3bd10.

📒 Files selected for processing (1)
  • apps/web/src/server/service/team-service.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{js,jsx,ts,tsx}

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

Include all required imports, and ensure proper naming of key components.

Files:

  • apps/web/src/server/service/team-service.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use 2-space indentation in TypeScript code (enforced by Prettier)
Use semicolons in TypeScript code (enforced by Prettier)
Do not use dynamic imports

Files:

  • apps/web/src/server/service/team-service.ts
**/*.{ts,tsx,md}

📄 CodeRabbit inference engine (AGENTS.md)

Format code with Prettier 3 via pnpm format for TypeScript and Markdown files

Files:

  • apps/web/src/server/service/team-service.ts
apps/web/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

In apps/web, use the / alias for src imports (e.g., import { x } from "/utils/x")

Files:

  • apps/web/src/server/service/team-service.ts
🧠 Learnings (1)
📚 Learning: 2025-09-10T12:33:42.627Z
Learnt from: KMKoushik
PR: usesend/useSend#224
File: apps/web/src/server/public-api/api/emails/get-email.ts:63-74
Timestamp: 2025-09-10T12:33:42.627Z
Learning: In the useSend project, Prisma's findUnique method works with composite where clauses including id, teamId, and optional domainId fields in apps/web/src/server/public-api/api/emails/get-email.ts

Applied to files:

  • apps/web/src/server/service/team-service.ts
🧬 Code graph analysis (1)
apps/web/src/server/service/team-service.ts (1)
apps/web/src/server/service/limit-service.ts (1)
  • LimitService (14-241)
🔇 Additional comments (1)
apps/web/src/server/service/team-service.ts (1)

165-166: LGTM: centralized limit check correctly skips self-hosted.

Delegating to LimitService honors the cloud-only gating and aligns with “do not limit users when self-hosting.”

@KMKoushik
KMKoushik merged commit 0167d13 into mainSep 10, 2025
6 checks passed
@KMKoushik
KMKoushik deleted the km/2025-09-11-team-limit-self-hosted branch September 10, 2025 19:52
Sign up for freeto 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

@KMKoushik
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: do not limit users when self-hosting - #225

Merged
KMKoushik merged 1 commit into
mainfrom
km/2025-09-11-team-limit-self-hosted
Sep 10, 2025
Merged

fix: do not limit users when self-hosting#225
KMKoushik merged 1 commit into
mainfrom
km/2025-09-11-team-limit-self-hosted

Conversation

@KMKoushik

@KMKoushikKMKoushik commented Sep 10, 2025

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • Refactor
    • Standardized how team member limits are validated during invite creation, ensuring consistent enforcement across the app.
    • Maintains current behavior and error messages when limits are reached; no changes to workflows or permissions.
    • Improves reliability and prepares the system for easier future updates to limit policies.
    • No user action required; this change is behind-the-scenes and does not affect existing teams or invitations.

@vercel

vercelBot commented Sep 10, 2025

Copy link
Copy Markdown

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

ProjectDeploymentPreviewCommentsUpdated (UTC)
unsend-marketingReadyReadyPreviewCommentSep 10, 2025 7:45pm

@coderabbitai

coderabbitaiBot commented Sep 10, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

The team invite member-limit check in apps/web/src/server/service/team-service.ts was refactored to delegate to LimitService. The previous logic that computed limits using PLAN_LIMITS and member counts was removed. In createTeamInvite, a single call to LimitService.checkTeamMemberLimit(teamId) now determines if the limit is reached and throws the same UnsendApiError when exceeded. Imports were updated to remove PLAN_LIMITS and add LimitService. No exported/public entity signatures were changed.

Possibly related PRs

  • block sending emails on limits #216: Also modifies team invite member-limit logic in team-service.ts, altering LimitService usage versus PLAN_LIMITS and introducing caching/notification adjustments.

Pre-merge checks (2 passed, 1 warning)

❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Title Check⚠️ WarningThe current title implies that self-hosted deployments will no longer enforce user limits, yet the diff chiefly centralizes the team member limit logic by migrating from a static PLAN_LIMITS calculation to a call into LimitService, without explicitly exposing any self-hosting conditional in the code shown, making the title misleading relative to the actual changes.Consider renaming the PR to directly reflect the code change—such as “refactor: delegate team member limit check to LimitService”—or, if bypassing limits for self-hosting is indeed implemented here, ensure the title and summary explicitly reference that behavior.
✅ Passed checks (2 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage✅ PassedNo functions found in the changes. Docstring coverage check skipped.

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
pre_merge_checks:
custom_checks:
- name: "Undocumented Breaking Changes"mode: "warning"instructions: | Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch km/2025-09-11-team-limit-self-hosted

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

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying usesend with Cloudflare Pages Cloudflare Pages

Latest commit:7b3bd10
Status: ✅ Deploy successful!
Preview URL:https://323032aa.usesend.pages.dev
Branch Preview URL:https://km-2025-09-11-team-limit-sel.usesend.pages.dev

View logs

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

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

⚠️ Outside diff range comments (1)
apps/web/src/server/service/team-service.ts (1)

165-171: Re-validate team member limit in invite acceptance
In apps/web/src/server/api/routers/invitiation.ts (at the ctx.db.teamUser.create call around line 60), invoke LimitService.checkTeamMemberLimit(invite.teamId) and throw if isLimitReached before creating the teamUser to prevent a TOCTOU race.

🧹 Nitpick comments (1)
apps/web/src/server/service/team-service.ts (1)

9-10: Use ~/ alias for LimitService import to match apps/web conventions.

Follow the repo guideline for src imports in apps/web.

Apply:

-import { LimitService } from "./limit-service";+import { LimitService } from "~/server/service/limit-service";
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cd40de0 and 7b3bd10.

📒 Files selected for processing (1)
  • apps/web/src/server/service/team-service.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{js,jsx,ts,tsx}

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

Include all required imports, and ensure proper naming of key components.

Files:

  • apps/web/src/server/service/team-service.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use 2-space indentation in TypeScript code (enforced by Prettier)
Use semicolons in TypeScript code (enforced by Prettier)
Do not use dynamic imports

Files:

  • apps/web/src/server/service/team-service.ts
**/*.{ts,tsx,md}

📄 CodeRabbit inference engine (AGENTS.md)

Format code with Prettier 3 via pnpm format for TypeScript and Markdown files

Files:

  • apps/web/src/server/service/team-service.ts
apps/web/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

In apps/web, use the / alias for src imports (e.g., import { x } from "/utils/x")

Files:

  • apps/web/src/server/service/team-service.ts
🧠 Learnings (1)
📚 Learning: 2025-09-10T12:33:42.627Z
Learnt from: KMKoushik
PR: usesend/useSend#224
File: apps/web/src/server/public-api/api/emails/get-email.ts:63-74
Timestamp: 2025-09-10T12:33:42.627Z
Learning: In the useSend project, Prisma's findUnique method works with composite where clauses including id, teamId, and optional domainId fields in apps/web/src/server/public-api/api/emails/get-email.ts

Applied to files:

  • apps/web/src/server/service/team-service.ts
🧬 Code graph analysis (1)
apps/web/src/server/service/team-service.ts (1)
apps/web/src/server/service/limit-service.ts (1)
  • LimitService (14-241)
🔇 Additional comments (1)
apps/web/src/server/service/team-service.ts (1)

165-166: LGTM: centralized limit check correctly skips self-hosted.

Delegating to LimitService honors the cloud-only gating and aligns with “do not limit users when self-hosting.”

@KMKoushik
KMKoushik merged commit 0167d13 into mainSep 10, 2025
6 checks passed
@KMKoushik
KMKoushik deleted the km/2025-09-11-team-limit-self-hosted branch September 10, 2025 19:52
Sign up for freeto 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

@KMKoushik
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

fix: do not limit users when self-hosting - #225

Merged
KMKoushik merged 1 commit into
mainfrom
km/2025-09-11-team-limit-self-hosted
Sep 10, 2025
Merged

fix: do not limit users when self-hosting#225
KMKoushik merged 1 commit into
mainfrom
km/2025-09-11-team-limit-self-hosted

Conversation

@KMKoushik

@KMKoushikKMKoushik commented Sep 10, 2025

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • Refactor
    • Standardized how team member limits are validated during invite creation, ensuring consistent enforcement across the app.
    • Maintains current behavior and error messages when limits are reached; no changes to workflows or permissions.
    • Improves reliability and prepares the system for easier future updates to limit policies.
    • No user action required; this change is behind-the-scenes and does not affect existing teams or invitations.

@vercel

vercelBot commented Sep 10, 2025

Copy link
Copy Markdown

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

ProjectDeploymentPreviewCommentsUpdated (UTC)
unsend-marketingReadyReadyPreviewCommentSep 10, 2025 7:45pm

@coderabbitai

coderabbitaiBot commented Sep 10, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

The team invite member-limit check in apps/web/src/server/service/team-service.ts was refactored to delegate to LimitService. The previous logic that computed limits using PLAN_LIMITS and member counts was removed. In createTeamInvite, a single call to LimitService.checkTeamMemberLimit(teamId) now determines if the limit is reached and throws the same UnsendApiError when exceeded. Imports were updated to remove PLAN_LIMITS and add LimitService. No exported/public entity signatures were changed.

Possibly related PRs

  • block sending emails on limits #216: Also modifies team invite member-limit logic in team-service.ts, altering LimitService usage versus PLAN_LIMITS and introducing caching/notification adjustments.

Pre-merge checks (2 passed, 1 warning)

❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Title Check⚠️ WarningThe current title implies that self-hosted deployments will no longer enforce user limits, yet the diff chiefly centralizes the team member limit logic by migrating from a static PLAN_LIMITS calculation to a call into LimitService, without explicitly exposing any self-hosting conditional in the code shown, making the title misleading relative to the actual changes.Consider renaming the PR to directly reflect the code change—such as “refactor: delegate team member limit check to LimitService”—or, if bypassing limits for self-hosting is indeed implemented here, ensure the title and summary explicitly reference that behavior.
✅ Passed checks (2 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage✅ PassedNo functions found in the changes. Docstring coverage check skipped.

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
pre_merge_checks:
custom_checks:
- name: "Undocumented Breaking Changes"mode: "warning"instructions: | Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch km/2025-09-11-team-limit-self-hosted

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

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying usesend with Cloudflare Pages Cloudflare Pages

Latest commit:7b3bd10
Status: ✅ Deploy successful!
Preview URL:https://323032aa.usesend.pages.dev
Branch Preview URL:https://km-2025-09-11-team-limit-sel.usesend.pages.dev

View logs

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

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

⚠️ Outside diff range comments (1)
apps/web/src/server/service/team-service.ts (1)

165-171: Re-validate team member limit in invite acceptance
In apps/web/src/server/api/routers/invitiation.ts (at the ctx.db.teamUser.create call around line 60), invoke LimitService.checkTeamMemberLimit(invite.teamId) and throw if isLimitReached before creating the teamUser to prevent a TOCTOU race.

🧹 Nitpick comments (1)
apps/web/src/server/service/team-service.ts (1)

9-10: Use ~/ alias for LimitService import to match apps/web conventions.

Follow the repo guideline for src imports in apps/web.

Apply:

-import { LimitService } from "./limit-service";+import { LimitService } from "~/server/service/limit-service";
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cd40de0 and 7b3bd10.

📒 Files selected for processing (1)
  • apps/web/src/server/service/team-service.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{js,jsx,ts,tsx}

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

Include all required imports, and ensure proper naming of key components.

Files:

  • apps/web/src/server/service/team-service.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use 2-space indentation in TypeScript code (enforced by Prettier)
Use semicolons in TypeScript code (enforced by Prettier)
Do not use dynamic imports

Files:

  • apps/web/src/server/service/team-service.ts
**/*.{ts,tsx,md}

📄 CodeRabbit inference engine (AGENTS.md)

Format code with Prettier 3 via pnpm format for TypeScript and Markdown files

Files:

  • apps/web/src/server/service/team-service.ts
apps/web/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

In apps/web, use the / alias for src imports (e.g., import { x } from "/utils/x")

Files:

  • apps/web/src/server/service/team-service.ts
🧠 Learnings (1)
📚 Learning: 2025-09-10T12:33:42.627Z
Learnt from: KMKoushik
PR: usesend/useSend#224
File: apps/web/src/server/public-api/api/emails/get-email.ts:63-74
Timestamp: 2025-09-10T12:33:42.627Z
Learning: In the useSend project, Prisma's findUnique method works with composite where clauses including id, teamId, and optional domainId fields in apps/web/src/server/public-api/api/emails/get-email.ts

Applied to files:

  • apps/web/src/server/service/team-service.ts
🧬 Code graph analysis (1)
apps/web/src/server/service/team-service.ts (1)
apps/web/src/server/service/limit-service.ts (1)
  • LimitService (14-241)
🔇 Additional comments (1)
apps/web/src/server/service/team-service.ts (1)

165-166: LGTM: centralized limit check correctly skips self-hosted.

Delegating to LimitService honors the cloud-only gating and aligns with “do not limit users when self-hosting.”

@KMKoushik
KMKoushik merged commit 0167d13 into mainSep 10, 2025
6 checks passed
@KMKoushik
KMKoushik deleted the km/2025-09-11-team-limit-self-hosted branch September 10, 2025 19:52
Sign up for freeto 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

@KMKoushik