RouteForge v0.9.1-rc
Modernes read-only Operator-Tool für Preflight Checks von ASN, Prefix, RPKI und Registry/IRR.
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index f434aac..b6516ac 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,3 +1,7 @@ +## v0.9.1-rc (2026-05-21) + +- UI Cleanup & English-only polish + ## v0.9.1-rc (2026-05-20) ### Motivation diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index cf7e8a4..e1a4d70 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -75,7 +75,7 @@ export default function App() { if (authMode === 'error') return
Modernes read-only Operator-Tool für Preflight Checks von ASN, Prefix, RPKI und Registry/IRR.
alembic current, alembic heads, alembic upgrade head.Current user: {currentUser?.username || '-'}
Role: {currentUser?.role || '-'}
Read-only: {readOnlyLabel}
Mode: {system?.demo_mode ? 'DEMO' : 'LIVE'}
Demo mode is active.
}alembic current, alembic heads, alembic upgrade head.| {r.summary} |
| {r.summary} |
alembic current, alembic heads, alembic upgrade head.Version: v0.9.1
RouteForge is a read-only routing operations console for validation workflows.
Read-only: All checks are non-destructive.
Version: v0.9.1-rc
RPKI bewertet Prefix-Origin-Paare, nicht die ASN isoliert.
setAsn(e.target.value)} />Extrahierte Prefixe: {extracted.length}
}{result && !batchAvailable &&RPKI-Batch nicht möglich
{rpkiBatch?.message || 'Für diese ASN konnten keine auswertbaren Prefixe gefunden werden.'}
Reason: {rpkiBatch?.reason_code || 'unknown'} · Prefix count: {rpkiBatch?.prefix_count ?? 0}
Prüfung läuft…
}{error &&{error.message}
}RPKI evaluates prefix-origin pairs, not an ASN in isolation.
setAsn(e.target.value)} />Extracted prefixes: {extracted.length}
}{result && !batchAvailable &&RPKI batch unavailable
{rpkiBatch?.message || 'No evaluable prefixes were found for this ASN.'}
Reason: {rpkiBatch?.reason_code || 'unknown'} · Prefix count: {rpkiBatch?.prefix_count ?? 0}
Running check…
}{error &&{error.message}
}| Time | User | Action | Target | IP | User Agent | Details |
|---|---|---|---|---|---|---|
| {a.created_at} | {a.username || a.user_id || '-'} | {a.action} | {a.target_type || '-'}:{a.target_id || '-'} | {a.ip_address || '-'} | {a.user_agent || '-'} | {JSON.stringify(a.details_json || {}, null, 2)} |
Viewer role: Seite ist sichtbar, aber Checks dürfen nicht ausgeführt werden.
} + {!canRun &&Viewer role: this page is visible, but checks cannot be run.
} setPrefix(e.target.value)} /> setExpectedOriginAs(e.target.value)} /> diff --git a/frontend/src/components/ChangeCasesView.tsx b/frontend/src/components/ChangeCasesView.tsx index d25d284..b955a43 100644 --- a/frontend/src/components/ChangeCasesView.tsx +++ b/frontend/src/components/ChangeCasesView.tsx @@ -63,7 +63,7 @@ export function ChangeCasesView({ role }: { role: UserRole }) { } - {loading ?| Title | Status | Owner | Created | Updated |
|---|---|---|---|---|
| {i.title} | {i.created_by_user_id ?? '—'} | {new Date(i.created_at).toLocaleString()} | {new Date(i.updated_at).toLocaleString()} |
| Title | Status | Owner | Created | Updated |
|---|---|---|---|---|
| {i.title} | {i.created_by_user_id ?? '—'} | {new Date(i.created_at).toLocaleString()} | {new Date(i.updated_at).toLocaleString()} |
No reports for this Change Case yet.
:| Type | Status | Summary | Created | Open |
|---|---|---|---|---|
| {r.check_type} | {r.status} | {r.summary} | {new Date(r.created_at).toLocaleString()} |
No reports yet.
:| Type | Status | Summary | Created | Open |
|---|---|---|---|---|
| {r.check_type} | {r.status} | {r.summary} | {new Date(r.created_at).toLocaleString()} |
Origin-AS empfohlen für vollständige Bewertung.
Prüfung läuft…
}{error &&{error.message}
}Provide Origin AS for a complete evaluation.
Running check…
}{error &&{error.message}
}Prüfung läuft…
} + {loading &&Running check…
} {error &&{error.message}
} {result &&Check-Typ: {checkType}
Resource: {report.input?.prefix || report.input?.asn || '-'}
+Check type: {checkType}
Resource: {report.input?.prefix || report.input?.asn || '-'}
Origin-AS: {report.input?.origin_as || report.input?.planned_origin_as || '-'}
Holder: {holder}
Preflight Decision: {preflightDecision}
} @@ -79,8 +79,8 @@ export function ReportView({ report }: { report: CheckResponse }) {Erklärung: {report.explanation || '-'}
Risiko: {report.risk || '-'}
+Explanation: {report.explanation || '-'}
Risk: {report.risk || '-'}
| Source | Endpoint | Status | Freshness | Attempts | Retries | Fallback | Stale Cache | Duration | Cache | Age | TTL | Message |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| {d.name || '-'} | {d.endpoint || '-'} | {d.freshness || 'UNKNOWN'} | {typeof d.attempts === 'number' ? d.attempts : '-'} | {typeof d.retry_count === 'number' ? d.retry_count : '-'} | {d.fallback_used === true ? 'yes' : d.fallback_used === false ? 'no' : '-'} | {d.stale_cache_used === true ? 'yes' : d.stale_cache_used === false ? 'no' : '-'} | {typeof d.duration_ms === 'number' ? `${d.duration_ms} ms` : '-'} | {d.cached === true ? 'HIT' : d.cached === false ? 'MISS' : '-'} | {typeof d.cache_age_seconds === 'number' ? formatDurationSeconds(d.cache_age_seconds) : 'Unknown'} | {typeof d.cache_ttl_seconds === 'number' ? formatDurationSeconds(d.cache_ttl_seconds) : 'Unknown'} | {d.message || '-'} {d.fallback_used === true && Live request failed. RouteForge used cached data. The result may be outdated. }{d.status === 'RATE_LIMITED' && Rate limited by data source. } |
{JSON.stringify({ input: report.input, holder: details.resource_holder, warnings: details.warnings, source_errors: details.source_errors }, null, 2)}{JSON.stringify({ input: report.input, holder: details.resource_holder, warnings: details.warnings, source_errors: details.source_errors }, null, 2)}| Status | Prefix | Summary |
|---|---|---|
| {item.prefix} | {item.summary || '-'} |
{rpkiBatch?.message || report.explanation || 'Keine Daten verfügbar.'}
{rpkiBatch.message}
{rpkiBatch?.message || report.explanation || 'No data available.'}
{rpkiBatch.message}
Export ist erst verfügbar, nachdem der Report gespeichert wurde.
} + {!hasReportId &&Export is available after the report is saved.
}Read-only: RouteForge erstellt, ändert oder löscht keine ROAs.
+Read-only: RouteForge does not create, update, or delete ROAs.
Viewer können Checks nicht ausführen.
} - {loading &&Prüfung läuft…
} + {!canRun &&Viewer role cannot run checks.
} + {loading &&Running check…
} {error &&{error.message}
}| User | Role | Status | Actions |
|---|---|---|---|
| {u.username} {u.email || '—'} | {u.role} | {u.is_active ? 'active' : 'inactive'} | Password resets via API/admin procedure only. |
| User | Role | Status | Actions |
|---|---|---|---|
| {u.username} {u.email || '—'} | {u.role} | {u.is_active ? 'active' : 'inactive'} | Password resets via API/admin procedure only. |
| created_at | previous_status | status | changed | summary | report_id |
|---|---|---|---|---|---|
| {r.created_at} | {r.previous_status ?? 'n/a'} | {r.status} | {String(r.changed)} | {r.summary} | {r.report_id ? {r.report_id} : 'n/a'} |
| created_at | previous_status | status | changed | summary | report_id |
|---|---|---|---|---|---|
| {r.created_at} | {r.previous_status ?? 'n/a'} | {r.status} | {String(r.changed)} | {r.summary} | {r.report_id ? {r.report_id} : 'n/a'} |