EB evanburgei.com Back to main

01·  What it is

The idea

BurgeiOS is a private dashboard at burgeios.com — my own operating system for managing the day. Every build I ship eventually generates inbound: recruiter emails during a job search, calendar bookings, text messages, LinkedIn messages. Without a system, that signal lives across five separate apps and I'm context-switching to piece it together.

The premise is simple: aggregate all inbound into one triage surface, prioritize it with a consistent classification scheme, and overlay it on top of a flexible time-blocked calendar. Then add intent-setting in the morning and a retro at night. Goal tracking on top of that.

The constraint that shaped every architectural decision: BurgeiOS is a lens on data that lives elsewhere (Gmail, Google Calendar, Cal.com), not a parallel store. It reads, classifies, and surfaces — but the source of truth stays in the source. If BurgeiOS's database were wiped, all the underlying data would still be intact.


02·  How it's built

Architecture

Layer 1

Aggregator Worker — burgeios-aggregator

Cron-triggered Cloudflare Worker that runs multiple times per day. Polls Gmail via the Gmail API (using a stored OAuth refresh token, never requiring re-auth) for threads classified under JobBoards/* labels. Polls Google Calendar for upcoming hard events. Receives Cal.com booking webhooks. Classifies each item by priority (P0/P1/P2) and kind (Recruiter / Booking / Digest / Noise). Writes metadata-only rows to D1 — subject line, sender, snippet capped at 200 characters, classification, timestamps. Never touches email bodies.

Layer 2

API Worker — burgeios-api

HTTP Worker behind Cloudflare Access. Handles all reads and writes from the frontend. Key routes:

  • GET /api/triage — triage list with annotations and priority overrides
  • POST /api/items/:id/annotate — set priority, note, snooze, or status; writes back to Gmail labels so state survives a D1 wipe
  • GET /api/plan/:date and POST /api/blocks — soft time-block management alongside hard Calendar events
  • GET/POST /api/goals — goal tracking with status and progress
  • POST /api/intents/:date and POST /api/retros/:date — morning intent and end-of-day retro
  • POST /webhooks/cal-com — Cal.com webhook with HMAC signature verification
Auth is layered: Cloudflare Access gates the domain at the edge; the Worker also checks the Cf-Access-Authenticated-User-Email header against the allowed email on every request. Both layers must pass.

Layer 3

Frontend — burgeios.com (Cloudflare Pages)

Static HTML/CSS/vanilla JS deployed on Cloudflare Pages. No CDN dependencies, no third-party scripts, no analytics — CSP locked down via _headers. Mobile-first responsive layout. Five pages: today's dashboard, triage, plan, goals, and retro. All API calls use credentials: 'include' so Cloudflare Access session cookies pass through automatically. Installable as a PWA on mobile.


03·  Stack

Tech stack

Compute

Two Cloudflare Workers — one cron-driven aggregator, one HTTP API. No server to provision or maintain.

Cloudflare Workers TypeScript

Storage

Cloudflare D1 (SQLite at the edge). Metadata only — no email bodies, no full calendar data. Every mutation appends to an audit log.

Cloudflare D1 SQLite

Inbound signals

Gmail via Google OAuth (offline access, stored refresh token in Worker Secrets). Google Calendar API. Cal.com webhooks with HMAC signature verification.

Gmail API Google Calendar API Cal.com Webhooks

Auth & access

Cloudflare Access gates the entire domain at the edge — one-time PIN to my email. API Worker checks the authenticated-user header on every request as a second layer.

Cloudflare Access Zero Trust

Frontend

Static HTML/CSS/vanilla JS on Cloudflare Pages. No frameworks, no CDN scripts, no trackers. PWA-installable for mobile access.

Cloudflare Pages Vanilla JS PWA

Build & deploy

Wrangler CLI for Workers and Pages deploys. D1 migrations via Wrangler. PowerShell deploy script that wraps both Workers in order.

Wrangler CLI PowerShell

04·  Phases

Build plan

The system ships in phases. Each phase is independent and leaves the system in a working state. Later phases add signal sources and intelligence layers.

Phase Name What ships
Phase 0 Prerequisites Done Cloudflare account provisioned, D1 database created, Cloudflare Access configured, Google Cloud project created with Gmail and Calendar APIs enabled, OAuth refresh token stored in Worker Secrets, Cal.com webhook registered.
Phase 1 Gmail + Cal.com triage In progress Aggregator Worker polling Gmail labels and Cal.com webhooks. D1 schema live. API Worker returning triage list. Frontend triage page showing classified items with priority overrides and annotation controls. Write-back to Gmail labels on annotation.
Phase 2 Plan & Calendar Planned Google Calendar read-only ingestion of hard events. Soft time-blocking via the plan page. Intent and retro endpoints. Day view combining hard events and soft blocks.
Phase 3 Goals Planned Goal CRUD with status and progress tracking. Goals surfaced on the dashboard alongside the daily intent.
Phase 4 SMS triage Planned Text messages aggregated into the same triage surface. Likely via a Twilio or similar relay depending on device constraints.
Phase 5 Intelligence layer Planned Claude API integration for smarter classification, draft replies surfaced in triage, and weekly digest synthesis. Token cost capped at the DB layer.
Phase 6 Retro & memory Planned reMarkable tablet journaling pipeline feeding into weekly reviews and long-term memory snapshots. Cross-references goals, retros, and intent history.

05·  Security

Why it stays private

This one is connected to my email, calendar, and eventually texts. The access model is non-negotiable: Cloudflare Access at the edge, defense-in-depth in the API Worker, secrets in Worker Secrets (never in code), no third-party scripts anywhere in the frontend.

What's in D1: metadata only. Subject lines (truncated), sender addresses, 200-character snippets, classification labels, timestamps. No email bodies, no full calendar event payloads, no message content.

Write-back strategy: Priority overrides write back to Gmail labels. This means user state is stored in Gmail, not just in D1 — a D1 wipe loses no information that can't be reconstructed.

Every state mutation: appends a row to the audit_log table. Not for compliance — for debuggability and peace of mind.

OAuth refresh token: stored in Cloudflare Worker Secrets, never in code or D1. Rotated manually when the Google Cloud project settings change.