Repository navigation
Usage analytics, monitoring and alerting, and architecture docs (#1034, #1033, #1032) - #1054
Merged
Kingsman-99 merged 4 commits intoOct 22, 2026
Conversation
Track how the contract is used so dashboards can read current activity without replaying the event history. - Event tracking: analytics::record is called from the lifecycle event helpers (created, paid, released, refunded), so every code path that emits those events is counted. - Aggregation: lifetime UsageTotals in instance storage and per-UTC-day DailyUsage buckets in persistent storage, plus unique creator/payer counts. - Reporting: get_usage_report(from_day, to_day), up to 90 days, empty days included. - Dashboard and insights: get_usage_dashboard and get_usage_insights (averages, release/refund rates, week-over-week payment trend, busiest day). - Admin can switch recording off with set_analytics_enabled. Recording never emits events and counters saturate, so it cannot change the event stream or revert the operation being recorded. Closes Stellar-split#1034 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Watch the contract for unusual activity using the usage analytics aggregates and raise alerts. - Metric collection: MetricKind covers today's invoices, payments, payment volume, refunds and refund volume, the lifetime refund rate, and the size of the payment being processed. get_metrics returns a snapshot. - Alerting rules: up to 20 admin-managed AlertRules (metric, Above or Below, threshold, severity, cooldown, enabled). - Evaluation: rules for the affected metrics run after each recorded usage event; check_alerts (open to anyone) evaluates all rules so a keeper can catch conditions no event triggers. - Alert delivery: alerts are stored (newest 50 kept), emitted as (split, alert, rule_id) events, and pushed to an optional receiver contract's on_alert via try_invoke_contract. A failing receiver never reverts the triggering operation. - Monitoring analytics and dashboard: MonitoringStats (evaluations, alerts by severity, unacknowledged, failed deliveries) and get_monitoring_dashboard. Admin can acknowledge alerts. With no rules registered the payment path pays one instance read. Closes Stellar-split#1033 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Rewrite docs/ARCHITECTURE.md: workspace crate map, split contract layering and module map, storage model, state flows, cross-cutting concerns, design decisions and references. - Mermaid diagrams: system context, module layering, invoice record layout, invoice status state machine (matches valid_transition), payment/release and refund sequences, alert lifecycle. - Update stale content: directory layout, lib.rs size, the broken EVENTS.md link, refund flow (Pending -> Expired -> Refunded), and list module files in src/ that lib.rs does not declare. - Add ADRs 0002 (single contract with modules), 0003 (analytics from event helpers), 0004 (split invoice records), 0005 (alert delivery) and index them in docs/adr/README.md. Closes Stellar-split#1032 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Resolves three issues with one commit each:
feat(split): contract usage analyticsfeat(split): contract monitoring and alertingdocs: contract architecture and design decisions#1034: Contract usage analytics (
contracts/split/src/analytics.rs)docs/ISSUE_1034_USAGE_ANALYTICS.mdand ADR 0003.analytics::recordis called from the lifecycle event helpers inevents.rs(created, paid, released, refunded). Every path that emits those events is counted, with no per-call-site changes.UsageTotals(instance) and oneDailyUsagebucket per UTC day (persistent), plus unique creator/payer counts.get_usage_report(from_day, to_day), up to 90 days, empty days included.get_usage_dashboard(): totals, today and insights in one read.get_usage_insights(): average payment and invoice size, payments per invoice, release and refund rates, week-over-week payment trend, busiest day.Recording never emits events and counters saturate, so the event stream is unchanged and analytics can never revert a payment. Admins can switch recording off with
set_analytics_enabled.#1033: Monitoring and alerting (
contracts/split/src/monitoring.rs)docs/ISSUE_1033_MONITORING_ALERTING.mdand ADR 0005.MetricKind: today's invoices, payments, payment volume, refunds and refund volume; lifetime refund rate; current payment amount.get_metrics()returns a snapshot.AlertRules: metric,Above/Below, threshold, severity, cooldown, enabled.get_monitoring_dashboard(): stats, rules, metrics, 10 most recent alerts, receiver.(split, alert, rule_id)event, and an optional receiver contract'son_alert(alert)viatry_invoke_contract. A failing receiver never reverts the triggering operation.MonitoringStats: evaluations, alerts by severity, unacknowledged, failed deliveries, last alert time.Rules run automatically after each usage event (only those for affected metrics).
check_alerts()is open to anyone, so keepers can catch conditions no event triggers, such as "no payments today". With no rules registered, the payment path pays one instance read.#1032: Architecture documentation
docs/ARCHITECTURE.md: crate map,splitlayering and module map, storage model, state flows, cross-cutting concerns, design decisions and references.valid_transition), payment/release and refund sequences, alert lifecycle.lib.rssize, the brokenEVENTS.mdlink, and the refund flow.docs/adr/README.md.STORAGE_KEY_REGISTRY.md.Testing
The
splitcrate does not compile onmain. There are 53 existing errors from earlier merges (for example missingContractErrorvariants,StorageTier,ShardError, and the undeclaredwebhooksmodule), socargo test -p splitcannot run on any branch right now.What I ran:
cargo check -p split --lib --testsproduces exactly the same errors onmainand on each commit, and no warnings in the new code beyond the existing deprecated-publishwarning.analytics.rsandmonitoring.rsin a standalone harness with soroban-sdk 28 testutils. 7 tests passed, covering totals and unique counts, daily buckets, reports and bounds, the week-over-week trend, enable/disable, rule CRUD and limits, firing on usage, cooldown,check_alertsforBelowrules, acknowledgement, delivery to a working and a failing receiver, and history pruning. These tests found and fixed an overflow inget_usage_reportatu64::MAX.test_1034_*andtest_1033_*incontracts/split/src/test.rs. They type-check, and will run oncemainbuilds again.Notes
Cargo.lockonmainis missing thecharity-splitmember, so cargo rewrites it locally. That change is not included in this PR.🤖 Generated with Claude Code