Skip to content

Conversation

harley
Copy link
Contributor

@harley harley commented Jun 25, 2025

Summary

  • Comprehensive multi-team support plan with phased implementation approach
  • Database schema design validated against current Pulse structure
  • Safe migration strategy to avoid data loss during transition
  • Authentication updates to remove hardcoded domain restrictions

Implementation Phases

  1. Phase 1: Core schema changes (teams, team_members tables)
  2. Phase 2: Data migration with default team creation
  3. Phase 3: Authentication & API updates for team context
  4. Phase 4: UI components for team management and switching

Key Benefits

  • Enables multiple organizations to use Pulse independently
  • Maintains data isolation between teams using Row Level Security
  • Backward compatible migration preserves existing CoderPush data
  • Scalable foundation for future multi-tenant features

Test Plan

  • Test migration script on production data copy
  • Validate data isolation between teams
  • Test authentication flows for team selection
  • Verify API endpoints respect team boundaries

🤖 Generated with Claude Code

Summary by Sourcery

Add a comprehensive implementation plan for Pulse’s multi-team support, outlining phased schema changes, data migration, authentication/API updates, UI enhancements, and data isolation strategies.

Documentation:

  • Introduce a new documentation file detailing goals, requirements, and technical steps for multi-team support
  • Define a four-phase rollout covering database schema, migration, authentication/API updates, and UI team management
  • Include open questions, performance considerations, and critical migration strategies to guide the implementation

Summary by CodeRabbit

  • Documentation
    • Added a detailed plan outlining upcoming multi-team support for the Pulse app, including architecture changes, data migration strategies, UI enhancements (such as a team switcher and team-specific branding), admin management features, and data isolation policies.
    • Included phased implementation steps, migration considerations, and open questions for future improvements.

- Detailed phased implementation approach for multi-team functionality
- Database schema design with safe migration strategy
- Authentication and API update requirements
- Data isolation strategy using Row Level Security
- Critical migration considerations and risk mitigation

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link

vercel bot commented Jun 25, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
pulse ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jun 25, 2025 2:44pm

Copy link
Contributor

⏳ I'm reviewing this pull request for security vulnerabilities and code quality issues. I'll provide an update when I'm done

Copy link
Contributor

sourcery-ai bot commented Jun 25, 2025

Reviewer's Guide

This PR introduces a comprehensive, phased implementation plan for multi-team support in Pulse by adding a detailed documentation file that covers schema design, data migration, authentication/API changes, UI updates, and data isolation strategies.

Class diagram for new and updated types in multi-team support

classDiagram
    class Team {
        +UUID id
        +String name
        +String slug
        +DateTime created_at
        +UUID owner_id
    }
    class TeamMember {
        +UUID team_id
        +UUID user_id
        +String role
        +DateTime joined_at
    }
    class User {
        +UUID id
        +UUID current_team_id
        ...
    }
    class Submission {
        +UUID id
        +UUID team_id
        ...
    }
    class Project {
        +UUID id
        +UUID team_id
        ...
    }
    class Question {
        +UUID id
        +UUID team_id
        ...
    }
    Team "1" -- "*" TeamMember : has
    User "1" -- "*" TeamMember : member_of
    Team "1" -- "*" Submission : owns
    Team "1" -- "*" Project : owns
    Team "1" -- "*" Question : owns
    User "1" -- "*" Submission : submits
    User "1" -- "*" Project : creates
    User "1" -- "*" Question : asks
    TeamMember "*" -- "1" User : user
    TeamMember "*" -- "1" Team : team
    Submission "*" -- "1" Team : team
    Project "*" -- "1" Team : team
    Question "*" -- "1" Team : team
    User "*" -- "1" Team : current_team
Loading

File-Level Changes

Change Details Files
Add multi-team support implementation plan documentation
  • Create a new doc outlining goals, requirements, and phased approach
  • Detail open questions, references, and next steps
  • Include test plan and key benefits overview
docs/multi-team-support-plan.md
Define database schema modifications
  • Introduce teams and team_members tables with UUID keys
  • Add team_id to users, submissions, projects, questions for safe migration
  • Plan for nullable columns initially, then enforce NOT NULL constraints
docs/multi-team-support-plan.md
Draft data migration strategy
  • Insert default 'CoderPush' team and assign existing users
  • Backfill team_id across all relevant tables
  • Alter columns to NOT NULL post-backfill for safety
docs/multi-team-support-plan.md
Plan authentication and API changes
  • Remove hardcoded domain restriction logic
  • Add team selection/creation to signup and login flows
  • Require and validate team context in all API endpoints
docs/multi-team-support-plan.md
Outline UI updates and data isolation measures
  • Specify team switcher, branding, and admin management interfaces
  • Enable Row Level Security (RLS) policies for team-scoped tables
  • Recommend indexing and partitioning for performance
docs/multi-team-support-plan.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

coderabbitai bot commented Jun 25, 2025

Walkthrough

A detailed plan for introducing multi-team support to the Pulse app is documented. The plan describes new database tables for teams and team memberships, schema changes to link entities to teams, removal of domain-based restrictions, team-specific authentication and UI changes, data isolation strategies, phased implementation steps, migration scripts, and open design questions.

Changes

File(s) / Area Change Summary
docs/multi-team-support-plan.md Added a comprehensive plan outlining schema, API, UI, and migration changes for multi-team support.
src/app/auth/callback/route.ts Planned removal of domain validation logic for authentication.
src/utils/companyDomain.ts Planned removal of hardcoded domain logic.
src/app/api/... (submissions, admin, etc.) Planned addition of team context parameters and filtering in API endpoints.
Database schema (teams, team_members, etc.) Planned addition of teams and team_members tables, and team_id columns to users, submissions, etc.
Migration scripts Planned scripts for creating default teams, assigning users, and backfilling team IDs.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant AuthService
    participant TeamService
    participant API
    participant Database

    User->>AuthService: Log in / Authenticate
    AuthService->>TeamService: Fetch user teams
    TeamService->>Database: Query team_members table
    Database-->>TeamService: Return teams for user
    TeamService-->>AuthService: Return team list
    AuthService->>User: Present team selection
    User->>API: Make request with selected team context
    API->>Database: Query data filtered by team_id
    Database-->>API: Return team-specific data
    API-->>User: Respond with isolated data
Loading

Poem

In burrows deep, teams multiply,
Each with their own carrot supply.
No more one warren, but many to roam,
With team switchers guiding each bunny home.
Data fences high, and branding anew—
Multi-team Pulse, we’re hopping through!
🥕


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.

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey @harley - I've reviewed your changes - here's some feedback:

  • Add an idempotency guard to the migration script to prevent creating duplicate default teams if the script is run more than once.
  • Move index creation on all new team_id columns before enforcing NOT NULL and RLS policies to avoid performance regressions during the transition.
  • Clarify in Phase 3 how the auth callback will resolve ambiguous team context for users belonging to multiple teams to ensure deterministic routing.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Add an idempotency guard to the migration script to prevent creating duplicate default teams if the script is run more than once.
- Move index creation on all new team_id columns before enforcing NOT NULL and RLS policies to avoid performance regressions during the transition.
- Clarify in Phase 3 how the auth callback will resolve ambiguous team context for users belonging to multiple teams to ensure deterministic routing.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Contributor

✅ I finished the code review, and didn't find any security or code quality issues.

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

🧹 Nitpick comments (2)
docs/multi-team-support-plan.md (2)

31-33: Minor wording duplication in bullet list.

LanguageTool flags a possible repeated word around “users select or are routed to their team ‑ Team admins…”.
Consider splitting the sentence or removing the second “Team” after the dash to avoid stuttering.


118-122: Plan for indexes on the new team_id columns.

Every query in a multi-team environment will filter by team_id; missing indexes will become an immediate performance bottleneck once data grows.

Proposed addition right after the ALTER TABLE … ADD COLUMN statements:

CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_users_current_team  ON users(current_team_id);
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_submissions_team    ON submissions(team_id);
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_projects_team       ON projects(team_id);
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_questions_team      ON questions(team_id);
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 7611f83 and 8394a58.

📒 Files selected for processing (1)
  • docs/multi-team-support-plan.md (1 hunks)
🧰 Additional context used
🪛 LanguageTool
docs/multi-team-support-plan.md

[duplication] ~32-~32: Possible typo: you repeated a word.
Context: ...in, users select or are routed to their team - Team admins can manage members, roles, and s...

(ENGLISH_WORD_REPEAT_RULE)


[duplication] ~124-~124: Possible typo: you repeated a word.
Context: ...ENCES teams(id); ### Phase 2: Data Migration **Migration Script:**sql -- Create default team...

(ENGLISH_WORD_REPEAT_RULE)

🔇 Additional comments (2)
docs/multi-team-support-plan.md (2)

143-145: users.current_team_id remains nullable—verify this is intentional.

After back-filling, the migration makes team_id in other tables NOT NULL but leaves users.current_team_id untouched.
If every user must always have an active team, consider tightening the constraint; otherwise document the scenarios where it can be null (e.g., during signup before team creation).


101-119: Circular reference between teams.owner_id ↔ users.current_team_id.

teams.owner_id references users(id) while users.current_team_id references teams(id). Inserts are possible but require careful ordering or deferrable constraints.

If you anticipate bulk imports or transactional inserts touching both tables, mark at least one of the FK constraints DEFERRABLE INITIALLY DEFERRED to avoid deadlocks.

Comment on lines +169 to +178
-- Enable RLS on all team-scoped tables
ALTER TABLE submissions ENABLE ROW LEVEL SECURITY;
ALTER TABLE projects ENABLE ROW LEVEL SECURITY;
ALTER TABLE questions ENABLE ROW LEVEL SECURITY;

-- Create policies for team isolation
CREATE POLICY team_isolation_submissions ON submissions
FOR ALL USING (team_id IN (
SELECT team_id FROM team_members WHERE user_id = auth.uid()
));
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

RLS policy created only for submissions; extend to other team-scoped tables.

Projects and questions are listed as team-scoped but do not yet have matching policies. The omission leaves them unprotected once RLS is enabled.

-- Example for projects
CREATE POLICY team_isolation_projects ON projects
FOR ALL USING (
    team_id IN (
        SELECT team_id FROM team_members WHERE user_id = auth.uid()
    )
);

-- Same pattern for questions …
🤖 Prompt for AI Agents
In docs/multi-team-support-plan.md around lines 169 to 178, the RLS policy is
created only for the submissions table but missing for projects and questions
tables. To fix this, add equivalent CREATE POLICY statements for projects and
questions tables using the same team isolation logic, ensuring each table has a
policy restricting access based on the user's team membership.

Comment on lines +101 to +115
CREATE TABLE teams (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name TEXT NOT NULL,
slug TEXT UNIQUE NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
owner_id UUID REFERENCES users(id)
);

CREATE TABLE team_members (
team_id UUID REFERENCES teams(id) ON DELETE CASCADE,
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
role TEXT DEFAULT 'member', -- 'owner', 'admin', 'member'
joined_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
PRIMARY KEY (team_id, user_id)
);
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add an explicit CHECK constraint on role for stronger data integrity.

Defining role as free-text invites accidental typos (“admni”, “owner ”, etc.). A simple CHECK keeps the data clean and removes the need for application-side validation.

-    role TEXT DEFAULT 'member', -- 'owner', 'admin', 'member'
+    role TEXT DEFAULT 'member'
+        CHECK (role IN ('owner', 'admin', 'member')),
📝 Committable suggestion

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

Suggested change
CREATE TABLE teams (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name TEXT NOT NULL,
slug TEXT UNIQUE NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
owner_id UUID REFERENCES users(id)
);
CREATE TABLE team_members (
team_id UUID REFERENCES teams(id) ON DELETE CASCADE,
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
role TEXT DEFAULT 'member', -- 'owner', 'admin', 'member'
joined_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
PRIMARY KEY (team_id, user_id)
);
CREATE TABLE teams (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name TEXT NOT NULL,
slug TEXT UNIQUE NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
owner_id UUID REFERENCES users(id)
);
CREATE TABLE team_members (
team_id UUID REFERENCES teams(id) ON DELETE CASCADE,
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
role TEXT DEFAULT 'member'
CHECK (role IN ('owner', 'admin', 'member')),
joined_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
PRIMARY KEY (team_id, user_id)
);
🤖 Prompt for AI Agents
In docs/multi-team-support-plan.md around lines 101 to 115, the role column in
the team_members table is defined as free-text, which risks invalid values due
to typos. Add an explicit CHECK constraint on the role column to restrict its
values to 'owner', 'admin', or 'member'. Modify the table definition to include
a CHECK(role IN ('owner', 'admin', 'member')) constraint to enforce data
integrity at the database level.

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.

1 participant