User Profile Management
Relevant source files
The following files were used as context for generating this wiki page:
User Profile Management in Barekey handles the lifecycle of user identities, account settings, and personal workspace routing. The system integrates Clerk for authentication and Convex for persistent user data storage, ensuring that every authenticated person has a corresponding internal record and a unique, URL-safe slug for their personal space.
The system is designed with a "Vercel/Apple-tier DX" philosophy, providing clean, minimal interfaces for account overview and management while maintaining strict data integrity through envelope encryption for sensitive assets associated with user projects.
Sources: AGENTS.md:6-10, pkg/ui/src/pages/u/user/layout.tsx:40-52
Authentication and Identity
Barekey utilizes Clerk to handle external authentication providers, including Google, GitHub, and Passkeys. The application ensures that a Convex user record exists for every signed-in Clerk user through an "ensure" mutation triggered during the initial application load or workspace navigation.
Authentication Flow
The following diagram illustrates the sequence from initial sign-in to the establishment of a local user record.
Identity Data Model
User records are stored in the users table within the Convex database. The schema includes fields for internal routing (slugs) and public-facing profile information.
| Field | Type | Description |
|---|---|---|
clerkUserId | string | The unique identifier from the Clerk identity provider. |
slug | string | Unique URL-safe identifier (e.g., johndoe1234). |
slugBase | string | The normalized base string used to generate the slug. |
email | string | null | The primary email address associated with the account. |
displayName | string | null | The user's preferred name or nickname. |
imageUrl | string | null | URL to the user's profile picture. |
lastSeenAtMs | number | Timestamp of the user's last interaction with the platform. |
Sources: pkg/convex/users.ts:40-48, pkg/convex/users.ts:114-124
Slug Generation and Reservation
Barekey implements a robust slug generation strategy to ensure every user has a unique path under /u/:userSlug. Slugs are derived from the user's email local part or full name and normalized to alphanumeric characters.
Normalization Logic
Slugs are normalized to lowercase a-z0-9 characters. If a derived base matches a reserved keyword, the system appends "user" to the base to avoid routing conflicts.
Sources: pkg/convex/users.ts:24-38, pkg/ui/src/lib/slugs.ts:28-44
Reserved Keywords
The system prevents users from claiming slugs that conflict with system routes:
auth,api,admino,u,orgsnew,select,settingsme,support,helplogin,signup,account,dashboard
Sources: pkg/convex/users.ts:8-19, pkg/ui/src/lib/slugs.ts:3-18
Collision Resolution
When creating a new user, the system attempts to allocate a unique slug by appending a 4-digit or 6-digit numeric suffix. It performs up to 12 attempts per suffix length to find a non-colliding entry in the users table.
Sources: pkg/convex/users.ts:85-110, pkg/ui/src/lib/slugs.ts:68-71
User Interface and Routing
The user profile is managed within a dedicated layout located at /u/[userSlug]. This layout includes a sidebar for navigation between account-specific pages like the Overview.
User Dashboard Layout
The dashboard provides a consistent navigation experience and validates that the authenticated user's slug matches the URL parameters.
Account Overview
The Overview page displays the current status and profile details extracted from the user record. It shows the user's display name and email address.
Sources: pkg/ui/src/pages/u/user/overview/page.tsx:15-38
Component Architecture
The profile management system relies on several key frontend and backend components:
| Component | Responsibility |
|---|---|
Layout (u/user/layout.tsx) | Manages user-specific navigation, sidebar, and route protection. |
ensureCurrentUser | Mutation that synchronizes Clerk session data with the Convex users table. |
useEnsureCurrentUserRecord | A hook used throughout the app to verify the local user record exists. |
normalizeBase | Function to sanitize strings for slug creation (alphanumeric only). |
SidebarUserMenu | A dropdown component in the organization layout for accessing user settings. |
Sources: pkg/ui/src/pages/u/user/layout.tsx:32-34, pkg/convex/users.ts:51, pkg/ui/src/lib/slugs.ts:28, pkg/ui/src/pages/o/[org]/layout.tsx:136-150
Implementation Details
Mutation: ensureCurrentUser
This function is critical for user onboarding and session updates. It updates the user's lastSeenAtMs and synchronization fields on every call.
// From pkg/convex/users.ts:51-125
export const ensureCurrentUser = mutation({
args: {},
returns: userRecordValidator,
handler: async (ctx) => {
const identity = await requireIdentity(ctx);
const now = Date.now();
const clerkUserId = identity.subject;
// ... logic to query existing user or insert new ...
if (existingUser) {
await ctx.db.patch(existingUser._id, {
email,
displayName,
imageUrl,
updatedAtMs: now,
lastSeenAtMs: now,
});
return { ...existingUser, email, displayName, imageUrl };
}
// ... slug generation and insertion for new users ...
},
});
Sources: pkg/convex/users.ts:51-125
The User Profile Management system ensures that Barekey remains a user-centric platform where identities are automatically provisioned, uniquely identified via URL-safe slugs, and kept in sync with third-party authentication providers. This foundation supports organization membership and project ownership across the platform.
Sources: AGENTS.md:38-40, pkg/ui/src/pages/u/user/layout.tsx:100-110