Skip to content

Commit

Permalink
feat(api): improve create user (#336)
Browse files Browse the repository at this point in the history
Now POST /users will actually upsert the user in database. When creating user in database fails, delete the existing user on Clerk.
  • Loading branch information
duongdev committed Sep 19, 2024
1 parent 605be77 commit d5ca2de
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 9 deletions.
9 changes: 5 additions & 4 deletions apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@6pm/utilities": "workspace:^",
"@6pm/validation": "workspace:^",
"@clerk/backend": "^1.2.4",
"@clerk/clerk-sdk-node": "^5.0.42",
"@hono/clerk-auth": "^2.0.0",
"@hono/node-server": "^1.11.4",
"@hono/zod-validator": "^0.2.2",
Expand All @@ -28,14 +29,14 @@
"hono": "^4.4.8",
"next": "^14.2.4",
"openai": "^4.52.7",
"pino-pretty": "^11.2.1",
"pino": "^9.2.0",
"pino-pretty": "^11.2.1",
"prisma": "5.19.0",
"react-dom": "18.3.1",
"react": "18.3.1",
"react-dom": "18.3.1",
"svix": "^1.28.0",
"zod-prisma-types": "^3.1.8",
"zod": "^3.23.8"
"zod": "^3.23.8",
"zod-prisma-types": "^3.1.8"
},
"devDependencies": {
"@types/node": "18.11.18",
Expand Down
15 changes: 14 additions & 1 deletion apps/api/v1/routes/users.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { zCreateUser } from '@6pm/validation'
import { zValidator } from '@hono/zod-validator'
import { Hono } from 'hono'
import { getLogger } from '../../lib/log'
import { getAuthUser } from '../middlewares/auth'
import { bootstrapUserDefaultCategories } from '../services/category.service'
import { deleteClerkUser } from '../services/clerk.service'
import { createUser } from '../services/user.service'
import { bootstrapUserDefaultWalletAccounts } from '../services/wallet.service'
import { zDeviceCurrencyHeader, zDeviceLanguageHeader } from './utils'
Expand All @@ -16,12 +18,19 @@ const router = new Hono().post(
const existingUser = getAuthUser(c)
const deviceLanguage = c.req.valid('header')['x-device-language']
const deviceCurrency = c.req.valid('header')['x-device-currency']
const logger = getLogger('POST /users')

if (existingUser) {
return c.json({ message: 'user already exists' }, 409)
}

const userId = c.get('userId')!
const userId = c.get('userId')

if (!userId) {
logger.warn('Clerk userId not found from headers while creating user')
return c.json({ message: 'unauthorized' }, 401)
}

const data = c.req.valid('json')

try {
Expand All @@ -39,6 +48,10 @@ const router = new Hono().post(

return c.json(user, 201)
} catch (e) {
logger.error('Failed to create user %o', e)

await deleteClerkUser(userId)

return c.json({ userId, message: 'failed to create user', cause: e }, 500)
}
},
Expand Down
16 changes: 16 additions & 0 deletions apps/api/v1/services/clerk.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { clerkClient } from '@clerk/clerk-sdk-node'
import { getLogger } from '../../lib/log'

export async function deleteClerkUser(userId: string) {
const logger = getLogger(`clerk.service:${deleteClerkUser.name}:${userId}`)

try {
const deletedUser = await clerkClient.users.deleteUser(userId)
logger.debug(`Deleted user %o`, deletedUser)
return deletedUser
} catch (error) {
logger.error(`Failed to delete user with id: ${userId}`)
logger.debug(error)
throw error
}
}
11 changes: 9 additions & 2 deletions apps/api/v1/services/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,16 @@ export async function findUserByEmail(email: string) {
}

export async function createUser({ data }: { data: CreateUser }) {
return await prisma.user.create({
data,
const user = await prisma.user.upsert({
where: {
id: data.id,
email: data.email,
},
create: data,
update: data,
})

return user
}

export async function deleteUser(userId: string) {
Expand Down
67 changes: 65 additions & 2 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit d5ca2de

Please sign in to comment.