A page per day: the whole contract, midnight to midnight
The daily snapshot outgrew Telegram. Past 1,000 members the post hit the 4,096-character limit and was rejected outright two mornings running, and capping the lists to fit meant choosing what to throw away. Manson caught what that cost: the level-up list was ordered by time, so the cap hid two Culmen and thirteen Fabrica behind two dozen routine Ascensus upgrades. /day/<date> now carries every climb, every payment with its Polygonscan link, every new position and every recruiter, with no cap on any of it. Company-wide, no team filter, keyed to the Central calendar day so a link posted on Monday still shows Monday next year. Today is computed live; a finished day is written to disk once, because the chain index only keeps a few hundred payouts and an older day could never be rebuilt from it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@ const path = require('path');
|
||||
const crypto = require('crypto');
|
||||
const { URL } = require('url');
|
||||
const chain = require('./chain');
|
||||
const daysnap = require('./daysnap'); // /day/<date>: the whole contract, one Central day, kept forever
|
||||
const messages = require('./messages');
|
||||
const profiles = require('./profiles');
|
||||
const placement = require('./placement');
|
||||
@@ -1847,6 +1848,14 @@ const server=http.createServer(async(req,res)=>{
|
||||
const u=new URL(req.url,`http://${req.headers.host||'localhost'}`),pathname=decodeURIComponent(u.pathname);
|
||||
// /p/<id> = member Page Builder pages: dynamic HTML, so it must reach the
|
||||
// API handler rather than the static-file path (which 404s it).
|
||||
if(pathname==='/day'||/^\/day\/\d{4}-\d{2}-\d{2}$/.test(pathname)){
|
||||
const key = pathname==='/day' ? daysnap.dayKey() : pathname.slice(5);
|
||||
const r = daysnap.render(key, { polUsd: await getPolUsd() });
|
||||
const fresh = key === daysnap.dayKey();
|
||||
res.writeHead(r.status, securityHeaders({ 'Content-Type':'text/html; charset=utf-8',
|
||||
'Cache-Control': fresh ? 'public, max-age=120' : 'public, max-age=86400' }));
|
||||
return res.end(r.html);
|
||||
}
|
||||
if(pathname==='/health'||pathname==='/announce.ics'||pathname.startsWith('/api/')||pathname.startsWith('/tv/')||/^\/p\/\d{1,15}(\/[a-z0-9-]{1,24})?$/.test(pathname))return await handleApi(req,res,pathname);
|
||||
if(req.method!=='GET'&&req.method!=='HEAD')return send(res,405,'Method Not Allowed',{'Content-Type':'text/plain; charset=utf-8'});
|
||||
// Members-area gate: the Circle Method lessons 2-10 + the e-gift cash-out
|
||||
@@ -1925,6 +1934,11 @@ function checkUpgradeAlerts(){
|
||||
}catch(e){ console.error('upgrade alert check', e.message); }
|
||||
}
|
||||
setInterval(checkUpgradeAlerts, 5*60*1000).unref();
|
||||
// close out finished days so the archive never depends on someone opening the page before the
|
||||
// chain index's rolling payout window scrolls past that day
|
||||
daysnap.init({ dataDir: DATA_DIR });
|
||||
setTimeout(() => { try { daysnap.tick(); } catch (e) { console.error('daysnap', e.message); } }, 20000).unref();
|
||||
setInterval(() => { try { daysnap.tick(); } catch (e) { console.error('daysnap', e.message); } }, 60 * 60 * 1000).unref();
|
||||
setTimeout(checkUpgradeAlerts, 30000).unref();
|
||||
chain.startIndexer(evt=>{
|
||||
// Any on-chain event makes cached member views stale (the new member, the
|
||||
|
||||
Reference in New Issue
Block a user