tsgo is clean

All five errors gone. Both were real resolution bugs rather than dead code that
happened to be noisy — the unreachable parts were unreachable for the wrong reason.

officerdb's export map gave the wildcard no extension:

  "./types": "./src/types.ts"     explicit entries carry it
  "./*":     "./src/*"            the wildcard did not

so `officerdb/soulseek/schema` resolved to `src/soulseek/schema`, which is not a
file, while `src/soulseek/schema.ts` sat right there. Now "./src/*.ts". Verified
every subpath still resolves at RUNTIME with Bun.resolveSync — an exports map is
exactly the thing where a typecheck fix can break the running app, and three of the
four paths are load-bearing.

types.ts inferred EmailAccount* and PushDevice* from `./schema`, the aggregator that
drizzle-kit reads — where both tables are commented out because they belong to
plugins. But inferring a TYPE has nothing to do with whether the table exists in the
live database: these describe rows the plugin's own code passes around, and that code
compiles whether or not the plugin is installed. Reading them off the aggregator
coupled the two, so commenting a plugin out of schema.ts broke the build of code that
was already unreachable.

They now come from ./email/schema and ./notify/schema directly — the same move the
query modules made when the split landed, and the thing that lets a table leave the
aggregator without breaking anything. src/databases/CLAUDE.md already describes this
as the rule; types.ts was the one file that had not followed it.

Verified: bunx tsgo --noEmit, zero output.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-14 13:24:32 +00:00
co-authored by Claude Opus 5
parent 11710f283a
commit d85f089817
2 changed files with 22 additions and 5 deletions
+1 -1
View File
@@ -9,7 +9,7 @@
"./db": "./src/db.ts", "./db": "./src/db.ts",
"./schema": "./src/schema.ts", "./schema": "./src/schema.ts",
"./secret-store": "./src/secret-store.ts", "./secret-store": "./src/secret-store.ts",
"./*": "./src/*" "./*": "./src/*.ts"
}, },
"scripts": { "scripts": {
"generate": "drizzle-kit generate --config=drizzle.config.ts", "generate": "drizzle-kit generate --config=drizzle.config.ts",
+21 -4
View File
@@ -1,5 +1,22 @@
import type * as Schema from './schema'; import type * as Schema from './schema';
// ── Plugin tables come from their OWN schema, not from the aggregator ──
//
// `./schema` is drizzle-kit's view of the database — what `bun db:push` reads — so a
// table that belongs to a plugin is commented out there and genuinely absent from the
// live database. That is the point of the core/plugin split.
//
// Inferring a TYPE from it, though, has nothing to do with whether the table exists:
// these describe rows that the plugin's own code passes around, and that code compiles
// whether or not the plugin is installed. Reading them off the aggregator coupled the
// two, so commenting a plugin out of `schema.ts` broke the build of code that was
// already unreachable.
//
// Same move the query modules made when the split landed — import the feature's schema
// directly — which is what lets a table leave the aggregator without breaking anything.
import type * as EmailSchema from './email/schema';
import type * as NotifySchema from './notify/schema';
// ── Auth ── // ── Auth ──
export type UserSelect = typeof Schema.users.$inferSelect; export type UserSelect = typeof Schema.users.$inferSelect;
@@ -47,8 +64,8 @@ export type ScreenInsert = typeof Schema.screens.$inferInsert;
// ── Email ── // ── Email ──
export type EmailAccountSelect = typeof Schema.emailAccounts.$inferSelect; export type EmailAccountSelect = typeof EmailSchema.emailAccounts.$inferSelect;
export type EmailAccountInsert = typeof Schema.emailAccounts.$inferInsert; export type EmailAccountInsert = typeof EmailSchema.emailAccounts.$inferInsert;
// ── Server ── // ── Server ──
@@ -64,8 +81,8 @@ export type PipelineJobSelect = typeof Schema.pipelineJobs.$inferSelect;
export type PipelineJobInsert = typeof Schema.pipelineJobs.$inferInsert; export type PipelineJobInsert = typeof Schema.pipelineJobs.$inferInsert;
// Notifications // Notifications
export type PushDeviceSelect = typeof Schema.pushDevices.$inferSelect; export type PushDeviceSelect = typeof NotifySchema.pushDevices.$inferSelect;
export type PushDeviceInsert = typeof Schema.pushDevices.$inferInsert; export type PushDeviceInsert = typeof NotifySchema.pushDevices.$inferInsert;
// ── API keys ── // ── API keys ──