feat(frontend): modèle et service Recommendations (liste, détail, génération)
Types alignés sur RecommendationResponse et RecommendationGenerationResponse
du backend. RecommendationsService couvre GET /recommendations,
GET /recommendations/{id} et POST /recommendations/generate?site_id= (réservé
admin côté API). recommendation-presentation.ts traduit les sept règles connues
du moteur et retombe sur la référence brute pour une règle inconnue, la
politique de renommage en -v2 de l'ADR 0006 l'impose.
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
import { libelleRegle, tonRegle } from './recommendation-presentation';
|
||||
|
||||
describe('recommendation-presentation', () => {
|
||||
it('traduit les sept règles connues du moteur', () => {
|
||||
expect(libelleRegle('spike-delestage-v1')).toBe('Délestage');
|
||||
expect(libelleRegle('threshold-reduction-v1')).toBe('Réduction de puissance');
|
||||
expect(libelleRegle('outage-secours-v1')).toBe('Alimentation de secours');
|
||||
expect(libelleRegle('sensor-maintenance-v1')).toBe('Maintenance capteur');
|
||||
expect(libelleRegle('anomaly-verification-v1')).toBe('Vérification');
|
||||
expect(libelleRegle('escalade-astreinte-v1')).toBe('Escalade astreinte');
|
||||
expect(libelleRegle('contrat-puissance-v1')).toBe('Contrat de puissance');
|
||||
});
|
||||
|
||||
it('affiche telle quelle une référence de règle inconnue', () => {
|
||||
expect(libelleRegle('spike-delestage-v2')).toBe('spike-delestage-v2');
|
||||
});
|
||||
|
||||
it("réserve le ton critique à l'escalade vers l'astreinte", () => {
|
||||
expect(tonRegle('escalade-astreinte-v1')).toBe('critical');
|
||||
expect(tonRegle('spike-delestage-v1')).toBe('neutral');
|
||||
expect(tonRegle('inconnue-v9')).toBe('neutral');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,23 @@
|
||||
import { BadgeTone } from '../components/ui/badge/badge';
|
||||
|
||||
// Contrainte : une règle dont le sens change reçoit un suffixe -v2 côté backend (ADR 0006) ;
|
||||
// une référence inconnue s'affiche donc telle quelle plutôt que de casser la vue.
|
||||
const LIBELLE_PAR_REGLE: Record<string, string> = {
|
||||
'spike-delestage-v1': 'Délestage',
|
||||
'threshold-reduction-v1': 'Réduction de puissance',
|
||||
'outage-secours-v1': 'Alimentation de secours',
|
||||
'sensor-maintenance-v1': 'Maintenance capteur',
|
||||
'anomaly-verification-v1': 'Vérification',
|
||||
'escalade-astreinte-v1': 'Escalade astreinte',
|
||||
'contrat-puissance-v1': 'Contrat de puissance',
|
||||
};
|
||||
|
||||
const REGLE_ESCALADE = 'escalade-astreinte-v1';
|
||||
|
||||
export function libelleRegle(reference: string): string {
|
||||
return LIBELLE_PAR_REGLE[reference] ?? reference;
|
||||
}
|
||||
|
||||
export function tonRegle(reference: string): BadgeTone {
|
||||
return reference === REGLE_ESCALADE ? 'critical' : 'neutral';
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
export interface Recommendation {
|
||||
recommendation_id: number;
|
||||
alert_id: number;
|
||||
action: string;
|
||||
explanation: string;
|
||||
rule_reference: string;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface RecommendationGenerationReport {
|
||||
alerts_examined: number;
|
||||
recommendations_created: number;
|
||||
already_present: number;
|
||||
}
|
||||
Reference in New Issue
Block a user