@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,9 @@
1
+ import { type GuardianWorksheetBundle, type LearnerWorksheetBundle } from './question-contracts.js';
2
+ /**
3
+ * Learner copy. It takes the keyless learner bundle, whose type has no key,
4
+ * rubric or provenance members, so a key cannot reach the PDF.
5
+ */
6
+ export declare function renderLearnerWorksheetPdf(bundle: LearnerWorksheetBundle, title: string): Promise<Uint8Array>;
7
+ /** Guardian copy: the same layout plus answer keys, explanations and rubric summaries. */
8
+ export declare function renderGuardianWorksheetPdf(bundle: GuardianWorksheetBundle, title: string): Promise<Uint8Array>;
9
+ //# sourceMappingURL=question-printable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"question-printable.d.ts","sourceRoot":"","sources":["../src/question-printable.ts"],"names":[],"mappings":"AAQA,OAAO,EAEL,KAAK,uBAAuB,EAE5B,KAAK,sBAAsB,EAO5B,MAAM,yBAAyB,CAAC;AAkUjC;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,sBAAsB,EAC9B,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,UAAU,CAAC,CAMrB;AAED,0FAA0F;AAC1F,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,uBAAuB,EAC/B,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,UAAU,CAAC,CAMrB"}
@@ -0,0 +1,20 @@
1
+ import type { GuardianWorksheetBundle, LearnerWorksheetBundle, LessonLayoutParams, LessonQuestionRefInput, QuestionRevisionView } from './question-contracts.js';
2
+ export declare const canonical: (value: unknown) => string;
3
+ /**
4
+ * Deterministic id of one worksheet layout: the ordered question revisions with
5
+ * their placement plus the layout params. Printable and online renders of the
6
+ * same inputs share it, so a later scan can be matched to the exact revisions.
7
+ */
8
+ export declare function worksheetVersionId(refs: readonly LessonQuestionRefInput[], layoutParams?: LessonLayoutParams): string;
9
+ export interface WorksheetRenderInput {
10
+ lessonRevisionId: string;
11
+ refs: readonly LessonQuestionRefInput[];
12
+ layoutParams?: LessonLayoutParams;
13
+ /** The pinned revisions, by id. Every ref must resolve. */
14
+ revisions: ReadonlyMap<string, QuestionRevisionView>;
15
+ }
16
+ /** Render input for learners (printable or online); answer keys are excluded by type. */
17
+ export declare function buildLearnerWorksheet(input: WorksheetRenderInput): LearnerWorksheetBundle;
18
+ /** Guardian/author bundle: the same items plus keys, rubrics and provenance. */
19
+ export declare function buildGuardianWorksheet(input: WorksheetRenderInput): GuardianWorksheetBundle;
20
+ //# sourceMappingURL=question-render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"question-render.d.ts","sourceRoot":"","sources":["../src/question-render.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,uBAAuB,EAEvB,sBAAsB,EACtB,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACrB,MAAM,yBAAyB,CAAC;AAEjC,eAAO,MAAM,SAAS,GAAI,OAAO,OAAO,KAAG,MAOxC,CAAC;AAEJ;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,SAAS,sBAAsB,EAAE,EACvC,YAAY,GAAE,kBAAuB,GACpC,MAAM,CAWR;AAwBD,MAAM,WAAW,oBAAoB;IACnC,gBAAgB,EAAE,MAAM,CAAC;IACzB,IAAI,EAAE,SAAS,sBAAsB,EAAE,CAAC;IACxC,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC,2DAA2D;IAC3D,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;CACtD;AAUD,yFAAyF;AACzF,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,oBAAoB,GAC1B,sBAAsB,CASxB;AAED,gFAAgF;AAChF,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,oBAAoB,GAC1B,uBAAuB,CAgBzB"}
@@ -0,0 +1,54 @@
1
+ import { CourseAuthoringError } from './course-authoring-contracts.js';
2
+ import type { GuardianWorksheetBundle, LearnerWorksheetBundle, QuestionAssistance, QuestionCompletionMode } from './question-contracts.js';
3
+ /**
4
+ * The learner's answer to one question. Only these members are accepted so a
5
+ * response can never smuggle other data; `choiceIds` must name the revision's
6
+ * choices and `parts` keys its subparts.
7
+ */
8
+ export interface QuestionResponseContent {
9
+ text?: string;
10
+ numeric?: number;
11
+ choiceIds?: string[];
12
+ parts?: Record<string, {
13
+ text?: string;
14
+ numeric?: number;
15
+ choiceIds?: string[];
16
+ }>;
17
+ }
18
+ /** Data-only view of one append-only response row. It carries no key or rubric. */
19
+ export interface QuestionResponseView {
20
+ id: string;
21
+ learnerId: string;
22
+ enrollmentId: string;
23
+ lessonRevisionId: string | null;
24
+ questionRevisionId: string;
25
+ worksheetVersionId: string;
26
+ /** Groups one attempt and its corrections. */
27
+ episodeId: string;
28
+ attemptNumber: number;
29
+ /** The response this row corrects, or null for a new attempt. */
30
+ previousResponseId: string | null;
31
+ completionMode: QuestionCompletionMode;
32
+ assistance: QuestionAssistance;
33
+ response: QuestionResponseContent;
34
+ actorUserId: string;
35
+ /** True when the author is not the learner (a guardian correction). */
36
+ byGuardian: boolean;
37
+ recordedAt: string;
38
+ }
39
+ /** Learner reads get the keyless bundle; guardians get the keyed one. */
40
+ export interface LessonQuestionResponses {
41
+ worksheet: LearnerWorksheetBundle | GuardianWorksheetBundle;
42
+ responses: QuestionResponseView[];
43
+ }
44
+ export declare class QuestionResponseValidationError extends CourseAuthoringError {
45
+ constructor(message: string);
46
+ }
47
+ /** The question revision is not in the enrollment's effective lesson set. */
48
+ export declare class QuestionResponseScopeError extends CourseAuthoringError {
49
+ constructor();
50
+ }
51
+ export declare class QuestionResponseNotFoundError extends CourseAuthoringError {
52
+ constructor();
53
+ }
54
+ //# sourceMappingURL=question-response-contracts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"question-response-contracts.d.ts","sourceRoot":"","sources":["../src/question-response-contracts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,KAAK,EACV,uBAAuB,EACvB,sBAAsB,EACtB,kBAAkB,EAClB,sBAAsB,EACvB,MAAM,yBAAyB,CAAC;AAEjC;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CACZ,MAAM,EACN;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAC1D,CAAC;CACH;AAED,mFAAmF;AACnF,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,iEAAiE;IACjE,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,cAAc,EAAE,sBAAsB,CAAC;IACvC,UAAU,EAAE,kBAAkB,CAAC;IAC/B,QAAQ,EAAE,uBAAuB,CAAC;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,uEAAuE;IACvE,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,yEAAyE;AACzE,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,sBAAsB,GAAG,uBAAuB,CAAC;IAC5D,SAAS,EAAE,oBAAoB,EAAE,CAAC;CACnC;AAED,qBAAa,+BAAgC,SAAQ,oBAAoB;gBAC3D,OAAO,EAAE,MAAM;CAG5B;AACD,6EAA6E;AAC7E,qBAAa,0BAA2B,SAAQ,oBAAoB;;CAOnE;AACD,qBAAa,6BAA8B,SAAQ,oBAAoB;;CAItE"}
@@ -0,0 +1,63 @@
1
+ import type { DatabaseInterface } from '@happyvertical/sql';
2
+ import { type LearnerRequest, LearnerService } from './learner-service.js';
3
+ import { type LearnerLessonView, type QuestionAssistance } from './question-contracts.js';
4
+ import { type LessonQuestionResponses, type QuestionResponseContent, type QuestionResponseView } from './question-response-contracts.js';
5
+ type LessonRequest = LearnerRequest & {
6
+ enrollmentId: string;
7
+ lessonId: string;
8
+ };
9
+ export type RecordQuestionResponseRequest = LessonRequest & {
10
+ questionRevisionId: string;
11
+ requestKey: string;
12
+ response: QuestionResponseContent;
13
+ /** Learners record online responses; printable/interactive need their own path. */
14
+ completionMode?: 'online';
15
+ assistance?: QuestionAssistance;
16
+ /** Names the response this one corrects; omit for a new attempt. */
17
+ correctsResponseId?: string;
18
+ };
19
+ export type GuardianCorrectionRequest = LessonRequest & {
20
+ questionRevisionId: string;
21
+ requestKey: string;
22
+ correctsResponseId: string;
23
+ /** Omit to record assistance only: the corrected response's answer is kept. */
24
+ response?: QuestionResponseContent;
25
+ assistance?: QuestionAssistance;
26
+ };
27
+ /**
28
+ * Guarded write path for learner question responses (SMRT #4515). Extends the
29
+ * learner boundary: the actor must be the learner (own enrollment) to record,
30
+ * or the authorized guardian to review/correct; the question revision must be in
31
+ * the enrollment's effective lesson set. Rows are append-only; question
32
+ * revisions are never written.
33
+ */
34
+ export declare class QuestionResponseService extends LearnerService {
35
+ protected createTransactionService(db: DatabaseInterface): this;
36
+ /** The learner records an online attempt, or corrects their own response. */
37
+ recordResponse(request: RecordQuestionResponseRequest): Promise<QuestionResponseView>;
38
+ /** A guardian appends a correction and/or assistance note; never overwrites. */
39
+ recordGuardianCorrection(request: GuardianCorrectionRequest): Promise<QuestionResponseView>;
40
+ /**
41
+ * The lesson's questions and recorded responses. The audience follows the
42
+ * actor: the learner gets the keyless bundle, an authorized guardian the
43
+ * keyed one. It is never a request choice.
44
+ */
45
+ readLessonResponses(request: LessonRequest): Promise<LessonQuestionResponses>;
46
+ /**
47
+ * One effective lesson for rendering, learner-safe. The audience is the same
48
+ * for the learner and an authorized guardian (`education.learner.read`, own or
49
+ * guardian relationship): the keyless bundle and an allowlisted lesson, never
50
+ * answer keys, rubrics, provenance, materials, source locators or the body of
51
+ * a personal-use-copy lesson. Keys are read through `QuestionAuthoringService.
52
+ * readReleasedLesson` (`read-draft`). A lesson outside the enrollment's
53
+ * effective set is a `QuestionResponseScopeError`.
54
+ */
55
+ readReleasedLesson(request: LessonRequest): Promise<LearnerLessonView>;
56
+ private view;
57
+ /** Effective lesson row to its immutable lesson revision's ordered question refs. */
58
+ private lessonQuestions;
59
+ private revisionRow;
60
+ private write;
61
+ }
62
+ export {};
63
+ //# sourceMappingURL=question-response-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"question-response-service.d.ts","sourceRoot":"","sources":["../src/question-response-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAI5D,OAAO,EAEL,KAAK,cAAc,EACnB,cAAc,EACf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,KAAK,iBAAiB,EAItB,KAAK,kBAAkB,EAOxB,MAAM,yBAAyB,CAAC;AAWjC,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,uBAAuB,EAI5B,KAAK,oBAAoB,EAC1B,MAAM,kCAAkC,CAAC;AAqH1C,KAAK,aAAa,GAAG,cAAc,GAAG;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AACF,MAAM,MAAM,6BAA6B,GAAG,aAAa,GAAG;IAC1D,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,uBAAuB,CAAC;IAClC,mFAAmF;IACnF,cAAc,CAAC,EAAE,QAAQ,CAAC;IAC1B,UAAU,CAAC,EAAE,kBAAkB,CAAC;IAChC,oEAAoE;IACpE,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B,CAAC;AACF,MAAM,MAAM,yBAAyB,GAAG,aAAa,GAAG;IACtD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,uBAAuB,CAAC;IACnC,UAAU,CAAC,EAAE,kBAAkB,CAAC;CACjC,CAAC;AAEF;;;;;;GAMG;AACH,qBAAa,uBAAwB,SAAQ,cAAc;cACtC,wBAAwB,CAAC,EAAE,EAAE,iBAAiB,GAAG,IAAI;IAQxE,6EAA6E;IACvE,cAAc,CAClB,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,oBAAoB,CAAC;IAIhC,gFAAgF;IAC1E,wBAAwB,CAC5B,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,oBAAoB,CAAC;IAIhC;;;;OAIG;IACG,mBAAmB,CACvB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,uBAAuB,CAAC;IA2DnC;;;;;;;;OAQG;IACG,kBAAkB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,iBAAiB,CAAC;IA0C5E,OAAO,CAAC,IAAI;IAuBZ,qFAAqF;YACvE,eAAe;YA6Cf,WAAW;YAYX,KAAK;CA0IpB"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Pure rubric/answer-key shapes shared by the question models, the authoring
3
+ * service and `Grade`. Importing nothing keeps `submissions.ts` cycle-free.
4
+ */
5
+ export interface QuestionRubricCriterion {
6
+ id: string;
7
+ label: string;
8
+ /** Positive maximum points for this criterion. */
9
+ maxPoints: number;
10
+ }
11
+ export interface QuestionRubric {
12
+ criteria: QuestionRubricCriterion[];
13
+ }
14
+ /** Returns a normalized rubric or throws `Error` naming the first problem. */
15
+ export declare function parseQuestionRubric(value: unknown): QuestionRubric;
16
+ /**
17
+ * Validates `Grade.rubricResults` against the exact revision's rubric. A value
18
+ * is a finite number or `{ points: number }`, never above the criterion's
19
+ * maximum. Empty results stay empty (unscored is never zero); results against a
20
+ * revision without a rubric are rejected.
21
+ */
22
+ export declare function validateRubricResults(rubricJson: string | null | undefined, results: Record<string, unknown>): void;
23
+ //# sourceMappingURL=question-rubric.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"question-rubric.d.ts","sourceRoot":"","sources":["../src/question-rubric.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,SAAS,EAAE,MAAM,CAAC;CACnB;AACD,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,uBAAuB,EAAE,CAAC;CACrC;AAID,8EAA8E;AAC9E,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,CAuBlE;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACrC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,IAAI,CAqBN"}