@happyvertical/smrt-education 0.57.9 → 0.57.10

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.
Files changed (57) hide show
  1. package/agents/catalog-sync.md +35 -0
  2. package/agents/ingestion.md +93 -0
  3. package/agents/learner-service.md +9 -0
  4. package/agents/source-import.md +9 -0
  5. package/agents/submission-service.md +18 -0
  6. package/dist/catalog-acquisition-service.d.ts +58 -0
  7. package/dist/catalog-acquisition-service.d.ts.map +1 -0
  8. package/dist/catalog-collections.d.ts +18 -0
  9. package/dist/catalog-collections.d.ts.map +1 -0
  10. package/dist/catalog-contracts.d.ts +88 -0
  11. package/dist/catalog-contracts.d.ts.map +1 -0
  12. package/dist/catalog-database-sync-store.d.ts +13 -0
  13. package/dist/catalog-database-sync-store.d.ts.map +1 -0
  14. package/dist/catalog-materialization-service.d.ts +78 -0
  15. package/dist/catalog-materialization-service.d.ts.map +1 -0
  16. package/dist/catalog-models.d.ts +63 -0
  17. package/dist/catalog-models.d.ts.map +1 -0
  18. package/dist/catalog-policy.d.ts +12 -0
  19. package/dist/catalog-policy.d.ts.map +1 -0
  20. package/dist/catalog-read-service.d.ts +44 -0
  21. package/dist/catalog-read-service.d.ts.map +1 -0
  22. package/dist/catalog-sync-service.d.ts +19 -0
  23. package/dist/catalog-sync-service.d.ts.map +1 -0
  24. package/dist/collections.d.ts +4 -1
  25. package/dist/collections.d.ts.map +1 -1
  26. package/dist/hearth-catalog-providers.d.ts +74 -0
  27. package/dist/hearth-catalog-providers.d.ts.map +1 -0
  28. package/dist/hearth-easy-peasy-grade4.d.ts +40 -0
  29. package/dist/hearth-easy-peasy-grade4.d.ts.map +1 -0
  30. package/dist/index.d.ts +28 -6
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +2279 -175
  33. package/dist/index.js.map +1 -1
  34. package/dist/ingestion-isolation.d.ts +8 -0
  35. package/dist/ingestion-isolation.d.ts.map +1 -0
  36. package/dist/ingestion.d.ts +103 -0
  37. package/dist/ingestion.d.ts.map +1 -0
  38. package/dist/ingestion.js +364 -0
  39. package/dist/ingestion.js.map +1 -0
  40. package/dist/learner-service.d.ts +74 -1
  41. package/dist/learner-service.d.ts.map +1 -1
  42. package/dist/manifest.json +2686 -481
  43. package/dist/smrt-knowledge.json +713 -14
  44. package/dist/source-import-service.d.ts +11 -1
  45. package/dist/source-import-service.d.ts.map +1 -1
  46. package/dist/sources/easy-peasy-parser.d.ts.map +1 -1
  47. package/dist/sources/google-drive-adapter.d.ts +125 -0
  48. package/dist/sources/google-drive-adapter.d.ts.map +1 -0
  49. package/dist/sources/illustrative-mathematics-parser.d.ts +8 -0
  50. package/dist/sources/illustrative-mathematics-parser.d.ts.map +1 -0
  51. package/dist/sources/oer-commons-rss-parser.d.ts +8 -0
  52. package/dist/sources/oer-commons-rss-parser.d.ts.map +1 -0
  53. package/dist/submission-service.d.ts +48 -1
  54. package/dist/submission-service.d.ts.map +1 -1
  55. package/dist/submissions.d.ts +18 -0
  56. package/dist/submissions.d.ts.map +1 -1
  57. package/package.json +16 -10
@@ -2,8 +2,1596 @@
2
2
  "version": "1.0.0",
3
3
  "timestamp": 0,
4
4
  "packageName": "@happyvertical/smrt-education",
5
- "packageVersion": "0.57.9",
5
+ "packageVersion": "0.57.10",
6
6
  "objects": {
7
+ "@happyvertical/smrt-education:CatalogProviderCollection": {
8
+ "name": "catalogprovidercollection",
9
+ "className": "CatalogProviderCollection",
10
+ "qualifiedName": "@happyvertical/smrt-education:CatalogProviderCollection",
11
+ "collection": "catalogproviders",
12
+ "filePath": "/home/runner/work/smrt/smrt/packages/education/src/catalog-collections.ts",
13
+ "packageName": "@happyvertical/smrt-education",
14
+ "fields": {},
15
+ "methods": {},
16
+ "decoratorConfig": {
17
+ "api": false,
18
+ "mcp": false,
19
+ "cli": false
20
+ },
21
+ "extends": "SmrtCollection",
22
+ "extendsTypeArg": "CatalogProvider",
23
+ "exportName": "CatalogProviderCollection",
24
+ "collectionExportName": "CatalogProviderCollectionCollection",
25
+ "schema": {
26
+ "tableName": "catalog_providers",
27
+ "ddl": "CREATE TABLE IF NOT EXISTS \"catalog_providers\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"provider_id\" TEXT NOT NULL,\n \"name\" TEXT NOT NULL,\n \"active\" BOOLEAN NOT NULL DEFAULT TRUE\n);",
28
+ "columns": {
29
+ "id": {
30
+ "type": "UUID",
31
+ "primaryKey": true,
32
+ "referenceKind": "id",
33
+ "notNull": true
34
+ },
35
+ "slug": {
36
+ "type": "TEXT",
37
+ "notNull": true
38
+ },
39
+ "context": {
40
+ "type": "TEXT",
41
+ "notNull": true,
42
+ "default": ""
43
+ },
44
+ "created_at": {
45
+ "type": "TIMESTAMP",
46
+ "notNull": true,
47
+ "default": "current_timestamp"
48
+ },
49
+ "updated_at": {
50
+ "type": "TIMESTAMP",
51
+ "notNull": true,
52
+ "default": "current_timestamp"
53
+ },
54
+ "provider_id": {
55
+ "type": "TEXT",
56
+ "notNull": true,
57
+ "unique": false
58
+ },
59
+ "name": {
60
+ "type": "TEXT",
61
+ "notNull": true,
62
+ "unique": false
63
+ },
64
+ "active": {
65
+ "type": "BOOLEAN",
66
+ "notNull": true,
67
+ "unique": false,
68
+ "default": true
69
+ }
70
+ },
71
+ "indexes": [
72
+ {
73
+ "name": "catalog_providers_slug_context_idx",
74
+ "columns": [
75
+ "slug",
76
+ "context"
77
+ ],
78
+ "unique": true
79
+ },
80
+ {
81
+ "name": "catalog_providers_created_at_idx",
82
+ "columns": [
83
+ "created_at"
84
+ ]
85
+ }
86
+ ],
87
+ "version": "f35557a4"
88
+ },
89
+ "importPath": "@happyvertical/smrt-education"
90
+ },
91
+ "@happyvertical/smrt-education:CatalogResourceCollection": {
92
+ "name": "catalogresourcecollection",
93
+ "className": "CatalogResourceCollection",
94
+ "qualifiedName": "@happyvertical/smrt-education:CatalogResourceCollection",
95
+ "collection": "catalogresources",
96
+ "filePath": "/home/runner/work/smrt/smrt/packages/education/src/catalog-collections.ts",
97
+ "packageName": "@happyvertical/smrt-education",
98
+ "fields": {},
99
+ "methods": {},
100
+ "decoratorConfig": {
101
+ "api": false,
102
+ "mcp": false,
103
+ "cli": false
104
+ },
105
+ "extends": "SmrtCollection",
106
+ "extendsTypeArg": "CatalogResource",
107
+ "exportName": "CatalogResourceCollection",
108
+ "collectionExportName": "CatalogResourceCollectionCollection",
109
+ "schema": {
110
+ "tableName": "catalog_resources",
111
+ "ddl": "CREATE TABLE IF NOT EXISTS \"catalog_resources\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"provider_id\" TEXT NOT NULL,\n \"stable_id\" TEXT NOT NULL,\n \"revision\" TEXT NOT NULL,\n \"canonical_url\" TEXT,\n \"title\" TEXT NOT NULL,\n \"supplied_description\" TEXT,\n \"author\" TEXT,\n \"subjects\" TEXT,\n \"grades\" TEXT,\n \"language\" TEXT,\n \"resource_type\" TEXT,\n \"parent_stable_id\" TEXT,\n \"available_formats\" TEXT,\n \"license_evidence\" TEXT,\n \"license_state\" TEXT DEFAULT 'unknown',\n \"visibility\" TEXT DEFAULT 'catalog',\n \"last_seen_run_id\" TEXT,\n \"withdrawn_at\" TEXT\n);",
112
+ "columns": {
113
+ "id": {
114
+ "type": "UUID",
115
+ "primaryKey": true,
116
+ "referenceKind": "id",
117
+ "notNull": true
118
+ },
119
+ "slug": {
120
+ "type": "TEXT",
121
+ "notNull": true
122
+ },
123
+ "context": {
124
+ "type": "TEXT",
125
+ "notNull": true,
126
+ "default": ""
127
+ },
128
+ "created_at": {
129
+ "type": "TIMESTAMP",
130
+ "notNull": true,
131
+ "default": "current_timestamp"
132
+ },
133
+ "updated_at": {
134
+ "type": "TIMESTAMP",
135
+ "notNull": true,
136
+ "default": "current_timestamp"
137
+ },
138
+ "provider_id": {
139
+ "type": "TEXT",
140
+ "notNull": true,
141
+ "unique": false
142
+ },
143
+ "stable_id": {
144
+ "type": "TEXT",
145
+ "notNull": true,
146
+ "unique": false
147
+ },
148
+ "revision": {
149
+ "type": "TEXT",
150
+ "notNull": true,
151
+ "unique": false
152
+ },
153
+ "canonical_url": {
154
+ "type": "TEXT",
155
+ "notNull": false,
156
+ "unique": false
157
+ },
158
+ "title": {
159
+ "type": "TEXT",
160
+ "notNull": true,
161
+ "unique": false
162
+ },
163
+ "supplied_description": {
164
+ "type": "TEXT",
165
+ "notNull": false,
166
+ "unique": false
167
+ },
168
+ "author": {
169
+ "type": "TEXT",
170
+ "notNull": false,
171
+ "unique": false
172
+ },
173
+ "subjects": {
174
+ "type": "TEXT",
175
+ "notNull": false,
176
+ "unique": false
177
+ },
178
+ "grades": {
179
+ "type": "TEXT",
180
+ "notNull": false,
181
+ "unique": false
182
+ },
183
+ "language": {
184
+ "type": "TEXT",
185
+ "notNull": false,
186
+ "unique": false
187
+ },
188
+ "resource_type": {
189
+ "type": "TEXT",
190
+ "notNull": false,
191
+ "unique": false
192
+ },
193
+ "parent_stable_id": {
194
+ "type": "TEXT",
195
+ "notNull": false,
196
+ "unique": false
197
+ },
198
+ "available_formats": {
199
+ "type": "TEXT",
200
+ "notNull": false,
201
+ "unique": false
202
+ },
203
+ "license_evidence": {
204
+ "type": "TEXT",
205
+ "notNull": false,
206
+ "unique": false
207
+ },
208
+ "license_state": {
209
+ "type": "TEXT",
210
+ "notNull": false,
211
+ "unique": false,
212
+ "default": "unknown"
213
+ },
214
+ "visibility": {
215
+ "type": "TEXT",
216
+ "notNull": false,
217
+ "unique": false,
218
+ "default": "catalog"
219
+ },
220
+ "last_seen_run_id": {
221
+ "type": "TEXT",
222
+ "notNull": false,
223
+ "unique": false
224
+ },
225
+ "withdrawn_at": {
226
+ "type": "TEXT",
227
+ "notNull": false,
228
+ "unique": false
229
+ }
230
+ },
231
+ "indexes": [
232
+ {
233
+ "name": "catalog_resources_slug_context_idx",
234
+ "columns": [
235
+ "slug",
236
+ "context"
237
+ ],
238
+ "unique": true
239
+ },
240
+ {
241
+ "name": "catalog_resources_created_at_idx",
242
+ "columns": [
243
+ "created_at"
244
+ ]
245
+ }
246
+ ],
247
+ "version": "441b7271"
248
+ },
249
+ "importPath": "@happyvertical/smrt-education"
250
+ },
251
+ "@happyvertical/smrt-education:CatalogSyncStateCollection": {
252
+ "name": "catalogsyncstatecollection",
253
+ "className": "CatalogSyncStateCollection",
254
+ "qualifiedName": "@happyvertical/smrt-education:CatalogSyncStateCollection",
255
+ "collection": "catalogsyncstates",
256
+ "filePath": "/home/runner/work/smrt/smrt/packages/education/src/catalog-collections.ts",
257
+ "packageName": "@happyvertical/smrt-education",
258
+ "fields": {},
259
+ "methods": {},
260
+ "decoratorConfig": {
261
+ "api": false,
262
+ "mcp": false,
263
+ "cli": false
264
+ },
265
+ "extends": "SmrtCollection",
266
+ "extendsTypeArg": "CatalogSyncState",
267
+ "exportName": "CatalogSyncStateCollection",
268
+ "collectionExportName": "CatalogSyncStateCollectionCollection",
269
+ "schema": {
270
+ "tableName": "catalog_sync_states",
271
+ "ddl": "CREATE TABLE IF NOT EXISTS \"catalog_sync_states\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"provider_id\" TEXT NOT NULL,\n \"cursor\" TEXT,\n \"run_id\" TEXT,\n \"complete\" BOOLEAN NOT NULL DEFAULT FALSE,\n \"paused\" BOOLEAN NOT NULL DEFAULT FALSE,\n \"pause_reason\" TEXT,\n \"imported_count\" INTEGER NOT NULL DEFAULT 0,\n \"failures\" TEXT,\n \"last_successful_at\" TEXT\n);",
272
+ "columns": {
273
+ "id": {
274
+ "type": "UUID",
275
+ "primaryKey": true,
276
+ "referenceKind": "id",
277
+ "notNull": true
278
+ },
279
+ "slug": {
280
+ "type": "TEXT",
281
+ "notNull": true
282
+ },
283
+ "context": {
284
+ "type": "TEXT",
285
+ "notNull": true,
286
+ "default": ""
287
+ },
288
+ "created_at": {
289
+ "type": "TIMESTAMP",
290
+ "notNull": true,
291
+ "default": "current_timestamp"
292
+ },
293
+ "updated_at": {
294
+ "type": "TIMESTAMP",
295
+ "notNull": true,
296
+ "default": "current_timestamp"
297
+ },
298
+ "provider_id": {
299
+ "type": "TEXT",
300
+ "notNull": true,
301
+ "unique": false
302
+ },
303
+ "cursor": {
304
+ "type": "TEXT",
305
+ "notNull": false,
306
+ "unique": false
307
+ },
308
+ "run_id": {
309
+ "type": "TEXT",
310
+ "notNull": false,
311
+ "unique": false
312
+ },
313
+ "complete": {
314
+ "type": "BOOLEAN",
315
+ "notNull": true,
316
+ "unique": false,
317
+ "default": false
318
+ },
319
+ "paused": {
320
+ "type": "BOOLEAN",
321
+ "notNull": true,
322
+ "unique": false,
323
+ "default": false
324
+ },
325
+ "pause_reason": {
326
+ "type": "TEXT",
327
+ "notNull": false,
328
+ "unique": false
329
+ },
330
+ "imported_count": {
331
+ "type": "INTEGER",
332
+ "notNull": true,
333
+ "unique": false,
334
+ "default": 0
335
+ },
336
+ "failures": {
337
+ "type": "TEXT",
338
+ "notNull": false,
339
+ "unique": false
340
+ },
341
+ "last_successful_at": {
342
+ "type": "TEXT",
343
+ "notNull": false,
344
+ "unique": false
345
+ }
346
+ },
347
+ "indexes": [
348
+ {
349
+ "name": "catalog_sync_states_slug_context_idx",
350
+ "columns": [
351
+ "slug",
352
+ "context"
353
+ ],
354
+ "unique": true
355
+ },
356
+ {
357
+ "name": "catalog_sync_states_created_at_idx",
358
+ "columns": [
359
+ "created_at"
360
+ ]
361
+ }
362
+ ],
363
+ "version": "52dc3ee1"
364
+ },
365
+ "importPath": "@happyvertical/smrt-education"
366
+ },
367
+ "@happyvertical/smrt-education:CatalogSelectionCollection": {
368
+ "name": "catalogselectioncollection",
369
+ "className": "CatalogSelectionCollection",
370
+ "qualifiedName": "@happyvertical/smrt-education:CatalogSelectionCollection",
371
+ "collection": "catalogselections",
372
+ "filePath": "/home/runner/work/smrt/smrt/packages/education/src/catalog-collections.ts",
373
+ "packageName": "@happyvertical/smrt-education",
374
+ "fields": {},
375
+ "methods": {},
376
+ "decoratorConfig": {
377
+ "api": false,
378
+ "mcp": false,
379
+ "cli": false
380
+ },
381
+ "extends": "SmrtCollection",
382
+ "extendsTypeArg": "CatalogSelection",
383
+ "exportName": "CatalogSelectionCollection",
384
+ "collectionExportName": "CatalogSelectionCollectionCollection",
385
+ "schema": {
386
+ "tableName": "catalog_selections",
387
+ "ddl": "CREATE TABLE IF NOT EXISTS \"catalog_selections\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" UUID NOT NULL,\n \"resource_id\" UUID NOT NULL,\n \"selected_by_user_id\" TEXT NOT NULL,\n \"selected_revision\" TEXT NOT NULL\n);",
388
+ "columns": {
389
+ "id": {
390
+ "type": "UUID",
391
+ "primaryKey": true,
392
+ "referenceKind": "id",
393
+ "notNull": true
394
+ },
395
+ "slug": {
396
+ "type": "TEXT",
397
+ "notNull": true
398
+ },
399
+ "context": {
400
+ "type": "TEXT",
401
+ "notNull": true,
402
+ "default": ""
403
+ },
404
+ "created_at": {
405
+ "type": "TIMESTAMP",
406
+ "notNull": true,
407
+ "default": "current_timestamp"
408
+ },
409
+ "updated_at": {
410
+ "type": "TIMESTAMP",
411
+ "notNull": true,
412
+ "default": "current_timestamp"
413
+ },
414
+ "tenant_id": {
415
+ "type": "UUID",
416
+ "referenceKind": "tenantId",
417
+ "notNull": true,
418
+ "unique": false
419
+ },
420
+ "resource_id": {
421
+ "type": "UUID",
422
+ "referenceKind": "foreignKey",
423
+ "notNull": true,
424
+ "unique": false,
425
+ "foreignKey": {
426
+ "table": "catalog_resources",
427
+ "column": "id",
428
+ "onDelete": "NO ACTION",
429
+ "onUpdate": "CASCADE"
430
+ }
431
+ },
432
+ "selected_by_user_id": {
433
+ "type": "TEXT",
434
+ "notNull": true,
435
+ "unique": false
436
+ },
437
+ "selected_revision": {
438
+ "type": "TEXT",
439
+ "notNull": true,
440
+ "unique": false
441
+ }
442
+ },
443
+ "indexes": [
444
+ {
445
+ "name": "catalog_selections_slug_context_idx",
446
+ "columns": [
447
+ "tenant_id",
448
+ "slug",
449
+ "context"
450
+ ],
451
+ "unique": true
452
+ },
453
+ {
454
+ "name": "catalog_selections_tenant_id_created_at_idx",
455
+ "columns": [
456
+ "tenant_id",
457
+ "created_at"
458
+ ]
459
+ },
460
+ {
461
+ "name": "catalog_selections_resource_id_idx",
462
+ "columns": [
463
+ "resource_id"
464
+ ]
465
+ }
466
+ ],
467
+ "version": "c6b02eb9"
468
+ },
469
+ "importPath": "@happyvertical/smrt-education"
470
+ },
471
+ "@happyvertical/smrt-education:CatalogAcquisitionCollection": {
472
+ "name": "catalogacquisitioncollection",
473
+ "className": "CatalogAcquisitionCollection",
474
+ "qualifiedName": "@happyvertical/smrt-education:CatalogAcquisitionCollection",
475
+ "collection": "catalogacquisitions",
476
+ "filePath": "/home/runner/work/smrt/smrt/packages/education/src/catalog-collections.ts",
477
+ "packageName": "@happyvertical/smrt-education",
478
+ "fields": {},
479
+ "methods": {},
480
+ "decoratorConfig": {
481
+ "api": false,
482
+ "mcp": false,
483
+ "cli": false
484
+ },
485
+ "extends": "SmrtCollection",
486
+ "extendsTypeArg": "CatalogAcquisition",
487
+ "exportName": "CatalogAcquisitionCollection",
488
+ "collectionExportName": "CatalogAcquisitionCollectionCollection",
489
+ "schema": {
490
+ "tableName": "catalog_acquisitions",
491
+ "ddl": "CREATE TABLE IF NOT EXISTS \"catalog_acquisitions\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" UUID NOT NULL,\n \"resource_id\" UUID NOT NULL,\n \"selection_id\" UUID NOT NULL,\n \"revision\" TEXT NOT NULL,\n \"format\" TEXT NOT NULL,\n \"sha256\" TEXT NOT NULL,\n \"attribution\" TEXT,\n \"notices\" TEXT\n);",
492
+ "columns": {
493
+ "id": {
494
+ "type": "UUID",
495
+ "primaryKey": true,
496
+ "referenceKind": "id",
497
+ "notNull": true
498
+ },
499
+ "slug": {
500
+ "type": "TEXT",
501
+ "notNull": true
502
+ },
503
+ "context": {
504
+ "type": "TEXT",
505
+ "notNull": true,
506
+ "default": ""
507
+ },
508
+ "created_at": {
509
+ "type": "TIMESTAMP",
510
+ "notNull": true,
511
+ "default": "current_timestamp"
512
+ },
513
+ "updated_at": {
514
+ "type": "TIMESTAMP",
515
+ "notNull": true,
516
+ "default": "current_timestamp"
517
+ },
518
+ "tenant_id": {
519
+ "type": "UUID",
520
+ "referenceKind": "tenantId",
521
+ "notNull": true,
522
+ "unique": false
523
+ },
524
+ "resource_id": {
525
+ "type": "UUID",
526
+ "referenceKind": "foreignKey",
527
+ "notNull": true,
528
+ "unique": false,
529
+ "foreignKey": {
530
+ "table": "catalog_resources",
531
+ "column": "id",
532
+ "onDelete": "NO ACTION",
533
+ "onUpdate": "CASCADE"
534
+ }
535
+ },
536
+ "selection_id": {
537
+ "type": "UUID",
538
+ "referenceKind": "foreignKey",
539
+ "notNull": true,
540
+ "unique": false,
541
+ "foreignKey": {
542
+ "table": "catalog_selections",
543
+ "column": "id",
544
+ "onDelete": "NO ACTION",
545
+ "onUpdate": "CASCADE"
546
+ }
547
+ },
548
+ "revision": {
549
+ "type": "TEXT",
550
+ "notNull": true,
551
+ "unique": false
552
+ },
553
+ "format": {
554
+ "type": "TEXT",
555
+ "notNull": true,
556
+ "unique": false
557
+ },
558
+ "sha256": {
559
+ "type": "TEXT",
560
+ "notNull": true,
561
+ "unique": false
562
+ },
563
+ "attribution": {
564
+ "type": "TEXT",
565
+ "notNull": false,
566
+ "unique": false
567
+ },
568
+ "notices": {
569
+ "type": "TEXT",
570
+ "notNull": false,
571
+ "unique": false
572
+ }
573
+ },
574
+ "indexes": [
575
+ {
576
+ "name": "catalog_acquisitions_slug_context_idx",
577
+ "columns": [
578
+ "tenant_id",
579
+ "slug",
580
+ "context"
581
+ ],
582
+ "unique": true
583
+ },
584
+ {
585
+ "name": "catalog_acquisitions_tenant_id_created_at_idx",
586
+ "columns": [
587
+ "tenant_id",
588
+ "created_at"
589
+ ]
590
+ },
591
+ {
592
+ "name": "catalog_acquisitions_resource_id_idx",
593
+ "columns": [
594
+ "resource_id"
595
+ ]
596
+ },
597
+ {
598
+ "name": "catalog_acquisitions_selection_id_idx",
599
+ "columns": [
600
+ "selection_id"
601
+ ]
602
+ }
603
+ ],
604
+ "version": "ee9c5add"
605
+ },
606
+ "importPath": "@happyvertical/smrt-education"
607
+ },
608
+ "@happyvertical/smrt-education:CatalogProvider": {
609
+ "name": "catalogprovider",
610
+ "className": "CatalogProvider",
611
+ "qualifiedName": "@happyvertical/smrt-education:CatalogProvider",
612
+ "collection": "catalogproviders",
613
+ "description": "Globally visible provider registration. Hosts configure adapters and credentials out of band.",
614
+ "filePath": "/home/runner/work/smrt/smrt/packages/education/src/catalog-models.ts",
615
+ "packageName": "@happyvertical/smrt-education",
616
+ "fields": {
617
+ "providerId": {
618
+ "type": "text",
619
+ "required": true,
620
+ "_meta": {
621
+ "required": true
622
+ }
623
+ },
624
+ "name": {
625
+ "type": "text",
626
+ "required": true,
627
+ "_meta": {
628
+ "required": true
629
+ }
630
+ },
631
+ "active": {
632
+ "type": "boolean",
633
+ "required": true,
634
+ "default": true
635
+ }
636
+ },
637
+ "methods": {},
638
+ "decoratorConfig": {
639
+ "api": false,
640
+ "mcp": false,
641
+ "cli": false
642
+ },
643
+ "extends": "SmrtObject",
644
+ "exportName": "CatalogProvider",
645
+ "collectionExportName": "CatalogProviderCollection",
646
+ "displayLabelField": "name",
647
+ "validationRules": [
648
+ {
649
+ "field": "providerId",
650
+ "rule": "required",
651
+ "fieldType": "text"
652
+ },
653
+ {
654
+ "field": "name",
655
+ "rule": "required",
656
+ "fieldType": "text"
657
+ },
658
+ {
659
+ "field": "active",
660
+ "rule": "required",
661
+ "fieldType": "boolean"
662
+ }
663
+ ],
664
+ "schema": {
665
+ "tableName": "catalog_providers",
666
+ "ddl": "CREATE TABLE IF NOT EXISTS \"catalog_providers\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"provider_id\" TEXT NOT NULL,\n \"name\" TEXT NOT NULL,\n \"active\" BOOLEAN NOT NULL DEFAULT TRUE\n);",
667
+ "columns": {
668
+ "id": {
669
+ "type": "UUID",
670
+ "primaryKey": true,
671
+ "referenceKind": "id",
672
+ "notNull": true
673
+ },
674
+ "slug": {
675
+ "type": "TEXT",
676
+ "notNull": true
677
+ },
678
+ "context": {
679
+ "type": "TEXT",
680
+ "notNull": true,
681
+ "default": ""
682
+ },
683
+ "created_at": {
684
+ "type": "TIMESTAMP",
685
+ "notNull": true,
686
+ "default": "current_timestamp"
687
+ },
688
+ "updated_at": {
689
+ "type": "TIMESTAMP",
690
+ "notNull": true,
691
+ "default": "current_timestamp"
692
+ },
693
+ "provider_id": {
694
+ "type": "TEXT",
695
+ "notNull": true,
696
+ "unique": false
697
+ },
698
+ "name": {
699
+ "type": "TEXT",
700
+ "notNull": true,
701
+ "unique": false
702
+ },
703
+ "active": {
704
+ "type": "BOOLEAN",
705
+ "notNull": true,
706
+ "unique": false,
707
+ "default": true
708
+ }
709
+ },
710
+ "indexes": [
711
+ {
712
+ "name": "catalog_providers_slug_context_idx",
713
+ "columns": [
714
+ "slug",
715
+ "context"
716
+ ],
717
+ "unique": true
718
+ },
719
+ {
720
+ "name": "catalog_providers_created_at_idx",
721
+ "columns": [
722
+ "created_at"
723
+ ]
724
+ }
725
+ ],
726
+ "version": "f35557a4"
727
+ },
728
+ "importPath": "@happyvertical/smrt-education"
729
+ },
730
+ "@happyvertical/smrt-education:CatalogResource": {
731
+ "name": "catalogresource",
732
+ "className": "CatalogResource",
733
+ "qualifiedName": "@happyvertical/smrt-education:CatalogResource",
734
+ "collection": "catalogresources",
735
+ "description": "A provider-native record. Rows are intentionally not merged across providers.",
736
+ "filePath": "/home/runner/work/smrt/smrt/packages/education/src/catalog-models.ts",
737
+ "packageName": "@happyvertical/smrt-education",
738
+ "fields": {
739
+ "providerId": {
740
+ "type": "text",
741
+ "required": true,
742
+ "_meta": {
743
+ "required": true
744
+ }
745
+ },
746
+ "stableId": {
747
+ "type": "text",
748
+ "required": true,
749
+ "_meta": {
750
+ "required": true
751
+ }
752
+ },
753
+ "revision": {
754
+ "type": "text",
755
+ "required": true,
756
+ "_meta": {
757
+ "required": true
758
+ }
759
+ },
760
+ "canonicalUrl": {
761
+ "type": "text",
762
+ "required": false
763
+ },
764
+ "title": {
765
+ "type": "text",
766
+ "required": true,
767
+ "_meta": {
768
+ "required": true
769
+ }
770
+ },
771
+ "suppliedDescription": {
772
+ "type": "text",
773
+ "required": false
774
+ },
775
+ "author": {
776
+ "type": "text",
777
+ "required": false
778
+ },
779
+ "subjects": {
780
+ "type": "text",
781
+ "required": false
782
+ },
783
+ "grades": {
784
+ "type": "text",
785
+ "required": false
786
+ },
787
+ "language": {
788
+ "type": "text",
789
+ "required": false
790
+ },
791
+ "resourceType": {
792
+ "type": "text",
793
+ "required": false
794
+ },
795
+ "parentStableId": {
796
+ "type": "text",
797
+ "required": false
798
+ },
799
+ "availableFormats": {
800
+ "type": "text",
801
+ "required": false
802
+ },
803
+ "licenseEvidence": {
804
+ "type": "text",
805
+ "required": false
806
+ },
807
+ "licenseState": {
808
+ "type": "text",
809
+ "required": false,
810
+ "default": "unknown",
811
+ "enum": [
812
+ "verified",
813
+ "unknown",
814
+ "conflicting",
815
+ "restricted"
816
+ ]
817
+ },
818
+ "visibility": {
819
+ "type": "text",
820
+ "required": false,
821
+ "default": "catalog",
822
+ "enum": [
823
+ "catalog",
824
+ "teacher"
825
+ ]
826
+ },
827
+ "lastSeenRunId": {
828
+ "type": "text",
829
+ "required": false
830
+ },
831
+ "withdrawnAt": {
832
+ "type": "text",
833
+ "required": false
834
+ }
835
+ },
836
+ "methods": {},
837
+ "decoratorConfig": {
838
+ "api": false,
839
+ "mcp": false,
840
+ "cli": false
841
+ },
842
+ "extends": "SmrtObject",
843
+ "exportName": "CatalogResource",
844
+ "collectionExportName": "CatalogResourceCollection",
845
+ "displayLabelField": "title",
846
+ "validationRules": [
847
+ {
848
+ "field": "providerId",
849
+ "rule": "required",
850
+ "fieldType": "text"
851
+ },
852
+ {
853
+ "field": "stableId",
854
+ "rule": "required",
855
+ "fieldType": "text"
856
+ },
857
+ {
858
+ "field": "revision",
859
+ "rule": "required",
860
+ "fieldType": "text"
861
+ },
862
+ {
863
+ "field": "title",
864
+ "rule": "required",
865
+ "fieldType": "text"
866
+ }
867
+ ],
868
+ "schema": {
869
+ "tableName": "catalog_resources",
870
+ "ddl": "CREATE TABLE IF NOT EXISTS \"catalog_resources\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"provider_id\" TEXT NOT NULL,\n \"stable_id\" TEXT NOT NULL,\n \"revision\" TEXT NOT NULL,\n \"canonical_url\" TEXT,\n \"title\" TEXT NOT NULL,\n \"supplied_description\" TEXT,\n \"author\" TEXT,\n \"subjects\" TEXT,\n \"grades\" TEXT,\n \"language\" TEXT,\n \"resource_type\" TEXT,\n \"parent_stable_id\" TEXT,\n \"available_formats\" TEXT,\n \"license_evidence\" TEXT,\n \"license_state\" TEXT DEFAULT 'unknown',\n \"visibility\" TEXT DEFAULT 'catalog',\n \"last_seen_run_id\" TEXT,\n \"withdrawn_at\" TEXT\n);",
871
+ "columns": {
872
+ "id": {
873
+ "type": "UUID",
874
+ "primaryKey": true,
875
+ "referenceKind": "id",
876
+ "notNull": true
877
+ },
878
+ "slug": {
879
+ "type": "TEXT",
880
+ "notNull": true
881
+ },
882
+ "context": {
883
+ "type": "TEXT",
884
+ "notNull": true,
885
+ "default": ""
886
+ },
887
+ "created_at": {
888
+ "type": "TIMESTAMP",
889
+ "notNull": true,
890
+ "default": "current_timestamp"
891
+ },
892
+ "updated_at": {
893
+ "type": "TIMESTAMP",
894
+ "notNull": true,
895
+ "default": "current_timestamp"
896
+ },
897
+ "provider_id": {
898
+ "type": "TEXT",
899
+ "notNull": true,
900
+ "unique": false
901
+ },
902
+ "stable_id": {
903
+ "type": "TEXT",
904
+ "notNull": true,
905
+ "unique": false
906
+ },
907
+ "revision": {
908
+ "type": "TEXT",
909
+ "notNull": true,
910
+ "unique": false
911
+ },
912
+ "canonical_url": {
913
+ "type": "TEXT",
914
+ "notNull": false,
915
+ "unique": false
916
+ },
917
+ "title": {
918
+ "type": "TEXT",
919
+ "notNull": true,
920
+ "unique": false
921
+ },
922
+ "supplied_description": {
923
+ "type": "TEXT",
924
+ "notNull": false,
925
+ "unique": false
926
+ },
927
+ "author": {
928
+ "type": "TEXT",
929
+ "notNull": false,
930
+ "unique": false
931
+ },
932
+ "subjects": {
933
+ "type": "TEXT",
934
+ "notNull": false,
935
+ "unique": false
936
+ },
937
+ "grades": {
938
+ "type": "TEXT",
939
+ "notNull": false,
940
+ "unique": false
941
+ },
942
+ "language": {
943
+ "type": "TEXT",
944
+ "notNull": false,
945
+ "unique": false
946
+ },
947
+ "resource_type": {
948
+ "type": "TEXT",
949
+ "notNull": false,
950
+ "unique": false
951
+ },
952
+ "parent_stable_id": {
953
+ "type": "TEXT",
954
+ "notNull": false,
955
+ "unique": false
956
+ },
957
+ "available_formats": {
958
+ "type": "TEXT",
959
+ "notNull": false,
960
+ "unique": false
961
+ },
962
+ "license_evidence": {
963
+ "type": "TEXT",
964
+ "notNull": false,
965
+ "unique": false
966
+ },
967
+ "license_state": {
968
+ "type": "TEXT",
969
+ "notNull": false,
970
+ "unique": false,
971
+ "default": "unknown"
972
+ },
973
+ "visibility": {
974
+ "type": "TEXT",
975
+ "notNull": false,
976
+ "unique": false,
977
+ "default": "catalog"
978
+ },
979
+ "last_seen_run_id": {
980
+ "type": "TEXT",
981
+ "notNull": false,
982
+ "unique": false
983
+ },
984
+ "withdrawn_at": {
985
+ "type": "TEXT",
986
+ "notNull": false,
987
+ "unique": false
988
+ }
989
+ },
990
+ "indexes": [
991
+ {
992
+ "name": "catalog_resources_slug_context_idx",
993
+ "columns": [
994
+ "slug",
995
+ "context"
996
+ ],
997
+ "unique": true
998
+ },
999
+ {
1000
+ "name": "catalog_resources_created_at_idx",
1001
+ "columns": [
1002
+ "created_at"
1003
+ ]
1004
+ }
1005
+ ],
1006
+ "version": "441b7271"
1007
+ },
1008
+ "importPath": "@happyvertical/smrt-education"
1009
+ },
1010
+ "@happyvertical/smrt-education:CatalogSyncState": {
1011
+ "name": "catalogsyncstate",
1012
+ "className": "CatalogSyncState",
1013
+ "qualifiedName": "@happyvertical/smrt-education:CatalogSyncState",
1014
+ "collection": "catalogsyncstates",
1015
+ "description": "Durable per-provider enumeration state. A failed or partial feed is never complete.",
1016
+ "filePath": "/home/runner/work/smrt/smrt/packages/education/src/catalog-models.ts",
1017
+ "packageName": "@happyvertical/smrt-education",
1018
+ "fields": {
1019
+ "providerId": {
1020
+ "type": "text",
1021
+ "required": true,
1022
+ "_meta": {
1023
+ "required": true
1024
+ }
1025
+ },
1026
+ "cursor": {
1027
+ "type": "text",
1028
+ "required": false
1029
+ },
1030
+ "runId": {
1031
+ "type": "text",
1032
+ "required": false
1033
+ },
1034
+ "complete": {
1035
+ "type": "boolean",
1036
+ "required": true,
1037
+ "default": false
1038
+ },
1039
+ "paused": {
1040
+ "type": "boolean",
1041
+ "required": true,
1042
+ "default": false
1043
+ },
1044
+ "pauseReason": {
1045
+ "type": "text",
1046
+ "required": false
1047
+ },
1048
+ "importedCount": {
1049
+ "type": "integer",
1050
+ "required": true,
1051
+ "default": 0
1052
+ },
1053
+ "failures": {
1054
+ "type": "text",
1055
+ "required": false
1056
+ },
1057
+ "lastSuccessfulAt": {
1058
+ "type": "text",
1059
+ "required": false
1060
+ }
1061
+ },
1062
+ "methods": {},
1063
+ "decoratorConfig": {
1064
+ "api": false,
1065
+ "mcp": false,
1066
+ "cli": false
1067
+ },
1068
+ "extends": "SmrtObject",
1069
+ "exportName": "CatalogSyncState",
1070
+ "collectionExportName": "CatalogSyncStateCollection",
1071
+ "validationRules": [
1072
+ {
1073
+ "field": "providerId",
1074
+ "rule": "required",
1075
+ "fieldType": "text"
1076
+ },
1077
+ {
1078
+ "field": "complete",
1079
+ "rule": "required",
1080
+ "fieldType": "boolean"
1081
+ },
1082
+ {
1083
+ "field": "paused",
1084
+ "rule": "required",
1085
+ "fieldType": "boolean"
1086
+ },
1087
+ {
1088
+ "field": "importedCount",
1089
+ "rule": "required",
1090
+ "fieldType": "integer"
1091
+ }
1092
+ ],
1093
+ "schema": {
1094
+ "tableName": "catalog_sync_states",
1095
+ "ddl": "CREATE TABLE IF NOT EXISTS \"catalog_sync_states\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"provider_id\" TEXT NOT NULL,\n \"cursor\" TEXT,\n \"run_id\" TEXT,\n \"complete\" BOOLEAN NOT NULL DEFAULT FALSE,\n \"paused\" BOOLEAN NOT NULL DEFAULT FALSE,\n \"pause_reason\" TEXT,\n \"imported_count\" INTEGER NOT NULL DEFAULT 0,\n \"failures\" TEXT,\n \"last_successful_at\" TEXT\n);",
1096
+ "columns": {
1097
+ "id": {
1098
+ "type": "UUID",
1099
+ "primaryKey": true,
1100
+ "referenceKind": "id",
1101
+ "notNull": true
1102
+ },
1103
+ "slug": {
1104
+ "type": "TEXT",
1105
+ "notNull": true
1106
+ },
1107
+ "context": {
1108
+ "type": "TEXT",
1109
+ "notNull": true,
1110
+ "default": ""
1111
+ },
1112
+ "created_at": {
1113
+ "type": "TIMESTAMP",
1114
+ "notNull": true,
1115
+ "default": "current_timestamp"
1116
+ },
1117
+ "updated_at": {
1118
+ "type": "TIMESTAMP",
1119
+ "notNull": true,
1120
+ "default": "current_timestamp"
1121
+ },
1122
+ "provider_id": {
1123
+ "type": "TEXT",
1124
+ "notNull": true,
1125
+ "unique": false
1126
+ },
1127
+ "cursor": {
1128
+ "type": "TEXT",
1129
+ "notNull": false,
1130
+ "unique": false
1131
+ },
1132
+ "run_id": {
1133
+ "type": "TEXT",
1134
+ "notNull": false,
1135
+ "unique": false
1136
+ },
1137
+ "complete": {
1138
+ "type": "BOOLEAN",
1139
+ "notNull": true,
1140
+ "unique": false,
1141
+ "default": false
1142
+ },
1143
+ "paused": {
1144
+ "type": "BOOLEAN",
1145
+ "notNull": true,
1146
+ "unique": false,
1147
+ "default": false
1148
+ },
1149
+ "pause_reason": {
1150
+ "type": "TEXT",
1151
+ "notNull": false,
1152
+ "unique": false
1153
+ },
1154
+ "imported_count": {
1155
+ "type": "INTEGER",
1156
+ "notNull": true,
1157
+ "unique": false,
1158
+ "default": 0
1159
+ },
1160
+ "failures": {
1161
+ "type": "TEXT",
1162
+ "notNull": false,
1163
+ "unique": false
1164
+ },
1165
+ "last_successful_at": {
1166
+ "type": "TEXT",
1167
+ "notNull": false,
1168
+ "unique": false
1169
+ }
1170
+ },
1171
+ "indexes": [
1172
+ {
1173
+ "name": "catalog_sync_states_slug_context_idx",
1174
+ "columns": [
1175
+ "slug",
1176
+ "context"
1177
+ ],
1178
+ "unique": true
1179
+ },
1180
+ {
1181
+ "name": "catalog_sync_states_created_at_idx",
1182
+ "columns": [
1183
+ "created_at"
1184
+ ]
1185
+ }
1186
+ ],
1187
+ "version": "52dc3ee1"
1188
+ },
1189
+ "importPath": "@happyvertical/smrt-education"
1190
+ },
1191
+ "@happyvertical/smrt-education:CatalogSelection": {
1192
+ "name": "catalogselection",
1193
+ "className": "CatalogSelection",
1194
+ "qualifiedName": "@happyvertical/smrt-education:CatalogSelection",
1195
+ "collection": "catalogselections",
1196
+ "description": "Tenant-owned intent to use a metadata record, distinct from acquiring bytes.",
1197
+ "filePath": "/home/runner/work/smrt/smrt/packages/education/src/catalog-models.ts",
1198
+ "packageName": "@happyvertical/smrt-education",
1199
+ "fields": {
1200
+ "tenantId": {
1201
+ "type": "text",
1202
+ "required": true,
1203
+ "_meta": {
1204
+ "sqlType": "UUID",
1205
+ "__tenancy": {
1206
+ "isTenantIdField": true,
1207
+ "autoFilter": true,
1208
+ "required": true,
1209
+ "autoPopulate": true,
1210
+ "nullable": false,
1211
+ "mode": "required",
1212
+ "field": "tenantId",
1213
+ "allowSuperAdminBypass": false
1214
+ }
1215
+ }
1216
+ },
1217
+ "resourceId": {
1218
+ "type": "foreignKey",
1219
+ "required": true,
1220
+ "related": "CatalogResource",
1221
+ "_meta": {
1222
+ "required": true
1223
+ }
1224
+ },
1225
+ "selectedByUserId": {
1226
+ "type": "text",
1227
+ "required": true,
1228
+ "_meta": {
1229
+ "required": true
1230
+ }
1231
+ },
1232
+ "selectedRevision": {
1233
+ "type": "text",
1234
+ "required": true,
1235
+ "_meta": {
1236
+ "required": true
1237
+ }
1238
+ }
1239
+ },
1240
+ "methods": {},
1241
+ "decoratorConfig": {
1242
+ "api": false,
1243
+ "mcp": false,
1244
+ "cli": false,
1245
+ "tenantScoped": {
1246
+ "mode": "required"
1247
+ },
1248
+ "conflictColumns": [
1249
+ "tenant_id",
1250
+ "slug",
1251
+ "context"
1252
+ ]
1253
+ },
1254
+ "extends": "SmrtObject",
1255
+ "exportName": "CatalogSelection",
1256
+ "collectionExportName": "CatalogSelectionCollection",
1257
+ "validationRules": [
1258
+ {
1259
+ "field": "resourceId",
1260
+ "rule": "required",
1261
+ "fieldType": "foreignKey"
1262
+ },
1263
+ {
1264
+ "field": "selectedByUserId",
1265
+ "rule": "required",
1266
+ "fieldType": "text"
1267
+ },
1268
+ {
1269
+ "field": "selectedRevision",
1270
+ "rule": "required",
1271
+ "fieldType": "text"
1272
+ }
1273
+ ],
1274
+ "schema": {
1275
+ "tableName": "catalog_selections",
1276
+ "ddl": "CREATE TABLE IF NOT EXISTS \"catalog_selections\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" UUID NOT NULL,\n \"resource_id\" UUID NOT NULL,\n \"selected_by_user_id\" TEXT NOT NULL,\n \"selected_revision\" TEXT NOT NULL\n);",
1277
+ "columns": {
1278
+ "id": {
1279
+ "type": "UUID",
1280
+ "primaryKey": true,
1281
+ "referenceKind": "id",
1282
+ "notNull": true
1283
+ },
1284
+ "slug": {
1285
+ "type": "TEXT",
1286
+ "notNull": true
1287
+ },
1288
+ "context": {
1289
+ "type": "TEXT",
1290
+ "notNull": true,
1291
+ "default": ""
1292
+ },
1293
+ "created_at": {
1294
+ "type": "TIMESTAMP",
1295
+ "notNull": true,
1296
+ "default": "current_timestamp"
1297
+ },
1298
+ "updated_at": {
1299
+ "type": "TIMESTAMP",
1300
+ "notNull": true,
1301
+ "default": "current_timestamp"
1302
+ },
1303
+ "tenant_id": {
1304
+ "type": "UUID",
1305
+ "referenceKind": "tenantId",
1306
+ "notNull": true,
1307
+ "unique": false
1308
+ },
1309
+ "resource_id": {
1310
+ "type": "UUID",
1311
+ "referenceKind": "foreignKey",
1312
+ "notNull": true,
1313
+ "unique": false,
1314
+ "foreignKey": {
1315
+ "table": "catalog_resources",
1316
+ "column": "id",
1317
+ "onDelete": "NO ACTION",
1318
+ "onUpdate": "CASCADE"
1319
+ }
1320
+ },
1321
+ "selected_by_user_id": {
1322
+ "type": "TEXT",
1323
+ "notNull": true,
1324
+ "unique": false
1325
+ },
1326
+ "selected_revision": {
1327
+ "type": "TEXT",
1328
+ "notNull": true,
1329
+ "unique": false
1330
+ }
1331
+ },
1332
+ "indexes": [
1333
+ {
1334
+ "name": "catalog_selections_slug_context_idx",
1335
+ "columns": [
1336
+ "tenant_id",
1337
+ "slug",
1338
+ "context"
1339
+ ],
1340
+ "unique": true
1341
+ },
1342
+ {
1343
+ "name": "catalog_selections_tenant_id_created_at_idx",
1344
+ "columns": [
1345
+ "tenant_id",
1346
+ "created_at"
1347
+ ]
1348
+ },
1349
+ {
1350
+ "name": "catalog_selections_resource_id_idx",
1351
+ "columns": [
1352
+ "resource_id"
1353
+ ]
1354
+ }
1355
+ ],
1356
+ "version": "c6b02eb9"
1357
+ },
1358
+ "importPath": "@happyvertical/smrt-education"
1359
+ },
1360
+ "@happyvertical/smrt-education:CatalogAcquisition": {
1361
+ "name": "catalogacquisition",
1362
+ "className": "CatalogAcquisition",
1363
+ "qualifiedName": "@happyvertical/smrt-education:CatalogAcquisition",
1364
+ "collection": "catalogacquisitions",
1365
+ "description": "A pinned, tenant-owned acquisition record. Bytes belong in a host storage service.",
1366
+ "filePath": "/home/runner/work/smrt/smrt/packages/education/src/catalog-models.ts",
1367
+ "packageName": "@happyvertical/smrt-education",
1368
+ "fields": {
1369
+ "tenantId": {
1370
+ "type": "text",
1371
+ "required": true,
1372
+ "_meta": {
1373
+ "sqlType": "UUID",
1374
+ "__tenancy": {
1375
+ "isTenantIdField": true,
1376
+ "autoFilter": true,
1377
+ "required": true,
1378
+ "autoPopulate": true,
1379
+ "nullable": false,
1380
+ "mode": "required",
1381
+ "field": "tenantId",
1382
+ "allowSuperAdminBypass": false
1383
+ }
1384
+ }
1385
+ },
1386
+ "resourceId": {
1387
+ "type": "foreignKey",
1388
+ "required": true,
1389
+ "related": "CatalogResource",
1390
+ "_meta": {
1391
+ "required": true
1392
+ }
1393
+ },
1394
+ "selectionId": {
1395
+ "type": "foreignKey",
1396
+ "required": true,
1397
+ "related": "CatalogSelection",
1398
+ "_meta": {
1399
+ "required": true
1400
+ }
1401
+ },
1402
+ "revision": {
1403
+ "type": "text",
1404
+ "required": true,
1405
+ "_meta": {
1406
+ "required": true
1407
+ }
1408
+ },
1409
+ "format": {
1410
+ "type": "text",
1411
+ "required": true,
1412
+ "_meta": {
1413
+ "required": true
1414
+ }
1415
+ },
1416
+ "sha256": {
1417
+ "type": "text",
1418
+ "required": true,
1419
+ "_meta": {
1420
+ "required": true
1421
+ }
1422
+ },
1423
+ "attribution": {
1424
+ "type": "text",
1425
+ "required": false
1426
+ },
1427
+ "notices": {
1428
+ "type": "text",
1429
+ "required": false
1430
+ }
1431
+ },
1432
+ "methods": {},
1433
+ "decoratorConfig": {
1434
+ "api": false,
1435
+ "mcp": false,
1436
+ "cli": false,
1437
+ "tenantScoped": {
1438
+ "mode": "required"
1439
+ },
1440
+ "conflictColumns": [
1441
+ "tenant_id",
1442
+ "slug",
1443
+ "context"
1444
+ ]
1445
+ },
1446
+ "extends": "SmrtObject",
1447
+ "exportName": "CatalogAcquisition",
1448
+ "collectionExportName": "CatalogAcquisitionCollection",
1449
+ "validationRules": [
1450
+ {
1451
+ "field": "resourceId",
1452
+ "rule": "required",
1453
+ "fieldType": "foreignKey"
1454
+ },
1455
+ {
1456
+ "field": "selectionId",
1457
+ "rule": "required",
1458
+ "fieldType": "foreignKey"
1459
+ },
1460
+ {
1461
+ "field": "revision",
1462
+ "rule": "required",
1463
+ "fieldType": "text"
1464
+ },
1465
+ {
1466
+ "field": "format",
1467
+ "rule": "required",
1468
+ "fieldType": "text"
1469
+ },
1470
+ {
1471
+ "field": "sha256",
1472
+ "rule": "required",
1473
+ "fieldType": "text"
1474
+ }
1475
+ ],
1476
+ "schema": {
1477
+ "tableName": "catalog_acquisitions",
1478
+ "ddl": "CREATE TABLE IF NOT EXISTS \"catalog_acquisitions\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" UUID NOT NULL,\n \"resource_id\" UUID NOT NULL,\n \"selection_id\" UUID NOT NULL,\n \"revision\" TEXT NOT NULL,\n \"format\" TEXT NOT NULL,\n \"sha256\" TEXT NOT NULL,\n \"attribution\" TEXT,\n \"notices\" TEXT\n);",
1479
+ "columns": {
1480
+ "id": {
1481
+ "type": "UUID",
1482
+ "primaryKey": true,
1483
+ "referenceKind": "id",
1484
+ "notNull": true
1485
+ },
1486
+ "slug": {
1487
+ "type": "TEXT",
1488
+ "notNull": true
1489
+ },
1490
+ "context": {
1491
+ "type": "TEXT",
1492
+ "notNull": true,
1493
+ "default": ""
1494
+ },
1495
+ "created_at": {
1496
+ "type": "TIMESTAMP",
1497
+ "notNull": true,
1498
+ "default": "current_timestamp"
1499
+ },
1500
+ "updated_at": {
1501
+ "type": "TIMESTAMP",
1502
+ "notNull": true,
1503
+ "default": "current_timestamp"
1504
+ },
1505
+ "tenant_id": {
1506
+ "type": "UUID",
1507
+ "referenceKind": "tenantId",
1508
+ "notNull": true,
1509
+ "unique": false
1510
+ },
1511
+ "resource_id": {
1512
+ "type": "UUID",
1513
+ "referenceKind": "foreignKey",
1514
+ "notNull": true,
1515
+ "unique": false,
1516
+ "foreignKey": {
1517
+ "table": "catalog_resources",
1518
+ "column": "id",
1519
+ "onDelete": "NO ACTION",
1520
+ "onUpdate": "CASCADE"
1521
+ }
1522
+ },
1523
+ "selection_id": {
1524
+ "type": "UUID",
1525
+ "referenceKind": "foreignKey",
1526
+ "notNull": true,
1527
+ "unique": false,
1528
+ "foreignKey": {
1529
+ "table": "catalog_selections",
1530
+ "column": "id",
1531
+ "onDelete": "NO ACTION",
1532
+ "onUpdate": "CASCADE"
1533
+ }
1534
+ },
1535
+ "revision": {
1536
+ "type": "TEXT",
1537
+ "notNull": true,
1538
+ "unique": false
1539
+ },
1540
+ "format": {
1541
+ "type": "TEXT",
1542
+ "notNull": true,
1543
+ "unique": false
1544
+ },
1545
+ "sha256": {
1546
+ "type": "TEXT",
1547
+ "notNull": true,
1548
+ "unique": false
1549
+ },
1550
+ "attribution": {
1551
+ "type": "TEXT",
1552
+ "notNull": false,
1553
+ "unique": false
1554
+ },
1555
+ "notices": {
1556
+ "type": "TEXT",
1557
+ "notNull": false,
1558
+ "unique": false
1559
+ }
1560
+ },
1561
+ "indexes": [
1562
+ {
1563
+ "name": "catalog_acquisitions_slug_context_idx",
1564
+ "columns": [
1565
+ "tenant_id",
1566
+ "slug",
1567
+ "context"
1568
+ ],
1569
+ "unique": true
1570
+ },
1571
+ {
1572
+ "name": "catalog_acquisitions_tenant_id_created_at_idx",
1573
+ "columns": [
1574
+ "tenant_id",
1575
+ "created_at"
1576
+ ]
1577
+ },
1578
+ {
1579
+ "name": "catalog_acquisitions_resource_id_idx",
1580
+ "columns": [
1581
+ "resource_id"
1582
+ ]
1583
+ },
1584
+ {
1585
+ "name": "catalog_acquisitions_selection_id_idx",
1586
+ "columns": [
1587
+ "selection_id"
1588
+ ]
1589
+ }
1590
+ ],
1591
+ "version": "ee9c5add"
1592
+ },
1593
+ "importPath": "@happyvertical/smrt-education"
1594
+ },
7
1595
  "@happyvertical/smrt-education:Course": {
8
1596
  "name": "course",
9
1597
  "className": "Course",
@@ -4980,7 +6568,7 @@
4980
6568
  "collectionExportName": "SubmissionCollectionCollection",
4981
6569
  "schema": {
4982
6570
  "tableName": "submissions",
4983
- "ddl": "CREATE TABLE IF NOT EXISTS \"submissions\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"_meta_type\" TEXT NOT NULL,\n \"_meta_data\" JSON,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" UUID,\n \"learner_id\" UUID,\n \"lesson_id\" UUID,\n \"progress_id\" UUID,\n \"submitted_at\" TEXT,\n \"status\" TEXT DEFAULT 'captured',\n \"notes\" TEXT,\n \"capture_key\" TEXT,\n \"capture_digest\" TEXT,\n \"page_count\" INTEGER DEFAULT 0,\n \"ocr_text\" TEXT,\n \"extracted\" TEXT,\n \"reported_by\" TEXT DEFAULT 'learner',\n \"evidence_url\" TEXT,\n \"reported_score\" REAL\n);",
6571
+ "ddl": "CREATE TABLE IF NOT EXISTS \"submissions\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"_meta_type\" TEXT NOT NULL,\n \"_meta_data\" JSON,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" UUID,\n \"learner_id\" UUID,\n \"lesson_id\" UUID,\n \"progress_id\" UUID,\n \"submitted_at\" TEXT,\n \"status\" TEXT DEFAULT 'captured',\n \"notes\" TEXT,\n \"capture_key\" TEXT,\n \"capture_digest\" TEXT,\n \"kind\" TEXT DEFAULT 'completed_work',\n \"previous_submission_id\" UUID,\n \"intake_item_id\" TEXT,\n \"page_count\" INTEGER DEFAULT 0,\n \"ocr_text\" TEXT,\n \"extracted\" TEXT,\n \"reported_by\" TEXT DEFAULT 'learner',\n \"evidence_url\" TEXT,\n \"reported_score\" REAL\n);",
4984
6572
  "columns": {
4985
6573
  "id": {
4986
6574
  "type": "UUID",
@@ -5074,6 +6662,26 @@
5074
6662
  "type": "TEXT",
5075
6663
  "notNull": false
5076
6664
  },
6665
+ "kind": {
6666
+ "type": "TEXT",
6667
+ "notNull": false,
6668
+ "default": "completed_work"
6669
+ },
6670
+ "previous_submission_id": {
6671
+ "type": "UUID",
6672
+ "referenceKind": "foreignKey",
6673
+ "notNull": false,
6674
+ "foreignKey": {
6675
+ "table": "submissions",
6676
+ "column": "id",
6677
+ "onDelete": "NO ACTION",
6678
+ "onUpdate": "CASCADE"
6679
+ }
6680
+ },
6681
+ "intake_item_id": {
6682
+ "type": "TEXT",
6683
+ "notNull": false
6684
+ },
5077
6685
  "page_count": {
5078
6686
  "type": "INTEGER",
5079
6687
  "notNull": false,
@@ -5143,9 +6751,121 @@
5143
6751
  "columns": [
5144
6752
  "progress_id"
5145
6753
  ]
6754
+ },
6755
+ {
6756
+ "name": "submissions_previous_submission_id_idx",
6757
+ "columns": [
6758
+ "previous_submission_id"
6759
+ ]
6760
+ }
6761
+ ],
6762
+ "version": "27a21ab4"
6763
+ },
6764
+ "importPath": "@happyvertical/smrt-education"
6765
+ },
6766
+ "@happyvertical/smrt-education:SubmissionIntakeBindingCollection": {
6767
+ "name": "submissionintakebindingcollection",
6768
+ "className": "SubmissionIntakeBindingCollection",
6769
+ "qualifiedName": "@happyvertical/smrt-education:SubmissionIntakeBindingCollection",
6770
+ "collection": "submissionintakebindings",
6771
+ "filePath": "/home/runner/work/smrt/smrt/packages/education/src/collections.ts",
6772
+ "packageName": "@happyvertical/smrt-education",
6773
+ "fields": {},
6774
+ "methods": {},
6775
+ "decoratorConfig": {
6776
+ "tableName": "submission_intake_bindings",
6777
+ "api": false,
6778
+ "mcp": false,
6779
+ "cli": false
6780
+ },
6781
+ "extends": "SmrtCollection",
6782
+ "extendsTypeArg": "SubmissionIntakeBinding",
6783
+ "exportName": "SubmissionIntakeBindingCollection",
6784
+ "collectionExportName": "SubmissionIntakeBindingCollectionCollection",
6785
+ "schema": {
6786
+ "tableName": "submission_intake_bindings",
6787
+ "ddl": "CREATE TABLE IF NOT EXISTS \"submission_intake_bindings\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" UUID NOT NULL,\n \"intake_item_id\" TEXT NOT NULL,\n \"submission_id\" UUID NOT NULL\n);",
6788
+ "columns": {
6789
+ "id": {
6790
+ "type": "UUID",
6791
+ "primaryKey": true,
6792
+ "referenceKind": "id",
6793
+ "notNull": true
6794
+ },
6795
+ "slug": {
6796
+ "type": "TEXT",
6797
+ "notNull": true
6798
+ },
6799
+ "context": {
6800
+ "type": "TEXT",
6801
+ "notNull": true,
6802
+ "default": ""
6803
+ },
6804
+ "created_at": {
6805
+ "type": "TIMESTAMP",
6806
+ "notNull": true,
6807
+ "default": "current_timestamp"
6808
+ },
6809
+ "updated_at": {
6810
+ "type": "TIMESTAMP",
6811
+ "notNull": true,
6812
+ "default": "current_timestamp"
6813
+ },
6814
+ "tenant_id": {
6815
+ "type": "UUID",
6816
+ "referenceKind": "tenantId",
6817
+ "notNull": true,
6818
+ "unique": false
6819
+ },
6820
+ "intake_item_id": {
6821
+ "type": "TEXT",
6822
+ "notNull": true,
6823
+ "unique": false
6824
+ },
6825
+ "submission_id": {
6826
+ "type": "UUID",
6827
+ "referenceKind": "foreignKey",
6828
+ "notNull": true,
6829
+ "unique": false,
6830
+ "foreignKey": {
6831
+ "table": "submissions",
6832
+ "column": "id",
6833
+ "onDelete": "NO ACTION",
6834
+ "onUpdate": "CASCADE"
6835
+ }
6836
+ }
6837
+ },
6838
+ "indexes": [
6839
+ {
6840
+ "name": "submission_intake_bindings_tenant_id_intake_item_id_idx",
6841
+ "columns": [
6842
+ "tenant_id",
6843
+ "intake_item_id"
6844
+ ],
6845
+ "unique": true
6846
+ },
6847
+ {
6848
+ "name": "submission_intake_bindings_slug_context_idx",
6849
+ "columns": [
6850
+ "slug",
6851
+ "context"
6852
+ ]
6853
+ },
6854
+ {
6855
+ "name": "submission_intake_bindings_tenant_id_created_at_idx",
6856
+ "columns": [
6857
+ "tenant_id",
6858
+ "created_at"
6859
+ ]
6860
+ },
6861
+ {
6862
+ "name": "submission_intake_bindings_submission_id_idx",
6863
+ "columns": [
6864
+ "submission_id"
6865
+ ]
5146
6866
  }
5147
6867
  ],
5148
- "version": "9839d766"
6868
+ "version": "7102c909"
5149
6869
  },
5150
6870
  "importPath": "@happyvertical/smrt-education"
5151
6871
  },
@@ -5170,7 +6890,7 @@
5170
6890
  "collectionExportName": "ScannedSubmissionCollectionCollection",
5171
6891
  "schema": {
5172
6892
  "tableName": "submissions",
5173
- "ddl": "CREATE TABLE IF NOT EXISTS \"submissions\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"_meta_type\" TEXT NOT NULL,\n \"_meta_data\" JSON,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" UUID,\n \"learner_id\" UUID,\n \"lesson_id\" UUID,\n \"progress_id\" UUID,\n \"submitted_at\" TEXT,\n \"status\" TEXT DEFAULT 'captured',\n \"notes\" TEXT,\n \"capture_key\" TEXT,\n \"capture_digest\" TEXT,\n \"page_count\" INTEGER DEFAULT 0,\n \"ocr_text\" TEXT,\n \"extracted\" TEXT,\n \"reported_by\" TEXT DEFAULT 'learner',\n \"evidence_url\" TEXT,\n \"reported_score\" REAL\n);",
6893
+ "ddl": "CREATE TABLE IF NOT EXISTS \"submissions\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"_meta_type\" TEXT NOT NULL,\n \"_meta_data\" JSON,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" UUID,\n \"learner_id\" UUID,\n \"lesson_id\" UUID,\n \"progress_id\" UUID,\n \"submitted_at\" TEXT,\n \"status\" TEXT DEFAULT 'captured',\n \"notes\" TEXT,\n \"capture_key\" TEXT,\n \"capture_digest\" TEXT,\n \"kind\" TEXT DEFAULT 'completed_work',\n \"previous_submission_id\" UUID,\n \"intake_item_id\" TEXT,\n \"page_count\" INTEGER DEFAULT 0,\n \"ocr_text\" TEXT,\n \"extracted\" TEXT,\n \"reported_by\" TEXT DEFAULT 'learner',\n \"evidence_url\" TEXT,\n \"reported_score\" REAL\n);",
5174
6894
  "columns": {
5175
6895
  "id": {
5176
6896
  "type": "UUID",
@@ -5264,6 +6984,26 @@
5264
6984
  "type": "TEXT",
5265
6985
  "notNull": false
5266
6986
  },
6987
+ "kind": {
6988
+ "type": "TEXT",
6989
+ "notNull": false,
6990
+ "default": "completed_work"
6991
+ },
6992
+ "previous_submission_id": {
6993
+ "type": "UUID",
6994
+ "referenceKind": "foreignKey",
6995
+ "notNull": false,
6996
+ "foreignKey": {
6997
+ "table": "submissions",
6998
+ "column": "id",
6999
+ "onDelete": "NO ACTION",
7000
+ "onUpdate": "CASCADE"
7001
+ }
7002
+ },
7003
+ "intake_item_id": {
7004
+ "type": "TEXT",
7005
+ "notNull": false
7006
+ },
5267
7007
  "page_count": {
5268
7008
  "type": "INTEGER",
5269
7009
  "notNull": false,
@@ -5333,9 +7073,15 @@
5333
7073
  "columns": [
5334
7074
  "progress_id"
5335
7075
  ]
7076
+ },
7077
+ {
7078
+ "name": "submissions_previous_submission_id_idx",
7079
+ "columns": [
7080
+ "previous_submission_id"
7081
+ ]
5336
7082
  }
5337
7083
  ],
5338
- "version": "9cf5d690"
7084
+ "version": "7c394510"
5339
7085
  },
5340
7086
  "importPath": "@happyvertical/smrt-education"
5341
7087
  },
@@ -5360,7 +7106,7 @@
5360
7106
  "collectionExportName": "ExternalCompletionCollectionCollection",
5361
7107
  "schema": {
5362
7108
  "tableName": "submissions",
5363
- "ddl": "CREATE TABLE IF NOT EXISTS \"submissions\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"_meta_type\" TEXT NOT NULL,\n \"_meta_data\" JSON,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" UUID,\n \"learner_id\" UUID,\n \"lesson_id\" UUID,\n \"progress_id\" UUID,\n \"submitted_at\" TEXT,\n \"status\" TEXT DEFAULT 'captured',\n \"notes\" TEXT,\n \"capture_key\" TEXT,\n \"capture_digest\" TEXT,\n \"page_count\" INTEGER DEFAULT 0,\n \"ocr_text\" TEXT,\n \"extracted\" TEXT,\n \"reported_by\" TEXT DEFAULT 'learner',\n \"evidence_url\" TEXT,\n \"reported_score\" REAL\n);",
7109
+ "ddl": "CREATE TABLE IF NOT EXISTS \"submissions\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"_meta_type\" TEXT NOT NULL,\n \"_meta_data\" JSON,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" UUID,\n \"learner_id\" UUID,\n \"lesson_id\" UUID,\n \"progress_id\" UUID,\n \"submitted_at\" TEXT,\n \"status\" TEXT DEFAULT 'captured',\n \"notes\" TEXT,\n \"capture_key\" TEXT,\n \"capture_digest\" TEXT,\n \"kind\" TEXT DEFAULT 'completed_work',\n \"previous_submission_id\" UUID,\n \"intake_item_id\" TEXT,\n \"page_count\" INTEGER DEFAULT 0,\n \"ocr_text\" TEXT,\n \"extracted\" TEXT,\n \"reported_by\" TEXT DEFAULT 'learner',\n \"evidence_url\" TEXT,\n \"reported_score\" REAL\n);",
5364
7110
  "columns": {
5365
7111
  "id": {
5366
7112
  "type": "UUID",
@@ -5450,7 +7196,27 @@
5450
7196
  "type": "TEXT",
5451
7197
  "notNull": false
5452
7198
  },
5453
- "capture_digest": {
7199
+ "capture_digest": {
7200
+ "type": "TEXT",
7201
+ "notNull": false
7202
+ },
7203
+ "kind": {
7204
+ "type": "TEXT",
7205
+ "notNull": false,
7206
+ "default": "completed_work"
7207
+ },
7208
+ "previous_submission_id": {
7209
+ "type": "UUID",
7210
+ "referenceKind": "foreignKey",
7211
+ "notNull": false,
7212
+ "foreignKey": {
7213
+ "table": "submissions",
7214
+ "column": "id",
7215
+ "onDelete": "NO ACTION",
7216
+ "onUpdate": "CASCADE"
7217
+ }
7218
+ },
7219
+ "intake_item_id": {
5454
7220
  "type": "TEXT",
5455
7221
  "notNull": false
5456
7222
  },
@@ -5523,9 +7289,15 @@
5523
7289
  "columns": [
5524
7290
  "progress_id"
5525
7291
  ]
7292
+ },
7293
+ {
7294
+ "name": "submissions_previous_submission_id_idx",
7295
+ "columns": [
7296
+ "previous_submission_id"
7297
+ ]
5526
7298
  }
5527
7299
  ],
5528
- "version": "97981928"
7300
+ "version": "eff3715d"
5529
7301
  },
5530
7302
  "importPath": "@happyvertical/smrt-education"
5531
7303
  },
@@ -5550,7 +7322,7 @@
5550
7322
  "collectionExportName": "AttestationCollectionCollection",
5551
7323
  "schema": {
5552
7324
  "tableName": "submissions",
5553
- "ddl": "CREATE TABLE IF NOT EXISTS \"submissions\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"_meta_type\" TEXT NOT NULL,\n \"_meta_data\" JSON,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" UUID,\n \"learner_id\" UUID,\n \"lesson_id\" UUID,\n \"progress_id\" UUID,\n \"submitted_at\" TEXT,\n \"status\" TEXT DEFAULT 'captured',\n \"notes\" TEXT,\n \"capture_key\" TEXT,\n \"capture_digest\" TEXT,\n \"page_count\" INTEGER DEFAULT 0,\n \"ocr_text\" TEXT,\n \"extracted\" TEXT,\n \"reported_by\" TEXT DEFAULT 'learner',\n \"evidence_url\" TEXT,\n \"reported_score\" REAL\n);",
7325
+ "ddl": "CREATE TABLE IF NOT EXISTS \"submissions\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"_meta_type\" TEXT NOT NULL,\n \"_meta_data\" JSON,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" UUID,\n \"learner_id\" UUID,\n \"lesson_id\" UUID,\n \"progress_id\" UUID,\n \"submitted_at\" TEXT,\n \"status\" TEXT DEFAULT 'captured',\n \"notes\" TEXT,\n \"capture_key\" TEXT,\n \"capture_digest\" TEXT,\n \"kind\" TEXT DEFAULT 'completed_work',\n \"previous_submission_id\" UUID,\n \"intake_item_id\" TEXT,\n \"page_count\" INTEGER DEFAULT 0,\n \"ocr_text\" TEXT,\n \"extracted\" TEXT,\n \"reported_by\" TEXT DEFAULT 'learner',\n \"evidence_url\" TEXT,\n \"reported_score\" REAL\n);",
5554
7326
  "columns": {
5555
7327
  "id": {
5556
7328
  "type": "UUID",
@@ -5644,6 +7416,26 @@
5644
7416
  "type": "TEXT",
5645
7417
  "notNull": false
5646
7418
  },
7419
+ "kind": {
7420
+ "type": "TEXT",
7421
+ "notNull": false,
7422
+ "default": "completed_work"
7423
+ },
7424
+ "previous_submission_id": {
7425
+ "type": "UUID",
7426
+ "referenceKind": "foreignKey",
7427
+ "notNull": false,
7428
+ "foreignKey": {
7429
+ "table": "submissions",
7430
+ "column": "id",
7431
+ "onDelete": "NO ACTION",
7432
+ "onUpdate": "CASCADE"
7433
+ }
7434
+ },
7435
+ "intake_item_id": {
7436
+ "type": "TEXT",
7437
+ "notNull": false
7438
+ },
5647
7439
  "page_count": {
5648
7440
  "type": "INTEGER",
5649
7441
  "notNull": false,
@@ -5713,9 +7505,15 @@
5713
7505
  "columns": [
5714
7506
  "progress_id"
5715
7507
  ]
7508
+ },
7509
+ {
7510
+ "name": "submissions_previous_submission_id_idx",
7511
+ "columns": [
7512
+ "previous_submission_id"
7513
+ ]
5716
7514
  }
5717
7515
  ],
5718
- "version": "03b3a269"
7516
+ "version": "4f3230a3"
5719
7517
  },
5720
7518
  "importPath": "@happyvertical/smrt-education"
5721
7519
  },
@@ -6751,8 +8549,239 @@
6751
8549
  }
6752
8550
  ],
6753
8551
  "schema": {
6754
- "tableName": "curricula",
6755
- "ddl": "CREATE TABLE IF NOT EXISTS \"curricula\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" UUID NOT NULL,\n \"learner_id\" UUID NOT NULL,\n \"title\" TEXT NOT NULL,\n \"starts_on\" TIMESTAMP,\n \"ends_on\" TIMESTAMP,\n \"status\" TEXT DEFAULT 'planned'\n);",
8552
+ "tableName": "curricula",
8553
+ "ddl": "CREATE TABLE IF NOT EXISTS \"curricula\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" UUID NOT NULL,\n \"learner_id\" UUID NOT NULL,\n \"title\" TEXT NOT NULL,\n \"starts_on\" TIMESTAMP,\n \"ends_on\" TIMESTAMP,\n \"status\" TEXT DEFAULT 'planned'\n);",
8554
+ "columns": {
8555
+ "id": {
8556
+ "type": "UUID",
8557
+ "primaryKey": true,
8558
+ "referenceKind": "id",
8559
+ "notNull": true
8560
+ },
8561
+ "slug": {
8562
+ "type": "TEXT",
8563
+ "notNull": true
8564
+ },
8565
+ "context": {
8566
+ "type": "TEXT",
8567
+ "notNull": true,
8568
+ "default": ""
8569
+ },
8570
+ "created_at": {
8571
+ "type": "TIMESTAMP",
8572
+ "notNull": true,
8573
+ "default": "current_timestamp"
8574
+ },
8575
+ "updated_at": {
8576
+ "type": "TIMESTAMP",
8577
+ "notNull": true,
8578
+ "default": "current_timestamp"
8579
+ },
8580
+ "tenant_id": {
8581
+ "type": "UUID",
8582
+ "referenceKind": "tenantId",
8583
+ "notNull": true,
8584
+ "unique": false
8585
+ },
8586
+ "learner_id": {
8587
+ "type": "UUID",
8588
+ "referenceKind": "foreignKey",
8589
+ "notNull": true,
8590
+ "unique": false,
8591
+ "foreignKey": {
8592
+ "table": "learners",
8593
+ "column": "id",
8594
+ "onDelete": "NO ACTION",
8595
+ "onUpdate": "CASCADE"
8596
+ }
8597
+ },
8598
+ "title": {
8599
+ "type": "TEXT",
8600
+ "notNull": true,
8601
+ "unique": false
8602
+ },
8603
+ "starts_on": {
8604
+ "type": "TIMESTAMP",
8605
+ "notNull": false,
8606
+ "unique": false
8607
+ },
8608
+ "ends_on": {
8609
+ "type": "TIMESTAMP",
8610
+ "notNull": false,
8611
+ "unique": false
8612
+ },
8613
+ "status": {
8614
+ "type": "TEXT",
8615
+ "notNull": false,
8616
+ "unique": false,
8617
+ "default": "planned"
8618
+ }
8619
+ },
8620
+ "indexes": [
8621
+ {
8622
+ "name": "curricula_slug_context_idx",
8623
+ "columns": [
8624
+ "tenant_id",
8625
+ "slug",
8626
+ "context"
8627
+ ],
8628
+ "unique": true
8629
+ },
8630
+ {
8631
+ "name": "curricula_tenant_id_created_at_idx",
8632
+ "columns": [
8633
+ "tenant_id",
8634
+ "created_at"
8635
+ ]
8636
+ },
8637
+ {
8638
+ "name": "curricula_learner_id_idx",
8639
+ "columns": [
8640
+ "learner_id"
8641
+ ]
8642
+ }
8643
+ ],
8644
+ "version": "b7e90cbd"
8645
+ },
8646
+ "importPath": "@happyvertical/smrt-education"
8647
+ },
8648
+ "@happyvertical/smrt-education:Enrollment": {
8649
+ "name": "enrollment",
8650
+ "className": "Enrollment",
8651
+ "qualifiedName": "@happyvertical/smrt-education:Enrollment",
8652
+ "collection": "enrollments",
8653
+ "description": "One course in one curriculum; a new curriculum means a new enrollment.",
8654
+ "filePath": "/home/runner/work/smrt/smrt/packages/education/src/learners.ts",
8655
+ "packageName": "@happyvertical/smrt-education",
8656
+ "fields": {
8657
+ "tenantId": {
8658
+ "type": "text",
8659
+ "required": true,
8660
+ "_meta": {
8661
+ "sqlType": "UUID",
8662
+ "__tenancy": {
8663
+ "isTenantIdField": true,
8664
+ "autoFilter": true,
8665
+ "required": true,
8666
+ "autoPopulate": true,
8667
+ "nullable": false,
8668
+ "mode": "required",
8669
+ "field": "tenantId",
8670
+ "allowSuperAdminBypass": false
8671
+ }
8672
+ }
8673
+ },
8674
+ "curriculumId": {
8675
+ "type": "foreignKey",
8676
+ "required": true,
8677
+ "related": "Curriculum",
8678
+ "_meta": {
8679
+ "required": true
8680
+ }
8681
+ },
8682
+ "learnerId": {
8683
+ "type": "foreignKey",
8684
+ "required": true,
8685
+ "related": "Learner",
8686
+ "_meta": {
8687
+ "required": true
8688
+ }
8689
+ },
8690
+ "courseId": {
8691
+ "type": "foreignKey",
8692
+ "required": true,
8693
+ "related": "Course",
8694
+ "_meta": {
8695
+ "required": true
8696
+ }
8697
+ },
8698
+ "status": {
8699
+ "type": "text",
8700
+ "required": false,
8701
+ "default": "planned",
8702
+ "enum": [
8703
+ "planned",
8704
+ "active",
8705
+ "paused",
8706
+ "completed",
8707
+ "dropped"
8708
+ ]
8709
+ },
8710
+ "startedAt": {
8711
+ "type": "datetime",
8712
+ "required": false
8713
+ },
8714
+ "completedAt": {
8715
+ "type": "datetime",
8716
+ "required": false
8717
+ },
8718
+ "targetMinutesPerWeek": {
8719
+ "type": "integer",
8720
+ "required": true,
8721
+ "default": 0
8722
+ },
8723
+ "sortOrder": {
8724
+ "type": "integer",
8725
+ "required": true,
8726
+ "default": 0
8727
+ }
8728
+ },
8729
+ "methods": {
8730
+ "save": {
8731
+ "name": "save",
8732
+ "async": true,
8733
+ "parameters": [],
8734
+ "returnType": "Promise<this>",
8735
+ "isStatic": false,
8736
+ "isPublic": true
8737
+ }
8738
+ },
8739
+ "decoratorConfig": {
8740
+ "api": false,
8741
+ "mcp": false,
8742
+ "cli": false,
8743
+ "conflictColumns": [
8744
+ "tenant_id",
8745
+ "curriculum_id",
8746
+ "course_id"
8747
+ ],
8748
+ "tenantScoped": {
8749
+ "mode": "required"
8750
+ }
8751
+ },
8752
+ "extends": "SmrtObject",
8753
+ "exportName": "Enrollment",
8754
+ "collectionExportName": "EnrollmentCollection",
8755
+ "validationRules": [
8756
+ {
8757
+ "field": "curriculumId",
8758
+ "rule": "required",
8759
+ "fieldType": "foreignKey"
8760
+ },
8761
+ {
8762
+ "field": "learnerId",
8763
+ "rule": "required",
8764
+ "fieldType": "foreignKey"
8765
+ },
8766
+ {
8767
+ "field": "courseId",
8768
+ "rule": "required",
8769
+ "fieldType": "foreignKey"
8770
+ },
8771
+ {
8772
+ "field": "targetMinutesPerWeek",
8773
+ "rule": "required",
8774
+ "fieldType": "integer"
8775
+ },
8776
+ {
8777
+ "field": "sortOrder",
8778
+ "rule": "required",
8779
+ "fieldType": "integer"
8780
+ }
8781
+ ],
8782
+ "schema": {
8783
+ "tableName": "enrollments",
8784
+ "ddl": "CREATE TABLE IF NOT EXISTS \"enrollments\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" UUID NOT NULL,\n \"curriculum_id\" UUID NOT NULL,\n \"learner_id\" UUID NOT NULL,\n \"course_id\" UUID NOT NULL,\n \"status\" TEXT DEFAULT 'planned',\n \"started_at\" TIMESTAMP,\n \"completed_at\" TIMESTAMP,\n \"target_minutes_per_week\" INTEGER NOT NULL DEFAULT 0,\n \"sort_order\" INTEGER NOT NULL DEFAULT 0\n);",
6756
8785
  "columns": {
6757
8786
  "id": {
6758
8787
  "type": "UUID",
@@ -6785,6 +8814,18 @@
6785
8814
  "notNull": true,
6786
8815
  "unique": false
6787
8816
  },
8817
+ "curriculum_id": {
8818
+ "type": "UUID",
8819
+ "referenceKind": "foreignKey",
8820
+ "notNull": true,
8821
+ "unique": false,
8822
+ "foreignKey": {
8823
+ "table": "curricula",
8824
+ "column": "id",
8825
+ "onDelete": "CASCADE",
8826
+ "onUpdate": "CASCADE"
8827
+ }
8828
+ },
6788
8829
  "learner_id": {
6789
8830
  "type": "UUID",
6790
8831
  "referenceKind": "foreignKey",
@@ -6797,62 +8838,100 @@
6797
8838
  "onUpdate": "CASCADE"
6798
8839
  }
6799
8840
  },
6800
- "title": {
6801
- "type": "TEXT",
8841
+ "course_id": {
8842
+ "type": "UUID",
8843
+ "referenceKind": "foreignKey",
6802
8844
  "notNull": true,
6803
- "unique": false
8845
+ "unique": false,
8846
+ "foreignKey": {
8847
+ "table": "courses",
8848
+ "column": "id",
8849
+ "onDelete": "CASCADE",
8850
+ "onUpdate": "CASCADE"
8851
+ }
6804
8852
  },
6805
- "starts_on": {
8853
+ "status": {
8854
+ "type": "TEXT",
8855
+ "notNull": false,
8856
+ "unique": false,
8857
+ "default": "planned"
8858
+ },
8859
+ "started_at": {
6806
8860
  "type": "TIMESTAMP",
6807
8861
  "notNull": false,
6808
8862
  "unique": false
6809
8863
  },
6810
- "ends_on": {
8864
+ "completed_at": {
6811
8865
  "type": "TIMESTAMP",
6812
8866
  "notNull": false,
6813
8867
  "unique": false
6814
8868
  },
6815
- "status": {
6816
- "type": "TEXT",
6817
- "notNull": false,
8869
+ "target_minutes_per_week": {
8870
+ "type": "INTEGER",
8871
+ "notNull": true,
6818
8872
  "unique": false,
6819
- "default": "planned"
8873
+ "default": 0
8874
+ },
8875
+ "sort_order": {
8876
+ "type": "INTEGER",
8877
+ "notNull": true,
8878
+ "unique": false,
8879
+ "default": 0
6820
8880
  }
6821
8881
  },
6822
8882
  "indexes": [
6823
8883
  {
6824
- "name": "curricula_slug_context_idx",
8884
+ "name": "enrollments_tenant_id_curriculum_id_idx",
6825
8885
  "columns": [
6826
8886
  "tenant_id",
6827
- "slug",
6828
- "context"
8887
+ "curriculum_id",
8888
+ "course_id"
6829
8889
  ],
6830
8890
  "unique": true
6831
8891
  },
6832
8892
  {
6833
- "name": "curricula_tenant_id_created_at_idx",
8893
+ "name": "enrollments_slug_context_idx",
8894
+ "columns": [
8895
+ "slug",
8896
+ "context"
8897
+ ]
8898
+ },
8899
+ {
8900
+ "name": "enrollments_tenant_id_created_at_idx",
6834
8901
  "columns": [
6835
8902
  "tenant_id",
6836
8903
  "created_at"
6837
8904
  ]
6838
8905
  },
6839
8906
  {
6840
- "name": "curricula_learner_id_idx",
8907
+ "name": "enrollments_curriculum_id_idx",
8908
+ "columns": [
8909
+ "curriculum_id"
8910
+ ]
8911
+ },
8912
+ {
8913
+ "name": "enrollments_learner_id_idx",
6841
8914
  "columns": [
6842
8915
  "learner_id"
6843
8916
  ]
8917
+ },
8918
+ {
8919
+ "name": "enrollments_course_id_idx",
8920
+ "columns": [
8921
+ "course_id"
8922
+ ]
6844
8923
  }
6845
8924
  ],
6846
- "version": "b7e90cbd"
8925
+ "version": "2a34b5ee"
6847
8926
  },
6848
8927
  "importPath": "@happyvertical/smrt-education"
6849
8928
  },
6850
- "@happyvertical/smrt-education:Enrollment": {
6851
- "name": "enrollment",
6852
- "className": "Enrollment",
6853
- "qualifiedName": "@happyvertical/smrt-education:Enrollment",
6854
- "collection": "enrollments",
6855
- "description": "One course in one curriculum; a new curriculum means a new enrollment.",
8929
+ "@happyvertical/smrt-education:LessonProgress": {
8930
+ "name": "lessonprogress",
8931
+ "className": "LessonProgress",
8932
+ "qualifiedName": "@happyvertical/smrt-education:LessonProgress",
8933
+ "collection": "lessonprogresses",
8934
+ "description": "Progress identity is enrollment + lesson, never learner + lesson.",
6856
8935
  "filePath": "/home/runner/work/smrt/smrt/packages/education/src/learners.ts",
6857
8936
  "packageName": "@happyvertical/smrt-education",
6858
8937
  "fields": {
@@ -6873,10 +8952,10 @@
6873
8952
  }
6874
8953
  }
6875
8954
  },
6876
- "curriculumId": {
8955
+ "enrollmentId": {
6877
8956
  "type": "foreignKey",
6878
8957
  "required": true,
6879
- "related": "Curriculum",
8958
+ "related": "Enrollment",
6880
8959
  "_meta": {
6881
8960
  "required": true
6882
8961
  }
@@ -6889,10 +8968,10 @@
6889
8968
  "required": true
6890
8969
  }
6891
8970
  },
6892
- "courseId": {
8971
+ "lessonId": {
6893
8972
  "type": "foreignKey",
6894
8973
  "required": true,
6895
- "related": "Course",
8974
+ "related": "Lesson",
6896
8975
  "_meta": {
6897
8976
  "required": true
6898
8977
  }
@@ -6900,13 +8979,14 @@
6900
8979
  "status": {
6901
8980
  "type": "text",
6902
8981
  "required": false,
6903
- "default": "planned",
8982
+ "default": "not_started",
6904
8983
  "enum": [
6905
- "planned",
6906
- "active",
6907
- "paused",
6908
- "completed",
6909
- "dropped"
8984
+ "not_started",
8985
+ "in_progress",
8986
+ "submitted",
8987
+ "needs_review",
8988
+ "complete",
8989
+ "skipped"
6910
8990
  ]
6911
8991
  },
6912
8992
  "startedAt": {
@@ -6917,15 +8997,22 @@
6917
8997
  "type": "datetime",
6918
8998
  "required": false
6919
8999
  },
6920
- "targetMinutesPerWeek": {
9000
+ "timeSpentSeconds": {
6921
9001
  "type": "integer",
6922
9002
  "required": true,
6923
9003
  "default": 0
6924
9004
  },
6925
- "sortOrder": {
9005
+ "attempts": {
6926
9006
  "type": "integer",
6927
9007
  "required": true,
6928
9008
  "default": 0
9009
+ },
9010
+ "bestScore": {
9011
+ "type": "decimal",
9012
+ "required": false,
9013
+ "_meta": {
9014
+ "nullable": true
9015
+ }
6929
9016
  }
6930
9017
  },
6931
9018
  "methods": {
@@ -6942,21 +9029,22 @@
6942
9029
  "api": false,
6943
9030
  "mcp": false,
6944
9031
  "cli": false,
9032
+ "tableName": "lesson_progress",
6945
9033
  "conflictColumns": [
6946
9034
  "tenant_id",
6947
- "curriculum_id",
6948
- "course_id"
9035
+ "enrollment_id",
9036
+ "lesson_id"
6949
9037
  ],
6950
9038
  "tenantScoped": {
6951
9039
  "mode": "required"
6952
9040
  }
6953
9041
  },
6954
9042
  "extends": "SmrtObject",
6955
- "exportName": "Enrollment",
6956
- "collectionExportName": "EnrollmentCollection",
9043
+ "exportName": "LessonProgress",
9044
+ "collectionExportName": "LessonProgressCollection",
6957
9045
  "validationRules": [
6958
9046
  {
6959
- "field": "curriculumId",
9047
+ "field": "enrollmentId",
6960
9048
  "rule": "required",
6961
9049
  "fieldType": "foreignKey"
6962
9050
  },
@@ -6966,24 +9054,24 @@
6966
9054
  "fieldType": "foreignKey"
6967
9055
  },
6968
9056
  {
6969
- "field": "courseId",
9057
+ "field": "lessonId",
6970
9058
  "rule": "required",
6971
9059
  "fieldType": "foreignKey"
6972
9060
  },
6973
9061
  {
6974
- "field": "targetMinutesPerWeek",
9062
+ "field": "timeSpentSeconds",
6975
9063
  "rule": "required",
6976
9064
  "fieldType": "integer"
6977
9065
  },
6978
9066
  {
6979
- "field": "sortOrder",
9067
+ "field": "attempts",
6980
9068
  "rule": "required",
6981
9069
  "fieldType": "integer"
6982
9070
  }
6983
9071
  ],
6984
9072
  "schema": {
6985
- "tableName": "enrollments",
6986
- "ddl": "CREATE TABLE IF NOT EXISTS \"enrollments\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" UUID NOT NULL,\n \"curriculum_id\" UUID NOT NULL,\n \"learner_id\" UUID NOT NULL,\n \"course_id\" UUID NOT NULL,\n \"status\" TEXT DEFAULT 'planned',\n \"started_at\" TIMESTAMP,\n \"completed_at\" TIMESTAMP,\n \"target_minutes_per_week\" INTEGER NOT NULL DEFAULT 0,\n \"sort_order\" INTEGER NOT NULL DEFAULT 0\n);",
9073
+ "tableName": "lesson_progress",
9074
+ "ddl": "CREATE TABLE IF NOT EXISTS \"lesson_progress\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" UUID NOT NULL,\n \"enrollment_id\" UUID NOT NULL,\n \"learner_id\" UUID NOT NULL,\n \"lesson_id\" UUID NOT NULL,\n \"status\" TEXT DEFAULT 'not_started',\n \"started_at\" TIMESTAMP,\n \"completed_at\" TIMESTAMP,\n \"time_spent_seconds\" INTEGER NOT NULL DEFAULT 0,\n \"attempts\" INTEGER NOT NULL DEFAULT 0,\n \"best_score\" REAL\n);",
6987
9075
  "columns": {
6988
9076
  "id": {
6989
9077
  "type": "UUID",
@@ -7016,13 +9104,13 @@
7016
9104
  "notNull": true,
7017
9105
  "unique": false
7018
9106
  },
7019
- "curriculum_id": {
9107
+ "enrollment_id": {
7020
9108
  "type": "UUID",
7021
9109
  "referenceKind": "foreignKey",
7022
9110
  "notNull": true,
7023
9111
  "unique": false,
7024
9112
  "foreignKey": {
7025
- "table": "curricula",
9113
+ "table": "enrollments",
7026
9114
  "column": "id",
7027
9115
  "onDelete": "CASCADE",
7028
9116
  "onUpdate": "CASCADE"
@@ -7040,13 +9128,13 @@
7040
9128
  "onUpdate": "CASCADE"
7041
9129
  }
7042
9130
  },
7043
- "course_id": {
9131
+ "lesson_id": {
7044
9132
  "type": "UUID",
7045
9133
  "referenceKind": "foreignKey",
7046
9134
  "notNull": true,
7047
9135
  "unique": false,
7048
9136
  "foreignKey": {
7049
- "table": "courses",
9137
+ "table": "lessons",
7050
9138
  "column": "id",
7051
9139
  "onDelete": "CASCADE",
7052
9140
  "onUpdate": "CASCADE"
@@ -7056,7 +9144,7 @@
7056
9144
  "type": "TEXT",
7057
9145
  "notNull": false,
7058
9146
  "unique": false,
7059
- "default": "planned"
9147
+ "default": "not_started"
7060
9148
  },
7061
9149
  "started_at": {
7062
9150
  "type": "TIMESTAMP",
@@ -7068,108 +9156,97 @@
7068
9156
  "notNull": false,
7069
9157
  "unique": false
7070
9158
  },
7071
- "target_minutes_per_week": {
9159
+ "time_spent_seconds": {
7072
9160
  "type": "INTEGER",
7073
9161
  "notNull": true,
7074
9162
  "unique": false,
7075
9163
  "default": 0
7076
9164
  },
7077
- "sort_order": {
9165
+ "attempts": {
7078
9166
  "type": "INTEGER",
7079
9167
  "notNull": true,
7080
9168
  "unique": false,
7081
9169
  "default": 0
9170
+ },
9171
+ "best_score": {
9172
+ "type": "REAL",
9173
+ "notNull": false,
9174
+ "unique": false
7082
9175
  }
7083
9176
  },
7084
9177
  "indexes": [
7085
9178
  {
7086
- "name": "enrollments_tenant_id_curriculum_id_idx",
9179
+ "name": "lesson_progress_tenant_id_enrollment_id_idx",
7087
9180
  "columns": [
7088
9181
  "tenant_id",
7089
- "curriculum_id",
7090
- "course_id"
9182
+ "enrollment_id",
9183
+ "lesson_id"
7091
9184
  ],
7092
9185
  "unique": true
7093
9186
  },
7094
9187
  {
7095
- "name": "enrollments_slug_context_idx",
9188
+ "name": "lesson_progress_slug_context_idx",
7096
9189
  "columns": [
7097
9190
  "slug",
7098
9191
  "context"
7099
9192
  ]
7100
9193
  },
7101
9194
  {
7102
- "name": "enrollments_tenant_id_created_at_idx",
9195
+ "name": "lesson_progress_tenant_id_created_at_idx",
7103
9196
  "columns": [
7104
9197
  "tenant_id",
7105
9198
  "created_at"
7106
9199
  ]
7107
9200
  },
7108
9201
  {
7109
- "name": "enrollments_curriculum_id_idx",
9202
+ "name": "lesson_progress_enrollment_id_idx",
7110
9203
  "columns": [
7111
- "curriculum_id"
9204
+ "enrollment_id"
7112
9205
  ]
7113
9206
  },
7114
9207
  {
7115
- "name": "enrollments_learner_id_idx",
9208
+ "name": "lesson_progress_learner_id_idx",
7116
9209
  "columns": [
7117
9210
  "learner_id"
7118
9211
  ]
7119
9212
  },
7120
9213
  {
7121
- "name": "enrollments_course_id_idx",
9214
+ "name": "lesson_progress_lesson_id_idx",
7122
9215
  "columns": [
7123
- "course_id"
9216
+ "lesson_id"
7124
9217
  ]
7125
9218
  }
7126
9219
  ],
7127
- "version": "2a34b5ee"
9220
+ "version": "36704fbd"
7128
9221
  },
7129
9222
  "importPath": "@happyvertical/smrt-education"
7130
9223
  },
7131
- "@happyvertical/smrt-education:LessonProgress": {
7132
- "name": "lessonprogress",
7133
- "className": "LessonProgress",
7134
- "qualifiedName": "@happyvertical/smrt-education:LessonProgress",
7135
- "collection": "lessonprogresses",
7136
- "description": "Progress identity is enrollment + lesson, never learner + lesson.",
7137
- "filePath": "/home/runner/work/smrt/smrt/packages/education/src/learners.ts",
9224
+ "@happyvertical/smrt-education:LessonAsset": {
9225
+ "name": "lessonasset",
9226
+ "className": "LessonAsset",
9227
+ "qualifiedName": "@happyvertical/smrt-education:LessonAsset",
9228
+ "collection": "lessonassets",
9229
+ "filePath": "/home/runner/work/smrt/smrt/packages/education/src/lesson-assets.ts",
7138
9230
  "packageName": "@happyvertical/smrt-education",
7139
9231
  "fields": {
7140
9232
  "tenantId": {
7141
9233
  "type": "text",
7142
- "required": true,
9234
+ "required": false,
7143
9235
  "_meta": {
7144
9236
  "sqlType": "UUID",
9237
+ "nullable": true,
7145
9238
  "__tenancy": {
7146
9239
  "isTenantIdField": true,
7147
9240
  "autoFilter": true,
7148
- "required": true,
9241
+ "required": false,
7149
9242
  "autoPopulate": true,
7150
- "nullable": false,
7151
- "mode": "required",
9243
+ "nullable": true,
9244
+ "mode": "optional",
7152
9245
  "field": "tenantId",
7153
9246
  "allowSuperAdminBypass": false
7154
9247
  }
7155
9248
  }
7156
9249
  },
7157
- "enrollmentId": {
7158
- "type": "foreignKey",
7159
- "required": true,
7160
- "related": "Enrollment",
7161
- "_meta": {
7162
- "required": true
7163
- }
7164
- },
7165
- "learnerId": {
7166
- "type": "foreignKey",
7167
- "required": true,
7168
- "related": "Learner",
7169
- "_meta": {
7170
- "required": true
7171
- }
7172
- },
7173
9250
  "lessonId": {
7174
9251
  "type": "foreignKey",
7175
9252
  "required": true,
@@ -7178,43 +9255,29 @@
7178
9255
  "required": true
7179
9256
  }
7180
9257
  },
7181
- "status": {
7182
- "type": "text",
7183
- "required": false,
7184
- "default": "not_started",
7185
- "enum": [
7186
- "not_started",
7187
- "in_progress",
7188
- "submitted",
7189
- "needs_review",
7190
- "complete",
7191
- "skipped"
7192
- ]
7193
- },
7194
- "startedAt": {
7195
- "type": "datetime",
7196
- "required": false
7197
- },
7198
- "completedAt": {
7199
- "type": "datetime",
7200
- "required": false
9258
+ "assetId": {
9259
+ "type": "crossPackageRef",
9260
+ "required": true,
9261
+ "related": "@happyvertical/smrt-assets:Asset"
7201
9262
  },
7202
- "timeSpentSeconds": {
7203
- "type": "integer",
9263
+ "relationship": {
9264
+ "type": "text",
7204
9265
  "required": true,
7205
- "default": 0
9266
+ "default": "attachment",
9267
+ "_meta": {
9268
+ "required": true
9269
+ },
9270
+ "enum": [
9271
+ "printable",
9272
+ "answer-key",
9273
+ "video",
9274
+ "attachment"
9275
+ ]
7206
9276
  },
7207
- "attempts": {
9277
+ "sortOrder": {
7208
9278
  "type": "integer",
7209
9279
  "required": true,
7210
9280
  "default": 0
7211
- },
7212
- "bestScore": {
7213
- "type": "decimal",
7214
- "required": false,
7215
- "_meta": {
7216
- "nullable": true
7217
- }
7218
9281
  }
7219
9282
  },
7220
9283
  "methods": {
@@ -7228,52 +9291,48 @@
7228
9291
  }
7229
9292
  },
7230
9293
  "decoratorConfig": {
7231
- "api": false,
7232
- "mcp": false,
7233
- "cli": false,
7234
- "tableName": "lesson_progress",
9294
+ "tableName": "lesson_assets",
7235
9295
  "conflictColumns": [
7236
9296
  "tenant_id",
7237
- "enrollment_id",
7238
- "lesson_id"
9297
+ "lesson_id",
9298
+ "asset_id",
9299
+ "relationship"
7239
9300
  ],
9301
+ "api": false,
9302
+ "mcp": false,
9303
+ "cli": false,
7240
9304
  "tenantScoped": {
7241
- "mode": "required"
9305
+ "mode": "optional"
7242
9306
  }
7243
9307
  },
7244
9308
  "extends": "SmrtObject",
7245
- "exportName": "LessonProgress",
7246
- "collectionExportName": "LessonProgressCollection",
9309
+ "exportName": "LessonAsset",
9310
+ "collectionExportName": "LessonAssetCollection",
7247
9311
  "validationRules": [
7248
9312
  {
7249
- "field": "enrollmentId",
7250
- "rule": "required",
7251
- "fieldType": "foreignKey"
7252
- },
7253
- {
7254
- "field": "learnerId",
9313
+ "field": "lessonId",
7255
9314
  "rule": "required",
7256
9315
  "fieldType": "foreignKey"
7257
9316
  },
7258
9317
  {
7259
- "field": "lessonId",
9318
+ "field": "assetId",
7260
9319
  "rule": "required",
7261
- "fieldType": "foreignKey"
9320
+ "fieldType": "crossPackageRef"
7262
9321
  },
7263
9322
  {
7264
- "field": "timeSpentSeconds",
9323
+ "field": "relationship",
7265
9324
  "rule": "required",
7266
- "fieldType": "integer"
9325
+ "fieldType": "text"
7267
9326
  },
7268
9327
  {
7269
- "field": "attempts",
9328
+ "field": "sortOrder",
7270
9329
  "rule": "required",
7271
9330
  "fieldType": "integer"
7272
9331
  }
7273
9332
  ],
7274
9333
  "schema": {
7275
- "tableName": "lesson_progress",
7276
- "ddl": "CREATE TABLE IF NOT EXISTS \"lesson_progress\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" UUID NOT NULL,\n \"enrollment_id\" UUID NOT NULL,\n \"learner_id\" UUID NOT NULL,\n \"lesson_id\" UUID NOT NULL,\n \"status\" TEXT DEFAULT 'not_started',\n \"started_at\" TIMESTAMP,\n \"completed_at\" TIMESTAMP,\n \"time_spent_seconds\" INTEGER NOT NULL DEFAULT 0,\n \"attempts\" INTEGER NOT NULL DEFAULT 0,\n \"best_score\" REAL\n);",
9334
+ "tableName": "lesson_assets",
9335
+ "ddl": "CREATE TABLE IF NOT EXISTS \"lesson_assets\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" UUID,\n \"lesson_id\" UUID NOT NULL,\n \"asset_id\" UUID NOT NULL,\n \"relationship\" TEXT NOT NULL DEFAULT 'attachment',\n \"sort_order\" INTEGER NOT NULL DEFAULT 0\n);",
7277
9336
  "columns": {
7278
9337
  "id": {
7279
9338
  "type": "UUID",
@@ -7303,33 +9362,9 @@
7303
9362
  "tenant_id": {
7304
9363
  "type": "UUID",
7305
9364
  "referenceKind": "tenantId",
7306
- "notNull": true,
9365
+ "notNull": false,
7307
9366
  "unique": false
7308
9367
  },
7309
- "enrollment_id": {
7310
- "type": "UUID",
7311
- "referenceKind": "foreignKey",
7312
- "notNull": true,
7313
- "unique": false,
7314
- "foreignKey": {
7315
- "table": "enrollments",
7316
- "column": "id",
7317
- "onDelete": "CASCADE",
7318
- "onUpdate": "CASCADE"
7319
- }
7320
- },
7321
- "learner_id": {
7322
- "type": "UUID",
7323
- "referenceKind": "foreignKey",
7324
- "notNull": true,
7325
- "unique": false,
7326
- "foreignKey": {
7327
- "table": "learners",
7328
- "column": "id",
7329
- "onDelete": "NO ACTION",
7330
- "onUpdate": "CASCADE"
7331
- }
7332
- },
7333
9368
  "lesson_id": {
7334
9369
  "type": "UUID",
7335
9370
  "referenceKind": "foreignKey",
@@ -7342,113 +9377,110 @@
7342
9377
  "onUpdate": "CASCADE"
7343
9378
  }
7344
9379
  },
7345
- "status": {
7346
- "type": "TEXT",
7347
- "notNull": false,
7348
- "unique": false,
7349
- "default": "not_started"
7350
- },
7351
- "started_at": {
7352
- "type": "TIMESTAMP",
7353
- "notNull": false,
7354
- "unique": false
7355
- },
7356
- "completed_at": {
7357
- "type": "TIMESTAMP",
7358
- "notNull": false,
9380
+ "asset_id": {
9381
+ "type": "UUID",
9382
+ "referenceKind": "crossPackageRef",
9383
+ "notNull": true,
7359
9384
  "unique": false
7360
9385
  },
7361
- "time_spent_seconds": {
7362
- "type": "INTEGER",
9386
+ "relationship": {
9387
+ "type": "TEXT",
7363
9388
  "notNull": true,
7364
9389
  "unique": false,
7365
- "default": 0
9390
+ "default": "attachment"
7366
9391
  },
7367
- "attempts": {
9392
+ "sort_order": {
7368
9393
  "type": "INTEGER",
7369
9394
  "notNull": true,
7370
9395
  "unique": false,
7371
9396
  "default": 0
7372
- },
7373
- "best_score": {
7374
- "type": "REAL",
7375
- "notNull": false,
7376
- "unique": false
7377
9397
  }
7378
9398
  },
7379
9399
  "indexes": [
7380
9400
  {
7381
- "name": "lesson_progress_tenant_id_enrollment_id_idx",
9401
+ "name": "lesson_assets_tenant_id_lesson_id_idx",
7382
9402
  "columns": [
7383
9403
  "tenant_id",
7384
- "enrollment_id",
7385
- "lesson_id"
9404
+ "lesson_id",
9405
+ "asset_id",
9406
+ "relationship"
7386
9407
  ],
7387
- "unique": true
9408
+ "unique": true,
9409
+ "nullsNotDistinct": true
7388
9410
  },
7389
9411
  {
7390
- "name": "lesson_progress_slug_context_idx",
9412
+ "name": "lesson_assets_slug_context_idx",
7391
9413
  "columns": [
7392
9414
  "slug",
7393
9415
  "context"
7394
9416
  ]
7395
9417
  },
7396
9418
  {
7397
- "name": "lesson_progress_tenant_id_created_at_idx",
9419
+ "name": "lesson_assets_tenant_id_created_at_idx",
7398
9420
  "columns": [
7399
9421
  "tenant_id",
7400
9422
  "created_at"
7401
9423
  ]
7402
9424
  },
7403
9425
  {
7404
- "name": "lesson_progress_enrollment_id_idx",
7405
- "columns": [
7406
- "enrollment_id"
7407
- ]
7408
- },
7409
- {
7410
- "name": "lesson_progress_learner_id_idx",
9426
+ "name": "lesson_assets_lesson_id_idx",
7411
9427
  "columns": [
7412
- "learner_id"
9428
+ "lesson_id"
7413
9429
  ]
7414
9430
  },
7415
9431
  {
7416
- "name": "lesson_progress_lesson_id_idx",
9432
+ "name": "lesson_assets_asset_id_idx",
7417
9433
  "columns": [
7418
- "lesson_id"
9434
+ "asset_id"
7419
9435
  ]
7420
9436
  }
7421
9437
  ],
7422
- "version": "36704fbd"
9438
+ "version": "d96385c6"
7423
9439
  },
7424
9440
  "importPath": "@happyvertical/smrt-education"
7425
9441
  },
7426
- "@happyvertical/smrt-education:LessonAsset": {
7427
- "name": "lessonasset",
7428
- "className": "LessonAsset",
7429
- "qualifiedName": "@happyvertical/smrt-education:LessonAsset",
7430
- "collection": "lessonassets",
7431
- "filePath": "/home/runner/work/smrt/smrt/packages/education/src/lesson-assets.ts",
9442
+ "@happyvertical/smrt-education:Submission": {
9443
+ "name": "submission",
9444
+ "className": "Submission",
9445
+ "qualifiedName": "@happyvertical/smrt-education:Submission",
9446
+ "collection": "submissions",
9447
+ "description": "Evidence that a learner completed one progress item.",
9448
+ "filePath": "/home/runner/work/smrt/smrt/packages/education/src/submissions.ts",
7432
9449
  "packageName": "@happyvertical/smrt-education",
7433
9450
  "fields": {
9451
+ "created_at": {
9452
+ "type": "datetime",
9453
+ "required": false
9454
+ },
9455
+ "updated_at": {
9456
+ "type": "datetime",
9457
+ "required": false
9458
+ },
7434
9459
  "tenantId": {
7435
9460
  "type": "text",
7436
- "required": false,
9461
+ "required": true,
7437
9462
  "_meta": {
7438
9463
  "sqlType": "UUID",
7439
- "nullable": true,
7440
9464
  "__tenancy": {
7441
9465
  "isTenantIdField": true,
7442
9466
  "autoFilter": true,
7443
- "required": false,
9467
+ "required": true,
7444
9468
  "autoPopulate": true,
7445
- "nullable": true,
7446
- "mode": "optional",
9469
+ "nullable": false,
9470
+ "mode": "required",
7447
9471
  "field": "tenantId",
7448
9472
  "allowSuperAdminBypass": false
7449
9473
  }
7450
9474
  }
7451
9475
  },
9476
+ "learnerId": {
9477
+ "type": "foreignKey",
9478
+ "required": true,
9479
+ "related": "Learner",
9480
+ "_meta": {
9481
+ "required": true
9482
+ }
9483
+ },
7452
9484
  "lessonId": {
7453
9485
  "type": "foreignKey",
7454
9486
  "required": true,
@@ -7457,29 +9489,68 @@
7457
9489
  "required": true
7458
9490
  }
7459
9491
  },
7460
- "assetId": {
7461
- "type": "crossPackageRef",
9492
+ "progressId": {
9493
+ "type": "foreignKey",
7462
9494
  "required": true,
7463
- "related": "@happyvertical/smrt-assets:Asset"
9495
+ "related": "LessonProgress",
9496
+ "_meta": {
9497
+ "required": true
9498
+ }
7464
9499
  },
7465
- "relationship": {
9500
+ "submittedAt": {
9501
+ "type": "text",
9502
+ "required": false
9503
+ },
9504
+ "status": {
9505
+ "type": "text",
9506
+ "required": false,
9507
+ "default": "captured",
9508
+ "enum": [
9509
+ "captured",
9510
+ "extracting",
9511
+ "needs_review",
9512
+ "graded",
9513
+ "rejected"
9514
+ ]
9515
+ },
9516
+ "notes": {
9517
+ "type": "text",
9518
+ "required": false
9519
+ },
9520
+ "captureKey": {
9521
+ "type": "text",
9522
+ "required": false
9523
+ },
9524
+ "captureDigest": {
9525
+ "type": "text",
9526
+ "required": false
9527
+ },
9528
+ "kind": {
7466
9529
  "type": "text",
7467
9530
  "required": true,
7468
- "default": "attachment",
9531
+ "default": "completed_work",
7469
9532
  "_meta": {
7470
9533
  "required": true
7471
9534
  },
7472
9535
  "enum": [
7473
- "printable",
7474
- "answer-key",
7475
- "video",
7476
- "attachment"
9536
+ "blank_reference",
9537
+ "completed_work"
7477
9538
  ]
7478
9539
  },
7479
- "sortOrder": {
7480
- "type": "integer",
7481
- "required": true,
7482
- "default": 0
9540
+ "previousSubmissionId": {
9541
+ "type": "foreignKey",
9542
+ "required": false,
9543
+ "related": "Submission",
9544
+ "_meta": {
9545
+ "nullable": true
9546
+ }
9547
+ },
9548
+ "intakeItemId": {
9549
+ "type": "text",
9550
+ "required": false,
9551
+ "_meta": {
9552
+ "nullable": true
9553
+ }
7483
9554
  }
7484
9555
  },
7485
9556
  "methods": {
@@ -7493,48 +9564,48 @@
7493
9564
  }
7494
9565
  },
7495
9566
  "decoratorConfig": {
7496
- "tableName": "lesson_assets",
7497
- "conflictColumns": [
7498
- "tenant_id",
7499
- "lesson_id",
7500
- "asset_id",
7501
- "relationship"
7502
- ],
9567
+ "tableStrategy": "sti",
7503
9568
  "api": false,
7504
9569
  "mcp": false,
7505
9570
  "cli": false,
7506
9571
  "tenantScoped": {
7507
- "mode": "optional"
7508
- }
9572
+ "mode": "required"
9573
+ },
9574
+ "conflictColumns": [
9575
+ "tenant_id",
9576
+ "slug",
9577
+ "context",
9578
+ "_meta_type"
9579
+ ]
7509
9580
  },
7510
9581
  "extends": "SmrtObject",
7511
- "exportName": "LessonAsset",
7512
- "collectionExportName": "LessonAssetCollection",
9582
+ "exportName": "Submission",
9583
+ "collectionExportName": "SubmissionCollection",
7513
9584
  "validationRules": [
7514
9585
  {
7515
- "field": "lessonId",
9586
+ "field": "learnerId",
7516
9587
  "rule": "required",
7517
9588
  "fieldType": "foreignKey"
7518
9589
  },
7519
9590
  {
7520
- "field": "assetId",
9591
+ "field": "lessonId",
7521
9592
  "rule": "required",
7522
- "fieldType": "crossPackageRef"
9593
+ "fieldType": "foreignKey"
7523
9594
  },
7524
9595
  {
7525
- "field": "relationship",
9596
+ "field": "progressId",
7526
9597
  "rule": "required",
7527
- "fieldType": "text"
9598
+ "fieldType": "foreignKey"
7528
9599
  },
7529
9600
  {
7530
- "field": "sortOrder",
9601
+ "field": "kind",
7531
9602
  "rule": "required",
7532
- "fieldType": "integer"
9603
+ "fieldType": "text"
7533
9604
  }
7534
9605
  ],
7535
9606
  "schema": {
7536
- "tableName": "lesson_assets",
7537
- "ddl": "CREATE TABLE IF NOT EXISTS \"lesson_assets\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" UUID,\n \"lesson_id\" UUID NOT NULL,\n \"asset_id\" UUID NOT NULL,\n \"relationship\" TEXT NOT NULL DEFAULT 'attachment',\n \"sort_order\" INTEGER NOT NULL DEFAULT 0\n);",
9607
+ "tableName": "submissions",
9608
+ "ddl": "CREATE TABLE IF NOT EXISTS \"submissions\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"_meta_type\" TEXT NOT NULL,\n \"_meta_data\" JSON,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" UUID,\n \"learner_id\" UUID,\n \"lesson_id\" UUID,\n \"progress_id\" UUID,\n \"submitted_at\" TEXT,\n \"status\" TEXT DEFAULT 'captured',\n \"notes\" TEXT,\n \"capture_key\" TEXT,\n \"capture_digest\" TEXT,\n \"kind\" TEXT DEFAULT 'completed_work',\n \"previous_submission_id\" UUID,\n \"intake_item_id\" TEXT,\n \"page_count\" INTEGER DEFAULT 0,\n \"ocr_text\" TEXT,\n \"extracted\" TEXT,\n \"reported_by\" TEXT DEFAULT 'learner',\n \"evidence_url\" TEXT,\n \"reported_score\" REAL\n);",
7538
9609
  "columns": {
7539
9610
  "id": {
7540
9611
  "type": "UUID",
@@ -7551,6 +9622,14 @@
7551
9622
  "notNull": true,
7552
9623
  "default": ""
7553
9624
  },
9625
+ "_meta_type": {
9626
+ "type": "TEXT",
9627
+ "notNull": true
9628
+ },
9629
+ "_meta_data": {
9630
+ "type": "JSON",
9631
+ "notNull": false
9632
+ },
7554
9633
  "created_at": {
7555
9634
  "type": "TIMESTAMP",
7556
9635
  "notNull": true,
@@ -7564,100 +9643,172 @@
7564
9643
  "tenant_id": {
7565
9644
  "type": "UUID",
7566
9645
  "referenceKind": "tenantId",
9646
+ "notNull": false
9647
+ },
9648
+ "learner_id": {
9649
+ "type": "UUID",
9650
+ "referenceKind": "foreignKey",
7567
9651
  "notNull": false,
7568
- "unique": false
9652
+ "foreignKey": {
9653
+ "table": "learners",
9654
+ "column": "id",
9655
+ "onDelete": "NO ACTION",
9656
+ "onUpdate": "CASCADE"
9657
+ }
7569
9658
  },
7570
9659
  "lesson_id": {
7571
9660
  "type": "UUID",
7572
9661
  "referenceKind": "foreignKey",
7573
- "notNull": true,
7574
- "unique": false,
9662
+ "notNull": false,
7575
9663
  "foreignKey": {
7576
9664
  "table": "lessons",
7577
9665
  "column": "id",
7578
- "onDelete": "CASCADE",
9666
+ "onDelete": "NO ACTION",
7579
9667
  "onUpdate": "CASCADE"
7580
9668
  }
7581
9669
  },
7582
- "asset_id": {
9670
+ "progress_id": {
7583
9671
  "type": "UUID",
7584
- "referenceKind": "crossPackageRef",
7585
- "notNull": true,
7586
- "unique": false
9672
+ "referenceKind": "foreignKey",
9673
+ "notNull": false,
9674
+ "foreignKey": {
9675
+ "table": "lesson_progress",
9676
+ "column": "id",
9677
+ "onDelete": "NO ACTION",
9678
+ "onUpdate": "CASCADE"
9679
+ }
7587
9680
  },
7588
- "relationship": {
9681
+ "submitted_at": {
7589
9682
  "type": "TEXT",
7590
- "notNull": true,
7591
- "unique": false,
7592
- "default": "attachment"
9683
+ "notNull": false
7593
9684
  },
7594
- "sort_order": {
9685
+ "status": {
9686
+ "type": "TEXT",
9687
+ "notNull": false,
9688
+ "default": "captured"
9689
+ },
9690
+ "notes": {
9691
+ "type": "TEXT",
9692
+ "notNull": false
9693
+ },
9694
+ "capture_key": {
9695
+ "type": "TEXT",
9696
+ "notNull": false
9697
+ },
9698
+ "capture_digest": {
9699
+ "type": "TEXT",
9700
+ "notNull": false
9701
+ },
9702
+ "kind": {
9703
+ "type": "TEXT",
9704
+ "notNull": false,
9705
+ "default": "completed_work"
9706
+ },
9707
+ "previous_submission_id": {
9708
+ "type": "UUID",
9709
+ "referenceKind": "foreignKey",
9710
+ "notNull": false,
9711
+ "foreignKey": {
9712
+ "table": "submissions",
9713
+ "column": "id",
9714
+ "onDelete": "NO ACTION",
9715
+ "onUpdate": "CASCADE"
9716
+ }
9717
+ },
9718
+ "intake_item_id": {
9719
+ "type": "TEXT",
9720
+ "notNull": false
9721
+ },
9722
+ "page_count": {
7595
9723
  "type": "INTEGER",
7596
- "notNull": true,
7597
- "unique": false,
9724
+ "notNull": false,
7598
9725
  "default": 0
9726
+ },
9727
+ "ocr_text": {
9728
+ "type": "TEXT",
9729
+ "notNull": false
9730
+ },
9731
+ "extracted": {
9732
+ "type": "TEXT",
9733
+ "notNull": false
9734
+ },
9735
+ "reported_by": {
9736
+ "type": "TEXT",
9737
+ "notNull": false,
9738
+ "default": "learner"
9739
+ },
9740
+ "evidence_url": {
9741
+ "type": "TEXT",
9742
+ "notNull": false
9743
+ },
9744
+ "reported_score": {
9745
+ "type": "REAL",
9746
+ "notNull": false
7599
9747
  }
7600
9748
  },
7601
9749
  "indexes": [
7602
9750
  {
7603
- "name": "lesson_assets_tenant_id_lesson_id_idx",
9751
+ "name": "submissions_slug_context_meta_type_idx",
7604
9752
  "columns": [
7605
9753
  "tenant_id",
7606
- "lesson_id",
7607
- "asset_id",
7608
- "relationship"
9754
+ "slug",
9755
+ "context",
9756
+ "_meta_type"
7609
9757
  ],
7610
9758
  "unique": true,
7611
9759
  "nullsNotDistinct": true
7612
9760
  },
7613
9761
  {
7614
- "name": "lesson_assets_slug_context_idx",
9762
+ "name": "submissions_meta_type_idx",
7615
9763
  "columns": [
7616
- "slug",
7617
- "context"
9764
+ "_meta_type"
7618
9765
  ]
7619
9766
  },
7620
9767
  {
7621
- "name": "lesson_assets_tenant_id_created_at_idx",
9768
+ "name": "submissions_tenant_id_created_at_idx",
7622
9769
  "columns": [
7623
9770
  "tenant_id",
7624
9771
  "created_at"
7625
9772
  ]
7626
9773
  },
7627
9774
  {
7628
- "name": "lesson_assets_lesson_id_idx",
9775
+ "name": "submissions_learner_id_idx",
9776
+ "columns": [
9777
+ "learner_id"
9778
+ ]
9779
+ },
9780
+ {
9781
+ "name": "submissions_lesson_id_idx",
7629
9782
  "columns": [
7630
9783
  "lesson_id"
7631
9784
  ]
7632
9785
  },
7633
9786
  {
7634
- "name": "lesson_assets_asset_id_idx",
9787
+ "name": "submissions_progress_id_idx",
7635
9788
  "columns": [
7636
- "asset_id"
9789
+ "progress_id"
9790
+ ]
9791
+ },
9792
+ {
9793
+ "name": "submissions_previous_submission_id_idx",
9794
+ "columns": [
9795
+ "previous_submission_id"
7637
9796
  ]
7638
9797
  }
7639
9798
  ],
7640
- "version": "d96385c6"
9799
+ "version": "27a21ab4"
7641
9800
  },
7642
9801
  "importPath": "@happyvertical/smrt-education"
7643
9802
  },
7644
- "@happyvertical/smrt-education:Submission": {
7645
- "name": "submission",
7646
- "className": "Submission",
7647
- "qualifiedName": "@happyvertical/smrt-education:Submission",
7648
- "collection": "submissions",
7649
- "description": "Evidence that a learner completed one progress item.",
9803
+ "@happyvertical/smrt-education:SubmissionIntakeBinding": {
9804
+ "name": "submissionintakebinding",
9805
+ "className": "SubmissionIntakeBinding",
9806
+ "qualifiedName": "@happyvertical/smrt-education:SubmissionIntakeBinding",
9807
+ "collection": "submissionintakebindings",
9808
+ "description": "Durable tenant/item claim for trusted ingestion receipts. This separate table keeps ordinary uploads (which have no intake item) out of the uniqueness key.",
7650
9809
  "filePath": "/home/runner/work/smrt/smrt/packages/education/src/submissions.ts",
7651
9810
  "packageName": "@happyvertical/smrt-education",
7652
9811
  "fields": {
7653
- "created_at": {
7654
- "type": "datetime",
7655
- "required": false
7656
- },
7657
- "updated_at": {
7658
- "type": "datetime",
7659
- "required": false
7660
- },
7661
9812
  "tenantId": {
7662
9813
  "type": "text",
7663
9814
  "required": true,
@@ -7675,57 +9826,20 @@
7675
9826
  }
7676
9827
  }
7677
9828
  },
7678
- "learnerId": {
7679
- "type": "foreignKey",
7680
- "required": true,
7681
- "related": "Learner",
7682
- "_meta": {
7683
- "required": true
7684
- }
7685
- },
7686
- "lessonId": {
7687
- "type": "foreignKey",
9829
+ "intakeItemId": {
9830
+ "type": "text",
7688
9831
  "required": true,
7689
- "related": "Lesson",
7690
9832
  "_meta": {
7691
9833
  "required": true
7692
9834
  }
7693
9835
  },
7694
- "progressId": {
9836
+ "submissionId": {
7695
9837
  "type": "foreignKey",
7696
9838
  "required": true,
7697
- "related": "LessonProgress",
9839
+ "related": "Submission",
7698
9840
  "_meta": {
7699
9841
  "required": true
7700
9842
  }
7701
- },
7702
- "submittedAt": {
7703
- "type": "text",
7704
- "required": false
7705
- },
7706
- "status": {
7707
- "type": "text",
7708
- "required": false,
7709
- "default": "captured",
7710
- "enum": [
7711
- "captured",
7712
- "extracting",
7713
- "needs_review",
7714
- "graded",
7715
- "rejected"
7716
- ]
7717
- },
7718
- "notes": {
7719
- "type": "text",
7720
- "required": false
7721
- },
7722
- "captureKey": {
7723
- "type": "text",
7724
- "required": false
7725
- },
7726
- "captureDigest": {
7727
- "type": "text",
7728
- "required": false
7729
9843
  }
7730
9844
  },
7731
9845
  "methods": {
@@ -7739,43 +9853,36 @@
7739
9853
  }
7740
9854
  },
7741
9855
  "decoratorConfig": {
7742
- "tableStrategy": "sti",
9856
+ "tableName": "submission_intake_bindings",
7743
9857
  "api": false,
7744
9858
  "mcp": false,
7745
9859
  "cli": false,
7746
- "tenantScoped": {
7747
- "mode": "required"
7748
- },
7749
9860
  "conflictColumns": [
7750
9861
  "tenant_id",
7751
- "slug",
7752
- "context",
7753
- "_meta_type"
7754
- ]
9862
+ "intake_item_id"
9863
+ ],
9864
+ "tenantScoped": {
9865
+ "mode": "required"
9866
+ }
7755
9867
  },
7756
9868
  "extends": "SmrtObject",
7757
- "exportName": "Submission",
7758
- "collectionExportName": "SubmissionCollection",
9869
+ "exportName": "SubmissionIntakeBinding",
9870
+ "collectionExportName": "SubmissionIntakeBindingCollection",
7759
9871
  "validationRules": [
7760
9872
  {
7761
- "field": "learnerId",
7762
- "rule": "required",
7763
- "fieldType": "foreignKey"
7764
- },
7765
- {
7766
- "field": "lessonId",
9873
+ "field": "intakeItemId",
7767
9874
  "rule": "required",
7768
- "fieldType": "foreignKey"
9875
+ "fieldType": "text"
7769
9876
  },
7770
9877
  {
7771
- "field": "progressId",
9878
+ "field": "submissionId",
7772
9879
  "rule": "required",
7773
9880
  "fieldType": "foreignKey"
7774
9881
  }
7775
9882
  ],
7776
9883
  "schema": {
7777
- "tableName": "submissions",
7778
- "ddl": "CREATE TABLE IF NOT EXISTS \"submissions\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"_meta_type\" TEXT NOT NULL,\n \"_meta_data\" JSON,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" UUID,\n \"learner_id\" UUID,\n \"lesson_id\" UUID,\n \"progress_id\" UUID,\n \"submitted_at\" TEXT,\n \"status\" TEXT DEFAULT 'captured',\n \"notes\" TEXT,\n \"capture_key\" TEXT,\n \"capture_digest\" TEXT,\n \"page_count\" INTEGER DEFAULT 0,\n \"ocr_text\" TEXT,\n \"extracted\" TEXT,\n \"reported_by\" TEXT DEFAULT 'learner',\n \"evidence_url\" TEXT,\n \"reported_score\" REAL\n);",
9884
+ "tableName": "submission_intake_bindings",
9885
+ "ddl": "CREATE TABLE IF NOT EXISTS \"submission_intake_bindings\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" UUID NOT NULL,\n \"intake_item_id\" TEXT NOT NULL,\n \"submission_id\" UUID NOT NULL\n);",
7779
9886
  "columns": {
7780
9887
  "id": {
7781
9888
  "type": "UUID",
@@ -7787,18 +9894,10 @@
7787
9894
  "type": "TEXT",
7788
9895
  "notNull": true
7789
9896
  },
7790
- "context": {
7791
- "type": "TEXT",
7792
- "notNull": true,
7793
- "default": ""
7794
- },
7795
- "_meta_type": {
7796
- "type": "TEXT",
7797
- "notNull": true
7798
- },
7799
- "_meta_data": {
7800
- "type": "JSON",
7801
- "notNull": false
9897
+ "context": {
9898
+ "type": "TEXT",
9899
+ "notNull": true,
9900
+ "default": ""
7802
9901
  },
7803
9902
  "created_at": {
7804
9903
  "type": "TIMESTAMP",
@@ -7813,134 +9912,58 @@
7813
9912
  "tenant_id": {
7814
9913
  "type": "UUID",
7815
9914
  "referenceKind": "tenantId",
7816
- "notNull": false
7817
- },
7818
- "learner_id": {
7819
- "type": "UUID",
7820
- "referenceKind": "foreignKey",
7821
- "notNull": false,
7822
- "foreignKey": {
7823
- "table": "learners",
7824
- "column": "id",
7825
- "onDelete": "NO ACTION",
7826
- "onUpdate": "CASCADE"
7827
- }
9915
+ "notNull": true,
9916
+ "unique": false
7828
9917
  },
7829
- "lesson_id": {
7830
- "type": "UUID",
7831
- "referenceKind": "foreignKey",
7832
- "notNull": false,
7833
- "foreignKey": {
7834
- "table": "lessons",
7835
- "column": "id",
7836
- "onDelete": "NO ACTION",
7837
- "onUpdate": "CASCADE"
7838
- }
9918
+ "intake_item_id": {
9919
+ "type": "TEXT",
9920
+ "notNull": true,
9921
+ "unique": false
7839
9922
  },
7840
- "progress_id": {
9923
+ "submission_id": {
7841
9924
  "type": "UUID",
7842
9925
  "referenceKind": "foreignKey",
7843
- "notNull": false,
9926
+ "notNull": true,
9927
+ "unique": false,
7844
9928
  "foreignKey": {
7845
- "table": "lesson_progress",
9929
+ "table": "submissions",
7846
9930
  "column": "id",
7847
9931
  "onDelete": "NO ACTION",
7848
9932
  "onUpdate": "CASCADE"
7849
9933
  }
7850
- },
7851
- "submitted_at": {
7852
- "type": "TEXT",
7853
- "notNull": false
7854
- },
7855
- "status": {
7856
- "type": "TEXT",
7857
- "notNull": false,
7858
- "default": "captured"
7859
- },
7860
- "notes": {
7861
- "type": "TEXT",
7862
- "notNull": false
7863
- },
7864
- "capture_key": {
7865
- "type": "TEXT",
7866
- "notNull": false
7867
- },
7868
- "capture_digest": {
7869
- "type": "TEXT",
7870
- "notNull": false
7871
- },
7872
- "page_count": {
7873
- "type": "INTEGER",
7874
- "notNull": false,
7875
- "default": 0
7876
- },
7877
- "ocr_text": {
7878
- "type": "TEXT",
7879
- "notNull": false
7880
- },
7881
- "extracted": {
7882
- "type": "TEXT",
7883
- "notNull": false
7884
- },
7885
- "reported_by": {
7886
- "type": "TEXT",
7887
- "notNull": false,
7888
- "default": "learner"
7889
- },
7890
- "evidence_url": {
7891
- "type": "TEXT",
7892
- "notNull": false
7893
- },
7894
- "reported_score": {
7895
- "type": "REAL",
7896
- "notNull": false
7897
9934
  }
7898
9935
  },
7899
9936
  "indexes": [
7900
9937
  {
7901
- "name": "submissions_slug_context_meta_type_idx",
9938
+ "name": "submission_intake_bindings_tenant_id_intake_item_id_idx",
7902
9939
  "columns": [
7903
9940
  "tenant_id",
7904
- "slug",
7905
- "context",
7906
- "_meta_type"
9941
+ "intake_item_id"
7907
9942
  ],
7908
- "unique": true,
7909
- "nullsNotDistinct": true
9943
+ "unique": true
7910
9944
  },
7911
9945
  {
7912
- "name": "submissions_meta_type_idx",
9946
+ "name": "submission_intake_bindings_slug_context_idx",
7913
9947
  "columns": [
7914
- "_meta_type"
9948
+ "slug",
9949
+ "context"
7915
9950
  ]
7916
9951
  },
7917
9952
  {
7918
- "name": "submissions_tenant_id_created_at_idx",
9953
+ "name": "submission_intake_bindings_tenant_id_created_at_idx",
7919
9954
  "columns": [
7920
9955
  "tenant_id",
7921
9956
  "created_at"
7922
9957
  ]
7923
9958
  },
7924
9959
  {
7925
- "name": "submissions_learner_id_idx",
7926
- "columns": [
7927
- "learner_id"
7928
- ]
7929
- },
7930
- {
7931
- "name": "submissions_lesson_id_idx",
7932
- "columns": [
7933
- "lesson_id"
7934
- ]
7935
- },
7936
- {
7937
- "name": "submissions_progress_id_idx",
9960
+ "name": "submission_intake_bindings_submission_id_idx",
7938
9961
  "columns": [
7939
- "progress_id"
9962
+ "submission_id"
7940
9963
  ]
7941
9964
  }
7942
9965
  ],
7943
- "version": "9839d766"
9966
+ "version": "7102c909"
7944
9967
  },
7945
9968
  "importPath": "@happyvertical/smrt-education"
7946
9969
  },
@@ -8027,6 +10050,33 @@
8027
10050
  "type": "text",
8028
10051
  "required": false
8029
10052
  },
10053
+ "kind": {
10054
+ "type": "text",
10055
+ "required": true,
10056
+ "default": "completed_work",
10057
+ "_meta": {
10058
+ "required": true
10059
+ },
10060
+ "enum": [
10061
+ "blank_reference",
10062
+ "completed_work"
10063
+ ]
10064
+ },
10065
+ "previousSubmissionId": {
10066
+ "type": "foreignKey",
10067
+ "required": false,
10068
+ "related": "Submission",
10069
+ "_meta": {
10070
+ "nullable": true
10071
+ }
10072
+ },
10073
+ "intakeItemId": {
10074
+ "type": "text",
10075
+ "required": false,
10076
+ "_meta": {
10077
+ "nullable": true
10078
+ }
10079
+ },
8030
10080
  "pageCount": {
8031
10081
  "type": "integer",
8032
10082
  "required": true,
@@ -8099,6 +10149,11 @@
8099
10149
  "rule": "required",
8100
10150
  "fieldType": "foreignKey"
8101
10151
  },
10152
+ {
10153
+ "field": "kind",
10154
+ "rule": "required",
10155
+ "fieldType": "text"
10156
+ },
8102
10157
  {
8103
10158
  "field": "pageCount",
8104
10159
  "rule": "required",
@@ -8107,7 +10162,7 @@
8107
10162
  ],
8108
10163
  "schema": {
8109
10164
  "tableName": "submissions",
8110
- "ddl": "CREATE TABLE IF NOT EXISTS \"submissions\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"_meta_type\" TEXT NOT NULL,\n \"_meta_data\" JSON,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" UUID,\n \"learner_id\" UUID,\n \"lesson_id\" UUID,\n \"progress_id\" UUID,\n \"submitted_at\" TEXT,\n \"status\" TEXT DEFAULT 'captured',\n \"notes\" TEXT,\n \"capture_key\" TEXT,\n \"capture_digest\" TEXT,\n \"page_count\" INTEGER DEFAULT 0,\n \"ocr_text\" TEXT,\n \"extracted\" TEXT,\n \"reported_by\" TEXT DEFAULT 'learner',\n \"evidence_url\" TEXT,\n \"reported_score\" REAL\n);",
10165
+ "ddl": "CREATE TABLE IF NOT EXISTS \"submissions\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"_meta_type\" TEXT NOT NULL,\n \"_meta_data\" JSON,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" UUID,\n \"learner_id\" UUID,\n \"lesson_id\" UUID,\n \"progress_id\" UUID,\n \"submitted_at\" TEXT,\n \"status\" TEXT DEFAULT 'captured',\n \"notes\" TEXT,\n \"capture_key\" TEXT,\n \"capture_digest\" TEXT,\n \"kind\" TEXT DEFAULT 'completed_work',\n \"previous_submission_id\" UUID,\n \"intake_item_id\" TEXT,\n \"page_count\" INTEGER DEFAULT 0,\n \"ocr_text\" TEXT,\n \"extracted\" TEXT,\n \"reported_by\" TEXT DEFAULT 'learner',\n \"evidence_url\" TEXT,\n \"reported_score\" REAL\n);",
8111
10166
  "columns": {
8112
10167
  "id": {
8113
10168
  "type": "UUID",
@@ -8201,6 +10256,26 @@
8201
10256
  "type": "TEXT",
8202
10257
  "notNull": false
8203
10258
  },
10259
+ "kind": {
10260
+ "type": "TEXT",
10261
+ "notNull": false,
10262
+ "default": "completed_work"
10263
+ },
10264
+ "previous_submission_id": {
10265
+ "type": "UUID",
10266
+ "referenceKind": "foreignKey",
10267
+ "notNull": false,
10268
+ "foreignKey": {
10269
+ "table": "submissions",
10270
+ "column": "id",
10271
+ "onDelete": "NO ACTION",
10272
+ "onUpdate": "CASCADE"
10273
+ }
10274
+ },
10275
+ "intake_item_id": {
10276
+ "type": "TEXT",
10277
+ "notNull": false
10278
+ },
8204
10279
  "page_count": {
8205
10280
  "type": "INTEGER",
8206
10281
  "notNull": false,
@@ -8270,9 +10345,15 @@
8270
10345
  "columns": [
8271
10346
  "progress_id"
8272
10347
  ]
10348
+ },
10349
+ {
10350
+ "name": "submissions_previous_submission_id_idx",
10351
+ "columns": [
10352
+ "previous_submission_id"
10353
+ ]
8273
10354
  }
8274
10355
  ],
8275
- "version": "9cf5d690"
10356
+ "version": "7c394510"
8276
10357
  },
8277
10358
  "importPath": "@happyvertical/smrt-education"
8278
10359
  },
@@ -8359,6 +10440,33 @@
8359
10440
  "type": "text",
8360
10441
  "required": false
8361
10442
  },
10443
+ "kind": {
10444
+ "type": "text",
10445
+ "required": true,
10446
+ "default": "completed_work",
10447
+ "_meta": {
10448
+ "required": true
10449
+ },
10450
+ "enum": [
10451
+ "blank_reference",
10452
+ "completed_work"
10453
+ ]
10454
+ },
10455
+ "previousSubmissionId": {
10456
+ "type": "foreignKey",
10457
+ "required": false,
10458
+ "related": "Submission",
10459
+ "_meta": {
10460
+ "nullable": true
10461
+ }
10462
+ },
10463
+ "intakeItemId": {
10464
+ "type": "text",
10465
+ "required": false,
10466
+ "_meta": {
10467
+ "nullable": true
10468
+ }
10469
+ },
8362
10470
  "reportedBy": {
8363
10471
  "type": "text",
8364
10472
  "required": false,
@@ -8414,11 +10522,16 @@
8414
10522
  "field": "progressId",
8415
10523
  "rule": "required",
8416
10524
  "fieldType": "foreignKey"
10525
+ },
10526
+ {
10527
+ "field": "kind",
10528
+ "rule": "required",
10529
+ "fieldType": "text"
8417
10530
  }
8418
10531
  ],
8419
10532
  "schema": {
8420
10533
  "tableName": "submissions",
8421
- "ddl": "CREATE TABLE IF NOT EXISTS \"submissions\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"_meta_type\" TEXT NOT NULL,\n \"_meta_data\" JSON,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" UUID,\n \"learner_id\" UUID,\n \"lesson_id\" UUID,\n \"progress_id\" UUID,\n \"submitted_at\" TEXT,\n \"status\" TEXT DEFAULT 'captured',\n \"notes\" TEXT,\n \"capture_key\" TEXT,\n \"capture_digest\" TEXT,\n \"page_count\" INTEGER DEFAULT 0,\n \"ocr_text\" TEXT,\n \"extracted\" TEXT,\n \"reported_by\" TEXT DEFAULT 'learner',\n \"evidence_url\" TEXT,\n \"reported_score\" REAL\n);",
10534
+ "ddl": "CREATE TABLE IF NOT EXISTS \"submissions\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"_meta_type\" TEXT NOT NULL,\n \"_meta_data\" JSON,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" UUID,\n \"learner_id\" UUID,\n \"lesson_id\" UUID,\n \"progress_id\" UUID,\n \"submitted_at\" TEXT,\n \"status\" TEXT DEFAULT 'captured',\n \"notes\" TEXT,\n \"capture_key\" TEXT,\n \"capture_digest\" TEXT,\n \"kind\" TEXT DEFAULT 'completed_work',\n \"previous_submission_id\" UUID,\n \"intake_item_id\" TEXT,\n \"page_count\" INTEGER DEFAULT 0,\n \"ocr_text\" TEXT,\n \"extracted\" TEXT,\n \"reported_by\" TEXT DEFAULT 'learner',\n \"evidence_url\" TEXT,\n \"reported_score\" REAL\n);",
8422
10535
  "columns": {
8423
10536
  "id": {
8424
10537
  "type": "UUID",
@@ -8512,6 +10625,26 @@
8512
10625
  "type": "TEXT",
8513
10626
  "notNull": false
8514
10627
  },
10628
+ "kind": {
10629
+ "type": "TEXT",
10630
+ "notNull": false,
10631
+ "default": "completed_work"
10632
+ },
10633
+ "previous_submission_id": {
10634
+ "type": "UUID",
10635
+ "referenceKind": "foreignKey",
10636
+ "notNull": false,
10637
+ "foreignKey": {
10638
+ "table": "submissions",
10639
+ "column": "id",
10640
+ "onDelete": "NO ACTION",
10641
+ "onUpdate": "CASCADE"
10642
+ }
10643
+ },
10644
+ "intake_item_id": {
10645
+ "type": "TEXT",
10646
+ "notNull": false
10647
+ },
8515
10648
  "page_count": {
8516
10649
  "type": "INTEGER",
8517
10650
  "notNull": false,
@@ -8581,9 +10714,15 @@
8581
10714
  "columns": [
8582
10715
  "progress_id"
8583
10716
  ]
10717
+ },
10718
+ {
10719
+ "name": "submissions_previous_submission_id_idx",
10720
+ "columns": [
10721
+ "previous_submission_id"
10722
+ ]
8584
10723
  }
8585
10724
  ],
8586
- "version": "97981928"
10725
+ "version": "eff3715d"
8587
10726
  },
8588
10727
  "importPath": "@happyvertical/smrt-education"
8589
10728
  },
@@ -8669,6 +10808,33 @@
8669
10808
  "captureDigest": {
8670
10809
  "type": "text",
8671
10810
  "required": false
10811
+ },
10812
+ "kind": {
10813
+ "type": "text",
10814
+ "required": true,
10815
+ "default": "completed_work",
10816
+ "_meta": {
10817
+ "required": true
10818
+ },
10819
+ "enum": [
10820
+ "blank_reference",
10821
+ "completed_work"
10822
+ ]
10823
+ },
10824
+ "previousSubmissionId": {
10825
+ "type": "foreignKey",
10826
+ "required": false,
10827
+ "related": "Submission",
10828
+ "_meta": {
10829
+ "nullable": true
10830
+ }
10831
+ },
10832
+ "intakeItemId": {
10833
+ "type": "text",
10834
+ "required": false,
10835
+ "_meta": {
10836
+ "nullable": true
10837
+ }
8672
10838
  }
8673
10839
  },
8674
10840
  "methods": {
@@ -8706,11 +10872,16 @@
8706
10872
  "field": "progressId",
8707
10873
  "rule": "required",
8708
10874
  "fieldType": "foreignKey"
10875
+ },
10876
+ {
10877
+ "field": "kind",
10878
+ "rule": "required",
10879
+ "fieldType": "text"
8709
10880
  }
8710
10881
  ],
8711
10882
  "schema": {
8712
10883
  "tableName": "submissions",
8713
- "ddl": "CREATE TABLE IF NOT EXISTS \"submissions\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"_meta_type\" TEXT NOT NULL,\n \"_meta_data\" JSON,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" UUID,\n \"learner_id\" UUID,\n \"lesson_id\" UUID,\n \"progress_id\" UUID,\n \"submitted_at\" TEXT,\n \"status\" TEXT DEFAULT 'captured',\n \"notes\" TEXT,\n \"capture_key\" TEXT,\n \"capture_digest\" TEXT,\n \"page_count\" INTEGER DEFAULT 0,\n \"ocr_text\" TEXT,\n \"extracted\" TEXT,\n \"reported_by\" TEXT DEFAULT 'learner',\n \"evidence_url\" TEXT,\n \"reported_score\" REAL\n);",
10884
+ "ddl": "CREATE TABLE IF NOT EXISTS \"submissions\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"_meta_type\" TEXT NOT NULL,\n \"_meta_data\" JSON,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" UUID,\n \"learner_id\" UUID,\n \"lesson_id\" UUID,\n \"progress_id\" UUID,\n \"submitted_at\" TEXT,\n \"status\" TEXT DEFAULT 'captured',\n \"notes\" TEXT,\n \"capture_key\" TEXT,\n \"capture_digest\" TEXT,\n \"kind\" TEXT DEFAULT 'completed_work',\n \"previous_submission_id\" UUID,\n \"intake_item_id\" TEXT,\n \"page_count\" INTEGER DEFAULT 0,\n \"ocr_text\" TEXT,\n \"extracted\" TEXT,\n \"reported_by\" TEXT DEFAULT 'learner',\n \"evidence_url\" TEXT,\n \"reported_score\" REAL\n);",
8714
10885
  "columns": {
8715
10886
  "id": {
8716
10887
  "type": "UUID",
@@ -8804,6 +10975,26 @@
8804
10975
  "type": "TEXT",
8805
10976
  "notNull": false
8806
10977
  },
10978
+ "kind": {
10979
+ "type": "TEXT",
10980
+ "notNull": false,
10981
+ "default": "completed_work"
10982
+ },
10983
+ "previous_submission_id": {
10984
+ "type": "UUID",
10985
+ "referenceKind": "foreignKey",
10986
+ "notNull": false,
10987
+ "foreignKey": {
10988
+ "table": "submissions",
10989
+ "column": "id",
10990
+ "onDelete": "NO ACTION",
10991
+ "onUpdate": "CASCADE"
10992
+ }
10993
+ },
10994
+ "intake_item_id": {
10995
+ "type": "TEXT",
10996
+ "notNull": false
10997
+ },
8807
10998
  "page_count": {
8808
10999
  "type": "INTEGER",
8809
11000
  "notNull": false,
@@ -8873,9 +11064,15 @@
8873
11064
  "columns": [
8874
11065
  "progress_id"
8875
11066
  ]
11067
+ },
11068
+ {
11069
+ "name": "submissions_previous_submission_id_idx",
11070
+ "columns": [
11071
+ "previous_submission_id"
11072
+ ]
8876
11073
  }
8877
11074
  ],
8878
- "version": "03b3a269"
11075
+ "version": "4f3230a3"
8879
11076
  },
8880
11077
  "importPath": "@happyvertical/smrt-education"
8881
11078
  },
@@ -9411,7 +11608,7 @@
9411
11608
  "demo": {
9412
11609
  "mode": "server",
9413
11610
  "reasons": [
9414
- "Needs a server because its package depends on @happyvertical/smrt-profiles, @happyvertical/smrt-tenancy, @happyvertical/smrt-users, which do not build for a browser (#3617, #3624, #3626)."
11611
+ "Needs a server because its package depends on @happyvertical/smrt-agents, @happyvertical/smrt-jobs, @happyvertical/smrt-profiles, @happyvertical/smrt-reports, @happyvertical/smrt-secrets, @happyvertical/smrt-tenancy, @happyvertical/smrt-users, which do not build for a browser (#3615, #3617, #3624, #3625, #3626, #3627)."
9415
11612
  ]
9416
11613
  }
9417
11614
  },
@@ -9455,7 +11652,7 @@
9455
11652
  "demo": {
9456
11653
  "mode": "server",
9457
11654
  "reasons": [
9458
- "Needs a server because its package depends on @happyvertical/smrt-profiles, @happyvertical/smrt-tenancy, @happyvertical/smrt-users, which do not build for a browser (#3617, #3624, #3626)."
11655
+ "Needs a server because its package depends on @happyvertical/smrt-agents, @happyvertical/smrt-jobs, @happyvertical/smrt-profiles, @happyvertical/smrt-reports, @happyvertical/smrt-secrets, @happyvertical/smrt-tenancy, @happyvertical/smrt-users, which do not build for a browser (#3615, #3617, #3624, #3625, #3626, #3627)."
9459
11656
  ]
9460
11657
  }
9461
11658
  }
@@ -9463,6 +11660,7 @@
9463
11660
  "smrtDependencies": [
9464
11661
  "@happyvertical/smrt-assets",
9465
11662
  "@happyvertical/smrt-core",
11663
+ "@happyvertical/smrt-ingestion",
9466
11664
  "@happyvertical/smrt-profiles",
9467
11665
  "@happyvertical/smrt-tenancy",
9468
11666
  "@happyvertical/smrt-users"
@@ -9470,12 +11668,19 @@
9470
11668
  "browser": {
9471
11669
  "status": "server-only",
9472
11670
  "issues": [
11671
+ "#3615",
9473
11672
  "#3617",
9474
11673
  "#3624",
9475
- "#3626"
11674
+ "#3625",
11675
+ "#3626",
11676
+ "#3627"
9476
11677
  ],
9477
11678
  "via": [
11679
+ "@happyvertical/smrt-agents",
11680
+ "@happyvertical/smrt-jobs",
9478
11681
  "@happyvertical/smrt-profiles",
11682
+ "@happyvertical/smrt-reports",
11683
+ "@happyvertical/smrt-secrets",
9479
11684
  "@happyvertical/smrt-tenancy",
9480
11685
  "@happyvertical/smrt-users"
9481
11686
  ]