a fancy canvas mcp server!
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: move cleanup to background

+67 -15
+25
src/index.ts
··· 815 815 return Response.json({ api_key: newApiKey }); 816 816 }, 817 817 }, 818 + 819 + // Admin endpoint to manually trigger cleanup 820 + "/api/admin/cleanup": { 821 + POST(req: Request) { 822 + const results = DB.runAllCleanups(); 823 + return Response.json({ 824 + success: true, 825 + removed: results, 826 + timestamp: new Date().toISOString(), 827 + }); 828 + }, 829 + }, 818 830 }; 819 831 820 832 // Start server ··· 832 844 console.log(`Canvas MCP Server running at ${BASE_URL}`); 833 845 console.log(`Dashboard: ${BASE_URL}/dashboard`); 834 846 console.log(`MCP Endpoint: ${BASE_URL}/mcp`); 847 + 848 + // Background cleanup job - runs every 5 minutes 849 + const CLEANUP_INTERVAL = 5 * 60 * 1000; // 5 minutes 850 + 851 + console.log(`[Cleanup] Starting background cleanup job (interval: ${CLEANUP_INTERVAL / 1000}s)`); 852 + 853 + // Run initial cleanup on startup 854 + DB.runAllCleanups(); 855 + 856 + // Schedule periodic cleanup 857 + setInterval(() => { 858 + DB.runAllCleanups(); 859 + }, CLEANUP_INTERVAL);
+42 -15
src/lib/db.ts
··· 387 387 }, 388 388 389 389 getSession(sessionId: string) { 390 - // Clean up expired sessions 391 - db.run("DELETE FROM sessions WHERE expires_at < ?", [Date.now()]); 392 - 393 390 return db 394 391 .query("SELECT * FROM sessions WHERE id = ? AND expires_at > ?") 395 392 .get(sessionId, Date.now()) as any; ··· 427 424 428 425 // Get session by API key (for MCP authentication) 429 426 getSessionByToken(token: string) { 430 - // Clean up expired sessions 431 - db.run("DELETE FROM sessions WHERE expires_at < ?", [Date.now()]); 432 - 433 427 return db 434 428 .query("SELECT * FROM sessions WHERE api_key = ? AND expires_at > ?") 435 429 .get(token, Date.now()) as any; ··· 444 438 }, 445 439 446 440 getMagicLink(token: string) { 447 - // Clean up expired magic links 448 - db.run("DELETE FROM magic_links WHERE expires_at < ?", [Date.now()]); 449 - 450 441 return db 451 442 .query( 452 443 "SELECT * FROM magic_links WHERE token = ? AND expires_at > ? AND used = 0" ··· 510 501 511 502 // Rate limiting for magic links 512 503 canSendMagicLink(email: string, cooldownMs: number = 60000): boolean { 513 - // Clean up old magic links first 514 - db.run("DELETE FROM magic_links WHERE expires_at < ?", [Date.now()]); 515 - 516 504 // Check if a magic link was sent recently (within cooldown period) 517 505 const recent = db 518 506 .query( ··· 547 535 }, 548 536 549 537 getUserByOAuthToken(token: string): User | null { 550 - // Clean up expired tokens 551 - db.run("DELETE FROM oauth_tokens WHERE expires_at < ?", [Date.now()]); 552 - 553 538 const tokenData = db 554 539 .query("SELECT * FROM oauth_tokens WHERE token = ? AND expires_at > ?") 555 540 .get(token, Date.now()) as any; ··· 579 564 size: apiKeyCache.size, 580 565 ttl: CACHE_TTL, 581 566 }; 567 + }, 568 + 569 + // Background cleanup operations (run these periodically, not on request path) 570 + cleanupExpiredSessions(): number { 571 + const result = db.run("DELETE FROM sessions WHERE expires_at < ?", [Date.now()]); 572 + return result.changes; 573 + }, 574 + 575 + cleanupExpiredMagicLinks(): number { 576 + const result = db.run("DELETE FROM magic_links WHERE expires_at < ?", [Date.now()]); 577 + return result.changes; 578 + }, 579 + 580 + cleanupExpiredAuthCodes(): number { 581 + const result = db.run("DELETE FROM auth_codes WHERE expires_at < ?", [Date.now()]); 582 + return result.changes; 583 + }, 584 + 585 + cleanupExpiredOAuthTokens(): number { 586 + const result = db.run("DELETE FROM oauth_tokens WHERE expires_at < ?", [Date.now()]); 587 + return result.changes; 588 + }, 589 + 590 + // Clean up old usage logs (keep last 90 days) 591 + cleanupOldUsageLogs(retentionDays: number = 90): number { 592 + const cutoffTime = Date.now() - (retentionDays * 24 * 60 * 60 * 1000); 593 + const result = db.run("DELETE FROM usage_logs WHERE timestamp < ?", [cutoffTime]); 594 + return result.changes; 595 + }, 596 + 597 + // Run all cleanup operations 598 + runAllCleanups(): { [key: string]: number } { 599 + const results = { 600 + sessions: this.cleanupExpiredSessions(), 601 + magicLinks: this.cleanupExpiredMagicLinks(), 602 + authCodes: this.cleanupExpiredAuthCodes(), 603 + oauthTokens: this.cleanupExpiredOAuthTokens(), 604 + usageLogs: this.cleanupOldUsageLogs(), 605 + }; 606 + 607 + console.log('[Cleanup] Removed expired records:', results); 608 + return results; 582 609 }, 583 610 }; 584 611