🐛 handle idempotency when adding/removing labels from sites/resources

This commit is contained in:
Fred KISSIE
2026-05-11 16:57:53 +02:00
parent 2fd519e102
commit b9ab35a05b
2 changed files with 44 additions and 31 deletions

View File

@@ -173,33 +173,41 @@ export const labels = pgTable("labels", {
.notNull() .notNull()
}); });
export const siteLabels = pgTable("siteLabels", { export const siteLabels = pgTable(
siteLabelId: serial("siteLabelId").primaryKey(), "siteLabels",
siteId: integer("siteId") {
.references(() => sites.siteId, { siteLabelId: serial("siteLabelId").primaryKey(),
onDelete: "cascade" siteId: integer("siteId")
}) .references(() => sites.siteId, {
.notNull(), onDelete: "cascade"
labelId: integer("labelId") })
.references(() => labels.labelId, { .notNull(),
onDelete: "cascade" labelId: integer("labelId")
}) .references(() => labels.labelId, {
.notNull() onDelete: "cascade"
}); })
.notNull()
},
(t) => [unique("site_label_uniq").on(t.siteId, t.labelId)]
);
export const resourceLabels = pgTable("resourceLabels", { export const resourceLabels = pgTable(
resourceLabelId: serial("resourceLabelId").primaryKey(), "resourceLabels",
resourceId: integer("resourceId") {
.references(() => resources.resourceId, { resourceLabelId: serial("resourceLabelId").primaryKey(),
onDelete: "cascade" resourceId: integer("resourceId")
}) .references(() => resources.resourceId, {
.notNull(), onDelete: "cascade"
labelId: integer("labelId") })
.references(() => labels.labelId, { .notNull(),
onDelete: "cascade" labelId: integer("labelId")
}) .references(() => labels.labelId, {
.notNull() onDelete: "cascade"
}); })
.notNull()
},
(t) => [unique("resource_label_uniq").on(t.resourceId, t.labelId)]
);
export const targets = pgTable("targets", { export const targets = pgTable("targets", {
targetId: serial("targetId").primaryKey(), targetId: serial("targetId").primaryKey(),

View File

@@ -106,13 +106,14 @@ export async function attachLabelToItem(
); );
} }
// idempotent, calling this endpoint multiple times should attach the label only once
await db await db
.insert(siteLabels) .insert(siteLabels)
.values({ .values({
labelId, labelId,
siteId siteId
}) })
.returning(); .onConflictDoNothing();
} }
if (resourceId) { if (resourceId) {
@@ -133,10 +134,14 @@ export async function attachLabelToItem(
); );
} }
await db.insert(resourceLabels).values({ // idempotent, calling this endpoint multiple times should attach the label only once
labelId, await db
resourceId .insert(resourceLabels)
}); .values({
labelId,
resourceId
})
.onConflictDoNothing();
} }
return response(res, { return response(res, {