From dbcfe8a98e46e15fe951e5e98c68fd6ac8bde1b3 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Wed, 3 Dec 2025 06:05:33 +0900 Subject: refactor(auth): introduce repository pattern for database access MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add repository types and implementations to abstract database operations, improving testability and separation of concerns. The auth routes now use dependency injection with UserRepository and RefreshTokenRepository interfaces, making tests simpler by mocking interfaces instead of Drizzle query builders. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- pkgs/server/src/repositories/refresh-token.ts | 35 +++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 pkgs/server/src/repositories/refresh-token.ts (limited to 'pkgs/server/src/repositories/refresh-token.ts') diff --git a/pkgs/server/src/repositories/refresh-token.ts b/pkgs/server/src/repositories/refresh-token.ts new file mode 100644 index 0000000..82302df --- /dev/null +++ b/pkgs/server/src/repositories/refresh-token.ts @@ -0,0 +1,35 @@ +import { and, eq, gt } from "drizzle-orm"; +import { db, refreshTokens } from "../db"; +import type { RefreshTokenRepository } from "./types"; + +export const refreshTokenRepository: RefreshTokenRepository = { + async findValidToken(tokenHash) { + const [token] = await db + .select({ + id: refreshTokens.id, + userId: refreshTokens.userId, + expiresAt: refreshTokens.expiresAt, + }) + .from(refreshTokens) + .where( + and( + eq(refreshTokens.tokenHash, tokenHash), + gt(refreshTokens.expiresAt, new Date()), + ), + ) + .limit(1); + return token; + }, + + async create(data) { + await db.insert(refreshTokens).values({ + userId: data.userId, + tokenHash: data.tokenHash, + expiresAt: data.expiresAt, + }); + }, + + async deleteById(id) { + await db.delete(refreshTokens).where(eq(refreshTokens.id, id)); + }, +}; -- cgit v1.2.3-70-g09d2