@bash-app/bash-common 30.399.0 → 30.403.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__/audienceImport.test.d.ts +2 -0
- package/dist/__tests__/audienceImport.test.d.ts.map +1 -0
- package/dist/__tests__/audienceImport.test.js +39 -0
- package/dist/__tests__/audienceImport.test.js.map +1 -0
- package/dist/__tests__/eventStaffRoles.test.d.ts +2 -0
- package/dist/__tests__/eventStaffRoles.test.d.ts.map +1 -0
- package/dist/__tests__/eventStaffRoles.test.js +37 -0
- package/dist/__tests__/eventStaffRoles.test.js.map +1 -0
- package/dist/audienceImport.d.ts +71 -0
- package/dist/audienceImport.d.ts.map +1 -0
- package/dist/audienceImport.js +115 -0
- package/dist/audienceImport.js.map +1 -0
- package/dist/eventStaffRoles.d.ts +39 -0
- package/dist/eventStaffRoles.d.ts.map +1 -0
- package/dist/eventStaffRoles.js +125 -0
- package/dist/eventStaffRoles.js.map +1 -0
- package/dist/extendedSchemas.d.ts +2 -0
- package/dist/extendedSchemas.d.ts.map +1 -1
- package/dist/extendedSchemas.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/utils/__tests__/locationVisibility.test.js +27 -1
- package/dist/utils/__tests__/locationVisibility.test.js.map +1 -1
- package/dist/utils/locationVisibility.d.ts +9 -0
- package/dist/utils/locationVisibility.d.ts.map +1 -1
- package/dist/utils/locationVisibility.js +13 -0
- package/dist/utils/locationVisibility.js.map +1 -1
- package/package.json +1 -1
- package/prisma/schema.prisma +102 -0
- package/src/__tests__/audienceImport.test.ts +58 -0
- package/src/__tests__/eventStaffRoles.test.ts +50 -0
- package/src/audienceImport.ts +181 -0
- package/src/eventStaffRoles.ts +168 -0
- package/src/extendedSchemas.ts +2 -0
- package/src/index.ts +2 -0
- package/src/utils/__tests__/locationVisibility.test.ts +38 -0
- package/src/utils/locationVisibility.ts +16 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audienceImport.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/audienceImport.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { compareBashVsPartifulTicketFees, importGuestDedupeKey, isAudienceImportDestination, isAudienceImportSource, mapCsvHeaderToImportField, normalizeImportEmail, normalizeImportPhone, stripeProcessingFeeCents, } from "../audienceImport.js";
|
|
2
|
+
describe("audienceImport", () => {
|
|
3
|
+
it("maps competitor CSV headers", () => {
|
|
4
|
+
expect(mapCsvHeaderToImportField("Attendee Email")).toBe("email");
|
|
5
|
+
expect(mapCsvHeaderToImportField("Ticket Type")).toBe("tierLabel");
|
|
6
|
+
expect(mapCsvHeaderToImportField("unknown col")).toBeUndefined();
|
|
7
|
+
expect(mapCsvHeaderToImportField("source")).toBeUndefined();
|
|
8
|
+
});
|
|
9
|
+
it("normalizes email and phone", () => {
|
|
10
|
+
expect(normalizeImportEmail(" A@B.com ")).toBe("a@b.com");
|
|
11
|
+
expect(normalizeImportEmail("not-an-email")).toBeUndefined();
|
|
12
|
+
expect(normalizeImportPhone("(555) 123-4567")).toBe("5551234567");
|
|
13
|
+
expect(normalizeImportPhone("12")).toBeUndefined();
|
|
14
|
+
});
|
|
15
|
+
it("dedupes by email then phone then external id", () => {
|
|
16
|
+
expect(importGuestDedupeKey({ source: "Eventbrite", email: "A@b.com" })).toBe("email:a@b.com");
|
|
17
|
+
expect(importGuestDedupeKey({ source: "Luma", phone: "5551234567" })).toBe("phone:5551234567");
|
|
18
|
+
expect(importGuestDedupeKey({ source: "Posh", externalId: "ord-1" })).toBe("ext:Posh:ord-1");
|
|
19
|
+
expect(importGuestDedupeKey({ source: "GenericCsv" })).toBeUndefined();
|
|
20
|
+
});
|
|
21
|
+
it("compares Bash vs Partiful with guest-pays primary", () => {
|
|
22
|
+
const result = compareBashVsPartifulTicketFees({
|
|
23
|
+
ticketPriceCents: 10000,
|
|
24
|
+
quantity: 1,
|
|
25
|
+
});
|
|
26
|
+
expect(result.bash.guestPaysCents).toBe(10000);
|
|
27
|
+
expect(result.bash.hostNetsCents).toBe(10000 - stripeProcessingFeeCents(10000));
|
|
28
|
+
expect(result.partiful.guestPaysCents).toBe(11200);
|
|
29
|
+
expect(result.partiful.hostNetsCents).toBe(10000);
|
|
30
|
+
expect(result.citation).toMatch(/June 2026/);
|
|
31
|
+
});
|
|
32
|
+
it("guards source and destination unions", () => {
|
|
33
|
+
expect(isAudienceImportSource("Eventbrite")).toBe(true);
|
|
34
|
+
expect(isAudienceImportSource("Dice")).toBe(false);
|
|
35
|
+
expect(isAudienceImportDestination("crm")).toBe(true);
|
|
36
|
+
expect(isAudienceImportDestination("sms")).toBe(false);
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
//# sourceMappingURL=audienceImport.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audienceImport.test.js","sourceRoot":"","sources":["../../src/__tests__/audienceImport.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eventStaffRoles.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/eventStaffRoles.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { associatedBashCanAccessDoor, associatedBashCanEditEvent, isEventStaffRole, roleFromLegacyFlags, writeThroughAssociatedBashFlags, } from "../eventStaffRoles.js";
|
|
2
|
+
describe("eventStaffRoles", () => {
|
|
3
|
+
it("write-through keeps organizer and door flags in sync", () => {
|
|
4
|
+
expect(writeThroughAssociatedBashFlags("Organizer", true)).toEqual({
|
|
5
|
+
isOrganizer: true,
|
|
6
|
+
isDoorStaff: false,
|
|
7
|
+
isCoHost: true,
|
|
8
|
+
});
|
|
9
|
+
expect(writeThroughAssociatedBashFlags("DoorStaff")).toEqual({
|
|
10
|
+
isOrganizer: false,
|
|
11
|
+
isDoorStaff: true,
|
|
12
|
+
isCoHost: false,
|
|
13
|
+
});
|
|
14
|
+
expect(writeThroughAssociatedBashFlags("Promoter").isOrganizer).toBe(false);
|
|
15
|
+
});
|
|
16
|
+
it("edit access honors role when set, else isOrganizer", () => {
|
|
17
|
+
expect(associatedBashCanEditEvent({ eventRole: "Organizer" })).toBe(true);
|
|
18
|
+
expect(associatedBashCanEditEvent({ eventRole: "DoorStaff" })).toBe(false);
|
|
19
|
+
expect(associatedBashCanEditEvent({ eventRole: "Admin", canEditEvent: false })).toBe(false);
|
|
20
|
+
expect(associatedBashCanEditEvent({ isOrganizer: true })).toBe(true);
|
|
21
|
+
expect(associatedBashCanEditEvent({ isOrganizer: false })).toBe(false);
|
|
22
|
+
});
|
|
23
|
+
it("door access honors role when set, else legacy flags", () => {
|
|
24
|
+
expect(associatedBashCanAccessDoor({ eventRole: "DoorStaff" })).toBe(true);
|
|
25
|
+
expect(associatedBashCanAccessDoor({ eventRole: "Volunteer" })).toBe(false);
|
|
26
|
+
expect(associatedBashCanAccessDoor({ isDoorStaff: true })).toBe(true);
|
|
27
|
+
expect(associatedBashCanAccessDoor({ isOrganizer: true })).toBe(true);
|
|
28
|
+
});
|
|
29
|
+
it("maps legacy flags and validates roles", () => {
|
|
30
|
+
expect(roleFromLegacyFlags({ isDoorStaff: true, isOrganizer: false })).toBe("DoorStaff");
|
|
31
|
+
expect(roleFromLegacyFlags({ isOrganizer: true })).toBe("Organizer");
|
|
32
|
+
expect(roleFromLegacyFlags({})).toBeNull();
|
|
33
|
+
expect(isEventStaffRole("Admin")).toBe(true);
|
|
34
|
+
expect(isEventStaffRole("Owner")).toBe(false);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
//# sourceMappingURL=eventStaffRoles.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eventStaffRoles.test.js","sourceRoot":"","sources":["../../src/__tests__/eventStaffRoles.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Competitor audience import — shared types, CSV header maps, and fee comparison math.
|
|
3
|
+
* Adapters normalize Eventbrite / Luma / Partiful / Posh / generic CSVs into one row shape.
|
|
4
|
+
*/
|
|
5
|
+
export declare const AUDIENCE_IMPORT_SOURCES: readonly ["Eventbrite", "Luma", "Partiful", "Posh", "GenericCsv"];
|
|
6
|
+
export type AudienceImportSource = (typeof AUDIENCE_IMPORT_SOURCES)[number];
|
|
7
|
+
export declare const AUDIENCE_IMPORT_DESTINATIONS: readonly ["admission", "crm", "standingGuestlist"];
|
|
8
|
+
export type AudienceImportDestination = (typeof AUDIENCE_IMPORT_DESTINATIONS)[number];
|
|
9
|
+
export type NormalizedImportGuest = {
|
|
10
|
+
source: AudienceImportSource;
|
|
11
|
+
externalId?: string;
|
|
12
|
+
fullName?: string;
|
|
13
|
+
email?: string;
|
|
14
|
+
phone?: string;
|
|
15
|
+
rsvpOrOrderStatus?: string;
|
|
16
|
+
tierLabel?: string;
|
|
17
|
+
checkedInAt?: string;
|
|
18
|
+
isComp?: boolean;
|
|
19
|
+
plusOnes?: number;
|
|
20
|
+
importedExternalPaid?: boolean;
|
|
21
|
+
};
|
|
22
|
+
export type AudienceImportPreviewRow = NormalizedImportGuest & {
|
|
23
|
+
willImport: boolean;
|
|
24
|
+
skipReason?: string;
|
|
25
|
+
};
|
|
26
|
+
export type AudienceImportCommitResult = {
|
|
27
|
+
added: number;
|
|
28
|
+
skipped: number;
|
|
29
|
+
failed: number;
|
|
30
|
+
failures: Array<{
|
|
31
|
+
email?: string;
|
|
32
|
+
fullName?: string;
|
|
33
|
+
reason: string;
|
|
34
|
+
}>;
|
|
35
|
+
};
|
|
36
|
+
export declare const MAX_IMPORT_ROWS = 5000;
|
|
37
|
+
export declare const IMPORT_BATCH_SIZE = 500;
|
|
38
|
+
/** Partiful's published June 2026 example: guest pays $112 for a $100 organizer price. */
|
|
39
|
+
export declare const PARTIFUL_PUBLISHED_GUEST_MULTIPLIER: number;
|
|
40
|
+
export declare const PARTIFUL_FEE_EXAMPLE_CITATION = "Based on Partiful's published June 2026 example \u2014 their fee varies by event.";
|
|
41
|
+
export type TicketFeeCompareInput = {
|
|
42
|
+
ticketPriceCents: number;
|
|
43
|
+
quantity: number;
|
|
44
|
+
};
|
|
45
|
+
export type TicketFeeCompareSide = {
|
|
46
|
+
guestPaysCents: number;
|
|
47
|
+
hostNetsCents: number;
|
|
48
|
+
};
|
|
49
|
+
export type TicketFeeCompareResult = {
|
|
50
|
+
bash: TicketFeeCompareSide;
|
|
51
|
+
partiful: TicketFeeCompareSide;
|
|
52
|
+
citation: string;
|
|
53
|
+
};
|
|
54
|
+
export declare function stripeProcessingFeeCents(amountCents: number): number;
|
|
55
|
+
/**
|
|
56
|
+
* Guest-pays is the primary comparison. Host-nets is secondary.
|
|
57
|
+
* Bash HostAbsorbs: guest pays listed price; host nets listed minus Stripe.
|
|
58
|
+
* Partiful fee-inclusive: guest pays listed × published multiplier; host receives listed.
|
|
59
|
+
*/
|
|
60
|
+
export declare function compareBashVsPartifulTicketFees(input: TicketFeeCompareInput): TicketFeeCompareResult;
|
|
61
|
+
export declare function normalizeImportEmail(value: string | undefined | null): string | undefined;
|
|
62
|
+
export declare function normalizeImportPhone(value: string | undefined | null): string | undefined;
|
|
63
|
+
export declare function importGuestDedupeKey(guest: NormalizedImportGuest): string | undefined;
|
|
64
|
+
/** CSV columns never overwrite `source` (set by the importer) or `importedExternalPaid`. */
|
|
65
|
+
export type AudienceImportCsvMappedField = Exclude<keyof NormalizedImportGuest, "source" | "importedExternalPaid">;
|
|
66
|
+
/** Competitor + generic CSV headers → NormalizedImportGuest fields. */
|
|
67
|
+
export declare const AUDIENCE_IMPORT_CSV_HEADERS: Record<string, AudienceImportCsvMappedField>;
|
|
68
|
+
export declare function mapCsvHeaderToImportField(header: string): AudienceImportCsvMappedField | undefined;
|
|
69
|
+
export declare function isAudienceImportSource(value: string): value is AudienceImportSource;
|
|
70
|
+
export declare function isAudienceImportDestination(value: string): value is AudienceImportDestination;
|
|
71
|
+
//# sourceMappingURL=audienceImport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audienceImport.d.ts","sourceRoot":"","sources":["../src/audienceImport.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Competitor audience import — shared types, CSV header maps, and fee comparison math.
|
|
3
|
+
* Adapters normalize Eventbrite / Luma / Partiful / Posh / generic CSVs into one row shape.
|
|
4
|
+
*/
|
|
5
|
+
import { calculateStripeProcessingFeeCents } from "./utils/paymentUtils.js";
|
|
6
|
+
export const AUDIENCE_IMPORT_SOURCES = [
|
|
7
|
+
"Eventbrite",
|
|
8
|
+
"Luma",
|
|
9
|
+
"Partiful",
|
|
10
|
+
"Posh",
|
|
11
|
+
"GenericCsv",
|
|
12
|
+
];
|
|
13
|
+
export const AUDIENCE_IMPORT_DESTINATIONS = [
|
|
14
|
+
"admission",
|
|
15
|
+
"crm",
|
|
16
|
+
"standingGuestlist",
|
|
17
|
+
];
|
|
18
|
+
export const MAX_IMPORT_ROWS = 5000;
|
|
19
|
+
export const IMPORT_BATCH_SIZE = 500;
|
|
20
|
+
/** Partiful's published June 2026 example: guest pays $112 for a $100 organizer price. */
|
|
21
|
+
export const PARTIFUL_PUBLISHED_GUEST_MULTIPLIER = 112 / 100;
|
|
22
|
+
export const PARTIFUL_FEE_EXAMPLE_CITATION = "Based on Partiful's published June 2026 example — their fee varies by event.";
|
|
23
|
+
export function stripeProcessingFeeCents(amountCents) {
|
|
24
|
+
return calculateStripeProcessingFeeCents(amountCents);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Guest-pays is the primary comparison. Host-nets is secondary.
|
|
28
|
+
* Bash HostAbsorbs: guest pays listed price; host nets listed minus Stripe.
|
|
29
|
+
* Partiful fee-inclusive: guest pays listed × published multiplier; host receives listed.
|
|
30
|
+
*/
|
|
31
|
+
export function compareBashVsPartifulTicketFees(input) {
|
|
32
|
+
const qty = Math.max(1, Math.floor(input.quantity) || 1);
|
|
33
|
+
const listed = Math.max(0, Math.floor(input.ticketPriceCents)) * qty;
|
|
34
|
+
const bashStripe = stripeProcessingFeeCents(listed);
|
|
35
|
+
const partifulGuest = Math.round(listed * PARTIFUL_PUBLISHED_GUEST_MULTIPLIER);
|
|
36
|
+
return {
|
|
37
|
+
bash: {
|
|
38
|
+
guestPaysCents: listed,
|
|
39
|
+
hostNetsCents: Math.max(0, listed - bashStripe),
|
|
40
|
+
},
|
|
41
|
+
partiful: {
|
|
42
|
+
guestPaysCents: partifulGuest,
|
|
43
|
+
hostNetsCents: listed,
|
|
44
|
+
},
|
|
45
|
+
citation: PARTIFUL_FEE_EXAMPLE_CITATION,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export function normalizeImportEmail(value) {
|
|
49
|
+
const trimmed = value?.trim().toLowerCase();
|
|
50
|
+
return trimmed && trimmed.includes("@") ? trimmed : undefined;
|
|
51
|
+
}
|
|
52
|
+
export function normalizeImportPhone(value) {
|
|
53
|
+
const digits = (value ?? "").replace(/\D/g, "");
|
|
54
|
+
if (digits.length < 7)
|
|
55
|
+
return undefined;
|
|
56
|
+
return digits;
|
|
57
|
+
}
|
|
58
|
+
export function importGuestDedupeKey(guest) {
|
|
59
|
+
const email = normalizeImportEmail(guest.email);
|
|
60
|
+
if (email)
|
|
61
|
+
return `email:${email}`;
|
|
62
|
+
const phone = normalizeImportPhone(guest.phone);
|
|
63
|
+
if (phone)
|
|
64
|
+
return `phone:${phone}`;
|
|
65
|
+
if (guest.externalId?.trim())
|
|
66
|
+
return `ext:${guest.source}:${guest.externalId.trim()}`;
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
/** Competitor + generic CSV headers → NormalizedImportGuest fields. */
|
|
70
|
+
export const AUDIENCE_IMPORT_CSV_HEADERS = {
|
|
71
|
+
"full name": "fullName",
|
|
72
|
+
name: "fullName",
|
|
73
|
+
"attendee name": "fullName",
|
|
74
|
+
"ticket buyer name": "fullName",
|
|
75
|
+
"first name last name": "fullName",
|
|
76
|
+
guest: "fullName",
|
|
77
|
+
"guest name": "fullName",
|
|
78
|
+
"first name": "fullName",
|
|
79
|
+
email: "email",
|
|
80
|
+
"e-mail": "email",
|
|
81
|
+
"email address": "email",
|
|
82
|
+
"attendee email": "email",
|
|
83
|
+
"ticket holder email": "email",
|
|
84
|
+
"buyer email": "email",
|
|
85
|
+
phone: "phone",
|
|
86
|
+
"phone number": "phone",
|
|
87
|
+
mobile: "phone",
|
|
88
|
+
cell: "phone",
|
|
89
|
+
status: "rsvpOrOrderStatus",
|
|
90
|
+
"rsvp status": "rsvpOrOrderStatus",
|
|
91
|
+
"order status": "rsvpOrOrderStatus",
|
|
92
|
+
"approval status": "rsvpOrOrderStatus",
|
|
93
|
+
"ticket type": "tierLabel",
|
|
94
|
+
"ticket class": "tierLabel",
|
|
95
|
+
tier: "tierLabel",
|
|
96
|
+
"order id": "externalId",
|
|
97
|
+
"attendee id": "externalId",
|
|
98
|
+
"guest id": "externalId",
|
|
99
|
+
"checked in": "checkedInAt",
|
|
100
|
+
"checked_in_at": "checkedInAt",
|
|
101
|
+
complimentary: "isComp",
|
|
102
|
+
comp: "isComp",
|
|
103
|
+
"plus ones": "plusOnes",
|
|
104
|
+
"plus ones count": "plusOnes",
|
|
105
|
+
};
|
|
106
|
+
export function mapCsvHeaderToImportField(header) {
|
|
107
|
+
return AUDIENCE_IMPORT_CSV_HEADERS[header.trim().toLowerCase()];
|
|
108
|
+
}
|
|
109
|
+
export function isAudienceImportSource(value) {
|
|
110
|
+
return AUDIENCE_IMPORT_SOURCES.includes(value);
|
|
111
|
+
}
|
|
112
|
+
export function isAudienceImportDestination(value) {
|
|
113
|
+
return AUDIENCE_IMPORT_DESTINATIONS.includes(value);
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=audienceImport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audienceImport.js","sourceRoot":"","sources":["../src/audienceImport.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-event staff role templates. Booleans on AssociatedBash stay the live
|
|
3
|
+
* write-through so existing canUserEditBashEvent / userCanAccessDoor callers
|
|
4
|
+
* keep working during the transition.
|
|
5
|
+
*/
|
|
6
|
+
export declare const EVENT_STAFF_ROLES: readonly ["Admin", "Organizer", "Promoter", "DoorStaff", "ServiceProvider", "Volunteer"];
|
|
7
|
+
export type EventStaffRole = (typeof EVENT_STAFF_ROLES)[number];
|
|
8
|
+
export type EventStaffPermissionKey = "canEditEvent" | "canEditTickets" | "canManageAttendees" | "canIssueComps" | "canAccessDoor" | "canViewFinances" | "canRefund" | "canMessage" | "canManageTrackingLinks";
|
|
9
|
+
export type EventStaffPermissionFlags = Record<EventStaffPermissionKey, boolean>;
|
|
10
|
+
export type EventStaffBooleanWriteThrough = {
|
|
11
|
+
isOrganizer: boolean;
|
|
12
|
+
isDoorStaff: boolean;
|
|
13
|
+
isCoHost: boolean;
|
|
14
|
+
};
|
|
15
|
+
export declare const EVENT_STAFF_TEMPLATE_DEFAULTS: Record<EventStaffRole, EventStaffPermissionFlags>;
|
|
16
|
+
export declare function isEventStaffRole(value: string | null | undefined): value is EventStaffRole;
|
|
17
|
+
/** Setting a role also writes the legacy booleans so existing callers stay valid. */
|
|
18
|
+
export declare function writeThroughAssociatedBashFlags(role: EventStaffRole, isCoHost?: boolean): EventStaffBooleanWriteThrough;
|
|
19
|
+
export declare function resolveEventStaffPermission(role: EventStaffRole | null | undefined, key: EventStaffPermissionKey, override: boolean | null | undefined): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Edit access: honor role+overrides when eventRole is set; otherwise the
|
|
22
|
+
* existing isOrganizer boolean. Never drop the boolean check for legacy rows.
|
|
23
|
+
*/
|
|
24
|
+
export declare function associatedBashCanEditEvent(row: {
|
|
25
|
+
eventRole?: string | null;
|
|
26
|
+
isOrganizer?: boolean | null;
|
|
27
|
+
canEditEvent?: boolean | null;
|
|
28
|
+
}): boolean;
|
|
29
|
+
export declare function associatedBashCanAccessDoor(row: {
|
|
30
|
+
eventRole?: string | null;
|
|
31
|
+
isOrganizer?: boolean | null;
|
|
32
|
+
isDoorStaff?: boolean | null;
|
|
33
|
+
canAccessDoor?: boolean | null;
|
|
34
|
+
}): boolean;
|
|
35
|
+
export declare function roleFromLegacyFlags(row: {
|
|
36
|
+
isOrganizer?: boolean | null;
|
|
37
|
+
isDoorStaff?: boolean | null;
|
|
38
|
+
}): EventStaffRole | null;
|
|
39
|
+
//# sourceMappingURL=eventStaffRoles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eventStaffRoles.d.ts","sourceRoot":"","sources":["../src/eventStaffRoles.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,iBAAiB,0FAOpB,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhE,MAAM,MAAM,uBAAuB,GAC/B,cAAc,GACd,gBAAgB,GAChB,oBAAoB,GACpB,eAAe,GACf,eAAe,GACf,iBAAiB,GACjB,WAAW,GACX,YAAY,GACZ,wBAAwB,CAAC;AAE7B,MAAM,MAAM,yBAAyB,GAAG,MAAM,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC;AAEjF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,eAAO,MAAM,6BAA6B,EAAE,MAAM,CAAC,cAAc,EAAE,yBAAyB,CAmE3F,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,KAAK,IAAI,cAAc,CAE1F;AAED,qFAAqF;AACrF,wBAAgB,+BAA+B,CAC7C,IAAI,EAAE,cAAc,EACpB,QAAQ,UAAQ,GACf,6BAA6B,CAQ/B;AAED,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,cAAc,GAAG,IAAI,GAAG,SAAS,EACvC,GAAG,EAAE,uBAAuB,EAC5B,QAAQ,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,GACnC,OAAO,CAIT;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE;IAC9C,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,YAAY,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAC/B,GAAG,OAAO,CAKV;AAED,wBAAgB,2BAA2B,CAAC,GAAG,EAAE;IAC/C,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,WAAW,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,aAAa,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAChC,GAAG,OAAO,CAKV;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE;IACvC,WAAW,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,WAAW,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAC9B,GAAG,cAAc,GAAG,IAAI,CAIxB"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-event staff role templates. Booleans on AssociatedBash stay the live
|
|
3
|
+
* write-through so existing canUserEditBashEvent / userCanAccessDoor callers
|
|
4
|
+
* keep working during the transition.
|
|
5
|
+
*/
|
|
6
|
+
export const EVENT_STAFF_ROLES = [
|
|
7
|
+
"Admin",
|
|
8
|
+
"Organizer",
|
|
9
|
+
"Promoter",
|
|
10
|
+
"DoorStaff",
|
|
11
|
+
"ServiceProvider",
|
|
12
|
+
"Volunteer",
|
|
13
|
+
];
|
|
14
|
+
export const EVENT_STAFF_TEMPLATE_DEFAULTS = {
|
|
15
|
+
Admin: {
|
|
16
|
+
canEditEvent: true,
|
|
17
|
+
canEditTickets: true,
|
|
18
|
+
canManageAttendees: true,
|
|
19
|
+
canIssueComps: true,
|
|
20
|
+
canAccessDoor: true,
|
|
21
|
+
canViewFinances: true,
|
|
22
|
+
canRefund: true,
|
|
23
|
+
canMessage: true,
|
|
24
|
+
canManageTrackingLinks: true,
|
|
25
|
+
},
|
|
26
|
+
Organizer: {
|
|
27
|
+
canEditEvent: true,
|
|
28
|
+
canEditTickets: true,
|
|
29
|
+
canManageAttendees: true,
|
|
30
|
+
canIssueComps: true,
|
|
31
|
+
canAccessDoor: true,
|
|
32
|
+
canViewFinances: false,
|
|
33
|
+
canRefund: false,
|
|
34
|
+
canMessage: true,
|
|
35
|
+
canManageTrackingLinks: true,
|
|
36
|
+
},
|
|
37
|
+
Promoter: {
|
|
38
|
+
canEditEvent: false,
|
|
39
|
+
canEditTickets: false,
|
|
40
|
+
canManageAttendees: false,
|
|
41
|
+
canIssueComps: true,
|
|
42
|
+
canAccessDoor: false,
|
|
43
|
+
canViewFinances: false,
|
|
44
|
+
canRefund: false,
|
|
45
|
+
canMessage: false,
|
|
46
|
+
canManageTrackingLinks: true,
|
|
47
|
+
},
|
|
48
|
+
DoorStaff: {
|
|
49
|
+
canEditEvent: false,
|
|
50
|
+
canEditTickets: false,
|
|
51
|
+
canManageAttendees: true,
|
|
52
|
+
canIssueComps: true,
|
|
53
|
+
canAccessDoor: true,
|
|
54
|
+
canViewFinances: false,
|
|
55
|
+
canRefund: false,
|
|
56
|
+
canMessage: false,
|
|
57
|
+
canManageTrackingLinks: false,
|
|
58
|
+
},
|
|
59
|
+
ServiceProvider: {
|
|
60
|
+
canEditEvent: false,
|
|
61
|
+
canEditTickets: false,
|
|
62
|
+
canManageAttendees: false,
|
|
63
|
+
canIssueComps: false,
|
|
64
|
+
canAccessDoor: false,
|
|
65
|
+
canViewFinances: false,
|
|
66
|
+
canRefund: false,
|
|
67
|
+
canMessage: false,
|
|
68
|
+
canManageTrackingLinks: false,
|
|
69
|
+
},
|
|
70
|
+
Volunteer: {
|
|
71
|
+
canEditEvent: false,
|
|
72
|
+
canEditTickets: false,
|
|
73
|
+
canManageAttendees: false,
|
|
74
|
+
canIssueComps: false,
|
|
75
|
+
canAccessDoor: false,
|
|
76
|
+
canViewFinances: false,
|
|
77
|
+
canRefund: false,
|
|
78
|
+
canMessage: false,
|
|
79
|
+
canManageTrackingLinks: false,
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
export function isEventStaffRole(value) {
|
|
83
|
+
return !!value && EVENT_STAFF_ROLES.includes(value);
|
|
84
|
+
}
|
|
85
|
+
/** Setting a role also writes the legacy booleans so existing callers stay valid. */
|
|
86
|
+
export function writeThroughAssociatedBashFlags(role, isCoHost = false) {
|
|
87
|
+
if (role === "Admin" || role === "Organizer") {
|
|
88
|
+
return { isOrganizer: true, isDoorStaff: false, isCoHost };
|
|
89
|
+
}
|
|
90
|
+
if (role === "DoorStaff") {
|
|
91
|
+
return { isOrganizer: false, isDoorStaff: true, isCoHost: false };
|
|
92
|
+
}
|
|
93
|
+
return { isOrganizer: false, isDoorStaff: false, isCoHost: false };
|
|
94
|
+
}
|
|
95
|
+
export function resolveEventStaffPermission(role, key, override) {
|
|
96
|
+
if (typeof override === "boolean")
|
|
97
|
+
return override;
|
|
98
|
+
if (!isEventStaffRole(role))
|
|
99
|
+
return false;
|
|
100
|
+
return EVENT_STAFF_TEMPLATE_DEFAULTS[role][key];
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Edit access: honor role+overrides when eventRole is set; otherwise the
|
|
104
|
+
* existing isOrganizer boolean. Never drop the boolean check for legacy rows.
|
|
105
|
+
*/
|
|
106
|
+
export function associatedBashCanEditEvent(row) {
|
|
107
|
+
if (isEventStaffRole(row.eventRole)) {
|
|
108
|
+
return resolveEventStaffPermission(row.eventRole, "canEditEvent", row.canEditEvent);
|
|
109
|
+
}
|
|
110
|
+
return !!row.isOrganizer;
|
|
111
|
+
}
|
|
112
|
+
export function associatedBashCanAccessDoor(row) {
|
|
113
|
+
if (isEventStaffRole(row.eventRole)) {
|
|
114
|
+
return resolveEventStaffPermission(row.eventRole, "canAccessDoor", row.canAccessDoor);
|
|
115
|
+
}
|
|
116
|
+
return Boolean(row.isOrganizer || row.isDoorStaff);
|
|
117
|
+
}
|
|
118
|
+
export function roleFromLegacyFlags(row) {
|
|
119
|
+
if (row.isDoorStaff && !row.isOrganizer)
|
|
120
|
+
return "DoorStaff";
|
|
121
|
+
if (row.isOrganizer)
|
|
122
|
+
return "Organizer";
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=eventStaffRoles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eventStaffRoles.js","sourceRoot":"","sources":["../src/eventStaffRoles.ts"],"names":[],"mappings":"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"}
|
|
@@ -4364,6 +4364,8 @@ export interface InvitationExtraData extends Invitation {
|
|
|
4364
4364
|
isFreeGuest: boolean;
|
|
4365
4365
|
isOrganizer?: boolean;
|
|
4366
4366
|
isCoHost?: boolean;
|
|
4367
|
+
isDoorStaff?: boolean;
|
|
4368
|
+
eventRole?: string;
|
|
4367
4369
|
organizerTitle?: string;
|
|
4368
4370
|
isOwnershipTransfer?: boolean;
|
|
4369
4371
|
includeQRCode?: boolean;
|