@infuro/cms-core 1.0.33 → 1.0.35

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.
Files changed (164) hide show
  1. package/README.md +22 -6
  2. package/dist/OrderTrackPage-W3J6WIG2.js +426 -0
  3. package/dist/OrderTrackPage-Z6FCJQYY.cjs +428 -0
  4. package/dist/admin.cjs +34072 -20487
  5. package/dist/admin.d.cts +191 -9
  6. package/dist/admin.d.ts +191 -9
  7. package/dist/admin.js +33913 -20423
  8. package/dist/api.cjs +123 -16508
  9. package/dist/api.d.cts +633 -3
  10. package/dist/api.d.ts +633 -3
  11. package/dist/api.js +14 -16519
  12. package/dist/auth.cjs +196 -955
  13. package/dist/auth.d.cts +201 -42
  14. package/dist/auth.d.ts +201 -42
  15. package/dist/auth.js +4 -888
  16. package/dist/chunk-2XE4X74C.js +29602 -0
  17. package/dist/chunk-3DZRIZOD.cjs +52 -0
  18. package/dist/chunk-3KPNTQBV.cjs +620 -0
  19. package/dist/chunk-46GKADYE.cjs +84 -0
  20. package/dist/chunk-4TRPKBKO.js +589 -0
  21. package/dist/chunk-5ELSW2UP.js +150 -0
  22. package/dist/chunk-6KPQWRFW.js +171 -0
  23. package/dist/chunk-7NMT3GBR.cjs +29 -0
  24. package/dist/chunk-7YIBMQDR.cjs +86 -0
  25. package/dist/chunk-BGJAV67S.cjs +29710 -0
  26. package/dist/chunk-CNTSLED2.cjs +559 -0
  27. package/dist/chunk-CRFV5WJK.js +16 -0
  28. package/dist/chunk-D5FBNKQM.cjs +104 -0
  29. package/dist/chunk-EF2JBPDM.js +114 -0
  30. package/dist/chunk-EQPITOP6.js +543 -0
  31. package/dist/chunk-GO7PPYNU.js +76 -0
  32. package/dist/chunk-HF3L2GIT.cjs +194 -0
  33. package/dist/chunk-J7XHLOLO.js +830 -0
  34. package/dist/chunk-JBRR5UYL.js +87 -0
  35. package/dist/chunk-JC6DLWTE.js +21 -0
  36. package/dist/chunk-JHF4YYRC.cjs +188 -0
  37. package/dist/chunk-JXF23MPG.js +25 -0
  38. package/dist/chunk-MQBT33IV.js +48 -0
  39. package/dist/chunk-N44BJZ4C.cjs +123 -0
  40. package/dist/chunk-OOTLNH63.cjs +18 -0
  41. package/dist/chunk-PAMVINEX.cjs +577 -0
  42. package/dist/chunk-PNOKNSG2.cjs +222 -0
  43. package/dist/chunk-QM733NUK.js +186 -0
  44. package/dist/chunk-R73BKDRO.cjs +90 -0
  45. package/dist/chunk-SHUYVCID.js +4 -0
  46. package/dist/chunk-SYBOCAWB.js +97 -0
  47. package/dist/chunk-TDV6EJHV.js +192 -0
  48. package/dist/chunk-TFUOHI37.cjs +839 -0
  49. package/dist/chunk-TIAEXJLI.cjs +182 -0
  50. package/dist/chunk-UPLVMVRX.cjs +23 -0
  51. package/dist/chunk-USNT2KNT.cjs +6 -0
  52. package/dist/chunk-WEMDMVHQ.js +216 -0
  53. package/dist/chunk-XDSNZUW7.js +564 -0
  54. package/dist/chunk-XQ3QUHWR.cjs +83 -0
  55. package/dist/chunk-XW5ATPRW.cjs +155 -0
  56. package/dist/chunk-ZQ4X6OAU.js +82 -0
  57. package/dist/chunk-ZSVCP6N3.js +83 -0
  58. package/dist/cli.cjs +142 -84
  59. package/dist/cli.js +101 -27
  60. package/dist/email-FKR4FXFI.js +5 -0
  61. package/dist/email-KVKVPNCL.cjs +58 -0
  62. package/dist/email-queue-CGZBVVAS.js +2 -0
  63. package/dist/email-queue-TPZWLTIV.cjs +23 -0
  64. package/dist/erp-config-enabled-CUMQ6N2V.cjs +11 -0
  65. package/dist/erp-config-enabled-T37X7T34.js +2 -0
  66. package/dist/erp-order-invoice-3YISSOWW.js +3 -0
  67. package/dist/erp-order-invoice-ZR5F2KTA.cjs +12 -0
  68. package/dist/event-order-defaults-6E543227.js +2 -0
  69. package/dist/event-order-defaults-DUGDVGJI.cjs +39 -0
  70. package/dist/event-order-notifications-5GSAOYVS.cjs +27 -0
  71. package/dist/event-order-notifications-IIIF23D5.js +10 -0
  72. package/dist/hooks.cjs +259 -132
  73. package/dist/hooks.d.cts +42 -1
  74. package/dist/hooks.d.ts +42 -1
  75. package/dist/hooks.js +234 -91
  76. package/dist/index.cjs +3884 -21070
  77. package/dist/index.d.cts +2255 -749
  78. package/dist/index.d.ts +2255 -749
  79. package/dist/index.js +1925 -19891
  80. package/dist/interpolate-WAKPN56R.cjs +11 -0
  81. package/dist/interpolate-WDUWDF3I.js +2 -0
  82. package/dist/layout-36UFTHC5.cjs +11 -0
  83. package/dist/layout-AOBN26XG.js +2 -0
  84. package/dist/migrations/1778660000004-CreateCustomerAndCustomerContacts.ts +99 -0
  85. package/dist/migrations/1778660000005-AddCustomerIdToVendorCustomers.ts +39 -0
  86. package/dist/migrations/1778660000006-UpdateVendorCustomersContactNullable.ts +36 -0
  87. package/dist/migrations/1778660000007-VendorOwnerCustomerContactsPermission.ts +39 -0
  88. package/dist/migrations/1779300000000-VendorOwnerContactsPermission.ts +39 -0
  89. package/dist/migrations/1779400000000-AddCustomerContactIdToOrders.ts +33 -0
  90. package/dist/migrations/1779400000000-ConvertStatusToEnum.ts +142 -0
  91. package/dist/migrations/1779400000000-SeedDefaultCurrencies.ts +33 -0
  92. package/dist/migrations/1779500000000-VendorRolesAndPermissions.ts +102 -0
  93. package/dist/migrations/1779600000000-VendorRegistrationProfile.ts +52 -0
  94. package/dist/migrations/1779700000000-CollectionIsCatalog.ts +22 -0
  95. package/dist/migrations/1779710000000-CollectionPlatformCatalog.ts +60 -0
  96. package/dist/migrations/1779720000000-ProductCategoryPlatformCatalog.ts +157 -0
  97. package/dist/migrations/1779800000000-EventsAndEventProducts.ts +173 -0
  98. package/dist/migrations/1779810000000-BackfillVendorRoleEventsPermissions.ts +38 -0
  99. package/dist/migrations/1779820000000-FixProductsCategoryForeignKey.ts +70 -0
  100. package/dist/migrations/1779830000000-ProductTitleColumn.ts +32 -0
  101. package/dist/migrations/1779840000000-EventAboutAndVisibilityFields.ts +34 -0
  102. package/dist/migrations/1779850000000-EventCityCountrySplit.ts +43 -0
  103. package/dist/migrations/1779860000000-CreateCombos.ts +140 -0
  104. package/dist/migrations/1780100000000-OrderAttendeesEventId.ts +55 -0
  105. package/dist/migrations/1780110000000-EventContactFormId.ts +49 -0
  106. package/dist/migrations/1780130000000-ProductVariants.ts +54 -0
  107. package/dist/migrations/1780140000000-EventManagementEnhancements.ts +44 -0
  108. package/dist/migrations/1780160000000-EventRegistrationGstProductContactForm.ts +79 -0
  109. package/dist/migrations/1780170000000-ComboCurrencyPrices.ts +20 -0
  110. package/dist/migrations/1781110000000-VendorOwnerCombosPermission.ts +38 -0
  111. package/dist/migrations/1781120000000-RefundPoliciesAndRequests.ts +225 -0
  112. package/dist/migrations/1781130000000-CreateAttendees.ts +44 -0
  113. package/dist/migrations/1781140000000-EventOrderNotifications.ts +29 -0
  114. package/dist/migrations/1781150000000-EventNamedLists.ts +28 -0
  115. package/dist/migrations/1781160000000-RefundPolicyEventTiers.ts +27 -0
  116. package/dist/migrations/1781170000000-EventRefundPolicy.ts +42 -0
  117. package/dist/migrations/1781180000000-RemoveCartItemsUniqueConstraint.ts +15 -0
  118. package/dist/migrations/1781190000000-RenameProductTaxesToProductConfig.ts +84 -0
  119. package/dist/migrations/1781200000000-VendorOwnerProductConfigPermissions.ts +51 -0
  120. package/dist/migrations/1781210000000-VendorRoleProductConfigPermissions.ts +46 -0
  121. package/dist/migrations/helpers/vendor-role-seed.ts +243 -0
  122. package/dist/paid-order-erp-3USEG6WL.js +3 -0
  123. package/dist/paid-order-erp-FSQ3GSXE.cjs +12 -0
  124. package/dist/pg-boss-service-4XF2TQ2E.js +2 -0
  125. package/dist/pg-boss-service-L6MTF4EQ.cjs +15 -0
  126. package/dist/razorpay-KLO2KNCB.js +49 -0
  127. package/dist/razorpay-U23LGY72.cjs +56 -0
  128. package/dist/rbac-debug-db-D7ME7QUY.cjs +35 -0
  129. package/dist/rbac-debug-db-MTCTVNNM.js +33 -0
  130. package/dist/sms-defaults-2NL24H57.js +2 -0
  131. package/dist/sms-defaults-KCOPKQBA.cjs +19 -0
  132. package/dist/stripe-4FD27QVJ.js +51 -0
  133. package/dist/stripe-VU6OEG2D.cjs +57 -0
  134. package/dist/theme.cjs +31 -59
  135. package/dist/theme.d.cts +78 -3
  136. package/dist/theme.d.ts +78 -3
  137. package/dist/theme.js +23 -20
  138. package/dist/vendor-invite-status-77O7ZQ3U.cjs +19 -0
  139. package/dist/vendor-invite-status-PWJ3DE76.js +2 -0
  140. package/dist/whatsapp-queue-3DXA4MXU.js +2 -0
  141. package/dist/whatsapp-queue-KG65MXD5.cjs +15 -0
  142. package/package.json +147 -141
  143. package/dist/admin.cjs.map +0 -1
  144. package/dist/admin.js.map +0 -1
  145. package/dist/api.cjs.map +0 -1
  146. package/dist/api.js.map +0 -1
  147. package/dist/auth.cjs.map +0 -1
  148. package/dist/auth.js.map +0 -1
  149. package/dist/cli.cjs.map +0 -1
  150. package/dist/cli.js.map +0 -1
  151. package/dist/config-DJ5CmQvS.d.cts +0 -8
  152. package/dist/config-DJ5CmQvS.d.ts +0 -8
  153. package/dist/hooks.cjs.map +0 -1
  154. package/dist/hooks.js.map +0 -1
  155. package/dist/index-DWd5Gjc4.d.ts +0 -582
  156. package/dist/index-rZTnpK7y.d.cts +0 -582
  157. package/dist/index.cjs.map +0 -1
  158. package/dist/index.js.map +0 -1
  159. package/dist/theme.cjs.map +0 -1
  160. package/dist/theme.js.map +0 -1
  161. package/dist/types-DCVaXlPV.d.cts +0 -78
  162. package/dist/types-DCVaXlPV.d.ts +0 -78
  163. package/dist/vendor-scope-DTYhJk_I.d.cts +0 -129
  164. package/dist/vendor-scope-DTYhJk_I.d.ts +0 -129
@@ -0,0 +1,60 @@
1
+ import type { MigrationInterface, QueryRunner } from 'typeorm';
2
+
3
+ /**
4
+ * Platform catalog collections: global types (no vendor owner).
5
+ * Vendors assign products to these fixed collections.
6
+ */
7
+ export class CollectionPlatformCatalog1779710000000 implements MigrationInterface {
8
+ name = 'CollectionPlatformCatalog1779710000000';
9
+
10
+ public async up(queryRunner: QueryRunner): Promise<void> {
11
+ await queryRunner.query(`
12
+ ALTER TABLE "collections"
13
+ ADD COLUMN IF NOT EXISTS "isCatalog" boolean NOT NULL DEFAULT false
14
+ `);
15
+
16
+ await queryRunner.query(`
17
+ ALTER TABLE "collections"
18
+ ALTER COLUMN "vendorId" DROP NOT NULL
19
+ `);
20
+
21
+ await queryRunner.query(`
22
+ UPDATE "collections"
23
+ SET "isCatalog" = true
24
+ WHERE "deleted" = false
25
+ `);
26
+
27
+ await queryRunner.query(`
28
+ UPDATE "collections"
29
+ SET "vendorId" = NULL
30
+ WHERE "isCatalog" = true AND "deleted" = false
31
+ `);
32
+
33
+ await queryRunner.query(`
34
+ CREATE UNIQUE INDEX IF NOT EXISTS "UQ_collections_catalog_slug"
35
+ ON "collections" ("slug")
36
+ WHERE "isCatalog" = true AND "deleted" = false
37
+ `);
38
+ }
39
+
40
+ public async down(queryRunner: QueryRunner): Promise<void> {
41
+ await queryRunner.query(`DROP INDEX IF EXISTS "UQ_collections_catalog_slug"`);
42
+
43
+ await queryRunner.query(`
44
+ UPDATE "collections" c
45
+ SET "vendorId" = COALESCE(
46
+ c."vendorId",
47
+ (SELECT id FROM "vendors" WHERE "slug" = 'default' AND "deleted" = false LIMIT 1),
48
+ (SELECT MIN(id) FROM "vendors" WHERE "deleted" = false)
49
+ )
50
+ WHERE c."isCatalog" = true AND c."vendorId" IS NULL
51
+ `);
52
+
53
+ await queryRunner.query(`
54
+ ALTER TABLE "collections"
55
+ ALTER COLUMN "vendorId" SET NOT NULL
56
+ `);
57
+
58
+ await queryRunner.query(`ALTER TABLE "collections" DROP COLUMN IF EXISTS "isCatalog"`);
59
+ }
60
+ }
@@ -0,0 +1,157 @@
1
+ import type { MigrationInterface, QueryRunner } from 'typeorm';
2
+
3
+ /**
4
+ * Platform catalog categories: global types (no vendor owner).
5
+ * Vendors see these as tabs and create collections/products under them.
6
+ */
7
+ export class ProductCategoryPlatformCatalog1779720000000 implements MigrationInterface {
8
+ name = 'ProductCategoryPlatformCatalog1779720000000';
9
+
10
+ public async up(queryRunner: QueryRunner): Promise<void> {
11
+ await queryRunner.query(`
12
+ ALTER TABLE "product_categories"
13
+ ADD COLUMN IF NOT EXISTS "isCatalog" boolean NOT NULL DEFAULT false
14
+ `);
15
+
16
+ await queryRunner.query(`
17
+ ALTER TABLE "product_categories"
18
+ ALTER COLUMN "vendorId" DROP NOT NULL
19
+ `);
20
+
21
+ await queryRunner.query(`
22
+ INSERT INTO "product_categories" (
23
+ "vendorId", "name", "slug", "parentId", "image", "description", "metadata",
24
+ "active", "sortOrder", "isCatalog", "deleted", "createdAt", "updatedAt"
25
+ )
26
+ SELECT
27
+ NULL,
28
+ c."name",
29
+ c."slug",
30
+ NULL,
31
+ c."image",
32
+ c."description",
33
+ c."metadata",
34
+ c."active",
35
+ c."sortOrder",
36
+ true,
37
+ false,
38
+ NOW(),
39
+ NOW()
40
+ FROM "collections" c
41
+ WHERE c."isCatalog" = true
42
+ AND c."deleted" = false
43
+ AND NOT EXISTS (
44
+ SELECT 1 FROM "product_categories" pc
45
+ WHERE pc."isCatalog" = true
46
+ AND pc."deleted" = false
47
+ AND pc."slug" = c."slug"
48
+ )
49
+ `);
50
+
51
+ await queryRunner.query(`
52
+ UPDATE "products" p
53
+ SET "categoryId" = pc."id"
54
+ FROM "collections" c
55
+ JOIN "product_categories" pc
56
+ ON pc."isCatalog" = true
57
+ AND pc."deleted" = false
58
+ AND pc."slug" = c."slug"
59
+ WHERE p."collectionId" = c."id"
60
+ AND c."isCatalog" = true
61
+ AND c."deleted" = false
62
+ AND (p."categoryId" IS NULL OR p."categoryId" != pc."id")
63
+ `);
64
+
65
+ await queryRunner.query(`
66
+ INSERT INTO "collections" (
67
+ "vendorId", "categoryId", "brandId", "name", "slug", "hsn", "description", "image",
68
+ "metadata", "variants", "active", "isCatalog", "sortOrder", "deleted", "createdAt", "updatedAt"
69
+ )
70
+ SELECT DISTINCT ON (p."vendorId", c."slug")
71
+ p."vendorId",
72
+ pc."id",
73
+ c."brandId",
74
+ c."name",
75
+ c."slug" || '-v' || p."vendorId",
76
+ c."hsn",
77
+ c."description",
78
+ c."image",
79
+ c."metadata",
80
+ c."variants",
81
+ c."active",
82
+ false,
83
+ c."sortOrder",
84
+ false,
85
+ NOW(),
86
+ NOW()
87
+ FROM "products" p
88
+ JOIN "collections" c ON c."id" = p."collectionId" AND c."isCatalog" = true AND c."deleted" = false
89
+ JOIN "product_categories" pc ON pc."isCatalog" = true AND pc."deleted" = false AND pc."slug" = c."slug"
90
+ WHERE NOT EXISTS (
91
+ SELECT 1 FROM "collections" vc
92
+ WHERE vc."vendorId" = p."vendorId"
93
+ AND vc."categoryId" = pc."id"
94
+ AND vc."isCatalog" = false
95
+ AND vc."deleted" = false
96
+ AND vc."slug" = c."slug" || '-v' || p."vendorId"
97
+ )
98
+ `);
99
+
100
+ await queryRunner.query(`
101
+ UPDATE "products" p
102
+ SET "collectionId" = vc."id"
103
+ FROM "collections" c
104
+ JOIN "product_categories" pc
105
+ ON pc."isCatalog" = true
106
+ AND pc."deleted" = false
107
+ AND pc."slug" = c."slug"
108
+ JOIN "collections" vc
109
+ ON vc."categoryId" = pc."id"
110
+ AND vc."isCatalog" = false
111
+ AND vc."deleted" = false
112
+ WHERE p."collectionId" = c."id"
113
+ AND c."isCatalog" = true
114
+ AND c."deleted" = false
115
+ AND p."vendorId" = vc."vendorId"
116
+ AND vc."slug" = c."slug" || '-v' || p."vendorId"
117
+ `);
118
+
119
+ await queryRunner.query(`
120
+ UPDATE "collections"
121
+ SET "isCatalog" = false,
122
+ "vendorId" = COALESCE(
123
+ "vendorId",
124
+ (SELECT id FROM "vendors" WHERE "slug" = 'default' AND "deleted" = false LIMIT 1),
125
+ (SELECT MIN(id) FROM "vendors" WHERE "deleted" = false)
126
+ )
127
+ WHERE "isCatalog" = true AND "deleted" = false
128
+ `);
129
+
130
+ await queryRunner.query(`
131
+ CREATE UNIQUE INDEX IF NOT EXISTS "UQ_product_categories_catalog_slug"
132
+ ON "product_categories" ("slug")
133
+ WHERE "isCatalog" = true AND "deleted" = false
134
+ `);
135
+ }
136
+
137
+ public async down(queryRunner: QueryRunner): Promise<void> {
138
+ await queryRunner.query(`DROP INDEX IF EXISTS "UQ_product_categories_catalog_slug"`);
139
+
140
+ await queryRunner.query(`
141
+ UPDATE "product_categories" pc
142
+ SET "vendorId" = COALESCE(
143
+ pc."vendorId",
144
+ (SELECT id FROM "vendors" WHERE "slug" = 'default' AND "deleted" = false LIMIT 1),
145
+ (SELECT MIN(id) FROM "vendors" WHERE "deleted" = false)
146
+ )
147
+ WHERE pc."isCatalog" = true AND pc."vendorId" IS NULL
148
+ `);
149
+
150
+ await queryRunner.query(`
151
+ ALTER TABLE "product_categories"
152
+ ALTER COLUMN "vendorId" SET NOT NULL
153
+ `);
154
+
155
+ await queryRunner.query(`ALTER TABLE "product_categories" DROP COLUMN IF EXISTS "isCatalog"`);
156
+ }
157
+ }
@@ -0,0 +1,173 @@
1
+ import type { MigrationInterface, QueryRunner } from 'typeorm';
2
+
3
+ const PERMISSION_ENTITIES = ['events', 'event_products'];
4
+
5
+ export class EventsAndEventProducts1779800000000 implements MigrationInterface {
6
+ name = 'EventsAndEventProducts1779800000000';
7
+
8
+ public async up(queryRunner: QueryRunner): Promise<void> {
9
+ await queryRunner.query(`
10
+ CREATE TABLE IF NOT EXISTS "events" (
11
+ "id" SERIAL NOT NULL,
12
+ "vendorId" integer,
13
+ "name" character varying NOT NULL,
14
+ "slug" character varying NOT NULL,
15
+ "description" text,
16
+ "isActive" boolean NOT NULL DEFAULT true,
17
+ "comingSoon" boolean NOT NULL DEFAULT false,
18
+ "bannerImageUrl" character varying,
19
+ "logoUrl" character varying,
20
+ "venue" character varying,
21
+ "startDate" TIMESTAMP,
22
+ "endDate" TIMESTAMP,
23
+ "pricingType" character varying,
24
+ "entityTypes" jsonb,
25
+ "entityMode" character varying,
26
+ "cityCountry" character varying,
27
+ "defaultCurrency" character varying,
28
+ "supportedCurrencies" jsonb,
29
+ "officialWebsiteUrl" character varying,
30
+ "supportContact" character varying,
31
+ "allowGroupOrders" boolean NOT NULL DEFAULT false,
32
+ "sendIndividualTicketPDFToAttendees" boolean NOT NULL DEFAULT false,
33
+ "maxGroupPurchaseQuantity" integer,
34
+ "sponsors" jsonb,
35
+ "sortOrder" integer NOT NULL DEFAULT 0,
36
+ "createdAt" TIMESTAMP NOT NULL DEFAULT now(),
37
+ "updatedAt" TIMESTAMP NOT NULL DEFAULT now(),
38
+ "deletedAt" TIMESTAMP,
39
+ "deleted" boolean NOT NULL DEFAULT false,
40
+ "createdBy" integer,
41
+ "updatedBy" integer,
42
+ "deletedBy" integer,
43
+ CONSTRAINT "PK_events" PRIMARY KEY ("id")
44
+ )
45
+ `);
46
+
47
+ await queryRunner.query(`
48
+ DO $$ BEGIN
49
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'FK_events_vendor') THEN
50
+ ALTER TABLE "events"
51
+ ADD CONSTRAINT "FK_events_vendor"
52
+ FOREIGN KEY ("vendorId") REFERENCES "vendors"("id") ON DELETE RESTRICT ON UPDATE NO ACTION;
53
+ END IF;
54
+ END $$;
55
+ `);
56
+
57
+ await queryRunner.query(`
58
+ CREATE UNIQUE INDEX IF NOT EXISTS "UQ_events_vendor_slug"
59
+ ON "events" ("vendorId", "slug")
60
+ WHERE "deleted" = false
61
+ `);
62
+
63
+ await queryRunner.query(`
64
+ CREATE TABLE IF NOT EXISTS "event_products" (
65
+ "id" SERIAL NOT NULL,
66
+ "eventId" integer NOT NULL,
67
+ "productId" integer NOT NULL,
68
+ "displayOrder" integer NOT NULL DEFAULT 0,
69
+ "isActive" boolean NOT NULL DEFAULT true,
70
+ "createdAt" TIMESTAMP NOT NULL DEFAULT now(),
71
+ "updatedAt" TIMESTAMP NOT NULL DEFAULT now(),
72
+ CONSTRAINT "PK_event_products" PRIMARY KEY ("id")
73
+ )
74
+ `);
75
+
76
+ await queryRunner.query(`
77
+ DO $$ BEGIN
78
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'FK_event_products_event') THEN
79
+ ALTER TABLE "event_products"
80
+ ADD CONSTRAINT "FK_event_products_event"
81
+ FOREIGN KEY ("eventId") REFERENCES "events"("id") ON DELETE CASCADE ON UPDATE NO ACTION;
82
+ END IF;
83
+ END $$;
84
+ `);
85
+
86
+ await queryRunner.query(`
87
+ DO $$ BEGIN
88
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'FK_event_products_product') THEN
89
+ ALTER TABLE "event_products"
90
+ ADD CONSTRAINT "FK_event_products_product"
91
+ FOREIGN KEY ("productId") REFERENCES "products"("id") ON DELETE CASCADE ON UPDATE NO ACTION;
92
+ END IF;
93
+ END $$;
94
+ `);
95
+
96
+ await queryRunner.query(`
97
+ CREATE UNIQUE INDEX IF NOT EXISTS "UQ_event_products_event_product"
98
+ ON "event_products" ("eventId", "productId")
99
+ `);
100
+
101
+ await queryRunner.query(`
102
+ CREATE INDEX IF NOT EXISTS "IDX_event_products_event"
103
+ ON "event_products" ("eventId")
104
+ `);
105
+
106
+ for (const entity of PERMISSION_ENTITIES) {
107
+ await queryRunner.query(`
108
+ INSERT INTO "permissions" ("groupId", "entity", "canCreate", "canRead", "canUpdate", "canDelete")
109
+ SELECT g.id, '${entity}', true, true, true, true
110
+ FROM "user_groups" g
111
+ WHERE g.name = 'Administrator' AND g.deleted = false
112
+ ON CONFLICT ("groupId", "entity") DO UPDATE SET
113
+ "canCreate" = EXCLUDED."canCreate",
114
+ "canRead" = EXCLUDED."canRead",
115
+ "canUpdate" = EXCLUDED."canUpdate",
116
+ "canDelete" = EXCLUDED."canDelete",
117
+ "updatedAt" = now()
118
+ `);
119
+
120
+ await queryRunner.query(`
121
+ INSERT INTO "permissions" ("groupId", "entity", "canCreate", "canRead", "canUpdate", "canDelete")
122
+ SELECT g.id, '${entity}', true, true, true, true
123
+ FROM "user_groups" g
124
+ WHERE g.deleted = false
125
+ AND lower(g.name) LIKE '%vendor%'
126
+ AND g.name <> 'Administrator'
127
+ ON CONFLICT ("groupId", "entity") DO NOTHING
128
+ `);
129
+ }
130
+
131
+ for (const entity of PERMISSION_ENTITIES) {
132
+ await queryRunner.query(`
133
+ INSERT INTO "vendor_role_permissions"
134
+ ("vendorRoleId", "entity", "canCreate", "canRead", "canUpdate", "canDelete")
135
+ SELECT vr.id, '${entity}', true, true, true, true
136
+ FROM "vendor_roles" vr
137
+ WHERE vr."isOwnerRole" = true AND vr.deleted = false
138
+ ON CONFLICT ("vendorRoleId", "entity") DO NOTHING
139
+ `);
140
+
141
+ await queryRunner.query(`
142
+ INSERT INTO "vendor_role_permissions"
143
+ ("vendorRoleId", "entity", "canCreate", "canRead", "canUpdate", "canDelete")
144
+ SELECT vr.id, '${entity}', false, true, false, false
145
+ FROM "vendor_roles" vr
146
+ WHERE vr.name = 'Viewer' AND vr.deleted = false
147
+ ON CONFLICT ("vendorRoleId", "entity") DO NOTHING
148
+ `);
149
+ }
150
+ }
151
+
152
+ public async down(queryRunner: QueryRunner): Promise<void> {
153
+ const entities = PERMISSION_ENTITIES.map((e) => `'${e}'`).join(', ');
154
+ await queryRunner.query(`
155
+ DELETE FROM "permissions" p
156
+ WHERE p.entity IN (${entities})
157
+ `);
158
+
159
+ await queryRunner.query(`DROP INDEX IF EXISTS "IDX_event_products_event"`);
160
+ await queryRunner.query(`DROP INDEX IF EXISTS "UQ_event_products_event_product"`);
161
+ await queryRunner.query(
162
+ `ALTER TABLE "event_products" DROP CONSTRAINT IF EXISTS "FK_event_products_product"`
163
+ );
164
+ await queryRunner.query(
165
+ `ALTER TABLE "event_products" DROP CONSTRAINT IF EXISTS "FK_event_products_event"`
166
+ );
167
+ await queryRunner.query(`DROP TABLE IF EXISTS "event_products"`);
168
+
169
+ await queryRunner.query(`DROP INDEX IF EXISTS "UQ_events_vendor_slug"`);
170
+ await queryRunner.query(`ALTER TABLE "events" DROP CONSTRAINT IF EXISTS "FK_events_vendor"`);
171
+ await queryRunner.query(`DROP TABLE IF EXISTS "events"`);
172
+ }
173
+ }
@@ -0,0 +1,38 @@
1
+ import type { MigrationInterface, QueryRunner } from 'typeorm';
2
+
3
+ const PERMISSION_ENTITIES = ['events', 'event_products'];
4
+
5
+ /** Backfill vendor_role_permissions for events (owner roles seeded before events existed). */
6
+ export class BackfillVendorRoleEventsPermissions1779810000000 implements MigrationInterface {
7
+ name = 'BackfillVendorRoleEventsPermissions1779810000000';
8
+
9
+ public async up(queryRunner: QueryRunner): Promise<void> {
10
+ for (const entity of PERMISSION_ENTITIES) {
11
+ await queryRunner.query(`
12
+ INSERT INTO "vendor_role_permissions"
13
+ ("vendorRoleId", "entity", "canCreate", "canRead", "canUpdate", "canDelete")
14
+ SELECT vr.id, '${entity}', true, true, true, true
15
+ FROM "vendor_roles" vr
16
+ WHERE vr."isOwnerRole" = true AND vr.deleted = false
17
+ ON CONFLICT ("vendorRoleId", "entity") DO NOTHING
18
+ `);
19
+
20
+ await queryRunner.query(`
21
+ INSERT INTO "vendor_role_permissions"
22
+ ("vendorRoleId", "entity", "canCreate", "canRead", "canUpdate", "canDelete")
23
+ SELECT vr.id, '${entity}', false, true, false, false
24
+ FROM "vendor_roles" vr
25
+ WHERE vr.name = 'Viewer' AND vr.deleted = false
26
+ ON CONFLICT ("vendorRoleId", "entity") DO NOTHING
27
+ `);
28
+ }
29
+ }
30
+
31
+ public async down(queryRunner: QueryRunner): Promise<void> {
32
+ const entities = PERMISSION_ENTITIES.map((e) => `'${e}'`).join(', ');
33
+ await queryRunner.query(`
34
+ DELETE FROM "vendor_role_permissions"
35
+ WHERE entity IN (${entities})
36
+ `);
37
+ }
38
+ }
@@ -0,0 +1,70 @@
1
+ import type { MigrationInterface, QueryRunner } from 'typeorm';
2
+
3
+ /**
4
+ * Repair products.categoryId FK when it incorrectly references blog `categories`
5
+ * instead of `product_categories` (store catalog types).
6
+ */
7
+ export class FixProductsCategoryForeignKey1779820000000 implements MigrationInterface {
8
+ name = 'FixProductsCategoryForeignKey1779820000000';
9
+
10
+ public async up(queryRunner: QueryRunner): Promise<void> {
11
+ await queryRunner.query(`
12
+ ALTER TABLE "products" DROP CONSTRAINT IF EXISTS "FK_products_category"
13
+ `);
14
+
15
+ await queryRunner.query(`
16
+ UPDATE "products" p
17
+ SET "categoryId" = pc."id"
18
+ FROM "categories" c
19
+ INNER JOIN "product_categories" pc
20
+ ON lower(pc."name") = lower(c."name")
21
+ AND pc."isCatalog" = true
22
+ AND pc."deleted" = false
23
+ WHERE p."categoryId" = c."id"
24
+ AND c."deleted" = false
25
+ AND NOT EXISTS (
26
+ SELECT 1 FROM "product_categories" x
27
+ WHERE x."id" = p."categoryId" AND x."deleted" = false
28
+ )
29
+ `);
30
+
31
+ await queryRunner.query(`
32
+ UPDATE "products" p
33
+ SET "categoryId" = NULL
34
+ WHERE p."categoryId" IS NOT NULL
35
+ AND NOT EXISTS (
36
+ SELECT 1 FROM "product_categories" pc
37
+ WHERE pc."id" = p."categoryId" AND pc."deleted" = false
38
+ )
39
+ `);
40
+
41
+ await queryRunner.query(`
42
+ DO $$
43
+ BEGIN
44
+ IF NOT EXISTS (
45
+ SELECT 1 FROM pg_constraint
46
+ WHERE conname = 'FK_products_category'
47
+ AND conrelid = 'products'::regclass
48
+ ) THEN
49
+ ALTER TABLE "products"
50
+ ADD CONSTRAINT "FK_products_category"
51
+ FOREIGN KEY ("categoryId") REFERENCES "product_categories"("id")
52
+ ON DELETE SET NULL ON UPDATE NO ACTION;
53
+ END IF;
54
+ END $$;
55
+ `);
56
+ }
57
+
58
+ public async down(queryRunner: QueryRunner): Promise<void> {
59
+ await queryRunner.query(`
60
+ ALTER TABLE "products" DROP CONSTRAINT IF EXISTS "FK_products_category"
61
+ `);
62
+
63
+ await queryRunner.query(`
64
+ ALTER TABLE "products"
65
+ ADD CONSTRAINT "FK_products_category"
66
+ FOREIGN KEY ("categoryId") REFERENCES "product_categories"("id")
67
+ ON DELETE SET NULL ON UPDATE NO ACTION
68
+ `);
69
+ }
70
+ }
@@ -0,0 +1,32 @@
1
+ import type { MigrationInterface, QueryRunner } from 'typeorm';
2
+
3
+ /** Align products.name and products.title so ticket/product labels persist reliably. */
4
+ export class ProductTitleColumn1779830000000 implements MigrationInterface {
5
+ name = 'ProductTitleColumn1779830000000';
6
+
7
+ public async up(queryRunner: QueryRunner): Promise<void> {
8
+ await queryRunner.query(`
9
+ ALTER TABLE "products" ADD COLUMN IF NOT EXISTS "title" character varying
10
+ `);
11
+
12
+ await queryRunner.query(`
13
+ UPDATE "products"
14
+ SET "title" = "name"
15
+ WHERE ("title" IS NULL OR TRIM("title") = '')
16
+ AND "name" IS NOT NULL
17
+ AND TRIM("name") <> ''
18
+ `);
19
+
20
+ await queryRunner.query(`
21
+ UPDATE "products"
22
+ SET "name" = "title"
23
+ WHERE ("name" IS NULL OR TRIM("name") = '')
24
+ AND "title" IS NOT NULL
25
+ AND TRIM("title") <> ''
26
+ `);
27
+ }
28
+
29
+ public async down(queryRunner: QueryRunner): Promise<void> {
30
+ await queryRunner.query(`ALTER TABLE "products" DROP COLUMN IF EXISTS "title"`);
31
+ }
32
+ }
@@ -0,0 +1,34 @@
1
+ import type { MigrationInterface, QueryRunner } from 'typeorm';
2
+
3
+ export class EventAboutAndVisibilityFields1779840000000 implements MigrationInterface {
4
+ name = 'EventAboutAndVisibilityFields1779840000000';
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ await queryRunner.query(`
8
+ ALTER TABLE "events"
9
+ ADD COLUMN IF NOT EXISTS "visibility" character varying NOT NULL DEFAULT 'public'
10
+ `);
11
+
12
+ await queryRunner.query(`
13
+ ALTER TABLE "events"
14
+ ADD COLUMN IF NOT EXISTS "additionalVenueDetails" text
15
+ `);
16
+
17
+ await queryRunner.query(`
18
+ ALTER TABLE "events"
19
+ ADD COLUMN IF NOT EXISTS "expectedSpeakers" integer
20
+ `);
21
+
22
+ await queryRunner.query(`
23
+ ALTER TABLE "events"
24
+ ADD COLUMN IF NOT EXISTS "expectedParticipants" integer
25
+ `);
26
+ }
27
+
28
+ public async down(queryRunner: QueryRunner): Promise<void> {
29
+ await queryRunner.query(`ALTER TABLE "events" DROP COLUMN IF EXISTS "expectedParticipants"`);
30
+ await queryRunner.query(`ALTER TABLE "events" DROP COLUMN IF EXISTS "expectedSpeakers"`);
31
+ await queryRunner.query(`ALTER TABLE "events" DROP COLUMN IF EXISTS "additionalVenueDetails"`);
32
+ await queryRunner.query(`ALTER TABLE "events" DROP COLUMN IF EXISTS "visibility"`);
33
+ }
34
+ }
@@ -0,0 +1,43 @@
1
+ import type { MigrationInterface, QueryRunner } from 'typeorm';
2
+
3
+ export class EventCityCountrySplit1779850000000 implements MigrationInterface {
4
+ name = 'EventCityCountrySplit1779850000000';
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ await queryRunner.query(`
8
+ ALTER TABLE "events"
9
+ ADD COLUMN IF NOT EXISTS "city" character varying
10
+ `);
11
+
12
+ await queryRunner.query(`
13
+ ALTER TABLE "events"
14
+ ADD COLUMN IF NOT EXISTS "country" character varying
15
+ `);
16
+
17
+ await queryRunner.query(`
18
+ UPDATE "events"
19
+ SET
20
+ "city" = NULLIF(trim(split_part("cityCountry", ',', 1)), ''),
21
+ "country" = NULLIF(trim(substring("cityCountry" from position(',' in "cityCountry") + 1)), '')
22
+ WHERE "cityCountry" IS NOT NULL
23
+ AND trim("cityCountry") <> ''
24
+ AND ("city" IS NULL OR trim("city") = '')
25
+ AND ("country" IS NULL OR trim("country") = '')
26
+ AND position(',' in "cityCountry") > 0
27
+ `);
28
+
29
+ await queryRunner.query(`
30
+ UPDATE "events"
31
+ SET "city" = NULLIF(trim("cityCountry"), '')
32
+ WHERE "cityCountry" IS NOT NULL
33
+ AND trim("cityCountry") <> ''
34
+ AND ("city" IS NULL OR trim("city") = '')
35
+ AND position(',' in "cityCountry") = 0
36
+ `);
37
+ }
38
+
39
+ public async down(queryRunner: QueryRunner): Promise<void> {
40
+ await queryRunner.query(`ALTER TABLE "events" DROP COLUMN IF EXISTS "country"`);
41
+ await queryRunner.query(`ALTER TABLE "events" DROP COLUMN IF EXISTS "city"`);
42
+ }
43
+ }