playcademy 0.31.0 → 0.31.1-beta.2

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.
package/dist/bucket.js CHANGED
@@ -42,7 +42,7 @@ var GAME_API_ROUTES_DIRECTORY = `${GAME_SERVER_ROOT_DIRECTORY}/api`;
42
42
  // ../better-auth/package.json
43
43
  var package_default = {
44
44
  name: "@playcademy/better-auth",
45
- version: "0.0.23",
45
+ version: "0.0.24-beta.2",
46
46
  type: "module",
47
47
  exports: {
48
48
  "./server": {
package/dist/cli.js CHANGED
@@ -1208,7 +1208,7 @@ var SAMPLE_BUCKET_FILENAME = "bucket.ts";
1208
1208
  // ../better-auth/package.json
1209
1209
  var package_default = {
1210
1210
  name: "@playcademy/better-auth",
1211
- version: "0.0.23",
1211
+ version: "0.0.24-beta.2",
1212
1212
  type: "module",
1213
1213
  exports: {
1214
1214
  "./server": {
@@ -3045,7 +3045,7 @@ import { existsSync as existsSync11, mkdirSync as mkdirSync5, readFileSync as re
3045
3045
  import { join as join12 } from "node:path";
3046
3046
 
3047
3047
  // src/version.ts
3048
- var cliVersion = false ? "0.0.0-dev" : "0.31.0";
3048
+ var cliVersion = false ? "0.0.0-dev" : "0.31.1-beta.2";
3049
3049
 
3050
3050
  // src/lib/init/database.ts
3051
3051
  var drizzleConfigTemplate = loadTemplateString("database/drizzle-config.ts");
package/dist/constants.js CHANGED
@@ -21,7 +21,7 @@ var SAMPLE_BUCKET_FILENAME = "bucket.ts";
21
21
  // ../better-auth/package.json
22
22
  var package_default = {
23
23
  name: "@playcademy/better-auth",
24
- version: "0.0.23",
24
+ version: "0.0.24-beta.2",
25
25
  type: "module",
26
26
  exports: {
27
27
  "./server": {
package/dist/db.js CHANGED
@@ -2333,7 +2333,7 @@ var GAME_API_ROUTES_DIRECTORY = `${GAME_SERVER_ROOT_DIRECTORY}/api`;
2333
2333
  // ../better-auth/package.json
2334
2334
  var package_default = {
2335
2335
  name: "@playcademy/better-auth",
2336
- version: "0.0.23",
2336
+ version: "0.0.24-beta.2",
2337
2337
  type: "module",
2338
2338
  exports: {
2339
2339
  "./server": {
package/dist/index.js CHANGED
@@ -2345,7 +2345,7 @@ var SAMPLE_BUCKET_FILENAME = "bucket.ts";
2345
2345
  // ../better-auth/package.json
2346
2346
  var package_default = {
2347
2347
  name: "@playcademy/better-auth",
2348
- version: "0.0.23",
2348
+ version: "0.0.24-beta.2",
2349
2349
  type: "module",
2350
2350
  exports: {
2351
2351
  "./server": {
@@ -6486,7 +6486,7 @@ import { existsSync as existsSync11, mkdirSync as mkdirSync2, readFileSync as re
6486
6486
  import { join as join12 } from "node:path";
6487
6487
 
6488
6488
  // src/version.ts
6489
- var cliVersion = false ? "0.0.0-dev" : "0.31.0";
6489
+ var cliVersion = false ? "0.0.0-dev" : "0.31.1-beta.2";
6490
6490
 
6491
6491
  // src/lib/init/database.ts
6492
6492
  var drizzleConfigTemplate = loadTemplateString("database/drizzle-config.ts");
@@ -22993,6 +22993,7 @@ var StartAssessmentBodySchema = external_exports.discriminatedUnion("purpose", [
22993
22993
  }),
22994
22994
  StartAssessmentBaseSchema.extend({
22995
22995
  purpose: external_exports.literal("review"),
22996
+ requireBothQuestions: external_exports.boolean().optional(),
22996
22997
  standards: external_exports.array(AssessmentStandardRefSchema2).min(1).max(TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.standards),
22997
22998
  candidateItemsPerStandard: external_exports.number().int().positive().max(TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.candidateItemsPerStandard).optional()
22998
22999
  }),
@@ -1,7 +1,7 @@
1
1
  {
2
- "cliVersion": "0.31.0",
3
- "sdkVersion": "0.19.0",
4
- "runtimeBuildId": "2837149d70ac",
5
- "inputFingerprint": "2837149d70acaaca9eff5567aae156188827aa8ac0e9977e1ecbfdd299868e16",
2
+ "cliVersion": "0.31.1-beta.2",
3
+ "sdkVersion": "0.19.1-beta.3",
4
+ "runtimeBuildId": "4673549da4d8",
5
+ "inputFingerprint": "4673549da4d81b760c8c8270835a45d570cb44eef97ca9052ba75da4876260e5",
6
6
  "entry": "index.js"
7
7
  }
@@ -10201,6 +10201,21 @@ function assessmentFlowForPurpose(purpose) {
10201
10201
  function assessmentFlowForSelection(selection) {
10202
10202
  return selection.kind === "platform-routed-diagnostic" ? "platform-routed-item-submit" : assessmentFlowForPurpose(selection.purpose);
10203
10203
  }
10204
+ function assessmentItemOutcomes(submissions, standardForItem) {
10205
+ return submissions.map((submission) => {
10206
+ const standard = standardForItem(submission.itemIdentifier);
10207
+ if (!standard) {
10208
+ throw new Error(`Missing outcome standard for item ${submission.itemIdentifier}`);
10209
+ }
10210
+ return {
10211
+ itemIdentifier: submission.itemIdentifier,
10212
+ standard: { ...standard },
10213
+ answered: submission.answered,
10214
+ score: { ...submission.score },
10215
+ isCorrect: submission.isCorrect
10216
+ };
10217
+ });
10218
+ }
10204
10219
  function isObject(value) {
10205
10220
  return typeof value === "object" && value !== null;
10206
10221
  }
@@ -11362,7 +11377,7 @@ function completeAssessmentTranscript(input) {
11362
11377
  }
11363
11378
  if (input.terminal) {
11364
11379
  const count = itemSubmissions.length;
11365
- const conventionalComplete = assessmentFlowForPurpose(input.purpose) === "item-submit" ? count > 0 : count === input.itemCount;
11380
+ const conventionalComplete = assessmentFlowForPurpose(input.purpose) === "item-submit" ? count > 0 : count === input.itemCount && (input.purpose !== "mastery" || count > 0);
11366
11381
  const complete = state ? state.status === "ready-to-complete" && count > 0 : conventionalComplete;
11367
11382
  if (!complete) {
11368
11383
  throw new AssessmentTranscriptError("A complete administered transcript is required for submission", count);
@@ -11370,9 +11385,6 @@ function completeAssessmentTranscript(input) {
11370
11385
  }
11371
11386
  return { itemSubmissions, ledger, state };
11372
11387
  }
11373
- function administeredItemIdentifiers(itemSubmissions) {
11374
- return new Set(itemSubmissions.map((submission) => submission.itemIdentifier));
11375
- }
11376
11388
  function selectAssessmentCourseCandidate(candidates, subjectSpecified) {
11377
11389
  if (candidates.length === 0) {
11378
11390
  return { outcome: "none" };
@@ -11622,6 +11634,33 @@ function scorePlatformAssessmentItem(item, responses) {
11622
11634
  isCorrect: verdicts.length > 0 && verdicts.every(Boolean)
11623
11635
  };
11624
11636
  }
11637
+ function reportReviewRequiredPairUnavailable(review, administeredItemIdentifiers2, report) {
11638
+ if (!review.requireBothQuestions) {
11639
+ return;
11640
+ }
11641
+ const administered = new Set(administeredItemIdentifiers2);
11642
+ const failures = [];
11643
+ for (const standard of review.standards) {
11644
+ const key = assessmentStandardRefKey(standard);
11645
+ const selected = new Set(review.selections.filter((selection) => assessmentStandardRefKey(selection.standard) === key).map((selection) => selection.itemIdentifier));
11646
+ const administeredCount = [...selected].filter((identifier) => administered.has(identifier)).length;
11647
+ if (selected.size < 2 || administeredCount === 1) {
11648
+ failures.push({
11649
+ standard,
11650
+ reason: selected.size < 2 ? "selection_shortage" : "not_administered",
11651
+ requiredCount: 2,
11652
+ selectedCount: selected.size,
11653
+ administeredCount
11654
+ });
11655
+ }
11656
+ }
11657
+ if (failures.length > 0) {
11658
+ try {
11659
+ report({ code: "REVIEW_REQUIRED_PAIR_UNAVAILABLE", failures });
11660
+ } catch {
11661
+ }
11662
+ }
11663
+ }
11625
11664
  function reviewStandardFieldsWithinLimits(input) {
11626
11665
  return input.framework.trim().length <= TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.standardFieldLength && input.identifier.trim().length <= TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.standardFieldLength;
11627
11666
  }
@@ -11661,7 +11700,11 @@ function normalizeReviewRequest(request2) {
11661
11700
  if (standards.length === 0) {
11662
11701
  throw new Error("At least one review standard is required");
11663
11702
  }
11664
- return { standards, candidateItemsPerStandard };
11703
+ return {
11704
+ standards,
11705
+ candidateItemsPerStandard,
11706
+ ...request2.requireBothQuestions ? { requireBothQuestions: true } : {}
11707
+ };
11665
11708
  }
11666
11709
  function reviewRequestFingerprint(request2, policy) {
11667
11710
  const normalized = normalizeReviewRequest(request2);
@@ -11671,6 +11714,7 @@ function reviewRequestFingerprint(request2, policy) {
11671
11714
  version: policy.version
11672
11715
  },
11673
11716
  candidateItemsPerStandard: normalized.candidateItemsPerStandard,
11717
+ ...normalized.requireBothQuestions ? { requireBothQuestions: true } : {},
11674
11718
  standardKeys: normalized.standards.map(assessmentStandardRefKey)
11675
11719
  });
11676
11720
  }
@@ -12659,6 +12703,7 @@ var init_assessment_runtime2 = __esm({
12659
12703
  }),
12660
12704
  StartAssessmentBaseSchema.extend({
12661
12705
  purpose: external_exports.literal("review"),
12706
+ requireBothQuestions: external_exports.boolean().optional(),
12662
12707
  standards: external_exports.array(AssessmentStandardRefSchema2).min(1).max(TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.standards),
12663
12708
  candidateItemsPerStandard: external_exports.number().int().positive().max(TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.candidateItemsPerStandard).optional()
12664
12709
  }),
@@ -12960,6 +13005,7 @@ var init_local_assessment_runtime = __esm({
12960
13005
  purpose: "review",
12961
13006
  standards: [...request2.standards],
12962
13007
  candidateItemsPerStandard: request2.candidateItemsPerStandard,
13008
+ ...request2.requireBothQuestions ? { requireBothQuestions: true } : {},
12963
13009
  selections: [...selected.selections],
12964
13010
  fulfillment: selected.fulfillment
12965
13011
  },
@@ -13204,16 +13250,25 @@ var init_local_assessment_runtime = __esm({
13204
13250
  return this.finalizeDiagnostic(attempt, input.submissionId);
13205
13251
  }
13206
13252
  if (attempt.selection.kind === "standards-review") {
13207
- attempt.itemOutcomes = this.calculateReviewItemOutcomes(
13208
- attempt,
13209
- this.testForAttempt(attempt)
13210
- );
13253
+ attempt.itemOutcomes = this.calculateReviewItemOutcomes(attempt);
13211
13254
  }
13212
13255
  attempt.score = aggregateFixtureItemScores(graded.scores);
13213
13256
  attempt.submissionId = input.submissionId;
13214
13257
  attempt.inProgress = ASSESSMENT_ATTEMPT_AWAITING_AWARD.inProgress;
13215
13258
  attempt.scoreStatus = ASSESSMENT_ATTEMPT_AWAITING_AWARD.scoreStatus;
13216
13259
  attempt.scoreDate = attempt.updatedAt;
13260
+ if (attempt.selection.kind === "standards-review") {
13261
+ reportReviewRequiredPairUnavailable(
13262
+ attempt.selection,
13263
+ attempt.itemSubmissions.map((item) => item.itemIdentifier),
13264
+ (error) => console.error({
13265
+ event: "assessment.review_required_pair_unavailable",
13266
+ attemptId,
13267
+ submissionId: input.submissionId,
13268
+ ...error
13269
+ })
13270
+ );
13271
+ }
13217
13272
  return this.submittedResult(attempt);
13218
13273
  }
13219
13274
  finalizeDiagnostic(attempt, submissionId) {
@@ -13609,10 +13664,18 @@ var init_local_assessment_runtime = __esm({
13609
13664
  ...result,
13610
13665
  purpose: "review",
13611
13666
  itemOutcomes: structuredClone(
13612
- attempt.itemOutcomes ?? this.calculateReviewItemOutcomes(attempt, this.testForAttempt(attempt))
13667
+ attempt.itemOutcomes ?? this.calculateReviewItemOutcomes(attempt)
13613
13668
  )
13614
13669
  };
13615
13670
  }
13671
+ if (attempt.selection.kind === "standard-quiz") {
13672
+ const { standard } = attempt.selection;
13673
+ return {
13674
+ ...result,
13675
+ purpose: "mastery",
13676
+ itemOutcomes: assessmentItemOutcomes(attempt.itemSubmissions, () => standard)
13677
+ };
13678
+ }
13616
13679
  return { ...result, purpose: attempt.selection.purpose };
13617
13680
  }
13618
13681
  submittedDiagnosticResult(attempt, tracks) {
@@ -13642,32 +13705,20 @@ var init_local_assessment_runtime = __esm({
13642
13705
  const diagnostic = this.requireDiagnosticAttempt(attempt);
13643
13706
  return projectDiagnosticRoutingSnapshot(diagnostic.routingRevision, state);
13644
13707
  }
13645
- calculateReviewItemOutcomes(attempt, test) {
13708
+ calculateReviewItemOutcomes(attempt) {
13646
13709
  if (attempt.selection.kind !== "standards-review") {
13647
13710
  return [];
13648
13711
  }
13649
- const scoringByItem = new Map(
13650
- scoreAssessmentFixtureItems(test, attempt.responses).map((result) => [
13651
- result.itemIdentifier,
13652
- result
13712
+ const standards = new Map(
13713
+ attempt.selection.selections.map((selection) => [
13714
+ selection.itemIdentifier,
13715
+ selection.standard
13653
13716
  ])
13654
13717
  );
13655
- const administered = administeredItemIdentifiers(attempt.itemSubmissions);
13656
- return attempt.selection.selections.filter((selection) => administered.has(selection.itemIdentifier)).map((selection) => {
13657
- const scoring = scoringByItem.get(selection.itemIdentifier);
13658
- if (!scoring) {
13659
- throw new Error(
13660
- `Selected review item ${selection.itemIdentifier} is absent from the projected assessment.`
13661
- );
13662
- }
13663
- return {
13664
- itemIdentifier: selection.itemIdentifier,
13665
- standard: structuredClone(selection.standard),
13666
- answered: Object.keys(attempt.responses[selection.itemIdentifier] ?? {}).length > 0,
13667
- score: structuredClone(scoring.score),
13668
- isCorrect: scoring.isCorrect
13669
- };
13670
- });
13718
+ return assessmentItemOutcomes(
13719
+ attempt.itemSubmissions,
13720
+ (identifier) => standards.get(identifier)
13721
+ );
13671
13722
  }
13672
13723
  scoreForAttempt(attempt) {
13673
13724
  return attempt.score ?? scoreAssessmentFixture(this.testForAttempt(attempt), attempt.responses);
@@ -14202,9 +14253,9 @@ var init_list = __esm({
14202
14253
  // ../edge-play/src/game/lib/metadata.ts
14203
14254
  function getRuntimeMetadata() {
14204
14255
  return {
14205
- cliVersion: true ? "0.31.0" : "0.0.0-dev",
14206
- sdkVersion: true ? "0.19.0" : "0.0.0-dev",
14207
- buildId: true ? "2837149d70ac" : "dev-source"
14256
+ cliVersion: true ? "0.31.1-beta.2" : "0.0.0-dev",
14257
+ sdkVersion: true ? "0.19.1-beta.3" : "0.0.0-dev",
14258
+ buildId: true ? "4673549da4d8" : "dev-source"
14208
14259
  };
14209
14260
  }
14210
14261
  var init_metadata = __esm({
@@ -1,7 +1,7 @@
1
1
  {
2
- "cliVersion": "0.31.0",
3
- "sdkVersion": "0.19.0",
4
- "runtimeBuildId": "2837149d70ac",
5
- "inputFingerprint": "2837149d70acaaca9eff5567aae156188827aa8ac0e9977e1ecbfdd299868e16",
2
+ "cliVersion": "0.31.1-beta.2",
3
+ "sdkVersion": "0.19.1-beta.3",
4
+ "runtimeBuildId": "4673549da4d8",
5
+ "inputFingerprint": "4673549da4d81b760c8c8270835a45d570cb44eef97ca9052ba75da4876260e5",
6
6
  "entry": "index.js"
7
7
  }
package/dist/utils.js CHANGED
@@ -396,7 +396,7 @@ var DASHBOARD_API_ROUTES_DIRECTORY = "api";
396
396
  // ../better-auth/package.json
397
397
  var package_default = {
398
398
  name: "@playcademy/better-auth",
399
- version: "0.0.23",
399
+ version: "0.0.24-beta.2",
400
400
  type: "module",
401
401
  exports: {
402
402
  "./server": {
@@ -2849,7 +2849,7 @@ import { existsSync as existsSync9, mkdirSync as mkdirSync2, writeFileSync as wr
2849
2849
  import { dirname as dirname4, join as join13 } from "node:path";
2850
2850
 
2851
2851
  // src/version.ts
2852
- var cliVersion = false ? "0.0.0-dev" : "0.31.0";
2852
+ var cliVersion = false ? "0.0.0-dev" : "0.31.1-beta.2";
2853
2853
 
2854
2854
  // src/lib/build/binary-resource.ts
2855
2855
  function writeFileTree(baseDir, files) {
@@ -15761,6 +15761,7 @@ var StartAssessmentBodySchema = external_exports.discriminatedUnion("purpose", [
15761
15761
  }),
15762
15762
  StartAssessmentBaseSchema.extend({
15763
15763
  purpose: external_exports.literal("review"),
15764
+ requireBothQuestions: external_exports.boolean().optional(),
15764
15765
  standards: external_exports.array(AssessmentStandardRefSchema2).min(1).max(TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.standards),
15765
15766
  candidateItemsPerStandard: external_exports.number().int().positive().max(TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.candidateItemsPerStandard).optional()
15766
15767
  }),
package/dist/version.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { createRequire as __pcCreateRequire } from 'node:module'; const require = __pcCreateRequire(import.meta.url);
2
2
 
3
3
  // src/version.ts
4
- var cliVersion = false ? "0.0.0-dev" : "0.31.0";
4
+ var cliVersion = false ? "0.0.0-dev" : "0.31.1-beta.2";
5
5
  export {
6
6
  cliVersion
7
7
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "playcademy",
3
- "version": "0.31.0",
3
+ "version": "0.31.1-beta.2",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -55,7 +55,7 @@
55
55
  },
56
56
  "dependencies": {
57
57
  "@inquirer/prompts": "^7.8.6",
58
- "@playcademy/sdk": "0.19.0",
58
+ "@playcademy/sdk": "0.19.1-beta.3",
59
59
  "chokidar": "^4.0.3",
60
60
  "colorette": "^2.0.20",
61
61
  "commander": "^14.0.1",