feat: forcePoll at startup + POST /api/refresh (bypasses market hours)
This commit is contained in:
parent
a0aede9294
commit
60e5c7647d
3 changed files with 44 additions and 2 deletions
|
|
@ -78,6 +78,14 @@ export function createServer(): express.Application {
|
|||
});
|
||||
|
||||
// ── GET /api/health ───────────────────────────────────────────────────────
|
||||
// ── POST /api/refresh ─────────────────────────────────────────────────────
|
||||
// Force-fetch positions right now (works outside market hours)
|
||||
app.post('/api/refresh', async (_req, res) => {
|
||||
const { forcePoll } = await import('../tracker/poll.js');
|
||||
await forcePoll();
|
||||
res.json({ ok: true, message: 'Refresh complete' });
|
||||
});
|
||||
|
||||
app.get('/api/health', (_req, res) => {
|
||||
const lastError = db.prepare(
|
||||
`SELECT error, occurred_at FROM poll_errors ORDER BY occurred_at DESC LIMIT 1`
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
import cron from 'node-cron';
|
||||
import { initDb } from './db/client.js';
|
||||
import { login } from './angel/auth.js';
|
||||
import { pollTick } from './tracker/poll.js';
|
||||
import { pollTick, forcePoll } from './tracker/poll.js';
|
||||
import { createServer } from './api/server.js';
|
||||
import { sendServiceNotification } from './notify/telegram.js';
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ async function main() {
|
|||
});
|
||||
|
||||
// 4. Run first poll immediately so dashboard shows data on startup
|
||||
await pollTick();
|
||||
await forcePoll();
|
||||
|
||||
// 5. Schedule recurring poll
|
||||
// node-cron doesn't support sub-minute; for 60s we use a cron expression.
|
||||
|
|
|
|||
|
|
@ -169,3 +169,37 @@ async function evaluateAlerts(positions: Position[], today: string): Promise<voi
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Force a poll regardless of market hours.
|
||||
* Used at startup and for manual refresh via API.
|
||||
*/
|
||||
export async function forcePoll(): Promise<void> {
|
||||
const today = todayIST();
|
||||
try {
|
||||
const positions = await fetchAllPositions();
|
||||
const upsertPos = db.prepare(`
|
||||
INSERT INTO positions (key, exchange, tradingsymbol, instrumenttype, producttype,
|
||||
netqty, ltp, avg_price, unrealised_pnl, realised_pnl, total_pnl, source, updated_at)
|
||||
VALUES (@key, @exchange, @tradingsymbol, @instrumenttype, @producttype,
|
||||
@netqty, @ltp, @avg_price, @unrealised_pnl, @realised_pnl, @total_pnl, @source, datetime('now'))
|
||||
ON CONFLICT(key) DO UPDATE SET
|
||||
netqty = excluded.netqty, ltp = excluded.ltp, avg_price = excluded.avg_price,
|
||||
unrealised_pnl = excluded.unrealised_pnl, realised_pnl = excluded.realised_pnl,
|
||||
total_pnl = excluded.total_pnl, updated_at = excluded.updated_at
|
||||
`);
|
||||
for (const pos of positions) {
|
||||
upsertPos.run({ key: pos.key, exchange: pos.exchange, tradingsymbol: pos.tradingsymbol,
|
||||
instrumenttype: pos.instrumenttype, producttype: pos.producttype, netqty: pos.netqty,
|
||||
ltp: pos.ltp, avg_price: pos.avgPrice, unrealised_pnl: pos.unrealisedPnl,
|
||||
realised_pnl: pos.realisedPnl, total_pnl: pos.totalPnl, source: pos.source });
|
||||
}
|
||||
const activeKeys = positions.map(p => p.key);
|
||||
if (activeKeys.length > 0) {
|
||||
db.prepare(`UPDATE positions SET is_closed = 1 WHERE key NOT IN (${activeKeys.map(() => "?").join(",")})`).run(...activeKeys);
|
||||
}
|
||||
console.log(`[poll] Force fetch: ${positions.length} positions`);
|
||||
} catch (err) {
|
||||
console.error(`[poll] Force fetch error: ${err instanceof Error ? err.message : err}`);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue