Description
#385 wires the backfill modules to the database through globals:
// src/db.ts
;(globalThis as any).__lens_prisma = prisma
;(globalThis as any).__lens_pgPool = pgPool
// src/backfill/gaps.ts
function getPrisma() { return (globalThis as any).__lens_prisma }Why it was done this way, and it is a real constraint. src/backfill/gaps.ts must not import ../db at module load. Several suites mock ../config only partially, and importing db.ts evaluates config.db.url at load time — so an eager import makes unrelated tests fail with Cannot read properties of undefined (reading 'url'). The globals are a decoupling seam, not laziness.
Why it is still worth changing. src/db.ts runs in the API process, not just the CLI, so every request handler shares a process where a live Prisma client and pg pool are reachable as globalThis.__lens_prisma by any code at all — including a dependency that never imported them. It is also untyped on both ends, so a refactor of db.ts will not surface here.
What I tried and why it is not a quick fix. I attempted two versions while merging and reverted both:
- Importing the handles in
gaps.tswith the global as an override — breaks 6 suites on the load-timeconfig.db.urlevaluation described above. - Moving the installation into
scripts/backfill.tsand making the accessors throw when absent — breaks 33 suites, because the API routes reachgaps.tswithout installing anything.
So it needs a deliberate approach rather than an in-flight patch. Options worth weighing:
- Make
src/db.tslazy — build the client on first use rather than at module load — which removes the reason for the seam entirely and is probably the real fix. - Pass the handles in as arguments to the backfill functions, so the dependency is explicit and the tests inject rather than mock.
- Keep the seam but confine it: a small
src/backfill/handles.tswith typed getters and a setter, so at least it is typed, greppable and not onglobalThis.
Not urgent — the current arrangement works and the feature is live. Worth doing before anything else starts reading those globals, because every new reader makes it harder to remove.
Activity