From 12d45660c6e67eecef809c2b03d11de605ac35b9 Mon Sep 17 00:00:00 2001 From: Bouni <948965+Bouni@users.noreply.github.com> Date: Fri, 9 Oct 2026 09:28:47 +0000 Subject: [PATCH 1/5] Update missing translations, sort translations --- TRANSLATIONS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TRANSLATIONS.md b/TRANSLATIONS.md index 6b60ea4..2fa4fd6 100644 --- a/TRANSLATIONS.md +++ b/TRANSLATIONS.md @@ -1,6 +1,6 @@ # Translation Status -Last updated: 2026-10-07 09:57:47 +Last updated: 2026-10-09 09:28:47 Reference locale (en): **346 keys** From b6a1dc9725c59e2202b458c209329d013f327083 Mon Sep 17 00:00:00 2001 From: Bouni Date: Fri, 9 Oct 2026 14:53:12 +0200 Subject: [PATCH 2/5] Allow db to be undefined after closeDatabase() closeDatabase() resets the module-level handle to undefined, which the DB type did not permit. Type it as DB | undefined and route the invoice-numbering helpers through getDatabase() so they get a clear 'Database not initialized' error instead of a TypeError. Co-Authored-By: Claude Opus 5.5 --- backend/src/database/init.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/backend/src/database/init.ts b/backend/src/database/init.ts index 14ce783..61652a7 100644 --- a/backend/src/database/init.ts +++ b/backend/src/database/init.ts @@ -5,7 +5,7 @@ import { generateUUID } from "../utils/uuid.ts"; import { RESOURCE_ACTIONS } from "../types/index.ts"; import type { Action, Resource } from "../types/index.ts"; -let db: DB; +let db: DB | undefined; // // Path helpers @@ -772,7 +772,7 @@ function getNumberingSettings(): { enabled: true, }; try { - const rows = db.query( + const rows = getDatabase().query( "SELECT key, value FROM settings WHERE key IN ('invoicePrefix','invoiceIncludeYear','invoiceNumberPadding','invoiceNumberPattern')", ); const m = new Map(); @@ -789,7 +789,7 @@ function getNumberingSettings(): { cfg.pattern = (m.get("invoiceNumberPattern") || "").trim() || undefined; try { - const raw = db.query( + const raw = getDatabase().query( "SELECT value FROM settings WHERE key = 'invoiceNumberingEnabled' LIMIT 1", ); if (raw.length > 0) { @@ -807,11 +807,11 @@ function getNumberingSettings(): { /** Find the highest existing sequential suffix matching `likePrefix%`, optionally scoped to a single customer. */ function findMaxSequence(likePrefix: string, customerId?: string): number { const rows = customerId - ? db.query( + ? getDatabase().query( "SELECT invoice_number FROM invoices WHERE invoice_number LIKE ? AND customer_id = ?", [likePrefix + "%", customerId], ) - : db.query( + : getDatabase().query( "SELECT invoice_number FROM invoices WHERE invoice_number LIKE ?", [likePrefix + "%"], ); @@ -829,7 +829,7 @@ function findMaxSequence(likePrefix: string, customerId?: string): number { function getCustomerNumber(customerId?: string): number | null { if (!customerId) return null; try { - const rows = db.query( + const rows = getDatabase().query( "SELECT customer_number FROM customers WHERE id = ?", [customerId], ) as unknown[][]; From d6fc5d6b9032fab6750e7891f2c85907b8bde2c9 Mon Sep 17 00:00:00 2001 From: Bouni Date: Fri, 9 Oct 2026 14:53:12 +0200 Subject: [PATCH 3/5] Type template zip data as Uint8Array The zip upload is always built from an ArrayBuffer; stating that lets it be passed to new Blob() under TypeScript 5.7+ typed arrays. Co-Authored-By: Claude Opus 5.5 --- backend/src/controllers/templates.ts | 2 +- backend/src/routes/admin.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/controllers/templates.ts b/backend/src/controllers/templates.ts index e4330a1..0c1a7a2 100644 --- a/backend/src/controllers/templates.ts +++ b/backend/src/controllers/templates.ts @@ -644,7 +644,7 @@ function assertLocalManifestShape(m: unknown): asserts m is LocalManifest { // Install a template from an uploaded .zip file (local template) export async function installLocalTemplateFromZip( - zipData: Uint8Array, + zipData: Uint8Array, ): Promise