- Flash.jsx: replace esp-web-tools with direct esptool-js integration
→ reads MAC address + chip type before flash via Web Serial API
→ step-by-step UI (connect → board info → download → flash → done)
→ retry button on failure with remaining-attempt counter
→ firmware update token request after successful flash
- Schema: FlashToken (maxAttempts/attemptCount/isLocked/isUpdateToken),
FlashLog (startedAt/completedAt/durationMs/chipId/flashSize),
FlashAnomaly model (RATE_LIMIT_IP/HIGH_VOLUME_IP/MAC_REUSE/TOKEN_LOCK/SUSPICIOUS_DURATION),
ProjectFile.firmwareVersion
- flash.js: new POST /start (board info + IP log + anomaly detection),
updated POST /consume (timing, lock on exhaustion), GET returns firmwareFiles
- orders.js: POST /request-reflash (free firmware update token for paid orders),
updated to flashTokens[] relation
- admin.js: GET /flash/metrics, GET/PUT /flash/anomalies, POST /flash/tokens/:id/unlock
- Admin/FlashMetrics.jsx: dashboard with today stats, recent logs table,
top-IP chart, anomaly management with resolve button
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>