@happyvertical/smrt-education 0.57.52 → 0.59.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/AGENTS.md +18 -8
  2. package/README.md +36 -2
  3. package/agents/class-crunchlabs.md +83 -0
  4. package/agents/course-bundle-import.md +108 -18
  5. package/agents/course-work-design.md +144 -0
  6. package/agents/group-sharing.md +5 -1
  7. package/agents/learner-plan.md +3 -3
  8. package/agents/learner-service.md +1 -1
  9. package/agents/lesson-materials.md +52 -0
  10. package/agents/{workbook-service.md → lesson-work-service.md} +164 -95
  11. package/agents/{workbook-test-matrix.md → lesson-work-test-matrix.md} +3 -3
  12. package/agents/photo-intake.md +37 -50
  13. package/agents/question-records.md +1 -1
  14. package/agents/submission-service.md +22 -6
  15. package/dist/catalog-contracts.d.ts +6 -2
  16. package/dist/catalog-contracts.d.ts.map +1 -1
  17. package/dist/catalog-materialization-service.d.ts.map +1 -1
  18. package/dist/catalog-policy.d.ts +11 -1
  19. package/dist/catalog-policy.d.ts.map +1 -1
  20. package/dist/catalog-preview.d.ts +6 -1
  21. package/dist/catalog-preview.d.ts.map +1 -1
  22. package/dist/catalog-service.d.ts +1 -1
  23. package/dist/catalog-service.d.ts.map +1 -1
  24. package/dist/catalog.d.ts +11 -0
  25. package/dist/catalog.d.ts.map +1 -1
  26. package/dist/chunks/course-authoring-contracts-C4Hqba-e.js +131 -0
  27. package/dist/chunks/course-authoring-contracts-C4Hqba-e.js.map +1 -0
  28. package/dist/chunks/course-bundle-zip-5KUe3C5H.js +323 -0
  29. package/dist/chunks/course-bundle-zip-5KUe3C5H.js.map +1 -0
  30. package/dist/chunks/{workbook-photo-service-BtMQsbhq.js → workbook-photo-service-CjcB0y8Y.js} +6151 -5091
  31. package/dist/chunks/workbook-photo-service-CjcB0y8Y.js.map +1 -0
  32. package/dist/course-authoring-contracts.d.ts +6 -2
  33. package/dist/course-authoring-contracts.d.ts.map +1 -1
  34. package/dist/course-authoring-service.d.ts.map +1 -1
  35. package/dist/course-bundle-contracts.d.ts +21 -3
  36. package/dist/course-bundle-contracts.d.ts.map +1 -1
  37. package/dist/course-bundle-manifest-util.d.ts +15 -0
  38. package/dist/course-bundle-manifest-util.d.ts.map +1 -0
  39. package/dist/course-bundle-manifest-v2.d.ts +66 -0
  40. package/dist/course-bundle-manifest-v2.d.ts.map +1 -0
  41. package/dist/course-bundle-models.d.ts +29 -1
  42. package/dist/course-bundle-models.d.ts.map +1 -1
  43. package/dist/course-bundle-service.d.ts +104 -5
  44. package/dist/course-bundle-service.d.ts.map +1 -1
  45. package/dist/course-bundle.d.ts +81 -2
  46. package/dist/course-bundle.d.ts.map +1 -1
  47. package/dist/course-work-migration.d.ts +27 -0
  48. package/dist/course-work-migration.d.ts.map +1 -0
  49. package/dist/document-converter.d.ts +30 -18
  50. package/dist/document-converter.d.ts.map +1 -1
  51. package/dist/group-sharing-contracts.d.ts +3 -3
  52. package/dist/group-sharing-contracts.d.ts.map +1 -1
  53. package/dist/group-sharing-policy.d.ts +4 -4
  54. package/dist/group-sharing-policy.d.ts.map +1 -1
  55. package/dist/group-sharing-reader.d.ts.map +1 -1
  56. package/dist/hearth-catalog-providers.d.ts +1 -1
  57. package/dist/hearth-catalog-providers.d.ts.map +1 -1
  58. package/dist/hearth-class-crunchlabs.d.ts +94 -0
  59. package/dist/hearth-class-crunchlabs.d.ts.map +1 -0
  60. package/dist/index.d.ts +18 -13
  61. package/dist/index.d.ts.map +1 -1
  62. package/dist/index.js +1968 -419
  63. package/dist/index.js.map +1 -1
  64. package/dist/ingestion.d.ts +12 -11
  65. package/dist/ingestion.d.ts.map +1 -1
  66. package/dist/ingestion.js +63 -56
  67. package/dist/ingestion.js.map +1 -1
  68. package/dist/learner-plan-service.d.ts +1 -1
  69. package/dist/learner-plan-service.d.ts.map +1 -1
  70. package/dist/learner-service.d.ts +19 -5
  71. package/dist/learner-service.d.ts.map +1 -1
  72. package/dist/lesson-assets.d.ts +66 -2
  73. package/dist/lesson-assets.d.ts.map +1 -1
  74. package/dist/lesson-pages.d.ts +36 -0
  75. package/dist/lesson-pages.d.ts.map +1 -0
  76. package/dist/{workbook-completion.d.ts → lesson-work-completion.d.ts} +10 -10
  77. package/dist/lesson-work-completion.d.ts.map +1 -0
  78. package/dist/{workbook-contracts.d.ts → lesson-work-contracts.d.ts} +100 -52
  79. package/dist/lesson-work-contracts.d.ts.map +1 -0
  80. package/dist/lesson-work-models.d.ts +118 -0
  81. package/dist/lesson-work-models.d.ts.map +1 -0
  82. package/dist/lesson-work-service.d.ts +239 -0
  83. package/dist/lesson-work-service.d.ts.map +1 -0
  84. package/dist/manifest.json +6830 -5333
  85. package/dist/node.d.ts +3 -0
  86. package/dist/node.d.ts.map +1 -0
  87. package/dist/node.js +134 -0
  88. package/dist/node.js.map +1 -0
  89. package/dist/smrt-knowledge.json +2260 -1705
  90. package/dist/sources/class-crunchlabs-files.d.ts +8 -0
  91. package/dist/sources/class-crunchlabs-files.d.ts.map +1 -0
  92. package/dist/sources/class-crunchlabs.d.ts +217 -0
  93. package/dist/sources/class-crunchlabs.d.ts.map +1 -0
  94. package/dist/submission-service.d.ts +135 -5
  95. package/dist/submission-service.d.ts.map +1 -1
  96. package/dist/submissions.d.ts +2 -0
  97. package/dist/submissions.d.ts.map +1 -1
  98. package/dist/work-answer-regions.d.ts +11 -0
  99. package/dist/work-answer-regions.d.ts.map +1 -0
  100. package/dist/work-layout.d.ts +13 -0
  101. package/dist/work-layout.d.ts.map +1 -0
  102. package/dist/workbook-photo-contracts.d.ts +9 -7
  103. package/dist/workbook-photo-contracts.d.ts.map +1 -1
  104. package/dist/workbook-photo-ingestion.d.ts +1 -1
  105. package/dist/workbook-photo-ingestion.d.ts.map +1 -1
  106. package/dist/workbook-photo-models.d.ts +5 -5
  107. package/dist/workbook-photo-models.d.ts.map +1 -1
  108. package/dist/workbook-photo-service.d.ts +13 -10
  109. package/dist/workbook-photo-service.d.ts.map +1 -1
  110. package/package.json +12 -8
  111. package/dist/chunks/workbook-photo-service-BtMQsbhq.js.map +0 -1
  112. package/dist/workbook-answer-regions.d.ts +0 -11
  113. package/dist/workbook-answer-regions.d.ts.map +0 -1
  114. package/dist/workbook-completion.d.ts.map +0 -1
  115. package/dist/workbook-contracts.d.ts.map +0 -1
  116. package/dist/workbook-layout.d.ts +0 -13
  117. package/dist/workbook-layout.d.ts.map +0 -1
  118. package/dist/workbook-models.d.ts +0 -129
  119. package/dist/workbook-models.d.ts.map +0 -1
  120. package/dist/workbook-service.d.ts +0 -163
  121. package/dist/workbook-service.d.ts.map +0 -1
@@ -16,6 +16,21 @@ PostgreSQL enrollment lock. No runtime schema creation occurs.
16
16
 
17
17
  ## Capture and grading
18
18
 
19
+ Every completed-work capture and correction is lesson work: the same transaction
20
+ records the learner's `LessonActivity` for the enrollment and lesson and one
21
+ immutable `WorkAttempt` bound to the submission (a correction continues its
22
+ predecessor's episode); see [lesson work](lesson-work-service.md#one-pipeline).
23
+ The lesson work tables are therefore required; a host without them gets
24
+ `LearnerHistoryUnavailableError`. Book and loose-page work is refused here with
25
+ `LessonWorkWorkflowRequiredError`; call `assertOrdinarySubmissionScope` before
26
+ creating a generic intake receipt.
27
+
28
+ Each page may carry a `pageKey` (1-200 printable characters, distinct within the
29
+ capture; default `p<position>`). Submission views list `pages` with their
30
+ `pageKey`; older rows read as `p<sortOrder+1>`. A correction (`resubmitSubmission`)
31
+ may carry only the pages it replaces; the attempt view folds the versions, while
32
+ each grade stays bound to the submission it was given on (#4613).
33
+
19
34
  `captureSubmission` takes the learner request, `enrollmentId`, `lessonId`, a
20
35
  nonempty stable `requestKey`, and `pages` containing `name`, `mimeType` and Buffer
21
36
  `data`. Each upload becomes a fresh Asset owned by the learner's profile and
@@ -45,12 +60,13 @@ non-authoritative Grade until guardian review.
45
60
  `reviewSubmission` accepts an existing authorized submission and optional score
46
61
  and feedback. `attestLesson` creates/reuses an Attestation for a matching progress
47
62
  item without requiring uploads. Both require a verified guardian and create a
48
- new guardian Grade and set submission to `graded`. Ordinary non-workbook progress
49
- becomes `complete`. Workbook-backed progress instead uses its explicit parent
50
- completion decision; grading alone leaves it in progress, including through a
51
- plain SubmissionService instance. Existing explicit completion on the current
52
- attempt is retained. The owning workbook join determines this policy, never a
53
- caller flag.
63
+ new guardian Grade and set submission to `graded`. On an ordinary lesson the
64
+ progress becomes `complete` and the grade on the current attempt is recorded as
65
+ that attempt's lesson work completion decision. Book and loose-page work (its
66
+ course has a book key, or it is unfiled photo work) instead uses its explicit
67
+ parent completion decision; grading alone leaves it in progress, including through
68
+ a plain SubmissionService instance. The authoritative activity and course decide
69
+ this, never a caller flag.
54
70
  `attestOwnLesson({ enrollmentId, lessonId, policyBasis, notes? })` is the
55
71
  learner's own "I read it" / "I watched it" for `SELF_ATTESTABLE_LESSON_KINDS`
56
72
  (Reading, Video) under `education.learner.attest-own`. Any other actor is
@@ -1,6 +1,10 @@
1
1
  import type { CatalogPreview } from './catalog-preview.js';
2
- /** Metadata-only resource visibility. Teacher material is never learner-visible. */
3
- export type CatalogVisibility = 'catalog' | 'teacher';
2
+ /**
3
+ * Metadata-only resource visibility. Teacher material is never learner-visible.
4
+ * `operator` records (a provider whose permission is pending) are visible only
5
+ * to the tenants the host designated as operator families; see `CatalogPolicy`.
6
+ */
7
+ export type CatalogVisibility = 'catalog' | 'teacher' | 'operator';
4
8
  export type CatalogLicenseState = 'verified' | 'unknown' | 'conflicting' | 'restricted';
5
9
  export type CatalogOperation = 'link' | 'download' | 'print' | 'adapt' | 'redistribute' | 'commercial-use';
6
10
  /** Exact source evidence; no provider-wide license inference is permitted. */
@@ -1 +1 @@
1
- {"version":3,"file":"catalog-contracts.d.ts","sourceRoot":"","sources":["../src/catalog-contracts.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"catalog-contracts.d.ts","sourceRoot":"","sources":["../src/catalog-contracts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;AACnE,MAAM,MAAM,mBAAmB,GAC3B,UAAU,GACV,SAAS,GACT,aAAa,GACb,YAAY,CAAC;AACjB,MAAM,MAAM,gBAAgB,GACxB,MAAM,GACN,UAAU,GACV,OAAO,GACP,OAAO,GACP,cAAc,GACd,gBAAgB,CAAC;AAErB,8EAA8E;AAC9E,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,mBAAmB,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,mBAAmB,CAAC,EAAE,gBAAgB,EAAE,CAAC;CAC1C;AAED,oFAAoF;AACpF,UAAU,6BAA6B;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;CACpD;AACD,MAAM,MAAM,6BAA6B,GAAG,6BAA6B,GACvE,CACI;IACE,MAAM,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;IAC/B,SAAS,EACL,iBAAiB,GACjB,iBAAiB,GACjB,yEAAyE,CAAC;IAC9E,WAAW,EACP;QAAE,MAAM,EAAE,WAAW,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GACzC;QAAE,MAAM,EAAE,oBAAoB,CAAA;KAAE,GAChC;QAAE,MAAM,EAAE,YAAY,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CAChD,GACD;IACE,MAAM,EAAE,SAAS,CAAC;IAClB,kFAAkF;IAClF,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE;QACX,MAAM,EAAE,gBAAgB,CAAC;QACzB,MAAM,EAAE,sBAAsB,GAAG,2BAA2B,CAAC;KAC9D,CAAC;CACH,CACJ,CAAC;AACJ,MAAM,MAAM,oCAAoC,GAC5C;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,YAAY,EAAE,UAAU,GAAG,QAAQ,CAAA;CAAE,GACtD;IACE,OAAO,EAAE,KAAK,CAAC;IACf,MAAM,EACF,oBAAoB,GACpB,oBAAoB,GACpB,gBAAgB,GAChB,YAAY,GACZ,iCAAiC,CAAC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEN,mFAAmF;AACnF,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,cAAc,CAAC,EAAE,6BAA6B,CAAC;IAC/C,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,eAAe,EAAE,sBAAsB,CAAC;IACxC,UAAU,EAAE,iBAAiB,CAAC;CAC/B;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,yFAAyF;AACzF,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,mEAAmE;IACnE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,mFAAmF;IACnF,UAAU,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAClC,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,kBAAkB,EAAE,CAAC;CACzC;AAED,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,qFAAqF;IACrF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,kBAAkB,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,KAAK,EAAE;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,qBAAqB,CAAC;KACnC,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,KAAK,EAAE;QACb,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;KAChB,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,UAAU,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACtE;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B"}
@@ -1 +1 @@
1
- {"version":3,"file":"catalog-materialization-service.d.ts","sourceRoot":"","sources":["../src/catalog-materialization-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"catalog-materialization-service.d.ts","sourceRoot":"","sources":["../src/catalog-materialization-service.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,20 @@
1
1
  import type { CatalogActor, CatalogOperation, CatalogSourceRecord } from './catalog-contracts.js';
2
2
  export interface CatalogPolicyDecision {
3
3
  allowed: boolean;
4
- reason?: 'teacher-material' | 'unverified-license' | 'operation-not-permitted';
4
+ reason?: 'teacher-material' | 'operator-only' | 'unverified-license' | 'operation-not-permitted';
5
+ }
6
+ export interface CatalogPolicyOptions {
7
+ /**
8
+ * Tenants (families) designated by the host operator that may see `operator`
9
+ * visibility records. Host configuration, never derived from a request; the
10
+ * default is none, so operator-only records are invisible to everyone.
11
+ */
12
+ operatorTenantIds?: Iterable<string>;
5
13
  }
6
14
  /** Server-side resource policy. UI affordances are advisory and cannot bypass it. */
7
15
  export declare class CatalogPolicy {
16
+ private readonly operatorTenants;
17
+ constructor(options?: CatalogPolicyOptions);
8
18
  canView(record: Pick<CatalogSourceRecord, 'visibility'>, actor: CatalogActor): boolean;
9
19
  authorize(record: Pick<CatalogSourceRecord, 'visibility' | 'licenseEvidence'>, operation: CatalogOperation, actor: CatalogActor): CatalogPolicyDecision;
10
20
  private isVerified;
@@ -1 +1 @@
1
- {"version":3,"file":"catalog-policy.d.ts","sourceRoot":"","sources":["../src/catalog-policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EAEZ,gBAAgB,EAChB,mBAAmB,EACpB,MAAM,wBAAwB,CAAC;AAEhC,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EACH,kBAAkB,GAClB,oBAAoB,GACpB,yBAAyB,CAAC;CAC/B;AAED,qFAAqF;AACrF,qBAAa,aAAa;IACxB,OAAO,CACL,MAAM,EAAE,IAAI,CAAC,mBAAmB,EAAE,YAAY,CAAC,EAC/C,KAAK,EAAE,YAAY,GAClB,OAAO;IAIV,SAAS,CACP,MAAM,EAAE,IAAI,CAAC,mBAAmB,EAAE,YAAY,GAAG,iBAAiB,CAAC,EACnE,SAAS,EAAE,gBAAgB,EAC3B,KAAK,EAAE,YAAY,GAClB,qBAAqB;IAWxB,OAAO,CAAC,UAAU;CAGnB"}
1
+ {"version":3,"file":"catalog-policy.d.ts","sourceRoot":"","sources":["../src/catalog-policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EAEZ,gBAAgB,EAChB,mBAAmB,EACpB,MAAM,wBAAwB,CAAC;AAEhC,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EACH,kBAAkB,GAClB,eAAe,GACf,oBAAoB,GACpB,yBAAyB,CAAC;CAC/B;AAED,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;CACtC;AAED,qFAAqF;AACrF,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAsB;gBAC1C,OAAO,GAAE,oBAAyB;IAQ9C,OAAO,CACL,MAAM,EAAE,IAAI,CAAC,mBAAmB,EAAE,YAAY,CAAC,EAC/C,KAAK,EAAE,YAAY,GAClB,OAAO;IASV,SAAS,CACP,MAAM,EAAE,IAAI,CAAC,mBAAmB,EAAE,YAAY,GAAG,iBAAiB,CAAC,EACnE,SAAS,EAAE,gBAAgB,EAC3B,KAAK,EAAE,YAAY,GAClB,qBAAqB;IAiBxB,OAAO,CAAC,UAAU;CAGnB"}
@@ -1,4 +1,5 @@
1
1
  import type { CatalogActor, CatalogSourceRecord } from './catalog-contracts.js';
2
+ import { CatalogPolicy } from './catalog-policy.js';
2
3
  /** Publisher preview permission is independent of original-resource permissions. */
3
4
  export interface CatalogPreview {
4
5
  providerId: 'illustrative-mathematics';
@@ -51,9 +52,13 @@ export interface CatalogPreviewLoader {
51
52
  export declare class CatalogPreviewService {
52
53
  private readonly store;
53
54
  private readonly loader;
55
+ /** Host policy carrying the operator families; the default shows operator records to nobody. */
56
+ private readonly policy;
54
57
  private readonly cache;
55
58
  private cacheBytes;
56
- constructor(store: CatalogPreviewStore, loader: CatalogPreviewLoader);
59
+ constructor(store: CatalogPreviewStore, loader: CatalogPreviewLoader,
60
+ /** Host policy carrying the operator families; the default shows operator records to nobody. */
61
+ policy?: CatalogPolicy);
57
62
  serve(input: {
58
63
  actor: CatalogActor;
59
64
  resourceId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"catalog-preview.d.ts","sourceRoot":"","sources":["../src/catalog-preview.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAGhF,oFAAoF;AACpF,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,0BAA0B,CAAC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,4EAA4E;IAC5E,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,WAAW,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE;QACN,KAAK,EAAE,UAAU,CAAC;QAClB,UAAU,EAAE,WAAW,CAAC;QACxB,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAED,eAAO,MAAM,yBAAyB,QAAkB,CAAC;AACzD,eAAO,MAAM,6BAA6B,OAAO,CAAC;AAElD,oFAAoF;AACpF,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,OAAO,GACb,cAAc,GAAG,SAAS,CAgF5B;AAED,oFAAoF;AACpF,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,IAAI,CACV,mBAAmB,EACnB,YAAY,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,CACnD,EACD,GAAG,SAAa,GACf,cAAc,GAAG,SAAS,CAS5B;AAED,yFAAyF;AACzF,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,UAAU,GAAG;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAqFA;AAED,MAAM,WAAW,mBAAmB;IAClC,6FAA6F;IAC7F,WAAW,CACT,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,YAAY,GAClB,OAAO,CACN,CAAC,mBAAmB,GAAG;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,GACnE,SAAS,CACZ,CAAC;IACF,uGAAuG;IACvG,SAAS,CACP,KAAK,EAAE,YAAY,EACnB,QAAQ,EAAE,mBAAmB,GAAG;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAC7C,OAAO,CAAC,OAAO,CAAC,CAAC;CACrB;AACD,MAAM,WAAW,oBAAoB;IACnC,4FAA4F;IAC5F,WAAW,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CAC3D;AAED,uGAAuG;AACvG,qBAAa,qBAAqB;IAO9B,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAPzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAGlB;IACJ,OAAO,CAAC,UAAU,CAAK;gBAEJ,KAAK,EAAE,mBAAmB,EAC1B,MAAM,EAAE,oBAAoB;IAGzC,KAAK,CAAC,KAAK,EAAE;QACjB,KAAK,EAAE,YAAY,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC,QAAQ,CAAC;CA8FtB"}
1
+ {"version":3,"file":"catalog-preview.d.ts","sourceRoot":"","sources":["../src/catalog-preview.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,oFAAoF;AACpF,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,0BAA0B,CAAC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,4EAA4E;IAC5E,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,WAAW,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE;QACN,KAAK,EAAE,UAAU,CAAC;QAClB,UAAU,EAAE,WAAW,CAAC;QACxB,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAED,eAAO,MAAM,yBAAyB,QAAkB,CAAC;AACzD,eAAO,MAAM,6BAA6B,OAAO,CAAC;AAElD,oFAAoF;AACpF,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,OAAO,GACb,cAAc,GAAG,SAAS,CAgF5B;AAED,oFAAoF;AACpF,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,IAAI,CACV,mBAAmB,EACnB,YAAY,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,CACnD,EACD,GAAG,SAAa,GACf,cAAc,GAAG,SAAS,CAS5B;AAED,yFAAyF;AACzF,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,UAAU,GAAG;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAqFA;AAED,MAAM,WAAW,mBAAmB;IAClC,6FAA6F;IAC7F,WAAW,CACT,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,YAAY,GAClB,OAAO,CACN,CAAC,mBAAmB,GAAG;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,GACnE,SAAS,CACZ,CAAC;IACF,uGAAuG;IACvG,SAAS,CACP,KAAK,EAAE,YAAY,EACnB,QAAQ,EAAE,mBAAmB,GAAG;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAC7C,OAAO,CAAC,OAAO,CAAC,CAAC;CACrB;AACD,MAAM,WAAW,oBAAoB;IACnC,4FAA4F;IAC5F,WAAW,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CAC3D;AAED,uGAAuG;AACvG,qBAAa,qBAAqB;IAO9B,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,gGAAgG;IAChG,OAAO,CAAC,QAAQ,CAAC,MAAM;IATzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAGlB;IACJ,OAAO,CAAC,UAAU,CAAK;gBAEJ,KAAK,EAAE,mBAAmB,EAC1B,MAAM,EAAE,oBAAoB;IAC7C,gGAAgG;IAC/E,MAAM,GAAE,aAAmC;IAGxD,KAAK,CAAC,KAAK,EAAE;QACjB,KAAK,EAAE,YAAY,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC,QAAQ,CAAC;CA8FtB"}
@@ -2,7 +2,7 @@ import type { TenantCollection } from '@happyvertical/smrt-users';
2
2
  import type { DatabaseInterface } from '@happyvertical/sql';
3
3
  import type { Course, CourseSection, Lesson } from './catalog.js';
4
4
  import type { CourseCollection, CourseSectionCollection, LessonAssetCollection, LessonCollection } from './collections.js';
5
- import type { LessonAsset } from './lesson-assets.js';
5
+ import { type LessonAsset } from './lesson-assets.js';
6
6
  /** The application-owned decision that permits a catalog view for one tenant. */
7
7
  export type TenantCatalogReadScope = TenantCollection['withTenantCatalogReadScope'];
8
8
  export type CatalogActorContext = Parameters<Parameters<TenantCatalogReadScope>[0]['authorize']>[0];
@@ -1 +1 @@
1
- {"version":3,"file":"catalog-service.d.ts","sourceRoot":"","sources":["../src/catalog-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,KAAK,EACV,gBAAgB,EAChB,uBAAuB,EACvB,qBAAqB,EACrB,gBAAgB,EACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,iFAAiF;AACjF,MAAM,MAAM,sBAAsB,GAChC,gBAAgB,CAAC,4BAA4B,CAAC,CAAC;AACjD,MAAM,MAAM,mBAAmB,GAAG,UAAU,CAC1C,UAAU,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CACnD,CAAC,CAAC,CAAC,CAAC;AAEL,MAAM,MAAM,iBAAiB,GAAG,CAC9B,OAAO,EAAE,IAAI,CAAC,mBAAmB,EAAE,MAAM,CAAC,GAAG;IAC3C,+EAA+E;IAC/E,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,MAAM,EACF,wBAAwB,GACxB,gCAAgC,GAChC,mCAAmC,GACnC,0BAA0B,CAAC;CAChC,KACE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEhC,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,OAAO,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;CAClE;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,KAAK,CAAC;QACd,OAAO,EAAE,aAAa,CAAC;QACvB,OAAO,EAAE,KAAK,CAAC;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,WAAW,EAAE,CAAA;SAAE,CAAC,CAAC;KAC3D,CAAC,CAAC;CACJ;AAED,qBAAa,yBAA0B,SAAQ,KAAK;;CAKnD;AAUD;;;;GAIG;AACH,qBAAa,cAAc;IAEvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAIxB,OAAO,CAAC,QAAQ,CAAC,SAAS;gBART,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,uBAAuB,EACjC,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAE,qBAAqB,EAC7B,OAAO,EAAE,IAAI,CAC5B,gBAAgB,EAChB,4BAA4B,CAC7B,EACgB,SAAS,EAAE,iBAAiB;IAE/C,OAAO,CAAC,QAAQ;IAWhB,OAAO,CAAC,gBAAgB;IAKlB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAuDjE,wFAAwF;IAClF,aAAa,CACjB,OAAO,EAAE,kBAAkB,GAAG;QAC5B,QAAQ,EAAE,MAAM,CAAC;QACjB,iBAAiB,CAAC,EAAE,OAAO,CAAC;KAC7B,GACA,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;CA+DrC"}
1
+ {"version":3,"file":"catalog-service.d.ts","sourceRoot":"","sources":["../src/catalog-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,KAAK,EACV,gBAAgB,EAChB,uBAAuB,EACvB,qBAAqB,EACrB,gBAAgB,EACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,KAAK,WAAW,EAAoB,MAAM,oBAAoB,CAAC;AAExE,iFAAiF;AACjF,MAAM,MAAM,sBAAsB,GAChC,gBAAgB,CAAC,4BAA4B,CAAC,CAAC;AACjD,MAAM,MAAM,mBAAmB,GAAG,UAAU,CAC1C,UAAU,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CACnD,CAAC,CAAC,CAAC,CAAC;AAEL,MAAM,MAAM,iBAAiB,GAAG,CAC9B,OAAO,EAAE,IAAI,CAAC,mBAAmB,EAAE,MAAM,CAAC,GAAG;IAC3C,+EAA+E;IAC/E,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,MAAM,EACF,wBAAwB,GACxB,gCAAgC,GAChC,mCAAmC,GACnC,0BAA0B,CAAC;CAChC,KACE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEhC,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,OAAO,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;CAClE;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,KAAK,CAAC;QACd,OAAO,EAAE,aAAa,CAAC;QACvB,OAAO,EAAE,KAAK,CAAC;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,WAAW,EAAE,CAAA;SAAE,CAAC,CAAC;KAC3D,CAAC,CAAC;CACJ;AAED,qBAAa,yBAA0B,SAAQ,KAAK;;CAKnD;AAUD;;;;GAIG;AACH,qBAAa,cAAc;IAEvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAIxB,OAAO,CAAC,QAAQ,CAAC,SAAS;gBART,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,uBAAuB,EACjC,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAE,qBAAqB,EAC7B,OAAO,EAAE,IAAI,CAC5B,gBAAgB,EAChB,4BAA4B,CAC7B,EACgB,SAAS,EAAE,iBAAiB;IAE/C,OAAO,CAAC,QAAQ;IAWhB,OAAO,CAAC,gBAAgB;IAKlB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAuDjE,wFAAwF;IAClF,aAAa,CACjB,OAAO,EAAE,kBAAkB,GAAG;QAC5B,QAAQ,EAAE,MAAM,CAAC;QACjB,iBAAiB,CAAC,EAAE,OAAO,CAAC;KAC7B,GACA,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;CAqErC"}
package/dist/catalog.d.ts CHANGED
@@ -23,6 +23,17 @@ export declare class Course extends SmrtObject {
23
23
  estimatedMinutes: number;
24
24
  modality: CourseModality;
25
25
  status: CourseStatus;
26
+ /**
27
+ * Optional physical-book identity: '' means the course is not a book. A
28
+ * family holds at most one course per book key; the key never changes.
29
+ */
30
+ bookKey: string;
31
+ /** Printed edition of the book; '' means unknown. */
32
+ bookEdition: string;
33
+ /** Course work policy: learners see AI marks only after a guardian release. */
34
+ workReviewRequired: boolean;
35
+ /** Compare-and-swap version of the work policy; captures snapshot it. */
36
+ workPolicyVersion: number;
26
37
  constructor(options?: Record<string, unknown>);
27
38
  /** A personal copy remains pinned to its original family and license. */
28
39
  save(options?: SmrtSaveOptions): Promise<this>;
@@ -1 +1 @@
1
- {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,UAAU,EACV,KAAK,eAAe,EAErB,MAAM,0BAA0B,CAAC;AAGlC,MAAM,MAAM,iBAAiB,GACzB,UAAU,GACV,cAAc,GACd,mBAAmB,GACnB,sBAAsB,CAAC;AAC3B,MAAM,MAAM,cAAc,GACtB,QAAQ,GACR,WAAW,GACX,KAAK,GACL,OAAO,GACP,MAAM,GACN,OAAO,CAAC;AACZ,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,WAAW,GAAG,UAAU,CAAC;AAC9D,MAAM,MAAM,oBAAoB,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,UAAU,CAAC;AAwB9E,qBAEa,MAAO,SAAQ,UAAU;IACN,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAClC,KAAK,SAAM;IACtC,OAAO,SAAM;IACb,WAAW,SAAM;IACjB,SAAS,SAAY;IACrB,SAAS,SAAM;IACf,SAAS,SAAM;IACf,OAAO,SAAM;IACb,WAAW,EAAE,iBAAiB,CAAc;IAC5C,WAAW,SAAM;IACjB,UAAU,SAAM;IAChB,OAAO,SAAM;IACb,IAAI,SAAM;IACV,QAAQ,SAAK;IACb,QAAQ,SAAK;IACb,UAAU,SAAO;IACjB,gBAAgB,SAAK;IACrB,QAAQ,EAAE,cAAc,CAAY;IACpC,MAAM,EAAE,YAAY,CAAW;IAC/B;;;OAGG;IACH,OAAO,SAAM;IACb,qDAAqD;IACrD,WAAW,SAAM;IACjB,+EAA+E;IAC/E,kBAAkB,UAAQ;IAC1B,yEAAyE;IACzE,iBAAiB,SAAK;gBACV,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM;IAKjD,yEAAyE;IAC1D,IAAI,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;CAgE9D;AAED,qBACa,cAAe,SAAQ,MAAM;CAAG;AAE7C,oGAAoG;AACpG,eAAO,MAAM,mBAAmB,yCAA0C,CAAC;AAC3E,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpE,qBACa,cAAe,SAAQ,MAAM;IACxC;;;OAGG;IACH,UAAU,EAAE,gBAAgB,GAAG,EAAE,CAAM;IACvC,4EAA4E;IAC5E,YAAY,SAAM;gBACN,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM;IAIlC,IAAI,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;CAQ9D;AAED,qBAEa,aAAc,SAAQ,UAAU;IACb,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IACnB,QAAQ,SAAM;IAC7B,KAAK,SAAM;IACtC,SAAS,SAAK;gBACF,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM;IAIlC,IAAI,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;CAmB9D;AAED,qBAEa,MAAO,SAAQ,UAAU;IACN,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IACZ,SAAS,SAAM;IACrC,KAAK,SAAM;IACtC,IAAI,SAAM;IACV,SAAS,SAAK;IACd,gBAAgB,SAAK;IACrB,UAAU,SAAO;IACjB,QAAQ,EAAE,cAAc,CAAY;IACpC,cAAc,EAAE,oBAAoB,CAAY;IAChD,WAAW,SAAM;IACjB,WAAW,SAAM;gBACL,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM;IAIlC,IAAI,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;CAmB9D;AAED,qBACa,OAAQ,SAAQ,MAAM;CAAG;AACtC,qBACa,KAAM,SAAQ,MAAM;IAC/B,QAAQ,SAAM;gBACF,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM;CAIlD;AACD,qBACa,SAAU,SAAQ,MAAM;IACnC,YAAY,SAAM;IAClB,SAAS,SAAM;IACf,KAAK,SAAK;IACD,cAAc,EAAE,oBAAoB,CAAY;gBAC7C,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM;CAIlD;AACD,qBACa,QAAS,SAAQ,MAAM;CAAG"}
@@ -0,0 +1,131 @@
1
+ //#region src/course-authoring-contracts.ts
2
+ var COURSE_AUTHORING_ACTIONS = [
3
+ "education.course.read-draft",
4
+ "education.course.author",
5
+ "education.course.generate",
6
+ "education.course.review",
7
+ "education.course.release",
8
+ "education.course.assign",
9
+ "education.course.archive",
10
+ "education.course.set-visibility",
11
+ "education.course.set-cover"
12
+ ];
13
+ var COURSE_PROVENANCES = [
14
+ "supplied",
15
+ "generated",
16
+ "edited",
17
+ "extracted"
18
+ ];
19
+ var MAX_PAGE_SIZE = 100;
20
+ var DEFAULT_PAGE_SIZE = 50;
21
+ var CourseAuthoringError = class extends Error {
22
+ constructor(code, message) {
23
+ super(message);
24
+ this.code = code;
25
+ this.name = new.target.name;
26
+ }
27
+ code;
28
+ };
29
+ var CourseAuthoringAuthorizationError = class extends CourseAuthoringError {
30
+ constructor() {
31
+ super("not-authorized", "Course authoring access is not authorized.");
32
+ }
33
+ };
34
+ var CourseAuthoringValidationError = class extends CourseAuthoringError {
35
+ constructor(message) {
36
+ super("invalid-request", message);
37
+ }
38
+ };
39
+ var CourseNotFoundError = class extends CourseAuthoringError {
40
+ constructor() {
41
+ super("course-not-found", "Course was not found.");
42
+ }
43
+ };
44
+ var CourseDiscardedError = class extends CourseAuthoringError {
45
+ constructor() {
46
+ super("course-discarded", "Course draft was discarded.");
47
+ }
48
+ };
49
+ var CourseArchivedError = class extends CourseAuthoringError {
50
+ constructor() {
51
+ super("course-archived", "Course is archived; unarchive it first.");
52
+ }
53
+ };
54
+ var CourseAppendRefusedError = class extends CourseAuthoringError {
55
+ constructor(reason) {
56
+ super("append-refused", `Lesson append refused: ${reason}.`);
57
+ this.reason = reason;
58
+ }
59
+ reason;
60
+ };
61
+ var CourseStaleHeadError = class extends CourseAuthoringError {
62
+ constructor(currentHeadRevisionId) {
63
+ super("stale-head", "The draft head moved; reload and retry.");
64
+ this.currentHeadRevisionId = currentHeadRevisionId;
65
+ }
66
+ currentHeadRevisionId;
67
+ };
68
+ var CoursePolicyBasisMismatchError = class extends CourseAuthoringError {
69
+ constructor() {
70
+ super("policy-basis-mismatch", "The supplied policy basis differs from the one the authorizer relied on.");
71
+ }
72
+ };
73
+ var CourseRequestKeyConflictError = class extends CourseAuthoringError {
74
+ constructor() {
75
+ super("request-key-conflict", "The request key was already used for a different request.");
76
+ }
77
+ };
78
+ var ReviewGateRequiredError = class extends CourseAuthoringError {
79
+ constructor() {
80
+ super("review-gate-required", "Release requires a configured review gate; none is configured.");
81
+ }
82
+ };
83
+ var ReviewNotCurrentError = class extends CourseAuthoringError {
84
+ constructor(reason) {
85
+ super("review-not-current", "Release requires a current review of this exact revision.");
86
+ this.reason = reason;
87
+ }
88
+ reason;
89
+ };
90
+ var CourseRevisionAlreadyReleasedError = class extends CourseAuthoringError {
91
+ constructor(releaseId) {
92
+ super("revision-already-released", "This revision is already released.");
93
+ this.releaseId = releaseId;
94
+ }
95
+ releaseId;
96
+ };
97
+ var CourseDiscardRefusedError = class extends CourseAuthoringError {
98
+ constructor(references) {
99
+ super("discard-refused", "Only drafts with no release, enrollment, attempt, review or variant can be discarded.");
100
+ this.references = references;
101
+ }
102
+ references;
103
+ };
104
+ var EnrollmentPinConflictError = class extends CourseAuthoringError {
105
+ constructor(message = "Enrollment pin request conflicts with current state.") {
106
+ super("enrollment-pin-conflict", message);
107
+ }
108
+ };
109
+ var CourseMaterialCopyError = class extends CourseAuthoringError {
110
+ constructor(message = "Course material could not be copied to an owned asset.") {
111
+ super("material-copy-failed", message);
112
+ }
113
+ };
114
+ var CourseVisibilityRefusedError = class extends CourseAuthoringError {
115
+ constructor(visibility) {
116
+ super("visibility-refused", "A personal-use course can only be family-visible.");
117
+ this.visibility = visibility;
118
+ }
119
+ visibility;
120
+ };
121
+ var CourseCoverInvalidError = class extends CourseAuthoringError {
122
+ constructor(reason) {
123
+ super("cover-invalid", "The cover must be a readable education-owned image.");
124
+ this.reason = reason;
125
+ }
126
+ reason;
127
+ };
128
+ //#endregion
129
+ export { ReviewNotCurrentError as S, CourseVisibilityRefusedError as _, CourseAuthoringAuthorizationError as a, MAX_PAGE_SIZE as b, CourseCoverInvalidError as c, CourseMaterialCopyError as d, CourseNotFoundError as f, CourseStaleHeadError as g, CourseRevisionAlreadyReleasedError as h, CourseArchivedError as i, CourseDiscardRefusedError as l, CourseRequestKeyConflictError as m, COURSE_PROVENANCES as n, CourseAuthoringError as o, CoursePolicyBasisMismatchError as p, CourseAppendRefusedError as r, CourseAuthoringValidationError as s, COURSE_AUTHORING_ACTIONS as t, CourseDiscardedError as u, DEFAULT_PAGE_SIZE as v, ReviewGateRequiredError as x, EnrollmentPinConflictError as y };
130
+
131
+ //# sourceMappingURL=course-authoring-contracts-C4Hqba-e.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"course-authoring-contracts-C4Hqba-e.js","names":[],"sources":["../../src/course-authoring-contracts.ts"],"sourcesContent":["import type { DatabaseInterface } from '@happyvertical/sql';\nimport type {\n CourseLicenseKind,\n CourseModality,\n CourseVisibility,\n} from './catalog.js';\nimport type {\n LessonAssetRelationship,\n MaterialAudience,\n} from './lesson-assets.js';\nimport type {\n LessonLayoutParams,\n LessonQuestionRefInput,\n} from './question-contracts.js';\n\n/** Authorizer actions. The host maps roles; the service never infers a role. */\nexport type CourseAuthoringAction =\n | 'education.course.read-draft'\n | 'education.course.author'\n | 'education.course.generate'\n | 'education.course.review'\n | 'education.course.release'\n | 'education.course.assign'\n | 'education.course.archive'\n | 'education.course.set-visibility'\n | 'education.course.set-cover';\n\nexport const COURSE_AUTHORING_ACTIONS: readonly CourseAuthoringAction[] = [\n 'education.course.read-draft',\n 'education.course.author',\n 'education.course.generate',\n 'education.course.review',\n 'education.course.release',\n 'education.course.assign',\n 'education.course.archive',\n 'education.course.set-visibility',\n 'education.course.set-cover',\n];\n\n/** Which service operation asked, so a host can deny agents specific operations. */\nexport type CourseAuthoringOperation =\n | 'create'\n | 'save-draft'\n | 'append-lesson'\n | 'read-draft'\n | 'release'\n | 'archive'\n | 'unarchive'\n | 'set-visibility'\n | 'set-cover'\n | 'discard'\n | 'pin-enrollment'\n | 'upgrade-enrollment'\n | 'set-auto-upgrade'\n | 'auto-upgrade'\n | 'read-enrollment'\n | 'create-question'\n | 'save-question'\n | 'read-question'\n | 'resolve-question-revisions'\n | 'create-objective'\n | 'save-objective'\n | 'link-objectives'\n | 'read-worksheet'\n | 'request-generation'\n | 'run-generation'\n | 'cancel-generation'\n | 'accept-proposal'\n | 'read-generation'\n | 'record-review'\n | 'read-review'\n | 'resolve-finding'\n | 'note-context-change'\n | 'list-courses'\n | 'list-upgrade-choices'\n | 'list-auto-upgrade-skips'\n | 'read-released-lesson'\n | 'attach-printable'\n | 'preserve-question-extraction'\n | 'read-question-extraction'\n | 'apply-question-extraction'\n | 'import-course-bundle'\n | 'read-course-bundle'\n | 'retry-course-bundle-rendering'\n | 'apply-course-bundle-materials';\n\n/** Trusted identity supplied by the host session, never by a browser form. */\nexport interface CourseAuthoringActor {\n tenantId: string;\n actorUserId: string;\n /** Agent calls: the guardian whose delegation the host re-validates per check. */\n delegatingGuardianUserId?: string;\n /**\n * Host-supplied opaque delegation id (1-200 printable characters), required\n * with, and only with, `delegatingGuardianUserId`. Recorded on every decision\n * and passed to every authorizer call; it grants nothing by itself.\n */\n delegationId?: string;\n}\n\n/**\n * A richer authorizer answer. `reason` (at most 200 characters) and `code` (a\n * short token, at most 64 characters of `[a-z0-9._-]`) are recorded on an\n * auto-upgrade skip when `allowed` is false; invalid values are dropped, never\n * thrown. A plain `boolean` stays valid everywhere.\n */\nexport interface CourseAuthorizationDecision {\n allowed: boolean;\n reason?: string;\n code?: string;\n /**\n * `education.course.assign` only: the assignment-setting value the host relied\n * on (1-200 printable characters). It becomes the recorded policy basis for pin,\n * upgrade and opt-in rows, replacing the caller-supplied one; if the caller also\n * sent one it must be equal (`CoursePolicyBasisMismatchError`). Ignored for other\n * actions. An invalid value is a validation error and nothing is written.\n */\n policyBasis?: string;\n}\n\n/** Result of a host delegation check; a bare boolean is accepted as well. */\nexport type CourseDelegationDecision =\n | boolean\n | { allowed: boolean; reason?: string; code?: string };\n\n/**\n * Host port that verifies a delegation (the agent may act for the guardian under\n * this id) on the supplied transaction executor. Without it every delegated\n * request is refused; it runs before the host authorizer and never grants by\n * itself.\n */\nexport type CourseDelegationVerifier = (\n executor: DatabaseInterface,\n request: {\n tenantId: string;\n actorUserId: string;\n delegatingGuardianUserId: string;\n delegationId: string;\n action: CourseAuthoringAction;\n operation: CourseAuthoringOperation;\n courseId?: string;\n enrollmentId?: string;\n learnerId?: string;\n /** Pin and upgrade only: the target release and its materialized course. */\n releaseId?: string;\n releaseCourseId?: string;\n },\n) => CourseDelegationDecision | Promise<CourseDelegationDecision>;\n\nexport type CourseAuthoringAuthorizer = (\n request: CourseAuthoringActor & {\n action: CourseAuthoringAction;\n operation: CourseAuthoringOperation;\n /** The active service executor; host policy reads must share its transaction. */\n executor: DatabaseInterface;\n courseId?: string;\n enrollmentId?: string;\n learnerId?: string;\n /** Pin and upgrade only: the target release and its materialized course. */\n releaseId?: string;\n releaseCourseId?: string;\n },\n) =>\n | boolean\n | CourseAuthorizationDecision\n | Promise<boolean | CourseAuthorizationDecision>;\n\nexport type CourseProvenance =\n | 'supplied'\n | 'generated'\n | 'edited'\n | 'extracted';\nexport const COURSE_PROVENANCES: readonly CourseProvenance[] = [\n 'supplied',\n 'generated',\n 'edited',\n 'extracted',\n];\nexport type CourseLessonType = 'reading' | 'video' | 'worksheet' | 'exercise';\nexport type CourseLessonCompletion = 'attest' | 'submit' | 'score' | 'external';\n\n/** Hook supplied by #4516; the service never treats an absent gate as a pass. */\nexport type ReleaseReviewGate = (\n executor: DatabaseInterface,\n request: { tenantId: string; courseId: string; revisionId: string },\n) =>\n | { current: boolean; reviewId?: string; reason?: string }\n | Promise<{ current: boolean; reviewId?: string; reason?: string }>;\n\n/** Hook supplied by #4516/variants: report review/variant rows that reference a draft. */\nexport type CourseReferenceGuard = (\n executor: DatabaseInterface,\n request: { tenantId: string; courseId: string },\n) =>\n | { referenced: boolean; kinds?: readonly string[] }\n | Promise<{ referenced: boolean; kinds?: readonly string[] }>;\n\n/** Copies an upload (for example an ingestion item) to an education-owned asset. */\nexport interface CourseMaterialSource {\n kind: string;\n ref: string;\n}\nexport interface CourseMaterialCopyRequest {\n tenantId: string;\n actorUserId: string;\n courseId: string;\n source: CourseMaterialSource;\n relationship: LessonAssetRelationship;\n}\nexport interface CourseMaterialCopyPort {\n /** Must return an asset owned by the same tenant, independent of the source's expiry. */\n copy(\n executor: DatabaseInterface,\n request: CourseMaterialCopyRequest,\n ): Promise<{ assetId: string }>;\n}\n\nexport interface CourseMaterialInput {\n /** Uploaded material to copy; mutually exclusive with `assetId`. */\n source?: CourseMaterialSource;\n /** Reuse an asset already copied into this course by an earlier revision. */\n assetId?: string;\n relationship: LessonAssetRelationship;\n licenseKind?: CourseLicenseKind;\n /** Who it is for; omitted means the role default (`LESSON_ASSET_DEFAULT_AUDIENCE`). */\n audience?: MaterialAudience;\n}\nexport interface CourseMaterialView {\n assetId: string;\n relationship: LessonAssetRelationship;\n /** Stated audience; absent means the role default. */\n audience?: MaterialAudience;\n licenseKind: CourseLicenseKind;\n provenance: {\n source: CourseMaterialSource | null;\n copiedAt: string;\n copiedByUserId: string;\n };\n}\n\nexport interface CourseLessonInput {\n /** Stable cross-version identity; omit for a new lesson. */\n lessonKey?: string;\n title: string;\n body?: string;\n lessonType?: CourseLessonType;\n completionRule?: CourseLessonCompletion;\n estimatedMinutes?: number;\n difficulty?: number;\n modality?: CourseModality;\n externalRef?: string;\n externalUrl?: string;\n licenseKind?: CourseLicenseKind;\n provenance?: CourseProvenance;\n fieldProvenance?: Record<string, CourseProvenance>;\n materials?: CourseMaterialInput[];\n /** Ordered immutable question revisions; each must exist in this tenant. */\n questions?: LessonQuestionRefInput[];\n /** Flat render parameters folded into the worksheet version id. */\n layoutParams?: LessonLayoutParams;\n}\nexport interface CourseSectionInput {\n sectionKey: string;\n title: string;\n lessons: CourseLessonInput[];\n}\nexport interface CourseDraftInput {\n title: string;\n summary?: string;\n subject?: string;\n theme?: string;\n levelMin?: number;\n levelMax?: number;\n objectives?: string[];\n sections: CourseSectionInput[];\n provenance: CourseProvenance;\n fieldProvenance?: Record<string, CourseProvenance>;\n}\n\nexport interface CourseLessonRevisionView {\n id: string;\n lessonKey: string;\n parentRevisionId: string | null;\n title: string;\n body: string;\n lessonType: CourseLessonType;\n completionRule: CourseLessonCompletion;\n estimatedMinutes: number;\n difficulty: number;\n modality: CourseModality;\n externalRef: string;\n externalUrl: string;\n licenseKind: CourseLicenseKind;\n provenance: CourseProvenance;\n fieldProvenance: Record<string, CourseProvenance>;\n materials: CourseMaterialView[];\n questions: LessonQuestionRefInput[];\n layoutParams: LessonLayoutParams;\n}\n/** Alias for hosts: a lesson revision as read by the authoring views. */\nexport type LessonRevisionView = CourseLessonRevisionView;\nexport interface CourseRevisionView {\n id: string;\n courseId: string;\n parentRevisionId: string | null;\n sequence: number;\n title: string;\n summary: string;\n subject: string;\n theme: string;\n levelMin: number;\n levelMax: number;\n objectives: string[];\n licenseKind: CourseLicenseKind;\n provenance: CourseProvenance;\n fieldProvenance: Record<string, CourseProvenance>;\n authorUserId: string;\n delegatingGuardianUserId: string | null;\n delegationId: string | null;\n recordedAt: string;\n sections: Array<{\n sectionKey: string;\n title: string;\n lessons: CourseLessonRevisionView[];\n }>;\n}\nexport interface CourseHeadView {\n courseId: string;\n /** The expected-head token for the next save. */\n headRevisionId: string;\n version: number;\n}\n/** Result of `appendLesson`: the new revision and, unless skipped, its release. */\nexport type CourseAppendLessonView = Readonly<{\n courseId: string;\n /** The appended revision; the new draft head. */\n revisionId: string;\n version: number;\n lessonKey: string;\n /** The release of that revision; null when `release: false` was requested. */\n release: CourseReleaseView | null;\n}>;\n\nexport type CourseReleaseView = Readonly<{\n id: string;\n courseId: string;\n revisionId: string;\n releaseNumber: number;\n releaseCourseId: string;\n /** The cover snapshotted onto this release; null when the course had none. */\n coverAssetId: string | null;\n reviewId: string | null;\n actorUserId: string;\n delegatingGuardianUserId: string | null;\n delegationId: string | null;\n /** The host setting the release relied on (for example an auto-approve); null if none. */\n policyBasis: string | null;\n recordedAt: string;\n lessons: ReadonlyArray<{\n lessonKey: string;\n lessonRevisionId: string;\n lessonId: string;\n sectionId: string;\n }>;\n}>;\nexport type CourseLifecycleState =\n | 'draft'\n | 'released'\n | 'archived'\n | 'discarded';\nexport type CourseStateView = Readonly<{\n courseId: string;\n title: string;\n state: CourseLifecycleState;\n licenseKind: CourseLicenseKind;\n /** Personal-use material makes the course tenant-private and never group-shareable. */\n groupShareable: boolean;\n /** `family` unless set otherwise (see `setVisibility`). */\n visibility: CourseVisibility;\n /** The education-owned cover image asset, or null (hosts render a fallback). */\n coverAssetId: string | null;\n headRevisionId: string | null;\n releases: ReadonlyArray<{\n id: string;\n releaseNumber: number;\n revisionId: string;\n releaseCourseId: string;\n }>;\n}>;\n/** Largest page a list read returns; the default is `DEFAULT_PAGE_SIZE`. */\nexport const MAX_PAGE_SIZE = 100;\nexport const DEFAULT_PAGE_SIZE = 50;\n\n/** Opaque, deterministic pagination: pass back `nextCursor` unchanged. */\nexport interface CoursePageRequest {\n limit?: number;\n cursor?: string;\n}\nexport type CoursePage<T> = Readonly<{\n items: ReadonlyArray<T>;\n /** Null on the last page. */\n nextCursor: string | null;\n}>;\n\nexport type CourseArchiveDecisionView = Readonly<{\n action: 'archive' | 'unarchive';\n sequence: number;\n actorUserId: string;\n delegatingGuardianUserId: string | null;\n delegationId: string | null;\n recordedAt: string;\n}>;\n/** One authored course in `listCourses`. */\nexport type CourseSummaryView = Readonly<{\n courseId: string;\n title: string;\n state: CourseLifecycleState;\n createdAt: string;\n /**\n * Effective licence: the most restrictive of the head revision and every release's\n * materialized course, so a restriction recorded by any release never loosens.\n * `CourseStateView.licenseKind` reads the head alone and may be looser.\n */\n licenseKind: CourseLicenseKind;\n /**\n * The group-sharing rule applied to this course: false for personal-use and\n * false until the course has a release (nothing to share).\n */\n groupShareable: boolean;\n visibility: CourseVisibility;\n coverAssetId: string | null;\n /** Number of releases (0 for a draft-only course). */\n releaseCount: number;\n /** The draft head; `revisionId` is the expected-head token for the next save. */\n head: Readonly<{\n revisionId: string;\n sequence: number;\n version: number;\n }> | null;\n latestRelease: Readonly<{\n id: string;\n revisionId: string;\n releaseNumber: number;\n releaseCourseId: string;\n /** The cover snapshotted onto that release. */\n coverAssetId: string | null;\n recordedAt: string;\n }> | null;\n archive: Readonly<{\n archived: boolean;\n latestDecision: CourseArchiveDecisionView | null;\n }>;\n}>;\n\nexport type CourseUpgradeChoiceView = Readonly<{\n id: string;\n courseId: string;\n scope: 'course' | 'enrollment';\n /** Null for a course-level choice. */\n enrollmentId: string | null;\n enabled: boolean;\n kind: 'opt-in' | 'opt-out';\n sequence: number;\n actorUserId: string;\n delegatingGuardianUserId: string | null;\n delegationId: string | null;\n policyBasis: string;\n recordedAt: string;\n}>;\n\nexport type AutoUpgradeSkipView = Readonly<{\n id: string;\n enrollmentId: string;\n learnerId: string;\n courseId: string;\n releaseId: string;\n optInScope: 'course' | 'enrollment';\n optInActorUserId: string;\n optInDelegatingGuardianUserId: string | null;\n optInDelegationId: string | null;\n policyBasis: string;\n /** The authorizer's reason when it gave one, else `not-authorized`. */\n reason: string;\n /** The authorizer's short code, or an empty string. */\n code: string;\n recordedAt: string;\n}>;\n\nexport type EnrollmentPinKind = 'initial' | 'explicit' | 'auto';\nexport type EnrollmentPinView = Readonly<{\n enrollmentId: string;\n /** The enrollment's learner, from the enrollment row; hosts never read `enrollments`. */\n learnerId: string;\n /** The authored course identity (`AuthoredCourse` id) the pin follows. */\n courseId: string;\n releaseId: string;\n /** The materialized release `Course` id the enrollment is created on. */\n releaseCourseId: string;\n releaseNumber: number;\n kind: EnrollmentPinKind;\n autoUpgrade: boolean;\n /** Assignment-setting value the host relied on for the current pin. */\n policyBasis: string;\n history: ReadonlyArray<{\n releaseId: string;\n releaseCourseId: string;\n previousReleaseId: string | null;\n kind: EnrollmentPinKind;\n sequence: number;\n actorUserId: string | null;\n delegatingGuardianUserId: string | null;\n delegationId: string | null;\n policyBasis: string;\n /** For automatic moves: the scope of the opt-in followed. */\n optInScope: 'course' | 'enrollment' | null;\n recordedAt: string;\n }>;\n}>;\n/** Result of `getEnrollmentRelease`; identity fields repeat the pin's for convenience. */\nexport type EnrollmentReleaseView = Readonly<{\n learnerId: string;\n courseId: string;\n releaseCourseId: string;\n pin: EnrollmentPinView;\n lessons: EffectiveLessonView[];\n}>;\n/** Result of `setAutoUpgrade`; `learnerId` is null for a course-level choice. */\nexport type SetAutoUpgradeResult = Readonly<{\n courseId: string;\n enrollmentId: string | null;\n learnerId: string | null;\n enabled: boolean;\n policyBasis: string;\n}>;\nexport type EffectiveLessonView = Readonly<{\n lessonKey: string;\n lessonId: string;\n releaseId: string;\n /** True when a started lesson stays on an older release than the current pin. */\n pinnedToOlderRelease: boolean;\n}>;\n\nexport class CourseAuthoringError extends Error {\n constructor(\n readonly code: string,\n message: string,\n ) {\n super(message);\n this.name = new.target.name;\n }\n}\nexport class CourseAuthoringAuthorizationError extends CourseAuthoringError {\n constructor() {\n super('not-authorized', 'Course authoring access is not authorized.');\n }\n}\nexport class CourseAuthoringValidationError extends CourseAuthoringError {\n constructor(message: string) {\n super('invalid-request', message);\n }\n}\nexport class CourseNotFoundError extends CourseAuthoringError {\n constructor() {\n super('course-not-found', 'Course was not found.');\n }\n}\nexport class CourseDiscardedError extends CourseAuthoringError {\n constructor() {\n super('course-discarded', 'Course draft was discarded.');\n }\n}\nexport class CourseArchivedError extends CourseAuthoringError {\n constructor() {\n super('course-archived', 'Course is archived; unarchive it first.');\n }\n}\n/**\n * `appendLesson` was refused for the course's state: it has no release yet\n * (`not-released`), its head holds changes that are not released\n * (`unreleased-changes`), or the lesson key or section is already taken\n * (`duplicate-lesson`).\n */\nexport class CourseAppendRefusedError extends CourseAuthoringError {\n constructor(\n readonly reason: 'not-released' | 'unreleased-changes' | 'duplicate-lesson',\n ) {\n super('append-refused', `Lesson append refused: ${reason}.`);\n }\n}\nexport class CourseStaleHeadError extends CourseAuthoringError {\n constructor(readonly currentHeadRevisionId: string) {\n super('stale-head', 'The draft head moved; reload and retry.');\n }\n}\n/** The caller and the assign authorizer named different policy bases. */\nexport class CoursePolicyBasisMismatchError extends CourseAuthoringError {\n constructor() {\n super(\n 'policy-basis-mismatch',\n 'The supplied policy basis differs from the one the authorizer relied on.',\n );\n }\n}\nexport class CourseRequestKeyConflictError extends CourseAuthoringError {\n constructor() {\n super(\n 'request-key-conflict',\n 'The request key was already used for a different request.',\n );\n }\n}\nexport class ReviewGateRequiredError extends CourseAuthoringError {\n constructor() {\n super(\n 'review-gate-required',\n 'Release requires a configured review gate; none is configured.',\n );\n }\n}\nexport class ReviewNotCurrentError extends CourseAuthoringError {\n constructor(readonly reason?: string) {\n super(\n 'review-not-current',\n 'Release requires a current review of this exact revision.',\n );\n }\n}\nexport class CourseRevisionAlreadyReleasedError extends CourseAuthoringError {\n constructor(readonly releaseId: string) {\n super('revision-already-released', 'This revision is already released.');\n }\n}\nexport class CourseDiscardRefusedError extends CourseAuthoringError {\n constructor(readonly references: readonly string[]) {\n super(\n 'discard-refused',\n 'Only drafts with no release, enrollment, attempt, review or variant can be discarded.',\n );\n }\n}\nexport class EnrollmentPinConflictError extends CourseAuthoringError {\n constructor(\n message = 'Enrollment pin request conflicts with current state.',\n ) {\n super('enrollment-pin-conflict', message);\n }\n}\nexport class CourseMaterialCopyError extends CourseAuthoringError {\n constructor(\n message = 'Course material could not be copied to an owned asset.',\n ) {\n super('material-copy-failed', message);\n }\n}\n\n/** Result of `setVisibility`/`setCover`: the course state after the (maybe unchanged) write. */\nexport type CourseVisibilityResult = CourseStateView;\nexport type CourseCoverResult = CourseStateView;\n\n/** A personal-use-copy course can never be shared with groups or listed publicly. */\nexport class CourseVisibilityRefusedError extends CourseAuthoringError {\n constructor(readonly visibility: CourseVisibility) {\n super(\n 'visibility-refused',\n 'A personal-use course can only be family-visible.',\n );\n }\n}\n/** The cover asset is missing, foreign, not an image, an answer key or unreadable. */\nexport class CourseCoverInvalidError extends CourseAuthoringError {\n constructor(readonly reason: string) {\n super(\n 'cover-invalid',\n 'The cover must be a readable education-owned image.',\n );\n }\n}\n"],"mappings":";AA2BO,IAAM,2BAA6D;CACxE;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAuIO,IAAM,qBAAkD;CAC7D;CACA;CACA;CACA;AACF;AAqNO,IAAM,gBAAgB;AACtB,IAAM,oBAAoB;AAuJ1B,IAAM,uBAAN,cAAmC,MAAM;CAC9C,YACW,MACT,SACA;EACA,MAAM,OAAO;EAHJ,KAAA,OAAA;EAIT,KAAK,OAAO,IAAA,OAAW;CACzB;CALW;AAMb;AACO,IAAM,oCAAN,cAAgD,qBAAqB;CAC1E,cAAc;EACZ,MAAM,kBAAkB,4CAA4C;CACtE;AACF;AACO,IAAM,iCAAN,cAA6C,qBAAqB;CACvE,YAAY,SAAiB;EAC3B,MAAM,mBAAmB,OAAO;CAClC;AACF;AACO,IAAM,sBAAN,cAAkC,qBAAqB;CAC5D,cAAc;EACZ,MAAM,oBAAoB,uBAAuB;CACnD;AACF;AACO,IAAM,uBAAN,cAAmC,qBAAqB;CAC7D,cAAc;EACZ,MAAM,oBAAoB,6BAA6B;CACzD;AACF;AACO,IAAM,sBAAN,cAAkC,qBAAqB;CAC5D,cAAc;EACZ,MAAM,mBAAmB,yCAAyC;CACpE;AACF;AAOO,IAAM,2BAAN,cAAuC,qBAAqB;CACjE,YACW,QACT;EACA,MAAM,kBAAkB,0BAA0B,OAAM,EAAG;EAFlD,KAAA,SAAA;CAGX;CAHW;AAIb;AACO,IAAM,uBAAN,cAAmC,qBAAqB;CAC7D,YAAqB,uBAA+B;EAClD,MAAM,cAAc,yCAAyC;EAD1C,KAAA,wBAAA;CAErB;CAFqB;AAGvB;AAEO,IAAM,iCAAN,cAA6C,qBAAqB;CACvE,cAAc;EACZ,MACE,yBACA,0EACF;CACF;AACF;AACO,IAAM,gCAAN,cAA4C,qBAAqB;CACtE,cAAc;EACZ,MACE,wBACA,2DACF;CACF;AACF;AACO,IAAM,0BAAN,cAAsC,qBAAqB;CAChE,cAAc;EACZ,MACE,wBACA,gEACF;CACF;AACF;AACO,IAAM,wBAAN,cAAoC,qBAAqB;CAC9D,YAAqB,QAAiB;EACpC,MACE,sBACA,2DACF;EAJmB,KAAA,SAAA;CAKrB;CALqB;AAMvB;AACO,IAAM,qCAAN,cAAiD,qBAAqB;CAC3E,YAAqB,WAAmB;EACtC,MAAM,6BAA6B,oCAAoC;EADpD,KAAA,YAAA;CAErB;CAFqB;AAGvB;AACO,IAAM,4BAAN,cAAwC,qBAAqB;CAClE,YAAqB,YAA+B;EAClD,MACE,mBACA,uFACF;EAJmB,KAAA,aAAA;CAKrB;CALqB;AAMvB;AACO,IAAM,6BAAN,cAAyC,qBAAqB;CACnE,YACE,UAAU,wDACV;EACA,MAAM,2BAA2B,OAAO;CAC1C;AACF;AACO,IAAM,0BAAN,cAAsC,qBAAqB;CAChE,YACE,UAAU,0DACV;EACA,MAAM,wBAAwB,OAAO;CACvC;AACF;AAOO,IAAM,+BAAN,cAA2C,qBAAqB;CACrE,YAAqB,YAA8B;EACjD,MACE,sBACA,mDACF;EAJmB,KAAA,aAAA;CAKrB;CALqB;AAMvB;AAEO,IAAM,0BAAN,cAAsC,qBAAqB;CAChE,YAAqB,QAAgB;EACnC,MACE,iBACA,qDACF;EAJmB,KAAA,SAAA;CAKrB;CALqB;AAMvB"}