mirror of
https://github.com/mito-systems/ranger-app.git
synced 2026-03-09 04:04:07 +00:00
points
This commit is contained in:
parent
29c6f9389b
commit
7239fd45f4
@ -134,22 +134,23 @@ export async function awardPointsForImage(
|
||||
};
|
||||
}
|
||||
|
||||
// If userId is an email, use it for consistent storage
|
||||
if (userId.includes('@')) {
|
||||
console.log('userId is an email, using it as the email field');
|
||||
// But keep the userId as is for consistent UUID generation
|
||||
// Log what email and userId we're starting with
|
||||
console.log('Award points starting values:', { userId, email });
|
||||
|
||||
// Make sure we have a valid email - NOT a generated one
|
||||
if (email === 'unknown@example.com' || email.endsWith('@user.wildlife.app')) {
|
||||
console.log('WARNING: Using a synthetic email address:', email);
|
||||
}
|
||||
|
||||
// If email is missing but userId looks like an email, use that
|
||||
if (!email && userId.includes('@')) {
|
||||
email = userId;
|
||||
console.log('Using userId as email since it contains @:', email);
|
||||
}
|
||||
|
||||
// Ensure we have a valid email
|
||||
// Always prefer the email parameter directly from the authentication system
|
||||
if (!email || email === 'unknown@example.com') {
|
||||
email = userId.includes('@') ? userId : `${userId}@user.wildlife.app`;
|
||||
console.log('Generated proper email for points system:', email);
|
||||
if (userId.includes('@')) {
|
||||
email = userId;
|
||||
console.log('Using userId as email since it looks like an email:', email);
|
||||
} else {
|
||||
// This should be very rare - only if both auth email and userId are invalid
|
||||
console.log('WARNING: Both userId and email are invalid or missing');
|
||||
}
|
||||
}
|
||||
|
||||
// Convert userId to UUID format
|
||||
@ -201,38 +202,87 @@ export async function awardPointsForImage(
|
||||
|
||||
console.log('Creating point transaction for user:', userIdUUID);
|
||||
|
||||
// Try to create transaction using RPC first with admin client
|
||||
const { data: transactionData, error: rpcError } = await supabaseAdmin
|
||||
.rpc('create_point_transaction', {
|
||||
user_id_param: userIdUUID,
|
||||
points_param: POINTS.IMAGE_UPLOAD,
|
||||
transaction_type_param: 'image_upload',
|
||||
image_hash_param: imageHash,
|
||||
image_url_param: imageUrl,
|
||||
description_param: description,
|
||||
animal_type_param: animalType
|
||||
});
|
||||
|
||||
if (rpcError) {
|
||||
console.log('Info: Could not create transaction via RPC, trying direct insert:', rpcError.message);
|
||||
|
||||
// Fallback to direct insert with admin client
|
||||
console.log('Attempting direct insert for transaction...');
|
||||
const { error: transactionError } = await supabaseAdmin
|
||||
.from('point_transactions')
|
||||
.insert({
|
||||
user_id: userIdUUID,
|
||||
points: POINTS.IMAGE_UPLOAD,
|
||||
transaction_type: 'image_upload',
|
||||
image_hash: imageHash,
|
||||
image_url: imageUrl,
|
||||
description,
|
||||
animal_type: animalType,
|
||||
created_at: new Date().toISOString()
|
||||
// We'll try these approaches in sequence, with detailed logging
|
||||
let transactionCreated = false;
|
||||
|
||||
// 1. Try to create transaction using RPC first with admin client
|
||||
try {
|
||||
console.log('Attempting to create transaction via RPC...');
|
||||
const { data: transactionData, error: rpcError } = await supabaseAdmin
|
||||
.rpc('create_point_transaction', {
|
||||
user_id_param: userIdUUID,
|
||||
points_param: POINTS.IMAGE_UPLOAD,
|
||||
transaction_type_param: 'image_upload',
|
||||
image_hash_param: imageHash,
|
||||
image_url_param: imageUrl,
|
||||
description_param: description,
|
||||
animal_type_param: animalType
|
||||
});
|
||||
|
||||
if (transactionError) {
|
||||
console.warn('Direct transaction insert also failed:', transactionError.message);
|
||||
|
||||
if (!rpcError) {
|
||||
console.log('Successfully created transaction via RPC:', transactionData);
|
||||
transactionCreated = true;
|
||||
} else {
|
||||
console.log('Could not create transaction via RPC:', rpcError.message);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Exception in RPC transaction creation:', error);
|
||||
}
|
||||
|
||||
// 2. Fallback to direct insert with admin client
|
||||
if (!transactionCreated) {
|
||||
try {
|
||||
console.log('Attempting direct insert for transaction...');
|
||||
const { data: insertData, error: transactionError } = await supabaseAdmin
|
||||
.from('point_transactions')
|
||||
.insert({
|
||||
user_id: userIdUUID,
|
||||
points: POINTS.IMAGE_UPLOAD,
|
||||
transaction_type: 'image_upload',
|
||||
image_hash: imageHash,
|
||||
image_url: imageUrl,
|
||||
description,
|
||||
animal_type: animalType
|
||||
})
|
||||
.select()
|
||||
.single();
|
||||
|
||||
if (transactionError) {
|
||||
console.warn('Direct transaction insert failed:', transactionError.message);
|
||||
} else {
|
||||
console.log('Successfully created transaction via direct insert:', insertData);
|
||||
transactionCreated = true;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Exception in direct transaction insert:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Last resort insert with minimal fields
|
||||
if (!transactionCreated) {
|
||||
try {
|
||||
console.log('Attempting minimal transaction insert as last resort...');
|
||||
const { error: minimalError } = await supabaseAdmin
|
||||
.from('point_transactions')
|
||||
.insert({
|
||||
user_id: userIdUUID,
|
||||
points: POINTS.IMAGE_UPLOAD,
|
||||
transaction_type: 'image_upload',
|
||||
image_hash: imageHash
|
||||
});
|
||||
|
||||
if (minimalError) {
|
||||
console.warn('Even minimal transaction insert failed:', minimalError.message);
|
||||
return {
|
||||
success: false,
|
||||
message: 'Failed to record points transaction after multiple attempts'
|
||||
};
|
||||
} else {
|
||||
console.log('Successfully created minimal transaction');
|
||||
transactionCreated = true;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Exception in minimal transaction insert:', error);
|
||||
return {
|
||||
success: false,
|
||||
message: 'Failed to record points transaction'
|
||||
@ -245,44 +295,89 @@ export async function awardPointsForImage(
|
||||
|
||||
let pointsUpdated = false;
|
||||
|
||||
// Try RPC method first with admin client
|
||||
const { error: updateError } = await supabaseAdmin.rpc('increment_user_points', {
|
||||
user_id_param: userIdUUID,
|
||||
points_param: POINTS.IMAGE_UPLOAD
|
||||
});
|
||||
|
||||
if (!updateError) {
|
||||
pointsUpdated = true;
|
||||
} else {
|
||||
console.log('Info: Could not update points via RPC, trying direct update:', updateError.message);
|
||||
|
||||
// Fallback: Direct update with admin client
|
||||
// 1. Try RPC method first with admin client
|
||||
try {
|
||||
console.log('Attempting to update points via RPC...');
|
||||
const { data: rpcData, error: updateError } = await supabaseAdmin.rpc('increment_user_points', {
|
||||
user_id_param: userIdUUID,
|
||||
points_param: POINTS.IMAGE_UPLOAD
|
||||
});
|
||||
|
||||
if (!updateError) {
|
||||
console.log('Successfully updated points via RPC:', rpcData);
|
||||
pointsUpdated = true;
|
||||
} else {
|
||||
console.log('Could not update points via RPC:', updateError.message);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Exception in RPC points update:', error);
|
||||
}
|
||||
|
||||
// 2. Fallback: Direct update with admin client
|
||||
if (!pointsUpdated) {
|
||||
try {
|
||||
console.log('Attempting direct update for points...');
|
||||
|
||||
// Get current points first with admin client
|
||||
const { data: currentPointsData } = await supabaseAdmin
|
||||
const { data: currentPointsData, error: selectError } = await supabaseAdmin
|
||||
.from('user_points')
|
||||
.select('total_points')
|
||||
.eq('user_id', userIdUUID)
|
||||
.maybeSingle();
|
||||
|
||||
const currentPoints = currentPointsData?.total_points || 0;
|
||||
|
||||
// Then update with new total with admin client
|
||||
const { error: fallbackError } = await supabaseAdmin
|
||||
if (selectError) {
|
||||
console.warn('Could not get current points:', selectError.message);
|
||||
} else {
|
||||
console.log('Current points data:', currentPointsData);
|
||||
|
||||
const currentPoints = currentPointsData?.total_points || 0;
|
||||
const newPoints = currentPoints + POINTS.IMAGE_UPLOAD;
|
||||
|
||||
console.log(`Updating points from ${currentPoints} to ${newPoints}`);
|
||||
|
||||
// Then update with new total with admin client
|
||||
const { data: updateData, error: fallbackError } = await supabaseAdmin
|
||||
.from('user_points')
|
||||
.update({
|
||||
total_points: newPoints,
|
||||
updated_at: new Date().toISOString()
|
||||
})
|
||||
.eq('user_id', userIdUUID)
|
||||
.select()
|
||||
.single();
|
||||
|
||||
if (!fallbackError) {
|
||||
console.log('Successfully updated points via direct update:', updateData);
|
||||
pointsUpdated = true;
|
||||
} else {
|
||||
console.warn('Direct points update failed:', fallbackError.message);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Exception in direct points update:', err);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Last resort: Force an update to 1 point if this is their first transaction
|
||||
if (!pointsUpdated) {
|
||||
try {
|
||||
console.log('Attempting force update as last resort...');
|
||||
const { error: forceError } = await supabaseAdmin
|
||||
.from('user_points')
|
||||
.update({
|
||||
total_points: currentPoints + POINTS.IMAGE_UPLOAD,
|
||||
total_points: 1, // Force to at least 1 point
|
||||
updated_at: new Date().toISOString()
|
||||
})
|
||||
.eq('user_id', userIdUUID);
|
||||
|
||||
if (!fallbackError) {
|
||||
if (!forceError) {
|
||||
console.log('Successfully forced points update to 1');
|
||||
pointsUpdated = true;
|
||||
} else {
|
||||
console.warn('Direct points update also failed:', fallbackError.message);
|
||||
console.warn('Even forced points update failed:', forceError.message);
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn('Error in points update fallback:', err);
|
||||
console.error('Exception in forced points update:', err);
|
||||
}
|
||||
}
|
||||
|
||||
@ -345,19 +440,15 @@ export async function getUserPoints(userId: string) {
|
||||
.eq('user_id', userIdUUID)
|
||||
.maybeSingle();
|
||||
|
||||
// If we got an empty result or a not found error, try to initialize the user
|
||||
// If we got an empty result or a not found error, the user doesn't exist yet
|
||||
if (!userExists || (checkError && checkError.code === 'PGRST116')) {
|
||||
// Check if the userId is an email
|
||||
let email;
|
||||
if (userId.includes('@')) {
|
||||
email = userId; // Use the userId as email if it is one
|
||||
console.log('Using email from userId for initialization:', email);
|
||||
} else {
|
||||
// Use a real email format if possible - but don't use example.com
|
||||
email = userId.includes('@') ? userId : `${userId}@user.wildlife.app`;
|
||||
console.log('Using generated email for initialization:', email);
|
||||
}
|
||||
console.log('User does not exist yet in user_points table, need to initialize');
|
||||
|
||||
// At this point, the user should already be authenticated, so we should have their real email
|
||||
// But if we don't, we need to handle that case
|
||||
const email = userId.includes('@') ? userId : `${userId}@user.wildlife.app`;
|
||||
|
||||
console.log('Initializing user with:', { userId, email });
|
||||
await initializeUser(userId, email);
|
||||
}
|
||||
} catch (initError) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user