mirror of
https://github.com/movie-web/backend.git
synced 2025-09-13 13:03:26 +00:00
Split user deletion job and add more job logs
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
import { challengeCodeJob } from '@/modules/jobs/list/challengeCode';
|
||||
import { sessionExpiryJob } from '@/modules/jobs/list/sessionExpiry';
|
||||
import { userDeletionJob } from '@/modules/jobs/list/userDeletion';
|
||||
|
||||
export async function setupJobs() {
|
||||
challengeCodeJob.start();
|
||||
sessionExpiryJob.start();
|
||||
userDeletionJob.start();
|
||||
}
|
||||
|
@@ -20,9 +20,11 @@ const wait = (sec: number) =>
|
||||
* @param cron crontime in this order: (min of hour) (hour of day) (day of month) (day of week) (sec of month)
|
||||
*/
|
||||
export function job(
|
||||
name: string,
|
||||
cron: string,
|
||||
cb: (ctx: { em: EntityManager; log: Logger }) => Promise<void>,
|
||||
): CronJob {
|
||||
log.info(`Registering job '${name}' with cron '${cron}'`);
|
||||
return CronJob.from({
|
||||
cronTime: cron,
|
||||
onTick: async () => {
|
||||
@@ -33,9 +35,10 @@ export function job(
|
||||
// actually run the job
|
||||
try {
|
||||
const em = getORM().em.fork();
|
||||
log.info(`Starting job '${name}' with cron '${cron}'`);
|
||||
await cb({ em, log });
|
||||
} catch (err) {
|
||||
log.error('Failed to run job!');
|
||||
log.error(`Failed to run '${name}' job!`);
|
||||
log.error(err);
|
||||
}
|
||||
},
|
||||
|
@@ -2,7 +2,10 @@ import { ChallengeCode } from '@/db/models/ChallengeCode';
|
||||
import { job } from '@/modules/jobs/job';
|
||||
|
||||
// every day at 12:00:00
|
||||
export const sessionExpiryJob = job('0 12 * * *', async ({ em }) => {
|
||||
export const challengeCodeJob = job(
|
||||
'Challenge Code Expiry',
|
||||
'0 12 * * *',
|
||||
async ({ em }) => {
|
||||
await em
|
||||
.createQueryBuilder(ChallengeCode)
|
||||
.delete()
|
||||
@@ -12,4 +15,5 @@ export const sessionExpiryJob = job('0 12 * * *', async ({ em }) => {
|
||||
},
|
||||
})
|
||||
.execute();
|
||||
});
|
||||
},
|
||||
);
|
||||
|
@@ -1,8 +1,12 @@
|
||||
import { Session } from '@/db/models/Session';
|
||||
import { User } from '@/db/models/User';
|
||||
import { job } from '@/modules/jobs/job';
|
||||
|
||||
// every day at 12:00:00
|
||||
export const sessionExpiryJob = job('0 12 * * *', async ({ em, log }) => {
|
||||
export const sessionExpiryJob = job(
|
||||
'Session Expiry',
|
||||
'0 12 * * *',
|
||||
async ({ em, log }) => {
|
||||
const deletedSessions = await em
|
||||
.createQueryBuilder(Session)
|
||||
.delete()
|
||||
@@ -13,7 +17,9 @@ export const sessionExpiryJob = job('0 12 * * *', async ({ em, log }) => {
|
||||
})
|
||||
.execute<{ affectedRows: number }>('run');
|
||||
|
||||
log.info(`Removed ${deletedSessions.affectedRows} sessions that had expired`);
|
||||
log.info(
|
||||
`Removed ${deletedSessions.affectedRows} sessions that had expired`,
|
||||
);
|
||||
|
||||
const knex = em.getKnex();
|
||||
|
||||
@@ -46,4 +52,5 @@ export const sessionExpiryJob = job('0 12 * * *', async ({ em, log }) => {
|
||||
log.info(
|
||||
`Removed ${deletedUsers.affectedRows} users older than 1 year with no sessions`,
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
|
42
src/modules/jobs/list/userDeletion.ts
Normal file
42
src/modules/jobs/list/userDeletion.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { Session } from '@/db/models/Session';
|
||||
import { User } from '@/db/models/User';
|
||||
import { job } from '@/modules/jobs/job';
|
||||
|
||||
// every day at 12:00:00
|
||||
export const userDeletionJob = job(
|
||||
'User Deletion',
|
||||
'0 12 * * *',
|
||||
async ({ em, log }) => {
|
||||
const knex = em.getKnex();
|
||||
|
||||
// Count all sessions for a user ID
|
||||
const sessionCountForUser = em
|
||||
.createQueryBuilder(Session, 'session')
|
||||
.count()
|
||||
.where({ user: knex.ref('user.id') })
|
||||
.getKnexQuery();
|
||||
|
||||
const now = new Date();
|
||||
const oneYearAgo = new Date();
|
||||
oneYearAgo.setFullYear(now.getFullYear() - 1);
|
||||
|
||||
// Delete all users who do not have any sessions AND
|
||||
// (their login date is null OR they last logged in over 1 year ago)
|
||||
const deletedUsers = await em
|
||||
.createQueryBuilder(User, 'user')
|
||||
.delete()
|
||||
.withSubQuery(sessionCountForUser, 'session.sessionCount')
|
||||
.where({
|
||||
'session.sessionCount': 0,
|
||||
$or: [
|
||||
{ lastLoggedIn: { $eq: undefined } },
|
||||
{ lastLoggedIn: { $lt: oneYearAgo } },
|
||||
],
|
||||
})
|
||||
.execute<{ affectedRows: number }>('run');
|
||||
|
||||
log.info(
|
||||
`Removed ${deletedUsers.affectedRows} users older than 1 year with no sessions`,
|
||||
);
|
||||
},
|
||||
);
|
Reference in New Issue
Block a user