Appearance
SymbolAdminManager
Handles admin operations for symbol management: promote/demote, batch operations, and the admin panel data endpoint.
High-Level Design
Responsibility
SymbolAdminManager is the human decision layer in the symbol lifecycle. The crawler (via CrawlingManager → RankingsManager) automatically discovers and recommends symbols for promotion or demotion. SymbolAdminManager provides the interface for admins to act on (or dismiss) those recommendations.
It is intentionally stateless — all state lives in the shared symbols SQLite table. This keeps the manager simple: read recommendations, write enable/disable flags, clear recommendation markers.
Separation of Concerns
SymbolAdminManager only mutates the database — it never triggers side effects. The parent SymbolRegistry wraps each mutation and conditionally calls pushNotificationManager.pushWithRetryOnFailure() on success. This keeps the manager focused and testable. See parent index for the full recommendation pipeline flow.
Admin Panel Data — Single-Query Optimization
getAdminPanelData() fetches all symbols in one SQL query, then filters recommendations in-memory. This avoids the N+1 pattern of querying symbols separately from recommendations. The method also receives CrawlerConfig as a parameter (from CrawlerConfigManager via SymbolRegistry) to bundle everything the admin UI needs in a single RPC call.
Batch Processing Constraint
CF Workers limits SQL bind parameters to 50, so IN (...) clauses can't handle large batches. Batch promote/demote operations process symbols individually in a loop instead. This is a deliberate trade-off: slightly more SQL round-trips (still within a single DO, so no network cost) in exchange for simpler code and no parameter limit issues. Batch size is capped at 100.
Push Notification Triggering
clearRecommendation() notably does not trigger a push — it only clears the recommendation flag without changing is_enabled, so downstream DOs don't need to update. All other mutations (promote, demote, batch variants) trigger a push via the parent SymbolRegistry.
Edge Cases & Error Handling
- All operations validate symbol existence before modification; returns
success: falsewith error message for unknown symbols. - Batch operations are partial-success tolerant — individual failures don't abort the batch. Results include both success and failure arrays.
getAdminPanelData()sorts recommendations in-memory by CMC rank (?? Infinityfor nulls-last), then alphabetically.getSymbolsWithRecommendations()sorts via SQLORDER BY cmc_rank, symbol— slightly different null handling but consistent in practice.
See Also
- CrawlingManager - sets PROMOTE/DEMOTE recommendations
- RankingsManager - persists crawler data that feeds recommendations
- SymbolStorageManager - owns the
symbolstable androwToConfig() - PushNotificationManager - fans out changes after promote/demote
- Parent DO:
SymbolRegistry