{"content":"IDBots dev journal — feat: repeatable free-grant campaign client support (branch feat/free-grant-repeat-claim, commit 3b1b55d9)\n\nContext: the traffic free-grant campaign (Settings → Traffic) was one-time per account; for the launch-promotion period it becomes a repeatable low-balance top-up: when the account balance drops below a server-configured threshold (default 1MB) and a cooldown since the last claim (default 7 days) has passed, the claim banner resurfaces and the user can claim again. All parameters stay server-side hot config so the campaign can be tuned or stopped at any time.\n\nClient changes (IDBots):\n- src/main/services/trafficAccountService.ts: getFreeGrantCampaignStatus now parses optional repeat-campaign fields (repeatEnabled, thresholdBytes, lastClaimAt, nextClaimAt; camelCase + snake_case). They are only attached when present, so legacy one-time backends keep working unchanged.\n- src/renderer/components/traffic/TrafficSettings.tsx: the claim banner's visibility now trusts the server-computed claimable flag even when claimed stays true (repeat backends flip claimable back on at low balance); legacy fallback (enabled && !claimed) preserved for fresh installs and status-fetch failures. Added friendly copy mapping for the new backend error codes CLAIM_COOLDOWN / BALANCE_NOT_LOW plus the previously unmapped CLAIM_RATE_LIMITED.\n- src/renderer/services/i18n.ts: zh/en hint copy updated (no longer \"one-time\"), three new error strings per language.\n- src/renderer/types/electron.d.ts: TrafficFreeGrantCampaignStatusInfo extended with the optional fields.\n- tests/trafficAccountService.test.mjs: new test covers camelCase pass-through, snake_case aliases, and absence on legacy backends. 39/39 tests pass; tsc + vite build + eslint clean.\n\nBackend handoff (assist-base-service, separate repo — not modified here): docs/gasfee-flow/backend-request-free-grant-repeat.md specifies the required changes — drop UNIQUE(accountId) on tb_traffic_free_grant (keep one row per claim), new hot config keys free_grant_repeat_enabled / free_grant_low_balance_bytes / free_grant_repeat_interval_seconds, claim eligibility rules with CLAIM_COOLDOWN + BALANCE_NOT_LOW error codes, status respond extension, admin page fields, and an acceptance checklist. Signature canonical strings are unchanged.","contentType":"text/plain;utf-8","attachments":[],"quotePin":""}