@playcademy/sandbox 0.3.8 → 0.3.9
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/cli.js +483 -344
- package/dist/server.js +483 -344
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -1223,7 +1223,7 @@ var package_default;
|
|
|
1223
1223
|
var init_package = __esm(() => {
|
|
1224
1224
|
package_default = {
|
|
1225
1225
|
name: "@playcademy/sandbox",
|
|
1226
|
-
version: "0.3.
|
|
1226
|
+
version: "0.3.9",
|
|
1227
1227
|
description: "Local development server for Playcademy game development",
|
|
1228
1228
|
type: "module",
|
|
1229
1229
|
exports: {
|
|
@@ -14979,6 +14979,62 @@ var init_level_service = __esm(() => {
|
|
|
14979
14979
|
logger15 = log.scope("LevelService");
|
|
14980
14980
|
});
|
|
14981
14981
|
|
|
14982
|
+
// ../api-core/src/services/logs.service.ts
|
|
14983
|
+
class LogsService {
|
|
14984
|
+
ctx;
|
|
14985
|
+
constructor(ctx) {
|
|
14986
|
+
this.ctx = ctx;
|
|
14987
|
+
}
|
|
14988
|
+
async generateToken(user, slug2, environment) {
|
|
14989
|
+
const db2 = this.ctx.db;
|
|
14990
|
+
if (user.role === "admin") {
|
|
14991
|
+
const game = await db2.query.games.findFirst({
|
|
14992
|
+
where: eq(games.slug, slug2),
|
|
14993
|
+
columns: { id: true }
|
|
14994
|
+
});
|
|
14995
|
+
if (!game) {
|
|
14996
|
+
throw new NotFoundError("Game", slug2);
|
|
14997
|
+
}
|
|
14998
|
+
logger16.info("Admin accessing game logs", { adminId: user.id, slug: slug2, environment });
|
|
14999
|
+
} else {
|
|
15000
|
+
const isApprovedDev = user.developerStatus === "approved";
|
|
15001
|
+
if (!isApprovedDev) {
|
|
15002
|
+
logger16.warn("Unapproved developer attempted log access", { userId: user.id, slug: slug2 });
|
|
15003
|
+
throw new AccessDeniedError("Must be an approved developer");
|
|
15004
|
+
}
|
|
15005
|
+
const game = await db2.query.games.findFirst({
|
|
15006
|
+
where: and(eq(games.slug, slug2), eq(games.developerId, user.id)),
|
|
15007
|
+
columns: { id: true }
|
|
15008
|
+
});
|
|
15009
|
+
if (!game) {
|
|
15010
|
+
logger16.warn("Developer attempted access to unowned game logs", {
|
|
15011
|
+
userId: user.id,
|
|
15012
|
+
slug: slug2
|
|
15013
|
+
});
|
|
15014
|
+
throw new NotFoundError("Game", slug2);
|
|
15015
|
+
}
|
|
15016
|
+
}
|
|
15017
|
+
const isProduction3 = environment === "production";
|
|
15018
|
+
const workerId = getDeploymentId(slug2, isProduction3);
|
|
15019
|
+
const token = await this.ctx.providers.auth.mintLogStreamToken(user.id, workerId);
|
|
15020
|
+
logger16.debug("Generated log stream token", {
|
|
15021
|
+
userId: user.id,
|
|
15022
|
+
slug: slug2,
|
|
15023
|
+
workerId
|
|
15024
|
+
});
|
|
15025
|
+
return { token, workerId };
|
|
15026
|
+
}
|
|
15027
|
+
}
|
|
15028
|
+
var logger16;
|
|
15029
|
+
var init_logs_service = __esm(() => {
|
|
15030
|
+
init_drizzle_orm();
|
|
15031
|
+
init_tables_index();
|
|
15032
|
+
init_src2();
|
|
15033
|
+
init_errors();
|
|
15034
|
+
init_deployment_util();
|
|
15035
|
+
logger16 = log.scope("LogsService");
|
|
15036
|
+
});
|
|
15037
|
+
|
|
14982
15038
|
// ../../node_modules/aws-jwt-verify/dist/esm/error.js
|
|
14983
15039
|
var JwtBaseError, FailedAssertionError, JwtParseError, ParameterValidationError, JwtInvalidSignatureError, JwtInvalidSignatureAlgorithmError, JwtInvalidClaimError, JwtInvalidIssuerError, JwtInvalidAudienceError, JwtInvalidScopeError, JwtExpiredError, JwtNotBeforeError, CognitoJwtInvalidGroupError, CognitoJwtInvalidTokenUseError, CognitoJwtInvalidClientIdError, JwksValidationError, JwkValidationError, JwtWithoutValidKidError, KidNotFoundInJwksError, WaitPeriodNotYetEndedJwkError, JwksNotAvailableInCacheError, JwkInvalidUseError, JwkInvalidKtyError, FetchError, NonRetryableFetchError;
|
|
14984
15040
|
var init_error = __esm(() => {
|
|
@@ -15988,7 +16044,7 @@ class LtiService {
|
|
|
15988
16044
|
}
|
|
15989
16045
|
getConfig() {
|
|
15990
16046
|
if (!this.ctx.config.lti) {
|
|
15991
|
-
|
|
16047
|
+
logger17.error("LTI configuration not available");
|
|
15992
16048
|
throw new ValidationError("LTI is not configured");
|
|
15993
16049
|
}
|
|
15994
16050
|
return this.ctx.config.lti;
|
|
@@ -16019,14 +16075,14 @@ class LtiService {
|
|
|
16019
16075
|
try {
|
|
16020
16076
|
const verifier = this.getVerifier();
|
|
16021
16077
|
const claims = await verifier.verify(idToken);
|
|
16022
|
-
|
|
16078
|
+
logger17.info("Verified token", {
|
|
16023
16079
|
sub: claims.sub,
|
|
16024
16080
|
email: claims.email,
|
|
16025
16081
|
roles: claims["https://purl.imsglobal.org/spec/lti/claim/roles"]
|
|
16026
16082
|
});
|
|
16027
16083
|
return claims;
|
|
16028
16084
|
} catch (error) {
|
|
16029
|
-
|
|
16085
|
+
logger17.error("Token verification failed", {
|
|
16030
16086
|
error: error instanceof Error ? error.message : String(error)
|
|
16031
16087
|
});
|
|
16032
16088
|
throw new ValidationError("Invalid LTI token");
|
|
@@ -16036,14 +16092,14 @@ class LtiService {
|
|
|
16036
16092
|
const claims = await this.verifyToken(idToken);
|
|
16037
16093
|
const validationError = validateLtiClaims(claims);
|
|
16038
16094
|
if (validationError) {
|
|
16039
|
-
|
|
16095
|
+
logger17.warn("LTI claims validation failed", {
|
|
16040
16096
|
error: validationError,
|
|
16041
16097
|
sub: claims.sub
|
|
16042
16098
|
});
|
|
16043
16099
|
throw new ValidationError(validationError);
|
|
16044
16100
|
}
|
|
16045
16101
|
const user = await this.provisionUser(claims);
|
|
16046
|
-
|
|
16102
|
+
logger17.info("Processed launch roles", {
|
|
16047
16103
|
userId: user.id,
|
|
16048
16104
|
isLearner: LtiRoleChecks.isLearner(claims),
|
|
16049
16105
|
isInstructor: LtiRoleChecks.isInstructor(claims),
|
|
@@ -16053,7 +16109,7 @@ class LtiService {
|
|
|
16053
16109
|
const sessionToken = await this.createSession(user.id);
|
|
16054
16110
|
const targetUri = claims["https://purl.imsglobal.org/spec/lti/claim/target_link_uri"];
|
|
16055
16111
|
const redirectPath = extractRedirectPath(targetUri, currentHost);
|
|
16056
|
-
|
|
16112
|
+
logger17.info("Launch processed", { userId: user.id, redirectPath });
|
|
16057
16113
|
const userInfo = {
|
|
16058
16114
|
sub: user.id,
|
|
16059
16115
|
email: user.email,
|
|
@@ -16099,10 +16155,10 @@ class LtiService {
|
|
|
16099
16155
|
updatedAt: new Date
|
|
16100
16156
|
}).returning({ id: sessions.id });
|
|
16101
16157
|
if (!session2) {
|
|
16102
|
-
|
|
16158
|
+
logger17.error("Session insert returned no rows", { userId });
|
|
16103
16159
|
throw new InternalError("Failed to create session");
|
|
16104
16160
|
}
|
|
16105
|
-
|
|
16161
|
+
logger17.info("Created session", {
|
|
16106
16162
|
userId,
|
|
16107
16163
|
providerId: AUTH_PROVIDER_IDS.TIMEBACK_LTI
|
|
16108
16164
|
});
|
|
@@ -16124,7 +16180,7 @@ class LtiService {
|
|
|
16124
16180
|
where: eq(users.id, existingAccount.userId)
|
|
16125
16181
|
});
|
|
16126
16182
|
if (user) {
|
|
16127
|
-
|
|
16183
|
+
logger17.info("Found user by account", {
|
|
16128
16184
|
userId: user.id,
|
|
16129
16185
|
ltiTimebackId
|
|
16130
16186
|
});
|
|
@@ -16153,13 +16209,13 @@ class LtiService {
|
|
|
16153
16209
|
updatedAt: new Date
|
|
16154
16210
|
}).returning({ id: accounts.id });
|
|
16155
16211
|
if (!account) {
|
|
16156
|
-
|
|
16212
|
+
logger17.error("LTI account link insert returned no rows", {
|
|
16157
16213
|
userId: existingUser.id,
|
|
16158
16214
|
ltiTimebackId
|
|
16159
16215
|
});
|
|
16160
16216
|
throw new InternalError("Failed to link LTI account");
|
|
16161
16217
|
}
|
|
16162
|
-
|
|
16218
|
+
logger17.info("Linked existing user", {
|
|
16163
16219
|
userId: existingUser.id,
|
|
16164
16220
|
ltiTimebackId
|
|
16165
16221
|
});
|
|
@@ -16180,7 +16236,7 @@ class LtiService {
|
|
|
16180
16236
|
updatedAt: new Date
|
|
16181
16237
|
}).returning();
|
|
16182
16238
|
if (!insertedUser) {
|
|
16183
|
-
|
|
16239
|
+
logger17.error("LTI user insert returned no rows", { email, ltiTimebackId });
|
|
16184
16240
|
throw new InternalError("Failed to create user");
|
|
16185
16241
|
}
|
|
16186
16242
|
await tx.insert(accounts).values({
|
|
@@ -16195,7 +16251,7 @@ class LtiService {
|
|
|
16195
16251
|
createdAt: new Date,
|
|
16196
16252
|
updatedAt: new Date
|
|
16197
16253
|
});
|
|
16198
|
-
|
|
16254
|
+
logger17.info("Provisioned user", {
|
|
16199
16255
|
userId: insertedUser.id,
|
|
16200
16256
|
ltiTimebackId
|
|
16201
16257
|
});
|
|
@@ -16204,7 +16260,7 @@ class LtiService {
|
|
|
16204
16260
|
return createdUser;
|
|
16205
16261
|
}
|
|
16206
16262
|
}
|
|
16207
|
-
var
|
|
16263
|
+
var logger17;
|
|
16208
16264
|
var init_lti_service = __esm(() => {
|
|
16209
16265
|
init_esm2();
|
|
16210
16266
|
init_drizzle_orm();
|
|
@@ -16213,7 +16269,7 @@ var init_lti_service = __esm(() => {
|
|
|
16213
16269
|
init_src2();
|
|
16214
16270
|
init_errors();
|
|
16215
16271
|
init_lti_util();
|
|
16216
|
-
|
|
16272
|
+
logger17 = log.scope("LtiService");
|
|
16217
16273
|
});
|
|
16218
16274
|
|
|
16219
16275
|
// ../api-core/src/services/map.service.ts
|
|
@@ -16230,7 +16286,7 @@ class MapService {
|
|
|
16230
16286
|
if (!mapDetails) {
|
|
16231
16287
|
throw new NotFoundError("Map", identifier);
|
|
16232
16288
|
}
|
|
16233
|
-
|
|
16289
|
+
logger18.debug("Retrieved map", { identifier });
|
|
16234
16290
|
return mapDetails;
|
|
16235
16291
|
}
|
|
16236
16292
|
async getElements(mapId) {
|
|
@@ -16246,7 +16302,7 @@ class MapService {
|
|
|
16246
16302
|
}
|
|
16247
16303
|
}
|
|
16248
16304
|
});
|
|
16249
|
-
|
|
16305
|
+
logger18.debug("Retrieved elements", { mapId, count: elements.length });
|
|
16250
16306
|
return elements;
|
|
16251
16307
|
}
|
|
16252
16308
|
async getObjects(mapId, userId) {
|
|
@@ -16267,7 +16323,7 @@ class MapService {
|
|
|
16267
16323
|
}
|
|
16268
16324
|
}
|
|
16269
16325
|
});
|
|
16270
|
-
|
|
16326
|
+
logger18.debug("Retrieved objects", { mapId, userId, count: objects.length });
|
|
16271
16327
|
return objects.map((object) => this.formatMapObjectWithItem(object));
|
|
16272
16328
|
}
|
|
16273
16329
|
async createObject(mapId, data, user) {
|
|
@@ -16294,7 +16350,7 @@ class MapService {
|
|
|
16294
16350
|
throw new NotFoundError("Item", data.itemId);
|
|
16295
16351
|
}
|
|
16296
16352
|
if (!item.isPlaceable) {
|
|
16297
|
-
|
|
16353
|
+
logger18.warn("Attempted to place non-placeable item", {
|
|
16298
16354
|
userId: user.id,
|
|
16299
16355
|
itemId: data.itemId,
|
|
16300
16356
|
mapId
|
|
@@ -16308,7 +16364,7 @@ class MapService {
|
|
|
16308
16364
|
};
|
|
16309
16365
|
const [createdObject] = await db2.insert(mapObjects).values(objectData).returning();
|
|
16310
16366
|
if (!createdObject) {
|
|
16311
|
-
|
|
16367
|
+
logger18.error("Map object insert returned no rows", {
|
|
16312
16368
|
userId: user.id,
|
|
16313
16369
|
mapId,
|
|
16314
16370
|
itemId: data.itemId
|
|
@@ -16332,12 +16388,12 @@ class MapService {
|
|
|
16332
16388
|
}
|
|
16333
16389
|
});
|
|
16334
16390
|
if (!objectWithItem) {
|
|
16335
|
-
|
|
16391
|
+
logger18.error("Map object query after insert returned no rows", {
|
|
16336
16392
|
objectId: createdObject.id
|
|
16337
16393
|
});
|
|
16338
16394
|
throw new InternalError("Failed to retrieve created object");
|
|
16339
16395
|
}
|
|
16340
|
-
|
|
16396
|
+
logger18.info("Created object", {
|
|
16341
16397
|
userId: user.id,
|
|
16342
16398
|
mapId,
|
|
16343
16399
|
objectId: createdObject.id,
|
|
@@ -16361,7 +16417,7 @@ class MapService {
|
|
|
16361
16417
|
if (result.length === 0) {
|
|
16362
16418
|
throw new NotFoundError("MapObject", objectId);
|
|
16363
16419
|
}
|
|
16364
|
-
|
|
16420
|
+
logger18.info("Deleted object", {
|
|
16365
16421
|
userId: user.id,
|
|
16366
16422
|
mapId,
|
|
16367
16423
|
objectId
|
|
@@ -16390,13 +16446,13 @@ class MapService {
|
|
|
16390
16446
|
};
|
|
16391
16447
|
}
|
|
16392
16448
|
}
|
|
16393
|
-
var
|
|
16449
|
+
var logger18;
|
|
16394
16450
|
var init_map_service = __esm(() => {
|
|
16395
16451
|
init_drizzle_orm();
|
|
16396
16452
|
init_tables_index();
|
|
16397
16453
|
init_src2();
|
|
16398
16454
|
init_errors();
|
|
16399
|
-
|
|
16455
|
+
logger18 = log.scope("MapService");
|
|
16400
16456
|
});
|
|
16401
16457
|
|
|
16402
16458
|
// ../realtime/src/server/domain/events.ts
|
|
@@ -16417,13 +16473,13 @@ async function publishToUser(baseUrl, secret, userId, type, payload) {
|
|
|
16417
16473
|
});
|
|
16418
16474
|
if (!res.ok) {
|
|
16419
16475
|
const text3 = await res.text().catch(() => "");
|
|
16420
|
-
|
|
16476
|
+
logger19.warn("Failed to publish to user", {
|
|
16421
16477
|
status: res.status,
|
|
16422
16478
|
body: text3
|
|
16423
16479
|
});
|
|
16424
16480
|
}
|
|
16425
16481
|
} catch (error) {
|
|
16426
|
-
|
|
16482
|
+
logger19.error("Publish to user error", { error });
|
|
16427
16483
|
}
|
|
16428
16484
|
}
|
|
16429
16485
|
|
|
@@ -16443,7 +16499,7 @@ class NotificationService {
|
|
|
16443
16499
|
if (type)
|
|
16444
16500
|
conditions2.push(eq(notifications.type, type));
|
|
16445
16501
|
const results = await this.ctx.db.select().from(notifications).where(and(...conditions2)).orderBy(desc(notifications.createdAt)).limit(limit).offset(offset);
|
|
16446
|
-
|
|
16502
|
+
logger19.debug("Listed notifications", { userId: user.id, count: results.length });
|
|
16447
16503
|
return results;
|
|
16448
16504
|
}
|
|
16449
16505
|
async updateStatus(notificationId, status, method) {
|
|
@@ -16461,7 +16517,7 @@ class NotificationService {
|
|
|
16461
16517
|
if (!updated) {
|
|
16462
16518
|
throw new NotFoundError("Notification", notificationId);
|
|
16463
16519
|
}
|
|
16464
|
-
|
|
16520
|
+
logger19.debug("Updated status", { notificationId, status });
|
|
16465
16521
|
return updated;
|
|
16466
16522
|
}
|
|
16467
16523
|
async getStats(user, options) {
|
|
@@ -16485,7 +16541,7 @@ class NotificationService {
|
|
|
16485
16541
|
const clicked = statsMap.clicked || 0;
|
|
16486
16542
|
const dismissed = statsMap.dismissed || 0;
|
|
16487
16543
|
const expired = statsMap.expired || 0;
|
|
16488
|
-
|
|
16544
|
+
logger19.debug("Retrieved stats", { userId: user.id, total });
|
|
16489
16545
|
return {
|
|
16490
16546
|
total,
|
|
16491
16547
|
delivered,
|
|
@@ -16531,7 +16587,7 @@ class NotificationService {
|
|
|
16531
16587
|
metadata: metadata2
|
|
16532
16588
|
});
|
|
16533
16589
|
}
|
|
16534
|
-
|
|
16590
|
+
logger19.debug("Created notification", {
|
|
16535
16591
|
userId,
|
|
16536
16592
|
type,
|
|
16537
16593
|
id: notificationId,
|
|
@@ -16539,14 +16595,14 @@ class NotificationService {
|
|
|
16539
16595
|
});
|
|
16540
16596
|
return notificationId;
|
|
16541
16597
|
} catch (error) {
|
|
16542
|
-
|
|
16598
|
+
logger19.error("Failed to create notification", { userId, type, error });
|
|
16543
16599
|
return null;
|
|
16544
16600
|
}
|
|
16545
16601
|
}
|
|
16546
16602
|
async publish(userId, notificationId, type, title, message, options) {
|
|
16547
16603
|
const realtimeConfig = this.ctx.config.realtime;
|
|
16548
16604
|
if (!realtimeConfig) {
|
|
16549
|
-
|
|
16605
|
+
logger19.warn("No realtime config for publish");
|
|
16550
16606
|
return;
|
|
16551
16607
|
}
|
|
16552
16608
|
const { relayUrl, publishSecret } = realtimeConfig;
|
|
@@ -16588,13 +16644,13 @@ class NotificationService {
|
|
|
16588
16644
|
metadata: data.metadata || {}
|
|
16589
16645
|
}).returning();
|
|
16590
16646
|
if (!notification) {
|
|
16591
|
-
|
|
16647
|
+
logger19.error("Notification insert returned no rows", {
|
|
16592
16648
|
userId: data.userId,
|
|
16593
16649
|
type: data.type
|
|
16594
16650
|
});
|
|
16595
16651
|
throw new InternalError("Failed to create notification");
|
|
16596
16652
|
}
|
|
16597
|
-
|
|
16653
|
+
logger19.info("Inserted notification", {
|
|
16598
16654
|
notificationId: notification.id,
|
|
16599
16655
|
userId: notification.userId,
|
|
16600
16656
|
type: notification.type
|
|
@@ -16604,7 +16660,7 @@ class NotificationService {
|
|
|
16604
16660
|
async deliverPending(userId) {
|
|
16605
16661
|
const realtimeConfig = this.ctx.config.realtime;
|
|
16606
16662
|
if (!realtimeConfig) {
|
|
16607
|
-
|
|
16663
|
+
logger19.warn("No realtime config for delivery");
|
|
16608
16664
|
return;
|
|
16609
16665
|
}
|
|
16610
16666
|
const { relayUrl, publishSecret } = realtimeConfig;
|
|
@@ -16631,13 +16687,13 @@ class NotificationService {
|
|
|
16631
16687
|
metadata: notification.metadata,
|
|
16632
16688
|
clickUrl: notification.clickUrl
|
|
16633
16689
|
});
|
|
16634
|
-
|
|
16690
|
+
logger19.info("Delivered notification", {
|
|
16635
16691
|
notificationId: notification.id,
|
|
16636
16692
|
userId,
|
|
16637
16693
|
type: notification.type
|
|
16638
16694
|
});
|
|
16639
16695
|
} catch (error) {
|
|
16640
|
-
|
|
16696
|
+
logger19.warn("Failed to deliver", {
|
|
16641
16697
|
notificationId: notification.id,
|
|
16642
16698
|
error
|
|
16643
16699
|
});
|
|
@@ -16645,7 +16701,7 @@ class NotificationService {
|
|
|
16645
16701
|
}
|
|
16646
16702
|
}
|
|
16647
16703
|
}
|
|
16648
|
-
var
|
|
16704
|
+
var logger19;
|
|
16649
16705
|
var init_notification_service = __esm(() => {
|
|
16650
16706
|
init_drizzle_orm();
|
|
16651
16707
|
init_src();
|
|
@@ -16654,7 +16710,7 @@ var init_notification_service = __esm(() => {
|
|
|
16654
16710
|
init_events();
|
|
16655
16711
|
init_notification();
|
|
16656
16712
|
init_errors();
|
|
16657
|
-
|
|
16713
|
+
logger19 = log.scope("NotificationService");
|
|
16658
16714
|
});
|
|
16659
16715
|
|
|
16660
16716
|
// ../api-core/src/services/realtime.service.ts
|
|
@@ -16689,20 +16745,20 @@ class RealtimeService {
|
|
|
16689
16745
|
}
|
|
16690
16746
|
const displayName = user.username || (user.name ? user.name.split(" ")[0] : undefined) || undefined;
|
|
16691
16747
|
const token = await this.ctx.providers.auth.mintRealtimeToken(user.id, resolvedGameId, displayName, user.role);
|
|
16692
|
-
|
|
16748
|
+
logger20.info("Generated token", {
|
|
16693
16749
|
userId: user.id,
|
|
16694
16750
|
gameId: resolvedGameId || "global"
|
|
16695
16751
|
});
|
|
16696
16752
|
return { token };
|
|
16697
16753
|
}
|
|
16698
16754
|
}
|
|
16699
|
-
var
|
|
16755
|
+
var logger20;
|
|
16700
16756
|
var init_realtime_service = __esm(() => {
|
|
16701
16757
|
init_drizzle_orm();
|
|
16702
16758
|
init_tables_index();
|
|
16703
16759
|
init_src2();
|
|
16704
16760
|
init_errors();
|
|
16705
|
-
|
|
16761
|
+
logger20 = log.scope("RealtimeService");
|
|
16706
16762
|
});
|
|
16707
16763
|
|
|
16708
16764
|
// ../api-core/src/services/secrets.service.ts
|
|
@@ -16715,7 +16771,7 @@ class SecretsService {
|
|
|
16715
16771
|
const game = await this.ctx.services.game.validateDeveloperAccessBySlug(user, slug2);
|
|
16716
16772
|
const secrets = await this.ctx.providers.secrets.readSecrets(game.id);
|
|
16717
16773
|
const keys = secrets ? Object.keys(secrets).filter((k) => !INTERNAL_SECRET_KEYS.includes(k)) : [];
|
|
16718
|
-
|
|
16774
|
+
logger21.debug("Listed secret keys", { gameId: game.id, slug: slug2, keyCount: keys.length });
|
|
16719
16775
|
return keys;
|
|
16720
16776
|
}
|
|
16721
16777
|
async getValues(slug2, user) {
|
|
@@ -16730,7 +16786,7 @@ class SecretsService {
|
|
|
16730
16786
|
filtered[key] = value;
|
|
16731
16787
|
}
|
|
16732
16788
|
}
|
|
16733
|
-
|
|
16789
|
+
logger21.debug("Retrieved secret values", { gameId: game.id, slug: slug2 });
|
|
16734
16790
|
return filtered;
|
|
16735
16791
|
}
|
|
16736
16792
|
async setSecrets(slug2, newSecrets, user) {
|
|
@@ -16744,7 +16800,7 @@ class SecretsService {
|
|
|
16744
16800
|
throw new ValidationError(`Secret value for "${key}" must be a string`);
|
|
16745
16801
|
}
|
|
16746
16802
|
if (INTERNAL_SECRET_KEYS.includes(key)) {
|
|
16747
|
-
|
|
16803
|
+
logger21.warn("Attempted to set reserved secret", {
|
|
16748
16804
|
userId: user.id,
|
|
16749
16805
|
gameId: game.id,
|
|
16750
16806
|
key
|
|
@@ -16755,7 +16811,7 @@ class SecretsService {
|
|
|
16755
16811
|
const existingSecrets = await this.ctx.providers.secrets.readSecrets(game.id) || {};
|
|
16756
16812
|
const updatedSecrets = { ...existingSecrets, ...newSecrets };
|
|
16757
16813
|
await this.ctx.providers.secrets.writeSecrets(game.id, updatedSecrets);
|
|
16758
|
-
|
|
16814
|
+
logger21.info("Set secrets", {
|
|
16759
16815
|
gameId: game.id,
|
|
16760
16816
|
slug: slug2,
|
|
16761
16817
|
addedKeys: secretKeys
|
|
@@ -16764,7 +16820,7 @@ class SecretsService {
|
|
|
16764
16820
|
}
|
|
16765
16821
|
async deleteSecret(slug2, key, user) {
|
|
16766
16822
|
if (INTERNAL_SECRET_KEYS.includes(key)) {
|
|
16767
|
-
|
|
16823
|
+
logger21.warn("Attempted to delete reserved secret", {
|
|
16768
16824
|
userId: user.id,
|
|
16769
16825
|
slug: slug2,
|
|
16770
16826
|
key
|
|
@@ -16782,14 +16838,14 @@ class SecretsService {
|
|
|
16782
16838
|
} else {
|
|
16783
16839
|
await this.ctx.providers.secrets.deleteSecrets(game.id);
|
|
16784
16840
|
}
|
|
16785
|
-
|
|
16841
|
+
logger21.info("Deleted secret", { gameId: game.id, slug: slug2, key });
|
|
16786
16842
|
}
|
|
16787
16843
|
}
|
|
16788
|
-
var
|
|
16844
|
+
var logger21, INTERNAL_SECRET_KEYS;
|
|
16789
16845
|
var init_secrets_service = __esm(() => {
|
|
16790
16846
|
init_src2();
|
|
16791
16847
|
init_errors();
|
|
16792
|
-
|
|
16848
|
+
logger21 = log.scope("SecretsService");
|
|
16793
16849
|
INTERNAL_SECRET_KEYS = ["PLAYCADEMY_API_KEY"];
|
|
16794
16850
|
});
|
|
16795
16851
|
|
|
@@ -16802,7 +16858,7 @@ class SeedService {
|
|
|
16802
16858
|
getCloudflare() {
|
|
16803
16859
|
const cf = this.ctx.cloudflare;
|
|
16804
16860
|
if (!cf) {
|
|
16805
|
-
|
|
16861
|
+
logger22.error("Cloudflare provider not available for seeding");
|
|
16806
16862
|
throw new ValidationError("Cloudflare provider not configured");
|
|
16807
16863
|
}
|
|
16808
16864
|
return cf;
|
|
@@ -16814,7 +16870,7 @@ class SeedService {
|
|
|
16814
16870
|
const deploymentId = getDeploymentId(slug2, isProd);
|
|
16815
16871
|
const uniqueSuffix = Date.now().toString(36);
|
|
16816
16872
|
const seedDeploymentId = `seed-${deploymentId}-${uniqueSuffix}`;
|
|
16817
|
-
|
|
16873
|
+
logger22.debug("Seeding database", {
|
|
16818
16874
|
userId: user.id,
|
|
16819
16875
|
gameId: game.id,
|
|
16820
16876
|
slug: slug2,
|
|
@@ -16823,7 +16879,7 @@ class SeedService {
|
|
|
16823
16879
|
});
|
|
16824
16880
|
try {
|
|
16825
16881
|
const workerResponse = await this.deployAndExecuteSeedWorker(cf, seedDeploymentId, game.id, deploymentId, code);
|
|
16826
|
-
|
|
16882
|
+
logger22.info("Seed completed", {
|
|
16827
16883
|
gameId: game.id,
|
|
16828
16884
|
slug: slug2,
|
|
16829
16885
|
deploymentId,
|
|
@@ -16839,7 +16895,7 @@ class SeedService {
|
|
|
16839
16895
|
};
|
|
16840
16896
|
} catch (error) {
|
|
16841
16897
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
16842
|
-
|
|
16898
|
+
logger22.error("Seed failed", {
|
|
16843
16899
|
slug: slug2,
|
|
16844
16900
|
error: errorMessage
|
|
16845
16901
|
});
|
|
@@ -16849,7 +16905,7 @@ class SeedService {
|
|
|
16849
16905
|
error: errorMessage,
|
|
16850
16906
|
developer: { id: user.id, email: user.email }
|
|
16851
16907
|
}).catch((err2) => {
|
|
16852
|
-
|
|
16908
|
+
logger22.warn("Failed to send failure alert", { error: err2 });
|
|
16853
16909
|
});
|
|
16854
16910
|
if (error instanceof Error) {
|
|
16855
16911
|
if (error.message.includes("timed out") || error.message.includes("AbortError")) {
|
|
@@ -16903,7 +16959,7 @@ class SeedService {
|
|
|
16903
16959
|
bindings: { d1: [deploymentId], r2: [], kv: [] },
|
|
16904
16960
|
keepAssets: false
|
|
16905
16961
|
});
|
|
16906
|
-
|
|
16962
|
+
logger22.info("Worker deployed", { seedDeploymentId, url: result.url });
|
|
16907
16963
|
return await this.executeSeedWorker(result.url, seedDeploymentId);
|
|
16908
16964
|
} finally {
|
|
16909
16965
|
await this.cleanupSeedWorker(cf, seedDeploymentId);
|
|
@@ -16919,7 +16975,7 @@ class SeedService {
|
|
|
16919
16975
|
await new Promise((resolve) => setTimeout(resolve, INITIAL_DELAY));
|
|
16920
16976
|
for (let attempt = 0;attempt < MAX_RETRIES; attempt++) {
|
|
16921
16977
|
if (attempt > 0) {
|
|
16922
|
-
|
|
16978
|
+
logger22.debug("Retrying seed execution", {
|
|
16923
16979
|
attempt: attempt + 1,
|
|
16924
16980
|
maxRetries: MAX_RETRIES,
|
|
16925
16981
|
nextRetryIn: `${RETRY_INTERVAL / 1000}s`
|
|
@@ -16939,14 +16995,14 @@ class SeedService {
|
|
|
16939
16995
|
const isRetryable = response.status === 404 || response.status >= 500;
|
|
16940
16996
|
if (isRetryable && attempt < MAX_RETRIES - 1) {
|
|
16941
16997
|
lastError = new Error(`Worker returned ${response.status}`);
|
|
16942
|
-
|
|
16998
|
+
logger22.debug("Worker not ready, will retry", {
|
|
16943
16999
|
status: response.status,
|
|
16944
17000
|
attempt: attempt + 1,
|
|
16945
17001
|
errorBody: errorBody?.substring(0, 500)
|
|
16946
17002
|
});
|
|
16947
17003
|
continue;
|
|
16948
17004
|
}
|
|
16949
|
-
|
|
17005
|
+
logger22.error("Worker returned error", {
|
|
16950
17006
|
status: response.status,
|
|
16951
17007
|
statusText: response.statusText,
|
|
16952
17008
|
errorBody
|
|
@@ -16956,7 +17012,7 @@ class SeedService {
|
|
|
16956
17012
|
const data = await response.json();
|
|
16957
17013
|
if (!data.success) {
|
|
16958
17014
|
const error = data.error || "Seed execution failed";
|
|
16959
|
-
|
|
17015
|
+
logger22.error("Seed execution failed", {
|
|
16960
17016
|
error,
|
|
16961
17017
|
stack: data.stack,
|
|
16962
17018
|
details: data.details,
|
|
@@ -16977,7 +17033,7 @@ class SeedService {
|
|
|
16977
17033
|
};
|
|
16978
17034
|
throw new InternalError(detailedMessage, errorDetails);
|
|
16979
17035
|
}
|
|
16980
|
-
|
|
17036
|
+
logger22.info("Seed executed successfully", {
|
|
16981
17037
|
seedDeploymentId,
|
|
16982
17038
|
duration: data.duration,
|
|
16983
17039
|
logCount: data.logs?.length ?? 0
|
|
@@ -16987,7 +17043,7 @@ class SeedService {
|
|
|
16987
17043
|
clearTimeout(timeout);
|
|
16988
17044
|
if (error instanceof Error && error.name === "AbortError") {
|
|
16989
17045
|
lastError = new Error("Seed execution timed out");
|
|
16990
|
-
|
|
17046
|
+
logger22.debug("Seed execution timed out, will retry", {
|
|
16991
17047
|
attempt: attempt + 1
|
|
16992
17048
|
});
|
|
16993
17049
|
if (attempt < MAX_RETRIES - 1)
|
|
@@ -16998,7 +17054,7 @@ class SeedService {
|
|
|
16998
17054
|
}
|
|
16999
17055
|
lastError = error instanceof Error ? error : new Error(String(error));
|
|
17000
17056
|
if (attempt < MAX_RETRIES - 1) {
|
|
17001
|
-
|
|
17057
|
+
logger22.debug("Network error, will retry", {
|
|
17002
17058
|
error: lastError.message,
|
|
17003
17059
|
attempt: attempt + 1
|
|
17004
17060
|
});
|
|
@@ -17011,19 +17067,19 @@ class SeedService {
|
|
|
17011
17067
|
async cleanupSeedWorker(cf, seedDeploymentId) {
|
|
17012
17068
|
try {
|
|
17013
17069
|
await cf.delete(seedDeploymentId);
|
|
17014
|
-
|
|
17070
|
+
logger22.info("Worker deleted", { seedDeploymentId });
|
|
17015
17071
|
} catch (error) {
|
|
17016
|
-
|
|
17072
|
+
logger22.warn("Failed to cleanup worker", { seedDeploymentId, error });
|
|
17017
17073
|
}
|
|
17018
17074
|
}
|
|
17019
17075
|
}
|
|
17020
|
-
var
|
|
17076
|
+
var logger22;
|
|
17021
17077
|
var init_seed_service = __esm(() => {
|
|
17022
17078
|
init_src2();
|
|
17023
17079
|
init_config2();
|
|
17024
17080
|
init_errors();
|
|
17025
17081
|
init_deployment_util();
|
|
17026
|
-
|
|
17082
|
+
logger22 = log.scope("SeedService");
|
|
17027
17083
|
});
|
|
17028
17084
|
|
|
17029
17085
|
// ../api-core/src/services/session.service.ts
|
|
@@ -17058,10 +17114,10 @@ class SessionService {
|
|
|
17058
17114
|
};
|
|
17059
17115
|
const [newSession] = await db2.insert(gameSessions).values(sessionToInsert).returning({ sessionId: gameSessions.id });
|
|
17060
17116
|
if (!newSession?.sessionId) {
|
|
17061
|
-
|
|
17117
|
+
logger23.error("Game session insert returned no rows", { userId, gameId });
|
|
17062
17118
|
throw new InternalError("Failed to create game session");
|
|
17063
17119
|
}
|
|
17064
|
-
|
|
17120
|
+
logger23.info("Started new session", {
|
|
17065
17121
|
sessionId: newSession.sessionId,
|
|
17066
17122
|
gameId,
|
|
17067
17123
|
userId
|
|
@@ -17082,23 +17138,23 @@ class SessionService {
|
|
|
17082
17138
|
return { success: true, message: "Session already ended" };
|
|
17083
17139
|
}
|
|
17084
17140
|
await db2.update(gameSessions).set({ endedAt: new Date }).where(eq(gameSessions.id, sessionId));
|
|
17085
|
-
|
|
17141
|
+
logger23.info("Ended session", { sessionId, gameId, userId });
|
|
17086
17142
|
return { success: true };
|
|
17087
17143
|
}
|
|
17088
17144
|
async mintToken(gameIdOrSlug, userId) {
|
|
17089
17145
|
const gameId = await this.resolveGameId(gameIdOrSlug);
|
|
17090
17146
|
const result = await this.ctx.providers.auth.mintGameToken(gameId, userId);
|
|
17091
|
-
|
|
17147
|
+
logger23.debug("Minted game token", { gameId, userId });
|
|
17092
17148
|
return result;
|
|
17093
17149
|
}
|
|
17094
17150
|
}
|
|
17095
|
-
var
|
|
17151
|
+
var logger23;
|
|
17096
17152
|
var init_session_service = __esm(() => {
|
|
17097
17153
|
init_drizzle_orm();
|
|
17098
17154
|
init_tables_index();
|
|
17099
17155
|
init_src2();
|
|
17100
17156
|
init_errors();
|
|
17101
|
-
|
|
17157
|
+
logger23 = log.scope("SessionService");
|
|
17102
17158
|
});
|
|
17103
17159
|
|
|
17104
17160
|
// ../api-core/src/services/shop-listing.service.ts
|
|
@@ -17110,7 +17166,7 @@ class ShopListingService {
|
|
|
17110
17166
|
async list() {
|
|
17111
17167
|
const db2 = this.ctx.db;
|
|
17112
17168
|
const allListings = await db2.query.shopListings.findMany();
|
|
17113
|
-
|
|
17169
|
+
logger24.debug("Listed shop listings", { count: allListings.length });
|
|
17114
17170
|
return allListings;
|
|
17115
17171
|
}
|
|
17116
17172
|
async getById(listingId) {
|
|
@@ -17121,7 +17177,7 @@ class ShopListingService {
|
|
|
17121
17177
|
if (!listing) {
|
|
17122
17178
|
throw new NotFoundError("ShopListing", listingId);
|
|
17123
17179
|
}
|
|
17124
|
-
|
|
17180
|
+
logger24.debug("Retrieved listing", { listingId });
|
|
17125
17181
|
return listing;
|
|
17126
17182
|
}
|
|
17127
17183
|
async create(data) {
|
|
@@ -17132,13 +17188,13 @@ class ShopListingService {
|
|
|
17132
17188
|
price: data.price
|
|
17133
17189
|
}).returning();
|
|
17134
17190
|
if (!newListing) {
|
|
17135
|
-
|
|
17191
|
+
logger24.error("Shop listing insert returned no rows", {
|
|
17136
17192
|
itemId: data.itemId,
|
|
17137
17193
|
currencyId: data.currencyId
|
|
17138
17194
|
});
|
|
17139
17195
|
throw new InternalError("Failed to create shop listing");
|
|
17140
17196
|
}
|
|
17141
|
-
|
|
17197
|
+
logger24.info("Created listing", {
|
|
17142
17198
|
listingId: newListing.id,
|
|
17143
17199
|
itemId: newListing.itemId,
|
|
17144
17200
|
currencyId: newListing.currencyId,
|
|
@@ -17181,7 +17237,7 @@ class ShopListingService {
|
|
|
17181
17237
|
if (!updatedListing) {
|
|
17182
17238
|
throw new NotFoundError("ShopListing", listingId);
|
|
17183
17239
|
}
|
|
17184
|
-
|
|
17240
|
+
logger24.info("Updated listing", {
|
|
17185
17241
|
listingId: updatedListing.id,
|
|
17186
17242
|
updatedFields: Object.keys(updateData)
|
|
17187
17243
|
});
|
|
@@ -17211,7 +17267,7 @@ class ShopListingService {
|
|
|
17211
17267
|
if (result.length === 0) {
|
|
17212
17268
|
throw new NotFoundError("ShopListing", listingId);
|
|
17213
17269
|
}
|
|
17214
|
-
|
|
17270
|
+
logger24.info("Deleted listing", { listingId });
|
|
17215
17271
|
}
|
|
17216
17272
|
async listByGame(gameId, user) {
|
|
17217
17273
|
await this.ctx.services.game.validateOwnership(user, gameId);
|
|
@@ -17229,7 +17285,7 @@ class ShopListingService {
|
|
|
17229
17285
|
item: true
|
|
17230
17286
|
}
|
|
17231
17287
|
});
|
|
17232
|
-
|
|
17288
|
+
logger24.debug("Listed game listings", {
|
|
17233
17289
|
gameId,
|
|
17234
17290
|
count: listings.length
|
|
17235
17291
|
});
|
|
@@ -17259,14 +17315,14 @@ class ShopListingService {
|
|
|
17259
17315
|
currencyId: currency.id
|
|
17260
17316
|
}).returning();
|
|
17261
17317
|
if (!newListing) {
|
|
17262
|
-
|
|
17318
|
+
logger24.error("Game item listing insert returned no rows", {
|
|
17263
17319
|
gameId,
|
|
17264
17320
|
itemId,
|
|
17265
17321
|
currencyId: currency.id
|
|
17266
17322
|
});
|
|
17267
17323
|
throw new InternalError("Failed to create shop listing");
|
|
17268
17324
|
}
|
|
17269
|
-
|
|
17325
|
+
logger24.info("Created game item listing", {
|
|
17270
17326
|
listingId: newListing.id,
|
|
17271
17327
|
gameId,
|
|
17272
17328
|
itemId,
|
|
@@ -17307,7 +17363,7 @@ class ShopListingService {
|
|
|
17307
17363
|
if (!updatedListing) {
|
|
17308
17364
|
throw new NotFoundError("ShopListing", `for item ${itemId}`);
|
|
17309
17365
|
}
|
|
17310
|
-
|
|
17366
|
+
logger24.info("Updated game item listing", {
|
|
17311
17367
|
listingId: updatedListing.id,
|
|
17312
17368
|
gameId,
|
|
17313
17369
|
itemId,
|
|
@@ -17332,7 +17388,7 @@ class ShopListingService {
|
|
|
17332
17388
|
if (result.length === 0) {
|
|
17333
17389
|
throw new NotFoundError("ShopListing", `for item ${itemId}`);
|
|
17334
17390
|
}
|
|
17335
|
-
|
|
17391
|
+
logger24.info("Deleted game item listing", {
|
|
17336
17392
|
listingId: result[0].id,
|
|
17337
17393
|
gameId,
|
|
17338
17394
|
itemId
|
|
@@ -17349,13 +17405,13 @@ class ShopListingService {
|
|
|
17349
17405
|
}
|
|
17350
17406
|
}
|
|
17351
17407
|
}
|
|
17352
|
-
var
|
|
17408
|
+
var logger24;
|
|
17353
17409
|
var init_shop_listing_service = __esm(() => {
|
|
17354
17410
|
init_drizzle_orm();
|
|
17355
17411
|
init_tables_index();
|
|
17356
17412
|
init_src2();
|
|
17357
17413
|
init_errors();
|
|
17358
|
-
|
|
17414
|
+
logger24 = log.scope("ShopListingService");
|
|
17359
17415
|
});
|
|
17360
17416
|
|
|
17361
17417
|
// ../api-core/src/services/shop.service.ts
|
|
@@ -17401,7 +17457,7 @@ class ShopService {
|
|
|
17401
17457
|
const shopItems = [];
|
|
17402
17458
|
for (const listing of listingsWithRelations) {
|
|
17403
17459
|
if (!listing.item || !listing.currency) {
|
|
17404
|
-
|
|
17460
|
+
logger25.warn("Listing missing item or currency, skipping", {
|
|
17405
17461
|
listingId: listing.id
|
|
17406
17462
|
});
|
|
17407
17463
|
continue;
|
|
@@ -17418,7 +17474,7 @@ class ShopService {
|
|
|
17418
17474
|
sellBackPercentage: listing.sellBackPercentage
|
|
17419
17475
|
});
|
|
17420
17476
|
}
|
|
17421
|
-
|
|
17477
|
+
logger25.debug("Retrieved shop view", {
|
|
17422
17478
|
userId: user.id,
|
|
17423
17479
|
itemCount: shopItems.length,
|
|
17424
17480
|
currencyCount: shopCurrencies.length
|
|
@@ -17429,12 +17485,12 @@ class ShopService {
|
|
|
17429
17485
|
};
|
|
17430
17486
|
}
|
|
17431
17487
|
}
|
|
17432
|
-
var
|
|
17488
|
+
var logger25;
|
|
17433
17489
|
var init_shop_service = __esm(() => {
|
|
17434
17490
|
init_drizzle_orm();
|
|
17435
17491
|
init_tables_index();
|
|
17436
17492
|
init_src2();
|
|
17437
|
-
|
|
17493
|
+
logger25 = log.scope("ShopService");
|
|
17438
17494
|
});
|
|
17439
17495
|
|
|
17440
17496
|
// ../api-core/src/services/sprite.service.ts
|
|
@@ -17451,17 +17507,17 @@ class SpriteService {
|
|
|
17451
17507
|
if (!template) {
|
|
17452
17508
|
throw new NotFoundError("SpriteTemplate", slug2);
|
|
17453
17509
|
}
|
|
17454
|
-
|
|
17510
|
+
logger26.debug("Retrieved sprite", { slug: slug2 });
|
|
17455
17511
|
return template;
|
|
17456
17512
|
}
|
|
17457
17513
|
}
|
|
17458
|
-
var
|
|
17514
|
+
var logger26;
|
|
17459
17515
|
var init_sprite_service = __esm(() => {
|
|
17460
17516
|
init_drizzle_orm();
|
|
17461
17517
|
init_tables_index();
|
|
17462
17518
|
init_src2();
|
|
17463
17519
|
init_errors();
|
|
17464
|
-
|
|
17520
|
+
logger26 = log.scope("SpriteService");
|
|
17465
17521
|
});
|
|
17466
17522
|
|
|
17467
17523
|
// ../timeback/dist/types.js
|
|
@@ -17904,7 +17960,7 @@ class TimebackService {
|
|
|
17904
17960
|
}
|
|
17905
17961
|
requireClient() {
|
|
17906
17962
|
if (!this.ctx.timeback) {
|
|
17907
|
-
|
|
17963
|
+
logger27.error("Timeback client not available in context");
|
|
17908
17964
|
throw new ValidationError("Timeback integration not available in this environment");
|
|
17909
17965
|
}
|
|
17910
17966
|
return this.ctx.timeback;
|
|
@@ -17957,7 +18013,7 @@ class TimebackService {
|
|
|
17957
18013
|
set: { xp: sql`excluded.xp`, updatedAt: new Date }
|
|
17958
18014
|
}).returning({ xp: timebackDailyXp.xp, date: timebackDailyXp.date });
|
|
17959
18015
|
if (!result) {
|
|
17960
|
-
|
|
18016
|
+
logger27.error("Daily XP upsert returned no rows", { userId, date: targetDate });
|
|
17961
18017
|
throw new InternalError("Failed to update daily XP record");
|
|
17962
18018
|
}
|
|
17963
18019
|
return { xp: result.xp, date: result.date.toISOString() };
|
|
@@ -17988,7 +18044,7 @@ class TimebackService {
|
|
|
17988
18044
|
columns: { id: true, timebackId: true }
|
|
17989
18045
|
});
|
|
17990
18046
|
if (dbUser?.timebackId) {
|
|
17991
|
-
|
|
18047
|
+
logger27.info("Student already onboarded", { userId: user.id });
|
|
17992
18048
|
return { status: "already_populated" };
|
|
17993
18049
|
}
|
|
17994
18050
|
let timebackId;
|
|
@@ -17997,7 +18053,7 @@ class TimebackService {
|
|
|
17997
18053
|
const existingUser = await client.oneroster.users.findByEmail(user.email);
|
|
17998
18054
|
timebackId = existingUser.sourcedId;
|
|
17999
18055
|
name3 = `${existingUser.givenName} ${existingUser.familyName}`;
|
|
18000
|
-
|
|
18056
|
+
logger27.info("Found existing student in OneRoster", {
|
|
18001
18057
|
userId: user.id,
|
|
18002
18058
|
timebackId
|
|
18003
18059
|
});
|
|
@@ -18026,7 +18082,7 @@ class TimebackService {
|
|
|
18026
18082
|
}
|
|
18027
18083
|
timebackId = response.sourcedIdPairs.allocatedSourcedId;
|
|
18028
18084
|
name3 = `${providedNames.firstName} ${providedNames.lastName}`;
|
|
18029
|
-
|
|
18085
|
+
logger27.info("Created student in OneRoster", { userId: user.id, timebackId });
|
|
18030
18086
|
}
|
|
18031
18087
|
const assessments = await this.fetchAssessments(timebackId);
|
|
18032
18088
|
await db2.transaction(async (tx) => {
|
|
@@ -18060,7 +18116,7 @@ class TimebackService {
|
|
|
18060
18116
|
}
|
|
18061
18117
|
const [updated] = await tx.update(users).set({ timebackId, name: name3 }).where(eq(users.id, user.id)).returning({ id: users.id });
|
|
18062
18118
|
if (!updated) {
|
|
18063
|
-
|
|
18119
|
+
logger27.error("User Timeback ID update returned no rows", {
|
|
18064
18120
|
userId: user.id,
|
|
18065
18121
|
timebackId
|
|
18066
18122
|
});
|
|
@@ -18083,13 +18139,13 @@ class TimebackService {
|
|
|
18083
18139
|
break;
|
|
18084
18140
|
offset += limit;
|
|
18085
18141
|
}
|
|
18086
|
-
|
|
18142
|
+
logger27.debug("Fetched assessments", {
|
|
18087
18143
|
studentSourcedId,
|
|
18088
18144
|
totalCount: allAssessments.length
|
|
18089
18145
|
});
|
|
18090
18146
|
return allAssessments;
|
|
18091
18147
|
} catch (error) {
|
|
18092
|
-
|
|
18148
|
+
logger27.warn("Failed to fetch assessments", { studentSourcedId, error });
|
|
18093
18149
|
return [];
|
|
18094
18150
|
}
|
|
18095
18151
|
}
|
|
@@ -18196,7 +18252,7 @@ class TimebackService {
|
|
|
18196
18252
|
masterableUnits: derivedMasterableUnits
|
|
18197
18253
|
} = courseConfig;
|
|
18198
18254
|
if (!isTimebackSubject(subjectInput)) {
|
|
18199
|
-
|
|
18255
|
+
logger27.warn("Invalid Timeback subject in course config", {
|
|
18200
18256
|
subject: subjectInput,
|
|
18201
18257
|
courseCode,
|
|
18202
18258
|
title
|
|
@@ -18204,7 +18260,7 @@ class TimebackService {
|
|
|
18204
18260
|
throw new ValidationError(`Invalid subject "${subjectInput}"`);
|
|
18205
18261
|
}
|
|
18206
18262
|
if (!isTimebackGrade(grade)) {
|
|
18207
|
-
|
|
18263
|
+
logger27.warn("Invalid Timeback grade in course config", {
|
|
18208
18264
|
grade,
|
|
18209
18265
|
courseCode,
|
|
18210
18266
|
title
|
|
@@ -18216,7 +18272,7 @@ class TimebackService {
|
|
|
18216
18272
|
const totalXp = derivedTotalXp ?? courseMetadata?.metrics?.totalXp;
|
|
18217
18273
|
const masterableUnits = derivedMasterableUnits ?? (isPlaycademyResourceMetadata(courseMetadata?.playcademy) ? courseMetadata?.playcademy?.mastery?.masterableUnits : undefined);
|
|
18218
18274
|
if (typeof totalXp !== "number") {
|
|
18219
|
-
|
|
18275
|
+
logger27.warn("Course missing totalXp in Timeback config", {
|
|
18220
18276
|
courseCode,
|
|
18221
18277
|
title
|
|
18222
18278
|
});
|
|
@@ -18387,7 +18443,7 @@ class TimebackService {
|
|
|
18387
18443
|
courseName: activityData.courseName,
|
|
18388
18444
|
studentEmail: activityData.studentEmail
|
|
18389
18445
|
});
|
|
18390
|
-
|
|
18446
|
+
logger27.info("Recorded activity completion", {
|
|
18391
18447
|
gameId,
|
|
18392
18448
|
courseId: integration.courseId,
|
|
18393
18449
|
studentId,
|
|
@@ -18404,7 +18460,7 @@ class TimebackService {
|
|
|
18404
18460
|
};
|
|
18405
18461
|
}
|
|
18406
18462
|
}
|
|
18407
|
-
var
|
|
18463
|
+
var logger27;
|
|
18408
18464
|
var init_timeback_service = __esm(() => {
|
|
18409
18465
|
init_drizzle_orm();
|
|
18410
18466
|
init_src();
|
|
@@ -18414,7 +18470,7 @@ var init_timeback_service = __esm(() => {
|
|
|
18414
18470
|
init_src4();
|
|
18415
18471
|
init_errors();
|
|
18416
18472
|
init_timeback_util();
|
|
18417
|
-
|
|
18473
|
+
logger27 = log.scope("TimebackService");
|
|
18418
18474
|
});
|
|
18419
18475
|
|
|
18420
18476
|
// ../api-core/src/services/upload.service.ts
|
|
@@ -18427,15 +18483,15 @@ class UploadService {
|
|
|
18427
18483
|
const { fileName, gameId } = request2;
|
|
18428
18484
|
const bucketName = this.ctx.config.uploadBucket;
|
|
18429
18485
|
if (!bucketName) {
|
|
18430
|
-
|
|
18486
|
+
logger28.error("Upload bucket not configured in environment");
|
|
18431
18487
|
throw new ValidationError("Upload bucket not configured");
|
|
18432
18488
|
}
|
|
18433
18489
|
await this.ctx.services.game.validateDeveloperAccess(user, gameId);
|
|
18434
18490
|
const version2 = ulid();
|
|
18435
18491
|
const tempS3Key = `uploads-temp/${gameId}/${version2}/${fileName}`;
|
|
18436
|
-
|
|
18492
|
+
logger28.debug("Initiating upload", { userId: user.id, gameId, fileName, version: version2 });
|
|
18437
18493
|
const presignedUrl = await this.ctx.providers.storage.generatePresignedPutUrl(bucketName, tempS3Key, "application/zip");
|
|
18438
|
-
|
|
18494
|
+
logger28.info("Presigned URL generated", {
|
|
18439
18495
|
userId: user.id,
|
|
18440
18496
|
gameId,
|
|
18441
18497
|
version: version2
|
|
@@ -18448,12 +18504,12 @@ class UploadService {
|
|
|
18448
18504
|
};
|
|
18449
18505
|
}
|
|
18450
18506
|
}
|
|
18451
|
-
var
|
|
18507
|
+
var logger28;
|
|
18452
18508
|
var init_upload_service = __esm(() => {
|
|
18453
18509
|
init_node();
|
|
18454
18510
|
init_src2();
|
|
18455
18511
|
init_errors();
|
|
18456
|
-
|
|
18512
|
+
logger28 = log.scope("UploadService");
|
|
18457
18513
|
});
|
|
18458
18514
|
|
|
18459
18515
|
// ../api-core/src/services/user.service.ts
|
|
@@ -18468,12 +18524,12 @@ class UserService {
|
|
|
18468
18524
|
where: eq(users.id, user.id)
|
|
18469
18525
|
});
|
|
18470
18526
|
if (!userData) {
|
|
18471
|
-
|
|
18527
|
+
logger29.error("User not found", { userId: user.id });
|
|
18472
18528
|
throw new NotFoundError("User", user.id);
|
|
18473
18529
|
}
|
|
18474
18530
|
const timeback2 = userData.timebackId ? await this.fetchTimebackData(userData.timebackId, gameId) : undefined;
|
|
18475
18531
|
if (gameId) {
|
|
18476
|
-
|
|
18532
|
+
logger29.debug("Fetched user profile (game context)", { userId: user.id, gameId });
|
|
18477
18533
|
return {
|
|
18478
18534
|
id: userData.id,
|
|
18479
18535
|
name: userData.name,
|
|
@@ -18486,7 +18542,7 @@ class UserService {
|
|
|
18486
18542
|
const timebackAccount = await db2.query.accounts.findFirst({
|
|
18487
18543
|
where: and(eq(accounts.userId, user.id), eq(accounts.providerId, "timeback"))
|
|
18488
18544
|
});
|
|
18489
|
-
|
|
18545
|
+
logger29.debug("Fetched user profile (platform context)", { userId: user.id });
|
|
18490
18546
|
return {
|
|
18491
18547
|
id: userData.id,
|
|
18492
18548
|
name: userData.name,
|
|
@@ -18510,7 +18566,7 @@ class UserService {
|
|
|
18510
18566
|
]);
|
|
18511
18567
|
const enrollments = gameId ? this.filterEnrollmentsByGame(allEnrollments, gameId) : allEnrollments;
|
|
18512
18568
|
const organizations = gameId ? this.filterOrganizationsByEnrollments(allOrganizations, enrollments) : allOrganizations;
|
|
18513
|
-
|
|
18569
|
+
logger29.debug("Fetched Timeback data", {
|
|
18514
18570
|
timebackId,
|
|
18515
18571
|
role,
|
|
18516
18572
|
enrollmentCount: enrollments.length,
|
|
@@ -18519,9 +18575,9 @@ class UserService {
|
|
|
18519
18575
|
return { id: timebackId, role, enrollments, organizations };
|
|
18520
18576
|
}
|
|
18521
18577
|
async fetchStudentProfile(timebackId) {
|
|
18522
|
-
|
|
18578
|
+
logger29.debug("Fetching student profile", { timebackId });
|
|
18523
18579
|
if (!this.ctx.timeback) {
|
|
18524
|
-
|
|
18580
|
+
logger29.warn("Timeback client not available");
|
|
18525
18581
|
return { role: "student", organizations: [] };
|
|
18526
18582
|
}
|
|
18527
18583
|
try {
|
|
@@ -18549,14 +18605,14 @@ class UserService {
|
|
|
18549
18605
|
}
|
|
18550
18606
|
return { role, organizations: Array.from(orgMap.values()) };
|
|
18551
18607
|
} catch (error) {
|
|
18552
|
-
|
|
18608
|
+
logger29.warn("Failed to fetch student profile", { error, timebackId });
|
|
18553
18609
|
return { role: "student", organizations: [] };
|
|
18554
18610
|
}
|
|
18555
18611
|
}
|
|
18556
18612
|
async fetchEnrollments(timebackId) {
|
|
18557
|
-
|
|
18613
|
+
logger29.debug("Fetching enrollments", { timebackId });
|
|
18558
18614
|
if (!this.ctx.timeback) {
|
|
18559
|
-
|
|
18615
|
+
logger29.warn("Timeback client not available");
|
|
18560
18616
|
return [];
|
|
18561
18617
|
}
|
|
18562
18618
|
try {
|
|
@@ -18576,7 +18632,7 @@ class UserService {
|
|
|
18576
18632
|
orgId: courseToSchool.get(i2.courseId)
|
|
18577
18633
|
}));
|
|
18578
18634
|
} catch (error) {
|
|
18579
|
-
|
|
18635
|
+
logger29.warn("Failed to fetch enrollments", { error, timebackId });
|
|
18580
18636
|
return [];
|
|
18581
18637
|
}
|
|
18582
18638
|
}
|
|
@@ -18590,13 +18646,13 @@ class UserService {
|
|
|
18590
18646
|
return organizations.filter((o) => enrollmentOrgIds.has(o.id));
|
|
18591
18647
|
}
|
|
18592
18648
|
}
|
|
18593
|
-
var
|
|
18649
|
+
var logger29;
|
|
18594
18650
|
var init_user_service = __esm(() => {
|
|
18595
18651
|
init_drizzle_orm();
|
|
18596
18652
|
init_tables_index();
|
|
18597
18653
|
init_src2();
|
|
18598
18654
|
init_errors();
|
|
18599
|
-
|
|
18655
|
+
logger29 = log.scope("UserService");
|
|
18600
18656
|
});
|
|
18601
18657
|
|
|
18602
18658
|
// ../api-core/src/services/verify.service.ts
|
|
@@ -18606,16 +18662,16 @@ class VerifyService {
|
|
|
18606
18662
|
this.ctx = ctx;
|
|
18607
18663
|
}
|
|
18608
18664
|
async verifyGameToken(token) {
|
|
18609
|
-
|
|
18665
|
+
logger30.debug("Verifying game token");
|
|
18610
18666
|
const payload = await this.ctx.providers.auth.validateGameToken(token);
|
|
18611
18667
|
if (!payload) {
|
|
18612
|
-
|
|
18668
|
+
logger30.warn("Invalid or expired game token presented");
|
|
18613
18669
|
throw new ValidationError("Invalid or expired token");
|
|
18614
18670
|
}
|
|
18615
18671
|
const gameId = payload.sub;
|
|
18616
18672
|
const userId = payload.uid;
|
|
18617
18673
|
if (typeof gameId !== "string" || typeof userId !== "string") {
|
|
18618
|
-
|
|
18674
|
+
logger30.warn("Game token missing required claims", {
|
|
18619
18675
|
hasGameId: typeof gameId === "string",
|
|
18620
18676
|
hasUserId: typeof userId === "string"
|
|
18621
18677
|
});
|
|
@@ -18626,7 +18682,7 @@ class VerifyService {
|
|
|
18626
18682
|
where: eq(users.id, userId)
|
|
18627
18683
|
});
|
|
18628
18684
|
if (!userData) {
|
|
18629
|
-
|
|
18685
|
+
logger30.error("User not found for valid token", {
|
|
18630
18686
|
userId
|
|
18631
18687
|
});
|
|
18632
18688
|
throw new NotFoundError("User", userId);
|
|
@@ -18640,7 +18696,7 @@ class VerifyService {
|
|
|
18640
18696
|
family_name: undefined,
|
|
18641
18697
|
timeback_id: userData.timebackId || undefined
|
|
18642
18698
|
};
|
|
18643
|
-
|
|
18699
|
+
logger30.info("Token verified", { gameId, userId });
|
|
18644
18700
|
return {
|
|
18645
18701
|
claims: payload,
|
|
18646
18702
|
gameId,
|
|
@@ -18648,13 +18704,13 @@ class VerifyService {
|
|
|
18648
18704
|
};
|
|
18649
18705
|
}
|
|
18650
18706
|
}
|
|
18651
|
-
var
|
|
18707
|
+
var logger30;
|
|
18652
18708
|
var init_verify_service = __esm(() => {
|
|
18653
18709
|
init_drizzle_orm();
|
|
18654
18710
|
init_tables_index();
|
|
18655
18711
|
init_src2();
|
|
18656
18712
|
init_errors();
|
|
18657
|
-
|
|
18713
|
+
logger30 = log.scope("VerifyService");
|
|
18658
18714
|
});
|
|
18659
18715
|
|
|
18660
18716
|
// ../api-core/src/services/index.ts
|
|
@@ -18674,6 +18730,7 @@ function createServices(ctx) {
|
|
|
18674
18730
|
item: new ItemService(ctx),
|
|
18675
18731
|
leaderboard: new LeaderboardService(ctx),
|
|
18676
18732
|
level: new LevelService(ctx),
|
|
18733
|
+
logs: new LogsService(ctx),
|
|
18677
18734
|
lti: new LtiService(ctx),
|
|
18678
18735
|
map: new MapService(ctx),
|
|
18679
18736
|
notification: new NotificationService(ctx),
|
|
@@ -18705,6 +18762,7 @@ var init_services = __esm(() => {
|
|
|
18705
18762
|
init_item_service();
|
|
18706
18763
|
init_leaderboard_service();
|
|
18707
18764
|
init_level_service();
|
|
18765
|
+
init_logs_service();
|
|
18708
18766
|
init_lti_service();
|
|
18709
18767
|
init_map_service();
|
|
18710
18768
|
init_notification_service();
|
|
@@ -18801,6 +18859,38 @@ function createSandboxAuthProvider() {
|
|
|
18801
18859
|
const header = btoa(JSON.stringify({ alg: "none", typ: "sandbox" }));
|
|
18802
18860
|
const payloadStr = btoa(JSON.stringify(payload));
|
|
18803
18861
|
return `${header}.${payloadStr}.sandbox`;
|
|
18862
|
+
},
|
|
18863
|
+
async mintLogStreamToken(userId, workerId) {
|
|
18864
|
+
const jti = crypto.randomUUID();
|
|
18865
|
+
const payload = {
|
|
18866
|
+
sub: userId,
|
|
18867
|
+
game: workerId,
|
|
18868
|
+
jti,
|
|
18869
|
+
exp: Date.now() + 60 * 1000
|
|
18870
|
+
};
|
|
18871
|
+
const header = btoa(JSON.stringify({ alg: "none", typ: "sandbox" }));
|
|
18872
|
+
const payloadStr = btoa(JSON.stringify(payload));
|
|
18873
|
+
return `${header}.${payloadStr}.sandbox`;
|
|
18874
|
+
},
|
|
18875
|
+
async validateLogStreamToken(token) {
|
|
18876
|
+
try {
|
|
18877
|
+
const parts2 = token.split(".");
|
|
18878
|
+
if (parts2.length !== 3)
|
|
18879
|
+
return null;
|
|
18880
|
+
if (parts2[2] === "sandbox") {
|
|
18881
|
+
const payload = JSON.parse(atob(parts2[1]));
|
|
18882
|
+
if (payload.jti && payload.sub && payload.game) {
|
|
18883
|
+
if (payload.exp && payload.exp < Date.now()) {
|
|
18884
|
+
log.debug("[SandboxAuthProvider] Log stream token expired");
|
|
18885
|
+
return null;
|
|
18886
|
+
}
|
|
18887
|
+
return { jti: payload.jti, sub: payload.sub, game: payload.game };
|
|
18888
|
+
}
|
|
18889
|
+
}
|
|
18890
|
+
return null;
|
|
18891
|
+
} catch {
|
|
18892
|
+
return null;
|
|
18893
|
+
}
|
|
18804
18894
|
}
|
|
18805
18895
|
};
|
|
18806
18896
|
}
|
|
@@ -20783,7 +20873,7 @@ var humanize = (times) => {
|
|
|
20783
20873
|
}
|
|
20784
20874
|
}
|
|
20785
20875
|
return `${status}`;
|
|
20786
|
-
},
|
|
20876
|
+
}, logger31 = (fn = console.log) => {
|
|
20787
20877
|
return async function logger2(c, next) {
|
|
20788
20878
|
const { method, url } = c.req;
|
|
20789
20879
|
const path = url.slice(url.indexOf("/", 8));
|
|
@@ -20960,7 +21050,7 @@ function createApp(db2, options) {
|
|
|
20960
21050
|
const app = new Hono2;
|
|
20961
21051
|
app.use("*", cors({ origin: "*", credentials: true }));
|
|
20962
21052
|
if (options.verbose && !options.quiet) {
|
|
20963
|
-
app.use("*",
|
|
21053
|
+
app.use("*", logger31());
|
|
20964
21054
|
}
|
|
20965
21055
|
app.use("/api/*", async (c, next) => {
|
|
20966
21056
|
c.set("db", db2);
|
|
@@ -27433,12 +27523,12 @@ var init_session2 = __esm(() => {
|
|
|
27433
27523
|
init_utils();
|
|
27434
27524
|
init_dist4();
|
|
27435
27525
|
PglitePreparedQuery = class PglitePreparedQuery extends PgPreparedQuery {
|
|
27436
|
-
constructor(client, queryString, params,
|
|
27526
|
+
constructor(client, queryString, params, logger32, fields, name3, _isResponseInArrayMode, customResultMapper) {
|
|
27437
27527
|
super({ sql: queryString, params });
|
|
27438
27528
|
this.client = client;
|
|
27439
27529
|
this.queryString = queryString;
|
|
27440
27530
|
this.params = params;
|
|
27441
|
-
this.logger =
|
|
27531
|
+
this.logger = logger32;
|
|
27442
27532
|
this.fields = fields;
|
|
27443
27533
|
this._isResponseInArrayMode = _isResponseInArrayMode;
|
|
27444
27534
|
this.customResultMapper = customResultMapper;
|
|
@@ -27542,11 +27632,11 @@ var init_session2 = __esm(() => {
|
|
|
27542
27632
|
// ../../node_modules/drizzle-orm/pglite/driver.js
|
|
27543
27633
|
function construct(client, config2 = {}) {
|
|
27544
27634
|
const dialect2 = new PgDialect({ casing: config2.casing });
|
|
27545
|
-
let
|
|
27635
|
+
let logger32;
|
|
27546
27636
|
if (config2.logger === true) {
|
|
27547
|
-
|
|
27637
|
+
logger32 = new DefaultLogger;
|
|
27548
27638
|
} else if (config2.logger !== false) {
|
|
27549
|
-
|
|
27639
|
+
logger32 = config2.logger;
|
|
27550
27640
|
}
|
|
27551
27641
|
let schema2;
|
|
27552
27642
|
if (config2.schema) {
|
|
@@ -27557,7 +27647,7 @@ function construct(client, config2 = {}) {
|
|
|
27557
27647
|
tableNamesMap: tablesConfig.tableNamesMap
|
|
27558
27648
|
};
|
|
27559
27649
|
}
|
|
27560
|
-
const driver = new PgliteDriver(client, dialect2, { logger:
|
|
27650
|
+
const driver = new PgliteDriver(client, dialect2, { logger: logger32 });
|
|
27561
27651
|
const session2 = driver.createSession(schema2);
|
|
27562
27652
|
const db2 = new PgliteDatabase(dialect2, session2, schema2);
|
|
27563
27653
|
db2.$client = client;
|
|
@@ -76138,8 +76228,8 @@ var init_currencies = __esm(() => {
|
|
|
76138
76228
|
});
|
|
76139
76229
|
|
|
76140
76230
|
// src/lib/logging/adapter.ts
|
|
76141
|
-
function setLogger(
|
|
76142
|
-
customLogger =
|
|
76231
|
+
function setLogger(logger32) {
|
|
76232
|
+
customLogger = logger32;
|
|
76143
76233
|
}
|
|
76144
76234
|
function getLogger() {
|
|
76145
76235
|
if (customLogger) {
|
|
@@ -76151,10 +76241,10 @@ function getLogger() {
|
|
|
76151
76241
|
error: (msg) => console.error(msg)
|
|
76152
76242
|
};
|
|
76153
76243
|
}
|
|
76154
|
-
var customLogger,
|
|
76244
|
+
var customLogger, logger32;
|
|
76155
76245
|
var init_adapter = __esm(() => {
|
|
76156
76246
|
init_config();
|
|
76157
|
-
|
|
76247
|
+
logger32 = {
|
|
76158
76248
|
info: (msg) => {
|
|
76159
76249
|
if (customLogger || !config.embedded) {
|
|
76160
76250
|
getLogger().info(msg);
|
|
@@ -76241,7 +76331,7 @@ async function seedCoreGames(db2) {
|
|
|
76241
76331
|
try {
|
|
76242
76332
|
await db2.insert(games).values(gameData).onConflictDoNothing();
|
|
76243
76333
|
} catch (error2) {
|
|
76244
|
-
|
|
76334
|
+
logger32.error(`Error seeding core game '${gameData.slug}': ${error2}`);
|
|
76245
76335
|
}
|
|
76246
76336
|
}
|
|
76247
76337
|
}
|
|
@@ -76282,7 +76372,7 @@ async function seedCurrentProjectGame(db2, project) {
|
|
|
76282
76372
|
}
|
|
76283
76373
|
return newGame;
|
|
76284
76374
|
} catch (error2) {
|
|
76285
|
-
|
|
76375
|
+
logger32.error(`❌ Error seeding project game: ${error2}`);
|
|
76286
76376
|
throw error2;
|
|
76287
76377
|
}
|
|
76288
76378
|
}
|
|
@@ -77721,21 +77811,21 @@ var init_utils11 = __esm(() => {
|
|
|
77721
77811
|
});
|
|
77722
77812
|
|
|
77723
77813
|
// ../api-core/src/controllers/achievement.controller.ts
|
|
77724
|
-
var
|
|
77814
|
+
var logger33, listCurrent, listHistory, postProgress, achievements3;
|
|
77725
77815
|
var init_achievement_controller = __esm(() => {
|
|
77726
77816
|
init_esm();
|
|
77727
77817
|
init_schemas_index();
|
|
77728
77818
|
init_src2();
|
|
77729
77819
|
init_errors();
|
|
77730
77820
|
init_utils11();
|
|
77731
|
-
|
|
77821
|
+
logger33 = log.scope("AchievementController");
|
|
77732
77822
|
listCurrent = requireAuth(async (ctx) => {
|
|
77733
|
-
|
|
77823
|
+
logger33.debug("Listing current achievements", { userId: ctx.user.id, gameId: ctx.gameId });
|
|
77734
77824
|
return ctx.services.achievement.listCurrent(ctx.user, ctx.gameId);
|
|
77735
77825
|
});
|
|
77736
77826
|
listHistory = requireAuth(async (ctx) => {
|
|
77737
77827
|
const limit = Math.max(1, Math.min(100, Number(ctx.url.searchParams.get("limit")) || 20));
|
|
77738
|
-
|
|
77828
|
+
logger33.debug("Listing achievement history", { userId: ctx.user.id, limit });
|
|
77739
77829
|
return ctx.services.achievement.listHistory(ctx.user, limit);
|
|
77740
77830
|
});
|
|
77741
77831
|
postProgress = requireAuth(async (ctx) => {
|
|
@@ -77746,12 +77836,12 @@ var init_achievement_controller = __esm(() => {
|
|
|
77746
77836
|
} catch (error2) {
|
|
77747
77837
|
if (error2 instanceof exports_external.ZodError) {
|
|
77748
77838
|
const details = formatZodError(error2);
|
|
77749
|
-
|
|
77839
|
+
logger33.warn("Submit achievement progress validation failed", { details });
|
|
77750
77840
|
throw ApiError.unprocessableEntity("Invalid request body", details);
|
|
77751
77841
|
}
|
|
77752
77842
|
throw ApiError.badRequest("Invalid JSON body");
|
|
77753
77843
|
}
|
|
77754
|
-
|
|
77844
|
+
logger33.debug("Submitting progress", {
|
|
77755
77845
|
userId: ctx.user.id,
|
|
77756
77846
|
achievementId: body2.achievementId
|
|
77757
77847
|
});
|
|
@@ -77765,14 +77855,14 @@ var init_achievement_controller = __esm(() => {
|
|
|
77765
77855
|
});
|
|
77766
77856
|
|
|
77767
77857
|
// ../api-core/src/controllers/admin.controller.ts
|
|
77768
|
-
var
|
|
77858
|
+
var logger34, getAllowedOrigins;
|
|
77769
77859
|
var init_admin_controller = __esm(() => {
|
|
77770
77860
|
init_src2();
|
|
77771
77861
|
init_utils11();
|
|
77772
|
-
|
|
77862
|
+
logger34 = log.scope("AdminController");
|
|
77773
77863
|
getAllowedOrigins = requireAdmin(async (ctx) => {
|
|
77774
77864
|
const shouldRefresh = ctx.url.searchParams.get("refresh") === "true";
|
|
77775
|
-
|
|
77865
|
+
logger34.debug("Getting allowed origins", { userId: ctx.user.id, refresh: shouldRefresh });
|
|
77776
77866
|
if (shouldRefresh) {
|
|
77777
77867
|
await ctx.providers.cache.refreshGameOrigins();
|
|
77778
77868
|
}
|
|
@@ -77787,14 +77877,14 @@ var init_admin_controller = __esm(() => {
|
|
|
77787
77877
|
});
|
|
77788
77878
|
|
|
77789
77879
|
// ../api-core/src/controllers/bucket.controller.ts
|
|
77790
|
-
var
|
|
77880
|
+
var logger35, listFiles, getFile, putFile, deleteFile, initiateUpload;
|
|
77791
77881
|
var init_bucket_controller = __esm(() => {
|
|
77792
77882
|
init_esm();
|
|
77793
77883
|
init_schemas_index();
|
|
77794
77884
|
init_src2();
|
|
77795
77885
|
init_errors();
|
|
77796
77886
|
init_utils11();
|
|
77797
|
-
|
|
77887
|
+
logger35 = log.scope("BucketController");
|
|
77798
77888
|
listFiles = requireDeveloper(async (ctx) => {
|
|
77799
77889
|
const slug2 = ctx.params.slug;
|
|
77800
77890
|
if (!slug2) {
|
|
@@ -77802,7 +77892,7 @@ var init_bucket_controller = __esm(() => {
|
|
|
77802
77892
|
}
|
|
77803
77893
|
const url = ctx.url;
|
|
77804
77894
|
const prefix2 = url.searchParams.get("prefix") || undefined;
|
|
77805
|
-
|
|
77895
|
+
logger35.debug("Listing files", { userId: ctx.user.id, slug: slug2, prefix: prefix2 });
|
|
77806
77896
|
const files = await ctx.services.bucket.listFiles(slug2, ctx.user, prefix2);
|
|
77807
77897
|
return { files };
|
|
77808
77898
|
});
|
|
@@ -77812,7 +77902,7 @@ var init_bucket_controller = __esm(() => {
|
|
|
77812
77902
|
if (!slug2 || !key) {
|
|
77813
77903
|
throw ApiError.badRequest("Missing game slug or file key");
|
|
77814
77904
|
}
|
|
77815
|
-
|
|
77905
|
+
logger35.debug("Getting file", { userId: ctx.user.id, slug: slug2, key });
|
|
77816
77906
|
const object = await ctx.services.bucket.getFile(slug2, key, ctx.user);
|
|
77817
77907
|
return new Response(Buffer.from(object.body), {
|
|
77818
77908
|
status: 200,
|
|
@@ -77831,7 +77921,7 @@ var init_bucket_controller = __esm(() => {
|
|
|
77831
77921
|
const arrayBuffer = await ctx.request.arrayBuffer();
|
|
77832
77922
|
const body2 = new Uint8Array(arrayBuffer);
|
|
77833
77923
|
const contentType = ctx.request.headers.get("content-type") || undefined;
|
|
77834
|
-
|
|
77924
|
+
logger35.debug("Uploading file", {
|
|
77835
77925
|
userId: ctx.user.id,
|
|
77836
77926
|
slug: slug2,
|
|
77837
77927
|
key,
|
|
@@ -77847,7 +77937,7 @@ var init_bucket_controller = __esm(() => {
|
|
|
77847
77937
|
if (!slug2 || !key) {
|
|
77848
77938
|
throw ApiError.badRequest("Missing game slug or file key");
|
|
77849
77939
|
}
|
|
77850
|
-
|
|
77940
|
+
logger35.debug("Deleting file", { userId: ctx.user.id, slug: slug2, key });
|
|
77851
77941
|
await ctx.services.bucket.deleteFile(slug2, key, ctx.user);
|
|
77852
77942
|
return { success: true, key };
|
|
77853
77943
|
});
|
|
@@ -77859,12 +77949,12 @@ var init_bucket_controller = __esm(() => {
|
|
|
77859
77949
|
} catch (error2) {
|
|
77860
77950
|
if (error2 instanceof exports_external.ZodError) {
|
|
77861
77951
|
const details = formatZodError(error2);
|
|
77862
|
-
|
|
77952
|
+
logger35.warn("Initiate upload validation failed", { details });
|
|
77863
77953
|
throw ApiError.unprocessableEntity("Validation failed", details);
|
|
77864
77954
|
}
|
|
77865
77955
|
throw ApiError.badRequest("Invalid JSON body");
|
|
77866
77956
|
}
|
|
77867
|
-
|
|
77957
|
+
logger35.debug("Initiating multipart upload", {
|
|
77868
77958
|
userId: ctx.user.id,
|
|
77869
77959
|
gameId: body2.gameId,
|
|
77870
77960
|
fileName: body2.fileName
|
|
@@ -77881,19 +77971,19 @@ async function listComponents(ctx) {
|
|
|
77881
77971
|
if (!isNaN(parsed) && isFinite(parsed)) {
|
|
77882
77972
|
level = Math.floor(Math.max(0, parsed));
|
|
77883
77973
|
}
|
|
77884
|
-
|
|
77974
|
+
logger36.debug("Listing components", { level });
|
|
77885
77975
|
return ctx.services.character.listAvailableComponents(level);
|
|
77886
77976
|
}
|
|
77887
|
-
var
|
|
77977
|
+
var logger36, get, getByUserId, create, update2, equipAccessory, removeAccessory, character2;
|
|
77888
77978
|
var init_character_controller = __esm(() => {
|
|
77889
77979
|
init_esm();
|
|
77890
77980
|
init_schemas_index();
|
|
77891
77981
|
init_src2();
|
|
77892
77982
|
init_errors();
|
|
77893
77983
|
init_utils11();
|
|
77894
|
-
|
|
77984
|
+
logger36 = log.scope("CharacterController");
|
|
77895
77985
|
get = requireAuth(async (ctx) => {
|
|
77896
|
-
|
|
77986
|
+
logger36.debug("Getting character", { userId: ctx.user.id });
|
|
77897
77987
|
return ctx.services.character.getByUser(ctx.user);
|
|
77898
77988
|
});
|
|
77899
77989
|
getByUserId = requireAuth(async (ctx) => {
|
|
@@ -77901,7 +77991,7 @@ var init_character_controller = __esm(() => {
|
|
|
77901
77991
|
if (!userId) {
|
|
77902
77992
|
throw ApiError.badRequest("User ID is required in the URL path");
|
|
77903
77993
|
}
|
|
77904
|
-
|
|
77994
|
+
logger36.debug("Getting character by user ID", { requestedUserId: userId });
|
|
77905
77995
|
return ctx.services.character.getByUserId(userId);
|
|
77906
77996
|
});
|
|
77907
77997
|
create = requireAuth(async (ctx) => {
|
|
@@ -77912,12 +78002,12 @@ var init_character_controller = __esm(() => {
|
|
|
77912
78002
|
} catch (error2) {
|
|
77913
78003
|
if (error2 instanceof exports_external.ZodError) {
|
|
77914
78004
|
const details = formatZodError(error2);
|
|
77915
|
-
|
|
78005
|
+
logger36.warn("Create character validation failed", { details });
|
|
77916
78006
|
throw ApiError.unprocessableEntity("Invalid request body", details);
|
|
77917
78007
|
}
|
|
77918
78008
|
throw ApiError.badRequest("Invalid JSON body");
|
|
77919
78009
|
}
|
|
77920
|
-
|
|
78010
|
+
logger36.debug("Creating character", {
|
|
77921
78011
|
userId: ctx.user.id,
|
|
77922
78012
|
bodyComponentId: body2.bodyComponentId,
|
|
77923
78013
|
hairstyleComponentId: body2.hairstyleComponentId
|
|
@@ -77932,12 +78022,12 @@ var init_character_controller = __esm(() => {
|
|
|
77932
78022
|
} catch (error2) {
|
|
77933
78023
|
if (error2 instanceof exports_external.ZodError) {
|
|
77934
78024
|
const details = formatZodError(error2);
|
|
77935
|
-
|
|
78025
|
+
logger36.warn("Update character validation failed", { details });
|
|
77936
78026
|
throw ApiError.unprocessableEntity("Invalid request body", details);
|
|
77937
78027
|
}
|
|
77938
78028
|
throw ApiError.badRequest("Invalid JSON body");
|
|
77939
78029
|
}
|
|
77940
|
-
|
|
78030
|
+
logger36.debug("Updating character", {
|
|
77941
78031
|
userId: ctx.user.id,
|
|
77942
78032
|
bodyComponentId: body2.bodyComponentId,
|
|
77943
78033
|
hairstyleComponentId: body2.hairstyleComponentId,
|
|
@@ -77953,12 +78043,12 @@ var init_character_controller = __esm(() => {
|
|
|
77953
78043
|
} catch (error2) {
|
|
77954
78044
|
if (error2 instanceof exports_external.ZodError) {
|
|
77955
78045
|
const details = formatZodError(error2);
|
|
77956
|
-
|
|
78046
|
+
logger36.warn("Equip accessory validation failed", { details });
|
|
77957
78047
|
throw ApiError.unprocessableEntity("Invalid request body", details);
|
|
77958
78048
|
}
|
|
77959
78049
|
throw ApiError.badRequest("Invalid JSON body");
|
|
77960
78050
|
}
|
|
77961
|
-
|
|
78051
|
+
logger36.debug("Equipping accessory", {
|
|
77962
78052
|
userId: ctx.user.id,
|
|
77963
78053
|
slot: body2.slot,
|
|
77964
78054
|
accessoryComponentId: body2.accessoryComponentId
|
|
@@ -77970,7 +78060,7 @@ var init_character_controller = __esm(() => {
|
|
|
77970
78060
|
if (!slot) {
|
|
77971
78061
|
throw ApiError.badRequest("Slot is required in the URL path");
|
|
77972
78062
|
}
|
|
77973
|
-
|
|
78063
|
+
logger36.debug("Removing accessory", { userId: ctx.user.id, slot });
|
|
77974
78064
|
await ctx.services.character.removeAccessory(slot, ctx.user);
|
|
77975
78065
|
return { success: true };
|
|
77976
78066
|
});
|
|
@@ -77986,7 +78076,7 @@ var init_character_controller = __esm(() => {
|
|
|
77986
78076
|
});
|
|
77987
78077
|
|
|
77988
78078
|
// ../api-core/src/controllers/currency.controller.ts
|
|
77989
|
-
var
|
|
78079
|
+
var logger37, list, getById, create2, update3, remove, currencyController;
|
|
77990
78080
|
var init_currency_controller = __esm(() => {
|
|
77991
78081
|
init_esm();
|
|
77992
78082
|
init_schemas_index();
|
|
@@ -77994,9 +78084,9 @@ var init_currency_controller = __esm(() => {
|
|
|
77994
78084
|
init_src4();
|
|
77995
78085
|
init_errors();
|
|
77996
78086
|
init_utils11();
|
|
77997
|
-
|
|
78087
|
+
logger37 = log.scope("CurrencyController");
|
|
77998
78088
|
list = requireAuth(async (ctx) => {
|
|
77999
|
-
|
|
78089
|
+
logger37.debug("Listing currencies", { userId: ctx.user.id });
|
|
78000
78090
|
return ctx.services.currency.list();
|
|
78001
78091
|
});
|
|
78002
78092
|
getById = requireAuth(async (ctx) => {
|
|
@@ -78007,7 +78097,7 @@ var init_currency_controller = __esm(() => {
|
|
|
78007
78097
|
if (!isValidUUID(currencyId)) {
|
|
78008
78098
|
throw ApiError.unprocessableEntity("currencyId must be a valid UUID format");
|
|
78009
78099
|
}
|
|
78010
|
-
|
|
78100
|
+
logger37.debug("Getting currency", { userId: ctx.user.id, currencyId });
|
|
78011
78101
|
return ctx.services.currency.getById(currencyId);
|
|
78012
78102
|
});
|
|
78013
78103
|
create2 = requireAdmin(async (ctx) => {
|
|
@@ -78018,12 +78108,12 @@ var init_currency_controller = __esm(() => {
|
|
|
78018
78108
|
} catch (error2) {
|
|
78019
78109
|
if (error2 instanceof exports_external.ZodError) {
|
|
78020
78110
|
const details = formatZodError(error2);
|
|
78021
|
-
|
|
78111
|
+
logger37.warn("Create currency validation failed", { details });
|
|
78022
78112
|
throw ApiError.unprocessableEntity("Validation failed", details);
|
|
78023
78113
|
}
|
|
78024
78114
|
throw ApiError.badRequest("Invalid JSON body");
|
|
78025
78115
|
}
|
|
78026
|
-
|
|
78116
|
+
logger37.debug("Creating currency", {
|
|
78027
78117
|
userId: ctx.user.id,
|
|
78028
78118
|
symbol: body2.symbol,
|
|
78029
78119
|
itemId: body2.itemId,
|
|
@@ -78046,12 +78136,12 @@ var init_currency_controller = __esm(() => {
|
|
|
78046
78136
|
} catch (error2) {
|
|
78047
78137
|
if (error2 instanceof exports_external.ZodError) {
|
|
78048
78138
|
const details = formatZodError(error2);
|
|
78049
|
-
|
|
78139
|
+
logger37.warn("Update currency validation failed", { details });
|
|
78050
78140
|
throw ApiError.unprocessableEntity("Validation failed", details);
|
|
78051
78141
|
}
|
|
78052
78142
|
throw ApiError.badRequest("Invalid JSON body");
|
|
78053
78143
|
}
|
|
78054
|
-
|
|
78144
|
+
logger37.debug("Updating currency", {
|
|
78055
78145
|
userId: ctx.user.id,
|
|
78056
78146
|
currencyId,
|
|
78057
78147
|
symbol: body2.symbol,
|
|
@@ -78068,7 +78158,7 @@ var init_currency_controller = __esm(() => {
|
|
|
78068
78158
|
if (!isValidUUID(currencyId)) {
|
|
78069
78159
|
throw ApiError.unprocessableEntity("currencyId must be a valid UUID format");
|
|
78070
78160
|
}
|
|
78071
|
-
|
|
78161
|
+
logger37.debug("Deleting currency", { userId: ctx.user.id, currencyId });
|
|
78072
78162
|
await ctx.services.currency.delete(currencyId);
|
|
78073
78163
|
});
|
|
78074
78164
|
currencyController = {
|
|
@@ -78081,14 +78171,14 @@ var init_currency_controller = __esm(() => {
|
|
|
78081
78171
|
});
|
|
78082
78172
|
|
|
78083
78173
|
// ../api-core/src/controllers/database.controller.ts
|
|
78084
|
-
var
|
|
78174
|
+
var logger38, reset;
|
|
78085
78175
|
var init_database_controller = __esm(() => {
|
|
78086
78176
|
init_esm();
|
|
78087
78177
|
init_schemas_index();
|
|
78088
78178
|
init_src2();
|
|
78089
78179
|
init_errors();
|
|
78090
78180
|
init_utils11();
|
|
78091
|
-
|
|
78181
|
+
logger38 = log.scope("DatabaseController");
|
|
78092
78182
|
reset = requireDeveloper(async (ctx) => {
|
|
78093
78183
|
const slug2 = ctx.params.slug;
|
|
78094
78184
|
if (!slug2) {
|
|
@@ -78101,11 +78191,11 @@ var init_database_controller = __esm(() => {
|
|
|
78101
78191
|
} catch (error2) {
|
|
78102
78192
|
if (error2 instanceof exports_external.ZodError) {
|
|
78103
78193
|
const details = formatZodError(error2);
|
|
78104
|
-
|
|
78194
|
+
logger38.warn("Database reset validation failed", { details });
|
|
78105
78195
|
throw ApiError.unprocessableEntity("Validation failed", details);
|
|
78106
78196
|
}
|
|
78107
78197
|
}
|
|
78108
|
-
|
|
78198
|
+
logger38.debug("Resetting database", {
|
|
78109
78199
|
userId: ctx.user.id,
|
|
78110
78200
|
slug: slug2,
|
|
78111
78201
|
hasSchema: !!body2.schema
|
|
@@ -87201,28 +87291,28 @@ var init_zip = __esm(() => {
|
|
|
87201
87291
|
});
|
|
87202
87292
|
|
|
87203
87293
|
// ../api-core/src/controllers/deploy.controller.ts
|
|
87204
|
-
var
|
|
87294
|
+
var logger39;
|
|
87205
87295
|
var init_deploy_controller = __esm(() => {
|
|
87206
87296
|
init_schemas_index();
|
|
87207
87297
|
init_src2();
|
|
87208
87298
|
init_zip();
|
|
87209
87299
|
init_errors();
|
|
87210
87300
|
init_utils11();
|
|
87211
|
-
|
|
87301
|
+
logger39 = log.scope("DeployController");
|
|
87212
87302
|
});
|
|
87213
87303
|
|
|
87214
87304
|
// ../api-core/src/controllers/developer.controller.ts
|
|
87215
|
-
var
|
|
87305
|
+
var logger40, apply, getStatus, developer;
|
|
87216
87306
|
var init_developer_controller = __esm(() => {
|
|
87217
87307
|
init_src2();
|
|
87218
87308
|
init_utils11();
|
|
87219
|
-
|
|
87309
|
+
logger40 = log.scope("DeveloperController");
|
|
87220
87310
|
apply = requireAuth(async (ctx) => {
|
|
87221
|
-
|
|
87311
|
+
logger40.debug("Applying for developer status", { userId: ctx.user.id });
|
|
87222
87312
|
await ctx.services.developer.apply(ctx.user);
|
|
87223
87313
|
});
|
|
87224
87314
|
getStatus = requireAuth(async (ctx) => {
|
|
87225
|
-
|
|
87315
|
+
logger40.debug("Getting developer status", { userId: ctx.user.id });
|
|
87226
87316
|
const status = await ctx.services.developer.getStatus(ctx.user.id);
|
|
87227
87317
|
return { status };
|
|
87228
87318
|
});
|
|
@@ -87233,7 +87323,7 @@ var init_developer_controller = __esm(() => {
|
|
|
87233
87323
|
});
|
|
87234
87324
|
|
|
87235
87325
|
// ../api-core/src/controllers/domain.controller.ts
|
|
87236
|
-
var
|
|
87326
|
+
var logger41, add, list2, getStatus2, remove2, domains2;
|
|
87237
87327
|
var init_domain_controller = __esm(() => {
|
|
87238
87328
|
init_esm();
|
|
87239
87329
|
init_schemas_index();
|
|
@@ -87241,7 +87331,7 @@ var init_domain_controller = __esm(() => {
|
|
|
87241
87331
|
init_config2();
|
|
87242
87332
|
init_errors();
|
|
87243
87333
|
init_utils11();
|
|
87244
|
-
|
|
87334
|
+
logger41 = log.scope("DomainController");
|
|
87245
87335
|
add = requireDeveloper(async (ctx) => {
|
|
87246
87336
|
const slug2 = ctx.params.slug;
|
|
87247
87337
|
if (!slug2) {
|
|
@@ -87254,12 +87344,12 @@ var init_domain_controller = __esm(() => {
|
|
|
87254
87344
|
} catch (error2) {
|
|
87255
87345
|
if (error2 instanceof exports_external.ZodError) {
|
|
87256
87346
|
const details = formatZodError(error2);
|
|
87257
|
-
|
|
87347
|
+
logger41.warn("Add domain validation failed", { details });
|
|
87258
87348
|
throw ApiError.unprocessableEntity("Validation failed", details);
|
|
87259
87349
|
}
|
|
87260
87350
|
throw ApiError.badRequest("Invalid JSON body");
|
|
87261
87351
|
}
|
|
87262
|
-
|
|
87352
|
+
logger41.debug("Adding domain", { userId: ctx.user.id, slug: slug2, hostname: body2.hostname });
|
|
87263
87353
|
return ctx.services.domain.add(slug2, body2.hostname, body2.environment, ctx.user);
|
|
87264
87354
|
});
|
|
87265
87355
|
list2 = requireDeveloper(async (ctx) => {
|
|
@@ -87268,7 +87358,7 @@ var init_domain_controller = __esm(() => {
|
|
|
87268
87358
|
throw ApiError.badRequest("Missing game slug");
|
|
87269
87359
|
}
|
|
87270
87360
|
const environment = getPlatformEnvironment(ctx.config);
|
|
87271
|
-
|
|
87361
|
+
logger41.debug("Listing domains", { userId: ctx.user.id, slug: slug2, environment });
|
|
87272
87362
|
const domains2 = await ctx.services.domain.list(slug2, environment, ctx.user);
|
|
87273
87363
|
return { domains: domains2 };
|
|
87274
87364
|
});
|
|
@@ -87283,7 +87373,7 @@ var init_domain_controller = __esm(() => {
|
|
|
87283
87373
|
}
|
|
87284
87374
|
const refresh = ctx.url.searchParams.get("refresh") === "true";
|
|
87285
87375
|
const environment = getPlatformEnvironment(ctx.config);
|
|
87286
|
-
|
|
87376
|
+
logger41.debug("Getting domain status", { userId: ctx.user.id, slug: slug2, hostname, refresh });
|
|
87287
87377
|
return ctx.services.domain.getStatus(slug2, hostname, environment, ctx.user, refresh);
|
|
87288
87378
|
});
|
|
87289
87379
|
remove2 = requireDeveloper(async (ctx) => {
|
|
@@ -87296,7 +87386,7 @@ var init_domain_controller = __esm(() => {
|
|
|
87296
87386
|
throw ApiError.badRequest("Missing hostname");
|
|
87297
87387
|
}
|
|
87298
87388
|
const environment = ctx.config.stage === "production" ? "production" : "staging";
|
|
87299
|
-
|
|
87389
|
+
logger41.debug("Removing domain", { userId: ctx.user.id, slug: slug2, hostname, environment });
|
|
87300
87390
|
await ctx.services.domain.delete(slug2, hostname, environment, ctx.user);
|
|
87301
87391
|
});
|
|
87302
87392
|
domains2 = {
|
|
@@ -87308,7 +87398,7 @@ var init_domain_controller = __esm(() => {
|
|
|
87308
87398
|
});
|
|
87309
87399
|
|
|
87310
87400
|
// ../api-core/src/controllers/game.controller.ts
|
|
87311
|
-
var
|
|
87401
|
+
var logger42, list3, getById2, getBySlug, upsertBySlug, remove3, games2;
|
|
87312
87402
|
var init_game_controller = __esm(() => {
|
|
87313
87403
|
init_esm();
|
|
87314
87404
|
init_schemas_index();
|
|
@@ -87316,9 +87406,9 @@ var init_game_controller = __esm(() => {
|
|
|
87316
87406
|
init_src4();
|
|
87317
87407
|
init_errors();
|
|
87318
87408
|
init_utils11();
|
|
87319
|
-
|
|
87409
|
+
logger42 = log.scope("GameController");
|
|
87320
87410
|
list3 = requireAuth(async (ctx) => {
|
|
87321
|
-
|
|
87411
|
+
logger42.debug("Listing games", { userId: ctx.user.id });
|
|
87322
87412
|
return ctx.services.game.list();
|
|
87323
87413
|
});
|
|
87324
87414
|
getById2 = requireAuth(async (ctx) => {
|
|
@@ -87329,7 +87419,7 @@ var init_game_controller = __esm(() => {
|
|
|
87329
87419
|
if (!isValidUUID(gameId)) {
|
|
87330
87420
|
throw ApiError.unprocessableEntity("gameId must be a valid UUID format");
|
|
87331
87421
|
}
|
|
87332
|
-
|
|
87422
|
+
logger42.debug("Getting game by ID", { userId: ctx.user.id, gameId });
|
|
87333
87423
|
return ctx.services.game.getById(gameId);
|
|
87334
87424
|
});
|
|
87335
87425
|
getBySlug = requireAuth(async (ctx) => {
|
|
@@ -87337,7 +87427,7 @@ var init_game_controller = __esm(() => {
|
|
|
87337
87427
|
if (!slug2) {
|
|
87338
87428
|
throw ApiError.badRequest("Missing game slug");
|
|
87339
87429
|
}
|
|
87340
|
-
|
|
87430
|
+
logger42.debug("Getting game by slug", { userId: ctx.user.id, slug: slug2 });
|
|
87341
87431
|
return ctx.services.game.getBySlug(slug2);
|
|
87342
87432
|
});
|
|
87343
87433
|
upsertBySlug = requireAuth(async (ctx) => {
|
|
@@ -87352,12 +87442,12 @@ var init_game_controller = __esm(() => {
|
|
|
87352
87442
|
} catch (error2) {
|
|
87353
87443
|
if (error2 instanceof exports_external.ZodError) {
|
|
87354
87444
|
const details = formatZodError(error2);
|
|
87355
|
-
|
|
87445
|
+
logger42.warn("Upsert game validation failed", { details });
|
|
87356
87446
|
throw ApiError.unprocessableEntity("Validation failed", details);
|
|
87357
87447
|
}
|
|
87358
87448
|
throw ApiError.badRequest("Invalid JSON body");
|
|
87359
87449
|
}
|
|
87360
|
-
|
|
87450
|
+
logger42.debug("Upserting game", { userId: ctx.user.id, slug: slug2, displayName: body2.displayName });
|
|
87361
87451
|
return ctx.services.game.upsertBySlug(slug2, body2, ctx.user);
|
|
87362
87452
|
});
|
|
87363
87453
|
remove3 = requireAuth(async (ctx) => {
|
|
@@ -87368,7 +87458,7 @@ var init_game_controller = __esm(() => {
|
|
|
87368
87458
|
if (!isValidUUID(gameId)) {
|
|
87369
87459
|
throw ApiError.unprocessableEntity("gameId must be a valid UUID format");
|
|
87370
87460
|
}
|
|
87371
|
-
|
|
87461
|
+
logger42.debug("Deleting game", { userId: ctx.user.id, gameId });
|
|
87372
87462
|
await ctx.services.game.delete(gameId, ctx.user);
|
|
87373
87463
|
});
|
|
87374
87464
|
games2 = {
|
|
@@ -87381,16 +87471,16 @@ var init_game_controller = __esm(() => {
|
|
|
87381
87471
|
});
|
|
87382
87472
|
|
|
87383
87473
|
// ../api-core/src/controllers/inventory.controller.ts
|
|
87384
|
-
var
|
|
87474
|
+
var logger43, list4, addItem, removeItem, inventory;
|
|
87385
87475
|
var init_inventory_controller = __esm(() => {
|
|
87386
87476
|
init_esm();
|
|
87387
87477
|
init_schemas_index();
|
|
87388
87478
|
init_src2();
|
|
87389
87479
|
init_errors();
|
|
87390
87480
|
init_utils11();
|
|
87391
|
-
|
|
87481
|
+
logger43 = log.scope("InventoryController");
|
|
87392
87482
|
list4 = requireAuth(async (ctx) => {
|
|
87393
|
-
|
|
87483
|
+
logger43.debug("Listing inventory", { userId: ctx.user.id });
|
|
87394
87484
|
return ctx.services.inventory.list(ctx.user);
|
|
87395
87485
|
});
|
|
87396
87486
|
addItem = requireAuth(async (ctx) => {
|
|
@@ -87401,12 +87491,12 @@ var init_inventory_controller = __esm(() => {
|
|
|
87401
87491
|
} catch (error2) {
|
|
87402
87492
|
if (error2 instanceof exports_external.ZodError) {
|
|
87403
87493
|
const details = formatZodError(error2);
|
|
87404
|
-
|
|
87494
|
+
logger43.warn("Add inventory item validation failed", { details });
|
|
87405
87495
|
throw ApiError.unprocessableEntity("Invalid request body", details);
|
|
87406
87496
|
}
|
|
87407
87497
|
throw ApiError.badRequest("Invalid JSON body");
|
|
87408
87498
|
}
|
|
87409
|
-
|
|
87499
|
+
logger43.debug("Adding item", {
|
|
87410
87500
|
userId: ctx.user.id,
|
|
87411
87501
|
itemId: body2.itemId,
|
|
87412
87502
|
qty: body2.qty
|
|
@@ -87421,12 +87511,12 @@ var init_inventory_controller = __esm(() => {
|
|
|
87421
87511
|
} catch (error2) {
|
|
87422
87512
|
if (error2 instanceof exports_external.ZodError) {
|
|
87423
87513
|
const details = formatZodError(error2);
|
|
87424
|
-
|
|
87514
|
+
logger43.warn("Remove inventory item validation failed", { details });
|
|
87425
87515
|
throw ApiError.unprocessableEntity("Invalid request body", details);
|
|
87426
87516
|
}
|
|
87427
87517
|
throw ApiError.badRequest("Invalid JSON body");
|
|
87428
87518
|
}
|
|
87429
|
-
|
|
87519
|
+
logger43.debug("Removing item", {
|
|
87430
87520
|
userId: ctx.user.id,
|
|
87431
87521
|
itemId: body2.itemId,
|
|
87432
87522
|
qty: body2.qty
|
|
@@ -87441,7 +87531,7 @@ var init_inventory_controller = __esm(() => {
|
|
|
87441
87531
|
});
|
|
87442
87532
|
|
|
87443
87533
|
// ../api-core/src/controllers/item.controller.ts
|
|
87444
|
-
var
|
|
87534
|
+
var logger44, list5, getById3, resolve2, create3, update4, remove4, listByGame, createForGame, updateForGame, deleteForGame, items2;
|
|
87445
87535
|
var init_item_controller = __esm(() => {
|
|
87446
87536
|
init_esm();
|
|
87447
87537
|
init_schemas_index();
|
|
@@ -87449,10 +87539,10 @@ var init_item_controller = __esm(() => {
|
|
|
87449
87539
|
init_src4();
|
|
87450
87540
|
init_errors();
|
|
87451
87541
|
init_utils11();
|
|
87452
|
-
|
|
87542
|
+
logger44 = log.scope("ItemController");
|
|
87453
87543
|
list5 = requireAuth(async (ctx) => {
|
|
87454
87544
|
const gameId = ctx.url.searchParams.get("gameId") || undefined;
|
|
87455
|
-
|
|
87545
|
+
logger44.debug("Listing items", { userId: ctx.user.id, gameId });
|
|
87456
87546
|
return ctx.services.item.list(gameId);
|
|
87457
87547
|
});
|
|
87458
87548
|
getById3 = requireAuth(async (ctx) => {
|
|
@@ -87463,7 +87553,7 @@ var init_item_controller = __esm(() => {
|
|
|
87463
87553
|
if (!isValidUUID(itemId)) {
|
|
87464
87554
|
throw ApiError.unprocessableEntity("itemId must be a valid UUID format");
|
|
87465
87555
|
}
|
|
87466
|
-
|
|
87556
|
+
logger44.debug("Getting item", { userId: ctx.user.id, itemId });
|
|
87467
87557
|
return ctx.services.item.getById(itemId);
|
|
87468
87558
|
});
|
|
87469
87559
|
resolve2 = requireAuth(async (ctx) => {
|
|
@@ -87475,7 +87565,7 @@ var init_item_controller = __esm(() => {
|
|
|
87475
87565
|
if (gameId && !isValidUUID(gameId)) {
|
|
87476
87566
|
throw ApiError.unprocessableEntity("gameId must be a valid UUID format");
|
|
87477
87567
|
}
|
|
87478
|
-
|
|
87568
|
+
logger44.debug("Resolving item", { userId: ctx.user.id, slug: slug2, gameId });
|
|
87479
87569
|
return ctx.services.item.resolveBySlug(slug2, gameId);
|
|
87480
87570
|
});
|
|
87481
87571
|
create3 = requireRole(["admin"], async (ctx) => {
|
|
@@ -87486,12 +87576,12 @@ var init_item_controller = __esm(() => {
|
|
|
87486
87576
|
} catch (error2) {
|
|
87487
87577
|
if (error2 instanceof exports_external.ZodError) {
|
|
87488
87578
|
const details = formatZodError(error2);
|
|
87489
|
-
|
|
87579
|
+
logger44.warn("Create item validation failed", { details });
|
|
87490
87580
|
throw ApiError.unprocessableEntity("Validation failed", details);
|
|
87491
87581
|
}
|
|
87492
87582
|
throw ApiError.badRequest("Invalid JSON body");
|
|
87493
87583
|
}
|
|
87494
|
-
|
|
87584
|
+
logger44.debug("Creating item", {
|
|
87495
87585
|
userId: ctx.user.id,
|
|
87496
87586
|
slug: body2.slug,
|
|
87497
87587
|
displayName: body2.displayName
|
|
@@ -87513,7 +87603,7 @@ var init_item_controller = __esm(() => {
|
|
|
87513
87603
|
} catch (error2) {
|
|
87514
87604
|
if (error2 instanceof exports_external.ZodError) {
|
|
87515
87605
|
const details = formatZodError(error2);
|
|
87516
|
-
|
|
87606
|
+
logger44.warn("Update item validation failed", { details });
|
|
87517
87607
|
throw ApiError.unprocessableEntity("Validation failed", details);
|
|
87518
87608
|
}
|
|
87519
87609
|
throw ApiError.badRequest("Invalid JSON body");
|
|
@@ -87521,7 +87611,7 @@ var init_item_controller = __esm(() => {
|
|
|
87521
87611
|
if (Object.keys(body2).length === 0) {
|
|
87522
87612
|
throw ApiError.badRequest("No update data provided");
|
|
87523
87613
|
}
|
|
87524
|
-
|
|
87614
|
+
logger44.debug("Updating item", {
|
|
87525
87615
|
userId: ctx.user.id,
|
|
87526
87616
|
itemId,
|
|
87527
87617
|
slug: body2.slug,
|
|
@@ -87538,7 +87628,7 @@ var init_item_controller = __esm(() => {
|
|
|
87538
87628
|
if (!isValidUUID(itemId)) {
|
|
87539
87629
|
throw ApiError.unprocessableEntity("itemId must be a valid UUID format");
|
|
87540
87630
|
}
|
|
87541
|
-
|
|
87631
|
+
logger44.debug("Deleting item", { userId: ctx.user.id, itemId });
|
|
87542
87632
|
await ctx.services.item.delete(itemId);
|
|
87543
87633
|
});
|
|
87544
87634
|
listByGame = requireAuth(async (ctx) => {
|
|
@@ -87549,7 +87639,7 @@ var init_item_controller = __esm(() => {
|
|
|
87549
87639
|
if (!isValidUUID(gameId)) {
|
|
87550
87640
|
throw ApiError.unprocessableEntity("gameId must be a valid UUID format");
|
|
87551
87641
|
}
|
|
87552
|
-
|
|
87642
|
+
logger44.debug("Listing game items", { userId: ctx.user.id, gameId });
|
|
87553
87643
|
return ctx.services.item.listByGame(gameId);
|
|
87554
87644
|
});
|
|
87555
87645
|
createForGame = requireAuth(async (ctx) => {
|
|
@@ -87567,12 +87657,12 @@ var init_item_controller = __esm(() => {
|
|
|
87567
87657
|
} catch (error2) {
|
|
87568
87658
|
if (error2 instanceof exports_external.ZodError) {
|
|
87569
87659
|
const details = formatZodError(error2);
|
|
87570
|
-
|
|
87660
|
+
logger44.warn("Create game item validation failed", { details });
|
|
87571
87661
|
throw ApiError.unprocessableEntity("Validation failed", details);
|
|
87572
87662
|
}
|
|
87573
87663
|
throw ApiError.badRequest("Invalid JSON body");
|
|
87574
87664
|
}
|
|
87575
|
-
|
|
87665
|
+
logger44.debug("Creating game item", {
|
|
87576
87666
|
userId: ctx.user.id,
|
|
87577
87667
|
gameId,
|
|
87578
87668
|
slug: body2.slug,
|
|
@@ -87599,7 +87689,7 @@ var init_item_controller = __esm(() => {
|
|
|
87599
87689
|
} catch (error2) {
|
|
87600
87690
|
if (error2 instanceof exports_external.ZodError) {
|
|
87601
87691
|
const details = formatZodError(error2);
|
|
87602
|
-
|
|
87692
|
+
logger44.warn("Update game item validation failed", { details });
|
|
87603
87693
|
throw ApiError.unprocessableEntity("Validation failed", details);
|
|
87604
87694
|
}
|
|
87605
87695
|
throw ApiError.badRequest("Invalid JSON body");
|
|
@@ -87607,7 +87697,7 @@ var init_item_controller = __esm(() => {
|
|
|
87607
87697
|
if (Object.keys(body2).length === 0) {
|
|
87608
87698
|
throw ApiError.badRequest("No update data provided");
|
|
87609
87699
|
}
|
|
87610
|
-
|
|
87700
|
+
logger44.debug("Updating game item", {
|
|
87611
87701
|
userId: ctx.user.id,
|
|
87612
87702
|
gameId,
|
|
87613
87703
|
itemId,
|
|
@@ -87629,7 +87719,7 @@ var init_item_controller = __esm(() => {
|
|
|
87629
87719
|
if (!isValidUUID(itemId)) {
|
|
87630
87720
|
throw ApiError.unprocessableEntity("itemId must be a valid UUID format");
|
|
87631
87721
|
}
|
|
87632
|
-
|
|
87722
|
+
logger44.debug("Deleting game item", { userId: ctx.user.id, gameId, itemId });
|
|
87633
87723
|
await ctx.services.item.deleteForGame(gameId, itemId, ctx.user);
|
|
87634
87724
|
});
|
|
87635
87725
|
items2 = {
|
|
@@ -87647,7 +87737,7 @@ var init_item_controller = __esm(() => {
|
|
|
87647
87737
|
});
|
|
87648
87738
|
|
|
87649
87739
|
// ../api-core/src/controllers/leaderboard.controller.ts
|
|
87650
|
-
var
|
|
87740
|
+
var logger45, submitScore, getGlobalLeaderboard, getLeaderboard, getUserRank, getUserAllScores, getUserScores, leaderboard;
|
|
87651
87741
|
var init_leaderboard_controller = __esm(() => {
|
|
87652
87742
|
init_esm();
|
|
87653
87743
|
init_schemas_index();
|
|
@@ -87655,7 +87745,7 @@ var init_leaderboard_controller = __esm(() => {
|
|
|
87655
87745
|
init_src4();
|
|
87656
87746
|
init_errors();
|
|
87657
87747
|
init_utils11();
|
|
87658
|
-
|
|
87748
|
+
logger45 = log.scope("LeaderboardController");
|
|
87659
87749
|
submitScore = requireAuth(async (ctx) => {
|
|
87660
87750
|
const gameId = ctx.params.gameId;
|
|
87661
87751
|
if (!gameId) {
|
|
@@ -87668,12 +87758,12 @@ var init_leaderboard_controller = __esm(() => {
|
|
|
87668
87758
|
} catch (error2) {
|
|
87669
87759
|
if (error2 instanceof exports_external.ZodError) {
|
|
87670
87760
|
const details = formatZodError(error2);
|
|
87671
|
-
|
|
87761
|
+
logger45.warn("Submit score validation failed", { details });
|
|
87672
87762
|
throw ApiError.unprocessableEntity("Validation failed", details);
|
|
87673
87763
|
}
|
|
87674
87764
|
throw ApiError.badRequest("Invalid JSON body");
|
|
87675
87765
|
}
|
|
87676
|
-
|
|
87766
|
+
logger45.debug("Submitting score", {
|
|
87677
87767
|
userId: ctx.user.id,
|
|
87678
87768
|
gameId,
|
|
87679
87769
|
score: body2.score
|
|
@@ -87696,12 +87786,12 @@ var init_leaderboard_controller = __esm(() => {
|
|
|
87696
87786
|
} catch (error2) {
|
|
87697
87787
|
if (error2 instanceof exports_external.ZodError) {
|
|
87698
87788
|
const details = formatZodError(error2);
|
|
87699
|
-
|
|
87789
|
+
logger45.warn("Get global leaderboard query validation failed", { details });
|
|
87700
87790
|
throw ApiError.badRequest("Invalid query parameters", details);
|
|
87701
87791
|
}
|
|
87702
87792
|
throw ApiError.badRequest("Invalid query parameters");
|
|
87703
87793
|
}
|
|
87704
|
-
|
|
87794
|
+
logger45.debug("Getting global leaderboard", {
|
|
87705
87795
|
userId: ctx.user.id,
|
|
87706
87796
|
gameId,
|
|
87707
87797
|
...query
|
|
@@ -87724,12 +87814,12 @@ var init_leaderboard_controller = __esm(() => {
|
|
|
87724
87814
|
} catch (error2) {
|
|
87725
87815
|
if (error2 instanceof exports_external.ZodError) {
|
|
87726
87816
|
const details = formatZodError(error2);
|
|
87727
|
-
|
|
87817
|
+
logger45.warn("Get leaderboard query validation failed", { details });
|
|
87728
87818
|
throw ApiError.badRequest("Invalid query parameters", details);
|
|
87729
87819
|
}
|
|
87730
87820
|
throw ApiError.badRequest("Invalid query parameters");
|
|
87731
87821
|
}
|
|
87732
|
-
|
|
87822
|
+
logger45.debug("Getting leaderboard", {
|
|
87733
87823
|
userId: ctx.user.id,
|
|
87734
87824
|
gameId,
|
|
87735
87825
|
...query
|
|
@@ -87744,7 +87834,7 @@ var init_leaderboard_controller = __esm(() => {
|
|
|
87744
87834
|
if (!isValidUUID(userId)) {
|
|
87745
87835
|
throw ApiError.unprocessableEntity("userId must be a valid UUID format");
|
|
87746
87836
|
}
|
|
87747
|
-
|
|
87837
|
+
logger45.debug("Getting user rank", {
|
|
87748
87838
|
requesterId: ctx.user.id,
|
|
87749
87839
|
gameId,
|
|
87750
87840
|
targetUserId: userId
|
|
@@ -87762,7 +87852,7 @@ var init_leaderboard_controller = __esm(() => {
|
|
|
87762
87852
|
const url = ctx.url;
|
|
87763
87853
|
const limit = Math.min(Number(url.searchParams.get("limit") || "50"), 100);
|
|
87764
87854
|
const gameId = url.searchParams.get("gameId") || undefined;
|
|
87765
|
-
|
|
87855
|
+
logger45.debug("Getting user all scores", {
|
|
87766
87856
|
requesterId: ctx.user.id,
|
|
87767
87857
|
targetUserId: userId,
|
|
87768
87858
|
gameId,
|
|
@@ -87780,7 +87870,7 @@ var init_leaderboard_controller = __esm(() => {
|
|
|
87780
87870
|
}
|
|
87781
87871
|
const url = ctx.url;
|
|
87782
87872
|
const limit = Math.min(Number(url.searchParams.get("limit") || "10"), 100);
|
|
87783
|
-
|
|
87873
|
+
logger45.debug("Getting user scores", {
|
|
87784
87874
|
requesterId: ctx.user.id,
|
|
87785
87875
|
gameId,
|
|
87786
87876
|
targetUserId: userId,
|
|
@@ -87800,7 +87890,7 @@ var init_leaderboard_controller = __esm(() => {
|
|
|
87800
87890
|
|
|
87801
87891
|
// ../api-core/src/controllers/level.controller.ts
|
|
87802
87892
|
async function listConfigs(ctx) {
|
|
87803
|
-
|
|
87893
|
+
logger46.debug("Listing level configs");
|
|
87804
87894
|
return ctx.services.level.listConfigs();
|
|
87805
87895
|
}
|
|
87806
87896
|
async function getConfig(ctx) {
|
|
@@ -87812,21 +87902,21 @@ async function getConfig(ctx) {
|
|
|
87812
87902
|
if (isNaN(level) || level < 1) {
|
|
87813
87903
|
throw ApiError.badRequest("Level must be a positive integer");
|
|
87814
87904
|
}
|
|
87815
|
-
|
|
87905
|
+
logger46.debug("Getting level config", { level });
|
|
87816
87906
|
return ctx.services.level.getConfig(level);
|
|
87817
87907
|
}
|
|
87818
|
-
var
|
|
87908
|
+
var logger46, getByUser, getProgress, levels;
|
|
87819
87909
|
var init_level_controller = __esm(() => {
|
|
87820
87910
|
init_src2();
|
|
87821
87911
|
init_errors();
|
|
87822
87912
|
init_utils11();
|
|
87823
|
-
|
|
87913
|
+
logger46 = log.scope("LevelController");
|
|
87824
87914
|
getByUser = requireAuth(async (ctx) => {
|
|
87825
|
-
|
|
87915
|
+
logger46.debug("Getting user level", { userId: ctx.user.id });
|
|
87826
87916
|
return ctx.services.level.getByUser(ctx.user);
|
|
87827
87917
|
});
|
|
87828
87918
|
getProgress = requireAuth(async (ctx) => {
|
|
87829
|
-
|
|
87919
|
+
logger46.debug("Getting level progress", { userId: ctx.user.id });
|
|
87830
87920
|
return ctx.services.level.getProgress(ctx.user);
|
|
87831
87921
|
});
|
|
87832
87922
|
levels = {
|
|
@@ -87837,6 +87927,42 @@ var init_level_controller = __esm(() => {
|
|
|
87837
87927
|
};
|
|
87838
87928
|
});
|
|
87839
87929
|
|
|
87930
|
+
// ../api-core/src/controllers/logs.controller.ts
|
|
87931
|
+
var logger47, generateToken, logs;
|
|
87932
|
+
var init_logs_controller = __esm(() => {
|
|
87933
|
+
init_src2();
|
|
87934
|
+
init_errors();
|
|
87935
|
+
init_utils11();
|
|
87936
|
+
logger47 = log.scope("LogsController");
|
|
87937
|
+
generateToken = requireDeveloper(async (ctx) => {
|
|
87938
|
+
const slug2 = ctx.params.slug;
|
|
87939
|
+
if (!slug2) {
|
|
87940
|
+
throw ApiError.badRequest("Missing game slug");
|
|
87941
|
+
}
|
|
87942
|
+
let body2;
|
|
87943
|
+
try {
|
|
87944
|
+
const json4 = await ctx.request.json();
|
|
87945
|
+
if (json4.environment !== "staging" && json4.environment !== "production") {
|
|
87946
|
+
throw ApiError.badRequest('Invalid environment. Must be "staging" or "production".');
|
|
87947
|
+
}
|
|
87948
|
+
body2 = json4;
|
|
87949
|
+
} catch (error2) {
|
|
87950
|
+
if (error2 instanceof ApiError)
|
|
87951
|
+
throw error2;
|
|
87952
|
+
throw ApiError.badRequest("Invalid JSON body");
|
|
87953
|
+
}
|
|
87954
|
+
logger47.debug("Generating log stream token", {
|
|
87955
|
+
userId: ctx.user.id,
|
|
87956
|
+
slug: slug2,
|
|
87957
|
+
environment: body2.environment
|
|
87958
|
+
});
|
|
87959
|
+
return ctx.services.logs.generateToken(ctx.user, slug2, body2.environment);
|
|
87960
|
+
});
|
|
87961
|
+
logs = {
|
|
87962
|
+
generateToken
|
|
87963
|
+
};
|
|
87964
|
+
});
|
|
87965
|
+
|
|
87840
87966
|
// ../api-core/src/controllers/lti.controller.ts
|
|
87841
87967
|
async function launch(ctx) {
|
|
87842
87968
|
const formData = await ctx.request.formData();
|
|
@@ -87845,17 +87971,17 @@ async function launch(ctx) {
|
|
|
87845
87971
|
throw ApiError.badRequest("Missing or invalid id_token");
|
|
87846
87972
|
}
|
|
87847
87973
|
const currentHost = ctx.url.hostname;
|
|
87848
|
-
|
|
87974
|
+
logger48.debug("Processing launch", { host: currentHost });
|
|
87849
87975
|
return ctx.services.lti.processLaunch(idToken, currentHost);
|
|
87850
87976
|
}
|
|
87851
|
-
var
|
|
87977
|
+
var logger48, getStatus3, lti;
|
|
87852
87978
|
var init_lti_controller = __esm(() => {
|
|
87853
87979
|
init_src2();
|
|
87854
87980
|
init_errors();
|
|
87855
87981
|
init_utils11();
|
|
87856
|
-
|
|
87982
|
+
logger48 = log.scope("LtiController");
|
|
87857
87983
|
getStatus3 = requireAuth(async (ctx) => {
|
|
87858
|
-
|
|
87984
|
+
logger48.debug("Getting status", { userId: ctx.user.id });
|
|
87859
87985
|
return ctx.services.lti.getStatus(ctx.user);
|
|
87860
87986
|
});
|
|
87861
87987
|
lti = {
|
|
@@ -87865,7 +87991,7 @@ var init_lti_controller = __esm(() => {
|
|
|
87865
87991
|
});
|
|
87866
87992
|
|
|
87867
87993
|
// ../api-core/src/controllers/map.controller.ts
|
|
87868
|
-
var
|
|
87994
|
+
var logger49, getByIdentifier, getElements, getObjects, createObject, deleteObject, maps2;
|
|
87869
87995
|
var init_map_controller = __esm(() => {
|
|
87870
87996
|
init_esm();
|
|
87871
87997
|
init_schemas_index();
|
|
@@ -87873,13 +87999,13 @@ var init_map_controller = __esm(() => {
|
|
|
87873
87999
|
init_src4();
|
|
87874
88000
|
init_errors();
|
|
87875
88001
|
init_utils11();
|
|
87876
|
-
|
|
88002
|
+
logger49 = log.scope("MapController");
|
|
87877
88003
|
getByIdentifier = requireAuth(async (ctx) => {
|
|
87878
88004
|
const identifier = ctx.params.identifier;
|
|
87879
88005
|
if (!identifier) {
|
|
87880
88006
|
throw ApiError.badRequest("Missing map identifier");
|
|
87881
88007
|
}
|
|
87882
|
-
|
|
88008
|
+
logger49.debug("Getting map", { userId: ctx.user.id, identifier });
|
|
87883
88009
|
return ctx.services.map.getByIdentifier(identifier);
|
|
87884
88010
|
});
|
|
87885
88011
|
getElements = requireAuth(async (ctx) => {
|
|
@@ -87890,7 +88016,7 @@ var init_map_controller = __esm(() => {
|
|
|
87890
88016
|
if (!isValidUUID(mapId)) {
|
|
87891
88017
|
throw ApiError.unprocessableEntity("mapId must be a valid UUID format");
|
|
87892
88018
|
}
|
|
87893
|
-
|
|
88019
|
+
logger49.debug("Getting map elements", { userId: ctx.user.id, mapId });
|
|
87894
88020
|
return ctx.services.map.getElements(mapId);
|
|
87895
88021
|
});
|
|
87896
88022
|
getObjects = requireAuth(async (ctx) => {
|
|
@@ -87901,7 +88027,7 @@ var init_map_controller = __esm(() => {
|
|
|
87901
88027
|
if (!isValidUUID(mapId)) {
|
|
87902
88028
|
throw ApiError.unprocessableEntity("mapId must be a valid UUID format");
|
|
87903
88029
|
}
|
|
87904
|
-
|
|
88030
|
+
logger49.debug("Getting map objects", { userId: ctx.user.id, mapId });
|
|
87905
88031
|
return ctx.services.map.getObjects(mapId, ctx.user.id);
|
|
87906
88032
|
});
|
|
87907
88033
|
createObject = requireAuth(async (ctx) => {
|
|
@@ -87923,12 +88049,12 @@ var init_map_controller = __esm(() => {
|
|
|
87923
88049
|
} catch (error2) {
|
|
87924
88050
|
if (error2 instanceof exports_external.ZodError) {
|
|
87925
88051
|
const details = formatZodError(error2);
|
|
87926
|
-
|
|
88052
|
+
logger49.warn("Create map object validation failed", { details });
|
|
87927
88053
|
throw ApiError.unprocessableEntity("Validation failed", details);
|
|
87928
88054
|
}
|
|
87929
88055
|
throw ApiError.badRequest("Invalid JSON body");
|
|
87930
88056
|
}
|
|
87931
|
-
|
|
88057
|
+
logger49.debug("Creating map object", {
|
|
87932
88058
|
userId: ctx.user.id,
|
|
87933
88059
|
mapId,
|
|
87934
88060
|
itemId: body2.itemId,
|
|
@@ -87952,7 +88078,7 @@ var init_map_controller = __esm(() => {
|
|
|
87952
88078
|
if (!isValidUUID(objectId)) {
|
|
87953
88079
|
throw ApiError.unprocessableEntity("objectId must be a valid UUID format");
|
|
87954
88080
|
}
|
|
87955
|
-
|
|
88081
|
+
logger49.debug("Deleting map object", { userId: ctx.user.id, mapId, objectId });
|
|
87956
88082
|
await ctx.services.map.deleteObject(mapId, objectId, ctx.user);
|
|
87957
88083
|
});
|
|
87958
88084
|
maps2 = {
|
|
@@ -87965,14 +88091,14 @@ var init_map_controller = __esm(() => {
|
|
|
87965
88091
|
});
|
|
87966
88092
|
|
|
87967
88093
|
// ../api-core/src/controllers/notification.controller.ts
|
|
87968
|
-
var
|
|
88094
|
+
var logger50, list6, updateStatus, getStats, create4, deliver, notifications2;
|
|
87969
88095
|
var init_notification_controller = __esm(() => {
|
|
87970
88096
|
init_esm();
|
|
87971
88097
|
init_schemas_index();
|
|
87972
88098
|
init_src2();
|
|
87973
88099
|
init_errors();
|
|
87974
88100
|
init_utils11();
|
|
87975
|
-
|
|
88101
|
+
logger50 = log.scope("NotificationController");
|
|
87976
88102
|
list6 = requireAuth(async (ctx) => {
|
|
87977
88103
|
const query = {
|
|
87978
88104
|
status: ctx.url.searchParams.get("status") || undefined,
|
|
@@ -87983,10 +88109,10 @@ var init_notification_controller = __esm(() => {
|
|
|
87983
88109
|
const result = NotificationListQuerySchema.omit({ userId: true }).safeParse(query);
|
|
87984
88110
|
if (!result.success) {
|
|
87985
88111
|
const details = formatZodError(result.error);
|
|
87986
|
-
|
|
88112
|
+
logger50.warn("List notifications query validation failed", { details });
|
|
87987
88113
|
throw ApiError.badRequest("Invalid query parameters", details);
|
|
87988
88114
|
}
|
|
87989
|
-
|
|
88115
|
+
logger50.debug("Listing notifications", { userId: ctx.user.id, ...result.data });
|
|
87990
88116
|
return ctx.services.notification.list(ctx.user, result.data);
|
|
87991
88117
|
});
|
|
87992
88118
|
updateStatus = requireAuth(async (ctx) => {
|
|
@@ -88001,12 +88127,12 @@ var init_notification_controller = __esm(() => {
|
|
|
88001
88127
|
} catch (error2) {
|
|
88002
88128
|
if (error2 instanceof exports_external.ZodError) {
|
|
88003
88129
|
const details = formatZodError(error2);
|
|
88004
|
-
|
|
88130
|
+
logger50.warn("Update notification status validation failed", { details });
|
|
88005
88131
|
throw ApiError.unprocessableEntity("Invalid request body", details);
|
|
88006
88132
|
}
|
|
88007
88133
|
throw ApiError.badRequest("Invalid JSON body");
|
|
88008
88134
|
}
|
|
88009
|
-
|
|
88135
|
+
logger50.debug("Updating status", {
|
|
88010
88136
|
userId: ctx.user.id,
|
|
88011
88137
|
notificationId,
|
|
88012
88138
|
status: body2.status
|
|
@@ -88016,7 +88142,7 @@ var init_notification_controller = __esm(() => {
|
|
|
88016
88142
|
getStats = requireAuth(async (ctx) => {
|
|
88017
88143
|
const startDate = ctx.url.searchParams.get("startDate");
|
|
88018
88144
|
const endDate = ctx.url.searchParams.get("endDate");
|
|
88019
|
-
|
|
88145
|
+
logger50.debug("Getting stats", { userId: ctx.user.id, startDate, endDate });
|
|
88020
88146
|
return ctx.services.notification.getStats(ctx.user, {
|
|
88021
88147
|
startDate: startDate ? new Date(startDate) : undefined,
|
|
88022
88148
|
endDate: endDate ? new Date(endDate) : undefined
|
|
@@ -88030,12 +88156,12 @@ var init_notification_controller = __esm(() => {
|
|
|
88030
88156
|
} catch (error2) {
|
|
88031
88157
|
if (error2 instanceof exports_external.ZodError) {
|
|
88032
88158
|
const details = formatZodError(error2);
|
|
88033
|
-
|
|
88159
|
+
logger50.warn("Create notification validation failed", { details });
|
|
88034
88160
|
throw ApiError.unprocessableEntity("Invalid request body", details);
|
|
88035
88161
|
}
|
|
88036
88162
|
throw ApiError.badRequest("Invalid JSON body");
|
|
88037
88163
|
}
|
|
88038
|
-
|
|
88164
|
+
logger50.debug("Creating notification", {
|
|
88039
88165
|
userId: ctx.user.id,
|
|
88040
88166
|
targetUserId: body2.userId,
|
|
88041
88167
|
type: body2.type
|
|
@@ -88053,12 +88179,12 @@ var init_notification_controller = __esm(() => {
|
|
|
88053
88179
|
});
|
|
88054
88180
|
});
|
|
88055
88181
|
deliver = requireAuth(async (ctx) => {
|
|
88056
|
-
|
|
88182
|
+
logger50.debug("Delivering notifications", { userId: ctx.user.id });
|
|
88057
88183
|
try {
|
|
88058
88184
|
await ctx.services.notification.deliverPending(ctx.user.id);
|
|
88059
88185
|
return { success: true };
|
|
88060
88186
|
} catch (error2) {
|
|
88061
|
-
|
|
88187
|
+
logger50.error("Failed to deliver notifications", { error: error2 });
|
|
88062
88188
|
throw ApiError.internal("Failed to deliver notifications");
|
|
88063
88189
|
}
|
|
88064
88190
|
});
|
|
@@ -88072,39 +88198,39 @@ var init_notification_controller = __esm(() => {
|
|
|
88072
88198
|
});
|
|
88073
88199
|
|
|
88074
88200
|
// ../api-core/src/controllers/realtime.controller.ts
|
|
88075
|
-
var
|
|
88201
|
+
var logger51, generateToken2, realtime;
|
|
88076
88202
|
var init_realtime_controller = __esm(() => {
|
|
88077
88203
|
init_src2();
|
|
88078
88204
|
init_utils11();
|
|
88079
|
-
|
|
88080
|
-
|
|
88205
|
+
logger51 = log.scope("RealtimeController");
|
|
88206
|
+
generateToken2 = requireAuth(async (ctx) => {
|
|
88081
88207
|
const gameIdOrSlug = ctx.params.gameId;
|
|
88082
|
-
|
|
88208
|
+
logger51.debug("Generating token", {
|
|
88083
88209
|
userId: ctx.user.id,
|
|
88084
88210
|
gameId: gameIdOrSlug || "global"
|
|
88085
88211
|
});
|
|
88086
88212
|
return ctx.services.realtime.generateToken(ctx.user, gameIdOrSlug);
|
|
88087
88213
|
});
|
|
88088
88214
|
realtime = {
|
|
88089
|
-
generateToken
|
|
88215
|
+
generateToken: generateToken2
|
|
88090
88216
|
};
|
|
88091
88217
|
});
|
|
88092
88218
|
|
|
88093
88219
|
// ../api-core/src/controllers/secrets.controller.ts
|
|
88094
|
-
var
|
|
88220
|
+
var logger52, listKeys, getValues, setSecrets, deleteSecret, secrets;
|
|
88095
88221
|
var init_secrets_controller = __esm(() => {
|
|
88096
88222
|
init_esm();
|
|
88097
88223
|
init_schemas_index();
|
|
88098
88224
|
init_src2();
|
|
88099
88225
|
init_errors();
|
|
88100
88226
|
init_utils11();
|
|
88101
|
-
|
|
88227
|
+
logger52 = log.scope("SecretsController");
|
|
88102
88228
|
listKeys = requireDeveloper(async (ctx) => {
|
|
88103
88229
|
const slug2 = ctx.params.slug;
|
|
88104
88230
|
if (!slug2) {
|
|
88105
88231
|
throw ApiError.badRequest("Missing game slug");
|
|
88106
88232
|
}
|
|
88107
|
-
|
|
88233
|
+
logger52.debug("Listing secret keys", { userId: ctx.user.id, slug: slug2 });
|
|
88108
88234
|
const keys = await ctx.services.secrets.listKeys(slug2, ctx.user);
|
|
88109
88235
|
return { keys };
|
|
88110
88236
|
});
|
|
@@ -88113,7 +88239,7 @@ var init_secrets_controller = __esm(() => {
|
|
|
88113
88239
|
if (!slug2) {
|
|
88114
88240
|
throw ApiError.badRequest("Missing game slug");
|
|
88115
88241
|
}
|
|
88116
|
-
|
|
88242
|
+
logger52.debug("Getting secret values", { userId: ctx.user.id, slug: slug2 });
|
|
88117
88243
|
const secrets = await ctx.services.secrets.getValues(slug2, ctx.user);
|
|
88118
88244
|
return { secrets };
|
|
88119
88245
|
});
|
|
@@ -88129,12 +88255,12 @@ var init_secrets_controller = __esm(() => {
|
|
|
88129
88255
|
} catch (error2) {
|
|
88130
88256
|
if (error2 instanceof exports_external.ZodError) {
|
|
88131
88257
|
const details = formatZodError(error2);
|
|
88132
|
-
|
|
88258
|
+
logger52.warn("Set secrets validation failed", { details });
|
|
88133
88259
|
throw ApiError.unprocessableEntity("Validation failed", details);
|
|
88134
88260
|
}
|
|
88135
88261
|
throw ApiError.badRequest("Invalid JSON body");
|
|
88136
88262
|
}
|
|
88137
|
-
|
|
88263
|
+
logger52.debug("Setting secrets", {
|
|
88138
88264
|
userId: ctx.user.id,
|
|
88139
88265
|
slug: slug2,
|
|
88140
88266
|
keyCount: Object.keys(body2).length
|
|
@@ -88151,7 +88277,7 @@ var init_secrets_controller = __esm(() => {
|
|
|
88151
88277
|
if (!key) {
|
|
88152
88278
|
throw ApiError.badRequest("Missing secret key");
|
|
88153
88279
|
}
|
|
88154
|
-
|
|
88280
|
+
logger52.debug("Deleting secret", { userId: ctx.user.id, slug: slug2, key });
|
|
88155
88281
|
await ctx.services.secrets.deleteSecret(slug2, key, ctx.user);
|
|
88156
88282
|
return { success: true };
|
|
88157
88283
|
});
|
|
@@ -88164,14 +88290,14 @@ var init_secrets_controller = __esm(() => {
|
|
|
88164
88290
|
});
|
|
88165
88291
|
|
|
88166
88292
|
// ../api-core/src/controllers/seed.controller.ts
|
|
88167
|
-
var
|
|
88293
|
+
var logger53, seed;
|
|
88168
88294
|
var init_seed_controller = __esm(() => {
|
|
88169
88295
|
init_esm();
|
|
88170
88296
|
init_schemas_index();
|
|
88171
88297
|
init_src2();
|
|
88172
88298
|
init_errors();
|
|
88173
88299
|
init_utils11();
|
|
88174
|
-
|
|
88300
|
+
logger53 = log.scope("SeedController");
|
|
88175
88301
|
seed = requireDeveloper(async (ctx) => {
|
|
88176
88302
|
const slug2 = ctx.params.slug;
|
|
88177
88303
|
if (!slug2) {
|
|
@@ -88184,29 +88310,29 @@ var init_seed_controller = __esm(() => {
|
|
|
88184
88310
|
} catch (error2) {
|
|
88185
88311
|
if (error2 instanceof exports_external.ZodError) {
|
|
88186
88312
|
const details = formatZodError(error2);
|
|
88187
|
-
|
|
88313
|
+
logger53.warn("Seed database validation failed", { details });
|
|
88188
88314
|
throw ApiError.unprocessableEntity("Validation failed", details);
|
|
88189
88315
|
}
|
|
88190
88316
|
throw ApiError.badRequest("Invalid JSON body");
|
|
88191
88317
|
}
|
|
88192
|
-
|
|
88318
|
+
logger53.debug("Seeding database", { userId: ctx.user.id, slug: slug2, codeLength: body2.code.length });
|
|
88193
88319
|
return ctx.services.seed.seed(slug2, body2.code, ctx.user);
|
|
88194
88320
|
});
|
|
88195
88321
|
});
|
|
88196
88322
|
|
|
88197
88323
|
// ../api-core/src/controllers/session.controller.ts
|
|
88198
|
-
var
|
|
88324
|
+
var logger54, start2, end, mintToken, sessions2;
|
|
88199
88325
|
var init_session_controller = __esm(() => {
|
|
88200
88326
|
init_src2();
|
|
88201
88327
|
init_errors();
|
|
88202
88328
|
init_utils11();
|
|
88203
|
-
|
|
88329
|
+
logger54 = log.scope("SessionController");
|
|
88204
88330
|
start2 = requireAuth(async (ctx) => {
|
|
88205
88331
|
const gameIdOrSlug = ctx.params.gameId;
|
|
88206
88332
|
if (!gameIdOrSlug) {
|
|
88207
88333
|
throw ApiError.badRequest("Missing game ID or slug");
|
|
88208
88334
|
}
|
|
88209
|
-
|
|
88335
|
+
logger54.debug("Starting session", { userId: ctx.user.id, gameIdOrSlug });
|
|
88210
88336
|
return ctx.services.session.start(gameIdOrSlug, ctx.user.id);
|
|
88211
88337
|
});
|
|
88212
88338
|
end = requireAuth(async (ctx) => {
|
|
@@ -88218,7 +88344,7 @@ var init_session_controller = __esm(() => {
|
|
|
88218
88344
|
if (!sessionId) {
|
|
88219
88345
|
throw ApiError.badRequest("Missing session ID");
|
|
88220
88346
|
}
|
|
88221
|
-
|
|
88347
|
+
logger54.debug("Ending session", { userId: ctx.user.id, gameIdOrSlug, sessionId });
|
|
88222
88348
|
return ctx.services.session.end(gameIdOrSlug, sessionId, ctx.user.id);
|
|
88223
88349
|
});
|
|
88224
88350
|
mintToken = requireAuth(async (ctx) => {
|
|
@@ -88226,7 +88352,7 @@ var init_session_controller = __esm(() => {
|
|
|
88226
88352
|
if (!gameIdOrSlug) {
|
|
88227
88353
|
throw ApiError.badRequest("Missing game ID or slug");
|
|
88228
88354
|
}
|
|
88229
|
-
|
|
88355
|
+
logger54.debug("Minting token", { userId: ctx.user.id, gameIdOrSlug });
|
|
88230
88356
|
return ctx.services.session.mintToken(gameIdOrSlug, ctx.user.id);
|
|
88231
88357
|
});
|
|
88232
88358
|
sessions2 = {
|
|
@@ -88237,13 +88363,13 @@ var init_session_controller = __esm(() => {
|
|
|
88237
88363
|
});
|
|
88238
88364
|
|
|
88239
88365
|
// ../api-core/src/controllers/shop.controller.ts
|
|
88240
|
-
var
|
|
88366
|
+
var logger55, getShopView, shop;
|
|
88241
88367
|
var init_shop_controller = __esm(() => {
|
|
88242
88368
|
init_src2();
|
|
88243
88369
|
init_utils11();
|
|
88244
|
-
|
|
88370
|
+
logger55 = log.scope("ShopController");
|
|
88245
88371
|
getShopView = requireAuth(async (ctx) => {
|
|
88246
|
-
|
|
88372
|
+
logger55.debug("Getting shop view", { userId: ctx.user.id });
|
|
88247
88373
|
return ctx.services.shop.getShopView(ctx.user);
|
|
88248
88374
|
});
|
|
88249
88375
|
shop = {
|
|
@@ -88252,7 +88378,7 @@ var init_shop_controller = __esm(() => {
|
|
|
88252
88378
|
});
|
|
88253
88379
|
|
|
88254
88380
|
// ../api-core/src/controllers/shop-listing.controller.ts
|
|
88255
|
-
var
|
|
88381
|
+
var logger56, list7, getById4, create5, update5, remove5, listByGame2, getByGameItem, createForGameItem, updateForGameItem, deleteForGameItem, shopListings2;
|
|
88256
88382
|
var init_shop_listing_controller = __esm(() => {
|
|
88257
88383
|
init_esm();
|
|
88258
88384
|
init_schemas_index();
|
|
@@ -88260,9 +88386,9 @@ var init_shop_listing_controller = __esm(() => {
|
|
|
88260
88386
|
init_src4();
|
|
88261
88387
|
init_errors();
|
|
88262
88388
|
init_utils11();
|
|
88263
|
-
|
|
88389
|
+
logger56 = log.scope("ShopListingController");
|
|
88264
88390
|
list7 = requireAdmin(async (ctx) => {
|
|
88265
|
-
|
|
88391
|
+
logger56.debug("Listing shop listings", { userId: ctx.user.id });
|
|
88266
88392
|
return ctx.services.shopListing.list();
|
|
88267
88393
|
});
|
|
88268
88394
|
getById4 = requireAdmin(async (ctx) => {
|
|
@@ -88273,7 +88399,7 @@ var init_shop_listing_controller = __esm(() => {
|
|
|
88273
88399
|
if (!isValidUUID(listingId)) {
|
|
88274
88400
|
throw ApiError.unprocessableEntity("listingId must be a valid UUID format");
|
|
88275
88401
|
}
|
|
88276
|
-
|
|
88402
|
+
logger56.debug("Getting listing", { userId: ctx.user.id, listingId });
|
|
88277
88403
|
return ctx.services.shopListing.getById(listingId);
|
|
88278
88404
|
});
|
|
88279
88405
|
create5 = requireAdmin(async (ctx) => {
|
|
@@ -88284,12 +88410,12 @@ var init_shop_listing_controller = __esm(() => {
|
|
|
88284
88410
|
} catch (error2) {
|
|
88285
88411
|
if (error2 instanceof exports_external.ZodError) {
|
|
88286
88412
|
const details = formatZodError(error2);
|
|
88287
|
-
|
|
88413
|
+
logger56.warn("Create shop listing validation failed", { details });
|
|
88288
88414
|
throw ApiError.unprocessableEntity("Validation failed", details);
|
|
88289
88415
|
}
|
|
88290
88416
|
throw ApiError.badRequest("Invalid JSON body");
|
|
88291
88417
|
}
|
|
88292
|
-
|
|
88418
|
+
logger56.debug("Creating listing", {
|
|
88293
88419
|
userId: ctx.user.id,
|
|
88294
88420
|
itemId: body2.itemId,
|
|
88295
88421
|
currencyId: body2.currencyId,
|
|
@@ -88312,12 +88438,12 @@ var init_shop_listing_controller = __esm(() => {
|
|
|
88312
88438
|
} catch (error2) {
|
|
88313
88439
|
if (error2 instanceof exports_external.ZodError) {
|
|
88314
88440
|
const details = formatZodError(error2);
|
|
88315
|
-
|
|
88441
|
+
logger56.warn("Update shop listing validation failed", { details });
|
|
88316
88442
|
throw ApiError.unprocessableEntity("Validation failed", details);
|
|
88317
88443
|
}
|
|
88318
88444
|
throw ApiError.badRequest("Invalid JSON body");
|
|
88319
88445
|
}
|
|
88320
|
-
|
|
88446
|
+
logger56.debug("Updating listing", {
|
|
88321
88447
|
userId: ctx.user.id,
|
|
88322
88448
|
listingId,
|
|
88323
88449
|
price: body2.price,
|
|
@@ -88334,7 +88460,7 @@ var init_shop_listing_controller = __esm(() => {
|
|
|
88334
88460
|
if (!isValidUUID(listingId)) {
|
|
88335
88461
|
throw ApiError.unprocessableEntity("listingId must be a valid UUID format");
|
|
88336
88462
|
}
|
|
88337
|
-
|
|
88463
|
+
logger56.debug("Deleting listing", { userId: ctx.user.id, listingId });
|
|
88338
88464
|
await ctx.services.shopListing.delete(listingId);
|
|
88339
88465
|
});
|
|
88340
88466
|
listByGame2 = requireAuth(async (ctx) => {
|
|
@@ -88345,7 +88471,7 @@ var init_shop_listing_controller = __esm(() => {
|
|
|
88345
88471
|
if (!isValidUUID(gameId)) {
|
|
88346
88472
|
throw ApiError.unprocessableEntity("gameId must be a valid UUID format");
|
|
88347
88473
|
}
|
|
88348
|
-
|
|
88474
|
+
logger56.debug("Listing game listings", { userId: ctx.user.id, gameId });
|
|
88349
88475
|
return ctx.services.shopListing.listByGame(gameId, ctx.user);
|
|
88350
88476
|
});
|
|
88351
88477
|
getByGameItem = requireAuth(async (ctx) => {
|
|
@@ -88360,7 +88486,7 @@ var init_shop_listing_controller = __esm(() => {
|
|
|
88360
88486
|
if (!isValidUUID(itemId)) {
|
|
88361
88487
|
throw ApiError.unprocessableEntity("itemId must be a valid UUID format");
|
|
88362
88488
|
}
|
|
88363
|
-
|
|
88489
|
+
logger56.debug("Getting game item listing", { userId: ctx.user.id, gameId, itemId });
|
|
88364
88490
|
return ctx.services.shopListing.getByGameItem(gameId, itemId, ctx.user);
|
|
88365
88491
|
});
|
|
88366
88492
|
createForGameItem = requireAuth(async (ctx) => {
|
|
@@ -88382,12 +88508,12 @@ var init_shop_listing_controller = __esm(() => {
|
|
|
88382
88508
|
} catch (error2) {
|
|
88383
88509
|
if (error2 instanceof exports_external.ZodError) {
|
|
88384
88510
|
const details = formatZodError(error2);
|
|
88385
|
-
|
|
88511
|
+
logger56.warn("Create game item listing validation failed", { details });
|
|
88386
88512
|
throw ApiError.unprocessableEntity("Validation failed", details);
|
|
88387
88513
|
}
|
|
88388
88514
|
throw ApiError.badRequest("Invalid JSON body");
|
|
88389
88515
|
}
|
|
88390
|
-
|
|
88516
|
+
logger56.debug("Creating game item listing", {
|
|
88391
88517
|
userId: ctx.user.id,
|
|
88392
88518
|
gameId,
|
|
88393
88519
|
itemId,
|
|
@@ -88415,12 +88541,12 @@ var init_shop_listing_controller = __esm(() => {
|
|
|
88415
88541
|
} catch (error2) {
|
|
88416
88542
|
if (error2 instanceof exports_external.ZodError) {
|
|
88417
88543
|
const details = formatZodError(error2);
|
|
88418
|
-
|
|
88544
|
+
logger56.warn("Update game item listing validation failed", { details });
|
|
88419
88545
|
throw ApiError.unprocessableEntity("Validation failed", details);
|
|
88420
88546
|
}
|
|
88421
88547
|
throw ApiError.badRequest("Invalid JSON body");
|
|
88422
88548
|
}
|
|
88423
|
-
|
|
88549
|
+
logger56.debug("Updating game item listing", {
|
|
88424
88550
|
userId: ctx.user.id,
|
|
88425
88551
|
gameId,
|
|
88426
88552
|
itemId,
|
|
@@ -88442,7 +88568,7 @@ var init_shop_listing_controller = __esm(() => {
|
|
|
88442
88568
|
if (!isValidUUID(itemId)) {
|
|
88443
88569
|
throw ApiError.unprocessableEntity("itemId must be a valid UUID format");
|
|
88444
88570
|
}
|
|
88445
|
-
|
|
88571
|
+
logger56.debug("Deleting game item listing", {
|
|
88446
88572
|
userId: ctx.user.id,
|
|
88447
88573
|
gameId,
|
|
88448
88574
|
itemId
|
|
@@ -88469,21 +88595,21 @@ async function getBySlug2(ctx) {
|
|
|
88469
88595
|
if (!slug2) {
|
|
88470
88596
|
throw ApiError.badRequest("Template slug is required");
|
|
88471
88597
|
}
|
|
88472
|
-
|
|
88598
|
+
logger57.debug("Getting sprite by slug", { slug: slug2 });
|
|
88473
88599
|
return ctx.services.sprite.getBySlug(slug2);
|
|
88474
88600
|
}
|
|
88475
|
-
var
|
|
88601
|
+
var logger57, sprites;
|
|
88476
88602
|
var init_sprite_controller = __esm(() => {
|
|
88477
88603
|
init_src2();
|
|
88478
88604
|
init_errors();
|
|
88479
|
-
|
|
88605
|
+
logger57 = log.scope("SpriteController");
|
|
88480
88606
|
sprites = {
|
|
88481
88607
|
getBySlug: getBySlug2
|
|
88482
88608
|
};
|
|
88483
88609
|
});
|
|
88484
88610
|
|
|
88485
88611
|
// ../api-core/src/controllers/timeback.controller.ts
|
|
88486
|
-
var
|
|
88612
|
+
var logger58, getTodayXp, getTotalXp, updateTodayXp, getXpHistory, populateStudent, getUser, getUserById, setupIntegration, getIntegrations, verifyIntegration, getConfig2, deleteIntegrations, endActivity, timeback2;
|
|
88487
88613
|
var init_timeback_controller = __esm(() => {
|
|
88488
88614
|
init_esm();
|
|
88489
88615
|
init_schemas_index();
|
|
@@ -88491,15 +88617,15 @@ var init_timeback_controller = __esm(() => {
|
|
|
88491
88617
|
init_src4();
|
|
88492
88618
|
init_errors();
|
|
88493
88619
|
init_utils11();
|
|
88494
|
-
|
|
88620
|
+
logger58 = log.scope("TimebackController");
|
|
88495
88621
|
getTodayXp = requireAuth(async (ctx) => {
|
|
88496
88622
|
const date4 = ctx.url.searchParams.get("date") || undefined;
|
|
88497
88623
|
const tz = ctx.url.searchParams.get("tz") || undefined;
|
|
88498
|
-
|
|
88624
|
+
logger58.debug("Getting today XP", { userId: ctx.user.id, date: date4, tz });
|
|
88499
88625
|
return ctx.services.timeback.getTodayXp(ctx.user.id, date4, tz);
|
|
88500
88626
|
});
|
|
88501
88627
|
getTotalXp = requireAuth(async (ctx) => {
|
|
88502
|
-
|
|
88628
|
+
logger58.debug("Getting total XP", { userId: ctx.user.id });
|
|
88503
88629
|
return ctx.services.timeback.getTotalXp(ctx.user.id);
|
|
88504
88630
|
});
|
|
88505
88631
|
updateTodayXp = requireAuth(async (ctx) => {
|
|
@@ -88510,18 +88636,18 @@ var init_timeback_controller = __esm(() => {
|
|
|
88510
88636
|
} catch (error2) {
|
|
88511
88637
|
if (error2 instanceof exports_external.ZodError) {
|
|
88512
88638
|
const details = formatZodError(error2);
|
|
88513
|
-
|
|
88639
|
+
logger58.warn("Update today XP validation failed", { details });
|
|
88514
88640
|
throw ApiError.unprocessableEntity("Validation failed", details);
|
|
88515
88641
|
}
|
|
88516
88642
|
throw ApiError.badRequest("Invalid JSON body");
|
|
88517
88643
|
}
|
|
88518
|
-
|
|
88644
|
+
logger58.debug("Updating today XP", { userId: ctx.user.id, xp: body2.xp });
|
|
88519
88645
|
return ctx.services.timeback.updateTodayXp(ctx.user.id, body2);
|
|
88520
88646
|
});
|
|
88521
88647
|
getXpHistory = requireAuth(async (ctx) => {
|
|
88522
88648
|
const startDate = ctx.url.searchParams.get("startDate") || undefined;
|
|
88523
88649
|
const endDate = ctx.url.searchParams.get("endDate") || undefined;
|
|
88524
|
-
|
|
88650
|
+
logger58.debug("Getting XP history", { userId: ctx.user.id, startDate, endDate });
|
|
88525
88651
|
return ctx.services.timeback.getXpHistory(ctx.user.id, startDate, endDate);
|
|
88526
88652
|
});
|
|
88527
88653
|
populateStudent = requireAuth(async (ctx) => {
|
|
@@ -88532,18 +88658,18 @@ var init_timeback_controller = __esm(() => {
|
|
|
88532
88658
|
} catch (error2) {
|
|
88533
88659
|
if (error2 instanceof exports_external.ZodError) {
|
|
88534
88660
|
const details = formatZodError(error2);
|
|
88535
|
-
|
|
88661
|
+
logger58.warn("Populate student validation failed", { details });
|
|
88536
88662
|
throw ApiError.unprocessableEntity("Validation failed", details);
|
|
88537
88663
|
}
|
|
88538
88664
|
}
|
|
88539
|
-
|
|
88665
|
+
logger58.debug("Populating student", {
|
|
88540
88666
|
userId: ctx.user.id,
|
|
88541
88667
|
hasProvidedNames: !!providedNames
|
|
88542
88668
|
});
|
|
88543
88669
|
return ctx.services.timeback.populateStudent(ctx.user, providedNames);
|
|
88544
88670
|
});
|
|
88545
88671
|
getUser = requireAuth(async (ctx) => {
|
|
88546
|
-
|
|
88672
|
+
logger58.debug("Getting user", { userId: ctx.user.id, gameId: ctx.gameId });
|
|
88547
88673
|
return ctx.services.timeback.getUserData(ctx.user.id, ctx.gameId);
|
|
88548
88674
|
});
|
|
88549
88675
|
getUserById = requireAuth(async (ctx) => {
|
|
@@ -88551,7 +88677,7 @@ var init_timeback_controller = __esm(() => {
|
|
|
88551
88677
|
if (!timebackId) {
|
|
88552
88678
|
throw ApiError.badRequest("Missing timebackId parameter");
|
|
88553
88679
|
}
|
|
88554
|
-
|
|
88680
|
+
logger58.debug("Getting user by ID", { requesterId: ctx.user.id, timebackId });
|
|
88555
88681
|
return ctx.services.timeback.getUserDataByTimebackId(timebackId);
|
|
88556
88682
|
});
|
|
88557
88683
|
setupIntegration = requireDeveloper(async (ctx) => {
|
|
@@ -88562,12 +88688,12 @@ var init_timeback_controller = __esm(() => {
|
|
|
88562
88688
|
} catch (error2) {
|
|
88563
88689
|
if (error2 instanceof exports_external.ZodError) {
|
|
88564
88690
|
const details = formatZodError(error2);
|
|
88565
|
-
|
|
88691
|
+
logger58.warn("Setup integration validation failed", { details });
|
|
88566
88692
|
throw ApiError.unprocessableEntity("Validation failed", details);
|
|
88567
88693
|
}
|
|
88568
88694
|
throw ApiError.badRequest("Invalid JSON body");
|
|
88569
88695
|
}
|
|
88570
|
-
|
|
88696
|
+
logger58.debug("Setting up integration", {
|
|
88571
88697
|
userId: ctx.user.id,
|
|
88572
88698
|
gameId: body2.gameId
|
|
88573
88699
|
});
|
|
@@ -88579,7 +88705,7 @@ var init_timeback_controller = __esm(() => {
|
|
|
88579
88705
|
throw ApiError.badRequest("Missing gameId");
|
|
88580
88706
|
if (!isValidUUID(gameId))
|
|
88581
88707
|
throw ApiError.unprocessableEntity("Invalid gameId format");
|
|
88582
|
-
|
|
88708
|
+
logger58.debug("Getting integrations", { userId: ctx.user.id, gameId });
|
|
88583
88709
|
return ctx.services.timeback.getIntegrations(gameId, ctx.user);
|
|
88584
88710
|
});
|
|
88585
88711
|
verifyIntegration = requireDeveloper(async (ctx) => {
|
|
@@ -88588,7 +88714,7 @@ var init_timeback_controller = __esm(() => {
|
|
|
88588
88714
|
throw ApiError.badRequest("Missing gameId");
|
|
88589
88715
|
if (!isValidUUID(gameId))
|
|
88590
88716
|
throw ApiError.unprocessableEntity("Invalid gameId format");
|
|
88591
|
-
|
|
88717
|
+
logger58.debug("Verifying integration", { userId: ctx.user.id, gameId });
|
|
88592
88718
|
return ctx.services.timeback.verifyIntegration(gameId, ctx.user);
|
|
88593
88719
|
});
|
|
88594
88720
|
getConfig2 = requireDeveloper(async (ctx) => {
|
|
@@ -88597,7 +88723,7 @@ var init_timeback_controller = __esm(() => {
|
|
|
88597
88723
|
throw ApiError.badRequest("Missing gameId");
|
|
88598
88724
|
if (!isValidUUID(gameId))
|
|
88599
88725
|
throw ApiError.unprocessableEntity("Invalid gameId format");
|
|
88600
|
-
|
|
88726
|
+
logger58.debug("Getting config", { userId: ctx.user.id, gameId });
|
|
88601
88727
|
return ctx.services.timeback.getConfig(gameId, ctx.user);
|
|
88602
88728
|
});
|
|
88603
88729
|
deleteIntegrations = requireDeveloper(async (ctx) => {
|
|
@@ -88606,7 +88732,7 @@ var init_timeback_controller = __esm(() => {
|
|
|
88606
88732
|
throw ApiError.badRequest("Missing gameId");
|
|
88607
88733
|
if (!isValidUUID(gameId))
|
|
88608
88734
|
throw ApiError.unprocessableEntity("Invalid gameId format");
|
|
88609
|
-
|
|
88735
|
+
logger58.debug("Deleting integrations", { userId: ctx.user.id, gameId });
|
|
88610
88736
|
await ctx.services.timeback.deleteIntegrations(gameId, ctx.user);
|
|
88611
88737
|
});
|
|
88612
88738
|
endActivity = requireDeveloper(async (ctx) => {
|
|
@@ -88617,13 +88743,13 @@ var init_timeback_controller = __esm(() => {
|
|
|
88617
88743
|
} catch (error2) {
|
|
88618
88744
|
if (error2 instanceof exports_external.ZodError) {
|
|
88619
88745
|
const details = formatZodError(error2);
|
|
88620
|
-
|
|
88746
|
+
logger58.warn("End activity validation failed", { details });
|
|
88621
88747
|
throw ApiError.unprocessableEntity("Validation failed", details);
|
|
88622
88748
|
}
|
|
88623
88749
|
throw ApiError.badRequest("Invalid JSON body");
|
|
88624
88750
|
}
|
|
88625
88751
|
const { gameId, studentId, activityData, scoreData, timingData, xpEarned, masteredUnits } = body2;
|
|
88626
|
-
|
|
88752
|
+
logger58.debug("Ending activity", { userId: ctx.user.id, gameId });
|
|
88627
88753
|
return ctx.services.timeback.endActivity(gameId, studentId, activityData, scoreData, timingData, xpEarned, masteredUnits, ctx.user);
|
|
88628
88754
|
});
|
|
88629
88755
|
timeback2 = {
|
|
@@ -88644,14 +88770,14 @@ var init_timeback_controller = __esm(() => {
|
|
|
88644
88770
|
});
|
|
88645
88771
|
|
|
88646
88772
|
// ../api-core/src/controllers/upload.controller.ts
|
|
88647
|
-
var
|
|
88773
|
+
var logger59, initiate;
|
|
88648
88774
|
var init_upload_controller = __esm(() => {
|
|
88649
88775
|
init_esm();
|
|
88650
88776
|
init_schemas_index();
|
|
88651
88777
|
init_src2();
|
|
88652
88778
|
init_errors();
|
|
88653
88779
|
init_utils11();
|
|
88654
|
-
|
|
88780
|
+
logger59 = log.scope("UploadController");
|
|
88655
88781
|
initiate = requireDeveloper(async (ctx) => {
|
|
88656
88782
|
let body2;
|
|
88657
88783
|
try {
|
|
@@ -88660,24 +88786,24 @@ var init_upload_controller = __esm(() => {
|
|
|
88660
88786
|
} catch (error2) {
|
|
88661
88787
|
if (error2 instanceof exports_external.ZodError) {
|
|
88662
88788
|
const details = formatZodError(error2);
|
|
88663
|
-
|
|
88789
|
+
logger59.warn("Initiate upload validation failed", { details });
|
|
88664
88790
|
throw ApiError.unprocessableEntity("Validation failed", details);
|
|
88665
88791
|
}
|
|
88666
88792
|
throw ApiError.badRequest("Invalid JSON body");
|
|
88667
88793
|
}
|
|
88668
|
-
|
|
88794
|
+
logger59.debug("Initiating upload", { userId: ctx.user.id, gameId: body2.gameId });
|
|
88669
88795
|
return ctx.services.upload.initiate(body2, ctx.user);
|
|
88670
88796
|
});
|
|
88671
88797
|
});
|
|
88672
88798
|
|
|
88673
88799
|
// ../api-core/src/controllers/user.controller.ts
|
|
88674
|
-
var
|
|
88800
|
+
var logger60, getMe, users2;
|
|
88675
88801
|
var init_user_controller = __esm(() => {
|
|
88676
88802
|
init_src2();
|
|
88677
88803
|
init_utils11();
|
|
88678
|
-
|
|
88804
|
+
logger60 = log.scope("UserController");
|
|
88679
88805
|
getMe = requireAuth(async (ctx) => {
|
|
88680
|
-
|
|
88806
|
+
logger60.debug("Getting current user", { userId: ctx.user.id, gameId: ctx.gameId });
|
|
88681
88807
|
return ctx.services.user.getMe(ctx.user, ctx.gameId);
|
|
88682
88808
|
});
|
|
88683
88809
|
users2 = {
|
|
@@ -88686,13 +88812,13 @@ var init_user_controller = __esm(() => {
|
|
|
88686
88812
|
});
|
|
88687
88813
|
|
|
88688
88814
|
// ../api-core/src/controllers/verify.controller.ts
|
|
88689
|
-
var
|
|
88815
|
+
var logger61;
|
|
88690
88816
|
var init_verify_controller = __esm(() => {
|
|
88691
88817
|
init_schemas_index();
|
|
88692
88818
|
init_src2();
|
|
88693
88819
|
init_errors();
|
|
88694
88820
|
init_utils11();
|
|
88695
|
-
|
|
88821
|
+
logger61 = log.scope("VerifyController");
|
|
88696
88822
|
});
|
|
88697
88823
|
|
|
88698
88824
|
// ../api-core/src/controllers/index.ts
|
|
@@ -88711,6 +88837,7 @@ var init_controllers = __esm(() => {
|
|
|
88711
88837
|
init_item_controller();
|
|
88712
88838
|
init_leaderboard_controller();
|
|
88713
88839
|
init_level_controller();
|
|
88840
|
+
init_logs_controller();
|
|
88714
88841
|
init_lti_controller();
|
|
88715
88842
|
init_map_controller();
|
|
88716
88843
|
init_notification_controller();
|
|
@@ -89227,6 +89354,16 @@ var init_items = __esm(() => {
|
|
|
89227
89354
|
gameItemsRouter.delete("/:gameId/items/:itemId", handle2(items2.deleteForGame, { status: 204 }));
|
|
89228
89355
|
});
|
|
89229
89356
|
|
|
89357
|
+
// src/routes/platform/games/logs.ts
|
|
89358
|
+
var gameLogsRouter;
|
|
89359
|
+
var init_logs = __esm(() => {
|
|
89360
|
+
init_dist3();
|
|
89361
|
+
init_controllers();
|
|
89362
|
+
init_api();
|
|
89363
|
+
gameLogsRouter = new Hono2;
|
|
89364
|
+
gameLogsRouter.post("/:slug/logs/token", handle2(logs.generateToken));
|
|
89365
|
+
});
|
|
89366
|
+
|
|
89230
89367
|
// src/routes/platform/games/scores.ts
|
|
89231
89368
|
var gameScoresRouter;
|
|
89232
89369
|
var init_scores = __esm(() => {
|
|
@@ -89542,6 +89679,7 @@ var init_games2 = __esm(() => {
|
|
|
89542
89679
|
init_deploy();
|
|
89543
89680
|
init_domains3();
|
|
89544
89681
|
init_items();
|
|
89682
|
+
init_logs();
|
|
89545
89683
|
init_scores();
|
|
89546
89684
|
init_secrets();
|
|
89547
89685
|
init_seed2();
|
|
@@ -89557,6 +89695,7 @@ var init_games2 = __esm(() => {
|
|
|
89557
89695
|
gamesRouter.route("/", gameDeployRouter);
|
|
89558
89696
|
gamesRouter.route("/", gameDomainsRouter);
|
|
89559
89697
|
gamesRouter.route("/", gameItemsRouter);
|
|
89698
|
+
gamesRouter.route("/", gameLogsRouter);
|
|
89560
89699
|
gamesRouter.route("/", gameShopRouter);
|
|
89561
89700
|
gamesRouter.route("/", gameScoresRouter);
|
|
89562
89701
|
gamesRouter.route("/", gameSecretsRouter);
|