feat: add last_seen tracking for users
Adds last_seen field to track when users last accessed the tool: - Add lastSeen column to users table schema (nullable timestamp) - Create migration to add last_seen column to existing databases - Add updateLastSeen() function to auth.service.js - Update auth derive middleware to update last_seen on each authenticated request (async, non-blocking) - Add lastSeen to admin getUserStats() query for display in admin users table - Add "Last Seen" column to admin users table in frontend Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
86
src/backend/migrations/add-last-seen.js
Normal file
86
src/backend/migrations/add-last-seen.js
Normal file
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
* Migration: Add last_seen column to users table
|
||||
*
|
||||
* This script adds the last_seen column to track when users last accessed the tool.
|
||||
*/
|
||||
|
||||
import Database from 'bun:sqlite';
|
||||
import { join, dirname } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
// ES module equivalent of __dirname
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
|
||||
const dbPath = join(__dirname, '../award.db');
|
||||
const sqlite = new Database(dbPath);
|
||||
|
||||
async function migrate() {
|
||||
console.log('Starting migration: Add last_seen column...');
|
||||
|
||||
try {
|
||||
// Check if last_seen column already exists
|
||||
const columnExists = sqlite.query(`
|
||||
SELECT COUNT(*) as count
|
||||
FROM pragma_table_info('users')
|
||||
WHERE name='last_seen'
|
||||
`).get();
|
||||
|
||||
if (columnExists.count > 0) {
|
||||
console.log('Column last_seen already exists. Skipping...');
|
||||
} else {
|
||||
// Add last_seen column
|
||||
sqlite.exec(`
|
||||
ALTER TABLE users
|
||||
ADD COLUMN last_seen INTEGER
|
||||
`);
|
||||
|
||||
console.log('Added last_seen column to users table');
|
||||
}
|
||||
|
||||
console.log('Migration complete! last_seen column added to database.');
|
||||
} catch (error) {
|
||||
console.error('Migration failed:', error);
|
||||
sqlite.close();
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
sqlite.close();
|
||||
}
|
||||
|
||||
async function rollback() {
|
||||
console.log('Starting rollback: Remove last_seen column...');
|
||||
|
||||
try {
|
||||
// SQLite doesn't support DROP COLUMN directly before version 3.35.5
|
||||
// For older versions, we need to recreate the table
|
||||
console.log('Note: SQLite does not support DROP COLUMN. Manual cleanup required.');
|
||||
console.log('To rollback: Recreate users table without last_seen column');
|
||||
|
||||
// For SQLite 3.35.5+, you can use:
|
||||
// sqlite.exec(`ALTER TABLE users DROP COLUMN last_seen`);
|
||||
|
||||
console.log('Rollback note issued.');
|
||||
} catch (error) {
|
||||
console.error('Rollback failed:', error);
|
||||
sqlite.close();
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
sqlite.close();
|
||||
}
|
||||
|
||||
// Check if this is a rollback
|
||||
const args = process.argv.slice(2);
|
||||
if (args.includes('--rollback') || args.includes('-r')) {
|
||||
rollback().then(() => {
|
||||
console.log('Rollback script completed');
|
||||
process.exit(0);
|
||||
});
|
||||
} else {
|
||||
// Run migration
|
||||
migrate().then(() => {
|
||||
console.log('Migration script completed successfully');
|
||||
process.exit(0);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user