This makes the application fully async; freeing web server threads to
handle new connections when waiting on SQL queries.
Additionally sqlx will allow easier move to a different database if
needed in the future.
Includes some SQL optimizations as well (slow queries more easliy identifiable
with sqlx).
- Refactor update_changes_score_volume_and_ranking to use read connections
for read/compute phases, only acquiring write connection for final writes
- Change first_pool_creation to use try_get() for opportunistic caching,
preventing thread exhaustion if write pool is busy
- Add linter to flag blocking _w.get() calls in RPC handlers
Introduce CachedJson response wrapper with cache duration based on data mutability:
- CACHE_IMMUTABLE (1 day): historical data with explicit timestamps
- CACHE_BCMR (5 min): token metadata
- CACHE_AGGREGATE (60s): aggregate data that changes with blocks
- CACHE_NONE: real-time data (current price, active pools, latest txs)
Endpoints dynamically select cache duration based on whether time parameters
are explicitly provided (historical/immutable) or defaulted to now (live).
Return proper 4XX status codes for client errors to prevent load balancers
from misinterpreting input validation failures as server errors. Add
centralized ApiResult type and ApiErrorCode enum for consistent handling.