diff --git a/apps/api/src/db/schema.ts b/apps/api/src/db/schema.ts index 906f78d..81d1c15 100644 --- a/apps/api/src/db/schema.ts +++ b/apps/api/src/db/schema.ts @@ -61,6 +61,7 @@ export const invites = pgTable('invites', { id: uuid('id').primaryKey().defaultRandom(), email: text('email').notNull(), name: text('name').notNull(), + role: text('role').default('user'), // Role to assign on acceptance: admin, user token: text('token').notNull().unique(), invitedBy: text('invited_by').references(() => users.id, { onDelete: 'set null' }), status: inviteStatusEnum('status').default('pending').notNull(), diff --git a/apps/api/src/routes/admin.ts b/apps/api/src/routes/admin.ts index ed8cd3a..f87c9dc 100644 --- a/apps/api/src/routes/admin.ts +++ b/apps/api/src/routes/admin.ts @@ -115,6 +115,7 @@ export const adminRoutes = new Elysia({ prefix: '/admin' }) const [invite] = await db.insert(invites).values({ email: body.email, name: body.name, + role: body.role || 'user', token, invitedBy: (user as User).id, expiresAt, @@ -149,6 +150,7 @@ export const adminRoutes = new Elysia({ prefix: '/admin' }) body: t.Object({ email: t.String({ format: 'email' }), name: t.String({ minLength: 1 }), + role: t.Optional(t.Union([t.Literal('admin'), t.Literal('user')])), }), }) diff --git a/apps/api/src/routes/auth.ts b/apps/api/src/routes/auth.ts index 3016fcf..a25a4d1 100644 --- a/apps/api/src/routes/auth.ts +++ b/apps/api/src/routes/auth.ts @@ -75,6 +75,11 @@ export const authRoutes = new Elysia({ prefix: '/auth' }) }); if (newUser) { + // Set role from invite if specified + if (invite.role && invite.role !== 'user') { + await db.update(users).set({ role: invite.role }).where(eq(users.id, newUser.id)); + } + // Create default inbox project await db.insert(projects).values({ userId: newUser.id,