From bab194a18478685b5c3ba8dd04ad3cf5ef3628c4 Mon Sep 17 00:00:00 2001 From: Mitchell R Date: Sat, 23 May 2026 13:00:18 +0200 Subject: [PATCH] fix(db): add RETURNING id to all INSERTs for PG compat PG doesn't populate lastInsertRowid without RETURNING clause. SQLite 3.35+ also supports RETURNING. Added to all 14 INSERT statements that use auto-generated integer IDs. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../src/plugins/service-store/repository.ts | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/server/src/plugins/service-store/repository.ts b/server/src/plugins/service-store/repository.ts index cdf3440..19c7ff9 100644 --- a/server/src/plugins/service-store/repository.ts +++ b/server/src/plugins/service-store/repository.ts @@ -189,7 +189,7 @@ export class Repository { const role: UserRole = input.role ?? "operator"; const result = await this._run( `INSERT INTO users (username, password_hash, role, is_active, must_change_password) - VALUES (?, ?, ?, ?, ?)`, + VALUES (?, ?, ?, ?, ?) RETURNING id`, [ input.username, input.password_hash, @@ -326,7 +326,7 @@ export class Repository { }): Promise { const result = await this._run( `INSERT INTO api_keys (name, key_hash, key_prefix, scopes, expires_at) - VALUES (?, ?, ?, ?, ?)`, + VALUES (?, ?, ?, ?, ?) RETURNING id`, [ input.name, input.key_hash, @@ -380,7 +380,7 @@ export class Repository { async createDefaultDisplay(): Promise { const result = await this._run( `INSERT INTO displays (name, "index", is_primary) - VALUES ('primary', 0, 0)`, + VALUES ('primary', 0, 0) RETURNING id`, ); const id = Number(result.lastInsertRowid); void this.notify("displays", "create", id); @@ -398,7 +398,7 @@ export class Repository { const idx = input.index ?? await this.nextDisplayIndexForKiosk(kioskId); const result = await this._run( `INSERT INTO displays (name, "index", is_primary, kiosk_id, width_px, height_px) - VALUES (?, ?, 0, ?, ?, ?)`, + VALUES (?, ?, 0, ?, ?, ?) RETURNING id`, [ input.name, idx, @@ -567,7 +567,7 @@ export class Repository { }): Promise { const result = await this._run( `INSERT INTO layouts (name, description, priority, cooling_timeout_seconds, preload_camera_ids, resets_idle_timer) - VALUES (?, ?, ?, ?, ?, ?)`, + VALUES (?, ?, ?, ?, ?, ?) RETURNING id`, [ input.name, input.description ?? null, @@ -712,7 +712,7 @@ export class Repository { const result = await this._run( `INSERT INTO layout_cells (layout_id, "row", col, row_span, col_span, content_type, camera_id, stream_selector, web_url, html_content, cooling_timeout_seconds, options, entity_id, fit) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING id`, [ input.layout_id, input.row, @@ -899,7 +899,7 @@ export class Repository { `INSERT INTO cameras (name, type, rtsp_url, onvif_host, onvif_port, onvif_username, onvif_password, capabilities, stream_policy) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`, + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING id`, [ input.name, input.type, @@ -945,7 +945,7 @@ export class Repository { const result = await this._run( `INSERT INTO cameras (name, type, cloud_account_id, cloud_vendor_camera_id, cloud_stream_url, cloud_stream_type, enabled) - VALUES (?, 'cloud', ?, ?, ?, ?, ?)`, + VALUES (?, 'cloud', ?, ?, ?, ?, ?) RETURNING id`, [input.name, input.cloud_account_id, input.cloud_vendor_camera_id, input.cloud_stream_url, input.cloud_stream_type, Boolean(input.enabled)], ); @@ -1006,7 +1006,7 @@ export class Repository { `INSERT INTO camera_streams (camera_id, role, name, profile_token, rtsp_uri, width, height, encoding, framerate, bitrate_kbps, is_discovered) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING id`, [ input.camera_id, input.role, @@ -1063,7 +1063,7 @@ export class Repository { }): Promise