import { supabase } from './supabase'; import type { Database, UserProfile, Project, Achievement, CommunityPost } from './database.types'; // User Profile Services export const userProfileService = { async getProfile(userId: string): Promise { const { data, error } = await supabase .from('user_profiles') .select('*') .eq('id', userId) .single(); if (error && error.code !== 'PGRST116') { throw error; } return data; }, async updateProfile(userId: string, updates: Partial): Promise { const { data, error } = await supabase .from('user_profiles') .update(updates) .eq('id', userId) .select() .single(); if (error) throw error; return data; }, async createProfile(profile: Omit): Promise { const { data, error } = await supabase .from('user_profiles') .insert(profile) .select() .single(); if (error) throw error; return data; }, async addInterests(userId: string, interests: string[]): Promise { const interestRows = interests.map(interest => ({ user_id: userId, interest, })); const { error } = await supabase .from('user_interests') .insert(interestRows); if (error) throw error; }, async getUserInterests(userId: string): Promise { const { data, error } = await supabase .from('user_interests') .select('interest') .eq('user_id', userId); if (error) throw error; return data.map(item => item.interest); }, }; // Project Services export const projectService = { async getUserProjects(userId: string): Promise { const { data, error } = await supabase .from('projects') .select('*') .eq('user_id', userId) .order('created_at', { ascending: false }); if (error) throw error; return data; }, async createProject(project: Omit): Promise { const { data, error } = await supabase .from('projects') .insert(project) .select() .single(); if (error) throw error; return data; }, async updateProject(projectId: string, updates: Partial): Promise { const { data, error } = await supabase .from('projects') .update(updates) .eq('id', projectId) .select() .single(); if (error) throw error; return data; }, async deleteProject(projectId: string): Promise { const { error } = await supabase .from('projects') .delete() .eq('id', projectId); if (error) throw error; }, async getAllProjects(limit = 10): Promise { const { data, error } = await supabase .from('projects') .select(` *, user_profiles ( username, full_name, avatar_url ) `) .eq('status', 'completed') .order('created_at', { ascending: false }) .limit(limit); if (error) throw error; return data; }, }; // Achievement Services export const achievementService = { async getAllAchievements(): Promise { const { data, error } = await supabase .from('achievements') .select('*') .order('xp_reward', { ascending: false }); if (error) throw error; return data; }, async getUserAchievements(userId: string): Promise { const { data, error } = await supabase .from('user_achievements') .select(` earned_at, achievements (*) `) .eq('user_id', userId) .order('earned_at', { ascending: false }); if (error) throw error; return data.map(item => item.achievements).filter(Boolean) as Achievement[]; }, async awardAchievement(userId: string, achievementId: string): Promise { const { error } = await supabase .from('user_achievements') .insert({ user_id: userId, achievement_id: achievementId, }); if (error && error.code !== '23505') { // Ignore duplicate key error throw error; } }, async checkAndAwardAchievements(userId: string): Promise { // Check for various achievement conditions const profile = await userProfileService.getProfile(userId); const projects = await projectService.getUserProjects(userId); if (!profile) return; const achievements = await this.getAllAchievements(); // Welcome achievement if (profile.full_name && profile.user_type) { const welcomeAchievement = achievements.find(a => a.name === 'Welcome to AeThex'); if (welcomeAchievement) { await this.awardAchievement(userId, welcomeAchievement.id); } } // First project achievement if (projects.length >= 1) { const firstProjectAchievement = achievements.find(a => a.name === 'First Project'); if (firstProjectAchievement) { await this.awardAchievement(userId, firstProjectAchievement.id); } } // Experienced developer achievement const completedProjects = projects.filter(p => p.status === 'completed'); if (completedProjects.length >= 5) { const experiencedAchievement = achievements.find(a => a.name === 'Experienced Developer'); if (experiencedAchievement) { await this.awardAchievement(userId, experiencedAchievement.id); } } }, }; // Community Services export const communityService = { async getPosts(limit = 10): Promise { const { data, error } = await supabase .from('community_posts') .select(` *, user_profiles ( username, full_name, avatar_url ) `) .eq('is_published', true) .order('created_at', { ascending: false }) .limit(limit); if (error) throw error; return data; }, async createPost(post: Omit): Promise { const { data, error } = await supabase .from('community_posts') .insert(post) .select() .single(); if (error) throw error; return data; }, async getUserPosts(userId: string): Promise { const { data, error } = await supabase .from('community_posts') .select('*') .eq('author_id', userId) .order('created_at', { ascending: false }); if (error) throw error; return data; }, }; // Notification Services export const notificationService = { async getUserNotifications(userId: string): Promise { const { data, error } = await supabase .from('notifications') .select('*') .eq('user_id', userId) .order('created_at', { ascending: false }) .limit(10); if (error) throw error; return data; }, async markAsRead(notificationId: string): Promise { const { error } = await supabase .from('notifications') .update({ read: true }) .eq('id', notificationId); if (error) throw error; }, async createNotification(userId: string, title: string, message?: string, type = 'info'): Promise { const { error } = await supabase .from('notifications') .insert({ user_id: userId, title, message, type, }); if (error) throw error; }, }; // Real-time subscriptions export const realtimeService = { subscribeToUserNotifications(userId: string, callback: (notification: any) => void) { return supabase .channel(`notifications:${userId}`) .on( 'postgres_changes', { event: 'INSERT', schema: 'public', table: 'notifications', filter: `user_id=eq.${userId}`, }, callback ) .subscribe(); }, subscribeToCommunityPosts(callback: (post: any) => void) { return supabase .channel('community_posts') .on( 'postgres_changes', { event: 'INSERT', schema: 'public', table: 'community_posts', filter: 'is_published=eq.true', }, callback ) .subscribe(); }, };