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

Skip to content

Conversation

myftija
Copy link
Member

@myftija myftija commented Sep 17, 2025

Adjusts the authentication in a couple of endpoints to accept OATs too.

Adjusts the authentication in a couple of endpoints to accept OATs too.
Copy link

changeset-bot bot commented Sep 17, 2025

⚠️ No Changeset found

Latest commit: cd93947

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link
Contributor

coderabbitai bot commented Sep 17, 2025

Walkthrough

This change standardizes identity handling for branch operations by replacing raw userId parameters with a discriminated union context ({ type: "userMembership"; userId } | { type: "orgId"; organizationId }). Services updated: UpsertBranchService and ArchiveBranchService. Call sites updated in four routes to pass the new context and, where applicable, switch to authenticateRequest supporting personal and organization tokens. Prisma queries in services now branch on context type to authorize by membership or organizationId. Public method signatures in both services changed accordingly; surrounding control flow and payload structures remain the same.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The PR description is too brief and does not follow the repository template: it lacks the required "Closes #" line, the ✅ Checklist, a Testing section with steps/results, a Changelog entry, and any screenshots or request/response examples, leaving reviewers without required context or verification instructions. Please update the PR to use the repository template: add "Closes #" if applicable and complete the ✅ Checklist items. Add a "Testing" section that lists exact manual or automated steps you ran and their results, and include a short "Changelog" summary describing the behavioral change and which endpoints were affected. Attach screenshots or request/response snippets if helpful and confirm that local/CI tests were run and passed.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Title Check ✅ Passed The title succinctly and accurately summarizes the primary change: enabling OAT (organization access token) support for preview-branch-related API endpoints. It follows the repo's "feat(scope): ..." convention and aligns with the authentication and service-signature changes shown in the diff.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch accept-oats-branch-endpoints

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.


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.

@myftija myftija merged commit 691903c into main Sep 17, 2025
30 of 31 checks passed
@myftija myftija deleted the accept-oats-branch-endpoints branch September 17, 2025 12:10
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 (9)
apps/webapp/app/services/archiveBranch.server.ts (2)

13-26: Consolidate the identity type (OrgFilter) in a shared module.

The discriminated union is duplicated across services. Export a single OrgFilter type (e.g., app/services/authz.ts) to prevent drift and ease future changes.


28-41: Push the “must be a branch” check into the query (optional).

Adding parentEnvironmentId: { not: null } to the where clause avoids fetching non-branch envs only to reject them later.

Apply this diff:

       const environment = await this.#prismaClient.runtimeEnvironment.findFirstOrThrow({
         where: {
           id: environmentId,
+          parentEnvironmentId: { not: null },
           organization:
             orgFilter.type === "userMembership"
               ? {
                   members: {
                     some: {
                       userId: orgFilter.userId,
                     },
                   },
                 }
               : { id: orgFilter.organizationId },
         },
apps/webapp/app/services/upsertBranch.server.ts (3)

17-26: Unify OrgFilter type and decouple from route schema.

  • Export a shared OrgFilter type to avoid duplication with ArchiveBranchService.
  • Avoid importing CreateBranchOptions from a route; define a local/service‑level type or move the schema to a shared module to fix dependency direction.

151-156: Fix logger message to reflect the service name.

Rename the log label for clarity.

Apply this diff:

-      logger.error("CreateBranchService error", { error: e });
+      logger.error("UpsertBranchService error", { error: e });

167-179: Use COUNT instead of fetching rows for limits (optional).

Replace findMany + length with count queries to reduce I/O for large projects.

Apply this diff:

-  const usedEnvs = await prisma.runtimeEnvironment.findMany({
-    where: {
-      projectId,
-      branchName: {
-        not: null,
-      },
-      archivedAt: null,
-    },
-  });
-
-  const count = newBranchName
-    ? usedEnvs.filter((env) => env.branchName !== newBranchName).length
-    : usedEnvs.length;
+  const totalCount = await prisma.runtimeEnvironment.count({
+    where: { projectId, branchName: { not: null }, archivedAt: null },
+  });
+  const existingWithSameName = newBranchName
+    ? await prisma.runtimeEnvironment.count({
+        where: { projectId, branchName: newBranchName, archivedAt: null },
+      })
+    : 0;
+  const count = totalCount - existingWithSameName;
apps/webapp/app/routes/api.v1.projects.$projectRef.branches.archive.ts (1)

52-73: Minor perf tidy: filter archived in SQL and use findFirst (optional).

You can avoid fetching multiple rows and in‑memory filtering by adding archivedAt: null and switching to findFirst. If you still need the “already archived” distinction, fall back to a second quick existence check when no active env is found.

apps/webapp/app/routes/api.v1.projects.$projectRef.branches.ts (3)

5-5: Consider unifying loader auth to authenticateRequest as well

Action now accepts org tokens; loader still uses PAT-only. If OATs should work for GET too, switch loader to authenticateRequest for consistency.

Is the intent to allow OATs on the GET endpoint as well?


46-56: Tighten Prisma filter: prefer scalar key for org path; use explicit relation filter for membership

For clarity and query planning, filter by organizationId when you already have it, and use an explicit relation filter for the membership branch.

Apply this diff:

-      organization:
-        authenticationResult.type === "organizationAccessToken"
-          ? { id: authenticationResult.result.organizationId }
-          : {
-              members: {
-                some: {
-                  userId: authenticationResult.result.userId,
-                },
-              },
-            },
+      ...(authenticationResult.type === "organizationAccessToken"
+        ? { organizationId: authenticationResult.result.organizationId }
+        : {
+            organization: {
+              members: {
+                some: { userId: authenticationResult.result.userId },
+              },
+            },
+          }),

Note: If you prefer relation filters everywhere, use organization: { is: { id: ... } } explicitly for the org branch.


92-101: Service identity handoff looks correct; drop unused env var above

Passing { type: "orgId" | "userMembership", ... } matches the new service signature. The destructured env from Line 89 is unused; remove to satisfy noUnusedLocals.

Example:

// Line 89
const { branch, git } = parsed.data;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 885ae5e and cd93947.

📒 Files selected for processing (6)
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.branches/route.tsx (1 hunks)
  • apps/webapp/app/routes/api.v1.projects.$projectRef.branches.archive.ts (4 hunks)
  • apps/webapp/app/routes/api.v1.projects.$projectRef.branches.ts (4 hunks)
  • apps/webapp/app/routes/resources.branches.archive.tsx (1 hunks)
  • apps/webapp/app/services/archiveBranch.server.ts (1 hunks)
  • apps/webapp/app/services/upsertBranch.server.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Always prefer using isomorphic code like fetch, ReadableStream, etc. instead of Node.js specific code
For TypeScript, we usually use types over interfaces
Avoid enums
No default exports, use function declarations

Files:

  • apps/webapp/app/routes/resources.branches.archive.tsx
  • apps/webapp/app/services/archiveBranch.server.ts
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.branches/route.tsx
  • apps/webapp/app/routes/api.v1.projects.$projectRef.branches.ts
  • apps/webapp/app/routes/api.v1.projects.$projectRef.branches.archive.ts
  • apps/webapp/app/services/upsertBranch.server.ts
{packages/core,apps/webapp}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

We use zod a lot in packages/core and in the webapp

Files:

  • apps/webapp/app/routes/resources.branches.archive.tsx
  • apps/webapp/app/services/archiveBranch.server.ts
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.branches/route.tsx
  • apps/webapp/app/routes/api.v1.projects.$projectRef.branches.ts
  • apps/webapp/app/routes/api.v1.projects.$projectRef.branches.archive.ts
  • apps/webapp/app/services/upsertBranch.server.ts
apps/webapp/**/*.{ts,tsx}

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

When importing from @trigger.dev/core in the webapp, never import the root package path; always use one of the documented subpath exports from @trigger.dev/core’s package.json

Files:

  • apps/webapp/app/routes/resources.branches.archive.tsx
  • apps/webapp/app/services/archiveBranch.server.ts
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.branches/route.tsx
  • apps/webapp/app/routes/api.v1.projects.$projectRef.branches.ts
  • apps/webapp/app/routes/api.v1.projects.$projectRef.branches.archive.ts
  • apps/webapp/app/services/upsertBranch.server.ts
{apps/webapp/app/**/*.server.{ts,tsx},apps/webapp/app/routes/**/*.ts}

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

Access environment variables only via the env export from app/env.server.ts; do not reference process.env directly

Files:

  • apps/webapp/app/services/archiveBranch.server.ts
  • apps/webapp/app/routes/api.v1.projects.$projectRef.branches.ts
  • apps/webapp/app/routes/api.v1.projects.$projectRef.branches.archive.ts
  • apps/webapp/app/services/upsertBranch.server.ts
apps/webapp/app/**/*.ts

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

Modules intended for test consumption under apps/webapp/app/**/*.ts must not read environment variables; accept configuration via options instead

Files:

  • apps/webapp/app/services/archiveBranch.server.ts
  • apps/webapp/app/routes/api.v1.projects.$projectRef.branches.ts
  • apps/webapp/app/routes/api.v1.projects.$projectRef.branches.archive.ts
  • apps/webapp/app/services/upsertBranch.server.ts
🧬 Code graph analysis (3)
apps/webapp/app/routes/api.v1.projects.$projectRef.branches.ts (1)
apps/webapp/app/services/apiAuth.server.ts (1)
  • authenticateRequest (379-441)
apps/webapp/app/routes/api.v1.projects.$projectRef.branches.archive.ts (1)
apps/webapp/app/services/apiAuth.server.ts (1)
  • authenticateRequest (379-441)
apps/webapp/app/services/upsertBranch.server.ts (1)
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.branches/route.tsx (2)
  • CreateBranchOptions (108-112)
  • CreateBranchOptions (114-114)
⏰ 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). (22)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (6, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (8, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
  • GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - npm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
  • GitHub Check: typecheck / typecheck
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (8)
apps/webapp/app/services/upsertBranch.server.ts (1)

46-56: LGTM: authorization filter matches token context.

Conditional organization filter via membership vs orgId is correct and consistent with archive flow.

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.branches/route.tsx (1)

132-136: LGTM: updated call signature is correct.

Route now passes the identity descriptor and payload as separate args, aligned with the service change.

apps/webapp/app/routes/api.v1.projects.$projectRef.branches.archive.ts (3)

24-29: Auth path updated to allow OATs — good.

authenticateRequest with personalAccessToken + organizationAccessToken (apiKey disabled) aligns with the PR goal.


58-67: DB filtering matches auth context — good.

Org membership vs orgId branching is correct.


85-92: LGTM: service call uses the correct identity descriptor.

Organization tokens map to { type: "orgId" } and PATs to { type: "userMembership" } as expected.

apps/webapp/app/routes/resources.branches.archive.tsx (1)

40-45: LGTM for this file — identity descriptor passed correctly; repo still contains legacy single-object .call(...) sites.

ArchiveBranchService calls in this PR use the identity descriptor correctly.

Examples of remaining single-object .call({...}) usages found:

  • apps/webapp/app/routes/api.v1.projects.$projectRef.branches.archive.ts:85-86
  • apps/webapp/app/services/projectSettings.server.ts:36
  • apps/webapp/app/services/deleteOrganization.server.ts:72
  • apps/webapp/app/v3/services/createCheckpoint.server.ts:320

Confirm whether those sites should be migrated to the (identityDescriptor, payload) signature.

apps/webapp/app/routes/api.v1.projects.$projectRef.branches.ts (2)

1-1: Type-only imports: good change

Using type-only imports reduces runtime bundle size and matches our TS guidelines.


23-27: OATs are handled as organizationAccessToken in authenticateRequest — no action required.
authenticateRequest checks allowedMethods.organizationAccessToken and calls authenticateApiRequestWithOrganizationAccessToken; organizationAccessToken.server.ts uses the "tr_oat_" prefix and isOrganizationAccessToken(token) checks startsWith(tokenPrefix).

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