Skip to content

fix(search-contexts): Fix issue where a repository would not appear in a search context if it was created after the search context was created #354

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

Merged
merged 11 commits into from
Jun 17, 2025

Conversation

brendan-kellam
Copy link
Contributor

@brendan-kellam brendan-kellam commented Jun 16, 2025

Problem

If a repository is added after a search context (e.g., a new repository is synced from the code host), then it will never be added to the context even if it should be included. The workaround is to restart the instance.

Solution

This PR adds a call to re-sync all search contexts whenever a connection is successfully synced. This PR adds the @sourcebot/shared package that contains syncSearchContexts.ts (previously in web) and it's dependencies (namely the entitlements system).

Why another package?

Because the syncSearchContexts call is now called from:

  1. initialize.ts in web - handles syncing search contexts on startup and whenever the config is modified in watch mode. This is the same as before.
  2. connectionManager.ts in backend - syncs the search contexts whenever a connection is successfully synced.

Follow-up devex work

Two things:

  1. We have several very thin shared packages (i.e., crypto, error, and logger) that we can probably fold into this "general" shared package. schemas and db feels like they should remain separate (mostly because they are "code-gen" packages).
  2. When running yarn dev, any changes made to the shared package will only get picked if you ctrl+c and restart the instance. Would be nice if we have watch mode work across package dependencies in the monorepo.

Summary by CodeRabbit

  • New Features

    • Introduced a shared package (@sourcebot/shared) providing centralized constants, environment configuration, entitlement utilities, and configuration loading for both backend and frontend.
    • Added new utility functions for Base64 decoding, remote path detection, and configuration validation.
  • Refactor

    • Migrated entitlements logic, plan definitions, and related utilities from local modules in web and backend packages to the shared package.
    • Updated imports throughout the codebase to use the new shared package for entitlements, constants, and configuration utilities.
    • Refactored configuration loading and validation in both backend and web to use the shared utility.
    • Enhanced synchronization of search contexts with organization-specific context and database parameters.
  • Chores

    • Updated Dockerfile and Makefile to include and clean shared package dependencies and build artifacts.
    • Added and updated package metadata and TypeScript configuration for the shared package.
    • Updated license to cover new shared directories.
  • Bug Fixes

    • Improved reliability and consistency of entitlement checks and configuration loading by centralizing logic.
    • Fixed issue where repositories created after a search context were not included in that context.
  • Style

    • Minor changes such as adding trailing newlines and updating logger labels for clarity.
  • Revert

    • Removed redundant or now-centralized local entitlements and constants files.

@brendan-kellam brendan-kellam requested a review from msukkari June 16, 2025 22:08
Copy link

coderabbitai bot commented Jun 16, 2025

Walkthrough

A new shared package (@sourcebot/shared) was introduced to centralize constants, utility functions, entitlement logic, and configuration loading across backend and web packages. Existing code was refactored to use these shared utilities, removing local implementations. The Dockerfile and Makefile were updated to support the new package. Entitlement and configuration logic was unified, and import paths were updated accordingly.

Changes

File(s) Change Summary
Dockerfile, Makefile Updated build and clean steps to include packages/shared.
LICENSE Added "packages/shared/src/ee/" to special license directory list.
packages/shared/… (all new files: package.json, tsconfig.json, .gitignore, src/*) Introduced new shared package with constants, entitlement logic, config/environment utilities, and search context sync.
packages/backend/package.json, packages/web/package.json Added @sourcebot/shared as a dependency.
packages/backend/src/connectionManager.ts Enhanced onSyncJobCompleted to load config and trigger search context sync using shared utilities.
packages/backend/src/main.ts, packages/web/src/initialize.ts Refactored config loading to use shared loadConfig.
packages/backend/src/utils.ts Removed isRemotePath (now in shared).
packages/backend/src/constants.ts, packages/backend/src/index.ts Added trailing newlines; minor logger label rename.
packages/web/src/actions.ts, .../layout.tsx, .../license/page.tsx, .../members/page.tsx, .../layout.tsx, .../auth.ts, .../stripe.ts, .../publicAccess/publicAccess.tsx, .../sso/sso.tsx, .../planProvider.tsx, .../useHasEntitlement.ts, .../lib/authUtils.ts, .../lib/constants.ts, .../env.mjs Changed imports for entitlements, constants, and config/environment to use @sourcebot/shared.
packages/web/src/features/entitlements/constants.ts Removed local entitlement and plan constants/types (now in shared).
packages/shared/src/ee/syncSearchContexts.ts Refactored to accept parameter object, dynamic org ID, and injected DB client.
packages/shared/src/entitlements.ts Centralized entitlement types, constants, and logic; refactored license key decoding.
packages/shared/src/utils.ts Added shared utilities: Base64 decode, remote path check, and config loader with schema validation.
packages/shared/src/env.ts Added shared environment variable schema using @t3-oss/env-core.

Sequence Diagram(s)

sequenceDiagram
    participant Backend
    participant Shared
    participant DB
    participant ConfigSource

    Backend->>Shared: loadConfig(configPath)
    alt Remote config
        Shared->>ConfigSource: fetch(configPath)
        ConfigSource-->>Shared: config JSON
    else Local config
        Shared->>ConfigSource: readFile(configPath)
        ConfigSource-->>Shared: config JSON
    end
    Shared->>Shared: strip comments, validate schema
    Shared-->>Backend: parsed config

    Backend->>Shared: syncSearchContexts({contexts, orgId, db})
    Shared->>DB: fetch repos, upsert/delete contexts
    DB-->>Shared: result
    Shared-->>Backend: true/false
Loading

Possibly related PRs

  • sourcebot-dev/sourcebot#273: The main PR introduces a shared package and refactors search context synchronization to be multi-tenant aware and reusable, while the retrieved PR Search contexts #273 implements the initial single-tenant search contexts feature including schema, database models, and synchronization logic; thus, the main PR builds upon and extends the foundational search contexts functionality introduced in the retrieved PR, making their changes directly related at the code level.
  • sourcebot-dev/sourcebot#319: Both PRs refactor entitlement constants and logic into a shared package, updating imports and usage accordingly.
  • sourcebot-dev/sourcebot#305: Related to connection sync logic and triggering search context synchronization, overlapping with enhancements in this PR.

Suggested reviewers

  • msukkari

Poem

In shared fields where code bunnies play,
Utilities and constants now hop the same way.
Entitlements unified, configs in one nest,
The backend and web teams can finally rest.
With one shared burrow for all to use,
This rabbit says, “No more code reuse blues!”
🐇✨


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 04daa01 and c423be7.

📒 Files selected for processing (1)
  • packages/shared/src/env.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/shared/src/env.ts
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: build
  • GitHub Check: build
  • GitHub Check: build
✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@brendan-kellam brendan-kellam marked this pull request as ready for review June 16, 2025 23:28
Copy link

@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: 4

🔭 Outside diff range comments (3)
packages/backend/src/main.ts (1)

14-25: Runtime crash when settings field is absent

loadConfig() may return a config without a settings key. Spreading undefined causes TypeError: Cannot convert undefined or null to object.

-    const config = await loadConfig(configPath);
-
-    return {
-        ...DEFAULT_SETTINGS,
-        ...config.settings,
-    }
+    const config = await loadConfig(configPath);
+
+    return {
+        ...DEFAULT_SETTINGS,
+        ...(config.settings ?? {}),
+    };

Add the null-coalescing guard (or default settings inside loadConfig) to prevent crashes on startup.

packages/shared/src/ee/syncSearchContexts.ts (1)

27-38: Repeated findMany is O(C×R) – fetch repos once per call

allRepos is queried inside the for … of Object.entries(contexts) loop, so the same repo set is fetched once for every context.
For orgs with many contexts this leads to needless DB round-trips.

-        for (const [key, newContextConfig] of Object.entries(contexts)) {
-            const allRepos = await db.repo.findMany({ where: { orgId }, … });
+        const allRepos = await db.repo.findMany({ where: { orgId }, … });
+
+        for (const [key, newContextConfig] of Object.entries(contexts)) {

Caching the result outside the loop drops the complexity to one query per org, greatly reducing latency.

packages/web/src/initialize.ts (1)

198-203: Un-awaited promise inside fs.watch callback – errors lost

syncDeclarativeConfig returns a promise, but the callback neither awaits nor .catches it.
An exception will be unhandled and silently dropped by Node.

-watch(configPath, () => {
-    logger.info(`Config file ${configPath} changed. Re-syncing...`);
-    syncDeclarativeConfig(configPath);
-});
+watch(configPath, async () => {
+    logger.info(`Config file ${configPath} changed. Re-syncing...`);
+    try {
+        await syncDeclarativeConfig(configPath);
+    } catch (err) {
+        logger.error('Re-sync failed', err);
+    }
+});
♻️ Duplicate comments (1)
packages/shared/src/entitlements.ts (1)

53-67: Signature verification depends on base64Decode fix

decodeLicenseKeyPayload uses base64Decode, which will fail under Node due to the atob call (see utils.ts).
Once the utility is patched, license verification will work consistently in all runtimes.

🧹 Nitpick comments (8)
packages/shared/src/constants.ts (1)

11-11: Confirm special seats flag.
SOURCEBOT_UNLIMITED_SEATS = -1 is clear, but consider documenting its semantics via a JSDoc comment for future maintainers.

packages/shared/src/index.client.ts (1)

2-2: Drop the explicit “.js” extension for better compatibility with TS/ESM setups

If moduleResolution is node/bundler and the compiler later rewrites this to .js, the runtime import will still resolve.
Leaving the extension off ("./constants") avoids edge-cases when tools rewrite extensions (.ts → .js, .js → .cjs, etc.) and makes the statement work in both build and test environments.

-export * from "./constants.js";
+export * from "./constants";
packages/web/src/app/[domain]/settings/license/page.tsx (1)

20-23: Removal of await is correct but drop the ? operator for entitlements

getEntitlements() always returns an array – never undefined.
You can simplify the rendering expression:

-<div className="text-sm font-mono">{entitlements?.join(", ") || "None"}</div>
+<div className="text-sm font-mono">{entitlements.length ? entitlements.join(", ") : "None"}</div>
packages/web/src/actions.ts (1)

34-35: Prefer the server-specific entry point of the shared package

packages/web/src/actions.ts executes exclusively on the server, yet the import points at the root of @sourcebot/shared.
If the shared package exposes both browser-safe and Node-only entry points, pulling from the generic root risks bundling client helpers (or vice-versa) and can enlarge the server bundle.

-import { getPlan, getSeats, hasEntitlement, SOURCEBOT_UNLIMITED_SEATS } from "@sourcebot/shared";
+import { getPlan, getSeats, hasEntitlement, SOURCEBOT_UNLIMITED_SEATS } from "@sourcebot/shared/server";

(Replace /server with the correct sub-path if different.)

This keeps the import tree minimal and prevents accidental inclusion of browser-only code.

packages/web/src/lib/constants.ts (1)

35-35: Minor: guard against unnecessary re-exports on the client

Re-exporting SOURCEBOT_SUPPORT_EMAIL directly is fine, but importing from the /client entry point here means every consumer of lib/constants.ts drags that module into the browser bundle—even when the constant is already statically known.

If the value is a plain string, consider just copying it instead of re-exporting, or switch to:

-export { SOURCEBOT_SUPPORT_EMAIL } from "@sourcebot/shared/client";
+import { SOURCEBOT_SUPPORT_EMAIL as _SUPPORT_EMAIL } from "@sourcebot/shared/client";
+export const SOURCEBOT_SUPPORT_EMAIL = _SUPPORT_EMAIL;

This allows bundlers to tree-shake unused parts of the shared package.

packages/backend/src/connectionManager.ts (1)

12-12: Untyped side-effects: import cost awareness

loadConfig + syncSearchContexts are added to the hot path. Ensure they do not pull in heavy JSON-schema / AJV deps for each worker thread. If unavoidable, lazy-require them only when env.CONFIG_PATH is set.

packages/shared/src/env.ts (1)

7-7: Consider making the enterprise license key validation more explicit.

The optional string validation for SOURCEBOT_EE_LICENSE_KEY could be enhanced to validate the format or length if there are specific requirements for license keys.

If there are specific format requirements for the license key, consider adding validation:

-        SOURCEBOT_EE_LICENSE_KEY: z.string().optional(),
+        SOURCEBOT_EE_LICENSE_KEY: z.string().min(1).optional(),
packages/shared/src/utils.ts (1)

21-34: Optional: guard against missing fetch in older Node versions

loadConfig relies on the global fetch API. Node ≤18 LTS does not enable it by default.
If the project supports those versions, consider a tiny ponyfill:

import nodeFetch from "node-fetch";
const fetchFn = globalThis.fetch ?? nodeFetch;

Otherwise document the minimum required Node version.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c0caa5a and cfb5ba9.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (36)
  • Dockerfile (4 hunks)
  • LICENSE (1 hunks)
  • Makefile (1 hunks)
  • packages/backend/package.json (1 hunks)
  • packages/backend/src/connectionManager.ts (3 hunks)
  • packages/backend/src/constants.ts (1 hunks)
  • packages/backend/src/index.ts (2 hunks)
  • packages/backend/src/main.ts (1 hunks)
  • packages/backend/src/utils.ts (0 hunks)
  • packages/shared/.gitignore (1 hunks)
  • packages/shared/package.json (1 hunks)
  • packages/shared/src/constants.ts (1 hunks)
  • packages/shared/src/ee/syncSearchContexts.ts (4 hunks)
  • packages/shared/src/entitlements.ts (2 hunks)
  • packages/shared/src/env.ts (1 hunks)
  • packages/shared/src/index.client.ts (1 hunks)
  • packages/shared/src/index.server.ts (1 hunks)
  • packages/shared/src/utils.ts (1 hunks)
  • packages/shared/tsconfig.json (1 hunks)
  • packages/web/package.json (1 hunks)
  • packages/web/src/actions.ts (1 hunks)
  • packages/web/src/app/[domain]/layout.tsx (1 hunks)
  • packages/web/src/app/[domain]/settings/license/page.tsx (2 hunks)
  • packages/web/src/app/[domain]/settings/members/page.tsx (1 hunks)
  • packages/web/src/app/layout.tsx (1 hunks)
  • packages/web/src/auth.ts (1 hunks)
  • packages/web/src/ee/features/billing/stripe.ts (1 hunks)
  • packages/web/src/ee/features/publicAccess/publicAccess.tsx (1 hunks)
  • packages/web/src/ee/sso/sso.tsx (2 hunks)
  • packages/web/src/env.mjs (2 hunks)
  • packages/web/src/features/entitlements/constants.ts (0 hunks)
  • packages/web/src/features/entitlements/planProvider.tsx (1 hunks)
  • packages/web/src/features/entitlements/useHasEntitlement.ts (1 hunks)
  • packages/web/src/initialize.ts (3 hunks)
  • packages/web/src/lib/authUtils.ts (1 hunks)
  • packages/web/src/lib/constants.ts (1 hunks)
💤 Files with no reviewable changes (2)
  • packages/backend/src/utils.ts
  • packages/web/src/features/entitlements/constants.ts
🧰 Additional context used
🧬 Code Graph Analysis (6)
packages/backend/src/index.ts (1)
packages/logger/src/index.ts (1)
  • createLogger (86-86)
packages/web/src/ee/sso/sso.tsx (1)
packages/shared/src/entitlements.ts (1)
  • getSeats (110-113)
packages/shared/src/env.ts (1)
packages/shared/src/constants.ts (1)
  • SOURCEBOT_CLOUD_ENVIRONMENT (4-9)
packages/web/src/app/[domain]/settings/license/page.tsx (1)
packages/shared/src/entitlements.ts (3)
  • getLicenseKey (78-85)
  • getEntitlements (120-123)
  • getPlan (87-108)
packages/shared/src/ee/syncSearchContexts.ts (3)
packages/logger/src/index.ts (1)
  • createLogger (86-86)
packages/shared/src/entitlements.ts (2)
  • hasEntitlement (115-118)
  • getPlan (87-108)
packages/shared/src/constants.ts (1)
  • SOURCEBOT_SUPPORT_EMAIL (2-2)
packages/shared/src/entitlements.ts (3)
packages/shared/src/utils.ts (1)
  • base64Decode (12-15)
packages/crypto/src/index.ts (1)
  • verifySignature (70-93)
packages/shared/src/env.ts (1)
  • env (5-15)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build
🔇 Additional comments (31)
packages/backend/src/constants.ts (1)

19-19: Skip trivial newline addition.
A single newline was added at the end of the file; there are no substantive changes to the constants object.

packages/backend/src/index.ts (1)

13-13: Refine logger context label.
The logger label was updated from 'index' to 'backend-entrypoint' for clearer identification in logs. Ensure any dashboards or alerting rules referencing the old label are updated accordingly.

packages/shared/.gitignore (1)

1-2: Ignore shared package build artifacts.
The new .gitignore correctly excludes dist/ and .tsbuildinfo files, preventing compiled outputs from being committed.

Makefile (1)

37-38: Extend clean target for shared package.
Added packages/shared/node_modules and packages/shared/dist to the clean target, aligning cleanup with the new shared workspace.

LICENSE (1)

5-5: Update enterprise license scope.
The license bullet now includes packages/shared/src/ee/, which covers the enterprise code in the shared package. Verify that this directory structure exists and the intended EE files are appropriately licensed.

packages/shared/src/constants.ts (2)

2-2: Approve centralization of support email.
The SOURCEBOT_SUPPORT_EMAIL constant is well-defined for reuse across packages.


4-9: Validate allowed environments tuple.
The readonly tuple for SOURCEBOT_CLOUD_ENVIRONMENT correctly enforces the set of valid environments. Ensure this aligns with any environment validation schemas.

packages/web/src/features/entitlements/planProvider.tsx (1)

4-4: Centralize Entitlement import from shared package.
The import path is updated correctly to use the new @sourcebot/shared package.

packages/web/src/features/entitlements/useHasEntitlement.ts (1)

3-3: Update Entitlement import to shared package.
Switching to the shared package import unifies entitlement types across the repo.

packages/web/src/lib/authUtils.ts (1)

6-6: Verify server-side hasEntitlement usage.
Confirm that the shared hasEntitlement function is synchronous and needs no additional context (user/org) here. Adjust the import or call signature if the function is async or requires parameters.

packages/web/src/app/layout.tsx (1)

11-11: Ensure getEntitlements runs synchronously.
Validate that getEntitlements() returns immediately and does not require await. If it is async, convert RootLayout to async and update the call accordingly.

packages/web/src/auth.ts (1)

17-17: Import path updated to shared package
Imported hasEntitlement from @sourcebot/shared aligns with the new shared-package refactor. Ensure that @sourcebot/shared is declared in packages/web/package.json and that your TypeScript path mappings have been updated to resolve this import correctly.

packages/web/src/app/[domain]/layout.tsx (1)

17-17: Centralize entitlement utility import
Switched hasEntitlement to come from @sourcebot/shared, matching the new shared-package strategy. Verify that this function’s signature (sync vs. async) is consistent with its usages here—remove any unnecessary await or adapt calls as needed.

packages/web/package.json (1)

79-79: Add shared package dependency
Adding "@sourcebot/shared": "workspace:*" correctly introduces the new shared package. Confirm that the lockfile and workspace installation have been updated accordingly so builds won’t break.

packages/web/src/app/[domain]/settings/members/page.tsx (1)

12-12: Switch to shared entitlements exports
Imported getSeats and SOURCEBOT_UNLIMITED_SEATS from @sourcebot/shared instead of the local module. Please verify that these exports exist in the shared package and that no legacy entitlement imports remain in this file.

packages/web/src/ee/features/publicAccess/publicAccess.tsx (1)

10-10: Refactored entitlement imports
Replaced local imports of getPlan and hasEntitlement with ones from @sourcebot/shared. Make sure the shared implementations match the previous behavior, especially around error messaging and license-key fallback logic.

packages/web/src/ee/sso/sso.tsx (2)

12-13: Import update looks good

Switching to the shared package keeps the SSO module in sync with the new entitlement utilities.
No further action required.


219-223: Confirmed: synchronous getSeats() call is safe

getSeats in @sourcebot/shared is synchronous, so removing await avoids an unnecessary micro-task without changing behaviour.
LGTM.

packages/backend/package.json (1)

36-36: Dependency added – ensure lockfile is updated

@sourcebot/shared has been added. After merging, run the workspace install (pnpm install / yarn install) so the lockfile picks up the new workspace link; otherwise CI may fail.

packages/web/src/app/[domain]/settings/license/page.tsx (1)

1-1: Import consolidation LGTM

Using the shared package eliminates duplicate logic and aligns with the new architecture.

packages/web/src/ee/features/billing/stripe.ts (1)

4-4: Good switch to shared entitlement util

The import path change is correct and keeps the feature in step with the new shared package.

packages/web/src/env.mjs (1)

3-4: Validate SOURCEBOT_CLOUD_ENVIRONMENT typing

z.enum() requires a tuple of literal strings (readonly ["a","b",…]). Ensure SOURCEBOT_CLOUD_ENVIRONMENT is declared as a const-asserted tuple in the shared package:

export const SOURCEBOT_CLOUD_ENVIRONMENT = ['dev','demo','staging','prod'] as const;

If it is instead a regular string[], TypeScript will accept the call, but at runtime z.enum() will throw.

Also applies to: 111-112

packages/shared/src/env.ts (1)

1-3: Well-structured environment configuration.

The use of @t3-oss/env-core with Zod validation and the centralized constants provides type-safe environment variable handling across the codebase. The server-side schema with appropriate optional/required fields aligns well with the application's needs.

Also applies to: 5-12

Dockerfile (2)

46-46: Proper integration of shared package in build process.

The shared package is correctly added to the build context and dependencies are installed appropriately in the shared-libs-builder stage.

Also applies to: 53-53


97-97: Consistent shared package distribution across build stages.

The built shared package is correctly copied from the shared-libs-builder stage to all dependent stages (web-builder, backend-builder, and runner), ensuring availability across the application components.

Also applies to: 138-138, 222-222

packages/shared/package.json (3)

28-31: Clear separation of server and client exports.

The dual export strategy with separate server and client entry points provides good separation of concerns for the shared package.


6-10: Appropriate build configuration with automatic postinstall.

The build scripts and postinstall hook ensure the package is built after installation, which is necessary for proper functioning in the monorepo setup.


11-21: Well-chosen dependencies for shared functionality.

The dependency selection aligns well with the package's purpose of providing shared utilities, environment configuration, and validation across the codebase.

packages/shared/tsconfig.json (1)

2-20: Modern and strict TypeScript configuration.

The configuration uses modern TypeScript features (ES2022, Node16 modules) with strict type checking enabled, which will help catch potential issues early and ensure code quality.

packages/shared/src/index.server.ts (1)

1-20: Clean centralized export structure.

The server entry point effectively consolidates shared functionality from multiple modules while maintaining clear separation between functions, types, and constants. This provides a clean API for consuming packages.

packages/web/src/initialize.ts (1)

125-128: Propagation of contexts: undefined may delete data

This call passes config.contexts verbatim; when the key is absent the downstream function currently deletes all contexts (see previous comment in syncSearchContexts.ts).
Until that behaviour is fixed, add a safeguard here or ensure the config always contains contexts.

msukkari
msukkari previously approved these changes Jun 17, 2025
@brendan-kellam brendan-kellam changed the title fix: Fix issue where a repository would not appear in a search context if it was created after the search context was created fix(search-contexts): Fix issue where a repository would not appear in a search context if it was created after the search context was created Jun 17, 2025
Copy link

@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

🧹 Nitpick comments (2)
CHANGELOG.md (1)

12-12: Rephrase changelog entry for consistency and clarity

Consider switching to past-tense and refining the description to align with other entries:

- - Fix issue where a repository would not be included in a search context if the context was created before the repository. [#354](https://github.com/sourcebot-dev/sourcebot/pull/354)
+ - Fixed issue where repositories created after a search context’s creation were not automatically included without a manual resync. [#354](https://github.com/sourcebot-dev/sourcebot/pull/354)
packages/shared/README.md (1)

5-9: Typos & casing (“Node.js”, “package”) and minor wording

Small polish keeps docs professional.

-... work in a Node.JS runtime (e.g., because it depends on the `fs` pacakge. Entitlements are a good example of this), and other code that is runtime agnostic (e.g., `constants.ts`). To deal with this, we these two index files export server code and client code, respectively.
+... work in a Node.js runtime (e.g. because it depends on the `fs` package; entitlements are a good example), and other code that is runtime-agnostic (e.g., `constants.ts`). To handle this, we provide two index files that export server-only and client-safe code, respectively.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e2b8911 and 04daa01.

📒 Files selected for processing (5)
  • CHANGELOG.md (1 hunks)
  • package.json (1 hunks)
  • packages/backend/src/connectionManager.ts (3 hunks)
  • packages/shared/README.md (1 hunks)
  • packages/shared/src/env.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • package.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/backend/src/connectionManager.ts
🧰 Additional context used
🪛 LanguageTool
packages/shared/README.md

[uncategorized] ~5-~5: The official spelling of this programming framework is “Node.js”.
Context: ...n this package that will only work in a Node.JS runtime (e.g., because it depends on th...

(NODE_JS)


[formatting] ~5-~5: If the ‘because’ clause is essential to the meaning, do not use a comma before the clause.
Context: ...ill only work in a Node.JS runtime (e.g., because it depends on the fs pacakge. Entitle...

(COMMA_BEFORE_BECAUSE)

⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: build
  • GitHub Check: build
  • GitHub Check: build
🔇 Additional comments (1)
packages/shared/src/env.ts (1)

25-25: SKIP_ENV_VALIDATION escape-hatch can mask prod mis-configurations

The toggle is handy during local dev, but leaving it wired into CI/CD or Docker images can silently bypass the very safety net this file provides.
Recommend:

  1. Add an assertion that process.env.NODE_ENV !== "production" when the flag is detected.
  2. Search infra configs to ensure the flag is never set outside development.
#!/bin/bash
# Detect accidental use of SKIP_ENV_VALIDATION in deployment configs
rg --line-number --context 2 'SKIP_ENV_VALIDATION' || true

@brendan-kellam brendan-kellam merged commit 22d548e into main Jun 17, 2025
5 checks passed
@brendan-kellam brendan-kellam deleted the bkellam/resync_search_contexts branch June 17, 2025 21:04
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