@timeback/caliper 0.2.1-beta.20260331191116 → 0.2.1

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.
@@ -1,972 +1,9 @@
1
- /**
2
- * Timeback Shared Primitives
3
- *
4
- * Core types used across multiple Timeback protocols.
5
- *
6
- * Organization:
7
- * - Shared types (this file): Used by multiple protocols (Caliper, OneRoster, etc.)
8
- * - Protocol-specific types: Live in their respective protocols/X/primitives.ts files
9
- *
10
- * What belongs here:
11
- * - TimebackSubject - Used in OneRoster courses AND Caliper events
12
- * - TimebackGrade - Used across OneRoster, Caliper, and QTI
13
- * - IMSErrorResponse - IMS Global standard used by multiple 1EdTech protocols
14
- *
15
- * What doesn't belong here:
16
- * - OneRoster-specific: protocols/oneroster/primitives.ts
17
- * - QTI-specific: protocols/qti/primitives.ts
18
- */
19
-
20
- // ─────────────────────────────────────────────────────────────────────────────
21
- // TIMEBACK SHARED TYPES
22
- // ─────────────────────────────────────────────────────────────────────────────
23
-
24
- /**
25
- * Valid Timeback subject values.
26
- * Used in OneRoster courses and Caliper events.
27
- */
28
- type TimebackSubject =
29
- | 'Reading'
30
- | 'Language'
31
- | 'Vocabulary'
32
- | 'Social Studies'
33
- | 'Writing'
34
- | 'Science'
35
- | 'FastMath'
36
- | 'Math'
37
- | 'None'
38
- | 'Other'
39
-
40
- /**
41
- * Timeback Profile Types
42
- *
43
- * First-class types for the Timeback Caliper profile, including
44
- * ActivityCompletedEvent and TimeSpentEvent.
45
- */
46
-
47
-
48
-
49
- // ═══════════════════════════════════════════════════════════════════════════════
50
- // TIMEBACK ACTIVITY CONTEXT
51
- // ═══════════════════════════════════════════════════════════════════════════════
52
-
53
- // ═══════════════════════════════════════════════════════════════════════════════
54
- // TIMEBACK USER
55
- // ═══════════════════════════════════════════════════════════════════════════════
56
-
57
- /**
58
- * User role in the Timeback platform.
59
- */
60
- type TimebackUserRole = 'student' | 'teacher' | 'admin' | 'guide'
61
-
62
- /**
63
- * Timeback user entity.
64
- *
65
- * Represents a user in the Timeback platform. The `id` should ideally be
66
- * the OneRoster URL for the user when available.
67
- *
68
- * @example
69
- * ```typescript
70
- * const user: TimebackUser = {
71
- * id: 'https://api.alpha-1edtech.ai/ims/oneroster/rostering/v1p2/users/123',
72
- * type: 'TimebackUser',
73
- * email: 'student@example.edu',
74
- * name: 'Jane Doe',
75
- * role: 'student',
76
- * }
77
- * ```
78
- */
79
- interface TimebackUser {
80
- /** User identifier (IRI format, preferably OneRoster URL) */
81
- id: string
82
- /** Must be 'TimebackUser' */
83
- type: 'TimebackUser'
84
- /** User email address */
85
- email: string
86
- /** User display name */
87
- name?: string
88
- /** User role */
89
- role?: TimebackUserRole
90
- /** Additional custom attributes */
91
- extensions?: Record<string, unknown>
92
- /** Index signature for Caliper compatibility */
93
- [key: string]: unknown
94
- }
95
-
96
- /**
97
- * Application reference within activity context.
98
- */
99
- interface TimebackApp {
100
- /** Application identifier (IRI format) */
101
- id?: string
102
- /** Application name */
103
- name: string
104
- /** Additional custom attributes */
105
- extensions?: Record<string, unknown>
106
- }
107
-
108
- /**
109
- * Course reference within activity context.
110
- */
111
- interface TimebackCourse {
112
- /** Course identifier (IRI format, preferably OneRoster URL) */
113
- id?: string
114
- /** Course name */
115
- name?: string
116
- /** Additional custom attributes */
117
- extensions?: Record<string, unknown>
118
- }
119
-
120
- /**
121
- * Activity reference within activity context.
122
- */
123
- interface TimebackActivity {
124
- /** Activity identifier (IRI format) */
125
- id?: string
126
- /** Activity name */
127
- name: string
128
- /** Additional custom attributes */
129
- extensions?: Record<string, unknown>
130
- }
131
-
132
- /**
133
- * Timeback activity context.
134
- *
135
- * Represents the context where an event was recorded, including
136
- * subject, application, course, and activity information.
137
- *
138
- * @example
139
- * ```typescript
140
- * const context: TimebackActivityContext = {
141
- * id: 'https://myapp.example.com/activities/123',
142
- * type: 'TimebackActivityContext',
143
- * subject: 'Math',
144
- * app: { name: 'My Learning App' },
145
- * course: { name: 'Algebra 101' },
146
- * activity: { name: 'Chapter 1 Quiz' },
147
- * }
148
- * ```
149
- */
150
- interface TimebackActivityContext {
151
- /** Context identifier (IRI format) */
152
- id: string
153
- /** Must be 'TimebackActivityContext' */
154
- type: 'TimebackActivityContext'
155
- /** Subject area */
156
- subject: TimebackSubject
157
- /** Application where event was recorded */
158
- app: TimebackApp
159
- /** Course where event was recorded */
160
- course: TimebackCourse
161
- /** Activity where event was recorded */
162
- activity?: TimebackActivity
163
- /** Whether to process this event */
164
- process?: boolean
165
- /** Index signature for Caliper compatibility */
166
- [key: string]: unknown
167
- }
168
-
169
- // ═══════════════════════════════════════════════════════════════════════════════
170
- // ACTIVITY METRICS
171
- // ═══════════════════════════════════════════════════════════════════════════════
172
-
173
- /**
174
- * Types of activity metrics.
175
- */
176
- type ActivityMetricType =
177
- | 'xpEarned'
178
- | 'totalQuestions'
179
- | 'correctQuestions'
180
- | 'masteredUnits'
181
-
182
- /**
183
- * Individual activity metric.
184
- *
185
- * @example
186
- * ```typescript
187
- * const metric: TimebackActivityMetric = {
188
- * type: 'correctQuestions',
189
- * value: 8,
190
- * }
191
- * ```
192
- */
193
- interface TimebackActivityMetric {
194
- /** Metric type */
195
- type: ActivityMetricType
196
- /** Metric value */
197
- value: number
198
- /** Additional custom attributes */
199
- extensions?: Record<string, unknown>
200
- }
201
-
202
- /**
203
- * Collection of activity metrics.
204
- *
205
- * @example
206
- * ```typescript
207
- * const metrics: TimebackActivityMetricsCollection = {
208
- * id: 'https://myapp.example.com/metrics/123',
209
- * type: 'TimebackActivityMetricsCollection',
210
- * attempt: 1,
211
- * items: [
212
- * { type: 'totalQuestions', value: 10 },
213
- * { type: 'correctQuestions', value: 8 },
214
- * { type: 'xpEarned', value: 150 },
215
- * ],
216
- * extensions: { pctCompleteApp: 67 },
217
- * }
218
- * ```
219
- */
220
- interface TimebackActivityMetricsCollection {
221
- /** Collection identifier (IRI format) */
222
- id: string
223
- /** Must be 'TimebackActivityMetricsCollection' */
224
- type: 'TimebackActivityMetricsCollection'
225
- /** Attempt number (1-based) */
226
- attempt?: number
227
- /** Array of metrics */
228
- items: TimebackActivityMetric[]
229
- /**
230
- * Additional custom attributes.
231
- *
232
- * Common fields:
233
- * - `pctCompleteApp`: App-defined course completion percentage (0–100)
234
- */
235
- extensions?: Record<string, unknown>
236
- /** Index signature for Caliper compatibility */
237
- [key: string]: unknown
238
- }
239
-
240
- // ═══════════════════════════════════════════════════════════════════════════════
241
- // TIME SPENT METRICS
242
- // ═══════════════════════════════════════════════════════════════════════════════
243
-
244
- /**
245
- * Types of time spent metrics.
246
- */
247
- type TimeSpentMetricType = 'active' | 'inactive' | 'waste' | 'unknown' | 'anti-pattern'
248
-
249
- /**
250
- * Individual time spent metric.
251
- *
252
- * @example
253
- * ```typescript
254
- * const metric: TimeSpentMetric = {
255
- * type: 'active',
256
- * value: 1800, // 30 minutes in seconds
257
- * startDate: '2024-01-15T10:00:00Z',
258
- * endDate: '2024-01-15T10:30:00Z',
259
- * }
260
- * ```
261
- */
262
- interface TimeSpentMetric {
263
- /** Metric type */
264
- type: TimeSpentMetricType
265
- /** Time spent in seconds (max 86400 = 24 hours) */
266
- value: number
267
- /** Sub-type for additional categorization */
268
- subType?: string
269
- /** Start of the time period */
270
- startDate?: string
271
- /** End of the time period */
272
- endDate?: string
273
- /** Additional custom attributes */
274
- extensions?: Record<string, unknown>
275
- }
276
-
277
- /**
278
- * Collection of time spent metrics.
279
- *
280
- * @example
281
- * ```typescript
282
- * const metrics: TimebackTimeSpentMetricsCollection = {
283
- * id: 'https://myapp.example.com/time-metrics/123',
284
- * type: 'TimebackTimeSpentMetricsCollection',
285
- * items: [
286
- * { type: 'active', value: 1800 },
287
- * { type: 'inactive', value: 300 },
288
- * ],
289
- * }
290
- * ```
291
- */
292
- interface TimebackTimeSpentMetricsCollection {
293
- /** Collection identifier (IRI format) */
294
- id: string
295
- /** Must be 'TimebackTimeSpentMetricsCollection' */
296
- type: 'TimebackTimeSpentMetricsCollection'
297
- /** Array of time spent metrics */
298
- items: TimeSpentMetric[]
299
- /** Additional custom attributes */
300
- extensions?: Record<string, unknown>
301
- /** Index signature for Caliper compatibility */
302
- [key: string]: unknown
303
- }
304
-
305
- // ═══════════════════════════════════════════════════════════════════════════════
306
- // TIMEBACK EVENTS
307
- // ═══════════════════════════════════════════════════════════════════════════════
308
-
309
- /**
310
- * Base properties common to all Timeback events.
311
- */
312
- interface TimebackEventBase {
313
- /** JSON-LD context */
314
- '@context': 'http://purl.imsglobal.org/ctx/caliper/v1p2'
315
- /** Unique identifier (URN UUID format) */
316
- id: string
317
- /** The user who performed the action */
318
- actor: TimebackUser
319
- /** The activity context */
320
- object: TimebackActivityContext
321
- /** ISO 8601 datetime when event occurred */
322
- eventTime: string
323
- /** Must be 'TimebackProfile' */
324
- profile: 'TimebackProfile'
325
- /** Application context (IRI or entity) */
326
- edApp?: string | Record<string, unknown>
327
- /** Target segment within object */
328
- target?: string | Record<string, unknown>
329
- /** Referring context */
330
- referrer?: string | Record<string, unknown>
331
- /** Organization/group context */
332
- group?: string | Record<string, unknown>
333
- /** User's membership/role */
334
- membership?: string | Record<string, unknown>
335
- /** Current user session */
336
- session?: string | Record<string, unknown>
337
- /** LTI session context */
338
- federatedSession?: string | Record<string, unknown>
339
- /** Additional custom attributes */
340
- extensions?: Record<string, unknown>
341
- }
342
-
343
- /**
344
- * Timeback Activity Completed Event.
345
- *
346
- * Records when a student completes an activity, along with performance metrics.
347
- *
348
- * @example
349
- * ```typescript
350
- * const event: ActivityCompletedEvent = {
351
- * '@context': 'http://purl.imsglobal.org/ctx/caliper/v1p2',
352
- * id: 'urn:uuid:c51570e4-f8ed-4c18-bb3a-dfe51b2cc594',
353
- * type: 'ActivityEvent',
354
- * action: 'Completed',
355
- * actor: {
356
- * id: 'https://api.example.com/users/123',
357
- * type: 'TimebackUser',
358
- * email: 'student@example.edu',
359
- * },
360
- * object: {
361
- * id: 'https://myapp.example.com/activities/456',
362
- * type: 'TimebackActivityContext',
363
- * subject: 'Math',
364
- * app: { name: 'My Learning App' },
365
- * },
366
- * eventTime: '2024-01-15T14:30:00Z',
367
- * profile: 'TimebackProfile',
368
- * generated: {
369
- * id: 'https://myapp.example.com/metrics/789',
370
- * type: 'TimebackActivityMetricsCollection',
371
- * items: [
372
- * { type: 'totalQuestions', value: 10 },
373
- * { type: 'correctQuestions', value: 8 },
374
- * ],
375
- * },
376
- * }
377
- * ```
378
- */
379
- interface ActivityCompletedEvent extends TimebackEventBase {
380
- /** Must be 'ActivityEvent' */
381
- type: 'ActivityEvent'
382
- /** Must be 'Completed' */
383
- action: 'Completed'
384
- /** Activity metrics generated from this completion */
385
- generated: TimebackActivityMetricsCollection
386
- }
387
-
388
- /**
389
- * Timeback Time Spent Event.
390
- *
391
- * Records time spent on an activity, categorized by engagement type.
392
- *
393
- * @example
394
- * ```typescript
395
- * const event: TimeSpentEvent = {
396
- * '@context': 'http://purl.imsglobal.org/ctx/caliper/v1p2',
397
- * id: 'urn:uuid:d62681f5-g9fe-5d29-cc4b-efg62c3dd695',
398
- * type: 'TimeSpentEvent',
399
- * action: 'SpentTime',
400
- * actor: {
401
- * id: 'https://api.example.com/users/123',
402
- * type: 'TimebackUser',
403
- * email: 'student@example.edu',
404
- * },
405
- * object: {
406
- * id: 'https://myapp.example.com/activities/456',
407
- * type: 'TimebackActivityContext',
408
- * subject: 'Reading',
409
- * app: { name: 'My Learning App' },
410
- * },
411
- * eventTime: '2024-01-15T15:00:00Z',
412
- * profile: 'TimebackProfile',
413
- * generated: {
414
- * id: 'https://myapp.example.com/time-metrics/789',
415
- * type: 'TimebackTimeSpentMetricsCollection',
416
- * items: [
417
- * { type: 'active', value: 1800 },
418
- * { type: 'inactive', value: 300 },
419
- * ],
420
- * },
421
- * }
422
- * ```
423
- */
424
- interface TimeSpentEvent extends TimebackEventBase {
425
- /** Must be 'TimeSpentEvent' */
426
- type: 'TimeSpentEvent'
427
- /** Must be 'SpentTime' */
428
- action: 'SpentTime'
429
- /** Time spent metrics generated from this session */
430
- generated: TimebackTimeSpentMetricsCollection
431
- }
432
-
433
- /**
434
- * Union of all Timeback event types.
435
- */
436
- type TimebackEvent = ActivityCompletedEvent | TimeSpentEvent
437
-
438
- /**
439
- * Caliper Event Types
440
- *
441
- * Types for Caliper Analytics events and envelopes.
442
- */
443
-
444
-
445
-
446
- /**
447
- * Supported Caliper profiles.
448
- */
449
- type CaliperProfile =
450
- | 'AnnotationProfile'
451
- | 'AssessmentProfile'
452
- | 'ToolUseProfile'
453
- | 'GeneralProfile'
454
- | 'FeedbackProfile'
455
- | 'MediaProfile'
456
- | 'SurveyProfile'
457
- | 'ResourceManagementProfile'
458
- | 'ForumProfile'
459
- | 'AssignableProfile'
460
- | 'GradingProfile'
461
- | 'ReadingProfile'
462
- | 'SessionProfile'
463
- | 'SearchProfile'
464
- | 'ToolLaunchProfile'
465
- | 'TimebackProfile'
466
-
467
- /**
468
- * Base Caliper entity representation.
469
- *
470
- * Many Caliper fields can be provided either as an IRI string or as an
471
- * object-shaped entity, so the shared protocol model keeps this flexible.
472
- */
473
- type CaliperEntity = string | { [key: string]: unknown }
474
-
475
- /**
476
- * One actor-object shape for sending events.
477
- *
478
- * This is a structured actor object with an `id`, a `type`, and an
479
- * `extensions` bag containing `email`. It is one valid actor-object shape,
480
- * not the only representation allowed by `CaliperEvent.actor`.
481
- */
482
- interface CaliperActor {
483
- /** Unique identifier (IRI format) */
484
- id: string
485
- /** Entity type (e.g., 'Person', 'TimebackUser') */
486
- type: string
487
- /** Extensions carried on this actor-object shape */
488
- extensions: {
489
- /** Actor email on this actor-object shape */
490
- email: string
491
- /** Additional extension properties */
492
- [key: string]: unknown
493
- }
494
- }
495
-
496
- /**
497
- * Caliper Event.
498
- *
499
- * Represents a learning activity event conforming to IMS Caliper v1.2.
500
- */
501
- interface CaliperEvent {
502
- /** JSON-LD context */
503
- '@context'?: string
504
- /** Unique identifier (URN UUID format) */
505
- id: string
506
- /** Event type */
507
- type: string
508
- /** The agent who initiated the event (IRI string, CaliperActor, TimebackUser, or generic entity) */
509
- actor: CaliperEntity | CaliperActor | TimebackUser
510
- /** The action or predicate */
511
- action: string
512
- /** The object of the interaction */
513
- object: CaliperEntity
514
- /** ISO 8601 datetime when event occurred */
515
- eventTime: string
516
- /** Profile governing interpretation */
517
- profile: CaliperProfile
518
- /** Application context */
519
- edApp?: CaliperEntity
520
- /** Entity generated as result */
521
- generated?: CaliperEntity
522
- /** Target segment within object */
523
- target?: CaliperEntity
524
- /** Referring context */
525
- referrer?: CaliperEntity
526
- /** Organization/group context */
527
- group?: CaliperEntity
528
- /** User's membership/role */
529
- membership?: CaliperEntity
530
- /** Current user session */
531
- session?: CaliperEntity
532
- /** LTI session context */
533
- federatedSession?: CaliperEntity
534
- /** Additional custom attributes */
535
- extensions?: Record<string, unknown>
536
- }
537
-
538
- /**
539
- * Caliper Envelope.
540
- *
541
- * Container for transmitting Caliper events to the API.
542
- */
543
- interface CaliperEnvelope {
544
- /** Sensor identifier (IRI format) */
545
- sensor: string
546
- /** ISO 8601 datetime when data was sent */
547
- sendTime: string
548
- /** Caliper data version */
549
- dataVersion: 'http://purl.imsglobal.org/ctx/caliper/v1p2'
550
- /** Array of events or entities */
551
- data: CaliperEvent[]
552
- /** Allow additional properties for forward-compatibility and transformer passthrough. */
553
- [key: string]: unknown
554
- }
555
-
556
- /**
557
- * Result of sending events.
558
- */
559
- interface SendEventsResult {
560
- /** Job ID for tracking async processing (undefined when the platform does not return one) */
561
- jobId: string | undefined
562
- }
563
-
564
- /**
565
- * Individual event result from job completion.
566
- */
567
- interface EventResult {
568
- /** Allocated internal ID */
569
- allocatedId: string
570
- /** External event ID */
571
- externalId: string
572
- }
573
-
574
- /**
575
- * Job status response.
576
- */
577
- interface JobStatus {
578
- id: string
579
- state: 'waiting' | 'active' | 'completed' | 'failed'
580
- returnValue?: {
581
- status: 'success' | 'error'
582
- results: EventResult[]
583
- }
584
- processedOn?: string | null
585
- }
586
-
587
- /**
588
- * Stored Caliper event (from list/get).
589
- *
590
- * This represents an event as returned by the API, which differs from the
591
- * input CaliperEvent format. The API adds internal fields and transforms
592
- * the original event ID to `externalId`.
593
- *
594
- * @remarks
595
- * **API Docs Drift**: The official OpenAPI spec (caliper-api.yaml) does not
596
- * accurately document this response structure. This type was derived from
597
- * actual API responses. Key differences:
598
- * - `id` is a number (internal DB ID), not a string
599
- * - `externalId` contains the original URN UUID (use this for `get()` calls)
600
- * - Response is wrapped in `{ events: StoredEvent[] }` for list, `{ event: StoredEvent }` for get
601
- */
602
- interface StoredEvent {
603
- /** Internal numeric ID (allocated by the database) */
604
- id: number
605
- /** Original event ID (URN UUID format) - use this for get() calls */
606
- externalId: string
607
- /** Sensor that sent the event */
608
- sensor: string
609
- /** Event type (e.g., 'ActivityEvent', 'Event') */
610
- type: string
611
- /** Caliper profile (e.g., 'TimebackProfile') */
612
- profile?: string
613
- /** The action or predicate */
614
- action: string
615
- /** When the event occurred */
616
- eventTime: string
617
- /** When the event was sent */
618
- sendTime: string
619
- /** When the record was last updated */
620
- updated_at: string | null
621
- /** When the record was created */
622
- created_at: string
623
- /** When the record was deleted (soft delete) */
624
- deleted_at: string | null
625
- /** The agent who initiated the event */
626
- actor: CaliperEntity
627
- /** The object of the event */
628
- object: CaliperEntity
629
- /** Generated entity (e.g., result, score) */
630
- generated?: CaliperEntity | null
631
- /** Target entity */
632
- target?: CaliperEntity | null
633
- /** Referrer entity */
634
- referrer?: CaliperEntity | null
635
- /** EdApp entity */
636
- edApp?: CaliperEntity | null
637
- /** Group/organization entity */
638
- group?: CaliperEntity | null
639
- /** Membership entity */
640
- membership?: CaliperEntity | null
641
- /** Session entity */
642
- session?: CaliperEntity | null
643
- /** Federated session entity */
644
- federatedSession?: CaliperEntity | null
645
- /** Extension data */
646
- extensions?: Record<string, unknown> | null
647
- /** Client application ID */
648
- clientAppId?: string | null
649
- }
650
-
651
- /**
652
- * Result from listing events.
653
- */
654
- interface ListEventsResult {
655
- events: StoredEvent[]
656
- pagination: PaginationMeta
657
- }
658
-
659
- // ═══════════════════════════════════════════════════════════════════════════════
660
- // QUESTION EVENT TYPES (Standard Caliper)
661
- // ═══════════════════════════════════════════════════════════════════════════════
662
-
663
- /**
664
- * AssessmentItemEvent (Question Seen / Question Answered).
665
- *
666
- * Represents when a student is presented with a question (Started)
667
- * or submits an answer (Completed).
668
- */
669
- interface AssessmentItemEvent extends CaliperEvent {
670
- type: 'AssessmentItemEvent'
671
- action: 'Started' | 'Completed'
672
- profile: 'AssessmentProfile'
673
- }
674
-
675
- /**
676
- * GradeEvent for question-level grading.
677
- *
678
- * Represents when a question response is graded, with a Score entity
679
- * containing `scoreType: "QUESTION_RESULT"` in the `generated` field.
680
- */
681
- interface QuestionGradeEvent extends CaliperEvent {
682
- type: 'GradeEvent'
683
- action: 'Graded'
684
- profile: 'GradingProfile'
685
- }
686
-
687
- /**
688
- * API Response Types
689
- *
690
- * Types for Caliper API responses.
691
- *
692
- * @remarks
693
- * **IMPORTANT - API Docs Drift**: The official API documentation (caliper/response.yaml
694
- * and caliper-api.yaml) does NOT accurately reflect actual API responses. The types
695
- * in this file were derived from testing actual API responses. See individual type
696
- * comments for specific discrepancies.
697
- */
698
-
699
-
700
-
701
- /**
702
- * Generic API response wrapper.
703
- */
704
- interface ApiResponse<T> {
705
- status: 'success' | 'error'
706
- message?: string
707
- data?: T
708
- }
709
-
710
- /**
711
- * Pagination metadata returned by list endpoints.
712
- */
713
- interface PaginationMeta {
714
- /** Total number of items across all pages */
715
- total: number
716
- /** Total number of pages */
717
- totalPages: number
718
- /** Current page number (1-indexed) */
719
- currentPage: number
720
- /** Number of items per page */
721
- limit: number
722
- }
723
-
724
- /**
725
- * Response from GET /caliper/events (list events).
726
- *
727
- * @remarks
728
- * **API Docs Drift**: Official docs (caliper/response.yaml) incorrectly show
729
- * `{ status, message, errors? }`. Actual response is `{ events, pagination }`.
730
- */
731
- interface ListEventsResponse {
732
- /** Array of stored events */
733
- events: StoredEvent[]
734
- /** Pagination metadata */
735
- pagination: PaginationMeta
736
- }
737
-
738
- /**
739
- * Response from GET /caliper/events/:externalId (get single event).
740
- *
741
- * @remarks
742
- * **API Docs Drift**: Official docs (caliper/response.yaml) incorrectly show
743
- * `{ status, message, errors? }`. Actual response is `{ status, event }`.
744
- */
745
- interface GetEventResponse {
746
- /** Status indicator */
747
- status: 'success' | 'error'
748
- /** The requested event */
749
- event: StoredEvent
750
- }
751
-
752
- /**
753
- * Response from POST /caliper/event (send events).
754
- *
755
- * @remarks
756
- * **API Docs Drift**: Official docs (caliper/response.yaml) incorrectly show
757
- * `{ status, message, errors? }`. Actual response is `{ jobId }`.
758
- * Use the jobId with `jobs.getStatus()` to track processing.
759
- */
760
- interface SendEventsResponse {
761
- /** Job ID for tracking async processing */
762
- jobId: string
763
- }
764
-
765
- /**
766
- * Job status response payload (GET /jobs/{jobId}/status).
767
- *
768
- * @remarks
769
- * This endpoint is correctly documented in caliper/response.yaml.
770
- */
771
- interface JobStatusResponse {
772
- job: JobStatus
773
- }
774
-
775
- /**
776
- * Options for waitForCompletion polling.
777
- */
778
- interface WaitForCompletionOptions {
779
- /** Maximum time to wait in milliseconds (default: 30000) */
780
- timeoutMs?: number
781
- /** Interval between status checks in milliseconds (default: 1000) */
782
- pollIntervalMs?: number
783
- }
784
-
785
- /**
786
- * Validation result from the validate endpoint.
787
- */
788
- interface ValidationResult {
789
- /** Whether validation succeeded */
790
- status: 'success' | 'error'
791
- /** Human-readable message */
792
- message?: string
793
- /** Validation errors (if any) */
794
- errors?: unknown
795
- }
1
+ export * from '@timeback/types/protocols/caliper';
2
+ export { ActivityCompletedInput, CaliperListEventsParams as ListEventsParams, QuestionAnsweredInput, QuestionGradedInput, QuestionSeenInput, TimeSpentInput } from '@timeback/types/zod';
796
3
 
797
4
  /**
798
5
  * Caliper JSON-LD context version.
799
6
  */
800
7
  declare const CALIPER_DATA_VERSION = "http://purl.imsglobal.org/ctx/caliper/v1p2";
801
8
 
802
- type input<T> = T extends {
803
- _zod: {
804
- input: any;
805
- };
806
- } ? T["_zod"]["input"] : unknown;
807
-
808
- /**
809
- * Caliper Schemas
810
- *
811
- * Zod schemas for the IMS Caliper Analytics standard with Timeback Profile.
812
- */
813
-
814
-
815
-
816
- // ═══════════════════════════════════════════════════════════════════════════════
817
- // BUILDER INPUTS
818
- // ═══════════════════════════════════════════════════════════════════════════════
819
-
820
- declare const ActivityCompletedInput = z
821
- .object({
822
- actor: TimebackUser,
823
- object: TimebackActivityContext,
824
- metrics: z.array(TimebackActivityMetric).min(1, 'metrics must contain at least one metric'),
825
- eventTime: IsoDateTimeString.optional(),
826
- metricsId: z.string().optional(),
827
- id: z.string().optional(),
828
- /** Event-level extensions */
829
- extensions: z.record(z.string(), z.unknown()).optional(),
830
- /**
831
- * Application context (IRI or entity).
832
- *
833
- * Maps to `edApp` in the Caliper event. Identifies the educational
834
- * application where the event occurred.
835
- */
836
- edApp: z.union([z.string(), z.record(z.string(), z.unknown())]).optional(),
837
- /**
838
- * Session context (IRI or entity).
839
- *
840
- * Maps to `session` in the Caliper event. Used for event-to-session
841
- * correlation (e.g., linking heartbeats with completions via runId).
842
- */
843
- session: z.union([z.string(), z.record(z.string(), z.unknown())]).optional(),
844
- /**
845
- * Attempt number (1-based).
846
- *
847
- * Maps to `generated.attempt` in the Caliper event.
848
- */
849
- attempt: z.number().int().min(1).optional(),
850
- /**
851
- * Extensions for the generated metrics collection.
852
- *
853
- * Maps to `generated.extensions` in the Caliper event.
854
- * Use `generatedExtensions.pctCompleteApp` (0–100) for app-reported course progress.
855
- */
856
- generatedExtensions: z
857
- .object({
858
- /**
859
- * App-reported course progress (per enrollment), as a percentage from 0–100.
860
- *
861
- * This is emitted to Caliper as `generated.extensions.pctCompleteApp`.
862
- *
863
- * @remarks
864
- * This value is not clamped here (Caliper client keeps the raw shape).
865
- */
866
- pctCompleteApp: z.number().optional(),
867
- })
868
- .loose()
869
- .optional(),
870
- })
871
- .strict()
872
-
873
- // ═══════════════════════════════════════════════════════════════════════════════
874
- // TYPE EXPORTS (REQUEST INPUTS)
875
- // ═══════════════════════════════════════════════════════════════════════════════
876
-
877
- type ActivityCompletedInput = input<typeof ActivityCompletedInput>
878
-
879
- declare const TimeSpentInput = z
880
- .object({
881
- actor: TimebackUser,
882
- object: TimebackActivityContext,
883
- metrics: z.array(TimebackTimeMetric).min(1, 'metrics must contain at least one metric'),
884
- eventTime: IsoDateTimeString.optional(),
885
- metricsId: z.string().optional(),
886
- id: z.string().optional(),
887
- extensions: z.record(z.string(), z.unknown()).optional(),
888
- edApp: z.union([z.string(), z.record(z.string(), z.unknown())]).optional(),
889
- session: z.union([z.string(), z.record(z.string(), z.unknown())]).optional(),
890
- })
891
- .strict()
892
- type TimeSpentInput = input<typeof TimeSpentInput>
893
-
894
- declare const QuestionSeenInput = z
895
- .object({
896
- /** Actor (Person IRI or entity object with id, type, name, etc.) */
897
- actor: z.union([z.string(), CaliperActor, TimebackUser]),
898
- /** AssessmentItem being presented */
899
- object: AssessmentItemObject,
900
- /** Application identifier (IRI or entity) */
901
- edApp: CaliperEntity,
902
- /** Event identifier (auto-generated if omitted) */
903
- id: z.string().optional(),
904
- /** ISO 8601 datetime (defaults to now) */
905
- eventTime: IsoDateTimeString.optional(),
906
- /** Session context (IRI or entity) */
907
- session: CaliperEntity.optional(),
908
- /** Event-level extensions */
909
- extensions: z.record(z.string(), z.unknown()).optional(),
910
- })
911
- .strict()
912
- type QuestionSeenInput = input<typeof QuestionSeenInput>
913
-
914
- declare const QuestionAnsweredInput = z
915
- .object({
916
- /** Actor (Person IRI or entity object with id, type, name, etc.) */
917
- actor: z.union([z.string(), CaliperActor, TimebackUser]),
918
- /** AssessmentItem being answered */
919
- object: AssessmentItemObject,
920
- /** Application identifier (IRI or entity) */
921
- edApp: CaliperEntity,
922
- /** Response entity with optional attempt and timing */
923
- generated: ResponseGenerated.optional(),
924
- /** Event identifier (auto-generated if omitted) */
925
- id: z.string().optional(),
926
- /** ISO 8601 datetime (defaults to now) */
927
- eventTime: IsoDateTimeString.optional(),
928
- /** Session context (IRI or entity) */
929
- session: CaliperEntity.optional(),
930
- /** Event-level extensions */
931
- extensions: z.record(z.string(), z.unknown()).optional(),
932
- })
933
- .strict()
934
- type QuestionAnsweredInput = input<typeof QuestionAnsweredInput>
935
-
936
- declare const QuestionGradedInput = z
937
- .object({
938
- /** Actor (Person IRI or entity object with id, type, name, etc.) */
939
- actor: z.union([z.string(), CaliperActor, TimebackUser]),
940
- /** Attempt being graded (IRI) */
941
- object: z.string(),
942
- /** Score awarded for the question */
943
- generated: ScoreGenerated,
944
- /** Application identifier (IRI or entity) */
945
- edApp: CaliperEntity,
946
- /** Event identifier (auto-generated if omitted) */
947
- id: z.string().optional(),
948
- /** ISO 8601 datetime (defaults to now) */
949
- eventTime: IsoDateTimeString.optional(),
950
- /** Session context (IRI or entity) */
951
- session: CaliperEntity.optional(),
952
- /** Event-level extensions */
953
- extensions: z.record(z.string(), z.unknown()).optional(),
954
- })
955
- .strict()
956
- type QuestionGradedInput = input<typeof QuestionGradedInput>
957
-
958
- declare const CaliperListEventsParams = z
959
- .object({
960
- limit: z.number().int().positive().optional(),
961
- offset: z.number().int().min(0).optional(),
962
- sensor: NonEmptyString.optional(),
963
- startDate: IsoDateTimeString.optional(),
964
- endDate: IsoDateTimeString.optional(),
965
- actorId: NonEmptyString.optional(),
966
- actorEmail: z.email().optional(),
967
- })
968
- .strict()
969
- type CaliperListEventsParams = input<typeof CaliperListEventsParams>
970
-
971
- export { ActivityCompletedInput, CALIPER_DATA_VERSION, CaliperListEventsParams as ListEventsParams, QuestionAnsweredInput, QuestionGradedInput, QuestionSeenInput, TimeSpentInput };
972
- export type { ActivityCompletedEvent, ActivityMetricType, ApiResponse, AssessmentItemEvent, CaliperActor, CaliperEntity, CaliperEnvelope, CaliperEvent, CaliperProfile, EventResult, GetEventResponse, JobStatus, JobStatusResponse, ListEventsResponse, ListEventsResult, PaginationMeta, QuestionGradeEvent, SendEventsResponse, SendEventsResult, StoredEvent, TimeSpentEvent, TimeSpentMetric, TimeSpentMetricType, TimebackActivity, TimebackActivityContext, TimebackActivityMetric, TimebackActivityMetricsCollection, TimebackApp, TimebackCourse, TimebackEvent, TimebackEventBase, TimebackSubject, TimebackTimeSpentMetricsCollection, TimebackUser, TimebackUserRole, ValidationResult, WaitForCompletionOptions };
9
+ export { CALIPER_DATA_VERSION };