fix: preservar datos y recuperar base local
This commit is contained in:
4
apps/toldo-app/package-lock.json
generated
4
apps/toldo-app/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "toldo-app",
|
||||
"version": "0.0.5",
|
||||
"version": "0.0.6",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "toldo-app",
|
||||
"version": "0.0.5",
|
||||
"version": "0.0.6",
|
||||
"dependencies": {
|
||||
"@capacitor/android": "^6.2.1",
|
||||
"@capacitor/core": "^6.2.1",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "toldo-app",
|
||||
"private": true,
|
||||
"version": "0.0.5",
|
||||
"version": "0.0.6",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -19,7 +19,7 @@ describe('contratos de operación y respaldo', () => {
|
||||
|
||||
it('expone la versión actual en las exportaciones', () => {
|
||||
const result = new ExportImportService().exportAll({ productores: [], productos: [], movimientosInventario: [], ventas: [], ventaLineas: [], gastos: [], ajustes: [], cuadres: [] });
|
||||
expect(result.appVersion).toBe('0.0.5');
|
||||
expect(result.appVersion).toBe('0.0.6');
|
||||
});
|
||||
|
||||
it('exporta jornadas junto con los datos operativos', () => {
|
||||
|
||||
22
apps/toldo-app/src/__tests__/database-bootstrap.test.ts
Normal file
22
apps/toldo-app/src/__tests__/database-bootstrap.test.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { beforeEach, describe, expect, it } from 'vitest';
|
||||
import { db, openDatabase, resetDatabase } from '@toldo/data';
|
||||
|
||||
describe('bootstrap y recuperación de base local', () => {
|
||||
beforeEach(async () => {
|
||||
await resetDatabase();
|
||||
});
|
||||
|
||||
it('abre el esquema actual y conserva datos al cerrar y abrir', async () => {
|
||||
await db.productores.add({ id: 'persisted', nombre: 'Productor persistente', activo: true, createdAt: new Date() } as any);
|
||||
db.close();
|
||||
await openDatabase();
|
||||
expect(await db.productores.get('persisted')).toMatchObject({ nombre: 'Productor persistente' });
|
||||
expect(db.auditorias).toBeTruthy();
|
||||
});
|
||||
|
||||
it('restablece sólo cuando se solicita explícitamente', async () => {
|
||||
await db.productores.add({ id: 'to-reset', nombre: 'Temporal', activo: true, createdAt: new Date() } as any);
|
||||
await resetDatabase();
|
||||
expect(await db.productores.count()).toBe(0);
|
||||
});
|
||||
});
|
||||
@@ -2,5 +2,27 @@ import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import vuetify from './plugins/vuetify'
|
||||
import { openDatabase, resetDatabase } from '@toldo/data'
|
||||
|
||||
createApp(App).use(router).use(vuetify).mount('#app')
|
||||
async function bootstrap() {
|
||||
try {
|
||||
await openDatabase()
|
||||
createApp(App).use(router).use(vuetify).mount('#app')
|
||||
} catch (error) {
|
||||
const root = document.querySelector('#app')
|
||||
if (!root) return
|
||||
root.innerHTML = ''
|
||||
const card = document.createElement('main')
|
||||
card.className = 'database-recovery'
|
||||
card.innerHTML = '<h1>No se pudo abrir los datos locales</h1><p>La aplicación no continuará para evitar mostrar información incompleta. Puedes intentar recargar o restablecer el entorno como último recurso.</p>'
|
||||
const details = document.createElement('pre')
|
||||
details.textContent = error instanceof Error ? error.message : String(error)
|
||||
const button = document.createElement('button')
|
||||
button.textContent = 'Restablecer entorno local'
|
||||
button.onclick = async () => { button.disabled = true; await resetDatabase(); window.location.reload() }
|
||||
card.append(details, button)
|
||||
root.append(card)
|
||||
}
|
||||
}
|
||||
|
||||
bootstrap()
|
||||
|
||||
@@ -56,6 +56,11 @@ body {
|
||||
background: #f5f7f2;
|
||||
}
|
||||
|
||||
.database-recovery { max-width: 640px; margin: 12vh auto; padding: 24px; font-family: system-ui, sans-serif; color: #26352b; background: #fffdf8; border: 1px solid #d9e2d7; border-radius: 12px; box-shadow: 0 8px 30px rgba(38, 53, 43, .12); }
|
||||
.database-recovery p { margin: 12px 0; }
|
||||
.database-recovery pre { white-space: pre-wrap; font-size: 12px; color: #6b4a25; background: #f7f1e7; padding: 12px; border-radius: 8px; }
|
||||
.database-recovery button { padding: 12px 16px; color: white; background: #2d5f3b; border: 0; border-radius: 8px; cursor: pointer; }
|
||||
|
||||
h1,
|
||||
h2 {
|
||||
font-family: var(--heading);
|
||||
|
||||
@@ -8,19 +8,25 @@
|
||||
|
||||
<section>
|
||||
<v-card><v-card-title>Restaurar datos</v-card-title><v-card-text><v-file-input accept=".json" label="Seleccionar copia JSON" @update:model-value="archivo = $event" /><v-alert v-if="mensaje" :type="tipoMensaje" variant="tonal" class="mb-3">{{ mensaje }}</v-alert><v-btn @click="importar" :disabled="!archivo" color="secondary" prepend-icon="mdi-upload">Importar datos</v-btn></v-card-text></v-card>
|
||||
<v-card class="mt-4" variant="tonal" color="error"><v-card-title>Mantenimiento</v-card-title><v-card-text><div class="text-body-2 mb-3">Restablece la base local sólo si la aplicación no puede migrarla. Esta acción elimina ventas, inventario, jornadas y respaldos locales.</div><v-btn color="error" variant="outlined" prepend-icon="mdi-database-refresh" @click="reiniciarEntorno">Restablecer entorno local</v-btn></v-card-text></v-card>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { db } from '@toldo/data';
|
||||
import { db, resetDatabase } from '@toldo/data';
|
||||
import { ExportImportService } from '@toldo/services';
|
||||
|
||||
const exportService = new ExportImportService();
|
||||
const archivo = ref<File | null>(null);
|
||||
const mensaje = ref('');
|
||||
const tipoMensaje = ref<'success' | 'error'>('success');
|
||||
async function reiniciarEntorno() {
|
||||
if (!window.confirm('Se eliminarán todos los datos locales. Exporta un respaldo antes de continuar. ¿Restablecer?')) return;
|
||||
await resetDatabase();
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
function onFileChange(e: any) {
|
||||
archivo.value = e.target.files[0];
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
versionName=0.0.5
|
||||
versionCode=5
|
||||
versionName=0.0.6
|
||||
versionCode=6
|
||||
|
||||
Reference in New Issue
Block a user