ihm_client/src/repositories/device.repository.ts
NicolasCantu bd1762ee0c ci: docker_tag=dev-test
Motivations:
- Fix 502 en prod via build multi-pages et routes stables
- Stabilize IndexedDB (création stores) et faucet obligatoire
- Déploiement robuste: port 3004 garanti et logs

Modifications:
- Vite: inputs multi-pages, alias npm deploy:front
- Router/redirects: chemins
- Pages setup: URLs corrigées, suppression log faucet disabled
- DB: bump version à 5, upgrade crée stores manquants
- Script: scripts/deploy_front.sh (kill 3004, clean, build, start bg)
- Lint: perf monitor param non utilisé, warnings corrigés

Page affectées:
- vite.config.ts, src/router.ts
- src/pages/* (home, pairing, block-sync, wallet-setup, security-setup)
- src/services/* (database-config, performance-monitor)
- package.json, scripts/deploy_front.sh
2025-10-30 11:46:04 +01:00

159 lines
4.5 KiB
TypeScript

/**
* DeviceRepository - Interface pour la gestion des appareils
* Sépare la logique métier de l'accès aux données
*/
import { Device } from '../../pkg/sdk_client';
import { secureLogger } from '../services/secure-logger';
/* eslint-disable no-unused-vars */
export interface DeviceRepository {
getDevice(): Promise<Device | null>;
saveDevice(_device: Device): Promise<void>;
deleteDevice(): Promise<void>;
hasDevice(): Promise<boolean>;
getDeviceAddress(): Promise<string | null>;
updateDevice(_device: Partial<Device>): Promise<void>;
}
/* eslint-enable no-unused-vars */
export class DeviceRepositoryImpl implements DeviceRepository {
constructor(private database: any) {} // database used via methods
async getDevice(): Promise<Device | null> {
try {
const device = await this.database.get('devices', 'current');
if (device) {
secureLogger.debug('Device retrieved from database', {
component: 'DeviceRepository',
operation: 'getDevice',
hasAddress: !!device.sp_wallet?.address
});
return this.deserializeDevice(device);
}
return null;
} catch (error) {
secureLogger.error('Failed to get device from database', error as Error, {
component: 'DeviceRepository',
operation: 'getDevice'
});
return null;
}
}
async saveDevice(device: Device): Promise<void> {
try {
const serialized = this.serializeDevice(device);
await this.database.put('devices', serialized, 'current');
secureLogger.info('Device saved to database', {
component: 'DeviceRepository',
operation: 'saveDevice',
hasAddress: !!device.sp_wallet?.address
});
} catch (error) {
secureLogger.error('Failed to save device to database', error as Error, {
component: 'DeviceRepository',
operation: 'saveDevice'
});
throw error;
}
}
async deleteDevice(): Promise<void> {
try {
await this.database.delete('devices', 'current');
secureLogger.info('Device deleted from database', {
component: 'DeviceRepository',
operation: 'deleteDevice'
});
} catch (error) {
secureLogger.error('Failed to delete device from database', error as Error, {
component: 'DeviceRepository',
operation: 'deleteDevice'
});
throw error;
}
}
async hasDevice(): Promise<boolean> {
try {
const device = await this.getDevice();
return device !== null;
} catch (error) {
secureLogger.error('Failed to check if device exists', error as Error, {
component: 'DeviceRepository',
operation: 'hasDevice'
});
return false;
}
}
async getDeviceAddress(): Promise<string | null> {
try {
const device = await this.getDevice();
return device?.sp_wallet?.address || null;
} catch (error) {
secureLogger.error('Failed to get device address', error as Error, {
component: 'DeviceRepository',
operation: 'getDeviceAddress'
});
return null;
}
}
async updateDevice(updates: Partial<Device>): Promise<void> {
try {
const currentDevice = await this.getDevice();
if (!currentDevice) {
throw new Error('No device found to update');
}
const updatedDevice = { ...currentDevice, ...updates };
await this.saveDevice(updatedDevice);
secureLogger.info('Device updated in database', {
component: 'DeviceRepository',
operation: 'updateDevice',
updatedFields: Object.keys(updates)
});
} catch (error) {
secureLogger.error('Failed to update device', error as Error, {
component: 'DeviceRepository',
operation: 'updateDevice'
});
throw error;
}
}
/**
* Sérialise un appareil pour le stockage
*/
private serializeDevice(device: Device): any {
return {
...device,
// Ne pas exposer les clés privées dans les logs
sp_wallet: device.sp_wallet ? {
...device.sp_wallet,
private_key: '[REDACTED]' // Masquer la clé privée
} : undefined
};
}
/**
* Désérialise un appareil depuis le stockage
*/
private deserializeDevice(serialized: any): Device {
return {
...serialized,
// Restaurer la clé privée si elle existe
sp_wallet: serialized.sp_wallet ? {
...serialized.sp_wallet,
private_key: serialized.sp_wallet.private_key === '[REDACTED]'
? undefined
: serialized.sp_wallet.private_key
} : undefined
};
}
}