@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.
Files changed (3) hide show
  1. package/dist/cli.js +483 -344
  2. package/dist/server.js +483 -344
  3. 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.8",
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
- logger16.error("LTI configuration not available");
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
- logger16.info("Verified token", {
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
- logger16.error("Token verification failed", {
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
- logger16.warn("LTI claims validation failed", {
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
- logger16.info("Processed launch roles", {
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
- logger16.info("Launch processed", { userId: user.id, redirectPath });
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
- logger16.error("Session insert returned no rows", { userId });
16159
+ logger17.error("Session insert returned no rows", { userId });
16104
16160
  throw new InternalError("Failed to create session");
16105
16161
  }
16106
- logger16.info("Created session", {
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
- logger16.info("Found user by account", {
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
- logger16.error("LTI account link insert returned no rows", {
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
- logger16.info("Linked existing user", {
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
- logger16.error("LTI user insert returned no rows", { email, ltiTimebackId });
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
- logger16.info("Provisioned user", {
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 logger16;
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
- logger16 = log.scope("LtiService");
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
- logger17.debug("Retrieved map", { identifier });
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
- logger17.debug("Retrieved elements", { mapId, count: elements.length });
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
- logger17.debug("Retrieved objects", { mapId, userId, count: objects.length });
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
- logger17.warn("Attempted to place non-placeable item", {
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
- logger17.error("Map object insert returned no rows", {
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
- logger17.error("Map object query after insert returned no rows", {
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
- logger17.info("Created object", {
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
- logger17.info("Deleted object", {
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 logger17;
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
- logger17 = log.scope("MapService");
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
- logger18.warn("Failed to publish to user", {
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
- logger18.error("Publish to user error", { error });
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
- logger18.debug("Listed notifications", { userId: user.id, count: results.length });
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
- logger18.debug("Updated status", { notificationId, status });
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
- logger18.debug("Retrieved stats", { userId: user.id, total });
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
- logger18.debug("Created notification", {
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
- logger18.error("Failed to create notification", { userId, type, error });
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
- logger18.warn("No realtime config for publish");
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
- logger18.error("Notification insert returned no rows", {
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
- logger18.info("Inserted notification", {
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
- logger18.warn("No realtime config for delivery");
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
- logger18.info("Delivered notification", {
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
- logger18.warn("Failed to deliver", {
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 logger18;
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
- logger18 = log.scope("NotificationService");
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
- logger19.info("Generated token", {
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 logger19;
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
- logger19 = log.scope("RealtimeService");
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
- logger20.debug("Listed secret keys", { gameId: game.id, slug: slug2, keyCount: keys.length });
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
- logger20.debug("Retrieved secret values", { gameId: game.id, slug: slug2 });
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
- logger20.warn("Attempted to set reserved secret", {
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
- logger20.info("Set secrets", {
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
- logger20.warn("Attempted to delete reserved secret", {
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
- logger20.info("Deleted secret", { gameId: game.id, slug: slug2, key });
16842
+ logger21.info("Deleted secret", { gameId: game.id, slug: slug2, key });
16787
16843
  }
16788
16844
  }
16789
- var logger20, INTERNAL_SECRET_KEYS;
16845
+ var logger21, INTERNAL_SECRET_KEYS;
16790
16846
  var init_secrets_service = __esm(() => {
16791
16847
  init_src2();
16792
16848
  init_errors();
16793
- logger20 = log.scope("SecretsService");
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
- logger21.error("Cloudflare provider not available for seeding");
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
- logger21.debug("Seeding database", {
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
- logger21.info("Seed completed", {
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
- logger21.error("Seed failed", {
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
- logger21.warn("Failed to send failure alert", { error: err2 });
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
- logger21.info("Worker deployed", { seedDeploymentId, url: result.url });
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
- logger21.debug("Retrying seed execution", {
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
- logger21.debug("Worker not ready, will retry", {
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
- logger21.error("Worker returned error", {
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
- logger21.error("Seed execution failed", {
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
- logger21.info("Seed executed successfully", {
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
- logger21.debug("Seed execution timed out, will retry", {
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
- logger21.debug("Network error, will retry", {
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
- logger21.info("Worker deleted", { seedDeploymentId });
17071
+ logger22.info("Worker deleted", { seedDeploymentId });
17016
17072
  } catch (error) {
17017
- logger21.warn("Failed to cleanup worker", { seedDeploymentId, error });
17073
+ logger22.warn("Failed to cleanup worker", { seedDeploymentId, error });
17018
17074
  }
17019
17075
  }
17020
17076
  }
17021
- var logger21;
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
- logger21 = log.scope("SeedService");
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
- logger22.error("Game session insert returned no rows", { userId, gameId });
17118
+ logger23.error("Game session insert returned no rows", { userId, gameId });
17063
17119
  throw new InternalError("Failed to create game session");
17064
17120
  }
17065
- logger22.info("Started new session", {
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
- logger22.info("Ended session", { sessionId, gameId, userId });
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
- logger22.debug("Minted game token", { gameId, userId });
17148
+ logger23.debug("Minted game token", { gameId, userId });
17093
17149
  return result;
17094
17150
  }
17095
17151
  }
17096
- var logger22;
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
- logger22 = log.scope("SessionService");
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
- logger23.debug("Listed shop listings", { count: allListings.length });
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
- logger23.debug("Retrieved listing", { listingId });
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
- logger23.error("Shop listing insert returned no rows", {
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
- logger23.info("Created listing", {
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
- logger23.info("Updated listing", {
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
- logger23.info("Deleted listing", { listingId });
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
- logger23.debug("Listed game listings", {
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
- logger23.error("Game item listing insert returned no rows", {
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
- logger23.info("Created game item listing", {
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
- logger23.info("Updated game item listing", {
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
- logger23.info("Deleted game item listing", {
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 logger23;
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
- logger23 = log.scope("ShopListingService");
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
- logger24.warn("Listing missing item or currency, skipping", {
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
- logger24.debug("Retrieved shop view", {
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 logger24;
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
- logger24 = log.scope("ShopService");
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
- logger25.debug("Retrieved sprite", { slug: slug2 });
17511
+ logger26.debug("Retrieved sprite", { slug: slug2 });
17456
17512
  return template;
17457
17513
  }
17458
17514
  }
17459
- var logger25;
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
- logger25 = log.scope("SpriteService");
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
- logger26.error("Timeback client not available in context");
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
- logger26.error("Daily XP upsert returned no rows", { userId, date: targetDate });
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
- logger26.info("Student already onboarded", { userId: user.id });
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
- logger26.info("Found existing student in OneRoster", {
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
- logger26.info("Created student in OneRoster", { userId: user.id, timebackId });
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
- logger26.error("User Timeback ID update returned no rows", {
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
- logger26.debug("Fetched assessments", {
18143
+ logger27.debug("Fetched assessments", {
18088
18144
  studentSourcedId,
18089
18145
  totalCount: allAssessments.length
18090
18146
  });
18091
18147
  return allAssessments;
18092
18148
  } catch (error) {
18093
- logger26.warn("Failed to fetch assessments", { studentSourcedId, error });
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
- logger26.warn("Invalid Timeback subject in course config", {
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
- logger26.warn("Invalid Timeback grade in course config", {
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
- logger26.warn("Course missing totalXp in Timeback config", {
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
- logger26.info("Recorded activity completion", {
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 logger26;
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
- logger26 = log.scope("TimebackService");
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
- logger27.error("Upload bucket not configured in environment");
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
- logger27.debug("Initiating upload", { userId: user.id, gameId, fileName, version: version2 });
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
- logger27.info("Presigned URL generated", {
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 logger27;
18508
+ var logger28;
18453
18509
  var init_upload_service = __esm(() => {
18454
18510
  init_node();
18455
18511
  init_src2();
18456
18512
  init_errors();
18457
- logger27 = log.scope("UploadService");
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
- logger28.error("User not found", { userId: user.id });
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
- logger28.debug("Fetched user profile (game context)", { userId: user.id, gameId });
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
- logger28.debug("Fetched user profile (platform context)", { userId: user.id });
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
- logger28.debug("Fetched Timeback data", {
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
- logger28.debug("Fetching student profile", { timebackId });
18579
+ logger29.debug("Fetching student profile", { timebackId });
18524
18580
  if (!this.ctx.timeback) {
18525
- logger28.warn("Timeback client not available");
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
- logger28.warn("Failed to fetch student profile", { error, timebackId });
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
- logger28.debug("Fetching enrollments", { timebackId });
18614
+ logger29.debug("Fetching enrollments", { timebackId });
18559
18615
  if (!this.ctx.timeback) {
18560
- logger28.warn("Timeback client not available");
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
- logger28.warn("Failed to fetch enrollments", { error, timebackId });
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 logger28;
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
- logger28 = log.scope("UserService");
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
- logger29.debug("Verifying game token");
18666
+ logger30.debug("Verifying game token");
18611
18667
  const payload = await this.ctx.providers.auth.validateGameToken(token);
18612
18668
  if (!payload) {
18613
- logger29.warn("Invalid or expired game token presented");
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
- logger29.warn("Game token missing required claims", {
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
- logger29.error("User not found for valid token", {
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
- logger29.info("Token verified", { gameId, userId });
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 logger29;
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
- logger29 = log.scope("VerifyService");
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
- }, logger30 = (fn = console.log) => {
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("*", logger30());
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, logger31, fields, name3, _isResponseInArrayMode, customResultMapper) {
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 = logger31;
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 logger31;
27636
+ let logger32;
27547
27637
  if (config2.logger === true) {
27548
- logger31 = new DefaultLogger;
27638
+ logger32 = new DefaultLogger;
27549
27639
  } else if (config2.logger !== false) {
27550
- logger31 = config2.logger;
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: logger31 });
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(logger31) {
76143
- customLogger = logger31;
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, logger31;
76245
+ var customLogger, logger32;
76156
76246
  var init_adapter = __esm(() => {
76157
76247
  init_config();
76158
- logger31 = {
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
- logger31.error(`Error seeding core game '${gameData.slug}': ${error2}`);
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
- logger31.error(`❌ Error seeding project game: ${error2}`);
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 logger32, listCurrent, listHistory, postProgress, achievements3;
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
- logger32 = log.scope("AchievementController");
77822
+ logger33 = log.scope("AchievementController");
77733
77823
  listCurrent = requireAuth(async (ctx) => {
77734
- logger32.debug("Listing current achievements", { userId: ctx.user.id, gameId: ctx.gameId });
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
- logger32.debug("Listing achievement history", { userId: ctx.user.id, limit });
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
- logger32.warn("Submit achievement progress validation failed", { details });
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
- logger32.debug("Submitting progress", {
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 logger33, getAllowedOrigins;
77859
+ var logger34, getAllowedOrigins;
77770
77860
  var init_admin_controller = __esm(() => {
77771
77861
  init_src2();
77772
77862
  init_utils11();
77773
- logger33 = log.scope("AdminController");
77863
+ logger34 = log.scope("AdminController");
77774
77864
  getAllowedOrigins = requireAdmin(async (ctx) => {
77775
77865
  const shouldRefresh = ctx.url.searchParams.get("refresh") === "true";
77776
- logger33.debug("Getting allowed origins", { userId: ctx.user.id, refresh: shouldRefresh });
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 logger34, listFiles, getFile, putFile, deleteFile, initiateUpload;
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
- logger34 = log.scope("BucketController");
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
- logger34.debug("Listing files", { userId: ctx.user.id, slug: slug2, prefix: prefix2 });
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
- logger34.debug("Getting file", { userId: ctx.user.id, slug: slug2, key });
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
- logger34.debug("Uploading file", {
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
- logger34.debug("Deleting file", { userId: ctx.user.id, slug: slug2, key });
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
- logger34.warn("Initiate upload validation failed", { details });
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
- logger34.debug("Initiating multipart upload", {
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
- logger35.debug("Listing components", { level });
77975
+ logger36.debug("Listing components", { level });
77886
77976
  return ctx.services.character.listAvailableComponents(level);
77887
77977
  }
77888
- var logger35, get, getByUserId, create, update2, equipAccessory, removeAccessory, character2;
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
- logger35 = log.scope("CharacterController");
77985
+ logger36 = log.scope("CharacterController");
77896
77986
  get = requireAuth(async (ctx) => {
77897
- logger35.debug("Getting character", { userId: ctx.user.id });
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
- logger35.debug("Getting character by user ID", { requestedUserId: userId });
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
- logger35.warn("Create character validation failed", { details });
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
- logger35.debug("Creating character", {
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
- logger35.warn("Update character validation failed", { details });
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
- logger35.debug("Updating character", {
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
- logger35.warn("Equip accessory validation failed", { details });
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
- logger35.debug("Equipping accessory", {
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
- logger35.debug("Removing accessory", { userId: ctx.user.id, slot });
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 logger36, list, getById, create2, update3, remove, currencyController;
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
- logger36 = log.scope("CurrencyController");
78088
+ logger37 = log.scope("CurrencyController");
77999
78089
  list = requireAuth(async (ctx) => {
78000
- logger36.debug("Listing currencies", { userId: ctx.user.id });
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
- logger36.debug("Getting currency", { userId: ctx.user.id, currencyId });
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
- logger36.warn("Create currency validation failed", { details });
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
- logger36.debug("Creating currency", {
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
- logger36.warn("Update currency validation failed", { details });
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
- logger36.debug("Updating currency", {
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
- logger36.debug("Deleting currency", { userId: ctx.user.id, currencyId });
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 logger37, reset;
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
- logger37 = log.scope("DatabaseController");
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
- logger37.warn("Database reset validation failed", { details });
78195
+ logger38.warn("Database reset validation failed", { details });
78106
78196
  throw ApiError.unprocessableEntity("Validation failed", details);
78107
78197
  }
78108
78198
  }
78109
- logger37.debug("Resetting database", {
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 logger38;
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
- logger38 = log.scope("DeployController");
87302
+ logger39 = log.scope("DeployController");
87213
87303
  });
87214
87304
 
87215
87305
  // ../api-core/src/controllers/developer.controller.ts
87216
- var logger39, apply, getStatus, developer;
87306
+ var logger40, apply, getStatus, developer;
87217
87307
  var init_developer_controller = __esm(() => {
87218
87308
  init_src2();
87219
87309
  init_utils11();
87220
- logger39 = log.scope("DeveloperController");
87310
+ logger40 = log.scope("DeveloperController");
87221
87311
  apply = requireAuth(async (ctx) => {
87222
- logger39.debug("Applying for developer status", { userId: ctx.user.id });
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
- logger39.debug("Getting developer status", { userId: ctx.user.id });
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 logger40, add, list2, getStatus2, remove2, domains2;
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
- logger40 = log.scope("DomainController");
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
- logger40.warn("Add domain validation failed", { details });
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
- logger40.debug("Adding domain", { userId: ctx.user.id, slug: slug2, hostname: body2.hostname });
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
- logger40.debug("Listing domains", { userId: ctx.user.id, slug: slug2, environment });
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
- logger40.debug("Getting domain status", { userId: ctx.user.id, slug: slug2, hostname, refresh });
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
- logger40.debug("Removing domain", { userId: ctx.user.id, slug: slug2, hostname, environment });
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 logger41, list3, getById2, getBySlug, upsertBySlug, remove3, games2;
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
- logger41 = log.scope("GameController");
87410
+ logger42 = log.scope("GameController");
87321
87411
  list3 = requireAuth(async (ctx) => {
87322
- logger41.debug("Listing games", { userId: ctx.user.id });
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
- logger41.debug("Getting game by ID", { userId: ctx.user.id, gameId });
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
- logger41.debug("Getting game by slug", { userId: ctx.user.id, slug: slug2 });
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
- logger41.warn("Upsert game validation failed", { details });
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
- logger41.debug("Upserting game", { userId: ctx.user.id, slug: slug2, displayName: body2.displayName });
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
- logger41.debug("Deleting game", { userId: ctx.user.id, gameId });
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 logger42, list4, addItem, removeItem, inventory;
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
- logger42 = log.scope("InventoryController");
87482
+ logger43 = log.scope("InventoryController");
87393
87483
  list4 = requireAuth(async (ctx) => {
87394
- logger42.debug("Listing inventory", { userId: ctx.user.id });
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
- logger42.warn("Add inventory item validation failed", { details });
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
- logger42.debug("Adding item", {
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
- logger42.warn("Remove inventory item validation failed", { details });
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
- logger42.debug("Removing item", {
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 logger43, list5, getById3, resolve2, create3, update4, remove4, listByGame, createForGame, updateForGame, deleteForGame, items2;
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
- logger43 = log.scope("ItemController");
87543
+ logger44 = log.scope("ItemController");
87454
87544
  list5 = requireAuth(async (ctx) => {
87455
87545
  const gameId = ctx.url.searchParams.get("gameId") || undefined;
87456
- logger43.debug("Listing items", { userId: ctx.user.id, gameId });
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
- logger43.debug("Getting item", { userId: ctx.user.id, itemId });
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
- logger43.debug("Resolving item", { userId: ctx.user.id, slug: slug2, gameId });
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
- logger43.warn("Create item validation failed", { details });
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
- logger43.debug("Creating item", {
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
- logger43.warn("Update item validation failed", { details });
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
- logger43.debug("Updating item", {
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
- logger43.debug("Deleting item", { userId: ctx.user.id, itemId });
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
- logger43.debug("Listing game items", { userId: ctx.user.id, gameId });
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
- logger43.warn("Create game item validation failed", { details });
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
- logger43.debug("Creating game item", {
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
- logger43.warn("Update game item validation failed", { details });
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
- logger43.debug("Updating game item", {
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
- logger43.debug("Deleting game item", { userId: ctx.user.id, gameId, itemId });
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 logger44, submitScore, getGlobalLeaderboard, getLeaderboard, getUserRank, getUserAllScores, getUserScores, leaderboard;
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
- logger44 = log.scope("LeaderboardController");
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
- logger44.warn("Submit score validation failed", { details });
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
- logger44.debug("Submitting score", {
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
- logger44.warn("Get global leaderboard query validation failed", { details });
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
- logger44.debug("Getting global leaderboard", {
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
- logger44.warn("Get leaderboard query validation failed", { details });
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
- logger44.debug("Getting leaderboard", {
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
- logger44.debug("Getting user rank", {
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
- logger44.debug("Getting user all scores", {
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
- logger44.debug("Getting user scores", {
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
- logger45.debug("Listing level configs");
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
- logger45.debug("Getting level config", { level });
87906
+ logger46.debug("Getting level config", { level });
87817
87907
  return ctx.services.level.getConfig(level);
87818
87908
  }
87819
- var logger45, getByUser, getProgress, levels;
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
- logger45 = log.scope("LevelController");
87914
+ logger46 = log.scope("LevelController");
87825
87915
  getByUser = requireAuth(async (ctx) => {
87826
- logger45.debug("Getting user level", { userId: ctx.user.id });
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
- logger45.debug("Getting level progress", { userId: ctx.user.id });
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
- logger46.debug("Processing launch", { host: currentHost });
87975
+ logger48.debug("Processing launch", { host: currentHost });
87850
87976
  return ctx.services.lti.processLaunch(idToken, currentHost);
87851
87977
  }
87852
- var logger46, getStatus3, lti;
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
- logger46 = log.scope("LtiController");
87983
+ logger48 = log.scope("LtiController");
87858
87984
  getStatus3 = requireAuth(async (ctx) => {
87859
- logger46.debug("Getting status", { userId: ctx.user.id });
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 logger47, getByIdentifier, getElements, getObjects, createObject, deleteObject, maps2;
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
- logger47 = log.scope("MapController");
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
- logger47.debug("Getting map", { userId: ctx.user.id, identifier });
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
- logger47.debug("Getting map elements", { userId: ctx.user.id, mapId });
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
- logger47.debug("Getting map objects", { userId: ctx.user.id, mapId });
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
- logger47.warn("Create map object validation failed", { details });
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
- logger47.debug("Creating map object", {
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
- logger47.debug("Deleting map object", { userId: ctx.user.id, mapId, objectId });
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 logger48, list6, updateStatus, getStats, create4, deliver, notifications2;
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
- logger48 = log.scope("NotificationController");
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
- logger48.warn("List notifications query validation failed", { details });
88113
+ logger50.warn("List notifications query validation failed", { details });
87988
88114
  throw ApiError.badRequest("Invalid query parameters", details);
87989
88115
  }
87990
- logger48.debug("Listing notifications", { userId: ctx.user.id, ...result.data });
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
- logger48.warn("Update notification status validation failed", { details });
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
- logger48.debug("Updating status", {
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
- logger48.debug("Getting stats", { userId: ctx.user.id, startDate, endDate });
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
- logger48.warn("Create notification validation failed", { details });
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
- logger48.debug("Creating notification", {
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
- logger48.debug("Delivering notifications", { userId: ctx.user.id });
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
- logger48.error("Failed to deliver notifications", { error: error2 });
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 logger49, generateToken, realtime;
88202
+ var logger51, generateToken2, realtime;
88077
88203
  var init_realtime_controller = __esm(() => {
88078
88204
  init_src2();
88079
88205
  init_utils11();
88080
- logger49 = log.scope("RealtimeController");
88081
- generateToken = requireAuth(async (ctx) => {
88206
+ logger51 = log.scope("RealtimeController");
88207
+ generateToken2 = requireAuth(async (ctx) => {
88082
88208
  const gameIdOrSlug = ctx.params.gameId;
88083
- logger49.debug("Generating token", {
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 logger50, listKeys, getValues, setSecrets, deleteSecret, secrets;
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
- logger50 = log.scope("SecretsController");
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
- logger50.debug("Listing secret keys", { userId: ctx.user.id, slug: slug2 });
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
- logger50.debug("Getting secret values", { userId: ctx.user.id, slug: slug2 });
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
- logger50.warn("Set secrets validation failed", { details });
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
- logger50.debug("Setting secrets", {
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
- logger50.debug("Deleting secret", { userId: ctx.user.id, slug: slug2, key });
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 logger51, seed;
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
- logger51 = log.scope("SeedController");
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
- logger51.warn("Seed database validation failed", { details });
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
- logger51.debug("Seeding database", { userId: ctx.user.id, slug: slug2, codeLength: body2.code.length });
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 logger52, start2, end, mintToken, sessions2;
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
- logger52 = log.scope("SessionController");
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
- logger52.debug("Starting session", { userId: ctx.user.id, gameIdOrSlug });
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
- logger52.debug("Ending session", { userId: ctx.user.id, gameIdOrSlug, sessionId });
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
- logger52.debug("Minting token", { userId: ctx.user.id, gameIdOrSlug });
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 logger53, getShopView, shop;
88367
+ var logger55, getShopView, shop;
88242
88368
  var init_shop_controller = __esm(() => {
88243
88369
  init_src2();
88244
88370
  init_utils11();
88245
- logger53 = log.scope("ShopController");
88371
+ logger55 = log.scope("ShopController");
88246
88372
  getShopView = requireAuth(async (ctx) => {
88247
- logger53.debug("Getting shop view", { userId: ctx.user.id });
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 logger54, list7, getById4, create5, update5, remove5, listByGame2, getByGameItem, createForGameItem, updateForGameItem, deleteForGameItem, shopListings2;
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
- logger54 = log.scope("ShopListingController");
88390
+ logger56 = log.scope("ShopListingController");
88265
88391
  list7 = requireAdmin(async (ctx) => {
88266
- logger54.debug("Listing shop listings", { userId: ctx.user.id });
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
- logger54.debug("Getting listing", { userId: ctx.user.id, listingId });
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
- logger54.warn("Create shop listing validation failed", { details });
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
- logger54.debug("Creating listing", {
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
- logger54.warn("Update shop listing validation failed", { details });
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
- logger54.debug("Updating listing", {
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
- logger54.debug("Deleting listing", { userId: ctx.user.id, listingId });
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
- logger54.debug("Listing game listings", { userId: ctx.user.id, gameId });
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
- logger54.debug("Getting game item listing", { userId: ctx.user.id, gameId, itemId });
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
- logger54.warn("Create game item listing validation failed", { details });
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
- logger54.debug("Creating game item listing", {
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
- logger54.warn("Update game item listing validation failed", { details });
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
- logger54.debug("Updating game item listing", {
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
- logger54.debug("Deleting game item listing", {
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
- logger55.debug("Getting sprite by slug", { slug: slug2 });
88599
+ logger57.debug("Getting sprite by slug", { slug: slug2 });
88474
88600
  return ctx.services.sprite.getBySlug(slug2);
88475
88601
  }
88476
- var logger55, sprites;
88602
+ var logger57, sprites;
88477
88603
  var init_sprite_controller = __esm(() => {
88478
88604
  init_src2();
88479
88605
  init_errors();
88480
- logger55 = log.scope("SpriteController");
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 logger56, getTodayXp, getTotalXp, updateTodayXp, getXpHistory, populateStudent, getUser, getUserById, setupIntegration, getIntegrations, verifyIntegration, getConfig2, deleteIntegrations, endActivity, timeback2;
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
- logger56 = log.scope("TimebackController");
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
- logger56.debug("Getting today XP", { userId: ctx.user.id, date: date4, tz });
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
- logger56.debug("Getting total XP", { userId: ctx.user.id });
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
- logger56.warn("Update today XP validation failed", { details });
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
- logger56.debug("Updating today XP", { userId: ctx.user.id, xp: body2.xp });
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
- logger56.debug("Getting XP history", { userId: ctx.user.id, startDate, endDate });
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
- logger56.warn("Populate student validation failed", { details });
88662
+ logger58.warn("Populate student validation failed", { details });
88537
88663
  throw ApiError.unprocessableEntity("Validation failed", details);
88538
88664
  }
88539
88665
  }
88540
- logger56.debug("Populating student", {
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
- logger56.debug("Getting user", { userId: ctx.user.id, gameId: ctx.gameId });
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
- logger56.debug("Getting user by ID", { requesterId: ctx.user.id, timebackId });
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
- logger56.warn("Setup integration validation failed", { details });
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
- logger56.debug("Setting up integration", {
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
- logger56.debug("Getting integrations", { userId: ctx.user.id, gameId });
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
- logger56.debug("Verifying integration", { userId: ctx.user.id, gameId });
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
- logger56.debug("Getting config", { userId: ctx.user.id, gameId });
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
- logger56.debug("Deleting integrations", { userId: ctx.user.id, gameId });
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
- logger56.warn("End activity validation failed", { details });
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
- logger56.debug("Ending activity", { userId: ctx.user.id, gameId });
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 logger57, initiate;
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
- logger57 = log.scope("UploadController");
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
- logger57.warn("Initiate upload validation failed", { details });
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
- logger57.debug("Initiating upload", { userId: ctx.user.id, gameId: body2.gameId });
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 logger58, getMe, users2;
88801
+ var logger60, getMe, users2;
88676
88802
  var init_user_controller = __esm(() => {
88677
88803
  init_src2();
88678
88804
  init_utils11();
88679
- logger58 = log.scope("UserController");
88805
+ logger60 = log.scope("UserController");
88680
88806
  getMe = requireAuth(async (ctx) => {
88681
- logger58.debug("Getting current user", { userId: ctx.user.id, gameId: ctx.gameId });
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 logger59;
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
- logger59 = log.scope("VerifyController");
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);