feat(attachments): R2 toggle, storage metrics, and demo R2 config
Add an ATTACHMENTS_ENABLED switch (default on when R2 is bound) via a central getAttachmentBucket helper, surface R2 + estimated KV usage against the free tier on the status page and /api/stats (refreshed by the hourly cron), let setup.sh create and wire the R2 bucket, and bind the demo bucket so the deployed demo has attachments. Co-Authored-By: Claude Opus 4.7 <[email protected]>
This commit is contained in:
1 parent
7226e718f7
commit
f150d40c45
19 files changed
+387
-23
No files matched your search
@@ -13,6 +13,7 @@ import {
|
||||
extractEmailDomain,
|
||||
} from "../utils/favicon-fetcher";
|
||||
import { parseOneClickUnsubscribe } from "../utils/unsubscribe";
|
||||
import { getAttachmentBucket } from "../utils/attachments";
|
||||
import { logger } from "./logger";
|
||||
import { FEED_MAX_BYTES } from "../config/constants";
|
||||
|
||||
@@ -170,9 +171,10 @@ export async function storeEmail(
|
||||
env: Env,
|
||||
ctx?: ExecutionContext,
|
||||
): Promise<void> {
|
||||
const attachmentBucket = getAttachmentBucket(env);
|
||||
const storedAttachments: AttachmentData[] =
|
||||
env.ATTACHMENT_BUCKET && input.attachments?.length
|
||||
? await uploadAttachments(input.attachments, env.ATTACHMENT_BUCKET)
|
||||
attachmentBucket && input.attachments?.length
|
||||
? await uploadAttachments(input.attachments, attachmentBucket)
|
||||
: [];
|
||||
|
||||
const emailData = {
|
||||
@@ -249,10 +251,10 @@ export async function storeEmail(
|
||||
}
|
||||
|
||||
const r2Deletions =
|
||||
env.ATTACHMENT_BUCKET && toDelete.length > 0
|
||||
attachmentBucket && toDelete.length > 0
|
||||
? toDelete
|
||||
.flatMap((e) => e.attachmentIds ?? [])
|
||||
.map((id) => env.ATTACHMENT_BUCKET!.delete(id))
|
||||
.map((id) => attachmentBucket.delete(id))
|
||||
: [];
|
||||
|
||||
await Promise.all([
|
||||
|
||||
Reference in new issue
Block a user