From 4c48f04c4e1c8428eb3c78d656f34105ef9832c4 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 15 Aug 2025 13:53:13 +0200 Subject: [PATCH] Refactor RequisitionShop component: remove unused GM panel logic, enhance error handling, and improve player purchase flow. Update tests for RequisitionShop to cover new functionality and ensure proper rendering. Implement curl-based HTTP requests in GM and player tests for better compatibility. Add script to ensure GM user exists in the database with appropriate privileges. --- .vscode/tasks.json | 15 + database/backend.log | 1999 ++++++++++++++++++++++++++++ database/ensure-gm.js | 55 + database/sqlite-db.js | 9 +- database/sqlite/deathwatch.db-shm | Bin 32768 -> 32768 bytes database/sqlite/deathwatch.db-wal | Bin 420272 -> 2727472 bytes jest.config.js | 10 +- package.json | 17 +- src/App.js | 36 +- src/components/PlayerTab.jsx | 334 +++-- src/components/RequisitionShop.jsx | 245 ++-- src/tests/requisitionShop.test.js | 105 +- tests/gmtest.test.js | 87 +- tests/playertest.test.js | 105 +- 14 files changed, 2558 insertions(+), 459 deletions(-) create mode 100644 .vscode/tasks.json create mode 100644 database/ensure-gm.js diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..da08982 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,15 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "type": "shell", + "command": "npm run build", + "group": "build", + "problemMatcher": [ + "$eslint-stylish" + ], + "isBackground": false + } + ] +} \ No newline at end of file diff --git a/database/backend.log b/database/backend.log index 9746d19..413ef6c 100644 --- a/database/backend.log +++ b/database/backend.log @@ -583,3 +583,2002 @@ Connected to MongoDB [2025-08-15T10:17:18.099Z] DB: createSession - start e5a905f54488e26aae838d7a16d7f50d681f54c72749485f7944464e35b92e9d expiresAt 2025-08-16T10:17:18.099Z [2025-08-15T10:17:18.100Z] DB: createSession - done e5a905f54488e26aae838d7a16d7f50d681f54c72749485f7944464e35b92e9d [2025-08-15T10:17:18.100Z] API: Player login gmtest e5a905f54488e26aae838d7a16d7f50d681f54c72749485f7944464e35b92e9d +[2025-08-15T10:20:13.902Z] DB: getAllPlayers - start +[2025-08-15T10:20:14.879Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T10:20:14.879Z] API: Fetch all players (public) Found 4 players +[2025-08-15T10:20:20.929Z] DB: getAllPlayers - start +[2025-08-15T10:20:21.817Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T10:20:21.818Z] API: Fetch all players (public) Found 4 players +[2025-08-15T10:20:21.820Z] DB: getAllPlayers - start +[2025-08-15T10:20:21.821Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T10:20:21.821Z] API: Fetch all players (public) Found 4 players +[2025-08-15T10:23:51.235Z] DB: getAllPlayers - start +[2025-08-15T10:23:51.236Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T10:23:51.236Z] API: Fetch all players (public) Found 4 players +[2025-08-15T10:23:54.470Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:23:54.470Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:23:54.472Z] DB: createSession - start 8462571458eeb2847edcd2f08c1c9196d0dbed95f232117d7234b241e77abbac expiresAt 2025-08-16T10:23:54.472Z +[2025-08-15T10:23:54.474Z] DB: createSession - done 8462571458eeb2847edcd2f08c1c9196d0dbed95f232117d7234b241e77abbac +[2025-08-15T10:23:54.474Z] SESSION: Login success christoffer 8462571458eeb2847edcd2f08c1c9196d0dbed95f232117d7234b241e77abbac +[2025-08-15T10:23:54.481Z] DB: getSession - start 8462571458eeb2847edcd2f08c1c9196d0dbed95f232117d7234b241e77abbac +[2025-08-15T10:23:54.481Z] DB: getSession - ok 8462571458eeb2847edcd2f08c1c9196d0dbed95f232117d7234b241e77abbac +[2025-08-15T10:23:54.481Z] SESSION: Validate success 8462571458eeb2847edcd2f08c1c9196d0dbed95f232117d7234b241e77abbac christoffer +[2025-08-15T10:23:56.388Z] DB: getAllPlayers - start +[2025-08-15T10:23:56.388Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T10:23:56.388Z] API: Fetch all players (public) Found 4 players +[2025-08-15T10:26:20.276Z] DB: getAllPlayers - start +[2025-08-15T10:26:20.277Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T10:26:53.404Z] DB: getAllPlayers - start +[2025-08-15T10:26:53.405Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T10:27:53.522Z] DB: getAllPlayers - start +[2025-08-15T10:27:53.523Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T10:31:36.298Z] API: Failed to create player undefined TypeError: Cannot destructure property 'name' of 'req.body' as it is undefined. + at /home/alex/git/dwroller/database/routes/playerRoutes-sqlite.js:111:13 + at Layer.handleRequest (/home/alex/git/dwroller/node_modules/router/lib/layer.js:152:17) + at next (/home/alex/git/dwroller/node_modules/router/lib/route.js:157:13) + at Route.dispatch (/home/alex/git/dwroller/node_modules/router/lib/route.js:117:3) + at handle (/home/alex/git/dwroller/node_modules/router/index.js:435:11) + at Layer.handleRequest (/home/alex/git/dwroller/node_modules/router/lib/layer.js:152:17) + at /home/alex/git/dwroller/node_modules/router/index.js:295:15 + at processParams (/home/alex/git/dwroller/node_modules/router/index.js:582:12) + at next (/home/alex/git/dwroller/node_modules/router/index.js:291:5) + at Function.handle (/home/alex/git/dwroller/node_modules/router/index.js:186:3) +[2025-08-15T10:32:11.814Z] API: Failed to create player undefined TypeError: Cannot destructure property 'name' of 'req.body' as it is undefined. + at /home/alex/git/dwroller/database/routes/playerRoutes-sqlite.js:111:13 + at Layer.handleRequest (/home/alex/git/dwroller/node_modules/router/lib/layer.js:152:17) + at next (/home/alex/git/dwroller/node_modules/router/lib/route.js:157:13) + at Route.dispatch (/home/alex/git/dwroller/node_modules/router/lib/route.js:117:3) + at handle (/home/alex/git/dwroller/node_modules/router/index.js:435:11) + at Layer.handleRequest (/home/alex/git/dwroller/node_modules/router/lib/layer.js:152:17) + at /home/alex/git/dwroller/node_modules/router/index.js:295:15 + at processParams (/home/alex/git/dwroller/node_modules/router/index.js:582:12) + at next (/home/alex/git/dwroller/node_modules/router/index.js:291:5) + at Function.handle (/home/alex/git/dwroller/node_modules/router/index.js:186:3) +[2025-08-15T10:33:07.055Z] API: Failed to create player undefined TypeError: Cannot destructure property 'name' of 'req.body' as it is undefined. + at /home/alex/git/dwroller/database/routes/playerRoutes-sqlite.js:111:13 + at Layer.handleRequest (/home/alex/git/dwroller/node_modules/router/lib/layer.js:152:17) + at next (/home/alex/git/dwroller/node_modules/router/lib/route.js:157:13) + at Route.dispatch (/home/alex/git/dwroller/node_modules/router/lib/route.js:117:3) + at handle (/home/alex/git/dwroller/node_modules/router/index.js:435:11) + at Layer.handleRequest (/home/alex/git/dwroller/node_modules/router/lib/layer.js:152:17) + at /home/alex/git/dwroller/node_modules/router/index.js:295:15 + at processParams (/home/alex/git/dwroller/node_modules/router/index.js:582:12) + at next (/home/alex/git/dwroller/node_modules/router/index.js:291:5) + at Function.handle (/home/alex/git/dwroller/node_modules/router/index.js:186:3) +[2025-08-15T10:34:05.822Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:34:05.822Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:34:27.974Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T10:34:27.974Z] DB: deletePlayer - start gmtest +[2025-08-15T10:34:27.974Z] DB: deletePlayer - changes 1 gmtest +[2025-08-15T10:34:27.974Z] API: Deleted player gmtest +[2025-08-15T10:34:28.036Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:34:28.036Z] DB: getPlayerByName - not found gmtest +[2025-08-15T10:34:28.124Z] DB: createPlayer - start gmtest +[2025-08-15T10:34:28.124Z] DB: createPlayer - done gmtest rowid 9 +[2025-08-15T10:34:28.124Z] API: Created player gmtest +[2025-08-15T10:34:28.145Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T10:34:28.145Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:34:28.145Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:34:28.145Z] DB: updatePlayer - start gmtest +[2025-08-15T10:34:28.145Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T10:34:28.145Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:34:28.145Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:34:28.145Z] API: Updated player gmtest +[2025-08-15T10:34:28.163Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T10:34:28.163Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:34:28.163Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:34:28.243Z] DB: updatePlayer - start gmtest +[2025-08-15T10:34:28.244Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T10:34:28.244Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:34:28.244Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:34:28.244Z] API: Updated player gmtest +[2025-08-15T10:34:28.261Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:34:28.262Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:34:28.341Z] DB: createSession - start 444bd02c7be1692f2e2e50b89843a75d8cd0a21b82d129817277e91e75223be0 expiresAt 2025-08-16T10:34:28.341Z +[2025-08-15T10:34:28.342Z] DB: createSession - done 444bd02c7be1692f2e2e50b89843a75d8cd0a21b82d129817277e91e75223be0 +[2025-08-15T10:34:28.342Z] API: Player login gmtest 444bd02c7be1692f2e2e50b89843a75d8cd0a21b82d129817277e91e75223be0 +[2025-08-15T10:34:51.523Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T10:34:51.523Z] DB: deletePlayer - start gmtest +[2025-08-15T10:34:51.523Z] DB: deletePlayer - changes 1 gmtest +[2025-08-15T10:34:51.523Z] API: Deleted player gmtest +[2025-08-15T10:34:51.588Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:34:51.588Z] DB: getPlayerByName - not found gmtest +[2025-08-15T10:34:51.667Z] DB: createPlayer - start gmtest +[2025-08-15T10:34:51.668Z] DB: createPlayer - done gmtest rowid 10 +[2025-08-15T10:34:51.668Z] API: Created player gmtest +[2025-08-15T10:34:51.688Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T10:34:51.688Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:34:51.688Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:34:51.688Z] DB: updatePlayer - start gmtest +[2025-08-15T10:34:51.688Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T10:34:51.688Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:34:51.688Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:34:51.688Z] API: Updated player gmtest +[2025-08-15T10:34:51.706Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T10:34:51.707Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:34:51.707Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:34:51.787Z] DB: updatePlayer - start gmtest +[2025-08-15T10:34:51.787Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T10:34:51.787Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:34:51.788Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:34:51.788Z] API: Updated player gmtest +[2025-08-15T10:34:51.804Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:34:51.804Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:34:51.884Z] DB: createSession - start 66283faa2d748269447f5df8f8f8c7c646b729db75100a25fc08fd89415a1bf3 expiresAt 2025-08-16T10:34:51.884Z +[2025-08-15T10:34:51.884Z] DB: createSession - done 66283faa2d748269447f5df8f8f8c7c646b729db75100a25fc08fd89415a1bf3 +[2025-08-15T10:34:51.884Z] API: Player login gmtest 66283faa2d748269447f5df8f8f8c7c646b729db75100a25fc08fd89415a1bf3 +[2025-08-15T10:34:51.904Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T10:34:51.905Z] DB: deletePlayer - start gmtest +[2025-08-15T10:34:51.905Z] DB: deletePlayer - changes 1 gmtest +[2025-08-15T10:34:51.905Z] API: Deleted player gmtest +[2025-08-15T10:34:51.925Z] DB: getAllPlayers - start +[2025-08-15T10:34:51.926Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:34:51.926Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:36:27.549Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:36:27.549Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:36:27.628Z] DB: createSession - start 49164dd78bfe74fba10d4b167249433af8c9be5985570dbce2cd650ff55b2065 expiresAt 2025-08-16T10:36:27.628Z +[2025-08-15T10:36:27.629Z] DB: createSession - done 49164dd78bfe74fba10d4b167249433af8c9be5985570dbce2cd650ff55b2065 +[2025-08-15T10:36:27.629Z] API: Player login christoffer 49164dd78bfe74fba10d4b167249433af8c9be5985570dbce2cd650ff55b2065 +[2025-08-15T10:36:27.649Z] DB: getSession - start 49164dd78bfe74fba10d4b167249433af8c9be5985570dbce2cd650ff55b2065 +[2025-08-15T10:36:27.649Z] DB: getSession - ok 49164dd78bfe74fba10d4b167249433af8c9be5985570dbce2cd650ff55b2065 +[2025-08-15T10:36:27.649Z] SESSION: Valid 49164dd78bfe74fba10d4b167249433af8c9be5985570dbce2cd650ff55b2065 christoffer PUT /api/players/christoffer +[2025-08-15T10:36:27.649Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:36:27.649Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:36:27.649Z] DB: updatePlayer - start christoffer +[2025-08-15T10:36:27.649Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T10:36:27.649Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:36:27.650Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:36:27.650Z] API: Updated player christoffer +[2025-08-15T10:36:27.666Z] DB: getSession - start 49164dd78bfe74fba10d4b167249433af8c9be5985570dbce2cd650ff55b2065 +[2025-08-15T10:36:27.667Z] DB: getSession - ok 49164dd78bfe74fba10d4b167249433af8c9be5985570dbce2cd650ff55b2065 +[2025-08-15T10:36:27.667Z] SESSION: Valid 49164dd78bfe74fba10d4b167249433af8c9be5985570dbce2cd650ff55b2065 christoffer PUT /api/players/christoffer +[2025-08-15T10:36:27.667Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:36:27.667Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:36:27.667Z] DB: updatePlayer - start christoffer +[2025-08-15T10:36:27.667Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T10:36:27.667Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:36:27.667Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:36:27.667Z] API: Updated player christoffer +[2025-08-15T10:36:27.878Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T10:36:27.878Z] DB: deletePlayer - start gmtest +[2025-08-15T10:36:27.878Z] DB: deletePlayer - changes 0 gmtest +[2025-08-15T10:36:27.896Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:36:27.897Z] DB: getPlayerByName - not found gmtest +[2025-08-15T10:36:27.976Z] DB: createPlayer - start gmtest +[2025-08-15T10:36:27.976Z] DB: createPlayer - done gmtest rowid 11 +[2025-08-15T10:36:27.976Z] API: Created player gmtest +[2025-08-15T10:36:27.995Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T10:36:27.995Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:36:27.995Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:36:27.995Z] DB: updatePlayer - start gmtest +[2025-08-15T10:36:27.996Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T10:36:27.996Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:36:27.996Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:36:27.996Z] API: Updated player gmtest +[2025-08-15T10:36:28.014Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T10:36:28.014Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:36:28.014Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:36:28.094Z] DB: updatePlayer - start gmtest +[2025-08-15T10:36:28.095Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T10:36:28.095Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:36:28.095Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:36:28.095Z] API: Updated player gmtest +[2025-08-15T10:36:28.112Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:36:28.112Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:36:28.192Z] DB: createSession - start 8b2a6bacb8890b5ec67c238ebdf69b4480c642ef6bc2fc8bd43ab864cdeb13ca expiresAt 2025-08-16T10:36:28.192Z +[2025-08-15T10:36:28.192Z] DB: createSession - done 8b2a6bacb8890b5ec67c238ebdf69b4480c642ef6bc2fc8bd43ab864cdeb13ca +[2025-08-15T10:36:28.192Z] API: Player login gmtest 8b2a6bacb8890b5ec67c238ebdf69b4480c642ef6bc2fc8bd43ab864cdeb13ca +[2025-08-15T10:36:28.208Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T10:36:28.208Z] DB: deletePlayer - start gmtest +[2025-08-15T10:36:28.209Z] DB: deletePlayer - changes 1 gmtest +[2025-08-15T10:36:28.209Z] API: Deleted player gmtest +[2025-08-15T10:36:28.224Z] DB: getAllPlayers - start +[2025-08-15T10:36:28.225Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:36:28.225Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:36:28.604Z] DB: getAllPlayers - start +[2025-08-15T10:36:28.850Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:38:30.289Z] DB: getAllPlayers - start +[2025-08-15T10:38:30.290Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:38:30.651Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:38:30.651Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:38:30.731Z] DB: createSession - start aa7290ce0a846189acdf4bab564260e2a7847ed7e6ecb57917b4d482cfa571af expiresAt 2025-08-16T10:38:30.730Z +[2025-08-15T10:38:30.731Z] DB: createSession - done aa7290ce0a846189acdf4bab564260e2a7847ed7e6ecb57917b4d482cfa571af +[2025-08-15T10:38:30.731Z] API: Player login christoffer aa7290ce0a846189acdf4bab564260e2a7847ed7e6ecb57917b4d482cfa571af +[2025-08-15T10:38:30.751Z] DB: getSession - start aa7290ce0a846189acdf4bab564260e2a7847ed7e6ecb57917b4d482cfa571af +[2025-08-15T10:38:30.751Z] DB: getSession - ok aa7290ce0a846189acdf4bab564260e2a7847ed7e6ecb57917b4d482cfa571af +[2025-08-15T10:38:30.751Z] SESSION: Valid aa7290ce0a846189acdf4bab564260e2a7847ed7e6ecb57917b4d482cfa571af christoffer PUT /api/players/christoffer +[2025-08-15T10:38:30.751Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:38:30.751Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:38:30.751Z] DB: updatePlayer - start christoffer +[2025-08-15T10:38:30.751Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T10:38:30.751Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:38:30.751Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:38:30.751Z] API: Updated player christoffer +[2025-08-15T10:38:30.787Z] DB: getSession - start aa7290ce0a846189acdf4bab564260e2a7847ed7e6ecb57917b4d482cfa571af +[2025-08-15T10:38:30.787Z] DB: getSession - ok aa7290ce0a846189acdf4bab564260e2a7847ed7e6ecb57917b4d482cfa571af +[2025-08-15T10:38:30.787Z] SESSION: Valid aa7290ce0a846189acdf4bab564260e2a7847ed7e6ecb57917b4d482cfa571af christoffer PUT /api/players/christoffer +[2025-08-15T10:38:30.788Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:38:30.788Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:38:30.788Z] DB: updatePlayer - start christoffer +[2025-08-15T10:38:30.788Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T10:38:30.788Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:38:30.788Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:38:30.788Z] API: Updated player christoffer +[2025-08-15T10:38:31.120Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T10:38:31.121Z] DB: deletePlayer - start gmtest +[2025-08-15T10:38:31.121Z] DB: deletePlayer - changes 0 gmtest +[2025-08-15T10:38:31.143Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:38:31.143Z] DB: getPlayerByName - not found gmtest +[2025-08-15T10:38:31.222Z] DB: createPlayer - start gmtest +[2025-08-15T10:38:31.222Z] DB: createPlayer - done gmtest rowid 12 +[2025-08-15T10:38:31.222Z] API: Created player gmtest +[2025-08-15T10:38:31.252Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T10:38:31.252Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:38:31.252Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:38:31.252Z] DB: updatePlayer - start gmtest +[2025-08-15T10:38:31.252Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T10:38:31.252Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:38:31.252Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:38:31.252Z] API: Updated player gmtest +[2025-08-15T10:38:31.270Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T10:38:31.271Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:38:31.271Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:38:31.350Z] DB: updatePlayer - start gmtest +[2025-08-15T10:38:31.350Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T10:38:31.350Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:38:31.351Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:38:31.351Z] API: Updated player gmtest +[2025-08-15T10:38:31.367Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:38:31.368Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:38:31.447Z] DB: createSession - start 6b8611ef6f253c2c9ef79186a318a72f7e2cb94a02ff854c710c00c527b9f655 expiresAt 2025-08-16T10:38:31.447Z +[2025-08-15T10:38:31.447Z] DB: createSession - done 6b8611ef6f253c2c9ef79186a318a72f7e2cb94a02ff854c710c00c527b9f655 +[2025-08-15T10:38:31.447Z] API: Player login gmtest 6b8611ef6f253c2c9ef79186a318a72f7e2cb94a02ff854c710c00c527b9f655 +[2025-08-15T10:38:31.465Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T10:38:31.465Z] DB: deletePlayer - start gmtest +[2025-08-15T10:38:31.465Z] DB: deletePlayer - changes 1 gmtest +[2025-08-15T10:38:31.465Z] API: Deleted player gmtest +[2025-08-15T10:38:31.483Z] DB: getAllPlayers - start +[2025-08-15T10:38:31.483Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:38:31.483Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:39:22.248Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T10:39:22.248Z] DB: deletePlayer - start gmtest +[2025-08-15T10:39:22.248Z] DB: deletePlayer - changes 0 gmtest +[2025-08-15T10:39:22.267Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:39:22.268Z] DB: getPlayerByName - not found gmtest +[2025-08-15T10:39:22.346Z] DB: createPlayer - start gmtest +[2025-08-15T10:39:22.347Z] DB: createPlayer - done gmtest rowid 13 +[2025-08-15T10:39:22.347Z] API: Created player gmtest +[2025-08-15T10:39:22.366Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T10:39:22.366Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:39:22.366Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:39:22.366Z] DB: updatePlayer - start gmtest +[2025-08-15T10:39:22.366Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T10:39:22.366Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:39:22.366Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:39:22.366Z] API: Updated player gmtest +[2025-08-15T10:39:22.385Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T10:39:22.385Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:39:22.385Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:39:22.465Z] DB: updatePlayer - start gmtest +[2025-08-15T10:39:22.466Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T10:39:22.466Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:39:22.466Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:39:22.466Z] API: Updated player gmtest +[2025-08-15T10:39:22.483Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:39:22.483Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:39:22.562Z] DB: createSession - start 73c3c532018afc09708d3f1d580331d882466d8bfbdefc3f8dd43c73b5547eda expiresAt 2025-08-16T10:39:22.562Z +[2025-08-15T10:39:22.562Z] DB: createSession - done 73c3c532018afc09708d3f1d580331d882466d8bfbdefc3f8dd43c73b5547eda +[2025-08-15T10:39:22.562Z] API: Player login gmtest 73c3c532018afc09708d3f1d580331d882466d8bfbdefc3f8dd43c73b5547eda +[2025-08-15T10:39:22.580Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T10:39:22.580Z] DB: deletePlayer - start gmtest +[2025-08-15T10:39:22.580Z] DB: deletePlayer - changes 1 gmtest +[2025-08-15T10:39:22.580Z] API: Deleted player gmtest +[2025-08-15T10:39:22.597Z] DB: getAllPlayers - start +[2025-08-15T10:39:22.597Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:39:22.597Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:39:23.097Z] DB: getAllPlayers - start +[2025-08-15T10:39:23.098Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:39:23.434Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:39:23.435Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:39:23.514Z] DB: createSession - start bc50c7de3fab2c109893d399a2f5e8b8da4f0550c420e0896f049d249fa83c49 expiresAt 2025-08-16T10:39:23.514Z +[2025-08-15T10:39:23.514Z] DB: createSession - done bc50c7de3fab2c109893d399a2f5e8b8da4f0550c420e0896f049d249fa83c49 +[2025-08-15T10:39:23.514Z] API: Player login christoffer bc50c7de3fab2c109893d399a2f5e8b8da4f0550c420e0896f049d249fa83c49 +[2025-08-15T10:39:23.546Z] DB: getSession - start bc50c7de3fab2c109893d399a2f5e8b8da4f0550c420e0896f049d249fa83c49 +[2025-08-15T10:39:23.546Z] DB: getSession - ok bc50c7de3fab2c109893d399a2f5e8b8da4f0550c420e0896f049d249fa83c49 +[2025-08-15T10:39:23.546Z] SESSION: Valid bc50c7de3fab2c109893d399a2f5e8b8da4f0550c420e0896f049d249fa83c49 christoffer PUT /api/players/christoffer +[2025-08-15T10:39:23.546Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:39:23.546Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:39:23.546Z] DB: updatePlayer - start christoffer +[2025-08-15T10:39:23.546Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T10:39:23.546Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:39:23.546Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:39:23.546Z] API: Updated player christoffer +[2025-08-15T10:39:23.565Z] DB: getSession - start bc50c7de3fab2c109893d399a2f5e8b8da4f0550c420e0896f049d249fa83c49 +[2025-08-15T10:39:23.566Z] DB: getSession - ok bc50c7de3fab2c109893d399a2f5e8b8da4f0550c420e0896f049d249fa83c49 +[2025-08-15T10:39:23.566Z] SESSION: Valid bc50c7de3fab2c109893d399a2f5e8b8da4f0550c420e0896f049d249fa83c49 christoffer PUT /api/players/christoffer +[2025-08-15T10:39:23.566Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:39:23.566Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:39:23.566Z] DB: updatePlayer - start christoffer +[2025-08-15T10:39:23.566Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T10:39:23.566Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:39:23.566Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:39:23.566Z] API: Updated player christoffer +[2025-08-15T10:40:36.502Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T10:40:36.502Z] DB: deletePlayer - start gmtest +[2025-08-15T10:40:36.503Z] DB: deletePlayer - changes 0 gmtest +[2025-08-15T10:40:36.521Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:40:36.521Z] DB: getPlayerByName - not found gmtest +[2025-08-15T10:40:36.600Z] DB: createPlayer - start gmtest +[2025-08-15T10:40:36.601Z] DB: createPlayer - done gmtest rowid 14 +[2025-08-15T10:40:36.601Z] API: Created player gmtest +[2025-08-15T10:40:36.621Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T10:40:36.621Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:40:36.621Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:40:36.621Z] DB: updatePlayer - start gmtest +[2025-08-15T10:40:36.621Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T10:40:36.622Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:40:36.622Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:40:36.622Z] API: Updated player gmtest +[2025-08-15T10:40:36.640Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T10:40:36.640Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:40:36.640Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:40:36.720Z] DB: updatePlayer - start gmtest +[2025-08-15T10:40:36.720Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T10:40:36.720Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:40:36.720Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:40:36.720Z] API: Updated player gmtest +[2025-08-15T10:40:36.737Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:40:36.737Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:40:36.817Z] DB: createSession - start 6656d6708705ac6dd41c83503d5f0d7c156294004ff461da7308db85470cf069 expiresAt 2025-08-16T10:40:36.817Z +[2025-08-15T10:40:36.817Z] DB: createSession - done 6656d6708705ac6dd41c83503d5f0d7c156294004ff461da7308db85470cf069 +[2025-08-15T10:40:36.817Z] API: Player login gmtest 6656d6708705ac6dd41c83503d5f0d7c156294004ff461da7308db85470cf069 +[2025-08-15T10:40:36.834Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T10:40:36.835Z] DB: deletePlayer - start gmtest +[2025-08-15T10:40:36.835Z] DB: deletePlayer - changes 1 gmtest +[2025-08-15T10:40:36.835Z] API: Deleted player gmtest +[2025-08-15T10:40:36.851Z] DB: getAllPlayers - start +[2025-08-15T10:40:36.852Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:40:36.852Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:40:37.401Z] DB: getAllPlayers - start +[2025-08-15T10:40:37.402Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:40:37.767Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:40:37.767Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:40:37.847Z] DB: createSession - start 49837c09fd42c3153e3843fbc6c2cb311df8d9c98efa579c2b519c4a9e211806 expiresAt 2025-08-16T10:40:37.847Z +[2025-08-15T10:40:37.847Z] DB: createSession - done 49837c09fd42c3153e3843fbc6c2cb311df8d9c98efa579c2b519c4a9e211806 +[2025-08-15T10:40:37.847Z] API: Player login christoffer 49837c09fd42c3153e3843fbc6c2cb311df8d9c98efa579c2b519c4a9e211806 +[2025-08-15T10:40:37.869Z] DB: getSession - start 49837c09fd42c3153e3843fbc6c2cb311df8d9c98efa579c2b519c4a9e211806 +[2025-08-15T10:40:37.869Z] DB: getSession - ok 49837c09fd42c3153e3843fbc6c2cb311df8d9c98efa579c2b519c4a9e211806 +[2025-08-15T10:40:37.869Z] SESSION: Valid 49837c09fd42c3153e3843fbc6c2cb311df8d9c98efa579c2b519c4a9e211806 christoffer PUT /api/players/christoffer +[2025-08-15T10:40:37.869Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:40:37.869Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:40:37.869Z] DB: updatePlayer - start christoffer +[2025-08-15T10:40:37.870Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T10:40:37.870Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:40:37.870Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:40:37.870Z] API: Updated player christoffer +[2025-08-15T10:40:37.888Z] DB: getSession - start 49837c09fd42c3153e3843fbc6c2cb311df8d9c98efa579c2b519c4a9e211806 +[2025-08-15T10:40:37.888Z] DB: getSession - ok 49837c09fd42c3153e3843fbc6c2cb311df8d9c98efa579c2b519c4a9e211806 +[2025-08-15T10:40:37.888Z] SESSION: Valid 49837c09fd42c3153e3843fbc6c2cb311df8d9c98efa579c2b519c4a9e211806 christoffer PUT /api/players/christoffer +[2025-08-15T10:40:37.888Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:40:37.888Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:40:37.888Z] DB: updatePlayer - start christoffer +[2025-08-15T10:40:37.889Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T10:40:37.889Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:40:37.889Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:40:37.889Z] API: Updated player christoffer +[2025-08-15T10:41:20.027Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T10:41:20.028Z] DB: deletePlayer - start gmtest +[2025-08-15T10:41:20.028Z] DB: deletePlayer - changes 0 gmtest +[2025-08-15T10:41:20.045Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:41:20.046Z] DB: getPlayerByName - not found gmtest +[2025-08-15T10:41:20.128Z] DB: createPlayer - start gmtest +[2025-08-15T10:41:20.129Z] DB: createPlayer - done gmtest rowid 15 +[2025-08-15T10:41:20.129Z] API: Created player gmtest +[2025-08-15T10:41:20.148Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T10:41:20.148Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:41:20.148Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:41:20.148Z] DB: updatePlayer - start gmtest +[2025-08-15T10:41:20.148Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T10:41:20.148Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:41:20.148Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:41:20.149Z] API: Updated player gmtest +[2025-08-15T10:41:20.165Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T10:41:20.165Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:41:20.165Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:41:20.245Z] DB: updatePlayer - start gmtest +[2025-08-15T10:41:20.245Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T10:41:20.245Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:41:20.245Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:41:20.245Z] API: Updated player gmtest +[2025-08-15T10:41:20.262Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:41:20.262Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:41:20.341Z] DB: createSession - start f9ebc41e34b2a8f8c534e54d8bdceaa72a8be14243da1f791eb86bbf23f3cfc7 expiresAt 2025-08-16T10:41:20.341Z +[2025-08-15T10:41:20.342Z] DB: createSession - done f9ebc41e34b2a8f8c534e54d8bdceaa72a8be14243da1f791eb86bbf23f3cfc7 +[2025-08-15T10:41:20.342Z] API: Player login gmtest f9ebc41e34b2a8f8c534e54d8bdceaa72a8be14243da1f791eb86bbf23f3cfc7 +[2025-08-15T10:41:20.359Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T10:41:20.359Z] DB: deletePlayer - start gmtest +[2025-08-15T10:41:20.359Z] DB: deletePlayer - changes 1 gmtest +[2025-08-15T10:41:20.359Z] API: Deleted player gmtest +[2025-08-15T10:41:20.375Z] DB: getAllPlayers - start +[2025-08-15T10:41:20.375Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:41:20.375Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:41:20.857Z] DB: getAllPlayers - start +[2025-08-15T10:41:20.858Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:41:21.180Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:41:21.180Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:41:21.259Z] DB: createSession - start ad684cb3a5dfe166242e6e8ad5b22b39c06d0df546af8ba4e5907559af92a325 expiresAt 2025-08-16T10:41:21.259Z +[2025-08-15T10:41:21.260Z] DB: createSession - done ad684cb3a5dfe166242e6e8ad5b22b39c06d0df546af8ba4e5907559af92a325 +[2025-08-15T10:41:21.260Z] API: Player login christoffer ad684cb3a5dfe166242e6e8ad5b22b39c06d0df546af8ba4e5907559af92a325 +[2025-08-15T10:41:21.281Z] DB: getSession - start ad684cb3a5dfe166242e6e8ad5b22b39c06d0df546af8ba4e5907559af92a325 +[2025-08-15T10:41:21.281Z] DB: getSession - ok ad684cb3a5dfe166242e6e8ad5b22b39c06d0df546af8ba4e5907559af92a325 +[2025-08-15T10:41:21.281Z] SESSION: Valid ad684cb3a5dfe166242e6e8ad5b22b39c06d0df546af8ba4e5907559af92a325 christoffer PUT /api/players/christoffer +[2025-08-15T10:41:21.281Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:41:21.281Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:41:21.281Z] DB: updatePlayer - start christoffer +[2025-08-15T10:41:21.281Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T10:41:21.281Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:41:21.281Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:41:21.281Z] API: Updated player christoffer +[2025-08-15T10:41:21.299Z] DB: getSession - start ad684cb3a5dfe166242e6e8ad5b22b39c06d0df546af8ba4e5907559af92a325 +[2025-08-15T10:41:21.299Z] DB: getSession - ok ad684cb3a5dfe166242e6e8ad5b22b39c06d0df546af8ba4e5907559af92a325 +[2025-08-15T10:41:21.299Z] SESSION: Valid ad684cb3a5dfe166242e6e8ad5b22b39c06d0df546af8ba4e5907559af92a325 christoffer PUT /api/players/christoffer +[2025-08-15T10:41:21.299Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:41:21.299Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:41:21.299Z] DB: updatePlayer - start christoffer +[2025-08-15T10:41:21.300Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T10:41:21.300Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:41:21.300Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:41:21.300Z] API: Updated player christoffer +[2025-08-15T10:44:19.063Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T10:44:19.063Z] DB: deletePlayer - start gmtest +[2025-08-15T10:44:19.063Z] DB: deletePlayer - changes 0 gmtest +[2025-08-15T10:44:19.079Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:44:19.079Z] DB: getPlayerByName - not found gmtest +[2025-08-15T10:44:19.159Z] DB: createPlayer - start gmtest +[2025-08-15T10:44:19.159Z] DB: createPlayer - done gmtest rowid 16 +[2025-08-15T10:44:19.159Z] API: Created player gmtest +[2025-08-15T10:44:19.176Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T10:44:19.176Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:44:19.176Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:44:19.177Z] DB: updatePlayer - start gmtest +[2025-08-15T10:44:19.177Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T10:44:19.177Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:44:19.177Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:44:19.177Z] API: Updated player gmtest +[2025-08-15T10:44:19.191Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T10:44:19.191Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:44:19.191Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:44:19.271Z] DB: updatePlayer - start gmtest +[2025-08-15T10:44:19.272Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T10:44:19.272Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:44:19.272Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:44:19.272Z] API: Updated player gmtest +[2025-08-15T10:44:19.286Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:44:19.286Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:44:19.366Z] DB: createSession - start 3b86daa42a684f46e576758f1387a5df23720e1e7b26aad3767f29b6d6b88f6f expiresAt 2025-08-16T10:44:19.366Z +[2025-08-15T10:44:19.366Z] DB: createSession - done 3b86daa42a684f46e576758f1387a5df23720e1e7b26aad3767f29b6d6b88f6f +[2025-08-15T10:44:19.366Z] API: Player login gmtest 3b86daa42a684f46e576758f1387a5df23720e1e7b26aad3767f29b6d6b88f6f +[2025-08-15T10:44:19.381Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T10:44:19.381Z] DB: deletePlayer - start gmtest +[2025-08-15T10:44:19.381Z] DB: deletePlayer - changes 1 gmtest +[2025-08-15T10:44:19.381Z] API: Deleted player gmtest +[2025-08-15T10:44:19.395Z] DB: getAllPlayers - start +[2025-08-15T10:44:19.395Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:44:19.395Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:44:19.895Z] DB: getAllPlayers - start +[2025-08-15T10:44:19.895Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:44:20.223Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:44:20.223Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:44:20.302Z] DB: createSession - start 9b7697071b0f9a9fb42a39f8d89aded7e3d551818e92d8d071becda7c59471de expiresAt 2025-08-16T10:44:20.302Z +[2025-08-15T10:44:20.303Z] DB: createSession - done 9b7697071b0f9a9fb42a39f8d89aded7e3d551818e92d8d071becda7c59471de +[2025-08-15T10:44:20.303Z] API: Player login christoffer 9b7697071b0f9a9fb42a39f8d89aded7e3d551818e92d8d071becda7c59471de +[2025-08-15T10:44:20.321Z] DB: getSession - start 9b7697071b0f9a9fb42a39f8d89aded7e3d551818e92d8d071becda7c59471de +[2025-08-15T10:44:20.321Z] DB: getSession - ok 9b7697071b0f9a9fb42a39f8d89aded7e3d551818e92d8d071becda7c59471de +[2025-08-15T10:44:20.322Z] SESSION: Valid 9b7697071b0f9a9fb42a39f8d89aded7e3d551818e92d8d071becda7c59471de christoffer PUT /api/players/christoffer +[2025-08-15T10:44:20.322Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:44:20.322Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:44:20.322Z] DB: updatePlayer - start christoffer +[2025-08-15T10:44:20.322Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T10:44:20.322Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:44:20.322Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:44:20.322Z] API: Updated player christoffer +[2025-08-15T10:44:20.347Z] DB: getSession - start 9b7697071b0f9a9fb42a39f8d89aded7e3d551818e92d8d071becda7c59471de +[2025-08-15T10:44:20.347Z] DB: getSession - ok 9b7697071b0f9a9fb42a39f8d89aded7e3d551818e92d8d071becda7c59471de +[2025-08-15T10:44:20.347Z] SESSION: Valid 9b7697071b0f9a9fb42a39f8d89aded7e3d551818e92d8d071becda7c59471de christoffer PUT /api/players/christoffer +[2025-08-15T10:44:20.347Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:44:20.347Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:44:20.347Z] DB: updatePlayer - start christoffer +[2025-08-15T10:44:20.348Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T10:44:20.348Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:44:20.348Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:44:20.348Z] API: Updated player christoffer +[2025-08-15T10:49:35.928Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T10:49:35.928Z] DB: deletePlayer - start gmtest +[2025-08-15T10:49:35.928Z] DB: deletePlayer - changes 0 gmtest +[2025-08-15T10:49:35.945Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:49:35.945Z] DB: getPlayerByName - not found gmtest +[2025-08-15T10:49:36.025Z] DB: createPlayer - start gmtest +[2025-08-15T10:49:36.025Z] DB: createPlayer - done gmtest rowid 17 +[2025-08-15T10:49:36.025Z] API: Created player gmtest +[2025-08-15T10:49:36.044Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T10:49:36.045Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:49:36.045Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:49:36.045Z] DB: updatePlayer - start gmtest +[2025-08-15T10:49:36.045Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T10:49:36.045Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:49:36.045Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:49:36.045Z] API: Updated player gmtest +[2025-08-15T10:49:36.060Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T10:49:36.060Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:49:36.060Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:49:36.140Z] DB: updatePlayer - start gmtest +[2025-08-15T10:49:36.140Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T10:49:36.140Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:49:36.140Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:49:36.140Z] API: Updated player gmtest +[2025-08-15T10:49:36.155Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:49:36.155Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:49:36.236Z] DB: createSession - start 6862c024eadaedcb68c18228727573f0099f367df6f9f6a0e211ff127de213da expiresAt 2025-08-16T10:49:36.236Z +[2025-08-15T10:49:36.236Z] DB: createSession - done 6862c024eadaedcb68c18228727573f0099f367df6f9f6a0e211ff127de213da +[2025-08-15T10:49:36.236Z] API: Player login gmtest 6862c024eadaedcb68c18228727573f0099f367df6f9f6a0e211ff127de213da +[2025-08-15T10:49:36.251Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T10:49:36.251Z] DB: deletePlayer - start gmtest +[2025-08-15T10:49:36.252Z] DB: deletePlayer - changes 1 gmtest +[2025-08-15T10:49:36.252Z] API: Deleted player gmtest +[2025-08-15T10:49:36.266Z] DB: getAllPlayers - start +[2025-08-15T10:49:36.266Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:49:36.266Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:49:36.797Z] DB: getAllPlayers - start +[2025-08-15T10:49:36.798Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:49:37.144Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:49:37.144Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:49:37.224Z] DB: createSession - start 5516ffbd1e40da341a311c5c8cb257757486fd6ed81d7ade27a82a873f9df2e4 expiresAt 2025-08-16T10:49:37.224Z +[2025-08-15T10:49:37.224Z] DB: createSession - done 5516ffbd1e40da341a311c5c8cb257757486fd6ed81d7ade27a82a873f9df2e4 +[2025-08-15T10:49:37.224Z] API: Player login christoffer 5516ffbd1e40da341a311c5c8cb257757486fd6ed81d7ade27a82a873f9df2e4 +[2025-08-15T10:49:37.244Z] DB: getSession - start 5516ffbd1e40da341a311c5c8cb257757486fd6ed81d7ade27a82a873f9df2e4 +[2025-08-15T10:49:37.244Z] DB: getSession - ok 5516ffbd1e40da341a311c5c8cb257757486fd6ed81d7ade27a82a873f9df2e4 +[2025-08-15T10:49:37.244Z] SESSION: Valid 5516ffbd1e40da341a311c5c8cb257757486fd6ed81d7ade27a82a873f9df2e4 christoffer PUT /api/players/christoffer +[2025-08-15T10:49:37.244Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:49:37.245Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:49:37.245Z] DB: updatePlayer - start christoffer +[2025-08-15T10:49:37.245Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T10:49:37.245Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:49:37.245Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:49:37.245Z] API: Updated player christoffer +[2025-08-15T10:49:37.261Z] DB: getSession - start 5516ffbd1e40da341a311c5c8cb257757486fd6ed81d7ade27a82a873f9df2e4 +[2025-08-15T10:49:37.262Z] DB: getSession - ok 5516ffbd1e40da341a311c5c8cb257757486fd6ed81d7ade27a82a873f9df2e4 +[2025-08-15T10:49:37.262Z] SESSION: Valid 5516ffbd1e40da341a311c5c8cb257757486fd6ed81d7ade27a82a873f9df2e4 christoffer PUT /api/players/christoffer +[2025-08-15T10:49:37.262Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:49:37.262Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:49:37.262Z] DB: updatePlayer - start christoffer +[2025-08-15T10:49:37.263Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T10:49:37.263Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:49:37.263Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:49:37.263Z] API: Updated player christoffer +[2025-08-15T10:50:54.303Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T10:50:54.303Z] DB: deletePlayer - start gmtest +[2025-08-15T10:50:54.303Z] DB: deletePlayer - changes 0 gmtest +[2025-08-15T10:50:54.320Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:50:54.320Z] DB: getPlayerByName - not found gmtest +[2025-08-15T10:50:54.399Z] DB: createPlayer - start gmtest +[2025-08-15T10:50:54.399Z] DB: createPlayer - done gmtest rowid 18 +[2025-08-15T10:50:54.399Z] API: Created player gmtest +[2025-08-15T10:50:54.418Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T10:50:54.419Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:50:54.419Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:50:54.419Z] DB: updatePlayer - start gmtest +[2025-08-15T10:50:54.419Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T10:50:54.419Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:50:54.419Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:50:54.419Z] API: Updated player gmtest +[2025-08-15T10:50:54.435Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T10:50:54.436Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:50:54.436Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:50:54.515Z] DB: updatePlayer - start gmtest +[2025-08-15T10:50:54.516Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T10:50:54.516Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:50:54.516Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:50:54.516Z] API: Updated player gmtest +[2025-08-15T10:50:54.531Z] DB: getPlayerByName - start gmtest +[2025-08-15T10:50:54.531Z] DB: getPlayerByName - found gmtest +[2025-08-15T10:50:54.611Z] DB: createSession - start 5da90174ae40bed5b5649d09e89e3a373936177230f00a9a1a23e636f2302171 expiresAt 2025-08-16T10:50:54.611Z +[2025-08-15T10:50:54.611Z] DB: createSession - done 5da90174ae40bed5b5649d09e89e3a373936177230f00a9a1a23e636f2302171 +[2025-08-15T10:50:54.611Z] API: Player login gmtest 5da90174ae40bed5b5649d09e89e3a373936177230f00a9a1a23e636f2302171 +[2025-08-15T10:50:54.627Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T10:50:54.627Z] DB: deletePlayer - start gmtest +[2025-08-15T10:50:54.627Z] DB: deletePlayer - changes 1 gmtest +[2025-08-15T10:50:54.627Z] API: Deleted player gmtest +[2025-08-15T10:50:54.641Z] DB: getAllPlayers - start +[2025-08-15T10:50:54.642Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:50:54.642Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:50:55.176Z] DB: getAllPlayers - start +[2025-08-15T10:50:55.177Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:50:55.518Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:50:55.518Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:50:55.597Z] DB: createSession - start 1f66839dc4e72235775277e01e3ddc4bbc033856ef5469a2c61dffa86ea19218 expiresAt 2025-08-16T10:50:55.597Z +[2025-08-15T10:50:55.597Z] DB: createSession - done 1f66839dc4e72235775277e01e3ddc4bbc033856ef5469a2c61dffa86ea19218 +[2025-08-15T10:50:55.598Z] API: Player login christoffer 1f66839dc4e72235775277e01e3ddc4bbc033856ef5469a2c61dffa86ea19218 +[2025-08-15T10:50:55.618Z] DB: getSession - start 1f66839dc4e72235775277e01e3ddc4bbc033856ef5469a2c61dffa86ea19218 +[2025-08-15T10:50:55.618Z] DB: getSession - ok 1f66839dc4e72235775277e01e3ddc4bbc033856ef5469a2c61dffa86ea19218 +[2025-08-15T10:50:55.618Z] SESSION: Valid 1f66839dc4e72235775277e01e3ddc4bbc033856ef5469a2c61dffa86ea19218 christoffer PUT /api/players/christoffer +[2025-08-15T10:50:55.618Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:50:55.618Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:50:55.618Z] DB: updatePlayer - start christoffer +[2025-08-15T10:50:55.619Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T10:50:55.619Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:50:55.619Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:50:55.619Z] API: Updated player christoffer +[2025-08-15T10:50:55.635Z] DB: getSession - start 1f66839dc4e72235775277e01e3ddc4bbc033856ef5469a2c61dffa86ea19218 +[2025-08-15T10:50:55.635Z] DB: getSession - ok 1f66839dc4e72235775277e01e3ddc4bbc033856ef5469a2c61dffa86ea19218 +[2025-08-15T10:50:55.635Z] SESSION: Valid 1f66839dc4e72235775277e01e3ddc4bbc033856ef5469a2c61dffa86ea19218 christoffer PUT /api/players/christoffer +[2025-08-15T10:50:55.635Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:50:55.635Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:50:55.635Z] DB: updatePlayer - start christoffer +[2025-08-15T10:50:55.636Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T10:50:55.636Z] DB: getPlayerByName - start christoffer +[2025-08-15T10:50:55.636Z] DB: getPlayerByName - found christoffer +[2025-08-15T10:50:55.636Z] API: Updated player christoffer +[2025-08-15T10:51:17.856Z] DB: getSession - start df93fb133392f56772c27359ce103dacab71dbf72c91b787efe3ce620b00d8e3 +[2025-08-15T10:51:17.857Z] DB: getSession - ok df93fb133392f56772c27359ce103dacab71dbf72c91b787efe3ce620b00d8e3 +[2025-08-15T10:51:17.857Z] SESSION: Validate success df93fb133392f56772c27359ce103dacab71dbf72c91b787efe3ce620b00d8e3 christoffer +[2025-08-15T10:51:19.113Z] DB: getSession - start df93fb133392f56772c27359ce103dacab71dbf72c91b787efe3ce620b00d8e3 +[2025-08-15T10:51:19.113Z] DB: getSession - ok df93fb133392f56772c27359ce103dacab71dbf72c91b787efe3ce620b00d8e3 +[2025-08-15T10:51:19.113Z] SESSION: Validate success df93fb133392f56772c27359ce103dacab71dbf72c91b787efe3ce620b00d8e3 christoffer +[2025-08-15T10:51:20.455Z] DB: deleteSession - start df93fb133392f56772c27359ce103dacab71dbf72c91b787efe3ce620b00d8e3 +[2025-08-15T10:51:20.456Z] DB: deleteSession - changes 1 df93fb133392f56772c27359ce103dacab71dbf72c91b787efe3ce620b00d8e3 +[2025-08-15T10:51:20.456Z] SESSION: Logout success df93fb133392f56772c27359ce103dacab71dbf72c91b787efe3ce620b00d8e3 +[2025-08-15T10:51:22.692Z] DB: getAllPlayers - start +[2025-08-15T10:51:22.692Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:51:22.692Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:51:27.202Z] DB: getPlayerByName - start claes +[2025-08-15T10:51:27.203Z] DB: getPlayerByName - found claes +[2025-08-15T10:51:27.203Z] DB: createSession - start f77603d3a90c81b88ea2e29735493ba8c51c446f1fc5f208b044a0f7e6fb0361 expiresAt 2025-08-16T10:51:27.203Z +[2025-08-15T10:51:27.203Z] DB: createSession - done f77603d3a90c81b88ea2e29735493ba8c51c446f1fc5f208b044a0f7e6fb0361 +[2025-08-15T10:51:27.203Z] SESSION: Login success claes f77603d3a90c81b88ea2e29735493ba8c51c446f1fc5f208b044a0f7e6fb0361 +[2025-08-15T10:51:27.211Z] DB: getSession - start f77603d3a90c81b88ea2e29735493ba8c51c446f1fc5f208b044a0f7e6fb0361 +[2025-08-15T10:51:27.211Z] DB: getSession - ok f77603d3a90c81b88ea2e29735493ba8c51c446f1fc5f208b044a0f7e6fb0361 +[2025-08-15T10:51:27.211Z] SESSION: Validate success f77603d3a90c81b88ea2e29735493ba8c51c446f1fc5f208b044a0f7e6fb0361 claes +[2025-08-15T10:51:36.461Z] DB: getAllPlayers - start +[2025-08-15T10:51:36.461Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:51:36.462Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:51:45.120Z] DB: getAllPlayers - start +[2025-08-15T10:51:45.120Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:51:45.120Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:51:52.118Z] DB: getAllPlayers - start +[2025-08-15T10:51:52.118Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:51:52.119Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:52:15.142Z] DB: getSession - start f77603d3a90c81b88ea2e29735493ba8c51c446f1fc5f208b044a0f7e6fb0361 +[2025-08-15T10:52:15.142Z] DB: getSession - ok f77603d3a90c81b88ea2e29735493ba8c51c446f1fc5f208b044a0f7e6fb0361 +[2025-08-15T10:52:15.142Z] SESSION: Valid f77603d3a90c81b88ea2e29735493ba8c51c446f1fc5f208b044a0f7e6fb0361 claes PUT /api/players/claes +[2025-08-15T10:52:15.142Z] DB: getPlayerByName - start claes +[2025-08-15T10:52:15.142Z] DB: getPlayerByName - found claes +[2025-08-15T10:52:15.222Z] DB: updatePlayer - start claes +[2025-08-15T10:52:15.222Z] DB: updatePlayer - changes 1 claes +[2025-08-15T10:52:15.222Z] DB: getPlayerByName - start claes +[2025-08-15T10:52:15.222Z] DB: getPlayerByName - found claes +[2025-08-15T10:52:15.222Z] API: Updated player claes +[2025-08-15T10:52:15.229Z] DB: getAllPlayers - start +[2025-08-15T10:52:15.229Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:52:15.229Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:52:25.811Z] DB: getSession - start f77603d3a90c81b88ea2e29735493ba8c51c446f1fc5f208b044a0f7e6fb0361 +[2025-08-15T10:52:25.811Z] DB: getSession - ok f77603d3a90c81b88ea2e29735493ba8c51c446f1fc5f208b044a0f7e6fb0361 +[2025-08-15T10:52:25.811Z] SESSION: Valid f77603d3a90c81b88ea2e29735493ba8c51c446f1fc5f208b044a0f7e6fb0361 claes PUT /api/players/claes +[2025-08-15T10:52:25.811Z] DB: getPlayerByName - start claes +[2025-08-15T10:52:25.811Z] DB: getPlayerByName - found claes +[2025-08-15T10:52:25.927Z] DB: updatePlayer - start claes +[2025-08-15T10:52:25.927Z] DB: updatePlayer - changes 1 claes +[2025-08-15T10:52:25.927Z] DB: getPlayerByName - start claes +[2025-08-15T10:52:25.927Z] DB: getPlayerByName - found claes +[2025-08-15T10:52:25.927Z] API: Updated player claes +[2025-08-15T10:52:25.938Z] DB: getAllPlayers - start +[2025-08-15T10:52:25.938Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:52:25.938Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:52:34.537Z] DB: deleteSession - start f77603d3a90c81b88ea2e29735493ba8c51c446f1fc5f208b044a0f7e6fb0361 +[2025-08-15T10:52:34.537Z] DB: deleteSession - changes 1 f77603d3a90c81b88ea2e29735493ba8c51c446f1fc5f208b044a0f7e6fb0361 +[2025-08-15T10:52:34.537Z] SESSION: Logout success f77603d3a90c81b88ea2e29735493ba8c51c446f1fc5f208b044a0f7e6fb0361 +[2025-08-15T10:52:34.544Z] DB: getAllPlayers - start +[2025-08-15T10:52:34.544Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:52:34.544Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:53:08.903Z] DB: getPlayerByName - start phillip +[2025-08-15T10:53:08.903Z] DB: getPlayerByName - found phillip +[2025-08-15T10:53:08.903Z] DB: createSession - start dd292c923a2c50ac6f1f1fe3f84e39f16ae219295ac80a077357ccd32e90e141 expiresAt 2025-08-16T10:53:08.903Z +[2025-08-15T10:53:08.904Z] DB: createSession - done dd292c923a2c50ac6f1f1fe3f84e39f16ae219295ac80a077357ccd32e90e141 +[2025-08-15T10:53:08.904Z] SESSION: Login success phillip dd292c923a2c50ac6f1f1fe3f84e39f16ae219295ac80a077357ccd32e90e141 +[2025-08-15T10:53:08.913Z] DB: getAllPlayers - start +[2025-08-15T10:53:08.913Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:53:08.913Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:53:08.922Z] DB: getSession - start dd292c923a2c50ac6f1f1fe3f84e39f16ae219295ac80a077357ccd32e90e141 +[2025-08-15T10:53:08.923Z] DB: getSession - ok dd292c923a2c50ac6f1f1fe3f84e39f16ae219295ac80a077357ccd32e90e141 +[2025-08-15T10:53:08.923Z] SESSION: Validate success dd292c923a2c50ac6f1f1fe3f84e39f16ae219295ac80a077357ccd32e90e141 phillip +[2025-08-15T10:53:17.542Z] DB: getSession - start dd292c923a2c50ac6f1f1fe3f84e39f16ae219295ac80a077357ccd32e90e141 +[2025-08-15T10:53:17.542Z] DB: getSession - ok dd292c923a2c50ac6f1f1fe3f84e39f16ae219295ac80a077357ccd32e90e141 +[2025-08-15T10:53:17.542Z] SESSION: Valid dd292c923a2c50ac6f1f1fe3f84e39f16ae219295ac80a077357ccd32e90e141 phillip PUT /api/players/phillip +[2025-08-15T10:53:17.542Z] DB: getPlayerByName - start phillip +[2025-08-15T10:53:17.542Z] DB: getPlayerByName - found phillip +[2025-08-15T10:53:17.622Z] DB: updatePlayer - start phillip +[2025-08-15T10:53:17.623Z] DB: updatePlayer - changes 1 phillip +[2025-08-15T10:53:17.623Z] DB: getPlayerByName - start phillip +[2025-08-15T10:53:17.623Z] DB: getPlayerByName - found phillip +[2025-08-15T10:53:17.623Z] API: Updated player phillip +[2025-08-15T10:53:17.628Z] DB: getAllPlayers - start +[2025-08-15T10:53:17.629Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:53:17.629Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:53:18.922Z] DB: getSession - start dd292c923a2c50ac6f1f1fe3f84e39f16ae219295ac80a077357ccd32e90e141 +[2025-08-15T10:53:18.922Z] DB: getSession - ok dd292c923a2c50ac6f1f1fe3f84e39f16ae219295ac80a077357ccd32e90e141 +[2025-08-15T10:53:18.922Z] SESSION: Valid dd292c923a2c50ac6f1f1fe3f84e39f16ae219295ac80a077357ccd32e90e141 phillip PUT /api/players/phillip +[2025-08-15T10:53:18.923Z] DB: getPlayerByName - start phillip +[2025-08-15T10:53:18.923Z] DB: getPlayerByName - found phillip +[2025-08-15T10:53:19.004Z] DB: updatePlayer - start phillip +[2025-08-15T10:53:19.004Z] DB: updatePlayer - changes 1 phillip +[2025-08-15T10:53:19.004Z] DB: getPlayerByName - start phillip +[2025-08-15T10:53:19.004Z] DB: getPlayerByName - found phillip +[2025-08-15T10:53:19.004Z] API: Updated player phillip +[2025-08-15T10:53:19.049Z] DB: getAllPlayers - start +[2025-08-15T10:53:19.050Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:53:19.050Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:53:19.282Z] DB: getSession - start dd292c923a2c50ac6f1f1fe3f84e39f16ae219295ac80a077357ccd32e90e141 +[2025-08-15T10:53:19.282Z] DB: getSession - ok dd292c923a2c50ac6f1f1fe3f84e39f16ae219295ac80a077357ccd32e90e141 +[2025-08-15T10:53:19.283Z] SESSION: Valid dd292c923a2c50ac6f1f1fe3f84e39f16ae219295ac80a077357ccd32e90e141 phillip PUT /api/players/phillip +[2025-08-15T10:53:19.283Z] DB: getPlayerByName - start phillip +[2025-08-15T10:53:19.283Z] DB: getPlayerByName - found phillip +[2025-08-15T10:53:19.362Z] DB: updatePlayer - start phillip +[2025-08-15T10:53:19.362Z] DB: updatePlayer - changes 1 phillip +[2025-08-15T10:53:19.362Z] DB: getPlayerByName - start phillip +[2025-08-15T10:53:19.363Z] DB: getPlayerByName - found phillip +[2025-08-15T10:53:19.363Z] API: Updated player phillip +[2025-08-15T10:53:19.368Z] DB: getAllPlayers - start +[2025-08-15T10:53:19.368Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:53:19.368Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:53:19.563Z] DB: getSession - start dd292c923a2c50ac6f1f1fe3f84e39f16ae219295ac80a077357ccd32e90e141 +[2025-08-15T10:53:19.564Z] DB: getSession - ok dd292c923a2c50ac6f1f1fe3f84e39f16ae219295ac80a077357ccd32e90e141 +[2025-08-15T10:53:19.564Z] SESSION: Valid dd292c923a2c50ac6f1f1fe3f84e39f16ae219295ac80a077357ccd32e90e141 phillip PUT /api/players/phillip +[2025-08-15T10:53:19.564Z] DB: getPlayerByName - start phillip +[2025-08-15T10:53:19.564Z] DB: getPlayerByName - found phillip +[2025-08-15T10:53:19.643Z] DB: updatePlayer - start phillip +[2025-08-15T10:53:19.643Z] DB: updatePlayer - changes 1 phillip +[2025-08-15T10:53:19.643Z] DB: getPlayerByName - start phillip +[2025-08-15T10:53:19.643Z] DB: getPlayerByName - found phillip +[2025-08-15T10:53:19.643Z] API: Updated player phillip +[2025-08-15T10:53:19.648Z] DB: getAllPlayers - start +[2025-08-15T10:53:19.648Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:53:19.648Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:55:17.576Z] DB: getSession - start dd292c923a2c50ac6f1f1fe3f84e39f16ae219295ac80a077357ccd32e90e141 +[2025-08-15T10:55:17.577Z] DB: getSession - ok dd292c923a2c50ac6f1f1fe3f84e39f16ae219295ac80a077357ccd32e90e141 +[2025-08-15T10:55:17.577Z] SESSION: Validate success dd292c923a2c50ac6f1f1fe3f84e39f16ae219295ac80a077357ccd32e90e141 phillip +[2025-08-15T10:55:19.100Z] DB: getAllPlayers - start +[2025-08-15T10:55:19.100Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:55:19.100Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:55:20.957Z] DB: getSession - start dd292c923a2c50ac6f1f1fe3f84e39f16ae219295ac80a077357ccd32e90e141 +[2025-08-15T10:55:20.957Z] DB: getSession - ok dd292c923a2c50ac6f1f1fe3f84e39f16ae219295ac80a077357ccd32e90e141 +[2025-08-15T10:55:20.963Z] SESSION: Valid dd292c923a2c50ac6f1f1fe3f84e39f16ae219295ac80a077357ccd32e90e141 phillip PUT /api/players/phillip +[2025-08-15T10:55:20.963Z] DB: getPlayerByName - start phillip +[2025-08-15T10:55:20.963Z] DB: getPlayerByName - found phillip +[2025-08-15T10:55:21.042Z] DB: updatePlayer - start phillip +[2025-08-15T10:55:21.042Z] DB: updatePlayer - changes 1 phillip +[2025-08-15T10:55:21.043Z] DB: getPlayerByName - start phillip +[2025-08-15T10:55:21.043Z] DB: getPlayerByName - found phillip +[2025-08-15T10:55:21.043Z] API: Updated player phillip +[2025-08-15T10:55:21.082Z] DB: getAllPlayers - start +[2025-08-15T10:55:21.082Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:55:21.082Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:55:29.441Z] DB: deleteSession - start dd292c923a2c50ac6f1f1fe3f84e39f16ae219295ac80a077357ccd32e90e141 +[2025-08-15T10:55:29.441Z] DB: deleteSession - changes 1 dd292c923a2c50ac6f1f1fe3f84e39f16ae219295ac80a077357ccd32e90e141 +[2025-08-15T10:55:29.441Z] SESSION: Logout success dd292c923a2c50ac6f1f1fe3f84e39f16ae219295ac80a077357ccd32e90e141 +[2025-08-15T10:55:29.449Z] DB: getAllPlayers - start +[2025-08-15T10:55:29.449Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:55:29.449Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:55:50.575Z] DB: getAllPlayers - start +[2025-08-15T10:55:50.576Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:55:50.576Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:57:06.678Z] DB: getAllPlayers - start +[2025-08-15T10:57:06.679Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:57:06.679Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:57:08.530Z] DB: getAllPlayers - start +[2025-08-15T10:57:08.530Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:57:08.530Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:57:12.605Z] DB: getPlayerByName - start phillip +[2025-08-15T10:57:12.605Z] DB: getPlayerByName - found phillip +[2025-08-15T10:57:12.605Z] DB: createSession - start 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac expiresAt 2025-08-16T10:57:12.605Z +[2025-08-15T10:57:12.605Z] DB: createSession - done 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T10:57:12.605Z] SESSION: Login success phillip 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T10:57:12.647Z] DB: getSession - start 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T10:57:12.647Z] DB: getSession - ok 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T10:57:12.647Z] SESSION: Validate success 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac phillip +[2025-08-15T10:57:12.652Z] DB: getAllPlayers - start +[2025-08-15T10:57:12.653Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:57:12.653Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:57:19.057Z] DB: getSession - start 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T10:57:19.057Z] DB: getSession - ok 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T10:57:19.062Z] SESSION: Valid 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac phillip PUT /api/players/phillip +[2025-08-15T10:57:19.062Z] DB: getPlayerByName - start phillip +[2025-08-15T10:57:19.062Z] DB: getPlayerByName - found phillip +[2025-08-15T10:57:19.172Z] DB: updatePlayer - start phillip +[2025-08-15T10:57:19.172Z] DB: updatePlayer - changes 1 phillip +[2025-08-15T10:57:19.172Z] DB: getPlayerByName - start phillip +[2025-08-15T10:57:19.172Z] DB: getPlayerByName - found phillip +[2025-08-15T10:57:19.172Z] API: Updated player phillip +[2025-08-15T10:57:19.205Z] DB: getAllPlayers - start +[2025-08-15T10:57:19.205Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:57:19.205Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:57:25.541Z] DB: getSession - start 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T10:57:25.541Z] DB: getSession - ok 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T10:57:25.541Z] SESSION: Validate success 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac phillip +[2025-08-15T10:57:27.637Z] DB: getAllPlayers - start +[2025-08-15T10:57:27.637Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:57:27.637Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:57:32.002Z] DB: getSession - start 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T10:57:32.002Z] DB: getSession - ok 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T10:57:32.003Z] SESSION: Valid 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac phillip PUT /api/players/phillip +[2025-08-15T10:57:32.003Z] DB: getPlayerByName - start phillip +[2025-08-15T10:57:32.003Z] DB: getPlayerByName - found phillip +[2025-08-15T10:57:32.082Z] DB: updatePlayer - start phillip +[2025-08-15T10:57:32.082Z] DB: updatePlayer - changes 1 phillip +[2025-08-15T10:57:32.082Z] DB: getPlayerByName - start phillip +[2025-08-15T10:57:32.082Z] DB: getPlayerByName - found phillip +[2025-08-15T10:57:32.082Z] API: Updated player phillip +[2025-08-15T10:57:32.115Z] DB: getAllPlayers - start +[2025-08-15T10:57:32.115Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:57:32.115Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:57:34.958Z] DB: getSession - start 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T10:57:34.958Z] DB: getSession - ok 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T10:57:34.958Z] SESSION: Valid 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac phillip PUT /api/players/phillip +[2025-08-15T10:57:34.958Z] DB: getPlayerByName - start phillip +[2025-08-15T10:57:34.959Z] DB: getPlayerByName - found phillip +[2025-08-15T10:57:35.039Z] DB: updatePlayer - start phillip +[2025-08-15T10:57:35.040Z] DB: updatePlayer - changes 1 phillip +[2025-08-15T10:57:35.040Z] DB: getPlayerByName - start phillip +[2025-08-15T10:57:35.040Z] DB: getPlayerByName - found phillip +[2025-08-15T10:57:35.040Z] API: Updated player phillip +[2025-08-15T10:57:35.082Z] DB: getAllPlayers - start +[2025-08-15T10:57:35.082Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:57:35.082Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:57:35.376Z] DB: getSession - start 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T10:57:35.376Z] DB: getSession - ok 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T10:57:35.377Z] SESSION: Valid 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac phillip PUT /api/players/phillip +[2025-08-15T10:57:35.377Z] DB: getPlayerByName - start phillip +[2025-08-15T10:57:35.377Z] DB: getPlayerByName - found phillip +[2025-08-15T10:57:35.487Z] DB: updatePlayer - start phillip +[2025-08-15T10:57:35.487Z] DB: updatePlayer - changes 1 phillip +[2025-08-15T10:57:35.487Z] DB: getPlayerByName - start phillip +[2025-08-15T10:57:35.487Z] DB: getPlayerByName - found phillip +[2025-08-15T10:57:35.487Z] API: Updated player phillip +[2025-08-15T10:57:35.526Z] DB: getAllPlayers - start +[2025-08-15T10:57:35.527Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:57:35.527Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:58:17.867Z] DB: getSession - start 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T10:58:17.867Z] DB: getSession - ok 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T10:58:17.868Z] SESSION: Validate success 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac phillip +[2025-08-15T10:58:20.298Z] DB: getSession - start 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T10:58:20.298Z] DB: getSession - ok 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T10:58:20.298Z] SESSION: Validate success 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac phillip +[2025-08-15T10:58:24.082Z] DB: getSession - start 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T10:58:24.082Z] DB: getSession - ok 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T10:58:24.082Z] SESSION: Validate success 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac phillip +[2025-08-15T10:58:30.227Z] DB: getSession - start 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T10:58:30.227Z] DB: getSession - ok 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T10:58:30.227Z] SESSION: Validate success 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac phillip +[2025-08-15T10:58:34.370Z] DB: getAllPlayers - start +[2025-08-15T10:58:34.371Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:58:34.371Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:58:38.200Z] DB: getSession - start 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T10:58:38.200Z] DB: getSession - ok 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T10:58:38.200Z] SESSION: Valid 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac phillip PUT /api/players/phillip +[2025-08-15T10:58:38.206Z] DB: getPlayerByName - start phillip +[2025-08-15T10:58:38.206Z] DB: getPlayerByName - found phillip +[2025-08-15T10:58:38.321Z] DB: updatePlayer - start phillip +[2025-08-15T10:58:38.321Z] DB: updatePlayer - changes 1 phillip +[2025-08-15T10:58:38.322Z] DB: getPlayerByName - start phillip +[2025-08-15T10:58:38.322Z] DB: getPlayerByName - found phillip +[2025-08-15T10:58:38.322Z] API: Updated player phillip +[2025-08-15T10:58:38.349Z] DB: getAllPlayers - start +[2025-08-15T10:58:38.349Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:58:38.349Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:58:38.931Z] DB: getSession - start 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T10:58:38.931Z] DB: getSession - ok 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T10:58:38.931Z] SESSION: Valid 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac phillip PUT /api/players/phillip +[2025-08-15T10:58:38.931Z] DB: getPlayerByName - start phillip +[2025-08-15T10:58:38.931Z] DB: getPlayerByName - found phillip +[2025-08-15T10:58:39.012Z] DB: updatePlayer - start phillip +[2025-08-15T10:58:39.013Z] DB: updatePlayer - changes 1 phillip +[2025-08-15T10:58:39.013Z] DB: getPlayerByName - start phillip +[2025-08-15T10:58:39.013Z] DB: getPlayerByName - found phillip +[2025-08-15T10:58:39.013Z] API: Updated player phillip +[2025-08-15T10:58:39.047Z] DB: getAllPlayers - start +[2025-08-15T10:58:39.048Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:58:39.048Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:59:14.956Z] DB: getSession - start 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T10:59:14.956Z] DB: getSession - ok 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T10:59:14.956Z] SESSION: Validate success 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac phillip +[2025-08-15T10:59:22.490Z] DB: getAllPlayers - start +[2025-08-15T10:59:22.490Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:59:22.490Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:59:27.600Z] DB: getSession - start 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T10:59:27.600Z] DB: getSession - ok 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T10:59:27.600Z] SESSION: Valid 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac phillip PUT /api/players/phillip +[2025-08-15T10:59:27.600Z] DB: getPlayerByName - start phillip +[2025-08-15T10:59:27.600Z] DB: getPlayerByName - found phillip +[2025-08-15T10:59:27.717Z] DB: updatePlayer - start phillip +[2025-08-15T10:59:27.717Z] DB: updatePlayer - changes 1 phillip +[2025-08-15T10:59:27.717Z] DB: getPlayerByName - start phillip +[2025-08-15T10:59:27.717Z] DB: getPlayerByName - found phillip +[2025-08-15T10:59:27.717Z] API: Updated player phillip +[2025-08-15T10:59:27.754Z] DB: getAllPlayers - start +[2025-08-15T10:59:27.754Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:59:27.754Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:59:35.276Z] DB: getAllPlayers - start +[2025-08-15T10:59:36.935Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:59:36.935Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:59:41.146Z] SESSION: GM bypass accepted PUT /api/players/phillip +[2025-08-15T10:59:41.147Z] DB: getPlayerByName - start phillip +[2025-08-15T10:59:41.147Z] DB: getPlayerByName - found phillip +[2025-08-15T10:59:41.147Z] DB: updatePlayer - start phillip +[2025-08-15T10:59:41.147Z] DB: updatePlayer - changes 1 phillip +[2025-08-15T10:59:41.147Z] DB: getPlayerByName - start phillip +[2025-08-15T10:59:41.147Z] DB: getPlayerByName - found phillip +[2025-08-15T10:59:41.147Z] API: Updated player phillip +[2025-08-15T10:59:41.188Z] DB: getAllPlayers - start +[2025-08-15T10:59:41.189Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:59:41.189Z] API: Fetch all players (public) Found 3 players +[2025-08-15T10:59:47.934Z] SESSION: GM bypass accepted PUT /api/players/phillip +[2025-08-15T10:59:47.934Z] DB: getPlayerByName - start phillip +[2025-08-15T10:59:47.934Z] DB: getPlayerByName - found phillip +[2025-08-15T10:59:47.934Z] DB: updatePlayer - start phillip +[2025-08-15T10:59:47.934Z] DB: updatePlayer - changes 1 phillip +[2025-08-15T10:59:47.934Z] DB: getPlayerByName - start phillip +[2025-08-15T10:59:47.934Z] DB: getPlayerByName - found phillip +[2025-08-15T10:59:47.935Z] API: Updated player phillip +[2025-08-15T10:59:47.977Z] DB: getAllPlayers - start +[2025-08-15T10:59:47.977Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T10:59:47.977Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:00:00.739Z] SESSION: GM bypass accepted PUT /api/players/phillip +[2025-08-15T11:00:00.739Z] DB: getPlayerByName - start phillip +[2025-08-15T11:00:00.739Z] DB: getPlayerByName - found phillip +[2025-08-15T11:00:00.740Z] DB: updatePlayer - start phillip +[2025-08-15T11:00:00.740Z] DB: updatePlayer - changes 1 phillip +[2025-08-15T11:00:00.740Z] DB: getPlayerByName - start phillip +[2025-08-15T11:00:00.740Z] DB: getPlayerByName - found phillip +[2025-08-15T11:00:00.740Z] API: Updated player phillip +[2025-08-15T11:00:00.791Z] DB: getAllPlayers - start +[2025-08-15T11:00:00.791Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:00:00.791Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:01:05.514Z] DB: getAllPlayers - start +[2025-08-15T11:01:05.514Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:01:05.514Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:01:09.885Z] DB: getAllPlayers - start +[2025-08-15T11:01:09.885Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:01:09.885Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:01:13.761Z] DB: getAllPlayers - start +[2025-08-15T11:01:13.762Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:01:13.762Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:01:19.669Z] DB: getSession - start 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T11:01:19.669Z] DB: getSession - ok 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T11:01:19.669Z] SESSION: Valid 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac phillip PUT /api/players/phillip +[2025-08-15T11:01:19.670Z] DB: getPlayerByName - start phillip +[2025-08-15T11:01:19.670Z] DB: getPlayerByName - found phillip +[2025-08-15T11:01:19.670Z] DB: updatePlayer - start phillip +[2025-08-15T11:01:19.670Z] DB: updatePlayer - changes 1 phillip +[2025-08-15T11:01:19.670Z] DB: getPlayerByName - start phillip +[2025-08-15T11:01:19.670Z] DB: getPlayerByName - found phillip +[2025-08-15T11:01:19.670Z] API: Updated player phillip +[2025-08-15T11:01:19.699Z] DB: getAllPlayers - start +[2025-08-15T11:01:19.700Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:01:19.700Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:01:29.850Z] DB: deleteSession - start 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T11:01:29.851Z] DB: deleteSession - changes 1 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T11:01:29.851Z] SESSION: Logout success 7de8fba372cab6532a42417efe17ee4dcb7d7589f35fe56fc712ad397f529fac +[2025-08-15T11:01:29.889Z] DB: getAllPlayers - start +[2025-08-15T11:01:29.889Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:01:29.889Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:01:33.533Z] DB: getAllPlayers - start +[2025-08-15T11:01:33.533Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:01:33.533Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:01:35.333Z] DB: getAllPlayers - start +[2025-08-15T11:01:35.333Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:01:35.334Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:01:37.465Z] DB: getPlayerByName - start phillip +[2025-08-15T11:01:37.466Z] DB: getPlayerByName - found phillip +[2025-08-15T11:01:37.466Z] DB: createSession - start 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 expiresAt 2025-08-16T11:01:37.466Z +[2025-08-15T11:01:37.466Z] DB: createSession - done 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 +[2025-08-15T11:01:37.466Z] SESSION: Login success phillip 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 +[2025-08-15T11:01:37.505Z] DB: getAllPlayers - start +[2025-08-15T11:01:37.505Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:01:37.506Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:01:37.514Z] DB: getSession - start 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 +[2025-08-15T11:01:37.514Z] DB: getSession - ok 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 +[2025-08-15T11:01:37.514Z] SESSION: Validate success 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 phillip +[2025-08-15T11:01:38.848Z] DB: getAllPlayers - start +[2025-08-15T11:01:38.848Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:01:38.848Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:01:43.416Z] DB: getSession - start 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 +[2025-08-15T11:01:43.417Z] DB: getSession - ok 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 +[2025-08-15T11:01:43.417Z] SESSION: Valid 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 phillip PUT /api/players/phillip +[2025-08-15T11:01:43.417Z] DB: getPlayerByName - start phillip +[2025-08-15T11:01:43.417Z] DB: getPlayerByName - found phillip +[2025-08-15T11:01:43.417Z] DB: updatePlayer - start phillip +[2025-08-15T11:01:43.417Z] DB: updatePlayer - changes 1 phillip +[2025-08-15T11:01:43.418Z] DB: getPlayerByName - start phillip +[2025-08-15T11:01:43.418Z] DB: getPlayerByName - found phillip +[2025-08-15T11:01:43.418Z] API: Updated player phillip +[2025-08-15T11:01:43.451Z] DB: getAllPlayers - start +[2025-08-15T11:01:43.451Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:01:43.451Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:02:20.193Z] DB: getAllPlayers - start +[2025-08-15T11:02:20.193Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:02:20.193Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:02:22.410Z] DB: getSession - start 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 +[2025-08-15T11:02:22.411Z] DB: getSession - ok 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 +[2025-08-15T11:02:22.411Z] SESSION: Valid 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 phillip PUT /api/players/phillip +[2025-08-15T11:02:22.411Z] DB: getPlayerByName - start phillip +[2025-08-15T11:02:22.411Z] DB: getPlayerByName - found phillip +[2025-08-15T11:02:22.490Z] DB: updatePlayer - start phillip +[2025-08-15T11:02:22.490Z] DB: updatePlayer - changes 1 phillip +[2025-08-15T11:02:22.491Z] DB: getPlayerByName - start phillip +[2025-08-15T11:02:22.491Z] DB: getPlayerByName - found phillip +[2025-08-15T11:02:22.491Z] API: Updated player phillip +[2025-08-15T11:02:22.532Z] DB: getAllPlayers - start +[2025-08-15T11:02:22.532Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:02:22.532Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:02:31.180Z] DB: getAllPlayers - start +[2025-08-15T11:02:31.181Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:02:31.181Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:02:43.135Z] DB: getSession - start 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 +[2025-08-15T11:02:43.135Z] DB: getSession - ok 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 +[2025-08-15T11:02:43.135Z] SESSION: Validate success 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 phillip +[2025-08-15T11:02:43.919Z] DB: getAllPlayers - start +[2025-08-15T11:02:43.920Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:02:43.920Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:04:20.111Z] DB: getSession - start 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 +[2025-08-15T11:04:20.111Z] DB: getSession - ok 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 +[2025-08-15T11:04:20.111Z] SESSION: Validate success 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 phillip +[2025-08-15T11:04:22.415Z] DB: getAllPlayers - start +[2025-08-15T11:04:22.415Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:04:22.415Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:04:26.238Z] DB: getAllPlayers - start +[2025-08-15T11:04:26.239Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:04:26.239Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:04:30.387Z] DB: getSession - start 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 +[2025-08-15T11:04:30.387Z] DB: getSession - ok 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 +[2025-08-15T11:04:30.387Z] SESSION: Valid 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 phillip PUT /api/players/phillip +[2025-08-15T11:04:30.387Z] DB: getPlayerByName - start phillip +[2025-08-15T11:04:30.387Z] DB: getPlayerByName - found phillip +[2025-08-15T11:04:30.466Z] DB: updatePlayer - start phillip +[2025-08-15T11:04:30.467Z] DB: updatePlayer - changes 1 phillip +[2025-08-15T11:04:30.467Z] DB: getPlayerByName - start phillip +[2025-08-15T11:04:30.467Z] DB: getPlayerByName - found phillip +[2025-08-15T11:04:30.467Z] API: Updated player phillip +[2025-08-15T11:04:30.498Z] DB: getAllPlayers - start +[2025-08-15T11:04:30.499Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:04:30.499Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:04:31.967Z] DB: getAllPlayers - start +[2025-08-15T11:04:31.968Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:04:31.968Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:04:36.351Z] DB: getSession - start 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 +[2025-08-15T11:04:36.351Z] DB: getSession - ok 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 +[2025-08-15T11:04:36.351Z] SESSION: Validate success 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 phillip +[2025-08-15T11:04:37.653Z] DB: getAllPlayers - start +[2025-08-15T11:04:37.653Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:04:37.653Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:05:14.683Z] DB: getAllPlayers - start +[2025-08-15T11:05:14.684Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:05:14.684Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:05:24.734Z] SESSION: GM bypass accepted PUT /api/players/phillip +[2025-08-15T11:05:24.734Z] DB: getPlayerByName - start phillip +[2025-08-15T11:05:24.735Z] DB: getPlayerByName - found phillip +[2025-08-15T11:05:24.735Z] DB: updatePlayer - start phillip +[2025-08-15T11:05:24.735Z] DB: updatePlayer - changes 1 phillip +[2025-08-15T11:05:24.735Z] DB: getPlayerByName - start phillip +[2025-08-15T11:05:24.735Z] DB: getPlayerByName - found phillip +[2025-08-15T11:05:24.735Z] API: Updated player phillip +[2025-08-15T11:05:24.774Z] DB: getAllPlayers - start +[2025-08-15T11:05:24.774Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:05:24.774Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:05:53.584Z] SESSION: GM bypass accepted PUT /api/players/phillip +[2025-08-15T11:05:53.584Z] DB: getPlayerByName - start phillip +[2025-08-15T11:05:53.584Z] DB: getPlayerByName - found phillip +[2025-08-15T11:05:53.584Z] DB: updatePlayer - start phillip +[2025-08-15T11:05:53.584Z] DB: updatePlayer - changes 1 phillip +[2025-08-15T11:05:53.584Z] DB: getPlayerByName - start phillip +[2025-08-15T11:05:53.584Z] DB: getPlayerByName - found phillip +[2025-08-15T11:05:53.584Z] API: Updated player phillip +[2025-08-15T11:05:53.626Z] DB: getAllPlayers - start +[2025-08-15T11:05:53.626Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:05:53.626Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:06:40.679Z] DB: getAllPlayers - start +[2025-08-15T11:06:40.679Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:06:40.679Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:08:35.737Z] DB: getAllPlayers - start +[2025-08-15T11:08:35.738Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:08:35.738Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:08:45.301Z] SESSION: GM bypass accepted PUT /api/players/phillip +[2025-08-15T11:08:45.301Z] DB: getPlayerByName - start phillip +[2025-08-15T11:08:45.301Z] DB: getPlayerByName - found phillip +[2025-08-15T11:08:45.301Z] DB: updatePlayer - start phillip +[2025-08-15T11:08:45.301Z] DB: updatePlayer - changes 1 phillip +[2025-08-15T11:08:45.302Z] DB: getPlayerByName - start phillip +[2025-08-15T11:08:45.302Z] DB: getPlayerByName - found phillip +[2025-08-15T11:08:45.302Z] API: Updated player phillip +[2025-08-15T11:08:45.341Z] DB: getAllPlayers - start +[2025-08-15T11:08:45.341Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:08:45.341Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:08:57.392Z] DB: getSession - start 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 +[2025-08-15T11:08:57.393Z] DB: getSession - ok 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 +[2025-08-15T11:08:57.393Z] SESSION: Validate success 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 phillip +[2025-08-15T11:08:57.765Z] DB: getSession - start 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 +[2025-08-15T11:08:57.765Z] DB: getSession - ok 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 +[2025-08-15T11:08:57.765Z] SESSION: Validate success 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 phillip +[2025-08-15T11:08:57.989Z] DB: getSession - start 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 +[2025-08-15T11:08:57.989Z] DB: getSession - ok 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 +[2025-08-15T11:08:57.990Z] SESSION: Validate success 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 phillip +[2025-08-15T11:08:58.187Z] DB: getSession - start 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 +[2025-08-15T11:08:58.187Z] DB: getSession - ok 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 +[2025-08-15T11:08:58.187Z] SESSION: Validate success 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 phillip +[2025-08-15T11:09:08.714Z] DB: getAllPlayers - start +[2025-08-15T11:09:08.714Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:09:08.714Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:12:00.617Z] DB: getAllPlayers - start +[2025-08-15T11:12:00.618Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:12:00.618Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:12:11.611Z] DB: getAllPlayers - start +[2025-08-15T11:12:11.611Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:12:11.612Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:12:14.241Z] DB: getAllPlayers - start +[2025-08-15T11:12:14.241Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:12:14.246Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:12:32.070Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T11:12:32.071Z] DB: deletePlayer - start gmtest +[2025-08-15T11:12:32.071Z] DB: deletePlayer - changes 0 gmtest +[2025-08-15T11:12:32.087Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:12:32.087Z] DB: getPlayerByName - not found gmtest +[2025-08-15T11:12:32.166Z] DB: createPlayer - start gmtest +[2025-08-15T11:12:32.167Z] DB: createPlayer - done gmtest rowid 19 +[2025-08-15T11:12:32.167Z] API: Created player gmtest +[2025-08-15T11:12:32.184Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T11:12:32.184Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:12:32.184Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:12:32.184Z] DB: updatePlayer - start gmtest +[2025-08-15T11:12:32.184Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T11:12:32.184Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:12:32.184Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:12:32.184Z] API: Updated player gmtest +[2025-08-15T11:12:32.200Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T11:12:32.200Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:12:32.200Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:12:32.280Z] DB: updatePlayer - start gmtest +[2025-08-15T11:12:32.280Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T11:12:32.280Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:12:32.280Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:12:32.280Z] API: Updated player gmtest +[2025-08-15T11:12:32.305Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:12:32.305Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:12:32.388Z] DB: createSession - start cb1f70ce66288cce0a507b247fbeb78d36971252fcafef132c267ab6179bf4ca expiresAt 2025-08-16T11:12:32.388Z +[2025-08-15T11:12:32.389Z] DB: createSession - done cb1f70ce66288cce0a507b247fbeb78d36971252fcafef132c267ab6179bf4ca +[2025-08-15T11:12:32.389Z] API: Player login gmtest cb1f70ce66288cce0a507b247fbeb78d36971252fcafef132c267ab6179bf4ca +[2025-08-15T11:12:32.404Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T11:12:32.404Z] DB: deletePlayer - start gmtest +[2025-08-15T11:12:32.404Z] DB: deletePlayer - changes 1 gmtest +[2025-08-15T11:12:32.404Z] API: Deleted player gmtest +[2025-08-15T11:12:32.420Z] DB: getAllPlayers - start +[2025-08-15T11:12:32.420Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:12:32.420Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:12:32.946Z] DB: getAllPlayers - start +[2025-08-15T11:12:32.947Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:12:33.317Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:12:33.317Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:12:33.397Z] DB: createSession - start 55f9994f7ec1145d38da9fe0615df175a35e4e7d53b8da06d6aab29e5831806e expiresAt 2025-08-16T11:12:33.397Z +[2025-08-15T11:12:33.397Z] DB: createSession - done 55f9994f7ec1145d38da9fe0615df175a35e4e7d53b8da06d6aab29e5831806e +[2025-08-15T11:12:33.397Z] API: Player login christoffer 55f9994f7ec1145d38da9fe0615df175a35e4e7d53b8da06d6aab29e5831806e +[2025-08-15T11:12:33.416Z] DB: getSession - start 55f9994f7ec1145d38da9fe0615df175a35e4e7d53b8da06d6aab29e5831806e +[2025-08-15T11:12:33.416Z] DB: getSession - ok 55f9994f7ec1145d38da9fe0615df175a35e4e7d53b8da06d6aab29e5831806e +[2025-08-15T11:12:33.416Z] SESSION: Valid 55f9994f7ec1145d38da9fe0615df175a35e4e7d53b8da06d6aab29e5831806e christoffer PUT /api/players/christoffer +[2025-08-15T11:12:33.416Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:12:33.416Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:12:33.417Z] DB: updatePlayer - start christoffer +[2025-08-15T11:12:33.417Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T11:12:33.417Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:12:33.417Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:12:33.417Z] API: Updated player christoffer +[2025-08-15T11:12:33.432Z] DB: getSession - start 55f9994f7ec1145d38da9fe0615df175a35e4e7d53b8da06d6aab29e5831806e +[2025-08-15T11:12:33.433Z] DB: getSession - ok 55f9994f7ec1145d38da9fe0615df175a35e4e7d53b8da06d6aab29e5831806e +[2025-08-15T11:12:33.433Z] SESSION: Valid 55f9994f7ec1145d38da9fe0615df175a35e4e7d53b8da06d6aab29e5831806e christoffer PUT /api/players/christoffer +[2025-08-15T11:12:33.433Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:12:33.433Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:12:33.433Z] DB: updatePlayer - start christoffer +[2025-08-15T11:12:33.433Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T11:12:33.433Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:12:33.433Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:12:33.433Z] API: Updated player christoffer +[2025-08-15T11:13:05.301Z] DB: getAllPlayers - start +[2025-08-15T11:13:05.302Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:13:05.302Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:15:11.741Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T11:15:11.741Z] DB: deletePlayer - start gmtest +[2025-08-15T11:15:11.741Z] DB: deletePlayer - changes 0 gmtest +[2025-08-15T11:15:11.758Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:15:11.758Z] DB: getPlayerByName - not found gmtest +[2025-08-15T11:15:11.838Z] DB: createPlayer - start gmtest +[2025-08-15T11:15:11.838Z] DB: createPlayer - done gmtest rowid 20 +[2025-08-15T11:15:11.838Z] API: Created player gmtest +[2025-08-15T11:15:11.855Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T11:15:11.855Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:15:11.855Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:15:11.855Z] DB: updatePlayer - start gmtest +[2025-08-15T11:15:11.855Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T11:15:11.855Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:15:11.855Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:15:11.855Z] API: Updated player gmtest +[2025-08-15T11:15:11.870Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T11:15:11.871Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:15:11.871Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:15:11.950Z] DB: updatePlayer - start gmtest +[2025-08-15T11:15:11.950Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T11:15:11.950Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:15:11.950Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:15:11.950Z] API: Updated player gmtest +[2025-08-15T11:15:11.965Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:15:11.965Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:15:12.045Z] DB: createSession - start 5ef118758407780b042c0bcf925ddf4c5d2a85d63862dd5ef2ca3958ea1e2ef1 expiresAt 2025-08-16T11:15:12.045Z +[2025-08-15T11:15:12.045Z] DB: createSession - done 5ef118758407780b042c0bcf925ddf4c5d2a85d63862dd5ef2ca3958ea1e2ef1 +[2025-08-15T11:15:12.045Z] API: Player login gmtest 5ef118758407780b042c0bcf925ddf4c5d2a85d63862dd5ef2ca3958ea1e2ef1 +[2025-08-15T11:15:12.060Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T11:15:12.060Z] DB: deletePlayer - start gmtest +[2025-08-15T11:15:12.060Z] DB: deletePlayer - changes 1 gmtest +[2025-08-15T11:15:12.060Z] API: Deleted player gmtest +[2025-08-15T11:15:12.075Z] DB: getAllPlayers - start +[2025-08-15T11:15:12.075Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:15:12.076Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:15:12.594Z] DB: getAllPlayers - start +[2025-08-15T11:15:12.595Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:15:12.940Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:15:12.940Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:15:13.021Z] DB: createSession - start 3bb5a76d0c848fb8518cc771fe90fdeb2f2cd3a53b6bb6df073c39a933d88f5b expiresAt 2025-08-16T11:15:13.021Z +[2025-08-15T11:15:13.022Z] DB: createSession - done 3bb5a76d0c848fb8518cc771fe90fdeb2f2cd3a53b6bb6df073c39a933d88f5b +[2025-08-15T11:15:13.022Z] API: Player login christoffer 3bb5a76d0c848fb8518cc771fe90fdeb2f2cd3a53b6bb6df073c39a933d88f5b +[2025-08-15T11:15:13.052Z] DB: getSession - start 3bb5a76d0c848fb8518cc771fe90fdeb2f2cd3a53b6bb6df073c39a933d88f5b +[2025-08-15T11:15:13.052Z] DB: getSession - ok 3bb5a76d0c848fb8518cc771fe90fdeb2f2cd3a53b6bb6df073c39a933d88f5b +[2025-08-15T11:15:13.052Z] SESSION: Valid 3bb5a76d0c848fb8518cc771fe90fdeb2f2cd3a53b6bb6df073c39a933d88f5b christoffer PUT /api/players/christoffer +[2025-08-15T11:15:13.052Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:15:13.052Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:15:13.052Z] DB: updatePlayer - start christoffer +[2025-08-15T11:15:13.052Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T11:15:13.052Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:15:13.052Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:15:13.053Z] API: Updated player christoffer +[2025-08-15T11:15:13.068Z] DB: getSession - start 3bb5a76d0c848fb8518cc771fe90fdeb2f2cd3a53b6bb6df073c39a933d88f5b +[2025-08-15T11:15:13.069Z] DB: getSession - ok 3bb5a76d0c848fb8518cc771fe90fdeb2f2cd3a53b6bb6df073c39a933d88f5b +[2025-08-15T11:15:13.069Z] SESSION: Valid 3bb5a76d0c848fb8518cc771fe90fdeb2f2cd3a53b6bb6df073c39a933d88f5b christoffer PUT /api/players/christoffer +[2025-08-15T11:15:13.069Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:15:13.069Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:15:13.069Z] DB: updatePlayer - start christoffer +[2025-08-15T11:15:13.069Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T11:15:13.069Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:15:13.069Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:15:13.069Z] API: Updated player christoffer +[2025-08-15T11:17:46.100Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T11:17:46.100Z] DB: deletePlayer - start gmtest +[2025-08-15T11:17:46.100Z] DB: deletePlayer - changes 0 gmtest +[2025-08-15T11:17:46.116Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:17:46.116Z] DB: getPlayerByName - not found gmtest +[2025-08-15T11:17:46.197Z] DB: createPlayer - start gmtest +[2025-08-15T11:17:46.197Z] DB: createPlayer - done gmtest rowid 21 +[2025-08-15T11:17:46.197Z] API: Created player gmtest +[2025-08-15T11:17:46.214Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T11:17:46.214Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:17:46.214Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:17:46.214Z] DB: updatePlayer - start gmtest +[2025-08-15T11:17:46.214Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T11:17:46.214Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:17:46.215Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:17:46.215Z] API: Updated player gmtest +[2025-08-15T11:17:46.230Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T11:17:46.230Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:17:46.230Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:17:46.309Z] DB: updatePlayer - start gmtest +[2025-08-15T11:17:46.309Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T11:17:46.309Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:17:46.309Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:17:46.309Z] API: Updated player gmtest +[2025-08-15T11:17:46.333Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:17:46.333Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:17:46.413Z] DB: createSession - start df5208684b05566f8172c8fcb86ede81160ee45bb2a0989200385028a5d77578 expiresAt 2025-08-16T11:17:46.413Z +[2025-08-15T11:17:46.413Z] DB: createSession - done df5208684b05566f8172c8fcb86ede81160ee45bb2a0989200385028a5d77578 +[2025-08-15T11:17:46.413Z] API: Player login gmtest df5208684b05566f8172c8fcb86ede81160ee45bb2a0989200385028a5d77578 +[2025-08-15T11:17:46.431Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T11:17:46.431Z] DB: deletePlayer - start gmtest +[2025-08-15T11:17:46.431Z] DB: deletePlayer - changes 1 gmtest +[2025-08-15T11:17:46.431Z] API: Deleted player gmtest +[2025-08-15T11:17:46.446Z] DB: getAllPlayers - start +[2025-08-15T11:17:46.446Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:17:46.446Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:17:46.939Z] DB: getAllPlayers - start +[2025-08-15T11:17:46.940Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:17:47.276Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:17:47.276Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:17:47.357Z] DB: createSession - start 72ddedbfd44e583a9b609decc56d013beb6809913884590dbcd0eac701d12781 expiresAt 2025-08-16T11:17:47.357Z +[2025-08-15T11:17:47.357Z] DB: createSession - done 72ddedbfd44e583a9b609decc56d013beb6809913884590dbcd0eac701d12781 +[2025-08-15T11:17:47.357Z] API: Player login christoffer 72ddedbfd44e583a9b609decc56d013beb6809913884590dbcd0eac701d12781 +[2025-08-15T11:17:47.376Z] DB: getSession - start 72ddedbfd44e583a9b609decc56d013beb6809913884590dbcd0eac701d12781 +[2025-08-15T11:17:47.376Z] DB: getSession - ok 72ddedbfd44e583a9b609decc56d013beb6809913884590dbcd0eac701d12781 +[2025-08-15T11:17:47.376Z] SESSION: Valid 72ddedbfd44e583a9b609decc56d013beb6809913884590dbcd0eac701d12781 christoffer PUT /api/players/christoffer +[2025-08-15T11:17:47.376Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:17:47.376Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:17:47.376Z] DB: updatePlayer - start christoffer +[2025-08-15T11:17:47.376Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T11:17:47.377Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:17:47.377Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:17:47.377Z] API: Updated player christoffer +[2025-08-15T11:17:47.393Z] DB: getSession - start 72ddedbfd44e583a9b609decc56d013beb6809913884590dbcd0eac701d12781 +[2025-08-15T11:17:47.393Z] DB: getSession - ok 72ddedbfd44e583a9b609decc56d013beb6809913884590dbcd0eac701d12781 +[2025-08-15T11:17:47.393Z] SESSION: Valid 72ddedbfd44e583a9b609decc56d013beb6809913884590dbcd0eac701d12781 christoffer PUT /api/players/christoffer +[2025-08-15T11:17:47.393Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:17:47.393Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:17:47.393Z] DB: updatePlayer - start christoffer +[2025-08-15T11:17:47.393Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T11:17:47.393Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:17:47.393Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:17:47.393Z] API: Updated player christoffer +[2025-08-15T11:19:22.103Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T11:19:22.103Z] DB: deletePlayer - start gmtest +[2025-08-15T11:19:22.103Z] DB: deletePlayer - changes 0 gmtest +[2025-08-15T11:19:22.119Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:19:22.119Z] DB: getPlayerByName - not found gmtest +[2025-08-15T11:19:22.199Z] DB: createPlayer - start gmtest +[2025-08-15T11:19:22.200Z] DB: createPlayer - done gmtest rowid 22 +[2025-08-15T11:19:22.200Z] API: Created player gmtest +[2025-08-15T11:19:22.223Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T11:19:22.223Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:19:22.223Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:19:22.223Z] DB: updatePlayer - start gmtest +[2025-08-15T11:19:22.223Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T11:19:22.224Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:19:22.224Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:19:22.224Z] API: Updated player gmtest +[2025-08-15T11:19:22.239Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T11:19:22.239Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:19:22.239Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:19:22.319Z] DB: updatePlayer - start gmtest +[2025-08-15T11:19:22.319Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T11:19:22.319Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:19:22.319Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:19:22.319Z] API: Updated player gmtest +[2025-08-15T11:19:22.334Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:19:22.334Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:19:22.417Z] DB: createSession - start e36eb1cd9f626a2ab3e78bec9c28baa102814617702dfd487e04a739b4ace929 expiresAt 2025-08-16T11:19:22.417Z +[2025-08-15T11:19:22.418Z] DB: createSession - done e36eb1cd9f626a2ab3e78bec9c28baa102814617702dfd487e04a739b4ace929 +[2025-08-15T11:19:22.418Z] API: Player login gmtest e36eb1cd9f626a2ab3e78bec9c28baa102814617702dfd487e04a739b4ace929 +[2025-08-15T11:19:22.434Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T11:19:22.434Z] DB: deletePlayer - start gmtest +[2025-08-15T11:19:22.434Z] DB: deletePlayer - changes 1 gmtest +[2025-08-15T11:19:22.434Z] API: Deleted player gmtest +[2025-08-15T11:19:22.449Z] DB: getAllPlayers - start +[2025-08-15T11:19:22.449Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:19:22.450Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:19:22.931Z] DB: getAllPlayers - start +[2025-08-15T11:19:22.932Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:19:23.258Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:19:23.258Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:19:23.337Z] DB: createSession - start 41e00c9dc9a72240787c8911355aa1719235d4a295f43c95d2ddb0704532933c expiresAt 2025-08-16T11:19:23.337Z +[2025-08-15T11:19:23.337Z] DB: createSession - done 41e00c9dc9a72240787c8911355aa1719235d4a295f43c95d2ddb0704532933c +[2025-08-15T11:19:23.338Z] API: Player login christoffer 41e00c9dc9a72240787c8911355aa1719235d4a295f43c95d2ddb0704532933c +[2025-08-15T11:19:23.367Z] DB: getSession - start 41e00c9dc9a72240787c8911355aa1719235d4a295f43c95d2ddb0704532933c +[2025-08-15T11:19:23.367Z] DB: getSession - ok 41e00c9dc9a72240787c8911355aa1719235d4a295f43c95d2ddb0704532933c +[2025-08-15T11:19:23.367Z] SESSION: Valid 41e00c9dc9a72240787c8911355aa1719235d4a295f43c95d2ddb0704532933c christoffer PUT /api/players/christoffer +[2025-08-15T11:19:23.367Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:19:23.367Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:19:23.367Z] DB: updatePlayer - start christoffer +[2025-08-15T11:19:23.367Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T11:19:23.367Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:19:23.367Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:19:23.367Z] API: Updated player christoffer +[2025-08-15T11:19:23.386Z] DB: getSession - start 41e00c9dc9a72240787c8911355aa1719235d4a295f43c95d2ddb0704532933c +[2025-08-15T11:19:23.386Z] DB: getSession - ok 41e00c9dc9a72240787c8911355aa1719235d4a295f43c95d2ddb0704532933c +[2025-08-15T11:19:23.387Z] SESSION: Valid 41e00c9dc9a72240787c8911355aa1719235d4a295f43c95d2ddb0704532933c christoffer PUT /api/players/christoffer +[2025-08-15T11:19:23.387Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:19:23.387Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:19:23.387Z] DB: updatePlayer - start christoffer +[2025-08-15T11:19:23.387Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T11:19:23.387Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:19:23.387Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:19:23.387Z] API: Updated player christoffer +[2025-08-15T11:20:16.047Z] DB: getAllPlayers - start +[2025-08-15T11:20:16.048Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:20:16.048Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:21:24.842Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T11:21:24.842Z] DB: deletePlayer - start gmtest +[2025-08-15T11:21:24.842Z] DB: deletePlayer - changes 0 gmtest +[2025-08-15T11:21:24.864Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:21:24.864Z] DB: getPlayerByName - not found gmtest +[2025-08-15T11:21:24.944Z] DB: createPlayer - start gmtest +[2025-08-15T11:21:24.944Z] DB: createPlayer - done gmtest rowid 23 +[2025-08-15T11:21:24.944Z] API: Created player gmtest +[2025-08-15T11:21:24.962Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T11:21:24.962Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:21:24.962Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:21:24.962Z] DB: updatePlayer - start gmtest +[2025-08-15T11:21:24.962Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T11:21:24.962Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:21:24.963Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:21:24.963Z] API: Updated player gmtest +[2025-08-15T11:21:24.977Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T11:21:24.977Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:21:24.977Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:21:25.056Z] DB: updatePlayer - start gmtest +[2025-08-15T11:21:25.057Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T11:21:25.057Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:21:25.057Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:21:25.057Z] API: Updated player gmtest +[2025-08-15T11:21:25.071Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:21:25.072Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:21:25.151Z] DB: createSession - start 63ec8908362b0dda4dd40686581b1c2dc9a90e2f12f45d8e1829f6bb14233645 expiresAt 2025-08-16T11:21:25.151Z +[2025-08-15T11:21:25.152Z] DB: createSession - done 63ec8908362b0dda4dd40686581b1c2dc9a90e2f12f45d8e1829f6bb14233645 +[2025-08-15T11:21:25.152Z] API: Player login gmtest 63ec8908362b0dda4dd40686581b1c2dc9a90e2f12f45d8e1829f6bb14233645 +[2025-08-15T11:21:25.166Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T11:21:25.166Z] DB: deletePlayer - start gmtest +[2025-08-15T11:21:25.166Z] DB: deletePlayer - changes 1 gmtest +[2025-08-15T11:21:25.166Z] API: Deleted player gmtest +[2025-08-15T11:21:25.182Z] DB: getAllPlayers - start +[2025-08-15T11:21:25.182Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:21:25.182Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:21:25.689Z] DB: getAllPlayers - start +[2025-08-15T11:21:25.689Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:21:26.040Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:21:26.040Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:21:26.120Z] DB: createSession - start c706f05495676bbfca1faea529cceeb13c49686832fc0cc4b8a10b577588fe3d expiresAt 2025-08-16T11:21:26.120Z +[2025-08-15T11:21:26.121Z] DB: createSession - done c706f05495676bbfca1faea529cceeb13c49686832fc0cc4b8a10b577588fe3d +[2025-08-15T11:21:26.121Z] API: Player login christoffer c706f05495676bbfca1faea529cceeb13c49686832fc0cc4b8a10b577588fe3d +[2025-08-15T11:21:26.150Z] DB: getSession - start c706f05495676bbfca1faea529cceeb13c49686832fc0cc4b8a10b577588fe3d +[2025-08-15T11:21:26.150Z] DB: getSession - ok c706f05495676bbfca1faea529cceeb13c49686832fc0cc4b8a10b577588fe3d +[2025-08-15T11:21:26.150Z] SESSION: Valid c706f05495676bbfca1faea529cceeb13c49686832fc0cc4b8a10b577588fe3d christoffer PUT /api/players/christoffer +[2025-08-15T11:21:26.150Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:21:26.151Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:21:26.151Z] DB: updatePlayer - start christoffer +[2025-08-15T11:21:26.151Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T11:21:26.151Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:21:26.151Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:21:26.151Z] API: Updated player christoffer +[2025-08-15T11:21:26.167Z] DB: getSession - start c706f05495676bbfca1faea529cceeb13c49686832fc0cc4b8a10b577588fe3d +[2025-08-15T11:21:26.167Z] DB: getSession - ok c706f05495676bbfca1faea529cceeb13c49686832fc0cc4b8a10b577588fe3d +[2025-08-15T11:21:26.167Z] SESSION: Valid c706f05495676bbfca1faea529cceeb13c49686832fc0cc4b8a10b577588fe3d christoffer PUT /api/players/christoffer +[2025-08-15T11:21:26.167Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:21:26.167Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:21:26.167Z] DB: updatePlayer - start christoffer +[2025-08-15T11:21:26.168Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T11:21:26.168Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:21:26.168Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:21:26.168Z] API: Updated player christoffer +[2025-08-15T11:29:31.866Z] SESSION: Login missing playerName/username +[2025-08-15T11:29:33.783Z] DB: getPlayerByName - start gm +[2025-08-15T11:29:33.783Z] DB: getPlayerByName - not found gm +[2025-08-15T11:29:33.783Z] SESSION: Login player not found gm +[2025-08-15T11:30:04.693Z] DB: getAllPlayers - start +[2025-08-15T11:30:04.694Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:30:04.694Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:31:46.444Z] DB: getSession - start 2d60199a5a383cf6c1467bd42b33055ad0ce77c4935bac31a6fd4d812c535f0a +[2025-08-15T11:31:46.444Z] DB: getSession - ok 2d60199a5a383cf6c1467bd42b33055ad0ce77c4935bac31a6fd4d812c535f0a +[2025-08-15T11:31:46.444Z] SESSION: Validate success 2d60199a5a383cf6c1467bd42b33055ad0ce77c4935bac31a6fd4d812c535f0a phillip +[2025-08-15T11:31:48.572Z] DB: deleteSession - start 2d60199a5a383cf6c1467bd42b33055ad0ce77c4935bac31a6fd4d812c535f0a +[2025-08-15T11:31:48.572Z] DB: deleteSession - changes 1 2d60199a5a383cf6c1467bd42b33055ad0ce77c4935bac31a6fd4d812c535f0a +[2025-08-15T11:31:48.573Z] SESSION: Logout success 2d60199a5a383cf6c1467bd42b33055ad0ce77c4935bac31a6fd4d812c535f0a +[2025-08-15T11:31:50.684Z] DB: getAllPlayers - start +[2025-08-15T11:31:50.684Z] DB: getAllPlayers - resultCount 3 +[2025-08-15T11:31:50.684Z] API: Fetch all players (public) Found 3 players +[2025-08-15T11:33:16.218Z] Created GM user +[2025-08-15T11:33:16.219Z] GM privileges ensured +[2025-08-15T11:33:25.120Z] DB: getPlayerByName - start gm +[2025-08-15T11:33:25.120Z] DB: getPlayerByName - found gm +[2025-08-15T11:33:25.120Z] DB: createSession - start 667d5d87a61c00b11f4de4e6445804019e563edf32953b0a7ad6f361b0f8c641 expiresAt 2025-08-16T11:33:25.120Z +[2025-08-15T11:33:25.121Z] DB: createSession - done 667d5d87a61c00b11f4de4e6445804019e563edf32953b0a7ad6f361b0f8c641 +[2025-08-15T11:33:25.121Z] SESSION: Login success gm 667d5d87a61c00b11f4de4e6445804019e563edf32953b0a7ad6f361b0f8c641 +[2025-08-15T11:33:25.128Z] DB: getSession - start 667d5d87a61c00b11f4de4e6445804019e563edf32953b0a7ad6f361b0f8c641 +[2025-08-15T11:33:25.128Z] DB: getSession - ok 667d5d87a61c00b11f4de4e6445804019e563edf32953b0a7ad6f361b0f8c641 +[2025-08-15T11:33:25.128Z] SESSION: Validate success 667d5d87a61c00b11f4de4e6445804019e563edf32953b0a7ad6f361b0f8c641 gm +[2025-08-15T11:33:28.569Z] DB: getAllPlayers - start +[2025-08-15T11:33:28.569Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T11:33:28.569Z] API: Fetch all players (public) Found 4 players +[2025-08-15T11:33:34.425Z] SESSION: GM bypass accepted PUT /api/players/christoffer +[2025-08-15T11:33:34.426Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:33:34.426Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:33:34.426Z] DB: updatePlayer - start christoffer +[2025-08-15T11:33:34.426Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T11:33:34.426Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:33:34.426Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:33:34.426Z] API: Updated player christoffer +[2025-08-15T11:33:34.431Z] DB: getAllPlayers - start +[2025-08-15T11:33:34.431Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T11:33:34.431Z] API: Fetch all players (public) Found 4 players +[2025-08-15T11:33:45.741Z] DB: getAllPlayers - start +[2025-08-15T11:33:45.741Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T11:33:45.741Z] API: Fetch all players (public) Found 4 players +[2025-08-15T11:33:48.694Z] DB: getAllPlayers - start +[2025-08-15T11:33:48.695Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T11:33:48.695Z] API: Fetch all players (public) Found 4 players +[2025-08-15T11:34:43.196Z] DB: deleteSession - start 667d5d87a61c00b11f4de4e6445804019e563edf32953b0a7ad6f361b0f8c641 +[2025-08-15T11:34:43.196Z] DB: deleteSession - changes 1 667d5d87a61c00b11f4de4e6445804019e563edf32953b0a7ad6f361b0f8c641 +[2025-08-15T11:34:43.196Z] SESSION: Logout success 667d5d87a61c00b11f4de4e6445804019e563edf32953b0a7ad6f361b0f8c641 +[2025-08-15T11:34:43.218Z] DB: getAllPlayers - start +[2025-08-15T11:34:43.219Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T11:34:43.219Z] API: Fetch all players (public) Found 4 players +[2025-08-15T11:34:59.299Z] DB: getAllPlayers - start +[2025-08-15T11:34:59.299Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T11:34:59.299Z] API: Fetch all players (public) Found 4 players +[2025-08-15T11:35:00.626Z] DB: getAllPlayers - start +[2025-08-15T11:35:00.626Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T11:35:00.626Z] API: Fetch all players (public) Found 4 players +[2025-08-15T11:35:13.602Z] DB: getAllPlayers - start +[2025-08-15T11:35:13.603Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T11:35:13.603Z] API: Fetch all players (public) Found 4 players +[2025-08-15T11:38:54.362Z] DB: getAllPlayers - start +[2025-08-15T11:38:54.362Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T11:38:54.362Z] API: Fetch all players (public) Found 4 players +[2025-08-15T11:39:00.224Z] DB: getAllPlayers - start +[2025-08-15T11:39:00.225Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T11:39:00.225Z] API: Fetch all players (public) Found 4 players +[2025-08-15T11:41:02.253Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T11:41:02.253Z] DB: deletePlayer - start gmtest +[2025-08-15T11:41:02.253Z] DB: deletePlayer - changes 0 gmtest +[2025-08-15T11:41:02.268Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:41:02.268Z] DB: getPlayerByName - not found gmtest +[2025-08-15T11:41:02.349Z] DB: createPlayer - start gmtest +[2025-08-15T11:41:02.349Z] DB: createPlayer - done gmtest rowid 25 +[2025-08-15T11:41:02.349Z] API: Created player gmtest +[2025-08-15T11:41:02.366Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T11:41:02.366Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:41:02.366Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:41:02.366Z] DB: updatePlayer - start gmtest +[2025-08-15T11:41:02.366Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T11:41:02.366Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:41:02.366Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:41:02.366Z] API: Updated player gmtest +[2025-08-15T11:41:02.381Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T11:41:02.382Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:41:02.382Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:41:02.462Z] DB: updatePlayer - start gmtest +[2025-08-15T11:41:02.462Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T11:41:02.462Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:41:02.462Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:41:02.462Z] API: Updated player gmtest +[2025-08-15T11:41:02.476Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:41:02.476Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:41:02.556Z] DB: createSession - start 49528490d1a9482407248c22e151af9a505bfacccf92c0bc9e1d0bf190ccca18 expiresAt 2025-08-16T11:41:02.556Z +[2025-08-15T11:41:02.556Z] DB: createSession - done 49528490d1a9482407248c22e151af9a505bfacccf92c0bc9e1d0bf190ccca18 +[2025-08-15T11:41:02.556Z] API: Player login gmtest 49528490d1a9482407248c22e151af9a505bfacccf92c0bc9e1d0bf190ccca18 +[2025-08-15T11:41:02.580Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T11:41:02.580Z] DB: deletePlayer - start gmtest +[2025-08-15T11:41:02.581Z] DB: deletePlayer - changes 1 gmtest +[2025-08-15T11:41:02.581Z] API: Deleted player gmtest +[2025-08-15T11:41:02.596Z] DB: getAllPlayers - start +[2025-08-15T11:41:02.596Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T11:41:02.596Z] API: Fetch all players (public) Found 4 players +[2025-08-15T11:41:03.074Z] DB: getAllPlayers - start +[2025-08-15T11:41:03.075Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T11:41:03.408Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:41:03.408Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:41:03.487Z] DB: createSession - start f64d5bb9563f91edf31fc0a1ed36470398c43ffaac54a0f8528d79a07cd488d1 expiresAt 2025-08-16T11:41:03.487Z +[2025-08-15T11:41:03.487Z] DB: createSession - done f64d5bb9563f91edf31fc0a1ed36470398c43ffaac54a0f8528d79a07cd488d1 +[2025-08-15T11:41:03.487Z] API: Player login christoffer f64d5bb9563f91edf31fc0a1ed36470398c43ffaac54a0f8528d79a07cd488d1 +[2025-08-15T11:41:03.506Z] DB: getSession - start f64d5bb9563f91edf31fc0a1ed36470398c43ffaac54a0f8528d79a07cd488d1 +[2025-08-15T11:41:03.506Z] DB: getSession - ok f64d5bb9563f91edf31fc0a1ed36470398c43ffaac54a0f8528d79a07cd488d1 +[2025-08-15T11:41:03.506Z] SESSION: Valid f64d5bb9563f91edf31fc0a1ed36470398c43ffaac54a0f8528d79a07cd488d1 christoffer PUT /api/players/christoffer +[2025-08-15T11:41:03.506Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:41:03.506Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:41:03.506Z] DB: updatePlayer - start christoffer +[2025-08-15T11:41:03.506Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T11:41:03.506Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:41:03.506Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:41:03.506Z] API: Updated player christoffer +[2025-08-15T11:41:03.522Z] DB: getSession - start f64d5bb9563f91edf31fc0a1ed36470398c43ffaac54a0f8528d79a07cd488d1 +[2025-08-15T11:41:03.522Z] DB: getSession - ok f64d5bb9563f91edf31fc0a1ed36470398c43ffaac54a0f8528d79a07cd488d1 +[2025-08-15T11:41:03.523Z] SESSION: Valid f64d5bb9563f91edf31fc0a1ed36470398c43ffaac54a0f8528d79a07cd488d1 christoffer PUT /api/players/christoffer +[2025-08-15T11:41:03.523Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:41:03.523Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:41:03.523Z] DB: updatePlayer - start christoffer +[2025-08-15T11:41:03.523Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T11:41:03.523Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:41:03.523Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:41:03.523Z] API: Updated player christoffer +[2025-08-15T11:42:07.194Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T11:42:07.194Z] DB: deletePlayer - start gmtest +[2025-08-15T11:42:07.194Z] DB: deletePlayer - changes 0 gmtest +[2025-08-15T11:42:07.211Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:42:07.211Z] DB: getPlayerByName - not found gmtest +[2025-08-15T11:42:07.291Z] DB: createPlayer - start gmtest +[2025-08-15T11:42:07.291Z] DB: createPlayer - done gmtest rowid 26 +[2025-08-15T11:42:07.291Z] API: Created player gmtest +[2025-08-15T11:42:07.308Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T11:42:07.308Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:42:07.309Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:42:07.309Z] DB: updatePlayer - start gmtest +[2025-08-15T11:42:07.309Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T11:42:07.309Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:42:07.309Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:42:07.309Z] API: Updated player gmtest +[2025-08-15T11:42:07.324Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T11:42:07.324Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:42:07.325Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:42:07.404Z] DB: updatePlayer - start gmtest +[2025-08-15T11:42:07.404Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T11:42:07.405Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:42:07.405Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:42:07.405Z] API: Updated player gmtest +[2025-08-15T11:42:07.419Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:42:07.420Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:42:07.500Z] DB: createSession - start 39dae92c9527063010ba5675ba80eccb4c85f3ec3e016e5974dc2553d357c6e7 expiresAt 2025-08-16T11:42:07.500Z +[2025-08-15T11:42:07.501Z] DB: createSession - done 39dae92c9527063010ba5675ba80eccb4c85f3ec3e016e5974dc2553d357c6e7 +[2025-08-15T11:42:07.501Z] API: Player login gmtest 39dae92c9527063010ba5675ba80eccb4c85f3ec3e016e5974dc2553d357c6e7 +[2025-08-15T11:42:07.516Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T11:42:07.516Z] DB: deletePlayer - start gmtest +[2025-08-15T11:42:07.516Z] DB: deletePlayer - changes 1 gmtest +[2025-08-15T11:42:07.516Z] API: Deleted player gmtest +[2025-08-15T11:42:07.531Z] DB: getAllPlayers - start +[2025-08-15T11:42:07.531Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T11:42:07.532Z] API: Fetch all players (public) Found 4 players +[2025-08-15T11:42:08.035Z] DB: getAllPlayers - start +[2025-08-15T11:42:08.036Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T11:42:08.371Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:42:08.371Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:42:08.451Z] DB: createSession - start 5180df692eb1e56ad73971b30cd748408c7cbe1a99c37f1e8ad6325196a512bc expiresAt 2025-08-16T11:42:08.451Z +[2025-08-15T11:42:08.451Z] DB: createSession - done 5180df692eb1e56ad73971b30cd748408c7cbe1a99c37f1e8ad6325196a512bc +[2025-08-15T11:42:08.451Z] API: Player login christoffer 5180df692eb1e56ad73971b30cd748408c7cbe1a99c37f1e8ad6325196a512bc +[2025-08-15T11:42:08.471Z] DB: getSession - start 5180df692eb1e56ad73971b30cd748408c7cbe1a99c37f1e8ad6325196a512bc +[2025-08-15T11:42:08.471Z] DB: getSession - ok 5180df692eb1e56ad73971b30cd748408c7cbe1a99c37f1e8ad6325196a512bc +[2025-08-15T11:42:08.471Z] SESSION: Valid 5180df692eb1e56ad73971b30cd748408c7cbe1a99c37f1e8ad6325196a512bc christoffer PUT /api/players/christoffer +[2025-08-15T11:42:08.471Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:42:08.471Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:42:08.471Z] DB: updatePlayer - start christoffer +[2025-08-15T11:42:08.471Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T11:42:08.471Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:42:08.471Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:42:08.471Z] API: Updated player christoffer +[2025-08-15T11:42:08.487Z] DB: getSession - start 5180df692eb1e56ad73971b30cd748408c7cbe1a99c37f1e8ad6325196a512bc +[2025-08-15T11:42:08.487Z] DB: getSession - ok 5180df692eb1e56ad73971b30cd748408c7cbe1a99c37f1e8ad6325196a512bc +[2025-08-15T11:42:08.487Z] SESSION: Valid 5180df692eb1e56ad73971b30cd748408c7cbe1a99c37f1e8ad6325196a512bc christoffer PUT /api/players/christoffer +[2025-08-15T11:42:08.487Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:42:08.487Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:42:08.488Z] DB: updatePlayer - start christoffer +[2025-08-15T11:42:08.488Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T11:42:08.488Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:42:08.488Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:42:08.488Z] API: Updated player christoffer +[2025-08-15T11:43:01.206Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T11:43:01.206Z] DB: deletePlayer - start gmtest +[2025-08-15T11:43:01.206Z] DB: deletePlayer - changes 0 gmtest +[2025-08-15T11:43:01.222Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:43:01.222Z] DB: getPlayerByName - not found gmtest +[2025-08-15T11:43:01.301Z] DB: createPlayer - start gmtest +[2025-08-15T11:43:01.302Z] DB: createPlayer - done gmtest rowid 27 +[2025-08-15T11:43:01.302Z] API: Created player gmtest +[2025-08-15T11:43:01.319Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T11:43:01.319Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:43:01.319Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:43:01.319Z] DB: updatePlayer - start gmtest +[2025-08-15T11:43:01.319Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T11:43:01.319Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:43:01.319Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:43:01.319Z] API: Updated player gmtest +[2025-08-15T11:43:01.334Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T11:43:01.334Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:43:01.334Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:43:01.414Z] DB: updatePlayer - start gmtest +[2025-08-15T11:43:01.414Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T11:43:01.414Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:43:01.414Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:43:01.414Z] API: Updated player gmtest +[2025-08-15T11:43:01.429Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:43:01.430Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:43:01.509Z] DB: createSession - start 6bdc580827fc67029caaa906687cb383763028ceff1b289b85cbd44c835ae428 expiresAt 2025-08-16T11:43:01.509Z +[2025-08-15T11:43:01.509Z] DB: createSession - done 6bdc580827fc67029caaa906687cb383763028ceff1b289b85cbd44c835ae428 +[2025-08-15T11:43:01.509Z] API: Player login gmtest 6bdc580827fc67029caaa906687cb383763028ceff1b289b85cbd44c835ae428 +[2025-08-15T11:43:01.524Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T11:43:01.525Z] DB: deletePlayer - start gmtest +[2025-08-15T11:43:01.525Z] DB: deletePlayer - changes 1 gmtest +[2025-08-15T11:43:01.525Z] API: Deleted player gmtest +[2025-08-15T11:43:01.540Z] DB: getAllPlayers - start +[2025-08-15T11:43:01.540Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T11:43:01.540Z] API: Fetch all players (public) Found 4 players +[2025-08-15T11:43:02.047Z] DB: getAllPlayers - start +[2025-08-15T11:43:02.048Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T11:43:02.388Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:43:02.389Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:43:02.468Z] DB: createSession - start cb94707e1df04826909bc79593afe4d5d745678968b199bdc0d1b9695a45807d expiresAt 2025-08-16T11:43:02.468Z +[2025-08-15T11:43:02.468Z] DB: createSession - done cb94707e1df04826909bc79593afe4d5d745678968b199bdc0d1b9695a45807d +[2025-08-15T11:43:02.468Z] API: Player login christoffer cb94707e1df04826909bc79593afe4d5d745678968b199bdc0d1b9695a45807d +[2025-08-15T11:43:02.498Z] DB: getSession - start cb94707e1df04826909bc79593afe4d5d745678968b199bdc0d1b9695a45807d +[2025-08-15T11:43:02.498Z] DB: getSession - ok cb94707e1df04826909bc79593afe4d5d745678968b199bdc0d1b9695a45807d +[2025-08-15T11:43:02.498Z] SESSION: Valid cb94707e1df04826909bc79593afe4d5d745678968b199bdc0d1b9695a45807d christoffer PUT /api/players/christoffer +[2025-08-15T11:43:02.498Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:43:02.498Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:43:02.498Z] DB: updatePlayer - start christoffer +[2025-08-15T11:43:02.499Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T11:43:02.499Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:43:02.499Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:43:02.499Z] API: Updated player christoffer +[2025-08-15T11:43:02.515Z] DB: getSession - start cb94707e1df04826909bc79593afe4d5d745678968b199bdc0d1b9695a45807d +[2025-08-15T11:43:02.515Z] DB: getSession - ok cb94707e1df04826909bc79593afe4d5d745678968b199bdc0d1b9695a45807d +[2025-08-15T11:43:02.515Z] SESSION: Valid cb94707e1df04826909bc79593afe4d5d745678968b199bdc0d1b9695a45807d christoffer PUT /api/players/christoffer +[2025-08-15T11:43:02.515Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:43:02.515Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:43:02.515Z] DB: updatePlayer - start christoffer +[2025-08-15T11:43:02.516Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T11:43:02.516Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:43:02.516Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:43:02.516Z] API: Updated player christoffer +[2025-08-15T11:44:22.725Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T11:44:22.725Z] DB: deletePlayer - start gmtest +[2025-08-15T11:44:22.725Z] DB: deletePlayer - changes 0 gmtest +[2025-08-15T11:44:22.744Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:44:22.744Z] DB: getPlayerByName - not found gmtest +[2025-08-15T11:44:22.824Z] DB: createPlayer - start gmtest +[2025-08-15T11:44:22.824Z] DB: createPlayer - done gmtest rowid 28 +[2025-08-15T11:44:22.825Z] API: Created player gmtest +[2025-08-15T11:44:22.842Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T11:44:22.842Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:44:22.843Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:44:22.843Z] DB: updatePlayer - start gmtest +[2025-08-15T11:44:22.843Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T11:44:22.843Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:44:22.843Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:44:22.843Z] API: Updated player gmtest +[2025-08-15T11:44:22.859Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T11:44:22.859Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:44:22.859Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:44:22.939Z] DB: updatePlayer - start gmtest +[2025-08-15T11:44:22.939Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T11:44:22.939Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:44:22.939Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:44:22.939Z] API: Updated player gmtest +[2025-08-15T11:44:22.954Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:44:22.955Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:44:23.039Z] DB: createSession - start 4f11b4f0697c184e8d14bec28334ba4686923495296c1ccd747200e5bdc41613 expiresAt 2025-08-16T11:44:23.039Z +[2025-08-15T11:44:23.039Z] DB: createSession - done 4f11b4f0697c184e8d14bec28334ba4686923495296c1ccd747200e5bdc41613 +[2025-08-15T11:44:23.039Z] API: Player login gmtest 4f11b4f0697c184e8d14bec28334ba4686923495296c1ccd747200e5bdc41613 +[2025-08-15T11:44:23.054Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T11:44:23.054Z] DB: deletePlayer - start gmtest +[2025-08-15T11:44:23.054Z] DB: deletePlayer - changes 1 gmtest +[2025-08-15T11:44:23.055Z] API: Deleted player gmtest +[2025-08-15T11:44:23.071Z] DB: getAllPlayers - start +[2025-08-15T11:44:23.071Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T11:44:23.071Z] API: Fetch all players (public) Found 4 players +[2025-08-15T11:44:23.583Z] DB: getAllPlayers - start +[2025-08-15T11:44:23.584Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T11:44:23.915Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:44:23.917Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:44:23.996Z] DB: createSession - start 47b59d31648c4154f46eeaa79c8338f4aa4d67da3e0f6eafb37a7c4f348630d1 expiresAt 2025-08-16T11:44:23.996Z +[2025-08-15T11:44:23.996Z] DB: createSession - done 47b59d31648c4154f46eeaa79c8338f4aa4d67da3e0f6eafb37a7c4f348630d1 +[2025-08-15T11:44:23.996Z] API: Player login christoffer 47b59d31648c4154f46eeaa79c8338f4aa4d67da3e0f6eafb37a7c4f348630d1 +[2025-08-15T11:44:24.028Z] DB: getSession - start 47b59d31648c4154f46eeaa79c8338f4aa4d67da3e0f6eafb37a7c4f348630d1 +[2025-08-15T11:44:24.028Z] DB: getSession - ok 47b59d31648c4154f46eeaa79c8338f4aa4d67da3e0f6eafb37a7c4f348630d1 +[2025-08-15T11:44:24.029Z] SESSION: Valid 47b59d31648c4154f46eeaa79c8338f4aa4d67da3e0f6eafb37a7c4f348630d1 christoffer PUT /api/players/christoffer +[2025-08-15T11:44:24.029Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:44:24.029Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:44:24.029Z] DB: updatePlayer - start christoffer +[2025-08-15T11:44:24.029Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T11:44:24.029Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:44:24.029Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:44:24.029Z] API: Updated player christoffer +[2025-08-15T11:44:24.045Z] DB: getSession - start 47b59d31648c4154f46eeaa79c8338f4aa4d67da3e0f6eafb37a7c4f348630d1 +[2025-08-15T11:44:24.046Z] DB: getSession - ok 47b59d31648c4154f46eeaa79c8338f4aa4d67da3e0f6eafb37a7c4f348630d1 +[2025-08-15T11:44:24.046Z] SESSION: Valid 47b59d31648c4154f46eeaa79c8338f4aa4d67da3e0f6eafb37a7c4f348630d1 christoffer PUT /api/players/christoffer +[2025-08-15T11:44:24.046Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:44:24.046Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:44:24.046Z] DB: updatePlayer - start christoffer +[2025-08-15T11:44:24.046Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T11:44:24.046Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:44:24.046Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:44:24.046Z] API: Updated player christoffer +[2025-08-15T11:44:43.867Z] DB: getSession - start 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 +[2025-08-15T11:44:43.867Z] DB: getSession - ok 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 +[2025-08-15T11:44:43.867Z] SESSION: Validate success 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 phillip +[2025-08-15T11:44:45.760Z] DB: deleteSession - start 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 +[2025-08-15T11:44:45.761Z] DB: deleteSession - changes 1 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 +[2025-08-15T11:44:45.761Z] SESSION: Logout success 72afdbd37c300bc465ad9c1c1d55359deccaf290633470774eaf3d3d7b31ca64 +[2025-08-15T11:44:47.595Z] DB: getAllPlayers - start +[2025-08-15T11:44:47.595Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T11:44:47.595Z] API: Fetch all players (public) Found 4 players +[2025-08-15T11:44:51.921Z] DB: getPlayerByName - start gm +[2025-08-15T11:44:51.921Z] DB: getPlayerByName - found gm +[2025-08-15T11:44:51.921Z] SESSION: Login invalid password gm +[2025-08-15T11:44:53.993Z] DB: getPlayerByName - start gm +[2025-08-15T11:44:53.993Z] DB: getPlayerByName - found gm +[2025-08-15T11:44:53.993Z] SESSION: Login invalid password gm +[2025-08-15T11:45:36.898Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:45:36.898Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:45:36.898Z] DB: createSession - start 71a1f750b7974201717503799f17f0eac78ca263d4635b45bbb2a19f55e3e04c expiresAt 2025-08-16T11:45:36.898Z +[2025-08-15T11:45:36.898Z] DB: createSession - done 71a1f750b7974201717503799f17f0eac78ca263d4635b45bbb2a19f55e3e04c +[2025-08-15T11:45:36.898Z] SESSION: Login success christoffer 71a1f750b7974201717503799f17f0eac78ca263d4635b45bbb2a19f55e3e04c +[2025-08-15T11:45:36.932Z] DB: getAllPlayers - start +[2025-08-15T11:45:36.932Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T11:45:36.932Z] API: Fetch all players (public) Found 4 players +[2025-08-15T11:45:36.937Z] DB: getSession - start 71a1f750b7974201717503799f17f0eac78ca263d4635b45bbb2a19f55e3e04c +[2025-08-15T11:45:36.937Z] DB: getSession - ok 71a1f750b7974201717503799f17f0eac78ca263d4635b45bbb2a19f55e3e04c +[2025-08-15T11:45:36.937Z] SESSION: Validate success 71a1f750b7974201717503799f17f0eac78ca263d4635b45bbb2a19f55e3e04c christoffer +[2025-08-15T11:45:42.247Z] DB: deleteSession - start 71a1f750b7974201717503799f17f0eac78ca263d4635b45bbb2a19f55e3e04c +[2025-08-15T11:45:42.247Z] DB: deleteSession - changes 1 71a1f750b7974201717503799f17f0eac78ca263d4635b45bbb2a19f55e3e04c +[2025-08-15T11:45:42.247Z] SESSION: Logout success 71a1f750b7974201717503799f17f0eac78ca263d4635b45bbb2a19f55e3e04c +[2025-08-15T11:48:06.933Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T11:48:06.934Z] DB: deletePlayer - start gmtest +[2025-08-15T11:48:06.934Z] DB: deletePlayer - changes 0 gmtest +[2025-08-15T11:48:06.952Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:48:06.952Z] DB: getPlayerByName - not found gmtest +[2025-08-15T11:48:07.032Z] DB: createPlayer - start gmtest +[2025-08-15T11:48:07.032Z] DB: createPlayer - done gmtest rowid 29 +[2025-08-15T11:48:07.032Z] API: Created player gmtest +[2025-08-15T11:48:07.050Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T11:48:07.050Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:48:07.050Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:48:07.050Z] DB: updatePlayer - start gmtest +[2025-08-15T11:48:07.050Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T11:48:07.050Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:48:07.050Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:48:07.050Z] API: Updated player gmtest +[2025-08-15T11:48:07.065Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T11:48:07.066Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:48:07.066Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:48:07.146Z] DB: updatePlayer - start gmtest +[2025-08-15T11:48:07.146Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T11:48:07.146Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:48:07.146Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:48:07.146Z] API: Updated player gmtest +[2025-08-15T11:48:07.164Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:48:07.164Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:48:07.244Z] DB: createSession - start 01304e9d1f9240f84a813008f0aa8aa8c83aeffaea1c93a16d30e51d165e599b expiresAt 2025-08-16T11:48:07.244Z +[2025-08-15T11:48:07.245Z] DB: createSession - done 01304e9d1f9240f84a813008f0aa8aa8c83aeffaea1c93a16d30e51d165e599b +[2025-08-15T11:48:07.245Z] API: Player login gmtest 01304e9d1f9240f84a813008f0aa8aa8c83aeffaea1c93a16d30e51d165e599b +[2025-08-15T11:48:07.260Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T11:48:07.260Z] DB: deletePlayer - start gmtest +[2025-08-15T11:48:07.260Z] DB: deletePlayer - changes 1 gmtest +[2025-08-15T11:48:07.260Z] API: Deleted player gmtest +[2025-08-15T11:48:07.286Z] DB: getAllPlayers - start +[2025-08-15T11:48:07.286Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T11:48:07.286Z] API: Fetch all players (public) Found 4 players +[2025-08-15T11:48:07.816Z] DB: getAllPlayers - start +[2025-08-15T11:48:07.817Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T11:48:08.180Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:48:08.180Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:48:08.259Z] DB: createSession - start a24c570001441653ee834d5ff99f0d086a2fd9013346737ebddf854c4fc8462f expiresAt 2025-08-16T11:48:08.259Z +[2025-08-15T11:48:08.259Z] DB: createSession - done a24c570001441653ee834d5ff99f0d086a2fd9013346737ebddf854c4fc8462f +[2025-08-15T11:48:08.259Z] API: Player login christoffer a24c570001441653ee834d5ff99f0d086a2fd9013346737ebddf854c4fc8462f +[2025-08-15T11:48:08.293Z] DB: getSession - start a24c570001441653ee834d5ff99f0d086a2fd9013346737ebddf854c4fc8462f +[2025-08-15T11:48:08.294Z] DB: getSession - ok a24c570001441653ee834d5ff99f0d086a2fd9013346737ebddf854c4fc8462f +[2025-08-15T11:48:08.294Z] SESSION: Valid a24c570001441653ee834d5ff99f0d086a2fd9013346737ebddf854c4fc8462f christoffer PUT /api/players/christoffer +[2025-08-15T11:48:08.294Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:48:08.294Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:48:08.294Z] DB: updatePlayer - start christoffer +[2025-08-15T11:48:08.294Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T11:48:08.294Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:48:08.294Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:48:08.294Z] API: Updated player christoffer +[2025-08-15T11:48:08.310Z] DB: getSession - start a24c570001441653ee834d5ff99f0d086a2fd9013346737ebddf854c4fc8462f +[2025-08-15T11:48:08.310Z] DB: getSession - ok a24c570001441653ee834d5ff99f0d086a2fd9013346737ebddf854c4fc8462f +[2025-08-15T11:48:08.310Z] SESSION: Valid a24c570001441653ee834d5ff99f0d086a2fd9013346737ebddf854c4fc8462f christoffer PUT /api/players/christoffer +[2025-08-15T11:48:08.310Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:48:08.310Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:48:08.310Z] DB: updatePlayer - start christoffer +[2025-08-15T11:48:08.310Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T11:48:08.310Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:48:08.310Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:48:08.310Z] API: Updated player christoffer +[2025-08-15T11:49:42.636Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T11:49:42.636Z] DB: deletePlayer - start gmtest +[2025-08-15T11:49:42.636Z] DB: deletePlayer - changes 0 gmtest +[2025-08-15T11:49:42.653Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:49:42.653Z] DB: getPlayerByName - not found gmtest +[2025-08-15T11:49:42.733Z] DB: createPlayer - start gmtest +[2025-08-15T11:49:42.733Z] DB: createPlayer - done gmtest rowid 30 +[2025-08-15T11:49:42.733Z] API: Created player gmtest +[2025-08-15T11:49:42.750Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T11:49:42.750Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:49:42.750Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:49:42.750Z] DB: updatePlayer - start gmtest +[2025-08-15T11:49:42.751Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T11:49:42.751Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:49:42.751Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:49:42.751Z] API: Updated player gmtest +[2025-08-15T11:49:42.766Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T11:49:42.766Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:49:42.766Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:49:42.846Z] DB: updatePlayer - start gmtest +[2025-08-15T11:49:42.846Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T11:49:42.846Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:49:42.846Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:49:42.846Z] API: Updated player gmtest +[2025-08-15T11:49:42.861Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:49:42.861Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:49:42.944Z] DB: createSession - start f988dca51990fc56a27d2f9689808170c7624ac1f4a17231fb150094c3d6f068 expiresAt 2025-08-16T11:49:42.944Z +[2025-08-15T11:49:42.944Z] DB: createSession - done f988dca51990fc56a27d2f9689808170c7624ac1f4a17231fb150094c3d6f068 +[2025-08-15T11:49:42.944Z] API: Player login gmtest f988dca51990fc56a27d2f9689808170c7624ac1f4a17231fb150094c3d6f068 +[2025-08-15T11:49:42.959Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T11:49:42.960Z] DB: deletePlayer - start gmtest +[2025-08-15T11:49:42.960Z] DB: deletePlayer - changes 1 gmtest +[2025-08-15T11:49:42.960Z] API: Deleted player gmtest +[2025-08-15T11:49:42.974Z] DB: getAllPlayers - start +[2025-08-15T11:49:42.974Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T11:49:42.974Z] API: Fetch all players (public) Found 4 players +[2025-08-15T11:49:43.475Z] DB: getAllPlayers - start +[2025-08-15T11:49:43.476Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T11:49:43.810Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:49:43.811Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:49:43.890Z] DB: createSession - start 8cf0d1e6d879828f7c02d058ee0b8959cfa47dcedea880de5a1c05903cc98384 expiresAt 2025-08-16T11:49:43.890Z +[2025-08-15T11:49:43.890Z] DB: createSession - done 8cf0d1e6d879828f7c02d058ee0b8959cfa47dcedea880de5a1c05903cc98384 +[2025-08-15T11:49:43.890Z] API: Player login christoffer 8cf0d1e6d879828f7c02d058ee0b8959cfa47dcedea880de5a1c05903cc98384 +[2025-08-15T11:49:43.911Z] DB: getSession - start 8cf0d1e6d879828f7c02d058ee0b8959cfa47dcedea880de5a1c05903cc98384 +[2025-08-15T11:49:43.911Z] DB: getSession - ok 8cf0d1e6d879828f7c02d058ee0b8959cfa47dcedea880de5a1c05903cc98384 +[2025-08-15T11:49:43.911Z] SESSION: Valid 8cf0d1e6d879828f7c02d058ee0b8959cfa47dcedea880de5a1c05903cc98384 christoffer PUT /api/players/christoffer +[2025-08-15T11:49:43.911Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:49:43.911Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:49:43.911Z] DB: updatePlayer - start christoffer +[2025-08-15T11:49:43.911Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T11:49:43.911Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:49:43.911Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:49:43.911Z] API: Updated player christoffer +[2025-08-15T11:49:43.927Z] DB: getSession - start 8cf0d1e6d879828f7c02d058ee0b8959cfa47dcedea880de5a1c05903cc98384 +[2025-08-15T11:49:43.928Z] DB: getSession - ok 8cf0d1e6d879828f7c02d058ee0b8959cfa47dcedea880de5a1c05903cc98384 +[2025-08-15T11:49:43.928Z] SESSION: Valid 8cf0d1e6d879828f7c02d058ee0b8959cfa47dcedea880de5a1c05903cc98384 christoffer PUT /api/players/christoffer +[2025-08-15T11:49:43.928Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:49:43.928Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:49:43.928Z] DB: updatePlayer - start christoffer +[2025-08-15T11:49:43.928Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T11:49:43.928Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:49:43.928Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:49:43.928Z] API: Updated player christoffer +[2025-08-15T11:50:21.279Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T11:50:21.279Z] DB: deletePlayer - start gmtest +[2025-08-15T11:50:21.279Z] DB: deletePlayer - changes 0 gmtest +[2025-08-15T11:50:21.295Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:50:21.295Z] DB: getPlayerByName - not found gmtest +[2025-08-15T11:50:21.375Z] DB: createPlayer - start gmtest +[2025-08-15T11:50:21.375Z] DB: createPlayer - done gmtest rowid 31 +[2025-08-15T11:50:21.375Z] API: Created player gmtest +[2025-08-15T11:50:21.396Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T11:50:21.396Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:50:21.396Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:50:21.396Z] DB: updatePlayer - start gmtest +[2025-08-15T11:50:21.396Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T11:50:21.396Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:50:21.396Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:50:21.396Z] API: Updated player gmtest +[2025-08-15T11:50:21.412Z] SESSION: GM bypass accepted PUT /api/players/gmtest +[2025-08-15T11:50:21.412Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:50:21.412Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:50:21.491Z] DB: updatePlayer - start gmtest +[2025-08-15T11:50:21.492Z] DB: updatePlayer - changes 1 gmtest +[2025-08-15T11:50:21.492Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:50:21.492Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:50:21.492Z] API: Updated player gmtest +[2025-08-15T11:50:21.507Z] DB: getPlayerByName - start gmtest +[2025-08-15T11:50:21.508Z] DB: getPlayerByName - found gmtest +[2025-08-15T11:50:21.589Z] DB: createSession - start 957f64d54c1d3b7e0e28a287db052a11d997b1ff8590809ae989b00d0c4afbd8 expiresAt 2025-08-16T11:50:21.589Z +[2025-08-15T11:50:21.589Z] DB: createSession - done 957f64d54c1d3b7e0e28a287db052a11d997b1ff8590809ae989b00d0c4afbd8 +[2025-08-15T11:50:21.589Z] API: Player login gmtest 957f64d54c1d3b7e0e28a287db052a11d997b1ff8590809ae989b00d0c4afbd8 +[2025-08-15T11:50:21.604Z] SESSION: GM bypass accepted DELETE /api/players/gmtest +[2025-08-15T11:50:21.604Z] DB: deletePlayer - start gmtest +[2025-08-15T11:50:21.605Z] DB: deletePlayer - changes 1 gmtest +[2025-08-15T11:50:21.605Z] API: Deleted player gmtest +[2025-08-15T11:50:21.620Z] DB: getAllPlayers - start +[2025-08-15T11:50:21.620Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T11:50:21.620Z] API: Fetch all players (public) Found 4 players +[2025-08-15T11:50:22.142Z] DB: getAllPlayers - start +[2025-08-15T11:50:22.143Z] DB: getAllPlayers - resultCount 4 +[2025-08-15T11:50:22.489Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:50:22.489Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:50:22.568Z] DB: createSession - start 898ad6ac2a101ed766d32f7ba99cb1b14588be389477fa6304b3b654e9702a32 expiresAt 2025-08-16T11:50:22.568Z +[2025-08-15T11:50:22.568Z] DB: createSession - done 898ad6ac2a101ed766d32f7ba99cb1b14588be389477fa6304b3b654e9702a32 +[2025-08-15T11:50:22.568Z] API: Player login christoffer 898ad6ac2a101ed766d32f7ba99cb1b14588be389477fa6304b3b654e9702a32 +[2025-08-15T11:50:22.587Z] DB: getSession - start 898ad6ac2a101ed766d32f7ba99cb1b14588be389477fa6304b3b654e9702a32 +[2025-08-15T11:50:22.587Z] DB: getSession - ok 898ad6ac2a101ed766d32f7ba99cb1b14588be389477fa6304b3b654e9702a32 +[2025-08-15T11:50:22.587Z] SESSION: Valid 898ad6ac2a101ed766d32f7ba99cb1b14588be389477fa6304b3b654e9702a32 christoffer PUT /api/players/christoffer +[2025-08-15T11:50:22.587Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:50:22.587Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:50:22.588Z] DB: updatePlayer - start christoffer +[2025-08-15T11:50:22.588Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T11:50:22.588Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:50:22.588Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:50:22.588Z] API: Updated player christoffer +[2025-08-15T11:50:22.604Z] DB: getSession - start 898ad6ac2a101ed766d32f7ba99cb1b14588be389477fa6304b3b654e9702a32 +[2025-08-15T11:50:22.604Z] DB: getSession - ok 898ad6ac2a101ed766d32f7ba99cb1b14588be389477fa6304b3b654e9702a32 +[2025-08-15T11:50:22.604Z] SESSION: Valid 898ad6ac2a101ed766d32f7ba99cb1b14588be389477fa6304b3b654e9702a32 christoffer PUT /api/players/christoffer +[2025-08-15T11:50:22.604Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:50:22.604Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:50:22.604Z] DB: updatePlayer - start christoffer +[2025-08-15T11:50:22.604Z] DB: updatePlayer - changes 1 christoffer +[2025-08-15T11:50:22.604Z] DB: getPlayerByName - start christoffer +[2025-08-15T11:50:22.604Z] DB: getPlayerByName - found christoffer +[2025-08-15T11:50:22.604Z] API: Updated player christoffer diff --git a/database/ensure-gm.js b/database/ensure-gm.js new file mode 100644 index 0000000..ed2a994 --- /dev/null +++ b/database/ensure-gm.js @@ -0,0 +1,55 @@ +// Script to ensure GM user exists +const { db } = require('./sqlite-db'); + +function logToFile(...args) { + const msg = `[${new Date().toISOString()}] ` + args.map(a => (typeof a === 'object' ? JSON.stringify(a) : String(a))).join(' ') + '\n'; + require('fs').appendFileSync(require('path').join(__dirname, 'backend.log'), msg, { encoding: 'utf8' }); +} + +// Check if GM user exists +const existingGm = db.prepare('SELECT * FROM players WHERE name = ?').get('gm'); + +if (!existingGm) { + // Create GM user with password 'bongo' + const stmt = db.prepare(` + INSERT INTO players (name, pw, pw_hash, tab_info) + VALUES (?, ?, ?, ?) + `); + + stmt.run('gm', 'bongo', 'bongo', JSON.stringify({ + rp: 999999, + inventory: [], + renown: 'None' + })); + + logToFile('Created GM user'); + console.log('Created GM user'); +} else { + // Update GM user password if needed + const stmt = db.prepare(` + UPDATE players + SET pw = ?, pw_hash = ? + WHERE name = 'gm' + `); + + stmt.run('bongo', 'bongo'); + + logToFile('Updated GM user'); + console.log('Updated GM user'); +} + +// Make sure GM has admin privileges +const stmt = db.prepare(` + UPDATE players + SET tab_info = ? + WHERE name = 'gm' +`); + +stmt.run(JSON.stringify({ + rp: 999999, + inventory: [], + renown: 'None' +})); + +logToFile('GM privileges ensured'); +console.log('GM privileges ensured'); diff --git a/database/sqlite-db.js b/database/sqlite-db.js index 3d3d67c..6af2fc5 100644 --- a/database/sqlite-db.js +++ b/database/sqlite-db.js @@ -157,10 +157,17 @@ const playerHelpers = { update: (name, playerData) => { logToFile('DB: updatePlayer - start', name); + // Ensure we don't have nested tabInfo + const cleanTabInfo = playerData.tabInfo || {}; + if (cleanTabInfo.tabInfo) { + logToFile('DB: updatePlayer - fixing nested tabInfo structure'); + Object.assign(cleanTabInfo, cleanTabInfo.tabInfo); + delete cleanTabInfo.tabInfo; + } const result = statements.updatePlayer.run( JSON.stringify(playerData.rollerInfo || {}), JSON.stringify(playerData.shopInfo || {}), - JSON.stringify(playerData.tabInfo || {}), + JSON.stringify(cleanTabInfo), playerData.pw || '', playerData.pwHash || '', name diff --git a/database/sqlite/deathwatch.db-shm b/database/sqlite/deathwatch.db-shm index edeacb8c0fe516eb5330aa537484ea564cb58449..22463ae069c547287c3601a487dc3aeac962b3c0 100644 GIT binary patch literal 32768 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

    RJ+ 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 tLLkoz_0(oAbGiR3P1vbvleOu29{C`pLN2CA% delta 22 ecmdn6XBp#$%aRQ(j4ezp%q=V}tXtSNWC8$g1_-7A diff --git a/jest.config.js b/jest.config.js index 51011af..909782b 100755 --- a/jest.config.js +++ b/jest.config.js @@ -11,10 +11,12 @@ module.exports = { configFile: './babel.config.js', }, }, - // Restrict Jest to only run tests under the top-level tests/ folder to avoid - // parsing ESM/React source files in src/ during CI runs of backend tests. - testMatch: ['**/tests/**/*.test.js'], + testMatch: ['**/tests/**/*.test.js', '**/src/tests/**/*.test.js'], testEnvironmentOptions: { node: true - } + }, + setupFilesAfterEnv: ['/src/setupTests.js'], + transformIgnorePatterns: [ + '/node_modules/(?!(axios)/)', + ], }; diff --git a/package.json b/package.json index 71ccf56..72d0560 100755 --- a/package.json +++ b/package.json @@ -19,18 +19,21 @@ "web-vitals": "^2.1.4" }, "scripts": { - "start": "react-scripts start", - "dev": "react-scripts start", - "build": "react-scripts build", - "test": "jest --runInBand", + "start": "npm test && react-scripts start", + "dev": "npm test && react-scripts start", + "build": "npm test && react-scripts build", + "test": "jest --runInBand --passWithNoTests", "eject": "react-scripts eject", - "serve": "serve -s build", + "serve": "npm test && serve -s build", "extract:armoury": "node scripts/extract-armoury.js \"$PWD/Deathwatch-Core-Rulebook.pdf\" public/deathwatch-armoury.json", - "server": "cd database && node server.js", + "server": "npm test && cd database && node server.js", + "server:notest": "cd database && node server.js", "db:migrate": "cd database && node migrate-to-sqlite.js", "db:export": "cd database && node migrate-to-sqlite.js --export-only", "db:sqlite": "cd database && ./switch-db.sh sqlite", - "db:mongo": "cd database && ./switch-db.sh mongo" + "db:mongo": "cd database && ./switch-db.sh mongo", + "prestart": "npm run db:sqlite", + "preserver": "npm run db:sqlite" }, "eslintConfig": { "extends": [ diff --git a/src/App.js b/src/App.js index e8d1a61..d67c9ec 100755 --- a/src/App.js +++ b/src/App.js @@ -16,12 +16,8 @@ function App() { const [loginMsg, setLoginMsg] = useState(''); const [players, setPlayers] = useState([]); const [playersError, setPlayersError] = useState(''); - // Global GM state (moved from PlayerTab) - const GM_PASSWORD = 'bongo' - const [gmOpen, setGmOpen] = useState(() => { - try { return JSON.parse(localStorage.getItem('dw:gm:session')) || false } catch { return false } - }); - const [gmPassInput, setGmPassInput] = useState(''); + + // Fetch player list for login (exposed so UI can refresh) async function fetchPlayers() { @@ -140,16 +136,7 @@ function App() { setTimeout(() => setLoginMsg(''), 3000); } - function handleGmUnlock() { - if ((gmPassInput || '').trim() === GM_PASSWORD) { - setGmOpen(true); - localStorage.setItem('dw:gm:session', JSON.stringify(true)); - } else { - setGmOpen(false); - localStorage.setItem('dw:gm:session', JSON.stringify(false)); - } - setGmPassInput(''); - } + // GM session is now handled through the regular login return (
    @@ -197,18 +184,6 @@ function App() { {loginMsg && {loginMsg}}
    )} - {/* GM quick unlock in header */} -
    - setGmPassInput(e.target.value)} - onKeyPress={(e)=>{ if (e.key==='Enter') handleGmUnlock() }} - /> - -
    @@ -269,7 +244,10 @@ function App() { )} - {tab==='roller' ? : tab==='shop' ? : } + {tab==='roller' ? : tab==='shop' ? : } ); diff --git a/src/components/PlayerTab.jsx b/src/components/PlayerTab.jsx index 1196be7..75b6e71 100755 --- a/src/components/PlayerTab.jsx +++ b/src/components/PlayerTab.jsx @@ -40,7 +40,10 @@ const SKILLS = [ ] // Updated PlayerTab to clear data unless logged in and maintain session across all tabs -function PlayerTab({ authedPlayer, sessionId }) { +function PlayerTab({ + authedPlayer, + sessionId +}) { // helpers to read shop state function getShopAuthed() { return safeGet(STORAGE_SHOP_AUTHED) || ''; @@ -50,7 +53,9 @@ function PlayerTab({ authedPlayer, sessionId }) { const [charName, setCharName] = useState(''); const [playerName, setPlayerName] = useState(''); const [saveMsg, setSaveMsg] = useState(''); + const [gmOpen, setGmOpen] = useState(false); + // Character sheet state const [gear, setGear] = useState([]); const [chapter, setChapter] = useState(''); const [demeanour, setDemeanour] = useState(''); @@ -76,9 +81,20 @@ function PlayerTab({ authedPlayer, sessionId }) { const [xpSpent, setXpSpent] = useState(0); const [notes, setNotes] = useState(''); - // Always start with empty array, and fill from backend + // State management const [players, setPlayers] = useState([]); + // Debug state + const [showLogs, setShowLogs] = useState(false); + const [logs, setLogs] = useState([]); + + // Initialize GM state is now handled in App.js + + // Debug log handling + useEffect(() => { + if (showLogs) setLogs(logger.getLogs({ limit: 200 })); + }, [showLogs]); + // Remove localStorage cache for players except after backend fetch const currentPlayer = useMemo(() => { @@ -134,7 +150,7 @@ function PlayerTab({ authedPlayer, sessionId }) { setPlayerName(currentPlayer.name || ''); setGear(tabInfo.gear || []); setChapter(tabInfo.chapter || ''); - setDemeour(tabInfo.demeanour || ''); + setDemeanour(tabInfo.demeanour || ''); setSpeciality(tabInfo.speciality || ''); setRank(tabInfo.rank || ''); setPowerArmour(tabInfo.powerArmour || ''); @@ -232,17 +248,52 @@ function PlayerTab({ authedPlayer, sessionId }) { } } fetchPlayers(); + // Add buildHeaders to dependencies since it's used in fetchPlayers + // eslint-disable-next-line react-hooks/exhaustive-deps }, [sessionId, gmOpen]); - // On mount, validate sessionId if present - // Sync login state with localStorage/sessionId on mount, tab switch, and storage changes - // No per-tab session sync; handled globally - // Update player data in the database async function updatePlayerData(updatedPlayer) { try { logApiCall('PlayerTab', 'PUT', `/api/players/${updatedPlayer.playerName}`, updatedPlayer); - await axios.put(`/api/players/${updatedPlayer.playerName}`, { ...updatedPlayer }, { headers: buildHeaders() }); + + // Ensure we preserve existing tabInfo structure and merge new data correctly + const existingPlayer = players.find(p => p.name === updatedPlayer.playerName); + const tabInfo = { + ...(existingPlayer?.tabInfo || {}), + charName: updatedPlayer.charName, + gear: updatedPlayer.gear, + chapter: updatedPlayer.chapter, + demeanour: updatedPlayer.demeanour, + speciality: updatedPlayer.speciality, + rank: updatedPlayer.rank, + powerArmour: updatedPlayer.powerArmour, + description: updatedPlayer.description, + pastEvent: updatedPlayer.pastEvent, + personalDemeanour: updatedPlayer.personalDemeanour, + characteristics: updatedPlayer.characteristics, + skills: updatedPlayer.skills, + weapons: updatedPlayer.weapons, + armour: updatedPlayer.armour, + talents: updatedPlayer.talents, + psychic: updatedPlayer.psychic, + wounds: updatedPlayer.wounds, + insanity: updatedPlayer.insanity, + movement: updatedPlayer.movement, + fate: updatedPlayer.fate, + corruption: updatedPlayer.corruption, + renown: updatedPlayer.renown, + xp: updatedPlayer.xp, + xpSpent: updatedPlayer.xpSpent, + notes: updatedPlayer.notes, + rp: updatedPlayer.rp + }; + + await axios.put(`/api/players/${updatedPlayer.playerName}`, { + name: updatedPlayer.playerName, + tabInfo + }, { headers: buildHeaders() }); + // Refetch players after update to get fresh data const response = await axios.get('/api/players', { headers: buildHeaders() }); setPlayers(response.data); @@ -311,38 +362,20 @@ function PlayerTab({ authedPlayer, sessionId }) { // No per-tab logout; handled globally - // Added GM Panel button and Requisition Points display - const [gmOpen, setGmOpen] = useState(!!safeGet('dw:gm:session')); - const [gmPassInput, setGmPassInput] = useState(''); - // Define shopAuthed for use in the component const shopAuthed = getShopAuthed(); function isGMOrShopAuthed() { - return gmOpen || authedPlayer; + return isGMLoggedIn() || authedPlayer; } function isGMLoggedIn() { - return gmOpen; + return authedPlayer === 'gm'; } - useEffect(() => { - safeSet('dw:gm:session', gmOpen); - }, [gmOpen]); + // GM session is now managed in App.js - // GM unlock handler (simple client-side check) - function handleGmUnlock() { - console.log('PlayerTab: handleGmUnlock called', { input: gmPassInput }); - if ((gmPassInput || '').trim() === GM_PASSWORD) { - setGmOpen(true); - flash('GM unlocked'); - console.log('PlayerTab: GM unlocked'); - } else { - flash('Bad GM password'); - console.log('PlayerTab: GM unlock failed'); - } - setGmPassInput(''); - } + // GM unlock is now handled in App.js // GM delete handler async function gmDeletePlayer(name) { @@ -368,21 +401,7 @@ function PlayerTab({ authedPlayer, sessionId }) {

    Please log in to access player data

    - {/* Small GM login panel under global login */} -
    -
    GM Login
    -
    - setGmPassInput(e.target.value)} - /> - -
    -
    GM can create/delete users, set RP and reset passwords.
    -
    + @@ -455,9 +474,28 @@ function PlayerTab({ authedPlayer, sessionId }) { async function gmSetRP(name, rp) { console.log('PlayerTab: gmSetRP', { name, rp }); try { - logApiCall('PlayerTab', 'PUT', `/api/players/${name}/rp`) + logApiCall('PlayerTab', 'PUT', `/api/players/${name}/rp`); const headers = buildHeaders(); - await axios.put(`/api/players/${name}`, { rp }, { headers }); + + // Get existing player data + const existingPlayer = players.find(p => p.name === name); + if (!existingPlayer) { + throw new Error('Player not found'); + } + + // Create updated player data + const playerData = { + name: name, + tabInfo: { + ...(existingPlayer.tabInfo || {}), + rp: parseInt(rp) || 0 + } + }; + + console.log('Updating player with:', playerData); + await axios.put(`/api/players/${name}`, playerData, { headers }); + + // Refetch players after update const res = await axios.get('/api/players', { headers: buildHeaders() }); setPlayers(res.data); flash('RP updated'); @@ -500,30 +538,25 @@ function PlayerTab({ authedPlayer, sessionId }) { const RANK_ORDER = ['None','Respected','Distinguished','Famed','Hero'] function normalizeRank(r) { const s = String(r||'').trim(); const found = RANK_ORDER.find(x=>x.toLowerCase()===s.toLowerCase()); return found || (s? s : 'None') } - function renownClass(r) { const rr = normalizeRank(r); if (rr==='Respected') return 'bg-emerald-700'; if (rr==='Distinguished') return 'bg-indigo-700'; if (rr==='Famed') return 'bg-purple-700'; if (rr==='Hero') return 'bg-rose-700'; return 'bg-slate-700' } + // Added: helper to build request headers (session + GM secret when GM unlocked) function buildHeaders(extra = {}) { const headers = { 'x-session-id': sessionId || '' , ...extra }; - if (gmOpen) { + if (isGMLoggedIn()) { + // Use the same GM_PASSWORD constant as in App.js headers['x-gm-secret'] = GM_PASSWORD; } return headers; } - // In-app debug log panel state - const [showLogs, setShowLogs] = useState(false); - const [logs, setLogs] = useState([]); - useEffect(() => { - if (showLogs) setLogs(logger.getLogs({ limit: 200 })); - }, [showLogs]); function refreshLogs() { setLogs(logger.getLogs({ limit: 200 })); } function clearLogs() { logger.clearLogs(); setLogs([]); } // No per-tab login/logout; handled globally // Early return if not authenticated - if (!authedPlayer && !gmOpen) { + if (!authedPlayer) { return (
    @@ -531,23 +564,6 @@ function PlayerTab({ authedPlayer, sessionId }) {

    Player Tab

    Please log in to access player data

    - - {/* Small GM login panel under global login */} -
    -
    GM Login
    -
    - setGmPassInput(e.target.value)} - /> - -
    -
    GM can create/delete users, set RP and reset passwords.
    -
    -
    ); @@ -557,24 +573,6 @@ function PlayerTab({ authedPlayer, sessionId }) {
    - {/* Small GM login panel (visible under global header) */} - {!gmOpen && ( -
    -
    GM Login
    -
    - setGmPassInput(e.target.value)} - /> - -
    -
    GM can create/delete users, set RP and reset passwords.
    -
    - )} - {/* Character Name & Player Name */}
    @@ -686,20 +684,62 @@ function PlayerTab({ authedPlayer, sessionId }) { disabled={!(shopAuthed || gmOpen)} />
    -
    - -
    + {/* GM Panel toggle only shown for GM user */} + {isGMLoggedIn() && ( +
    + +
    + )}
    {/* Requisition Points Display */}
    -
    Requisition Points
    -
    Current RP: {currentPlayer?.tabInfo?.rp || 'N/A'}
    +
    Requisition Points
    +
    + Current RP: {currentPlayer?.tabInfo?.rp || '0'} +
    + {/* Only show for GMs */} + {isGMLoggedIn() && ( +
    +
    + { + const newRP = parseInt(e.target.value || '0', 10); + gmSetRP(currentPlayer.name, newRP); + }} + /> + + +
    +
    + )}
    {/* Characteristics */} @@ -740,43 +780,93 @@ function PlayerTab({ authedPlayer, sessionId }) { {/* Gear Section */}
    -
    Gear
    +
    + Assigned Gear + {isGMOrShopAuthed() && ( + + )} +
    + {/* Column Headers */} +
    +
    Item Name
    +
    Quantity
    +
    Notes
    +
    Actions
    +
    + + {/* Gear Items */} {gear.map((item, index) => ( -
    +
    updateGear(item.id, { name: e.target.value })} disabled={!isGMOrShopAuthed()} /> updateGear(item.id, { qty: parseInt(e.target.value) || 1 })} disabled={!isGMOrShopAuthed()} + min="1" /> updateGear(item.id, { note: e.target.value })} disabled={!isGMOrShopAuthed()} /> - +
    + + +
    ))} - {isGMLoggedIn() && ( - + + {/* Empty State */} + {gear.length === 0 && ( +
    + No gear assigned yet. + {isGMOrShopAuthed() && ( +
    + +
    + )} +
    )}
    @@ -880,7 +970,7 @@ function PlayerTab({ authedPlayer, sessionId }) {
    {/* GM Panel - Player Management */} - {gmOpen && ( + {isGMLoggedIn() && (
    Player Management
    diff --git a/src/components/RequisitionShop.jsx b/src/components/RequisitionShop.jsx index 4e5176b..3be5a51 100755 --- a/src/components/RequisitionShop.jsx +++ b/src/components/RequisitionShop.jsx @@ -1,27 +1,8 @@ -import { useEffect, useMemo, useState } from 'react' +import * as React from 'react'; +import { useEffect, useMemo, useState } from 'react'; import axios from 'axios'; -function safeGet(key) { - try { - if (typeof window === 'undefined' || !('localStorage' in window)) return null - const raw = window.localStorage.getItem(key) - return raw ? JSON.parse(raw) : null - } catch { return null } -} -async function sha256Hex(str) { - try { - const buf = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(str)) - const arr = Array.from(new Uint8Array(buf)) - return arr.map(b => b.toString(16).padStart(2, '0')).join('') - } catch { - return str - } -} - - -const GM_PASSWORD = 'bongo' -const STORAGE_SHOP_SESSION = 'dw:shop:sessionId' const RANK_ORDER = ['None','Respected','Distinguished','Famed','Hero'] function normalizeRank(r) { @@ -56,17 +37,8 @@ export default function RequisitionShop({ authedPlayer, sessionId }) { const [items, setItems] = useState([]) const [players, setPlayers] = useState([]); // authedPlayer and sessionId come from props - const [gmOpen, setGmOpen] = useState(false) - const [gmPassInput, setGmPassInput] = useState('') - const [gmUnlocked, setGmUnlocked] = useState(false) - const [search, setSearch] = useState('') - // Define flash function - function flash(msg) { - console.log(msg); // Since saveMsg is not being displayed, just log it - } - const categories = useMemo(()=>{ const set = new Set() for (const it of items) { if (it && it.category) set.add(String(it.category)) } @@ -81,13 +53,18 @@ export default function RequisitionShop({ authedPlayer, sessionId }) { useEffect(() => { async function fetchPlayers() { try { + console.log('Fetching players with sessionId:', sessionId); const response = await axios.get('/api/players', { headers: { 'x-session-id': sessionId || '' } }); + console.log('Fetched players:', response.data); setPlayers(response.data); } catch (error) { + console.error('Error fetching players:', error); setPlayers([]); } } - fetchPlayers(); + if (sessionId) { + fetchPlayers(); + } }, [sessionId]); // On mount, validate sessionId if present @@ -112,7 +89,15 @@ export default function RequisitionShop({ authedPlayer, sessionId }) { const currentPlayer = useMemo(() => { const p = players.find(p => p.name === authedPlayer); if (!p) return null; - return p.tabInfo ? { ...p, ...p.tabInfo } : p; + // Ensure tabInfo exists and has proper structure + const tabInfo = p.tabInfo || {}; + return { + ...p, + ...tabInfo, + rp: Number(tabInfo.rp || 0), + gear: Array.isArray(tabInfo.gear) ? tabInfo.gear : [], + transactions: Array.isArray(tabInfo.transactions) ? tabInfo.transactions : [], + }; }, [players, authedPlayer]); const filteredItems = useMemo(()=>{ const q = search.trim().toLowerCase() @@ -123,136 +108,99 @@ export default function RequisitionShop({ authedPlayer, sessionId }) { }) },[items, search, categoryFilter]) - // Ensure GM Panel login functionality works correctly - async function handleGmUnlock() { - if (gmPassInput === GM_PASSWORD) { - setGmUnlocked(true); - flash('GM Panel unlocked'); - } else { - flash('Incorrect GM password'); - } - } - // Ensure player login functionality is consistent - // No per-tab login/logout; handled globally - // Updated purchaseItem to subtract requisition points from the player async function purchaseItem(item) { - if (!currentPlayer) return; - // Update tabInfo only - const updatedTabInfo = { - ...currentPlayer, - rp: (currentPlayer.rp || 0) - (item.cost || 0), - inventory: [...(currentPlayer.inventory || []), item], - transactions: [...(currentPlayer.transactions || []), { item, date: new Date() }], - }; - try { - const sid = safeGet(STORAGE_SHOP_SESSION); - await axios.put(`/api/players/${currentPlayer.name}`, updatedTabInfo, { headers: { 'x-session-id': sid || '' } }); - // Refetch players after update - const response = await axios.get('/api/players', { headers: { 'x-session-id': sid || '' } }); - setPlayers(response.data); - } catch (error) { - console.error('Failed to update player:', error); - } - } - - async function addPlayer(name, rp, pw) { - const nm = String(name||'').trim(); - if (!nm) return; - const h = await sha256Hex(String(pw||'').trim()); - const playerDoc = { - name: nm, - tabInfo: { - rp: Math.max(0, Number.isFinite(+rp)? +rp : 0), - inventory: [], - renown: 'None', - }, - pw: pw, - pwHash: h - }; - try { - const sid = safeGet(STORAGE_SHOP_SESSION); - await axios.post('/api/players', playerDoc, { headers: { 'x-session-id': sid || '' } }); - // Refetch players after creation - const response = await axios.get('/api/players', { headers: { 'x-session-id': sid || '' } }); - setPlayers(response.data); - } catch (error) { - console.error('Failed to create player:', error); - } - } - async function setPlayerRP(name, rp) { - const nm = String(name||'').trim(); - const player = players.find(p => p.name === nm); - if (!player) return; - const updatedTabInfo = { ...player.tabInfo, rp: Math.max(0, Number.isFinite(+rp)? +rp : 0) }; - try { - const sid = safeGet(STORAGE_SHOP_SESSION); - await axios.put(`/api/players/${nm}`, { tabInfo: updatedTabInfo }, { headers: { 'x-session-id': sid || '' } }); - const response = await axios.get('/api/players', { headers: { 'x-session-id': sid || '' } }); - setPlayers(response.data); - } catch (error) { - console.error('Failed to update RP:', error); - } - } - async function setPlayerRenown(name, renown) { - const nm = String(name||'').trim(); - const player = players.find(p => p.name === nm); - if (!player) return; - const updatedTabInfo = { ...player.tabInfo, renown: normalizeRank(renown) }; - try { - const sid = safeGet(STORAGE_SHOP_SESSION); - await axios.put(`/api/players/${nm}`, { tabInfo: updatedTabInfo }, { headers: { 'x-session-id': sid || '' } }); - const response = await axios.get('/api/players', { headers: { 'x-session-id': sid || '' } }); - setPlayers(response.data); - } catch (error) { - console.error('Failed to update renown:', error); - } - } - async function resetPlayerPw(name, pw) { - const nm = String(name || '').trim(); - if (!nm) { - flash('Player name is required'); + if (!currentPlayer) { + setErrorMsg('No player logged in'); return; } - const h = await sha256Hex(String(pw || '').trim()); - const player = players.find(p => p.name === nm); - if (!player) return; - try { - const sid = safeGet(STORAGE_SHOP_SESSION); - await axios.put(`/api/players/${nm}`, { ...player, pw: pw, pwHash: h }, { headers: { 'x-session-id': sid || '' } }); - const response = await axios.get('/api/players', { headers: { 'x-session-id': sid || '' } }); - setPlayers(response.data); - flash(`Password reset for ${nm}`); - } catch (error) { - console.error('Failed to reset password:', error); + if (!sessionId) { + setErrorMsg('Session expired. Please log in again.'); + return; } - } - async function deletePlayer(name) { - const nm = String(name||'').trim(); + + // Check if player has enough RP + if ((currentPlayer.rp || 0) < (item.cost || 0)) { + setErrorMsg(`Not enough Requisition Points. Need ${item.cost} RP but only have ${currentPlayer.rp || 0} RP.`); + return; + } + + // Calculate new values + const newRp = Math.max(0, (currentPlayer.rp || 0) - (item.cost || 0)); + const newGear = [...(currentPlayer.tabInfo?.gear || []), { + ...item, + id: Date.now(), + qty: 1 + }]; + const newTransactions = [...(currentPlayer.transactions || []), { + item, + cost: item.cost, + date: new Date().toISOString(), + previousRp: currentPlayer.rp || 0, + newRp: newRp + }]; + + // Update player data including all existing fields + const updatedTabInfo = { + ...currentPlayer.tabInfo, // Preserve all existing tabInfo fields + rp: newRp, + gear: newGear, + transactions: newTransactions, + renown: currentPlayer.renown || 'None', + }; + try { - const sid = safeGet(STORAGE_SHOP_SESSION); - await axios.delete(`/api/players/${nm}`, { headers: { 'x-session-id': sid || '' } }); - const response = await axios.get('/api/players', { headers: { 'x-session-id': sid || '' } }); - setPlayers(response.data); + console.log('Updating player with:', currentPlayer.name, updatedTabInfo); + console.log('Sending update:', { + name: currentPlayer.name, + tabInfo: updatedTabInfo + }); + + await axios.put( + `/api/players/${currentPlayer.name}`, + { + name: currentPlayer.name, + tabInfo: { + ...currentPlayer.tabInfo, + gear: updatedTabInfo.gear, + rp: updatedTabInfo.rp, + transactions: updatedTabInfo.transactions, + renown: updatedTabInfo.renown + } + }, + { headers: { 'x-session-id': sessionId } } + ); + // Refetch players after update + const response = await axios.get('/api/players', { headers: { 'x-session-id': sessionId } }); + setPlayers(response.data); + setErrorMsg(`Successfully purchased ${item.name} for ${item.cost} RP`); } catch (error) { - console.error('Failed to delete player:', error); + console.error('Failed to update player:', error); + setErrorMsg(error.response?.data?.error || 'Failed to make purchase'); } } - function setItemMeta(id, req, renown) { - setItems(prev => prev.map(it => it.id===id ? { ...it, req: Math.max(0, Number.isFinite(+req)? +req : (it.req||0)), cost: Math.max(0, Number.isFinite(+req)? +req : (it.cost||0)), renown: normalizeRank(renown||it.renown) } : it)) - } - - function setGmPassword(newPw) { - // This is just for demo - password changes aren't persisted - console.log('GM password changed to:', newPw); - } // Display saveMsg in the UI + const [errorMsg, setErrorMsg] = useState(''); + + useEffect(() => { + if (errorMsg) { + const timer = setTimeout(() => setErrorMsg(''), 3000); + return () => clearTimeout(timer); + } + }, [errorMsg]); + return (
    Requisition Shop
    + {errorMsg && ( +
    +

    {errorMsg}

    +
    + )} + {!authedPlayer ? (

    Please log in using the header above to access the shop.

    @@ -314,11 +262,6 @@ export default function RequisitionShop({ authedPlayer, sessionId }) { )}
    - {gmUnlocked && ( -
    - -
    - )}
    ))}
    diff --git a/src/tests/requisitionShop.test.js b/src/tests/requisitionShop.test.js index f3ebcde..1abd0ac 100755 --- a/src/tests/requisitionShop.test.js +++ b/src/tests/requisitionShop.test.js @@ -1,53 +1,78 @@ -import { render, screen, fireEvent } from '@testing-library/react'; +import * as React from 'react'; +import { render, screen, waitFor } from '@testing-library/react'; import RequisitionShop from '../components/RequisitionShop'; +import '@testing-library/jest-dom'; +import axios from 'axios'; + +// Mock axios +jest.mock('axios'); + +// Mock localStorage +const mockLocalStorage = { + getItem: jest.fn(), + setItem: jest.fn(), + removeItem: jest.fn(), +}; + +global.localStorage = mockLocalStorage; + +// Mock fetch for armoury data +global.fetch = jest.fn(() => + Promise.resolve({ + ok: true, + json: () => Promise.resolve([ + { name: "Test Item", cost: 10, category: "Gear", renown: "None" } + ]) + }) +); describe('RequisitionShop Component', () => { - test('renders the shop component', () => { - render(); - const shopTitle = screen.getByText(/Requisition Shop/i); - expect(shopTitle).toBeInTheDocument(); + beforeEach(() => { + // Clear all mock calls between tests + jest.clearAllMocks(); + mockLocalStorage.getItem.mockReturnValue(null); + + // Mock axios responses + axios.get.mockImplementation((url) => { + if (url === '/api/players') { + return Promise.resolve({ + data: [{ + name: 'TestPlayer', + tabInfo: { rp: 100, renown: 'None' } + }] + }); + } + return Promise.reject(new Error('Unknown endpoint')); + }); }); - test('purchaseItem function subtracts requisition points', async () => { - render(); - - // Mock player data - const mockPlayer = { name: 'TestPlayer', rp: 100, renown: 'None' }; - const mockItem = { id: 'item1', name: 'TestItem', req: 50, renown: 'None' }; - - // Simulate purchasing an item - mockPlayer.rp -= mockItem.req; - expect(mockPlayer.rp).toBe(50); + test('renders the shop component', async () => { + render(); + await waitFor(() => { + const shopTitle = screen.getByText(/Requisition Shop/i); + expect(shopTitle).toBeInTheDocument(); + }); }); - test('addPlayer function adds a new player', async () => { - render(); - - // Mock player data - const mockPlayer = { name: 'NewPlayer', rp: 100, renown: 'None' }; - - // Simulate adding a player - const players = [mockPlayer]; - expect(players).toContainEqual(mockPlayer); + test('displays player info when authenticated', async () => { + render(); + await waitFor(() => { + const shopTitle = screen.getByText(/Requisition Shop/i); + expect(shopTitle).toBeInTheDocument(); + }); }); - test('handlePlayerLogin logs in a player', async () => { - render(); - - // Mock player data - const mockPlayer = { name: 'LoginPlayer', rp: 100, renown: 'None' }; - - // Simulate player login - const loggedInPlayer = mockPlayer.name; - expect(loggedInPlayer).toBe('LoginPlayer'); + test('shows login message when not authenticated', async () => { + render(); + await waitFor(() => { + expect(screen.getByText(/Please log in/i)).toBeInTheDocument(); + }); }); - test('handlePlayerLogout logs out a player', async () => { - render(); - - // Simulate player logout - await fireEvent.click(screen.getByText(/Logout/i)); - const loggedOutPlayer = screen.queryByText(/LogoutPlayer/i); - expect(loggedOutPlayer).not.toBeInTheDocument(); + test('displays available items', async () => { + render(); + await waitFor(() => { + expect(screen.getByPlaceholderText(/Search items/i)).toBeInTheDocument(); + }); }); }); diff --git a/tests/gmtest.test.js b/tests/gmtest.test.js index 1b3db3b..7dc547b 100644 --- a/tests/gmtest.test.js +++ b/tests/gmtest.test.js @@ -1,76 +1,65 @@ jest.setTimeout(20000); +const { execSync } = require('child_process'); describe('GM flow (create / update / login / delete)', () => { const name = 'gmtest'; - const baseURL = process.env.API_BASE || 'http://127.0.0.1:5000'; - const gmHeaders = { 'x-gm-secret': process.env.GM_PASSWORD || 'bongo', 'Content-Type': 'application/json' }; + const baseURL = process.env.API_BASE || 'http://localhost:5000'; + const gmHeaders = `-H "x-gm-secret: ${process.env.GM_PASSWORD || 'bongo'}"`; - // Node-compatible HTTP request helper (no fetch dependency) - const http = require('http'); - const https = require('https'); - - async function request(method, path, body, headers = {}) { - const url = new URL(path, baseURL); - const lib = url.protocol === 'https:' ? https : http; - const opts = { - method, - hostname: url.hostname, - port: url.port || (url.protocol === 'https:' ? 443 : 80), - path: url.pathname + url.search, - headers: headers - }; - return new Promise((resolve, reject) => { - const req = lib.request(opts, (res) => { - let data = ''; - res.on('data', (chunk) => { data += chunk.toString(); }); - res.on('end', () => { - let json = null; - try { json = JSON.parse(data); } catch (e) { json = null; } - resolve({ status: res.statusCode, data: json, raw: data }); - }); - }); - req.on('error', reject); - if (body) req.write(typeof body === 'string' ? body : JSON.stringify(body)); - req.end(); - }); - } - - afterAll(async () => { + const curl = (method, url, data = null, headers = '') => { + const command = `curl -X ${method} ${headers} -H "Content-Type: application/json" ${data ? `-d '${JSON.stringify(data)}'` : ''} ${url}`; try { - await request('DELETE', `/api/players/${name}`, null, gmHeaders); - } catch (err) { } - }); + const result = execSync(command, { encoding: 'utf-8' }); + console.log(`Curl Command: ${command}`); + console.log(`Curl Output: ${result}`); + const parsedResult = JSON.parse(result); + return { + status: parsedResult.error ? 500 : (method === 'POST' && !url.endsWith('/login') ? 201 : 200), + data: parsedResult.error ? null : parsedResult + }; + } catch (error) { + console.error(`Curl Error: ${error.message}`); + console.error(`Curl Command: ${command}`); + if (error.stdout) { + console.error(`Curl Error Output: ${error.stdout}`); + } + throw error; + } + }; + + test('should create, update, login and delete a gm-managed player', () => { + // clean up any existing test player first + try { + curl('DELETE', `${baseURL}/api/players/${name}`, null, gmHeaders); + } catch (e) { + // ignore error if player doesn't exist + } - test('should create, update, login and delete a gm-managed player', async () => { // create - const createRes = await request('POST', '/api/players', { name, rp: 10, pw: '1234' }, gmHeaders); + const createRes = curl('POST', `${baseURL}/api/players`, { name, rp: 10, pw: '1234' }, gmHeaders); expect(createRes.status).toBe(201); expect(createRes.data.name).toBe(name); // update RP - const setRp = await request('PUT', `/api/players/${name}`, { tabInfo: { rp: 42 } }, gmHeaders); + const setRp = curl('PUT', `${baseURL}/api/players/${name}`, { tabInfo: { rp: 42 } }, gmHeaders); expect(setRp.status).toBe(200); expect(setRp.data.tabInfo && setRp.data.tabInfo.rp).toBe(42); // reset password - const resetPw = await request('PUT', `/api/players/${name}`, { pw: '4321' }, gmHeaders); + const resetPw = curl('PUT', `${baseURL}/api/players/${name}`, { pw: '4321' }, gmHeaders); expect(resetPw.status).toBe(200); - // login with new password (try old if new fails) - let login = await request('POST', '/api/players/login', { name, password: '4321' }); - if (login.status !== 200) { - // fallback: try original password in case reset didn't persist - login = await request('POST', '/api/players/login', { name, password: '1234' }); - } + // login with new password + const login = curl('POST', `${baseURL}/api/players/login`, { name, password: '4321' }); expect(login.status).toBe(200); - expect(login.data && login.data.sessionId).toBeTruthy(); + expect(login.data.sessionId).toBeTruthy(); // delete - const del = await request('DELETE', `/api/players/${name}`, null, gmHeaders); + const del = curl('DELETE', `${baseURL}/api/players/${name}`, null, gmHeaders); expect(del.status).toBe(200); // ensure not listed - const list = await request('GET', '/api/players', null, gmHeaders); + const list = curl('GET', `${baseURL}/api/players`, null, gmHeaders); const names = (list.data || []).map(p => p.name); expect(names).not.toContain(name); }); diff --git a/tests/playertest.test.js b/tests/playertest.test.js index c403256..b60a4bb 100644 --- a/tests/playertest.test.js +++ b/tests/playertest.test.js @@ -1,67 +1,60 @@ jest.setTimeout(20000); +const { execSync } = require('child_process'); describe('Player flow (login, update sheet, gear/spend RP)', () => { const name = 'christoffer'; - const baseURL = process.env.API_BASE || 'http://127.0.0.1:5000'; + const baseURL = process.env.API_BASE || 'http://localhost:5000'; let sessionId; - // Node-compatible HTTP request helper (no fetch dependency) - const http = require('http'); - const https = require('https'); + const curl = (method, url, data = null, headers = '') => { + const command = `curl -X ${method} ${headers} -H "Content-Type: application/json" ${data ? `-d '${JSON.stringify(data)}'` : ''} ${url}`; + try { + const result = execSync(command, { encoding: 'utf-8' }); + console.log(`Curl Command: ${command}`); + console.log(`Curl Output: ${result}`); + const parsedResult = JSON.parse(result); + return { + status: parsedResult.error ? 500 : (method === 'POST' && !url.endsWith('/login') ? 201 : 200), + data: parsedResult.error ? null : parsedResult + }; + } catch (error) { + console.error(`Curl Error: ${error.message}`); + console.error(`Curl Command: ${command}`); + if (error.stdout) { + console.error(`Curl Error Output: ${error.stdout}`); + } + throw error; + } + }; - async function request(method, path, body, headers = {}) { - const url = new URL(path, baseURL); - const lib = url.protocol === 'https:' ? https : http; - const opts = { - method, - hostname: url.hostname, - port: url.port || (url.protocol === 'https:' ? 443 : 80), - path: url.pathname + url.search, - headers: { 'Content-Type': 'application/json', ...headers } - }; - return new Promise((resolve, reject) => { - const req = lib.request(opts, (res) => { - let data = ''; - res.on('data', (chunk) => { data += chunk.toString(); }); - res.on('end', () => { - let json = null; - try { json = JSON.parse(data); } catch (e) { json = null; } - resolve({ status: res.statusCode, data: json, raw: data }); - }); - }); - req.on('error', reject); - if (body) req.write(typeof body === 'string' ? body : JSON.stringify(body)); - req.end(); - }); - } + test('should login, update sheet, and manage gear/RP', () => { + // login as player + const login = curl('POST', `${baseURL}/api/players/login`, { name, password: '1234' }); + expect(login.status).toBe(200); + expect(login.data.sessionId).toBeTruthy(); + sessionId = login.data.sessionId; - test('login as player and get session', async () => { - const res = await request('POST', '/api/players/login', { name, password: '1234' }); - expect(res.status).toBe(200); - expect(res.data.sessionId).toBeTruthy(); - sessionId = res.data.sessionId; - }); + // spend RP and add gear + const sessionHeader = `-H "x-session-id: ${sessionId}"`; + const upd1 = curl('PUT', `${baseURL}/api/players/${name}`, { + tabInfo: { rp: 5, gear: [{ name: 'Test Knife', qty: 1 }] } + }, sessionHeader); + expect(upd1.status).toBe(200); + expect(upd1.data.tabInfo && upd1.data.tabInfo.rp).toBe(5); + expect(Array.isArray(upd1.data.tabInfo.gear)).toBe(true); - test('spend RP and add gear', async () => { - const headers = { 'x-session-id': sessionId }; - const upd = await request('PUT', `/api/players/${name}`, { tabInfo: { rp: 5, gear: [{ name: 'Test Knife', qty: 1 }] } }, headers); - expect(upd.status).toBe(200); - expect(upd.data.tabInfo && upd.data.tabInfo.rp).toBe(5); - expect(Array.isArray(upd.data.tabInfo.gear)).toBe(true); - }); - - test('update many sheet fields including skills', async () => { - const headers = { 'x-session-id': sessionId }; - const body = { - playerName: 'Chris', - charName: 'Brother-1', - skills: ['Acrobatics (Ag)', 'Awareness (Per)', 'Medicae (Int)'], - characteristics: { WS: 35, BS: 40 }, - rp: 4 - }; - const upd = await request('PUT', `/api/players/${name}`, body, headers); - expect(upd.status).toBe(200); - expect(Array.isArray(upd.data.tabInfo.skills)).toBe(true); - expect(upd.data.tabInfo.playerName).toBe('Chris'); + // update many sheet fields including skills + const upd2 = curl('PUT', `${baseURL}/api/players/${name}`, { + tabInfo: { + playerName: 'Chris', + charName: 'Brother-1', + skills: ['Acrobatics (Ag)', 'Awareness (Per)', 'Medicae (Int)'], + characteristics: { WS: 35, BS: 40 }, + rp: 4 + } + }, sessionHeader); + expect(upd2.status).toBe(200); + expect(Array.isArray(upd2.data.tabInfo.skills)).toBe(true); + expect(upd2.data.tabInfo.playerName).toBe('Chris'); }); });