@bash-app/bash-common 29.50.0 → 29.51.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/package.json +3 -3
- package/prisma/schema.prisma +51 -9
- package/scripts/symlinks.sh +31 -0
- package/src/definitions.ts +168 -103
- package/src/extendedSchemas.ts +233 -104
- package/src/index.ts +3 -0
- package/src/utils/entityUtils.ts +4 -0
- package/src/utils/service/serviceUtils.ts +128 -84
- package/src/utils/service/venueUtils.ts +22 -22
- package/src/utils/userPromoCodeUtils.ts +25 -23
- package/src/utils/userSubscriptionUtils.ts +86 -63
|
@@ -1,101 +1,145 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
ServiceCancelationPolicy as ServiceCancelationPolicyOption,
|
|
3
|
+
ServiceSubscriptionStatus,
|
|
4
|
+
} from "@prisma/client";
|
|
2
5
|
|
|
3
6
|
export type ServiceCancelationRefundPolicy = {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
7
|
+
days?: number;
|
|
8
|
+
hours?: number;
|
|
9
|
+
refundPercentage: number;
|
|
10
|
+
};
|
|
8
11
|
|
|
9
12
|
export type ServiceCancelationPolicyData = {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
name: string;
|
|
14
|
+
description?: string;
|
|
15
|
+
refundPolicy: ServiceCancelationRefundPolicy[];
|
|
13
16
|
};
|
|
14
17
|
|
|
15
18
|
export type ServiceCancelationPolicyMap = {
|
|
16
|
-
|
|
19
|
+
[key in ServiceCancelationPolicyOption]: ServiceCancelationPolicyData;
|
|
17
20
|
};
|
|
18
21
|
|
|
19
|
-
export const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
22
|
+
export const SERVICE_CANCELATION_POLICY_DATA: ServiceCancelationPolicyMap = {
|
|
23
|
+
[ServiceCancelationPolicyOption.None]: {
|
|
24
|
+
name: "None",
|
|
25
|
+
refundPolicy: [],
|
|
26
|
+
description: "No cancellation policy.",
|
|
27
|
+
},
|
|
28
|
+
[ServiceCancelationPolicyOption.VeryFlexible]: {
|
|
29
|
+
name: "Very Flexible",
|
|
30
|
+
refundPolicy: [
|
|
31
|
+
{
|
|
32
|
+
hours: 24,
|
|
33
|
+
refundPercentage: 100,
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
[ServiceCancelationPolicyOption.Flexible]: {
|
|
38
|
+
name: "Flexible",
|
|
39
|
+
refundPolicy: [
|
|
40
|
+
{
|
|
41
|
+
days: 7,
|
|
42
|
+
refundPercentage: 100,
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
hours: 24,
|
|
46
|
+
refundPercentage: 50,
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
[ServiceCancelationPolicyOption.Standard30Day]: {
|
|
51
|
+
name: "Standard 30 Day",
|
|
52
|
+
refundPolicy: [
|
|
53
|
+
{
|
|
54
|
+
days: 30,
|
|
55
|
+
refundPercentage: 100,
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
days: 7,
|
|
59
|
+
refundPercentage: 50,
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
},
|
|
63
|
+
[ServiceCancelationPolicyOption.Standard90Day]: {
|
|
64
|
+
name: "Very Flexible",
|
|
65
|
+
refundPolicy: [
|
|
66
|
+
{
|
|
67
|
+
days: 90,
|
|
68
|
+
refundPercentage: 100,
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
days: 14,
|
|
72
|
+
refundPercentage: 50,
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
},
|
|
73
76
|
} as const;
|
|
74
77
|
|
|
75
|
-
function generateDescription(
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
78
|
+
function generateDescription(
|
|
79
|
+
refundPolicy: ServiceCancelationRefundPolicy[]
|
|
80
|
+
): string {
|
|
81
|
+
const descriptions = refundPolicy.map((policy, index) => {
|
|
82
|
+
const unit = policy.days ? "days" : "hours";
|
|
83
|
+
const timeValue = policy.days ?? policy.hours;
|
|
79
84
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
85
|
+
const refundText =
|
|
86
|
+
policy.refundPercentage === 100
|
|
87
|
+
? "a full refund (including all Fees)"
|
|
88
|
+
: `${policy.refundPercentage}% refund (excluding Fees)`;
|
|
83
89
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
90
|
+
if (index === 0) {
|
|
91
|
+
return `Guests may cancel their Booking until ${timeValue} ${unit} before the event start time and will receive ${refundText} of their Booking Price.`;
|
|
92
|
+
} else {
|
|
93
|
+
const previousTime =
|
|
94
|
+
refundPolicy[index - 1].days ?? refundPolicy[index - 1].hours;
|
|
95
|
+
return `Guests may cancel their Booking between ${timeValue} ${unit} and ${previousTime} ${unit} before the event start time and receive ${refundText} of their Booking Price.`;
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
const lastTime =
|
|
100
|
+
refundPolicy[refundPolicy.length - 1].days ??
|
|
101
|
+
refundPolicy[refundPolicy.length - 1].hours;
|
|
102
|
+
descriptions.push(
|
|
103
|
+
`Cancellations submitted less than ${lastTime} ${
|
|
104
|
+
refundPolicy[refundPolicy.length - 1].days ? "days" : "hours"
|
|
105
|
+
} before the Event start time are not refundable.`
|
|
106
|
+
);
|
|
91
107
|
|
|
92
|
-
|
|
93
|
-
descriptions.push(`Cancellations submitted less than ${lastTime} ${refundPolicy[refundPolicy.length - 1].days ? 'days' : 'hours'} before the Event start time are not refundable.`);
|
|
94
|
-
|
|
95
|
-
return descriptions.join(" ");
|
|
108
|
+
return descriptions.join(" ");
|
|
96
109
|
}
|
|
97
110
|
|
|
98
|
-
Object.keys(
|
|
99
|
-
|
|
111
|
+
Object.keys(SERVICE_CANCELATION_POLICY_DATA)
|
|
112
|
+
.filter(
|
|
113
|
+
(policyKey) =>
|
|
114
|
+
(policyKey as ServiceCancelationPolicyOption) !=
|
|
115
|
+
ServiceCancelationPolicyOption.None
|
|
116
|
+
)
|
|
117
|
+
.forEach((policyKey) => {
|
|
118
|
+
const policy =
|
|
119
|
+
SERVICE_CANCELATION_POLICY_DATA[
|
|
120
|
+
policyKey as ServiceCancelationPolicyOption
|
|
121
|
+
];
|
|
100
122
|
policy.description = generateDescription(policy.refundPolicy);
|
|
101
|
-
});
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
export function serviceSubscriptionIsActive(
|
|
126
|
+
status: ServiceSubscriptionStatus
|
|
127
|
+
): boolean {
|
|
128
|
+
return status in ["Trialing", "Normal"];
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export function serviceDetailUrl(
|
|
132
|
+
serviceId: string,
|
|
133
|
+
serviceType: string,
|
|
134
|
+
specificId: string
|
|
135
|
+
) {
|
|
136
|
+
return `/services/${serviceId}/${serviceType}/${specificId}`;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export function serviceCheckoutUrl(
|
|
140
|
+
serviceId: string,
|
|
141
|
+
serviceType: string,
|
|
142
|
+
specificId: string
|
|
143
|
+
) {
|
|
144
|
+
return `/checkout/services/${serviceId}/${serviceType}/${specificId}`;
|
|
145
|
+
}
|
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
import { VenuePricingPlan as VenuePricingPlanOption } from "@prisma/client";
|
|
2
2
|
|
|
3
3
|
export type VenuePricingPlanData = {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
name: string;
|
|
5
|
+
description: string;
|
|
6
|
+
percentageFee: number;
|
|
7
|
+
monthlyFee: number;
|
|
8
|
+
flatFee: number;
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
export type VenuePricingPlanMap = {
|
|
12
|
-
|
|
12
|
+
[key in VenuePricingPlanOption]: VenuePricingPlanData;
|
|
13
13
|
};
|
|
14
14
|
|
|
15
|
-
export const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
} as const;
|
|
15
|
+
export const VENUE_PRICING_PLAN_DATA: VenuePricingPlanMap = {
|
|
16
|
+
[VenuePricingPlanOption.Percentage]: {
|
|
17
|
+
name: "Pay per booking",
|
|
18
|
+
description: "15% of each booking goes to Bash.",
|
|
19
|
+
percentageFee: 0.15,
|
|
20
|
+
monthlyFee: 0.0,
|
|
21
|
+
flatFee: 0.0,
|
|
22
|
+
},
|
|
23
|
+
[VenuePricingPlanOption.Subscription]: {
|
|
24
|
+
name: "Monthly subscription",
|
|
25
|
+
description: "Pay $100/month and keep 100% of each booking.",
|
|
26
|
+
percentageFee: 0.0,
|
|
27
|
+
monthlyFee: 100.0,
|
|
28
|
+
flatFee: 0.0,
|
|
29
|
+
},
|
|
30
|
+
} as const;
|
|
@@ -1,36 +1,38 @@
|
|
|
1
1
|
export type UserPromoCodeType = "PerUser" | "PerService" | "PerBashEvent";
|
|
2
2
|
|
|
3
3
|
export type UserPromoCodeDuration = {
|
|
4
|
-
|
|
4
|
+
days?: number;
|
|
5
5
|
};
|
|
6
6
|
|
|
7
7
|
export type UserPromoCode = {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
8
|
+
code?: string;
|
|
9
|
+
maxRedemptions?: number;
|
|
10
|
+
isTrial?: boolean;
|
|
11
|
+
discountPercentageFee?: number;
|
|
12
|
+
discountMonthlyFee?: number;
|
|
13
|
+
duration: UserPromoCodeDuration;
|
|
14
|
+
type: UserPromoCodeType;
|
|
15
|
+
automaticallyApplied: boolean;
|
|
16
|
+
expiresAfter?: number;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
export type UserPromoCodeMap = {
|
|
20
|
-
|
|
20
|
+
[key: string]: UserPromoCode;
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
-
export const
|
|
24
|
-
"Service0001": {
|
|
25
|
-
isTrial: true,
|
|
26
|
-
duration: {
|
|
27
|
-
days: 90
|
|
28
|
-
},
|
|
29
|
-
type: "PerUser",
|
|
30
|
-
automaticallyApplied: true,
|
|
31
|
-
}
|
|
32
|
-
} as const;
|
|
23
|
+
export const SERVICE_FREE_TRIAL_PROMO_CODE = "ServiceFreeTrial0000" as const;
|
|
33
24
|
|
|
34
|
-
|
|
25
|
+
export const USER_PROMO_CODES: UserPromoCodeMap = {
|
|
26
|
+
[SERVICE_FREE_TRIAL_PROMO_CODE]: {
|
|
27
|
+
isTrial: true,
|
|
28
|
+
duration: {
|
|
29
|
+
days: 90,
|
|
30
|
+
},
|
|
31
|
+
type: "PerUser",
|
|
32
|
+
automaticallyApplied: true,
|
|
33
|
+
},
|
|
34
|
+
} as const;
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
Object.entries(USER_PROMO_CODES).forEach(
|
|
37
|
+
(promoCode) => (promoCode[1].code = promoCode[0])
|
|
38
|
+
);
|
|
@@ -1,80 +1,103 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ServiceTypes, UserSubscriptionType } from "@prisma/client";
|
|
2
|
+
|
|
3
|
+
export const ServiceSubscriptionTier = {
|
|
4
|
+
Ally: "Ally",
|
|
5
|
+
Partner: "Partner",
|
|
6
|
+
Patreon: "Patron",
|
|
7
|
+
} as const;
|
|
8
|
+
export type ServiceSubscriptionTier = "Ally" | "Partner" | "Patron";
|
|
2
9
|
|
|
3
10
|
export type UserSubscriptionServiceTierInfo = {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
11
|
+
name: string;
|
|
12
|
+
type?: ServiceSubscriptionTier;
|
|
13
|
+
description: string;
|
|
14
|
+
price: number;
|
|
8
15
|
};
|
|
9
16
|
|
|
10
|
-
export type UserSubscriptionServiceTierInfoMap = {
|
|
17
|
+
export type UserSubscriptionServiceTierInfoMap = {
|
|
18
|
+
[key in ServiceSubscriptionTier]: UserSubscriptionServiceTierInfo;
|
|
19
|
+
};
|
|
11
20
|
|
|
12
21
|
export type UserSubscriptionInfo = {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
22
|
+
name: string;
|
|
23
|
+
type?: UserSubscriptionType;
|
|
24
|
+
description: string;
|
|
25
|
+
price: number;
|
|
26
|
+
// serviceTiers: UserSubscriptionServiceTierInfoMap;
|
|
27
|
+
// maxServicesToList?: number;
|
|
28
|
+
// maxServicesByTypeToList?:
|
|
20
29
|
};
|
|
21
30
|
|
|
22
|
-
export type UserSubscriptionServiceInfoMap = {
|
|
31
|
+
export type UserSubscriptionServiceInfoMap = {
|
|
32
|
+
[key in UserSubscriptionType]: UserSubscriptionInfo;
|
|
33
|
+
};
|
|
23
34
|
|
|
24
|
-
export type UserServiceSubscriptionTierToServiceTypes = {
|
|
25
|
-
|
|
35
|
+
export type UserServiceSubscriptionTierToServiceTypes = {
|
|
36
|
+
[key in ServiceSubscriptionTier]: ServiceTypes[];
|
|
37
|
+
};
|
|
38
|
+
export type UserServiceSubscriptionTierFromServiceTypes = {
|
|
39
|
+
[key in ServiceTypes]: ServiceSubscriptionTier;
|
|
40
|
+
};
|
|
26
41
|
|
|
27
|
-
export const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
42
|
+
export const SERVICE_TIER_TO_SERVICES_LIST = {
|
|
43
|
+
Ally: ["EventServices", "EntertainmentServices"],
|
|
44
|
+
Partner: ["Vendors", "Exhibitors", "Sponsors"],
|
|
45
|
+
Patron: ["Venues", "Organizations"],
|
|
31
46
|
} as UserServiceSubscriptionTierToServiceTypes;
|
|
32
47
|
|
|
33
|
-
export const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
48
|
+
export const SERVICE_TIER_FROM_SERVICE_TYPE = Object.entries(
|
|
49
|
+
SERVICE_TIER_TO_SERVICES_LIST
|
|
50
|
+
).reduce((sofar, [type, serviceTypes]) => {
|
|
51
|
+
serviceTypes.forEach(
|
|
52
|
+
(serviceType) => (sofar[serviceType] = type as ServiceSubscriptionTier)
|
|
53
|
+
);
|
|
54
|
+
return sofar;
|
|
55
|
+
}, {} as UserServiceSubscriptionTierFromServiceTypes);
|
|
37
56
|
|
|
38
|
-
export const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
export const USER_SUBSCRIPTION_TYPES = {
|
|
58
|
+
// "Free": {
|
|
59
|
+
// name: "Free",
|
|
60
|
+
// description: "Free",
|
|
61
|
+
// price: 0,
|
|
62
|
+
// },
|
|
63
|
+
Basic: {
|
|
64
|
+
name: "Basic",
|
|
65
|
+
description: "Basic",
|
|
66
|
+
price: 0,
|
|
67
|
+
},
|
|
68
|
+
// "Premium": {
|
|
69
|
+
// name: "Premium",
|
|
70
|
+
// description: "Premium",
|
|
71
|
+
// price: 200,
|
|
72
|
+
// },
|
|
73
|
+
// "VIP": {
|
|
74
|
+
// name: "VIP",
|
|
75
|
+
// description: "VIP",
|
|
76
|
+
// price: 500,
|
|
77
|
+
// }
|
|
59
78
|
} as UserSubscriptionServiceInfoMap;
|
|
60
79
|
|
|
61
|
-
export const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
80
|
+
export const SERVICE_SUBSCRIPTION_TIERS = {
|
|
81
|
+
Ally: {
|
|
82
|
+
name: "Ally",
|
|
83
|
+
description: "Ally",
|
|
84
|
+
price: 14,
|
|
85
|
+
},
|
|
86
|
+
Partner: {
|
|
87
|
+
name: "Partner",
|
|
88
|
+
description: "Partner",
|
|
89
|
+
price: 49.0,
|
|
90
|
+
},
|
|
91
|
+
Patron: {
|
|
92
|
+
name: "Patron",
|
|
93
|
+
description: "Patron",
|
|
94
|
+
price: 99.0,
|
|
95
|
+
},
|
|
77
96
|
} as UserSubscriptionServiceTierInfoMap;
|
|
78
97
|
|
|
79
|
-
Object.entries(
|
|
80
|
-
|
|
98
|
+
Object.entries(USER_SUBSCRIPTION_TYPES).forEach(
|
|
99
|
+
([type, info]) => (info.type = type as UserSubscriptionType)
|
|
100
|
+
);
|
|
101
|
+
Object.entries(SERVICE_SUBSCRIPTION_TIERS).forEach(
|
|
102
|
+
([type, info]) => (info.type = type as ServiceSubscriptionTier)
|
|
103
|
+
);
|