mirror of
https://github.com/caty21/forex-dashboard.git
synced 2026-07-28 12:57:45 +00:00
a978f19088
- investinglive: tryUrl HEAD→GET + res.body?.cancel() (WordPress bloque HEAD) fenêtre recherche article préc. élargie 21→28 jours - rateprobability: CBRatePath + prevMeetings/prevWeekDate, loadPrevWeekCachedBody() fetchAllCBPaths enrichit prevMeetings depuis snapshot GitHub Actions - fetch-rate-data.mjs: rotation current→previousWeek (5–9 jours) pour Rate Curve - CurrencyCard: rateCurveData préfère prevMeetings (exact/meeting) > ilDelta (approx) légende hasPrevCurve pilote affichage ligne bleue et label date - page.tsx: suppression footer Sources/LLM, remplacement par pb-12 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
82 lines
3.0 KiB
JavaScript
82 lines
3.0 KiB
JavaScript
// Runs in GitHub Actions (not Vercel) — fetches from rateprobability.com
|
||
// GitHub Actions IPs are not blocked by the site.
|
||
import { writeFileSync, mkdirSync, readFileSync } from "fs";
|
||
|
||
const CB_KEYS = [
|
||
["USD", "fed"],
|
||
["EUR", "ecb"],
|
||
["GBP", "boe"],
|
||
["JPY", "boj"],
|
||
["CAD", "boc"],
|
||
["AUD", "rba"],
|
||
["NZD", "rbnz"],
|
||
];
|
||
|
||
const HEADERS = {
|
||
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36",
|
||
"Accept": "application/json, text/plain, */*",
|
||
"Accept-Language": "en-US,en;q=0.9",
|
||
"sec-ch-ua": '"Chromium";v="125", "Not.A/Brand";v="24"',
|
||
"sec-ch-ua-mobile":"?0",
|
||
"sec-fetch-dest": "empty",
|
||
"sec-fetch-mode": "cors",
|
||
"sec-fetch-site": "same-origin",
|
||
};
|
||
|
||
async function fetchCB(ccy, slug) {
|
||
try {
|
||
const res = await fetch(`https://rateprobability.com/api/${slug}/latest`, {
|
||
headers: { ...HEADERS, "Referer": `https://rateprobability.com/${slug}`, "Origin": "https://rateprobability.com" },
|
||
});
|
||
if (!res.ok) { console.error(`[${ccy}] HTTP ${res.status}`); return null; }
|
||
const body = await res.json();
|
||
console.log(`[${ccy}] OK — meetings: ${body?.today?.rows?.length ?? "?"}`);
|
||
return body;
|
||
} catch (e) {
|
||
console.error(`[${ccy}] Error: ${e.message}`);
|
||
return null;
|
||
}
|
||
}
|
||
|
||
const results = {};
|
||
for (const [ccy, slug] of CB_KEYS) {
|
||
const data = await fetchCB(ccy, slug);
|
||
if (data) results[ccy] = data;
|
||
await new Promise(r => setTimeout(r, 300)); // 300ms entre requêtes
|
||
}
|
||
|
||
// Rotation : si les données existantes datent de 5–9 jours → les sauvegarder comme previousWeek
|
||
let previousWeek = null;
|
||
let previousWeekFetchedAt = null;
|
||
try {
|
||
const existing = JSON.parse(readFileSync("data/rate-probabilities.json", "utf8"));
|
||
const ageMs = Date.now() - new Date(existing.fetchedAt).getTime();
|
||
const day = 86400000;
|
||
if (ageMs >= 5 * day && ageMs <= 9 * day) {
|
||
// Les données courantes datent d'une semaine → les promouvoir en previousWeek
|
||
previousWeek = existing.data;
|
||
previousWeekFetchedAt = existing.fetchedAt;
|
||
console.log(`\nRotated existing data (${(ageMs / day).toFixed(1)}d old) to previousWeek`);
|
||
} else if (existing.previousWeek && existing.previousWeekFetchedAt) {
|
||
// Conserver le previousWeek existant s'il est encore dans la fenêtre utile (< 11 jours)
|
||
const prevAge = Date.now() - new Date(existing.previousWeekFetchedAt).getTime();
|
||
if (prevAge < 11 * day) {
|
||
previousWeek = existing.previousWeek;
|
||
previousWeekFetchedAt = existing.previousWeekFetchedAt;
|
||
}
|
||
}
|
||
} catch { /* pas de fichier existant */ }
|
||
|
||
mkdirSync("data", { recursive: true });
|
||
writeFileSync(
|
||
"data/rate-probabilities.json",
|
||
JSON.stringify({
|
||
data: results,
|
||
fetchedAt: new Date().toISOString(),
|
||
...(previousWeek ? { previousWeek, previousWeekFetchedAt } : {}),
|
||
}, null, 2)
|
||
);
|
||
|
||
console.log(`\nSaved ${Object.keys(results).length} CBs: ${Object.keys(results).join(", ")}`);
|
||
if (previousWeek) console.log(`previousWeek preserved (${Object.keys(previousWeek).join(", ")})`);
|