@happyvertical/smrt-education 0.57.43 → 0.57.45

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 (84) hide show
  1. package/AGENTS.md +13 -0
  2. package/README.md +5 -0
  3. package/agents/course-authoring-service.md +179 -0
  4. package/agents/course-generation-review.md +79 -0
  5. package/agents/learner-service.md +33 -0
  6. package/agents/question-records.md +140 -0
  7. package/dist/chunks/{workbook-photo-service-C6mbUUp6.js → workbook-photo-service-DKgoUHeb.js} +6203 -5072
  8. package/dist/chunks/workbook-photo-service-DKgoUHeb.js.map +1 -0
  9. package/dist/course-append-only.d.ts +15 -0
  10. package/dist/course-append-only.d.ts.map +1 -0
  11. package/dist/course-authoring-contracts.d.ts +464 -0
  12. package/dist/course-authoring-contracts.d.ts.map +1 -0
  13. package/dist/course-authoring-licence.d.ts +15 -0
  14. package/dist/course-authoring-licence.d.ts.map +1 -0
  15. package/dist/course-authoring-models.d.ts +291 -0
  16. package/dist/course-authoring-models.d.ts.map +1 -0
  17. package/dist/course-authoring-service.d.ts +244 -0
  18. package/dist/course-authoring-service.d.ts.map +1 -0
  19. package/dist/course-delegation.d.ts +26 -0
  20. package/dist/course-delegation.d.ts.map +1 -0
  21. package/dist/course-generation-contracts.d.ts +186 -0
  22. package/dist/course-generation-contracts.d.ts.map +1 -0
  23. package/dist/course-generation-models.d.ts +94 -0
  24. package/dist/course-generation-models.d.ts.map +1 -0
  25. package/dist/course-generation-output.d.ts +31 -0
  26. package/dist/course-generation-output.d.ts.map +1 -0
  27. package/dist/course-generation-proposal-generator.d.ts +94 -0
  28. package/dist/course-generation-proposal-generator.d.ts.map +1 -0
  29. package/dist/course-generation-review-service.d.ts +149 -0
  30. package/dist/course-generation-review-service.d.ts.map +1 -0
  31. package/dist/course-release-scope.d.ts +37 -0
  32. package/dist/course-release-scope.d.ts.map +1 -0
  33. package/dist/course-review-contracts.d.ts +127 -0
  34. package/dist/course-review-contracts.d.ts.map +1 -0
  35. package/dist/course-review-digest.d.ts +4 -0
  36. package/dist/course-review-digest.d.ts.map +1 -0
  37. package/dist/course-review-evaluation.d.ts +63 -0
  38. package/dist/course-review-evaluation.d.ts.map +1 -0
  39. package/dist/course-review-gate.d.ts +15 -0
  40. package/dist/course-review-gate.d.ts.map +1 -0
  41. package/dist/course-review-models.d.ts +96 -0
  42. package/dist/course-review-models.d.ts.map +1 -0
  43. package/dist/group-sharing-contracts.d.ts +5 -0
  44. package/dist/group-sharing-contracts.d.ts.map +1 -1
  45. package/dist/group-sharing-policy.d.ts.map +1 -1
  46. package/dist/group-sharing-reader.d.ts.map +1 -1
  47. package/dist/index.d.ts +28 -0
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +6200 -94
  50. package/dist/index.js.map +1 -1
  51. package/dist/ingestion.js +1 -1
  52. package/dist/learner-plan-service.d.ts.map +1 -1
  53. package/dist/learner-service.d.ts +81 -7
  54. package/dist/learner-service.d.ts.map +1 -1
  55. package/dist/learners.d.ts +6 -0
  56. package/dist/learners.d.ts.map +1 -1
  57. package/dist/manifest.json +14735 -2164
  58. package/dist/question-authoring-service.d.ts +154 -0
  59. package/dist/question-authoring-service.d.ts.map +1 -0
  60. package/dist/question-content.d.ts +25 -0
  61. package/dist/question-content.d.ts.map +1 -0
  62. package/dist/question-contracts.d.ts +292 -0
  63. package/dist/question-contracts.d.ts.map +1 -0
  64. package/dist/question-models.d.ts +151 -0
  65. package/dist/question-models.d.ts.map +1 -0
  66. package/dist/question-printable.d.ts +9 -0
  67. package/dist/question-printable.d.ts.map +1 -0
  68. package/dist/question-render.d.ts +20 -0
  69. package/dist/question-render.d.ts.map +1 -0
  70. package/dist/question-response-contracts.d.ts +54 -0
  71. package/dist/question-response-contracts.d.ts.map +1 -0
  72. package/dist/question-response-service.d.ts +63 -0
  73. package/dist/question-response-service.d.ts.map +1 -0
  74. package/dist/question-rubric.d.ts +23 -0
  75. package/dist/question-rubric.d.ts.map +1 -0
  76. package/dist/smrt-knowledge.json +5500 -839
  77. package/dist/submission-service.d.ts.map +1 -1
  78. package/dist/submissions.d.ts +5 -0
  79. package/dist/submissions.d.ts.map +1 -1
  80. package/dist/workbook-contracts.d.ts +6 -0
  81. package/dist/workbook-contracts.d.ts.map +1 -1
  82. package/dist/workbook-models.d.ts.map +1 -1
  83. package/package.json +8 -8
  84. package/dist/chunks/workbook-photo-service-C6mbUUp6.js.map +0 -1
@@ -0,0 +1,154 @@
1
+ import { type AssetRuntimeOptions } from '@happyvertical/smrt-assets';
2
+ import type { DatabaseInterface } from '@happyvertical/sql';
3
+ import { type CourseAuthoringActor, type CourseAuthoringAuthorizer } from './course-authoring-contracts.js';
4
+ import { CourseAuthoringService, type CourseAuthoringServiceOptions } from './course-authoring-service.js';
5
+ import { type AttachGeneratedPrintableRequest, type GeneratedPrintableResult, type LearningObjectiveInput, type LearningObjectiveView, type QuestionContentInput, type QuestionHeadView, type QuestionRevisionView, type ReleasedLessonView, type ResolvedQuestionRevisions, type WorksheetBundle } from './question-contracts.js';
6
+ export interface QuestionAuthoringServiceOptions extends CourseAuthoringServiceOptions {
7
+ /** Trusted concept ids; when supplied, question and objective concepts must belong. */
8
+ conceptVocabulary?: ReadonlyArray<{
9
+ id: string;
10
+ }>;
11
+ /**
12
+ * Private asset storage for `attachGeneratedPrintable`, the same shape
13
+ * `SubmissionService` takes. Server configuration only. Without it the call
14
+ * fails closed with `PrintableStorageNotConfiguredError`.
15
+ */
16
+ printableAssets?: {
17
+ storage: AssetRuntimeOptions['storage'];
18
+ storeOptions?: AssetRuntimeOptions['storeOptions'];
19
+ };
20
+ }
21
+ /**
22
+ * Actor-bound authoring of immutable questions and stable learning objectives.
23
+ * It shares `CourseAuthoringService`'s authorizer and actions: writes need
24
+ * `education.course.author` (plus `generate` for generated provenance); reads of
25
+ * answer keys need `education.course.read-draft`.
26
+ */
27
+ export declare class QuestionAuthoringService extends CourseAuthoringService {
28
+ private readonly vocabulary;
29
+ /** The non-transactional database: compensation must read committed state. */
30
+ private readonly rootDatabase;
31
+ private readonly printableAssets;
32
+ constructor(db: DatabaseInterface, authorizer: CourseAuthoringAuthorizer, options?: QuestionAuthoringServiceOptions);
33
+ private normalize;
34
+ private normalizeObjective;
35
+ private authorizeWrite;
36
+ /** Objectives and media named by a revision must exist in the same tenant. */
37
+ private requireReferences;
38
+ private lock;
39
+ private head;
40
+ /** Creates the stable question identity and its first immutable revision. */
41
+ createQuestion(request: CourseAuthoringActor & {
42
+ requestKey: string;
43
+ courseId?: string;
44
+ content: QuestionContentInput;
45
+ }): Promise<QuestionHeadView>;
46
+ private appendQuestionRevision;
47
+ /**
48
+ * Appends an immutable revision when `expectedHeadRevisionId` is still the
49
+ * head. A retried key replays its original result; the same key with a
50
+ * different payload is a typed conflict.
51
+ */
52
+ saveQuestionRevision(request: CourseAuthoringActor & {
53
+ questionId: string;
54
+ expectedHeadRevisionId: string;
55
+ requestKey: string;
56
+ content: QuestionContentInput;
57
+ }): Promise<QuestionHeadView>;
58
+ /** Replaces a question's objective links by appending a revision. */
59
+ linkObjectives(request: CourseAuthoringActor & {
60
+ questionId: string;
61
+ expectedHeadRevisionId: string;
62
+ requestKey: string;
63
+ objectiveIds: string[];
64
+ }): Promise<QuestionHeadView>;
65
+ private saveRevision;
66
+ private questionRow;
67
+ private contentFromRow;
68
+ private questionRevisionView;
69
+ /** Reads a question revision (the head unless `revisionId` is given), key included. */
70
+ readQuestion(request: CourseAuthoringActor & {
71
+ questionId: string;
72
+ revisionId?: string;
73
+ }): Promise<{
74
+ head: QuestionHeadView;
75
+ revision: QuestionRevisionView;
76
+ }>;
77
+ /**
78
+ * Resolves question revision ids to reference labels for a host (e.g. a printed
79
+ * worksheet's question list). Needs `read-draft` (operation
80
+ * `resolve-question-revisions`, no course). Tenant-exact: an id that is unknown
81
+ * or belongs to another tenant is simply reported in `missing`, with no
82
+ * distinction. The result never carries answer keys, rubrics, choices, media or
83
+ * provenance. At most 200 ids; duplicates are folded; an empty list, a
84
+ * non-string or an over-long id is a validation error.
85
+ */
86
+ resolveQuestionRevisions(request: CourseAuthoringActor & {
87
+ revisionIds: string[];
88
+ }): Promise<ResolvedQuestionRevisions>;
89
+ /**
90
+ * Creates a stable objective identity under a tenant-unique `externalKey`. The
91
+ * same key with the same request replays; any other use of the key conflicts.
92
+ */
93
+ createLearningObjective(request: CourseAuthoringActor & {
94
+ requestKey: string;
95
+ externalKey: string;
96
+ objective: LearningObjectiveInput;
97
+ }): Promise<LearningObjectiveView>;
98
+ private appendObjective;
99
+ /** Appends new wording; the objective's id and `externalKey` never change. */
100
+ saveLearningObjectiveRevision(request: CourseAuthoringActor & {
101
+ objectiveId: string;
102
+ expectedHeadRevisionId: string;
103
+ requestKey: string;
104
+ objective: LearningObjectiveInput;
105
+ }): Promise<LearningObjectiveView>;
106
+ private objectiveRow;
107
+ private objectiveView;
108
+ /** Reads an objective by id or by its stable external key. */
109
+ readLearningObjective(request: CourseAuthoringActor & {
110
+ objectiveId?: string;
111
+ externalKey?: string;
112
+ }): Promise<LearningObjectiveView>;
113
+ /**
114
+ * Render input for one lesson of a release, from its pinned question
115
+ * revisions. `learner` omits keys and rubrics by type. Both audiences need
116
+ * `read-draft` here; learner delivery is a host path that calls
117
+ * `buildLearnerWorksheet` over data it already authorized.
118
+ */
119
+ getWorksheet(request: CourseAuthoringActor & {
120
+ releaseId: string;
121
+ lessonKey: string;
122
+ audience: 'learner' | 'guardian';
123
+ }): Promise<WorksheetBundle>;
124
+ /** The release lesson's immutable revision row and keyed worksheet inputs. */
125
+ private releasedLessonInput;
126
+ /**
127
+ * Renders the released lesson's worksheet as a PDF and attaches it to the
128
+ * lesson as a private education-owned asset, so the durable print queue can
129
+ * serve it. `worksheetVersionId` must be the digest of the lesson revision's
130
+ * pinned questions and layout. The learner copy is built from the keyless
131
+ * bundle and linked as `printable`; the guardian copy carries keys and is
132
+ * linked as `answer-key`, which `SubmissionService.signLessonPrintable` never
133
+ * signs. Idempotent per (tenant, lesson, worksheet version, audience).
134
+ * Needs `education.course.author`, plus `read-draft` for the guardian audience.
135
+ * A learner of the tenant, or a delegation naming one, is refused before the
136
+ * host is asked.
137
+ */
138
+ attachGeneratedPrintable(request: AttachGeneratedPrintableRequest): Promise<GeneratedPrintableResult>;
139
+ /** Removes files planned by a rolled-back attach, unless their asset committed. */
140
+ private compensatePrintables;
141
+ private attachOnce;
142
+ /**
143
+ * Authoring/guardian read of one released lesson: the full lesson revision
144
+ * (materials, provenance, ordered question refs, layout params) and the keyed
145
+ * worksheet bundle (answer keys and rubrics included). Needs `read-draft`;
146
+ * learners use `QuestionResponseService.readReleasedLesson`, which is keyless
147
+ * and limited to their effective lessons.
148
+ */
149
+ readReleasedLesson(request: CourseAuthoringActor & {
150
+ releaseId: string;
151
+ lessonKey: string;
152
+ }): Promise<ReleasedLessonView>;
153
+ }
154
+ //# sourceMappingURL=question-authoring-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"question-authoring-service.d.ts","sourceRoot":"","sources":["../src/question-authoring-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { type QuestionAnswerKey, type QuestionChoice, type QuestionContentInput, type QuestionField, type QuestionMediaRef, type QuestionProvenance, type QuestionResponseType, type QuestionRubric, type QuestionSubpart } from './question-contracts.js';
2
+ export interface NormalizedQuestionContent {
3
+ prompt: string;
4
+ responseType: QuestionResponseType;
5
+ choices: QuestionChoice[];
6
+ subparts: QuestionSubpart[];
7
+ media: Required<QuestionMediaRef>[];
8
+ objectiveIds: string[];
9
+ conceptIds: string[];
10
+ /** Null when no key was supplied; never an empty key. */
11
+ answerKey: QuestionAnswerKey | null;
12
+ rubric: QuestionRubric | null;
13
+ pointsPossible: number | null;
14
+ provenance: QuestionProvenance;
15
+ /** Effective provenance of every present field; absent fields have no entry. */
16
+ fieldProvenance: Partial<Record<QuestionField, QuestionProvenance>>;
17
+ }
18
+ /**
19
+ * Validates and normalizes authored question content. Pure; ownership checks
20
+ * (assets, objectives) are the caller's. Throws `CourseAuthoringValidationError`.
21
+ */
22
+ export declare function normalizeQuestionContent(input: QuestionContentInput, options?: {
23
+ conceptVocabulary?: ReadonlySet<string>;
24
+ }): NormalizedQuestionContent;
25
+ //# sourceMappingURL=question-content.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"question-content.d.ts","sourceRoot":"","sources":["../src/question-content.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,KAAK,eAAe,EACrB,MAAM,yBAAyB,CAAC;AAMjC,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,oBAAoB,CAAC;IACnC,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,KAAK,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;IACpC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,yDAAyD;IACzD,SAAS,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACpC,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,EAAE,kBAAkB,CAAC;IAC/B,gFAAgF;IAChF,eAAe,EAAE,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,kBAAkB,CAAC,CAAC,CAAC;CACrE;AAyED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,oBAAoB,EAC3B,OAAO,GAAE;IAAE,iBAAiB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;CAAO,GACxD,yBAAyB,CAuP3B"}
@@ -0,0 +1,292 @@
1
+ import { type CourseAuthoringActor, CourseAuthoringError, type CourseLessonCompletion, type CourseLessonRevisionView, type CourseLessonType } from './course-authoring-contracts.js';
2
+ import type { QuestionRubric } from './question-rubric.js';
3
+ export type { QuestionRubric, QuestionRubricCriterion, } from './question-rubric.js';
4
+ /** Supplied by the author, or inferred/generated/extracted by a tool. */
5
+ export type QuestionProvenance = 'supplied' | 'inferred' | 'generated' | 'edited' | 'extracted';
6
+ export declare const QUESTION_PROVENANCES: readonly QuestionProvenance[];
7
+ export type QuestionResponseType = 'short-answer' | 'numeric' | 'multiple-choice' | 'multi-select' | 'true-false' | 'extended' | 'multi-part';
8
+ export declare const QUESTION_RESPONSE_TYPES: readonly QuestionResponseType[];
9
+ /** Where a learner completed the question; same completion vocabulary as workbooks. */
10
+ export type QuestionCompletionMode = 'printable' | 'online' | 'interactive';
11
+ export declare const QUESTION_COMPLETION_MODES: readonly QuestionCompletionMode[];
12
+ export type QuestionAssistance = 'independent' | 'assisted' | 'unknown';
13
+ /** Fields that carry their own provenance. A field that is absent has no entry. */
14
+ export type QuestionField = 'prompt' | 'responseType' | 'choices' | 'subparts' | 'media' | 'objectives' | 'concepts' | 'answerKey' | 'rubric' | 'pointsPossible';
15
+ export declare const QUESTION_FIELDS: readonly QuestionField[];
16
+ export interface QuestionChoice {
17
+ id: string;
18
+ label: string;
19
+ }
20
+ export interface QuestionSubpart {
21
+ partKey: string;
22
+ prompt: string;
23
+ responseType?: Exclude<QuestionResponseType, 'multi-part'>;
24
+ pointsPossible?: number;
25
+ }
26
+ export interface QuestionMediaRef {
27
+ assetId: string;
28
+ role?: 'figure' | 'passage' | 'audio' | 'other';
29
+ alt?: string;
30
+ }
31
+ /** Atomic accepted answer(s). At least one member is required; never `{}`. */
32
+ export interface QuestionAnswerAtom {
33
+ correctChoiceIds?: string[];
34
+ acceptedAnswers?: string[];
35
+ numeric?: {
36
+ value: number;
37
+ tolerance?: number;
38
+ };
39
+ }
40
+ export interface QuestionAnswerKey extends QuestionAnswerAtom {
41
+ /** Per-subpart keys by `partKey`. */
42
+ parts?: Record<string, QuestionAnswerAtom>;
43
+ explanation?: string;
44
+ }
45
+ /** Everything an author states about one question revision. */
46
+ export interface QuestionContentInput {
47
+ prompt: string;
48
+ responseType: QuestionResponseType;
49
+ choices?: QuestionChoice[];
50
+ subparts?: QuestionSubpart[];
51
+ media?: QuestionMediaRef[];
52
+ /** Stable `LearningObjective` identity ids. */
53
+ objectiveIds?: string[];
54
+ conceptIds?: string[];
55
+ /** Omit (or null) when no key exists: a missing key stays missing. */
56
+ answerKey?: QuestionAnswerKey | null;
57
+ rubric?: QuestionRubric | null;
58
+ pointsPossible?: number | null;
59
+ /** Default for every present field without its own entry. */
60
+ provenance: QuestionProvenance;
61
+ fieldProvenance?: Partial<Record<QuestionField, QuestionProvenance>>;
62
+ }
63
+ export interface QuestionRevisionView {
64
+ id: string;
65
+ questionId: string;
66
+ parentRevisionId: string | null;
67
+ sequence: number;
68
+ prompt: string;
69
+ responseType: QuestionResponseType;
70
+ choices: QuestionChoice[];
71
+ subparts: QuestionSubpart[];
72
+ media: QuestionMediaRef[];
73
+ objectives: Array<{
74
+ objectiveId: string;
75
+ externalKey: string;
76
+ revisionId: string;
77
+ statement: string;
78
+ }>;
79
+ conceptIds: string[];
80
+ /** Null means no key was ever supplied; it is never an empty/zero key. */
81
+ answerKey: QuestionAnswerKey | null;
82
+ rubric: QuestionRubric | null;
83
+ pointsPossible: number | null;
84
+ provenance: QuestionProvenance;
85
+ fieldProvenance: Partial<Record<QuestionField, QuestionProvenance>>;
86
+ authorUserId: string;
87
+ delegatingGuardianUserId: string | null;
88
+ delegationId: string | null;
89
+ recordedAt: string;
90
+ }
91
+ /** Most question revision ids one `resolveQuestionRevisions` call accepts. */
92
+ export declare const MAX_RESOLVE_QUESTION_REVISIONS = 200;
93
+ /** Longest `promptSummary`, in characters. */
94
+ export declare const QUESTION_PROMPT_SUMMARY_LENGTH = 200;
95
+ /**
96
+ * A question revision as a host reference label. Never carries an answer key,
97
+ * rubric, choices, media or provenance.
98
+ */
99
+ export interface QuestionRevisionSummary {
100
+ revisionId: string;
101
+ questionId: string;
102
+ sequence: number;
103
+ responseType: QuestionResponseType;
104
+ /** Plain-text excerpt of the prompt: whitespace collapsed, at most 200 characters. */
105
+ promptSummary: string;
106
+ /** Stable objective external keys; present only when the revision links objectives. */
107
+ learningObjectiveKeys?: string[];
108
+ }
109
+ export interface ResolvedQuestionRevisions {
110
+ /** Found revisions, in the order of the first occurrence of each requested id. */
111
+ items: QuestionRevisionSummary[];
112
+ /** Requested ids with no revision in this tenant (foreign and unknown are alike). */
113
+ missing: string[];
114
+ }
115
+ export interface QuestionHeadView {
116
+ questionId: string;
117
+ /** The expected-head token for the next save. */
118
+ headRevisionId: string;
119
+ sequence: number;
120
+ }
121
+ export interface LearningObjectiveInput {
122
+ statement: string;
123
+ conceptIds?: string[];
124
+ subject?: string;
125
+ levelMin?: number;
126
+ levelMax?: number;
127
+ provenance?: QuestionProvenance;
128
+ }
129
+ export interface LearningObjectiveView {
130
+ id: string;
131
+ /** Stable key shared with consumers (for example hearthed.org#35). */
132
+ externalKey: string;
133
+ headRevisionId: string;
134
+ sequence: number;
135
+ statement: string;
136
+ conceptIds: string[];
137
+ subject: string;
138
+ levelMin: number;
139
+ levelMax: number;
140
+ provenance: QuestionProvenance;
141
+ }
142
+ /** One ordered question in a lesson revision. Order is array order. */
143
+ export interface LessonQuestionRefInput {
144
+ questionRevisionId: string;
145
+ section?: string;
146
+ column?: number;
147
+ /** Source page/region where known; normalized `rect` is x, y, width, height. */
148
+ anchor?: {
149
+ assetId?: string;
150
+ page?: number;
151
+ rect?: [number, number, number, number];
152
+ };
153
+ }
154
+ export type LessonLayoutParams = Record<string, string | number | boolean>;
155
+ /** Learner-facing item. Built from an allowlist, so keys and rubrics cannot leak. */
156
+ export interface LearnerQuestionItem {
157
+ ordinal: number;
158
+ questionId: string;
159
+ questionRevisionId: string;
160
+ section: string;
161
+ column: number;
162
+ anchor: LessonQuestionRefInput['anchor'] | null;
163
+ prompt: string;
164
+ responseType: QuestionResponseType;
165
+ choices: QuestionChoice[];
166
+ subparts: QuestionSubpart[];
167
+ media: QuestionMediaRef[];
168
+ pointsPossible: number | null;
169
+ }
170
+ export interface GuardianQuestionItem extends LearnerQuestionItem {
171
+ answerKey: QuestionAnswerKey | null;
172
+ rubric: QuestionRubric | null;
173
+ fieldProvenance: Partial<Record<QuestionField, QuestionProvenance>>;
174
+ }
175
+ interface WorksheetBundleBase {
176
+ /** Digest of ordered question revision ids and layout params. */
177
+ worksheetVersionId: string;
178
+ lessonRevisionId: string;
179
+ layoutParams: LessonLayoutParams;
180
+ }
181
+ export interface LearnerWorksheetBundle extends WorksheetBundleBase {
182
+ audience: 'learner';
183
+ items: LearnerQuestionItem[];
184
+ }
185
+ export interface GuardianWorksheetBundle extends WorksheetBundleBase {
186
+ audience: 'guardian';
187
+ items: GuardianQuestionItem[];
188
+ }
189
+ export type WorksheetBundle = LearnerWorksheetBundle | GuardianWorksheetBundle;
190
+ export type QuestionActor = CourseAuthoringActor;
191
+ /**
192
+ * Authoring/guardian read of one released lesson (`read-draft`): the full lesson
193
+ * revision (materials and provenance included) and the keyed worksheet bundle.
194
+ */
195
+ export type ReleasedLessonView = Readonly<{
196
+ releaseId: string;
197
+ courseId: string;
198
+ lessonKey: string;
199
+ lessonId: string;
200
+ sectionId: string;
201
+ lessonRevisionId: string;
202
+ revision: CourseLessonRevisionView;
203
+ worksheet: GuardianWorksheetBundle;
204
+ }>;
205
+ /**
206
+ * Learner-safe read of one effective lesson. Built from an allowlist: no key,
207
+ * rubric, provenance, material, source locator or licence detail. The body of a
208
+ * personal-use-copy lesson is withheld (empty, `bodyWithheld`).
209
+ */
210
+ export type LearnerLessonView = Readonly<{
211
+ enrollmentId: string;
212
+ releaseId: string;
213
+ lessonKey: string;
214
+ lessonId: string;
215
+ lessonRevisionId: string;
216
+ title: string;
217
+ body: string;
218
+ bodyWithheld: boolean;
219
+ lessonType: CourseLessonType;
220
+ completionRule: CourseLessonCompletion;
221
+ estimatedMinutes: number;
222
+ /** True when a started lesson stays on an older release than the current pin. */
223
+ pinnedToOlderRelease: boolean;
224
+ worksheet: LearnerWorksheetBundle;
225
+ }>;
226
+ export declare class QuestionNotFoundError extends CourseAuthoringError {
227
+ constructor();
228
+ }
229
+ export declare class LearningObjectiveNotFoundError extends CourseAuthoringError {
230
+ constructor();
231
+ }
232
+ export declare class LearningObjectiveKeyConflictError extends CourseAuthoringError {
233
+ constructor();
234
+ }
235
+ /** A lesson revision named a question revision that is missing or foreign. */
236
+ export declare class QuestionReferenceError extends CourseAuthoringError {
237
+ readonly references: readonly string[];
238
+ constructor(references: readonly string[]);
239
+ }
240
+ /** Audience of a generated printable: which artefact is produced, never authority. */
241
+ export type GeneratedPrintableAudience = 'learner' | 'guardian';
242
+ export declare const GENERATED_PRINTABLE_AUDIENCES: readonly GeneratedPrintableAudience[];
243
+ /** `LessonAsset` relationship per audience: the learner copy is the only signable one. */
244
+ export type GeneratedPrintableRelationship = 'printable' | 'answer-key';
245
+ export declare const GENERATED_PRINTABLE_RELATIONSHIPS: Readonly<Record<GeneratedPrintableAudience, GeneratedPrintableRelationship>>;
246
+ /** Most question items one generated printable may carry. */
247
+ export declare const MAX_PRINTABLE_ITEMS = 200;
248
+ /** Longest single text value (prompt, choice, key, ...) rendered, in characters. */
249
+ export declare const MAX_PRINTABLE_TEXT_LENGTH = 10000;
250
+ /** Most characters of all rendered text in one generated printable. */
251
+ export declare const MAX_PRINTABLE_TOTAL_TEXT = 400000;
252
+ /** Most pages one generated printable may span. */
253
+ export declare const MAX_PRINTABLE_PAGES = 150;
254
+ /** Attach the rendered worksheet of a released lesson to the durable print queue. */
255
+ export type AttachGeneratedPrintableRequest = CourseAuthoringActor & {
256
+ /** The materialised `lessons` row id of a released lesson. */
257
+ lessonId: string;
258
+ /** Must equal the worksheet version id of the lesson revision's questions and layout. */
259
+ worksheetVersionId: string;
260
+ audience: GeneratedPrintableAudience;
261
+ };
262
+ /** Closed result: never carries keys, answers or storage locators. */
263
+ export interface GeneratedPrintableResult {
264
+ lessonId: string;
265
+ worksheetVersionId: string;
266
+ audience: GeneratedPrintableAudience;
267
+ assetId: string;
268
+ relationship: GeneratedPrintableRelationship;
269
+ /** False when an earlier call already attached this printable. */
270
+ created: boolean;
271
+ }
272
+ /** The request's worksheet version is unknown or no longer the lesson's own. */
273
+ export declare class WorksheetVersionMismatchError extends CourseAuthoringError {
274
+ constructor();
275
+ }
276
+ /** No asset runtime/storage was configured for generated printables. */
277
+ export declare class PrintableStorageNotConfiguredError extends CourseAuthoringError {
278
+ constructor();
279
+ }
280
+ /** The acting guardian (or delegating guardian) has no profile to own the asset. */
281
+ export declare class PrintableOwnerError extends CourseAuthoringError {
282
+ constructor();
283
+ }
284
+ /**
285
+ * A rolled-back attach could not remove its fresh private PDF(s). Carries the
286
+ * fresh asset ids only, for operator reconciliation; the original cause is kept.
287
+ */
288
+ export declare class PrintableStorageCleanupError extends CourseAuthoringError {
289
+ readonly assetIds: readonly string[];
290
+ constructor(assetIds: readonly string[], cause: unknown);
291
+ }
292
+ //# sourceMappingURL=question-contracts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"question-contracts.d.ts","sourceRoot":"","sources":["../src/question-contracts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,151 @@
1
+ import { SmrtCollection, SmrtObject, type SmrtSaveOptions } from '@happyvertical/smrt-core';
2
+ import { type GeneratedPrintableAudience } from './question-contracts.js';
3
+ /** Stable learning-objective identity: survives wording changes, variants and themes. */
4
+ export declare class LearningObjective extends SmrtObject {
5
+ tenantId: string;
6
+ /** Stable coordination key (for example with hearthed.org#35); unique per tenant. */
7
+ externalKey: string;
8
+ createdByUserId: string;
9
+ requestKey: string;
10
+ recordedAt: Date;
11
+ constructor(options?: Record<string, unknown>);
12
+ delete(): Promise<void>;
13
+ save(options?: SmrtSaveOptions): Promise<this>;
14
+ }
15
+ export declare class LearningObjectiveCollection extends SmrtCollection<LearningObjective> {
16
+ static readonly _itemClass: typeof LearningObjective;
17
+ }
18
+ /** Append-only objective wording; the highest sequence is the head. */
19
+ export declare class LearningObjectiveRevision extends SmrtObject {
20
+ tenantId: string;
21
+ objectiveId: string;
22
+ parentRevisionId: string | null;
23
+ sequence: number;
24
+ statement: string;
25
+ conceptIdsJson: string;
26
+ subject: string;
27
+ levelMin: number;
28
+ levelMax: number;
29
+ provenance: string;
30
+ authorUserId: string;
31
+ delegatingGuardianUserId: string;
32
+ delegationId: string;
33
+ requestKey: string;
34
+ payloadDigest: string;
35
+ recordedAt: Date;
36
+ constructor(options?: Record<string, unknown>);
37
+ delete(): Promise<void>;
38
+ save(options?: SmrtSaveOptions): Promise<this>;
39
+ }
40
+ export declare class LearningObjectiveRevisionCollection extends SmrtCollection<LearningObjectiveRevision> {
41
+ static readonly _itemClass: typeof LearningObjectiveRevision;
42
+ }
43
+ /** Stable question identity. Content lives only in immutable revisions. */
44
+ export declare class Question extends SmrtObject {
45
+ tenantId: string;
46
+ /** Authored course this question was written for; reuse across courses is allowed. */
47
+ courseId: string | null;
48
+ createdByUserId: string;
49
+ requestKey: string;
50
+ recordedAt: Date;
51
+ constructor(options?: Record<string, unknown>);
52
+ delete(): Promise<void>;
53
+ save(options?: SmrtSaveOptions): Promise<this>;
54
+ }
55
+ export declare class QuestionCollection extends SmrtCollection<Question> {
56
+ static readonly _itemClass: typeof Question;
57
+ }
58
+ /**
59
+ * Immutable question snapshot. A missing answer key or rubric is stored as NULL
60
+ * and never as an empty object, zero or an inferred value.
61
+ */
62
+ export declare class QuestionRevision extends SmrtObject {
63
+ tenantId: string;
64
+ questionId: string;
65
+ parentRevisionId: string | null;
66
+ sequence: number;
67
+ prompt: string;
68
+ responseType: string;
69
+ choicesJson: string;
70
+ subpartsJson: string;
71
+ mediaJson: string;
72
+ objectiveIdsJson: string;
73
+ conceptIdsJson: string;
74
+ answerKeyJson: string | null;
75
+ rubricJson: string | null;
76
+ pointsPossible: number | null;
77
+ provenance: string;
78
+ fieldProvenanceJson: string;
79
+ authorUserId: string;
80
+ delegatingGuardianUserId: string;
81
+ delegationId: string;
82
+ requestKey: string;
83
+ payloadDigest: string;
84
+ recordedAt: Date;
85
+ constructor(options?: Record<string, unknown>);
86
+ delete(): Promise<void>;
87
+ save(options?: SmrtSaveOptions): Promise<this>;
88
+ }
89
+ export declare class QuestionRevisionCollection extends SmrtCollection<QuestionRevision> {
90
+ static readonly _itemClass: typeof QuestionRevision;
91
+ }
92
+ /**
93
+ * Append-only learner response to one exact question revision. A correction is a
94
+ * new row naming its predecessor; a response never rewrites question content.
95
+ */
96
+ export declare class QuestionResponse extends SmrtObject {
97
+ tenantId: string;
98
+ learnerId: string;
99
+ enrollmentId: string;
100
+ questionRevisionId: string;
101
+ lessonRevisionId: string | null;
102
+ /** The worksheet render the learner saw, for scan matching. */
103
+ worksheetVersionId: string;
104
+ submissionId: string | null;
105
+ previousResponseId: string | null;
106
+ /** Groups an attempt and its corrections. */
107
+ episodeId: string;
108
+ completionMode: string;
109
+ assistance: string;
110
+ responseJson: string;
111
+ /** 1-based attempt (episode) number per learner and question revision. */
112
+ attemptNumber: number;
113
+ actorUserId: string;
114
+ requestKey: string;
115
+ /** Digest of the request that wrote this row; empty for rows written directly. */
116
+ payloadDigest: string;
117
+ recordedAt: Date;
118
+ constructor(options?: Record<string, unknown>);
119
+ delete(): Promise<void>;
120
+ save(options?: SmrtSaveOptions): Promise<this>;
121
+ }
122
+ export declare class QuestionResponseCollection extends SmrtCollection<QuestionResponse> {
123
+ static readonly _itemClass: typeof QuestionResponse;
124
+ }
125
+ /**
126
+ * Append-only record that a released lesson's worksheet render was attached to
127
+ * the print queue: one row per tenant, lesson, worksheet version and audience.
128
+ * The unique index is what makes concurrent first attaches converge. It holds
129
+ * ids only (never keys or locators); the PDF is a private education-owned asset.
130
+ */
131
+ export declare class GeneratedPrintable extends SmrtObject {
132
+ tenantId: string;
133
+ lessonId: string;
134
+ worksheetVersionId: string;
135
+ /** `learner` (relationship `printable`) or `guardian` (relationship `answer-key`). */
136
+ audience: GeneratedPrintableAudience;
137
+ assetId: string;
138
+ /** Provenance only: checked in `save()`, not a database constraint, so the table depends on lessons and assets alone. */
139
+ lessonRevisionId: string;
140
+ generatedByUserId: string;
141
+ delegatingGuardianUserId: string;
142
+ delegationId: string;
143
+ recordedAt: Date;
144
+ constructor(options?: Record<string, unknown>);
145
+ delete(): Promise<void>;
146
+ save(options?: SmrtSaveOptions): Promise<this>;
147
+ }
148
+ export declare class GeneratedPrintableCollection extends SmrtCollection<GeneratedPrintable> {
149
+ static readonly _itemClass: typeof GeneratedPrintable;
150
+ }
151
+ //# sourceMappingURL=question-models.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"question-models.d.ts","sourceRoot":"","sources":["../src/question-models.ts"],"names":[],"mappings":"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"}