Update documentation and routes to remove /v1 prefix
- Update all route documentation comments - Update README, env.example, and starter-docs - Update install.sh
This commit is contained in:
10
README.md
10
README.md
@@ -118,8 +118,6 @@ Interactive API documentation is available at:
|
||||
|
||||
## API Endpoints
|
||||
|
||||
Base URL: `/v1`
|
||||
|
||||
### System
|
||||
|
||||
| Method | Endpoint | Description |
|
||||
@@ -309,21 +307,21 @@ All admin actions are audited. Never deletes raw data.
|
||||
|
||||
```bash
|
||||
# Add a mint manually
|
||||
curl -X POST http://localhost:3000/v1/admin/mints \
|
||||
curl -X POST http://localhost:3000/admin/mints \
|
||||
-H "X-Admin-Api-Key: $ADMIN_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"mint_url": "https://mint.example.com", "notes": "Trusted operator"}'
|
||||
|
||||
# Get system metrics
|
||||
curl http://localhost:3000/v1/admin/system/metrics \
|
||||
curl http://localhost:3000/admin/system/metrics \
|
||||
-H "X-Admin-Api-Key: $ADMIN_API_KEY"
|
||||
|
||||
# Force trust recalculation
|
||||
curl -X POST http://localhost:3000/v1/admin/mints/{mint_id}/trust/recompute \
|
||||
curl -X POST http://localhost:3000/admin/mints/{mint_id}/trust/recompute \
|
||||
-H "X-Admin-Api-Key: $ADMIN_API_KEY"
|
||||
|
||||
# View audit log
|
||||
curl http://localhost:3000/v1/admin/audit \
|
||||
curl http://localhost:3000/admin/audit \
|
||||
-H "X-Admin-Api-Key: $ADMIN_API_KEY"
|
||||
```
|
||||
|
||||
|
||||
@@ -163,7 +163,7 @@ echo " sudo journalctl -u cashumints-api -f"
|
||||
echo " sudo journalctl -u cashumints-workers -f"
|
||||
echo ""
|
||||
echo "5. Test API:"
|
||||
echo " curl http://localhost:3000/v1/health"
|
||||
echo " curl http://localhost:3000/health"
|
||||
echo ""
|
||||
if command -v nginx &> /dev/null; then
|
||||
echo "6. Setup SSL (Let's Encrypt):"
|
||||
|
||||
@@ -129,10 +129,10 @@ PLAUSIBLE_SITE_ID=cashumints.space
|
||||
# npm run workers
|
||||
#
|
||||
# Test health:
|
||||
# curl http://localhost:3000/v1/health
|
||||
# curl http://localhost:3000/health
|
||||
#
|
||||
# Test admin (requires ADMIN_API_KEY):
|
||||
# curl -H "X-Admin-Api-Key: YOUR_KEY" http://localhost:3000/v1/admin/system/metrics
|
||||
# curl -H "X-Admin-Api-Key: YOUR_KEY" http://localhost:3000/admin/system/metrics
|
||||
#
|
||||
# View docs:
|
||||
# open http://localhost:3000/docs
|
||||
|
||||
@@ -35,7 +35,7 @@ router.use(adminAuth);
|
||||
// ==========================================
|
||||
|
||||
/**
|
||||
* POST /v1/admin/mints
|
||||
* POST /admin/mints
|
||||
* Manually add a mint to the system
|
||||
*/
|
||||
router.post('/mints', auditLog('create_mint', 'mint'), (req, res) => {
|
||||
@@ -59,7 +59,7 @@ router.post('/mints', auditLog('create_mint', 'mint'), (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* POST /v1/admin/mints/:mint_id/urls
|
||||
* POST /admin/mints/:mint_id/urls
|
||||
* Add URL to existing mint
|
||||
*/
|
||||
router.post('/mints/:mint_id/urls', auditLog('add_url', 'mint'), (req, res) => {
|
||||
@@ -97,7 +97,7 @@ router.post('/mints/:mint_id/urls', auditLog('add_url', 'mint'), (req, res) => {
|
||||
// ==========================================
|
||||
|
||||
/**
|
||||
* POST /v1/admin/mints/merge
|
||||
* POST /admin/mints/merge
|
||||
* Merge two mints
|
||||
*/
|
||||
router.post('/mints/merge', auditLog('merge_mints', 'mint'), (req, res) => {
|
||||
@@ -132,7 +132,7 @@ router.post('/mints/merge', auditLog('merge_mints', 'mint'), (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* POST /v1/admin/mints/split
|
||||
* POST /admin/mints/split
|
||||
* Undo a mint merge
|
||||
*/
|
||||
router.post('/mints/split', auditLog('split_mints', 'mint'), (req, res) => {
|
||||
@@ -167,7 +167,7 @@ router.post('/mints/split', auditLog('split_mints', 'mint'), (req, res) => {
|
||||
// ==========================================
|
||||
|
||||
/**
|
||||
* POST /v1/admin/mints/:mint_id/disable
|
||||
* POST /admin/mints/:mint_id/disable
|
||||
* Hide a mint from public listings
|
||||
*/
|
||||
router.post('/mints/:mint_id/disable', auditLog('disable_mint', 'mint'), (req, res) => {
|
||||
@@ -196,7 +196,7 @@ router.post('/mints/:mint_id/disable', auditLog('disable_mint', 'mint'), (req, r
|
||||
});
|
||||
|
||||
/**
|
||||
* POST /v1/admin/mints/:mint_id/enable
|
||||
* POST /admin/mints/:mint_id/enable
|
||||
* Re-enable a hidden mint
|
||||
*/
|
||||
router.post('/mints/:mint_id/enable', auditLog('enable_mint', 'mint'), (req, res) => {
|
||||
@@ -227,7 +227,7 @@ router.post('/mints/:mint_id/enable', auditLog('enable_mint', 'mint'), (req, res
|
||||
// ==========================================
|
||||
|
||||
/**
|
||||
* POST /v1/admin/mints/:mint_id/metadata/refresh
|
||||
* POST /admin/mints/:mint_id/metadata/refresh
|
||||
* Force metadata fetch
|
||||
*/
|
||||
router.post('/mints/:mint_id/metadata/refresh', auditLog('force_metadata', 'mint'), (req, res) => {
|
||||
@@ -251,7 +251,7 @@ router.post('/mints/:mint_id/metadata/refresh', auditLog('force_metadata', 'mint
|
||||
});
|
||||
|
||||
/**
|
||||
* POST /v1/admin/mints/:mint_id/trust/recompute
|
||||
* POST /admin/mints/:mint_id/trust/recompute
|
||||
* Force trust score recomputation
|
||||
*/
|
||||
router.post('/mints/:mint_id/trust/recompute', auditLog('force_trust', 'mint'), (req, res) => {
|
||||
@@ -275,7 +275,7 @@ router.post('/mints/:mint_id/trust/recompute', auditLog('force_trust', 'mint'),
|
||||
});
|
||||
|
||||
/**
|
||||
* POST /v1/admin/mints/:mint_id/status/reset
|
||||
* POST /admin/mints/:mint_id/status/reset
|
||||
* Reset stuck mint status
|
||||
*/
|
||||
router.post('/mints/:mint_id/status/reset', auditLog('reset_status', 'mint'), (req, res) => {
|
||||
@@ -306,7 +306,7 @@ router.post('/mints/:mint_id/status/reset', auditLog('reset_status', 'mint'), (r
|
||||
// ==========================================
|
||||
|
||||
/**
|
||||
* GET /v1/admin/jobs
|
||||
* GET /admin/jobs
|
||||
* Inspect the job queue
|
||||
*/
|
||||
router.get('/jobs', (req, res) => {
|
||||
@@ -333,7 +333,7 @@ router.get('/jobs', (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/admin/system/metrics
|
||||
* GET /admin/system/metrics
|
||||
* System health metrics
|
||||
*/
|
||||
router.get('/system/metrics', (req, res) => {
|
||||
@@ -347,7 +347,7 @@ router.get('/system/metrics', (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/admin/audit
|
||||
* GET /admin/audit
|
||||
* Get audit log entries
|
||||
*/
|
||||
router.get('/audit', (req, res) => {
|
||||
@@ -380,7 +380,7 @@ router.get('/audit', (req, res) => {
|
||||
// ==========================================
|
||||
|
||||
/**
|
||||
* POST /v1/admin/mints/:mint_id/probe
|
||||
* POST /admin/mints/:mint_id/probe
|
||||
* Force probe a mint immediately
|
||||
*/
|
||||
router.post('/mints/:mint_id/probe', auditLog('force_probe', 'mint'), (req, res) => {
|
||||
@@ -408,7 +408,7 @@ router.post('/mints/:mint_id/probe', auditLog('force_probe', 'mint'), (req, res)
|
||||
// ==========================================
|
||||
|
||||
/**
|
||||
* GET /v1/admin/mints/:mint_id/visibility
|
||||
* GET /admin/mints/:mint_id/visibility
|
||||
* Get mint visibility status
|
||||
*/
|
||||
router.get('/mints/:mint_id/visibility', (req, res) => {
|
||||
@@ -450,7 +450,7 @@ function resolveMintFromUrl(req, res) {
|
||||
}
|
||||
|
||||
/**
|
||||
* POST /v1/admin/mints/by-url/disable
|
||||
* POST /admin/mints/by-url/disable
|
||||
* Disable mint by URL
|
||||
*/
|
||||
router.post('/mints/by-url/disable', auditLog('disable_mint', 'mint'), (req, res) => {
|
||||
@@ -474,7 +474,7 @@ router.post('/mints/by-url/disable', auditLog('disable_mint', 'mint'), (req, res
|
||||
});
|
||||
|
||||
/**
|
||||
* POST /v1/admin/mints/by-url/enable
|
||||
* POST /admin/mints/by-url/enable
|
||||
* Enable mint by URL
|
||||
*/
|
||||
router.post('/mints/by-url/enable', auditLog('enable_mint', 'mint'), (req, res) => {
|
||||
@@ -496,7 +496,7 @@ router.post('/mints/by-url/enable', auditLog('enable_mint', 'mint'), (req, res)
|
||||
});
|
||||
|
||||
/**
|
||||
* POST /v1/admin/mints/by-url/metadata/refresh
|
||||
* POST /admin/mints/by-url/metadata/refresh
|
||||
* Force metadata refresh by URL
|
||||
*/
|
||||
router.post('/mints/by-url/metadata/refresh', auditLog('force_metadata', 'mint'), (req, res) => {
|
||||
@@ -516,7 +516,7 @@ router.post('/mints/by-url/metadata/refresh', auditLog('force_metadata', 'mint')
|
||||
});
|
||||
|
||||
/**
|
||||
* POST /v1/admin/mints/by-url/trust/recompute
|
||||
* POST /admin/mints/by-url/trust/recompute
|
||||
* Force trust recompute by URL
|
||||
*/
|
||||
router.post('/mints/by-url/trust/recompute', auditLog('force_trust', 'mint'), (req, res) => {
|
||||
@@ -536,7 +536,7 @@ router.post('/mints/by-url/trust/recompute', auditLog('force_trust', 'mint'), (r
|
||||
});
|
||||
|
||||
/**
|
||||
* POST /v1/admin/mints/by-url/status/reset
|
||||
* POST /admin/mints/by-url/status/reset
|
||||
* Reset mint status by URL
|
||||
*/
|
||||
router.post('/mints/by-url/status/reset', auditLog('reset_status', 'mint'), (req, res) => {
|
||||
@@ -558,7 +558,7 @@ router.post('/mints/by-url/status/reset', auditLog('reset_status', 'mint'), (req
|
||||
});
|
||||
|
||||
/**
|
||||
* POST /v1/admin/mints/by-url/probe
|
||||
* POST /admin/mints/by-url/probe
|
||||
* Force probe by URL
|
||||
*/
|
||||
router.post('/mints/by-url/probe', auditLog('force_probe', 'mint'), (req, res) => {
|
||||
@@ -578,7 +578,7 @@ router.post('/mints/by-url/probe', auditLog('force_probe', 'mint'), (req, res) =
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/admin/mints/by-url/visibility
|
||||
* GET /admin/mints/by-url/visibility
|
||||
* Get mint visibility by URL
|
||||
*/
|
||||
router.get('/mints/by-url/visibility', (req, res) => {
|
||||
|
||||
@@ -82,7 +82,7 @@ function resolveMintMiddleware(req, res, next) {
|
||||
// ==========================================
|
||||
|
||||
/**
|
||||
* GET /v1/mints
|
||||
* GET /mints
|
||||
* List all mints with optional filters
|
||||
*/
|
||||
router.get('/', (req, res) => {
|
||||
@@ -118,7 +118,7 @@ router.get('/', (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* POST /v1/mints/submit
|
||||
* POST /mints/submit
|
||||
*/
|
||||
router.post('/submit', (req, res) => {
|
||||
try {
|
||||
@@ -141,7 +141,7 @@ router.post('/submit', (req, res) => {
|
||||
// ==========================================
|
||||
|
||||
/**
|
||||
* GET /v1/mints/activity
|
||||
* GET /mints/activity
|
||||
* Get mint ecosystem activity overview
|
||||
*/
|
||||
router.get('/activity', (req, res) => {
|
||||
@@ -155,7 +155,7 @@ router.get('/activity', (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/recent
|
||||
* GET /mints/recent
|
||||
* Get recently added mints
|
||||
*/
|
||||
router.get('/recent', (req, res) => {
|
||||
@@ -176,7 +176,7 @@ router.get('/recent', (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/updated
|
||||
* GET /mints/updated
|
||||
* Get recently updated mints
|
||||
*/
|
||||
router.get('/updated', (req, res) => {
|
||||
@@ -191,7 +191,7 @@ router.get('/updated', (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/popular
|
||||
* GET /mints/popular
|
||||
* Get popular mints by views
|
||||
*/
|
||||
router.get('/popular', async(req, res) => {
|
||||
@@ -212,7 +212,7 @@ router.get('/popular', async(req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/trending
|
||||
* GET /mints/trending
|
||||
* Get trending mints by view velocity
|
||||
*/
|
||||
router.get('/trending', async(req, res) => {
|
||||
@@ -254,7 +254,7 @@ router.get('/trending', async(req, res) => {
|
||||
// ==========================================
|
||||
|
||||
/**
|
||||
* GET /v1/mints/by-url
|
||||
* GET /mints/by-url
|
||||
*/
|
||||
router.get('/by-url', (req, res) => {
|
||||
try {
|
||||
@@ -285,7 +285,7 @@ router.get('/by-url', (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/by-url/urls
|
||||
* GET /mints/by-url/urls
|
||||
*/
|
||||
router.get('/by-url/urls', (req, res) => {
|
||||
try {
|
||||
@@ -304,7 +304,7 @@ router.get('/by-url/urls', (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/by-url/metadata
|
||||
* GET /mints/by-url/metadata
|
||||
*/
|
||||
router.get('/by-url/metadata', (req, res) => {
|
||||
try {
|
||||
@@ -338,7 +338,7 @@ router.get('/by-url/metadata', (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/by-url/metadata/history
|
||||
* GET /mints/by-url/metadata/history
|
||||
*/
|
||||
router.get('/by-url/metadata/history', (req, res) => {
|
||||
try {
|
||||
@@ -355,7 +355,7 @@ router.get('/by-url/metadata/history', (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/by-url/status
|
||||
* GET /mints/by-url/status
|
||||
*/
|
||||
router.get('/by-url/status', (req, res) => {
|
||||
try {
|
||||
@@ -376,7 +376,7 @@ router.get('/by-url/status', (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/by-url/uptime
|
||||
* GET /mints/by-url/uptime
|
||||
*/
|
||||
router.get('/by-url/uptime', (req, res) => {
|
||||
try {
|
||||
@@ -397,7 +397,7 @@ router.get('/by-url/uptime', (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/by-url/uptime/timeseries
|
||||
* GET /mints/by-url/uptime/timeseries
|
||||
*/
|
||||
router.get('/by-url/uptime/timeseries', (req, res) => {
|
||||
try {
|
||||
@@ -414,7 +414,7 @@ router.get('/by-url/uptime/timeseries', (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/by-url/incidents
|
||||
* GET /mints/by-url/incidents
|
||||
*/
|
||||
router.get('/by-url/incidents', (req, res) => {
|
||||
try {
|
||||
@@ -431,7 +431,7 @@ router.get('/by-url/incidents', (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/by-url/trust
|
||||
* GET /mints/by-url/trust
|
||||
*/
|
||||
router.get('/by-url/trust', (req, res) => {
|
||||
try {
|
||||
@@ -456,7 +456,7 @@ router.get('/by-url/trust', (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/by-url/reviews
|
||||
* GET /mints/by-url/reviews
|
||||
*/
|
||||
router.get('/by-url/reviews', (req, res) => {
|
||||
try {
|
||||
@@ -477,7 +477,7 @@ router.get('/by-url/reviews', (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/by-url/views
|
||||
* GET /mints/by-url/views
|
||||
*/
|
||||
router.get('/by-url/views', async(req, res) => {
|
||||
try {
|
||||
@@ -493,7 +493,7 @@ router.get('/by-url/views', async(req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/by-url/features
|
||||
* GET /mints/by-url/features
|
||||
*/
|
||||
router.get('/by-url/features', (req, res) => {
|
||||
try {
|
||||
@@ -514,7 +514,7 @@ router.get('/by-url/features', (req, res) => {
|
||||
// ==========================================
|
||||
|
||||
/**
|
||||
* GET /v1/mints/:mint_id
|
||||
* GET /mints/:mint_id
|
||||
*/
|
||||
router.get('/:mint_id', resolveMintMiddleware, (req, res) => {
|
||||
try {
|
||||
@@ -554,7 +554,7 @@ router.get('/:mint_id', resolveMintMiddleware, (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/:mint_id/urls
|
||||
* GET /mints/:mint_id/urls
|
||||
*/
|
||||
router.get('/:mint_id/urls', resolveMintMiddleware, (req, res) => {
|
||||
try {
|
||||
@@ -571,7 +571,7 @@ router.get('/:mint_id/urls', resolveMintMiddleware, (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/:mint_id/metadata
|
||||
* GET /mints/:mint_id/metadata
|
||||
*/
|
||||
router.get('/:mint_id/metadata', resolveMintMiddleware, (req, res) => {
|
||||
try {
|
||||
@@ -603,7 +603,7 @@ router.get('/:mint_id/metadata', resolveMintMiddleware, (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/:mint_id/metadata/history
|
||||
* GET /mints/:mint_id/metadata/history
|
||||
*/
|
||||
router.get('/:mint_id/metadata/history', resolveMintMiddleware, (req, res) => {
|
||||
try {
|
||||
@@ -618,7 +618,7 @@ router.get('/:mint_id/metadata/history', resolveMintMiddleware, (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/:mint_id/status
|
||||
* GET /mints/:mint_id/status
|
||||
*/
|
||||
router.get('/:mint_id/status', resolveMintMiddleware, (req, res) => {
|
||||
try {
|
||||
@@ -638,7 +638,7 @@ router.get('/:mint_id/status', resolveMintMiddleware, (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/:mint_id/uptime
|
||||
* GET /mints/:mint_id/uptime
|
||||
*/
|
||||
router.get('/:mint_id/uptime', resolveMintMiddleware, (req, res) => {
|
||||
try {
|
||||
@@ -657,7 +657,7 @@ router.get('/:mint_id/uptime', resolveMintMiddleware, (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/:mint_id/uptime/timeseries
|
||||
* GET /mints/:mint_id/uptime/timeseries
|
||||
*/
|
||||
router.get('/:mint_id/uptime/timeseries', resolveMintMiddleware, (req, res) => {
|
||||
try {
|
||||
@@ -672,7 +672,7 @@ router.get('/:mint_id/uptime/timeseries', resolveMintMiddleware, (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/:mint_id/incidents
|
||||
* GET /mints/:mint_id/incidents
|
||||
*/
|
||||
router.get('/:mint_id/incidents', resolveMintMiddleware, (req, res) => {
|
||||
try {
|
||||
@@ -687,7 +687,7 @@ router.get('/:mint_id/incidents', resolveMintMiddleware, (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/:mint_id/trust
|
||||
* GET /mints/:mint_id/trust
|
||||
*/
|
||||
router.get('/:mint_id/trust', resolveMintMiddleware, (req, res) => {
|
||||
try {
|
||||
@@ -710,7 +710,7 @@ router.get('/:mint_id/trust', resolveMintMiddleware, (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/:mint_id/reviews
|
||||
* GET /mints/:mint_id/reviews
|
||||
*/
|
||||
router.get('/:mint_id/reviews', resolveMintMiddleware, (req, res) => {
|
||||
try {
|
||||
@@ -728,7 +728,7 @@ router.get('/:mint_id/reviews', resolveMintMiddleware, (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/:mint_id/views
|
||||
* GET /mints/:mint_id/views
|
||||
*/
|
||||
router.get('/:mint_id/views', resolveMintMiddleware, async(req, res) => {
|
||||
try {
|
||||
@@ -741,7 +741,7 @@ router.get('/:mint_id/views', resolveMintMiddleware, async(req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/:mint_id/features
|
||||
* GET /mints/:mint_id/features
|
||||
*/
|
||||
router.get('/:mint_id/features', resolveMintMiddleware, (req, res) => {
|
||||
try {
|
||||
@@ -758,7 +758,7 @@ router.get('/:mint_id/features', resolveMintMiddleware, (req, res) => {
|
||||
// ==========================================
|
||||
|
||||
/**
|
||||
* GET /v1/mints/:mint_id/stats
|
||||
* GET /mints/:mint_id/stats
|
||||
* Aggregated mint KPIs (single endpoint for summary cards)
|
||||
*/
|
||||
router.get('/:mint_id/stats', resolveMintMiddleware, async(req, res) => {
|
||||
@@ -772,7 +772,7 @@ router.get('/:mint_id/stats', resolveMintMiddleware, async(req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/:mint_id/latency/timeseries
|
||||
* GET /mints/:mint_id/latency/timeseries
|
||||
* Response time history for charting
|
||||
*/
|
||||
router.get('/:mint_id/latency/timeseries', resolveMintMiddleware, (req, res) => {
|
||||
@@ -797,7 +797,7 @@ router.get('/:mint_id/latency/timeseries', resolveMintMiddleware, (req, res) =>
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/:mint_id/availability
|
||||
* GET /mints/:mint_id/availability
|
||||
* Availability breakdown (online/degraded/offline percentages)
|
||||
*/
|
||||
router.get('/:mint_id/availability', resolveMintMiddleware, (req, res) => {
|
||||
@@ -815,7 +815,7 @@ router.get('/:mint_id/availability', resolveMintMiddleware, (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/:mint_id/trust/history
|
||||
* GET /mints/:mint_id/trust/history
|
||||
* Trust score history with change reasons
|
||||
*/
|
||||
router.get('/:mint_id/trust/history', resolveMintMiddleware, (req, res) => {
|
||||
@@ -833,7 +833,7 @@ router.get('/:mint_id/trust/history', resolveMintMiddleware, (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/:mint_id/trust/compare
|
||||
* GET /mints/:mint_id/trust/compare
|
||||
* Compare trust score against ecosystem benchmarks
|
||||
*/
|
||||
router.get('/:mint_id/trust/compare', resolveMintMiddleware, (req, res) => {
|
||||
@@ -851,7 +851,7 @@ router.get('/:mint_id/trust/compare', resolveMintMiddleware, (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/:mint_id/reviews/summary
|
||||
* GET /mints/:mint_id/reviews/summary
|
||||
* Quick review overview (rating distribution, averages)
|
||||
*/
|
||||
router.get('/:mint_id/reviews/summary', resolveMintMiddleware, (req, res) => {
|
||||
@@ -865,7 +865,7 @@ router.get('/:mint_id/reviews/summary', resolveMintMiddleware, (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/:mint_id/views/timeseries
|
||||
* GET /mints/:mint_id/views/timeseries
|
||||
* Pageview history for adoption trends
|
||||
*/
|
||||
router.get('/:mint_id/views/timeseries', resolveMintMiddleware, async(req, res) => {
|
||||
@@ -890,7 +890,7 @@ router.get('/:mint_id/views/timeseries', resolveMintMiddleware, async(req, res)
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/mints/:mint_id/card
|
||||
* GET /mints/:mint_id/card
|
||||
* Optimized endpoint for grid/list views
|
||||
*/
|
||||
router.get('/:mint_id/card', resolveMintMiddleware, (req, res) => {
|
||||
|
||||
@@ -24,7 +24,7 @@ import { nowISO } from '../utils/time.js';
|
||||
const router = Router();
|
||||
|
||||
/**
|
||||
* GET /v1/health
|
||||
* GET /health
|
||||
* Health check endpoint
|
||||
*/
|
||||
router.get('/health', (req, res) => {
|
||||
@@ -56,7 +56,7 @@ router.get('/health', (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/stats
|
||||
* GET /stats
|
||||
* System statistics
|
||||
*/
|
||||
router.get('/stats', (req, res) => {
|
||||
@@ -132,7 +132,7 @@ router.get('/stats', (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/stats/timeline
|
||||
* GET /stats/timeline
|
||||
* Activity timeline
|
||||
*/
|
||||
router.get('/stats/timeline', (req, res) => {
|
||||
@@ -192,7 +192,7 @@ router.get('/stats/timeline', (req, res) => {
|
||||
// ==========================================
|
||||
|
||||
/**
|
||||
* GET /v1/reviews
|
||||
* GET /reviews
|
||||
* Global reviews feed with filtering
|
||||
*/
|
||||
router.get('/reviews', (req, res) => {
|
||||
@@ -243,7 +243,7 @@ router.get('/reviews', (req, res) => {
|
||||
// ==========================================
|
||||
|
||||
/**
|
||||
* GET /v1/analytics/uptime
|
||||
* GET /analytics/uptime
|
||||
* Ecosystem-wide uptime analytics
|
||||
*/
|
||||
router.get('/analytics/uptime', (req, res) => {
|
||||
@@ -261,7 +261,7 @@ router.get('/analytics/uptime', (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/analytics/versions
|
||||
* GET /analytics/versions
|
||||
* Mint version distribution analytics
|
||||
*/
|
||||
router.get('/analytics/versions', (req, res) => {
|
||||
@@ -275,7 +275,7 @@ router.get('/analytics/versions', (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/analytics/nuts
|
||||
* GET /analytics/nuts
|
||||
* NUT support analytics across all mints
|
||||
*/
|
||||
router.get('/analytics/nuts', (req, res) => {
|
||||
@@ -289,7 +289,7 @@ router.get('/analytics/nuts', (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/analytics/status-distribution
|
||||
* GET /analytics/status-distribution
|
||||
* Status distribution across all mints
|
||||
*/
|
||||
router.get('/analytics/status-distribution', (req, res) => {
|
||||
@@ -303,7 +303,7 @@ router.get('/analytics/status-distribution', (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/analytics/networks
|
||||
* GET /analytics/networks
|
||||
* Network type breakdown (clearnet, tor, dual-stack)
|
||||
*/
|
||||
router.get('/analytics/networks', (req, res) => {
|
||||
@@ -317,7 +317,7 @@ router.get('/analytics/networks', (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /v1/analytics/metadata-quality
|
||||
* GET /analytics/metadata-quality
|
||||
* Metadata completeness leaderboard
|
||||
*/
|
||||
router.get('/analytics/metadata-quality', (req, res) => {
|
||||
@@ -339,7 +339,7 @@ router.get('/analytics/metadata-quality', (req, res) => {
|
||||
// ==========================================
|
||||
|
||||
/**
|
||||
* GET /v1/reviews/recent
|
||||
* GET /reviews/recent
|
||||
* Recent ecosystem-wide reviews
|
||||
*/
|
||||
router.get('/reviews/recent', (req, res) => {
|
||||
|
||||
@@ -16,7 +16,7 @@ Admin endpoints **never fabricate reality**. They annotate, correct routing, or
|
||||
|
||||
## General Rules
|
||||
|
||||
* Base path: `/v1/admin`
|
||||
* Base path: `/admin`
|
||||
* Authentication: `ADMIN_API_KEY` (static header)
|
||||
* All admin actions are **audited**
|
||||
* No admin endpoint deletes raw data
|
||||
@@ -33,7 +33,7 @@ Audit log fields:
|
||||
|
||||
---
|
||||
|
||||
## POST /v1/admin/mints
|
||||
## POST /admin/mints
|
||||
|
||||
### Purpose
|
||||
|
||||
@@ -81,7 +81,7 @@ Used for:
|
||||
|
||||
---
|
||||
|
||||
## POST /v1/admin/mints/{mint_id}/urls
|
||||
## POST /admin/mints/{mint_id}/urls
|
||||
|
||||
### Purpose
|
||||
|
||||
@@ -112,7 +112,7 @@ Manually attach an additional URL (clearnet, Tor, mirror) to an existing mint.
|
||||
|
||||
---
|
||||
|
||||
## POST /v1/admin/mints/merge
|
||||
## POST /admin/mints/merge
|
||||
|
||||
### Purpose
|
||||
|
||||
@@ -150,7 +150,7 @@ Merge two mints that represent the same operator.
|
||||
|
||||
---
|
||||
|
||||
## POST /v1/admin/mints/split
|
||||
## POST /admin/mints/split
|
||||
|
||||
### Purpose
|
||||
|
||||
@@ -178,7 +178,7 @@ Undo a previous mint merge.
|
||||
|
||||
---
|
||||
|
||||
## POST /v1/admin/mints/{mint_id}/disable
|
||||
## POST /admin/mints/{mint_id}/disable
|
||||
|
||||
### Purpose
|
||||
|
||||
@@ -198,7 +198,7 @@ Hide a mint from public listings without deleting it.
|
||||
|
||||
---
|
||||
|
||||
## POST /v1/admin/mints/{mint_id}/enable
|
||||
## POST /admin/mints/{mint_id}/enable
|
||||
|
||||
### Purpose
|
||||
|
||||
@@ -211,7 +211,7 @@ Re-enable a previously hidden mint.
|
||||
|
||||
---
|
||||
|
||||
## POST /v1/admin/mints/{mint_id}/metadata/refresh
|
||||
## POST /admin/mints/{mint_id}/metadata/refresh
|
||||
|
||||
### Purpose
|
||||
|
||||
@@ -230,7 +230,7 @@ Force metadata fetch, bypassing the hourly limit.
|
||||
|
||||
---
|
||||
|
||||
## POST /v1/admin/mints/{mint_id}/trust/recompute
|
||||
## POST /admin/mints/{mint_id}/trust/recompute
|
||||
|
||||
### Purpose
|
||||
|
||||
@@ -250,7 +250,7 @@ Force trust score recomputation.
|
||||
|
||||
---
|
||||
|
||||
## GET /v1/admin/jobs
|
||||
## GET /admin/jobs
|
||||
|
||||
### Purpose
|
||||
|
||||
@@ -278,7 +278,7 @@ Inspect the background job queue.
|
||||
|
||||
---
|
||||
|
||||
## GET /v1/admin/system/metrics
|
||||
## GET /admin/system/metrics
|
||||
|
||||
### Purpose
|
||||
|
||||
@@ -300,7 +300,7 @@ Used for operations and debugging.
|
||||
|
||||
---
|
||||
|
||||
## POST /v1/admin/mints/{mint_id}/status/reset
|
||||
## POST /admin/mints/{mint_id}/status/reset
|
||||
|
||||
### Purpose
|
||||
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
# Cashumints.space API – Endpoints
|
||||
|
||||
Base path:
|
||||
|
||||
/v1
|
||||
|
||||
All endpoints are read‑only unless stated otherwise.
|
||||
All timestamps are ISO‑8601 UTC.
|
||||
All mint‑specific endpoints accept either a mint ID or a mint URL.
|
||||
@@ -13,8 +9,8 @@ All mint‑specific endpoints accept either a mint ID or a mint URL.
|
||||
## Resolution Rules
|
||||
|
||||
Endpoints support:
|
||||
- `/v1/mints/{mint_id}`
|
||||
- `/v1/mints/by-url?url=...`
|
||||
- `/mints/{mint_id}`
|
||||
- `/mints/by-url?url=...`
|
||||
|
||||
The API resolves URLs to the canonical mint_id internally.
|
||||
|
||||
@@ -22,8 +18,8 @@ The API resolves URLs to the canonical mint_id internally.
|
||||
|
||||
## Single Mint – Core
|
||||
|
||||
GET /v1/mints/{mint_id}
|
||||
GET /v1/mints/by-url?url=
|
||||
GET /mints/{mint_id}
|
||||
GET /mints/by-url?url=
|
||||
|
||||
Returns:
|
||||
- mint_id
|
||||
@@ -47,8 +43,8 @@ Returns:
|
||||
|
||||
## Mint URLs
|
||||
|
||||
GET /v1/mints/{mint_id}/urls
|
||||
GET /v1/mints/by-url/urls?url=
|
||||
GET /mints/{mint_id}/urls
|
||||
GET /mints/by-url/urls?url=
|
||||
|
||||
Returns:
|
||||
- canonical_url
|
||||
@@ -61,8 +57,8 @@ Returns:
|
||||
|
||||
## Metadata (NUT‑06)
|
||||
|
||||
GET /v1/mints/{mint_id}/metadata
|
||||
GET /v1/mints/by-url/metadata?url=
|
||||
GET /mints/{mint_id}/metadata
|
||||
GET /mints/by-url/metadata?url=
|
||||
|
||||
Returns:
|
||||
- name
|
||||
@@ -81,8 +77,8 @@ Returns:
|
||||
|
||||
---
|
||||
|
||||
GET /v1/mints/{mint_id}/metadata/history
|
||||
GET /v1/mints/by-url/metadata/history?url=
|
||||
GET /mints/{mint_id}/metadata/history
|
||||
GET /mints/by-url/metadata/history?url=
|
||||
|
||||
Returns:
|
||||
- fetched_at
|
||||
@@ -94,8 +90,8 @@ Returns:
|
||||
|
||||
## Status (Lightweight)
|
||||
|
||||
GET /v1/mints/{mint_id}/status
|
||||
GET /v1/mints/by-url/status?url=
|
||||
GET /mints/{mint_id}/status
|
||||
GET /mints/by-url/status?url=
|
||||
|
||||
Returns:
|
||||
- status
|
||||
@@ -107,8 +103,8 @@ Returns:
|
||||
|
||||
## Uptime & Reliability
|
||||
|
||||
GET /v1/mints/{mint_id}/uptime
|
||||
GET /v1/mints/by-url/uptime?url=
|
||||
GET /mints/{mint_id}/uptime
|
||||
GET /mints/by-url/uptime?url=
|
||||
|
||||
Query:
|
||||
- window=24h | 7d | 30d
|
||||
@@ -123,8 +119,8 @@ Returns:
|
||||
|
||||
---
|
||||
|
||||
GET /v1/mints/{mint_id}/uptime/timeseries
|
||||
GET /v1/mints/by-url/uptime/timeseries?url=
|
||||
GET /mints/{mint_id}/uptime/timeseries
|
||||
GET /mints/by-url/uptime/timeseries?url=
|
||||
|
||||
Query:
|
||||
- window=24h | 7d | 30d
|
||||
@@ -140,8 +136,8 @@ Returns:
|
||||
|
||||
## Incidents
|
||||
|
||||
GET /v1/mints/{mint_id}/incidents
|
||||
GET /v1/mints/by-url/incidents?url=
|
||||
GET /mints/{mint_id}/incidents
|
||||
GET /mints/by-url/incidents?url=
|
||||
|
||||
Returns:
|
||||
- started_at
|
||||
@@ -153,8 +149,8 @@ Returns:
|
||||
|
||||
## Trust
|
||||
|
||||
GET /v1/mints/{mint_id}/trust
|
||||
GET /v1/mints/by-url/trust?url=
|
||||
GET /mints/{mint_id}/trust
|
||||
GET /mints/by-url/trust?url=
|
||||
|
||||
Returns:
|
||||
- score_total
|
||||
@@ -166,8 +162,8 @@ Returns:
|
||||
|
||||
## Reviews (Nostr)
|
||||
|
||||
GET /v1/mints/{mint_id}/reviews
|
||||
GET /v1/mints/by-url/reviews?url=
|
||||
GET /mints/{mint_id}/reviews
|
||||
GET /mints/by-url/reviews?url=
|
||||
|
||||
Returns:
|
||||
- event_id
|
||||
@@ -180,8 +176,8 @@ Returns:
|
||||
|
||||
## Popularity
|
||||
|
||||
GET /v1/mints/{mint_id}/views
|
||||
GET /v1/mints/by-url/views?url=
|
||||
GET /mints/{mint_id}/views
|
||||
GET /mints/by-url/views?url=
|
||||
|
||||
Returns:
|
||||
- views_24h
|
||||
@@ -194,8 +190,8 @@ Returns:
|
||||
|
||||
## Derived Features
|
||||
|
||||
GET /v1/mints/{mint_id}/features
|
||||
GET /v1/mints/by-url/features?url=
|
||||
GET /mints/{mint_id}/features
|
||||
GET /mints/by-url/features?url=
|
||||
|
||||
Returns:
|
||||
- supported_nuts
|
||||
@@ -210,7 +206,7 @@ Returns:
|
||||
|
||||
## Submission
|
||||
|
||||
POST /v1/mints/submit
|
||||
POST /mints/submit
|
||||
|
||||
Body:
|
||||
- mint_url
|
||||
@@ -224,6 +220,6 @@ Returns:
|
||||
|
||||
## Health & Stats
|
||||
|
||||
GET /v1/health
|
||||
GET /v1/stats
|
||||
GET /health
|
||||
GET /stats
|
||||
|
||||
|
||||
@@ -149,7 +149,7 @@ Each rollup stores:
|
||||
|
||||
## Metadata (NUT‑06)
|
||||
|
||||
- Fetched from `/v1/info`
|
||||
- Fetched from `/info`
|
||||
- Only fetched after a successful probe
|
||||
- Fetched at most once per hour per mint
|
||||
- Stored as a current snapshot
|
||||
|
||||
@@ -66,7 +66,7 @@ If offline longer than ABANDONED_AFTER:
|
||||
- Only fetch if last_fetched_at older than 1 hour
|
||||
|
||||
Steps:
|
||||
1. GET /v1/info
|
||||
1. GET /info
|
||||
2. Validate against NUT‑06
|
||||
3. Normalize payload
|
||||
4. Compute hash
|
||||
|
||||
Reference in New Issue
Block a user