-
-
Notifications
You must be signed in to change notification settings - Fork 439
✨ Add space member model #1780
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
✨ Add space member model #1780
Conversation
✨ Space members migration
The latest updates on your projects. Learn more about Vercel for Git ↗︎
1 Skipped Deployment
|
""" WalkthroughThe changes introduce new database structures and relationships for managing spaces and their members. A new enum, tables, and models are added to represent spaces and memberships, with appropriate indexes and foreign key constraints. Existing spaces are backfilled with owner memberships. The user model is updated to support these new relationships. User creation logic is refactored to centralize creation with associated default personal space and membership. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant AuthRouter
participant UserMutations
participant PrismaDB
Client->>AuthRouter: authenticateRegistration(data)
AuthRouter->>UserMutations: createUser(data)
UserMutations->>PrismaDB: Begin transaction
UserMutations->>PrismaDB: Create user record
UserMutations->>PrismaDB: Create "Personal" space owned by user
UserMutations->>PrismaDB: Create space member record with role OWNER
UserMutations->>PrismaDB: Commit transaction
UserMutations-->>AuthRouter: Return created user (id, name, email)
AuthRouter-->>Client: Return user info
sequenceDiagram
participant Client
participant SpacesMutations
participant PrismaDB
Client->>SpacesMutations: createSpace({ownerId, name})
SpacesMutations->>PrismaDB: Create space record
SpacesMutations->>PrismaDB: Create space member record with role OWNER
SpacesMutations-->>Client: Return created space
Possibly related PRs
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms (1)
✨ Finishing Touches
🧪 Generate Unit Tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed 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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Nitpick comments (1)
packages/database/prisma/models/user.prisma (1)
61-63
: Explicit relation naming for clarity
You’ve linkedspaces Space[] @relation("UserSpaces")
to matchSpace.owner
. FormemberOf SpaceMember[]
, consider adding an explicit@relation
name (e.g.@relation("SpaceMemberToUser")
) to tie it unambiguously toSpaceMember.user
.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
packages/database/prisma/migrations/20250616140319_create_space_members/migration.sql
(1 hunks)packages/database/prisma/migrations/20250616140359_space_members_migration/migration.sql
(1 hunks)packages/database/prisma/models/space.prisma
(1 hunks)packages/database/prisma/models/user.prisma
(2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Integration tests
🔇 Additional comments (5)
packages/database/prisma/models/space.prisma (2)
1-17
: Relation and mapping fields look good
TheSpace
model correctly maps snake-cased columns via@map
, uses@default(uuid())
for IDs, and sets up theowner
relation withonDelete: Cascade
. IndexingownerId
with a hash is appropriate for fast owner‐space lookups.
19-23
: Enum definition is correct
SpaceMemberRole
enumerates exactly the roles needed (OWNER
,ADMIN
,MEMBER
) with clear naming.packages/database/prisma/migrations/20250616140319_create_space_members/migration.sql (3)
1-4
: Enum creation is correct
TheSpaceMemberRole
enum is created before any table references it—order is correct.
16-21
: Indexes and unique constraints are properly defined
You’ve added both the single‐column index onspace_id
and the unique composite index on(space_id, user_id)
, matching the Prisma schema’s intent.
23-27
: Foreign keys with cascading actions look good
Both FK constraints includeON DELETE CASCADE
andON UPDATE CASCADE
, ensuring referential integrity on space and user removals/updates.
packages/database/prisma/migrations/20250616140359_space_members_migration/migration.sql
Show resolved
Hide resolved
packages/database/prisma/migrations/20250616140319_create_space_members/migration.sql
Show resolved
Hide resolved
There was a problem hiding this 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 (3)
apps/web/src/features/spaces/mutations.ts (2)
14-18
: Avoid magic string for role – prefer the generated enumUsing a raw string literal makes refactors error-prone and bypasses type-safety. Leverage the generated Prisma enum instead:
-import { prisma } from "@rallly/database"; +import { prisma, SpaceMemberRole } from "@rallly/database"; ... - role: "OWNER", + role: SpaceMemberRole.OWNER,If
SpaceMemberRole
is re-exported from another module, import from that path instead.
3-9
: Add lightweight validation for the public API surface
createSpace
currently trusts its caller. A stray emptyname
or undefinedownerId
would raise a DB error. Guard early (e.g. with a small Zod schema):export async function createSpace({ ownerId, name, }: { ownerId: string; name: string; }) { + if (!ownerId) throw new Error("ownerId is required"); + if (!name?.trim()) throw new Error("name cannot be empty"); +This keeps boundary checks close to the mutation and returns clearer errors to the caller.
apps/web/src/features/user/mutations.ts (1)
22-53
: Prefer enum constants over string literals for rolesHard-coded role strings (
"user"
&"OWNER"
) sidestep compile-time checks. Import the generated enums:-import { type TimeFormat, prisma } from "@rallly/database"; +import { type TimeFormat, prisma, SpaceMemberRole, UserRole } from "@rallly/database"; ... - role: "user", + role: UserRole.USER, ... - role: "OWNER", + role: SpaceMemberRole.OWNER,This prevents typos and guarantees sync with future schema changes.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
apps/web/src/auth/adapters/prisma.ts
(2 hunks)apps/web/src/features/spaces/mutations.ts
(1 hunks)apps/web/src/features/user/mutations.ts
(1 hunks)apps/web/src/trpc/routers/auth.ts
(3 hunks)
🧰 Additional context used
🧠 Learnings (1)
apps/web/src/auth/adapters/prisma.ts (1)
Learnt from: lukevella
PR: lukevella/rallly#1776
File: apps/web/src/auth/adapters/prisma.ts:40-60
Timestamp: 2025-06-14T16:32:39.947Z
Learning: In the Rallly authentication system, data migration (via options.migrateData) happens at login time, not during user creation. The createUser method in CustomPrismaAdapter should not call migrateData.
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Integration tests
🔇 Additional comments (1)
apps/web/src/auth/adapters/prisma.ts (1)
42-50
: Confirm type compatibility betweencreateUser
return andAdapterUser
createUser
returns the raw PrismaUser
, which contains extra fields (role
, etc.) thatnext-auth
’sAdapterUser
omits. Ensure downstream code (and JSON serialization) tolerates these extras or cast explicitly:const rawUser = await createUser({...}); return rawUser as unknown as AdapterUser; // or pick the needed fieldsFailing to align the types can surface subtle runtime issues when
next-auth
serialises the session.
Summary by CodeRabbit
New Features
Bug Fixes
Style