@bash-app/bash-common 30.117.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,302 @@
|
|
|
1
|
+
-- ============================================================================
|
|
2
|
+
-- DELTA MIGRATION - January 20, 2026
|
|
3
|
+
-- New columns and tables added since last commit
|
|
4
|
+
-- ============================================================================
|
|
5
|
+
|
|
6
|
+
-- 1. BashFeedPost: Make bashId optional, add serviceId
|
|
7
|
+
-- ============================================================================
|
|
8
|
+
ALTER TABLE "BashFeedPost" ALTER COLUMN "bashId" DROP NOT NULL;
|
|
9
|
+
ALTER TABLE "BashFeedPost" ADD COLUMN IF NOT EXISTS "serviceId" TEXT;
|
|
10
|
+
ALTER TABLE "BashFeedPost" ADD CONSTRAINT "BashFeedPost_serviceId_fkey"
|
|
11
|
+
FOREIGN KEY ("serviceId") REFERENCES "Service"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
12
|
+
CREATE INDEX IF NOT EXISTS "BashFeedPost_serviceId_idx" ON "BashFeedPost"("serviceId");
|
|
13
|
+
|
|
14
|
+
-- 2. BashEvent: Add isAutoApprovable and organization fields
|
|
15
|
+
-- ============================================================================
|
|
16
|
+
ALTER TABLE "BashEvent" ADD COLUMN IF NOT EXISTS "isAutoApprovable" BOOLEAN NOT NULL DEFAULT false;
|
|
17
|
+
ALTER TABLE "BashEvent" ADD COLUMN IF NOT EXISTS "organizationId" TEXT;
|
|
18
|
+
ALTER TABLE "BashEvent" ADD CONSTRAINT "BashEvent_organizationId_fkey"
|
|
19
|
+
FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
20
|
+
CREATE INDEX IF NOT EXISTS "BashEvent_organizationId_idx" ON "BashEvent"("organizationId");
|
|
21
|
+
|
|
22
|
+
-- 3. Service: Add verification and certification fields
|
|
23
|
+
-- ============================================================================
|
|
24
|
+
ALTER TABLE "Service" ADD COLUMN IF NOT EXISTS "isVerified" BOOLEAN NOT NULL DEFAULT false;
|
|
25
|
+
ALTER TABLE "Service" ADD COLUMN IF NOT EXISTS "isLicensed" BOOLEAN NOT NULL DEFAULT false;
|
|
26
|
+
ALTER TABLE "Service" ADD COLUMN IF NOT EXISTS "verifiedAt" TIMESTAMP(3);
|
|
27
|
+
ALTER TABLE "Service" ADD COLUMN IF NOT EXISTS "licenseNumber" TEXT;
|
|
28
|
+
ALTER TABLE "Service" ADD COLUMN IF NOT EXISTS "certifications" TEXT[] DEFAULT ARRAY[]::TEXT[];
|
|
29
|
+
CREATE INDEX IF NOT EXISTS "Service_isVerified_idx" ON "Service"("isVerified");
|
|
30
|
+
CREATE INDEX IF NOT EXISTS "Service_isLicensed_idx" ON "Service"("isLicensed");
|
|
31
|
+
|
|
32
|
+
-- 4. User: Add organization relations (these are handled by Organization tables below)
|
|
33
|
+
-- Note: These are just relation fields in Prisma, no actual columns needed in User table
|
|
34
|
+
|
|
35
|
+
-- 5. Organization: Create complete organization system
|
|
36
|
+
-- ============================================================================
|
|
37
|
+
|
|
38
|
+
-- Create OrganizationType enum if it doesn't exist
|
|
39
|
+
DO $$ BEGIN
|
|
40
|
+
CREATE TYPE "OrganizationType" AS ENUM (
|
|
41
|
+
'Nonprofit',
|
|
42
|
+
'ForProfit',
|
|
43
|
+
'Religious',
|
|
44
|
+
'Educational',
|
|
45
|
+
'Government',
|
|
46
|
+
'Club',
|
|
47
|
+
'Association',
|
|
48
|
+
'Fraternity',
|
|
49
|
+
'Sorority',
|
|
50
|
+
'Union',
|
|
51
|
+
'Cooperative',
|
|
52
|
+
'Other'
|
|
53
|
+
);
|
|
54
|
+
EXCEPTION
|
|
55
|
+
WHEN duplicate_object THEN null;
|
|
56
|
+
END $$;
|
|
57
|
+
|
|
58
|
+
-- Create Organization table
|
|
59
|
+
CREATE TABLE IF NOT EXISTS "Organization" (
|
|
60
|
+
"id" TEXT NOT NULL PRIMARY KEY,
|
|
61
|
+
"name" TEXT NOT NULL,
|
|
62
|
+
"slug" TEXT NOT NULL UNIQUE,
|
|
63
|
+
"organizationType" "OrganizationType"[],
|
|
64
|
+
"bio" TEXT,
|
|
65
|
+
"mission" TEXT,
|
|
66
|
+
"pocName" TEXT,
|
|
67
|
+
"pocEmail" TEXT,
|
|
68
|
+
"pocPhone" TEXT,
|
|
69
|
+
"street" TEXT,
|
|
70
|
+
"city" TEXT,
|
|
71
|
+
"state" TEXT,
|
|
72
|
+
"zipCode" TEXT,
|
|
73
|
+
"country" TEXT DEFAULT 'US',
|
|
74
|
+
"coverPhoto" TEXT,
|
|
75
|
+
"logoUrl" TEXT,
|
|
76
|
+
"websiteUrl" TEXT,
|
|
77
|
+
"socialLinks" JSONB,
|
|
78
|
+
"goodsOrServices" TEXT[],
|
|
79
|
+
"venueTypes" TEXT[],
|
|
80
|
+
"secondaryVenueTypes" TEXT[] DEFAULT ARRAY[]::TEXT[],
|
|
81
|
+
"baseMembershipPriceCents" INTEGER,
|
|
82
|
+
"premiumMembershipPriceCents" INTEGER,
|
|
83
|
+
"allowGuestsByDefault" BOOLEAN DEFAULT false,
|
|
84
|
+
"defaultGuestLimit" INTEGER DEFAULT 0,
|
|
85
|
+
"visibility" TEXT DEFAULT 'Public',
|
|
86
|
+
"requiresApproval" BOOLEAN DEFAULT true,
|
|
87
|
+
"memberAutoApproval" BOOLEAN DEFAULT false,
|
|
88
|
+
"ownerId" TEXT NOT NULL,
|
|
89
|
+
"parentOrganizationId" TEXT,
|
|
90
|
+
"departmentName" TEXT,
|
|
91
|
+
"hierarchyLevel" INTEGER DEFAULT 0,
|
|
92
|
+
"subscriptionTier" TEXT,
|
|
93
|
+
"subscriptionStatus" TEXT,
|
|
94
|
+
"stripeSubscriptionId" TEXT UNIQUE,
|
|
95
|
+
"stripeCustomerId" TEXT,
|
|
96
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
97
|
+
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
98
|
+
CONSTRAINT "Organization_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE,
|
|
99
|
+
CONSTRAINT "Organization_parentOrganizationId_fkey" FOREIGN KEY ("parentOrganizationId") REFERENCES "Organization"("id") ON DELETE SET NULL ON UPDATE CASCADE
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
CREATE INDEX IF NOT EXISTS "Organization_ownerId_idx" ON "Organization"("ownerId");
|
|
103
|
+
CREATE INDEX IF NOT EXISTS "Organization_slug_idx" ON "Organization"("slug");
|
|
104
|
+
CREATE INDEX IF NOT EXISTS "Organization_parentOrganizationId_idx" ON "Organization"("parentOrganizationId");
|
|
105
|
+
|
|
106
|
+
-- Create OrganizationMember table
|
|
107
|
+
CREATE TABLE IF NOT EXISTS "OrganizationMember" (
|
|
108
|
+
"id" TEXT NOT NULL PRIMARY KEY,
|
|
109
|
+
"organizationId" TEXT NOT NULL,
|
|
110
|
+
"userId" TEXT NOT NULL,
|
|
111
|
+
"role" TEXT DEFAULT 'Member',
|
|
112
|
+
"membershipTier" TEXT DEFAULT 'Base',
|
|
113
|
+
"status" TEXT DEFAULT 'Pending',
|
|
114
|
+
"joinedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
115
|
+
"approvedAt" TIMESTAMP(3),
|
|
116
|
+
"approvedBy" TEXT,
|
|
117
|
+
"paidUntil" TIMESTAMP(3),
|
|
118
|
+
"paymentStatus" TEXT DEFAULT 'Current',
|
|
119
|
+
"guestLimit" INTEGER,
|
|
120
|
+
"canInvite" BOOLEAN DEFAULT true,
|
|
121
|
+
"canCreateEvents" BOOLEAN DEFAULT false,
|
|
122
|
+
"canManageBudgets" BOOLEAN DEFAULT false,
|
|
123
|
+
CONSTRAINT "OrganizationMember_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
|
124
|
+
CONSTRAINT "OrganizationMember_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
|
125
|
+
CONSTRAINT "OrganizationMember_organizationId_userId_key" UNIQUE ("organizationId", "userId")
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
CREATE INDEX IF NOT EXISTS "OrganizationMember_organizationId_idx" ON "OrganizationMember"("organizationId");
|
|
129
|
+
CREATE INDEX IF NOT EXISTS "OrganizationMember_userId_idx" ON "OrganizationMember"("userId");
|
|
130
|
+
CREATE INDEX IF NOT EXISTS "OrganizationMember_status_idx" ON "OrganizationMember"("status");
|
|
131
|
+
|
|
132
|
+
-- Create Department table
|
|
133
|
+
CREATE TABLE IF NOT EXISTS "Department" (
|
|
134
|
+
"id" TEXT NOT NULL PRIMARY KEY,
|
|
135
|
+
"organizationId" TEXT NOT NULL,
|
|
136
|
+
"name" TEXT NOT NULL,
|
|
137
|
+
"description" TEXT,
|
|
138
|
+
"parentDeptId" TEXT,
|
|
139
|
+
"headUserId" TEXT,
|
|
140
|
+
"budgetCents" INTEGER,
|
|
141
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
142
|
+
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
143
|
+
CONSTRAINT "Department_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
|
144
|
+
CONSTRAINT "Department_parentDeptId_fkey" FOREIGN KEY ("parentDeptId") REFERENCES "Department"("id") ON DELETE SET NULL ON UPDATE CASCADE,
|
|
145
|
+
CONSTRAINT "Department_headUserId_fkey" FOREIGN KEY ("headUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
CREATE INDEX IF NOT EXISTS "Department_organizationId_idx" ON "Department"("organizationId");
|
|
149
|
+
CREATE INDEX IF NOT EXISTS "Department_parentDeptId_idx" ON "Department"("parentDeptId");
|
|
150
|
+
|
|
151
|
+
-- Create OrganizationEvent table
|
|
152
|
+
CREATE TABLE IF NOT EXISTS "OrganizationEvent" (
|
|
153
|
+
"id" TEXT NOT NULL PRIMARY KEY,
|
|
154
|
+
"organizationId" TEXT NOT NULL,
|
|
155
|
+
"title" TEXT NOT NULL,
|
|
156
|
+
"description" TEXT,
|
|
157
|
+
"eventType" TEXT,
|
|
158
|
+
"startTime" TIMESTAMP(3) NOT NULL,
|
|
159
|
+
"endTime" TIMESTAMP(3),
|
|
160
|
+
"location" TEXT,
|
|
161
|
+
"maxAttendees" INTEGER,
|
|
162
|
+
"requiresRSVP" BOOLEAN DEFAULT true,
|
|
163
|
+
"allowGuests" BOOLEAN DEFAULT false,
|
|
164
|
+
"guestLimit" INTEGER DEFAULT 0,
|
|
165
|
+
"creatorId" TEXT NOT NULL,
|
|
166
|
+
"departmentId" TEXT,
|
|
167
|
+
"isPublic" BOOLEAN DEFAULT false,
|
|
168
|
+
"budgetCents" INTEGER,
|
|
169
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
170
|
+
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
171
|
+
CONSTRAINT "OrganizationEvent_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
|
172
|
+
CONSTRAINT "OrganizationEvent_creatorId_fkey" FOREIGN KEY ("creatorId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE,
|
|
173
|
+
CONSTRAINT "OrganizationEvent_departmentId_fkey" FOREIGN KEY ("departmentId") REFERENCES "Department"("id") ON DELETE SET NULL ON UPDATE CASCADE
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
CREATE INDEX IF NOT EXISTS "OrganizationEvent_organizationId_idx" ON "OrganizationEvent"("organizationId");
|
|
177
|
+
CREATE INDEX IF NOT EXISTS "OrganizationEvent_creatorId_idx" ON "OrganizationEvent"("creatorId");
|
|
178
|
+
CREATE INDEX IF NOT EXISTS "OrganizationEvent_startTime_idx" ON "OrganizationEvent"("startTime");
|
|
179
|
+
|
|
180
|
+
-- Create EventRSVP table
|
|
181
|
+
CREATE TABLE IF NOT EXISTS "EventRSVP" (
|
|
182
|
+
"id" TEXT NOT NULL PRIMARY KEY,
|
|
183
|
+
"eventId" TEXT NOT NULL,
|
|
184
|
+
"memberId" TEXT NOT NULL,
|
|
185
|
+
"userId" TEXT NOT NULL,
|
|
186
|
+
"status" TEXT DEFAULT 'Pending',
|
|
187
|
+
"guestCount" INTEGER DEFAULT 0,
|
|
188
|
+
"respondedAt" TIMESTAMP(3),
|
|
189
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
190
|
+
CONSTRAINT "EventRSVP_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "OrganizationEvent"("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
|
191
|
+
CONSTRAINT "EventRSVP_memberId_fkey" FOREIGN KEY ("memberId") REFERENCES "OrganizationMember"("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
|
192
|
+
CONSTRAINT "EventRSVP_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
|
193
|
+
CONSTRAINT "EventRSVP_eventId_memberId_key" UNIQUE ("eventId", "memberId")
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
CREATE INDEX IF NOT EXISTS "EventRSVP_eventId_idx" ON "EventRSVP"("eventId");
|
|
197
|
+
CREATE INDEX IF NOT EXISTS "EventRSVP_memberId_idx" ON "EventRSVP"("memberId");
|
|
198
|
+
|
|
199
|
+
-- Create OrganizationBudget table
|
|
200
|
+
CREATE TABLE IF NOT EXISTS "OrganizationBudget" (
|
|
201
|
+
"id" TEXT NOT NULL PRIMARY KEY,
|
|
202
|
+
"organizationId" TEXT NOT NULL,
|
|
203
|
+
"name" TEXT NOT NULL,
|
|
204
|
+
"description" TEXT,
|
|
205
|
+
"totalCents" INTEGER NOT NULL,
|
|
206
|
+
"spentCents" INTEGER DEFAULT 0,
|
|
207
|
+
"fiscalYear" INTEGER,
|
|
208
|
+
"startDate" TIMESTAMP(3) NOT NULL,
|
|
209
|
+
"endDate" TIMESTAMP(3) NOT NULL,
|
|
210
|
+
"approvedBy" TEXT,
|
|
211
|
+
"approvedAt" TIMESTAMP(3),
|
|
212
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
213
|
+
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
214
|
+
CONSTRAINT "OrganizationBudget_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
|
215
|
+
CONSTRAINT "OrganizationBudget_approvedBy_fkey" FOREIGN KEY ("approvedBy") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
CREATE INDEX IF NOT EXISTS "OrganizationBudget_organizationId_idx" ON "OrganizationBudget"("organizationId");
|
|
219
|
+
|
|
220
|
+
-- Create BudgetExpense table
|
|
221
|
+
CREATE TABLE IF NOT EXISTS "BudgetExpense" (
|
|
222
|
+
"id" TEXT NOT NULL PRIMARY KEY,
|
|
223
|
+
"budgetId" TEXT NOT NULL,
|
|
224
|
+
"eventId" TEXT,
|
|
225
|
+
"description" TEXT NOT NULL,
|
|
226
|
+
"amountCents" INTEGER NOT NULL,
|
|
227
|
+
"category" TEXT,
|
|
228
|
+
"submittedBy" TEXT NOT NULL,
|
|
229
|
+
"approvedBy" TEXT,
|
|
230
|
+
"approvedAt" TIMESTAMP(3),
|
|
231
|
+
"rejectedAt" TIMESTAMP(3),
|
|
232
|
+
"receiptUrl" TEXT,
|
|
233
|
+
"status" TEXT DEFAULT 'Pending',
|
|
234
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
235
|
+
CONSTRAINT "BudgetExpense_budgetId_fkey" FOREIGN KEY ("budgetId") REFERENCES "OrganizationBudget"("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
|
236
|
+
"eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "OrganizationEvent"("id") ON DELETE SET NULL ON UPDATE CASCADE,
|
|
237
|
+
CONSTRAINT "BudgetExpense_submittedBy_fkey" FOREIGN KEY ("submittedBy") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE,
|
|
238
|
+
CONSTRAINT "BudgetExpense_approvedBy_fkey" FOREIGN KEY ("approvedBy") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE
|
|
239
|
+
);
|
|
240
|
+
|
|
241
|
+
CREATE INDEX IF NOT EXISTS "BudgetExpense_budgetId_idx" ON "BudgetExpense"("budgetId");
|
|
242
|
+
CREATE INDEX IF NOT EXISTS "BudgetExpense_eventId_idx" ON "BudgetExpense"("eventId");
|
|
243
|
+
|
|
244
|
+
-- Create EventProposal table
|
|
245
|
+
CREATE TABLE IF NOT EXISTS "EventProposal" (
|
|
246
|
+
"id" TEXT NOT NULL PRIMARY KEY,
|
|
247
|
+
"organizationId" TEXT NOT NULL,
|
|
248
|
+
"title" TEXT NOT NULL,
|
|
249
|
+
"description" TEXT NOT NULL,
|
|
250
|
+
"proposedDate" TIMESTAMP(3),
|
|
251
|
+
"estimatedBudgetCents" INTEGER,
|
|
252
|
+
"creatorId" TEXT NOT NULL,
|
|
253
|
+
"status" TEXT DEFAULT 'Pending',
|
|
254
|
+
"votingDeadline" TIMESTAMP(3),
|
|
255
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
256
|
+
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
257
|
+
CONSTRAINT "EventProposal_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
|
258
|
+
CONSTRAINT "EventProposal_creatorId_fkey" FOREIGN KEY ("creatorId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
|
259
|
+
);
|
|
260
|
+
|
|
261
|
+
CREATE INDEX IF NOT EXISTS "EventProposal_organizationId_idx" ON "EventProposal"("organizationId");
|
|
262
|
+
CREATE INDEX IF NOT EXISTS "EventProposal_status_idx" ON "EventProposal"("status");
|
|
263
|
+
|
|
264
|
+
-- Create ProposalVote table
|
|
265
|
+
CREATE TABLE IF NOT EXISTS "ProposalVote" (
|
|
266
|
+
"id" TEXT NOT NULL PRIMARY KEY,
|
|
267
|
+
"proposalId" TEXT NOT NULL,
|
|
268
|
+
"voterId" TEXT NOT NULL,
|
|
269
|
+
"vote" TEXT NOT NULL,
|
|
270
|
+
"comment" TEXT,
|
|
271
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
272
|
+
CONSTRAINT "ProposalVote_proposalId_fkey" FOREIGN KEY ("proposalId") REFERENCES "EventProposal"("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
|
273
|
+
CONSTRAINT "ProposalVote_voterId_fkey" FOREIGN KEY ("voterId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
|
274
|
+
CONSTRAINT "ProposalVote_proposalId_voterId_key" UNIQUE ("proposalId", "voterId")
|
|
275
|
+
);
|
|
276
|
+
|
|
277
|
+
CREATE INDEX IF NOT EXISTS "ProposalVote_proposalId_idx" ON "ProposalVote"("proposalId");
|
|
278
|
+
|
|
279
|
+
-- Create _FavoriteOrganizations join table
|
|
280
|
+
CREATE TABLE IF NOT EXISTS "_FavoriteOrganizations" (
|
|
281
|
+
"A" TEXT NOT NULL,
|
|
282
|
+
"B" TEXT NOT NULL,
|
|
283
|
+
CONSTRAINT "_FavoriteOrganizations_A_fkey" FOREIGN KEY ("A") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
|
284
|
+
CONSTRAINT "_FavoriteOrganizations_B_fkey" FOREIGN KEY ("B") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE
|
|
285
|
+
);
|
|
286
|
+
|
|
287
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "_FavoriteOrganizations_AB_unique" ON "_FavoriteOrganizations"("A", "B");
|
|
288
|
+
CREATE INDEX IF NOT EXISTS "_FavoriteOrganizations_B_index" ON "_FavoriteOrganizations"("B");
|
|
289
|
+
|
|
290
|
+
-- ============================================================================
|
|
291
|
+
-- VERIFICATION QUERIES
|
|
292
|
+
-- ============================================================================
|
|
293
|
+
|
|
294
|
+
-- Run these after migration to verify:
|
|
295
|
+
-- SELECT column_name FROM information_schema.columns WHERE table_name = 'BashFeedPost' AND column_name = 'serviceId';
|
|
296
|
+
-- SELECT column_name FROM information_schema.columns WHERE table_name = 'BashEvent' AND column_name = 'isAutoApprovable';
|
|
297
|
+
-- SELECT column_name FROM information_schema.columns WHERE table_name = 'Service' AND column_name = 'isVerified';
|
|
298
|
+
-- SELECT table_name FROM information_schema.tables WHERE table_name = 'Organization';
|
|
299
|
+
|
|
300
|
+
-- ============================================================================
|
|
301
|
+
-- END OF DELTA MIGRATION
|
|
302
|
+
-- ============================================================================
|
package/prisma/schema.prisma
CHANGED
|
@@ -16,6 +16,7 @@ model Club {
|
|
|
16
16
|
events BashEvent[]
|
|
17
17
|
admin ClubAdmin[]
|
|
18
18
|
members ClubMember[]
|
|
19
|
+
budgets Budget[] @relation("ClubBudgets")
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
model ClubAdmin {
|
|
@@ -56,7 +57,8 @@ model BashComment {
|
|
|
56
57
|
model BashFeedPost {
|
|
57
58
|
id String @id @default(cuid())
|
|
58
59
|
userId String
|
|
59
|
-
bashId String
|
|
60
|
+
bashId String?
|
|
61
|
+
serviceId String?
|
|
60
62
|
content String? @db.Text
|
|
61
63
|
mediaIds String[] // Array of Media IDs
|
|
62
64
|
mentionedUserIds String[] // Array of User IDs mentioned in post
|
|
@@ -71,7 +73,8 @@ model BashFeedPost {
|
|
|
71
73
|
|
|
72
74
|
// Relationships
|
|
73
75
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
74
|
-
bash BashEvent
|
|
76
|
+
bash BashEvent? @relation(fields: [bashId], references: [id], onDelete: Cascade)
|
|
77
|
+
service Service? @relation(fields: [serviceId], references: [id], onDelete: Cascade)
|
|
75
78
|
likes BashFeedLike[]
|
|
76
79
|
comments BashFeedComment[]
|
|
77
80
|
ratings BashFeedRating[]
|
|
@@ -80,6 +83,7 @@ model BashFeedPost {
|
|
|
80
83
|
reposts BashFeedRepost[]
|
|
81
84
|
|
|
82
85
|
@@index([bashId])
|
|
86
|
+
@@index([serviceId])
|
|
83
87
|
@@index([userId])
|
|
84
88
|
@@index([createdAt])
|
|
85
89
|
@@index([isAnonymous])
|
|
@@ -338,6 +342,7 @@ model EventTask {
|
|
|
338
342
|
neededCount Int? // Number of volunteers needed
|
|
339
343
|
estimatedDuration Int? // Estimated duration in minutes
|
|
340
344
|
createdAt DateTime? @default(now())
|
|
345
|
+
organizationId String? // Organization association
|
|
341
346
|
assignedTo User? @relation("TasksAssignedToMe", fields: [assignedToId], references: [id], onDelete: Cascade)
|
|
342
347
|
bashEvent BashEvent @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
|
|
343
348
|
creator User @relation(fields: [creatorId], references: [id], onDelete: Cascade)
|
|
@@ -630,6 +635,16 @@ model BashEvent {
|
|
|
630
635
|
autoApprovedAt DateTime?
|
|
631
636
|
lastEngagementAt DateTime? // Track last interest/share for decay
|
|
632
637
|
|
|
638
|
+
// Organization field
|
|
639
|
+
organizationId String?
|
|
640
|
+
organization Organization? @relation("OrganizationBashEvents", fields: [organizationId], references: [id])
|
|
641
|
+
|
|
642
|
+
// Organization access controls (only apply when organizationId is set)
|
|
643
|
+
requiresOrgMembership Boolean @default(false) // Must be member to attend/RSVP
|
|
644
|
+
allowMemberGuests Boolean @default(false) // Members can bring +1s
|
|
645
|
+
maxGuestsPerMember Int? // Guest limit per member (null = unlimited)
|
|
646
|
+
restrictToOrgDepartments String[] @default([]) // Empty = all departments can see/join
|
|
647
|
+
|
|
633
648
|
associatedBashesReferencingMe AssociatedBash[]
|
|
634
649
|
comments BashComment[]
|
|
635
650
|
amountOfGuests AmountOfGuests? @relation(fields: [amountOfGuestsId], references: [id], onDelete: Cascade)
|
|
@@ -689,9 +704,14 @@ model BashEvent {
|
|
|
689
704
|
|
|
690
705
|
// Analytics Relations
|
|
691
706
|
analyticsPredictions AnalyticsPrediction[]
|
|
707
|
+
|
|
708
|
+
// Organization Relations
|
|
709
|
+
budgets Budget[] @relation("EventBudgets")
|
|
710
|
+
rsvps EventRSVP[] @relation("EventRSVPs")
|
|
692
711
|
|
|
693
712
|
@@index([templateId])
|
|
694
713
|
@@index([parentEventId])
|
|
714
|
+
@@index([organizationId])
|
|
695
715
|
}
|
|
696
716
|
|
|
697
717
|
// ============================================
|
|
@@ -924,6 +944,12 @@ model TicketTier {
|
|
|
924
944
|
waitList User[] @relation("TicketTierToUser")
|
|
925
945
|
specialOffers SpecialOffer[] // NEW - Special offers for this tier
|
|
926
946
|
appliedDiscounts AppliedDiscount[] // NEW - Discounts applied to this tier
|
|
947
|
+
|
|
948
|
+
// Organization member restrictions (for org events)
|
|
949
|
+
restrictedToRoles String[] @default([]) // ["Admin", "Owner"] - empty = all roles
|
|
950
|
+
restrictedToDepartments String[] @default([]) // [deptId1, deptId2] - empty = all departments
|
|
951
|
+
restrictedToMembershipTiers String[] @default([]) // ["Premium"] - empty = all membership tiers
|
|
952
|
+
isGuestTier Boolean @default(false) // Ticket for member +1s
|
|
927
953
|
|
|
928
954
|
@@unique([bashEventId, title])
|
|
929
955
|
}
|
|
@@ -1510,6 +1536,18 @@ model User {
|
|
|
1510
1536
|
|
|
1511
1537
|
// Idea Interest Relations
|
|
1512
1538
|
ideaInterests IdeaInterest[]
|
|
1539
|
+
|
|
1540
|
+
// Organization Relations
|
|
1541
|
+
ownedOrganizations Organization[] @relation("OrganizationOwner")
|
|
1542
|
+
organizationMemberships OrganizationMember[] @relation("OrganizationMemberUser")
|
|
1543
|
+
organizationEventRSVPs EventRSVP[] @relation("OrganizationEventRSVP")
|
|
1544
|
+
submittedExpenses Expense[] @relation("ExpenseSubmitter")
|
|
1545
|
+
approvedExpenses Expense[] @relation("ExpenseApprover")
|
|
1546
|
+
approvedBudgets Budget[] @relation("BudgetApprover")
|
|
1547
|
+
submittedBudgets Budget[] @relation("BudgetSubmitter")
|
|
1548
|
+
ownedBudgets Budget[] @relation("UserBudgets")
|
|
1549
|
+
departmentsHeaded Department[] @relation("DepartmentHead")
|
|
1550
|
+
favoriteOrganizations Organization[] @relation("FavoriteOrganizations")
|
|
1513
1551
|
}
|
|
1514
1552
|
|
|
1515
1553
|
model UserPreferences {
|
|
@@ -1952,6 +1990,12 @@ model Service {
|
|
|
1952
1990
|
monthlyPrice Decimal @default(0)
|
|
1953
1991
|
serviceListingStripeSubscriptionId String?
|
|
1954
1992
|
acceptsBashCash Boolean @default(true) // NEW: Allow BashCash payments
|
|
1993
|
+
isVerified Boolean @default(false) // Service owner verified
|
|
1994
|
+
isLicensed Boolean @default(false) // Has required licenses
|
|
1995
|
+
verifiedAt DateTime? // When verification was approved
|
|
1996
|
+
licenseNumber String? // License/registration number
|
|
1997
|
+
certifications String[] @default([]) // Array of certification names
|
|
1998
|
+
bashFeedPosts BashFeedPost[]
|
|
1955
1999
|
associatedServicesReferencingMe AssociatedService[]
|
|
1956
2000
|
exhibitorBookingRequests ExhibitorBookingRequest[] @relation("ExhibitorBookingService")
|
|
1957
2001
|
notification Notification[]
|
|
@@ -1987,6 +2031,8 @@ model Service {
|
|
|
1987
2031
|
|
|
1988
2032
|
@@index([serviceListingStripeSubscriptionId])
|
|
1989
2033
|
@@index([isFreeFirstListing])
|
|
2034
|
+
@@index([isVerified])
|
|
2035
|
+
@@index([isLicensed])
|
|
1990
2036
|
}
|
|
1991
2037
|
|
|
1992
2038
|
model StripeAccount {
|
|
@@ -2318,12 +2364,203 @@ model UserPromoCodeRedemption {
|
|
|
2318
2364
|
}
|
|
2319
2365
|
|
|
2320
2366
|
model Organization {
|
|
2321
|
-
id
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2367
|
+
id String @id @default(cuid())
|
|
2368
|
+
name String
|
|
2369
|
+
slug String @unique
|
|
2370
|
+
organizationType OrganizationType[]
|
|
2371
|
+
bio String?
|
|
2372
|
+
mission String?
|
|
2373
|
+
pocName String?
|
|
2374
|
+
pocEmail String?
|
|
2375
|
+
pocPhone String?
|
|
2376
|
+
street String?
|
|
2377
|
+
city String?
|
|
2378
|
+
state String?
|
|
2379
|
+
zipCode String?
|
|
2380
|
+
country String? @default("US")
|
|
2381
|
+
coverPhoto String?
|
|
2382
|
+
logoUrl String?
|
|
2383
|
+
websiteUrl String?
|
|
2384
|
+
socialLinks Json?
|
|
2385
|
+
goodsOrServices String[]
|
|
2386
|
+
venueTypes String[]
|
|
2387
|
+
secondaryVenueTypes String[] @default([])
|
|
2388
|
+
baseMembershipPriceCents Int?
|
|
2389
|
+
premiumMembershipPriceCents Int?
|
|
2390
|
+
allowGuestsByDefault Boolean @default(false)
|
|
2391
|
+
defaultGuestLimit Int @default(0)
|
|
2392
|
+
visibility String @default("Public")
|
|
2393
|
+
requiresApproval Boolean @default(true)
|
|
2394
|
+
memberAutoApproval Boolean @default(false)
|
|
2395
|
+
ownerId String
|
|
2396
|
+
parentOrganizationId String?
|
|
2397
|
+
departmentName String?
|
|
2398
|
+
hierarchyLevel Int @default(0)
|
|
2399
|
+
subscriptionTier String?
|
|
2400
|
+
subscriptionStatus String?
|
|
2401
|
+
stripeSubscriptionId String? @unique
|
|
2402
|
+
stripeCustomerId String?
|
|
2403
|
+
createdAt DateTime @default(now())
|
|
2404
|
+
updatedAt DateTime @updatedAt
|
|
2405
|
+
service Service?
|
|
2406
|
+
owner User @relation("OrganizationOwner", fields: [ownerId], references: [id], onDelete: Restrict)
|
|
2407
|
+
parentOrganization Organization? @relation("OrganizationHierarchy", fields: [parentOrganizationId], references: [id])
|
|
2408
|
+
childOrganizations Organization[] @relation("OrganizationHierarchy")
|
|
2409
|
+
members OrganizationMember[]
|
|
2410
|
+
budgets Budget[] @relation("OrganizationBudgets")
|
|
2411
|
+
departments Department[]
|
|
2412
|
+
bashEvents BashEvent[] @relation("OrganizationBashEvents")
|
|
2413
|
+
favoriteBy User[] @relation("FavoriteOrganizations")
|
|
2414
|
+
|
|
2415
|
+
@@index([ownerId])
|
|
2416
|
+
@@index([slug])
|
|
2417
|
+
@@index([parentOrganizationId])
|
|
2418
|
+
}
|
|
2419
|
+
|
|
2420
|
+
model OrganizationMember {
|
|
2421
|
+
id String @id @default(cuid())
|
|
2422
|
+
organizationId String
|
|
2423
|
+
userId String
|
|
2424
|
+
role String @default("Member") // Owner, Admin, Coordinator, EventOrganizer, Treasurer, Member
|
|
2425
|
+
membershipTier String @default("Base") // Base, Premium
|
|
2426
|
+
status String @default("Pending") // Pending, Active, Suspended, Removed
|
|
2427
|
+
joinedAt DateTime @default(now())
|
|
2428
|
+
approvedAt DateTime?
|
|
2429
|
+
approvedBy String?
|
|
2430
|
+
paidUntil DateTime?
|
|
2431
|
+
paymentStatus String? @default("Current") // Current, Overdue, Cancelled
|
|
2432
|
+
guestLimit Int?
|
|
2433
|
+
canInvite Boolean @default(true)
|
|
2434
|
+
canCreateEvents Boolean @default(false)
|
|
2435
|
+
canManageBudgets Boolean @default(false)
|
|
2436
|
+
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
2437
|
+
user User @relation("OrganizationMemberUser", fields: [userId], references: [id], onDelete: Cascade)
|
|
2438
|
+
eventRSVPs EventRSVP[]
|
|
2439
|
+
|
|
2440
|
+
@@unique([organizationId, userId])
|
|
2441
|
+
@@index([organizationId])
|
|
2442
|
+
@@index([userId])
|
|
2443
|
+
@@index([status])
|
|
2444
|
+
}
|
|
2445
|
+
|
|
2446
|
+
model Department {
|
|
2447
|
+
id String @id @default(cuid())
|
|
2448
|
+
organizationId String
|
|
2449
|
+
name String
|
|
2450
|
+
description String?
|
|
2451
|
+
parentDeptId String?
|
|
2452
|
+
headUserId String?
|
|
2453
|
+
budgetCents Int?
|
|
2454
|
+
createdAt DateTime @default(now())
|
|
2455
|
+
updatedAt DateTime @updatedAt
|
|
2456
|
+
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
2457
|
+
parentDept Department? @relation("DepartmentHierarchy", fields: [parentDeptId], references: [id])
|
|
2458
|
+
childDepts Department[] @relation("DepartmentHierarchy")
|
|
2459
|
+
head User? @relation("DepartmentHead", fields: [headUserId], references: [id])
|
|
2460
|
+
budgets Budget[] @relation("DepartmentBudgets")
|
|
2461
|
+
|
|
2462
|
+
@@index([organizationId])
|
|
2463
|
+
@@index([parentDeptId])
|
|
2464
|
+
}
|
|
2465
|
+
|
|
2466
|
+
|
|
2467
|
+
model EventRSVP {
|
|
2468
|
+
id String @id @default(cuid())
|
|
2469
|
+
eventId String
|
|
2470
|
+
memberId String
|
|
2471
|
+
userId String
|
|
2472
|
+
status String @default("Going") // Going, Maybe, NotGoing
|
|
2473
|
+
guestsCount Int @default(0)
|
|
2474
|
+
checkedIn Boolean @default(false)
|
|
2475
|
+
checkedInAt DateTime?
|
|
2476
|
+
createdAt DateTime @default(now())
|
|
2477
|
+
updatedAt DateTime @updatedAt
|
|
2478
|
+
event BashEvent @relation("EventRSVPs", fields: [eventId], references: [id], onDelete: Cascade)
|
|
2479
|
+
member OrganizationMember @relation(fields: [memberId], references: [id], onDelete: Cascade)
|
|
2480
|
+
user User @relation("OrganizationEventRSVP", fields: [userId], references: [id])
|
|
2481
|
+
|
|
2482
|
+
@@unique([eventId, userId])
|
|
2483
|
+
@@index([eventId])
|
|
2484
|
+
@@index([userId])
|
|
2485
|
+
}
|
|
2486
|
+
|
|
2487
|
+
model Budget {
|
|
2488
|
+
id String @id @default(cuid())
|
|
2489
|
+
name String
|
|
2490
|
+
|
|
2491
|
+
// Flexible ownership - at least ONE should be set
|
|
2492
|
+
organizationId String?
|
|
2493
|
+
bashEventId String?
|
|
2494
|
+
clubId String?
|
|
2495
|
+
departmentId String?
|
|
2496
|
+
userId String? // For personal event budgets
|
|
2497
|
+
|
|
2498
|
+
// Budget details
|
|
2499
|
+
totalAllocatedCents Int
|
|
2500
|
+
totalBudgetCents Int? // Alias for backward compatibility
|
|
2501
|
+
spentCents Int @default(0)
|
|
2502
|
+
remainingCents Int? // Can be computed: totalAllocatedCents - spentCents
|
|
2503
|
+
|
|
2504
|
+
// Categorization
|
|
2505
|
+
category String? // "Marketing", "Catering", "Venue", "Annual", "Activities"
|
|
2506
|
+
fiscalYear String? // Keep as String for flexibility ("2026", "2026-Q1", "FY2026")
|
|
2507
|
+
|
|
2508
|
+
// Approval workflow
|
|
2509
|
+
status String? @default("Draft") // Draft, Submitted, Approved, Active, Closed, Archived
|
|
2510
|
+
submittedBy String?
|
|
2511
|
+
approverId String?
|
|
2512
|
+
approvedBy String? // Alias for approverId
|
|
2513
|
+
approvedAt DateTime?
|
|
2514
|
+
|
|
2515
|
+
// Date ranges
|
|
2516
|
+
startDate DateTime?
|
|
2517
|
+
endDate DateTime?
|
|
2518
|
+
|
|
2519
|
+
// Timestamps
|
|
2520
|
+
createdAt DateTime @default(now())
|
|
2521
|
+
updatedAt DateTime @updatedAt
|
|
2522
|
+
|
|
2523
|
+
// Relations
|
|
2524
|
+
organization Organization? @relation("OrganizationBudgets", fields: [organizationId], references: [id], onDelete: Cascade)
|
|
2525
|
+
bashEvent BashEvent? @relation("EventBudgets", fields: [bashEventId], references: [id], onDelete: Cascade)
|
|
2526
|
+
club Club? @relation("ClubBudgets", fields: [clubId], references: [id], onDelete: Cascade)
|
|
2527
|
+
department Department? @relation("DepartmentBudgets", fields: [departmentId], references: [id], onDelete: Cascade)
|
|
2528
|
+
user User? @relation("UserBudgets", fields: [userId], references: [id], onDelete: Cascade)
|
|
2529
|
+
submitter User? @relation("BudgetSubmitter", fields: [submittedBy], references: [id])
|
|
2530
|
+
approver User? @relation("BudgetApprover", fields: [approverId], references: [id])
|
|
2531
|
+
expenses Expense[]
|
|
2532
|
+
|
|
2533
|
+
@@index([organizationId])
|
|
2534
|
+
@@index([bashEventId])
|
|
2535
|
+
@@index([clubId])
|
|
2536
|
+
@@index([departmentId])
|
|
2537
|
+
@@index([userId])
|
|
2538
|
+
@@index([status])
|
|
2539
|
+
@@index([fiscalYear])
|
|
2540
|
+
}
|
|
2541
|
+
|
|
2542
|
+
model Expense {
|
|
2543
|
+
id String @id @default(cuid())
|
|
2544
|
+
budgetId String
|
|
2545
|
+
submittedBy String
|
|
2546
|
+
description String
|
|
2547
|
+
amountCents Int
|
|
2548
|
+
category String?
|
|
2549
|
+
receiptUrl String?
|
|
2550
|
+
expenseDate DateTime? // When the expense occurred
|
|
2551
|
+
status String @default("Pending") // Pending, Approved, Rejected
|
|
2552
|
+
approvedBy String?
|
|
2553
|
+
approvedAt DateTime?
|
|
2554
|
+
rejectionReason String?
|
|
2555
|
+
createdAt DateTime @default(now())
|
|
2556
|
+
updatedAt DateTime @updatedAt
|
|
2557
|
+
budget Budget @relation(fields: [budgetId], references: [id], onDelete: Cascade)
|
|
2558
|
+
submitter User @relation("ExpenseSubmitter", fields: [submittedBy], references: [id])
|
|
2559
|
+
approver User? @relation("ExpenseApprover", fields: [approvedBy], references: [id])
|
|
2560
|
+
|
|
2561
|
+
@@index([budgetId])
|
|
2562
|
+
@@index([submittedBy])
|
|
2563
|
+
@@index([status])
|
|
2327
2564
|
}
|
|
2328
2565
|
|
|
2329
2566
|
model ServiceRange {
|
|
@@ -3729,11 +3966,6 @@ enum AudioVisualSupportSubType {
|
|
|
3729
3966
|
ProjectorSetup
|
|
3730
3967
|
}
|
|
3731
3968
|
|
|
3732
|
-
enum HostingSupportSubType {
|
|
3733
|
-
Emcee
|
|
3734
|
-
Greeter
|
|
3735
|
-
}
|
|
3736
|
-
|
|
3737
3969
|
enum PromotionAndMarketingSubType {
|
|
3738
3970
|
Influencer
|
|
3739
3971
|
Promoter
|
|
@@ -3744,6 +3976,10 @@ enum StaffingSubType {
|
|
|
3744
3976
|
CrewHand
|
|
3745
3977
|
ParkingManagement
|
|
3746
3978
|
GuestRegistration
|
|
3979
|
+
Greeter
|
|
3980
|
+
Ushers
|
|
3981
|
+
CoatCheck
|
|
3982
|
+
DoorAttendant
|
|
3747
3983
|
Security
|
|
3748
3984
|
}
|
|
3749
3985
|
|
|
@@ -4781,6 +5017,10 @@ enum OrganizationType {
|
|
|
4781
5017
|
Youth
|
|
4782
5018
|
Senior
|
|
4783
5019
|
Tradeshow
|
|
5020
|
+
Professional
|
|
5021
|
+
RecordLabel
|
|
5022
|
+
School
|
|
5023
|
+
StudentClub
|
|
4784
5024
|
Conference
|
|
4785
5025
|
FoodAndBeverage
|
|
4786
5026
|
TechAndStartups
|