Adding a DB Column
This guide walks through adding a new column to an existing TomoriBot database table.
-
Add an idempotent migration to
src/db/schema.sql. Useadd_column_if_not_existsor anIF NOT EXISTSguard so the migration is safe to re-run:SELECT add_column_if_not_exists('table_name', 'column_name', 'TEXT DEFAULT NULL'); -
Update the Zod schema and TypeScript types in
src/types/db/schema.tsto include the new field. -
Wire read/write usage in the relevant
src/utils/db/module. Use Bun SQL template literals:const rows = await sql`SELECT column_name FROM table_name WHERE id = ${id}`;⚠️ If the column lives on a
server_*_configstable and must be readable at runtime viatomoriState.config, you MUST also add it to the config-assembly SELECTs insrc/utils/db/repositories/PersonaRepository.ts(there are two —loadTomoriStateandloadAllForServer, search forscaps.tool_use_enabled). These rows are validated withassembledServerConfigSchema.safeParse(...). Because that schema gives each field a.default(...), a column that’s missing from the SELECT is silently filled with its default instead of erroring — so a runtime gate likeconfig.flag === falsewill never fire and the feature appears not to work, with no type or test failure to flag it. Adding the column to the Zod schema and the/capabilitieswrite path is NOT enough. -
Invalidate any affected caches after successful writes — never before, never on failure. Keep the invalidation call in the same code path as the write:
await sql`UPDATE table_name SET column_name = ${value} WHERE id = ${id}`;someCache.delete(cacheKey); // only reached if update didn't throw
Quality Gate
Section titled “Quality Gate”bun run check # TypeScript strict modebun run lint # Biome formattingbun run db:lifecycle # full schema lifecycle test (requires local PostgreSQL)bun run db:lifecycle creates and drops its own temporary database and runs fresh initialization plus backup/restore scripts. It requires a local disposable PostgreSQL target with CREATE/DROP database permission.
Related Docs
Section titled “Related Docs”docs/en/architecture/subsystems/database-schema.md— full schema reference and column indexdocs/en/architecture/subsystems/caching.md— cache map and invalidation APIs