Profile System Overview
Profiles provide complete isolation between different groups of users:- Separate media libraries - Each profile has its own collection of movies and TV shows
- Member-based access - Users must be members of a profile to access its content
- Admin-managed - Only the global admin can create profiles
- Multi-membership - Users can be members of multiple profiles
Database Schema
The profile system uses three core tables (src/lib/server/db/schema.ts):
Organization Table
Stores profile configuration (src/lib/server/db/schema.ts:26-40):
| Field | Type | Description |
|---|---|---|
id | text | Primary key |
name | text | Display name |
slug | text | Unique URL-friendly identifier |
logo | text | Optional logo URL |
color | text | Profile theme color (default: #6366F1) |
metadata | text | JSON field for additional data |
createdAt | timestamp | Creation timestamp |
updatedAt | timestamp | Last update timestamp |
Member Table
Tracks user memberships (src/lib/server/db/schema.ts:117-133):
| Field | Type | Description |
|---|---|---|
id | text | Primary key |
userId | text | Foreign key to user |
organizationId | text | Foreign key to organization |
role | text | Member role (default: member) |
createdAt | timestamp | Membership start timestamp |
(userId, organizationId).
Invitation Table
Manages pending profile invitations (src/lib/server/db/schema.ts:135-154):
| Field | Type | Description |
|---|---|---|
id | text | Primary key |
email | text | Invitee email address |
inviterId | text | User who sent the invitation |
organizationId | text | Profile being invited to |
role | text | Role to assign (default: member) |
status | text | Invitation status (default: pending) |
expiresAt | timestamp | Expiration timestamp |
createdAt | timestamp | Creation timestamp |
updatedAt | timestamp | Last update timestamp |
Creating Profiles
Only users with theadmin role can create profiles (src/lib/server/auth.ts:58-66):
Sign in as admin
Ensure you’re logged in with an account that has the
admin role. The first registered user is automatically promoted to admin.Navigate to profile management
Go to
/profiles/manage to access the profile management interface. This page is admin-only (src/routes/(app)/profiles/manage/+page.server.ts:12-15).Create new profile
Provide the required profile information:
- Name - Display name for the profile
- Slug - Unique URL-friendly identifier
- Logo (optional) - Image URL for the profile avatar
- Color (optional) - Hex color code for theming (defaults to
#6366F1)
Profile Selection
When users sign in, they’re redirected to/profiles to select which profile to use (src/routes/(app)/profiles/+page.server.ts:7-53).
Profile Display Logic
- Admin users see all profiles with a “Manage” option
- Standard users see all profiles but can only access those they’re members of
- No profiles exist - Admins are redirected to
/onboardingto set up the instance
Active Profile Tracking
The selected profile is stored in the user’s session asactiveOrganizationId (src/lib/server/db/schema.ts:59-61):
Managing Members
Members are users who have access to a specific profile’s media library.Member Roles
Themember table includes a role field (defaulting to member). While better-auth supports custom roles, Plank’s current implementation uses a simple member system.
Adding Members via Invitation
Admins and profile owners can invite users by email:Send invitation
Create an invitation with:
- Target email address
- Profile to invite them to
- Role to assign (default:
member) - Expiration time
pending.User receives invitation
The invitee receives an email with an invitation link containing the invitation ID.
Accept invitation
When the user clicks the link, they’re directed to
/accept-invitation/[id] (src/routes/accept-invitation/[id]/+page.server.ts).If not logged in, they’re redirected to /login with a return URL.Invitation Acceptance Flow
The invitation acceptance handler (src/routes/accept-invitation/[id]/+page.server.ts:5-39):
Media Isolation
Each media item is scoped to an organization via theorganizationId field (src/lib/server/db/schema.ts:167):
Unique Constraint
Themedia table enforces unique content per profile using a composite unique index (src/lib/server/db/schema.ts:197):
Profile Statistics
Profile pages display member counts by aggregating themember table (src/routes/(app)/profiles/manage/+page.server.ts:20-29):
- Total member count per profile
- User’s membership status
- Access control visibility
Access Control
Admin Privileges
Admins have special access (src/lib/server/auth.ts:58-66):
- Create new profiles
- View all profiles at
/profiles/manage - Manage members across all profiles
Standard User Access
Standard users:- See all profiles but only access those they’re members of
- Cannot create new profiles
- Must be invited to join profiles
Onboarding Flow
When a fresh instance has no profiles, admins are automatically redirected to/onboarding (src/routes/(app)/profiles/+page.server.ts:17-20):