@infuro/cms-core 1.0.30 → 1.0.33
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/README.md +20 -15
- package/dist/admin.cjs +13061 -7814
- package/dist/admin.cjs.map +1 -1
- package/dist/admin.d.cts +13 -2
- package/dist/admin.d.ts +13 -2
- package/dist/admin.js +8416 -3167
- package/dist/admin.js.map +1 -1
- package/dist/api.cjs +5667 -1110
- package/dist/api.cjs.map +1 -1
- package/dist/api.d.cts +2 -2
- package/dist/api.d.ts +2 -2
- package/dist/api.js +5418 -855
- package/dist/api.js.map +1 -1
- package/dist/auth.cjs +620 -76
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.d.cts +93 -52
- package/dist/auth.d.ts +93 -52
- package/dist/auth.js +578 -52
- package/dist/auth.js.map +1 -1
- package/dist/cli.cjs +19 -15
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +19 -15
- package/dist/cli.js.map +1 -1
- package/dist/{index-BPQSXgXF.d.cts → index-DWd5Gjc4.d.ts} +38 -5
- package/dist/{index-D9SdaDJ0.d.ts → index-rZTnpK7y.d.cts} +38 -5
- package/dist/index.cjs +5921 -1177
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +334 -59
- package/dist/index.d.ts +334 -59
- package/dist/index.js +5733 -1026
- package/dist/index.js.map +1 -1
- package/dist/migrations/1775400000001-AddDiscountAndOrderAddresses.ts +274 -0
- package/dist/migrations/1775800000000-VendorsAndVendorUsers.ts +74 -0
- package/dist/migrations/1775900000000-StoreVendorIdColumns.ts +124 -0
- package/dist/migrations/1775910000000-VendorOwnerRbacSeed.ts +54 -0
- package/dist/migrations/1775920000000-VendorOwnerSettingsPermission.ts +25 -0
- package/dist/migrations/1775930000000-VendorGroupStorePermissions.ts +54 -0
- package/dist/migrations/1775940000000-VendorRls.ts +71 -0
- package/dist/migrations/1775950000000-VendorCustomers.ts +87 -0
- package/dist/migrations/1775950000001-VendorCustomersPermissions.ts +67 -0
- package/dist/migrations/1778652250860-CreateCurrencyTables.ts +16 -0
- package/dist/migrations/1778652250861-OrderAddressTables.ts +88 -0
- package/dist/migrations/1778652250862-UpdateDiscountandRules.ts +100 -0
- package/dist/migrations/1778652250863-MakeCouponCodeNullable.ts +19 -0
- package/dist/migrations/1778652250864-RemoveUniqueConstraintFromDiscountCouponCode.ts +22 -0
- package/dist/migrations/1778652250865-FixOrdersAddressForeignKeys.ts +71 -0
- package/dist/migrations/1778660000000-DiscountVendorId.ts +90 -0
- package/dist/migrations/1778660000001-FixOrdersAddressFkToOrderAddresses.ts +79 -0
- package/dist/migrations/1778660000002-VendorUserIdInviteStatus.ts +61 -0
- package/dist/migrations/1778660000003-AddQrTokenToOrders.ts +32 -0
- package/dist/migrations/1779100000000-ChatConversationLeadEmailSent.ts +16 -0
- package/dist/migrations/1779200000000-LlmAgentScope.ts +72 -0
- package/dist/theme.d.cts +2 -2
- package/dist/theme.d.ts +2 -2
- package/dist/{types-D34wmivy.d.cts → types-DCVaXlPV.d.cts} +1 -1
- package/dist/{types-D34wmivy.d.ts → types-DCVaXlPV.d.ts} +1 -1
- package/dist/vendor-scope-DTYhJk_I.d.cts +129 -0
- package/dist/vendor-scope-DTYhJk_I.d.ts +129 -0
- package/package.json +3 -2
- package/dist/helpers-dlrF_49e.d.cts +0 -60
- package/dist/helpers-dlrF_49e.d.ts +0 -60
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { MigrationInterface, QueryRunner } from 'typeorm';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Creates the `vendor_customers` table and enables Row Level Security on it.
|
|
5
|
+
*
|
|
6
|
+
* Each row links a vendor to one of their contacts (customers). The RLS policy
|
|
7
|
+
* mirrors the one on all other vendor-scoped store tables: a row is visible only
|
|
8
|
+
* when `app.vendor_id` matches the row's `vendorId`, or when `app.vendor_id` is
|
|
9
|
+
* unset / '0' (platform-admin / no restriction).
|
|
10
|
+
*/
|
|
11
|
+
export class VendorCustomers1775950000000 implements MigrationInterface {
|
|
12
|
+
name = 'VendorCustomers1775950000000';
|
|
13
|
+
|
|
14
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
15
|
+
await queryRunner.query(`
|
|
16
|
+
CREATE TABLE IF NOT EXISTS "vendor_customers" (
|
|
17
|
+
"id" SERIAL NOT NULL,
|
|
18
|
+
"vendorId" integer NOT NULL,
|
|
19
|
+
"contactId" integer NOT NULL,
|
|
20
|
+
"notes" text,
|
|
21
|
+
"tags" text,
|
|
22
|
+
"createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
23
|
+
"updatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
24
|
+
CONSTRAINT "PK_vendor_customers" PRIMARY KEY ("id")
|
|
25
|
+
)
|
|
26
|
+
`);
|
|
27
|
+
|
|
28
|
+
await queryRunner.query(`
|
|
29
|
+
DO $$ BEGIN
|
|
30
|
+
ALTER TABLE "vendor_customers"
|
|
31
|
+
ADD CONSTRAINT "FK_vendor_customers_vendor"
|
|
32
|
+
FOREIGN KEY ("vendorId") REFERENCES "vendors"("id") ON DELETE CASCADE ON UPDATE NO ACTION;
|
|
33
|
+
EXCEPTION WHEN duplicate_object THEN NULL; END $$
|
|
34
|
+
`);
|
|
35
|
+
|
|
36
|
+
await queryRunner.query(`
|
|
37
|
+
DO $$ BEGIN
|
|
38
|
+
ALTER TABLE "vendor_customers"
|
|
39
|
+
ADD CONSTRAINT "FK_vendor_customers_contact"
|
|
40
|
+
FOREIGN KEY ("contactId") REFERENCES "contacts"("id") ON DELETE CASCADE ON UPDATE NO ACTION;
|
|
41
|
+
EXCEPTION WHEN duplicate_object THEN NULL; END $$
|
|
42
|
+
`);
|
|
43
|
+
|
|
44
|
+
await queryRunner.query(`
|
|
45
|
+
DO $$ BEGIN
|
|
46
|
+
ALTER TABLE "vendor_customers"
|
|
47
|
+
ADD CONSTRAINT "UQ_vendor_customers_vendor_contact"
|
|
48
|
+
UNIQUE ("vendorId", "contactId");
|
|
49
|
+
EXCEPTION WHEN duplicate_object THEN NULL; END $$
|
|
50
|
+
`);
|
|
51
|
+
|
|
52
|
+
await queryRunner.query(`
|
|
53
|
+
CREATE INDEX IF NOT EXISTS "IDX_vendor_customers_vendor"
|
|
54
|
+
ON "vendor_customers" ("vendorId")
|
|
55
|
+
`);
|
|
56
|
+
|
|
57
|
+
await queryRunner.query(`
|
|
58
|
+
CREATE INDEX IF NOT EXISTS "IDX_vendor_customers_contact"
|
|
59
|
+
ON "vendor_customers" ("contactId")
|
|
60
|
+
`);
|
|
61
|
+
|
|
62
|
+
// Row Level Security — same pattern as other vendor-scoped tables.
|
|
63
|
+
await queryRunner.query(`ALTER TABLE "vendor_customers" ENABLE ROW LEVEL SECURITY`);
|
|
64
|
+
await queryRunner.query(`ALTER TABLE "vendor_customers" FORCE ROW LEVEL SECURITY`);
|
|
65
|
+
await queryRunner.query(`DROP POLICY IF EXISTS "vendor_isolation" ON "vendor_customers"`);
|
|
66
|
+
await queryRunner.query(`
|
|
67
|
+
CREATE POLICY "vendor_isolation" ON "vendor_customers"
|
|
68
|
+
USING (
|
|
69
|
+
COALESCE(NULLIF(current_setting('app.vendor_id', true), ''), '0') = '0'
|
|
70
|
+
OR "vendorId" = NULLIF(current_setting('app.vendor_id', true), '')::integer
|
|
71
|
+
)
|
|
72
|
+
WITH CHECK (
|
|
73
|
+
COALESCE(NULLIF(current_setting('app.vendor_id', true), ''), '0') = '0'
|
|
74
|
+
OR "vendorId" = NULLIF(current_setting('app.vendor_id', true), '')::integer
|
|
75
|
+
)
|
|
76
|
+
`);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
80
|
+
await queryRunner.query(`DROP POLICY IF EXISTS "vendor_isolation" ON "vendor_customers"`);
|
|
81
|
+
await queryRunner.query(`ALTER TABLE "vendor_customers" NO FORCE ROW LEVEL SECURITY`);
|
|
82
|
+
await queryRunner.query(`ALTER TABLE "vendor_customers" DISABLE ROW LEVEL SECURITY`);
|
|
83
|
+
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_vendor_customers_contact"`);
|
|
84
|
+
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_vendor_customers_vendor"`);
|
|
85
|
+
await queryRunner.query(`DROP TABLE IF EXISTS "vendor_customers"`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { MigrationInterface, QueryRunner } from 'typeorm';
|
|
2
|
+
|
|
3
|
+
/** Grant vendor groups CRUD on `vendor_customers` (Customers tab). */
|
|
4
|
+
export class VendorCustomersPermissions1775950000001 implements MigrationInterface {
|
|
5
|
+
name = 'VendorCustomersPermissions1775950000001';
|
|
6
|
+
|
|
7
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
8
|
+
// Ensure unique (groupId, entity) so future permission seeds can use ON CONFLICT.
|
|
9
|
+
await queryRunner.query(`
|
|
10
|
+
DELETE FROM permissions a USING permissions b
|
|
11
|
+
WHERE a.id > b.id AND a."groupId" = b."groupId" AND a.entity = b.entity
|
|
12
|
+
`);
|
|
13
|
+
await queryRunner.query(`
|
|
14
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "UQ_permissions_group_entity"
|
|
15
|
+
ON "permissions" ("groupId", "entity")
|
|
16
|
+
`);
|
|
17
|
+
|
|
18
|
+
await queryRunner.query(`
|
|
19
|
+
INSERT INTO "permissions" ("groupId", "entity", "canCreate", "canRead", "canUpdate", "canDelete")
|
|
20
|
+
SELECT g.id, 'vendor_customers', true, true, true, true
|
|
21
|
+
FROM "user_groups" g
|
|
22
|
+
WHERE g.deleted = false
|
|
23
|
+
AND (
|
|
24
|
+
lower(g.name) LIKE '%vendor%'
|
|
25
|
+
OR g.name = 'Vendor Owner'
|
|
26
|
+
)
|
|
27
|
+
AND g.name <> 'Administrator'
|
|
28
|
+
AND NOT EXISTS (
|
|
29
|
+
SELECT 1 FROM "permissions" p
|
|
30
|
+
WHERE p."groupId" = g.id AND p.entity = 'vendor_customers'
|
|
31
|
+
)
|
|
32
|
+
`);
|
|
33
|
+
|
|
34
|
+
await queryRunner.query(`
|
|
35
|
+
UPDATE "permissions" p
|
|
36
|
+
SET
|
|
37
|
+
"canCreate" = true,
|
|
38
|
+
"canRead" = true,
|
|
39
|
+
"canUpdate" = true,
|
|
40
|
+
"canDelete" = true
|
|
41
|
+
FROM "user_groups" g
|
|
42
|
+
WHERE p."groupId" = g.id
|
|
43
|
+
AND p.entity = 'vendor_customers'
|
|
44
|
+
AND g.deleted = false
|
|
45
|
+
AND (
|
|
46
|
+
lower(g.name) LIKE '%vendor%'
|
|
47
|
+
OR g.name = 'Vendor Owner'
|
|
48
|
+
)
|
|
49
|
+
AND g.name <> 'Administrator'
|
|
50
|
+
`);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
54
|
+
await queryRunner.query(`
|
|
55
|
+
DELETE FROM "permissions" p
|
|
56
|
+
USING "user_groups" g
|
|
57
|
+
WHERE p."groupId" = g.id
|
|
58
|
+
AND p.entity = 'vendor_customers'
|
|
59
|
+
AND g.deleted = false
|
|
60
|
+
AND (
|
|
61
|
+
lower(g.name) LIKE '%vendor%'
|
|
62
|
+
OR g.name = 'Vendor Owner'
|
|
63
|
+
)
|
|
64
|
+
AND g.name <> 'Administrator'
|
|
65
|
+
`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
export class CreateCurrencyTables1778652250860 implements MigrationInterface {
|
|
4
|
+
name = 'CreateCurrencyTables1778652250860'
|
|
5
|
+
|
|
6
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
7
|
+
await queryRunner.query(`CREATE TABLE "currency" ("id" SERIAL NOT NULL, "code" character varying NOT NULL, "name" character varying NOT NULL, "symbol" character varying NOT NULL, "isActive" boolean NOT NULL DEFAULT true, "isBaseCurrency" boolean NOT NULL DEFAULT false, CONSTRAINT "UQ_723472e41cae44beb0763f4039c" UNIQUE ("code"), CONSTRAINT "PK_3cda65c731a6264f0e444cc9b91" PRIMARY KEY ("id"))`);
|
|
8
|
+
await queryRunner.query(`CREATE TABLE "currency_exchange" ("id" SERIAL NOT NULL, "fromCurrency" character varying NOT NULL, "toCurrency" character varying NOT NULL, "rate" numeric(12,6) NOT NULL, CONSTRAINT "PK_408ce7731cf7527a37ad3848d2b" PRIMARY KEY ("id"))`);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
12
|
+
await queryRunner.query(`DROP TABLE "currency_exchange"`);
|
|
13
|
+
await queryRunner.query(`DROP TABLE "currency"`);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from 'typeorm';
|
|
2
|
+
|
|
3
|
+
export class UpdateOrdersAddressRelations1778652250861
|
|
4
|
+
implements MigrationInterface
|
|
5
|
+
{
|
|
6
|
+
name = 'UpdateOrdersAddressRelations1778652250861';
|
|
7
|
+
|
|
8
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
9
|
+
await queryRunner.query(`
|
|
10
|
+
ALTER TABLE "orders"
|
|
11
|
+
DROP CONSTRAINT IF EXISTS "FK_orders_billingAddressId_address"
|
|
12
|
+
`);
|
|
13
|
+
|
|
14
|
+
await queryRunner.query(`
|
|
15
|
+
ALTER TABLE "orders"
|
|
16
|
+
DROP CONSTRAINT IF EXISTS "FK_orders_shippingAddressId_address"
|
|
17
|
+
`);
|
|
18
|
+
|
|
19
|
+
await queryRunner.query(`
|
|
20
|
+
ALTER TABLE "orders"
|
|
21
|
+
ADD CONSTRAINT "FK_orders_billing_order_address"
|
|
22
|
+
FOREIGN KEY ("billingAddressId")
|
|
23
|
+
REFERENCES "order_addresses"("id")
|
|
24
|
+
ON DELETE SET NULL
|
|
25
|
+
`);
|
|
26
|
+
|
|
27
|
+
await queryRunner.query(`
|
|
28
|
+
ALTER TABLE "orders"
|
|
29
|
+
ADD CONSTRAINT "FK_orders_shipping_order_address"
|
|
30
|
+
FOREIGN KEY ("shippingAddressId")
|
|
31
|
+
REFERENCES "order_addresses"("id")
|
|
32
|
+
ON DELETE SET NULL
|
|
33
|
+
`);
|
|
34
|
+
|
|
35
|
+
await queryRunner.query(`
|
|
36
|
+
ALTER TABLE "order_addresses"
|
|
37
|
+
DROP CONSTRAINT IF EXISTS "FK_order_addresses_contact"
|
|
38
|
+
`);
|
|
39
|
+
|
|
40
|
+
await queryRunner.query(`
|
|
41
|
+
ALTER TABLE "order_addresses"
|
|
42
|
+
ADD CONSTRAINT "FK_order_addresses_contact"
|
|
43
|
+
FOREIGN KEY ("contactId")
|
|
44
|
+
REFERENCES "contacts"("id")
|
|
45
|
+
ON DELETE CASCADE
|
|
46
|
+
`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
50
|
+
await queryRunner.query(`
|
|
51
|
+
ALTER TABLE "orders"
|
|
52
|
+
DROP CONSTRAINT IF EXISTS "FK_orders_billing_order_address"
|
|
53
|
+
`);
|
|
54
|
+
|
|
55
|
+
await queryRunner.query(`
|
|
56
|
+
ALTER TABLE "orders"
|
|
57
|
+
DROP CONSTRAINT IF EXISTS "FK_orders_shipping_order_address"
|
|
58
|
+
`);
|
|
59
|
+
|
|
60
|
+
await queryRunner.query(`
|
|
61
|
+
ALTER TABLE "orders"
|
|
62
|
+
ADD CONSTRAINT "FK_orders_billingAddressId_address"
|
|
63
|
+
FOREIGN KEY ("billingAddressId")
|
|
64
|
+
REFERENCES "address"("id")
|
|
65
|
+
ON DELETE SET NULL
|
|
66
|
+
`);
|
|
67
|
+
|
|
68
|
+
await queryRunner.query(`
|
|
69
|
+
ALTER TABLE "orders"
|
|
70
|
+
ADD CONSTRAINT "FK_orders_shippingAddressId_address"
|
|
71
|
+
FOREIGN KEY ("shippingAddressId")
|
|
72
|
+
REFERENCES "address"("id")
|
|
73
|
+
ON DELETE SET NULL
|
|
74
|
+
`);
|
|
75
|
+
|
|
76
|
+
await queryRunner.query(`
|
|
77
|
+
ALTER TABLE "order_addresses"
|
|
78
|
+
DROP CONSTRAINT IF EXISTS "FK_order_addresses_contact"
|
|
79
|
+
`);
|
|
80
|
+
|
|
81
|
+
await queryRunner.query(`
|
|
82
|
+
ALTER TABLE "order_addresses"
|
|
83
|
+
ADD CONSTRAINT "FK_order_addresses_contact"
|
|
84
|
+
FOREIGN KEY ("contactId")
|
|
85
|
+
REFERENCES "contacts"("id")
|
|
86
|
+
`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
export class UpdateDiscountAndRules1778652250862 implements MigrationInterface {
|
|
4
|
+
name = 'UpdateDiscountAndRules1778652250862'
|
|
5
|
+
|
|
6
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
7
|
+
|
|
8
|
+
// Add isAutomatic column
|
|
9
|
+
await queryRunner.query(`
|
|
10
|
+
ALTER TABLE "discounts"
|
|
11
|
+
ADD COLUMN "isAutomatic" boolean NOT NULL DEFAULT false
|
|
12
|
+
`);
|
|
13
|
+
|
|
14
|
+
// Add currency column
|
|
15
|
+
await queryRunner.query(`
|
|
16
|
+
ALTER TABLE "discounts"
|
|
17
|
+
ADD COLUMN "currency" varchar NOT NULL DEFAULT 'INR'
|
|
18
|
+
`);
|
|
19
|
+
|
|
20
|
+
// Update enum for discount_rules.type
|
|
21
|
+
await queryRunner.query(`
|
|
22
|
+
ALTER TYPE "public"."discount_rules_type_enum"
|
|
23
|
+
RENAME TO "discount_rules_type_enum_old"
|
|
24
|
+
`);
|
|
25
|
+
|
|
26
|
+
await queryRunner.query(`
|
|
27
|
+
CREATE TYPE "public"."discount_rules_type_enum" AS ENUM(
|
|
28
|
+
'minAmount',
|
|
29
|
+
'user',
|
|
30
|
+
'product',
|
|
31
|
+
'category',
|
|
32
|
+
'cart',
|
|
33
|
+
'paymentMethod',
|
|
34
|
+
'order',
|
|
35
|
+
'quantity',
|
|
36
|
+
'time',
|
|
37
|
+
'shipping',
|
|
38
|
+
'referral',
|
|
39
|
+
'reward'
|
|
40
|
+
)
|
|
41
|
+
`);
|
|
42
|
+
|
|
43
|
+
await queryRunner.query(`
|
|
44
|
+
ALTER TABLE "discount_rules"
|
|
45
|
+
ALTER COLUMN "type"
|
|
46
|
+
TYPE "public"."discount_rules_type_enum"
|
|
47
|
+
USING "type"::text::"public"."discount_rules_type_enum"
|
|
48
|
+
`);
|
|
49
|
+
|
|
50
|
+
await queryRunner.query(`
|
|
51
|
+
DROP TYPE "public"."discount_rules_type_enum_old"
|
|
52
|
+
`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
56
|
+
|
|
57
|
+
// Revert enum changes
|
|
58
|
+
await queryRunner.query(`
|
|
59
|
+
CREATE TYPE "public"."discount_rules_type_enum_old" AS ENUM(
|
|
60
|
+
'minAmount',
|
|
61
|
+
'user',
|
|
62
|
+
'product',
|
|
63
|
+
'category',
|
|
64
|
+
'cart',
|
|
65
|
+
'paymentMethod',
|
|
66
|
+
'order',
|
|
67
|
+
'quantity',
|
|
68
|
+
'time',
|
|
69
|
+
'shipping'
|
|
70
|
+
)
|
|
71
|
+
`);
|
|
72
|
+
|
|
73
|
+
await queryRunner.query(`
|
|
74
|
+
ALTER TABLE "discount_rules"
|
|
75
|
+
ALTER COLUMN "type"
|
|
76
|
+
TYPE "public"."discount_rules_type_enum_old"
|
|
77
|
+
USING "type"::text::"public"."discount_rules_type_enum_old"
|
|
78
|
+
`);
|
|
79
|
+
|
|
80
|
+
await queryRunner.query(`
|
|
81
|
+
DROP TYPE "public"."discount_rules_type_enum"
|
|
82
|
+
`);
|
|
83
|
+
|
|
84
|
+
await queryRunner.query(`
|
|
85
|
+
ALTER TYPE "public"."discount_rules_type_enum_old"
|
|
86
|
+
RENAME TO "discount_rules_type_enum"
|
|
87
|
+
`);
|
|
88
|
+
|
|
89
|
+
// Remove added columns
|
|
90
|
+
await queryRunner.query(`
|
|
91
|
+
ALTER TABLE "discounts"
|
|
92
|
+
DROP COLUMN "currency"
|
|
93
|
+
`);
|
|
94
|
+
|
|
95
|
+
await queryRunner.query(`
|
|
96
|
+
ALTER TABLE "discounts"
|
|
97
|
+
DROP COLUMN "isAutomatic"
|
|
98
|
+
`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
export class MakeCouponCodeNullable1778652250863 implements MigrationInterface {
|
|
4
|
+
name = 'MakeCouponCodeNullable1778652250863'
|
|
5
|
+
|
|
6
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
7
|
+
await queryRunner.query(`
|
|
8
|
+
ALTER TABLE "discounts"
|
|
9
|
+
ALTER COLUMN "couponCode" DROP NOT NULL
|
|
10
|
+
`);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
14
|
+
await queryRunner.query(`
|
|
15
|
+
ALTER TABLE "discounts"
|
|
16
|
+
ALTER COLUMN "couponCode" SET NOT NULL
|
|
17
|
+
`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
export class RemoveUniqueConstraintFromDiscountCouponCode1778652250864
|
|
4
|
+
implements MigrationInterface
|
|
5
|
+
{
|
|
6
|
+
name = 'RemoveUniqueConstraintFromDiscountCouponCode1778652250864';
|
|
7
|
+
|
|
8
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
9
|
+
await queryRunner.query(`
|
|
10
|
+
ALTER TABLE "discounts"
|
|
11
|
+
DROP CONSTRAINT IF EXISTS "discounts_couponCode_key"
|
|
12
|
+
`);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
16
|
+
await queryRunner.query(`
|
|
17
|
+
ALTER TABLE "discounts"
|
|
18
|
+
ADD CONSTRAINT "discounts_couponCode_key"
|
|
19
|
+
UNIQUE ("couponCode")
|
|
20
|
+
`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from 'typeorm';
|
|
2
|
+
|
|
3
|
+
export class RemoveOldOrdersAddressForeignKeys1778652250865
|
|
4
|
+
implements MigrationInterface
|
|
5
|
+
{
|
|
6
|
+
name = 'RemoveOldOrdersAddressForeignKeys1778652250866';
|
|
7
|
+
|
|
8
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
9
|
+
// Remove old FK constraints pointing to addresses table
|
|
10
|
+
await queryRunner.query(`
|
|
11
|
+
ALTER TABLE "orders"
|
|
12
|
+
DROP CONSTRAINT IF EXISTS "FK_orders_billing_address"
|
|
13
|
+
`);
|
|
14
|
+
|
|
15
|
+
await queryRunner.query(`
|
|
16
|
+
ALTER TABLE "orders"
|
|
17
|
+
DROP CONSTRAINT IF EXISTS "FK_orders_shipping_address"
|
|
18
|
+
`);
|
|
19
|
+
|
|
20
|
+
// Remove possible alternate old constraint names
|
|
21
|
+
await queryRunner.query(`
|
|
22
|
+
ALTER TABLE "orders"
|
|
23
|
+
DROP CONSTRAINT IF EXISTS "FK_orders_billingAddressId_address"
|
|
24
|
+
`);
|
|
25
|
+
|
|
26
|
+
await queryRunner.query(`
|
|
27
|
+
ALTER TABLE "orders"
|
|
28
|
+
DROP CONSTRAINT IF EXISTS "FK_orders_shippingAddressId_address"
|
|
29
|
+
`);
|
|
30
|
+
|
|
31
|
+
await queryRunner.query(`
|
|
32
|
+
DO $$ BEGIN
|
|
33
|
+
ALTER TABLE "orders"
|
|
34
|
+
ADD CONSTRAINT "FK_orders_billing_order_address"
|
|
35
|
+
FOREIGN KEY ("billingAddressId") REFERENCES "order_addresses"("id")
|
|
36
|
+
ON DELETE SET NULL ON UPDATE NO ACTION;
|
|
37
|
+
EXCEPTION WHEN duplicate_object THEN NULL;
|
|
38
|
+
END $$;
|
|
39
|
+
`);
|
|
40
|
+
|
|
41
|
+
await queryRunner.query(`
|
|
42
|
+
DO $$ BEGIN
|
|
43
|
+
ALTER TABLE "orders"
|
|
44
|
+
ADD CONSTRAINT "FK_orders_shipping_order_address"
|
|
45
|
+
FOREIGN KEY ("shippingAddressId") REFERENCES "order_addresses"("id")
|
|
46
|
+
ON DELETE SET NULL ON UPDATE NO ACTION;
|
|
47
|
+
EXCEPTION WHEN duplicate_object THEN NULL;
|
|
48
|
+
END $$;
|
|
49
|
+
`);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
53
|
+
// Restore old constraints back to addresses table
|
|
54
|
+
|
|
55
|
+
await queryRunner.query(`
|
|
56
|
+
ALTER TABLE "orders"
|
|
57
|
+
ADD CONSTRAINT "FK_orders_billing_address"
|
|
58
|
+
FOREIGN KEY ("billingAddressId")
|
|
59
|
+
REFERENCES "addresses"("id")
|
|
60
|
+
ON DELETE SET NULL
|
|
61
|
+
`);
|
|
62
|
+
|
|
63
|
+
await queryRunner.query(`
|
|
64
|
+
ALTER TABLE "orders"
|
|
65
|
+
ADD CONSTRAINT "FK_orders_shipping_address"
|
|
66
|
+
FOREIGN KEY ("shippingAddressId")
|
|
67
|
+
REFERENCES "addresses"("id")
|
|
68
|
+
ON DELETE SET NULL
|
|
69
|
+
`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { MigrationInterface, QueryRunner } from 'typeorm';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Scope discounts to a vendor store (`vendorId` column, FK, RLS, permissions).
|
|
5
|
+
*/
|
|
6
|
+
export class DiscountVendorId1778660000000 implements MigrationInterface {
|
|
7
|
+
name = 'DiscountVendorId1778660000000';
|
|
8
|
+
|
|
9
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
10
|
+
await queryRunner.query(`ALTER TABLE "discounts" ADD COLUMN IF NOT EXISTS "vendorId" integer`);
|
|
11
|
+
|
|
12
|
+
await queryRunner.query(`
|
|
13
|
+
UPDATE "discounts" d
|
|
14
|
+
SET "vendorId" = COALESCE(
|
|
15
|
+
(SELECT o."vendorId" FROM "order_discounts" od
|
|
16
|
+
INNER JOIN "orders" o ON o.id = od."orderId"
|
|
17
|
+
WHERE od."discountId" = d.id
|
|
18
|
+
ORDER BY od.id DESC LIMIT 1),
|
|
19
|
+
(SELECT id FROM "vendors" WHERE "slug" = 'default' LIMIT 1)
|
|
20
|
+
)
|
|
21
|
+
WHERE d."vendorId" IS NULL
|
|
22
|
+
`);
|
|
23
|
+
|
|
24
|
+
await queryRunner.query(`ALTER TABLE "discounts" ALTER COLUMN "vendorId" SET NOT NULL`);
|
|
25
|
+
|
|
26
|
+
await queryRunner.query(`
|
|
27
|
+
DO $$ BEGIN
|
|
28
|
+
ALTER TABLE "discounts" ADD CONSTRAINT "FK_discounts_vendorId"
|
|
29
|
+
FOREIGN KEY ("vendorId") REFERENCES "vendors"("id") ON DELETE RESTRICT ON UPDATE NO ACTION;
|
|
30
|
+
EXCEPTION WHEN duplicate_object THEN NULL;
|
|
31
|
+
END $$
|
|
32
|
+
`);
|
|
33
|
+
|
|
34
|
+
await queryRunner.query(
|
|
35
|
+
`CREATE INDEX IF NOT EXISTS "IDX_discounts_vendorId" ON "discounts" ("vendorId")`
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
await queryRunner.query(`
|
|
39
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "UQ_discounts_vendor_couponCode"
|
|
40
|
+
ON "discounts" ("vendorId", "couponCode")
|
|
41
|
+
WHERE "couponCode" IS NOT NULL AND TRIM("couponCode") <> ''
|
|
42
|
+
`);
|
|
43
|
+
|
|
44
|
+
await queryRunner.query(`ALTER TABLE "discounts" ENABLE ROW LEVEL SECURITY`);
|
|
45
|
+
await queryRunner.query(`ALTER TABLE "discounts" FORCE ROW LEVEL SECURITY`);
|
|
46
|
+
await queryRunner.query(`DROP POLICY IF EXISTS "vendor_isolation" ON "discounts"`);
|
|
47
|
+
await queryRunner.query(`
|
|
48
|
+
CREATE POLICY "vendor_isolation" ON "discounts"
|
|
49
|
+
USING (
|
|
50
|
+
COALESCE(NULLIF(current_setting('app.vendor_id', true), ''), '0') = '0'
|
|
51
|
+
OR "vendorId" = NULLIF(current_setting('app.vendor_id', true), '')::integer
|
|
52
|
+
)
|
|
53
|
+
WITH CHECK (
|
|
54
|
+
COALESCE(NULLIF(current_setting('app.vendor_id', true), ''), '0') = '0'
|
|
55
|
+
OR "vendorId" = NULLIF(current_setting('app.vendor_id', true), '')::integer
|
|
56
|
+
)
|
|
57
|
+
`);
|
|
58
|
+
|
|
59
|
+
await queryRunner.query(`
|
|
60
|
+
INSERT INTO "permissions" ("groupId", "entity", "canCreate", "canRead", "canUpdate", "canDelete")
|
|
61
|
+
SELECT g.id, 'discounts', true, true, true, true
|
|
62
|
+
FROM "user_groups" g
|
|
63
|
+
WHERE g.deleted = false
|
|
64
|
+
AND lower(g.name) LIKE '%vendor%'
|
|
65
|
+
AND g.name <> 'Administrator'
|
|
66
|
+
ON CONFLICT ("groupId", "entity") DO NOTHING
|
|
67
|
+
`);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
71
|
+
await queryRunner.query(`
|
|
72
|
+
DELETE FROM "permissions" p
|
|
73
|
+
USING "user_groups" g
|
|
74
|
+
WHERE p."groupId" = g.id
|
|
75
|
+
AND g.deleted = false
|
|
76
|
+
AND lower(g.name) LIKE '%vendor%'
|
|
77
|
+
AND g.name <> 'Administrator'
|
|
78
|
+
AND p.entity = 'discounts'
|
|
79
|
+
`);
|
|
80
|
+
|
|
81
|
+
await queryRunner.query(`DROP POLICY IF EXISTS "vendor_isolation" ON "discounts"`);
|
|
82
|
+
await queryRunner.query(`ALTER TABLE "discounts" NO FORCE ROW LEVEL SECURITY`);
|
|
83
|
+
await queryRunner.query(`ALTER TABLE "discounts" DISABLE ROW LEVEL SECURITY`);
|
|
84
|
+
|
|
85
|
+
await queryRunner.query(`DROP INDEX IF EXISTS "UQ_discounts_vendor_couponCode"`);
|
|
86
|
+
await queryRunner.query(`ALTER TABLE "discounts" DROP CONSTRAINT IF EXISTS "FK_discounts_vendorId"`);
|
|
87
|
+
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_discounts_vendorId"`);
|
|
88
|
+
await queryRunner.query(`ALTER TABLE "discounts" DROP COLUMN IF EXISTS "vendorId"`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { MigrationInterface, QueryRunner } from 'typeorm';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Orders.billingAddressId / shippingAddressId must reference order_addresses,
|
|
5
|
+
* not the legacy contacts `addresses` table (TypeORM / old migrations may leave wrong FKs).
|
|
6
|
+
*/
|
|
7
|
+
export class FixOrdersAddressFkToOrderAddresses1778660000001 implements MigrationInterface {
|
|
8
|
+
name = 'FixOrdersAddressFkToOrderAddresses1778660000001';
|
|
9
|
+
|
|
10
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
11
|
+
await queryRunner.query(`
|
|
12
|
+
DO $$
|
|
13
|
+
DECLARE r RECORD;
|
|
14
|
+
BEGIN
|
|
15
|
+
FOR r IN
|
|
16
|
+
SELECT con.conname AS conname
|
|
17
|
+
FROM pg_constraint con
|
|
18
|
+
INNER JOIN pg_class rel ON rel.oid = con.conrelid AND rel.relname = 'orders'
|
|
19
|
+
INNER JOIN pg_class frel ON frel.oid = con.confrelid AND frel.relname = 'addresses'
|
|
20
|
+
WHERE con.contype = 'f'
|
|
21
|
+
AND EXISTS (
|
|
22
|
+
SELECT 1
|
|
23
|
+
FROM pg_attribute a
|
|
24
|
+
WHERE a.attrelid = con.conrelid
|
|
25
|
+
AND a.attnum = ANY (con.conkey)
|
|
26
|
+
AND a.attname IN ('billingAddressId', 'shippingAddressId')
|
|
27
|
+
)
|
|
28
|
+
LOOP
|
|
29
|
+
EXECUTE format('ALTER TABLE orders DROP CONSTRAINT IF EXISTS %I', r.conname);
|
|
30
|
+
END LOOP;
|
|
31
|
+
END $$;
|
|
32
|
+
`);
|
|
33
|
+
|
|
34
|
+
await queryRunner.query(`
|
|
35
|
+
ALTER TABLE "orders" DROP CONSTRAINT IF EXISTS "FK_orders_billing_address"
|
|
36
|
+
`);
|
|
37
|
+
await queryRunner.query(`
|
|
38
|
+
ALTER TABLE "orders" DROP CONSTRAINT IF EXISTS "FK_orders_shipping_address"
|
|
39
|
+
`);
|
|
40
|
+
await queryRunner.query(`
|
|
41
|
+
ALTER TABLE "orders" DROP CONSTRAINT IF EXISTS "FK_orders_billingAddressId_address"
|
|
42
|
+
`);
|
|
43
|
+
await queryRunner.query(`
|
|
44
|
+
ALTER TABLE "orders" DROP CONSTRAINT IF EXISTS "FK_orders_shippingAddressId_address"
|
|
45
|
+
`);
|
|
46
|
+
await queryRunner.query(`
|
|
47
|
+
ALTER TABLE "orders" DROP CONSTRAINT IF EXISTS "FK_820a4c09ddad44884a97378d336"
|
|
48
|
+
`);
|
|
49
|
+
|
|
50
|
+
await queryRunner.query(`
|
|
51
|
+
DO $$ BEGIN
|
|
52
|
+
ALTER TABLE "orders"
|
|
53
|
+
ADD CONSTRAINT "FK_orders_billing_order_address"
|
|
54
|
+
FOREIGN KEY ("billingAddressId") REFERENCES "order_addresses"("id")
|
|
55
|
+
ON DELETE SET NULL ON UPDATE NO ACTION;
|
|
56
|
+
EXCEPTION WHEN duplicate_object THEN NULL;
|
|
57
|
+
END $$;
|
|
58
|
+
`);
|
|
59
|
+
|
|
60
|
+
await queryRunner.query(`
|
|
61
|
+
DO $$ BEGIN
|
|
62
|
+
ALTER TABLE "orders"
|
|
63
|
+
ADD CONSTRAINT "FK_orders_shipping_order_address"
|
|
64
|
+
FOREIGN KEY ("shippingAddressId") REFERENCES "order_addresses"("id")
|
|
65
|
+
ON DELETE SET NULL ON UPDATE NO ACTION;
|
|
66
|
+
EXCEPTION WHEN duplicate_object THEN NULL;
|
|
67
|
+
END $$;
|
|
68
|
+
`);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
72
|
+
await queryRunner.query(`
|
|
73
|
+
ALTER TABLE "orders" DROP CONSTRAINT IF EXISTS "FK_orders_billing_order_address"
|
|
74
|
+
`);
|
|
75
|
+
await queryRunner.query(`
|
|
76
|
+
ALTER TABLE "orders" DROP CONSTRAINT IF EXISTS "FK_orders_shipping_order_address"
|
|
77
|
+
`);
|
|
78
|
+
}
|
|
79
|
+
}
|