Skip to content

feat: overhaul landing page and implement dashboard components#67

Merged
Tinna23 merged 25 commits into
StellarCommons:mainfrom
BigBen-7:feat/nextjs-dashboard
May 25, 2026
Merged

feat: overhaul landing page and implement dashboard components#67
Tinna23 merged 25 commits into
StellarCommons:mainfrom
BigBen-7:feat/nextjs-dashboard

Conversation

@BigBen-7
Copy link
Copy Markdown
Contributor

@BigBen-7 BigBen-7 commented Mar 6, 2026

  • Refactored the landing page to include new components: Nav, Hero, StatStrip, MockDashboard, FeatureOrbit, HowItWorks, OpenSourceCTA, and Footer.
  • Created DashboardShell component to manage dashboard data fetching and state.
  • Added FeeChart, PercentileRow, RollingAverages, StatCards, TopBar, and TrendPanel components for displaying fee data and trends.
  • Implemented API utility functions for fetching current fees, fee history, fee trends, and insights.
  • Defined TypeScript types for API responses to ensure type safety across components.
  • Enhanced utility functions for formatting and styling data.

BigBen-7 and others added 5 commits March 6, 2026 15:12
- Refactored the landing page to include new components: Nav, Hero, StatStrip, MockDashboard, FeatureOrbit, HowItWorks, OpenSourceCTA, and Footer.
- Created DashboardShell component to manage dashboard data fetching and state.
- Added FeeChart, PercentileRow, RollingAverages, StatCards, TopBar, and TrendPanel components for displaying fee data and trends.
- Implemented API utility functions for fetching current fees, fee history, fee trends, and insights.
- Defined TypeScript types for API responses to ensure type safety across components.
- Enhanced utility functions for formatting and styling data.
Excludes target/, node_modules/, .next/, .env files, SQLite DBs,
OS/editor noise, and proptest-regressions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…caffold harness & simulation modules

Closes StellarCommons#91
Closes StellarCommons#92
Closes StellarCommons#93
Closes StellarCommons#94

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… delay

- ScenarioRotator cycles through a list of scenario names (StellarCommons#107)
- HorizonMock::rotate() advances to the next scenario via the rotator (StellarCommons#107)
- HorizonMock::with_delay_ms() / apply_delay() simulate network latency (StellarCommons#110)

Closes StellarCommons#107, StellarCommons#110
@Tinna23 Tinna23 marked this pull request as ready for review May 25, 2026 15:11
Tyler7x and others added 20 commits May 25, 2026 16:13
…k server

- log_request() prints timestamp, method, path, and active scenario name (StellarCommons#108)
- health_payload() returns {"status":"ok","scenario":"<current>"} for GET /health (StellarCommons#109)

Closes StellarCommons#108, StellarCommons#109
- Add analysis module with percentile, spike_classifier, rolling_window stubs (StellarCommons#95)
- Add cli module with replay, export, benchmark stubs (StellarCommons#96)
- Add shared types module with FeeRecord, Scenario, SimResult stubs (StellarCommons#97)
- Add DevkitError enum using thiserror; add thiserror dep to Cargo.toml (StellarCommons#98)

Closes StellarCommons#95, StellarCommons#96, StellarCommons#97, StellarCommons#98
… fixtures

- congested.json: high-load, p95 > 100,000 stroops, multiple spikes (StellarCommons#103)
- recovery.json: post-spike normalisation, fees declining to baseline (StellarCommons#104)
- spike.json: single 10x spike ledger then normal (StellarCommons#105)

Closes StellarCommons#103, StellarCommons#104, StellarCommons#105
…ons#106)

- HorizonMock now accepts a scenario_path and exposes fee_stats_payload()
- scenarios::load_from_file reads a JSON scenario from disk

Closes StellarCommons#106
…all scenario JSONs

- HorizonMock::with_error_rate() injects 500/503 at a configurable rate (StellarCommons#111)
- tests/harness_normal.rs: asserts normal scenario p50 fee_charged == 100 (StellarCommons#112)
- tests/harness_congested.rs: asserts congested p95 fee_charged > 100,000 (StellarCommons#113)
- Add max_fee object to congested, normal, recovery, spike scenario JSONs (StellarCommons#114)

Closes StellarCommons#111
Closes StellarCommons#112
Closes StellarCommons#113
Closes StellarCommons#114
- README.md: scope, boundary rules, module table, run instructions (StellarCommons#99)
- CONTRIBUTING.md: PR requirements, test expectations, code style, boundary rules (StellarCommons#100)
- horizon_mock.rs: HorizonMock serves canned GET /fee_stats response; add axum/tokio/serde_json deps (StellarCommons#101)
- scenarios/normal.json: baseline fee scenario, p50 ≈ 100 stroops (StellarCommons#102)

Closes StellarCommons#99
Closes StellarCommons#100
Closes StellarCommons#101
Closes StellarCommons#102
- Add optional seed to FeeModel and NetworkLoad for reproducible runs (StellarCommons#130)
- Add timestamp field to FeePoint spaced by ledger_interval_secs (StellarCommons#129)
- Unit tests for spike injection rate and fee values (StellarCommons#127)
- Unit tests for all four CongestionPredictor tiers (StellarCommons#128)
- Fix unclosed brace in scenarios/mod.rs
- Rename ScenarioRotator::next -> advance (clippy)
- Implement Percentile::nearest_rank (StellarCommons#136)
- Implement Percentile::linear_interpolation (StellarCommons#137)
- Document simulation module in README (StellarCommons#135)
…mmons#153, StellarCommons#154

- StellarCommons#151: Add FeeDistributionSummary struct and fee_distribution_summary()
  to percentile.rs returning min/max/mean/median/std_dev/p10-p99
- StellarCommons#152: Add iqr_outliers() to spike_classifier.rs flagging fees outside
  1.5x IQR as outlier indices
- StellarCommons#153: Add benches/percentile_bench.rs benchmarking nearest_rank,
  linear_interpolation, and fee_distribution_summary on 1M samples
- StellarCommons#154: Add benches/rolling_window_bench.rs benchmarking SMA/EMA/WMA
  on 100k samples; implement SMA/EMA/WMA in rolling_window.rs
- Update Cargo.toml to register percentile_bench and rolling_window_bench
- Add RollingWindow::ema() with configurable alpha (StellarCommons#147)
- Add RollingWindow::wma() with linear weighting (StellarCommons#148)
- Add Benchmark::compare_spike() printing SMA/EMA/WMA table (StellarCommons#149)
- Add integration tests for all three algorithms (StellarCommons#150)
- Implement SpikeSeverity enum and SpikeClassifier::classify() (StellarCommons#143)
  Thresholds: Low 2-5x, Medium 5-10x, High 10-50x, Critical >50x baseline
- Implement SpikeClassifier::detect() with duration_ledgers tracking (StellarCommons#144)
  Consecutive spike ledgers grouped into one SpikeEvent with max severity
- Implement RollingWindow::sma() and push() for configurable-window SMA (StellarCommons#146)
- Add 11 unit tests covering all severity levels, duration, and edge cases (StellarCommons#145)

Closes StellarCommons#143, StellarCommons#144, StellarCommons#145, StellarCommons#146
…larCommons#141 StellarCommons#142

- Define SpikeEvent struct with SpikeSeverity enum (closes StellarCommons#141)
- Implement SpikeClassifier::detect() for fee spike detection (closes StellarCommons#142)
- Write nearest-rank percentile tests p10/p50/p90/p95/p99 (closes StellarCommons#139)
- Write interpolation percentile tests with boundary and midpoint cases (closes StellarCommons#140)
Correctness
-----------
- horizon.rs: fix avg_fee field mapping — was reading Horizon 'mode' (statistical
  mode) instead of 'avg' (arithmetic mean); renamed serde rename to use actual avg
- api/fees.rs: fix 1h_pct always returning 0 — now compares short_term vs
  medium_term and medium_term vs long_term instead of a window against itself
- repository.rs: add "Moderate" to VALID_THRESHOLDS (was missing, breaking
  SpikeSeverity round-trips)

Security
--------
- api/alerts.rs: SSRF guard on webhook_url — rejects non-HTTPS URLs and
  loopback/private-range IPs (is_safe_webhook_url)
- middleware/rate_limit.rs: XFF only trusted from loopback peers (reverse-proxy
  guard); direct connections always use the TCP peer address

Performance / Reliability
--------------------------
- api/fees.rs: eliminate thundering herd — hold Mutex across staleness check
  and cache write so concurrent requests share one upstream fetch
- insights/horizon_adapter.rs: use pooled HorizonClient HTTP client instead of
  ephemeral reqwest::get() call; add http_client() getter on HorizonClient
- alerts/mod.rs: prune seen_spikes to active congestion window entries, bounding
  the HashSet to recent_spikes.len() and preventing unbounded growth
- middleware/rate_limit.rs: evict stale DashMap buckets when map exceeds 10k
  entries (120s cutoff)

Infrastructure
--------------
- main.rs: restructure router — /health outside rate limiter, /metrics outside
  API-key auth but still rate-limited, business routes get both
- main.rs: replace panic on invalid ALLOWED_ORIGINS with warn-and-skip
- api/headers.rs: replace non-stable DefaultHasher with FNV-1a for ETags so
  ETags survive server restarts with identical data
- api/fees.rs + headers.rs: replace .expect() on Response/HeaderValue builders
  with .unwrap_or_else() fallbacks
- metrics.rs: remove http_requests_total and http_request_duration (registered
  but never incremented — produced misleading zeros in Prometheus)

Code Quality
------------
- main.rs: remove #![allow(dead_code)] blanket suppression
- insights/mod.rs: remove #![allow(unused_imports)] blanket suppression
- scheduler.rs: delete run_fee_polling (never called; only
  run_fee_polling_with_retry is used in production)
- repository.rs: delete insert_snapshot (never called in production)
- services/horizon.rs: delete HorizonTransaction, HorizonOperation, four
  wrapper structs, fetch_latest_transaction, fetch_operations — all dead;
  HorizonFeeDataProvider has its own deserialization
- insights/tracker.rs: delete 6 unused methods (get_historical_extremes,
  get_all_historical_extremes, reset_current_period, has_current_data,
  historical_period_count, get_current_period_info)
- insights/calculator.rs: delete 3 unused methods (get_average_for_window,
  get_sample_count, has_sufficient_data)
- insights/detector.rs: delete get_historical_spikes
- insights/engine.rs: delete reset()
- repository.rs: replace silent filter_map ok()? drops with explicit
  tracing::error! logging for all three row-decode sites

Tests
-----
- Fix duplicate struct field initializers in api/fees.rs, services/horizon.rs,
  repository.rs tests (were compile errors masked by blanket allow)
- Fix duplicate JSON keys in horizon.rs test strings
- Update rate limit tests: different_ips_have_independent_buckets now uses
  ConnectInfo socket addresses; add xff_is_trusted_when_connection_is_from_loopback
- Update insights/tests.rs: replace reset() call with get_last_update assertion;
  replace has_current_data() with get_current_extremes().is_err()
- Update integration test: remove reference to deleted http_request_duration metric

All 193 tests pass.
# Conflicts:
#	.gitignore
#	Cargo.lock
#	packages/core/src/api/fees.rs
#	packages/core/src/api/headers.rs
#	packages/core/src/insights/calculator.rs
#	packages/core/src/insights/detector.rs
#	packages/core/src/insights/engine.rs
#	packages/core/src/insights/horizon_adapter.rs
#	packages/core/src/insights/mod.rs
#	packages/core/src/insights/tests.rs
#	packages/core/src/insights/tracker.rs
#	packages/core/src/main.rs
#	packages/core/src/metrics.rs
#	packages/core/src/repository.rs
#	packages/core/src/services/horizon.rs
#	packages/devkit/Cargo.toml
#	packages/devkit/benches/fee_model_bench.rs
#	packages/devkit/benches/rolling_window_bench.rs
#	packages/devkit/src/analysis/percentile.rs
#	packages/devkit/src/analysis/rolling_window.rs
#	packages/devkit/src/analysis/spike_classifier.rs
#	packages/devkit/src/harness/horizon_mock.rs
#	packages/devkit/src/harness/scenarios/mod.rs
#	packages/devkit/src/simulation/congestion_predictor.rs
#	packages/devkit/src/simulation/fee_model.rs
#	packages/devkit/src/simulation/network_load.rs
#	packages/devkit/tests/fee_model.rs
# Conflicts:
#	.gitignore
#	packages/devkit/Cargo.toml
#	packages/devkit/benches/fee_model_bench.rs
#	packages/devkit/benches/rolling_window_bench.rs
#	packages/devkit/src/analysis/percentile.rs
#	packages/devkit/src/analysis/rolling_window.rs
#	packages/devkit/src/analysis/spike_classifier.rs
#	packages/devkit/src/harness/horizon_mock.rs
#	packages/devkit/src/harness/scenarios/mod.rs
#	packages/devkit/src/simulation/congestion_predictor.rs
#	packages/devkit/src/simulation/fee_model.rs
#	packages/devkit/src/simulation/network_load.rs
#	packages/devkit/tests/fee_model.rs
- cargo fmt --all: fix formatting across core and devkit files
- clippy: remove unused imports in mod.rs and tests.rs
- clippy: replace map_or(false) with is_some_and in rate_limit.rs
- clippy: add dead_code allows on intentional public-API items
- devkit lib.rs: wire up missing module declarations (analysis, cli, harness, simulation)
- devkit Cargo.toml: add criterion dev-dep and bench targets

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Tinna23 Tinna23 merged commit 0ac47eb into StellarCommons:main May 25, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.