- Update all route documentation comments - Update README, env.example, and starter-docs - Update install.sh
328 lines
4.9 KiB
Markdown
328 lines
4.9 KiB
Markdown
# Cashumints.space – Admin Endpoints
|
||
|
||
This document defines the **admin-only API surface** of Cashumints.space.
|
||
|
||
These endpoints exist to:
|
||
|
||
* curate mint data safely
|
||
* correct discovery or URL issues
|
||
* resolve identity conflicts
|
||
* force recomputation when rules change
|
||
* debug the background system
|
||
|
||
Admin endpoints **never fabricate reality**. They annotate, correct routing, or trigger recomputation, but they do not delete historical data.
|
||
|
||
---
|
||
|
||
## General Rules
|
||
|
||
* Base path: `/admin`
|
||
* Authentication: `ADMIN_API_KEY` (static header)
|
||
* All admin actions are **audited**
|
||
* No admin endpoint deletes raw data
|
||
* Every mutation writes to the admin audit log
|
||
|
||
Audit log fields:
|
||
|
||
* admin_id
|
||
* action
|
||
* target
|
||
* before_state
|
||
* after_state
|
||
* timestamp
|
||
|
||
---
|
||
|
||
## POST /admin/mints
|
||
|
||
### Purpose
|
||
|
||
Manually add a mint to the system.
|
||
|
||
Used for:
|
||
|
||
* trusted bootstrap
|
||
* known operators
|
||
* recovery when auto-discovery fails
|
||
|
||
### Request body
|
||
|
||
```
|
||
{
|
||
"mint_url": "https://mint.example",
|
||
"notes": "optional internal notes"
|
||
}
|
||
```
|
||
|
||
### Logic
|
||
|
||
1. Normalize the URL
|
||
2. Check if URL already exists in `mint_urls`
|
||
3. If exists:
|
||
|
||
* return existing mint_id
|
||
4. If not:
|
||
|
||
* create new mint record
|
||
* status = `unknown`
|
||
* discovered_from = `manual`
|
||
* create mint_url entry (active)
|
||
5. Enqueue immediate probe job
|
||
|
||
### Response
|
||
|
||
```
|
||
{
|
||
"mint_id": "uuid",
|
||
"status": "unknown",
|
||
"message": "Mint added and scheduled for probing"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## POST /admin/mints/{mint_id}/urls
|
||
|
||
### Purpose
|
||
|
||
Manually attach an additional URL (clearnet, Tor, mirror) to an existing mint.
|
||
|
||
### Request body
|
||
|
||
```
|
||
{
|
||
"url": "http://example.onion",
|
||
"type": "tor",
|
||
"active": true
|
||
}
|
||
```
|
||
|
||
### Logic
|
||
|
||
1. Normalize URL
|
||
2. Ensure URL is not linked to another mint
|
||
3. Create mint_urls entry
|
||
4. Mark source = `admin`
|
||
5. Enqueue probe for new URL
|
||
|
||
### Rules
|
||
|
||
* URLs are never deleted
|
||
* If duplicate URL exists, return 409
|
||
|
||
---
|
||
|
||
## POST /admin/mints/merge
|
||
|
||
### Purpose
|
||
|
||
Merge two mints that represent the same operator.
|
||
|
||
### Request body
|
||
|
||
```
|
||
{
|
||
"source_mint_id": "uuid",
|
||
"target_mint_id": "uuid",
|
||
"reason": "Same pubkey, different URLs"
|
||
}
|
||
```
|
||
|
||
### Logic
|
||
|
||
1. Validate both mint IDs exist
|
||
2. Ensure source != target
|
||
3. Create merge record
|
||
4. Reassign all related data:
|
||
|
||
* mint_urls
|
||
* probes
|
||
* metadata history
|
||
* reviews
|
||
* rollups
|
||
5. Mark source mint as `merged`
|
||
6. Target mint becomes canonical
|
||
|
||
### Rules
|
||
|
||
* No data is deleted
|
||
* Merge is reversible
|
||
|
||
---
|
||
|
||
## POST /admin/mints/split
|
||
|
||
### Purpose
|
||
|
||
Undo a previous mint merge.
|
||
|
||
### Request body
|
||
|
||
```
|
||
{
|
||
"merge_id": "uuid"
|
||
}
|
||
```
|
||
|
||
### Logic
|
||
|
||
1. Load merge record
|
||
2. Restore original mint records
|
||
3. Reassign data back to original mint
|
||
4. Mark merge record as reverted
|
||
|
||
### Rules
|
||
|
||
* Only one split per merge
|
||
* Full restoration required
|
||
|
||
---
|
||
|
||
## POST /admin/mints/{mint_id}/disable
|
||
|
||
### Purpose
|
||
|
||
Hide a mint from public listings without deleting it.
|
||
|
||
### Logic
|
||
|
||
1. Set mint.visibility = `hidden`
|
||
2. Mint continues to be probed
|
||
3. Mint remains accessible by direct ID or URL
|
||
|
||
### Use cases
|
||
|
||
* scam submissions
|
||
* spam mints
|
||
* broken test instances
|
||
|
||
---
|
||
|
||
## POST /admin/mints/{mint_id}/enable
|
||
|
||
### Purpose
|
||
|
||
Re-enable a previously hidden mint.
|
||
|
||
### Logic
|
||
|
||
1. Set mint.visibility = `public`
|
||
2. No other state changes
|
||
|
||
---
|
||
|
||
## POST /admin/mints/{mint_id}/metadata/refresh
|
||
|
||
### Purpose
|
||
|
||
Force metadata fetch, bypassing the hourly limit.
|
||
|
||
### Logic
|
||
|
||
1. Enqueue metadata fetch job
|
||
2. Ignore METADATA_FETCH_INTERVAL
|
||
3. Metadata still validated normally
|
||
|
||
### Rules
|
||
|
||
* Does not fabricate metadata
|
||
* Failure does not erase existing metadata
|
||
|
||
---
|
||
|
||
## POST /admin/mints/{mint_id}/trust/recompute
|
||
|
||
### Purpose
|
||
|
||
Force trust score recomputation.
|
||
|
||
### Logic
|
||
|
||
1. Enqueue trust recompute job
|
||
2. Uses current rollups, reviews, metadata
|
||
3. Stores new score and breakdown
|
||
|
||
### Use cases
|
||
|
||
* scoring logic changes
|
||
* review moderation
|
||
* metadata correction
|
||
|
||
---
|
||
|
||
## GET /admin/jobs
|
||
|
||
### Purpose
|
||
|
||
Inspect the background job queue.
|
||
|
||
### Returns
|
||
|
||
```
|
||
[
|
||
{
|
||
"job_id": "uuid",
|
||
"type": "probe_mint",
|
||
"status": "pending",
|
||
"run_at": "timestamp",
|
||
"attempts": 2,
|
||
"last_error": null
|
||
}
|
||
]
|
||
```
|
||
|
||
### Rules
|
||
|
||
* Read-only
|
||
* No mutation
|
||
|
||
---
|
||
|
||
## GET /admin/system/metrics
|
||
|
||
### Purpose
|
||
|
||
High-level system health view.
|
||
|
||
### Returns
|
||
|
||
* total_mints
|
||
* online_mints
|
||
* offline_mints
|
||
* probes_last_minute
|
||
* failed_probes_last_minute
|
||
* job_backlog
|
||
* oldest_job_age_seconds
|
||
* database_size_mb
|
||
* worker_heartbeat
|
||
|
||
Used for operations and debugging.
|
||
|
||
---
|
||
|
||
## POST /admin/mints/{mint_id}/status/reset
|
||
|
||
### Purpose
|
||
|
||
Clear a stuck mint state caused by transient infrastructure issues.
|
||
|
||
### Logic
|
||
|
||
1. Reset consecutive_failures to 0
|
||
2. Clear offline_since
|
||
3. Do NOT change historical probes
|
||
4. Enqueue immediate probe
|
||
|
||
### Rules
|
||
|
||
* Does not fabricate uptime
|
||
* Next probe determines real status
|
||
|
||
---
|
||
|
||
## Final Admin Rule
|
||
|
||
Admins may correct **structure and routing**, but never rewrite **history or truth**.
|
||
|
||
If an action cannot be explained in the audit log, it does not belong in the admin API.
|