Skip to content

Membership settings rework #198

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 4 commits into from
Feb 18, 2025
Merged

Membership settings rework #198

merged 4 commits into from
Feb 18, 2025

Conversation

brendan-kellam
Copy link
Contributor

@brendan-kellam brendan-kellam commented Feb 17, 2025

Summary by CodeRabbit

  • New Features

    • Introduced a new settings page for managing organization members, including pending invites and comprehensive team management.
    • Rolled out a custom dropdown component that enhances the selection experience.
    • Launched a dedicated invitation card to streamline inviting new members.
  • Refactor

    • Improved role-based access control with refined permission checks and clearer error messaging.
    • Streamlined secret handling with more flexible form validations.
  • Style

    • Updated layout and sidebar navigation for a cleaner, more responsive user interface.

Copy link

coderabbitai bot commented Feb 17, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This pull request introduces several changes across the codebase. A new dependency (@radix-ui/react-select) is added to the web package. The organization membership flow is updated by enhancing the withOrgMembership function with a new role parameter, additional invite and member management functions, and removal of redundant code. Changes are also made to UI components and layout files for settings, including new components for member and invite management. Additionally, a custom Select component is integrated using Radix UI, and error codes are updated. A new data function for fetching a user’s role is also added.

Changes

File(s) Change Summary
packages/web/package.json Added dependency @radix-ui/react-select version ^2.1.6.
packages/web/src/actions.ts Updated withOrgMembership signature (added minRequiredRole and callback parameter change), removed withOwner, renamed removeMember to removeMemberFromOrg, and added functions: createInvites, cancelInvite, leaveOrg, getOrgMembers, getOrgInvites.
packages/web/src/app/[domain]/secrets/secretsTable.tsx Modified the form schema (removed max length on value) and refactored secret key fetching logic into the useEffect hook.
packages/web/src/app/[domain]/settings/(general)/page.tsx
packages/web/src/app/[domain]/settings/components/header.tsx
Added new GeneralSettingsPage and a new Header component with configurable top margin and class names.
packages/web/src/app/[domain]/settings/components/inviteTable.tsx
.../inviteTableColumns.tsx
.../memberInviteForm.tsx
.../memberTable.tsx
.../memberTableColumns.tsx
Removed various invite and member table components, associated interfaces, and functions to streamline the settings display.
packages/web/src/app/[domain]/settings/layout.tsx Restructured layout: removed the Separator import, integrated the new Header component, updated sidebar navigation items, and reorganized the JSX structure for improved presentation.
packages/web/src/app/[domain]/settings/members/components/inviteMemberCard.tsx
.../invitesList.tsx
.../membersList.tsx
.../members/page.tsx
Introduced new components and a page for managing organization invites and members with state management, filtering, and role-based checks.
packages/web/src/components/ui/select.tsx Added a new custom Select component and its subcomponents (e.g., SelectTrigger, SelectContent) built with Radix UI primitives.
packages/web/src/data/user.ts Introduced getUserRoleInOrg, an asynchronous function to retrieve a user’s role within an organization using Prisma.
packages/web/src/lib/errorCodes.ts Updated error codes by removing SELF_INVITE and MEMBER_NOT_OWNER and adding INSUFFICIENT_PERMISSIONS, OWNER_CANNOT_LEAVE_ORG, and INVALID_INVITE.

Sequence Diagram(s)

Organization Membership Flow

sequenceDiagram
    participant User
    participant withOrgMembership
    participant RoleChecker as getAuthorizationPrecendence
    participant Service
    User->>withOrgMembership: Initiate action with orgId and userRole
    withOrgMembership->>RoleChecker: Compare userRole vs. minRequiredRole
    RoleChecker-->>withOrgMembership: Return precedence result
    alt Insufficient role
        withOrgMembership-->>User: Return ServiceError (403)
    else Sufficient role
        withOrgMembership->>Service: Execute callback with { orgId, userRole }
        Service-->>withOrgMembership: Return result
        withOrgMembership-->>User: Return success
    end
Loading

Invite Member Process

sequenceDiagram
    participant User
    participant InviteMemberCard
    participant API as createInvites
    participant Toast
    User->>InviteMemberCard: Submit invite form with emails
    InviteMemberCard->>API: Call createInvites with email list
    API-->>InviteMemberCard: Return success/failure response
    InviteMemberCard->>Toast: Display notification
    InviteMemberCard-->>User: Confirm invitation status
Loading

Possibly related PRs

  • enforce owner perms #191: Enhances role-based access in the actions.ts file. This PR makes similar modifications by consolidating permission checks and streamlining the roles management functions.

Poem

I’m a little rabbit, hopping with glee,
Code carrots abound, fresh as can be.
New roles and invites now dance in the night,
With checks and balances, everything’s right.
In a field of code, I nibble and play—
Celebrating changes in a joyous way!
🥕🐇 Happy coding, have a brilliant day!


🪧 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.
    • Generate unit testing code for this file.
    • 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 generate unit testing code for this file.
    • @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 generate unit testing code.
    • @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.

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. (Beta)
  • @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 force-pushed the bkellam/settings_rework branch from 3d0a401 to 13d1c46 Compare February 17, 2025 18:19
@brendan-kellam
Copy link
Contributor Author

@coderabbitai review

Copy link

coderabbitai bot commented Feb 17, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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

🧹 Nitpick comments (14)
packages/web/src/app/[domain]/settings/members/page.tsx (4)

1-12: Ensure consistent error handling vs. returning null.
Here, when the session or data lookups fail, the function returns null, leading to a blank page. You might consider rendering a user-friendly error message or redirecting to a dedicated error page to improve the user experience.


22-27: Encapsulate fallback logic for session checks.
Lines 24–26 return null when no session exists. To improve clarity and reuse, consider extracting this logic into a helper, if repeated in multiple components.


28-46: Use consistent null checks or typed errors in data fetches.
Instead of returning null upon not finding org, user, or userRoleInOrg, you might throw or display an error message to the user. This would make it clear which part of the fetch logic failed.


55-94: UI structure and tabbed interface.
The tab setup for members and invites is properly segmented. Consider adding loading states for large organizations, especially if members and invites arrays can be large.

packages/web/src/actions.ts (4)

61-68: Refine naming for getAuthorizationPrecendence.
The helper function reliably returns numeric precedence, though consider a name like getRolePrecedence for clarity. Otherwise, logic is correct for current roles.


139-139: Check for potential key collisions.
When creating secrets, there’s no explicit check for existing keys. If overwriting an existing secret is undesired, add a check/unique constraint.


161-161: Deletion guard.
Similar to creation, consider verifying the secret exists before deleting it to improve error clarity or idempotency.


383-441: createInvites: validate concurrency and partial errors.
All invites are created in a single transaction. If any creation fails, they all roll back, which is good. However, partial successes aren’t possible if more than one email fails. Consider clarifying that behavior in user feedback.

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

1-6: Expand placeholder page.
The component currently returns just a <p>todo</p>. Consider implementing additional content or a clear layout for general settings, or remove until ready to avoid confusion.

packages/web/src/app/[domain]/settings/components/header.tsx (1)

11-22: Consider adding aria-role for better accessibility.

The component implementation looks good, but could benefit from accessibility improvements.

-        <div className={cn("mb-16", className)}>
+        <div role="banner" className={cn("mb-16", className)}>
packages/web/src/data/user.ts (1)

28-39: Add type safety and error handling.

The function implementation could be improved with:

  1. Type safety for the role return value
  2. Error handling for database failures
-export const getUserRoleInOrg = async (userId: string, orgId: number) => {
+import { Role } from '@prisma/client';
+
+export const getUserRoleInOrg = async (userId: string, orgId: number): Promise<Role | undefined> => {
+  try {
     const userToOrg = await prisma.userToOrg.findUnique({
         where: {
             orgId_userId: {
                 userId,
                 orgId,
             }
         },
     });
 
     return userToOrg?.role;
+  } catch (error) {
+    console.error('Failed to fetch user role:', error);
+    throw new Error('Failed to fetch user role');
+  }
 }
packages/web/src/app/[domain]/settings/members/components/inviteMemberCard.tsx (1)

20-28: Consider adding maximum length validation for email addresses.

While the current validation ensures unique email addresses, it's good practice to add a maximum length constraint to prevent potential abuse.

 const formSchema = z.object({
     emails: z.array(z.object({
-        email: z.string().email()
+        email: z.string().email().max(254)
     }))
     .refine((emails) => {
         const emailSet = new Set(emails.map(e => e.email.toLowerCase()));
         return emailSet.size === emails.length;
     }, "Duplicate email addresses are not allowed")
 });
packages/web/src/app/[domain]/settings/members/components/invitesList.tsx (1)

40-53: Consider memoizing filter predicates.

The useMemo implementation could be optimized by separating the filter predicates.

 const filteredInvites = useMemo(() => {
+    const filterBySearch = (invite: Invite) => {
+        const searchLower = searchQuery.toLowerCase();
+        return invite.email.toLowerCase().includes(searchLower);
+    };
+
+    const sortByDate = (a: Invite, b: Invite) => {
+        return dateSort === "newest"
+            ? b.createdAt.getTime() - a.createdAt.getTime()
+            : a.createdAt.getTime() - b.createdAt.getTime();
+    };
+
     return invites
-        .filter((invite) => {
-            const searchLower = searchQuery.toLowerCase();
-            const matchesSearch =
-                invite.email.toLowerCase().includes(searchLower);
-            return matchesSearch;
-        })
-        .sort((a, b) => {
-            return dateSort === "newest"
-                ? b.createdAt.getTime() - a.createdAt.getTime()
-                : a.createdAt.getTime() - b.createdAt.getTime()
-        });
+        .filter(filterBySearch)
+        .sort(sortByDate);
 }, [invites, searchQuery, dateSort]);
packages/web/src/app/[domain]/settings/members/components/membersList.tsx (1)

48-62: Consider extracting filter and sort logic into custom hooks.

The filtering and sorting logic is similar to invitesList.tsx. Consider creating reusable hooks.

Create a new hook useFilteredList.ts:

interface FilterOptions<T> {
  items: T[];
  searchFields: (item: T) => string[];
  searchQuery: string;
  dateField: keyof T;
  dateSort: "newest" | "oldest";
  additionalFilters?: (item: T) => boolean;
}

export function useFilteredList<T>({
  items,
  searchFields,
  searchQuery,
  dateField,
  dateSort,
  additionalFilters
}: FilterOptions<T>) {
  return useMemo(() => {
    return items
      .filter((item) => {
        const searchLower = searchQuery.toLowerCase();
        const matchesSearch = searchFields(item)
          .some(field => field.toLowerCase().includes(searchLower));
        return matchesSearch && (additionalFilters ? additionalFilters(item) : true);
      })
      .sort((a, b) => {
        const aDate = (a[dateField] as Date).getTime();
        const bDate = (b[dateField] as Date).getTime();
        return dateSort === "newest" ? bDate - aDate : aDate - bDate;
      });
  }, [items, searchQuery, dateSort, additionalFilters]);
}
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between e09b21f and 13d1c46.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (20)
  • packages/web/package.json (1 hunks)
  • packages/web/src/actions.ts (25 hunks)
  • packages/web/src/app/[domain]/secrets/secretsTable.tsx (2 hunks)
  • packages/web/src/app/[domain]/settings/(general)/page.tsx (1 hunks)
  • packages/web/src/app/[domain]/settings/components/header.tsx (1 hunks)
  • packages/web/src/app/[domain]/settings/components/inviteTable.tsx (0 hunks)
  • packages/web/src/app/[domain]/settings/components/inviteTableColumns.tsx (0 hunks)
  • packages/web/src/app/[domain]/settings/components/memberInviteForm.tsx (0 hunks)
  • packages/web/src/app/[domain]/settings/components/memberTable.tsx (0 hunks)
  • packages/web/src/app/[domain]/settings/components/memberTableColumns.tsx (0 hunks)
  • packages/web/src/app/[domain]/settings/components/sidebar-nav.tsx (1 hunks)
  • packages/web/src/app/[domain]/settings/layout.tsx (2 hunks)
  • packages/web/src/app/[domain]/settings/members/components/inviteMemberCard.tsx (1 hunks)
  • packages/web/src/app/[domain]/settings/members/components/invitesList.tsx (1 hunks)
  • packages/web/src/app/[domain]/settings/members/components/membersList.tsx (1 hunks)
  • packages/web/src/app/[domain]/settings/members/page.tsx (1 hunks)
  • packages/web/src/app/[domain]/settings/page.tsx (0 hunks)
  • packages/web/src/components/ui/select.tsx (1 hunks)
  • packages/web/src/data/user.ts (1 hunks)
  • packages/web/src/lib/errorCodes.ts (1 hunks)
💤 Files with no reviewable changes (6)
  • packages/web/src/app/[domain]/settings/components/memberInviteForm.tsx
  • packages/web/src/app/[domain]/settings/components/inviteTable.tsx
  • packages/web/src/app/[domain]/settings/components/inviteTableColumns.tsx
  • packages/web/src/app/[domain]/settings/components/memberTableColumns.tsx
  • packages/web/src/app/[domain]/settings/page.tsx
  • packages/web/src/app/[domain]/settings/components/memberTable.tsx
🔇 Additional comments (25)
packages/web/src/app/[domain]/settings/members/page.tsx (3)

13-21: Interface composition looks good.
The MembersSettingsPageProps interface is clearly defined and provides a strong contract for the function's parameters. No issues found here.


48-52: Validate invites data handling.
When invites is a service error, the function returns null. If there's important context to convey (e.g., “Couldn’t load invites”), consider a user-facing message to help debugging.


53-54: Tab logic defaults to "members".
Good approach to fallback on a default tab if none is specified. This ensures a consistent user experience.

packages/web/src/actions.ts (14)

37-42: Added minRequiredRole to withOrgMembership.
This enhances role-based access control, allowing fine-grained role requirements. The approach looks solid.


71-82: Permission check logic is straightforward.
Using numeric precedence simplifies comparisons. The fallback error for insufficient permissions is properly structured.


117-119: Integration with withOrgMembership.
Line 119 ensures secrets are fetched only by authenticated org members. This usage is consistent and secure.


188-188: Promote consistent pattern.
All connection fetch methods use withOrgMembership seamlessly. This line nicely follows the established pattern.


379-381: getCurrentUserRole usage.
The function now returns userRole. Ensure you handle any needed revalidation on the frontend or server for mission-critical actions.


443-467: cancelInvite function looks good.
It properly checks existences and permissions, ensuring only owners can cancel. The transaction scope is small, so the risk of concurrency issues is minimal.


532-532: Initial pointer to transferOwnership.
Ensure you reflect updated ownership in places that rely on OrgRole. This line alone doesn’t show an immediate issue, but continued checks in the function are crucial.


534-534: Minimum required role set to OWNER.
This is consistent with the concept that only an owner can transfer ownership. Good usage of the new minRequiredRole param.


795-816: getCustomerPortalSessionLink with minRequiredRole = OWNER.
This ensures only owners can manage billing details. The approach is consistent with your role model. Make sure the UI warns non-owners accordingly.


864-885: changeSubscriptionBillingEmail with minRequiredRole = OWNER.
Again, ensures that only an owner can modify billing. The changes appear consistent.


908-966: removeMemberFromOrg: concurrency caution.
Decrementing seats in Stripe subscription is performed inside a single transaction with Prisma. Though the seat update to Stripe is separate. If concurrency arises, consider implementing a lock or an external queue system for consistent seat counts.


968-1022: leaveOrg: Restricts owners from leaving directly.
Good safeguard to prevent an org without an owner. The seat count decrement is consistent with other membership changes.


1041-1062: getOrgMembers approach.
Fetching members with include: { user: true } is appropriate for gathering relevant user info. The returned structure is straightforward.


1065-1080: getOrgInvites approach.
Similarly straightforward for invites. No immediate concerns regarding performance or security.

packages/web/src/app/[domain]/settings/components/header.tsx (1)

5-9: LGTM! Well-structured interface definition.

The HeaderProps interface is well-defined with appropriate types and optional flags.

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

15-18: LGTM! Error codes align with membership rework.

The new error codes provide better granularity for permission handling and organization-specific scenarios.

packages/web/src/app/[domain]/settings/components/sidebar-nav.tsx (1)

21-21: LGTM! Improved layout behavior.

The class name changes improve the default layout while maintaining responsive behavior.

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

32-46: Well-structured layout with improved organization!

The new layout structure with flex classes provides better responsiveness and visual hierarchy. The centered content with max-width constraint ensures consistent presentation across different screen sizes.

packages/web/src/components/ui/select.tsx (1)

1-160: Excellent implementation of the Select component!

The component is well-structured using Radix UI primitives, ensuring accessibility and proper keyboard navigation. The implementation includes:

  • Type-safe components with proper ref forwarding
  • Comprehensive set of subcomponents for different use cases
  • Proper styling and animations
packages/web/src/app/[domain]/settings/members/components/invitesList.tsx (2)

20-29: LGTM! Well-defined types and interfaces.

The types are clear, concise, and properly structured.


122-135: Verify clipboard API availability.

The clipboard operations should be wrapped in a try-catch block with proper feature detection.

-navigator.clipboard.writeText(url)
+if (navigator?.clipboard?.writeText) {
+    try {
+        await navigator.clipboard.writeText(url)
+        toast({
+            description: `✅ Copied invite link for ${invite.email} to clipboard`
+        })
+    } catch (error) {
+        toast({
+            description: "❌ Failed to copy invite link"
+        })
+    }
+} else {
+    toast({
+        description: "❌ Clipboard API not supported in this browser"
+    })
+}
packages/web/package.json (1)

52-52:

✅ Verification successful

Verify Radix UI package version compatibility.

The new @radix-ui/react-select package is added with version ^2.1.6. Let's verify its compatibility with other Radix UI packages and check for any security advisories.


🏁 Script executed:

#!/bin/bash
# Check for compatibility issues and security advisories

# Get all installed Radix UI package versions
echo "Installed Radix UI package versions:"
npm list | grep "@radix-ui"

# Check for security advisories
gh api graphql -f query='
{
  securityVulnerabilities(first: 5, ecosystem: NPM, package: "@radix-ui/react-select") {
    nodes {
      advisory {
        summary
        severity
        publishedAt
      }
      vulnerableVersionRange
      firstPatchedVersion {
        identifier
      }
    }
  }
}'

Length of output: 466


Radix UI Dependency (@radix-ui/react-select) Verified: No Compatibility or Security Concerns

  • The dependency was added at version ^2.1.6 in packages/web/package.json (line 52).
  • Our compatibility check against other installed Radix UI packages did not reveal any version conflicts.
  • A security scan using GitHub’s advisory API returned no vulnerabilities for this package.

No further action is required.

@brendan-kellam brendan-kellam merged commit f652ca5 into v3 Feb 18, 2025
1 check passed
@brendan-kellam brendan-kellam deleted the bkellam/settings_rework branch February 18, 2025 19:27
brendan-kellam added a commit that referenced this pull request Apr 1, 2025
* SQL Database (#157)

* point zoekt to v3 branch

* bump zoekt version

* Add tenant ID concept into web app and backend (#160)

* hacked together a example of using zoekt grpc api

* provide tenant id to zoekt git indexer

* update zoekt version to point to multitenant branch

* pipe tenant id through header to zoekt

* remove incorrect submodule reference and settings typo

* update zoekt commit

* remove unused yarn script

* remove unused grpc client in web server

* remove unneeded deps and improve tenant id log

* pass tenant id when creating repo in db

* add mt yarn script

* add nocheckin comment to tenant id in v2 schema

---------

Co-authored-by: bkellam <bshizzle1234@gmail.com>

* bump zoekt version

* parallelize repo indexing (#163)

* hacked together a example of using zoekt grpc api

* provide tenant id to zoekt git indexer

* update zoekt version to point to multitenant branch

* pipe tenant id through header to zoekt

* remove incorrect submodule reference and settings typo

* update zoekt commit

* remove unused yarn script

* remove unused grpc client in web server

* remove unneeded deps and improve tenant id log

* pass tenant id when creating repo in db

* add mt yarn script

* add pol of bullmq into backend

* add better error handling and concurrency setting

* spin up redis instance in dockerfile

* cleanup transaction logic when adding repos to index queue

* add NEW index status fetch condition

* move bullmq deps to backend

---------

Co-authored-by: bkellam <bshizzle1234@gmail.com>

* Authentication (#164)

* Add Org table (#167)

* Move logout button & profile picture into settings dropdown (#172)

* Multi tenancy support in config syncer (#171)

* [wip] initial mt support in config syncer

* Move logout button & profile picture into settings dropdown (#172)

* update sync status properly and fix bug with multiple config in db case

* make config path required in single tenant mode

NOTE: deleting config/repos is currently not supported in multi tenancy case. Support for this will be added in a future PR

---------

Co-authored-by: Brendan Kellam <bshizzle1234@gmail.com>

* add tenant mode support in docker container:

* Organization switching & active org management (#173)

* updated syncedAt date after config sync:

* Migrate to postgres (#174)

* spin up postgres in docker container

* get initial pol of postgres db working in docker image

* spin up postgres server in dev case

* updated syncedAt date after config sync:

* remove unnecessary port expose in docker file

* Connection creation form (#175)

* fix issue with yarn dev startup

* init (#176)

* Add `@sourcebot/schemas` package (#177)

* Connection management (#178)

* add concept of secrets (#180)

* add @sourcebot/schemas package

* migrate things to use the schemas package

* Dockerfile support

* add secret table to schema

* Add concept of connection manager

* Rename Config->Connection

* Handle job failures

* Add join table between repo and connection

* nits

* create first version of crypto package

* add crypto package as deps to others

* forgot to add package changes

* add server action for adding and listing secrets, create test page for it

* add secrets page to nav menu

* add secret to config and support fetching it in backend

* reset secret form on successful submission

* add toast feedback for secrets form

* add instructions for adding encryption key to dev instructions

* add encryption key support in docker file

* add delete secret button

* fix nits from pr review

---------

Co-authored-by: bkellam <bshizzle1234@gmail.com>

* bump zoekt version

* enforce tenancy on search and repo listing endpoints (#181)

* enforce tenancy on search and repo listing

* remove orgId from request schemas

* adds garbage collection for repos (#182)

* refactor repo indexing logic into RepoManager

* wip cleanup stale repos

* add rest of gc logic

* set status to indexing properly

* add initial logic for staging environment

* try to move encryption key env decleration in docker file to fix build issues

* switch encryption key as build arg to se if that fixes build issues

* add deployment action for staging image

* try using mac github action runners instead

* switch to using arm64 runners on arm64 build

* change workflow names to fix trigger issue

* trigger staging actions to see if it works

* fix working directory typo and pray it doesnt push to prod

* checkout v3 when deploying staging

* try to change into the staging dir manuall

* dummy commit to trigger v3 workflows to test

* update staging deploy script to match new version in main

* reference proper image:tag in staging fly config

* update staging fly config to point to ghcr

* Connection management (#183)

* add invite system and google oauth provider (#185)

* add settings page with members list

* add invite to schema and basic create form

* add invite table

* add basic invite link copy button

* add auth invite accept case

* add non auth logic

* add google oauth provider

* fix reference to header component in connections

* add google logo to google oauth

* fix web build errors

* bump staging resources

* change staging cpu to perf

* add side bar nav in settings page

* improve styling of members page

* wip adding stripe checkout button

* wip onboarding flow

* add stripe subscription id to org

* save stripe session id and add manage subscription button in settings

* properly block access to pages if user isn't in an org

* wip add paywall

* Domain support

* Domain support (#188)

* Update Makefile to include crypto package when doing a make clean

* Add default for AUTH_URL in attempt to fix build

* attempt 2

* fix attempt #3: Do not require a encrpytion key at build time

* Fix generate script race condition

* Attempt #4

* add back paywall and also add support for incrememnting seat count on invite redemption

* prevent self invite

* action button styling in settings and toast on copy

* add ability to remove member from org

* move stripe product id to env var

* add await for blocking loop in backend

* add subscription info to billing page

* handle trial case in billing info page

* add trial duration indicator to nav bar

* check if domain starts or ends with dash

* remove unused no org component

* Generate AUTH_SECRET if not provided (#189)

* remove package lock file and fix prisma dep version

* revert dep version updates

* fix yarn.lock

* add auth and membership check to fetchSubscription

* properly handle invite redeem with no valid subscription case

* change back fetch subscription to not require org membership

* add back subscription check in invite redeem page

* Add stripe billing logic (#190)

* add side bar nav in settings page

* improve styling of members page

* wip adding stripe checkout button

* wip onboarding flow

* add stripe subscription id to org

* save stripe session id and add manage subscription button in settings

* properly block access to pages if user isn't in an org

* wip add paywall

* Domain support

* add back paywall and also add support for incrememnting seat count on invite redemption

* prevent self invite

* action button styling in settings and toast on copy

* add ability to remove member from org

* move stripe product id to env var

* add await for blocking loop in backend

* add subscription info to billing page

* handle trial case in billing info page

* add trial duration indicator to nav bar

* check if domain starts or ends with dash

* remove unused no org component

* remove package lock file and fix prisma dep version

* revert dep version updates

* fix yarn.lock

* add auth and membership check to fetchSubscription

* properly handle invite redeem with no valid subscription case

* change back fetch subscription to not require org membership

* add back subscription check in invite redeem page

---------

Co-authored-by: bkellam <bshizzle1234@gmail.com>

* fix nits

* remove providers check

* fix more nits

* change stripe init to be behind function

* fix publishible stripe key handling in docker container

* enforce owner perms (#191)

* add make owner logic, and owner perms for removal, invite, and manage subscription

* add change billing email card to billing settings

* enforce owner role in action level

* remove unused hover card component

* cleanup

* add back gitlab, gitea, and gerrit support (#184)

* add non github config definitions

* refactor github config compilation to seperate file

* add gitlab config compilation

* Connection management (#183)

* wip gitlab repo sync support

* fix gitlab zoekt metadata

* add gitea support

* add gerrit support

* Connection management (#183)

* add gerrit config compilation

* Connection management (#183)

---------

Co-authored-by: Brendan Kellam <bshizzle1234@gmail.com>

* fix apos usage in redeem page

* change csrf cookie to secure not host

* Credentials provider (#192)

* email password functionality

* feedback

* cleanup org's repos and shards if it's inactive (#194)

* add stripe subscription status and webhook

* add inactive org repo cleanup logic

* mark reactivated org connections for sync

* connections qol improvements (#195)

* add client side polling to connections list

* properly fetch repo image url

* add client polling to connection management page, and add ability to sync failed connections

* Fix build with suspense boundary

* improved fix

* add retries for 429 issues (#196)

* add connection compile retry and hard repo limit

* add more retry checks

* cleanup unused change

* address feedback

* fix build errors and add index concurrency env var

* add config upsert timeout env var

* Membership settings rework (#198)

* Add refined members list

* futher progress on members settings polish

* Remove old components

* feedback

* Magic links (#199)

* wip on magic link support

* Switch to nodemailer / resend for transactional mail

* Further cleanup

* Add stylized email using react-email

* fix

* Fix build

* db performance improvements and job resilience  (#200)

* replace upsert with seperate create many and raw update many calls

* add bulk repo status update and queue addition with priority

* add support for managed redis

* add note for changing raw sql on schema change

* remove non secret token options

* fix token examples in schema

* add better visualization for connection/repo errors and warnings (#201)

* replace upsert with seperate create many and raw update many calls

* add bulk repo status update and queue addition with priority

* add support for managed redis

* add note for changing raw sql on schema change

* add error package and use BackendException in connection manager

* handle connection failure display on web app

* add warning banner for not found orgs/repos/users

* add failure handling for gerrit

* add gitea notfound warning support

* add warning icon in connections list

* style nits

* add failed repo vis in connections list

* added retry failed repo index buttons

* move nav indicators to client with polling

* fix indicator flash issue and truncate large list results

* display error nav better

* truncate failed repo list in connection list item

* fix merge error

* fix merge bug

* add connection util file [wip]

* refactor notfound fetch logic and add missing error package to dockerfile

* move repeated logic to function and add zod schema for syncStatusMetadata

* add orgid unique constraint to repo

* revert repo compile update logic to upsert loop

* log upsert stats

* [temp] disable polling everywhere (#205)

* add health check endpoint

* Refined onboarding flow (#202)

* Redeem UX pass (#204)

* add log for health check

* fix new connection complete callback route

* add cpu split logic and only wait for postgres if we're going to connec to it

* Inline secret creation (#207)

* use docker scopes to try and improve caching

* Dummy change

* remove cpu split logic

* Add some instrumentation to web

* add posthog events on various user actions (#208)

* add page view event support

* add posthog events

* nit: remove unused import

* feedback

* fix merge error

* use staging posthog papik when building staging image

* fix other merge error and build warnings

* Add invite email (#209)

* wrap posthog provider in suspense to fix build error

* add grafana alloy config and setup (#210)

* add grafana alloy config and setup

* add basic repo prom metrics

* nits in dockerfile

* remove invalid characters when auto filling domain

* add login posthog events

* remove hard coded sourcebot.app references

* make repo garbage collection async (#211)

* add gc queue logic

* fix missing switch cases for gc status

* style org create form better with new staging domain

* change repo rm logic to be async

* simplify repo for inactive org query

* add grace period for garbage collecting repos

* make prom scrape interval 500ms

* fix typo in trial card

* onboarding tweaks

* rename some prom metrics and cleanup unused

* wipe existing repo if we've picked up a killed job to ensure good state

* Connections UX pass + query optimizations (#212)

* remove git & local schemas (#213)

* skip stripe checkout for trial + fix indexing in progress UI + additional schema validation (#214)

* add additional config validation

* wip bypass stripe checkout for trial

* fix stripe trial checkout bypass

* fix indexing in progress ui on home page

* add subscription checks, more schema validation, and fix issue with complete page

* dont display if no indexed repos

* fix skipping onboard complete check

* fix build error

* add back button in onboard connection creation flow

* Add back revision support (#215)

* fix build

* Fix bug with repository snapshot

* fix share links

* fix repo rm issue, 502 page, condition on test clock

* Make login and onboarding mobile friendly

* fix ordering of quick actions

* remove error msg dump on failed repo index job, and update indexedAt field

* Add mobile unsupported splash screne

* cherry pick fix for file links

* [Cherry Pick] Syntax reference guide (#169) (#216)

* Add .env to db gitignore

* fix case where we have repos but they're all failed for repo snapshot

* /settings/secrets page (#217)

* display domain properly in org create form

* Quick action tweaks (#218)

* revamp repo page (#220)

* wip repo table

* new repo page

* add indicator for when feedback is applied in repo page

* add repo button

* fetch connection data in one query

* fix styling

* fix (#219)

* remove / keyboard shortcut hint in search bar

* prevent switching to first page on data update and truncate long repo names in repo list

* General settings + cleanup (#221)

* General settings

* Add alert to org domain change

* First attempt at sending logs to grafana

* logs wip

* add alloy logs

* wip

* [temp] comment out loki for now

* update trial card content and add events for code host selection on onboard

* reduce scraping interval to 15s

* Add prometheus metric for pending repo indexing jobs

* switch magic link to invite code (#222)

* wip magic link codes

* pipe email to email provider properly

* remove magic link data cookie after sign in

* clean up unused imports

* dont remove cookie before we use it

* rm package-lock.json

* revert yarn files to v3 state

* switch email passing from cookie to search param

* add comment for settings dropdown auth update

* remove unused middleware file

* fix build error and warnings

* fix build error with useSearchParam not wrapped in suspense

* add sentry support to backend and webapp (#223)

* add sentry to web app

* set sentry environemnt from env var

* add sentry env replace logic in docker container

* wip add backend sentry

* add sentry to backend

* move dns to env var

* remove test exception

* Fix root domain issue on onboarding

* add setup sentry cli step to github action

* login to sentry

* fix sentry login in action

* Update grafana loki endpoint

* switch source map publish to runtime in entrypoint

* catch and rethrow simplegit exceptions

* alloy nits

* fix alloy

* backend logging (#224)

* revert grafana loki config

* fix login ui nits

* fix quick actions

* fix typo in secret creation

* fix private repo clone issue for gitlab

* add repo index timeout logic

* add posthog identify call after registeration

* various changes to add terms and security info (#225)

* add terms and security to footer

* add security card

* add demo card

* fix build error

* nit fix: center 'get in touch' on security card

* Dark theme improvements (#226)

* (fix) Fixed bug with gitlab and gitea not including hostname in the repoName

* Switch to using t3-env for env-var management (#230)

* Add missing env var

* fix build

* Centralize to using a single .env.development for development workflows (#231)

* Make billing optional (#232)

* Massage environment variables from strings to numbers (#234)

* Single tenancy & auth modes (#233)

* Add docs to this repo

* dummy change

* Declarative connection configuration (#235)

* fix build

* upgrade to next 14.2.25

* Improved database DX

* migrate to yarn v4

* Use origin from header for baseUrl of emails (instead of AUTH_URL). Also removed reference to hide scrollbars

* Remove SOURCEBOT_ENCRYPTION_KEY from build arg

* Fix issue with linking default user to org in single tenant + no-auth mode

* Fix fallback tokens (#242)

* add SECURITY_CARD_ENABLED flag

* Add repository weburl (#243)

* Random fixes and improvements (#244)

* add zoekt max wall time env var

* remove empty warning in docs

* fix reference in sh docs

* add connection manager upsert timeout env var

* Declarative connection cleanup + improvements (#245)

* change contact us footer in app to point to main contact form

* PostHog event pass (#246)

* fix typo

* Add sourcebot cloud environment prop to staging workflow

* Update generated files

* remove AUTH_URL since it unused and (likely) unnecessary

* Revert "remove AUTH_URL since it unused and (likely) unnecessary"

This reverts commit 1f4a5ae.

* cleanup GitHub action releases (#252)

* remove alloy, change auth defaul to disabled, add settings page in me dropdown

* enforce connection management perms to owner (#253)

* enforce conneciton management perms to owner

* fix formatting

* more formatting

* naming nits

* fix var name error

* change empty repo set copy if auth is disabled

* add CONTRIBUTING.md file

* hide settings in dropdown with auth isnt enabled

* handle case where gerrit weburl is just gitiles path

* Docs overhall (#251)

* remove nocheckin

* fix build error

* remove v3 trigger from deploy staging

* fix build errors round 2

* another error fix

---------

Co-authored-by: msukkari <michael.sukkarieh@mail.mcgill.ca>
@coderabbitai coderabbitai bot mentioned this pull request May 22, 2025
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