Issues fixed:
1. Charts not rendering correctly due to sparse data (missing time buckets)
2. Period "1h" returning empty data when aggregate stats not yet available
Changes:
- Generate continuous time series with 0 values for all time buckets
- Truncate start time to hour/day boundaries for consistent bucketing
- Fallback to package-level stats aggregation when registry totals unavailable
- Add proper time range filtering (since <= time_bucket <= now)
Behavior now:
- All time periods (1h, 1day, 7day, 30day) return complete data sets
- Missing hours/days are filled with value: 0
- Chart libraries can render continuous lines/bars correctly
- No more empty data for "1h" period
Example output (1 hour period):
Before: [{"timestamp":"14:00","value":5}, {"timestamp":"15:00","value":3}]
After: [{"timestamp":"13:00","value":0}, {"timestamp":"14:00","value":5},
{"timestamp":"15:00","value":3}, {"timestamp":"16:00","value":0}]
Resolves: "Chart doesn't generate correctly - it should automatically
fill 0 for the empty periods to render correctly"
Previously, download counts only incremented on cache hits (when package
was served from cache). First-time downloads (cache misses) were not counted.
Changes:
- Add UpdateDownloadCount() call when serving newly cached packages
- This ensures every download through the proxy increments the counter
- Analytics tracking also added for cache misses
Behavior now:
- First download (cache miss): counter = 1
- Second download (cache hit): counter = 2
- Third download (cache hit): counter = 3
- etc.
Updated all relevant tests to expect the additional UpdateDownloadCount call.
Resolves user requirement: "I want the counters to increase whenever
package is downloaded via proxy - regardless of it being new download
or cached download"
Problem:
- Download counts were not incrementing when packages existed in storage
but not in the database (e.g., after database migration/reset)
- UpdateDownloadCount() was failing silently when package didn't exist in DB
- Error was completely ignored despite comment claiming "error logged"
Changes:
1. Log errors when UpdateDownloadCount() fails instead of silently ignoring
2. Auto-save package to database if UpdateDownloadCount() fails
3. Retry download count update after saving package
4. Provide detailed error logging for troubleshooting
This fixes the issue where:
- Database is migrated but storage still has cached packages
- Cache hits occur but download events aren't recorded
- Statistics show zero downloads despite actual usage
Resolves user report: "I cleaned go mod which redownloaded the modules
through the proxy but counters did not increased"
- Rate limits (403) are now accepted as healthy
- Rate limiting is expected without a GitHub token
- Only real errors (network failures, 500s) fail the health check
- Prevents health check failures due to unauthenticated API usage
Related: GHSA scanner health checks
- Scanner failures (e.g., GitHub API rate limits) no longer mark server as unhealthy
- Server can still serve cached packages when scanners are unavailable
- Readiness probes will now pass with degraded scanner status
- Prevents unnecessary pod restarts due to external API issues
Fixes: Readiness probes failing with 503 due to GHSA rate limiting
- OSV API expects clean module paths like 'gorm.io/driver/sqlite'
- Cache keys include Go proxy format like 'gorm.io/driver/sqlite/@v/v1.6.0.zip'
- Added cleanGoModuleName() to extract module path and version
- Strips /@v/ prefix and .zip/.mod/.info suffixes
- Fixes 404 errors when scanning Go modules
Resolves: OSV API returning 404 for Go module scans
- [x] Implement GORM V2 metadata store with SQLite, PostgreSQL, and MySQL support
- [x] Add database migration system using gormigrate for schema versioning
- [x] Create migration CLI tool with support for migrate, rollback, and status commands
- [x] Add Docker support for migration container (Dockerfile.migrate)
- [x] Implement automatic partition management for PostgreSQL time-series tables
- [x] Add background aggregation worker for download statistics
- [x] Support connection pooling configuration (max_open_conns, max_idle_conns, conn_max_lifetime)
- [x] Add blocking mechanism based on vulnerability thresholds in stats and handlers
- [x] Update Helm charts with migration init containers and multi-database configuration
- [x] Replace deprecated SQLite store with optimized GORM implementation
- [x] Add comprehensive integration tests for MySQL and PostgreSQL
- [x] Update frontend to display blocked packages and storage utilization
- [x] Add goreleaser configuration for migrate binary and container image
- [x] Update configuration examples with database backend options and recommendations