@bash-app/bash-common 30.116.0 → 30.118.0
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/extendedSchemas.d.ts +54 -0
- package/dist/extendedSchemas.d.ts.map +1 -1
- package/dist/extendedSchemas.js +10 -1
- package/dist/extendedSchemas.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/utils/__tests__/paymentUtils.test.d.ts +6 -0
- package/dist/utils/__tests__/paymentUtils.test.d.ts.map +1 -0
- package/dist/utils/__tests__/paymentUtils.test.js +77 -0
- package/dist/utils/__tests__/paymentUtils.test.js.map +1 -0
- package/dist/utils/discountEngine/__tests__/bestPriceResolver.test.d.ts +2 -0
- package/dist/utils/discountEngine/__tests__/bestPriceResolver.test.d.ts.map +1 -0
- package/dist/utils/discountEngine/__tests__/bestPriceResolver.test.js +457 -0
- package/dist/utils/discountEngine/__tests__/bestPriceResolver.test.js.map +1 -0
- package/dist/utils/discountEngine/__tests__/eligibilityValidator.test.d.ts +2 -0
- package/dist/utils/discountEngine/__tests__/eligibilityValidator.test.d.ts.map +1 -0
- package/dist/utils/discountEngine/__tests__/eligibilityValidator.test.js +480 -0
- package/dist/utils/discountEngine/__tests__/eligibilityValidator.test.js.map +1 -0
- package/package.json +2 -2
- package/prisma/COMPREHENSIVE-MIGRATION-README.md +295 -0
- package/prisma/MIGRATION-FILES-GUIDE.md +76 -0
- package/prisma/comprehensive-migration-20260120.sql +5751 -0
- package/prisma/delta-migration-20260120.sql +302 -0
- package/prisma/schema.prisma +253 -13
- package/prisma/verify-migration.sql +132 -0
- package/src/extendedSchemas.ts +10 -1
- package/src/index.ts +4 -0
- package/src/utils/__tests__/paymentUtils.test.ts +95 -0
- package/src/utils/discountEngine/__tests__/bestPriceResolver.test.ts +558 -0
- package/src/utils/discountEngine/__tests__/eligibilityValidator.test.ts +655 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
-- ============================================================================
|
|
2
|
+
-- POST-MIGRATION VERIFICATION SCRIPT
|
|
3
|
+
-- Run this after applying comprehensive-migration-20260120.sql
|
|
4
|
+
-- ============================================================================
|
|
5
|
+
|
|
6
|
+
-- 1. Count all tables (expect 160+)
|
|
7
|
+
SELECT COUNT(*) as total_tables
|
|
8
|
+
FROM information_schema.tables
|
|
9
|
+
WHERE table_schema = 'public';
|
|
10
|
+
|
|
11
|
+
-- 2. Count all enums (expect 170+)
|
|
12
|
+
SELECT COUNT(*) as total_enums
|
|
13
|
+
FROM pg_type
|
|
14
|
+
WHERE typtype = 'e';
|
|
15
|
+
|
|
16
|
+
-- 3. Count all indexes (expect 400+)
|
|
17
|
+
SELECT COUNT(*) as total_indexes
|
|
18
|
+
FROM pg_indexes
|
|
19
|
+
WHERE schemaname = 'public';
|
|
20
|
+
|
|
21
|
+
-- 4. Verify critical tables exist
|
|
22
|
+
SELECT
|
|
23
|
+
CASE
|
|
24
|
+
WHEN EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'User') THEN '✅'
|
|
25
|
+
ELSE '❌'
|
|
26
|
+
END as "User",
|
|
27
|
+
CASE
|
|
28
|
+
WHEN EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'BashEvent') THEN '✅'
|
|
29
|
+
ELSE '❌'
|
|
30
|
+
END as "BashEvent",
|
|
31
|
+
CASE
|
|
32
|
+
WHEN EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'Service') THEN '✅'
|
|
33
|
+
ELSE '❌'
|
|
34
|
+
END as "Service",
|
|
35
|
+
CASE
|
|
36
|
+
WHEN EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'Ticket') THEN '✅'
|
|
37
|
+
ELSE '❌'
|
|
38
|
+
END as "Ticket",
|
|
39
|
+
CASE
|
|
40
|
+
WHEN EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'BashFeedPost') THEN '✅'
|
|
41
|
+
ELSE '❌'
|
|
42
|
+
END as "BashFeedPost",
|
|
43
|
+
CASE
|
|
44
|
+
WHEN EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'Competition') THEN '✅'
|
|
45
|
+
ELSE '❌'
|
|
46
|
+
END as "Competition",
|
|
47
|
+
CASE
|
|
48
|
+
WHEN EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'Organization') THEN '✅'
|
|
49
|
+
ELSE '❌'
|
|
50
|
+
END as "Organization",
|
|
51
|
+
CASE
|
|
52
|
+
WHEN EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'TaskComment') THEN '✅'
|
|
53
|
+
ELSE '❌'
|
|
54
|
+
END as "TaskComment",
|
|
55
|
+
CASE
|
|
56
|
+
WHEN EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'TaskInvitation') THEN '✅'
|
|
57
|
+
ELSE '❌'
|
|
58
|
+
END as "TaskInvitation",
|
|
59
|
+
CASE
|
|
60
|
+
WHEN EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'AuditLog') THEN '✅'
|
|
61
|
+
ELSE '❌'
|
|
62
|
+
END as "AuditLog";
|
|
63
|
+
|
|
64
|
+
-- 5. Verify critical enums exist
|
|
65
|
+
SELECT
|
|
66
|
+
CASE
|
|
67
|
+
WHEN EXISTS (SELECT 1 FROM pg_type WHERE typname = 'BashStatus') THEN '✅'
|
|
68
|
+
ELSE '❌'
|
|
69
|
+
END as "BashStatus",
|
|
70
|
+
CASE
|
|
71
|
+
WHEN EXISTS (SELECT 1 FROM pg_type WHERE typname = 'ServiceStatus') THEN '✅'
|
|
72
|
+
ELSE '❌'
|
|
73
|
+
END as "ServiceStatus",
|
|
74
|
+
CASE
|
|
75
|
+
WHEN EXISTS (SELECT 1 FROM pg_type WHERE typname = 'NotificationType') THEN '✅'
|
|
76
|
+
ELSE '❌'
|
|
77
|
+
END as "NotificationType",
|
|
78
|
+
CASE
|
|
79
|
+
WHEN EXISTS (SELECT 1 FROM pg_type WHERE typname = 'Privacy') THEN '✅'
|
|
80
|
+
ELSE '❌'
|
|
81
|
+
END as "Privacy";
|
|
82
|
+
|
|
83
|
+
-- 6. Check for any foreign key constraint errors
|
|
84
|
+
SELECT
|
|
85
|
+
conname as constraint_name,
|
|
86
|
+
conrelid::regclass as table_name,
|
|
87
|
+
confrelid::regclass as referenced_table
|
|
88
|
+
FROM pg_constraint
|
|
89
|
+
WHERE contype = 'f'
|
|
90
|
+
AND connamespace = 'public'::regnamespace
|
|
91
|
+
LIMIT 10;
|
|
92
|
+
|
|
93
|
+
-- 7. Verify specific columns from November migration
|
|
94
|
+
SELECT
|
|
95
|
+
CASE
|
|
96
|
+
WHEN EXISTS (
|
|
97
|
+
SELECT 1 FROM information_schema.columns
|
|
98
|
+
WHERE table_name = 'Service' AND column_name = 'acceptsBashCash'
|
|
99
|
+
) THEN '✅ Service.acceptsBashCash exists'
|
|
100
|
+
ELSE '❌ Service.acceptsBashCash MISSING'
|
|
101
|
+
END as service_column,
|
|
102
|
+
CASE
|
|
103
|
+
WHEN EXISTS (
|
|
104
|
+
SELECT 1 FROM information_schema.columns
|
|
105
|
+
WHERE table_name = 'User' AND column_name = 'isLightweightAccount'
|
|
106
|
+
) THEN '✅ User.isLightweightAccount exists'
|
|
107
|
+
ELSE '❌ User.isLightweightAccount MISSING'
|
|
108
|
+
END as user_column;
|
|
109
|
+
|
|
110
|
+
-- 8. List all tables (alphabetically)
|
|
111
|
+
SELECT table_name
|
|
112
|
+
FROM information_schema.tables
|
|
113
|
+
WHERE table_schema = 'public'
|
|
114
|
+
AND table_type = 'BASE TABLE'
|
|
115
|
+
ORDER BY table_name;
|
|
116
|
+
|
|
117
|
+
-- ============================================================================
|
|
118
|
+
-- Expected Results
|
|
119
|
+
-- ============================================================================
|
|
120
|
+
--
|
|
121
|
+
-- Query 1: total_tables should be 160+
|
|
122
|
+
-- Query 2: total_enums should be 170+
|
|
123
|
+
-- Query 3: total_indexes should be 400+
|
|
124
|
+
-- Query 4: All columns should show ✅
|
|
125
|
+
-- Query 5: All enums should show ✅
|
|
126
|
+
-- Query 6: Should return 10 foreign keys without errors
|
|
127
|
+
-- Query 7: Both columns should show ✅
|
|
128
|
+
-- Query 8: Should list all your tables alphabetically
|
|
129
|
+
--
|
|
130
|
+
-- If any ❌ appears, the migration may have failed partially
|
|
131
|
+
-- Check postgres logs for errors
|
|
132
|
+
-- ============================================================================
|
package/src/extendedSchemas.ts
CHANGED
|
@@ -223,7 +223,7 @@ export const BASH_EVENT_DATA_TO_INCLUDE = {
|
|
|
223
223
|
recurrence: true,
|
|
224
224
|
ticketTiers: true,
|
|
225
225
|
media: true,
|
|
226
|
-
eventTasks: true,
|
|
226
|
+
eventTasks: true, // ✅ FIXED: assignedMemberId issue resolved by syncing API schema
|
|
227
227
|
invitations: true,
|
|
228
228
|
competitions: {
|
|
229
229
|
include: {
|
|
@@ -398,6 +398,15 @@ export const SERVICE_DATA_TO_INCLUDE = {
|
|
|
398
398
|
sponsor: {
|
|
399
399
|
include: SPONSOR_DATA_TO_INCLUDE,
|
|
400
400
|
},
|
|
401
|
+
organization: {
|
|
402
|
+
include: {
|
|
403
|
+
_count: {
|
|
404
|
+
select: {
|
|
405
|
+
members: true,
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}, // Include organization data with member counts
|
|
401
410
|
// bookings: {
|
|
402
411
|
// include: SERVICE_BOOKING_PRIVATE_DATA_TO_INCLUDE, //make sure only to include owned bookedDays
|
|
403
412
|
// },
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
export * from "./definitions";
|
|
2
2
|
export * from "./extendedSchemas";
|
|
3
3
|
export * from "./membershipDefinitions";
|
|
4
|
+
|
|
5
|
+
// Re-export commonly used Prisma types
|
|
6
|
+
export type { Service, Organization, User, BashEvent } from '@prisma/client';
|
|
7
|
+
|
|
4
8
|
export * from "./utils/addressUtils";
|
|
5
9
|
export * from "./utils/apiUtils";
|
|
6
10
|
export * from "./utils/arrayUtils";
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for payment utility functions
|
|
3
|
+
* Testing business logic without database dependencies
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
calculateDiscountFromPromoCode,
|
|
8
|
+
convertCentsToDollars,
|
|
9
|
+
convertDollarsToCents,
|
|
10
|
+
calculateBashAppFee,
|
|
11
|
+
calculateBashAppFeeWithMembershipDiscount,
|
|
12
|
+
} from "../paymentUtils";
|
|
13
|
+
|
|
14
|
+
describe("PaymentUtils - Core Functions", () => {
|
|
15
|
+
describe("Currency Conversion", () => {
|
|
16
|
+
test("convertCentsToDollars", () => {
|
|
17
|
+
expect(convertCentsToDollars(100)).toBe(1);
|
|
18
|
+
expect(convertCentsToDollars(1000)).toBe(10);
|
|
19
|
+
expect(convertCentsToDollars(12345)).toBe(123.45);
|
|
20
|
+
expect(convertCentsToDollars(null)).toBe(0);
|
|
21
|
+
expect(convertCentsToDollars(undefined)).toBe(0);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test("convertDollarsToCents", () => {
|
|
25
|
+
expect(convertDollarsToCents(1)).toBe(100);
|
|
26
|
+
expect(convertDollarsToCents(10)).toBe(1000);
|
|
27
|
+
expect(convertDollarsToCents(123.45)).toBe(12345);
|
|
28
|
+
expect(convertDollarsToCents(null)).toBe(0);
|
|
29
|
+
expect(convertDollarsToCents(undefined)).toBe(0);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test("round-trip conversion", () => {
|
|
33
|
+
const dollars = 123.45;
|
|
34
|
+
const cents = convertDollarsToCents(dollars);
|
|
35
|
+
const backToDollars = convertCentsToDollars(cents);
|
|
36
|
+
expect(backToDollars).toBe(dollars);
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
describe("Promo Code Discounts", () => {
|
|
41
|
+
test("fixed amount discount", () => {
|
|
42
|
+
const promoCode: any = {
|
|
43
|
+
discountAmountInCents: 500,
|
|
44
|
+
discountAmountPercentage: null,
|
|
45
|
+
};
|
|
46
|
+
expect(calculateDiscountFromPromoCode(100, promoCode)).toBe(5);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test("percentage discount", () => {
|
|
50
|
+
const promoCode: any = {
|
|
51
|
+
discountAmountInCents: null,
|
|
52
|
+
discountAmountPercentage: 20,
|
|
53
|
+
};
|
|
54
|
+
expect(calculateDiscountFromPromoCode(100, promoCode)).toBe(20);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test("no discount when undefined", () => {
|
|
58
|
+
expect(calculateDiscountFromPromoCode(100, undefined)).toBe(0);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test("caps at 100%", () => {
|
|
62
|
+
const promoCode: any = {
|
|
63
|
+
discountAmountInCents: null,
|
|
64
|
+
discountAmountPercentage: 150,
|
|
65
|
+
};
|
|
66
|
+
expect(calculateDiscountFromPromoCode(100, promoCode)).toBe(100);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
describe("Platform Fees", () => {
|
|
71
|
+
test("calculateBashAppFee", () => {
|
|
72
|
+
expect(calculateBashAppFee(1000)).toBe(70); // 7%
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test("calculateBashAppFeeWithMembershipDiscount - Basic tier", () => {
|
|
76
|
+
const fee = calculateBashAppFeeWithMembershipDiscount(10000, "Basic" as any);
|
|
77
|
+
expect(fee).toBe(700); // 7%
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test("calculateBashAppFeeWithMembershipDiscount - Creator tier", () => {
|
|
81
|
+
const fee = calculateBashAppFeeWithMembershipDiscount(10000, "Creator" as any);
|
|
82
|
+
expect(fee).toBe(300); // 3%
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
test("applies minimum fee", () => {
|
|
86
|
+
const fee = calculateBashAppFeeWithMembershipDiscount(100, "Creator" as any);
|
|
87
|
+
expect(fee).toBe(50); // minimum is 50 cents
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test("applies cap", () => {
|
|
91
|
+
const fee = calculateBashAppFeeWithMembershipDiscount(100000, "Basic" as any);
|
|
92
|
+
expect(fee).toBe(1000); // cap at $10
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
});
|