First-time user experience fixes and platform contract repairs
FTUX fixes (Sprint 316-001): - Remove all hardcoded fake data from dashboard — fresh installs show honest setup guide instead of fake crisis data (5 fake criticals gone) - Curate advisory source defaults: 32 sources disabled by default (ecosystem, geo-restricted, exploit, hardware, mirror). ~43 core sources remain enabled. StellaOps Mirror no longer enabled at priority 1. - Filter Mirror-category sources from Create Domain wizard to prevent circular mirror-from-mirror chains - Add 404 catch-all route — unknown URLs show "Page Not Found" instead of silently rendering the dashboard - Fix arrow characters in release target path dropdown (? → →) - Add login credentials to quickstart documentation - Update Feature Matrix: 14 release orchestration features marked as shipped (was marked planned) Platform contract repairs (from prior session): - Add /api/v1/jobengine/quotas/summary endpoint on Platform - Fix gateway route prefix matching for /policy/shadow/* and /policy/simulations/* (regex routes instead of exact match) - Fix VexHub PostgresVexSourceRepository missing interface method - Fix advisory-vex-sources sweep text expectation - Fix mirror operator journey auth (session storage token extraction) Verified: 110/111 canonical routes passing (1 unrelated stale approval ref) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -121,6 +121,35 @@ public sealed class PostgresVexSourceRepository : IVexSourceRepository
|
||||
await dbContext.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public async Task UpdateFailureTrackingAsync(
|
||||
string sourceId,
|
||||
int consecutiveFailures,
|
||||
DateTimeOffset? nextEligiblePollAt,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
await using var connection = await _dataSource.OpenSystemConnectionAsync(cancellationToken);
|
||||
await using var dbContext = VexHubDbContextFactory.Create(connection, CommandTimeoutSeconds, GetSchemaName());
|
||||
|
||||
var entity = await dbContext.Sources.FirstOrDefaultAsync(s => s.SourceId == sourceId, cancellationToken);
|
||||
if (entity is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Store failure count in LastErrorMessage when failures > 0
|
||||
if (consecutiveFailures > 0)
|
||||
{
|
||||
entity.LastErrorMessage = $"consecutive_failures={consecutiveFailures}; {entity.LastErrorMessage}";
|
||||
}
|
||||
else
|
||||
{
|
||||
entity.LastErrorMessage = null;
|
||||
}
|
||||
|
||||
entity.UpdatedAt = DateTime.UtcNow;
|
||||
await dbContext.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<bool> DeleteAsync(string sourceId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
await using var connection = await _dataSource.OpenSystemConnectionAsync(cancellationToken);
|
||||
|
||||
Reference in New Issue
Block a user