Add complete sync worker system for NPM package discovery and metrics:
**Sync Workers:**
- Changes Feed Sync (/api/sync/changes) - Polls NPM changes every 2 min
- Keyword Search Sync (/api/sync/keyword) - Searches tpmjs-tool keyword every 15 min
- Metrics Sync (/api/sync/metrics) - Updates downloads & quality scores hourly
**Features:**
- Secure CRON_SECRET authentication for all sync endpoints
- Comprehensive error handling with sync logs and checkpoints
- Smart package validation and filtering (skip invalid tpmjs fields)
- Automatic tool upsert with discovery method tracking
- Quality score calculation based on tier, downloads, and GitHub stars
- 5-minute timeout support for long-running sync operations
**Dependencies:**
- Add @tpmjs/npm-client to web app for NPM API integration
- Use barrel exports from npm-client package (no subpath imports)
- Add CRON_SECRET env variable validation
- Add ~/src path alias to tsconfig
**Infrastructure:**
- Configure Vercel Cron jobs in vercel.json for automated syncing
- Add publishedAt field to PackageVersion schema
- Fix Prisma JSON field handling (use undefined instead of null)
- Proper null checks for fetchLatestPackageVersion return values
**Type Safety:**
- Cast TpmjsField union type to access optional rich-tier properties
- Handle searchByKeyword array return type correctly
- Fix fetchDownloadStats to return number directly
All API routes follow Next.js 16 conventions with proper type checking.
Type-check and full build successful.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Implement changes feed client for real-time package discovery
- Implement keyword search with auto-pagination support
- Implement package metadata fetcher with tpmjs field extraction
- Implement download statistics client for quality scoring
- Implement rate limiter with configurable concurrency and delays
- Implement retry logic with exponential backoff for 429 errors
All API responses validated with Zod schemas for type safety.
Rate limiter defaults: max 10 concurrent, 100ms minimum delay.
Handles scoped packages (@scope/name) correctly.
Graceful 404 handling returns null instead of throwing.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>