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