@happyvertical/smrt-events 0.30.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/AGENTS.md +20 -0
- package/CLAUDE.md +1 -0
- package/LICENSE +7 -0
- package/README.md +151 -0
- package/dist/__smrt-register__.d.ts +2 -0
- package/dist/__smrt-register__.d.ts.map +1 -0
- package/dist/collections/EventAssetCollection.d.ts +16 -0
- package/dist/collections/EventAssetCollection.d.ts.map +1 -0
- package/dist/collections/EventCollection.d.ts +108 -0
- package/dist/collections/EventCollection.d.ts.map +1 -0
- package/dist/collections/EventParticipantCollection.d.ts +42 -0
- package/dist/collections/EventParticipantCollection.d.ts.map +1 -0
- package/dist/collections/EventSeriesCollection.d.ts +62 -0
- package/dist/collections/EventSeriesCollection.d.ts.map +1 -0
- package/dist/collections/EventTypeCollection.d.ts +53 -0
- package/dist/collections/EventTypeCollection.d.ts.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1419 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest.json +4067 -0
- package/dist/models/Event.d.ts +92 -0
- package/dist/models/Event.d.ts.map +1 -0
- package/dist/models/EventAsset.d.ts +17 -0
- package/dist/models/EventAsset.d.ts.map +1 -0
- package/dist/models/EventParticipant.d.ts +65 -0
- package/dist/models/EventParticipant.d.ts.map +1 -0
- package/dist/models/EventSeries.d.ts +73 -0
- package/dist/models/EventSeries.d.ts.map +1 -0
- package/dist/models/EventType.d.ts +44 -0
- package/dist/models/EventType.d.ts.map +1 -0
- package/dist/playground.d.ts +2 -0
- package/dist/playground.d.ts.map +1 -0
- package/dist/playground.js +47 -0
- package/dist/playground.js.map +1 -0
- package/dist/smrt-knowledge.json +1662 -0
- package/dist/svelte/components/MeetingView.svelte +321 -0
- package/dist/svelte/components/MeetingView.svelte.d.ts +9 -0
- package/dist/svelte/components/MeetingView.svelte.d.ts.map +1 -0
- package/dist/svelte/i18n.d.ts +10 -0
- package/dist/svelte/i18n.d.ts.map +1 -0
- package/dist/svelte/i18n.js +11 -0
- package/dist/svelte/index.d.ts +11 -0
- package/dist/svelte/index.d.ts.map +1 -0
- package/dist/svelte/index.js +18 -0
- package/dist/svelte/playground.d.ts +40 -0
- package/dist/svelte/playground.d.ts.map +1 -0
- package/dist/svelte/playground.js +43 -0
- package/dist/svelte/types.d.ts +37 -0
- package/dist/svelte/types.d.ts.map +1 -0
- package/dist/svelte/types.js +6 -0
- package/dist/types.d.ts +127 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/ui.d.ts +10 -0
- package/dist/ui.d.ts.map +1 -0
- package/dist/ui.js +28 -0
- package/dist/ui.js.map +1 -0
- package/dist/utils.d.ts +93 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +127 -0
- package/dist/utils.js.map +1 -0
- package/package.json +102 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1419 @@
|
|
|
1
|
+
import { ObjectRegistry, foreignKey, crossPackageRef, field, smrt, SmrtObject, SmrtJunction, SmrtHierarchical, SmrtCollection } from "@happyvertical/smrt-core";
|
|
2
|
+
import { getOwnedAssetsFromCollection, addOwnedAssetFromCollection, removeOwnedAssetFromCollection, resolveOwnedAssetsById, assertValidOwnedAssetRelationship, assertValidOwnedAssetSortOrder } from "@happyvertical/smrt-assets";
|
|
3
|
+
import { tenantId, TenantScoped } from "@happyvertical/smrt-tenancy";
|
|
4
|
+
import { EVENTS_MODULE_META, EVENTS_UI_SLOTS } from "./ui.js";
|
|
5
|
+
import { calculateDuration, calculateNextOccurrence, checkSchedulingConflict, formatDuration, formatEventDateRange, generateEventSlug, getEventStatusFromDates, isEventNow, parseRecurrencePattern, sortEventsByDate, validateEventStatus } from "./utils.js";
|
|
6
|
+
ObjectRegistry.registerPackageManifest(
|
|
7
|
+
new URL("./manifest.json", import.meta.url)
|
|
8
|
+
);
|
|
9
|
+
var __defProp$6 = Object.defineProperty;
|
|
10
|
+
var __getOwnPropDesc$6 = Object.getOwnPropertyDescriptor;
|
|
11
|
+
var __decorateClass$6 = (decorators, target, key, kind) => {
|
|
12
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$6(target, key) : target;
|
|
13
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
14
|
+
if (decorator = decorators[i])
|
|
15
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
16
|
+
if (kind && result) __defProp$6(target, key, result);
|
|
17
|
+
return result;
|
|
18
|
+
};
|
|
19
|
+
let EventAsset = class extends SmrtObject {
|
|
20
|
+
tenantId = null;
|
|
21
|
+
eventId = "";
|
|
22
|
+
assetId = "";
|
|
23
|
+
relationship = "attachment";
|
|
24
|
+
sortOrder = 0;
|
|
25
|
+
constructor(options = {}) {
|
|
26
|
+
super(options);
|
|
27
|
+
if (options.eventId) this.eventId = options.eventId;
|
|
28
|
+
if (options.assetId) this.assetId = options.assetId;
|
|
29
|
+
if (options.relationship) this.relationship = options.relationship;
|
|
30
|
+
if (options.sortOrder !== void 0) this.sortOrder = options.sortOrder;
|
|
31
|
+
if (options.tenantId !== void 0) this.tenantId = options.tenantId;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
__decorateClass$6([
|
|
35
|
+
tenantId({ nullable: true })
|
|
36
|
+
], EventAsset.prototype, "tenantId", 2);
|
|
37
|
+
__decorateClass$6([
|
|
38
|
+
foreignKey("Event", { required: true })
|
|
39
|
+
], EventAsset.prototype, "eventId", 2);
|
|
40
|
+
__decorateClass$6([
|
|
41
|
+
crossPackageRef("@happyvertical/smrt-assets:Asset", { required: true })
|
|
42
|
+
], EventAsset.prototype, "assetId", 2);
|
|
43
|
+
__decorateClass$6([
|
|
44
|
+
field({ required: true })
|
|
45
|
+
], EventAsset.prototype, "relationship", 2);
|
|
46
|
+
__decorateClass$6([
|
|
47
|
+
field()
|
|
48
|
+
], EventAsset.prototype, "sortOrder", 2);
|
|
49
|
+
EventAsset = __decorateClass$6([
|
|
50
|
+
TenantScoped({ mode: "optional" }),
|
|
51
|
+
smrt({
|
|
52
|
+
tableName: "event_assets",
|
|
53
|
+
conflictColumns: ["event_id", "asset_id", "relationship"],
|
|
54
|
+
api: false,
|
|
55
|
+
mcp: false,
|
|
56
|
+
cli: false
|
|
57
|
+
})
|
|
58
|
+
], EventAsset);
|
|
59
|
+
var __defProp$5 = Object.defineProperty;
|
|
60
|
+
var __getOwnPropDesc$5 = Object.getOwnPropertyDescriptor;
|
|
61
|
+
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
62
|
+
var __decorateClass$5 = (decorators, target, key, kind) => {
|
|
63
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$5(target, key) : target;
|
|
64
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
65
|
+
if (decorator = decorators[i])
|
|
66
|
+
result = decorator(result) || result;
|
|
67
|
+
return result;
|
|
68
|
+
};
|
|
69
|
+
var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, key + "", value);
|
|
70
|
+
let EventAssetCollection = class extends SmrtJunction {
|
|
71
|
+
leftField = "eventId";
|
|
72
|
+
rightField = "assetId";
|
|
73
|
+
eventCollectionPromise = null;
|
|
74
|
+
async getEventCollection() {
|
|
75
|
+
if (!this.eventCollectionPromise) {
|
|
76
|
+
const { EventCollection: EventCollection2 } = await Promise.resolve().then(() => EventCollection$1);
|
|
77
|
+
this.eventCollectionPromise = EventCollection2.create({ db: this.db });
|
|
78
|
+
}
|
|
79
|
+
return this.eventCollectionPromise;
|
|
80
|
+
}
|
|
81
|
+
async getAssets(eventId, relationship) {
|
|
82
|
+
return getOwnedAssetsFromCollection(
|
|
83
|
+
await this.getEventCollection(),
|
|
84
|
+
eventId,
|
|
85
|
+
relationship
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
async addAsset(eventId, asset, relationship = "attachment", sortOrder = 0) {
|
|
89
|
+
await addOwnedAssetFromCollection(
|
|
90
|
+
await this.getEventCollection(),
|
|
91
|
+
"Event",
|
|
92
|
+
eventId,
|
|
93
|
+
asset,
|
|
94
|
+
relationship,
|
|
95
|
+
sortOrder
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
async removeAsset(eventId, assetId, relationship) {
|
|
99
|
+
await removeOwnedAssetFromCollection(
|
|
100
|
+
await this.getEventCollection(),
|
|
101
|
+
"Event",
|
|
102
|
+
eventId,
|
|
103
|
+
assetId,
|
|
104
|
+
relationship
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
__publicField$1(EventAssetCollection, "_itemClass", EventAsset);
|
|
109
|
+
EventAssetCollection = __decorateClass$5([
|
|
110
|
+
smrt({
|
|
111
|
+
api: false,
|
|
112
|
+
mcp: false,
|
|
113
|
+
cli: false
|
|
114
|
+
})
|
|
115
|
+
], EventAssetCollection);
|
|
116
|
+
const EventAssetCollection$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
117
|
+
__proto__: null,
|
|
118
|
+
get EventAssetCollection() {
|
|
119
|
+
return EventAssetCollection;
|
|
120
|
+
}
|
|
121
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
122
|
+
var __defProp$4 = Object.defineProperty;
|
|
123
|
+
var __getOwnPropDesc$4 = Object.getOwnPropertyDescriptor;
|
|
124
|
+
var __decorateClass$4 = (decorators, target, key, kind) => {
|
|
125
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$4(target, key) : target;
|
|
126
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
127
|
+
if (decorator = decorators[i])
|
|
128
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
129
|
+
if (kind && result) __defProp$4(target, key, result);
|
|
130
|
+
return result;
|
|
131
|
+
};
|
|
132
|
+
let Event = class extends SmrtHierarchical {
|
|
133
|
+
tenantId = null;
|
|
134
|
+
name = "";
|
|
135
|
+
seriesId = "";
|
|
136
|
+
typeId = "";
|
|
137
|
+
placeId = "";
|
|
138
|
+
// FK to Place (from @happyvertical/smrt-places)
|
|
139
|
+
description = "";
|
|
140
|
+
startDate = null;
|
|
141
|
+
endDate = null;
|
|
142
|
+
status = "scheduled";
|
|
143
|
+
round = null;
|
|
144
|
+
// Sequence/round number in series
|
|
145
|
+
metadata = "";
|
|
146
|
+
// JSON metadata (stored as text)
|
|
147
|
+
externalId = "";
|
|
148
|
+
// External system identifier
|
|
149
|
+
source = "";
|
|
150
|
+
// Source system
|
|
151
|
+
// Timestamps
|
|
152
|
+
createdAt = /* @__PURE__ */ new Date();
|
|
153
|
+
updatedAt = /* @__PURE__ */ new Date();
|
|
154
|
+
constructor(options = {}) {
|
|
155
|
+
super(options);
|
|
156
|
+
if (options.seriesId !== void 0) this.seriesId = options.seriesId;
|
|
157
|
+
if (options.parentId !== void 0)
|
|
158
|
+
this.parentId = options.parentId ?? null;
|
|
159
|
+
if (options.typeId) this.typeId = options.typeId;
|
|
160
|
+
if (options.placeId !== void 0) this.placeId = options.placeId;
|
|
161
|
+
if (options.description !== void 0)
|
|
162
|
+
this.description = options.description;
|
|
163
|
+
if (options.startDate !== void 0)
|
|
164
|
+
this.startDate = options.startDate || null;
|
|
165
|
+
if (options.endDate !== void 0) this.endDate = options.endDate || null;
|
|
166
|
+
if (options.status !== void 0) this.status = options.status;
|
|
167
|
+
if (options.round !== void 0) this.round = options.round;
|
|
168
|
+
if (options.externalId !== void 0) this.externalId = options.externalId;
|
|
169
|
+
if (options.source !== void 0) this.source = options.source;
|
|
170
|
+
if (options.metadata !== void 0) {
|
|
171
|
+
if (typeof options.metadata === "string") {
|
|
172
|
+
this.metadata = options.metadata;
|
|
173
|
+
} else {
|
|
174
|
+
this.metadata = JSON.stringify(options.metadata);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
if (options.createdAt) this.createdAt = options.createdAt;
|
|
178
|
+
if (options.updatedAt) this.updatedAt = options.updatedAt;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Get metadata as parsed object
|
|
182
|
+
*
|
|
183
|
+
* @returns Parsed metadata object or empty object
|
|
184
|
+
*/
|
|
185
|
+
getMetadata() {
|
|
186
|
+
if (!this.metadata) return {};
|
|
187
|
+
try {
|
|
188
|
+
return JSON.parse(this.metadata);
|
|
189
|
+
} catch {
|
|
190
|
+
return {};
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Set metadata from object
|
|
195
|
+
*
|
|
196
|
+
* @param data - Metadata object to store
|
|
197
|
+
*/
|
|
198
|
+
setMetadata(data) {
|
|
199
|
+
this.metadata = JSON.stringify(data);
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Update metadata by merging with existing values
|
|
203
|
+
*
|
|
204
|
+
* @param updates - Partial metadata to merge
|
|
205
|
+
*/
|
|
206
|
+
updateMetadata(updates) {
|
|
207
|
+
const current = this.getMetadata();
|
|
208
|
+
this.setMetadata({ ...current, ...updates });
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Update event status
|
|
212
|
+
*
|
|
213
|
+
* @param newStatus - New status to set
|
|
214
|
+
*/
|
|
215
|
+
async updateStatus(newStatus) {
|
|
216
|
+
this.status = newStatus;
|
|
217
|
+
this.updatedAt = /* @__PURE__ */ new Date();
|
|
218
|
+
await this.save();
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Get the series for this event
|
|
222
|
+
*
|
|
223
|
+
* @returns EventSeries instance or null
|
|
224
|
+
*/
|
|
225
|
+
async getSeries() {
|
|
226
|
+
if (!this.seriesId) return null;
|
|
227
|
+
const { EventSeriesCollection: EventSeriesCollection2 } = await Promise.resolve().then(() => EventSeriesCollection$1);
|
|
228
|
+
const collection = await EventSeriesCollection2.create(
|
|
229
|
+
this.options
|
|
230
|
+
);
|
|
231
|
+
return await collection.get({ id: this.seriesId });
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Get the event type
|
|
235
|
+
*
|
|
236
|
+
* @returns EventType instance or null
|
|
237
|
+
*/
|
|
238
|
+
async getType() {
|
|
239
|
+
if (!this.typeId) return null;
|
|
240
|
+
const { EventTypeCollection: EventTypeCollection2 } = await Promise.resolve().then(() => EventTypeCollection$1);
|
|
241
|
+
const collection = await EventTypeCollection2.create(this.options);
|
|
242
|
+
return await collection.get({ id: this.typeId });
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Get the place for this event
|
|
246
|
+
*
|
|
247
|
+
* @returns Place instance or null
|
|
248
|
+
*/
|
|
249
|
+
async getPlace() {
|
|
250
|
+
if (!this.placeId) return null;
|
|
251
|
+
try {
|
|
252
|
+
const { PlaceCollection } = await import("@happyvertical/smrt-places");
|
|
253
|
+
const collection = await PlaceCollection.create(this.options);
|
|
254
|
+
return await collection.get({ id: this.placeId });
|
|
255
|
+
} catch {
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
// Hierarchy traversal (getParent / getChildren / getAncestors /
|
|
260
|
+
// getDescendants / getHierarchy / moveTo) provided by SmrtHierarchical.
|
|
261
|
+
/**
|
|
262
|
+
* Get the root event (top-level ancestor) of this event's hierarchy.
|
|
263
|
+
*
|
|
264
|
+
* @returns Root event instance — `this` when already root
|
|
265
|
+
*/
|
|
266
|
+
async getRootEvent() {
|
|
267
|
+
const ancestors = await this.getAncestors();
|
|
268
|
+
return ancestors.length > 0 ? ancestors[0] : this;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Get all participants for this event
|
|
272
|
+
*
|
|
273
|
+
* @returns Array of EventParticipant instances
|
|
274
|
+
*/
|
|
275
|
+
async getParticipants() {
|
|
276
|
+
const { EventParticipantCollection: EventParticipantCollection2 } = await Promise.resolve().then(() => EventParticipantCollection$1);
|
|
277
|
+
const collection = await EventParticipantCollection2.create(
|
|
278
|
+
this.options
|
|
279
|
+
);
|
|
280
|
+
return await collection.list({ where: { eventId: this.id } });
|
|
281
|
+
}
|
|
282
|
+
async getEventAssetCollection() {
|
|
283
|
+
const { EventAssetCollection: EventAssetCollection2 } = await Promise.resolve().then(() => EventAssetCollection$1);
|
|
284
|
+
return EventAssetCollection2.create({ db: this.db });
|
|
285
|
+
}
|
|
286
|
+
async getAssets(relationship) {
|
|
287
|
+
if (!this.id) {
|
|
288
|
+
return [];
|
|
289
|
+
}
|
|
290
|
+
const eventAssets = await this.getEventAssetCollection();
|
|
291
|
+
const linkedAssets = await eventAssets.byLeft(
|
|
292
|
+
this.id,
|
|
293
|
+
relationship ? { relationship } : {}
|
|
294
|
+
);
|
|
295
|
+
return resolveOwnedAssetsById(
|
|
296
|
+
this.db,
|
|
297
|
+
linkedAssets.map((link) => link.assetId),
|
|
298
|
+
this.tenantId
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
async addAsset(asset, relationship = "attachment", sortOrder = 0) {
|
|
302
|
+
if (!this.id || !asset.id) {
|
|
303
|
+
throw new Error("Cannot associate unsaved event or asset");
|
|
304
|
+
}
|
|
305
|
+
assertValidOwnedAssetRelationship(relationship);
|
|
306
|
+
assertValidOwnedAssetSortOrder(sortOrder);
|
|
307
|
+
const eventAssets = await this.getEventAssetCollection();
|
|
308
|
+
await eventAssets.attach(this.id, asset.id, {
|
|
309
|
+
relationship,
|
|
310
|
+
sortOrder,
|
|
311
|
+
tenantId: this.tenantId
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
async removeAsset(assetId, relationship) {
|
|
315
|
+
if (!this.id) {
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
const eventAssets = await this.getEventAssetCollection();
|
|
319
|
+
await eventAssets.detach(
|
|
320
|
+
this.id,
|
|
321
|
+
assetId,
|
|
322
|
+
relationship ? { relationship } : {}
|
|
323
|
+
);
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Check if event is currently in progress
|
|
327
|
+
*
|
|
328
|
+
* @returns True if current time is between start and end
|
|
329
|
+
*/
|
|
330
|
+
isInProgress() {
|
|
331
|
+
if (this.status !== "in_progress") return false;
|
|
332
|
+
const now = /* @__PURE__ */ new Date();
|
|
333
|
+
if (this.startDate && now < this.startDate) return false;
|
|
334
|
+
if (this.endDate && now > this.endDate) return false;
|
|
335
|
+
return true;
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Check if event is a root event (no parent)
|
|
339
|
+
*
|
|
340
|
+
* @returns True if parentId is null/empty
|
|
341
|
+
*/
|
|
342
|
+
isRoot() {
|
|
343
|
+
return !this.parentId;
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
__decorateClass$4([
|
|
347
|
+
tenantId({ nullable: true })
|
|
348
|
+
], Event.prototype, "tenantId", 2);
|
|
349
|
+
__decorateClass$4([
|
|
350
|
+
foreignKey("EventSeries")
|
|
351
|
+
], Event.prototype, "seriesId", 2);
|
|
352
|
+
__decorateClass$4([
|
|
353
|
+
foreignKey("EventType")
|
|
354
|
+
], Event.prototype, "typeId", 2);
|
|
355
|
+
__decorateClass$4([
|
|
356
|
+
crossPackageRef("@happyvertical/smrt-places:Place")
|
|
357
|
+
], Event.prototype, "placeId", 2);
|
|
358
|
+
Event = __decorateClass$4([
|
|
359
|
+
TenantScoped({ mode: "optional" }),
|
|
360
|
+
smrt({
|
|
361
|
+
tableStrategy: "sti",
|
|
362
|
+
api: { include: ["list", "get", "create", "update", "delete"] },
|
|
363
|
+
mcp: { include: ["list", "get", "create", "update"] },
|
|
364
|
+
cli: true
|
|
365
|
+
})
|
|
366
|
+
], Event);
|
|
367
|
+
class EventCollection extends SmrtCollection {
|
|
368
|
+
static _itemClass = Event;
|
|
369
|
+
/**
|
|
370
|
+
* Get events by series
|
|
371
|
+
*
|
|
372
|
+
* @param seriesId - EventSeries ID
|
|
373
|
+
* @returns Array of Event instances
|
|
374
|
+
*/
|
|
375
|
+
async getBySeriesId(seriesId) {
|
|
376
|
+
return await this.list({ where: { seriesId } });
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Get events at a specific place
|
|
380
|
+
*
|
|
381
|
+
* @param placeId - Place ID
|
|
382
|
+
* @returns Array of Event instances
|
|
383
|
+
*/
|
|
384
|
+
async getByPlace(placeId) {
|
|
385
|
+
return await this.list({ where: { placeId } });
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Get events by date range
|
|
389
|
+
*
|
|
390
|
+
* @param startDate - Start of date range
|
|
391
|
+
* @param endDate - End of date range
|
|
392
|
+
* @returns Array of Event instances
|
|
393
|
+
*/
|
|
394
|
+
async getByDateRange(startDate, endDate) {
|
|
395
|
+
const allEvents = await this.list({});
|
|
396
|
+
return allEvents.filter((event) => {
|
|
397
|
+
if (!event.startDate) return false;
|
|
398
|
+
return event.startDate >= startDate && event.startDate <= endDate;
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Get upcoming events
|
|
403
|
+
*
|
|
404
|
+
* @param limit - Maximum number of events to return
|
|
405
|
+
* @returns Array of Event instances starting in the future
|
|
406
|
+
*/
|
|
407
|
+
async getUpcoming(limit) {
|
|
408
|
+
const allEvents = await this.list({});
|
|
409
|
+
const now = /* @__PURE__ */ new Date();
|
|
410
|
+
const upcoming = allEvents.filter((event) => event.startDate && event.startDate > now).sort((a, b) => {
|
|
411
|
+
if (!a.startDate || !b.startDate) return 0;
|
|
412
|
+
return a.startDate.getTime() - b.startDate.getTime();
|
|
413
|
+
});
|
|
414
|
+
return limit ? upcoming.slice(0, limit) : upcoming;
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Get events by status
|
|
418
|
+
*
|
|
419
|
+
* @param status - Event status to filter by
|
|
420
|
+
* @returns Array of Event instances
|
|
421
|
+
*/
|
|
422
|
+
async getByStatus(status) {
|
|
423
|
+
return await this.list({ where: { status } });
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Get events by type
|
|
427
|
+
*
|
|
428
|
+
* @param typeId - EventType ID
|
|
429
|
+
* @returns Array of Event instances
|
|
430
|
+
*/
|
|
431
|
+
async getByType(typeId) {
|
|
432
|
+
return await this.list({ where: { typeId } });
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Get root events (no parent)
|
|
436
|
+
*
|
|
437
|
+
* @returns Array of Event instances with no parent
|
|
438
|
+
*/
|
|
439
|
+
async getRootEvents() {
|
|
440
|
+
const allEvents = await this.list({});
|
|
441
|
+
return allEvents.filter((event) => !event.parentId);
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Get children of a parent event
|
|
445
|
+
*
|
|
446
|
+
* @param parentId - Parent event ID
|
|
447
|
+
* @returns Array of child Event instances
|
|
448
|
+
*/
|
|
449
|
+
async getByParent(parentId) {
|
|
450
|
+
return await this.list({ where: { parentId } });
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Get full event tree (hierarchy)
|
|
454
|
+
*
|
|
455
|
+
* @param eventId - Root event ID
|
|
456
|
+
* @returns Object with root event and nested children
|
|
457
|
+
*/
|
|
458
|
+
async getEventTree(eventId) {
|
|
459
|
+
const event = await this.get({ id: eventId });
|
|
460
|
+
if (!event) return null;
|
|
461
|
+
return await event.getHierarchy().then((h) => h.current);
|
|
462
|
+
}
|
|
463
|
+
async getAssets(eventId, relationship) {
|
|
464
|
+
return getOwnedAssetsFromCollection(this, eventId, relationship);
|
|
465
|
+
}
|
|
466
|
+
async addAsset(eventId, asset, relationship = "attachment", sortOrder = 0) {
|
|
467
|
+
await addOwnedAssetFromCollection(
|
|
468
|
+
this,
|
|
469
|
+
"Event",
|
|
470
|
+
eventId,
|
|
471
|
+
asset,
|
|
472
|
+
relationship,
|
|
473
|
+
sortOrder
|
|
474
|
+
);
|
|
475
|
+
}
|
|
476
|
+
async removeAsset(eventId, assetId, relationship) {
|
|
477
|
+
await removeOwnedAssetFromCollection(
|
|
478
|
+
this,
|
|
479
|
+
"Event",
|
|
480
|
+
eventId,
|
|
481
|
+
assetId,
|
|
482
|
+
relationship
|
|
483
|
+
);
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* Search events with filters
|
|
487
|
+
*
|
|
488
|
+
* @param query - Search query for name/description
|
|
489
|
+
* @param filters - Additional filter criteria
|
|
490
|
+
* @returns Array of matching Event instances
|
|
491
|
+
*/
|
|
492
|
+
async search(query, filters) {
|
|
493
|
+
let events = await this.list({});
|
|
494
|
+
if (query) {
|
|
495
|
+
const lowerQuery = query.toLowerCase();
|
|
496
|
+
events = events.filter(
|
|
497
|
+
(e) => e.name?.toLowerCase().includes(lowerQuery) || e.description?.toLowerCase().includes(lowerQuery)
|
|
498
|
+
);
|
|
499
|
+
}
|
|
500
|
+
if (filters) {
|
|
501
|
+
if (filters.typeId) {
|
|
502
|
+
events = events.filter((e) => e.typeId === filters.typeId);
|
|
503
|
+
}
|
|
504
|
+
if (filters.seriesId) {
|
|
505
|
+
events = events.filter((e) => e.seriesId === filters.seriesId);
|
|
506
|
+
}
|
|
507
|
+
if (filters.placeId) {
|
|
508
|
+
events = events.filter((e) => e.placeId === filters.placeId);
|
|
509
|
+
}
|
|
510
|
+
if (filters.status) {
|
|
511
|
+
if (Array.isArray(filters.status)) {
|
|
512
|
+
events = events.filter((e) => filters.status?.includes(e.status));
|
|
513
|
+
} else {
|
|
514
|
+
events = events.filter((e) => e.status === filters.status);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
if (filters.startDate) {
|
|
518
|
+
const startDate = filters.startDate;
|
|
519
|
+
events = events.filter((e) => e.startDate && e.startDate >= startDate);
|
|
520
|
+
}
|
|
521
|
+
if (filters.endDate) {
|
|
522
|
+
const endDate = filters.endDate;
|
|
523
|
+
events = events.filter((e) => e.startDate && e.startDate <= endDate);
|
|
524
|
+
}
|
|
525
|
+
if (filters.organizerId) {
|
|
526
|
+
events = events.filter(async (e) => {
|
|
527
|
+
const series = await e.getSeries();
|
|
528
|
+
return series && series.organizerId === filters.organizerId;
|
|
529
|
+
});
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
return events;
|
|
533
|
+
}
|
|
534
|
+
/**
|
|
535
|
+
* Get events in progress
|
|
536
|
+
*
|
|
537
|
+
* @returns Array of Event instances currently in progress
|
|
538
|
+
*/
|
|
539
|
+
async getInProgress() {
|
|
540
|
+
const inProgressEvents = await this.getByStatus("in_progress");
|
|
541
|
+
return inProgressEvents.filter((event) => event.isInProgress());
|
|
542
|
+
}
|
|
543
|
+
// ============================================
|
|
544
|
+
// Tenant Helper Methods
|
|
545
|
+
// ============================================
|
|
546
|
+
/**
|
|
547
|
+
* Find all events for a specific tenant
|
|
548
|
+
*
|
|
549
|
+
* @param tenantId - Tenant ID to filter by
|
|
550
|
+
* @returns Array of Event instances for the tenant
|
|
551
|
+
*/
|
|
552
|
+
async findByTenant(tenantId2) {
|
|
553
|
+
return this.list({ where: { tenantId: tenantId2 } });
|
|
554
|
+
}
|
|
555
|
+
/**
|
|
556
|
+
* Find all global events (no tenant association)
|
|
557
|
+
*
|
|
558
|
+
* @returns Array of Event instances with no tenant
|
|
559
|
+
*/
|
|
560
|
+
async findGlobal() {
|
|
561
|
+
return this.list({ where: { tenantId: null } });
|
|
562
|
+
}
|
|
563
|
+
/**
|
|
564
|
+
* Find events for a tenant including global events
|
|
565
|
+
*
|
|
566
|
+
* @param tenantId - Tenant ID to filter by
|
|
567
|
+
* @returns Array of Event instances for the tenant and global events
|
|
568
|
+
*/
|
|
569
|
+
async findWithGlobals(tenantId2) {
|
|
570
|
+
return this.query(
|
|
571
|
+
`SELECT * FROM ${this.tableName} WHERE tenant_id = ? OR tenant_id IS NULL`,
|
|
572
|
+
[tenantId2]
|
|
573
|
+
);
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
const EventCollection$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
577
|
+
__proto__: null,
|
|
578
|
+
EventCollection
|
|
579
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
580
|
+
var __defProp$3 = Object.defineProperty;
|
|
581
|
+
var __getOwnPropDesc$3 = Object.getOwnPropertyDescriptor;
|
|
582
|
+
var __decorateClass$3 = (decorators, target, key, kind) => {
|
|
583
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$3(target, key) : target;
|
|
584
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
585
|
+
if (decorator = decorators[i])
|
|
586
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
587
|
+
if (kind && result) __defProp$3(target, key, result);
|
|
588
|
+
return result;
|
|
589
|
+
};
|
|
590
|
+
let EventParticipant = class extends SmrtObject {
|
|
591
|
+
tenantId = null;
|
|
592
|
+
eventId = "";
|
|
593
|
+
profileId = "";
|
|
594
|
+
// FK to Profile (from @happyvertical/smrt-profiles)
|
|
595
|
+
role = "";
|
|
596
|
+
// Participant role (ParticipantRole or custom)
|
|
597
|
+
placement = null;
|
|
598
|
+
// Numeric position/placement
|
|
599
|
+
groupId = "";
|
|
600
|
+
// Optional grouping (e.g., team ID for individual players)
|
|
601
|
+
metadata = "";
|
|
602
|
+
// JSON metadata (stored as text)
|
|
603
|
+
externalId = "";
|
|
604
|
+
// External system identifier
|
|
605
|
+
source = "";
|
|
606
|
+
// Source system
|
|
607
|
+
// Timestamps
|
|
608
|
+
createdAt = /* @__PURE__ */ new Date();
|
|
609
|
+
updatedAt = /* @__PURE__ */ new Date();
|
|
610
|
+
constructor(options = {}) {
|
|
611
|
+
super(options);
|
|
612
|
+
if (options.eventId) this.eventId = options.eventId;
|
|
613
|
+
if (options.profileId) this.profileId = options.profileId;
|
|
614
|
+
if (options.role !== void 0) this.role = options.role;
|
|
615
|
+
if (options.placement !== void 0) this.placement = options.placement;
|
|
616
|
+
if (options.groupId !== void 0) this.groupId = options.groupId;
|
|
617
|
+
if (options.externalId !== void 0) this.externalId = options.externalId;
|
|
618
|
+
if (options.source !== void 0) this.source = options.source;
|
|
619
|
+
if (options.metadata !== void 0) {
|
|
620
|
+
if (typeof options.metadata === "string") {
|
|
621
|
+
this.metadata = options.metadata;
|
|
622
|
+
} else {
|
|
623
|
+
this.metadata = JSON.stringify(options.metadata);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
if (options.createdAt) this.createdAt = options.createdAt;
|
|
627
|
+
if (options.updatedAt) this.updatedAt = options.updatedAt;
|
|
628
|
+
}
|
|
629
|
+
/**
|
|
630
|
+
* Get metadata as parsed object
|
|
631
|
+
*
|
|
632
|
+
* @returns Parsed metadata object or empty object
|
|
633
|
+
*/
|
|
634
|
+
getMetadata() {
|
|
635
|
+
if (!this.metadata) return {};
|
|
636
|
+
try {
|
|
637
|
+
return JSON.parse(this.metadata);
|
|
638
|
+
} catch {
|
|
639
|
+
return {};
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* Set metadata from object
|
|
644
|
+
*
|
|
645
|
+
* @param data - Metadata object to store
|
|
646
|
+
*/
|
|
647
|
+
setMetadata(data) {
|
|
648
|
+
this.metadata = JSON.stringify(data);
|
|
649
|
+
}
|
|
650
|
+
/**
|
|
651
|
+
* Update metadata by merging with existing values
|
|
652
|
+
*
|
|
653
|
+
* @param updates - Partial metadata to merge
|
|
654
|
+
*/
|
|
655
|
+
updateMetadata(updates) {
|
|
656
|
+
const current = this.getMetadata();
|
|
657
|
+
this.setMetadata({ ...current, ...updates });
|
|
658
|
+
}
|
|
659
|
+
/**
|
|
660
|
+
* Get the event for this participant
|
|
661
|
+
*
|
|
662
|
+
* @returns Event instance or null
|
|
663
|
+
*/
|
|
664
|
+
async getEvent() {
|
|
665
|
+
if (!this.eventId) return null;
|
|
666
|
+
const { EventCollection: EventCollection2 } = await Promise.resolve().then(() => EventCollection$1);
|
|
667
|
+
const collection = await EventCollection2.create(this.options);
|
|
668
|
+
return await collection.get({ id: this.eventId });
|
|
669
|
+
}
|
|
670
|
+
/**
|
|
671
|
+
* Get the profile for this participant
|
|
672
|
+
*
|
|
673
|
+
* @returns Profile instance or null
|
|
674
|
+
*/
|
|
675
|
+
async getProfile() {
|
|
676
|
+
if (!this.profileId) return null;
|
|
677
|
+
try {
|
|
678
|
+
const { ProfileCollection } = await import("@happyvertical/smrt-profiles");
|
|
679
|
+
const collection = await ProfileCollection.create(this.options);
|
|
680
|
+
return await collection.get({ id: this.profileId });
|
|
681
|
+
} catch {
|
|
682
|
+
return null;
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
/**
|
|
686
|
+
* Get group participants (others with same groupId)
|
|
687
|
+
*
|
|
688
|
+
* @returns Array of EventParticipant instances
|
|
689
|
+
*/
|
|
690
|
+
async getGroupParticipants() {
|
|
691
|
+
if (!this.groupId) return [];
|
|
692
|
+
const { EventParticipantCollection: EventParticipantCollection2 } = await Promise.resolve().then(() => EventParticipantCollection$1);
|
|
693
|
+
const collection = await EventParticipantCollection2.create(
|
|
694
|
+
this.options
|
|
695
|
+
);
|
|
696
|
+
const participants = await collection.list({
|
|
697
|
+
where: { eventId: this.eventId, groupId: this.groupId }
|
|
698
|
+
});
|
|
699
|
+
return participants.filter((p) => p.id !== this.id);
|
|
700
|
+
}
|
|
701
|
+
/**
|
|
702
|
+
* Check if this is a home participant (placement = 0)
|
|
703
|
+
*
|
|
704
|
+
* @returns True if placement is 0
|
|
705
|
+
*/
|
|
706
|
+
isHome() {
|
|
707
|
+
return this.placement === 0;
|
|
708
|
+
}
|
|
709
|
+
/**
|
|
710
|
+
* Check if this is an away participant (placement = 1)
|
|
711
|
+
*
|
|
712
|
+
* @returns True if placement is 1
|
|
713
|
+
*/
|
|
714
|
+
isAway() {
|
|
715
|
+
return this.placement === 1;
|
|
716
|
+
}
|
|
717
|
+
};
|
|
718
|
+
__decorateClass$3([
|
|
719
|
+
tenantId({ nullable: true })
|
|
720
|
+
], EventParticipant.prototype, "tenantId", 2);
|
|
721
|
+
__decorateClass$3([
|
|
722
|
+
foreignKey("Event")
|
|
723
|
+
], EventParticipant.prototype, "eventId", 2);
|
|
724
|
+
__decorateClass$3([
|
|
725
|
+
crossPackageRef("@happyvertical/smrt-profiles:Profile")
|
|
726
|
+
], EventParticipant.prototype, "profileId", 2);
|
|
727
|
+
EventParticipant = __decorateClass$3([
|
|
728
|
+
TenantScoped({ mode: "optional" }),
|
|
729
|
+
smrt({
|
|
730
|
+
// Junction table - uses event_id + profile_id + role as natural key
|
|
731
|
+
// instead of slug-based conflict columns
|
|
732
|
+
conflictColumns: ["event_id", "profile_id", "role"],
|
|
733
|
+
api: { include: ["list", "get", "create", "update", "delete"] },
|
|
734
|
+
mcp: { include: ["list", "get", "create", "update"] },
|
|
735
|
+
cli: true
|
|
736
|
+
})
|
|
737
|
+
], EventParticipant);
|
|
738
|
+
var __defProp$2 = Object.defineProperty;
|
|
739
|
+
var __getOwnPropDesc$2 = Object.getOwnPropertyDescriptor;
|
|
740
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
741
|
+
var __decorateClass$2 = (decorators, target, key, kind) => {
|
|
742
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$2(target, key) : target;
|
|
743
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
744
|
+
if (decorator = decorators[i])
|
|
745
|
+
result = decorator(result) || result;
|
|
746
|
+
return result;
|
|
747
|
+
};
|
|
748
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, key + "", value);
|
|
749
|
+
let EventParticipantCollection = class extends SmrtJunction {
|
|
750
|
+
leftField = "eventId";
|
|
751
|
+
rightField = "profileId";
|
|
752
|
+
// EventParticipant has no sortOrder column; `placement` is domain ordering
|
|
753
|
+
// (0=home, 1=away) and must not be auto-assigned by setLinks.
|
|
754
|
+
sortField = null;
|
|
755
|
+
positionField = null;
|
|
756
|
+
// ============================================
|
|
757
|
+
// Domain helpers
|
|
758
|
+
// ============================================
|
|
759
|
+
/**
|
|
760
|
+
* Get participants ordered by placement (nulls last).
|
|
761
|
+
*/
|
|
762
|
+
async getByPlacement(eventId) {
|
|
763
|
+
const participants = await this.byLeft(eventId);
|
|
764
|
+
return participants.sort((a, b) => {
|
|
765
|
+
if (a.placement === null && b.placement === null) return 0;
|
|
766
|
+
if (a.placement === null) return 1;
|
|
767
|
+
if (b.placement === null) return -1;
|
|
768
|
+
return a.placement - b.placement;
|
|
769
|
+
});
|
|
770
|
+
}
|
|
771
|
+
/**
|
|
772
|
+
* Get participants by group within an event.
|
|
773
|
+
*/
|
|
774
|
+
async getByGroup(eventId, groupId) {
|
|
775
|
+
return this.byLeft(eventId, { groupId });
|
|
776
|
+
}
|
|
777
|
+
/**
|
|
778
|
+
* Get the home participant(s) — placement = 0.
|
|
779
|
+
*/
|
|
780
|
+
async getHome(eventId) {
|
|
781
|
+
return this.byLeft(eventId, { placement: 0 });
|
|
782
|
+
}
|
|
783
|
+
/**
|
|
784
|
+
* Get the away participant(s) — placement = 1.
|
|
785
|
+
*/
|
|
786
|
+
async getAway(eventId) {
|
|
787
|
+
return this.byLeft(eventId, { placement: 1 });
|
|
788
|
+
}
|
|
789
|
+
/**
|
|
790
|
+
* Search participants with optional filters.
|
|
791
|
+
*/
|
|
792
|
+
async search(filters) {
|
|
793
|
+
let participants = await this.list({});
|
|
794
|
+
if (filters.eventId) {
|
|
795
|
+
participants = participants.filter((p) => p.eventId === filters.eventId);
|
|
796
|
+
}
|
|
797
|
+
if (filters.profileId) {
|
|
798
|
+
participants = participants.filter(
|
|
799
|
+
(p) => p.profileId === filters.profileId
|
|
800
|
+
);
|
|
801
|
+
}
|
|
802
|
+
if (filters.role) {
|
|
803
|
+
participants = participants.filter((p) => p.role === filters.role);
|
|
804
|
+
}
|
|
805
|
+
if (filters.groupId) {
|
|
806
|
+
participants = participants.filter((p) => p.groupId === filters.groupId);
|
|
807
|
+
}
|
|
808
|
+
return participants;
|
|
809
|
+
}
|
|
810
|
+
/**
|
|
811
|
+
* Get participation statistics for a profile, optionally filtered by event type.
|
|
812
|
+
*/
|
|
813
|
+
async getParticipantStats(profileId, eventTypeId) {
|
|
814
|
+
const participants = await this.byRight(profileId);
|
|
815
|
+
let filteredParticipants = participants;
|
|
816
|
+
if (eventTypeId) {
|
|
817
|
+
filteredParticipants = [];
|
|
818
|
+
for (const participant of participants) {
|
|
819
|
+
const event = await participant.getEvent();
|
|
820
|
+
if (event && event.typeId === eventTypeId) {
|
|
821
|
+
filteredParticipants.push(participant);
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
const byRole = {};
|
|
826
|
+
const byPlacement = {};
|
|
827
|
+
for (const participant of filteredParticipants) {
|
|
828
|
+
byRole[participant.role] = (byRole[participant.role] || 0) + 1;
|
|
829
|
+
if (participant.placement !== null) {
|
|
830
|
+
byPlacement[participant.placement] = (byPlacement[participant.placement] || 0) + 1;
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
return {
|
|
834
|
+
totalEvents: filteredParticipants.length,
|
|
835
|
+
byRole,
|
|
836
|
+
byPlacement
|
|
837
|
+
};
|
|
838
|
+
}
|
|
839
|
+
// ============================================
|
|
840
|
+
// Tenant helpers
|
|
841
|
+
// ============================================
|
|
842
|
+
async findByTenant(tenantId2) {
|
|
843
|
+
return this.list({ where: { tenantId: tenantId2 } });
|
|
844
|
+
}
|
|
845
|
+
async findGlobal() {
|
|
846
|
+
return this.list({ where: { tenantId: null } });
|
|
847
|
+
}
|
|
848
|
+
async findWithGlobals(tenantId2) {
|
|
849
|
+
return this.query(
|
|
850
|
+
`SELECT * FROM ${this.tableName} WHERE tenant_id = ? OR tenant_id IS NULL`,
|
|
851
|
+
[tenantId2]
|
|
852
|
+
);
|
|
853
|
+
}
|
|
854
|
+
};
|
|
855
|
+
__publicField(EventParticipantCollection, "_itemClass", EventParticipant);
|
|
856
|
+
EventParticipantCollection = __decorateClass$2([
|
|
857
|
+
smrt()
|
|
858
|
+
], EventParticipantCollection);
|
|
859
|
+
const EventParticipantCollection$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
860
|
+
__proto__: null,
|
|
861
|
+
get EventParticipantCollection() {
|
|
862
|
+
return EventParticipantCollection;
|
|
863
|
+
}
|
|
864
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
865
|
+
var __defProp$1 = Object.defineProperty;
|
|
866
|
+
var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
|
|
867
|
+
var __decorateClass$1 = (decorators, target, key, kind) => {
|
|
868
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$1(target, key) : target;
|
|
869
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
870
|
+
if (decorator = decorators[i])
|
|
871
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
872
|
+
if (kind && result) __defProp$1(target, key, result);
|
|
873
|
+
return result;
|
|
874
|
+
};
|
|
875
|
+
let EventSeries = class extends SmrtObject {
|
|
876
|
+
tenantId = null;
|
|
877
|
+
name = "";
|
|
878
|
+
typeId = "";
|
|
879
|
+
organizerId = "";
|
|
880
|
+
// FK to Profile (from @happyvertical/smrt-profiles)
|
|
881
|
+
description = "";
|
|
882
|
+
startDate = null;
|
|
883
|
+
endDate = null;
|
|
884
|
+
recurrence = "";
|
|
885
|
+
// JSON recurrence pattern (stored as text)
|
|
886
|
+
metadata = "";
|
|
887
|
+
// JSON metadata (stored as text)
|
|
888
|
+
externalId = "";
|
|
889
|
+
// External system identifier
|
|
890
|
+
source = "";
|
|
891
|
+
// Source system (e.g., 'ticketmaster', 'espn')
|
|
892
|
+
// Timestamps
|
|
893
|
+
createdAt = /* @__PURE__ */ new Date();
|
|
894
|
+
updatedAt = /* @__PURE__ */ new Date();
|
|
895
|
+
constructor(options = {}) {
|
|
896
|
+
super(options);
|
|
897
|
+
if (options.typeId) this.typeId = options.typeId;
|
|
898
|
+
if (options.organizerId) this.organizerId = options.organizerId;
|
|
899
|
+
if (options.description !== void 0)
|
|
900
|
+
this.description = options.description;
|
|
901
|
+
if (options.startDate !== void 0)
|
|
902
|
+
this.startDate = options.startDate || null;
|
|
903
|
+
if (options.endDate !== void 0) this.endDate = options.endDate || null;
|
|
904
|
+
if (options.externalId !== void 0) this.externalId = options.externalId;
|
|
905
|
+
if (options.source !== void 0) this.source = options.source;
|
|
906
|
+
if (options.recurrence !== void 0) {
|
|
907
|
+
if (typeof options.recurrence === "string") {
|
|
908
|
+
this.recurrence = options.recurrence;
|
|
909
|
+
} else {
|
|
910
|
+
this.recurrence = JSON.stringify(options.recurrence);
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
if (options.metadata !== void 0) {
|
|
914
|
+
if (typeof options.metadata === "string") {
|
|
915
|
+
this.metadata = options.metadata;
|
|
916
|
+
} else {
|
|
917
|
+
this.metadata = JSON.stringify(options.metadata);
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
if (options.createdAt) this.createdAt = options.createdAt;
|
|
921
|
+
if (options.updatedAt) this.updatedAt = options.updatedAt;
|
|
922
|
+
}
|
|
923
|
+
/**
|
|
924
|
+
* Get recurrence pattern as parsed object
|
|
925
|
+
*
|
|
926
|
+
* @returns Parsed recurrence pattern or null
|
|
927
|
+
*/
|
|
928
|
+
getRecurrence() {
|
|
929
|
+
if (!this.recurrence) return null;
|
|
930
|
+
try {
|
|
931
|
+
return JSON.parse(this.recurrence);
|
|
932
|
+
} catch {
|
|
933
|
+
return null;
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
/**
|
|
937
|
+
* Set recurrence pattern from object
|
|
938
|
+
*
|
|
939
|
+
* @param pattern - Recurrence pattern to store
|
|
940
|
+
*/
|
|
941
|
+
setRecurrence(pattern) {
|
|
942
|
+
this.recurrence = JSON.stringify(pattern);
|
|
943
|
+
}
|
|
944
|
+
/**
|
|
945
|
+
* Get metadata as parsed object
|
|
946
|
+
*
|
|
947
|
+
* @returns Parsed metadata object or empty object
|
|
948
|
+
*/
|
|
949
|
+
getMetadata() {
|
|
950
|
+
if (!this.metadata) return {};
|
|
951
|
+
try {
|
|
952
|
+
return JSON.parse(this.metadata);
|
|
953
|
+
} catch {
|
|
954
|
+
return {};
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
/**
|
|
958
|
+
* Set metadata from object
|
|
959
|
+
*
|
|
960
|
+
* @param data - Metadata object to store
|
|
961
|
+
*/
|
|
962
|
+
setMetadata(data) {
|
|
963
|
+
this.metadata = JSON.stringify(data);
|
|
964
|
+
}
|
|
965
|
+
/**
|
|
966
|
+
* Update metadata by merging with existing values
|
|
967
|
+
*
|
|
968
|
+
* @param updates - Partial metadata to merge
|
|
969
|
+
*/
|
|
970
|
+
updateMetadata(updates) {
|
|
971
|
+
const current = this.getMetadata();
|
|
972
|
+
this.setMetadata({ ...current, ...updates });
|
|
973
|
+
}
|
|
974
|
+
/**
|
|
975
|
+
* Get the event type for this series
|
|
976
|
+
*
|
|
977
|
+
* @returns EventType instance or null
|
|
978
|
+
*/
|
|
979
|
+
async getType() {
|
|
980
|
+
if (!this.typeId) return null;
|
|
981
|
+
const { EventTypeCollection: EventTypeCollection2 } = await Promise.resolve().then(() => EventTypeCollection$1);
|
|
982
|
+
const collection = await EventTypeCollection2.create(this.options);
|
|
983
|
+
return await collection.get({ id: this.typeId });
|
|
984
|
+
}
|
|
985
|
+
/**
|
|
986
|
+
* Get the organizer profile for this series
|
|
987
|
+
*
|
|
988
|
+
* @returns Profile instance or null
|
|
989
|
+
*/
|
|
990
|
+
async getOrganizer() {
|
|
991
|
+
if (!this.organizerId) return null;
|
|
992
|
+
try {
|
|
993
|
+
const { ProfileCollection } = await import("@happyvertical/smrt-profiles");
|
|
994
|
+
const collection = await ProfileCollection.create(this.options);
|
|
995
|
+
return await collection.get({ id: this.organizerId });
|
|
996
|
+
} catch {
|
|
997
|
+
return null;
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
/**
|
|
1001
|
+
* Get all events in this series
|
|
1002
|
+
*
|
|
1003
|
+
* @returns Array of Event instances
|
|
1004
|
+
*/
|
|
1005
|
+
async getEvents() {
|
|
1006
|
+
const { EventCollection: EventCollection2 } = await Promise.resolve().then(() => EventCollection$1);
|
|
1007
|
+
const collection = await EventCollection2.create(this.options);
|
|
1008
|
+
return await collection.list({ where: { seriesId: this.id } });
|
|
1009
|
+
}
|
|
1010
|
+
/**
|
|
1011
|
+
* Check if series is currently active
|
|
1012
|
+
*
|
|
1013
|
+
* @returns True if current date is between start and end
|
|
1014
|
+
*/
|
|
1015
|
+
isActive() {
|
|
1016
|
+
const now = /* @__PURE__ */ new Date();
|
|
1017
|
+
if (this.startDate && now < this.startDate) return false;
|
|
1018
|
+
if (this.endDate && now > this.endDate) return false;
|
|
1019
|
+
return true;
|
|
1020
|
+
}
|
|
1021
|
+
};
|
|
1022
|
+
__decorateClass$1([
|
|
1023
|
+
tenantId({ nullable: true })
|
|
1024
|
+
], EventSeries.prototype, "tenantId", 2);
|
|
1025
|
+
__decorateClass$1([
|
|
1026
|
+
foreignKey("EventType")
|
|
1027
|
+
], EventSeries.prototype, "typeId", 2);
|
|
1028
|
+
__decorateClass$1([
|
|
1029
|
+
crossPackageRef("@happyvertical/smrt-profiles:Profile")
|
|
1030
|
+
], EventSeries.prototype, "organizerId", 2);
|
|
1031
|
+
EventSeries = __decorateClass$1([
|
|
1032
|
+
TenantScoped({ mode: "optional" }),
|
|
1033
|
+
smrt({
|
|
1034
|
+
tableStrategy: "sti",
|
|
1035
|
+
api: { include: ["list", "get", "create", "update", "delete"] },
|
|
1036
|
+
mcp: { include: ["list", "get", "create", "update"] },
|
|
1037
|
+
cli: true
|
|
1038
|
+
})
|
|
1039
|
+
], EventSeries);
|
|
1040
|
+
class EventSeriesCollection extends SmrtCollection {
|
|
1041
|
+
static _itemClass = EventSeries;
|
|
1042
|
+
/**
|
|
1043
|
+
* Get series by organizer
|
|
1044
|
+
*
|
|
1045
|
+
* @param organizerId - Profile ID of the organizer
|
|
1046
|
+
* @returns Array of EventSeries instances
|
|
1047
|
+
*/
|
|
1048
|
+
async getByOrganizer(organizerId) {
|
|
1049
|
+
return await this.list({ where: { organizerId } });
|
|
1050
|
+
}
|
|
1051
|
+
/**
|
|
1052
|
+
* Get currently active series
|
|
1053
|
+
*
|
|
1054
|
+
* @returns Array of EventSeries instances active today
|
|
1055
|
+
*/
|
|
1056
|
+
async getActive() {
|
|
1057
|
+
const allSeries = await this.list({});
|
|
1058
|
+
const now = /* @__PURE__ */ new Date();
|
|
1059
|
+
return allSeries.filter((series) => {
|
|
1060
|
+
if (series.startDate && now < series.startDate) return false;
|
|
1061
|
+
if (series.endDate && now > series.endDate) return false;
|
|
1062
|
+
return true;
|
|
1063
|
+
});
|
|
1064
|
+
}
|
|
1065
|
+
/**
|
|
1066
|
+
* Get upcoming series
|
|
1067
|
+
*
|
|
1068
|
+
* @param limit - Maximum number of series to return
|
|
1069
|
+
* @returns Array of EventSeries instances starting in the future
|
|
1070
|
+
*/
|
|
1071
|
+
async getUpcoming(limit) {
|
|
1072
|
+
const allSeries = await this.list({});
|
|
1073
|
+
const now = /* @__PURE__ */ new Date();
|
|
1074
|
+
const upcoming = allSeries.filter((series) => series.startDate && series.startDate > now).sort((a, b) => {
|
|
1075
|
+
if (!a.startDate || !b.startDate) return 0;
|
|
1076
|
+
return a.startDate.getTime() - b.startDate.getTime();
|
|
1077
|
+
});
|
|
1078
|
+
return limit ? upcoming.slice(0, limit) : upcoming;
|
|
1079
|
+
}
|
|
1080
|
+
/**
|
|
1081
|
+
* Get series by type
|
|
1082
|
+
*
|
|
1083
|
+
* @param typeId - EventType ID
|
|
1084
|
+
* @returns Array of EventSeries instances
|
|
1085
|
+
*/
|
|
1086
|
+
async getByType(typeId) {
|
|
1087
|
+
return await this.list({ where: { typeId } });
|
|
1088
|
+
}
|
|
1089
|
+
/**
|
|
1090
|
+
* Search series with filters
|
|
1091
|
+
*
|
|
1092
|
+
* @param query - Search query for name/description
|
|
1093
|
+
* @param filters - Additional filter criteria
|
|
1094
|
+
* @returns Array of matching EventSeries instances
|
|
1095
|
+
*/
|
|
1096
|
+
async search(query, filters) {
|
|
1097
|
+
let series = await this.list({});
|
|
1098
|
+
if (query) {
|
|
1099
|
+
const lowerQuery = query.toLowerCase();
|
|
1100
|
+
series = series.filter(
|
|
1101
|
+
(s) => s.name?.toLowerCase().includes(lowerQuery) || s.description?.toLowerCase().includes(lowerQuery)
|
|
1102
|
+
);
|
|
1103
|
+
}
|
|
1104
|
+
if (filters) {
|
|
1105
|
+
if (filters.typeId) {
|
|
1106
|
+
series = series.filter((s) => s.typeId === filters.typeId);
|
|
1107
|
+
}
|
|
1108
|
+
if (filters.organizerId) {
|
|
1109
|
+
series = series.filter((s) => s.organizerId === filters.organizerId);
|
|
1110
|
+
}
|
|
1111
|
+
if (filters.startDate) {
|
|
1112
|
+
const startDate = filters.startDate;
|
|
1113
|
+
series = series.filter((s) => s.startDate && s.startDate >= startDate);
|
|
1114
|
+
}
|
|
1115
|
+
if (filters.endDate) {
|
|
1116
|
+
const endDate = filters.endDate;
|
|
1117
|
+
series = series.filter((s) => s.endDate && s.endDate <= endDate);
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
return series;
|
|
1121
|
+
}
|
|
1122
|
+
// ============================================
|
|
1123
|
+
// Tenant Helper Methods
|
|
1124
|
+
// ============================================
|
|
1125
|
+
/**
|
|
1126
|
+
* Find all event series for a specific tenant
|
|
1127
|
+
*
|
|
1128
|
+
* @param tenantId - Tenant ID to filter by
|
|
1129
|
+
* @returns Array of EventSeries instances for the tenant
|
|
1130
|
+
*/
|
|
1131
|
+
async findByTenant(tenantId2) {
|
|
1132
|
+
return this.list({ where: { tenantId: tenantId2 } });
|
|
1133
|
+
}
|
|
1134
|
+
/**
|
|
1135
|
+
* Find all global event series (no tenant association)
|
|
1136
|
+
*
|
|
1137
|
+
* @returns Array of EventSeries instances with no tenant
|
|
1138
|
+
*/
|
|
1139
|
+
async findGlobal() {
|
|
1140
|
+
return this.list({ where: { tenantId: null } });
|
|
1141
|
+
}
|
|
1142
|
+
/**
|
|
1143
|
+
* Find event series for a tenant including global series
|
|
1144
|
+
*
|
|
1145
|
+
* @param tenantId - Tenant ID to filter by
|
|
1146
|
+
* @returns Array of EventSeries instances for the tenant and global series
|
|
1147
|
+
*/
|
|
1148
|
+
async findWithGlobals(tenantId2) {
|
|
1149
|
+
return this.query(
|
|
1150
|
+
`SELECT * FROM ${this.tableName} WHERE tenant_id = ? OR tenant_id IS NULL`,
|
|
1151
|
+
[tenantId2]
|
|
1152
|
+
);
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
const EventSeriesCollection$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1156
|
+
__proto__: null,
|
|
1157
|
+
EventSeriesCollection
|
|
1158
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
1159
|
+
var __defProp = Object.defineProperty;
|
|
1160
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
1161
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
1162
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
1163
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
1164
|
+
if (decorator = decorators[i])
|
|
1165
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
1166
|
+
if (kind && result) __defProp(target, key, result);
|
|
1167
|
+
return result;
|
|
1168
|
+
};
|
|
1169
|
+
let EventType = class extends SmrtObject {
|
|
1170
|
+
tenantId = null;
|
|
1171
|
+
name = "";
|
|
1172
|
+
description = "";
|
|
1173
|
+
// Optional description
|
|
1174
|
+
schema = "";
|
|
1175
|
+
// JSON schema for event metadata (stored as text)
|
|
1176
|
+
participantSchema = "";
|
|
1177
|
+
// JSON schema for participant metadata (stored as text)
|
|
1178
|
+
// Timestamps
|
|
1179
|
+
createdAt = /* @__PURE__ */ new Date();
|
|
1180
|
+
updatedAt = /* @__PURE__ */ new Date();
|
|
1181
|
+
constructor(options = {}) {
|
|
1182
|
+
super(options);
|
|
1183
|
+
if (options.name) this.name = options.name;
|
|
1184
|
+
if (options.description !== void 0)
|
|
1185
|
+
this.description = options.description;
|
|
1186
|
+
if (options.schema !== void 0) {
|
|
1187
|
+
if (typeof options.schema === "string") {
|
|
1188
|
+
this.schema = options.schema;
|
|
1189
|
+
} else {
|
|
1190
|
+
this.schema = JSON.stringify(options.schema);
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
if (options.participantSchema !== void 0) {
|
|
1194
|
+
if (typeof options.participantSchema === "string") {
|
|
1195
|
+
this.participantSchema = options.participantSchema;
|
|
1196
|
+
} else {
|
|
1197
|
+
this.participantSchema = JSON.stringify(options.participantSchema);
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
if (options.createdAt) this.createdAt = options.createdAt;
|
|
1201
|
+
if (options.updatedAt) this.updatedAt = options.updatedAt;
|
|
1202
|
+
}
|
|
1203
|
+
/**
|
|
1204
|
+
* Get schema as parsed object
|
|
1205
|
+
*
|
|
1206
|
+
* @returns Parsed schema object or empty object if no schema
|
|
1207
|
+
*/
|
|
1208
|
+
getSchema() {
|
|
1209
|
+
if (!this.schema) return {};
|
|
1210
|
+
try {
|
|
1211
|
+
return JSON.parse(this.schema);
|
|
1212
|
+
} catch {
|
|
1213
|
+
return {};
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
/**
|
|
1217
|
+
* Set schema from object
|
|
1218
|
+
*
|
|
1219
|
+
* @param data - Schema object to store
|
|
1220
|
+
*/
|
|
1221
|
+
setSchema(data) {
|
|
1222
|
+
this.schema = JSON.stringify(data);
|
|
1223
|
+
}
|
|
1224
|
+
/**
|
|
1225
|
+
* Get participant schema as parsed object
|
|
1226
|
+
*
|
|
1227
|
+
* @returns Parsed participant schema object or empty object
|
|
1228
|
+
*/
|
|
1229
|
+
getParticipantSchema() {
|
|
1230
|
+
if (!this.participantSchema) return {};
|
|
1231
|
+
try {
|
|
1232
|
+
return JSON.parse(this.participantSchema);
|
|
1233
|
+
} catch {
|
|
1234
|
+
return {};
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
/**
|
|
1238
|
+
* Set participant schema from object
|
|
1239
|
+
*
|
|
1240
|
+
* @param data - Participant schema object to store
|
|
1241
|
+
*/
|
|
1242
|
+
setParticipantSchema(data) {
|
|
1243
|
+
this.participantSchema = JSON.stringify(data);
|
|
1244
|
+
}
|
|
1245
|
+
/**
|
|
1246
|
+
* Convenience method for slug-based lookup
|
|
1247
|
+
*
|
|
1248
|
+
* @param slug - The slug to search for
|
|
1249
|
+
* @returns EventType instance or null if not found
|
|
1250
|
+
*/
|
|
1251
|
+
static async getBySlug(_slug) {
|
|
1252
|
+
return null;
|
|
1253
|
+
}
|
|
1254
|
+
};
|
|
1255
|
+
__decorateClass([
|
|
1256
|
+
tenantId({ nullable: true })
|
|
1257
|
+
], EventType.prototype, "tenantId", 2);
|
|
1258
|
+
__decorateClass([
|
|
1259
|
+
field({ required: true })
|
|
1260
|
+
], EventType.prototype, "name", 2);
|
|
1261
|
+
EventType = __decorateClass([
|
|
1262
|
+
TenantScoped({ mode: "optional" }),
|
|
1263
|
+
smrt({
|
|
1264
|
+
tableStrategy: "sti",
|
|
1265
|
+
api: { include: ["list", "get", "create", "update", "delete"] },
|
|
1266
|
+
mcp: { include: ["list", "get", "create"] },
|
|
1267
|
+
cli: true
|
|
1268
|
+
})
|
|
1269
|
+
], EventType);
|
|
1270
|
+
class EventTypeCollection extends SmrtCollection {
|
|
1271
|
+
static _itemClass = EventType;
|
|
1272
|
+
/**
|
|
1273
|
+
* Get or create an event type by slug
|
|
1274
|
+
*
|
|
1275
|
+
* @param slug - EventType slug (e.g., 'basketball-game', 'concert')
|
|
1276
|
+
* @param name - Optional display name (defaults to capitalized slug)
|
|
1277
|
+
* @returns EventType instance
|
|
1278
|
+
*/
|
|
1279
|
+
async getOrCreate(slug, name) {
|
|
1280
|
+
const existing = await this.get({ slug });
|
|
1281
|
+
if (existing) {
|
|
1282
|
+
return existing;
|
|
1283
|
+
}
|
|
1284
|
+
const displayName = name || slug.replace(/-/g, " ").replace(/\b\w/g, (l) => l.toUpperCase());
|
|
1285
|
+
return await this.create({
|
|
1286
|
+
slug,
|
|
1287
|
+
name: displayName
|
|
1288
|
+
});
|
|
1289
|
+
}
|
|
1290
|
+
/**
|
|
1291
|
+
* Get an event type by slug
|
|
1292
|
+
*
|
|
1293
|
+
* @param slug - EventType slug to search for
|
|
1294
|
+
* @returns EventType instance or null if not found
|
|
1295
|
+
*/
|
|
1296
|
+
async getBySlug(slug) {
|
|
1297
|
+
return await this.get({ slug });
|
|
1298
|
+
}
|
|
1299
|
+
/**
|
|
1300
|
+
* Initialize default event types
|
|
1301
|
+
*
|
|
1302
|
+
* Creates common event types if they don't exist:
|
|
1303
|
+
* - Sports: game, period, goal, assist, penalty
|
|
1304
|
+
* - Entertainment: concert, performance, song
|
|
1305
|
+
* - Professional: conference, session, presentation, workshop
|
|
1306
|
+
* - Community: meeting, agenda-item, motion, vote
|
|
1307
|
+
*
|
|
1308
|
+
* @returns Array of created/existing event types
|
|
1309
|
+
*/
|
|
1310
|
+
async initializeDefaults() {
|
|
1311
|
+
const defaults = [
|
|
1312
|
+
// Sports
|
|
1313
|
+
{ slug: "game", name: "Game" },
|
|
1314
|
+
{ slug: "match", name: "Match" },
|
|
1315
|
+
{ slug: "period", name: "Period" },
|
|
1316
|
+
{ slug: "quarter", name: "Quarter" },
|
|
1317
|
+
{ slug: "inning", name: "Inning" },
|
|
1318
|
+
{ slug: "goal", name: "Goal" },
|
|
1319
|
+
{ slug: "assist", name: "Assist" },
|
|
1320
|
+
{ slug: "penalty", name: "Penalty" },
|
|
1321
|
+
{ slug: "substitution", name: "Substitution" },
|
|
1322
|
+
// Entertainment
|
|
1323
|
+
{ slug: "concert", name: "Concert" },
|
|
1324
|
+
{ slug: "performance", name: "Performance" },
|
|
1325
|
+
{ slug: "set", name: "Set" },
|
|
1326
|
+
{ slug: "song", name: "Song" },
|
|
1327
|
+
{ slug: "theater", name: "Theater" },
|
|
1328
|
+
{ slug: "show", name: "Show" },
|
|
1329
|
+
// Professional
|
|
1330
|
+
{ slug: "conference", name: "Conference" },
|
|
1331
|
+
{ slug: "session", name: "Session" },
|
|
1332
|
+
{ slug: "presentation", name: "Presentation" },
|
|
1333
|
+
{ slug: "workshop", name: "Workshop" },
|
|
1334
|
+
{ slug: "seminar", name: "Seminar" },
|
|
1335
|
+
{ slug: "keynote", name: "Keynote" },
|
|
1336
|
+
{ slug: "panel", name: "Panel" },
|
|
1337
|
+
// Community
|
|
1338
|
+
{ slug: "meeting", name: "Meeting" },
|
|
1339
|
+
{ slug: "town-hall", name: "Town Hall" },
|
|
1340
|
+
{ slug: "agenda-item", name: "Agenda Item" },
|
|
1341
|
+
{ slug: "motion", name: "Motion" },
|
|
1342
|
+
{ slug: "amendment", name: "Amendment" },
|
|
1343
|
+
{ slug: "vote", name: "Vote" },
|
|
1344
|
+
{ slug: "discussion", name: "Discussion" },
|
|
1345
|
+
// General
|
|
1346
|
+
{ slug: "event", name: "Event" },
|
|
1347
|
+
{ slug: "activity", name: "Activity" },
|
|
1348
|
+
{ slug: "action", name: "Action" }
|
|
1349
|
+
];
|
|
1350
|
+
const types = [];
|
|
1351
|
+
for (const def of defaults) {
|
|
1352
|
+
const type = await this.getOrCreate(def.slug, def.name);
|
|
1353
|
+
types.push(type);
|
|
1354
|
+
}
|
|
1355
|
+
return types;
|
|
1356
|
+
}
|
|
1357
|
+
// ============================================
|
|
1358
|
+
// Tenant Helper Methods
|
|
1359
|
+
// ============================================
|
|
1360
|
+
/**
|
|
1361
|
+
* Find all event types for a specific tenant
|
|
1362
|
+
*
|
|
1363
|
+
* @param tenantId - Tenant ID to filter by
|
|
1364
|
+
* @returns Array of EventType instances for the tenant
|
|
1365
|
+
*/
|
|
1366
|
+
async findByTenant(tenantId2) {
|
|
1367
|
+
return this.list({ where: { tenantId: tenantId2 } });
|
|
1368
|
+
}
|
|
1369
|
+
/**
|
|
1370
|
+
* Find all global event types (no tenant association)
|
|
1371
|
+
*
|
|
1372
|
+
* @returns Array of EventType instances with no tenant
|
|
1373
|
+
*/
|
|
1374
|
+
async findGlobal() {
|
|
1375
|
+
return this.list({ where: { tenantId: null } });
|
|
1376
|
+
}
|
|
1377
|
+
/**
|
|
1378
|
+
* Find event types for a tenant including global types
|
|
1379
|
+
*
|
|
1380
|
+
* @param tenantId - Tenant ID to filter by
|
|
1381
|
+
* @returns Array of EventType instances for the tenant and global types
|
|
1382
|
+
*/
|
|
1383
|
+
async findWithGlobals(tenantId2) {
|
|
1384
|
+
return this.query(
|
|
1385
|
+
`SELECT * FROM ${this.tableName} WHERE tenant_id = ? OR tenant_id IS NULL`,
|
|
1386
|
+
[tenantId2]
|
|
1387
|
+
);
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
const EventTypeCollection$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1391
|
+
__proto__: null,
|
|
1392
|
+
EventTypeCollection
|
|
1393
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
1394
|
+
export {
|
|
1395
|
+
EVENTS_MODULE_META,
|
|
1396
|
+
EVENTS_UI_SLOTS,
|
|
1397
|
+
Event,
|
|
1398
|
+
EventAsset,
|
|
1399
|
+
EventAssetCollection,
|
|
1400
|
+
EventCollection,
|
|
1401
|
+
EventParticipant,
|
|
1402
|
+
EventParticipantCollection,
|
|
1403
|
+
EventSeries,
|
|
1404
|
+
EventSeriesCollection,
|
|
1405
|
+
EventType,
|
|
1406
|
+
EventTypeCollection,
|
|
1407
|
+
calculateDuration,
|
|
1408
|
+
calculateNextOccurrence,
|
|
1409
|
+
checkSchedulingConflict,
|
|
1410
|
+
formatDuration,
|
|
1411
|
+
formatEventDateRange,
|
|
1412
|
+
generateEventSlug,
|
|
1413
|
+
getEventStatusFromDates,
|
|
1414
|
+
isEventNow,
|
|
1415
|
+
parseRecurrencePattern,
|
|
1416
|
+
sortEventsByDate,
|
|
1417
|
+
validateEventStatus
|
|
1418
|
+
};
|
|
1419
|
+
//# sourceMappingURL=index.js.map
|