fix: persistent random Snowflake worker ID + clean reaction API

Two fixes addressing architectural review feedback:

1. Snowflake ID collisions: Replace process.pid-based worker ID with a
   cryptographically random value (0-1023) generated once at first boot
   and persisted to instance_settings.worker_id. Eliminates deterministic
   ID collisions between Docker instances that all run as PID 1.

2. Reaction API leak: Revert addReaction/removeReaction signatures to
   (messageId, emoji) — the store now resolves the channel internally by
   scanning its message cache, keeping routing logic out of the UI layer.
This commit is contained in:
Jannis Braun
2026-03-03 00:03:29 +01:00
parent 5194dbef25
commit 72e07c1cc1
6 changed files with 76 additions and 10 deletions
+12
View File
@@ -3,6 +3,7 @@ import { drizzle } from 'drizzle-orm/better-sqlite3';
import { config } from '../config.js';
import * as schema from './schema.js';
import { runMigrations } from './migrate.js';
import { setWorkerId } from '../utils/snowflake.js';
import { mkdirSync } from 'fs';
import { dirname } from 'path';
@@ -180,6 +181,7 @@ function createTables(db: Database.Database): void {
CREATE TABLE IF NOT EXISTS instance_settings (
id INTEGER PRIMARY KEY DEFAULT 1 CHECK (id = 1),
instance_name TEXT DEFAULT 'Backspace',
worker_id INTEGER,
max_bitrate_kbps INTEGER NOT NULL DEFAULT 20000,
min_bitrate_kbps INTEGER NOT NULL DEFAULT 500,
bitrate_step_kbps INTEGER NOT NULL DEFAULT 500,
@@ -199,6 +201,16 @@ export function initDatabase() {
sqlite.pragma('foreign_keys = ON');
createTables(sqlite);
runMigrations(sqlite);
// Initialize Snowflake worker ID from persisted value (set by migration)
const settings = sqlite.prepare('SELECT worker_id FROM instance_settings WHERE id = 1').get() as { worker_id: number } | undefined;
if (settings?.worker_id !== undefined && settings.worker_id !== null) {
setWorkerId(settings.worker_id);
console.log(`Snowflake worker ID: ${settings.worker_id}`);
} else {
throw new Error('Snowflake worker_id not found in instance_settings — migration failed');
}
console.log(`Database initialized at ${config.dbPath}`);
return drizzle(sqlite, { schema });
}