Compare commits

..

3 Commits

Author SHA1 Message Date
1b992522de Merge pull request 'purge-session' (#18) from purge-session into main
All checks were successful
Sync to GitHub / sync (push) Successful in 9s
Reviewed-on: #18
2026-02-19 14:38:41 +07:00
133ebb4668 🗃️ db: add composite index to userSession
All checks were successful
Integration Tests / integration-tests (pull_request) Successful in 57s
2026-02-19 14:23:37 +07:00
7a3c46c6c1 feat: add internal endpoint to purge user session 2026-02-19 14:16:12 +07:00
5 changed files with 50 additions and 1 deletions

View File

@ -395,6 +395,8 @@ model UserSession {
logs UserLog[] @relation("UserSessionLogs")
episode_likes EpisodeLike[] @relation("SessionEpisodeLikes")
watch_histories WatchHistory[] @relation("SessionWatchHistories")
@@index([userId, isAuthenticated, deletedAt])
@@map("user_sessions")
}

View File

@ -0,0 +1,18 @@
import { Context } from "elysia";
import { mainErrorHandler } from "../../../helpers/error/handler";
import { returnWriteResponse } from "../../../helpers/callback/httpResponse";
import { purgeUnusedSessionService } from "../services/http/purgeUnusedSession.service";
export const purgeUnusedSessionController = async (ctx: Context) => {
try {
const result = await purgeUnusedSessionService();
return returnWriteResponse(
ctx.set,
200,
"Successfully purged all unused user sessions",
result,
);
} catch (error) {
return mainErrorHandler(ctx.set, error);
}
};

View File

@ -4,10 +4,12 @@ import { bulkInsertMediaController } from "./controllers/bulkInsertMedia.control
import { createVideoServiceInternalController } from "./controllers/createVideoService.controller";
import { bulkInsertVideoController } from "./controllers/bulkInsertVideo.controller";
import { updateAllEpisodeThumbnailController } from "./controllers/updateAllEpisodeThumbnail.controller";
import { purgeUnusedSessionController } from "./controllers/purgeUnusedSession.controller";
export const internalModule = new Elysia({ prefix: "/internal" })
.post("/media/bulk-insert", bulkInsertMediaController)
.post("/episode/bulk-insert", bulkInsertEpisodeController)
.put("/episode/update-thumbnails", updateAllEpisodeThumbnailController)
.post("/video/bulk-insert", bulkInsertVideoController)
.post("/video-service", createVideoServiceInternalController);
.post("/video-service", createVideoServiceInternalController)
.post("/user-session/purge-unused", purgeUnusedSessionController);

View File

@ -0,0 +1,17 @@
import { AppError } from "../../../helpers/error/instances/app";
import { prisma } from "../../../utils/databases/prisma/connection";
export const deleteAllUnusedUserSessionRepository = async () => {
try {
return await prisma.userSession.deleteMany({
where: {
isAuthenticated: false,
deletedAt: {
not: null,
},
},
});
} catch (error) {
throw new AppError(500, "Failed to delete all unused user sessions", error);
}
};

View File

@ -0,0 +1,10 @@
import { ErrorForwarder } from "../../../../helpers/error/instances/forwarder";
import { deleteAllUnusedUserSessionRepository } from "../../repositories/deleteAllUnusedUserSession.repository";
export const purgeUnusedSessionService = async () => {
try {
return await deleteAllUnusedUserSessionRepository();
} catch (error) {
ErrorForwarder(error);
}
};