added recovery entires, changed recovery icon

This commit is contained in:
duffyduck 2026-02-08 19:43:46 +01:00
parent e348e86c60
commit dd4d57fa1b
4 changed files with 195 additions and 153 deletions

View File

@ -236,6 +236,8 @@ export async function createBackup(): Promise<BackupResult> {
{ name: 'CarInsuranceDetails', query: () => prisma.carInsuranceDetails.findMany() },
{ name: 'PhoneNumber', query: () => prisma.phoneNumber.findMany() },
{ name: 'SimCard', query: () => prisma.simCard.findMany() },
{ name: 'Invoice', query: () => prisma.invoice.findMany() },
{ name: 'ContractHistoryEntry', query: () => prisma.contractHistoryEntry.findMany() },
{ name: 'Address', query: () => prisma.address.findMany() },
{ name: 'BankCard', query: () => prisma.bankCard.findMany() },
{ name: 'IdentityDocument', query: () => prisma.identityDocument.findMany() },
@ -304,8 +306,10 @@ export async function restoreBackup(backupName: string): Promise<RestoreResult>
await prisma.mobileContractDetails.deleteMany({});
await prisma.phoneNumber.deleteMany({});
await prisma.internetContractDetails.deleteMany({});
await prisma.invoice.deleteMany({});
await prisma.energyContractDetails.deleteMany({});
await prisma.meterReading.deleteMany({});
await prisma.contractHistoryEntry.deleteMany({});
// E-Mail & Verträge
await prisma.cachedEmail.deleteMany({});
@ -691,6 +695,30 @@ export async function restoreBackup(backupName: string): Promise<RestoreResult>
}
},
},
{
name: 'Invoice',
restore: async (data: any[]) => {
for (const item of data) {
await prisma.invoice.upsert({
where: { id: item.id },
update: convertDates(item),
create: convertDates(item),
});
}
},
},
{
name: 'ContractHistoryEntry',
restore: async (data: any[]) => {
for (const item of data) {
await prisma.contractHistoryEntry.upsert({
where: { id: item.id },
update: convertDates(item),
create: convertDates(item),
});
}
},
},
{
name: 'Address',
restore: async (data: any[]) => {
@ -882,8 +910,10 @@ export async function factoryReset(): Promise<{ success: boolean; error?: string
await prisma.mobileContractDetails.deleteMany({});
await prisma.phoneNumber.deleteMany({});
await prisma.internetContractDetails.deleteMany({});
await prisma.invoice.deleteMany({});
await prisma.energyContractDetails.deleteMany({});
await prisma.meterReading.deleteMany({});
await prisma.contractHistoryEntry.deleteMany({});
// E-Mail & Verträge
await prisma.cachedEmail.deleteMany({});
@ -1113,55 +1143,62 @@ export async function factoryReset(): Promise<{ success: boolean; error?: string
}
console.log('[FactoryReset] Vertriebsplattformen erstellt');
// Standard Anbieter (wie in seed.ts)
const providers = [
// Anbieter mit Tarifen (aus bestehender Datenbank)
const providersWithTariffs = [
{
name: 'Vodafone',
portalUrl: 'https://www.vodafone.de/meinvodafone/account/login',
usernameFieldName: 'username',
passwordFieldName: 'password',
provider: { name: '1&1', portalUrl: 'https://control-center.1und1.de/' },
tariffs: [],
},
{
name: 'Klarmobil',
portalUrl: 'https://www.klarmobil.de/login',
usernameFieldName: 'username',
passwordFieldName: 'password',
provider: { name: 'Congstar', portalUrl: 'https://www.congstar.de/login/' },
tariffs: [],
},
{
name: 'Otelo',
portalUrl: 'https://www.otelo.de/mein-otelo/login',
usernameFieldName: 'username',
passwordFieldName: 'password',
provider: { name: 'E wie einfach', portalUrl: '' },
tariffs: ['Grün & Günstig Strom'],
},
{
name: 'Congstar',
portalUrl: 'https://www.congstar.de/login/',
usernameFieldName: 'username',
passwordFieldName: 'password',
provider: { name: 'EVD Energieversogung Deutschland', portalUrl: 'https://mein.ev-d.de/selfcare' },
tariffs: ['EVD Gas Bonus 12'],
},
{
name: 'Telekom',
portalUrl: 'https://www.telekom.de/kundencenter/startseite',
usernameFieldName: 'username',
passwordFieldName: 'password',
provider: { name: 'Klarmobil', portalUrl: 'https://www.klarmobil.de/login' },
tariffs: ['Allnet Flat 30GB 5G (+00) Telekom'],
},
{
name: 'O2',
portalUrl: 'https://www.o2online.de/ecare/selfcare',
usernameFieldName: 'username',
passwordFieldName: 'password',
provider: { name: 'O2', portalUrl: 'https://www.o2online.de/ecare/selfcare' },
tariffs: [],
},
{
name: '1&1',
portalUrl: 'https://control-center.1und1.de/',
usernameFieldName: 'username',
passwordFieldName: 'password',
provider: { name: 'Otelo', portalUrl: 'https://www.otelo.de/mein-otelo/login' },
tariffs: [],
},
{
provider: { name: 'Telekom', portalUrl: 'https://www.telekom.de/kundencenter/startseite' },
tariffs: [],
},
{
provider: { name: 'Vodafone', portalUrl: 'https://www.vodafone.de/meinvodafone/account/login' },
tariffs: [],
},
];
for (const provider of providers) {
await prisma.provider.create({ data: { ...provider, isActive: true } });
for (const { provider, tariffs } of providersWithTariffs) {
const createdProvider = await prisma.provider.create({
data: { ...provider, isActive: true },
});
// Tarife für diesen Anbieter anlegen
for (const tariffName of tariffs) {
await prisma.tariff.create({
data: {
providerId: createdProvider.id,
name: tariffName,
isActive: true,
},
});
}
}
console.log('[FactoryReset] Anbieter erstellt');
console.log('[FactoryReset] Anbieter mit Tarifen erstellt');
// Standard App-Einstellungen (wie in seed.ts)
const appSettings = [

File diff suppressed because one or more lines are too long

View File

@ -5,7 +5,7 @@
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>OpenCRM</title>
<script type="module" crossorigin src="/assets/index-Cdzd21Iz.js"></script>
<script type="module" crossorigin src="/assets/index-AsLwOxex.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-b8RXSgxB.css">
</head>
<body>

View File

@ -1,6 +1,6 @@
import { useState, useRef } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { Database, Download, Upload, Trash2, RefreshCw, HardDrive, Clock, FileText, FolderOpen, Archive, AlertTriangle, RotateCcw } from 'lucide-react';
import { Database, Download, Upload, Trash2, RefreshCw, HardDrive, Clock, FileText, FolderOpen, Archive, AlertTriangle, Bomb } from 'lucide-react';
import { backupApi, BackupInfo } from '../../services/api';
import { useAuth } from '../../context/AuthContext';
import Button from '../../components/ui/Button';
@ -412,7 +412,7 @@ export default function DatabaseBackup() {
variant="danger"
onClick={() => setShowFactoryResetConfirm(true)}
>
<RotateCcw className="w-4 h-4 mr-2" />
<Bomb className="w-4 h-4 mr-2" />
Werkseinstellungen
</Button>
</div>