@takaro/db 0.4.3 → 0.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/migrations/sql/20251014120000-shop-order-auto-cancel-on-listing-delete.d.ts +4 -0
- package/dist/migrations/sql/20251014120000-shop-order-auto-cancel-on-listing-delete.d.ts.map +1 -0
- package/dist/migrations/sql/20251014120000-shop-order-auto-cancel-on-listing-delete.js +70 -0
- package/dist/migrations/sql/20251014120000-shop-order-auto-cancel-on-listing-delete.js.map +1 -0
- package/package.json +1 -1
- package/src/migrations/sql/20251014120000-shop-order-auto-cancel-on-listing-delete.ts +75 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"20251014120000-shop-order-auto-cancel-on-listing-delete.d.ts","sourceRoot":"","sources":["../../../src/migrations/sql/20251014120000-shop-order-auto-cancel-on-listing-delete.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,wBAAsB,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CA0DlD;AAED,wBAAsB,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAYpD"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
export async function up(knex) {
|
|
2
|
+
// Step 1: Create trigger function that auto-cancels orders when listing is deleted
|
|
3
|
+
await knex.raw(`
|
|
4
|
+
CREATE OR REPLACE FUNCTION cancel_orders_on_listing_delete()
|
|
5
|
+
RETURNS TRIGGER AS $$
|
|
6
|
+
BEGIN
|
|
7
|
+
-- Only proceed if deletedAt changed from NULL to a value (soft-delete)
|
|
8
|
+
IF OLD."deletedAt" IS NULL AND NEW."deletedAt" IS NOT NULL THEN
|
|
9
|
+
-- Cancel all PAID orders for this listing and refund currency
|
|
10
|
+
-- Aggregate refunds by player to handle multiple orders correctly
|
|
11
|
+
WITH orders_to_cancel AS (
|
|
12
|
+
SELECT
|
|
13
|
+
so.id AS order_id,
|
|
14
|
+
so."playerId",
|
|
15
|
+
NEW."gameServerId",
|
|
16
|
+
NEW.domain AS domain,
|
|
17
|
+
NEW.price * so.amount AS refund_amount
|
|
18
|
+
FROM "shopOrder" so
|
|
19
|
+
WHERE so."listingId" = NEW.id
|
|
20
|
+
AND so.status = 'PAID'
|
|
21
|
+
),
|
|
22
|
+
aggregated_refunds AS (
|
|
23
|
+
SELECT
|
|
24
|
+
"playerId",
|
|
25
|
+
"gameServerId",
|
|
26
|
+
domain,
|
|
27
|
+
SUM(refund_amount) AS total_refund
|
|
28
|
+
FROM orders_to_cancel
|
|
29
|
+
GROUP BY "playerId", "gameServerId", domain
|
|
30
|
+
)
|
|
31
|
+
-- Update playerOnGameServer currency with aggregated total
|
|
32
|
+
UPDATE "playerOnGameServer" pogs
|
|
33
|
+
SET currency = pogs.currency + ar.total_refund
|
|
34
|
+
FROM aggregated_refunds ar
|
|
35
|
+
WHERE pogs."playerId" = ar."playerId"
|
|
36
|
+
AND pogs."gameServerId" = ar."gameServerId"
|
|
37
|
+
AND pogs.domain = ar.domain;
|
|
38
|
+
|
|
39
|
+
-- Update order status to CANCELED
|
|
40
|
+
UPDATE "shopOrder"
|
|
41
|
+
SET status = 'CANCELED'
|
|
42
|
+
WHERE "listingId" = NEW.id
|
|
43
|
+
AND status = 'PAID';
|
|
44
|
+
END IF;
|
|
45
|
+
|
|
46
|
+
RETURN NEW;
|
|
47
|
+
END;
|
|
48
|
+
$$ LANGUAGE plpgsql;
|
|
49
|
+
`);
|
|
50
|
+
// Step 2: Create trigger on shopListing table
|
|
51
|
+
await knex.raw(`
|
|
52
|
+
CREATE TRIGGER auto_cancel_orders_on_listing_delete
|
|
53
|
+
AFTER UPDATE ON "shopListing"
|
|
54
|
+
FOR EACH ROW
|
|
55
|
+
WHEN (OLD."deletedAt" IS NULL AND NEW."deletedAt" IS NOT NULL)
|
|
56
|
+
EXECUTE FUNCTION cancel_orders_on_listing_delete();
|
|
57
|
+
`);
|
|
58
|
+
}
|
|
59
|
+
export async function down(knex) {
|
|
60
|
+
// Drop trigger
|
|
61
|
+
await knex.raw(`
|
|
62
|
+
DROP TRIGGER IF EXISTS auto_cancel_orders_on_listing_delete ON "shopListing";
|
|
63
|
+
`);
|
|
64
|
+
// Drop function
|
|
65
|
+
await knex.raw(`
|
|
66
|
+
DROP FUNCTION IF EXISTS cancel_orders_on_listing_delete();
|
|
67
|
+
`);
|
|
68
|
+
// Note: We don't reverse the data cleanup since those were genuinely bad orders
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=20251014120000-shop-order-auto-cancel-on-listing-delete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"20251014120000-shop-order-auto-cancel-on-listing-delete.js","sourceRoot":"","sources":["../../../src/migrations/sql/20251014120000-shop-order-auto-cancel-on-listing-delete.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,KAAK,UAAU,EAAE,CAAC,IAAU;IACjC,mFAAmF;IACnF,MAAM,IAAI,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8Cd,CAAC,CAAC;IAEH,8CAA8C;IAC9C,MAAM,IAAI,CAAC,GAAG,CAAC;;;;;;GAMd,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,IAAU;IACnC,eAAe;IACf,MAAM,IAAI,CAAC,GAAG,CAAC;;GAEd,CAAC,CAAC;IAEH,gBAAgB;IAChB,MAAM,IAAI,CAAC,GAAG,CAAC;;GAEd,CAAC,CAAC;IAEH,gFAAgF;AAClF,CAAC"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { Knex } from 'knex';
|
|
2
|
+
|
|
3
|
+
export async function up(knex: Knex): Promise<void> {
|
|
4
|
+
// Step 1: Create trigger function that auto-cancels orders when listing is deleted
|
|
5
|
+
await knex.raw(`
|
|
6
|
+
CREATE OR REPLACE FUNCTION cancel_orders_on_listing_delete()
|
|
7
|
+
RETURNS TRIGGER AS $$
|
|
8
|
+
BEGIN
|
|
9
|
+
-- Only proceed if deletedAt changed from NULL to a value (soft-delete)
|
|
10
|
+
IF OLD."deletedAt" IS NULL AND NEW."deletedAt" IS NOT NULL THEN
|
|
11
|
+
-- Cancel all PAID orders for this listing and refund currency
|
|
12
|
+
-- Aggregate refunds by player to handle multiple orders correctly
|
|
13
|
+
WITH orders_to_cancel AS (
|
|
14
|
+
SELECT
|
|
15
|
+
so.id AS order_id,
|
|
16
|
+
so."playerId",
|
|
17
|
+
NEW."gameServerId",
|
|
18
|
+
NEW.domain AS domain,
|
|
19
|
+
NEW.price * so.amount AS refund_amount
|
|
20
|
+
FROM "shopOrder" so
|
|
21
|
+
WHERE so."listingId" = NEW.id
|
|
22
|
+
AND so.status = 'PAID'
|
|
23
|
+
),
|
|
24
|
+
aggregated_refunds AS (
|
|
25
|
+
SELECT
|
|
26
|
+
"playerId",
|
|
27
|
+
"gameServerId",
|
|
28
|
+
domain,
|
|
29
|
+
SUM(refund_amount) AS total_refund
|
|
30
|
+
FROM orders_to_cancel
|
|
31
|
+
GROUP BY "playerId", "gameServerId", domain
|
|
32
|
+
)
|
|
33
|
+
-- Update playerOnGameServer currency with aggregated total
|
|
34
|
+
UPDATE "playerOnGameServer" pogs
|
|
35
|
+
SET currency = pogs.currency + ar.total_refund
|
|
36
|
+
FROM aggregated_refunds ar
|
|
37
|
+
WHERE pogs."playerId" = ar."playerId"
|
|
38
|
+
AND pogs."gameServerId" = ar."gameServerId"
|
|
39
|
+
AND pogs.domain = ar.domain;
|
|
40
|
+
|
|
41
|
+
-- Update order status to CANCELED
|
|
42
|
+
UPDATE "shopOrder"
|
|
43
|
+
SET status = 'CANCELED'
|
|
44
|
+
WHERE "listingId" = NEW.id
|
|
45
|
+
AND status = 'PAID';
|
|
46
|
+
END IF;
|
|
47
|
+
|
|
48
|
+
RETURN NEW;
|
|
49
|
+
END;
|
|
50
|
+
$$ LANGUAGE plpgsql;
|
|
51
|
+
`);
|
|
52
|
+
|
|
53
|
+
// Step 2: Create trigger on shopListing table
|
|
54
|
+
await knex.raw(`
|
|
55
|
+
CREATE TRIGGER auto_cancel_orders_on_listing_delete
|
|
56
|
+
AFTER UPDATE ON "shopListing"
|
|
57
|
+
FOR EACH ROW
|
|
58
|
+
WHEN (OLD."deletedAt" IS NULL AND NEW."deletedAt" IS NOT NULL)
|
|
59
|
+
EXECUTE FUNCTION cancel_orders_on_listing_delete();
|
|
60
|
+
`);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export async function down(knex: Knex): Promise<void> {
|
|
64
|
+
// Drop trigger
|
|
65
|
+
await knex.raw(`
|
|
66
|
+
DROP TRIGGER IF EXISTS auto_cancel_orders_on_listing_delete ON "shopListing";
|
|
67
|
+
`);
|
|
68
|
+
|
|
69
|
+
// Drop function
|
|
70
|
+
await knex.raw(`
|
|
71
|
+
DROP FUNCTION IF EXISTS cancel_orders_on_listing_delete();
|
|
72
|
+
`);
|
|
73
|
+
|
|
74
|
+
// Note: We don't reverse the data cleanup since those were genuinely bad orders
|
|
75
|
+
}
|