-
Notifications
You must be signed in to change notification settings - Fork 11.6k
feat: add seat tracking infrastructure for monthly proration #27001
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Add seat change logging infrastructure with operationId for idempotency. This PR adds the foundation for monthly proration billing by tracking seat additions and removals, gated behind the monthly-proration feature flag. - Add operationId field to SeatChangeLog for idempotency - Update SeatChangeLogRepository to support upsert with operationId - Add feature flag guard in SeatChangeTrackingService - Integrate seat tracking in team member invites - Integrate seat tracking in bulk user deletions - Integrate seat tracking in team service operations - Integrate seat tracking in DSYNC user creation When monthly-proration feature flag is disabled, seat logging is skipped and behavior remains unchanged. Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2 issues found across 12 files
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="packages/trpc/server/routers/viewer/organizations/utils.ts">
<violation number="1" location="packages/trpc/server/routers/viewer/organizations/utils.ts:128">
P2: This counts seats by filtering `membershipData` for every team, which makes the new seat-tracking logic O(n^2) for bulk invites. Precompute seat counts in one pass and then map teams to counts to keep it O(n).</violation>
</file>
<file name="packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts">
<violation number="1" location="packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts:420">
P2: Pass an idempotency `operationId` into the new seat tracking calls so retries don’t double-count seat additions.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| const additionsByTeam = Array.from(topLevelTeamIds) | ||
| .map((teamId) => ({ | ||
| teamId, | ||
| seatCount: membershipData.filter((entry) => entry.teamId === teamId).length, | ||
| })) | ||
| .filter((entry) => entry.seatCount > 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: This counts seats by filtering membershipData for every team, which makes the new seat-tracking logic O(n^2) for bulk invites. Precompute seat counts in one pass and then map teams to counts to keep it O(n).
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/trpc/server/routers/viewer/organizations/utils.ts, line 128:
<comment>This counts seats by filtering `membershipData` for every team, which makes the new seat-tracking logic O(n^2) for bulk invites. Precompute seat counts in one pass and then map teams to counts to keep it O(n).</comment>
<file context>
@@ -106,6 +123,26 @@ export const addMembersToTeams = async ({ user, input }: AddBulkToTeamProps) =>
+ if (topLevelTeamIds.size > 0 && membershipData.length > 0) {
+ const seatTracker = new SeatChangeTrackingService();
+ const additionsByTeam = Array.from(topLevelTeamIds)
+ .map((teamId) => ({
+ teamId,
</file context>
Fix confidence (alpha): 8/10
| const additionsByTeam = Array.from(topLevelTeamIds) | |
| .map((teamId) => ({ | |
| teamId, | |
| seatCount: membershipData.filter((entry) => entry.teamId === teamId).length, | |
| })) | |
| .filter((entry) => entry.seatCount > 0); | |
| const seatCountsByTeam = membershipData.reduce((acc, { teamId }) => { | |
| acc.set(teamId, (acc.get(teamId) ?? 0) + 1); | |
| return acc; | |
| }, new Map()); | |
| const additionsByTeam = Array.from(topLevelTeamIds) | |
| .map((teamId) => ({ | |
| teamId, | |
| seatCount: seatCountsByTeam.get(teamId) ?? 0, | |
| })) | |
| .filter((entry) => entry.seatCount > 0); |
| if (createdUsers.length > 0) { | ||
| const seatTracker = new SeatChangeTrackingService(); | ||
| const trackingTeamId = parentId ?? teamId; | ||
| await seatTracker.logSeatAddition({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: Pass an idempotency operationId into the new seat tracking calls so retries don’t double-count seat additions.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts, line 420:
<comment>Pass an idempotency `operationId` into the new seat tracking calls so retries don’t double-count seat additions.</comment>
<file context>
@@ -415,6 +413,16 @@ export async function createNewUsersConnectToOrgIfExists({
+ if (createdUsers.length > 0) {
+ const seatTracker = new SeatChangeTrackingService();
+ const trackingTeamId = parentId ?? teamId;
+ await seatTracker.logSeatAddition({
+ teamId: trackingTeamId,
+ seatCount: createdUsers.length,
</file context>
Devin AI is addressing Cubic AI's review feedbackA Devin session has been created to address the issues identified by Cubic AI. |
|
I reviewed the Cubic AI feedback and checked the confidence scores for each issue:
Per the guidelines to only fix issues with confidence scores of 9/10 or higher, no changes were made to this PR. Both issues are below the threshold. |
emrysal
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this, looked at the cubic review and don't think it's critical for perf optimisation in this case.
Part 1 of monthly proration feature.
Adds seat change tracking infrastructure with operationId for idempotency.
Dependency chain: