@infuro/cms-core 1.0.34 → 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 (158) hide show
  1. package/README.md +13 -0
  2. package/dist/OrderTrackPage-W3J6WIG2.js +426 -0
  3. package/dist/OrderTrackPage-Z6FCJQYY.cjs +428 -0
  4. package/dist/admin.cjs +34329 -20923
  5. package/dist/admin.d.cts +186 -9
  6. package/dist/admin.d.ts +186 -9
  7. package/dist/admin.js +34140 -20829
  8. package/dist/api.cjs +120 -17515
  9. package/dist/api.d.cts +633 -3
  10. package/dist/api.d.ts +633 -3
  11. package/dist/api.js +14 -17528
  12. package/dist/auth.cjs +192 -1034
  13. package/dist/auth.d.cts +194 -51
  14. package/dist/auth.d.ts +194 -51
  15. package/dist/auth.js +4 -966
  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 +103 -84
  59. package/dist/cli.js +62 -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 -22307
  77. package/dist/index.d.cts +2203 -772
  78. package/dist/index.d.ts +2203 -772
  79. package/dist/index.js +2871 -22064
  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/1779400000000-ConvertStatusToEnum.ts +142 -0
  85. package/dist/migrations/1779400000000-SeedDefaultCurrencies.ts +33 -0
  86. package/dist/migrations/1779500000000-VendorRolesAndPermissions.ts +102 -0
  87. package/dist/migrations/1779600000000-VendorRegistrationProfile.ts +52 -0
  88. package/dist/migrations/1779700000000-CollectionIsCatalog.ts +22 -0
  89. package/dist/migrations/1779710000000-CollectionPlatformCatalog.ts +60 -0
  90. package/dist/migrations/1779720000000-ProductCategoryPlatformCatalog.ts +157 -0
  91. package/dist/migrations/1779800000000-EventsAndEventProducts.ts +173 -0
  92. package/dist/migrations/1779810000000-BackfillVendorRoleEventsPermissions.ts +38 -0
  93. package/dist/migrations/1779820000000-FixProductsCategoryForeignKey.ts +70 -0
  94. package/dist/migrations/1779830000000-ProductTitleColumn.ts +32 -0
  95. package/dist/migrations/1779840000000-EventAboutAndVisibilityFields.ts +34 -0
  96. package/dist/migrations/1779850000000-EventCityCountrySplit.ts +43 -0
  97. package/dist/migrations/1779860000000-CreateCombos.ts +140 -0
  98. package/dist/migrations/1780100000000-OrderAttendeesEventId.ts +55 -0
  99. package/dist/migrations/1780110000000-EventContactFormId.ts +49 -0
  100. package/dist/migrations/1780130000000-ProductVariants.ts +54 -0
  101. package/dist/migrations/1780140000000-EventManagementEnhancements.ts +44 -0
  102. package/dist/migrations/1780160000000-EventRegistrationGstProductContactForm.ts +79 -0
  103. package/dist/migrations/1780170000000-ComboCurrencyPrices.ts +20 -0
  104. package/dist/migrations/1781110000000-VendorOwnerCombosPermission.ts +38 -0
  105. package/dist/migrations/1781120000000-RefundPoliciesAndRequests.ts +225 -0
  106. package/dist/migrations/1781130000000-CreateAttendees.ts +44 -0
  107. package/dist/migrations/1781140000000-EventOrderNotifications.ts +29 -0
  108. package/dist/migrations/1781150000000-EventNamedLists.ts +28 -0
  109. package/dist/migrations/1781160000000-RefundPolicyEventTiers.ts +27 -0
  110. package/dist/migrations/1781170000000-EventRefundPolicy.ts +42 -0
  111. package/dist/migrations/1781180000000-RemoveCartItemsUniqueConstraint.ts +15 -0
  112. package/dist/migrations/1781190000000-RenameProductTaxesToProductConfig.ts +84 -0
  113. package/dist/migrations/1781200000000-VendorOwnerProductConfigPermissions.ts +51 -0
  114. package/dist/migrations/1781210000000-VendorRoleProductConfigPermissions.ts +46 -0
  115. package/dist/migrations/helpers/vendor-role-seed.ts +243 -0
  116. package/dist/paid-order-erp-3USEG6WL.js +3 -0
  117. package/dist/paid-order-erp-FSQ3GSXE.cjs +12 -0
  118. package/dist/pg-boss-service-4XF2TQ2E.js +2 -0
  119. package/dist/pg-boss-service-L6MTF4EQ.cjs +15 -0
  120. package/dist/razorpay-KLO2KNCB.js +49 -0
  121. package/dist/razorpay-U23LGY72.cjs +56 -0
  122. package/dist/rbac-debug-db-D7ME7QUY.cjs +35 -0
  123. package/dist/rbac-debug-db-MTCTVNNM.js +33 -0
  124. package/dist/sms-defaults-2NL24H57.js +2 -0
  125. package/dist/sms-defaults-KCOPKQBA.cjs +19 -0
  126. package/dist/stripe-4FD27QVJ.js +51 -0
  127. package/dist/stripe-VU6OEG2D.cjs +57 -0
  128. package/dist/theme.cjs +31 -59
  129. package/dist/theme.d.cts +78 -3
  130. package/dist/theme.d.ts +78 -3
  131. package/dist/theme.js +23 -20
  132. package/dist/vendor-invite-status-77O7ZQ3U.cjs +19 -0
  133. package/dist/vendor-invite-status-PWJ3DE76.js +2 -0
  134. package/dist/whatsapp-queue-3DXA4MXU.js +2 -0
  135. package/dist/whatsapp-queue-KG65MXD5.cjs +15 -0
  136. package/package.json +147 -142
  137. package/dist/admin.cjs.map +0 -1
  138. package/dist/admin.js.map +0 -1
  139. package/dist/api.cjs.map +0 -1
  140. package/dist/api.js.map +0 -1
  141. package/dist/auth.cjs.map +0 -1
  142. package/dist/auth.js.map +0 -1
  143. package/dist/cli.cjs.map +0 -1
  144. package/dist/cli.js.map +0 -1
  145. package/dist/config-DJ5CmQvS.d.cts +0 -8
  146. package/dist/config-DJ5CmQvS.d.ts +0 -8
  147. package/dist/hooks.cjs.map +0 -1
  148. package/dist/hooks.js.map +0 -1
  149. package/dist/index-Bf5GO8fu.d.cts +0 -583
  150. package/dist/index-DOiJuMQA.d.ts +0 -583
  151. package/dist/index.cjs.map +0 -1
  152. package/dist/index.js.map +0 -1
  153. package/dist/theme.cjs.map +0 -1
  154. package/dist/theme.js.map +0 -1
  155. package/dist/types-DCVaXlPV.d.cts +0 -78
  156. package/dist/types-DCVaXlPV.d.ts +0 -78
  157. package/dist/vendor-scope-DTYhJk_I.d.cts +0 -129
  158. package/dist/vendor-scope-DTYhJk_I.d.ts +0 -129
@@ -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
+ }
@@ -0,0 +1,140 @@
1
+ import { MigrationInterface, QueryRunner } from 'typeorm';
2
+
3
+ export class CreateCombos1779860000000
4
+ implements MigrationInterface
5
+ {
6
+ name = 'CreateCombos1779860000000';
7
+
8
+ public async up(queryRunner: QueryRunner): Promise<void> {
9
+ await queryRunner.query(`
10
+ DO $$ BEGIN
11
+ CREATE TYPE "combos_status_enum"
12
+ AS ENUM ('active', 'inactive', 'draft');
13
+ EXCEPTION
14
+ WHEN duplicate_object THEN NULL;
15
+ END $$;
16
+ `);
17
+
18
+ await queryRunner.query(`
19
+ DO $$ BEGIN
20
+ CREATE TYPE "combo_items_type_enum"
21
+ AS ENUM ('fixed', 'addons');
22
+ EXCEPTION
23
+ WHEN duplicate_object THEN NULL;
24
+ END $$;
25
+ `);
26
+
27
+ await queryRunner.query(`
28
+ CREATE TABLE IF NOT EXISTS "combos" (
29
+ "id" SERIAL NOT NULL,
30
+ "name" character varying NOT NULL,
31
+ "desc" text,
32
+ "eventId" integer NOT NULL,
33
+ "price" decimal(12,2) NOT NULL DEFAULT 0,
34
+ "minSelectableItems" integer NOT NULL DEFAULT 1,
35
+ "maxSelectableItems" integer NOT NULL DEFAULT 1,
36
+ "status" "combos_status_enum" NOT NULL DEFAULT 'active',
37
+ "startsAt" TIMESTAMP,
38
+ "endsAt" TIMESTAMP,
39
+ "metadata" jsonb,
40
+ "createdAt" TIMESTAMP NOT NULL DEFAULT now(),
41
+ "updatedAt" TIMESTAMP NOT NULL DEFAULT now(),
42
+ "deletedAt" TIMESTAMP,
43
+ "deleted" boolean NOT NULL DEFAULT false,
44
+ "createdBy" integer,
45
+ "updatedBy" integer,
46
+ "deletedBy" integer,
47
+ CONSTRAINT "PK_combos" PRIMARY KEY ("id")
48
+ )
49
+ `);
50
+
51
+ await queryRunner.query(`
52
+ DO $$ BEGIN
53
+ IF NOT EXISTS (
54
+ SELECT 1
55
+ FROM pg_constraint
56
+ WHERE conname = 'FK_combos_event'
57
+ ) THEN
58
+ ALTER TABLE "combos"
59
+ ADD CONSTRAINT "FK_combos_event"
60
+ FOREIGN KEY ("eventId")
61
+ REFERENCES "events"("id")
62
+ ON DELETE CASCADE
63
+ ON UPDATE NO ACTION;
64
+ END IF;
65
+ END $$;
66
+ `);
67
+
68
+ await queryRunner.query(`
69
+ CREATE TABLE IF NOT EXISTS "combo_items" (
70
+ "id" SERIAL NOT NULL,
71
+ "comboId" integer NOT NULL,
72
+ "productId" integer NOT NULL,
73
+ "type" "combo_items_type_enum" NOT NULL DEFAULT 'fixed',
74
+ CONSTRAINT "PK_combo_items" PRIMARY KEY ("id")
75
+ )
76
+ `);
77
+
78
+ await queryRunner.query(`
79
+ DO $$ BEGIN
80
+ IF NOT EXISTS (
81
+ SELECT 1
82
+ FROM pg_constraint
83
+ WHERE conname = 'FK_combo_items_combo'
84
+ ) THEN
85
+ ALTER TABLE "combo_items"
86
+ ADD CONSTRAINT "FK_combo_items_combo"
87
+ FOREIGN KEY ("comboId")
88
+ REFERENCES "combos"("id")
89
+ ON DELETE CASCADE
90
+ ON UPDATE NO ACTION;
91
+ END IF;
92
+ END $$;
93
+ `);
94
+
95
+ await queryRunner.query(`
96
+ DO $$ BEGIN
97
+ IF NOT EXISTS (
98
+ SELECT 1
99
+ FROM pg_constraint
100
+ WHERE conname = 'FK_combo_items_product'
101
+ ) THEN
102
+ ALTER TABLE "combo_items"
103
+ ADD CONSTRAINT "FK_combo_items_product"
104
+ FOREIGN KEY ("productId")
105
+ REFERENCES "products"("id")
106
+ ON DELETE CASCADE
107
+ ON UPDATE NO ACTION;
108
+ END IF;
109
+ END $$;
110
+ `);
111
+
112
+ await queryRunner.query(`
113
+ CREATE INDEX IF NOT EXISTS "IDX_combo_items_combo"
114
+ ON "combo_items" ("comboId")
115
+ `);
116
+
117
+ await queryRunner.query(`
118
+ CREATE INDEX IF NOT EXISTS "IDX_combo_items_product"
119
+ ON "combo_items" ("productId")
120
+ `);
121
+ }
122
+
123
+ public async down(queryRunner: QueryRunner): Promise<void> {
124
+ await queryRunner.query(`
125
+ DROP TABLE IF EXISTS "combo_items"
126
+ `);
127
+
128
+ await queryRunner.query(`
129
+ DROP TABLE IF EXISTS "combos"
130
+ `);
131
+
132
+ await queryRunner.query(`
133
+ DROP TYPE IF EXISTS "combo_items_type_enum"
134
+ `);
135
+
136
+ await queryRunner.query(`
137
+ DROP TYPE IF EXISTS "combos_status_enum"
138
+ `);
139
+ }
140
+ }
@@ -0,0 +1,55 @@
1
+ import type { MigrationInterface, QueryRunner } from 'typeorm';
2
+
3
+ /**
4
+ * Store CMS event id on each order_attendees pass (from event_products at sync time).
5
+ */
6
+ export class OrderAttendeesEventId1780100000000 implements MigrationInterface {
7
+ name = 'OrderAttendeesEventId1780100000000';
8
+
9
+ public async up(queryRunner: QueryRunner): Promise<void> {
10
+ const exists = await queryRunner.hasTable('order_attendees');
11
+ if (!exists) return;
12
+
13
+ const table = await queryRunner.getTable('order_attendees');
14
+ if (!table?.findColumnByName('eventId')) {
15
+ await queryRunner.query(`ALTER TABLE "order_attendees" ADD COLUMN "eventId" integer;`);
16
+ await queryRunner.query(
17
+ `CREATE INDEX IF NOT EXISTS "IDX_order_attendees_eventId" ON "order_attendees" ("eventId");`,
18
+ );
19
+ }
20
+
21
+ const hasEventProducts = await queryRunner.hasTable('event_products');
22
+ if (!hasEventProducts) return;
23
+
24
+ await queryRunner.query(`
25
+ UPDATE "order_attendees" oa
26
+ SET "eventId" = sub."eventId"
27
+ FROM (
28
+ SELECT DISTINCT ON (oa2.id)
29
+ oa2.id AS pass_id,
30
+ ep."eventId" AS "eventId"
31
+ FROM "order_attendees" oa2
32
+ INNER JOIN event_products ep
33
+ ON ep."productId" = (oa2."productId")::integer
34
+ AND ep."isActive" = true
35
+ WHERE oa2."eventId" IS NULL
36
+ AND oa2."productId" ~ '^[0-9]+$'
37
+ ORDER BY oa2.id, ep."eventId" ASC
38
+ ) sub
39
+ WHERE oa.id = sub.pass_id
40
+ AND oa."eventId" IS NULL;
41
+ `);
42
+ }
43
+
44
+ public async down(queryRunner: QueryRunner): Promise<void> {
45
+ const exists = await queryRunner.hasTable('order_attendees');
46
+ if (!exists) return;
47
+
48
+ await queryRunner.query(`DROP INDEX IF EXISTS "IDX_order_attendees_eventId";`);
49
+
50
+ const table = await queryRunner.getTable('order_attendees');
51
+ if (table?.findColumnByName('eventId')) {
52
+ await queryRunner.query(`ALTER TABLE "order_attendees" DROP COLUMN "eventId";`);
53
+ }
54
+ }
55
+ }
@@ -0,0 +1,49 @@
1
+ import type { MigrationInterface, QueryRunner } from 'typeorm';
2
+
3
+ /**
4
+ * Link events to a CMS contact/attendee form for registration checkout.
5
+ */
6
+ export class EventContactFormId1780110000000 implements MigrationInterface {
7
+ name = 'EventContactFormId1780110000000';
8
+
9
+ public async up(queryRunner: QueryRunner): Promise<void> {
10
+ const hasEvents = await queryRunner.hasTable('events');
11
+ if (!hasEvents) return;
12
+
13
+ const table = await queryRunner.getTable('events');
14
+ if (!table?.findColumnByName('contactFormId')) {
15
+ await queryRunner.query(`ALTER TABLE "events" ADD COLUMN "contactFormId" integer;`);
16
+ }
17
+
18
+ const hasForms = await queryRunner.hasTable('forms');
19
+ if (!hasForms) return;
20
+
21
+ await queryRunner.query(`
22
+ DO $$ BEGIN
23
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'FK_events_contactForm') THEN
24
+ ALTER TABLE "events"
25
+ ADD CONSTRAINT "FK_events_contactForm"
26
+ FOREIGN KEY ("contactFormId") REFERENCES "forms"("id")
27
+ ON DELETE SET NULL ON UPDATE NO ACTION;
28
+ END IF;
29
+ END $$;
30
+ `);
31
+
32
+ await queryRunner.query(`
33
+ CREATE INDEX IF NOT EXISTS "IDX_events_contactFormId" ON "events" ("contactFormId");
34
+ `);
35
+ }
36
+
37
+ public async down(queryRunner: QueryRunner): Promise<void> {
38
+ const hasEvents = await queryRunner.hasTable('events');
39
+ if (!hasEvents) return;
40
+
41
+ await queryRunner.query(`DROP INDEX IF EXISTS "IDX_events_contactFormId";`);
42
+ await queryRunner.query(`ALTER TABLE "events" DROP CONSTRAINT IF EXISTS "FK_events_contactForm";`);
43
+
44
+ const table = await queryRunner.getTable('events');
45
+ if (table?.findColumnByName('contactFormId')) {
46
+ await queryRunner.query(`ALTER TABLE "events" DROP COLUMN "contactFormId";`);
47
+ }
48
+ }
49
+ }