@bash-app/bash-common 30.323.0 → 30.327.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/__tests__/hostCrmSegments.test.js +62 -1
- package/dist/__tests__/hostCrmSegments.test.js.map +1 -1
- package/dist/hostCrmSegments.d.ts +75 -1
- package/dist/hostCrmSegments.d.ts.map +1 -1
- package/dist/hostCrmSegments.js +112 -0
- package/dist/hostCrmSegments.js.map +1 -1
- package/package.json +1 -1
- package/prisma/schema.prisma +16 -0
- package/src/__tests__/hostCrmSegments.test.ts +79 -0
- package/src/hostCrmSegments.ts +201 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { applyHostCrmSegmentRules, HOST_CRM_PRESET_SEGMENTS, } from "../hostCrmSegments.js";
|
|
1
|
+
import { applyHostCrmSegmentRules, communityStrengthTierFromScore, computeCommunityStrengthScore, computeHostCrmSystemTags, EMPTY_HOST_CRM_ASSOCIATION_BREAKDOWN, HOST_CRM_PRESET_SEGMENTS, meetsAudienceInclusionThreshold, } from "../hostCrmSegments.js";
|
|
2
2
|
const NOW = new Date("2026-07-14T12:00:00Z");
|
|
3
3
|
function member(overrides = {}) {
|
|
4
4
|
return {
|
|
@@ -30,9 +30,70 @@ function member(overrides = {}) {
|
|
|
30
30
|
discoverySource: "direct",
|
|
31
31
|
expectedGapDays: null,
|
|
32
32
|
nextExpectedAt: null,
|
|
33
|
+
associatedEventCount: 1,
|
|
34
|
+
associatedEventIds: ["evt-a"],
|
|
35
|
+
associationBreakdown: { ...EMPTY_HOST_CRM_ASSOCIATION_BREAKDOWN, tickets: 1 },
|
|
36
|
+
communityStrengthScore: 8,
|
|
37
|
+
communityStrengthTier: "Casual",
|
|
38
|
+
systemTags: [],
|
|
33
39
|
...overrides,
|
|
34
40
|
};
|
|
35
41
|
}
|
|
42
|
+
describe("audience inclusion + community strength helpers", () => {
|
|
43
|
+
it("includes on one heavy/medium edge", () => {
|
|
44
|
+
expect(meetsAudienceInclusionThreshold({
|
|
45
|
+
heavyMediumEdgeCount: 1,
|
|
46
|
+
lightEdgeCount: 0,
|
|
47
|
+
lightEdgeBashCount: 0,
|
|
48
|
+
})).toBe(true);
|
|
49
|
+
});
|
|
50
|
+
it("excludes like-only and single-comment", () => {
|
|
51
|
+
expect(meetsAudienceInclusionThreshold({
|
|
52
|
+
heavyMediumEdgeCount: 0,
|
|
53
|
+
lightEdgeCount: 1,
|
|
54
|
+
lightEdgeBashCount: 1,
|
|
55
|
+
})).toBe(false);
|
|
56
|
+
});
|
|
57
|
+
it("includes light-only when ≥3 edges across ≥2 bashes", () => {
|
|
58
|
+
expect(meetsAudienceInclusionThreshold({
|
|
59
|
+
heavyMediumEdgeCount: 0,
|
|
60
|
+
lightEdgeCount: 3,
|
|
61
|
+
lightEdgeBashCount: 2,
|
|
62
|
+
})).toBe(true);
|
|
63
|
+
});
|
|
64
|
+
it("scores and tiers without colliding with Relationship Health names", () => {
|
|
65
|
+
const score = computeCommunityStrengthScore(["attended", "volunteer", "ticket"]);
|
|
66
|
+
expect(score).toBe(12 + 15 + 8);
|
|
67
|
+
expect(communityStrengthTierFromScore(score, 1)).toBe("Regular");
|
|
68
|
+
expect(communityStrengthTierFromScore(80, 1)).toBe("Core");
|
|
69
|
+
});
|
|
70
|
+
it("computes suggested system tags separately from host tags", () => {
|
|
71
|
+
const tags = computeHostCrmSystemTags({
|
|
72
|
+
associatedEventCount: 6,
|
|
73
|
+
eventCount: 3,
|
|
74
|
+
communityStrengthTier: "Core",
|
|
75
|
+
breakdown: {
|
|
76
|
+
...EMPTY_HOST_CRM_ASSOCIATION_BREAKDOWN,
|
|
77
|
+
volunteer: 1,
|
|
78
|
+
vendor: 1,
|
|
79
|
+
},
|
|
80
|
+
tierTitles: ["VIP"],
|
|
81
|
+
hostTags: [],
|
|
82
|
+
attendeeCity: "Denver",
|
|
83
|
+
hostCity: "Denver",
|
|
84
|
+
isStudent: true,
|
|
85
|
+
});
|
|
86
|
+
expect(tags).toEqual(expect.arrayContaining([
|
|
87
|
+
"Super Fan",
|
|
88
|
+
"Frequent Attendee",
|
|
89
|
+
"VIP",
|
|
90
|
+
"Volunteer",
|
|
91
|
+
"Vendor",
|
|
92
|
+
"Local",
|
|
93
|
+
"Student",
|
|
94
|
+
]));
|
|
95
|
+
});
|
|
96
|
+
});
|
|
36
97
|
describe("applyHostCrmSegmentRules", () => {
|
|
37
98
|
it("filters by sourceEventId (trims whitespace)", () => {
|
|
38
99
|
const audience = [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hostCrmSegments.test.js","sourceRoot":"","sources":["../../src/__tests__/hostCrmSegments.test.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,EACxB,wBAAwB,
|
|
1
|
+
{"version":3,"file":"hostCrmSegments.test.js","sourceRoot":"","sources":["../../src/__tests__/hostCrmSegments.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -38,6 +38,72 @@ export type HostCrmSegmentRules = {
|
|
|
38
38
|
sourceEventIdIn?: string[];
|
|
39
39
|
};
|
|
40
40
|
export type HostCrmDiscoverySource = "promoter" | "referral" | "direct";
|
|
41
|
+
/** Edge kinds that connect a person to a host bash (Community Builder associations). */
|
|
42
|
+
export type HostCrmAssociationEdgeType = "ticket" | "rsvp" | "attended" | "feedPost" | "feedComment" | "feedLike" | "volunteer" | "coHost" | "organizer" | "doorStaff" | "serviceProvider" | "vendor" | "artist" | "memoriesUpload" | "review" | "feedRating";
|
|
43
|
+
/** Aggregate counts by association type across the host's bashes. */
|
|
44
|
+
export type HostCrmAssociationBreakdown = {
|
|
45
|
+
tickets: number;
|
|
46
|
+
rsvps: number;
|
|
47
|
+
attended: number;
|
|
48
|
+
feedPosts: number;
|
|
49
|
+
feedComments: number;
|
|
50
|
+
feedLikes: number;
|
|
51
|
+
volunteer: number;
|
|
52
|
+
coHost: number;
|
|
53
|
+
organizer: number;
|
|
54
|
+
doorStaff: number;
|
|
55
|
+
serviceProvider: number;
|
|
56
|
+
vendor: number;
|
|
57
|
+
artist: number;
|
|
58
|
+
memoriesUploads: number;
|
|
59
|
+
reviews: number;
|
|
60
|
+
feedRatings: number;
|
|
61
|
+
};
|
|
62
|
+
export declare const EMPTY_HOST_CRM_ASSOCIATION_BREAKDOWN: HostCrmAssociationBreakdown;
|
|
63
|
+
/**
|
|
64
|
+
* Overall relationship depth with the host's community (not Relationship Health).
|
|
65
|
+
* Intentionally avoids Health's Steady/Cooling vocabulary.
|
|
66
|
+
*/
|
|
67
|
+
export type CommunityStrengthTier = "Casual" | "Regular" | "Strong" | "Core";
|
|
68
|
+
export declare const COMMUNITY_STRENGTH_TIER_LABELS: Record<CommunityStrengthTier, string>;
|
|
69
|
+
/** Tunable weights for communityStrengthScore (sum capped at 100). */
|
|
70
|
+
export declare const COMMUNITY_STRENGTH_EDGE_WEIGHTS: Record<HostCrmAssociationEdgeType, number>;
|
|
71
|
+
export declare function isLightAssociationEdge(type: HostCrmAssociationEdgeType): boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Audience inclusion: ≥1 heavy/medium edge, or ≥3 light edges across ≥2 bashes.
|
|
74
|
+
* HostAttendeeProfile-only rows are handled separately by the audience builder.
|
|
75
|
+
*/
|
|
76
|
+
export declare function meetsAudienceInclusionThreshold(params: {
|
|
77
|
+
heavyMediumEdgeCount: number;
|
|
78
|
+
lightEdgeCount: number;
|
|
79
|
+
lightEdgeBashCount: number;
|
|
80
|
+
}): boolean;
|
|
81
|
+
export declare function computeCommunityStrengthScore(edgeTypes: HostCrmAssociationEdgeType[]): number;
|
|
82
|
+
export declare function communityStrengthTierFromScore(score: number, associatedEventCount: number): CommunityStrengthTier;
|
|
83
|
+
/** Rule-based suggested tags (never merged into host-editable profile tags). */
|
|
84
|
+
export declare function computeHostCrmSystemTags(params: {
|
|
85
|
+
associatedEventCount: number;
|
|
86
|
+
eventCount: number;
|
|
87
|
+
communityStrengthTier: CommunityStrengthTier;
|
|
88
|
+
breakdown: HostCrmAssociationBreakdown;
|
|
89
|
+
tierTitles: string[];
|
|
90
|
+
hostTags: string[];
|
|
91
|
+
attendeeCity: string | null;
|
|
92
|
+
hostCity: string | null;
|
|
93
|
+
isStudent?: boolean;
|
|
94
|
+
}): string[];
|
|
95
|
+
export type HostCrmAssociationEdge = {
|
|
96
|
+
type: HostCrmAssociationEdgeType;
|
|
97
|
+
/** ISO timestamp when known. */
|
|
98
|
+
at: string | null;
|
|
99
|
+
detail?: string;
|
|
100
|
+
};
|
|
101
|
+
export type HostCrmBashAssociations = {
|
|
102
|
+
bashEventId: string;
|
|
103
|
+
title: string;
|
|
104
|
+
startDateTime: string | null;
|
|
105
|
+
edges: HostCrmAssociationEdge[];
|
|
106
|
+
};
|
|
41
107
|
export type HostCrmAudienceMember = {
|
|
42
108
|
userId: string | null;
|
|
43
109
|
email: string | null;
|
|
@@ -56,7 +122,7 @@ export type HostCrmAudienceMember = {
|
|
|
56
122
|
firstAttendedAt: string | null;
|
|
57
123
|
city: string | null;
|
|
58
124
|
tierTitles: string[];
|
|
59
|
-
/** Bash event ids this person attended (for cohort / source filters) */
|
|
125
|
+
/** Bash event ids this person attended via tickets (for cohort / source filters) */
|
|
60
126
|
sourceEventIds?: string[];
|
|
61
127
|
/** True when row is email-only (guest checkout) without a linked user id */
|
|
62
128
|
emailOnly: boolean;
|
|
@@ -80,6 +146,14 @@ export type HostCrmAudienceMember = {
|
|
|
80
146
|
expectedGapDays: number | null;
|
|
81
147
|
/** Predicted next-attendance date (now + expectedGapDays from lastAttendedAt), or null when unknown. */
|
|
82
148
|
nextExpectedAt: string | null;
|
|
149
|
+
/** Distinct bashes with ≥1 meaningful association edge (Community Builder column). */
|
|
150
|
+
associatedEventCount: number;
|
|
151
|
+
associatedEventIds?: string[];
|
|
152
|
+
associationBreakdown: HostCrmAssociationBreakdown;
|
|
153
|
+
communityStrengthScore: number;
|
|
154
|
+
communityStrengthTier: CommunityStrengthTier;
|
|
155
|
+
/** Rule-based suggested tags — never merged into host-editable `tags`. */
|
|
156
|
+
systemTags: string[];
|
|
83
157
|
};
|
|
84
158
|
export declare function applyHostCrmSegmentRules<T extends HostCrmAudienceMember>(audience: T[], rules: HostCrmSegmentRules, now?: Date): T[];
|
|
85
159
|
export declare const HOST_CRM_PRESET_SEGMENTS: Array<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hostCrmSegments.d.ts","sourceRoot":"","sources":["../src/hostCrmSegments.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEzD,OAAO,KAAK,EACV,wBAAwB,EACxB,wBAAwB,EACzB,MAAM,yBAAyB,CAAC;AAEjC,4EAA4E;AAC5E,MAAM,MAAM,mBAAmB,GAAG;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mFAAmF;IACnF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2CAA2C;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qDAAqD;IACrD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,YAAY,CAAC,EAAE,wBAAwB,CAAC;IACxC,kDAAkD;IAClD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,4DAA4D;IAC5D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,0EAA0E;IAC1E,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,6EAA6E;IAC7E,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,8EAA8E;IAC9E,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,6DAA6D;IAC7D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,0FAA0F;IAC1F,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gIAAgI;IAChI,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,UAAU,GAAG,UAAU,GAAG,QAAQ,CAAC;AAExE,MAAM,MAAM,qBAAqB,GAAG;IAClC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,kBAAkB,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAC9C,cAAc,EAAE,OAAO,CAAC;IACxB,YAAY,EAAE,OAAO,CAAC;IACtB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,oGAAoG;IACpG,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,
|
|
1
|
+
{"version":3,"file":"hostCrmSegments.d.ts","sourceRoot":"","sources":["../src/hostCrmSegments.ts"],"names":[],"mappings":"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"}
|
package/dist/hostCrmSegments.js
CHANGED
|
@@ -1,3 +1,115 @@
|
|
|
1
|
+
export const EMPTY_HOST_CRM_ASSOCIATION_BREAKDOWN = {
|
|
2
|
+
tickets: 0,
|
|
3
|
+
rsvps: 0,
|
|
4
|
+
attended: 0,
|
|
5
|
+
feedPosts: 0,
|
|
6
|
+
feedComments: 0,
|
|
7
|
+
feedLikes: 0,
|
|
8
|
+
volunteer: 0,
|
|
9
|
+
coHost: 0,
|
|
10
|
+
organizer: 0,
|
|
11
|
+
doorStaff: 0,
|
|
12
|
+
serviceProvider: 0,
|
|
13
|
+
vendor: 0,
|
|
14
|
+
artist: 0,
|
|
15
|
+
memoriesUploads: 0,
|
|
16
|
+
reviews: 0,
|
|
17
|
+
feedRatings: 0,
|
|
18
|
+
};
|
|
19
|
+
export const COMMUNITY_STRENGTH_TIER_LABELS = {
|
|
20
|
+
Casual: "Casual",
|
|
21
|
+
Regular: "Regular",
|
|
22
|
+
Strong: "Strong",
|
|
23
|
+
Core: "Core",
|
|
24
|
+
};
|
|
25
|
+
/** Tunable weights for communityStrengthScore (sum capped at 100). */
|
|
26
|
+
export const COMMUNITY_STRENGTH_EDGE_WEIGHTS = {
|
|
27
|
+
attended: 12,
|
|
28
|
+
volunteer: 15,
|
|
29
|
+
coHost: 15,
|
|
30
|
+
organizer: 15,
|
|
31
|
+
doorStaff: 12,
|
|
32
|
+
serviceProvider: 15,
|
|
33
|
+
vendor: 15,
|
|
34
|
+
artist: 15,
|
|
35
|
+
ticket: 8,
|
|
36
|
+
rsvp: 6,
|
|
37
|
+
feedPost: 7,
|
|
38
|
+
review: 8,
|
|
39
|
+
feedRating: 6,
|
|
40
|
+
memoriesUpload: 7,
|
|
41
|
+
feedComment: 2,
|
|
42
|
+
feedLike: 1,
|
|
43
|
+
};
|
|
44
|
+
const LIGHT_EDGE_TYPES = new Set([
|
|
45
|
+
"feedComment",
|
|
46
|
+
"feedLike",
|
|
47
|
+
]);
|
|
48
|
+
export function isLightAssociationEdge(type) {
|
|
49
|
+
return LIGHT_EDGE_TYPES.has(type);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Audience inclusion: ≥1 heavy/medium edge, or ≥3 light edges across ≥2 bashes.
|
|
53
|
+
* HostAttendeeProfile-only rows are handled separately by the audience builder.
|
|
54
|
+
*/
|
|
55
|
+
export function meetsAudienceInclusionThreshold(params) {
|
|
56
|
+
if (params.heavyMediumEdgeCount >= 1)
|
|
57
|
+
return true;
|
|
58
|
+
return params.lightEdgeCount >= 3 && params.lightEdgeBashCount >= 2;
|
|
59
|
+
}
|
|
60
|
+
export function computeCommunityStrengthScore(edgeTypes) {
|
|
61
|
+
let score = 0;
|
|
62
|
+
for (const type of edgeTypes) {
|
|
63
|
+
score += COMMUNITY_STRENGTH_EDGE_WEIGHTS[type] ?? 0;
|
|
64
|
+
}
|
|
65
|
+
return Math.min(100, score);
|
|
66
|
+
}
|
|
67
|
+
export function communityStrengthTierFromScore(score, associatedEventCount) {
|
|
68
|
+
if (score >= 75 || associatedEventCount >= 8)
|
|
69
|
+
return "Core";
|
|
70
|
+
if (score >= 50 || associatedEventCount >= 5)
|
|
71
|
+
return "Strong";
|
|
72
|
+
if (score >= 25 || associatedEventCount >= 2)
|
|
73
|
+
return "Regular";
|
|
74
|
+
return "Casual";
|
|
75
|
+
}
|
|
76
|
+
/** Rule-based suggested tags (never merged into host-editable profile tags). */
|
|
77
|
+
export function computeHostCrmSystemTags(params) {
|
|
78
|
+
const tags = [];
|
|
79
|
+
const { breakdown } = params;
|
|
80
|
+
if (params.communityStrengthTier === "Core" || params.associatedEventCount >= 6) {
|
|
81
|
+
tags.push("Super Fan");
|
|
82
|
+
}
|
|
83
|
+
if (params.eventCount >= 3) {
|
|
84
|
+
tags.push("Frequent Attendee");
|
|
85
|
+
}
|
|
86
|
+
const vipTier = params.tierTitles.some((t) => t.trim().toLowerCase() === "vip");
|
|
87
|
+
const vipHostTag = params.hostTags.some((t) => t.trim().toLowerCase() === "vip");
|
|
88
|
+
if (vipTier || vipHostTag) {
|
|
89
|
+
tags.push("VIP");
|
|
90
|
+
}
|
|
91
|
+
if (breakdown.volunteer > 0)
|
|
92
|
+
tags.push("Volunteer");
|
|
93
|
+
if (breakdown.vendor > 0)
|
|
94
|
+
tags.push("Vendor");
|
|
95
|
+
if (breakdown.artist > 0)
|
|
96
|
+
tags.push("Artist");
|
|
97
|
+
if (breakdown.coHost > 0 || breakdown.organizer > 0)
|
|
98
|
+
tags.push("Organizer Friend");
|
|
99
|
+
if (breakdown.serviceProvider > 0)
|
|
100
|
+
tags.push("Service Provider");
|
|
101
|
+
if (breakdown.doorStaff > 0)
|
|
102
|
+
tags.push("Door Staff");
|
|
103
|
+
const hostCity = params.hostCity?.trim().toLowerCase();
|
|
104
|
+
const attendeeCity = params.attendeeCity?.trim().toLowerCase();
|
|
105
|
+
if (hostCity && attendeeCity && attendeeCity.includes(hostCity)) {
|
|
106
|
+
tags.push("Local");
|
|
107
|
+
}
|
|
108
|
+
if (params.isStudent) {
|
|
109
|
+
tags.push("Student");
|
|
110
|
+
}
|
|
111
|
+
return tags;
|
|
112
|
+
}
|
|
1
113
|
export function applyHostCrmSegmentRules(audience, rules, now = new Date()) {
|
|
2
114
|
let rows = audience;
|
|
3
115
|
if (rules.tag?.trim()) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hostCrmSegments.js","sourceRoot":"","sources":["../src/hostCrmSegments.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hostCrmSegments.js","sourceRoot":"","sources":["../src/hostCrmSegments.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/prisma/schema.prisma
CHANGED
|
@@ -1023,6 +1023,7 @@ model BashEvent {
|
|
|
1023
1023
|
sponsorBookingRequests SponsorBookingRequest[] @relation("SponsorBookingEvent")
|
|
1024
1024
|
sponsorships SponsoredEvent[]
|
|
1025
1025
|
tickets Ticket[]
|
|
1026
|
+
hostCrmCommunityPromptDismisses HostCrmCommunityPromptDismiss[]
|
|
1026
1027
|
ticketGiftGrants TicketGiftGrant[]
|
|
1027
1028
|
ticketTiers TicketTier[]
|
|
1028
1029
|
tierReleaseReminders TierReleaseReminder[]
|
|
@@ -2549,6 +2550,20 @@ model HostAttendeeActivity {
|
|
|
2549
2550
|
@@index([hostUserId, attendeeEmail, createdAt])
|
|
2550
2551
|
}
|
|
2551
2552
|
|
|
2553
|
+
/// Host dismissed the post-bash "Build My Community" prompt for this bash.
|
|
2554
|
+
model HostCrmCommunityPromptDismiss {
|
|
2555
|
+
id String @id @default(cuid())
|
|
2556
|
+
hostUserId String
|
|
2557
|
+
bashEventId String
|
|
2558
|
+
dismissedAt DateTime @default(now())
|
|
2559
|
+
|
|
2560
|
+
host User @relation("HostCrmCommunityPromptDismissHost", fields: [hostUserId], references: [id], onDelete: Cascade)
|
|
2561
|
+
bashEvent BashEvent @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
|
|
2562
|
+
|
|
2563
|
+
@@unique([hostUserId, bashEventId])
|
|
2564
|
+
@@index([hostUserId])
|
|
2565
|
+
}
|
|
2566
|
+
|
|
2552
2567
|
/// Host-defined reusable CRM audience filters (tag, cadence, lapsed, cohorts).
|
|
2553
2568
|
model HostCrmSavedSegment {
|
|
2554
2569
|
id String @id @default(cuid())
|
|
@@ -4019,6 +4034,7 @@ model User {
|
|
|
4019
4034
|
hostCrmAutomations HostCrmAutomation[] @relation("HostCrmAutomationsHost")
|
|
4020
4035
|
hostAttendeeActivityAsHost HostAttendeeActivity[] @relation("HostAttendeeActivityHost")
|
|
4021
4036
|
hostAttendeeActivityAsTarget HostAttendeeActivity[] @relation("HostAttendeeActivityAttendee")
|
|
4037
|
+
hostCrmCommunityPromptDismisses HostCrmCommunityPromptDismiss[] @relation("HostCrmCommunityPromptDismissHost")
|
|
4022
4038
|
bashListsCreated BashList[]
|
|
4023
4039
|
userItineraries UserItinerary[]
|
|
4024
4040
|
aiRecommendationLogs AIRecommendationLog[]
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
applyHostCrmSegmentRules,
|
|
3
|
+
communityStrengthTierFromScore,
|
|
4
|
+
computeCommunityStrengthScore,
|
|
5
|
+
computeHostCrmSystemTags,
|
|
6
|
+
EMPTY_HOST_CRM_ASSOCIATION_BREAKDOWN,
|
|
3
7
|
HOST_CRM_PRESET_SEGMENTS,
|
|
8
|
+
meetsAudienceInclusionThreshold,
|
|
4
9
|
type HostCrmAudienceMember,
|
|
5
10
|
} from "../hostCrmSegments.js";
|
|
6
11
|
|
|
@@ -38,10 +43,84 @@ function member(
|
|
|
38
43
|
discoverySource: "direct",
|
|
39
44
|
expectedGapDays: null,
|
|
40
45
|
nextExpectedAt: null,
|
|
46
|
+
associatedEventCount: 1,
|
|
47
|
+
associatedEventIds: ["evt-a"],
|
|
48
|
+
associationBreakdown: { ...EMPTY_HOST_CRM_ASSOCIATION_BREAKDOWN, tickets: 1 },
|
|
49
|
+
communityStrengthScore: 8,
|
|
50
|
+
communityStrengthTier: "Casual",
|
|
51
|
+
systemTags: [],
|
|
41
52
|
...overrides,
|
|
42
53
|
};
|
|
43
54
|
}
|
|
44
55
|
|
|
56
|
+
describe("audience inclusion + community strength helpers", () => {
|
|
57
|
+
it("includes on one heavy/medium edge", () => {
|
|
58
|
+
expect(
|
|
59
|
+
meetsAudienceInclusionThreshold({
|
|
60
|
+
heavyMediumEdgeCount: 1,
|
|
61
|
+
lightEdgeCount: 0,
|
|
62
|
+
lightEdgeBashCount: 0,
|
|
63
|
+
})
|
|
64
|
+
).toBe(true);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("excludes like-only and single-comment", () => {
|
|
68
|
+
expect(
|
|
69
|
+
meetsAudienceInclusionThreshold({
|
|
70
|
+
heavyMediumEdgeCount: 0,
|
|
71
|
+
lightEdgeCount: 1,
|
|
72
|
+
lightEdgeBashCount: 1,
|
|
73
|
+
})
|
|
74
|
+
).toBe(false);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("includes light-only when ≥3 edges across ≥2 bashes", () => {
|
|
78
|
+
expect(
|
|
79
|
+
meetsAudienceInclusionThreshold({
|
|
80
|
+
heavyMediumEdgeCount: 0,
|
|
81
|
+
lightEdgeCount: 3,
|
|
82
|
+
lightEdgeBashCount: 2,
|
|
83
|
+
})
|
|
84
|
+
).toBe(true);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("scores and tiers without colliding with Relationship Health names", () => {
|
|
88
|
+
const score = computeCommunityStrengthScore(["attended", "volunteer", "ticket"]);
|
|
89
|
+
expect(score).toBe(12 + 15 + 8);
|
|
90
|
+
expect(communityStrengthTierFromScore(score, 1)).toBe("Regular");
|
|
91
|
+
expect(communityStrengthTierFromScore(80, 1)).toBe("Core");
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it("computes suggested system tags separately from host tags", () => {
|
|
95
|
+
const tags = computeHostCrmSystemTags({
|
|
96
|
+
associatedEventCount: 6,
|
|
97
|
+
eventCount: 3,
|
|
98
|
+
communityStrengthTier: "Core",
|
|
99
|
+
breakdown: {
|
|
100
|
+
...EMPTY_HOST_CRM_ASSOCIATION_BREAKDOWN,
|
|
101
|
+
volunteer: 1,
|
|
102
|
+
vendor: 1,
|
|
103
|
+
},
|
|
104
|
+
tierTitles: ["VIP"],
|
|
105
|
+
hostTags: [],
|
|
106
|
+
attendeeCity: "Denver",
|
|
107
|
+
hostCity: "Denver",
|
|
108
|
+
isStudent: true,
|
|
109
|
+
});
|
|
110
|
+
expect(tags).toEqual(
|
|
111
|
+
expect.arrayContaining([
|
|
112
|
+
"Super Fan",
|
|
113
|
+
"Frequent Attendee",
|
|
114
|
+
"VIP",
|
|
115
|
+
"Volunteer",
|
|
116
|
+
"Vendor",
|
|
117
|
+
"Local",
|
|
118
|
+
"Student",
|
|
119
|
+
])
|
|
120
|
+
);
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
45
124
|
describe("applyHostCrmSegmentRules", () => {
|
|
46
125
|
it("filters by sourceEventId (trims whitespace)", () => {
|
|
47
126
|
const audience = [
|
package/src/hostCrmSegments.ts
CHANGED
|
@@ -45,6 +45,198 @@ export type HostCrmSegmentRules = {
|
|
|
45
45
|
|
|
46
46
|
export type HostCrmDiscoverySource = "promoter" | "referral" | "direct";
|
|
47
47
|
|
|
48
|
+
/** Edge kinds that connect a person to a host bash (Community Builder associations). */
|
|
49
|
+
export type HostCrmAssociationEdgeType =
|
|
50
|
+
| "ticket"
|
|
51
|
+
| "rsvp"
|
|
52
|
+
| "attended"
|
|
53
|
+
| "feedPost"
|
|
54
|
+
| "feedComment"
|
|
55
|
+
| "feedLike"
|
|
56
|
+
| "volunteer"
|
|
57
|
+
| "coHost"
|
|
58
|
+
| "organizer"
|
|
59
|
+
| "doorStaff"
|
|
60
|
+
| "serviceProvider"
|
|
61
|
+
| "vendor"
|
|
62
|
+
| "artist"
|
|
63
|
+
| "memoriesUpload"
|
|
64
|
+
| "review"
|
|
65
|
+
| "feedRating";
|
|
66
|
+
|
|
67
|
+
/** Aggregate counts by association type across the host's bashes. */
|
|
68
|
+
export type HostCrmAssociationBreakdown = {
|
|
69
|
+
tickets: number;
|
|
70
|
+
rsvps: number;
|
|
71
|
+
attended: number;
|
|
72
|
+
feedPosts: number;
|
|
73
|
+
feedComments: number;
|
|
74
|
+
feedLikes: number;
|
|
75
|
+
volunteer: number;
|
|
76
|
+
coHost: number;
|
|
77
|
+
organizer: number;
|
|
78
|
+
doorStaff: number;
|
|
79
|
+
serviceProvider: number;
|
|
80
|
+
vendor: number;
|
|
81
|
+
artist: number;
|
|
82
|
+
memoriesUploads: number;
|
|
83
|
+
reviews: number;
|
|
84
|
+
feedRatings: number;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export const EMPTY_HOST_CRM_ASSOCIATION_BREAKDOWN: HostCrmAssociationBreakdown = {
|
|
88
|
+
tickets: 0,
|
|
89
|
+
rsvps: 0,
|
|
90
|
+
attended: 0,
|
|
91
|
+
feedPosts: 0,
|
|
92
|
+
feedComments: 0,
|
|
93
|
+
feedLikes: 0,
|
|
94
|
+
volunteer: 0,
|
|
95
|
+
coHost: 0,
|
|
96
|
+
organizer: 0,
|
|
97
|
+
doorStaff: 0,
|
|
98
|
+
serviceProvider: 0,
|
|
99
|
+
vendor: 0,
|
|
100
|
+
artist: 0,
|
|
101
|
+
memoriesUploads: 0,
|
|
102
|
+
reviews: 0,
|
|
103
|
+
feedRatings: 0,
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Overall relationship depth with the host's community (not Relationship Health).
|
|
108
|
+
* Intentionally avoids Health's Steady/Cooling vocabulary.
|
|
109
|
+
*/
|
|
110
|
+
export type CommunityStrengthTier = "Casual" | "Regular" | "Strong" | "Core";
|
|
111
|
+
|
|
112
|
+
export const COMMUNITY_STRENGTH_TIER_LABELS: Record<CommunityStrengthTier, string> = {
|
|
113
|
+
Casual: "Casual",
|
|
114
|
+
Regular: "Regular",
|
|
115
|
+
Strong: "Strong",
|
|
116
|
+
Core: "Core",
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
/** Tunable weights for communityStrengthScore (sum capped at 100). */
|
|
120
|
+
export const COMMUNITY_STRENGTH_EDGE_WEIGHTS: Record<HostCrmAssociationEdgeType, number> = {
|
|
121
|
+
attended: 12,
|
|
122
|
+
volunteer: 15,
|
|
123
|
+
coHost: 15,
|
|
124
|
+
organizer: 15,
|
|
125
|
+
doorStaff: 12,
|
|
126
|
+
serviceProvider: 15,
|
|
127
|
+
vendor: 15,
|
|
128
|
+
artist: 15,
|
|
129
|
+
ticket: 8,
|
|
130
|
+
rsvp: 6,
|
|
131
|
+
feedPost: 7,
|
|
132
|
+
review: 8,
|
|
133
|
+
feedRating: 6,
|
|
134
|
+
memoriesUpload: 7,
|
|
135
|
+
feedComment: 2,
|
|
136
|
+
feedLike: 1,
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
const LIGHT_EDGE_TYPES: ReadonlySet<HostCrmAssociationEdgeType> = new Set([
|
|
140
|
+
"feedComment",
|
|
141
|
+
"feedLike",
|
|
142
|
+
]);
|
|
143
|
+
|
|
144
|
+
export function isLightAssociationEdge(type: HostCrmAssociationEdgeType): boolean {
|
|
145
|
+
return LIGHT_EDGE_TYPES.has(type);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Audience inclusion: ≥1 heavy/medium edge, or ≥3 light edges across ≥2 bashes.
|
|
150
|
+
* HostAttendeeProfile-only rows are handled separately by the audience builder.
|
|
151
|
+
*/
|
|
152
|
+
export function meetsAudienceInclusionThreshold(params: {
|
|
153
|
+
heavyMediumEdgeCount: number;
|
|
154
|
+
lightEdgeCount: number;
|
|
155
|
+
lightEdgeBashCount: number;
|
|
156
|
+
}): boolean {
|
|
157
|
+
if (params.heavyMediumEdgeCount >= 1) return true;
|
|
158
|
+
return params.lightEdgeCount >= 3 && params.lightEdgeBashCount >= 2;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export function computeCommunityStrengthScore(
|
|
162
|
+
edgeTypes: HostCrmAssociationEdgeType[]
|
|
163
|
+
): number {
|
|
164
|
+
let score = 0;
|
|
165
|
+
for (const type of edgeTypes) {
|
|
166
|
+
score += COMMUNITY_STRENGTH_EDGE_WEIGHTS[type] ?? 0;
|
|
167
|
+
}
|
|
168
|
+
return Math.min(100, score);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export function communityStrengthTierFromScore(
|
|
172
|
+
score: number,
|
|
173
|
+
associatedEventCount: number
|
|
174
|
+
): CommunityStrengthTier {
|
|
175
|
+
if (score >= 75 || associatedEventCount >= 8) return "Core";
|
|
176
|
+
if (score >= 50 || associatedEventCount >= 5) return "Strong";
|
|
177
|
+
if (score >= 25 || associatedEventCount >= 2) return "Regular";
|
|
178
|
+
return "Casual";
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/** Rule-based suggested tags (never merged into host-editable profile tags). */
|
|
182
|
+
export function computeHostCrmSystemTags(params: {
|
|
183
|
+
associatedEventCount: number;
|
|
184
|
+
eventCount: number;
|
|
185
|
+
communityStrengthTier: CommunityStrengthTier;
|
|
186
|
+
breakdown: HostCrmAssociationBreakdown;
|
|
187
|
+
tierTitles: string[];
|
|
188
|
+
hostTags: string[];
|
|
189
|
+
attendeeCity: string | null;
|
|
190
|
+
hostCity: string | null;
|
|
191
|
+
isStudent?: boolean;
|
|
192
|
+
}): string[] {
|
|
193
|
+
const tags: string[] = [];
|
|
194
|
+
const { breakdown } = params;
|
|
195
|
+
|
|
196
|
+
if (params.communityStrengthTier === "Core" || params.associatedEventCount >= 6) {
|
|
197
|
+
tags.push("Super Fan");
|
|
198
|
+
}
|
|
199
|
+
if (params.eventCount >= 3) {
|
|
200
|
+
tags.push("Frequent Attendee");
|
|
201
|
+
}
|
|
202
|
+
const vipTier = params.tierTitles.some((t) => t.trim().toLowerCase() === "vip");
|
|
203
|
+
const vipHostTag = params.hostTags.some((t) => t.trim().toLowerCase() === "vip");
|
|
204
|
+
if (vipTier || vipHostTag) {
|
|
205
|
+
tags.push("VIP");
|
|
206
|
+
}
|
|
207
|
+
if (breakdown.volunteer > 0) tags.push("Volunteer");
|
|
208
|
+
if (breakdown.vendor > 0) tags.push("Vendor");
|
|
209
|
+
if (breakdown.artist > 0) tags.push("Artist");
|
|
210
|
+
if (breakdown.coHost > 0 || breakdown.organizer > 0) tags.push("Organizer Friend");
|
|
211
|
+
if (breakdown.serviceProvider > 0) tags.push("Service Provider");
|
|
212
|
+
if (breakdown.doorStaff > 0) tags.push("Door Staff");
|
|
213
|
+
|
|
214
|
+
const hostCity = params.hostCity?.trim().toLowerCase();
|
|
215
|
+
const attendeeCity = params.attendeeCity?.trim().toLowerCase();
|
|
216
|
+
if (hostCity && attendeeCity && attendeeCity.includes(hostCity)) {
|
|
217
|
+
tags.push("Local");
|
|
218
|
+
}
|
|
219
|
+
if (params.isStudent) {
|
|
220
|
+
tags.push("Student");
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return tags;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
export type HostCrmAssociationEdge = {
|
|
227
|
+
type: HostCrmAssociationEdgeType;
|
|
228
|
+
/** ISO timestamp when known. */
|
|
229
|
+
at: string | null;
|
|
230
|
+
detail?: string;
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
export type HostCrmBashAssociations = {
|
|
234
|
+
bashEventId: string;
|
|
235
|
+
title: string;
|
|
236
|
+
startDateTime: string | null;
|
|
237
|
+
edges: HostCrmAssociationEdge[];
|
|
238
|
+
};
|
|
239
|
+
|
|
48
240
|
export type HostCrmAudienceMember = {
|
|
49
241
|
userId: string | null;
|
|
50
242
|
email: string | null;
|
|
@@ -63,7 +255,7 @@ export type HostCrmAudienceMember = {
|
|
|
63
255
|
firstAttendedAt: string | null;
|
|
64
256
|
city: string | null;
|
|
65
257
|
tierTitles: string[];
|
|
66
|
-
/** Bash event ids this person attended (for cohort / source filters) */
|
|
258
|
+
/** Bash event ids this person attended via tickets (for cohort / source filters) */
|
|
67
259
|
sourceEventIds?: string[];
|
|
68
260
|
/** True when row is email-only (guest checkout) without a linked user id */
|
|
69
261
|
emailOnly: boolean;
|
|
@@ -87,6 +279,14 @@ export type HostCrmAudienceMember = {
|
|
|
87
279
|
expectedGapDays: number | null;
|
|
88
280
|
/** Predicted next-attendance date (now + expectedGapDays from lastAttendedAt), or null when unknown. */
|
|
89
281
|
nextExpectedAt: string | null;
|
|
282
|
+
/** Distinct bashes with ≥1 meaningful association edge (Community Builder column). */
|
|
283
|
+
associatedEventCount: number;
|
|
284
|
+
associatedEventIds?: string[];
|
|
285
|
+
associationBreakdown: HostCrmAssociationBreakdown;
|
|
286
|
+
communityStrengthScore: number;
|
|
287
|
+
communityStrengthTier: CommunityStrengthTier;
|
|
288
|
+
/** Rule-based suggested tags — never merged into host-editable `tags`. */
|
|
289
|
+
systemTags: string[];
|
|
90
290
|
};
|
|
91
291
|
|
|
92
292
|
export function applyHostCrmSegmentRules<T extends HostCrmAudienceMember>(
|