Improve teh securty of teh DB

This commit is contained in:
Urtzi Alfaro
2025-10-19 19:22:37 +02:00
parent 62971c07d7
commit 05da20357d
87 changed files with 7998 additions and 932 deletions

View File

@@ -0,0 +1,178 @@
// frontend/src/api/services/equipment.ts
/**
* Equipment API service
*/
import { apiClient } from '../client';
import type {
Equipment,
EquipmentCreate,
EquipmentUpdate,
EquipmentResponse,
EquipmentListResponse
} from '../types/equipment';
class EquipmentService {
private readonly baseURL = '/tenants';
/**
* Helper to convert snake_case API response to camelCase Equipment
*/
private convertToEquipment(response: EquipmentResponse): Equipment {
return {
id: response.id,
tenant_id: response.tenant_id,
name: response.name,
type: response.type,
model: response.model || '',
serialNumber: response.serial_number || '',
location: response.location || '',
status: response.status,
installDate: response.install_date || new Date().toISOString().split('T')[0],
lastMaintenance: response.last_maintenance_date || new Date().toISOString().split('T')[0],
nextMaintenance: response.next_maintenance_date || new Date().toISOString().split('T')[0],
maintenanceInterval: response.maintenance_interval_days || 30,
temperature: response.current_temperature || undefined,
targetTemperature: response.target_temperature || undefined,
efficiency: response.efficiency_percentage || 0,
uptime: response.uptime_percentage || 0,
energyUsage: response.energy_usage_kwh || 0,
utilizationToday: 0, // Not in backend yet
alerts: [], // Not in backend yet
maintenanceHistory: [], // Not in backend yet
specifications: {
power: response.power_kw || 0,
capacity: response.capacity || 0,
dimensions: {
width: 0, // Not in backend separately
height: 0,
depth: 0
},
weight: response.weight_kg || 0
},
is_active: response.is_active,
created_at: response.created_at,
updated_at: response.updated_at
};
}
/**
* Helper to convert Equipment to API request format (snake_case)
*/
private convertToApiFormat(equipment: Partial<Equipment>): EquipmentCreate | EquipmentUpdate {
return {
name: equipment.name,
type: equipment.type,
model: equipment.model,
serial_number: equipment.serialNumber,
location: equipment.location,
status: equipment.status,
install_date: equipment.installDate,
last_maintenance_date: equipment.lastMaintenance,
next_maintenance_date: equipment.nextMaintenance,
maintenance_interval_days: equipment.maintenanceInterval,
efficiency_percentage: equipment.efficiency,
uptime_percentage: equipment.uptime,
energy_usage_kwh: equipment.energyUsage,
power_kw: equipment.specifications?.power,
capacity: equipment.specifications?.capacity,
weight_kg: equipment.specifications?.weight,
current_temperature: equipment.temperature,
target_temperature: equipment.targetTemperature,
is_active: equipment.is_active
};
}
/**
* Get all equipment for a tenant
*/
async getEquipment(
tenantId: string,
filters?: {
status?: string;
type?: string;
is_active?: boolean;
}
): Promise<Equipment[]> {
const params = new URLSearchParams();
if (filters?.status) params.append('status', filters.status);
if (filters?.type) params.append('type', filters.type);
if (filters?.is_active !== undefined) params.append('is_active', String(filters.is_active));
const queryString = params.toString();
const url = `${this.baseURL}/${tenantId}/production/equipment${queryString ? `?${queryString}` : ''}`;
const data: EquipmentListResponse = await apiClient.get(url, {
headers: { 'X-Tenant-ID': tenantId }
});
return data.equipment.map(eq => this.convertToEquipment(eq));
}
/**
* Get a specific equipment item
*/
async getEquipmentById(
tenantId: string,
equipmentId: string
): Promise<Equipment> {
const data: EquipmentResponse = await apiClient.get(
`${this.baseURL}/${tenantId}/production/equipment/${equipmentId}`,
{
headers: { 'X-Tenant-ID': tenantId }
}
);
return this.convertToEquipment(data);
}
/**
* Create a new equipment item
*/
async createEquipment(
tenantId: string,
equipmentData: Equipment
): Promise<Equipment> {
const apiData = this.convertToApiFormat(equipmentData);
const data: EquipmentResponse = await apiClient.post(
`${this.baseURL}/${tenantId}/production/equipment`,
apiData,
{
headers: { 'X-Tenant-ID': tenantId }
}
);
return this.convertToEquipment(data);
}
/**
* Update an equipment item
*/
async updateEquipment(
tenantId: string,
equipmentId: string,
equipmentData: Partial<Equipment>
): Promise<Equipment> {
const apiData = this.convertToApiFormat(equipmentData);
const data: EquipmentResponse = await apiClient.put(
`${this.baseURL}/${tenantId}/production/equipment/${equipmentId}`,
apiData,
{
headers: { 'X-Tenant-ID': tenantId }
}
);
return this.convertToEquipment(data);
}
/**
* Delete an equipment item
*/
async deleteEquipment(tenantId: string, equipmentId: string): Promise<void> {
await apiClient.delete(
`${this.baseURL}/${tenantId}/production/equipment/${equipmentId}`,
{
headers: { 'X-Tenant-ID': tenantId }
}
);
}
}
export const equipmentService = new EquipmentService();

View File

@@ -172,9 +172,11 @@ class TrainingService {
* Get WebSocket URL for real-time training updates
*/
getTrainingWebSocketUrl(tenantId: string, jobId: string): string {
const baseWsUrl = apiClient.getAxiosInstance().defaults.baseURL?.replace(/^http/, 'ws');
const baseWsUrl = apiClient.getAxiosInstance().defaults.baseURL
?.replace(/^http(s?):/, 'ws$1:'); // http: → ws:, https: → wss:
return `${baseWsUrl}/tenants/${tenantId}/training/jobs/${jobId}/live`;
}
/**
* Helper method to construct WebSocket connection