everydaytok commited on
Commit
f4cb457
·
verified ·
1 Parent(s): da7a53a

Update app.js

Browse files
Files changed (1) hide show
  1. app.js +58 -3
app.js CHANGED
@@ -106,15 +106,37 @@ function extractCommands(text) {
106
  return commands;
107
  }
108
 
 
109
  async function registerMorningCron(projectId, offset) {
110
  const now = new Date();
111
  const target = new Date(now);
112
- target.setUTCHours(6 - offset, 0, 0, 0);
 
 
 
 
 
 
 
 
 
 
113
  if (target <= now) target.setDate(target.getDate() + 1);
 
114
  const delayMs = target.getTime() - now.getTime();
 
 
115
  fetch(`${CRON_REGISTRY_URL}/register`, {
116
  method: 'POST', headers: { 'Content-Type': 'application/json' },
117
- body: JSON.stringify({ secret: CRON_SECRET, jobId: `briefing_${projectId}`, intervalMs: 86400000, initialDelay: delayMs, webhookUrl: `https://everydaytok-thrust-core-server.hf.space/automated-briefing`, leadId: projectId, payload: { projectId, timezoneOffset: offset } })
 
 
 
 
 
 
 
 
118
  }).catch(()=>{});
119
  }
120
 
@@ -175,8 +197,40 @@ async function executeCommands(userId, projectId, commands) {
175
  } catch (e) {}
176
  }
177
  return flags;
178
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
179
 
 
180
  app.post('/init-project', async (req, res) => {
181
  const { userId, name, description, localPath } = req.body;
182
  const { data: lead } = await supabase.from('leads').insert({ user_id: userId, name, description, local_path: localPath, status: 'active', requirements_doc: "Init..." }).select().single();
@@ -194,6 +248,7 @@ app.post('/init-project', async (req, res) => {
194
  } catch (err) {}
195
  });
196
  });
 
197
 
198
  app.post('/process', async (req, res) => {
199
  const { userId, projectId, prompt, context, images, task_type = 'chat' } = req.body;
 
106
  return commands;
107
  }
108
 
109
+ // --- BULLETPROOF CRON MATH ---
110
  async function registerMorningCron(projectId, offset) {
111
  const now = new Date();
112
  const target = new Date(now);
113
+
114
+ // We want exactly 6:00 AM local time.
115
+ // So we calculate the target UTC minutes needed.
116
+ // E.g., Local 6 AM in EST (-5) = 11 AM UTC (660 mins).
117
+ // E.g., Local 6 AM in IST (+5.5) = 12:30 AM UTC (30 mins).
118
+ const targetUtcMinutes = (6 * 60) - (offset * 60);
119
+
120
+ // setUTCHours natively handles fractional minutes and negative hour rollovers!
121
+ target.setUTCHours(0, targetUtcMinutes, 0, 0);
122
+
123
+ // If 6 AM today has already passed, schedule for tomorrow
124
  if (target <= now) target.setDate(target.getDate() + 1);
125
+
126
  const delayMs = target.getTime() - now.getTime();
127
+ console.log(`⏰ Briefing Scheduled for ${projectId}. Local 6AM occurs in ${(delayMs/1000/60/60).toFixed(2)} hours.`);
128
+
129
  fetch(`${CRON_REGISTRY_URL}/register`, {
130
  method: 'POST', headers: { 'Content-Type': 'application/json' },
131
+ body: JSON.stringify({
132
+ secret: CRON_SECRET,
133
+ jobId: `briefing_${projectId}`,
134
+ intervalMs: 86400000, // 24 hours
135
+ initialDelay: delayMs,
136
+ webhookUrl: `https://everydaytok-thrust-core-server.hf.space/automated-briefing`,
137
+ leadId: projectId,
138
+ payload: { projectId, timezoneOffset: offset }
139
+ })
140
  }).catch(()=>{});
141
  }
142
 
 
197
  } catch (e) {}
198
  }
199
  return flags;
200
+ };
201
+
202
+ app.post('/init-project', async (req, res) => {
203
+ // 1. Receive timezoneOffset from frontend
204
+ const { userId, name, description, localPath, timezoneOffset = 0 } = req.body;
205
+
206
+ const { data: lead } = await supabase.from('leads').insert({
207
+ user_id: userId, name, description, local_path: localPath, status: 'active', requirements_doc: "Init..."
208
+ }).select().single();
209
+
210
+ res.json({ success: true, leadId: lead.id });
211
+
212
+ setImmediate(async () => {
213
+ try {
214
+ // 2. Inject the explicit timezone offset into the initialization prompt
215
+ const initInput = `PROJECT: ${name}\nDESC: ${description}\nUSER TIMEZONE OFFSET: ${timezoneOffset}\nTask: Init PRD, First Thrust, Schedule Morning Briefing.`;
216
+
217
+ const aiResult = await callAI([], initInput, {}, [], prompts.init_system_prompt, "", SMART_MODEL_ID);
218
+ aiResult.text += `\n<notification>Project '${name}' initialized successfully!</notification>`;
219
+
220
+ await StateManager.addHistory(lead.id, 'user', initInput);
221
+ await StateManager.addHistory(lead.id, 'model', aiResult.text);
222
+
223
+ const cmds = extractCommands(aiResult.text);
224
+ const flags = await executeCommands(userId, lead.id, cmds);
225
+
226
+ if (flags.newThrustId) {
227
+ await dispatchEmail(userId, lead.id, lead.name, flags.newThrustId, flags.newThrustMarkdown);
228
+ }
229
+ } catch (err) {}
230
+ });
231
+ });
232
 
233
+ /*
234
  app.post('/init-project', async (req, res) => {
235
  const { userId, name, description, localPath } = req.body;
236
  const { data: lead } = await supabase.from('leads').insert({ user_id: userId, name, description, local_path: localPath, status: 'active', requirements_doc: "Init..." }).select().single();
 
248
  } catch (err) {}
249
  });
250
  });
251
+ */
252
 
253
  app.post('/process', async (req, res) => {
254
  const { userId, projectId, prompt, context, images, task_type = 'chat' } = req.body;