Skip to content

Commit 73dcf64

Browse files
committed
refactor(db): split session context API into distinct handler and context functions
Previously, the session context API had confusing naming and overlapping responsibilities: - withSessionDb and withImpersonation did the same thing (confusing) - withImpersonation had two overloads for different use cases (ambiguous) - databaseType field was exposed but never used (bloat) This refactor creates a clearer, more intentional API: ## API Changes **Before:** - withSessionDb(handler, options) - callback pattern - withImpersonation() - get context OR callback pattern (overloaded) **After:** - withImpersonation(handler, options) - callback pattern for server actions - getImpersonationContext(options) - context retrieval for components/routes ## New Function Purposes **withImpersonation(handler, options)** - Execute handler with session context - Best for: Server actions, self-contained operations - Usage: `return withImpersonation(async ({ db, userId }) => { ... })` **getImpersonationContext(options)** - Retrieve session context for use in outer scope - Best for: Server components, API routes, complex flow control - Usage: `const { db, userId } = await getImpersonationContext()` ## Type Changes - SessionDbContext → SessionContext - WithSessionDbOptions → SessionContextOptions - Removed: databaseType field (unused) - Removed: DatabaseType type (unused) - Removed: getDatabaseType() function (unused) ## Benefits ✓ Clear naming convention (get* vs with*) ✓ Single responsibility per function ✓ More discoverable API (name indicates usage) ✓ Follows Next.js patterns (getServerSession, etc.) ✓ Removed unused code (databaseType) ✓ Better documentation with usage examples ## Files Changed: 68 - 52 files using withImpersonation (callback pattern) - 54 files using getImpersonationContext (direct context) - 2 core files updated (sessionContext.ts, helpers.ts)
1 parent 18c2d56 commit 73dcf64

File tree

69 files changed

+291
-306
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+291
-306
lines changed

app/src/app/api/admin/impersonation-status/route.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ import {
1010
isAdminUser,
1111
isImpersonationEnabled,
1212
} from "@/lib/auth/adminConfig"
13-
import { withImpersonation } from "@/lib/db/sessionContext"
13+
import { getImpersonationContext } from "@/lib/db/sessionContext"
1414

1515
export const dynamic = 'force-dynamic'
1616

1717
export async function GET() {
1818
try {
19-
const { session, userId } = await withImpersonation()
19+
const { session, userId } = await getImpersonationContext()
2020
const adminUserId = session?.user?.id
2121

2222
if (!userId || !adminUserId) {

app/src/app/api/admin/search-users/route.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import { NextRequest, NextResponse } from "next/server"
77
import { isAdminUser, isImpersonationEnabled } from "@/lib/auth/adminConfig"
8-
import { withImpersonation } from "@/lib/db/sessionContext"
8+
import { getImpersonationContext } from "@/lib/db/sessionContext"
99
import { impersonationService } from "@/lib/services/impersonationService"
1010

1111
export const dynamic = 'force-dynamic'
@@ -19,7 +19,7 @@ export async function GET(request: NextRequest) {
1919
)
2020
}
2121

22-
const { session, userId } = await withImpersonation()
22+
const { session, userId } = await getImpersonationContext()
2323
const adminUserId = session?.user?.id
2424
if (!userId || !adminUserId) {
2525
return NextResponse.json(

app/src/app/api/cron/kyc-emails/route.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { NextRequest } from "next/server"
22

3-
import { withImpersonation } from "@/lib/db/sessionContext"
3+
import { getImpersonationContext } from "@/lib/db/sessionContext"
44
import { withCronObservability } from "@/lib/cron"
55
import {
66
sendKYBReminderEmail,
@@ -24,7 +24,7 @@ async function handleKYCEmailsCron(request: NextRequest) {
2424
errors: [] as string[],
2525
}
2626

27-
const { db } = await withImpersonation({ forceProd: true, session: null })
27+
const { db } = await getImpersonationContext({ forceProd: true, session: null })
2828

2929
try {
3030
console.log("🔍 Processing KYC reminder emails...")

app/src/app/api/kyc/verify/[token]/route.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ import { NextRequest, NextResponse } from "next/server"
22

33
import { verifyKYCToken, isKYCLinkExpired } from "@/lib/utils/kycToken"
44
import { personaClient } from "@/lib/persona"
5-
import { withImpersonation } from "@/lib/db/sessionContext"
5+
import { getImpersonationContext } from "@/lib/db/sessionContext"
66

77
export async function POST(
88
request: NextRequest,
99
{ params }: { params: { token: string } },
1010
) {
1111
try {
12-
const { db } = await withImpersonation({ forceProd: true, session: null })
12+
const { db } = await getImpersonationContext({ forceProd: true, session: null })
1313
const { token } = params
1414

1515
// Verify and decode the token

app/src/app/api/projects/[projectId]/contracts/count/route.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { NextResponse } from "next/server"
22
import { getAddress } from "viem"
33

4-
import { withImpersonation } from "@/lib/db/sessionContext"
4+
import { getImpersonationContext } from "@/lib/db/sessionContext"
55

66
export const dynamic = "force-dynamic"
77
export const revalidate = 0
@@ -10,7 +10,7 @@ export async function GET(
1010
request: Request,
1111
{ params }: { params: { projectId: string } },
1212
) {
13-
const { db } = await withImpersonation()
13+
const { db } = await getImpersonationContext()
1414
const { searchParams } = new URL(request.url)
1515
const deployer = searchParams.get("deployer")
1616

app/src/app/api/projects/[projectId]/contracts/publish-progress/route.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { NextResponse } from "next/server"
33
import { getProjectContractsFresh } from "@/db/projects"
44
import { getUnpublishedContractChanges } from "@/lib/actions/projects"
55
import { verifyMembership } from "@/lib/actions/utils"
6-
import { withImpersonation } from "@/lib/db/sessionContext"
6+
import { getImpersonationContext } from "@/lib/db/sessionContext"
77

88
export const dynamic = "force-dynamic"
99
export const revalidate = 0
@@ -15,7 +15,7 @@ export async function GET(
1515
const { projectId } = params
1616

1717
try {
18-
const { db, userId } = await withImpersonation()
18+
const { db, userId } = await getImpersonationContext()
1919

2020
if (!userId) {
2121
return NextResponse.json({ error: "Unauthorized" }, { status: 401 })

app/src/app/api/sc/endorsements/eligibility/route.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { NextRequest, NextResponse } from "next/server"
22

3-
import { withImpersonation } from "@/lib/db/sessionContext"
3+
import { getImpersonationContext } from "@/lib/db/sessionContext"
44
import { isTop100Delegate } from "@/lib/services/top100"
55

66
export async function GET(req: NextRequest) {
7-
const { db, userId } = await withImpersonation()
7+
const { db, userId } = await getImpersonationContext()
88
const { searchParams } = new URL(req.url)
99
const roleId = Number(searchParams.get("roleId"))
1010

app/src/app/api/sc/endorsements/me/route.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import { NextRequest, NextResponse } from "next/server"
22

3-
import { withImpersonation } from "@/lib/db/sessionContext"
3+
import { getImpersonationContext } from "@/lib/db/sessionContext"
44
import {
55
getEndorsedNomineeIdsForAddressesByRole,
66
hasEndorsed,
77
} from "@/db/endorsements"
88

99
export async function GET(req: NextRequest) {
10-
const { db, userId } = await withImpersonation()
10+
const { db, userId } = await getImpersonationContext()
1111
if (!userId) return new Response("Unauthorized", { status: 401 })
1212
const { searchParams } = new URL(req.url)
1313
const context = searchParams.get("context")

app/src/app/api/sc/endorsements/route.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { NextRequest, NextResponse } from "next/server"
22
import { z } from "zod"
33

4-
import { withImpersonation } from "@/lib/db/sessionContext"
4+
import { getImpersonationContext } from "@/lib/db/sessionContext"
55
import {
66
createEndorsement,
77
deleteEndorsementsForAddresses,
@@ -18,7 +18,7 @@ const payloadSchema = z.object({
1818
})
1919

2020
export async function POST(req: NextRequest) {
21-
const { db, userId } = await withImpersonation()
21+
const { db, userId } = await getImpersonationContext()
2222
if (!userId) return new Response("Unauthorized", { status: 401 })
2323

2424
const json = await req.json().catch(() => null)
@@ -103,7 +103,7 @@ export async function POST(req: NextRequest) {
103103
}
104104

105105
export async function GET(req: NextRequest) {
106-
const { db } = await withImpersonation()
106+
const { db } = await getImpersonationContext()
107107
const { searchParams } = new URL(req.url)
108108
const context = searchParams.get("context")
109109
const roleId = Number(searchParams.get("roleId"))
@@ -154,7 +154,7 @@ export async function GET(req: NextRequest) {
154154
}
155155

156156
export async function DELETE(req: NextRequest) {
157-
const { db, userId } = await withImpersonation()
157+
const { db, userId } = await getImpersonationContext()
158158
if (!userId) return new Response("Unauthorized", { status: 401 })
159159

160160
const { searchParams } = new URL(req.url)

app/src/app/api/sc/top100/route.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { NextResponse } from "next/server"
22

3-
import { withImpersonation } from "@/lib/db/sessionContext"
3+
import { getImpersonationContext } from "@/lib/db/sessionContext"
44
import { isTop100Delegate } from "@/lib/services/top100"
55

66
export async function GET() {
7-
const { db, userId } = await withImpersonation()
7+
const { db, userId } = await getImpersonationContext()
88

99
if (!userId) {
1010
return NextResponse.json({ top100: false })

0 commit comments

Comments
 (0)