Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@N2D4
Copy link
Contributor

@N2D4 N2D4 commented Nov 4, 2025

Summary by CodeRabbit

  • Refactor

    • Tenancy is resolved earlier in request handling and user data now consistently uses project-level configuration as the source of truth.
  • Bug Fixes

    • Strengthened runtime validations and cross-checks to reduce mismatches and improve reliability of user endpoints.
    • Project-config lookup now defaults safely when no override exists, preventing unnecessary errors.
  • Tests

    • Added end-to-end tests for handling invalid project IDs and branch IDs, with clearer error responses.

Copilot AI review requested due to automatic review settings November 4, 2025 07:16
@vercel
Copy link

vercel bot commented Nov 4, 2025

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

Project Deployment Preview Comments Updated (UTC)
stack-backend Ready Ready Preview Comment Nov 5, 2025 11:39am
stack-dashboard Ready Ready Preview Comment Nov 5, 2025 11:39am
stack-demo Ready Ready Preview Comment Nov 5, 2025 11:39am
stack-docs Ready Ready Preview Comment Nov 5, 2025 11:39am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 4, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Replaces Prisma-based tenancy lookups with RawQuery-driven tenancy/project/config queries, changes getUser to accept a Tenancy object (deriving project/branch and sourceOfTruth from it), updates callers to pass tenancy objects, and adds dev-time cross-checks between RawQuery and legacy Prisma results.

Changes

Cohort / File(s) Summary
Tenancy retrieval refactor
apps/backend/src/lib/tenancies.tsx
Replace Prisma-based tenancy lookups with RawQuery helpers (getTenancyFromProjectQuery, getSoleTenancyFromProjectBranchQuery), add tenancyPrismaToCrudUnused, change exported Tenancy type, and add non-prod cross-checks vs. legacy Prisma path.
getUser signature and flow
apps/backend/src/app/api/latest/users/crud.tsx
Change getUser signature to accept { tenancy: Tenancy } instead of { tenancyId: string }; resolve projectId/branchId and sourceOfTruth from tenancy.config when tenancy provided; update callers (e.g., onRead) to pass auth.tenancy.
SmartRequest integration
apps/backend/src/route-handlers/smart-request.tsx
Switch to getSoleTenancyFromProjectBranchQuery(...), include tenancy in bundled parallel queries, await tenancy result, remove prior tenancy-fetch bypasses, and include tenancy in returned SmartRequest/auth.
Config query post-processing
apps/backend/src/lib/config.tsx
getProjectConfigOverrideQuery now returns migrateConfigOverride("project", queryResult[0]?.projectConfigOverride ?? {}) when no rows instead of throwing; getBranchConfigOverrideQuery defers non-default branch validation to postProcess and throws there.
E2E test types
apps/e2e/tests/backend/backend-helpers.ts
Add optional branchId?: string to ProjectKeys union variant to carry branch context in tests.
E2E tests - error cases
apps/e2e/tests/backend/endpoints/api/v1/index.test.ts
Add tests asserting 400 errors for non-existent projectId and non-existent branch header (checks error codes and x-stack-known-error header).
Minor test fix
apps/e2e/tests/backend/endpoints/api/v1/projects.test.ts
Fix duplicate word in test description (non-functional).
Manifest
package.json
Manifest listed (no code detail provided).

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant API as API Handler
    participant Smart as smart-request
    participant TenLib as tenancies
    participant RawQ as RawQuery
    participant DB

    rect rgb(245,250,255)
    Note over Client,API: Incoming request with auth and project/branch headers
    Client->>API: HTTP request
    API->>Smart: build SmartRequest (include projectId, branchId)
    Smart->>TenLib: getSoleTenancyFromProjectBranchQuery(projectId, branchId, true)
    TenLib->>RawQ: compose bundled RawQuery (tenancy, project, rendered config)
    RawQ->>DB: execute queries
    DB-->>RawQ: tenancy, project, config
    RawQ-->>TenLib: tenancy (includes tenancy.config)
    TenLib-->>Smart: return Tenancy
    Smart->>API: call getUser({ tenancy, userId })
    API->>RawQ: user lookup using tenancy.config.sourceOfTruth
    RawQ->>DB: fetch user
    DB-->>RawQ: user
    RawQ-->>API: return user
    API-->>Client: response
    end

    rect rgb(240,255,240)
    Note over TenLib,DB: Dev-time cross-check (non-prod)
    TenLib->>DB: run legacy Prisma path for comparison
    DB-->>TenLib: legacy result
    alt mismatch
        TenLib-->>API: throw StackAssertionError (dev)
    else match
        TenLib-->>API: continue
    end
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Pay extra attention to:
    • apps/backend/src/lib/tenancies.tsx — RawQuery composition, post-processing, and dev-time cross-check logic.
    • apps/backend/src/app/api/latest/users/crud.tsxgetUser signature change and sourceOfTruth derivation and all call-sites.
    • apps/backend/src/route-handlers/smart-request.tsx — bundling parallel queries and inclusion/propagation of tenancy in SmartRequest.

Possibly related PRs

Poem

🐰 I nibble queries, soft and spry,
Tenancy bundled, no ID to try,
Source-of-truth now hops from within,
Dev-time checks hum if old and new spin,
A little hop — backend feels bright and spry!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description contains only a template comment with no actual description of changes, objectives, motivation, or implementation details. Add a meaningful description explaining the performance improvements, technical approach, and any breaking changes or considerations for reviewers.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: a performance improvement to the users endpoint and related endpoints.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch faster-users-endpoint

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.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR refactors tenancy fetching to use the new RawQuery pattern for improved performance and query bundling. The key motivation is to optimize the smart request authentication flow by fetching tenancies alongside other required data rather than sequentially.

  • Introduced getSoleTenancyFromProjectBranchQuery and getTenancyFromProjectQuery to support query bundling
  • Refactored getUser to accept a Tenancy object directly, avoiding redundant fetches
  • Added development mode validation to ensure the new RawQuery implementation matches the old Prisma-based approach

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
apps/backend/src/route-handlers/smart-request.tsx Integrated tenancy fetching into bundled queries and removed the performance hack for /users/me endpoint
apps/backend/src/lib/tenancies.tsx Added RawQuery-based implementations and deprecated old Prisma methods, with development mode validation
apps/backend/src/app/api/latest/users/crud.tsx Updated getUser to accept Tenancy object and use getRenderedProjectConfigQuery for optimization

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Greptile Overview

Greptile Summary

Performance optimization that reduces database queries by batching tenancy fetching into the initial request bundle in SmartRequestAuth.

Key Changes

  • tenancies.tsx: refactored getTenancyFromProject to use RawQuery pattern, enabling parallel query execution
  • smart-request.tsx: tenancy now fetched in bundled query alongside project/user/config, eliminating redundant calls
  • users/crud.tsx: getUser() accepts tenancy object directly to avoid re-fetching config when tenancy is already available

Issues Found

  • Critical logic bug in tenancies.tsx:185 - development validation runs in production instead of development due to inverted boolean logic

Confidence Score: 1/5

  • Critical logic error causes validation code to run in production instead of development
  • The inverted condition in tenancies.tsx:185 causes expensive validation queries to execute in production environments where they shouldn't run, while skipping validation in development where they're needed. This will cause performance degradation in prod and miss bugs in dev.
  • apps/backend/src/lib/tenancies.tsx requires immediate fix to line 185 condition

Important Files Changed

File Analysis

Filename Score Overview
apps/backend/src/lib/tenancies.tsx 1/5 refactored tenancy fetching to use RawQuery for performance; critical logic bug in development validation (runs in prod instead of dev)
apps/backend/src/route-handlers/smart-request.tsx 5/5 optimized by fetching tenancy in bundled query instead of separate call; removed performance hack comment
apps/backend/src/app/api/latest/users/crud.tsx 5/5 updated getUser to accept tenancy object directly, avoiding redundant config queries

Sequence Diagram

sequenceDiagram
    participant Client
    participant SmartRequest
    participant RawQuery as RawQuery Bundle
    participant GlobalDB as Global Database
    participant SourceDB as Source-of-Truth DB
    
    Client->>SmartRequest: API Request (e.g., GET /users/:user_id)
    SmartRequest->>RawQuery: Create bundled query (project, tenancy, user, config, keys)
    RawQuery->>GlobalDB: Execute all queries in parallel
    GlobalDB-->>RawQuery: Return results
    RawQuery-->>SmartRequest: project, tenancy, config, userIfOnGlobal
    
    alt Source-of-truth is hosted (global DB)
        SmartRequest->>SmartRequest: Use userIfOnGlobal from bundle
    else Source-of-truth is external
        SmartRequest->>SourceDB: getUser(projectId, branchId, userId)
        SourceDB-->>SmartRequest: user data
    end
    
    SmartRequest->>Client: Complete request with auth context
    
    Note over SmartRequest,GlobalDB: Performance improvement: tenancy fetched<br/>in initial bundle instead of separate call
Loading

3 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

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: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1e36f0e and 0e84c60.

📒 Files selected for processing (3)
  • apps/backend/src/app/api/latest/users/crud.tsx (3 hunks)
  • apps/backend/src/lib/tenancies.tsx (5 hunks)
  • apps/backend/src/route-handlers/smart-request.tsx (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
apps/backend/src/lib/tenancies.tsx (6)
apps/backend/src/prisma-client.tsx (4)
  • rawQuery (304-307)
  • globalPrismaClient (37-37)
  • RawQuery (230-234)
  • RawQuery (236-302)
packages/stack-shared/src/utils/errors.tsx (1)
  • StackAssertionError (69-85)
apps/backend/src/lib/projects.tsx (1)
  • getProjectQuery (41-69)
apps/backend/src/lib/config.tsx (1)
  • getRenderedOrganizationConfigQuery (51-56)
packages/stack-shared/src/utils/env.tsx (1)
  • getNodeEnvironment (65-67)
packages/stack-shared/src/utils/objects.tsx (1)
  • deepPlainEquals (29-65)
apps/backend/src/app/api/latest/users/crud.tsx (3)
apps/backend/src/lib/tenancies.tsx (1)
  • Tenancy (53-53)
apps/backend/src/prisma-client.tsx (4)
  • rawQuery (304-307)
  • globalPrismaClient (37-37)
  • getPrismaClientForSourceOfTruth (91-112)
  • getPrismaSchemaForSourceOfTruth (114-134)
apps/backend/src/lib/config.tsx (1)
  • getRenderedProjectConfigQuery (30-35)
apps/backend/src/route-handlers/smart-request.tsx (3)
apps/backend/src/lib/tenancies.tsx (1)
  • getSoleTenancyFromProjectBranchQuery (78-80)
apps/backend/src/prisma-client.tsx (2)
  • rawQueryAll (309-313)
  • globalPrismaClient (37-37)
packages/stack-shared/src/known-errors.tsx (2)
  • KnownErrors (1570-1572)
  • KnownErrors (1574-1695)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (13)
  • GitHub Check: CodeQL analysis (javascript-typescript)
  • GitHub Check: Vercel Agent Review
  • GitHub Check: lint_and_build (latest)
  • GitHub Check: build (22.x)
  • GitHub Check: restart-dev-and-test
  • GitHub Check: docker
  • GitHub Check: check_prisma_migrations (22.x)
  • GitHub Check: all-good
  • GitHub Check: build (22.x)
  • GitHub Check: restart-dev-and-test-with-custom-base-port
  • GitHub Check: setup-tests
  • GitHub Check: build (22.x)
  • GitHub Check: Security Check

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: 0

🧹 Nitpick comments (1)
apps/backend/src/lib/tenancies.tsx (1)

180-218: Excellent validation approach; consider case normalization.

The development-mode cross-validation against the legacy Prisma path is a robust migration pattern. The logic on line 185 is correct (runs validation when environment does NOT include "prod").

For added robustness, consider normalizing the case to handle edge cases where NODE_ENV might be capitalized:

-  if (!getNodeEnvironment().includes("prod")) {
+  if (!getNodeEnvironment().toLowerCase().includes("prod")) {

This ensures the validation skips in production regardless of case (e.g., "PRODUCTION", "Production").

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0e84c60 and 65c8f9b.

📒 Files selected for processing (1)
  • apps/backend/src/lib/tenancies.tsx (5 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
apps/backend/src/lib/tenancies.tsx (6)
apps/backend/src/prisma-client.tsx (4)
  • rawQuery (304-307)
  • globalPrismaClient (37-37)
  • RawQuery (230-234)
  • RawQuery (236-302)
packages/stack-shared/src/utils/errors.tsx (1)
  • StackAssertionError (69-85)
apps/backend/src/lib/projects.tsx (1)
  • getProjectQuery (41-69)
apps/backend/src/lib/config.tsx (1)
  • getRenderedOrganizationConfigQuery (51-56)
packages/stack-shared/src/utils/env.tsx (1)
  • getNodeEnvironment (65-67)
packages/stack-shared/src/utils/objects.tsx (1)
  • deepPlainEquals (29-65)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
  • GitHub Check: build (22.x)
  • GitHub Check: lint_and_build (latest)
  • GitHub Check: build (22.x)
  • GitHub Check: build (22.x)
  • GitHub Check: restart-dev-and-test
  • GitHub Check: restart-dev-and-test-with-custom-base-port
  • GitHub Check: check_prisma_migrations (22.x)
  • GitHub Check: docker
  • GitHub Check: all-good
  • GitHub Check: setup-tests
  • GitHub Check: Vercel Agent Review
  • GitHub Check: Security Check
🔇 Additional comments (7)
apps/backend/src/lib/tenancies.tsx (7)

1-8: LGTM: Imports support the new RawQuery migration.

All new imports are necessary and correctly sourced for the RawQuery-based tenancy retrieval and development-mode validation.


21-51: LGTM: Legacy implementation preserved for validation.

Keeping the old Prisma-based implementation as tenancyPrismaToCrudUnused for development-mode cross-validation is a solid migration safety pattern.


53-53: LGTM: Type definition ensures consistency.

Deriving the Tenancy type from the legacy implementation maintains type stability during the migration.


59-72: LGTM: Clean refactor to RawQuery.

The function now correctly delegates to getSoleTenancyFromProjectBranchQuery while preserving the existing overloads and error handling.


74-80: LGTM: Query helper correctly implemented.

The new getSoleTenancyFromProjectBranchQuery properly returns a RawQuery and delegates to getTenancyFromProjectQuery with the sole-tenancy assumption (null organizationId).


82-91: LGTM: Simplified to use unified tenancy retrieval.

Refactoring getTenancy to delegate to getTenancyFromProject eliminates duplication and ensures all tenancy retrieval flows through the new RawQuery path.


93-171: LGTM: Well-structured RawQuery implementation.

The new getTenancyFromProjectQuery effectively combines tenancy, project, and config fetching in a single query batch via RawQuery.all, improving performance. The SQL is properly parameterized, the validation logic for hasNoOrganization is correctly duplicated from the legacy path, and error handling is comprehensive.

Refactor to await tenancyResultPromise separately and check for null.
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: 0

🧹 Nitpick comments (2)
apps/backend/src/lib/tenancies.tsx (2)

78-80: Remove unused parameter or document its purpose.

The returnNullIfNotFound parameter is declared in the signature but never used in the function body. Since getTenancyFromProjectQuery always returns a nullable result, this parameter doesn't affect the query behavior and only serves as a type-level constraint.

Consider removing the parameter for clarity:

-export function getSoleTenancyFromProjectBranchQuery(project: Omit<ProjectsCrud["Admin"]["Read"], "config"> | string, branchId: string, returnNullIfNotFound: true): RawQuery<Promise<Tenancy | null>> {
+export function getSoleTenancyFromProjectBranchQuery(project: Omit<ProjectsCrud["Admin"]["Read"], "config"> | string, branchId: string): RawQuery<Promise<Tenancy | null>> {
   return getTenancyFromProjectQuery(typeof project === 'string' ? project : project.id, branchId, null);
 }

And update the caller on line 66:

-  const res = await rawQuery(globalPrismaClient, getSoleTenancyFromProjectBranchQuery(projectOrId, branchId, true));
+  const res = await rawQuery(globalPrismaClient, getSoleTenancyFromProjectBranchQuery(projectOrId, branchId));

187-187: Make environment check case-insensitive.

While the logic is now correct (single negation), the environment check should be case-insensitive for robustness, as NODE_ENV could theoretically be uppercase.

Apply this diff:

-  if (!getNodeEnvironment().includes("prod")) {
+  if (!getNodeEnvironment().toLowerCase().includes("prod")) {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e42b3b9 and f044989.

📒 Files selected for processing (1)
  • apps/backend/src/lib/tenancies.tsx (5 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
apps/backend/src/lib/tenancies.tsx (6)
apps/backend/src/prisma-client.tsx (4)
  • rawQuery (304-307)
  • globalPrismaClient (37-37)
  • RawQuery (230-234)
  • RawQuery (236-302)
packages/stack-shared/src/utils/errors.tsx (1)
  • StackAssertionError (69-85)
apps/backend/src/lib/projects.tsx (1)
  • getProjectQuery (41-69)
apps/backend/src/lib/config.tsx (1)
  • getRenderedOrganizationConfigQuery (51-56)
packages/stack-shared/src/utils/env.tsx (1)
  • getNodeEnvironment (65-67)
packages/stack-shared/src/utils/objects.tsx (1)
  • deepPlainEquals (29-65)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
  • GitHub Check: Vercel Agent Review
  • GitHub Check: build (22.x)
  • GitHub Check: setup-tests
  • GitHub Check: build (22.x)
  • GitHub Check: docker
  • GitHub Check: all-good
  • GitHub Check: restart-dev-and-test
  • GitHub Check: build (22.x)
  • GitHub Check: check_prisma_migrations (22.x)
  • GitHub Check: restart-dev-and-test-with-custom-base-port
  • GitHub Check: lint_and_build (latest)
  • GitHub Check: Security Check
🔇 Additional comments (6)
apps/backend/src/lib/tenancies.tsx (6)

1-8: LGTM!

The new imports correctly support the RawQuery-based implementation and development-mode validation logic.


21-51: LGTM!

The deprecated function is correctly preserved for development-mode validation. The validation logic duplication with the new implementation (lines 147-159) is intentional to ensure correctness of the migration.


93-173: LGTM!

The new RawQuery-based implementation correctly:

  • Combines tenancy, project, and config queries efficiently using RawQuery.all
  • Handles the two organizationId cases (null vs non-null) with appropriate SQL
  • Validates cardinality and data consistency
  • Returns early when no tenancy is found

188-217: LGTM! Development-mode validation is thorough.

The cross-check between old and new implementations provides strong confidence in the migration. The strict deepPlainEquals comparison (without ignoreUndefinedValues) will catch any structural differences.

Note: This validation doubles database queries in development environments. Once confidence is established, consider removing or feature-flagging this check to improve development performance.


82-91: LGTM!

The function correctly delegates to the updated getTenancyFromProject, maintaining the public API while benefiting from the new RawQuery-based implementation.


65-72: LGTM!

The function correctly uses the new RawQuery-based getSoleTenancyFromProjectBranchQuery while maintaining the same public behavior and error handling.

@N2D4
Copy link
Contributor Author

N2D4 commented Nov 4, 2025

@claude fix this

FAIL |@stackframe/e2e-tests| tests/backend/endpoints/api/v1/auth/oauth/authorize.test.ts > should not redirect the user to the OAuth provider with the right arguments when forcing a branch id that does not exist
StackAssertionError: API threw ISE in GET /api/v1/auth/oauth/authorize/spotify: 500 Internal Server Error. The error message follows, but will be stripped in production. StackAssertionError: Not implemented
Stack:
This is likely an error in Stack. Please make sure you are running the newest version and report it.
at getBranchConfigOverrideQuery (/home/runner/work/stack-auth/stack-auth/apps/backend/.next/server/chunks/323.js:1228:15)
at getIncompleteBranchConfigQuery (/home/runner/work/stack-auth/stack-auth/apps/backend/.next/server/chunks/323.js:1362:19)
at getIncompleteEnvironmentConfigQuery (/home/runner/work/stack-auth/stack-auth/apps/backend/.next/server/chunks/323.js:1369:19)
at getIncompleteOrganizationConfigQuery (/home/runner/work/stack-auth/stack-auth/apps/backend/.next/server/chunks/323.js:1377:19)
at getRenderedOrganizationConfigQuery (/home/runner/work/stack-auth/stack-auth/apps/backend/.next/server/chunks/323.js:1165:80)
at getTenancyFromProjectQuery (/home/runner/work/stack-auth/stack-auth/apps/backend/.next/server/chunks/323.js:2644:94)
at getSoleTenancyFromProjectBranchQuery (/home/runner/work/stack-auth/stack-auth/apps/backend/.next/server/chunks/323.js:2598:12)
at getSoleTenancyFromProjectBranch (/home/runner/work/stack-auth/stack-auth/apps/backend/.next/server/chunks/323.js:2585:164)
at Object.handler (/home/runner/work/stack-auth/stack-auth/apps/backend/.next/server/app/api/latest/auth/oauth/authorize/[provider_id]/route.js:273:120)
at /home/runner/work/stack-auth/stack-auth/apps/backend/.next/server/chunks/963.js:3935:34
Extra properties: { "extraData": undefined }

This is likely an error in Stack. Please make sure you are running the newest version and report it.
❯ getBranchConfigOverrideQuery ../backend/.next/server/chunks/323.js:1228:15
❯ getIncompleteBranchConfigQuery ../backend/.next/server/chunks/323.js:1362:19
❯ getIncompleteEnvironmentConfigQuery ../backend/.next/server/chunks/323.js:1369:19
❯ getIncompleteOrganizationConfigQuery ../backend/.next/server/chunks/323.js:1377:19
❯ getRenderedOrganizationConfigQuery ../backend/.next/server/chunks/323.js:1165:80
❯ getTenancyFromProjectQuery ../backend/.next/server/chunks/323.js:2644:94
❯ getSoleTenancyFromProjectBranchQuery ../backend/.next/server/chunks/323.js:2598:12
❯ getSoleTenancyFromProjectBranch ../backend/.next/server/chunks/323.js:2585:164
❯ Object.handler ../backend/.next/server/app/api/latest/auth/oauth/authorize/[provider_id]/route.js:273:120
❯ ../backend/.next/server/chunks/963.js:3935:34
❯ Module.niceBackendFetch tests/backend/backend-helpers.ts:159:11

@claude
Copy link
Contributor

claude bot commented Nov 4, 2025

Claude finished @N2D4's task —— View job


I'll analyze this and get back to you.

@N2D4
Copy link
Contributor Author

N2D4 commented Nov 4, 2025

@claude fix this

FAIL |@stackframe/e2e-tests| tests/backend/endpoints/api/v1/auth/oauth/authorize.test.ts > should not redirect the user to the OAuth provider with the right arguments when forcing a branch id that does not exist
StackAssertionError: API threw ISE in GET /api/v1/auth/oauth/authorize/spotify: 500 Internal Server Error. The error message follows, but will be stripped in production. StackAssertionError: Not implemented
Stack:
This is likely an error in Stack. Please make sure you are running the newest version and report it.
at getBranchConfigOverrideQuery (/home/runner/work/stack-auth/stack-auth/apps/backend/.next/server/chunks/323.js:1228:15)
at getIncompleteBranchConfigQuery (/home/runner/work/stack-auth/stack-auth/apps/backend/.next/server/chunks/323.js:1362:19)
at getIncompleteEnvironmentConfigQuery (/home/runner/work/stack-auth/stack-auth/apps/backend/.next/server/chunks/323.js:1369:19)
at getIncompleteOrganizationConfigQuery (/home/runner/work/stack-auth/stack-auth/apps/backend/.next/server/chunks/323.js:1377:19)
at getRenderedOrganizationConfigQuery (/home/runner/work/stack-auth/stack-auth/apps/backend/.next/server/chunks/323.js:1165:80)
at getTenancyFromProjectQuery (/home/runner/work/stack-auth/stack-auth/apps/backend/.next/server/chunks/323.js:2644:94)
at getSoleTenancyFromProjectBranchQuery (/home/runner/work/stack-auth/stack-auth/apps/backend/.next/server/chunks/323.js:2598:12)
at getSoleTenancyFromProjectBranch (/home/runner/work/stack-auth/stack-auth/apps/backend/.next/server/chunks/323.js:2585:164)
at Object.handler (/home/runner/work/stack-auth/stack-auth/apps/backend/.next/server/app/api/latest/auth/oauth/authorize/[provider_id]/route.js:273:120)
at /home/runner/work/stack-auth/stack-auth/apps/backend/.next/server/chunks/963.js:3935:34
Extra properties: { "extraData": undefined }

This is likely an error in Stack. Please make sure you are running the newest version and report it.
❯ getBranchConfigOverrideQuery ../backend/.next/server/chunks/323.js:1228:15
❯ getIncompleteBranchConfigQuery ../backend/.next/server/chunks/323.js:1362:19
❯ getIncompleteEnvironmentConfigQuery ../backend/.next/server/chunks/323.js:1369:19
❯ getIncompleteOrganizationConfigQuery ../backend/.next/server/chunks/323.js:1377:19
❯ getRenderedOrganizationConfigQuery ../backend/.next/server/chunks/323.js:1165:80
❯ getTenancyFromProjectQuery ../backend/.next/server/chunks/323.js:2644:94
❯ getSoleTenancyFromProjectBranchQuery ../backend/.next/server/chunks/323.js:2598:12
❯ getSoleTenancyFromProjectBranch ../backend/.next/server/chunks/323.js:2585:164
❯ Object.handler ../backend/.next/server/app/api/latest/auth/oauth/authorize/[provider_id]/route.js:273:120
❯ ../backend/.next/server/chunks/963.js:3935:34
❯ Module.niceBackendFetch tests/backend/backend-helpers.ts:159:11

fix it in tenancies.tsx

@claude
Copy link
Contributor

claude bot commented Nov 4, 2025

Claude finished @N2D4's task —— View job


I'll analyze this and get back to you.

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: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f044989 and 05508b3.

📒 Files selected for processing (6)
  • apps/backend/src/lib/config.tsx (1 hunks)
  • apps/backend/src/lib/tenancies.tsx (5 hunks)
  • apps/backend/src/route-handlers/smart-request.tsx (3 hunks)
  • apps/e2e/tests/backend/backend-helpers.ts (1 hunks)
  • apps/e2e/tests/backend/endpoints/api/v1/index.test.ts (1 hunks)
  • apps/e2e/tests/backend/endpoints/api/v1/projects.test.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (5)
apps/e2e/tests/backend/endpoints/api/v1/projects.test.ts (1)
apps/e2e/tests/helpers.ts (1)
  • it (12-12)
apps/backend/src/route-handlers/smart-request.tsx (4)
apps/backend/src/lib/tenancies.tsx (1)
  • getSoleTenancyFromProjectBranchQuery (78-80)
apps/backend/src/lib/config.tsx (1)
  • getRenderedEnvironmentConfigQuery (44-49)
apps/backend/src/prisma-client.tsx (2)
  • rawQueryAll (309-313)
  • globalPrismaClient (37-37)
apps/backend/src/app/api/latest/users/crud.tsx (1)
  • getUser (391-408)
apps/e2e/tests/backend/endpoints/api/v1/index.test.ts (2)
apps/e2e/tests/backend/backend-helpers.ts (3)
  • backendContext (35-57)
  • niceBackendFetch (109-173)
  • InternalProjectKeys (77-82)
apps/e2e/tests/helpers.ts (1)
  • it (12-12)
apps/backend/src/lib/tenancies.tsx (6)
apps/backend/src/prisma-client.tsx (4)
  • rawQuery (304-307)
  • globalPrismaClient (37-37)
  • RawQuery (230-234)
  • RawQuery (236-302)
packages/stack-shared/src/utils/errors.tsx (1)
  • StackAssertionError (69-85)
apps/backend/src/lib/projects.tsx (1)
  • getProjectQuery (41-69)
apps/backend/src/lib/config.tsx (1)
  • getRenderedOrganizationConfigQuery (51-56)
packages/stack-shared/src/utils/env.tsx (1)
  • getNodeEnvironment (65-67)
packages/stack-shared/src/utils/objects.tsx (1)
  • deepPlainEquals (29-65)
apps/backend/src/lib/config.tsx (4)
packages/stack-shared/src/config/schema.ts (2)
  • migrateConfigOverride (271-347)
  • BranchConfigOverride (1025-1025)
apps/backend/src/prisma-client.tsx (2)
  • RawQuery (230-234)
  • RawQuery (236-302)
apps/backend/src/lib/tenancies.tsx (1)
  • DEFAULT_BRANCH_ID (19-19)
packages/stack-shared/src/utils/errors.tsx (1)
  • StackAssertionError (69-85)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
  • GitHub Check: Vercel Agent Review
  • GitHub Check: all-good
  • GitHub Check: build (22.x)
  • GitHub Check: restart-dev-and-test-with-custom-base-port
  • GitHub Check: check_prisma_migrations (22.x)
  • GitHub Check: build (22.x)
  • GitHub Check: docker
  • GitHub Check: lint_and_build (latest)
  • GitHub Check: restart-dev-and-test
  • GitHub Check: build (22.x)
  • GitHub Check: setup-tests
  • GitHub Check: Security Check

Comment on lines +146 to +148
if (options.branchId !== DEFAULT_BRANCH_ID) {
throw new StackAssertionError('getBranchConfigOverrideQuery is not implemented for branches other than the default one');
}
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 | 🔴 Critical

Invalid branch still returns 500

This guard still throws a StackAssertionError whenever branchId !== DEFAULT_BRANCH_ID, so the bundled environmentRenderedConfig query in parseAuth explodes before the tenancy lookup can emit KnownErrors.BranchDoesNotExist. Repro: send any request with x-stack-project-id set to a real project and x-stack-branch-id: invalid-branch; you still get the old “Not implemented” 500 from here, so the new e2e test will keep failing. Please drop the throw (return the empty override instead) so the tenancy logic can surface the intended 400.

-      if (options.branchId !== DEFAULT_BRANCH_ID) {
-        throw new StackAssertionError('getBranchConfigOverrideQuery is not implemented for branches other than the default one');
-      }
       return migrateConfigOverride("branch", {});
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (options.branchId !== DEFAULT_BRANCH_ID) {
throw new StackAssertionError('getBranchConfigOverrideQuery is not implemented for branches other than the default one');
}
return migrateConfigOverride("branch", {});
🤖 Prompt for AI Agents
In apps/backend/src/lib/config.tsx around lines 146 to 148, the guard currently
throws a StackAssertionError when options.branchId !== DEFAULT_BRANCH_ID which
causes a 500 instead of allowing tenancy lookup to surface
KnownErrors.BranchDoesNotExist; remove the throw and return an empty override
(e.g., an empty config override object) in that branch so the function succeeds
and downstream tenancy logic can emit the intended 400.

@N2D4 N2D4 closed this Nov 5, 2025
@N2D4 N2D4 reopened this Nov 5, 2025
@N2D4 N2D4 merged commit fbf36d1 into dev Nov 5, 2025
31 of 34 checks passed
@N2D4 N2D4 deleted the faster-users-endpoint branch November 5, 2025 17:15
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Greptile Overview

Greptile Summary

Performance optimization that reduces database roundtrips for user endpoints by resolving tenancy earlier and bundling queries.

Key Changes:

  • Refactored getTenancyFromProject to use RawQuery for query composition and parallel execution
  • Moved tenancy resolution into bundled queries in smart-request.tsx, fetching project, tenancy, config, and user data in parallel instead of sequentially
  • Updated getUser to accept tenancy directly, eliminating redundant config lookups by reusing already-fetched data
  • Changed config lookup from environment-level to project-level for sourceOfTruth field, which is valid since sourceOfTruth is defined at project level
  • Added development-mode validation that compares new RawQuery implementation against old Prisma implementation to ensure correctness
  • Improved error handling for missing project configs to gracefully handle null results
  • Added E2E tests for invalid project IDs and branch IDs

Confidence Score: 4/5

  • Safe to merge with one minor logic issue already flagged in previous comments
  • The refactoring is well-structured with strong validation in development mode. The bundled query approach is sound, and the change from environment to project config for sourceOfTruth is valid. However, there's one logic issue (inverted condition on line 187) that was already caught in previous review.
  • Pay attention to apps/backend/src/lib/tenancies.tsx:187 - the validation condition logic was flagged in previous comments

Important Files Changed

File Analysis

Filename Score Overview
apps/backend/src/lib/tenancies.tsx 4/5 Refactored tenancy queries to use RawQuery for better performance, with development-mode validation comparing old and new implementations
apps/backend/src/route-handlers/smart-request.tsx 5/5 Moved tenancy resolution to bundled queries for parallel execution, improving request handling performance
apps/backend/src/app/api/latest/users/crud.tsx 5/5 Changed getUser to accept tenancy directly, avoiding unnecessary database lookups by using config from already-fetched tenancy
apps/backend/src/lib/config.tsx 5/5 Improved error handling for missing project configs and moved branch validation check to postProcess function

Sequence Diagram

sequenceDiagram
    participant Client
    participant SmartRequest as SmartRequest Handler
    participant RawQueryAll
    participant DB as Global DB
    participant TenancyQuery as Tenancy Query
    participant ProjectQuery as Project Query
    participant ConfigQuery as Config Query
    participant UserQuery as User Query (optimistic)
    participant SourceOfTruthDB as Source-of-Truth DB

    Client->>SmartRequest: HTTP Request (users/[user_id])
    
    Note over SmartRequest: OLD: Sequential fetching<br/>project → tenancy → config → user
    Note over SmartRequest: NEW: Parallel fetching with bundled queries
    
    SmartRequest->>RawQueryAll: Bundle queries in parallel
    
    par Parallel Query Execution
        RawQueryAll->>ProjectQuery: getProjectQuery(projectId)
        ProjectQuery->>DB: SELECT Project
        DB-->>ProjectQuery: Project data
        
        RawQueryAll->>TenancyQuery: getSoleTenancyFromProjectBranchQuery()
        TenancyQuery->>DB: SELECT Tenancy + Project + Config
        DB-->>TenancyQuery: Tenancy with config
        
        RawQueryAll->>ConfigQuery: getRenderedEnvironmentConfigQuery()
        ConfigQuery->>DB: SELECT Config overrides
        DB-->>ConfigQuery: Rendered config
        
        RawQueryAll->>UserQuery: getUserIfOnGlobalPrismaClient()
        UserQuery->>DB: SELECT User (optimistic)
        DB-->>UserQuery: User data or null
    end
    
    RawQueryAll-->>SmartRequest: All query results
    
    Note over SmartRequest: Validate project & tenancy exist
    
    alt Source of Truth is Hosted (Global DB)
        SmartRequest->>SmartRequest: Use optimistically fetched user
    else Source of Truth is External
        SmartRequest->>SourceOfTruthDB: getUser(projectId, branchId)
        SourceOfTruthDB-->>SmartRequest: User from external DB
    end
    
    SmartRequest->>Client: Response with user data
    
    Note over SmartRequest,Client: Performance improvement: 1 roundtrip instead of multiple sequential queries
Loading

7 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

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