Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions web/drizzle/0018_add_service_purchase_idempotency.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
-- Per-buyer idempotency for inter-agent service purchases.
--
-- The previous partial unique index on (talosId, idempotencyKey) scoped
-- idempotency per service *provider*, which would prevent two different
-- buyers from reusing the same idempotency key on the same service — a
-- conflict with the purchase contract where the key must be scoped per
-- buyer.
--
-- We drop that provider-scoped index and replace it with a composite
-- (talosId, requesterTalosId, idempotencyKey) index so that the same key
-- is safe to reuse across different buyers on the same service, while
-- still blocking duplicate jobs for the same buyer+service+key.

DROP INDEX IF EXISTS "tls_commerce_jobs_talosId_idempotencyKey_unique";

CREATE UNIQUE INDEX IF NOT EXISTS "tls_commerce_jobs_talos_requester_idempotencyKey_unique"
ON "tls_commerce_jobs" ("talosId", "requesterTalosId", "idempotencyKey")
WHERE "idempotencyKey" IS NOT NULL;
10 changes: 8 additions & 2 deletions web/drizzle/meta/0015_snapshot.json
Original file line number Diff line number Diff line change
Expand Up @@ -456,15 +456,21 @@
"method": "btree",
"with": {}
},
"tls_commerce_jobs_talosId_idempotencyKey_unique": {
"name": "tls_commerce_jobs_talosId_idempotencyKey_unique",
"tls_commerce_jobs_talos_requester_idempotencyKey_unique": {
"name": "tls_commerce_jobs_talos_requester_idempotencyKey_unique",
"columns": [
{
"expression": "talosId",
"isExpression": false,
"asc": true,
"nulls": "last"
},
{
"expression": "requesterTalosId",
"isExpression": false,
"asc": true,
"nulls": "last"
},
{
"expression": "idempotencyKey",
"isExpression": false,
Expand Down
2 changes: 1 addition & 1 deletion web/drizzle/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ fencingToken: integer().default(0).notNull(),
}, (table) => [
index("tls_commerce_jobs_talosId_status_idx").using("btree", table.talosId.asc().nullsLast().op("text_ops"), table.status.asc().nullsLast().op("text_ops")),
uniqueIndex("tls_commerce_jobs_paymentSig_unique").using("btree", table.paymentSig.asc().nullsLast().op("text_ops")).where(sql`"paymentSig" IS NOT NULL`),
uniqueIndex("tls_commerce_jobs_talosId_idempotencyKey_unique").using("btree", table.talosId.asc().nullsLast().op("text_ops"), table.idempotencyKey.asc().nullsLast().op("text_ops")).where(sql`"idempotencyKey" IS NOT NULL`),
uniqueIndex("tls_commerce_jobs_talos_requester_idempotencyKey_unique").using("btree", table.talosId.asc().nullsLast().op("text_ops"), table.requesterTalosId.asc().nullsLast().op("text_ops"), table.idempotencyKey.asc().nullsLast().op("text_ops")).where(sql`"idempotencyKey" IS NOT NULL`),
foreignKey({
columns: [table.talosId],
foreignColumns: [tlsTalos.id],
Expand Down
Loading