Database Schema
The worker uses Cloudflare D1 (SQLite) with Drizzle ORM. The schema is defined in worker/src/db/schema.ts.
Tables
Section titled “Tables”emails
Section titled “emails”| Column | Type | Description |
|---|---|---|
id | text PK | UUID, auto-generated |
message_id | text | Original Message-ID header |
sender | text | Envelope sender address |
from_header | text | From header (may include display name) |
to_header | text | To header |
subject | text | Subject line |
body_preview | text | First 500 chars of body text |
raw_size | integer | Raw message size in bytes |
spf_pass | boolean | Whether SPF passed |
dkim_pass | boolean | Whether DKIM passed |
status | text | pending, approved, rejected, or forwarded |
classification | text | cold_outreach, spam, newsletter, legitimate, unknown |
classification_reason | text | Human-readable reason for classification |
raw_storage_key | text | R2 key for raw MIME (optional) |
created_at | text | ISO datetime, defaults to now |
actioned_at | text | ISO datetime when approved/rejected |
senders
Section titled “senders”| Column | Type | Description |
|---|---|---|
address | text PK | Email address |
display_name | text | Display name from From header |
status | text | allowed, blocked, or unknown |
email_count | integer | Total emails received from sender |
first_seen | text | ISO datetime of first email |
last_seen | text | ISO datetime of most recent email |
notes | text | Optional notes |
settings
Section titled “settings”| Column | Type | Description |
|---|---|---|
key | text PK | Setting name |
value | text | Setting value |
Default settings keys:
destination_email— where approved mail gets forwardedauto_forward_allowed—"true"or"false", auto-forward from allowed sendersauto_reject_blocked—"true"or"false", silently drop from blocked senders
Migrations
Section titled “Migrations”Generate a new migration after schema changes:
cd workerbun run db:generateApply migrations:
# Localbun run db:migrate:local
# Productionbun run db:migrate:remote