@playcademy/vite-plugin 0.2.24-beta.2 → 0.2.24-beta.4
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/index.js +214 -20
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -25335,7 +25335,7 @@ var package_default;
|
|
|
25335
25335
|
var init_package = __esm(() => {
|
|
25336
25336
|
package_default = {
|
|
25337
25337
|
name: "@playcademy/sandbox",
|
|
25338
|
-
version: "0.3.17-beta.
|
|
25338
|
+
version: "0.3.17-beta.7",
|
|
25339
25339
|
description: "Local development server for Playcademy game development",
|
|
25340
25340
|
type: "module",
|
|
25341
25341
|
exports: {
|
|
@@ -35611,7 +35611,7 @@ var init_table6 = __esm(() => {
|
|
|
35611
35611
|
init_drizzle_orm();
|
|
35612
35612
|
init_pg_core();
|
|
35613
35613
|
init_table5();
|
|
35614
|
-
userRoleEnum = pgEnum("user_role", ["admin", "player", "developer"]);
|
|
35614
|
+
userRoleEnum = pgEnum("user_role", ["admin", "player", "developer", "teacher"]);
|
|
35615
35615
|
developerStatusEnum = pgEnum("developer_status", ["none", "pending", "approved"]);
|
|
35616
35616
|
users = pgTable("user", {
|
|
35617
35617
|
id: text("id").primaryKey().$defaultFn(() => crypto.randomUUID()),
|
|
@@ -50583,10 +50583,13 @@ var init_game_service = __esm(() => {
|
|
|
50583
50583
|
});
|
|
50584
50584
|
}
|
|
50585
50585
|
async listManageable(user) {
|
|
50586
|
-
|
|
50586
|
+
const seesAllGames = user.role === "admin" || user.role === "teacher";
|
|
50587
|
+
if (!seesAllGames) {
|
|
50588
|
+
this.validateDeveloperStatus(user);
|
|
50589
|
+
}
|
|
50587
50590
|
const db2 = this.deps.db;
|
|
50588
50591
|
return db2.query.games.findMany({
|
|
50589
|
-
where:
|
|
50592
|
+
where: seesAllGames ? undefined : eq(games.developerId, user.id),
|
|
50590
50593
|
orderBy: [desc(games.createdAt)]
|
|
50591
50594
|
});
|
|
50592
50595
|
}
|
|
@@ -50990,6 +50993,19 @@ var init_game_service = __esm(() => {
|
|
|
50990
50993
|
throw new NotFoundError("Game", gameId);
|
|
50991
50994
|
}
|
|
50992
50995
|
}
|
|
50996
|
+
async validateGameManagementAccess(user, gameId) {
|
|
50997
|
+
if (user.role === "admin" || user.role === "teacher") {
|
|
50998
|
+
const gameExists = await this.deps.db.query.games.findFirst({
|
|
50999
|
+
where: eq(games.id, gameId),
|
|
51000
|
+
columns: { id: true }
|
|
51001
|
+
});
|
|
51002
|
+
if (!gameExists) {
|
|
51003
|
+
throw new NotFoundError("Game", gameId);
|
|
51004
|
+
}
|
|
51005
|
+
return;
|
|
51006
|
+
}
|
|
51007
|
+
return this.validateDeveloperAccess(user, gameId);
|
|
51008
|
+
}
|
|
50993
51009
|
async validateDeveloperAccessBySlug(user, slug) {
|
|
50994
51010
|
this.validateDeveloperStatus(user);
|
|
50995
51011
|
const db2 = this.deps.db;
|
|
@@ -51058,6 +51074,7 @@ function createGameServices(deps) {
|
|
|
51058
51074
|
validators: {
|
|
51059
51075
|
validateDeveloperAccessBySlug: (user, slug) => game.validateDeveloperAccessBySlug(user, slug),
|
|
51060
51076
|
validateDeveloperAccess: (user, gameId) => game.validateDeveloperAccess(user, gameId),
|
|
51077
|
+
validateGameManagementAccess: (user, gameId) => game.validateGameManagementAccess(user, gameId),
|
|
51061
51078
|
validateOwnership: (user, gameId) => game.validateOwnership(user, gameId)
|
|
51062
51079
|
}
|
|
51063
51080
|
};
|
|
@@ -54499,9 +54516,13 @@ class TimebackAdminService {
|
|
|
54499
54516
|
});
|
|
54500
54517
|
});
|
|
54501
54518
|
}
|
|
54502
|
-
async resolveAdminMutationContext(gameId, courseId, user, studentId) {
|
|
54519
|
+
async resolveAdminMutationContext(gameId, courseId, user, studentId, accessLevel = "developer") {
|
|
54503
54520
|
const client = this.requireClient();
|
|
54504
|
-
|
|
54521
|
+
if (accessLevel === "dashboard") {
|
|
54522
|
+
await this.deps.validateGameManagementAccess(user, gameId);
|
|
54523
|
+
} else {
|
|
54524
|
+
await this.deps.validateDeveloperAccess(user, gameId);
|
|
54525
|
+
}
|
|
54505
54526
|
const integration = await this.deps.db.query.gameTimebackIntegrations.findFirst({
|
|
54506
54527
|
where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId))
|
|
54507
54528
|
});
|
|
@@ -54761,7 +54782,7 @@ class TimebackAdminService {
|
|
|
54761
54782
|
}
|
|
54762
54783
|
async listStudentsForCourse(gameId, courseId, user) {
|
|
54763
54784
|
const client = this.requireClient();
|
|
54764
|
-
await this.deps.
|
|
54785
|
+
await this.deps.validateGameManagementAccess(user, gameId);
|
|
54765
54786
|
const integration = await this.deps.db.query.gameTimebackIntegrations.findFirst({
|
|
54766
54787
|
where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId))
|
|
54767
54788
|
});
|
|
@@ -54799,7 +54820,7 @@ class TimebackAdminService {
|
|
|
54799
54820
|
}
|
|
54800
54821
|
async getStudentOverview(gameId, studentId, user, courseId) {
|
|
54801
54822
|
const client = this.requireClient();
|
|
54802
|
-
await this.deps.
|
|
54823
|
+
await this.deps.validateGameManagementAccess(user, gameId);
|
|
54803
54824
|
const integrations = await this.deps.db.query.gameTimebackIntegrations.findMany({
|
|
54804
54825
|
where: courseId ? and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId)) : eq(gameTimebackIntegrations.gameId, gameId)
|
|
54805
54826
|
});
|
|
@@ -54853,7 +54874,7 @@ class TimebackAdminService {
|
|
|
54853
54874
|
const client = this.requireClient();
|
|
54854
54875
|
const safeLimit = Math.max(1, Math.min(limit, TimebackAdminService.MAX_STUDENT_ACTIVITY_LIMIT));
|
|
54855
54876
|
const safeOffset = Math.max(0, Math.min(offset, TimebackAdminService.MAX_STUDENT_ACTIVITY_OFFSET));
|
|
54856
|
-
await this.deps.
|
|
54877
|
+
await this.deps.validateGameManagementAccess(user, gameId);
|
|
54857
54878
|
const [integration, sensorUrl] = await Promise.all([
|
|
54858
54879
|
this.deps.db.query.gameTimebackIntegrations.findFirst({
|
|
54859
54880
|
where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId))
|
|
@@ -54917,7 +54938,7 @@ class TimebackAdminService {
|
|
|
54917
54938
|
return { status: "ok" };
|
|
54918
54939
|
}
|
|
54919
54940
|
async toggleCourseCompletion(data, user) {
|
|
54920
|
-
const { client, sensorUrl, appName, actor } = await this.resolveAdminMutationContext(data.gameId, data.courseId, user, data.studentId);
|
|
54941
|
+
const { client, sensorUrl, appName, actor } = await this.resolveAdminMutationContext(data.gameId, data.courseId, user, data.studentId, "dashboard");
|
|
54921
54942
|
const historyClient = client;
|
|
54922
54943
|
const ids = deriveSourcedIds(data.courseId);
|
|
54923
54944
|
const lineItemId = `${ids.course}-mastery-completion-assessment`;
|
|
@@ -55010,6 +55031,77 @@ class TimebackAdminService {
|
|
|
55010
55031
|
}
|
|
55011
55032
|
return { status: "ok" };
|
|
55012
55033
|
}
|
|
55034
|
+
async searchStudentsForEnrollment(gameId, courseId, query, user) {
|
|
55035
|
+
const client = this.requireClient();
|
|
55036
|
+
await this.deps.validateGameManagementAccess(user, gameId);
|
|
55037
|
+
const integration = await this.deps.db.query.gameTimebackIntegrations.findFirst({
|
|
55038
|
+
where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId))
|
|
55039
|
+
});
|
|
55040
|
+
if (!integration) {
|
|
55041
|
+
throw new NotFoundError("Timeback integration", `${gameId}:${courseId}`);
|
|
55042
|
+
}
|
|
55043
|
+
const trimmedQuery = query.trim();
|
|
55044
|
+
if (trimmedQuery.length < 2) {
|
|
55045
|
+
return { students: [] };
|
|
55046
|
+
}
|
|
55047
|
+
const filterParts = [
|
|
55048
|
+
`givenName~'${escapeFilterValue(trimmedQuery)}'`,
|
|
55049
|
+
`familyName~'${escapeFilterValue(trimmedQuery)}'`,
|
|
55050
|
+
`email~'${escapeFilterValue(trimmedQuery)}'`
|
|
55051
|
+
];
|
|
55052
|
+
const filter = filterParts.join(" OR ");
|
|
55053
|
+
const params = new URLSearchParams({ filter, limit: "25" });
|
|
55054
|
+
const endpoint = `/ims/oneroster/rostering/v1p2/users?${params}`;
|
|
55055
|
+
let allUsers = [];
|
|
55056
|
+
try {
|
|
55057
|
+
const response = await client["request"](endpoint, "GET");
|
|
55058
|
+
allUsers = response.users || [];
|
|
55059
|
+
} catch (error) {
|
|
55060
|
+
logger16.warn("Failed to search OneRoster users", {
|
|
55061
|
+
query: trimmedQuery,
|
|
55062
|
+
error: error instanceof Error ? error.message : String(error)
|
|
55063
|
+
});
|
|
55064
|
+
return { students: [] };
|
|
55065
|
+
}
|
|
55066
|
+
const roster = await client.oneroster.enrollments.listByCourse(courseId, {
|
|
55067
|
+
role: "student",
|
|
55068
|
+
includeUsers: false
|
|
55069
|
+
});
|
|
55070
|
+
const enrolledStudentIds = new Set(roster.map((entry) => entry.enrollment.user.sourcedId));
|
|
55071
|
+
const students = allUsers.filter((entry) => Boolean(entry.sourcedId) && entry.roles?.some((role) => role.role === "student") === true).map((entry) => ({
|
|
55072
|
+
studentId: entry.sourcedId,
|
|
55073
|
+
name: `${entry.givenName || ""} ${entry.familyName || ""}`.trim() || entry.sourcedId,
|
|
55074
|
+
email: entry.email || null,
|
|
55075
|
+
alreadyEnrolled: enrolledStudentIds.has(entry.sourcedId)
|
|
55076
|
+
}));
|
|
55077
|
+
return { students };
|
|
55078
|
+
}
|
|
55079
|
+
async enrollStudent(data, user) {
|
|
55080
|
+
const client = this.requireClient();
|
|
55081
|
+
await this.deps.validateGameManagementAccess(user, data.gameId);
|
|
55082
|
+
const integration = await this.deps.db.query.gameTimebackIntegrations.findFirst({
|
|
55083
|
+
where: and(eq(gameTimebackIntegrations.gameId, data.gameId), eq(gameTimebackIntegrations.courseId, data.courseId))
|
|
55084
|
+
});
|
|
55085
|
+
if (!integration) {
|
|
55086
|
+
throw new NotFoundError("Timeback integration", `${data.gameId}:${data.courseId}`);
|
|
55087
|
+
}
|
|
55088
|
+
await client.edubridge.enrollments.enroll(data.studentId, data.courseId, {
|
|
55089
|
+
role: "student"
|
|
55090
|
+
});
|
|
55091
|
+
return { status: "ok" };
|
|
55092
|
+
}
|
|
55093
|
+
async unenrollStudent(data, user) {
|
|
55094
|
+
const client = this.requireClient();
|
|
55095
|
+
await this.deps.validateGameManagementAccess(user, data.gameId);
|
|
55096
|
+
const integration = await this.deps.db.query.gameTimebackIntegrations.findFirst({
|
|
55097
|
+
where: and(eq(gameTimebackIntegrations.gameId, data.gameId), eq(gameTimebackIntegrations.courseId, data.courseId))
|
|
55098
|
+
});
|
|
55099
|
+
if (!integration) {
|
|
55100
|
+
throw new NotFoundError("Timeback integration", `${data.gameId}:${data.courseId}`);
|
|
55101
|
+
}
|
|
55102
|
+
await client.edubridge.enrollments.unenroll(data.studentId, data.courseId);
|
|
55103
|
+
return { status: "ok" };
|
|
55104
|
+
}
|
|
55013
55105
|
async getCompletionStatus(client, courseId, studentId) {
|
|
55014
55106
|
const ids = deriveSourcedIds(courseId);
|
|
55015
55107
|
const lineItemId = `${ids.course}-mastery-completion-assessment`;
|
|
@@ -55460,7 +55552,7 @@ class TimebackService {
|
|
|
55460
55552
|
return { integrations, ...verbose && verboseData.length > 0 && { verbose: verboseData } };
|
|
55461
55553
|
}
|
|
55462
55554
|
async getIntegrations(gameId, user) {
|
|
55463
|
-
await this.deps.
|
|
55555
|
+
await this.deps.validateGameManagementAccess(user, gameId);
|
|
55464
55556
|
const rows = await this.deps.db.query.gameTimebackIntegrations.findMany({
|
|
55465
55557
|
where: eq(gameTimebackIntegrations.gameId, gameId)
|
|
55466
55558
|
});
|
|
@@ -55712,6 +55804,7 @@ function createPlatformServices(deps) {
|
|
|
55712
55804
|
alerts,
|
|
55713
55805
|
validateDeveloperAccessBySlug,
|
|
55714
55806
|
validateDeveloperAccess,
|
|
55807
|
+
validateGameManagementAccess,
|
|
55715
55808
|
validateOwnership
|
|
55716
55809
|
} = deps;
|
|
55717
55810
|
const bucket = new BucketService({
|
|
@@ -55746,12 +55839,14 @@ function createPlatformServices(deps) {
|
|
|
55746
55839
|
const timeback2 = new TimebackService({
|
|
55747
55840
|
db: db2,
|
|
55748
55841
|
timeback: timebackClient,
|
|
55749
|
-
validateDeveloperAccess
|
|
55842
|
+
validateDeveloperAccess,
|
|
55843
|
+
validateGameManagementAccess
|
|
55750
55844
|
});
|
|
55751
55845
|
const timebackAdmin = new TimebackAdminService({
|
|
55752
55846
|
db: db2,
|
|
55753
55847
|
timeback: timebackClient,
|
|
55754
|
-
validateDeveloperAccess
|
|
55848
|
+
validateDeveloperAccess,
|
|
55849
|
+
validateGameManagementAccess
|
|
55755
55850
|
});
|
|
55756
55851
|
return {
|
|
55757
55852
|
bucket,
|
|
@@ -58845,6 +58940,34 @@ function createEduBridgeNamespace(client) {
|
|
|
58845
58940
|
listByUser: async (userId) => {
|
|
58846
58941
|
const response = await client["request"](`/edubridge/enrollments/user/${userId}`, "GET");
|
|
58847
58942
|
return response.data;
|
|
58943
|
+
},
|
|
58944
|
+
enroll: async (userId, courseId, options) => {
|
|
58945
|
+
const segments = [userId, courseId];
|
|
58946
|
+
if (options?.schoolId) {
|
|
58947
|
+
segments.push(options.schoolId);
|
|
58948
|
+
}
|
|
58949
|
+
const body2 = {};
|
|
58950
|
+
if (options?.role) {
|
|
58951
|
+
body2.role = options.role;
|
|
58952
|
+
}
|
|
58953
|
+
if (options?.sourcedId) {
|
|
58954
|
+
body2.sourcedId = options.sourcedId;
|
|
58955
|
+
}
|
|
58956
|
+
if (options?.beginDate) {
|
|
58957
|
+
body2.beginDate = options.beginDate;
|
|
58958
|
+
}
|
|
58959
|
+
if (options?.metadata) {
|
|
58960
|
+
body2.metadata = options.metadata;
|
|
58961
|
+
}
|
|
58962
|
+
const response = await client["request"](`/edubridge/enrollments/enroll/${segments.join("/")}`, "POST", body2);
|
|
58963
|
+
return response.data;
|
|
58964
|
+
},
|
|
58965
|
+
unenroll: async (userId, courseId, options) => {
|
|
58966
|
+
const segments = [userId, courseId];
|
|
58967
|
+
if (options?.schoolId) {
|
|
58968
|
+
segments.push(options.schoolId);
|
|
58969
|
+
}
|
|
58970
|
+
await client["request"](`/edubridge/enrollments/unenroll/${segments.join("/")}`, "DELETE");
|
|
58848
58971
|
}
|
|
58849
58972
|
};
|
|
58850
58973
|
const analytics = {
|
|
@@ -59020,6 +59143,10 @@ function createOneRosterNamespace(client) {
|
|
|
59020
59143
|
logTimebackError("list course roster", error, { courseSourcedId });
|
|
59021
59144
|
throw error;
|
|
59022
59145
|
}
|
|
59146
|
+
},
|
|
59147
|
+
create: async (data) => client["request"](ONEROSTER_ENDPOINTS4.enrollments, "POST", { enrollment: data }),
|
|
59148
|
+
delete: async (sourcedId) => {
|
|
59149
|
+
await client["request"](`${ONEROSTER_ENDPOINTS4.enrollments}/${sourcedId}`, "DELETE");
|
|
59023
59150
|
}
|
|
59024
59151
|
},
|
|
59025
59152
|
organizations: {
|
|
@@ -120050,6 +120177,8 @@ var GrantTimebackXpRequestSchema;
|
|
|
120050
120177
|
var AdjustTimebackTimeRequestSchema;
|
|
120051
120178
|
var AdjustTimebackMasteryRequestSchema;
|
|
120052
120179
|
var ToggleCourseCompletionRequestSchema;
|
|
120180
|
+
var EnrollStudentRequestSchema;
|
|
120181
|
+
var UnenrollStudentRequestSchema;
|
|
120053
120182
|
var init_schemas11 = __esm(() => {
|
|
120054
120183
|
init_esm();
|
|
120055
120184
|
TIMEBACK_GRADES = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
|
|
@@ -120192,6 +120321,16 @@ var init_schemas11 = __esm(() => {
|
|
|
120192
120321
|
studentId: exports_external.string().min(1),
|
|
120193
120322
|
action: exports_external.enum(["complete", "resume"])
|
|
120194
120323
|
});
|
|
120324
|
+
EnrollStudentRequestSchema = exports_external.object({
|
|
120325
|
+
gameId: exports_external.string().uuid(),
|
|
120326
|
+
courseId: exports_external.string().min(1),
|
|
120327
|
+
studentId: exports_external.string().min(1)
|
|
120328
|
+
});
|
|
120329
|
+
UnenrollStudentRequestSchema = exports_external.object({
|
|
120330
|
+
gameId: exports_external.string().uuid(),
|
|
120331
|
+
courseId: exports_external.string().min(1),
|
|
120332
|
+
studentId: exports_external.string().min(1)
|
|
120333
|
+
});
|
|
120195
120334
|
});
|
|
120196
120335
|
var init_schemas_index = __esm(() => {
|
|
120197
120336
|
init_schemas();
|
|
@@ -120210,6 +120349,9 @@ function isAuthenticated(ctx) {
|
|
|
120210
120349
|
return ctx.user != null;
|
|
120211
120350
|
}
|
|
120212
120351
|
var init_types9 = () => {};
|
|
120352
|
+
function hasGameManagementAccess(user) {
|
|
120353
|
+
return user.role === "admin" || user.role === "teacher" || user.role === "developer" && user.developerStatus === "approved";
|
|
120354
|
+
}
|
|
120213
120355
|
function requireAuth(handler) {
|
|
120214
120356
|
return async (ctx) => {
|
|
120215
120357
|
if (!isAuthenticated(ctx)) {
|
|
@@ -120253,6 +120395,17 @@ function requireDeveloper(handler) {
|
|
|
120253
120395
|
return handler(ctx);
|
|
120254
120396
|
};
|
|
120255
120397
|
}
|
|
120398
|
+
function requireGameManagementAccess(handler) {
|
|
120399
|
+
return async (ctx) => {
|
|
120400
|
+
if (!isAuthenticated(ctx)) {
|
|
120401
|
+
throw ApiError.unauthorized("Valid session or bearer token required");
|
|
120402
|
+
}
|
|
120403
|
+
if (!hasGameManagementAccess(ctx.user)) {
|
|
120404
|
+
throw ApiError.forbidden("Game management access required");
|
|
120405
|
+
}
|
|
120406
|
+
return handler(ctx);
|
|
120407
|
+
};
|
|
120408
|
+
}
|
|
120256
120409
|
var init_auth_util = __esm(() => {
|
|
120257
120410
|
init_errors();
|
|
120258
120411
|
init_types9();
|
|
@@ -122386,6 +122539,9 @@ var grantXp;
|
|
|
122386
122539
|
var adjustTime;
|
|
122387
122540
|
var adjustMastery;
|
|
122388
122541
|
var toggleCompletion;
|
|
122542
|
+
var searchStudents;
|
|
122543
|
+
var enrollStudent;
|
|
122544
|
+
var unenrollStudent;
|
|
122389
122545
|
var timeback2;
|
|
122390
122546
|
var init_timeback_controller = __esm(() => {
|
|
122391
122547
|
init_esm();
|
|
@@ -122476,7 +122632,7 @@ var init_timeback_controller = __esm(() => {
|
|
|
122476
122632
|
});
|
|
122477
122633
|
return ctx.services.timeback.setupIntegration(body2.gameId, body2, ctx.user);
|
|
122478
122634
|
});
|
|
122479
|
-
getIntegrations =
|
|
122635
|
+
getIntegrations = requireGameManagementAccess(async (ctx) => {
|
|
122480
122636
|
const gameId = ctx.params.gameId;
|
|
122481
122637
|
if (!gameId) {
|
|
122482
122638
|
throw ApiError.badRequest("Missing gameId");
|
|
@@ -122601,7 +122757,7 @@ var init_timeback_controller = __esm(() => {
|
|
|
122601
122757
|
include
|
|
122602
122758
|
});
|
|
122603
122759
|
});
|
|
122604
|
-
getRoster =
|
|
122760
|
+
getRoster = requireGameManagementAccess(async (ctx) => {
|
|
122605
122761
|
const gameId = ctx.params.gameId;
|
|
122606
122762
|
const courseId = ctx.params.courseId;
|
|
122607
122763
|
if (!gameId || !courseId) {
|
|
@@ -122614,7 +122770,7 @@ var init_timeback_controller = __esm(() => {
|
|
|
122614
122770
|
});
|
|
122615
122771
|
return ctx.services.timebackAdmin.listStudentsForCourse(gameId, courseId, ctx.user);
|
|
122616
122772
|
});
|
|
122617
|
-
getStudentOverview =
|
|
122773
|
+
getStudentOverview = requireGameManagementAccess(async (ctx) => {
|
|
122618
122774
|
const timebackId = ctx.params.timebackId;
|
|
122619
122775
|
const gameId = ctx.url.searchParams.get("gameId") || undefined;
|
|
122620
122776
|
const courseId = ctx.url.searchParams.get("courseId") || undefined;
|
|
@@ -122629,7 +122785,7 @@ var init_timeback_controller = __esm(() => {
|
|
|
122629
122785
|
});
|
|
122630
122786
|
return ctx.services.timebackAdmin.getStudentOverview(gameId, timebackId, ctx.user, courseId);
|
|
122631
122787
|
});
|
|
122632
|
-
getStudentActivity =
|
|
122788
|
+
getStudentActivity = requireGameManagementAccess(async (ctx) => {
|
|
122633
122789
|
const timebackId = ctx.params.timebackId;
|
|
122634
122790
|
const courseId = ctx.params.courseId;
|
|
122635
122791
|
const gameId = ctx.url.searchParams.get("gameId") || undefined;
|
|
@@ -122692,7 +122848,7 @@ var init_timeback_controller = __esm(() => {
|
|
|
122692
122848
|
});
|
|
122693
122849
|
return ctx.services.timebackAdmin.adjustMasteredUnits(body2, ctx.user);
|
|
122694
122850
|
});
|
|
122695
|
-
toggleCompletion =
|
|
122851
|
+
toggleCompletion = requireGameManagementAccess(async (ctx) => {
|
|
122696
122852
|
const body2 = await parseRequestBody(ctx.request, ToggleCourseCompletionRequestSchema);
|
|
122697
122853
|
logger63.debug("Toggling course completion", {
|
|
122698
122854
|
requesterId: ctx.user.id,
|
|
@@ -122703,6 +122859,41 @@ var init_timeback_controller = __esm(() => {
|
|
|
122703
122859
|
});
|
|
122704
122860
|
return ctx.services.timebackAdmin.toggleCourseCompletion(body2, ctx.user);
|
|
122705
122861
|
});
|
|
122862
|
+
searchStudents = requireGameManagementAccess(async (ctx) => {
|
|
122863
|
+
const gameId = ctx.params.gameId;
|
|
122864
|
+
const courseId = ctx.params.courseId;
|
|
122865
|
+
const query = ctx.url.searchParams.get("q") || "";
|
|
122866
|
+
if (!gameId || !courseId) {
|
|
122867
|
+
throw ApiError.badRequest("Missing gameId or courseId parameter");
|
|
122868
|
+
}
|
|
122869
|
+
logger63.debug("Searching students for enrollment", {
|
|
122870
|
+
requesterId: ctx.user.id,
|
|
122871
|
+
gameId,
|
|
122872
|
+
courseId,
|
|
122873
|
+
query
|
|
122874
|
+
});
|
|
122875
|
+
return ctx.services.timebackAdmin.searchStudentsForEnrollment(gameId, courseId, query, ctx.user);
|
|
122876
|
+
});
|
|
122877
|
+
enrollStudent = requireGameManagementAccess(async (ctx) => {
|
|
122878
|
+
const body2 = await parseRequestBody(ctx.request, EnrollStudentRequestSchema);
|
|
122879
|
+
logger63.debug("Enrolling student", {
|
|
122880
|
+
requesterId: ctx.user.id,
|
|
122881
|
+
gameId: body2.gameId,
|
|
122882
|
+
courseId: body2.courseId,
|
|
122883
|
+
studentId: body2.studentId
|
|
122884
|
+
});
|
|
122885
|
+
return ctx.services.timebackAdmin.enrollStudent(body2, ctx.user);
|
|
122886
|
+
});
|
|
122887
|
+
unenrollStudent = requireGameManagementAccess(async (ctx) => {
|
|
122888
|
+
const body2 = await parseRequestBody(ctx.request, UnenrollStudentRequestSchema);
|
|
122889
|
+
logger63.debug("Unenrolling student", {
|
|
122890
|
+
requesterId: ctx.user.id,
|
|
122891
|
+
gameId: body2.gameId,
|
|
122892
|
+
courseId: body2.courseId,
|
|
122893
|
+
studentId: body2.studentId
|
|
122894
|
+
});
|
|
122895
|
+
return ctx.services.timebackAdmin.unenrollStudent(body2, ctx.user);
|
|
122896
|
+
});
|
|
122706
122897
|
timeback2 = {
|
|
122707
122898
|
getTodayXp,
|
|
122708
122899
|
getTotalXp,
|
|
@@ -122724,7 +122915,10 @@ var init_timeback_controller = __esm(() => {
|
|
|
122724
122915
|
grantXp,
|
|
122725
122916
|
adjustTime,
|
|
122726
122917
|
adjustMastery,
|
|
122727
|
-
toggleCompletion
|
|
122918
|
+
toggleCompletion,
|
|
122919
|
+
searchStudents,
|
|
122920
|
+
enrollStudent,
|
|
122921
|
+
unenrollStudent
|
|
122728
122922
|
};
|
|
122729
122923
|
});
|
|
122730
122924
|
var logger64;
|
|
@@ -125286,7 +125480,7 @@ var import_picocolors12 = __toESM(require_picocolors(), 1);
|
|
|
125286
125480
|
// package.json
|
|
125287
125481
|
var package_default2 = {
|
|
125288
125482
|
name: "@playcademy/vite-plugin",
|
|
125289
|
-
version: "0.2.24-beta.
|
|
125483
|
+
version: "0.2.24-beta.4",
|
|
125290
125484
|
type: "module",
|
|
125291
125485
|
exports: {
|
|
125292
125486
|
".": {
|