113 lines
5.4 KiB
TypeScript
113 lines
5.4 KiB
TypeScript
import React from 'react';
|
|
import { Box, Typography, Button, Alert, Card, CardContent } from '@mui/material';
|
|
import { Edit as EditIcon } from '@mui/icons-material';
|
|
import type { VerdictConfigData } from '../types';
|
|
import { ConfigValue } from '../helpers';
|
|
|
|
interface Props {
|
|
verdictConfig: VerdictConfigData | null;
|
|
onEdit: () => void;
|
|
}
|
|
|
|
export const OverridesTab: React.FC<Props> = ({ verdictConfig, onEdit }) => (
|
|
<Box py={2}>
|
|
<Box display="flex" justifyContent="space-between" alignItems="flex-start" mb={2} gap={2}>
|
|
<Typography variant="body2" color="text.secondary">
|
|
Override rules that adjust the final risk score. Used by <code>applyOverrides()</code> and <code>applySynergyBonus()</code>.
|
|
Stored in <code>component_config(pipeline, verdict_config)</code>; saved values auto-sync to Redis.
|
|
</Typography>
|
|
<Button
|
|
startIcon={<EditIcon />}
|
|
variant="contained"
|
|
size="small"
|
|
disabled={!verdictConfig}
|
|
onClick={onEdit}
|
|
>
|
|
Edit Overrides & Synergy
|
|
</Button>
|
|
</Box>
|
|
|
|
{!verdictConfig ? (
|
|
<Alert severity="warning">
|
|
verdict_config not found in PostgreSQL or Redis. Re-run sync-redis or seed the row.
|
|
</Alert>
|
|
) : (
|
|
<Box display="flex" flexDirection="column" gap={2}>
|
|
<Card variant="outlined">
|
|
<CardContent>
|
|
<Typography variant="subtitle1" fontWeight={700} gutterBottom>
|
|
Synergy Bonus
|
|
</Typography>
|
|
<Typography variant="body2" color="text.secondary" mb={1}>
|
|
When multiple components show high risk (above threshold), adds a bonus to the final score.
|
|
</Typography>
|
|
<ConfigValue label="Enabled" value={verdictConfig.synergy.enabled} />
|
|
<ConfigValue label="Threshold (component score)" value={verdictConfig.synergy.threshold} />
|
|
<ConfigValue label="Bonus per component" value={`+${verdictConfig.synergy.bonus_per_component}%`} />
|
|
<ConfigValue label="Max bonus" value={`+${verdictConfig.synergy.max_bonus}%`} />
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<Typography variant="subtitle1" fontWeight={700}>Override Rules</Typography>
|
|
<Box display="grid" gridTemplateColumns="repeat(auto-fill, minmax(320px, 1fr))" gap={2}>
|
|
<Card variant="outlined">
|
|
<CardContent>
|
|
<Typography variant="subtitle2" fontWeight={700} gutterBottom>
|
|
False Claims
|
|
</Typography>
|
|
<ConfigValue label="Enabled" value={verdictConfig.overrides.false_claims.enabled} />
|
|
<ConfigValue label="Threshold (min false claims)" value={verdictConfig.overrides.false_claims.threshold} />
|
|
<ConfigValue label="Bonus per false claim" value={`+${verdictConfig.overrides.false_claims.bonus_per_claim}%`} />
|
|
<ConfigValue label="Max bonus" value={`+${verdictConfig.overrides.false_claims.max_bonus}%`} />
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<Card variant="outlined">
|
|
<CardContent>
|
|
<Typography variant="subtitle2" fontWeight={700} gutterBottom>
|
|
Severe Techniques
|
|
</Typography>
|
|
<ConfigValue label="Enabled" value={verdictConfig.overrides.severe_techniques.enabled} />
|
|
<ConfigValue label="Threshold (min severe count)" value={verdictConfig.overrides.severe_techniques.threshold} />
|
|
<ConfigValue label="Bonus" value={`+${verdictConfig.overrides.severe_techniques.bonus}%`} />
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<Card variant="outlined">
|
|
<CardContent>
|
|
<Typography variant="subtitle2" fontWeight={700} gutterBottom>
|
|
Undisclosed AI
|
|
</Typography>
|
|
<ConfigValue label="Enabled" value={verdictConfig.overrides.undisclosed_ai.enabled} />
|
|
<ConfigValue label="Bonus" value={`+${verdictConfig.overrides.undisclosed_ai.bonus}%`} />
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<Card variant="outlined">
|
|
<CardContent>
|
|
<Typography variant="subtitle2" fontWeight={700} gutterBottom>
|
|
Untrusted Domain
|
|
</Typography>
|
|
<ConfigValue label="Enabled" value={verdictConfig.overrides.untrusted_domain.enabled} />
|
|
<ConfigValue label="Untrusted bonus" value={`+${verdictConfig.overrides.untrusted_domain.untrusted_bonus}%`} />
|
|
<ConfigValue label="Suspicious bonus" value={`+${verdictConfig.overrides.untrusted_domain.suspicious_bonus}%`} />
|
|
<ConfigValue label="Blacklisted bonus" value={`+${verdictConfig.overrides.untrusted_domain.blacklisted_bonus}%`} />
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<Card variant="outlined">
|
|
<CardContent>
|
|
<Typography variant="subtitle2" fontWeight={700} gutterBottom>
|
|
Domain Red Flags
|
|
</Typography>
|
|
<ConfigValue label="Enabled" value={verdictConfig.overrides.domain_red_flags.enabled} />
|
|
<ConfigValue label="Threshold (min flags)" value={verdictConfig.overrides.domain_red_flags.threshold} />
|
|
<ConfigValue label="Bonus per flag" value={`+${verdictConfig.overrides.domain_red_flags.bonus_per_flag}%`} />
|
|
<ConfigValue label="Max bonus" value={`+${verdictConfig.overrides.domain_red_flags.max_bonus}%`} />
|
|
</CardContent>
|
|
</Card>
|
|
</Box>
|
|
</Box>
|
|
)}
|
|
</Box>
|
|
);
|