WebHooker/server/lib/storage/d1.ts
RhenCloud 25ebae4ae5
feat(storage): migrate config, dedup and delivery state to D1
- Move oversized queue payloads from KV to R2 (PAYLOAD binding, webhooks/YYYY/MM/DD/*.json, KV queue:payload:* fallback)
- Persist routes/groups to D1 (d1_routes/d1_groups) with memory -> KV -> D1 three-tier cache, seeded from legacy KV config keys
- Move webhook dedup (dedup_keys), delivery state (delivery_state) and message tracking (message_tracking) to D1 via canUseD1 probe with automatic KV fallback
- Batch send_logs inserts (recordSendBatch) and add group_id/ts index
- Add storage-prune scheduled task for expired dedup/state/tracking rows
- Add TTL to invite:group:{id} index and audit all ephemeral KV keys
- Add D1 indexes for the new tables
- Sync AGENTS.md, README.md/zh and docs/ (en/zh) with the new storage layout
2026-08-17 15:01:20 +08:00

14 lines
No EOL
605 B
TypeScript

/**
* True when a D1Database binding looks like the real thing. Production D1
* always exposes both `prepare` and `batch`; test harnesses range from
* `DB: {}` (no methods at all) to minimal mocks that only implement
* `prepare`→`bind`→{`run`,`all`} without `batch`. Using the presence of
* `batch` as the probe means every existing test keeps its KV fallback path
* while production eagerly routes through D1.
*/
export function canUseD1(db: D1Database | undefined | null): boolean {
return (
typeof db?.prepare === "function" &&
typeof (db as D1Database).batch === "function"
);
}