From c6929c6baec7629bda567e6aa48a24458cc0de34 Mon Sep 17 00:00:00 2001 From: wtclaude Date: Mon, 17 Aug 2026 17:41:22 -0500 Subject: [PATCH] fix(teams): take `query` from the core facade, not a `core.db` that does not exist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Team provider's db layer built its query helper as `core.db.query(...)`. The facade has no `db` member -- every other *.db.js in this module destructures `query` from it directly -- so every call threw `Cannot read properties of undefined (reading 'query')`. The failure mode is the bad part. That throw is caught by the provider's own error handling and turned into `{ ok: false, reason: 'roster unreadable: …' }`, which is a perfectly valid refusal -- so core would have accepted it, held the projection it had, and reported staleness. A provider that answers correctly and never returns data, forever, with nothing in any log louder than a warning. Invisible to the unit tests because they stub every db function, so the helper was never called. Found by running a real roster frame through the ingest and then asking the provider what it saw, against the real database. Co-Authored-By: Claude --- server/model/teamProvider/teamProvider.db.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/server/model/teamProvider/teamProvider.db.js b/server/model/teamProvider/teamProvider.db.js index 49024cc..3608c26 100644 --- a/server/model/teamProvider/teamProvider.db.js +++ b/server/model/teamProvider/teamProvider.db.js @@ -5,9 +5,10 @@ // core-internal (docs/website/TEAMS.md §10.3) and this module must never name // one, even though it is what fills them. -const core = require('../../core') - -const query = (...args) => core.db.query(...args) +// `query` is destructured from the core facade at require time, like every other +// *.db.js here. The facade resolves `ctx` per call, so taking it now is safe even +// though `ctx` does not exist yet when this file is first required. +const { query } = require('../../core') /** * The guild board — one row per guild the shard has told us about.