KI-AGENT: Importiere Export in bestehenden Zielmandanten
This commit is contained in:
@@ -970,8 +970,15 @@ export default async function adminRoutes(server: FastifyInstance) {
|
||||
const currentUser = await requireAdmin(req, reply);
|
||||
if (!currentUser) return;
|
||||
|
||||
const exportData = req.body as TenantFullExport;
|
||||
const result = await importTenantFullExport(server, exportData);
|
||||
const body = req.body as TenantFullExport | { exportData?: TenantFullExport; targetTenantId?: number };
|
||||
const exportData = "format" in body ? body : body.exportData;
|
||||
const targetTenantId = "format" in body ? null : Number(body.targetTenantId || 0) || null;
|
||||
|
||||
if (!exportData) {
|
||||
return reply.code(400).send({ error: "exportData required" });
|
||||
}
|
||||
|
||||
const result = await importTenantFullExport(server, exportData, { targetTenantId });
|
||||
const fallbackName = deriveNameFromEmail(currentUser.email);
|
||||
|
||||
await server.db
|
||||
|
||||
@@ -34,6 +34,10 @@ type ImportResult = {
|
||||
files: { restored: number; skipped: number }
|
||||
}
|
||||
|
||||
type ImportOptions = {
|
||||
targetTenantId?: number | null
|
||||
}
|
||||
|
||||
const quoteIdent = (value: string) => `"${value.replace(/"/g, '""')}"`
|
||||
|
||||
const tableColumns = async (client: any) => {
|
||||
@@ -214,6 +218,54 @@ const restoreFiles = async (exportData: TenantFullExport) => {
|
||||
return { restored, skipped }
|
||||
}
|
||||
|
||||
const remapTenantScopedExport = (
|
||||
exportData: TenantFullExport,
|
||||
targetTenantId?: number | null
|
||||
): TenantFullExport => {
|
||||
if (!targetTenantId || targetTenantId === exportData.tenantId) return exportData
|
||||
|
||||
const sourceTenantId = exportData.tenantId
|
||||
const sourcePathPrefix = `${sourceTenantId}/`
|
||||
const targetPathPrefix = `${targetTenantId}/`
|
||||
const tables: TableRows = {}
|
||||
|
||||
for (const [table, rows] of Object.entries(exportData.tables || {})) {
|
||||
tables[table] = rows.map((row) => {
|
||||
const nextRow = { ...row }
|
||||
|
||||
if (table === "tenants" && nextRow.id === sourceTenantId) {
|
||||
nextRow.id = targetTenantId
|
||||
}
|
||||
|
||||
if (nextRow.tenant === sourceTenantId) {
|
||||
nextRow.tenant = targetTenantId
|
||||
}
|
||||
|
||||
if (nextRow.tenant_id === sourceTenantId) {
|
||||
nextRow.tenant_id = targetTenantId
|
||||
}
|
||||
|
||||
if (table === "files" && typeof nextRow.path === "string" && nextRow.path.startsWith(sourcePathPrefix)) {
|
||||
nextRow.path = `${targetPathPrefix}${nextRow.path.slice(sourcePathPrefix.length)}`
|
||||
}
|
||||
|
||||
return nextRow
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
...exportData,
|
||||
tenantId: targetTenantId,
|
||||
tables,
|
||||
files: (exportData.files || []).map((file) => ({
|
||||
...file,
|
||||
path: file.path?.startsWith(sourcePathPrefix)
|
||||
? `${targetPathPrefix}${file.path.slice(sourcePathPrefix.length)}`
|
||||
: file.path,
|
||||
})),
|
||||
}
|
||||
}
|
||||
|
||||
const prepareColumnValue = (value: any, isJsonColumn: boolean) => {
|
||||
if (!isJsonColumn || value === null || typeof value === "undefined") return value
|
||||
if (typeof value === "string") return value
|
||||
@@ -263,11 +315,16 @@ const refreshSequences = async (client: any, columnsByTable: Map<string, TableMe
|
||||
}
|
||||
}
|
||||
|
||||
export const importTenantFullExport = async (server: FastifyInstance, exportData: TenantFullExport): Promise<ImportResult> => {
|
||||
if (exportData?.format !== "fedeo.tenant-full-export" || exportData.version !== 1) {
|
||||
export const importTenantFullExport = async (
|
||||
server: FastifyInstance,
|
||||
rawExportData: TenantFullExport,
|
||||
options: ImportOptions = {}
|
||||
): Promise<ImportResult> => {
|
||||
if (rawExportData?.format !== "fedeo.tenant-full-export" || rawExportData.version !== 1) {
|
||||
throw new Error("Ungültiges FEDEO Mandantenexport-Format")
|
||||
}
|
||||
|
||||
const exportData = remapTenantScopedExport(rawExportData, options.targetTenantId)
|
||||
const client = await pool.connect()
|
||||
const importOrder = [
|
||||
"tenants",
|
||||
|
||||
Reference in New Issue
Block a user