Spaces:
Running
Running
Update apps/aura_measure.js
Browse files- apps/aura_measure.js +18 -14
apps/aura_measure.js
CHANGED
|
@@ -84,6 +84,17 @@ router.post('/analyze', async (req, res) => {
|
|
| 84 |
return res.status(400).json({ success: false, error: 'Missing media or device_id.' });
|
| 85 |
}
|
| 86 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 87 |
let systemPrompt = AURA_PROMPT_STANDALONE;
|
| 88 |
let promptText = 'Analyze this image and calculate my Aura. Return JSON.';
|
| 89 |
let imagesToProcess = [media_base64];
|
|
@@ -94,6 +105,7 @@ router.post('/analyze', async (req, res) => {
|
|
| 94 |
imagesToProcess = [reference_data.image_base64, media_base64];
|
| 95 |
}
|
| 96 |
|
|
|
|
| 97 |
console.log('[Analyze] Running AI...');
|
| 98 |
const aiResult = await generateCompletion({
|
| 99 |
model: 'qwen-vl-max',
|
|
@@ -118,14 +130,14 @@ router.post('/analyze', async (req, res) => {
|
|
| 118 |
|
| 119 |
console.log('[Analyze] AI done. Score:', parsedData.score);
|
| 120 |
|
| 121 |
-
// Store temp entry
|
| 122 |
const tempId = crypto.randomUUID();
|
| 123 |
const imageBuffer = Buffer.from(media_base64, 'base64');
|
| 124 |
|
| 125 |
tempScans.set(tempId, {
|
| 126 |
filepath: path.join(TEMP_DIR, `${tempId}.jpg`),
|
| 127 |
timestamp: Date.now(),
|
| 128 |
-
user_id:
|
| 129 |
session_id: null,
|
| 130 |
score: parsedData.score,
|
| 131 |
analysis: parsedData.analysis_markdown,
|
|
@@ -134,28 +146,22 @@ router.post('/analyze', async (req, res) => {
|
|
| 134 |
ready: false,
|
| 135 |
});
|
| 136 |
|
| 137 |
-
// Respond immediately
|
| 138 |
res.json({
|
| 139 |
success: true,
|
| 140 |
score: parsedData.score,
|
| 141 |
analysis: parsedData.analysis_markdown,
|
| 142 |
-
temp_scan_id: tempId
|
|
|
|
| 143 |
});
|
| 144 |
|
| 145 |
console.log('[Analyze] Response sent. Running async DB writes...');
|
| 146 |
|
| 147 |
-
//
|
| 148 |
(async () => {
|
| 149 |
try {
|
| 150 |
await fs.writeFile(path.join(TEMP_DIR, `${tempId}.jpg`), imageBuffer);
|
| 151 |
|
| 152 |
-
const { data: profile, error: profileError } = await supabase
|
| 153 |
-
.from('aura_profiles')
|
| 154 |
-
.upsert({ device_id, username, avatar }, { onConflict: 'device_id' })
|
| 155 |
-
.select('id')
|
| 156 |
-
.single();
|
| 157 |
-
if (profileError) throw profileError;
|
| 158 |
-
|
| 159 |
let { data: session } = await supabase
|
| 160 |
.from('aura_sessions')
|
| 161 |
.select('id')
|
|
@@ -182,7 +188,6 @@ router.post('/analyze', async (req, res) => {
|
|
| 182 |
});
|
| 183 |
if (rpcError) throw rpcError;
|
| 184 |
|
| 185 |
-
// Fetch updated profile so publish has accurate data
|
| 186 |
const { data: updatedProfile } = await supabase
|
| 187 |
.from('aura_profiles')
|
| 188 |
.select('cumulative_aura, current_grade')
|
|
@@ -193,7 +198,6 @@ router.post('/analyze', async (req, res) => {
|
|
| 193 |
if (existing) {
|
| 194 |
tempScans.set(tempId, {
|
| 195 |
...existing,
|
| 196 |
-
user_id: profile.id,
|
| 197 |
session_id: session.id,
|
| 198 |
ready: true,
|
| 199 |
cumulative_aura: updatedProfile?.cumulative_aura ?? 0,
|
|
|
|
| 84 |
return res.status(400).json({ success: false, error: 'Missing media or device_id.' });
|
| 85 |
}
|
| 86 |
|
| 87 |
+
// ββ Step 1: Upsert profile FIRST (fast DB write, gives us the ID) ββββ
|
| 88 |
+
const { data: profile, error: profileError } = await supabase
|
| 89 |
+
.from('aura_profiles')
|
| 90 |
+
.upsert({ device_id, username, avatar }, { onConflict: 'device_id' })
|
| 91 |
+
.select('id')
|
| 92 |
+
.single();
|
| 93 |
+
|
| 94 |
+
if (profileError) throw profileError;
|
| 95 |
+
console.log('[Analyze] Profile ID:', profile.id);
|
| 96 |
+
|
| 97 |
+
// ββ Step 2: Build AI prompt βββββββββββββββββββββββββββββββββββββββββββ
|
| 98 |
let systemPrompt = AURA_PROMPT_STANDALONE;
|
| 99 |
let promptText = 'Analyze this image and calculate my Aura. Return JSON.';
|
| 100 |
let imagesToProcess = [media_base64];
|
|
|
|
| 105 |
imagesToProcess = [reference_data.image_base64, media_base64];
|
| 106 |
}
|
| 107 |
|
| 108 |
+
// ββ Step 3: Run AI ββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 109 |
console.log('[Analyze] Running AI...');
|
| 110 |
const aiResult = await generateCompletion({
|
| 111 |
model: 'qwen-vl-max',
|
|
|
|
| 130 |
|
| 131 |
console.log('[Analyze] AI done. Score:', parsedData.score);
|
| 132 |
|
| 133 |
+
// ββ Step 4: Store temp scan entry βββββββββββββββββββββββββββββββββββββ
|
| 134 |
const tempId = crypto.randomUUID();
|
| 135 |
const imageBuffer = Buffer.from(media_base64, 'base64');
|
| 136 |
|
| 137 |
tempScans.set(tempId, {
|
| 138 |
filepath: path.join(TEMP_DIR, `${tempId}.jpg`),
|
| 139 |
timestamp: Date.now(),
|
| 140 |
+
user_id: profile.id, // We have this now
|
| 141 |
session_id: null,
|
| 142 |
score: parsedData.score,
|
| 143 |
analysis: parsedData.analysis_markdown,
|
|
|
|
| 146 |
ready: false,
|
| 147 |
});
|
| 148 |
|
| 149 |
+
// ββ Step 5: Respond immediately with profile_id included ββββββββββββββ
|
| 150 |
res.json({
|
| 151 |
success: true,
|
| 152 |
score: parsedData.score,
|
| 153 |
analysis: parsedData.analysis_markdown,
|
| 154 |
+
temp_scan_id: tempId,
|
| 155 |
+
profile_id: profile.id, // β send this so client can store it
|
| 156 |
});
|
| 157 |
|
| 158 |
console.log('[Analyze] Response sent. Running async DB writes...');
|
| 159 |
|
| 160 |
+
// ββ Step 6: Remaining DB writes async βββββββββββββββββββββββββββββββββ
|
| 161 |
(async () => {
|
| 162 |
try {
|
| 163 |
await fs.writeFile(path.join(TEMP_DIR, `${tempId}.jpg`), imageBuffer);
|
| 164 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 165 |
let { data: session } = await supabase
|
| 166 |
.from('aura_sessions')
|
| 167 |
.select('id')
|
|
|
|
| 188 |
});
|
| 189 |
if (rpcError) throw rpcError;
|
| 190 |
|
|
|
|
| 191 |
const { data: updatedProfile } = await supabase
|
| 192 |
.from('aura_profiles')
|
| 193 |
.select('cumulative_aura, current_grade')
|
|
|
|
| 198 |
if (existing) {
|
| 199 |
tempScans.set(tempId, {
|
| 200 |
...existing,
|
|
|
|
| 201 |
session_id: session.id,
|
| 202 |
ready: true,
|
| 203 |
cumulative_aura: updatedProfile?.cumulative_aura ?? 0,
|