-
Notifications
You must be signed in to change notification settings - Fork 612
fix: upsert identity when creating keys in dashboard #2111
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
aef29c2
caf3f87
db49abd
fd7369c
fe706b7
ed476fd
bece6ec
37dd148
b3797a4
b4f9273
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,4 +1,4 @@ | ||||||
| import { db, schema } from "@/lib/db"; | ||||||
| import { type Database, type Identity, db, schema } from "@/lib/db"; | ||||||
| import { ingestAuditLogs } from "@/lib/tinybird"; | ||||||
| import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; | ||||||
| import { TRPCError } from "@trpc/server"; | ||||||
|
|
@@ -77,6 +77,10 @@ export const createKey = rateLimitedProcedure(ratelimit.create) | |||||
| }); | ||||||
| } | ||||||
|
|
||||||
| const identity = input.ownerId | ||||||
| ? await upsertIdentity(db, keyAuth.workspaceId, input.ownerId) | ||||||
| : null; | ||||||
|
|
||||||
| const keyId = newId("key"); | ||||||
| const { key, hash, start } = await newKey({ | ||||||
| prefix: input.prefix, | ||||||
|
|
@@ -107,6 +111,7 @@ export const createKey = rateLimitedProcedure(ratelimit.create) | |||||
| deletedAt: null, | ||||||
| enabled: input.enabled, | ||||||
| environment: input.environment, | ||||||
| identityId: identity?.id, | ||||||
| }) | ||||||
| .catch((_err) => { | ||||||
| throw new TRPCError({ | ||||||
|
|
@@ -135,3 +140,53 @@ export const createKey = rateLimitedProcedure(ratelimit.create) | |||||
|
|
||||||
| return { keyId, key }; | ||||||
| }); | ||||||
|
|
||||||
| async function upsertIdentity( | ||||||
| db: Database, | ||||||
| workspaceId: string, | ||||||
| externalId: string, | ||||||
| ): Promise<Identity> { | ||||||
| let identity = await db.query.identities.findFirst({ | ||||||
| where: (table, { and, eq }) => | ||||||
| and(eq(table.workspaceId, workspaceId), eq(table.externalId, externalId)), | ||||||
| }); | ||||||
|
Comment on lines
+149
to
+152
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Optimize Currently, if the identity does not exist, you insert it and then perform another query to retrieve the identity. This results in two database calls. You can optimize this by using the result of the insert operation or by using an Modify the if (!identity) {
- await db
+ identity = await db
.insert(schema.identities)
.values({
id: newId("identity"),
- createdAt: Date.now(),
+ createdAt: new Date(),
environment: "default",
- meta: {},
+ meta: JSON.stringify({}),
externalId,
- updatedAt: null,
+ updatedAt: null,
workspaceId,
})
.onDuplicateKeyUpdate({
set: {
- updatedAt: Date.now(),
+ updatedAt: new Date(),
},
})
+ .returning()
+ .then((rows) => rows[0])
.catch((_err) => {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: "Failed to insert identity",
});
});
- identity = await db.query.identities
- .findFirst({
- where: (table, { and, eq }) =>
- and(
- eq(table.workspaceId, workspaceId),
- eq(table.externalId, externalId)
- ),
- })
- .catch((_err) => {
- throw new TRPCError({
- code: "INTERNAL_SERVER_ERROR",
- message: "Failed to read identity after upsert",
- });
- });
}This change eliminates the need for a second query, improving the efficiency of the function. Also applies to: 178-185 |
||||||
|
|
||||||
| if (!identity) { | ||||||
| await db | ||||||
| .insert(schema.identities) | ||||||
| .values({ | ||||||
| id: newId("identity"), | ||||||
| createdAt: Date.now(), | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use In your code, you're using Apply this diff to fix the inconsistency: - createdAt: Date.now(),
+ createdAt: new Date(),And in the - updatedAt: Date.now(),
+ updatedAt: new Date(),Also applies to: 168-168 |
||||||
| environment: "default", | ||||||
| meta: {}, | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ensure consistent handling of the In the Consider serializing - meta: {},
+ meta: JSON.stringify({}),Or, if the database schema for 📝 Committable suggestion
Suggested change
|
||||||
| externalId, | ||||||
| updatedAt: null, | ||||||
| workspaceId, | ||||||
| }) | ||||||
| .onDuplicateKeyUpdate({ | ||||||
| set: { | ||||||
| updatedAt: Date.now(), | ||||||
| }, | ||||||
| }) | ||||||
| .catch((_err) => { | ||||||
| throw new TRPCError({ | ||||||
| code: "INTERNAL_SERVER_ERROR", | ||||||
| message: "Failed to insert identity", | ||||||
| }); | ||||||
| }); | ||||||
|
|
||||||
| identity = await db.query.identities | ||||||
| .findFirst({ | ||||||
| where: (table, { and, eq }) => | ||||||
| and(eq(table.workspaceId, workspaceId), eq(table.externalId, externalId)), | ||||||
| }) | ||||||
| .catch((_err) => { | ||||||
| throw new TRPCError({ | ||||||
| code: "INTERNAL_SERVER_ERROR", | ||||||
| message: "Failed to read identity after upsert", | ||||||
| }); | ||||||
| }); | ||||||
| } | ||||||
|
|
||||||
| return identity as Identity; | ||||||
| } | ||||||
|
Comment on lines
+144
to
+192
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Optimize upsertIdentity function and address inconsistencies The new
Here's a suggested refactor: async function upsertIdentity(
db: Database,
workspaceId: string,
externalId: string,
): Promise<Identity> {
try {
const result = await db
.insert(schema.identities)
.values({
id: newId("identity"),
createdAt: new Date(),
environment: "default",
meta: JSON.stringify({}),
externalId,
updatedAt: null,
workspaceId,
})
.onConflict((oc) =>
oc.constraint('identities_workspace_id_external_id_unique').merge({
updatedAt: new Date(),
})
)
.returning()
.execute();
return result[0] as Identity;
} catch (error) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: "Failed to upsert identity",
cause: error,
});
}
}This refactored version addresses the identified issues and improves the overall efficiency and consistency of the function. |
||||||
Uh oh!
There was an error while loading. Please reload this page.