Rewrite achievement service with live Supabase only
cgen-d394e95e3d044de08e8ebd9a4a72699c
This commit is contained in:
parent
4fe07bc717
commit
fc1fbe2a98
1 changed files with 19 additions and 61 deletions
|
|
@ -568,9 +568,7 @@ export const aethexProjectService = {
|
||||||
// Achievement Services (Supabase only)
|
// Achievement Services (Supabase only)
|
||||||
export const aethexAchievementService = {
|
export const aethexAchievementService = {
|
||||||
async getAllAchievements(): Promise<AethexAchievement[]> {
|
async getAllAchievements(): Promise<AethexAchievement[]> {
|
||||||
if (!isSupabaseConfigured) {
|
ensureSupabase();
|
||||||
return fallbackAchievementCatalog.map((achievement) => ({ ...achievement }));
|
|
||||||
}
|
|
||||||
|
|
||||||
const { data, error } = await supabase
|
const { data, error } = await supabase
|
||||||
.from("achievements")
|
.from("achievements")
|
||||||
|
|
@ -585,13 +583,7 @@ export const aethexAchievementService = {
|
||||||
},
|
},
|
||||||
|
|
||||||
async getUserAchievements(userId: string): Promise<AethexAchievement[]> {
|
async getUserAchievements(userId: string): Promise<AethexAchievement[]> {
|
||||||
if (!isSupabaseConfigured) {
|
ensureSupabase();
|
||||||
const unlocked = fallbackUserAchievements.get(userId);
|
|
||||||
if (!unlocked) return [];
|
|
||||||
return Array.from(unlocked)
|
|
||||||
.map((achievementId) => fallbackAchievementsById.get(achievementId))
|
|
||||||
.filter((value): value is AethexAchievement => Boolean(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
const { data, error } = await supabase
|
const { data, error } = await supabase
|
||||||
.from("user_achievements")
|
.from("user_achievements")
|
||||||
|
|
@ -613,22 +605,7 @@ export const aethexAchievementService = {
|
||||||
},
|
},
|
||||||
|
|
||||||
async awardAchievement(userId: string, achievementId: string): Promise<void> {
|
async awardAchievement(userId: string, achievementId: string): Promise<void> {
|
||||||
if (!isSupabaseConfigured) {
|
ensureSupabase();
|
||||||
const achievement =
|
|
||||||
fallbackAchievementsById.get(achievementId) ||
|
|
||||||
fallbackAchievementsByName.get(achievementId);
|
|
||||||
if (!achievement) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const current = fallbackUserAchievements.get(userId) ?? new Set<string>();
|
|
||||||
if (!current.has(achievement.id)) {
|
|
||||||
current.add(achievement.id);
|
|
||||||
fallbackUserAchievements.set(userId, current);
|
|
||||||
await this.updateUserXPAndLevel(userId, achievement.xp_reward ?? 0);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { data: achievement, error: fetchError } = await supabase
|
const { data: achievement, error: fetchError } = await supabase
|
||||||
.from("achievements")
|
.from("achievements")
|
||||||
|
|
@ -640,6 +617,10 @@ export const aethexAchievementService = {
|
||||||
throw fetchError;
|
throw fetchError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!achievement) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const { error } = await supabase.from("user_achievements").insert({
|
const { error } = await supabase.from("user_achievements").insert({
|
||||||
user_id: userId,
|
user_id: userId,
|
||||||
achievement_id: achievementId,
|
achievement_id: achievementId,
|
||||||
|
|
@ -655,24 +636,7 @@ export const aethexAchievementService = {
|
||||||
},
|
},
|
||||||
|
|
||||||
async updateUserXPAndLevel(userId: string, xpGained: number | null = null): Promise<void> {
|
async updateUserXPAndLevel(userId: string, xpGained: number | null = null): Promise<void> {
|
||||||
if (!isSupabaseConfigured) {
|
ensureSupabase();
|
||||||
const xpDelta = xpGained ?? 0;
|
|
||||||
const currentProfile = (await mockAuth.getUserProfile(userId)) as any;
|
|
||||||
const currentXP = currentProfile?.total_xp ?? 0;
|
|
||||||
const newTotalXP = currentXP + xpDelta;
|
|
||||||
const newLevel = Math.floor(newTotalXP / 1000) + 1;
|
|
||||||
const newLoyaltyPoints = (currentProfile?.loyalty_points ?? 0) + xpDelta;
|
|
||||||
|
|
||||||
await mockAuth.updateProfile(
|
|
||||||
userId,
|
|
||||||
{
|
|
||||||
total_xp: newTotalXP,
|
|
||||||
level: newLevel,
|
|
||||||
loyalty_points: newLoyaltyPoints,
|
|
||||||
} as any,
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { data: profile, error } = await supabase
|
const { data: profile, error } = await supabase
|
||||||
.from("user_profiles")
|
.from("user_profiles")
|
||||||
|
|
@ -704,27 +668,13 @@ export const aethexAchievementService = {
|
||||||
.from("user_profiles")
|
.from("user_profiles")
|
||||||
.update(updates)
|
.update(updates)
|
||||||
.eq("id", userId);
|
.eq("id", userId);
|
||||||
|
|
||||||
if (updateError) throw updateError;
|
if (updateError) throw updateError;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async checkAndAwardOnboardingAchievement(userId: string): Promise<void> {
|
async checkAndAwardOnboardingAchievement(userId: string): Promise<void> {
|
||||||
const awardDirectly = async () => {
|
ensureSupabase();
|
||||||
const names = ["Welcome to AeThex", "AeThex Explorer"];
|
|
||||||
const achievements = await this.getAllAchievements();
|
|
||||||
const byName = new Map(achievements.map((item) => [item.name, item.id] as const));
|
|
||||||
|
|
||||||
for (const name of names) {
|
|
||||||
const id = byName.get(name);
|
|
||||||
if (!id) continue;
|
|
||||||
await this.awardAchievement(userId, id);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!isSupabaseConfigured) {
|
|
||||||
await awardDirectly();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const resp = await fetch(`/api/achievements/award`, {
|
const resp = await fetch(`/api/achievements/award`, {
|
||||||
|
|
@ -743,7 +693,15 @@ export const aethexAchievementService = {
|
||||||
console.warn("Edge function award failed, attempting direct Supabase insert", error);
|
console.warn("Edge function award failed, attempting direct Supabase insert", error);
|
||||||
}
|
}
|
||||||
|
|
||||||
await awardDirectly();
|
const achievements = await this.getAllAchievements();
|
||||||
|
const byName = new Map(achievements.map((item) => [item.name, item.id] as const));
|
||||||
|
const names = ["Welcome to AeThex", "AeThex Explorer"];
|
||||||
|
|
||||||
|
for (const name of names) {
|
||||||
|
const id = byName.get(name);
|
||||||
|
if (!id) continue;
|
||||||
|
await this.awardAchievement(userId, id);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async checkAndAwardProjectAchievements(userId: string): Promise<void> {
|
async checkAndAwardProjectAchievements(userId: string): Promise<void> {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue