Skip to main content

Profile API

The Profile API provides functions for managing user profiles, builder profiles, and related authentication and permission systems.

Implementation Status

Current State: Partially implementing StandardApiResponse patterns
Type System: Unified BuilderProfileData in progress
Authentication: Clerk-based with role management
Validation: ValidationTier unified with marketplace domain

Core Features Confirmed

  • Builder Profile Management: Fetching and updating builder profile data
  • Authentication Integration: Clerk-based profile access control
  • Permission Management: Owner/admin/public access patterns
  • Role Management: CLIENT, BUILDER, ADMIN, SUBSCRIBER roles
  • Validation Tier Integration: Using marketplace ValidationTier enum

API Response Structure

StandardApiResponse Pattern (In Progress)

Target Structure (from Mintlify docs):
interface StandardApiResponse<T> {
  success: boolean;
  data?: T;
  error?: ApiError;
  metadata?: ResponseMetadata;
}

export interface BuilderProfileResponseData {
  // User information (flattened)
  userId: string;
  clerkId?: string;
  email: string;
  name?: string;
  
  // Profile information (unified)
  id: string;
  bio?: string;
  headline?: string;
  slug?: string;
  tagline?: string;
  displayName?: string;
  title?: string; // Component compatibility
  validationTier: number; // Marketplace enum values (1,2,3)
  domains: string[];
  badges: string[];
  completedProjects: number;
  topSkills: string[];
  portfolioItems: any[];
  // ... additional properties
  
  // Component compatibility
  avatar?: { url: string; alt?: string };
  specializations?: string[];
  permissions?: ProfilePermissions;
}

Core API Functions (Verified)

getUserProfile()

Location: /lib/profile/actions.ts
Type: Server Action
Authentication: Required
export async function getUserProfile(
  profileId: string
): Promise<{ user?: UserData; error?: string }>
Current Issues:
  • Returns different structure than BuilderProfileResponseData
  • Requires manual transformation for component consumption

Profile Data Service Functions

Location: /lib/profile/data-service.ts
Access: Server-side only
Functions include profile creation, updates, and data retrieval with proper database integration.

Type Definitions (Session 11 Status)

Core Profile Types

Source of Truth: /lib/profile/types.ts
// ✅ STANDARDIZED - Unified interface
export interface BuilderProfileData {
  id: string;
  bio?: string;
  headline?: string;
  slug?: string;
  tagline?: string;
  displayName?: string;
  name?: string; // Component compatibility
  title?: string; // Component compatibility  
  validationTier: number; // ✅ Uses marketplace ValidationTier
  domains: string[];
  badges: string[];
  completedProjects: number;
  responseRate?: number;
  hourlyRate?: number;
  availableForHire: boolean;
  adhd_focus: boolean;
  expertiseAreas: Record<string, any>;
  socialLinks: Record<string, string>;
  portfolioItems: any[];
  featured: boolean;
  searchable: boolean;
  availability: string; // ✅ CONFIRMED: String type, not object
  topSkills: string[];
  
  // Optional component compatibility
  avatarUrl?: string;
  coverImageUrl?: string;
  joinDate?: Date;
  rating?: number;
}

// ✅ STANDARDIZED - For API responses
export interface BuilderProfileResponseData extends BuilderProfileData {
  // User info
  userId: string;
  clerkId?: string;
  email: string;
  
  // Additional component properties
  avatar?: { url: string; alt?: string };
  specializations?: string[];
  sessionTypes?: SessionTypeWithId[];
  permissions?: ProfilePermissions;
}

// ✅ STANDARDIZED - Permission system
export interface ProfilePermissions {
  canView: boolean;
  canEdit: boolean;
  canDelete: boolean;
  canVerify: boolean;
}

ValidationTier Integration

✅ COMPLETED: ValidationTier unification with marketplace domain
// Source of truth
import { ValidationTier } from '@/lib/marketplace/types';

// Conversion utilities  
import { 
  validationTierToString, 
  stringToValidationTier,
  getValidationTierStyle 
} from '@/lib/utils/type-converters';

// Usage in components
const tierString = validationTierToString(profile.validationTier);
<ValidationTierBadge tier={tierString} />

User Role System

✅ COMPLETED: Enhanced role support
// User roles (using Prisma enum)
export enum UserRole {
  CLIENT = "CLIENT",
  BUILDER = "BUILDER", 
  ADMIN = "ADMIN",
  SUBSCRIBER = "SUBSCRIBER" // ✅ ADDED in Session 11
}

Component Integration Patterns

Profile Wrapper Pattern

✅ STANDARDIZED: BuilderProfileWrapper following Mintlify patterns
// Correct usage pattern
export function BuilderProfileWrapper({ 
  profileId, 
  isPublicView = false,
  profile: providedProfile 
}: BuilderProfileWrapperProps) {
  const [profile, setProfile] = useState(providedProfile);
  
  // Direct type compatibility - no adapters needed ✅
  return (
    <div>
      <BuilderProfile profile={profile} />
    </div>
  );
}

Component Prop Standards

Following Mintlify documentation:
// Base component interface
export interface ProfileComponentProps extends BaseComponentProps {
  profileId?: string;
  userId?: string;
  isPublicView?: boolean;
  profile?: BuilderProfileData;
}

// Specific implementations
export interface BuilderProfileWrapperProps extends 
  ProfileComponentProps,
  LoadableProps {
  userRole?: UserRole;
  authContext?: ProfileAuthContext;
}

Known API Issues (Session 12 Priority)

🚨 Critical Import/Export Issues

// ❌ BROKEN: These imports fail after Session 11 changes
import { BuilderProfileData } from '@/components/profile/builder-profile';

// Affected files:
// - lib/contexts/profile-context.tsx:4
// - lib/utils/profile-form-helpers.ts:3

// ✅ SOLUTION: Update imports to use unified types
import { BuilderProfileData } from '@/lib/profile/types';

⚠️ API Standardization Gaps

  1. Inconsistent Response Formats: Not all profile endpoints follow StandardApiResponse pattern
  2. Manual Data Transformation: Some pages manually create BuilderProfile objects
  3. Property Mismatches: Existing API routes may return different field names

Data Mapping Issues

Problem: API responses don’t always match component expectations
// Current: Manual transformation required
const transformedProfile: BuilderProfileData = {
  id: user.id,
  name: user.name,
  // ... manual field mapping
};

// Target: Direct API compatibility
const profileResponse = await getBuilderProfileById(id);
const profile = profileResponse.data; // ✅ Direct usage

Authentication Integration

Current Auth Patterns

Clerk Integration: Profile access control through Clerk authentication
// ✅ CORRECT: Updated auth hook usage
const { isLoaded, isSignedIn, user } = useUser();

// ❌ DEPRECATED: Old auth properties  
const { isLoading, isAuthenticated } = useAuth();

Permission System

Access Control: Implemented through ProfilePermissions interface
export interface ProfilePermissions {
  canView: boolean;    // Public or authenticated access
  canEdit: boolean;    // Owner or admin
  canDelete: boolean;  // Owner or admin  
  canVerify: boolean;  // Admin only
}

Missing Features & Future Considerations

Features Temporarily Disabled

During type unification, these features were temporarily disabled:
// ❌ TEMPORARILY REMOVED from unified interface
interface BuilderProfileDataLegacy {
  apps?: AppItem[];           // App showcase functionality
  metrics?: MetricsCategory[]; // Detailed metrics dashboard
  roles?: UserRole[];         // Multi-role display
  isDemo?: boolean;           // Demo account flagging
  sessionTypes?: SessionType[]; // Direct session integration
}
Evaluation Needed: Determine which features should be:
  • Re-integrated into unified interface
  • Kept as separate optional features
  • Permanently removed

API Endpoints Requiring Standardization

  1. Profile Creation/Update: Apply StandardApiResponse pattern
  2. Profile Search: Implement consistent filtering
  3. Profile Analytics: Standardize metrics endpoints
  4. Profile Permissions: Consistent access control

Migration Guidelines

For API Route Updates

// ✅ TARGET: Standardized response format
export async function GET(request: NextRequest) {
  try {
    const profileData = await getBuilderProfileById(id);
    
    return NextResponse.json({
      success: true,
      data: profileData, // BuilderProfileResponseData
      metadata: { /* pagination, etc */ }
    } satisfies StandardApiResponse<BuilderProfileResponseData>);
  } catch (error) {
    return NextResponse.json({
      success: false,
      error: {
        code: 'profile_not_found',
        message: 'Profile could not be found'
      }
    } satisfies StandardApiResponse);
  }
}

For Component Updates

// ✅ CORRECT: Direct API consumption
const profileResponse = await getBuilderProfileById(id);
if (profileResponse.success && profileResponse.data) {
  // Direct usage - no transformation needed
  return <BuilderProfile profile={profileResponse.data} />;
}

// ❌ AVOID: Data adaptation layers
const adaptedProfile = adaptProfileData(rawData);

Testing Patterns

Profile Component Testing

Verified Patterns from Session 11:
// Mock profile data using unified interface
const mockProfile: BuilderProfileData = {
  id: 'test-profile',
  validationTier: ValidationTier.EXPERT, // Use marketplace enum
  topSkills: ['React', 'TypeScript'],
  portfolioItems: [],
  // ... full interface compliance
};

describe('ProfileComponent', () => {
  it('renders with unified profile data', () => {
    render(<BuilderProfile profile={mockProfile} />);
    // Assertions using standardized interface
  });
});

See Also

Session 12 Focus Areas

Primary: Fix BuilderProfileData import breakage and complete API standardization
Secondary: Re-evaluate temporarily disabled features for inclusion
Future: Complete migration to StandardApiResponse pattern across all profile endpoints