feat(db): Drizzle DAL with withUser/asAdmin GUC wrapper (Phase 2)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-07-23 15:50:57 +08:00
co-authored by Claude Sonnet 4.6
parent e5fd2436fa
commit a95273b182
9 changed files with 1640 additions and 2 deletions
+2
View File
@@ -0,0 +1,2 @@
// no-op stub for server-only in test environment
export {}
+53
View File
@@ -0,0 +1,53 @@
import { describe, it, expect, vi, beforeEach } from 'vitest'
// Mock the pools before importing with-user
vi.mock('../../../lib/db/index', () => {
const mockTx = {
execute: vi.fn().mockResolvedValue(undefined),
}
const mockUserDb = {
transaction: vi.fn().mockImplementation(async (fn: (tx: typeof mockTx) => Promise<unknown>) => fn(mockTx)),
}
const mockAdminDb = { query: vi.fn() }
return {
userDb: mockUserDb,
adminDb: mockAdminDb,
}
})
import { withUser, asAdmin } from '../../../lib/db/with-user'
import { userDb, adminDb } from '../../../lib/db/index'
describe('withUser', () => {
beforeEach(() => vi.clearAllMocks())
it('sets app.user_id GUC via set_config inside transaction', async () => {
const userId = 'test-user-uuid-1234'
const fn = vi.fn().mockResolvedValue('result')
const result = await withUser(userId, fn)
expect(result).toBe('result')
// transaction was called
expect((userDb as unknown as { transaction: ReturnType<typeof vi.fn> }).transaction).toHaveBeenCalledOnce()
// fn received the tx object
expect(fn).toHaveBeenCalledOnce()
// The tx.execute was called (GUC set_config invoked)
const tx = fn.mock.calls[0][0] as { execute: ReturnType<typeof vi.fn> }
expect(tx.execute).toHaveBeenCalledOnce()
})
it('propagates errors from fn', async () => {
const fn = vi.fn().mockRejectedValue(new Error('query failed'))
await expect(withUser('uid', fn)).rejects.toThrow('query failed')
})
})
describe('asAdmin', () => {
it('passes adminDb to fn', async () => {
const fn = vi.fn().mockResolvedValue('admin-result')
const result = await asAdmin(fn)
expect(result).toBe('admin-result')
expect(fn).toHaveBeenCalledWith(adminDb)
})
})