diff --git a/backend/src/utils/tenantExportGlobalResources.ts b/backend/src/utils/tenantExportGlobalResources.ts new file mode 100644 index 0000000..ce1d388 --- /dev/null +++ b/backend/src/utils/tenantExportGlobalResources.ts @@ -0,0 +1,36 @@ +type TableRows = Record[]> + +type LoadRows = ( + table: string, + whereSql: string, + params?: any[] +) => Promise[]> + +type AddRows = ( + tables: TableRows, + table: string, + rows: Record[] +) => void + +export const TENANT_EXPORT_GLOBAL_TABLES = ["units", "citys", "countrys"] as const + +export const addTenantExportGlobalResources = async ( + tables: TableRows, + availableTables: ReadonlySet, + tenant: Record, + loadRows: LoadRows, + addRows: AddRows +) => { + for (const table of TENANT_EXPORT_GLOBAL_TABLES) { + if (!availableTables.has(table)) continue + addRows(tables, table, await loadRows(table, "true")) + } + + if (availableTables.has("accounts")) { + addRows( + tables, + "accounts", + await loadRows("accounts", `"accountChart" = $1`, [tenant.accountChart || "skr03"]) + ) + } +} diff --git a/backend/src/utils/tenantFullExport.ts b/backend/src/utils/tenantFullExport.ts index 1fc4aeb..e8ab4be 100644 --- a/backend/src/utils/tenantFullExport.ts +++ b/backend/src/utils/tenantFullExport.ts @@ -11,6 +11,7 @@ import { pool } from "../../db" import { s3 } from "./s3" import { secrets } from "./secrets" import { decrypt, encrypt } from "./crypt" +import { addTenantExportGlobalResources } from "./tenantExportGlobalResources" import { restoreImportedTenantNumberRanges } from "./tenantImportNumberRanges" type TableRows = Record[]> @@ -300,6 +301,13 @@ export const buildTenantFullExport = async ( if (!tenantRows.length) throw new Error("Tenant nicht gefunden") addRows(tables, "tenants", tenantRows) + await addTenantExportGlobalResources( + tables, + new Set(columnsByTable.keys()), + tenantRows[0], + (table, whereSql, params) => loadRows(client, table, whereSql, params), + addRows + ) for (const [table, metadata] of columnsByTable.entries()) { if (table === "tenants") continue diff --git a/backend/tests/tenantExportGlobalResources.test.ts b/backend/tests/tenantExportGlobalResources.test.ts new file mode 100644 index 0000000..c9ae9fd --- /dev/null +++ b/backend/tests/tenantExportGlobalResources.test.ts @@ -0,0 +1,52 @@ +import assert from "node:assert/strict" +import test from "node:test" + +import { addTenantExportGlobalResources } from "../src/utils/tenantExportGlobalResources" + +test("adds global resources and the tenant account chart to a tenant export", async () => { + const tables: Record[]> = {} + const calls: { table: string, whereSql: string, params?: any[] }[] = [] + const rowsByTable: Record[]> = { + units: [{ id: 1, name: "Monat" }], + citys: [{ id: 1, zip: 26316 }], + countrys: [{ id: 1, name: "Deutschland" }], + accounts: [{ id: 1, accountChart: "skr04", number: "4400" }], + } + + await addTenantExportGlobalResources( + tables, + new Set(Object.keys(rowsByTable)), + { id: 42, accountChart: "skr04" }, + async (table, whereSql, params) => { + calls.push({ table, whereSql, params }) + return rowsByTable[table] + }, + (target, table, rows) => { + target[table] = rows + } + ) + + assert.deepEqual(tables, rowsByTable) + assert.deepEqual(calls, [ + { table: "units", whereSql: "true", params: undefined }, + { table: "citys", whereSql: "true", params: undefined }, + { table: "countrys", whereSql: "true", params: undefined }, + { table: "accounts", whereSql: `"accountChart" = $1`, params: ["skr04"] }, + ]) +}) + +test("skips global tables that do not exist in an older database schema", async () => { + const tables: Record[]> = {} + + await addTenantExportGlobalResources( + tables, + new Set(["units"]), + { id: 42 }, + async () => [{ id: 1, name: "Stück" }], + (target, table, rows) => { + target[table] = rows + } + ) + + assert.deepEqual(tables, { units: [{ id: 1, name: "Stück" }] }) +})