208 lines
2.9 KiB
Markdown
208 lines
2.9 KiB
Markdown
# Cashumints.space API – Logic
|
||
|
||
This document defines exactly how the system behaves internally.
|
||
|
||
---
|
||
|
||
## URL Normalization
|
||
|
||
All URLs are normalized before storage:
|
||
- force https if available
|
||
- lowercase hostname
|
||
- remove trailing slashes
|
||
- strip default ports
|
||
|
||
Normalized URLs are used for identity resolution.
|
||
|
||
---
|
||
|
||
## Mint Resolution
|
||
|
||
If request uses mint_id:
|
||
- direct lookup
|
||
|
||
If request uses URL:
|
||
- normalize
|
||
- lookup in mint_urls
|
||
- resolve mint_id
|
||
|
||
If URL unknown:
|
||
- return 404
|
||
|
||
---
|
||
|
||
## Probing Logic
|
||
|
||
### Probe Execution
|
||
|
||
- HTTP GET to mint endpoints
|
||
- strict timeout
|
||
- record RTT
|
||
- record status code or error
|
||
|
||
### State Transitions
|
||
|
||
On success:
|
||
- last_success_at = now
|
||
- consecutive_failures = 0
|
||
- status = online or degraded
|
||
- offline_since = null
|
||
|
||
On failure:
|
||
- last_failure_at = now
|
||
- consecutive_failures += 1
|
||
- if threshold reached:
|
||
- status = offline
|
||
- offline_since = now (if not set)
|
||
|
||
If offline longer than ABANDONED_AFTER:
|
||
- status = abandoned
|
||
|
||
---
|
||
|
||
## Metadata Fetch Logic
|
||
|
||
- Only fetch metadata after successful probe
|
||
- Only fetch if last_fetched_at older than 1 hour
|
||
|
||
Steps:
|
||
1. GET /v1/info
|
||
2. Validate against NUT‑06
|
||
3. Normalize payload
|
||
4. Compute hash
|
||
5. If hash changed:
|
||
- store history record
|
||
- update snapshot
|
||
|
||
Metadata is never deleted on failure.
|
||
|
||
---
|
||
|
||
## URL Discovery
|
||
|
||
URLs are discovered from:
|
||
- metadata.urls
|
||
- Nostr review references
|
||
- user submissions
|
||
|
||
New URLs:
|
||
- linked to existing mint
|
||
- marked active
|
||
|
||
Removed URLs:
|
||
- marked inactive
|
||
- never deleted
|
||
|
||
---
|
||
|
||
## Uptime Rollups
|
||
|
||
Raw probes are aggregated into windows:
|
||
- 1h, 24h, 7d, 30d
|
||
|
||
Computed values:
|
||
- uptime_pct
|
||
- avg_rtt
|
||
- p95_rtt
|
||
- downtime_seconds
|
||
- incident count
|
||
|
||
Rollups are recomputable at any time.
|
||
|
||
---
|
||
|
||
## Incident Detection
|
||
|
||
Incident starts when:
|
||
- status transitions online → offline
|
||
|
||
Incident ends when:
|
||
- first successful probe after offline
|
||
|
||
Incident data:
|
||
- start
|
||
- end
|
||
- duration
|
||
- severity
|
||
|
||
---
|
||
|
||
## Trust Score Calculation
|
||
|
||
Score range: 0–100
|
||
|
||
Components:
|
||
- uptime (max 40)
|
||
- speed (max 25)
|
||
- reviews (max 20)
|
||
- identity (max 10)
|
||
- penalties (up to ‑15)
|
||
|
||
Total score = sum, clamped.
|
||
|
||
Scores are recomputed:
|
||
- after rollups
|
||
- after new reviews
|
||
- periodically
|
||
|
||
---
|
||
|
||
## Review Aggregation
|
||
|
||
- One review per pubkey per mint per window
|
||
- Raw reviews stored forever
|
||
- Aggregates computed separately
|
||
|
||
---
|
||
|
||
## Pageviews
|
||
|
||
- Recorded per mint page load
|
||
- Session‑based
|
||
- No IP storage
|
||
|
||
Aggregated into:
|
||
- daily counts
|
||
- rolling windows
|
||
|
||
---
|
||
|
||
## Job System
|
||
|
||
Jobs stored in database:
|
||
- type
|
||
- payload
|
||
- run_at
|
||
- status
|
||
- retries
|
||
|
||
Workers:
|
||
- poll jobs
|
||
- lock atomically
|
||
- execute
|
||
- retry with backoff
|
||
|
||
---
|
||
|
||
## Failure Handling
|
||
|
||
- All failures are recorded
|
||
- No silent drops
|
||
- History preserved
|
||
|
||
---
|
||
|
||
## Determinism Guarantees
|
||
|
||
- Same input data always produces same rollups
|
||
- Same rollups always produce same trust score
|
||
- System can be fully rebuilt from raw tables
|
||
|
||
---
|
||
|
||
## Final Rule
|
||
|
||
If data is not stored, it does not exist.
|
||
If it exists, it must be explainable.
|
||
|